branch: externals/phpinspect
commit 2520c8968011ba714919448e09c59c857ecc77e0
Author: Hugo Thunnissen <[email protected]>
Commit: Hugo Thunnissen <[email protected]>
Account for tokens after @method annotation when indexing
- Add :rest keyword to `phpinspect--match-sequence'
- Use :rest keyword in `phpinspect--index-method-annotations'
---
phpinspect-index.el | 12 ++++++++----
phpinspect-util.el | 23 +++++++++++++++++++----
test/test-index.el | 2 +-
test/test-util.el | 28 ++++++++++++++++++++++++++++
4 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/phpinspect-index.el b/phpinspect-index.el
index f948d6f61b..474e9123ca 100644
--- a/phpinspect-index.el
+++ b/phpinspect-index.el
@@ -224,24 +224,28 @@ SCOPE should be a scope token (`phpinspect-scope-p')."
(dolist (annotation annotations)
(let ((return-type) (name) (arg-list) (static))
;; Annotation is static
- (when (phpinspect--match-sequence (take 2 annotation)
- :m :method-annotation :m '(:word "static"))
+ (when (phpinspect--match-sequence annotation
+ :m :method-annotation :m '(:word "static") :rest *)
(setcdr annotation (cddr annotation))
(setq static t))
(cond
+ ;; Sequence is: return-type, method-name, method signature
((phpinspect--match-sequence annotation
:m :method-annotation
:f #'phpinspect-word-p
:f #'phpinspect-word-p
- :f #'phpinspect-list-p)
+ :f #'phpinspect-list-p
+ :rest *)
(setq return-type (cadr (nth 1 annotation)))
(setq name (cadr (nth 2 annotation)))
(setq arg-list (nth 3 annotation)))
+ ;; Sequence is: method-name, method-signature
((phpinspect--match-sequence annotation
:m :method-annotation
:f #'phpinspect-word-p
- :f #'phpinspect-list-p)
+ :f #'phpinspect-list-p
+ :rest *)
(setq return-type "void")
(setq name (cadr (nth 1 annotation)))
(setq arg-list (nth 2 annotation))))
diff --git a/phpinspect-util.el b/phpinspect-util.el
index bd722871f2..4aaf2fa32a 100644
--- a/phpinspect-util.el
+++ b/phpinspect-util.el
@@ -170,6 +170,13 @@ pattern. See `phpinspect--match-sequence'."
"Match SEQUENCE to PATTERN."
(funcall (phpinspect--pattern-matcher pattern) sequence))
+(defun phpinspect--list-all-equal (val sequence)
+ (catch 'not-equal
+ (dolist (item sequence)
+ (unless (equal val item)
+ (throw 'not-equal nil)))
+ t))
+
(defmacro phpinspect--match-sequence (sequence &rest pattern)
"Match SEQUENCE to positional matchers defined in PATTERN.
@@ -201,7 +208,7 @@ it evaluates to a non-nil value."
(match-rear-sym (gensym))
(checkers (cons nil nil))
(checkers-rear checkers)
- key value)
+ rest key value)
(while (setq key (pop pattern))
(unless (keywordp key)
@@ -224,6 +231,8 @@ it evaluates to a non-nil value."
`(,value (elt ,sequence-sym ,sequence-pos))
`(funcall ,value (elt ,sequence-sym ,sequence-pos)))
nil))))
+ ((eq key :rest)
+ (setq rest value))
(t (error "Invalid keyword: %s" key)))
(setq checkers-rear
@@ -240,9 +249,15 @@ it evaluates to a non-nil value."
`(let* ((,sequence-sym ,sequence)
(,match-sym (cons nil nil))
(,match-rear-sym ,match-sym))
- (and (= ,sequence-length (length ,sequence))
- ,@checkers
- (cdr ,match-sym)))))
+ ,(if rest
+ `(and ,@checkers
+ (cdr ,match-sym)
+ ,(if (eq rest '*)
+ 't
+ `(phpinspect--list-all-equal ,rest (nthcdr
,sequence-length ,sequence-sym))))
+ `(and (= ,sequence-length (length ,sequence))
+ ,@checkers
+ (cdr ,match-sym))))))
(defun phpinspect--pattern-concat (pattern1 pattern2)
(let* ((pattern1-sequence-length (/ (length (phpinspect--pattern-code
pattern1)) 2)))
diff --git a/test/test-index.el b/test/test-index.el
index d1621bc8ae..5f3f4bf4e0 100644
--- a/test/test-index.el
+++ b/test/test-index.el
@@ -127,7 +127,7 @@ return StaticThing::create(new
ThingFactory())->makeThing((((new Potato())->anti
"<?php
/* @method int peel(bool $fast, array $loose)
- * @method Banana duplicate()
+ * @method Banana duplicate() Words after annotation
@method hold() **/
class Banana {}")))
(class (car (alist-get 'classes result)))
diff --git a/test/test-util.el b/test/test-util.el
index 2e708dceb8..c580367519 100644
--- a/test/test-util.el
+++ b/test/test-util.el
@@ -55,3 +55,31 @@
:m '(:object-attrib (:word "not-a-match")))))
(should-not result)))
+
+(ert-deftest phpinspect--pattern-match-rest ()
+ (should (phpinspect--match-sequence '((:variable "this") (:object-attrib
(:word "em")) (:list))
+ :m '(:variable "this")
+ :m *
+ :rest '(:list)))
+
+ (should (phpinspect--match-sequence '((:variable "this") (:object-attrib
(:word "em")) (:list))
+ :m '(:variable "this")
+ :m *
+ :rest *))
+
+ (should (phpinspect--match-sequence '((:variable "this") (:object-attrib
(:word "em")) (:list))
+ :m '(:variable "this")
+ :m *
+ :rest '(:list)))
+
+ (should (phpinspect--match-sequence '((:variable "this") (:object-attrib
(:word "em")) (:list))
+ :m '(:variable "this")
+ :rest *))
+
+ (should-not (phpinspect--match-sequence '((:variable "this") (:object-attrib
(:word "em")) (:variable "ba") (:list))
+ :m '(:variable "this")
+ :rest '(:list)))
+
+ (should-not (phpinspect--match-sequence '((:variable "this") (:object-attrib
(:word "em")) (:list))
+ :m '(:variable "this")
+ :m *)))