branch: externals/phpinspect commit 4ec4c40c9df59ce395fa3796e12799b6f7abc32f Author: Hugo Thunnissen <de...@hugot.nl> Commit: Hugo Thunnissen <de...@hugot.nl>
Add eldoc for sigil variables and allow display of multiple eldoc results By allowing multiple eldoc results, displaying variable information doesn't interfere with function parameter hints. --- phpinspect-eldoc.el | 43 ++++++++++++++++++++++++++++++------------- phpinspect-index.el | 7 ++++--- phpinspect-resolvecontext.el | 3 ++- phpinspect-type.el | 9 +++++++++ test/test-eldoc.el | 9 +++++---- 5 files changed, 50 insertions(+), 21 deletions(-) diff --git a/phpinspect-eldoc.el b/phpinspect-eldoc.el index 613c1c4df0..1a24485767 100644 --- a/phpinspect-eldoc.el +++ b/phpinspect-eldoc.el @@ -53,6 +53,22 @@ and CONTEXT. All strategies must implement this method.") "Should return a string to be displayed by eldoc. This needs to be implemented for return values of `phpinspect-eld-strategy-execute'") +(cl-defstruct (phpinspect-eld-sigil (:constructor phpinspect-make-eld-sigil)) + "Eldoc strategy for sigil ($) variables.") + +(cl-defmethod phpinspect-eld-strategy-supports + ((_strat phpinspect-eld-sigil) (_q phpinspect-eldoc-query) (rctx phpinspect--resolvecontext)) + (phpinspect-variable-p (car (last (phpinspect--resolvecontext-subject rctx))))) + +(cl-defmethod phpinspect-eld-strategy-execute + ((_strat phpinspect-eld-sigil) (_q phpinspect-eldoc-query) (rctx phpinspect--resolvecontext)) + (when-let ((type (phpinspect-resolve-type-from-context rctx)) + (variable (car (last (phpinspect--resolvecontext-subject rctx))))) + (when (and (phpinspect-variable-p variable) (cadr variable)) + (phpinspect--make-variable :name (cadr variable) + :scope '(:public) + :type type)))) + (cl-defstruct (phpinspect-eld-attribute (:constructor phpinspect-make-eld-attribute)) "Eldoc strategy for object attributes.") @@ -120,25 +136,23 @@ be implemented for return values of `phpinspect-eld-strategy-execute'") (left-sibling ) (statement ) match-result static arg-list arg-pos) - (cond ;; Subject is a statement ((and (phpinspect-list-p (car (last (phpinspect--resolvecontext-subject rctx)))) enclosing-token) - (setq left-sibling (phpinspect-meta-find-child-before-recursively enclosing-token (phpinspect-eldoc-query-point q)))) ;; Subject is inside an argument list ((and enclosing-token - (phpinspect-list-p (phpinspect-meta-token enclosing-token))) + (phpinspect-list-p (phpinspect-meta-token enclosing-token))) (setq left-sibling (phpinspect-meta-find-left-sibling enclosing-token) statement (list enclosing-token)))) (phpinspect--log "Left sibling: %s" (phpinspect-meta-string left-sibling)) (phpinspect--log "Enclosing parent: %s" (phpinspect-meta-string (phpinspect-meta-parent enclosing-token))) - (while (and left-sibling + (not (phpinspect-variable-p (phpinspect-meta-token (car statement)))) (not (phpinspect-statement-introduction-p (phpinspect-meta-token left-sibling)))) (unless (phpinspect-comment-p (phpinspect-meta-token left-sibling)) (push left-sibling statement)) @@ -212,7 +226,7 @@ be implemented for return values of `phpinspect-eld-strategy-execute'") 'face 'font-lock-variable-name-face) phpinspect-eldoc-word-width) ": " - (propertize (phpinspect--format-type-name (phpinspect--variable-type var)) + (propertize (phpinspect--display-format-type-name (phpinspect--variable-type var)) 'face 'font-lock-type-face))) (cl-defstruct (phpinspect-function-doc (:constructor phpinspect-make-function-doc)) @@ -232,7 +246,7 @@ be implemented for return values of `phpinspect-eld-strategy-execute'") (concat "$" (truncate-string-to-width (car arg) phpinspect-eldoc-word-width) (if (cadr arg) " " "") - (phpinspect--format-type-name (or (cadr arg) ""))))) + (phpinspect--display-format-type-name (or (cadr arg) ""))))) (when (and arg-pos (= arg-count arg-pos)) (setq doc-string (propertize @@ -243,11 +257,12 @@ be implemented for return values of `phpinspect-eld-strategy-execute'") ", ") "): " (propertize - (phpinspect--format-type-name (phpinspect--function-return-type fn)) + (phpinspect--display-format-type-name (phpinspect--function-return-type fn)) 'face 'font-lock-type-face)))) (defvar phpinspect-eldoc-strategies (list (phpinspect-make-eld-attribute) - (phpinspect-make-eld-function-args)) + (phpinspect-make-eld-function-args) + (phpinspect-make-eld-sigil)) "The eldoc strategies that phpinspect is currently allowed to employ. Strategies are queried in the order of this list. See also `phpinspect-eldoc-query-execute'.") @@ -256,13 +271,15 @@ also `phpinspect-eldoc-query-execute'.") (let* ((buffer (phpinspect-eldoc-query-buffer query)) (point (phpinspect-eldoc-query-point query)) (buffer-map (phpinspect-buffer-parse-map buffer)) - (rctx (phpinspect-get-resolvecontext buffer-map point))) + (rctx (phpinspect-get-resolvecontext buffer-map point)) + responses) (phpinspect-buffer-update-project-index buffer) - (catch 'matched - (dolist (strategy phpinspect-eldoc-strategies) + (dolist (strategy phpinspect-eldoc-strategies) + (let ((rctx (phpinspect--copy-resolvecontext rctx))) (when (phpinspect-eld-strategy-supports strategy query rctx) (phpinspect--log "Found matching eldoc strategy. Executing...") - (throw 'matched (phpinspect-eld-strategy-execute strategy query rctx))))))) + (push (phpinspect-eld-strategy-execute strategy query rctx) responses)))) + (remove nil responses))) (defun phpinspect-eldoc-function () "An `eldoc-documentation-function` implementation for PHP files. @@ -278,7 +295,7 @@ TODO: :buffer phpinspect-current-buffer :point (phpinspect--determine-completion-point))))) (when resp - (phpinspect-eldoc-string resp))))) + (mapconcat #'phpinspect-eldoc-string resp "\n"))))) (provide 'phpinspect-eldoc) diff --git a/phpinspect-index.el b/phpinspect-index.el index a026080522..93507e4fa4 100644 --- a/phpinspect-index.el +++ b/phpinspect-index.el @@ -138,9 +138,10 @@ function (think \"new\" statements, return types etc.)." ;; @return annotation. When dealing with a collection, we want to store the ;; type of its members. - (let* ((return-annotation-type - (cadadr (seq-find #'phpinspect-return-annotation-p comment-before)))) - (phpinspect--apply-annotation-type return-annotation-type type type-resolver)) + (when type + (let* ((return-annotation-type + (cadadr (seq-find #'phpinspect-return-annotation-p comment-before)))) + (phpinspect--apply-annotation-type return-annotation-type type type-resolver))) (when add-used-types (let ((used-types (phpinspect--find-used-types-in-tokens diff --git a/phpinspect-resolvecontext.el b/phpinspect-resolvecontext.el index 42d087fff3..8d3b9f580b 100644 --- a/phpinspect-resolvecontext.el +++ b/phpinspect-resolvecontext.el @@ -49,7 +49,8 @@ (phpinspect-function-p ,token))))) (cl-defstruct (phpinspect--resolvecontext - (:constructor phpinspect--make-resolvecontext)) + (:constructor phpinspect--make-resolvecontext) + (:copier phpinspect--copy-resolvecontext)) (subject nil :type phpinspect--token :documentation diff --git a/phpinspect-type.el b/phpinspect-type.el index bee9a406ca..dc55ae143e 100644 --- a/phpinspect-type.el +++ b/phpinspect-type.el @@ -215,6 +215,15 @@ NAMESPACE may be nil, or a string with a namespace FQN." (cl-defmethod phpinspect--format-type-name ((type phpinspect--type)) (phpinspect--format-type-name (phpinspect--type-name type))) +(cl-defmethod phpinspect--display-format-type-name ((name string)) + (phpinspect--format-type-name name)) + +(cl-defmethod phpinspect--display-format-type-name ((type phpinspect--type)) + (let ((self (phpinspect--format-type-name type))) + (if (phpinspect--type-contains type) + (concat self "<" (phpinspect--format-type-name (phpinspect--type-contains type)) ">") + self))) + (cl-defstruct (phpinspect--function (:constructor phpinspect--make-function-generated) (:copier phpinspect--copy-function)) "A PHP function." diff --git a/test/test-eldoc.el b/test/test-eldoc.el index 79696e6ca8..c3bd509157 100644 --- a/test/test-eldoc.el +++ b/test/test-eldoc.el @@ -38,8 +38,9 @@ class Thing (backward-char 8) (setq first-arg-pos (point)) - (let ((result (phpinspect-eldoc-query-execute - (phpinspect-make-eldoc-query :point second-arg-pos :buffer buffer)))) + (let ((result (seq-find #'phpinspect-function-doc-p + (phpinspect-eldoc-query-execute + (phpinspect-make-eldoc-query :point second-arg-pos :buffer buffer))))) (should (phpinspect-function-doc-p result)) (should (= 1 (phpinspect-function-doc-arg-pos result))) (should (string= "getThis" (phpinspect--function-name (phpinspect-function-doc-fn result)))) @@ -48,8 +49,8 @@ class Thing (phpinspect-make-eldoc-query :point inside-nested-list-pos :buffer buffer))) (should-not result) - (setq result (phpinspect-eldoc-query-execute - (phpinspect-make-eldoc-query :point first-arg-pos :buffer buffer))) + (setq result (car (phpinspect-eldoc-query-execute + (phpinspect-make-eldoc-query :point first-arg-pos :buffer buffer)))) (should (phpinspect-function-doc-p result)) (should (= 0 (phpinspect-function-doc-arg-pos result))) (should (string= "getThis" (phpinspect--function-name (phpinspect-function-doc-fn result))))))))