From 817ff0052383bdc6790d0130d22951f9f64825c6 Mon Sep 17 00:00:00 2001 From: Hugo Thunnissen Date: Fri, 25 Aug 2023 21:02:33 +0200 Subject: [PATCH] Add :extending and :implementing queries --- phpinspect-cache.el | 127 +++++++++++++++++++++++++++++++++++--------- test/test-cache.el | 49 ++++++++++++++++- 2 files changed, 149 insertions(+), 27 deletions(-) diff --git a/phpinspect-cache.el b/phpinspect-cache.el index 998a7d2..088f2fd 100644 --- a/phpinspect-cache.el +++ b/phpinspect-cache.el @@ -328,6 +328,7 @@ then returned." (groups (make-hash-table :test #'equal :size 2000 :rehash-size 1.2))) (cl-defstruct (phpinspect-cache-type (:constructor phpinspect-make-cache-type)) + (group nil) (category nil) (name nil) (methods nil) @@ -353,6 +354,36 @@ then returned." (defconst phpinspect-cache-member-types '(method abstract-method function variable) "Types of entities that the cache can store as members.")) +(defun phpinspect-cache-type-get-extends (type) + (phpinspect-cache-group-get-extends + (phpinspect-cache-type-group type) + (phpinspect-cache-type-name type))) + +(defun phpinspect-cache-type-get-implements (type) + (phpinspect-cache-group-get-implements + (phpinspect-cache-type-group type) + (phpinspect-cache-type-name type))) + +(defun phpinspect-cache-group-get-extends (group type-name) + (phpinspect-bidi-graph-get-linking-from + (phpinspect-cache-group-extends group) + type-name)) + +(defun phpinspect-cache-group-get-implements (group type-name) + (phpinspect-bidi-graph-get-linking-from + (phpinspect-cache-group-implements group) + type-name)) + +(defun phpinspect-cache-group-get-extending (group type-name) + (phpinspect-bidi-graph-get-linking-to + (phpinspect-cache-group-extends group) + type-name)) + +(defun phpinspect-cache-group-get-implementing (group type-name) + (phpinspect-bidi-graph-get-linking-to + (phpinspect-cache-group-implements group) + type-name)) + (defun phpinspect-cache-group-get-namespace (group namespace) (gethash namespace (phpinspect-cache-group-namespaces group))) @@ -361,13 +392,15 @@ then returned." (puthash namespace (phpinspect-make-cache-namespace) (phpinspect-cache-group-namespaces group)))) -(defun phpinspect-cache-namespace-get-type-create (namespace type category) +(defun phpinspect-cache-namespace-get-type-create (namespace type category group) (or (phpinspect-cache-namespace-get-type namespace type category) - (push (cons (phpinspect--type-short-name type) - (phpinspect-make-cache-type - :name (phpinspect--type-name-symbol type) - :category category)) - (phpinspect-cache-namespace-types namespace)))) + (cdar + (push (cons (phpinspect--type-short-name type) + (phpinspect-make-cache-type + :name (phpinspect--type-name-symbol type) + :category category + :group group)) + (phpinspect-cache-namespace-types namespace))))) (defun phpinspect-cache-namespace-get-type (namespace type category) (when-let ((entity @@ -578,7 +611,8 @@ then returned." ,(when implements `(phpinspect-cache-group-register-implements ,group ,param ,implements)) - (phpinspect-cache-namespace-get-type-create namespace ,param (quote ,type)))))) + (phpinspect-cache-namespace-get-type-create + namespace ,param (quote ,type) ,group))))) ((and (eq 'function type) (not member)) (setq register-form (inline-quote @@ -595,26 +629,67 @@ then returned." (define-inline phpinspect-cache-query--do-get-type (group param type member namespace implements extends) (inline-letevals (group param member namespace implements extends) - (if (and (inline-const-p param) (eq '* (inline-const-val param))) - (if namespace + (let ((form + (if (and (inline-const-p param) (eq '* (inline-const-val param))) + (if namespace + (inline-quote + (when-let ((namespace (phpinspect-cache-group-get-namespace + ,group ,namespace))) + (cons 'phpinspect-cache-multiresult + (mapcar #'cdr (phpinspect-cache-namespace-types namespace))))) + (inline-quote + (cons + 'phpinspect-cache-multiresult + (mapcan + (lambda (namespace) + (mapcar #'cdr (phpinspect-cache-namespace-types namespace))) + (hash-table-values (phpinspect-cache-group-namespaces ,group)))))) + (inline-quote + (when-let* ((namespace (phpinspect-cache-group-get-namespace + ,group + (or ,namespace + (phpinspect--type-namespace ,param))))) + (phpinspect-cache-namespace-get-type namespace ,param (quote ,type))))))) + + (setq form (inline-quote - (when-let ((namespace (phpinspect-cache-group-get-namespace - ,group ,namespace))) - (cons 'phpinspect-cache-multiresult - (mapcar #'cdr (phpinspect-cache-namespace-types namespace))))) - (inline-quote - (cons - 'phpinspect-cache-multiresult - (mapcan - (lambda (namespace) - (mapcar #'cdr (phpinspect-cache-namespace-types namespace))) - (hash-table-values (phpinspect-cache-group-namespaces ,group)))))) - (inline-quote - (when-let* ((namespace (phpinspect-cache-group-get-namespace - ,group - (or ,namespace - (phpinspect--type-namespace ,param))))) - (phpinspect-cache-namespace-get-type namespace ,param (quote ,type))))))) + (if ,implements + (let ((implementing (phpinspect-cache-group-get-implementing ,group ,implements)) + (result ,form) + filtered) + (when result + (if (and (consp result) + (eq 'phpinspect-cache-multiresult (car result))) + (progn + (dolist (res (cdr result)) + (when (memq (phpinspect-cache-type-name res) implementing) + (push res filtered))) + (setq filtered (cons 'phpinspect-cache-multiresult filtered))) + (when (memq (phpinspect-cache-type-name result) implementing) + (setq filtered result))))) + ,form))) + + (setq form + (inline-quote + (if ,extends + (let ((extending (phpinspect-cache-group-get-extending ,group ,extends)) + (result ,form) + filtered) + (when result + (if (and (consp result) + (eq 'phpinspect-cache-multiresult (car result))) + (progn + (dolist (res (cdr result)) + (when (memq (phpinspect-cache-type-name res) extending) + (push res filtered))) + (setq filtered (cons 'phpinspect-cache-multiresult filtered))) + (when (memq (phpinspect-cache-type-name result) extending) + (setq filtered result))))) + ,form))) + form))) + + + (define-inline phpinspect-cache-query--do-get-function (group param type member namespace implements extends) diff --git a/test/test-cache.el b/test/test-cache.el index c705c86..0956380 100644 --- a/test/test-cache.el +++ b/test/test-cache.el @@ -41,7 +41,6 @@ (should (= 1 (length result))) (should (phpinspect-cache-type-p (car result))) - (phpinspect-cache-transact cache '((label test)) :insert (phpinspect--make-type :name "\\TestInterface") :as 'interface) @@ -273,3 +272,51 @@ :delete '* :as 'function)) (should result) (should (= 3 (length result))))) + +(ert-deftest phpinspect-insert-type-extending/implementing () + (let ((cache (phpinspect-make-cache)) + result) + + (setq result + (phpinspect-cache-transact cache '((label test)) + :insert (phpinspect--make-type :name "\\Namespace1\\TestClass") + :as 'class + :extending (phpinspect--make-type :name "\\App\\TestClassAbstract") + :implementing (phpinspect--make-type :name "\\App\\TestInterface"))) + + (should result) + (should (= 1 (length result))) + + (setq result (car result)) + + (should (phpinspect-cache-type-get-implements result)) + (should (= 1 (length (phpinspect-cache-type-get-implements result)))) + (should (eq (phpinspect-intern-name "\\App\\TestInterface") + (car (phpinspect-cache-type-get-implements result)))) + + (setq result (phpinspect-cache-transact cache '((label test)) + :get '* + :implementing (phpinspect-intern-name "\\App\\TestInterface") + :as 'type)) + + (should result) + (should (= 1 (length result))) + (should (eq (phpinspect-intern-name "\\Namespace1\\TestClass") + (phpinspect-cache-type-name (car result)))) + + (setq result (phpinspect-cache-transact cache '((label test)) + :get '* + :extending (phpinspect-intern-name "\\App\\TestClassAbstract") + :as 'type)) + + (should result) + (should (= 1 (length result))) + (should (eq (phpinspect-intern-name "\\Namespace1\\TestClass") + (phpinspect-cache-type-name (car result)))) + + (setq result (phpinspect-cache-transact cache '((label test)) + :get '* + :extending (phpinspect-intern-name "\\App\\TestClass") + :as 'type)) + + (should-not result)))