Completion: filter out attributes that are not accessible from the current scope

master
Hugo Thunnissen 1 month ago
parent 25ae878cfc
commit e111df4ca9

@ -155,25 +155,35 @@ Conditionally executes BODY depending on
(puthash (phpinspect--function-name-symbol method)
method
map))
map)
method)
(cl-defmethod phpinspect--class-set-method ((class phpinspect--class)
(method phpinspect--function))
(method phpinspect--function)
&optional extended)
(phpinspect--class-edit class
(phpinspect--log "Adding method by name %s to class"
(phpinspect--function-name method))
(phpinspect--add-method-copy-to-map
(phpinspect--class-methods class)
(phpinspect--class-name class)
method)))
(setq method (phpinspect--add-method-copy-to-map
(phpinspect--class-methods class)
(phpinspect--class-name class)
method))
(when extended
(setf (phpinspect--function--inherited method) extended))))
(cl-defmethod phpinspect--class-set-static-method ((class phpinspect--class)
(method phpinspect--function))
(method phpinspect--function)
&optional extended)
(phpinspect--class-edit class
(phpinspect--add-method-copy-to-map
(phpinspect--class-static-methods class)
(phpinspect--class-name class)
method)))
(setq method (phpinspect--add-method-copy-to-map
(phpinspect--class-static-methods class)
(phpinspect--class-name class)
method))
(when extended
(setf (phpinspect--function--inherited method) extended))))
(cl-defmethod phpinspect--class-delete-method ((class phpinspect--class) (method phpinspect--function))
(phpinspect--class-edit class
@ -226,8 +236,7 @@ Conditionally executes BODY depending on
(phpinspect--class-static-methods class))))
(if existing
(phpinspect--merge-method (phpinspect--class-name class) existing method extended)
(setf (phpinspect--function--inherited method) extended)
(phpinspect--class-set-static-method class method)))))
(phpinspect--class-set-static-method class method extended)))))
(cl-defmethod phpinspect--class-update-method ((class phpinspect--class)
(method phpinspect--function)
@ -238,19 +247,30 @@ Conditionally executes BODY depending on
(if existing
(phpinspect--merge-method (phpinspect--class-name class) existing method extended)
(setf (phpinspect--function--inherited method) extended)
(phpinspect--class-set-method class method)))))
(phpinspect--class-set-method class method extended)))))
(define-inline phpinspect--scope-inherits-p (scope)
"Returns non-nil when FN has a public or protected scope."
(inline-letevals (fn)
(inline-quote (or (phpinspect-public-p ,scope)
(phpinspect-protected-p ,scope)))))
(define-inline phpinspect--function-inherits-p (fn)
(inline-quote (phpinspect--scope-inherits-p (phpinspect--function-scope ,fn))))
;; FIXME: Remove inherited methods when they no longer exist in parent classes
;; (and/or the current class in the case of abstract methods).
;; TODO: Check if above comment is still accurate ^^
(cl-defmethod phpinspect--class-incorporate ((class phpinspect--class)
(other-class phpinspect--class))
(phpinspect--class-edit class
(dolist (method (phpinspect--class-get-method-list other-class))
(phpinspect--class-update-method class method 'extended))
(when (phpinspect--function-inherits-p method)
(phpinspect--class-update-method class method 'extended)))
(dolist (method (phpinspect--class-get-static-method-list other-class))
(phpinspect--class-update-static-method class method 'extended))
(when (phpinspect--function-inherits-p method)
(phpinspect--class-update-static-method class method 'extended)))
(phpinspect--class-subscribe class other-class)))

@ -105,6 +105,19 @@
(lambda (fqn)
(phpinspect--get-methods-for-class resolvecontext fqn static)))
(cl-defmethod phpinspect--candidate-scope ((candidate phpinspect--function))
(phpinspect--function-scope candidate))
(cl-defmethod phpinspect--candidate-scope ((candidate phpinspect--variable))
(phpinspect--variable-scope candidate))
(cl-defmethod phpinspect--candiate-inherited ((candidate phpinspect--function))
(phpinspect--function--inherited candidate))
;; FIXME: when inheriting of variables is implemented
(cl-defmethod phpinspect--candidate-inherited ((candidate phpinspect--variable))
nil)
(defun phpinspect-suggest-attributes-at-point
(resolvecontext &optional static)
"Suggest object or class attributes at point.
@ -129,22 +142,41 @@ static variables and static methods."
(setf (phpinspect--resolvecontext-subject resolvecontext)
(butlast (phpinspect--resolvecontext-subject resolvecontext))))
(let* ((type-resolver (phpinspect--make-type-resolver-for-resolvecontext
(let* ((enclosing-class (seq-find #'phpinspect-class-p
(phpinspect--resolvecontext-enclosing-tokens resolvecontext)))
(type-resolver (phpinspect--make-type-resolver-for-resolvecontext
resolvecontext))
(method-lister (phpinspect--make-method-lister
resolvecontext
static)))
(let ((statement-type (phpinspect-resolve-type-from-context
static))
(statement-type (phpinspect-resolve-type-from-context
resolvecontext
type-resolver)))
(phpinspect--log "Statement type: %s" statement-type)
(when statement-type
(let ((type (funcall type-resolver statement-type)))
(when-let ((result
(append (phpinspect--get-variables-for-class
resolvecontext type static)
(funcall method-lister type))))
(phpinspect--log "Returning attributes %s" result)
result))))))
type-resolver))
enclosing-class-name)
(phpinspect--log "Statement type: %s" statement-type)
(when statement-type
(when-let* ((type (funcall type-resolver statement-type))
(result
(append (phpinspect--get-variables-for-class
resolvecontext type static)
(funcall method-lister type))))
;; Filter out candidates according to scoping rules
(when (and enclosing-class
(setq enclosing-class-name
(phpinspect--get-class-name-from-token enclosing-class)))
(let* ((enclosing-type (funcall type-resolver (phpinspect--make-type :name enclosing-class-name)))
(allow-protected (phpinspect--type= type enclosing-type))
filtered-result)
(dolist (candidate result)
(if allow-protected
(push candidate filtered-result)
(when (phpinspect-public-p (phpinspect--candidate-scope candidate))
(push candidate filtered-result))))
(setq result filtered-result))
(phpinspect--log "Returning attributes %s" result)
result)))))
(provide 'phpinspect-suggest)

@ -81,6 +81,12 @@ Type can be any of the token types returned by
(or (phpinspect-token-type-p token :const)
(phpinspect-incomplete-const-p token)))
(define-inline phpinspect-public-p (token)
(inline-quote (phpinspect-token-type-p ,token :public)))
(define-inline phpinspect-protected-p (token)
(inline-quote (phpinspect-token-type-p ,token :protected)))
(define-inline phpinspect-scope-p (token)
(inline-letevals (token)
(inline-quote

@ -52,10 +52,10 @@
(phpinspect--class-set-index class `(phpinspect--indexed-class (class-name . ,(phpinspect--make-type :name "Class"))))
(phpinspect--class-set-index other-class `(phpinspect--indexed-class (class-name . ,(phpinspect--make-type :name "OtherClass"))))
(phpinspect--class-update-method
class (phpinspect--make-function :name "test" :return-type phpinspect--null-type))
class (phpinspect--make-function :scope '(:private) :name "test" :return-type phpinspect--null-type))
(phpinspect--class-update-method
other-class (phpinspect--make-function :name "other-test" :return-type phpinspect--null-type))
other-class (phpinspect--make-function :scope '(:protected) :name "other-test" :return-type phpinspect--null-type))
(phpinspect--class-incorporate class other-class)

Loading…
Cancel
Save