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))))))))

Reply via email to