Refactor use of project root to project obj injection + test and fix some bugs

- Test/Fix indexation of method return types
- Get rid of some technical debt (use of project-root and global variables)
- Cleanup/refactor tests
master
Hugo Thunnissen 1 month ago
parent e04ab0c118
commit 58ef5e3599

@ -163,13 +163,6 @@ currently opened projects."
project))
(defun phpinspect-get-or-create-cached-project-class (project-root class-fqn &optional no-enqueue)
(when project-root
(let ((project (phpinspect--cache-get-project-create
(phpinspect--get-or-create-global-cache)
project-root)))
(phpinspect-project-get-class-extra-or-create project class-fqn no-enqueue))))
(cl-defmethod phpinspect--cache-get-project-create
((cache phpinspect--cache) (project-root string))
"Get a project that is located in PROJECT-ROOT from CACHE.
@ -196,6 +189,10 @@ then returned."
(phpinspect-project-enqueue-include-dirs project))))
project))
(defun phpinspect-current-project ()
(phpinspect--cache-get-project-create (phpinspect--get-or-create-global-cache)
(phpinspect-current-project-root)))
(defun phpinspect-project-enqueue-include-dirs (project)
(interactive (list (phpinspect--cache-get-project-create
(phpinspect--get-or-create-global-cache)

@ -104,9 +104,16 @@ Conditionally executes BODY depending on
(cl-defmethod phpinspect--class-get-method ((class phpinspect--class) (method-name (head phpinspect-name)))
(gethash method-name (phpinspect--class-methods class)))
(cl-defmethod phpinspect--class-get-method ((class phpinspect--class) (method-name string))
(phpinspect--class-get-method class (phpinspect-intern-name method-name)))
(cl-defmethod phpinspect--class-get-static-method ((class phpinspect--class) (method-name (head phpinspect-name)))
(gethash method-name (phpinspect--class-static-methods class)))
(cl-defmethod phpinspect--class-get-static-method ((class phpinspect--class) (method-name string))
(phpinspect--class-get-static-method class (phpinspect-intern-name method-name)))
(cl-defmethod phpinspect--class-get-variable
((class phpinspect--class) (variable-name string))
(catch 'found

@ -224,7 +224,8 @@ Returns list of `phpinspect--completion'."
(let* ((buffer (phpinspect-completion-query-buffer query))
(point (phpinspect-completion-query-point query))
(buffer-map (phpinspect-buffer-parse-map buffer))
(rctx (phpinspect-get-resolvecontext buffer-map point))
(rctx (phpinspect-get-resolvecontext
(phpinspect-buffer-project buffer) buffer-map point))
(completion-list (phpinspect--make-completion-list)))
(phpinspect-buffer-update-project-index buffer)

@ -128,21 +128,15 @@ be implemented for return values of `phpinspect-eld-strategy-execute'")
(phpinspect-list-p
(car (last (phpinspect--resolvecontext-subject rctx)))))))
(cl-defmethod phpinspect-eld-strategy-execute
((_strat phpinspect-eld-function-args) (q phpinspect-eldoc-query) (rctx phpinspect--resolvecontext))
(phpinspect--log "Executing `phpinspect-eld-function-args' strategy")
(let* ((enclosing-token (car (phpinspect--resolvecontext-enclosing-metadata
rctx)))
(left-sibling )
(statement )
match-result static arg-list arg-pos)
(defun phpinspect--determine-function-call-statement (rctx eld-query enclosing-token)
(let (statement left-sibling)
(cond
;; Subject is a statement
((and (phpinspect-list-p (car (last (phpinspect--resolvecontext-subject rctx))))
enclosing-token)
(setq left-sibling (phpinspect-meta-find-child-before-recursively
enclosing-token (phpinspect-eldoc-query-point q))))
;; Subject is inside an argument list
enclosing-token (phpinspect-eldoc-query-point eld-query))))
;; Subject is inside an argument list
((and enclosing-token
(phpinspect-list-p (phpinspect-meta-token enclosing-token)))
(setq left-sibling (phpinspect-meta-find-left-sibling enclosing-token)
@ -160,6 +154,15 @@ be implemented for return values of `phpinspect-eld-strategy-execute'")
(phpinspect--log "Eldoc statement is: %s" (mapcar #'phpinspect-meta-token statement))
(phpinspect--log "Enclosing token was: %s" (phpinspect-meta-token enclosing-token))
statement))
(cl-defmethod phpinspect-eld-strategy-execute
((_strat phpinspect-eld-function-args) (q phpinspect-eldoc-query) (rctx phpinspect--resolvecontext))
(phpinspect--log "Executing `phpinspect-eld-function-args' strategy")
(let* ((enclosing-token (car (phpinspect--resolvecontext-enclosing-metadata
rctx)))
(statement (phpinspect--determine-function-call-statement rctx q enclosing-token))
match-result static arg-list arg-pos)
(when enclosing-token
(cond
@ -167,7 +170,6 @@ be implemented for return values of `phpinspect-eld-strategy-execute'")
((setq match-result (phpinspect--match-sequence (last statement 2)
:f (phpinspect-meta-wrap-token-pred #'phpinspect-attrib-p)
:f (phpinspect-meta-wrap-token-pred #'phpinspect-list-p)))
(phpinspect--log "Eldoc context is a method call")
(setq arg-list (car (last match-result))
static (phpinspect-static-attrib-p (phpinspect-meta-token (car match-result)))
@ -184,18 +186,14 @@ be implemented for return values of `phpinspect-eld-strategy-execute'")
(setf (phpinspect--resolvecontext-subject rctx)
(mapcar #'phpinspect-meta-token (butlast statement 2)))
(when-let* ((type-of-previous-statement
(let* ((type-of-previous-statement
(phpinspect-resolve-type-from-context rctx))
(method-name-sym (phpinspect-intern-name (cadadr (phpinspect-meta-token (car match-result)))))
(class (phpinspect-project-get-class-extra-or-create
(phpinspect--resolvecontext-project rctx)
type-of-previous-statement
'no-enqueue))
(method (if static
(phpinspect--class-get-static-method class method-name-sym)
(phpinspect--class-get-method class method-name-sym))))
(method-name (cadadr (phpinspect-meta-token (car match-result))))
(class (phpinspect-rctx-get-or-create-cached-project-class
rctx type-of-previous-statement 'no-enqueue))
(method (if static
(phpinspect--class-get-static-method class method-name)
(phpinspect--class-get-method class method-name))))
(when method
(phpinspect-make-function-doc :fn method :arg-pos arg-pos))))
@ -268,7 +266,7 @@ also `phpinspect-eldoc-query-execute'.")
(let* ((buffer (phpinspect-eldoc-query-buffer query))
(point (phpinspect-eldoc-query-point query))
(buffer-map (phpinspect-buffer-parse-map buffer))
(rctx (phpinspect-get-resolvecontext buffer-map point))
(rctx (phpinspect-get-resolvecontext (phpinspect-buffer-project buffer) buffer-map point))
responses)
(phpinspect-buffer-update-project-index buffer)
(dolist (strategy phpinspect-eldoc-strategies)
@ -276,6 +274,7 @@ also `phpinspect-eldoc-query-execute'.")
(when (phpinspect-eld-strategy-supports strategy query rctx)
(phpinspect--log "Found matching eldoc strategy. Executing...")
(push (phpinspect-eld-strategy-execute strategy query rctx) responses))))
(remove nil responses)))
(defun phpinspect-eldoc-function ()

@ -138,10 +138,11 @@ function (think \"new\" statements, return types etc.)."
;; @return annotation. When dealing with a collection, we want to store the
;; type of its members.
(when type
(let* ((return-annotation-type
(cadadr (seq-find #'phpinspect-return-annotation-p comment-before))))
(phpinspect--apply-annotation-type return-annotation-type type type-resolver)))
(when-let* ((return-annotation-type
(cadadr (seq-find #'phpinspect-return-annotation-p comment-before))))
(if type
(phpinspect--apply-annotation-type return-annotation-type type type-resolver)
(setq type (funcall type-resolver (phpinspect--make-type :name return-annotation-type)))))
(when add-used-types
(let ((used-types (phpinspect--find-used-types-in-tokens

@ -141,65 +141,51 @@ Destructively removes tokens from the end of ASSIGNMENT-TOKENS."
(pop statement))
statement)
;; FIXME: the use of this function and similar ones should be replaced with code
;; that uses locally injected project objects in stead of retrieving the project
;; object through global variables.
(defsubst phpinspect-get-cached-project-class (project-root class-fqn)
(when project-root
(phpinspect-project-get-class-or-extra
(phpinspect--cache-get-project-create (phpinspect--get-or-create-global-cache)
project-root)
class-fqn)))
(defun phpinspect-get-cached-project-class-methods (project-root class-fqn &optional static)
(phpinspect--log "Getting cached project class methods for %s (%s)"
project-root class-fqn)
(when project-root
(let ((class (phpinspect-get-or-create-cached-project-class
project-root
class-fqn)))
(when class
(phpinspect--log "Retrieved class index, starting method collection %s (%s)"
project-root class-fqn)
(if static
(phpinspect--class-get-static-method-list class)
(phpinspect--class-get-method-list class))))))
(defsubst phpinspect-get-cached-project-class-method-type
(project-root class-fqn method-name)
(when project-root
(let* ((class (phpinspect-get-or-create-cached-project-class project-root class-fqn))
(method))
(defsubst phpinspect-get-cached-project-class (rctx class-fqn)
(phpinspect-project-get-class-or-extra (phpinspect--resolvecontext-project rctx) class-fqn))
(defun phpinspect-get-cached-project-class-methods (rctx class-fqn &optional static)
(phpinspect--log "Getting cached project class methods for %s"
class-fqn)
(let ((class (phpinspect-rctx-get-or-create-cached-project-class rctx class-fqn)))
(when class
(setq method
(phpinspect--class-get-method class (phpinspect-intern-name method-name)))
(when method
(phpinspect--function-return-type method))))))
(phpinspect--log "Retrieved class index, starting method collection for %s"
class-fqn)
(if static
(phpinspect--class-get-static-method-list class)
(phpinspect--class-get-method-list class)))))
(defsubst phpinspect-get-cached-project-class-method-type (rctx class-fqn method-name)
(let* ((class (phpinspect-rctx-get-or-create-cached-project-class rctx class-fqn))
(method))
(when class
(setq method
(phpinspect--class-get-method class (phpinspect-intern-name method-name)))
(when method
(phpinspect--function-return-type method)))))
(defsubst phpinspect-get-cached-project-class-variable-type
(project-root class-fqn variable-name)
(phpinspect--log "Getting cached project class variable type for %s (%s::%s)"
project-root class-fqn variable-name)
(when project-root
(let ((found-variable
(phpinspect--class-get-variable
(phpinspect-get-or-create-cached-project-class project-root class-fqn)
variable-name)))
(when found-variable
(phpinspect--variable-type found-variable)))))
(rctx class-fqn variable-name)
(phpinspect--log "Getting cached project class variable type %s::%s"
class-fqn variable-name)
(let ((found-variable
(phpinspect--class-get-variable
(phpinspect-rctx-get-or-create-cached-project-class rctx class-fqn)
variable-name)))
(when found-variable
(phpinspect--variable-type found-variable))))
(defsubst phpinspect-get-cached-project-class-static-method-type
(project-root class-fqn method-name)
(when project-root
(let* ((class (phpinspect-get-or-create-cached-project-class project-root class-fqn))
(method))
(when class
(setq method
(phpinspect--class-get-static-method
class
(phpinspect-intern-name method-name)))
(when method
(phpinspect--function-return-type method))))))
(rctx class-fqn method-name)
(let* ((class (phpinspect-rctx-get-or-create-cached-project-class rctx class-fqn))
(method))
(when class
(setq method
(phpinspect--class-get-static-method
class
(phpinspect-intern-name method-name)))
(when method
(phpinspect--function-return-type method)))))
(defun phpinspect-get-derived-statement-type-in-block
(resolvecontext statement php-block type-resolver &optional function-arg-list assignments)
@ -265,16 +251,14 @@ $variable = $variable->method();"
(setq previous-attribute-type
(or
(phpinspect-get-cached-project-class-method-type
(phpinspect--resolvecontext-project-root
resolvecontext)
(funcall type-resolver previous-attribute-type)
(cadr attribute-word))
resolvecontext
(funcall type-resolver previous-attribute-type)
(cadr attribute-word))
previous-attribute-type)))
(setq previous-attribute-type
(or
(phpinspect-get-cached-project-class-variable-type
(phpinspect--resolvecontext-project-root
resolvecontext)
resolvecontext
(funcall type-resolver previous-attribute-type)
(cadr attribute-word))
previous-attribute-type))))))
@ -290,8 +274,7 @@ $variable = $variable->method();"
(setq previous-attribute-type
(or
(phpinspect-get-cached-project-class-static-method-type
(phpinspect--resolvecontext-project-root
resolvecontext)
resolvecontext
(funcall type-resolver previous-attribute-type)
(cadr attribute-word))
previous-attribute-type)))))))

@ -55,10 +55,10 @@
:type phpinspect--token
:documentation
"The statement we're trying to resolve the type of.")
(project-root nil
:type string
:documentation
"The root directory of the project we're resolving types for.")
(project nil
:type phpinspect-project
:documentation
"The project we're resolving types for.")
(enclosing-metadata nil
:type list
:documentation
@ -127,7 +127,7 @@ it would no longer be valid for the new enclosing tokens."
(reverse token))))
(cl-defmethod phpinspect-get-resolvecontext
((bmap phpinspect-bmap) (point integer))
((project phpinspect-project) (bmap phpinspect-bmap) (point integer))
"Construct resolvecontext for BMAP, orienting around POINT."
(let* ((enclosing-tokens)
;; When there are no enclosing tokens, point is probably at the absolute
@ -184,14 +184,9 @@ it would no longer be valid for the new enclosing tokens."
:subject (phpinspect--get-last-statement-in-token subject-token)
:enclosing-tokens (nreverse (mapcar #'phpinspect-meta-token enclosing-tokens))
:enclosing-metadata (nreverse enclosing-tokens)
:project-root (phpinspect-current-project-root))))
(defun phpinspect--resolvecontext-project (rctx)
(phpinspect--cache-get-project-create
(phpinspect--get-or-create-global-cache)
(phpinspect--resolvecontext-project-root rctx)))
:project project)))
(defun phpinspect--get-resolvecontext (token &optional resolvecontext)
(defun phpinspect--get-resolvecontext (project token &optional resolvecontext)
"Find the deepest nested incomplete token in TOKEN.
If RESOLVECONTEXT is nil, it is created. Returns RESOLVECONTEXT
of type `phpinspect--resolvecontext' containing the last
@ -199,7 +194,7 @@ statement of the innermost incomplete token as subject
accompanied by all of its enclosing tokens."
(unless resolvecontext
(setq resolvecontext (phpinspect--make-resolvecontext
:project-root (phpinspect-current-project-root))))
:project project)))
(let ((last-token (car (last token)))
(last-encountered-token (car
@ -213,13 +208,18 @@ accompanied by all of its enclosing tokens."
(phpinspect--resolvecontext-push-enclosing-token resolvecontext token))
(if (phpinspect-incomplete-token-p last-token)
(phpinspect--get-resolvecontext last-token resolvecontext)
(phpinspect--get-resolvecontext project last-token resolvecontext)
;; else
(setf (phpinspect--resolvecontext-subject resolvecontext)
(phpinspect--get-last-statement-in-token token))
resolvecontext)))
(defun phpinspect-rctx-get-or-create-cached-project-class (rctx class-fqn &optional no-enqueue)
(cl-assert (phpinspect--resolvecontext-p rctx))
(let ((project (phpinspect--resolvecontext-project rctx)))
(phpinspect-project-get-class-extra-or-create project class-fqn no-enqueue)))
(defun phpinspect--make-type-resolver-for-resolvecontext
(resolvecontext)
(let ((namespace-or-root

@ -75,34 +75,27 @@
variable-list)))
(defun phpinspect-get-cached-project-class-methods (project-root class-fqn &optional static)
(phpinspect--log "Getting cached project class methods for %s (%s)"
project-root class-fqn)
(when project-root
(let ((class (phpinspect-get-or-create-cached-project-class
project-root
class-fqn 'no-enqueue)))
(phpinspect--log (if class
"Retrieved class index, starting method collection %s (%s)"
"No class index found in %s for %s")
project-root class-fqn)
(when class
(if static
(phpinspect--class-get-static-method-list class)
(phpinspect--class-get-method-list class))))))
(defun phpinspect-get-cached-project-class-methods (rctx class-fqn &optional static)
(phpinspect--log "Getting cached project class methods for %s" class-fqn)
(let ((class (phpinspect-rctx-get-or-create-cached-project-class rctx class-fqn 'no-enqueue)))
(phpinspect--log (if class
"Retrieved class index, starting method collection %s"
"No class index found for %s")
class-fqn)
(when class
(if static
(phpinspect--class-get-static-method-list class)
(phpinspect--class-get-method-list class)))))
(defun phpinspect--get-methods-for-class
(resolvecontext class &optional static)
"Find all known cached methods for CLASS."
(or (phpinspect-get-cached-project-class-methods
(phpinspect--resolvecontext-project-root resolvecontext)
class static)
(or (phpinspect-get-cached-project-class-methods resolvecontext class static)
(progn (phpinspect--log "Failed to find methods for class %s :(" class) nil)))
(defun phpinspect--get-variables-for-class (class-name &optional static)
(let ((class (phpinspect-get-or-create-cached-project-class
(phpinspect-current-project-root)
class-name 'no-enqueue)))
(defun phpinspect--get-variables-for-class (rctx class-name &optional static)
(let ((class (phpinspect-rctx-get-or-create-cached-project-class
rctx class-name 'no-enqueue)))
(when class
(if static
(append (phpinspect--class-get-static-variables class) (phpinspect--class-get-constants class))
@ -149,8 +142,7 @@ static variables and static methods."
(let ((type (funcall type-resolver statement-type)))
(when-let ((result
(append (phpinspect--get-variables-for-class
type
static)
resolvecontext type static)
(funcall method-lister type))))
(phpinspect--log "Returning attributes %s" result)
result))))))

@ -57,13 +57,6 @@
(inline-quote
(funcall phpinspect-type-filepath-function ,fqn)))
(defsubst phpinspect-cache-project-class (project-root indexed-class)
(when project-root
(phpinspect-project-add-class
(phpinspect--cache-get-project-create (phpinspect--get-or-create-global-cache)
project-root)
indexed-class)))
(defun phpinspect-parse-string-to-bmap (string)
(with-temp-buffer
(insert string)

@ -10,6 +10,12 @@
(phpinspect-ensure-worker)
(phpinspect-purge-cache)
(defun phpinspect--make-dummy-project ()
(phpinspect--make-project
:fs (phpinspect-make-virtual-fs)
:autoload (phpinspect-make-autoloader)
:worker 'nil-worker))
(defvar phpinspect-test-directory
(file-name-directory (macroexp-file-name))
"Directory that phpinspect tests reside in.")

@ -34,8 +34,8 @@
(let* ((code "class Foo { function a(\\Thing $baz) { $foo = new \\DateTime(); $bar = $foo; Whatever comes after don't matter.")
(bmap (phpinspect-parse-string-to-bmap code))
(tokens (phpinspect-parse-string "class Foo { function a(\\Thing $baz) { $foo = new \\DateTime(); $bar = $foo;"))
(context (phpinspect--get-resolvecontext tokens))
(bmap-context (phpinspect-get-resolvecontext bmap (- (length code) 36)))
(context (phpinspect--get-resolvecontext (phpinspect-current-project) tokens))
(bmap-context (phpinspect-get-resolvecontext (phpinspect--make-dummy-project) bmap (- (length code) 36)))
(project-root "could never be a real project root")
(phpinspect-project-root-function
(lambda (&rest _ignored) project-root))
@ -65,7 +65,7 @@
(ert-deftest phpinspect-get-pattern-type-in-block ()
(let* ((code "class Foo { function a(\\Thing $baz) { $foo = new \\DateTime(); $this->potato = $foo;")
(bmap (phpinspect-parse-string-to-bmap "class Foo { function a(\\Thing $baz) { $foo = new \\DateTime(); $this->potato = $foo;"))
(context (phpinspect-get-resolvecontext bmap (length code)))
(context (phpinspect-get-resolvecontext (phpinspect--make-dummy-project) bmap (length code)))
(project-root "could never be a real project root")
(phpinspect-project-root-function
(lambda (&rest _ignored) project-root))
@ -90,8 +90,8 @@
(code2 "class Foo { function a(\\Thing $baz) { $foo = []; $foo[] = $baz; $bar = $foo[0]; $bork = [$foo[0]]; $bark = $bork[0]; $borknest = [$bork]; $barknest = $borknest[0][0]")
(bmap (phpinspect-parse-string-to-bmap code1))
(tokens (phpinspect-parse-string code2))
(context1 (phpinspect-get-resolvecontext bmap (- (length code1) 4)))
(context2 (phpinspect--get-resolvecontext tokens)))
(context1 (phpinspect-get-resolvecontext (phpinspect--make-dummy-project) bmap (- (length code1) 4)))
(context2 (phpinspect--get-resolvecontext (phpinspect-current-project) tokens)))
(should (equal (phpinspect--resolvecontext-subject context1)
(phpinspect--resolvecontext-subject context2)))
@ -101,7 +101,7 @@
(ert-deftest phpinspect-get-variable-type-in-block-array-foreach ()
(let* ((code "class Foo { function a(\\Thing $baz) { $foo = []; $foo[] = $baz; foreach ($foo as $bar) {$bar->")
(bmap (phpinspect-parse-string-to-bmap code))
(context (phpinspect-get-resolvecontext bmap (length code)))
(context (phpinspect-get-resolvecontext (phpinspect--make-dummy-project) bmap (length code)))
(project-root "could never be a real project root")
(phpinspect-project-root-function
(lambda (&rest _ignored) project-root))
@ -123,32 +123,6 @@
(should (phpinspect--type= (phpinspect--make-type :name "\\Thing")
result)))))
(ert-deftest phpinspect-get-variable-type-in-block-nested-array ()
(let* ((code "class Foo { function a(\\Thing $baz) { $foo = [[$baz]]; foreach ($foo[0] as $bar) {$bar->")
(bmap (phpinspect-parse-string-to-bmap code))
(context (phpinspect-get-resolvecontext bmap (length code)))
(project-root "could never be a real project root")
(phpinspect-project-root-function
(lambda (&rest _ignored) project-root))
(project (phpinspect--make-project
:fs (phpinspect-make-virtual-fs)
:root project-root
:worker (phpinspect-make-worker))))
(puthash project-root project (phpinspect--cache-projects phpinspect-cache))
(let* ((function-token (seq-find #'phpinspect-function-p
(phpinspect--resolvecontext-enclosing-tokens context)))
(result (phpinspect-get-variable-type-in-block
context "bar"
(phpinspect-function-block function-token)
(phpinspect--make-type-resolver-for-resolvecontext context)
(phpinspect-function-argument-list function-token))))
(should (phpinspect--type= (phpinspect--make-type :name "\\Thing")
result)))))
(ert-deftest phpinspect--find-assignment-ctxs-in-token ()
(let* ((tokens (cadr
(phpinspect-parse-string "{ $foo = ['nr 1']; $bar = $nr2; if (true === ($foo = $nr3)) { $foo = $nr4; $notfoo = $nr5; if ([] === ($foo = [ $nr6 ])){ $foo = [ $nr7 ];}}}")))
@ -241,17 +215,12 @@ class FlufferUpper
$this->upFluff = $upFluff;
}
}"))
(phpinspect-project-root-function (lambda () "phpinspect-test"))
(context (phpinspect-get-resolvecontext bmap 310)))
(setf (phpinspect--resolvecontext-project-root context)
"phpinspect-test")
(project (phpinspect--make-dummy-project))
(context (phpinspect-get-resolvecontext project bmap 310)))
(phpinspect-purge-cache)
(dolist (tree (list token-tree fluffer vendor-fluff vendor-fluffer-upper))
(phpinspect-cache-project-class
"phpinspect-test"
(cdar (alist-get 'classes (cdr (phpinspect--index-tokens tree))))))
(phpinspect-project-add-index project (phpinspect--index-tokens tree)))
(should (phpinspect--type=
(phpinspect--make-type :name "\\Vendor\\FluffLib\\DoubleFluffer")
@ -260,7 +229,7 @@ class FlufferUpper
(phpinspect--make-type-resolver-for-resolvecontext
context))))
(setq context (phpinspect-get-resolvecontext bmap 405))
(setq context (phpinspect-get-resolvecontext project bmap 405))
(should (phpinspect--type=
(phpinspect--make-type :name "\\Vendor\\FluffLib\\FlufferUpper")
(phpinspect-resolve-type-from-context
@ -268,7 +237,6 @@ class FlufferUpper
(phpinspect--make-type-resolver-for-resolvecontext
context))))))
(ert-deftest phpinspect-resolve-type-from-context-static-method ()
(with-temp-buffer
(insert "
@ -289,11 +257,11 @@ class Thing
(index (phpinspect--index-tokens tokens))
(phpinspect-project-root-function (lambda () "phpinspect-test"))
(phpinspect-eldoc-word-width 100)
(context (phpinspect-get-resolvecontext bmap (point))))
(project (phpinspect--make-dummy-project))
(context (phpinspect-get-resolvecontext project bmap (point))))
(phpinspect-purge-cache)
(phpinspect-cache-project-class
(phpinspect-current-project-root)
(cdar (alist-get 'classes (cdr index))))
(phpinspect-project-add-index project index)
(should (phpinspect--type= (phpinspect--make-type :name "\\Thing")
(phpinspect-resolve-type-from-context
@ -320,13 +288,11 @@ class Thing
:bmap bmap)
(phpinspect-parse-current-buffer)))
(index (phpinspect--index-tokens tokens))
(phpinspect-project-root-function (lambda () "phpinspect-test"))
(phpinspect-eldoc-word-width 100)
(context (phpinspect-get-resolvecontext bmap (point))))
(project (phpinspect--make-dummy-project))
(context (phpinspect-get-resolvecontext project bmap (point))))
(phpinspect-purge-cache)
(phpinspect-cache-project-class
(phpinspect-current-project-root)
(cdar (alist-get 'classes (cdr index))))
(phpinspect-project-add-index project index)
(should (phpinspect--type= (phpinspect--make-type :name "\\Thing")
(phpinspect-resolve-type-from-context

@ -28,6 +28,10 @@
(require 'phpinspect-fs)
(require 'phpinspect-autoload)
(require 'phpinspect-resolvecontext)
(require 'phpinspect-test-env
(expand-file-name "phpinspect-test-env.el"
(file-name-directory (macroexp-file-name))))
(ert-deftest phpinspect-filename-to-typename ()
(should (eq (phpinspect-intern-name "\\Foo\\Bar") (phpinspect-filename-to-typename "src/" "src/Foo////////Bar.php")))

@ -2,13 +2,16 @@
(require 'phpinspect)
(require 'phpinspect-eldoc)
(require 'phpinspect-test-env
(expand-file-name "phpinspect-test-env.el"
(file-name-directory (macroexp-file-name))))
(ert-deftest phpinspect-eld-method-call ()
(setq phpinspect-load-stubs nil)
(with-temp-buffer
(phpinspect-ensure-worker)
(phpinspect-purge-cache)
(let* ((php-code "
(let* ((php-code "<?php
class Thing
{
@ -20,17 +23,14 @@ class Thing
function doStuff()
{
$this->getThis(new \\DateTime(), bla)")
(tokens (phpinspect-parse-string php-code))
(index (phpinspect--index-tokens tokens))
(phpinspect-project-root-function (lambda () "phpinspect-test"))
(phpinspect-eldoc-word-width 100)
(buffer (phpinspect-make-buffer :buffer (current-buffer)))
(project (phpinspect--make-project :autoload (phpinspect-make-autoloader) :worker 'nil-worker))
(buffer (phpinspect-make-buffer :buffer (current-buffer) :-project project))
second-arg-pos inside-nested-list-pos first-arg-pos)
(phpinspect-cache-project-class
(phpinspect-current-project-root)
(cdar (alist-get 'classes (cdr index))))
(setq-local phpinspect-current-buffer buffer)
(insert php-code)
(backward-char)
(setq second-arg-pos (point))
(backward-char 6)
@ -38,22 +38,47 @@ class Thing
(backward-char 8)
(setq first-arg-pos (point))
(let ((result (seq-find #'phpinspect-function-doc-p
(phpinspect-eldoc-query-execute
(phpinspect-make-eldoc-query :point second-arg-pos :buffer buffer)))))
(should (phpinspect-function-doc-p result))
(should (= 1 (phpinspect-function-doc-arg-pos result)))
(should (string= "getThis" (phpinspect--function-name (phpinspect-function-doc-fn result))))
(phpinspect-buffer-reindex buffer)
;; Strategy should not trigger inside constructor/function arguments
(let ((query (phpinspect-make-eldoc-query :point inside-nested-list-pos :buffer buffer))
(strat (phpinspect-make-eld-function-args))
(rctx (phpinspect-get-resolvecontext project (phpinspect-buffer-parse-map buffer) inside-nested-list-pos)))
(should-not (phpinspect-eld-strategy-execute strat query rctx)))
(dolist (expected (list (cons second-arg-pos 1) (cons first-arg-pos 0)))
;; Test strat separately to ensure it is not erroneous
(let ((query (phpinspect-make-eldoc-query :point (car expected) :buffer buffer))
(strat (phpinspect-make-eld-function-args))
(rctx (phpinspect-get-resolvecontext project (phpinspect-buffer-parse-map buffer) (car expected))))
;; Subject is correct
(should (phpinspect-word-p (car (phpinspect--resolvecontext-subject rctx))))
(setq result (phpinspect-eldoc-query-execute
(phpinspect-make-eldoc-query :point inside-nested-list-pos :buffer buffer)))
(should-not result)
;; Enclosing token is correct
(should (phpinspect-list-p (car (phpinspect--resolvecontext-enclosing-tokens rctx))))
;; Statement is correctly determined
(should (equal (cdr (phpinspect-parse-string "$this->getThis(new \\DateTime(), bla)"))
(mapcar #'phpinspect-meta-token
(phpinspect--determine-function-call-statement
rctx query (car (phpinspect--resolvecontext-enclosing-metadata
rctx))))))
;; Strategy correctly signals support
(should (phpinspect-eld-strategy-supports strat query rctx))
;; Strategy correctly returns result
(should (phpinspect-eld-strategy-execute strat query rctx)))
;; Test query execution
(let ((result (seq-find #'phpinspect-function-doc-p
(phpinspect-eldoc-query-execute
(phpinspect-make-eldoc-query :point (car expected) :buffer buffer)))))
(should (phpinspect-function-doc-p result))
(should (= (cdr expected) (phpinspect-function-doc-arg-pos result)))
(should (string= "getThis" (phpinspect--function-name (phpinspect-function-doc-fn result)))))))))
(setq result (car (phpinspect-eldoc-query-execute
(phpinspect-make-eldoc-query :point first-arg-pos :buffer buffer))))
(should (phpinspect-function-doc-p result))
(should (= 0 (phpinspect-function-doc-arg-pos result)))
(should (string= "getThis" (phpinspect--function-name (phpinspect-function-doc-fn result))))))))
(ert-deftest phpinspect-eldoc-function-for-object-method ()
(phpinspect-purge-cache)
@ -70,18 +95,16 @@ class Thing
$this->getThis(new \\DateTime(), bla)")
(tokens (phpinspect-parse-string php-code))
(index (phpinspect--index-tokens tokens))
(phpinspect-project-root-function (lambda () "phpinspect-test"))
(project (phpinspect--make-dummy-project))
(phpinspect-eldoc-word-width 100))
(phpinspect-cache-project-class
(phpinspect-current-project-root)
(cdar (alist-get 'classes (cdr index))))
(phpinspect-project-add-index project index)
(should (string= "getThis: ($moment DateTime, $thing Thing, $other): Thing"
(with-temp-buffer
(insert php-code)
(backward-char)
(setq-local phpinspect-current-buffer
(phpinspect-make-buffer :buffer (current-buffer)))
(phpinspect-make-buffer :buffer (current-buffer) :-project project))
(phpinspect-buffer-parse phpinspect-current-buffer)
(phpinspect-eldoc-function))))))
@ -100,11 +123,9 @@ class Thing
self::doThing(")
(tokens (phpinspect-parse-string php-code))
(index (phpinspect--index-tokens tokens))
(phpinspect-project-root-function (lambda () "phpinspect-test"))
(project (phpinspect--make-dummy-project))
(phpinspect-eldoc-word-width 100))
(phpinspect-cache-project-class
(phpinspect-current-project-root)
(cdar (alist-get 'classes (cdr index))))
(phpinspect-project-add-index project index)
(should (string= "doThing: ($moment DateTime, $thing Thing, $other): Thing"
(with-temp-buffer

@ -356,3 +356,31 @@ class AccountStatisticsController {
(should (phpinspect--type= relation-type (phpinspect--variable-type relation)))
(should (phpinspect--variable-type static-relation))
(should (phpinspect--type= relation-type (phpinspect--variable-type static-relation)))))))))
(ert-deftest phpinspect-index-return-type-annotation-for-method ()
(with-temp-buffer
(let ((project (phpinspect--make-project :autoload (phpinspect-make-autoloader))))
(insert "<?php
declare(strict_types=1);
namespace App\\Controller\\Api\\V1;
class AccountStatisticsController {
/**
* @return $this
*/
public function doStuff()
{
}
}")
(phpinspect-project-add-index project (phpinspect-index-current-buffer))
(let ((class (phpinspect-project-get-class
project
(phpinspect--make-type
:name "\\App\\Controller\\Api\\V1\\AccountStatisticsController"
:fully-qualified t))))
(should class)
(should (phpinspect--class-get-method class "doStuff"))))))

@ -6,20 +6,28 @@
(expand-file-name "phpinspect-test-env.el"
(file-name-directory (macroexp-file-name))))
(ert-deftest phpinspect-get-variable-type-in-block-nested-array ()
(let* ((code "class Foo { function a(\\Thing $baz) { $foo = [[$baz]]; foreach ($foo[0] as $bar) {$bar->")
(bmap (phpinspect-parse-string-to-bmap code))
(project (phpinspect--make-dummy-project))
(context (phpinspect-get-resolvecontext project bmap (length code))))
(let* ((function-token (seq-find #'phpinspect-function-p
(phpinspect--resolvecontext-enclosing-tokens context)))
(result (phpinspect-get-variable-type-in-block
context "bar"
(phpinspect-function-block function-token)
(phpinspect--make-type-resolver-for-resolvecontext context)
(phpinspect-function-argument-list function-token))))
(should (phpinspect--type= (phpinspect--make-type :name "\\Thing")
result)))))
(ert-deftest phpinspect-get-variable-type-in-block-array-access ()
(let* ((code "class Foo { function a(\\Thing $baz) { $foo = []; $foo[] = $baz; $bar = $foo[0]; $bork = [$foo[0]]; $bark = $bork[0]; $borknest = [$bork]; $barknest = $borknest[0][0]; }}")
(tokens (phpinspect-parse-string-to-bmap code))
(context (phpinspect-get-resolvecontext tokens (- (length code) 4)))
(project-root "could never be a real project root")
(phpinspect-project-root-function
(lambda (&rest _ignored) project-root))
(project (phpinspect--make-project
:fs (phpinspect-make-virtual-fs)
:root project-root
:worker (phpinspect-make-worker))))
(puthash project-root project (phpinspect--cache-projects phpinspect-cache))
(bmap (phpinspect-parse-string-to-bmap code))
(project (phpinspect--make-dummy-project))
(context (phpinspect-get-resolvecontext project bmap (length code))))
(let* ((function-token (car (phpinspect--resolvecontext-enclosing-tokens context)))
(result1 (phpinspect-get-variable-type-in-block
@ -41,16 +49,8 @@
(ert-deftest phpinspect-get-variable-type-in-block-array-foreach-self-referential ()
(let* ((code "class Foo { function a(\\Thing $baz) { $foo = []; $foo[] = $baz; foreach ($foo as $bar) {$bar = $bar; $bar->")
(bmap (phpinspect-parse-string-to-bmap code))
(context (phpinspect-get-resolvecontext bmap (length code)))
(project-root "could never be a real project root")
(phpinspect-project-root-function
(lambda (&rest _ignored) project-root))
(project (phpinspect--make-project
:fs (phpinspect-make-virtual-fs)
:root project-root
:worker (phpinspect-make-worker))))
(puthash project-root project (phpinspect--cache-projects phpinspect-cache))
(project (phpinspect--make-dummy-project))
(context (phpinspect-get-resolvecontext project bmap (length code))))
(let* ((function-token (seq-find #'phpinspect-function-p
(phpinspect--resolvecontext-enclosing-tokens context)))

@ -28,7 +28,7 @@ class TestClass {
(phpinspect-parse-string code))
(setq bmap (phpinspect-pctx-bmap ctx))
(let ((rctx (phpinspect-get-resolvecontext bmap 317)))
(let ((rctx (phpinspect-get-resolvecontext (phpinspect--make-dummy-project) bmap 317)))
(should (phpinspect--resolvecontext-subject rctx))
(should (phpinspect--resolvecontext-enclosing-tokens rctx)))))
@ -37,7 +37,7 @@ class TestClass {
(with-temp-buffer
(insert-file-contents (expand-file-name "IncompleteClass.php" phpinspect-test-php-file-directory))
(let* ((bmap (phpinspect-parse-string-to-bmap (buffer-string)))
(resolvecontext (phpinspect-get-resolvecontext bmap (point-max)))
(resolvecontext (phpinspect-get-resolvecontext (phpinspect--make-dummy-project) bmap (point-max)))
(type-resolver (phpinspect--make-type-resolver-for-resolvecontext
resolvecontext)))
@ -65,7 +65,7 @@ class TestClass {
(with-temp-buffer
(insert-file-contents (concat phpinspect-test-php-file-directory "/IncompleteClassBlockedNamespace.php"))
(let* ((bmap (phpinspect-parse-string-to-bmap (buffer-string)))
(resolvecontext (phpinspect-get-resolvecontext bmap (point-max)))
(resolvecontext (phpinspect-get-resolvecontext (phpinspect--make-dummy-project) bmap (point-max)))
(type-resolver (phpinspect--make-type-resolver-for-resolvecontext
resolvecontext)))
@ -87,6 +87,7 @@ class TestClass {
(ert-deftest phpinspect-type-resolver-for-resolvecontext-multiple-namespace-blocks ()
(let* ((resolvecontext (phpinspect--get-resolvecontext
(phpinspect-current-project)
(phpinspect-test-read-fixture-data
"IncompleteClassMultipleNamespaces")))
(type-resolver (phpinspect--make-type-resolver-for-resolvecontext

Loading…
Cancel
Save