branch: externals/phpinspect
commit d3f100388eeefde2f218faa6f5056fe59352889c
Author: Hugo Thunnissen <[email protected]>
Commit: Hugo Thunnissen <[email protected]>
Resolve property types using other methods when resolving from constructor
fails
Property types of classes in live buffers are now resolved from assignments
in
other methods when resolving from the __construct method fails.
---
phpinspect-buffer.el | 14 +++-----------
phpinspect-class.el | 1 +
phpinspect-resolve.el | 38 ++++++++++++++++++++++++++++++++++++++
phpinspect-resolvecontext.el | 3 ++-
4 files changed, 44 insertions(+), 12 deletions(-)
diff --git a/phpinspect-buffer.el b/phpinspect-buffer.el
index 4872aed20d..bfd603c470 100644
--- a/phpinspect-buffer.el
+++ b/phpinspect-buffer.el
@@ -404,17 +404,9 @@ linked with."
static)))
(when (and (phpinspect-variable-p (phpinspect-meta-token var)) (not
(phpinspect--variable-type indexed)))
- (when-let* ((constructor (phpinspect--class-get-method class-obj
(phpinspect-intern-name "__construct")))
- (rctx (phpinspect--make-resolvecontext
:enclosing-tokens (list (phpinspect-meta-token class))
-
:enclosing-metadata (list class))))
- (setf (phpinspect--variable-type indexed)
- (phpinspect-get-pattern-type-in-block
- rctx (phpinspect--make-pattern :m `(:variable "this")
- :m `(:object-attrib (:word
,(cadr (phpinspect-meta-token var)))))
- (phpinspect-function-block (phpinspect--function-token
constructor))
- type-resolver
- (phpinspect-function-argument-list
(phpinspect--function-token constructor))))))
-
+ (setf (phpinspect--variable-type indexed)
+ (phpinspect--class-resolve-property-type
+ class-obj (cadr (phpinspect-meta-token var)) type-resolver
class)))
(phpinspect--class-set-variable class-obj indexed)
diff --git a/phpinspect-class.el b/phpinspect-class.el
index 2ee761e508..2a71acc1ff 100644
--- a/phpinspect-class.el
+++ b/phpinspect-class.el
@@ -259,5 +259,6 @@ Conditionally executes BODY depending on
(puthash subscription-class update-function
(phpinspect--class-subscriptions subscription-class))))))
+
(provide 'phpinspect-class)
;;; phpinspect-class.el ends here
diff --git a/phpinspect-resolve.el b/phpinspect-resolve.el
index bf473c4a4d..2dfc2b5452 100644
--- a/phpinspect-resolve.el
+++ b/phpinspect-resolve.el
@@ -25,6 +25,7 @@
(require 'phpinspect-resolvecontext)
(require 'phpinspect-cache)
+(require 'phpinspect-class)
(require 'phpinspect-type)
(require 'phpinspect-token-predicates)
@@ -497,4 +498,41 @@ EXPRESSION."
(phpinspect-function-argument-list enclosing-token))))))
type))
+(defun phpinspect--function-get-pattern-type (fn rctx pattern type-resolver)
+ (phpinspect-get-pattern-type-in-block
+ rctx pattern
+ (phpinspect-function-block (phpinspect--function-token fn))
+ type-resolver
+ (phpinspect-function-argument-list (phpinspect--function-token fn))))
+
+
+(cl-defmethod phpinspect--class-resolve-property-type
+ ((class phpinspect--class) (property-name string) type-resolver
class-token-meta)
+ "Resolve type of POPERTY-NAME in the context of CLASS using
+CLASS-TOKEN-META as parse result."
+ (let ((pattern (phpinspect--make-pattern
+ :m `(:variable "this")
+ :m `(:object-attrib (:word ,property-name))))
+ (rctx (phpinspect--make-resolvecontext :enclosing-tokens (list
(phpinspect-meta-token class-token-meta))
+ :enclosing-metadata (list
class-token-meta)))
+ (constructor-name (phpinspect-intern-name "__construct")))
+
+ (or
+ (when-let ((constructor (phpinspect--class-get-method class
constructor-name)))
+ (phpinspect--function-get-pattern-type constructor rctx pattern
type-resolver))
+ (catch 'found
+ (dolist (method (phpinspect--class-get-method-list class))
+ (unless (eq constructor-name (phpinspect--function-name-symbol
method))
+ (when-let ((result (phpinspect--function-get-pattern-type method
rctx pattern type-resolver)))
+ (throw 'found result))))
+ nil))))
+
+(cl-defmethod phpinspect--class-resolve-property-type
+ ((_class phpinspect--class) property-name &rest _ignored)
+ ;; Catch-all for cases where one attempts to resolve a nil property
+ ;; name. Saves an if-statement for the caller.
+ ;; Can't resolve property type when property name is nil, so we do nothing.
+ (cl-assert (not property-name))
+ nil)
+
(provide 'phpinspect-resolve)
diff --git a/phpinspect-resolvecontext.el b/phpinspect-resolvecontext.el
index 4290aba693..42d087fff3 100644
--- a/phpinspect-resolvecontext.el
+++ b/phpinspect-resolvecontext.el
@@ -31,7 +31,6 @@
(require 'phpinspect-meta)
(require 'phpinspect-util)
-
(defsubst phpinspect-blocklike-p (token)
(or (phpinspect-block-p token)
(phpinspect-function-p token)
@@ -111,6 +110,7 @@
(cl-defmethod phpinspect-get-resolvecontext
((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
;; end of the buffer, so we find the last child before point.
@@ -227,5 +227,6 @@ return it. Pops enclosing tokens to keep both in sync."
(pop (phpinspect--resolvecontext-enclosing-tokens rctx))
(pop (phpinspect--resolvecontext-enclosing-metadata rctx)))
+
(provide 'phpinspect-resolvecontext)
;;; phpinspect-resolvecontext.el ends here