branch: externals/phpinspect
commit 6b8db3a318862bb5788947863860e8c59acfa749
Author: Hugo Thunnissen <de...@hugot.nl>
Commit: Hugo Thunnissen <de...@hugot.nl>

    Test and fix eldoc function for static methods
    
    Add tests for
    - phpinspect-eldoc-function in the context of static attribute and object 
attribute references
    - phpinspect-resolve-type-from-context in the context of static attribute 
references
    
    Fix:
    - phpinspect-get-derived-statement-type-in-block
---
 phpinspect.el           | 41 +++++++++++++------------
 test/phpinspect-test.el | 82 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 103 insertions(+), 20 deletions(-)

diff --git a/phpinspect.el b/phpinspect.el
index 5ebf68cad7..6184206fc8 100644
--- a/phpinspect.el
+++ b/phpinspect.el
@@ -63,6 +63,9 @@ phpinspect")
   "Used internally to save metadata about completion options
   between company backend calls")
 
+(defvar phpinspect-eldoc-word-width 14
+  "The maximum width of words in eldoc strings.")
+
 (defvar phpinspect-index-executable
   (concat (file-name-directory
            (or load-file-name
@@ -1220,20 +1223,23 @@ TODO:
                 (comma-count
                  (length (seq-filter #'phpinspect-comma-p incomplete-token))))
             (concat (truncate-string-to-width
-                     (phpinspect--function-name method) 14) ": ("
+                     (phpinspect--function-name method) 
phpinspect-eldoc-word-width) ": ("
                      (mapconcat
                       (lambda (arg)
                         (setq arg-count (+ arg-count 1))
                         (if (= arg-count comma-count)
                             (propertize (concat
                                          "$"
-                                         (truncate-string-to-width (car arg) 8)
+                                         (truncate-string-to-width
+                                          (car arg)
+                                          phpinspect-eldoc-word-width)
                                          " "
                                          (phpinspect--format-type-name (or 
(cadr arg) "")))
                                         'face 
'eldoc-highlight-function-argument)
                           (concat "$"
-                                  (truncate-string-to-width (car arg) 8)
-                                  " "
+                                  (truncate-string-to-width (car arg)
+                                                            
phpinspect-eldoc-word-width)
+                                  (if (cadr arg) " " "")
                                   (phpinspect--format-type-name (or (cadr arg) 
"")))))
                       (phpinspect--function-arguments method)
                       ", ")
@@ -1280,6 +1286,11 @@ TODO:
           (push assignment variable-assignments)))
     (nreverse variable-assignments)))
 
+(defun phpinspect-drop-preceding-barewords (statement)
+  (while (and statement (phpinspect-word-p (cadr statement)))
+    (pop statement))
+  statement)
+
 (defun phpinspect-get-derived-statement-type-in-block
     (resolvecontext statement php-block type-resolver &optional 
function-arg-list)
   "Get type of RESOLVECONTEXT subject in PHP-BLOCK.
@@ -1305,25 +1316,15 @@ $variable = $variable->method();"
       ;; No first token means we were passed an empty list.
       (when (and first-token
                  (setq previous-attribute-type
-                       ;; Statements that are only bare words can be something 
preceding
-                       ;; a static attribute that is not passed to this 
function. For
-                       ;; example "return self" could have prefixed another 
attribute
-                       ;; that the caller is trying to derive. Therefore we 
just try to
-                       ;; resolve the type of the last bare word in the 
statement.
-                       (or (when (and (phpinspect-word-p first-token)
-                                      (seq-every-p #'phpinspect-word-p 
statement))
-                             (setq statement (last statement))
-                             (funcall type-resolver (cadr (pop statement))))
-
+                       (or
                            ;; Statements starting with a bare word can 
indicate a static
                            ;; method call. These could be statements with 
"return" or
-                           ;; another bare-word at the start though, so we dop 
tokens
-                           ;; from the statement until it starts with a static 
attribute
-                           ;; refererence (::something in PHP code).
+                           ;; another bare-word at the start though, so we 
drop preceding
+                           ;; barewords when they are present.
                            (when (phpinspect-word-p first-token)
-                             (while (and first-token
-                                         (not (phpinspect-static-attrib-p
-                                               (car statement))))
+                             (when (phpinspect-word-p (car statement))
+                               (setq statement 
(phpinspect-drop-preceding-barewords
+                                                statement))
                                (setq first-token (pop statement)))
                              (funcall type-resolver (cadr first-token)))
 
diff --git a/test/phpinspect-test.el b/test/phpinspect-test.el
index 338a3c7159..da8605220d 100644
--- a/test/phpinspect-test.el
+++ b/test/phpinspect-test.el
@@ -313,5 +313,87 @@ class FlufferUpper
                     (phpinspect--make-type-resolver-for-resolvecontext
                      context))))))
 
+(ert-deftest phpinspect-eldoc-function-for-object-method ()
+  (let* ((php-code "
+class Thing
+{
+    function getThis(\\DateTime $moment, Thing $thing, $other): static
+    {
+        return $this;
+    }
+
+    function doStuff()
+    {
+        $this->getThis(")
+         (tokens (phpinspect-parse-string php-code))
+         (index (phpinspect--index-tokens tokens))
+         (phpinspect-project-root-function (lambda () "phpinspect-test"))
+         (phpinspect-eldoc-word-width 100))
+    (phpinspect-purge-cache)
+    (phpinspect-cache-project-class
+     (phpinspect-project-root)
+     (cdar (alist-get 'classes (cdr index))))
+
+    (should (string= "getThis: ($moment DateTime, $thing Thing, $other): Thing"
+                   (with-temp-buffer
+                     (insert php-code)
+                     (phpinspect-eldoc-function))))))
+
+(ert-deftest phpinspect-eldoc-function-for-static-method ()
+  (let* ((php-code "
+class Thing
+{
+    static function doThing(\\DateTime $moment, Thing $thing, $other): static
+    {
+        return $this;
+    }
+
+    function doStuff()
+    {
+        self::doThing(")
+         (tokens (phpinspect-parse-string php-code))
+         (index (phpinspect--index-tokens tokens))
+         (phpinspect-project-root-function (lambda () "phpinspect-test"))
+         (phpinspect-eldoc-word-width 100))
+    (phpinspect-purge-cache)
+    (phpinspect-cache-project-class
+     (phpinspect-project-root)
+     (cdar (alist-get 'classes (cdr index))))
+
+    (should (string= "doThing: ($moment DateTime, $thing Thing, $other): Thing"
+                   (with-temp-buffer
+                     (insert php-code)
+                     (phpinspect-eldoc-function))))))
+
+
+(ert-deftest phpinspect-resolve-type-from-context-static-method ()
+  (let* ((php-code "
+class Thing
+{
+    static function doThing(\\DateTime $moment, Thing $thing, $other): static
+    {
+        return $this;
+    }
+
+    function doStuff()
+    {
+        self::doThing()->")
+         (tokens (phpinspect-parse-string php-code))
+         (index (phpinspect--index-tokens tokens))
+         (phpinspect-project-root-function (lambda () "phpinspect-test"))
+         (phpinspect-eldoc-word-width 100)
+         (context (phpinspect--get-resolvecontext tokens)))
+    (phpinspect-purge-cache)
+    (phpinspect-cache-project-class
+     (phpinspect-project-root)
+     (cdar (alist-get 'classes (cdr index))))
+
+    (should (string= "\\Thing"
+                     (phpinspect-resolve-type-from-context
+                      context
+                      (phpinspect--make-type-resolver-for-resolvecontext
+                       context))))))
+
+
 (provide 'phpinspect-test)
 ;;; phpinspect-test.el ends here

Reply via email to