Account for tokens after @method annotation when indexing

- Add :rest keyword to  `phpinspect--match-sequence'
- Use :rest keyword in  `phpinspect--index-method-annotations'
master
Hugo Thunnissen 1 month ago
parent 5528aff2a2
commit 2520c89680

@ -224,24 +224,28 @@ SCOPE should be a scope token (`phpinspect-scope-p')."
(dolist (annotation annotations) (dolist (annotation annotations)
(let ((return-type) (name) (arg-list) (static)) (let ((return-type) (name) (arg-list) (static))
;; Annotation is static ;; Annotation is static
(when (phpinspect--match-sequence (take 2 annotation) (when (phpinspect--match-sequence annotation
:m :method-annotation :m '(:word "static")) :m :method-annotation :m '(:word "static") :rest *)
(setcdr annotation (cddr annotation)) (setcdr annotation (cddr annotation))
(setq static t)) (setq static t))
(cond (cond
;; Sequence is: return-type, method-name, method signature
((phpinspect--match-sequence annotation ((phpinspect--match-sequence annotation
:m :method-annotation :m :method-annotation
:f #'phpinspect-word-p :f #'phpinspect-word-p
: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 return-type (cadr (nth 1 annotation)))
(setq name (cadr (nth 2 annotation))) (setq name (cadr (nth 2 annotation)))
(setq arg-list (nth 3 annotation))) (setq arg-list (nth 3 annotation)))
;; Sequence is: method-name, method-signature
((phpinspect--match-sequence annotation ((phpinspect--match-sequence annotation
:m :method-annotation :m :method-annotation
:f #'phpinspect-word-p :f #'phpinspect-word-p
:f #'phpinspect-list-p) :f #'phpinspect-list-p
:rest *)
(setq return-type "void") (setq return-type "void")
(setq name (cadr (nth 1 annotation))) (setq name (cadr (nth 1 annotation)))
(setq arg-list (nth 2 annotation)))) (setq arg-list (nth 2 annotation))))

@ -170,6 +170,13 @@ pattern. See `phpinspect--match-sequence'."
"Match SEQUENCE to PATTERN." "Match SEQUENCE to PATTERN."
(funcall (phpinspect--pattern-matcher pattern) sequence)) (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) (defmacro phpinspect--match-sequence (sequence &rest pattern)
"Match SEQUENCE to positional matchers defined in PATTERN. "Match SEQUENCE to positional matchers defined in PATTERN.
@ -201,7 +208,7 @@ it evaluates to a non-nil value."
(match-rear-sym (gensym)) (match-rear-sym (gensym))
(checkers (cons nil nil)) (checkers (cons nil nil))
(checkers-rear checkers) (checkers-rear checkers)
key value) rest key value)
(while (setq key (pop pattern)) (while (setq key (pop pattern))
(unless (keywordp key) (unless (keywordp key)
@ -224,6 +231,8 @@ it evaluates to a non-nil value."
`(,value (elt ,sequence-sym ,sequence-pos)) `(,value (elt ,sequence-sym ,sequence-pos))
`(funcall ,value (elt ,sequence-sym ,sequence-pos))) `(funcall ,value (elt ,sequence-sym ,sequence-pos)))
nil)))) nil))))
((eq key :rest)
(setq rest value))
(t (error "Invalid keyword: %s" key))) (t (error "Invalid keyword: %s" key)))
(setq checkers-rear (setq checkers-rear
@ -240,9 +249,15 @@ it evaluates to a non-nil value."
`(let* ((,sequence-sym ,sequence) `(let* ((,sequence-sym ,sequence)
(,match-sym (cons nil nil)) (,match-sym (cons nil nil))
(,match-rear-sym ,match-sym)) (,match-rear-sym ,match-sym))
(and (= ,sequence-length (length ,sequence)) ,(if rest
,@checkers `(and ,@checkers
(cdr ,match-sym))))) (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) (defun phpinspect--pattern-concat (pattern1 pattern2)
(let* ((pattern1-sequence-length (/ (length (phpinspect--pattern-code pattern1)) 2))) (let* ((pattern1-sequence-length (/ (length (phpinspect--pattern-code pattern1)) 2)))

@ -127,7 +127,7 @@ return StaticThing::create(new ThingFactory())->makeThing((((new Potato())->anti
"<?php "<?php
/* @method int peel(bool $fast, array $loose) /* @method int peel(bool $fast, array $loose)
* @method Banana duplicate() * @method Banana duplicate() Words after annotation
@method hold() **/ @method hold() **/
class Banana {}"))) class Banana {}")))
(class (car (alist-get 'classes result))) (class (car (alist-get 'classes result)))

@ -55,3 +55,31 @@
:m '(:object-attrib (:word "not-a-match"))))) :m '(:object-attrib (:word "not-a-match")))))
(should-not result))) (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 *)))

Loading…
Cancel
Save