Fix all remaining byte compiler warnings
ci/woodpecker/push/woodpecker Pipeline failed Details

WIP-cache
Hugo Thunnissen 9 months ago
parent d86ef5756b
commit 05ca0ace20

@ -26,6 +26,7 @@
(require 'phpinspect-parser)
(require 'phpinspect-bmap)
(require 'phpinspect-edtrack)
(require 'phpinspect-index)
(defvar-local phpinspect-current-buffer nil
"An instance of `phpinspect-buffer' local to the active

@ -27,6 +27,17 @@
(require 'phpinspect-autoload)
(require 'phpinspect-worker)
(defvar phpinspect-cache nil
"An object used to store and access metadata of PHP projects.")
(defun phpinspect--get-or-create-global-cache ()
"Get `phpinspect-cache'.
If its value is nil, it is created and then returned."
(or phpinspect-cache
(setq phpinspect-cache (phpinspect--make-cache))))
(cl-defstruct (phpinspect--cache (:constructor phpinspect--make-cache))
(projects (make-hash-table :test 'equal :size 10)
:type hash-table

@ -29,6 +29,7 @@
(require 'phpinspect-index)
(require 'phpinspect-autoload)
(require 'phpinspect-buffer)
(require 'phpinspect-cache)
(defun phpinspect-insert-at-point (point data)
(save-excursion

@ -54,7 +54,8 @@
(nreverse arg-index)))
(defsubst phpinspect--should-prefer-return-annotation (type)
"When the return annotation should be preferred over typehint of TYPE, if available."
"Returns non-nil if return annotation should supersede typehint
of TYPE, if available."
(or (not type)
(phpinspect--type= type phpinspect--object-type)))
@ -349,7 +350,7 @@ Accounts for namespaces that are defined with '{}' blocks."
(cdr namespace)))
(defun phpinspect--index-classes-in-tokens
(imports tokens type-resolver-factory location-resolver &optional namespace indexed)
(imports tokens type-resolver-factory location-resolver &optional namespace)
"Index the class tokens among TOKENS.
NAMESPACE will be assumed the root namespace if not provided"
@ -386,7 +387,7 @@ NAMESPACE will be assumed the root namespace if not provided"
(phpinspect--index-classes-in-tokens
(phpinspect--uses-to-types (seq-filter #'phpinspect-use-p namespace))
namespace
type-resolver-factory location-resolver (cadadr namespace) nil))
type-resolver-factory location-resolver (cadadr namespace)))
(defun phpinspect--index-namespaces
(namespaces type-resolver-factory location-resolver &optional indexed)

@ -387,7 +387,8 @@ token is \";\", which marks the end of a statement in PHP."
(defun phpinspect-make-incremental-parser-function (name tree-type handlers &optional delimiter-predicate)
"Like `phpinspect-make-parser-function', but returned function is able to reuse an already parsed tree."
"Like `phpinspect-make-parser-function', but returned function
is able to reuse an already parsed tree."
(let ((delimiter-predicate (if (symbolp delimiter-predicate)
`(quote ,delimiter-predicate)
delimiter-predicate)))
@ -504,7 +505,8 @@ executing.")
(phpinspect-parser-delimiter-predicate parser)))))
(cl-defmethod phpinspect-parser-compile-incremental ((parser phpinspect-parser))
"Like `phpinspect-parser-compile', but for an incremental version of the parser function."
"Like `phpinspect-parser-compile', but for an incremental
version of the parser function."
(or (phpinspect-parser-incremental-func parser)
(setf (phpinspect-parser-incremental-func parser)
(phpinspect-make-incremental-parser-function

@ -36,37 +36,15 @@ serious performance hits. Enable at your own risk (:")
(defvar phpinspect-project-root-function #'phpinspect--find-project-root
"Function that phpinspect uses to find the root directory of a project.")
(defvar-local phpinspect--buffer-project nil
"The root directory of the PHP project that this buffer belongs to")
(defsubst phpinspect-current-project-root ()
"Call `phpinspect-project-root-function' with ARGS as arguments."
(unless (and (boundp 'phpinspect--buffer-project) phpinspect--buffer-project)
(set (make-local-variable 'phpinspect--buffer-project) (funcall phpinspect-project-root-function)))
phpinspect--buffer-project)
(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
`phpinspect--locate-dominating-project-file'.
If START-FILE is provided, searching starts at the directory
level of START-FILE in stead of `default-directory`."
(let ((project-file (phpinspect--locate-dominating-project-file
(or start-file default-directory))))
(phpinspect--log "Checking for project root at %s" project-file)
(when project-file
(let* ((directory (file-name-directory project-file))
(directory-slugs (split-string (expand-file-name directory) "/")))
(if (not (member "vendor" directory-slugs))
(expand-file-name directory)
;; else. Only continue if the parent directory is not "/"
(let ((parent-without-vendor
(string-join (seq-take-while (lambda (s) (not (string= s "vendor" )))
directory-slugs)
"/")))
(when (not (or (string= parent-without-vendor "/")
(string= parent-without-vendor "")))
(phpinspect--find-project-root parent-without-vendor))))))))
(cl-defstruct (phpinspect-project (:constructor phpinspect--make-project))
(class-index (make-hash-table :test 'eq :size 100 :rehash-size 40)
:type hash-table

@ -314,9 +314,10 @@ near the top of the tee."
(setq ,current (phpinspect-splayt-node-right ,current)))))))
(defmacro phpinspect-splayt-traverse-lr (place-and-splayt &rest body)
"Traverse splay tree in cadr of PLACE-AND-SPLAYT depth-first from left to right, executing BODY.
"Traverse splay tree depth-first from left to right,executing BODY.
The car of PLACE-AND-SPLAYT is assigned the value of each node."
The car of PLACE-AND-SPLAYT is assigned the value of each node.
The cadr of PLACE-AND-SPLAYT is expected to be a splay tree."
(declare (indent 1))
`(phpinspect-splayt-node-traverse-lr
(,(car place-and-splayt) (phpinspect-splayt-root-node ,(cadr place-and-splayt)))

@ -76,24 +76,12 @@
(phpinspect--class-get-method-list class))))))
(defun phpinspect--get-methods-for-class
(resolvecontext buffer-classes class &optional static)
"Extract all possible methods for a class from `buffer-classes` and the class index.
`buffer-classes` will be preferred because their data should be
more recent"
(let ((methods (phpinspect-get-cached-project-class-methods
(phpinspect--resolvecontext-project-root
resolvecontext)
class
static))
(buffer-index (alist-get class buffer-classes nil nil #'phpinspect--type=)))
(phpinspect--log "Getting methods for class (%s)" class)
(when buffer-index
(dolist (method (alist-get (if static 'static-methods 'methods)
buffer-index))
(push method methods)))
(unless methods
(phpinspect--log "Failed to find methods for class %s :(" class))
methods))
(resolvecontext class &optional static)
"Find all known cached methods for CLASS."
(or (phpinspect-get-cached-project-class-methods
(phpinspect--resolvecontext-project-root resolvecontext)
class static)
(progn (phpinspect--log "Failed to find methods for class %s :(" class) nil)))
(defun phpinspect--get-variables-for-class (class-name &optional static)
(let ((class (phpinspect-get-or-create-cached-project-class
@ -104,9 +92,9 @@ more recent"
(append (phpinspect--class-get-static-variables class) (phpinspect--class-get-constants class))
(phpinspect--class-get-variables class)))))
(defun phpinspect--make-method-lister (resolvecontext buffer-classes &optional static)
(defun phpinspect--make-method-lister (resolvecontext &optional static)
(lambda (fqn)
(phpinspect--get-methods-for-class resolvecontext buffer-classes fqn static)))
(phpinspect--get-methods-for-class resolvecontext fqn static)))
(defun phpinspect-suggest-attributes-at-point
(resolvecontext &optional static)
@ -118,13 +106,10 @@ resolved to provide completion candidates.
If STATIC is non-nil, candidates are provided for constants,
static variables and static methods."
(let* ((buffer-index phpinspect--buffer-index)
(buffer-classes (alist-get 'classes (cdr buffer-index)))
(type-resolver (phpinspect--make-type-resolver-for-resolvecontext
(let* ((type-resolver (phpinspect--make-type-resolver-for-resolvecontext
resolvecontext))
(method-lister (phpinspect--make-method-lister
resolvecontext
buffer-classes
static)))
(let ((statement-type (phpinspect-resolve-type-from-context
resolvecontext

@ -40,7 +40,8 @@
(contains nil
:type phpinspect--type
:documentation
"When the type is a collection, this attribute is set to the type that the collection is expected to contain")
"When the type is a collection, this attribute is set to the type
that the collection is expected to contain")
(fully-qualified nil
:type bool
:documentation

@ -27,6 +27,35 @@
"An obarray containing symbols for all encountered names in
PHP. Used to optimize string comparison.")
(defvar phpinspect-project-root-file-list
'("composer.json" "composer.lock" ".git" ".svn" ".hg")
"List of files that could indicate a project root directory.")
(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
`phpinspect--locate-dominating-project-file'.
If START-FILE is provided, searching starts at the directory
level of START-FILE in stead of `default-directory`."
(let ((project-file (phpinspect--locate-dominating-project-file
(or start-file default-directory))))
(phpinspect--log "Checking for project root at %s" project-file)
(when project-file
(let* ((directory (file-name-directory project-file))
(directory-slugs (split-string (expand-file-name directory) "/")))
(if (not (member "vendor" directory-slugs))
(expand-file-name directory)
;; else. Only continue if the parent directory is not "/"
(let ((parent-without-vendor
(string-join (seq-take-while (lambda (s) (not (string= s "vendor" )))
directory-slugs)
"/")))
(when (not (or (string= parent-without-vendor "/")
(string= parent-without-vendor "")))
(phpinspect--find-project-root parent-without-vendor))))))))
(defvar phpinspect--debug nil
"Enable debug logs for phpinspect by setting this variable to true")

@ -63,7 +63,7 @@ manage phpinspect's worker thread centrally in a dynamic
variable, while also making the behaviour of objects that depend
on the worker independent of dynamic variables during testing.")
(cl-defmethod phpinspect-resolve-dynamic-worker ((worker phpinspect-dynamic-worker))
(cl-defmethod phpinspect-resolve-dynamic-worker ((_worker phpinspect-dynamic-worker))
phpinspect-worker)
(defsubst phpinspect-make-dynamic-worker ()
@ -206,7 +206,7 @@ already present in the queue."
(cl-defgeneric phpinspect-task-execute (task worker)
"Execute TASK for WORKER.")
(cl-defmethod phpinspect-task= (task1 task2)
(cl-defmethod phpinspect-task= (_task1 _task2)
"Whether or not TASK1 and TASK2 are set to execute the exact same action."
nil)

@ -51,19 +51,16 @@
"The result of the last successfull parse + index action
executed by phpinspect for the current buffer")
(defvar phpinspect-cache ()
"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-type-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.")
(define-inline phpinspect-type-filepath (fqn)
"Call `phpinspect-type-filepath-function' with FQN as argument."
(inline-quote
(funcall phpinspect-type-filepath-function ,fqn)))
(defsubst phpinspect-cache-project-class (project-root indexed-class)
(when project-root
@ -93,7 +90,7 @@ phpinspect")
:buffer (current-buffer)
:project (phpinspect--cache-get-project-create
(phpinspect--get-or-create-global-cache)
(phpinspect--find-project-root))))
(phpinspect-current-project-root))))
(add-hook 'after-change-functions #'phpinspect-after-change-function)
(make-local-variable 'company-backends)
(add-to-list 'company-backends #'phpinspect-company-backend)
@ -205,20 +202,24 @@ Example configuration:
:completion-point (phpinspect--determine-completion-point)
:point (point))))
(eval-when-compile
(declare-function company-begin-backend "company.el"))
(defun phpinspect-company-backend (command &optional arg &rest _ignored)
"A company backend for PHP."
(interactive (list 'interactive))
(require 'company)
(cond
((eq command 'interactive)
(company-begin-backend 'company-phpinspect-backend))
((eq command 'prefix)
(cond ((looking-back "->[A-Za-z_0-9-]*")
(cond ((looking-back "->[A-Za-z_0-9-]*" nil)
(let ((match (match-string 0)))
(substring match 2 (length match))))
((looking-back "::[A-Za-z_0-9-]*")
((looking-back "::[A-Za-z_0-9-]*" nil)
(let ((match (match-string 0)))
(substring match 2 (length match))))
((looking-back "\\$[A-Za-z_0-9-]*")
((looking-back "\\$[A-Za-z_0-9-]*" nil)
(let ((match (match-string 0)))
(substring match 1 (length match))))))
((eq command 'post-completion)
@ -255,12 +256,6 @@ Example configuration:
(phpinspect--completion-meta
(phpinspect--completion-list-get-metadata phpinspect--last-completion-list arg)))))
(defun phpinspect--get-or-create-global-cache ()
"Get `phpinspect-cache'.
If its value is nil, it is created and then returned."
(or phpinspect-cache
(setq phpinspect-cache (phpinspect--make-cache))))
(defun phpinspect-purge-cache ()
"Assign a fresh, empty cache object to `phpinspect-cache'.
This effectively purges any cached code information from all
@ -319,10 +314,6 @@ located in \"vendor\" folder."
(completing-read "Class: " (phpinspect-get-all-fqns 'own)))))
(find-file (phpinspect-type-filepath fqn)))
(defsubst phpinspect-type-filepath (fqn)
"Call `phpinspect-type-filepath-function' with FQN as argument."
(funcall phpinspect-type-filepath-function fqn))
(defun phpinspect-get-class-filepath (class &optional index-new)
"Retrieve filepath to CLASS definition file.

Loading…
Cancel
Save