From c35c00ceff060eb0b7145c691680ca67254c2f19 Mon Sep 17 00:00:00 2001 From: Hugo Thunnissen Date: Fri, 28 Jul 2023 20:18:09 +0200 Subject: [PATCH] Implement strategy pattern for completion backend --- phpinspect-class.el | 13 ++++++++++++- phpinspect-completion.el | 30 +++++++++++++++++++++--------- phpinspect-index.el | 4 +++- phpinspect-suggest.el | 5 +++-- phpinspect-type.el | 4 ++++ phpinspect.el | 32 ++++++-------------------------- 6 files changed, 49 insertions(+), 39 deletions(-) diff --git a/phpinspect-class.el b/phpinspect-class.el index 1e51bdf..7d756cd 100644 --- a/phpinspect-class.el +++ b/phpinspect-class.el @@ -78,7 +78,9 @@ (phpinspect--class-update-static-method class method)) (setf (phpinspect--class-variables class) - (alist-get 'variables index)) + (append (alist-get 'variables index) + (alist-get 'constants index) + (alist-get 'static-variables index))) (setf (phpinspect--class-extended-classes class) (seq-filter @@ -108,6 +110,15 @@ (when (string= variable-name (phpinspect--variable-name variable)) (throw 'found variable))))) +(cl-defmethod phpinspect--class-get-variables ((class phpinspect--class)) + (seq-filter #'phpinspect--variable-vanilla-p (phpinspect--class-variables class))) + +(cl-defmethod phpinspect--class-get-static-variables ((class phpinspect--class)) + (seq-filter #'phpinspect--variable-static-p (phpinspect--class-variables class))) + +(cl-defmethod phpinspect--class-get-constants ((class phpinspect--class)) + (seq-filter #'phpinspect--variable-const-p (phpinspect--class-variables class))) + (cl-defmethod phpinspect--add-method-copy-to-map ((map hash-table) (class-name phpinspect--type) diff --git a/phpinspect-completion.el b/phpinspect-completion.el index c41894c..338664a 100644 --- a/phpinspect-completion.el +++ b/phpinspect-completion.el @@ -98,13 +98,14 @@ Returns list of `phpinspect--completion'." (point (phpinspect-completion-query-point query)) (buffer-map (phpinspect-buffer-parse-map buffer)) (rctx (phpinspect-get-resolvecontext buffer-map point)) - (candidates)) + (completion-list (phpinspect--make-completion-list))) (dolist (strategy phpinspect-completion-strategies) (when (phpinspect-comp-strategy-supports strategy query rctx) (phpinspect--log "Found matching completion strategy. Executing...") - (nconc candidates (phpinspect-comp-strategy-execute strategy query rctx)))) - - (mapcar #'phpinspect--make-completion candidates))) + (dolist (candidate (phpinspect-comp-strategy-execute strategy query rctx)) + (phpinspect--completion-list-add + completion-list (phpinspect--make-completion candidate))))) + completion-list)) (cl-defgeneric phpinspect-comp-strategy-supports (strategy (query phpinspect-completion-query) (context phpinspect--resolvecontext)) "Should return non-nil if STRATEGY should be deployed for QUERY @@ -137,20 +138,31 @@ and CONTEXT. All strategies must implement this method.") (cl-defmethod phpinspect-comp-strategy-supports ((strat phpinspect-comp-attribute) (q phpinspect-completion-query) - (context phpinspect--resolvecontext)) + (rctx phpinspect--resolvecontext)) (phpinspect-object-attrib-p (car (last (phpinspect--resolvecontext-subject rctx))))) (cl-defmethod phpinspect-comp-strategy-execute - ((strat phpinspect-comp-sigil) (q phpinspect-completion-query) + ((strat phpinspect-comp-attribute) (q phpinspect-completion-query) (rctx phpinspect--resolvecontext)) - (phpinspect-suggest-variables-at-point rctx)) + (phpinspect-suggest-attributes-at-point rctx)) (cl-defstruct (phpinspect-comp-static-attribute (:constructor phpinspect-make-comp-static-attribute)) "Completion strategy for static attributes") -(cl-defstruct (phpinspect-comp-bareword (:constructor phpinspect-make-comp-bareword)) - "Completion strategy for bare words") +(cl-defmethod phpinspect-comp-strategy-supports + ((strat phpinspect-comp-static-attribute) (q phpinspect-completion-query) + (rctx phpinspect--resolvecontext)) + (phpinspect-static-attrib-p (car (last (phpinspect--resolvecontext-subject rctx))))) + +(cl-defmethod phpinspect-comp-strategy-execute + ((strat phpinspect-comp-static-attribute) (q phpinspect-completion-query) + (rctx phpinspect--resolvecontext)) + (phpinspect-suggest-attributes-at-point rctx 'static)) +(defvar phpinspect-completion-strategies (list (phpinspect-make-comp-attribute) + (phpinspect-make-comp-sigil) + (phpinspect-make-comp-static-attribute)) + "List of completion strategies that phpinspect can use.") (cl-defmethod phpinspect--make-completion ((completion-candidate phpinspect--function)) diff --git a/phpinspect-index.el b/phpinspect-index.el index b0a6b25..b43177b 100644 --- a/phpinspect-index.el +++ b/phpinspect-index.el @@ -132,7 +132,9 @@ function (think \"new\" statements, return types etc.)." (cadr (cadr (car (last var-annotations)))))))) (phpinspect--log "calling resolver from index-variable-from-scope") (phpinspect--make-variable - :name variable-name + ;; Static class variables are always prefixed with dollar signs when + ;; referenced. + :name (if static (concat "$" variable-name) variable-name) :scope `(,(car scope)) :lifetime (when static '(:static)) :type (if type (funcall type-resolver (phpinspect--make-type :name type)))))) diff --git a/phpinspect-suggest.el b/phpinspect-suggest.el index 7953142..6e42da9 100644 --- a/phpinspect-suggest.el +++ b/phpinspect-suggest.el @@ -99,9 +99,10 @@ more recent" (let ((class (phpinspect-get-or-create-cached-project-class (phpinspect-current-project-root) class-name))) - ;; TODO return static variables/constants when static is set (when class - (phpinspect--class-variables class)))) + (if static + (append (phpinspect--class-get-static-variables class) (phpinspect--class-get-constants class)) + (phpinspect--class-get-variables class))))) (defun phpinspect--make-method-lister (resolvecontext buffer-classes &optional static) (lambda (fqn) diff --git a/phpinspect-type.el b/phpinspect-type.el index 37ee587..c4d8507 100644 --- a/phpinspect-type.el +++ b/phpinspect-type.el @@ -260,5 +260,9 @@ mutability of the variable") (defun phpinspect--variable-const-p (variable) (phpinspect-const-p (phpinspect--variable-mutability variable))) +(defun phpinspect--variable-vanilla-p (variable) + (not (or (phpinspect--variable-static-p variable) + (phpinspect--variable-const-p variable)))) + (provide 'phpinspect-type) ;;; phpinspect-type.el ends here diff --git a/phpinspect.el b/phpinspect.el index 33cc004..aefdeda 100644 --- a/phpinspect.el +++ b/phpinspect.el @@ -146,7 +146,6 @@ users will have to use \\[phpinspect-purge-cache]." (when imports (phpinspect-project-enqueue-imports project imports))))) - (when imports (phpinspect-project-enqueue-imports project imports))))) @@ -226,26 +225,11 @@ Example configuration: (defun phpinspect--suggest-at-point () (phpinspect--log "Entering suggest at point. Point: %d" (point)) - (let* ((bmap (phpinspect-buffer-parse-map phpinspect-current-buffer)) - (resolvecontext (phpinspect-get-resolvecontext bmap (phpinspect--determine-completion-point))) - (last-tokens (last (phpinspect--resolvecontext-subject resolvecontext) 2))) - (phpinspect--log "Subject: %s" (phpinspect--resolvecontext-subject - resolvecontext)) - (phpinspect--log "Last tokens: %s" last-tokens) - (cond ((and (phpinspect-object-attrib-p (car last-tokens)) - (phpinspect-word-p (cadr last-tokens))) - (phpinspect--log "word-attributes") - (phpinspect-suggest-attributes-at-point resolvecontext)) - ((phpinspect-object-attrib-p (cadr last-tokens)) - (phpinspect--log "object-attributes") - (phpinspect-suggest-attributes-at-point resolvecontext)) - ((phpinspect-static-attrib-p (cadr last-tokens)) - (phpinspect--log "static-attributes") - (phpinspect-suggest-attributes-at-point token-tree resolvecontext t)) - ((phpinspect-variable-p (car(phpinspect--resolvecontext-subject - resolvecontext))) - (phpinspect-suggest-variables-at-point resolvecontext))))) - + (phpinspect-completion-query-execute + (phpinspect-make-completion-query + :buffer phpinspect-current-buffer + :completion-point (phpinspect--determine-completion-point) + :point (point)))) (defun phpinspect-company-backend (command &optional arg &rest _ignored) "A company backend for PHP." @@ -271,12 +255,8 @@ Example configuration: (insert "("))) ((eq command 'candidates) (catch 'phpinspect-parse-interrupted - (let ((completion-list (phpinspect--make-completion-list)) + (let ((completion-list (phpinspect--suggest-at-point)) (candidates)) - (dolist (completion (phpinspect--suggest-at-point)) - (phpinspect--completion-list-add - completion-list - (phpinspect--make-completion completion))) (setq candidates (seq-filter (lambda (completion)