Fix tests and patch bugs that came to light in the process

WIP-incremental-parsing
Hugo Thunnissen 2 years ago
parent 3a3e2cd362
commit 0bc9e795b2

@ -106,28 +106,36 @@
(cl-defmethod phpinspect--class-get-static-method ((class phpinspect--class) method-name)
(gethash method-name (phpinspect--class-static-methods class)))
(cl-defmethod phpinspect--class-set-method ((class phpinspect--class)
(method phpinspect--function))
(phpinspect--log "Adding method by name %s to class"
(phpinspect--function-name method))
(cl-defmethod phpinspect--add-method-copy-to-map
((map hash-table)
(class-name phpinspect--type)
(method phpinspect--function))
(setq method (phpinspect--copy-function method))
(when (phpinspect--type-does-late-static-binding
(phpinspect--function-return-type method))
(setf (phpinspect--function-return-type method)
(phpinspect--resolve-late-static-binding
(phpinspect--function-return-type method)
class-name))
(setf (phpinspect--function-return-type method)
(alist-get 'class-name (phpinspect--class-index class))))
(puthash (phpinspect--function-name-symbol method)
method
map))
(puthash (phpinspect--function-name-symbol method)
method
(phpinspect--class-methods class)))
(cl-defmethod phpinspect--class-set-method ((class phpinspect--class)
(method phpinspect--function))
(phpinspect--log "Adding method by name %s to class"
(phpinspect--function-name method))
(phpinspect--add-method-copy-to-map
(phpinspect--class-methods class)
(alist-get 'class-name (phpinspect--class-index class))
method))
(cl-defmethod phpinspect--class-set-static-method ((class phpinspect--class)
(method phpinspect--function))
(setq method (phpinspect--copy-function method))
(puthash (phpinspect--function-name-symbol method)
method
(phpinspect--class-static-methods class)))
(phpinspect--add-method-copy-to-map
(phpinspect--class-static-methods class)
(alist-get 'class-name (phpinspect--class-index class))
method))
(cl-defmethod phpinspect--class-get-method-return-type
((class phpinspect--class) (method-name symbol))
@ -155,39 +163,38 @@
(phpinspect--class-static-methods class))
methods))
(cl-defmethod phpinspect--merge-method ((class-name phpinspect--type)
(existing phpinspect--function)
(method phpinspect--function))
(let ((new-return-type (phpinspect--resolve-late-static-binding
class-name
(phpinspect--function-return-type method))))
(unless (phpinspect--type= new-return-type phpinspect--null-type)
(phpinspect--log "method return type %s" (phpinspect--function-return-type method))
(setf (phpinspect--function-return-type existing)
new-return-type))
(setf (phpinspect--function-arguments existing)
(phpinspect--function-arguments method))))
(cl-defmethod phpinspect--class-update-static-method ((class phpinspect--class)
(method phpinspect--function))
(let ((existing (gethash (phpinspect--function-name-symbol method)
(phpinspect--class-static-methods class))))
(if existing
(progn
(unless (phpinspect--type= (phpinspect--function-return-type method)
phpinspect--null-type)
(setf (phpinspect--function-return-type existing)
(phpinspect--function-return-type method)))
(setf (phpinspect--function-arguments existing)
(phpinspect--function-arguments method)))
(phpinspect--merge-method
(alist-get 'class-name (phpinspect--class-index class))
existing method)
(phpinspect--class-set-static-method class method))))
(cl-defmethod phpinspect--class-update-method ((class phpinspect--class)
(method phpinspect--function))
(let ((existing (gethash (phpinspect--function-name-symbol method)
(let* ((existing (gethash (phpinspect--function-name-symbol method)
(phpinspect--class-methods class))))
(if existing
(progn
(unless (phpinspect--type= (phpinspect--function-return-type method)
phpinspect--null-type)
(phpinspect--log "method return type %s" (phpinspect--function-return-type method))
(setf (phpinspect--function-return-type existing)
;; The "static" return type returns the class that the method
;; is called on
(if (phpinspect--type-does-late-static-binding
(phpinspect--function-return-type method))
(alist-get 'class-name (phpinspect--class-index class))
(phpinspect--function-return-type method))))
(setf (phpinspect--function-arguments existing)
(phpinspect--function-arguments method)))
(phpinspect--merge-method
(alist-get 'class-name (phpinspect--class-index class))
existing method)
(phpinspect--class-set-method class method))))
(cl-defmethod phpinspect--class-incorporate ((class phpinspect--class)

@ -267,9 +267,9 @@
(let ((class-name (funcall type-resolver (phpinspect--make-type :name class-name))))
`(,class-name .
(phpinspect--indexed-class
(class-name . ,class-name)
(imports . ,imports)
(methods . ,methods)
(class-name . ,class-name)
(static-methods . ,static-methods)
(static-variables . ,static-variables)
(variables . ,variables)

@ -0,0 +1,105 @@
;;; phpinspect-index.el --- PHP parsing and completion package -*- lexical-binding: t; -*-
;; Copyright (C) 2021 Free Software Foundation, Inc
;; Author: Hugo Thunnissen <devel@hugot.nl>
;; Keywords: php, languages, tools, convenience
;; Version: 0
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
(require 'phpinspect-type)
(require 'phpinspect-class)
(cl-defmethod phpinspect--serialize-type ((type phpinspect--type))
`(phpinspect--make-type
:name ,(phpinspect--type-name type)
:collection ,(phpinspect--type-collection type)
:contains ,(when (phpinspect--type-contains type)
(phpinspect--serialize-type (phpinspect--type-contains type)))
:fully-qualified ,(phpinspect--type-fully-qualified type)))
(cl-defmethod phpinspect--serialize-function ((func phpinspect--function))
`(phpinspect--make-function
:name ,(phpinspect--function-name func)
:scope (quote ,(phpinspect--function-scope func))
:arguments ,(append '(list)
(mapcar (lambda (arg)
`(list ,(car arg) ,(phpinspect--serialize-type (cadr arg))))
(phpinspect--function-arguments func)))
:return-type ,(when (phpinspect--function-return-type func)
(phpinspect--serialize-type
(phpinspect--function-return-type func)))))
(cl-defmethod phpinspect--serialize-variable ((var phpinspect--variable))
`(phpinspect--make-variable :name ,(phpinspect--variable-name var)
:type ,(when (phpinspect--variable-type var)
(phpinspect--serialize-type
(phpinspect--variable-type var)))
:scope (quote ,(phpinspect--variable-scope var))))
(cl-defmethod phpinspect--serialize-indexed-class ((class (head phpinspect--indexed-class)))
``(phpinspect--indexed-class
(class-name . ,,(phpinspect--serialize-type (alist-get 'class-name class)))
(imports . ,,(append '(list)
(mapcar #'phpinspect--serialize-import
(alist-get 'imports class))))
(methods . ,,(append '(list)
(mapcar #'phpinspect--serialize-function
(alist-get 'methods class))))
(static-methods . ,,(append '(list)
(mapcar #'phpinspect--serialize-function
(alist-get 'static-methods class))))
(static-variables . ,,(append '(list)
(mapcar #'phpinspect--serialize-variable
(alist-get 'static-variables class))))
(variables . ,,(append '(list)
(mapcar #'phpinspect--serialize-variable
(alist-get 'variables class))))
(constants . ,,(append '(list)
(mapcar #'phpinspect--serialize-variable
(alist-get 'constants class))))
(extends . ,,(append '(list)
(mapcar #'phpinspect--serialize-type
(alist-get 'extends class))))
(implements . ,,(append '(list)
(mapcar #'phpinspect--serialize-type
(alist-get 'implements class))))))
(cl-defmethod phpinspect--serialize-root-index ((index (head phpinspect--root-index)))
``(phpinspect--root-index
(imports . ,,(append '(list)
(mapcar #'phpinspect--serialize-import
(alist-get 'imports index))))
(classes ,,@(mapcar (lambda (cons-class)
`(list ,(phpinspect--serialize-type (car cons-class))
,(phpinspect--serialize-indexed-class (cdr cons-class))))
(alist-get 'classes index)))
(functions . ,,(append '(list)
(mapcar #'phpinspect--serialize-function
(alist-get 'functions index))))))
(defun phpinspect--serialize-import (import)
`(cons
(phpinspect-intern-name ,(symbol-name (car import)))
,(phpinspect--serialize-type (cdr import))))
(provide 'phpinspect-serialize)
;;; phpinspect-serialize.el ends here

@ -84,6 +84,13 @@ See https://wiki.php.net/rfc/static_return_type ."
(or (phpinspect--type= type phpinspect--static-type)
(phpinspect--type= type phpinspect--this-type)))
(cl-defmethod phpinspect--resolve-late-static-binding
((type phpinspect--type)
(class-type phpinspect--type))
(if (phpinspect--type-does-late-static-binding type)
class-type
type))
(defsubst phpinspect--type-is-native (type)
(catch 'found
(dolist (native phpinspect-native-types)

@ -359,7 +359,9 @@ TODO:
(phpinspect--resolvecontext-project-root resolvecontext))
type-of-previous-statement))
(method (when class
(phpinspect--class-get-method class method-name-sym))))
(if static
(phpinspect--class-get-static-method class method-name-sym)
(phpinspect--class-get-method class method-name-sym)))))
(phpinspect--log "Eldoc method name: %s" method-name-sym)
(phpinspect--log "Eldoc type of previous statement: %s"
type-of-previous-statement)
@ -418,20 +420,18 @@ TODO:
(phpinspect--find-assignments-in-token block-or-list)
assignments)))))
;; return
(phpinspect--log "Yayo Returning %s" assignments)
(phpinspect--log "Yayo had statements %s" statements)
(phpinspect--log "Found assignments in token: %s" assignments)
(phpinspect--log "Found statements in token: %s" statements)
assignments))
(cl-defmethod phpinspect--find-assignments-in-token ((token (head :list)))
"Find assignments that are in a list token."
(phpinspect--log "looking for assignments in list %s" token)
(let ((ajaja (seq-filter
(lambda (statement)
(phpinspect--log "checking statement %s" statement)
(seq-find #'phpinspect-maybe-assignment-p statement))
(phpinspect--split-list #'phpinspect-end-of-statement-p (cdr token)))))
(phpinspect--log "Found ajaja %s" ajaja)
ajaja))
(seq-filter
(lambda (statement)
(phpinspect--log "checking statement %s" statement)
(seq-find #'phpinspect-maybe-assignment-p statement))
(phpinspect--split-list #'phpinspect-end-of-statement-p (cdr token))))
(defsubst phpinspect-not-assignment-p (token)
"Inverse of applying `phpinspect-assignment-p to TOKEN."
@ -595,6 +595,7 @@ resolve types of function argument variables."
(last-assignment-value (when assignments (car (last assignments)))))
(phpinspect--log "Last assignment: %s" last-assignment-value)
(phpinspect--log "Current block: %s" php-block)
;; When the right of an assignment is more than $variable; or "string";(so
;; (:variable "variable") (:terminator ";") or (:string "string") (:terminator ";")
;; in tokens), we're likely working with a derived assignment like $object->method()
@ -602,7 +603,7 @@ resolve types of function argument variables."
(cond ((and (phpinspect-word-p (car last-assignment-value))
(string= (cadar last-assignment-value) "new"))
(funcall type-resolver (phpinspect--make-type :name (cadadr last-assignment-value))))
((and (> (length last-assignment-value) 2)
((and (> (length last-assignment-value) 1)
(seq-find #'phpinspect-attrib-p last-assignment-value))
(phpinspect--log "Variable was assigned with a derived statement")
(phpinspect-get-derived-statement-type-in-block resolvecontext
@ -613,7 +614,8 @@ resolve types of function argument variables."
;; If the right of an assignment is just $variable;, we can check if it is a
;; function argument and otherwise recurse to find the type of that variable.
((phpinspect-variable-p (car last-assignment-value))
(phpinspect--log "Variable was assigned with the value of another variable")
(phpinspect--log "Variable was assigned with the value of another variable: %s"
last-assignment-value)
(or (when function-arg-list
(phpinspect-get-variable-type-in-function-arg-list (cadar last-assignment-value)
type-resolver
@ -852,44 +854,6 @@ level of a token. Nested variables are ignored."
(defun phpinspect--buffer-index (buffer)
(with-current-buffer buffer phpinspect--buffer-index))
(cl-defgeneric phpinspect--merge-indexes (index1 index2)
"Merge two phpinspect index types into one and return it")
(cl-defmethod phpinspect--merge-indexes
((class1 (head phpinspect--indexed-class))
(class2 (head phpinspect--indexed-class)))
"Merge two indexed classes."
(let* ((class1-methods (alist-get 'methods (cdr class1)))
(class1-variables (alist-get 'variables (cdr class1))))
(dolist (method (alist-get 'methods (cdr class2)))
(cl-pushnew method class1-methods :test #'equal))
(setf (alist-get 'methods (cdr class1)) class1-methods)
(dolist (variable (alist-get 'variables (cdr class2)))
(cl-pushnew variable class1-variables :test #'equal))
(setf (alist-get 'variables (cdr class1)) class1-variables))
class1)
(cl-defmethod phpinspect--merge-indexes
((index1 (head phpinspect--root-index))
(index2 (head phpinspect--root-index)))
(let ((index1-classes (alist-get 'classes (cdr index1)))
(index2-classes (alist-get 'classes (cdr index2))))
(dolist (class index2-classes)
(when class
(let* ((class-name (alist-get 'class-name (cdr class)))
(existing-class (alist-get class-name index1-classes nil nil 'phpinspect--type=)))
(if existing-class
(progn
(phpinspect--log "Found existing class in root index: %s" class-name)
(setcdr (assoc class-name index1-classes)
(phpinspect--merge-indexes existing-class (cdr class))))
;; else
(phpinspect--log "Didn't find existing class in root index: %s" class-name)
(push class index1-classes)))))
(setf (alist-get 'classes index1) index1-classes)
index1))
(defsubst phpinspect-not-variable-p (token)
(not (phpinspect-variable-p token)))

@ -1 +1 @@
(phpinspect--root-index (classes ("\\App\\Entity\\AuthToken" phpinspect--class (methods #s(phpinspect--function "getCreationTime" (:public) nil "\\DateTime") #s(phpinspect--function "isValid" (:public) nil "\\bool") #s(phpinspect--function "hasStudentRole" (:public) nil "\\bool") #s(phpinspect--function "getUser" (:public) nil "\\App\\Entity\\User") #s(phpinspect--function "getToken" (:public) nil "\\string") #s(phpinspect--function "__construct" (:public) (("token" "\\string") ("user" "\\App\\Entity\\User") ("valid" "\\bool") ("creation_time" "\\DateTime")) nil)) (class-name . "\\App\\Entity\\AuthToken") (static-methods) (static-variables) (variables #s(phpinspect--variable "creation_time" (:private) "\\DateTime") #s(phpinspect--variable "valid" (:private) "\\bool") #s(phpinspect--variable "user" (:private) "\\App\\Entity\\App\\\\Entity\\\\User") #s(phpinspect--variable "token" (:private) "\\string")) (constants) (extends) (implements))) (functions))
`(phpinspect--root-index (imports \, (list)) (classes ,(list (phpinspect--make-type :name "\\App\\Entity\\AuthToken" :collection nil :contains nil :fully-qualified t) `(phpinspect--indexed-class (class-name \, (phpinspect--make-type :name "\\App\\Entity\\AuthToken" :collection nil :contains nil :fully-qualified t)) (imports \, (list (cons (phpinspect-intern-name "ORM") (phpinspect--make-type :name "\\Doctrine\\ORM\\Mapping" :collection nil :contains nil :fully-qualified t)))) (methods \, (list (phpinspect--make-function :name "getCreationTime" :scope '(:public) :arguments (list) :return-type (phpinspect--make-type :name "\\DateTime" :collection nil :contains nil :fully-qualified t)) (phpinspect--make-function :name "isValid" :scope '(:public) :arguments (list) :return-type (phpinspect--make-type :name "\\bool" :collection nil :contains nil :fully-qualified t)) (phpinspect--make-function :name "hasStudentRole" :scope '(:public) :arguments (list) :return-type (phpinspect--make-type :name "\\bool" :collection nil :contains nil :fully-qualified t)) (phpinspect--make-function :name "getUser" :scope '(:public) :arguments (list) :return-type (phpinspect--make-type :name "\\App\\Entity\\User" :collection nil :contains nil :fully-qualified t)) (phpinspect--make-function :name "getToken" :scope '(:public) :arguments (list) :return-type (phpinspect--make-type :name "\\string" :collection nil :contains nil :fully-qualified t)) (phpinspect--make-function :name "__construct" :scope '(:public) :arguments (list (list "token" (phpinspect--make-type :name "\\string" :collection nil :contains nil :fully-qualified t)) (list "user" (phpinspect--make-type :name "\\App\\Entity\\User" :collection nil :contains nil :fully-qualified t)) (list "valid" (phpinspect--make-type :name "\\bool" :collection nil :contains nil :fully-qualified t)) (list "creation_time" (phpinspect--make-type :name "\\DateTime" :collection nil :contains nil :fully-qualified t))) :return-type (phpinspect--make-type :name "\\null" :collection nil :contains nil :fully-qualified t)))) (static-methods \, (list)) (static-variables \, (list)) (variables \, (list (phpinspect--make-variable :name "creation_time" :type (phpinspect--make-type :name "\\DateTime" :collection nil :contains nil :fully-qualified t) :scope '(:private)) (phpinspect--make-variable :name "valid" :type (phpinspect--make-type :name "\\bool" :collection nil :contains nil :fully-qualified t) :scope '(:private)) (phpinspect--make-variable :name "user" :type (phpinspect--make-type :name "\\App\\Entity\\App\\\\Entity\\\\User" :collection nil :contains nil :fully-qualified t) :scope '(:private)) (phpinspect--make-variable :name "token" :type (phpinspect--make-type :name "\\string" :collection nil :contains nil :fully-qualified t) :scope '(:private)))) (constants \, (list)) (extends \, (list)) (implements \, (list))))) (functions \, (list)))

@ -1 +1 @@
(phpinspect--root-index (classes ("\\App\\Entity\\AuthToken" phpinspect--class (methods #s(phpinspect--function "getCreationTime" (:public) nil "\\DateTime") #s(phpinspect--function "anAddedFunction" (:public) nil nil) #s(phpinspect--function "isValid" (:public) nil "\\bool") #s(phpinspect--function "hasStudentRole" (:public) nil "\\bool") #s(phpinspect--function "getUser" (:public) nil "\\App\\Entity\\User") #s(phpinspect--function "getToken" (:public) nil "\\bool") #s(phpinspect--function "__construct" (:public) (("token" "\\string") ("user" "\\App\\Entity\\User") ("valid" "\\bool") ("creation_time" "\\DateTime")) nil)) (class-name . "\\App\\Entity\\AuthToken") (static-methods) (static-variables) (variables #s(phpinspect--variable "creation_time" (:private) "\\DateTime") #s(phpinspect--variable "valid" (:private) "\\bool") #s(phpinspect--variable "user" (:private) "\\App\\Entity\\App\\\\Entity\\\\User") #s(phpinspect--variable "extra" (:private) nil) #s(phpinspect--variable "token" (:private) "\\string")) (constants) (extends) (implements))) (functions))
`(phpinspect--root-index (imports \, (list)) (classes ,(list (phpinspect--make-type :name "\\App\\Entity\\AuthToken" :collection nil :contains nil :fully-qualified t) `(phpinspect--indexed-class (class-name \, (phpinspect--make-type :name "\\App\\Entity\\AuthToken" :collection nil :contains nil :fully-qualified t)) (imports \, (list (cons (phpinspect-intern-name "ORM") (phpinspect--make-type :name "\\Doctrine\\ORM\\Mapping" :collection nil :contains nil :fully-qualified t)))) (methods \, (list (phpinspect--make-function :name "getCreationTime" :scope '(:public) :arguments (list) :return-type (phpinspect--make-type :name "\\DateTime" :collection nil :contains nil :fully-qualified t)) (phpinspect--make-function :name "anAddedFunction" :scope '(:public) :arguments (list) :return-type (phpinspect--make-type :name "\\null" :collection nil :contains nil :fully-qualified t)) (phpinspect--make-function :name "isValid" :scope '(:public) :arguments (list) :return-type (phpinspect--make-type :name "\\bool" :collection nil :contains nil :fully-qualified t)) (phpinspect--make-function :name "hasStudentRole" :scope '(:public) :arguments (list) :return-type (phpinspect--make-type :name "\\bool" :collection nil :contains nil :fully-qualified t)) (phpinspect--make-function :name "getUser" :scope '(:public) :arguments (list) :return-type (phpinspect--make-type :name "\\App\\Entity\\User" :collection nil :contains nil :fully-qualified t)) (phpinspect--make-function :name "getToken" :scope '(:public) :arguments (list) :return-type (phpinspect--make-type :name "\\bool" :collection nil :contains nil :fully-qualified t)) (phpinspect--make-function :name "__construct" :scope '(:public) :arguments (list (list "token" (phpinspect--make-type :name "\\string" :collection nil :contains nil :fully-qualified t)) (list "user" (phpinspect--make-type :name "\\App\\Entity\\User" :collection nil :contains nil :fully-qualified t)) (list "valid" (phpinspect--make-type :name "\\bool" :collection nil :contains nil :fully-qualified t)) (list "creation_time" (phpinspect--make-type :name "\\DateTime" :collection nil :contains nil :fully-qualified t))) :return-type (phpinspect--make-type :name "\\null" :collection nil :contains nil :fully-qualified t)))) (static-methods \, (list)) (static-variables \, (list)) (variables \, (list (phpinspect--make-variable :name "creation_time" :type (phpinspect--make-type :name "\\DateTime" :collection nil :contains nil :fully-qualified t) :scope '(:private)) (phpinspect--make-variable :name "valid" :type (phpinspect--make-type :name "\\bool" :collection nil :contains nil :fully-qualified t) :scope '(:private)) (phpinspect--make-variable :name "user" :type (phpinspect--make-type :name "\\App\\Entity\\App\\\\Entity\\\\User" :collection nil :contains nil :fully-qualified t) :scope '(:private)) (phpinspect--make-variable :name "extra" :type nil :scope '(:private)) (phpinspect--make-variable :name "token" :type (phpinspect--make-type :name "\\string" :collection nil :contains nil :fully-qualified t) :scope '(:private)))) (constants \, (list)) (extends \, (list)) (implements \, (list))))) (functions \, (list)))

@ -39,6 +39,11 @@
(insert-file-contents-literally (concat phpinspect-test-php-file-directory "/" name ".eld"))
(read (current-buffer))))
(defun phpinspect-test-read-fixture-serialization (name)
(with-temp-buffer
(insert-file-contents-literally (concat phpinspect-test-php-file-directory "/" name ".eld"))
(eval (read (current-buffer)))))
(defun phpinspect-test-parse-fixture-code (name)
(phpinspect-parse-file
(concat phpinspect-test-php-file-directory "/" name ".php")))
@ -113,21 +118,19 @@
(phpinspect-test-read-fixture-data "IndexClass1"))))
(should (equal index expected-result))))
(ert-deftest phpinspect-index-tokens ()
(should (equal
(phpinspect--index-tokens
(phpinspect-test-read-fixture-data "IndexClass1"))
(phpinspect-test-read-fixture-data "IndexClass1-indexed"))))
(ert-deftest phpinspect-merge-class-indexes ()
(should (equal
(phpinspect--merge-indexes
(phpinspect-test-read-fixture-data "IndexClass1-indexed")
(phpinspect-test-read-fixture-data "IndexClass2-indexed"))
(phpinspect-test-read-fixture-data
"class-index-1-2-undestructive-merge"))))
(ert-deftest phpinspect--get-resolvecontext ()
(ert-deftest phpinspect-index-tokens-class ()
(let* ((index1
(phpinspect--index-tokens
(phpinspect-test-read-fixture-data "IndexClass1")))
(index2
(phpinspect-test-read-fixture-serialization "IndexClass1-indexed"))
(index1-class (cdr (alist-get 'classes index1)))
(index2-class (cdr (alist-get 'classes index2))))
(dolist (key '(class-name imports methods static-methods static-variables variables constants extends implements))
(should (equal (alist-get key index1-class)
(alist-get key index2-class))))))
(ert-deftest phpinspect-get-resolvecontext ()
(let ((resolvecontext (phpinspect--get-resolvecontext
(phpinspect-test-read-fixture-data "IncompleteClass"))))
@ -158,15 +161,25 @@
(type-resolver (phpinspect--make-type-resolver-for-resolvecontext
resolvecontext)))
(should (string= "\\array" (funcall type-resolver "array")))
(should (string= "\\array" (funcall type-resolver "\\array")))
(should (string= "\\Symfony\\Component\\HttpFoundation\\Response"
(funcall type-resolver "Response")))
(should (string= "\\Response" (funcall type-resolver "\\Response")))
(should (string= "\\App\\Controller\\GastonLagaffe"
(funcall type-resolver "GastonLagaffe")))
(should (string= "\\App\\Controller\\Dupuis\\GastonLagaffe"
(funcall type-resolver "Dupuis\\GastonLagaffe")))))
(should (phpinspect--type= (phpinspect--make-type :name "\\array")
(funcall type-resolver
(phpinspect--make-type :name "array"))))
(should (phpinspect--type= (phpinspect--make-type :name "\\array")
(funcall type-resolver
(phpinspect--make-type :name "\\array"))))
(should (phpinspect--type= (phpinspect--make-type
:name "\\Symfony\\Component\\HttpFoundation\\Response")
(funcall type-resolver (phpinspect--make-type :name "Response"))))
(should (phpinspect--type= (phpinspect--make-type :name "\\Response")
(funcall type-resolver
(phpinspect--make-type :name "\\Response"))))
(should (phpinspect--type= (phpinspect--make-type :name "\\App\\Controller\\GastonLagaffe")
(funcall type-resolver
(phpinspect--make-type :name "GastonLagaffe"))))
(should (phpinspect--type=
(phpinspect--make-type :name "\\App\\Controller\\Dupuis\\GastonLagaffe")
(funcall type-resolver
(phpinspect--make-type :name "Dupuis\\GastonLagaffe"))))))
(ert-deftest phpinspect-type-resolver-for-resolvecontext-namespace-block ()
(let* ((resolvecontext (phpinspect--get-resolvecontext
@ -175,15 +188,21 @@
(type-resolver (phpinspect--make-type-resolver-for-resolvecontext
resolvecontext)))
(should (string= "\\array" (funcall type-resolver "array")))
(should (string= "\\array" (funcall type-resolver "\\array")))
(should (string= "\\Symfony\\Component\\HttpFoundation\\Response"
(funcall type-resolver "Response")))
(should (string= "\\Response" (funcall type-resolver "\\Response")))
(should (string= "\\App\\Controller\\GastonLagaffe"
(funcall type-resolver "GastonLagaffe")))
(should (string= "\\App\\Controller\\Dupuis\\GastonLagaffe"
(funcall type-resolver "Dupuis\\GastonLagaffe")))))
(should (phpinspect--type= (phpinspect--make-type :name "\\array")
(funcall type-resolver (phpinspect--make-type :name "array"))))
(should (phpinspect--type= (phpinspect--make-type :name "\\array")
(funcall type-resolver (phpinspect--make-type :name "\\array"))))
(should (phpinspect--type= (phpinspect--make-type
:name "\\Symfony\\Component\\HttpFoundation\\Response")
(funcall type-resolver (phpinspect--make-type :name "Response"))))
(should (phpinspect--type= (phpinspect--make-type :name "\\Response")
(funcall type-resolver (phpinspect--make-type :name "\\Response"))))
(should (phpinspect--type= (phpinspect--make-type :name "\\App\\Controller\\GastonLagaffe")
(funcall type-resolver (phpinspect--make-type
:name "GastonLagaffe"))))
(should (phpinspect--type= (phpinspect--make-type
:name "\\App\\Controller\\Dupuis\\GastonLagaffe")
(funcall type-resolver (phpinspect--make-type :name "Dupuis\\GastonLagaffe"))))))
(ert-deftest phpinspect-type-resolver-for-resolvecontext-multiple-namespace-blocks ()
(let* ((resolvecontext (phpinspect--get-resolvecontext
@ -192,15 +211,24 @@
(type-resolver (phpinspect--make-type-resolver-for-resolvecontext
resolvecontext)))
(should (string= "\\array" (funcall type-resolver "array")))
(should (string= "\\array" (funcall type-resolver "\\array")))
(should (string= "\\Symfony\\Component\\HttpFoundation\\Response"
(funcall type-resolver "Response")))
(should (string= "\\Response" (funcall type-resolver "\\Response")))
(should (string= "\\App\\Controller\\GastonLagaffe"
(funcall type-resolver "GastonLagaffe")))
(should (string= "\\App\\Controller\\Dupuis\\GastonLagaffe"
(funcall type-resolver "Dupuis\\GastonLagaffe")))))
(should (phpinspect--type= (phpinspect--make-type :name "\\array")
(funcall type-resolver
(phpinspect--make-type :name "array"))))
(should (phpinspect--type= (phpinspect--make-type :name "\\array")
(funcall type-resolver
(phpinspect--make-type :name "\\array"))))
(should (phpinspect--type= (phpinspect--make-type
:name "\\Symfony\\Component\\HttpFoundation\\Response")
(funcall type-resolver (phpinspect--make-type :name "Response"))))
(should (phpinspect--type= (phpinspect--make-type :name "\\Response")
(funcall type-resolver
(phpinspect--make-type :name "\\Response"))))
(should (phpinspect--type= (phpinspect--make-type :name "\\App\\Controller\\GastonLagaffe")
(funcall type-resolver (phpinspect--make-type :name "GastonLagaffe"))))
(should (phpinspect--type= (phpinspect--make-type
:name "\\App\\Controller\\Dupuis\\GastonLagaffe")
(funcall type-resolver (phpinspect--make-type
:name "Dupuis\\GastonLagaffe"))))))
(ert-deftest phpinspect-index-static-methods ()
(let* ((class-tokens
@ -219,22 +247,28 @@
(index (phpinspect--index-tokens class-tokens))
(expected-index
`(phpinspect--root-index
(imports)
(classes
("\\Potato" phpinspect--class
(,(phpinspect--make-type :name"\\Potato" :fully-qualified t)
phpinspect--indexed-class
(class-name . ,(phpinspect--make-type :name "\\Potato" :fully-qualified t))
(imports)
(methods)
(class-name . "\\Potato")
(static-methods . (,(phpinspect--make-function
:name "staticMethod"
:scope '(:public)
:arguments '(("untyped" nil)
("things" "\\array"))
:return-type nil)))
:arguments `(("untyped" nil)
("things" ,(phpinspect--make-type :name "\\array"
:fully-qualified t)))
:return-type phpinspect--null-type)))
(static-variables)
(variables)
(constants)
(extends)
(implements)))
(functions))))
;; (pp expected-index)
;; (pp index))
(should (equal expected-index index))))
(ert-deftest phpinspect-resolve-type-from-context ()
@ -256,7 +290,7 @@ class FluffBall
if ($ball) {
if(isset($ball->fluff()->poof->upFluff->"))
(fluffer "
(fluffer (phpinspect-parse-string "
namespace Amazing;
use Vendor\\FluffLib\\Fluff;
@ -266,8 +300,8 @@ class Fluffer
public function fluff(): Fluff
{
}
}")
(vendor-fluff "
}"))
(vendor-fluff (phpinspect-parse-string "
namespace Vendor\\FluffLib;
class Fluff
{
@ -275,8 +309,8 @@ class Fluff
* @var FlufferUpper
*/
public $poof;
}")
(vendor-fluffer-upper "
}"))
(vendor-fluffer-upper (phpinspect-parse-string "
namespace Vendor\\FluffLib;
class FlufferUpper
{
@ -285,33 +319,25 @@ class FlufferUpper
{
$this->upFluff = $upFluff;
}
}")
}"))
(phpinspect-project-root-function (lambda () "phpinspect-test"))
(phpinspect-class-filepath-function
(lambda (fqn)
(pcase fqn
("\\Amazing\\Fluffer" "fluffer")
("\\Vendor\\FluffLib\\Fluff" "vendor-fluff")
("\\Vendor\\FluffLib\\FlufferUpper" "vendor-fluffer-upper")
(_ (ert-fail (format "Unexpected class FQN filepath was requested: %s" fqn))))))
(phpinspect-insert-file-contents-function
(lambda (filepath)
(pcase filepath
("fluffer" (insert fluffer))
("vendor-fluff" (insert vendor-fluff))
("vendor-fluffer-upper" (insert vendor-fluffer-upper))
(_ (ert-fail (format "Unexpected filepath was requested: %s" filepath))))))
(context (phpinspect--get-resolvecontext token-tree)))
(phpinspect-purge-cache)
(phpinspect-cache-project-class
(phpinspect-project-root)
(cdar (alist-get 'classes (cdr (phpinspect--index-tokens token-tree)))))
(should (equal "\\Vendor\\FluffLib\\DoubleFluffer"
(phpinspect-resolve-type-from-context
context
(phpinspect--make-type-resolver-for-resolvecontext
context))))))
(setf (phpinspect--resolvecontext-project-root context)
"phpinspect-test")
(phpinspect-purge-cache)
(dolist (tree (list token-tree fluffer vendor-fluff vendor-fluffer-upper))
(phpinspect-cache-project-class
"phpinspect-test"
(cdar (alist-get 'classes (cdr (phpinspect--index-tokens tree))))))
(should (phpinspect--type=
(phpinspect--make-type :name "\\Vendor\\FluffLib\\DoubleFluffer")
(phpinspect-resolve-type-from-context
context
(phpinspect--make-type-resolver-for-resolvecontext
context))))))
(ert-deftest phpinspect-eldoc-function-for-object-method ()
(let* ((php-code "
@ -330,6 +356,7 @@ class Thing
(phpinspect-project-root-function (lambda () "phpinspect-test"))
(phpinspect-eldoc-word-width 100))
(phpinspect-purge-cache)
(phpinspect--ensure-index-thread)
(phpinspect-cache-project-class
(phpinspect-project-root)
(cdar (alist-get 'classes (cdr index))))
@ -356,6 +383,7 @@ class Thing
(phpinspect-project-root-function (lambda () "phpinspect-test"))
(phpinspect-eldoc-word-width 100))
(phpinspect-purge-cache)
(phpinspect--ensure-index-thread)
(phpinspect-cache-project-class
(phpinspect-project-root)
(cdar (alist-get 'classes (cdr index))))
@ -388,11 +416,11 @@ class Thing
(phpinspect-project-root)
(cdar (alist-get 'classes (cdr index))))
(should (string= "\\Thing"
(phpinspect-resolve-type-from-context
context
(phpinspect--make-type-resolver-for-resolvecontext
context))))))
(should (phpinspect--type= (phpinspect--make-type :name "\\Thing")
(phpinspect-resolve-type-from-context
context
(phpinspect--make-type-resolver-for-resolvecontext
context))))))
(ert-deftest phpinspect-resolve-type-from-context-static-method-with-preceding-words ()
(let* ((php-code "
@ -417,7 +445,7 @@ class Thing
(phpinspect-project-root)
(cdar (alist-get 'classes (cdr index))))
(should (string= "\\Thing"
(should (phpinspect--type= (phpinspect--make-type :name "\\Thing")
(phpinspect-resolve-type-from-context
context
(phpinspect--make-type-resolver-for-resolvecontext

@ -1,5 +1,7 @@
(require 'phpinspect)
(require 'phpinspect-index)
(require 'phpinspect-serialize)
(let ((here (file-name-directory
(or load-file-name
@ -20,5 +22,6 @@
(insert-file-contents-literally (concat here "/../fixtures/" class ".eld"))
(read (current-buffer)))))
(with-temp-buffer
(insert (prin1-to-string (phpinspect--index-tokens index-class)))
(insert (prin1-to-string (phpinspect--serialize-root-index
(phpinspect--index-tokens index-class))))
(write-file (concat here "/../fixtures/" class "-indexed.eld"))))))

Loading…
Cancel
Save