Make functions that access the filesystem configurable and add test

Add test for `phpinspect-resolve-type-from-context'
WIP
Hugo Thunnissen 3 years ago
parent a6bb09b2b3
commit f5fe299c01

@ -46,6 +46,15 @@
"In-memory nested key-value store used for caching by
phpinspect")
(defvar phpinspect-insert-file-contents-function #'insert-file-contents-literally
"Function that phpinspect uses to insert file contents into a buffer.")
(defvar phpinspect-project-root-function #'phpinspect--find-project-root
"Function that phpinspect uses to find the root directory of a project.")
(defvar phpinspect-class-filepath-function #'phpinspect-get-class-filepath
"Function that phpinspect uses to find the filepath of a class by its FQN.")
(defvar phpinspect-project-root-file-list
'("composer.json" "composer.lock" ".git" ".svn" ".hg")
"List of files that could indicate a project root directory.")
@ -963,7 +972,7 @@ statement of the innermost incomplete token as subject
accompanied by all of its enclosing tokens."
(unless resolvecontext
(setq resolvecontext (phpinspect--make-resolvecontext
:project-root (phpinspect--get-project-root))))
:project-root (phpinspect-project-root))))
(let ((last-token (car (last token)))
(last-encountered-token (car
@ -1109,7 +1118,7 @@ accompanied by all of its enclosing tokens."
(defun phpinspect-parse-file (file)
(with-temp-buffer
(insert-file-contents-literally file)
(phpinspect-insert-file-contents file)
(phpinspect-parse-current-buffer)))
(defun phpinspect-parse-current-buffer ()
@ -1117,6 +1126,11 @@ accompanied by all of its enclosing tokens."
(current-buffer)
(point-max)))
(defun phpinspect-parse-string (string)
(with-temp-buffer
(insert string)
(phpinspect-parse-current-buffer)))
(defun phpinspect--split-list (predicate list)
(seq-reduce (let ((current-sublist))
(lambda (result elt)
@ -1785,7 +1799,7 @@ namespace if not provided"
(defun phpinspect--get-or-create-index-for-class-file (class-fqn)
(phpinspect--log "Getting or creating index for %s" class-fqn)
(phpinspect-get-or-create-cached-project-class
(phpinspect--get-project-root)
(phpinspect-project-root)
class-fqn))
(defun phpinspect-index-file (file-name)
@ -1799,7 +1813,7 @@ namespace if not provided"
(or
existing-index
(progn
(let* ((class-file (phpinspect-get-class-filepath class-fqn))
(let* ((class-file (phpinspect-class-filepath class-fqn))
(visited-buffer (when class-file (find-buffer-visiting class-file)))
(new-index))
@ -1889,7 +1903,7 @@ users will have to use \\[phpinspect-purge-cache]."
(setq phpinspect--buffer-index (phpinspect--index-current-buffer))
(dolist (class (alist-get 'classes phpinspect--buffer-index))
(when class
(phpinspect-cache-project-class (phpinspect--get-project-root)
(phpinspect-cache-project-class (phpinspect-project-root)
(cdr class))))))
(defun phpinspect--disable-mode ()
@ -2340,7 +2354,7 @@ hierarchy as long as no matching files are found. See also
phpinspect-project-root-file-list)
dominating-file))
(defun phpinspect--get-project-root (&optional start-file)
(defun phpinspect--find-project-root (&optional start-file)
"(Attempt to) Find the root directory of the visited PHP project.
If a found project root has a parent directory called \"vendor\",
the search continues upwards. See also
@ -2363,14 +2377,18 @@ level of START-FILE in stead of `default-directory`."
"/")))
(when (not (or (string= parent-without-vendor "/")
(string= parent-without-vendor "")))
(phpinspect--get-project-root parent-without-vendor))))))))
(phpinspect--find-project-root parent-without-vendor))))))))
(defsubst phpinspect-project-root (&rest args)
"Call `phpinspect-project-root-function' with ARGS as arguments."
(apply phpinspect-project-root-function args))
;; Use statements
;;;###autoload
(defun phpinspect-fix-uses-interactive ()
"Add missing use statements to the currently visited PHP file."
(interactive)
(let ((project-root (phpinspect--get-project-root)))
(let ((project-root (phpinspect-project-root)))
(when project-root
(save-buffer)
(let* ((phpinspect-json (shell-command-to-string
@ -2417,12 +2435,16 @@ level of START-FILE in stead of `default-directory`."
(forward-line -1)
(phpinspect-goto-first-line-no-comment-up)))
(defsubst phpinspect-insert-file-contents (&rest args)
"Call `phpinspect-insert-file-contents-function' with ARGS as arguments."
(apply phpinspect-insert-file-contents-function args))
(defun phpinspect-get-all-fqns (&optional fqn-file)
(unless fqn-file
(setq fqn-file "uses"))
(with-temp-buffer
(insert-file-contents-literally
(concat (phpinspect--get-project-root) "/.cache/phpinspect/" fqn-file))
(phpinspect-insert-file-contents
(concat (phpinspect-project-root) "/.cache/phpinspect/" fqn-file))
(split-string (buffer-string) (char-to-string ?\n))))
;;;###autoload
@ -2434,7 +2456,7 @@ available FQNs in a project. This may require
`phpinspect-index-current-project' to have run once for the
project directory before it can be used."
(interactive (list (completing-read "Class: " (phpinspect-get-all-fqns))))
(find-file (phpinspect-get-class-filepath fqn)))
(find-file (phpinspect-class-filepath fqn)))
(defun phpinspect-find-own-class-file (fqn)
"`phpinspect-find-class-file', but for non-vendored classes.
@ -2443,8 +2465,11 @@ When called interactively, presents the user with a list of
available FQNs for classes in the current project, which aren't
located in \"vendor\" folder."
(interactive (list (completing-read "Class: " (phpinspect-get-all-fqns "uses_own"))))
(find-file (phpinspect-get-class-filepath fqn)))
(find-file (phpinspect-class-filepath fqn)))
(defsubst phpinspect-class-filepath (fqn)
"Call `phpinspect-class-filepath-function' with FQN as argument."
(funcall phpinspect-class-filepath-function fqn))
(defun phpinspect-get-class-filepath (class &optional index-new)
"Retrieve filepath to CLASS definition file.
@ -2454,7 +2479,7 @@ before the search is executed."
(when (eq index-new 'index-new)
(with-temp-buffer
(call-process phpinspect-index-executable nil (current-buffer) nil "index" "--new")))
(let* ((default-directory (phpinspect--get-project-root))
(let* ((default-directory (phpinspect-project-root))
(result (with-temp-buffer
(phpinspect--log "dir: %s" default-directory)
(phpinspect--log "class: %s" (string-remove-prefix "\\" class))
@ -2489,7 +2514,7 @@ before the search is executed."
Index is stored in files in the .cache directory of
the project root."
(interactive)
(let* ((default-directory (phpinspect--get-project-root)))
(let* ((default-directory (phpinspect-project-root)))
(with-current-buffer (get-buffer-create "**phpinspect-index**")
(goto-char (point-max))
(make-process

@ -237,6 +237,81 @@
(functions))))
(should (equal expected-index index))))
(ert-deftest phpinspect-resolve-type-from-context ()
(let* ((token-tree (phpinspect-parse-string "
namespace Amazing;
class FluffBall
{
private $fluffer;
public function __construct(Fluffer $fluffer)
{
$this->fluffer = $fluffer;
}
public function beFluffy(): void
{
$ball = $this->fluffer;
if ($ball) {
if(isset($ball->fluff()->poof->upFluff->"))
(fluffer "
namespace Amazing;
use Vendor\\FluffLib\\Fluff;
class Fluffer
{
public function fluff(): Fluff
{
}
}")
(vendor-fluff "
namespace Vendor\\FluffLib;
class Fluff
{
/**
* @var FlufferUpper
*/
public $poof;
}")
(vendor-fluffer-upper "
namespace Vendor\\FluffLib;
class FlufferUpper
{
public $upFluff;
public function __construct(DoubleFluffer $upFluff)
{
$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))))))
(provide 'phpinspect-test)
;;; phpinspect-test.el ends here

Loading…
Cancel
Save