From 2520c8968011ba714919448e09c59c857ecc77e0 Mon Sep 17 00:00:00 2001 From: Hugo Thunnissen Date: Mon, 12 Aug 2024 11:18:25 +0200 Subject: [PATCH] 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 f948d6f..474e912 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 bd72287..4aaf2fa 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 d1621bc..5f3f4bf 100644 --- a/test/test-index.el +++ b/test/test-index.el @@ -127,7 +127,7 @@ return StaticThing::create(new ThingFactory())->makeThing((((new Potato())->anti "