Make project indexation asynchronous using `phpinspect-pipeline'
ci/woodpecker/push/woodpecker Pipeline failed Details

WIP-cache
Hugo Thunnissen 9 months ago
parent 2fd91898a3
commit f003b6a279

@ -27,12 +27,19 @@
(require 'phpinspect-project)
(require 'phpinspect-fs)
(require 'phpinspect-util)
(require 'phpinspect-pipeline)
(cl-defstruct (phpinspect-psr0
(:constructor phpinspect-make-psr0-generated))
(prefix nil
:type string
:documentation "The namespace prefix for which the directories contain code.")
(autoloader nil
:type phpinspect-autoloader)
(own nil
:type boolean)
(fs nil
:type phpinspect-fs)
(directories nil
:type list
:documentation
@ -43,17 +50,17 @@
(prefix nil
:type string
:documentation "The namespace prefix for which the directories contain code.")
(autoloader nil
:type phpinspect-autoloader)
(own nil
:type boolean)
(fs nil
:type phpinspect-fs)
(directories nil
:type list
:documentation
"The directories that this autoloader finds code in."))
(cl-defstruct (phpinspect-classmap
(:constructor phpinspect-make-classmap-generated))
(directories nil
:type list
:documentation
"The directories that this autoloader finds code in."))
(cl-defstruct (phpinspect-autoloader
(:constructor phpinspect-make-autoloader))
@ -75,34 +82,29 @@
qualified names congruent with a bareword type name. Keyed by
bareword typenames."))
(defun phpinspect-make-autoload-definition-closure (project-root fs typehash)
"Create a closure that can be used to `maphash' the autoload
section of a composer-json."
(lambda (type prefixes)
(let ((strategy))
(cond
((string= "psr-0" type)
(maphash
(lambda (prefix directory-paths)
(when (stringp directory-paths) (setq directory-paths (list directory-paths)))
(setq strategy (phpinspect-make-psr0-generated :prefix prefix))
(dolist (path directory-paths)
(push (concat project-root "/" path)
(phpinspect-psr0-directories strategy))))
prefixes))
((string= "psr-4" type)
(maphash
(lambda (prefix directory-paths)
(when (stringp directory-paths) (setq directory-paths (list directory-paths)))
(setq strategy (phpinspect-make-psr4-generated :prefix prefix))
(dolist (path directory-paths)
(push (concat project-root "/" path)
(phpinspect-psr4-directories strategy))))
prefixes))
(t (phpinspect--log "Unsupported autoload strategy \"%s\" encountered" type)))
(when strategy
(phpinspect-al-strategy-fill-typehash strategy fs typehash)))))
;; (define-inline phpinspect-directory-lister (dirs &optional fs)
;; (inline-letevals (dirs fs)
;; (inline-quote
;; (let* ((directory (pop ,dirs))
;; (files
;; (phpinspect-fs-directory-files ,fs directory))
;; listing)
;; (dolist (file files)
;; (if (phpinspect-fs-file-directory-p ,fs file)
;; (push file ,dirs)
;; (push file listing)))
;; listing))))
;; (phpinspect-define-pipeline-step phpinspect-directory-lister phpinspect-directory-lister)
(cl-defstruct (phpinspect-cj-iter-ctx (:constructor phpinspect-make-cj-iter-ctx))
(autoloader nil
:type phpinspect-autoloader)
(compiled-dirs nil
:type boolean)
(dirs nil
:type list))
(cl-defmethod phpinspect--read-json-file (fs file)
(with-temp-buffer
@ -110,100 +112,161 @@ section of a composer-json."
(goto-char 0)
(phpinspect-json-preset (json-read))))
(cl-defmethod phpinspect-autoloader-refresh ((autoloader phpinspect-autoloader))
"Refresh autoload definitions by reading composer.json files
from the project and vendor folders."
(let* ((project-root (phpinspect-project-root (phpinspect-autoloader-project autoloader)))
(fs (phpinspect-project-fs (phpinspect-autoloader-project autoloader)))
(vendor-dir (concat project-root "/vendor"))
(composer-json-path (concat project-root "/composer.json"))
(composer-json)
(project-autoload )
(type-name-fqn-bags (make-hash-table :test 'eq :size 3000 :rehash-size 3000))
(own-types (make-hash-table :test 'eq :size 10000 :rehash-size 10000))
(types (make-hash-table :test 'eq :size 10000 :rehash-size 10000)))
(when (phpinspect-fs-file-exists-p fs composer-json-path)
(setq composer-json (phpinspect--read-json-file fs composer-json-path))
(if (hash-table-p composer-json)
(setq project-autoload (gethash "autoload" composer-json))
(phpinspect--log "Error: Parsing %s did not return a hashmap."
composer-json-path)))
(define-inline phpinspect-filename-to-typename (dir filename &optional prefix)
(inline-quote
(phpinspect-intern-name
(replace-regexp-in-string
"[\\\\]+"
"\\\\"
(concat "\\"
(or ,prefix "")
(replace-regexp-in-string
"/" "\\\\"
(string-remove-suffix
".php"
(string-remove-prefix ,dir ,filename))))))))
(when project-autoload
(maphash (phpinspect-make-autoload-definition-closure project-root fs own-types)
project-autoload)
(maphash (phpinspect-make-autoload-definition-closure project-root fs types)
project-autoload))
(defun phpinspect-find-composer-json-files (fs project-root)
(let ((cj-path (concat project-root "/composer.json"))
(vendor-dir (concat project-root "/vendor"))
files)
(when (phpinspect-fs-file-exists-p fs cj-path)
(push `(local . ,cj-path) files))
(when (phpinspect-fs-file-directory-p fs vendor-dir)
(dolist (author-dir (phpinspect-fs-directory-files fs vendor-dir))
(when (phpinspect-fs-file-directory-p fs author-dir)
(dolist (dependency-dir (phpinspect-fs-directory-files fs author-dir))
(setq cj-path (concat dependency-dir "/composer.json"))
(when (and (phpinspect-fs-file-directory-p fs dependency-dir)
(phpinspect-fs-file-exists-p fs (concat dependency-dir "/composer.json")))
(let* ((dependency-json (phpinspect--read-json-file
fs
(concat dependency-dir "/composer.json")))
(dependency-autoload (gethash "autoload" dependency-json)))
(when dependency-autoload
(maphash (phpinspect-make-autoload-definition-closure
dependency-dir fs types)
dependency-autoload))))))))
(maphash (lambda (type-fqn _)
(let* ((type-name (phpinspect-intern-name
(car (last (split-string (symbol-name type-fqn) "\\\\")))))
(bag (gethash type-name type-name-fqn-bags)))
(push type-fqn bag)
(puthash type-name bag type-name-fqn-bags)))
types)
(setf (phpinspect-autoloader-own-types autoloader) own-types)
(setf (phpinspect-autoloader-types autoloader) types)
(setf (phpinspect-autoloader-type-name-fqn-bags autoloader)
type-name-fqn-bags)))
(phpinspect-fs-file-exists-p fs cj-path))
(push `(vendor . ,cj-path) files))))))
files))
(cl-defmethod phpinspect-al-strategy-execute ((strat phpinspect-psr4))
(let* ((fs (phpinspect-psr4-fs strat))
(al (phpinspect-psr4-autoloader strat))
(own (phpinspect-psr4-own strat))
(own-typehash (phpinspect-autoloader-own-types al))
(typehash (phpinspect-autoloader-types al))
(prefix (phpinspect-psr4-prefix strat))
type-fqn)
(dolist (dir (phpinspect-psr4-directories strat))
(dolist (file (phpinspect-fs-directory-files-recursively fs dir "\\.php$"))
(setq type-fqn (phpinspect-filename-to-typename dir file prefix))
(phpinspect-autoloader-put-type-bag al type-fqn)
(puthash type-fqn file typehash)
(when own
(puthash type-fqn file own-typehash))))))
(cl-defmethod phpinspect-al-strategy-execute ((strat phpinspect-psr0))
(let* ((fs (phpinspect-psr0-fs strat))
(al (phpinspect-psr0-autoloader strat))
(own (phpinspect-psr0-own strat))
(own-typehash (phpinspect-autoloader-own-types al))
(typehash (phpinspect-autoloader-types al))
type-fqn)
(dolist (dir (phpinspect-psr0-directories strat))
(dolist (file (phpinspect-fs-directory-files-recursively fs dir "\\.php$"))
(setq type-fqn (phpinspect-filename-to-typename dir file))
(phpinspect-autoloader-put-type-bag al type-fqn)
(puthash type-fqn file typehash)
(when own
(puthash type-fqn file own-typehash))))))
(cl-defmethod phpinspect-autoloader-put-type-bag ((al phpinspect-autoloader) (type-fqn symbol))
(let* ((type-name (phpinspect-intern-name
(car (last (split-string (symbol-name type-fqn) "\\\\")))))
(bag (gethash type-name (phpinspect-autoloader-type-name-fqn-bags al))))
(if bag
(push type-fqn bag)
(push type-fqn bag)
(puthash type-name bag (phpinspect-autoloader-type-name-fqn-bags al)))))
(phpinspect-define-pipeline-step phpinspect-al-strategy-execute phpinspect-al-strategy-execute)
(cl-defmethod phpinspect-iterate-composer-jsons
((al phpinspect-autoloader) file)
(let* ((fs (phpinspect-project-fs (phpinspect-autoloader-project al)))
(project-root (file-name-directory (cdr file)))
(json (phpinspect--read-json-file fs (cdr file)))
(autoload (gethash "autoload" json))
batch)
(when (hash-table-p autoload)
(maphash
(lambda (type prefixes)
(let ((strategy))
(pcase type
("psr-0"
(maphash
(lambda (prefix directory-paths)
(when (stringp directory-paths)
(setq directory-paths (list directory-paths)))
(setq strategy (phpinspect-make-psr0-generated
:autoloader al
:fs fs
:prefix prefix
:own (eq 'local (car file))))
(dolist (path directory-paths)
(push (file-name-concat project-root path)
(phpinspect-psr0-directories strategy))))
prefixes))
("psr-4"
(maphash
(lambda (prefix directory-paths)
(when (stringp directory-paths)
(setq directory-paths (list directory-paths)))
(setq strategy (phpinspect-make-psr4-generated
:fs fs
:autoloader al
:prefix prefix
:own (eq 'local (car file))))
(dolist (path directory-paths)
(push (file-name-concat project-root path)
(phpinspect-psr4-directories strategy))))
prefixes))
(_ (phpinspect--log "Unsupported autoload strategy \"%s\" encountered" type)))
(push strategy batch)))
autoload)
(phpinspect-pipeline-emit-all batch))))
(phpinspect-define-pipeline-step phpinspect-iterate-composer-jsons
phpinspect-iterate-composer-jsons)
(cl-defmethod phpinspect-autoloader-resolve ((autoloader phpinspect-autoloader)
typename-symbol)
(or (gethash typename-symbol (phpinspect-autoloader-own-types autoloader))
(gethash typename-symbol (phpinspect-autoloader-types autoloader))))
(cl-defmethod phpinspect-autoloader-refresh ((autoloader phpinspect-autoloader) &optional async-callback)
"Refresh autoload definitions by reading composer.json files
from the project and vendor folders."
(let* ((project-root (phpinspect-project-root (phpinspect-autoloader-project autoloader)))
(fs (phpinspect-project-fs (phpinspect-autoloader-project autoloader)))
result error)
(setf (phpinspect-autoloader-type-name-fqn-bags autoloader)
(make-hash-table :test 'eq :size 3000 :rehash-size 3000))
(setf (phpinspect-autoloader-own-types autoloader)
(make-hash-table :test 'eq :size 10000 :rehash-size 10000))
(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)))
(cl-defmethod phpinspect-autoloader-refresh
(cl-defgeneric phpinspect-al-strategy-fill-typehash (strategy fs typehash)
"Make STRATEGY return a map with type names as keys and the
paths to the files they are defined in as values.")
(defsubst phpinspect-filename-to-typename (dir filename &optional prefix)
(phpinspect-intern-name
(replace-regexp-in-string
"[\\\\]+"
"\\\\"
(concat "\\"
(or prefix "")
(replace-regexp-in-string
"/" "\\\\"
(string-remove-suffix
".php"
(string-remove-prefix dir filename)))))))
(cl-defmethod phpinspect-al-strategy-fill-typehash ((strategy phpinspect-psr0)
fs
typehash)
(dolist (dir (phpinspect-psr0-directories strategy))
(dolist (file (phpinspect-fs-directory-files-recursively fs dir "\\.php$"))
(puthash (phpinspect-filename-to-typename dir file) file typehash))))
(cl-defmethod phpinspect-al-strategy-fill-typehash ((strategy phpinspect-psr4)
fs
typehash)
(let ((prefix (phpinspect-psr4-prefix strategy)))
(dolist (dir (phpinspect-psr4-directories strategy))
(dolist (file (phpinspect-fs-directory-files-recursively fs dir "\\.php$"))
(puthash (phpinspect-filename-to-typename dir file prefix) file typehash)))))
(provide 'phpinspect-autoload)
;;; phpinspect-autoload.el ends here

@ -55,9 +55,9 @@ then returned."
:root project-root
:worker (phpinspect-make-dynamic-worker))
(phpinspect--cache-projects cache)))
(let ((autoload (phpinspect-make-autoloader :project project)))
(setf (phpinspect-project-autoload project) autoload)
(phpinspect-autoloader-refresh autoload)))
(let ((autoloader (phpinspect-make-autoloader :project project)))
(setf (phpinspect-project-autoload project) autoloader)
(phpinspect-autoloader-refresh autoloader)))
project))
(provide 'phpinspect-cache)

@ -41,9 +41,8 @@
(defalias 'phpinspect-virtual-file-modification-time #'cadr)
(defalias 'phpinspect-virtual-file-contents #'car)
(cl-defmethod phpinspect-virtual-fs-set-file ((fs phpinspect-virtual-fs)
path
contents)
(defun phpinspect-virtual-fs-set-file (fs path contents)
(declare (indent defun))
(puthash path (phpinspect-make-virtual-file contents)
(phpinspect-virtual-fs-files fs)))

@ -70,7 +70,7 @@
thread-live (thread-live-p (car thread)))
(when thread-live
(if ended
(if end
(setq errors (nconc errors (list (format "Thread %s ended pipeline, but is still running"
(thread-name (car thread))))))
(setq errors (nconc errors (list (format "Thread %s is still running when pipeline is closing"
@ -91,13 +91,19 @@
(signal 'phpinspect-pipeline-error errors))))
(defmacro phpinspect-pipeline-emit (data)
`(throw 'phpinspect-pipeline-emit ,data))
(define-inline phpinspect-pipeline-emit (data)
(inline-letevals (data)
(inline-quote
(throw 'phpinspect-pipeline-emit ,data))))
(defmacro phpinspect-pipeline-emit-all (collection)
`(throw 'phpinspect-pipeline-emit
(phpinspect-make-pipeline-emission
:collection ,collection)))
(define-inline phpinspect-pipeline-emit-all (collection)
(inline-letevals (collection)
(inline-quote
(throw 'phpinspect-pipeline-emit
(if ,collection
(phpinspect-make-pipeline-emission
:collection ,collection)
,collection)))))
(defmacro phpinspect-pipeline-end (&optional value)
(if value
@ -197,8 +203,8 @@
(end-queue-sym (gensym "end-queue"))
(ctx-sym (gensym "ctx"))
(recv-sym (gensym))
(errors (gensym))
(result-sym (gensym))
(seed-sym (gensym))
(collecting-sym (gensym)))
`(progn
(when (eq main-thread (current-thread))
@ -209,13 +215,15 @@
(,queue-sym (phpinspect-make-queue))
(,end-queue-sym (phpinspect-make-queue))
(,collecting-sym t)
,recv-sym ,result-sym)
,recv-sym ,result-sym ,seed-sym)
,(phpinspect--chain-pipeline-steps steps queue-sym end-queue-sym ctx-sym)
(phpinspect-pipeline--enqueue
,queue-sym
(phpinspect-make-pipeline-emission :collection ,seed-form) 'no-notify)
(setq ,seed-sym ,seed-form)
(when ,seed-sym
(phpinspect-pipeline--enqueue
,queue-sym
(phpinspect-make-pipeline-emission :collection ,seed-form) 'no-notify))
(phpinspect-pipeline--enqueue
,queue-sym (phpinspect-make-pipeline-end :thread (current-thread)))
@ -249,7 +257,7 @@
(lambda ()
(condition-case err
(let ((,result ,(append '(phpinspect--pipeline) (list seed-form) macro-params)))
(funcall ,async ,result nil))
(funcall ,async (or ,result 'phpinspect-pipeline-nil-result) nil))
(t (funcall ,async nil err))))
"phpinspect-pipeline-async")
,(append '(phpinspect--pipeline) (list seed-form) macro-params)))))
@ -257,11 +265,11 @@
(define-inline phpinspect-pipeline-receive (queue)
(inline-letevals (queue)
`(or (phpinspect-queue-dequeue ,queue)
(let ((mx (make-mutex)))
(with-mutex mx
(condition-wait (make-condition-variable mx "phpinspect-pipeline-receive")))
(phpinspect-queue-dequeue ,queue)))))
(inline-quote
(let ((val))
(while (not (setq val (phpinspect-queue-dequeue ,queue)))
(thread-yield))
val))))
(defun phpinspect-pipeline-step-name (name &optional suffix)
(intern (concat (symbol-name name) (if suffix (concat "-" suffix) ""))))
@ -275,17 +283,16 @@
(define-inline phpinspect-pipeline--enqueue (queue emission &optional no-notify)
(inline-letevals (queue emission no-notify)
(inline-quote
(if (and (phpinspect-pipeline-emission-p ,emission)
(phpinspect-pipeline-emission-collection ,emission))
(progn
(while (cdr (phpinspect-pipeline-emission-collection ,emission))
(when ,emission
(if (phpinspect-pipeline-emission-p ,emission)
(when (phpinspect-pipeline-emission-collection ,emission)
(while (cdr (phpinspect-pipeline-emission-collection ,emission))
(phpinspect-queue-enqueue
,queue (pop (phpinspect-pipeline-emission-collection ,emission))
,no-notify))
(phpinspect-queue-enqueue
,queue (pop (phpinspect-pipeline-emission-collection ,emission))
,no-notify))
(phpinspect-queue-enqueue
,queue (pop (phpinspect-pipeline-emission-collection ,emission)) ,no-notify))
(phpinspect-queue-enqueue ,queue ,emission ,no-notify)))))
,queue (pop (phpinspect-pipeline-emission-collection ,emission)) ,no-notify))
(phpinspect-queue-enqueue ,queue ,emission ,no-notify))))))
(defmacro phpinspect-define-pipeline-step (name function-name)
(unless (symbolp name)
@ -320,7 +327,6 @@
(out-queue (gensym "queue"))
(context-sym (gensym "context"))
(continue-running (gensym "continue-running"))
(original-thread (gensym "original-thread"))
(pctx-sym (gensym "pipeline-ctx"))
(incoming-end (gensym "incoming-end"))
(end (gensym "end")))
@ -330,8 +336,7 @@
(setq statement (nconc statement (list context-sym))))
(inline-quote
(let ((,original-thread (current-thread))
(,inc-queue ,queue)
(let ((,inc-queue ,queue)
(,out-queue ,consumer-queue)
(,context-sym ,context)
(,pctx-sym ,pipeline-ctx))
@ -345,33 +350,29 @@
(condition-case err
(progn
(phpinspect-pipeline-pause)
(catch 'phpinspect-pipeline-break
(while ,continue-running
(setq ,incoming (phpinspect-pipeline-receive ,inc-queue))
(if (phpinspect-pipeline-end-p ,incoming)
(setq ,incoming (phpinspect-pipeline-receive ,inc-queue))
(if (phpinspect-pipeline-end-p ,incoming)
(progn
(setq ,incoming-end ,incoming)
(when (phpinspect-pipeline-end-value ,incoming)
(progn
(setq ,incoming-end ,incoming)
(when (phpinspect-pipeline-end-value ,incoming)
(progn
(setq ,incoming (phpinspect-pipeline-end-value ,incoming)
,outgoing ,statement)
(phpinspect-pipeline--enqueue ,out-queue ,outgoing 'no-notify)))
(setq ,end (phpinspect-make-pipeline-end :thread (current-thread)))
(phpinspect-pipeline-ctx-register-end ,pctx-sym ,end)
(setq ,continue-running nil)
(phpinspect-pipeline--enqueue ,out-queue ,end))
;; Else
(setq ,outgoing ,statement)
(when (phpinspect-pipeline-end-p ,outgoing)
(setq ,end (phpinspect-make-pipeline-end :thread (current-thread)))
(phpinspect-pipeline-ctx-register-end ,pctx-sym ,end)
(setq ,continue-running nil))
(phpinspect-pipeline--enqueue ,out-queue ,outgoing))
(when ,end
(throw 'phpinspect-pipeline-break nil)))))
(setq ,incoming (phpinspect-pipeline-end-value ,incoming)
,outgoing ,statement)
(phpinspect-pipeline--enqueue ,out-queue ,outgoing 'no-notify)))
(setq ,end (phpinspect-make-pipeline-end :thread (current-thread)))
(phpinspect-pipeline-ctx-register-end ,pctx-sym ,end)
(setq ,continue-running nil)
(phpinspect-pipeline--enqueue ,out-queue ,end))
;; Else
(setq ,outgoing ,statement)
(when (phpinspect-pipeline-end-p ,outgoing)
(setq ,end (phpinspect-make-pipeline-end :thread (current-thread)))
(phpinspect-pipeline-ctx-register-end ,pctx-sym ,end)
(setq ,continue-running nil))
(phpinspect-pipeline--enqueue ,out-queue ,outgoing)))
(phpinspect-pipeline-incoming)
(t (phpinspect--log "Pipeline thread errored: %s" err)
(setq ,end (phpinspect-make-pipeline-end :thread (current-thread) :error err))

@ -352,11 +352,15 @@ before the search is executed."
(phpinspect--get-or-create-global-cache)
(phpinspect-current-project-root)))
(autoloader (phpinspect-project-autoload project)))
(phpinspect-autoloader-refresh autoloader)
(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)))))
;; Update display so that it is clear to the user that emacs is
;; responsive. Otherwise the autoloader refresh thread hogging the cpu will
;; make it look like emacs is not responsive, especially when M-x uses some
;; kind of completion framework, in which case the completion popup will
;; appear frozen while the thread is executing.
(redisplay)
(phpinspect-autoloader-refresh autoloader)))
(provide 'phpinspect)
;;; phpinspect.el ends here

@ -28,91 +28,73 @@
(require 'phpinspect-fs)
(require 'phpinspect-autoload)
(ert-deftest phpinspect-psr0-fill-typehash ()
(ert-deftest phpinspect-find-composer-json-files ()
(let* ((fs (phpinspect-make-virtual-fs))
(typehash (make-hash-table :size 10 :test 'eq))
(autoload
(phpinspect-make-psr0-generated :prefix "App\\")))
(phpinspect-virtual-fs-set-file
fs "/home/user/projects/app/src/App/Services/SuperService.php" "")
(phpinspect-virtual-fs-set-file
fs "/home/user/projects/app/src/Kernel.php" "")
(phpinspect-virtual-fs-set-file
fs "/home/user/projects/app/src/App/Controller/Banana.php" "")
(phpinspect-virtual-fs-set-file
fs "/home/user/projects/app/lib/Mailer_Lib.php" "")
(autoloader (phpinspect-make-autoloader
:project (phpinspect--make-project :root "/root" :fs fs))))
(phpinspect-virtual-fs-set-file fs
"/root/composer.json"
"{ \"autoload\": { \"psr-4\": {\"WoW\\\\Dwarves\\\\\": \"src/\"}}}")
(setf (phpinspect-psr0-directories autoload) (list "/home/user/projects/app/src/"
"/home/user/projects/app/lib/"))
(phpinspect-virtual-fs-set-file fs
"/root/vendor/runescape/client/composer.json"
"{\"autoload\": { \"psr-0\": {\"Runescape\\\\Banana\\\\\": [\"src/\", \"lib\"]}}}")
(phpinspect-al-strategy-fill-typehash autoload fs typehash)
(should-not (hash-table-empty-p typehash))
(phpinspect-virtual-fs-set-file fs
"/root/vendor/apples/pears/composer.json"
"{\"autoload\": { \"psr-0\": {\"Runescape\\\\Banana\\\\\": [\"src/\", \"lib\"]}}}")
(should (string= "/home/user/projects/app/src/App/Services/SuperService.php"
(gethash (phpinspect-intern-name "\\App\\Services\\SuperService")
typehash)))
(should (string= "/home/user/projects/app/src/Kernel.php"
(gethash (phpinspect-intern-name "\\Kernel")
typehash)))
(should (string= "/home/user/projects/app/src/App/Controller/Banana.php"
(gethash (phpinspect-intern-name "\\App\\Controller\\Banana")
typehash)))
(let ((sorter (lambda (file1 file2) (string-lessp (cdr file1) (cdr file2)))))
(should (string= "/home/user/projects/app/lib/Mailer_Lib.php"
(gethash (phpinspect-intern-name "\\Mailer_Lib")
typehash)))))
(should (equal (sort '((vendor . "/root/vendor/apples/pears/composer.json")
(vendor . "/root/vendor/runescape/client/composer.json")
(local . "/root/composer.json"))
sorter)
(sort (phpinspect-find-composer-json-files fs "/root")
sorter))))))
(ert-deftest phpinspect-psr4-fill-typehash ()
(ert-deftest phpinspect-autoload-composer-json-iterator ()
(let* ((fs (phpinspect-make-virtual-fs))
(typehash (make-hash-table :size 10 :test 'eq))
(autoload
(phpinspect-make-psr4-generated :prefix "App\\")))
(phpinspect-virtual-fs-set-file
fs "/home/user/projects/app/src/Services/SuperService.php" "")
(autoloader (phpinspect-make-autoloader
:project (phpinspect--make-project :root "/root" :fs fs)))
result error)
(phpinspect-virtual-fs-set-file
fs "/home/user/projects/app/src/Kernel.php" "")
(phpinspect-virtual-fs-set-file fs
"/root/composer.json"
"{ \"autoload\": { \"psr-4\": {\"WoW\\\\Dwarves\\\\\": \"src/\"}}}")
(phpinspect-virtual-fs-set-file
fs "/home/user/projects/app/src/Controller/Banana.php" "")
(phpinspect-virtual-fs-set-file fs
"/root/vendor/runescape/client/composer.json"
"{\"autoload\": { \"psr-0\": {\"Runescape\\\\Banana\\\\\": [\"src/\", \"lib\"]}}}")
(phpinspect-virtual-fs-set-file
fs "/home/user/projects/app/lib/Mailer_Lib.php" "")
(setf (phpinspect-psr4-directories autoload) (list "/home/user/projects/app/src/"
"/home/user/projects/app/lib/"))
(phpinspect-virtual-fs-set-file fs
"/root/vendor/apples/pears/composer.json"
"{\"autoload\": { \"psr-0\": {\"Runescape\\\\Banana\\\\\": [\"src/\", \"lib\"]},
\"psr-4\": {\"Another\\\\Namespace\\\\\": [\"separate/\"]}}}")
(phpinspect-al-strategy-fill-typehash autoload fs typehash)
(phpinspect-pipeline (phpinspect-find-composer-json-files fs "/root")
:async (lambda (res err)
(setq result res
error err))
:into (phpinspect-iterate-composer-jsons :with-context autoloader))
(should-not (hash-table-empty-p typehash))
(while (not (or result error))
(thread-yield))
(should (string= "/home/user/projects/app/src/Services/SuperService.php"
(gethash (phpinspect-intern-name "\\App\\Services\\SuperService")
typehash)))
(should (string= "/home/user/projects/app/src/Kernel.php"
(gethash (phpinspect-intern-name "\\App\\Kernel")
typehash)))
(should (string= "/home/user/projects/app/src/Controller/Banana.php"
(gethash (phpinspect-intern-name "\\App\\Controller\\Banana")
typehash)))
(should-not error)
(should (string= "/home/user/projects/app/lib/Mailer_Lib.php"
(gethash (phpinspect-intern-name "\\App\\Mailer_Lib")
typehash)))))
(should (= 4 (length result)))
(should (= 2 (length (seq-filter #'phpinspect-psr0-p result))))
(should (= 2 (length (seq-filter #'phpinspect-psr4-p result))))))
(ert-deftest phpinspect-autoloader-refresh ()
(ert-deftest phpinspect-al-strategy-execute ()
(let* ((fs (phpinspect-make-virtual-fs))
(project (phpinspect--make-project
:fs fs
:root "/project/root"))
(autoloader (phpinspect-make-autoloader
:project project)))
:project (phpinspect--make-project :root "/project/root" :fs fs)))
result error)
(phpinspect-virtual-fs-set-file
fs
"/project/root/composer.json"
@ -144,7 +126,17 @@
(phpinspect-virtual-fs-set-file
fs "/project/root/vendor/not-runescape/wow/src/TestClass.php" "")
(phpinspect-autoloader-refresh autoloader)
(phpinspect-pipeline (phpinspect-find-composer-json-files fs "/project/root")
:async (lambda (res err)
(setq result res
error err))
:into (phpinspect-iterate-composer-jsons :with-context autoloader)
:into phpinspect-al-strategy-execute)
(while (not (or result error))
(thread-yield))
(should-not error)
(should-not (hash-table-empty-p (phpinspect-autoloader-own-types autoloader)))
(should-not (hash-table-empty-p (phpinspect-autoloader-types autoloader)))
@ -152,4 +144,8 @@
(should (string= "/project/root/vendor/runescape/client/src/Runescape/Banana/App.php"
(phpinspect-autoloader-resolve
autoloader
(phpinspect-intern-name "\\Runescape\\Banana\\App"))))))
(phpinspect-intern-name "\\Runescape\\Banana\\App"))))
(should (string= "/project/root/vendor/not-runescape/wow/src/TestClass.php"
(phpinspect-autoloader-resolve
autoloader
(phpinspect-intern-name "\\WoW\\Dwarves\\TestClass"))))))

Loading…
Cancel
Save