diff --git a/phpinspect-autoload.el b/phpinspect-autoload.el index 6ea4c47..307b000 100644 --- a/phpinspect-autoload.el +++ b/phpinspect-autoload.el @@ -70,6 +70,8 @@ (cl-defstruct (phpinspect-autoloader (:constructor phpinspect-make-autoloader)) + (refresh-thread nil + :type thread) (project nil :type phpinspect-project :documentation "The project that this autoloader can find files for") @@ -229,7 +231,18 @@ bareword typenames.")) (cl-defmethod phpinspect-autoloader-resolve ((autoloader phpinspect-autoloader) - typename-symbol) + typename-symbol) + ;; Wait for pending refresh if not running in main thread. + (unless (eq main-thread (current-thread)) + (when (and (phpinspect-autoloader-refresh-thread autoloader) + (thread-live-p (phpinspect-autoloader-refresh-thread autoloader))) + (phpinspect--log + "Pausing thread %s to await autoload refresh completion" + (thread-name (current-thread))) + (thread-join (phpinspect-autoloader-refresh-thread autoloader)) + (phpinspect--log "Autoload refresh completed, continuing waiting thread %s" + (thread-name (current-thread))))) + (or (gethash typename-symbol (phpinspect-autoloader-own-types autoloader)) (gethash typename-symbol (phpinspect-autoloader-types autoloader)))) @@ -252,18 +265,19 @@ bareword typenames.")) (setf (phpinspect-autoloader-types autoloader) (make-hash-table :test 'eq :size 10000 :rehash-size 10000)) - (phpinspect-pipeline (phpinspect-find-composer-json-files fs project-root) - :async (or async-callback - (lambda (_result error) - (if error - (message "Error during autoloader refresh: %s" error) - (message - (concat "Refreshed project autoloader. Found %d types within project," - " %d types total.") - (hash-table-count (phpinspect-autoloader-own-types autoloader)) - (hash-table-count (phpinspect-autoloader-types autoloader)))))) - :into (phpinspect-iterate-composer-jsons :with-context autoloader) - :into phpinspect-al-strategy-execute))) + (setf (phpinspect-autoloader-refresh-thread autoloader) + (phpinspect-pipeline (phpinspect-find-composer-json-files fs project-root) + :async (or async-callback + (lambda (_result error) + (if error + (message "Error during autoloader refresh: %s" error) + (message + (concat "Refreshed project autoloader. Found %d types within project," + " %d types total.") + (hash-table-count (phpinspect-autoloader-own-types autoloader)) + (hash-table-count (phpinspect-autoloader-types autoloader)))))) + :into (phpinspect-iterate-composer-jsons :with-context autoloader) + :into phpinspect-al-strategy-execute)))) (provide 'phpinspect-autoload) ;;; phpinspect-autoload.el ends here diff --git a/phpinspect-buffer.el b/phpinspect-buffer.el index 357381d..ddb2004 100644 --- a/phpinspect-buffer.el +++ b/phpinspect-buffer.el @@ -43,12 +43,15 @@ emacs buffer." "Parsed token tree that resulted from last parse") (map nil :type phpinspect-bmap) + (project nil + :type phpinspect-project) (edit-tracker (phpinspect-make-edtrack) :type phpinspect-edtrack)) -(cl-defmethod phpinspect-buffer-parse ((buffer phpinspect-buffer) &optional no-interrupt) +(cl-defmethod phpinspect-buffer-parse ((buffer phpinspect-buffer) &optional no-interrupt no-index) "Parse the PHP code in the the emacs buffer that this object is linked with." + (let ((tree)) (if (or (not (phpinspect-buffer-tree buffer)) (phpinspect-edtrack-taint-pool (phpinspect-buffer-edit-tracker buffer))) (with-current-buffer (phpinspect-buffer-buffer buffer) @@ -67,10 +70,19 @@ linked with." (setf (phpinspect-buffer-tree buffer) parsed) (phpinspect-edtrack-clear (phpinspect-buffer-edit-tracker buffer)) - ;; return - parsed)))) + ;; set return value + (setq tree parsed) + + (unless (or no-index + (not (phpinspect-buffer-project buffer))) + (phpinspect-project-add-index + (phpinspect-buffer-project buffer) + (phpinspect--index-tokens tree nil (phpinspect-buffer-location-resolver buffer)) + 'index-imports)))))) ;; Else: Just return last parse result - (phpinspect-buffer-tree buffer))) + (setq tree (phpinspect-buffer-tree buffer))) + + tree)) (cl-defmethod phpinspect-buffer-reparse ((buffer phpinspect-buffer)) diff --git a/phpinspect-project.el b/phpinspect-project.el index b8797f1..8d855fe 100644 --- a/phpinspect-project.el +++ b/phpinspect-project.el @@ -154,9 +154,11 @@ indexed by the absolute paths of the files they're watching.")) (phpinspect--class-variables class))) (cl-defmethod phpinspect-project-add-index - ((project phpinspect-project) (index (head phpinspect--root-index))) + ((project phpinspect-project) (index (head phpinspect--root-index)) &optional index-imports) + (when index-imports + (phpinspect-project-enqueue-imports project (alist-get 'imports (cdr index)))) (dolist (indexed-class (alist-get 'classes (cdr index))) - (phpinspect-project-add-class project (cdr indexed-class)))) + (phpinspect-project-add-class project (cdr indexed-class) index-imports))) (cl-defmethod phpinspect-project-enqueue-imports ((project phpinspect-project) imports) @@ -166,7 +168,7 @@ indexed by the absolute paths of the files they're watching.")) (phpinspect-project-enqueue-if-not-present project (cdr import))))) (cl-defmethod phpinspect-project-add-class - ((project phpinspect-project) (indexed-class (head phpinspect--indexed-class))) + ((project phpinspect-project) (indexed-class (head phpinspect--indexed-class)) &optional index-imports) (let* ((class-name (phpinspect--type-name-symbol (alist-get 'class-name (cdr indexed-class)))) (class (gethash class-name @@ -174,6 +176,10 @@ indexed by the absolute paths of the files they're watching.")) (unless class (setq class (phpinspect--make-class-generated :project project))) + (when index-imports + (phpinspect-project-enqueue-imports + project (alist-get 'imports (cdr indexed-class)))) + (phpinspect--class-set-index class indexed-class) (puthash class-name class (phpinspect-project-class-index project)) (phpinspect-project-add-class-attribute-types-to-index-queue project class))) diff --git a/phpinspect.el b/phpinspect.el index fa7c124..fbd5cc9 100644 --- a/phpinspect.el +++ b/phpinspect.el @@ -88,7 +88,12 @@ phpinspect") (defun phpinspect--init-mode () "Initialize the phpinspect minor mode for the current buffer." - (setq phpinspect-current-buffer (phpinspect-make-buffer :buffer (current-buffer))) + (setq phpinspect-current-buffer + (phpinspect-make-buffer + :buffer (current-buffer) + :project (phpinspect--cache-get-project-create + (phpinspect--get-or-create-global-cache) + (phpinspect--find-project-root)))) (add-hook 'after-change-functions #'phpinspect-after-change-function) (make-local-variable 'company-backends) (add-to-list 'company-backends #'phpinspect-company-backend) @@ -116,24 +121,7 @@ Assuming that files are only changed from within Emacs, this keeps the cache valid. If changes are made outside of Emacs, users will have to use \\[phpinspect-purge-cache]." (when (and (boundp 'phpinspect-mode) phpinspect-mode) - (setq phpinspect--buffer-index - (phpinspect--index-tokens - (phpinspect-buffer-reparse phpinspect-current-buffer))) - (let ((imports (alist-get 'imports phpinspect--buffer-index)) - (project (phpinspect--cache-get-project-create - (phpinspect--get-or-create-global-cache) - (phpinspect-current-project-root)))) - - (dolist (class (alist-get 'classes phpinspect--buffer-index)) - (when class - (phpinspect-project-add-class project (cdr class)) - - (let ((imports (alist-get 'imports (cdr class)))) - (when imports - (phpinspect-project-enqueue-imports project imports))))) - - (when imports (phpinspect-project-enqueue-imports project imports))))) - + (phpinspect-buffer-reparse phpinspect-current-buffer))) (defun phpinspect--disable-mode () "Clean up the buffer environment for the mode to be disabled."