branch: externals/phpinspect commit 87b86812ff75dc9b67c78dd267ec3923dfef5c5f Author: Hugo Thunnissen <de...@hugot.nl> Commit: Hugo Thunnissen <de...@hugot.nl>
Implement initial algorithm for indexation of traits This just add a function, it is not in use for anything yet --- phpinspect-index.el | 59 ++++++++++++++++++++++++++++++++++++++++++ phpinspect-parser.el | 2 +- phpinspect-token-predicates.el | 5 +++- test/test-index.el | 14 ++++++++++ test/test-parser.el | 13 ++++++++++ 5 files changed, 91 insertions(+), 2 deletions(-) diff --git a/phpinspect-index.el b/phpinspect-index.el index ffa0689d82..12b226241b 100644 --- a/phpinspect-index.el +++ b/phpinspect-index.el @@ -707,5 +707,64 @@ Returns a list of type name strings." "Index a PHP file for classes and the methods they have" (phpinspect--index-tokens (phpinspect-parse-current-buffer))) + +(defun phpinspect--index-trait-use (token type-resolver add-used-types) + (cl-assert (phpinspect-use-p token)) + (setq token (cddr (seq-filter #'phpinspect-not-comment-p token))) + + (let ((block? (car (last token))) + used-types config match) + (when (phpinspect-end-of-statement-p block?) + (setq token (butlast token))) + + (setq token (seq-filter #'phpinspect-not-comma-p token)) + + (dolist (word token) + (when (phpinspect-word-p word) + (push (cadr token) used-types) + (push `(,(funcall type-resolver (phpinspect--make-type :name (cadr word)))) + config))) + + (when (phpinspect-block-p block?) + (setq block? (cdr (seq-filter #'phpinspect-not-comment-p block?))) + + (while block? + (cond ((phpinspect-comma-p (car block?)) + (pop block?)) + ;; Override + ((phpinspect--match-sequence block? + :f #'phpinspect-word-p + :f #'phpinspect-static-attrib-p + :m '(:word "insteadof") + :f #'phpinspect-word-p + :rest *) + (let* ((type (funcall type-resolver (phpinspect--make-type :name (cadr (nth 3 block?))))) + (t-config (assoc type config #'phpinspect--type=))) + (when t-config + (push `(override ,(cadadr (cadr block?)) + ,(funcall type-resolver + (phpinspect--make-type :name (cadar block?)))) + (cdr t-config)))) + + (setq block? (nthcdr 4 block?))) + + ;; alias + ((phpinspect--match-sequence block? + :f #'phpinspect-word-p + :f #'phpinspect-static-attrib-p + :m '(:word "as") + :f #'phpinspect-word-p + :rest *) + (let* ((type (funcall type-resolver (phpinspect--make-type :name (cadar block?)))) + (t-config (assoc type config #'phpinspect--type=))) + + (when t-config + (push `(alias ,(cadadr (cadr block?)) ,(cadr (nth 3 block?))) + (cdr t-config)))) + + (setq block? (nthcdr 4 block?))))) + + config))) + (provide 'phpinspect-index) ;;; phpinspect-index.el ends here diff --git a/phpinspect-parser.el b/phpinspect-parser.el index 948fc38470..d5c7a96d0f 100644 --- a/phpinspect-parser.el +++ b/phpinspect-parser.el @@ -599,7 +599,7 @@ nature like argument lists" (phpinspect-defparser use :tree-keyword "use" - :handlers '(word tag block-without-scopes terminator) + :handlers '(comment word tag block-without-scopes comma terminator) :delimiter-predicate #'phpinspect-end-of-use-p) (phpinspect-defhandler use-keyword (start-token max-point) diff --git a/phpinspect-token-predicates.el b/phpinspect-token-predicates.el index 76acb8425c..29690f0bcc 100644 --- a/phpinspect-token-predicates.el +++ b/phpinspect-token-predicates.el @@ -51,6 +51,9 @@ Type can be any of the token types returned by (defun phpinspect-comma-p (token) (phpinspect-token-type-p token :comma)) +(defun phpinspect-not-comma-p (token) + (not (phpinspect-comma-p token))) + (defsubst phpinspect-terminator-p (token) (phpinspect-token-type-p token :terminator)) @@ -72,7 +75,7 @@ Type can be any of the token types returned by (defun phpinspect-end-of-use-p (token) (or (phpinspect-block-p token) - (phpinspect-end-of-token-p token))) + (phpinspect-terminator-p token))) (defun phpinspect-static-p (token) (phpinspect-token-type-p token :static)) diff --git a/test/test-index.el b/test/test-index.el index 718ffeb2ef..9244fef669 100644 --- a/test/test-index.el +++ b/test/test-index.el @@ -439,3 +439,17 @@ if (something()) { (conditional (cadr functions))) (should (string= "conditional" (phpinspect--function-name conditional))) (should (string= "nestedConditional" (phpinspect--function-name nestedConditional))))))) + +(ert-deftest phpinspect-index-trait-use () + (let* ((tree (with-temp-buffer + (insert "use B, C { C::foo insteadof B, B::bar as banana }") + (goto-char (point-min)) + (phpinspect--parse-use (current-buffer) (point-max)))) + (expected `((,(phpinspect--make-type :name "\\C" :fully-qualified t)) + (,(phpinspect--make-type :name "\\B" :fully-qualified t) + (alias "bar" "banana") + (override "foo" ,(phpinspect--make-type :name "\\C" :fully-qualified t))))) + (index (phpinspect--index-trait-use tree (phpinspect--make-type-resolver nil nil nil) nil))) + + (should index) + (should (equal expected index)))) diff --git a/test/test-parser.el b/test/test-parser.el index 0e86853e83..6df6e53fab 100644 --- a/test/test-parser.el +++ b/test/test-parser.el @@ -144,3 +144,16 @@ class TestClass { (expected-result (phpinspect--index-tokens (phpinspect-test-read-fixture-data "IndexClass1")))) (should (equal index expected-result)))) + +(ert-deftest phpinspect-parse-class-with-trait-uses () + (let ((tree (phpinspect-parse-string "class A { use B, C { C::foo insteadof A } }"))) + + (should tree) + (should (equal + '(:root (:class (:declaration (:word "class") (:word "A")) + (:block + (:use (:word "B") (:comma ",") (:word "C") + (:block + (:word "C") (:static-attrib (:word "foo")) + (:word "insteadof") (:word "A")))))) + tree))))