Resolve types of suggested variable completions

master
Hugo Thunnissen 1 month ago
parent ae681a0663
commit e04ab0c118

@ -73,6 +73,7 @@
(blocks-or-lists) (blocks-or-lists)
(statements (phpinspect--split-statements token))) (statements (phpinspect--split-statements token)))
(dolist (statement statements) (dolist (statement statements)
(phpinspect--log "Finding assignment in statement '%s'" statement)
(when (seq-find #'phpinspect-maybe-assignment-p statement) (when (seq-find #'phpinspect-maybe-assignment-p statement)
(phpinspect--log "Found assignment statement") (phpinspect--log "Found assignment statement")
(push (phpinspect--make-assignment-context (push (phpinspect--make-assignment-context
@ -500,9 +501,16 @@ EXPRESSION."
(defun phpinspect-resolve-type-from-context (resolvecontext &optional type-resolver) (defun phpinspect-resolve-type-from-context (resolvecontext &optional type-resolver)
"Resolve the type that RESOLVECONTEXT's subject evaluates to."
;; Subject should be a statement, not a single token.
(when (phpinspect-probably-token-p (phpinspect--resolvecontext-subject resolvecontext))
(setf (phpinspect--resolvecontext-subject resolvecontext)
(list (phpinspect--resolvecontext-subject resolvecontext))))
(unless type-resolver (unless type-resolver
(setq type-resolver (setq type-resolver
(phpinspect--make-type-resolver-for-resolvecontext resolvecontext))) (phpinspect--make-type-resolver-for-resolvecontext resolvecontext)))
(phpinspect--log "Looking for type of statement: %s in nested token" (phpinspect--log "Looking for type of statement: %s in nested token"
(phpinspect--resolvecontext-subject resolvecontext)) (phpinspect--resolvecontext-subject resolvecontext))
;; Find all enclosing tokens that aren't classes. Classes do not contain variable ;; Find all enclosing tokens that aren't classes. Classes do not contain variable

@ -68,6 +68,23 @@
:documentation :documentation
"Tokens that enclose the subject.")) "Tokens that enclose the subject."))
(defun phpinspect--repurpose-resolvecontext (rctx &optional enclosing-tokens subject)
"Copy RCTX, optionally replacing the enclosing tokens and subject.
Note: if ENCLOSING-TOKENS are provided, the repurposed
resolvecontext will have it's enclosing token metadata unset as
it would no longer be valid for the new enclosing tokens."
(let ((rctx (phpinspect--copy-resolvecontext rctx)))
(when subject
(setf (phpinspect--resolvecontext-subject rctx) subject))
(when enclosing-tokens
;; Unset enclosing-metadata as it is no longer valid.
(setf (phpinspect--resolvecontext-enclosing-metadata rctx) nil)
(setf (phpinspect--resolvecontext-enclosing-tokens rctx) enclosing-tokens))
rctx))
(cl-defmethod phpinspect--resolvecontext-push-enclosing-token (cl-defmethod phpinspect--resolvecontext-push-enclosing-token
((resolvecontext phpinspect--resolvecontext) enclosing-token) ((resolvecontext phpinspect--resolvecontext) enclosing-token)
"Add ENCLOSING-TOKEN to RESOLVECONTEXTs enclosing token stack." "Add ENCLOSING-TOKEN to RESOLVECONTEXTs enclosing token stack."

@ -38,7 +38,8 @@
(defun phpinspect-suggest-variables-at-point (resolvecontext) (defun phpinspect-suggest-variables-at-point (resolvecontext)
(phpinspect--log "Suggesting variables at point") (phpinspect--log "Suggesting variables at point")
(let ((variables))
(let ((variables (make-hash-table :test 'equal)))
(dolist (token (phpinspect--resolvecontext-enclosing-tokens resolvecontext)) (dolist (token (phpinspect--resolvecontext-enclosing-tokens resolvecontext))
(when (phpinspect-not-class-p token) (when (phpinspect-not-class-p token)
(let ((token-list token) (let ((token-list token)
@ -46,26 +47,33 @@
(while token-list (while token-list
(setq potential-variable (pop token-list)) (setq potential-variable (pop token-list))
(cond ((phpinspect-variable-p potential-variable) (cond ((phpinspect-variable-p potential-variable)
(phpinspect--log "Pushing variable %s" potential-variable) (puthash (cadr potential-variable)
(push (phpinspect--make-variable (phpinspect--make-variable :name (cadr potential-variable))
:name (cadr potential-variable)
:type phpinspect--null-type)
variables)) variables))
((phpinspect-function-p potential-variable) ((phpinspect-function-p potential-variable)
(push (phpinspect-function-block potential-variable) token-list) (push (phpinspect-function-block potential-variable) token-list)
(dolist (argument (phpinspect-function-argument-list potential-variable)) (dolist (argument (phpinspect-function-argument-list potential-variable))
(when (phpinspect-variable-p argument) (when (phpinspect-variable-p argument)
(push (phpinspect--make-variable (puthash (cadr argument)
:name (cadr argument) (phpinspect--make-variable :name (cadr argument))
:type phpinspect--null-type)
variables)))) variables))))
((phpinspect-block-p potential-variable) ((phpinspect-block-p potential-variable)
(dolist (nested-token (cdr potential-variable)) (dolist (nested-token (cdr potential-variable))
(push nested-token token-list)))))))) (push nested-token token-list))))))))
(let (variable-list)
(dolist (var (hash-table-values variables))
;; Only return variables that have a name. Unnamed variables are just dollar ;; Only return variables that have a name. Unnamed variables are just dollar
;; signs (: ;; signs (:
(seq-filter #'phpinspect--variable-name variables))) (when (phpinspect--variable-name var)
(setf (phpinspect--variable-type var)
(phpinspect-resolve-type-from-context
(phpinspect--repurpose-resolvecontext
resolvecontext nil `(:variable ,(phpinspect--variable-name var)))))
(push var variable-list)))
variable-list)))
(defun phpinspect-get-cached-project-class-methods (project-root class-fqn &optional static) (defun phpinspect-get-cached-project-class-methods (project-root class-fqn &optional static)
(phpinspect--log "Getting cached project class methods for %s (%s)" (phpinspect--log "Getting cached project class methods for %s (%s)"

Loading…
Cancel
Save