Support @method annotations for static methods

master
Hugo Thunnissen 2 months ago
parent 4d9907fedc
commit 2aac7a273e

@ -190,33 +190,43 @@ function (think \"new\" statements, return types etc.)."
(defun phpinspect-doc-block-p (token)
(phpinspect-token-type-p token :doc-block))
(defsubst phpinspect--index-method-annotations (type-resolver comment)
(let ((annotations (seq-filter #'phpinspect-method-annotation-p comment))
(static-methods)
(methods))
(dolist (annotation annotations)
(let ((return-type) (name) (arg-list))
(when (> (length annotation) 2)
(cond ((and (phpinspect-word-p (nth 1 annotation))
(phpinspect-word-p (nth 2 annotation))
(phpinspect-list-p (nth 3 annotation)))
(setq return-type (cadr (nth 1 annotation)))
(setq name (cadr (nth 2 annotation)))
(setq arg-list (nth 3 annotation)))
((and (phpinspect-word-p (nth 1 annotation))
(phpinspect-list-p (nth 2 annotation)))
(setq return-type "void")
(setq name (cadr (nth 1 annotation)))
(setq arg-list (nth 2 annotation))))
(when name
(let ((return-type) (name) (arg-list) (static))
;; Annotation is static
(when (phpinspect--match-sequence (take 2 annotation)
:m :method-annotation :m '(:word "static"))
(setcdr annotation (cddr annotation))
(setq static t))
(cond
((phpinspect--match-sequence annotation
:m :method-annotation
:f #'phpinspect-word-p
:f #'phpinspect-word-p
:f #'phpinspect-list-p)
(setq return-type (cadr (nth 1 annotation)))
(setq name (cadr (nth 2 annotation)))
(setq arg-list (nth 3 annotation)))
((phpinspect--match-sequence annotation
:m :method-annotation
:f #'phpinspect-word-p
:f #'phpinspect-list-p)
(setq return-type "void")
(setq name (cadr (nth 1 annotation)))
(setq arg-list (nth 2 annotation))))
(when name
(push (phpinspect--make-function
:scope '(:public)
:name name
:return-type (funcall type-resolver (phpinspect--make-type :name return-type))
:arguments (phpinspect--index-function-arg-list type-resolver arg-list))
methods)))))
methods))
(if static static-methods methods)))))
(list static-methods methods)))
(defun phpinspect--index-class (imports type-resolver location-resolver class &optional doc-block)
"Create an alist with relevant attributes of a parsed class."
@ -317,7 +327,11 @@ function (think \"new\" statements, return types etc.)."
;; Dirty hack that assumes the constructor argument names to be the same as the object
;; attributes' names.
;;;
;; TODO: actually check the types of the variables assigned to object attributes
;; TODO: actually check the types of the variables assigned to object properties
;;
;; Note: The indexing code in phpinspect-buffer does check the variable
;; types which are actually assigned to object properties for classes opened
;; in buffers.
(let* ((constructor-sym (phpinspect-intern-name "__construct"))
(constructor (seq-find (lambda (method)
(eq (phpinspect--function-name-symbol method)
@ -339,8 +353,11 @@ function (think \"new\" statements, return types etc.)."
;; Add method annotations to methods
(when doc-block
(setq methods
(nconc methods (phpinspect--index-method-annotations type-resolver doc-block))))
(let ((result-tuple (phpinspect--index-method-annotations type-resolver doc-block)))
(setq static-methods
(nconc static-methods (car result-tuple)))
(setq methods
(nconc methods (cadr result-tuple)))))
`(,class-name .
(phpinspect--indexed-class

@ -483,7 +483,7 @@ nature like argument lists"
(phpinspect--parse-annotation-parameters 2)))
((string= annotation-name "method")
(cons :method-annotation
(phpinspect--parse-annotation-parameters 3)))
(phpinspect--parse-annotation-parameters 4)))
(t
(list :annotation annotation-name))))
(list :annotation nil)))

@ -107,7 +107,7 @@
(defun phpinspect--serialize-import (import)
`(cons
(phpinspect-intern-name ,(symbol-name (car import)))
(phpinspect-intern-name ,(phpinspect-name-string (car import)))
,(phpinspect--serialize-type (cdr import))))
(provide 'phpinspect-serialize)

File diff suppressed because one or more lines are too long

@ -163,6 +163,49 @@ return StaticThing::create(new ThingFactory())->makeThing((((new Potato())->anti
(phpinspect--make-type :name "\\void" :fully-qualified t)
(phpinspect--function-return-type method))))))))
(ert-deftest phpinspect-index-static-method-annotations ()
(let* ((result (phpinspect--index-tokens
(phpinspect-parse-string
"<?php
/* @method static int peel(bool $fast, array $loose)
* @method static Banana create()
@method static hold() **/
class Banana {}")))
(class (car (alist-get 'classes result)))
(methods (alist-get 'static-methods class)))
(should (= 3 (length methods)))
(dolist (method methods)
(should (member (phpinspect--function-name method)
'("create" "hold" "peel")))
(cond ((string= (phpinspect--function-name method)
"duplicate")
(should (phpinspect--type=
(phpinspect--make-type :name "\\Banana" :fully-qualified t)
(phpinspect--function-return-type method))))
((string= (phpinspect--function-name method)
"peel")
(should (phpinspect--type=
(phpinspect--make-type :name "\\int" :fully-qualified t)
(phpinspect--function-return-type method)))
(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=))))
(should (phpinspect--type=
(phpinspect--make-type :name "\\bool" :fully-qualified t)
(car (alist-get
"fast" (phpinspect--function-arguments method) nil nil #'string=)))))
((string= (phpinspect--function-name method)
"hold")
(should (phpinspect--type=
(phpinspect--make-type :name "\\void" :fully-qualified t)
(phpinspect--function-return-type method))))))))
(ert-deftest phpinspect-index-tokens-class ()
(let* ((index1
(phpinspect--index-tokens

Loading…
Cancel
Save