Implement indexation and resolving of @param annotation types

master
Hugo Thunnissen 1 month ago
parent 5c61d4b293
commit 6f1e11c32a

@ -242,8 +242,8 @@ be implemented for return values of `phpinspect-eld-strategy-execute'")
(let ((doc-string
(concat "$" (truncate-string-to-width
(car arg) phpinspect-eldoc-word-width)
(if (cadr arg) " " "")
(phpinspect--display-format-type-name (or (cadr arg) "")))))
(if (cdr arg) " " "")
(phpinspect--display-format-type-name (or (cdr arg) "")))))
(when (and arg-pos (= arg-count arg-pos))
(setq doc-string
(propertize

@ -37,20 +37,35 @@
(cadr scope))
(t nil)))
(defun phpinspect--index-function-arg-list (type-resolver arg-list &optional add-used-types)
(defun phpinspect--index-function-arg-list (type-resolver arg-list &optional add-used-types comment-before)
(let ((arg-index)
(current-token)
param-annotation
(arg-list (cl-copy-list arg-list)))
(while (setq current-token (pop arg-list))
(cond ((and (phpinspect-word-p current-token)
(phpinspect-variable-p (car arg-list)))
(push `(,(cadr (pop arg-list))
,(funcall type-resolver (phpinspect--make-type :name (cadr current-token))))
(push (cons (cadr (pop arg-list))
(funcall type-resolver
(phpinspect--make-type :name (cadr current-token))))
arg-index)
(when add-used-types (funcall add-used-types (list (cadr current-token)))))
((and (phpinspect-variable-p (car arg-list))
comment-before
(setq param-annotation
(phpinspect--find-var-annotation-for-variable
comment-before (cadr (car arg-list)) #'phpinspect-param-annotation-p)))
(push (cons (cadr (car arg-list))
(funcall type-resolver
(phpinspect--make-type
:name (phpinspect-var-annotation-type param-annotation))))
arg-index)
(when add-used-types
(funcall add-used-types
(list (phpinspect-var-annotation-type param-annotation)))))
((phpinspect-variable-p (car arg-list))
(push `(,(cadr (pop arg-list))
nil)
(push (cons (cadr (pop arg-list)) nil)
arg-index))))
(nreverse arg-index)))
@ -60,7 +75,7 @@ of TYPE, if available."
(or (not type)
(phpinspect--type= type phpinspect--object-type)))
(defun phpinspect--index-function-declaration (declaration type-resolver add-used-types)
(defun phpinspect--index-function-declaration (declaration type-resolver add-used-types &optional comment-before)
(let (current name function-args return-type)
(catch 'break
(while (setq current (pop declaration))
@ -71,7 +86,7 @@ of TYPE, if available."
((phpinspect-list-p current)
(setq function-args
(phpinspect--index-function-arg-list
type-resolver current add-used-types))
type-resolver current add-used-types comment-before))
(when (setq return-type (seq-find #'phpinspect-word-p declaration))
(setq return-type (funcall type-resolver
@ -127,7 +142,7 @@ function (think \"new\" statements, return types etc.)."
(pcase-setq `(,name ,arguments ,type)
(phpinspect--index-function-declaration
declaration type-resolver add-used-types))
declaration type-resolver add-used-types comment-before))
;; FIXME: Anonymous functions should not be indexed! (or if they are, they
;; should at least not be visible from various UIs unless assigned to a
@ -178,10 +193,10 @@ function (think \"new\" statements, return types etc.)."
(define-inline phpinspect-var-annotation-type (annotation)
(inline-quote (cadadr ,annotation)))
(defun phpinspect--find-var-annotation-for-variable (annotation-list variable)
(defun phpinspect--find-var-annotation-for-variable (annotation-list variable &optional predicate)
(catch 'return
(dolist (annotation annotation-list)
(when (and (phpinspect-var-annotation-p annotation)
(when (and (or (phpinspect-var-annotation-p annotation) (and predicate (funcall predicate annotation)))
(phpinspect-var-annotation-variable annotation)
(string= (phpinspect-var-annotation-variable annotation)
variable))
@ -408,9 +423,8 @@ SCOPE should be a scope token (`phpinspect-scope-p')."
(phpinspect--log "Looking for variable type in constructor arguments (%s)"
variable)
(let ((constructor-parameter-type
(car (alist-get (phpinspect--variable-name variable)
(phpinspect--function-arguments constructor)
nil nil #'string=))))
(phpinspect--function-argument-type
constructor (phpinspect--variable-name variable))))
(if constructor-parameter-type
(setf (phpinspect--variable-type variable)
(funcall type-resolver constructor-parameter-type))))))))
@ -566,6 +580,13 @@ Returns a list of type name strings."
(let ((type (cadr token)))
(when (not (string-match-p "\\\\" type))
(setq used-types-rear (setcdr used-types-rear (cons type nil))))))
((phpinspect-comment-p token)
(setq used-types-rear
(nconc used-types-rear (phpinspect--find-used-types-in-tokens (cdr token)))))
((and (or (phpinspect-var-annotation-p token) (phpinspect-param-annotation-p token))
(phpinspect-var-annotation-type token))
(setq used-types-rear
(setcdr used-types-rear (cons (phpinspect-var-annotation-type token) nil))))
((and (phpinspect-static-attrib-p token)
(phpinspect-word-p previous-token))
(let ((type (cadr previous-token)))

@ -47,7 +47,7 @@
:scope (quote ,(phpinspect--function-scope func))
:arguments ,(append '(list)
(mapcar (lambda (arg)
`(list ,(car arg) ,(phpinspect--serialize-type (cadr arg))))
`(cons ,(car arg) ,(phpinspect--serialize-type (cdr arg))))
(phpinspect--function-arguments func)))
:return-type ,(when (phpinspect--function-return-type func)
(phpinspect--serialize-type

@ -148,6 +148,9 @@ Type can be any of the token types returned by
(defun phpinspect-var-annotation-p (token)
(phpinspect-token-type-p token :var-annotation))
(defun phpinspect-param-annotation-p (token)
(phpinspect-token-type-p token :param-annotation))
(defun phpinspect-return-annotation-p (token)
(phpinspect-token-type-p token :return-annotation))

@ -259,6 +259,9 @@ as first element and the type as second element.")
"A phpinspect--type object representing the the
return type of the function."))
(defun phpinspect--function-argument-type (fn argument-name)
(alist-get argument-name (phpinspect--function-arguments fn) nil nil #'string=))
(defun phpinspect--function-anonyous-p (fn)
(eq (phpinspect-intern-name "anonymous") (phpinspect--function-name-symbol fn)))

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -70,8 +70,8 @@
(:word "array")
(:variable "things")))
(:block))
:arguments `(("untyped" nil)
("things" ,(phpinspect--make-type :name "\\array"
:arguments `(("untyped" . nil)
("things" . ,(phpinspect--make-type :name "\\array"
:collection t
:fully-qualified t)))
:return-type phpinspect--null-type)))
@ -94,13 +94,15 @@ use UsedTrait;
private PropertyType $property;
public function makeThing(): Thing
/** @param ParamAnnotation $par */
public function makeThing($par): Thing
{
if ((new Monkey())->tree() === true) {
return new ExtendedThing();
}
return StaticThing::create(new ThingFactory())->makeThing((((new Potato())->antiPotato(new OtherThing(function (InnerFunctionParam $param) {
if ($param instanceof InstanceOffed) {
/** @var VarAnnotation $bing */
$bing = [ 'bong' => [ 'nested' => NestedArray::call(), ], ];
// nothing
}
@ -113,7 +115,8 @@ if ($param instanceof InstanceOffed) {
(copy-sequence
'("Cheese" "Bacon" "Ham" "Bagel" "Monkey" "ExtendedThing"
"StaticThing" "Thing" "ThingFactory" "Potato" "OtherThing"
"InnerFunctionParam" "PropertyType" "InstanceOffed" "NestedArray" "UsedTrait"))
"InnerFunctionParam" "PropertyType" "InstanceOffed"
"NestedArray" "UsedTrait" "VarAnnotation" "ParamAnnotation"))
#'string<))
(sort used-types (lambda (s1 s2) (string< (phpinspect-name-string s1) (phpinspect-name-string s2))))))))
@ -163,12 +166,11 @@ if ($param instanceof InstanceOffed) {
(should (= 2 (length (phpinspect--function-arguments method))))
(should (phpinspect--type=
(phpinspect--make-type :name "\\array" :fully-qualified t)
(car (alist-get
"loose" (phpinspect--function-arguments method) nil nil #'string=))))
(phpinspect--function-argument-type method "loose")))
(should (phpinspect--type=
(phpinspect--make-type :name "\\bool" :fully-qualified t)
(car (alist-get
"fast" (phpinspect--function-arguments method) nil nil #'string=)))))
(phpinspect--function-argument-type method "fast"))))
((string= (phpinspect--function-name method)
"hold")
(should (phpinspect--type=
@ -205,12 +207,10 @@ if ($param instanceof InstanceOffed) {
(should (= 2 (length (phpinspect--function-arguments method))))
(should (phpinspect--type=
(phpinspect--make-type :name "\\array" :fully-qualified t)
(car (alist-get
"loose" (phpinspect--function-arguments method) nil nil #'string=))))
(phpinspect--function-argument-type method "loose")))
(should (phpinspect--type=
(phpinspect--make-type :name "\\bool" :fully-qualified t)
(car (alist-get
"fast" (phpinspect--function-arguments method) nil nil #'string=)))))
(phpinspect--function-argument-type method "fast"))))
((string= (phpinspect--function-name method)
"hold")
(should (phpinspect--type=
@ -260,7 +260,8 @@ use Example\\Thing;
function test_func(): array {}
function example(): Thing {}")
/** @param \\array $bing */
function example($bing): Thing {}")
(tokens (phpinspect-parse-string code))
(index (phpinspect--index-tokens tokens))
functions)
@ -270,6 +271,12 @@ function example(): Thing {}")
(should (string= "test_func" (phpinspect--function-name (cadr functions))))
(should (string= "example" (phpinspect--function-name (car functions))))
(let ((example (car functions)))
(should (= 1 (length (phpinspect--function-arguments example))))
(should (phpinspect--type=
(phpinspect--make-type :name "\\array")
(phpinspect--function-argument-type example "bing"))))
(should (phpinspect--type= (phpinspect--make-type :name "\\array")
(phpinspect--function-return-type (cadr functions))))
(should (phpinspect--type= (phpinspect--make-type :name "\\Example\\Thing")

Loading…
Cancel
Save