branch: externals/phpinspect commit 459e03855993b76651d427ef527d165e3de5a16d Author: Hugo Thunnissen <de...@hugot.nl> Commit: Hugo Thunnissen <de...@hugot.nl>
WIP shadow buffer --- benchmarks/parse-file.el | 182 +++++++++++++------------- phpinspect-bmap.el | 20 +-- phpinspect-buffer.el | 284 ++++++++++++++++++++++++++++++++++++----- phpinspect-change.el | 178 ++++++++++++++++++++++++++ phpinspect-completion.el | 16 +-- phpinspect-diagnose.el | 87 +++++++++++++ phpinspect-eldoc.el | 2 +- phpinspect-parse-context.el | 108 +++++++--------- phpinspect-parser.el | 57 +++++---- phpinspect-resolvecontext.el | 3 +- phpinspect-shadow.el | 212 ++++++++++++++++++++++++++++++ phpinspect-token-predicates.el | 3 + phpinspect.el | 7 +- test/test-buffer.el | 70 ++++------ test/test-changeset.el | 64 +++++----- test/test-eldoc.el | 6 +- test/test-imports.el | 81 ++++-------- test/test-parse-context.el | 40 +++--- test/test-parser.el | 144 ++++++++++----------- test/test-shadow.el | 66 ++++++++++ test/test-suggest.el | 64 +++++----- 21 files changed, 1198 insertions(+), 496 deletions(-) diff --git a/benchmarks/parse-file.el b/benchmarks/parse-file.el index d9685a16bb..27573e618f 100644 --- a/benchmarks/parse-file.el +++ b/benchmarks/parse-file.el @@ -24,128 +24,128 @@ ;;(require 'profiler) -(require 'phpinspect-parser) -(require 'phpinspect-buffer) +;; (require 'phpinspect-parser) +;; (require 'phpinspect-buffer) -(defun phpinspect-parse-current-buffer () - (phpinspect-parse-buffer-until-point - (current-buffer) - (point-max))) +;; (defun phpinspect-parse-current-buffer () +;; (phpinspect-parse-buffer-until-point +;; (current-buffer) +;; (point-max))) -(let* ((here (file-name-directory (macroexp-file-name))) - (benchmark-file (or (getenv "PHPINSPECT_BENCHMARK_FILE") - (expand-file-name "Response.php" here))) - buffer - result) +;; (let* ((here (file-name-directory (macroexp-file-name))) +;; (benchmark-file (or (getenv "PHPINSPECT_BENCHMARK_FILE") +;; (expand-file-name "Response.php" here))) +;; buffer +;; result) - (with-temp-buffer - (insert-file-contents benchmark-file) +;; (with-temp-buffer +;; (insert-file-contents benchmark-file) - (message "Incremental parse (warmup):") - (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t :bmap (phpinspect-make-bmap)) - (setq result (benchmark-run 1 (phpinspect-parse-current-buffer)))) +;; (message "Incremental parse (warmup):") +;; (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t :bmap (phpinspect-make-bmap)) +;; (setq result (benchmark-run 1 (phpinspect-parse-current-buffer)))) - (message "Elapsed time: %f (%f in %d GC's)" (car result) (caddr result) (cadr result)) +;; (message "Elapsed time: %f (%f in %d GC's)" (car result) (caddr result) (cadr result)) - (let ((bmap (phpinspect-make-bmap)) - (bmap2 (phpinspect-make-bmap))) - (message "Incremental parse:") - (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t :bmap bmap) - (setq result (benchmark-run 1 (phpinspect-parse-current-buffer)))) +;; (let ((bmap (phpinspect-make-bmap)) +;; (bmap2 (phpinspect-make-bmap))) +;; (message "Incremental parse:") +;; (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t :bmap bmap) +;; (setq result (benchmark-run 1 (phpinspect-parse-current-buffer)))) - (message "Elapsed time: %f (%f in %d GC's)" (car result) (caddr result) (cadr result)) +;; (message "Elapsed time: %f (%f in %d GC's)" (car result) (caddr result) (cadr result)) - (garbage-collect) - (message "Incremental parse (no edits):") - (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t - :bmap bmap2 - :previous-bmap bmap - :edtrack (phpinspect-make-edtrack)) - (setq result (benchmark-run 1 (phpinspect-parse-current-buffer)))) +;; (garbage-collect) +;; (message "Incremental parse (no edits):") +;; (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t +;; :bmap bmap2 +;; :previous-bmap bmap +;; :edtrack (phpinspect-make-edtrack)) +;; (setq result (benchmark-run 1 (phpinspect-parse-current-buffer)))) - (message "Elapsed time: %f (%f in %d GC's)" (car result) (caddr result) (cadr result)) - (garbage-collect) +;; (message "Elapsed time: %f (%f in %d GC's)" (car result) (caddr result) (cadr result)) +;; (garbage-collect) - (message "Incremental parse repeat (no edits):") - (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t - :bmap (phpinspect-make-bmap) - :previous-bmap bmap2 - :edtrack (phpinspect-make-edtrack)) - (setq result (benchmark-run 1 (phpinspect-parse-current-buffer)))) - (message "Elapsed time: %f (%f in %d GC's)" (car result) (caddr result) (cadr result)) +;; (message "Incremental parse repeat (no edits):") +;; (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t +;; :bmap (phpinspect-make-bmap) +;; :previous-bmap bmap2 +;; :edtrack (phpinspect-make-edtrack)) +;; (setq result (benchmark-run 1 (phpinspect-parse-current-buffer)))) +;; (message "Elapsed time: %f (%f in %d GC's)" (car result) (caddr result) (cadr result)) - (garbage-collect) +;; (garbage-collect) - (setq buffer (phpinspect-claim-buffer (current-buffer))) - (let ((edtrack (phpinspect-buffer-edit-tracker buffer)) - (bmap (phpinspect-make-bmap)) - (bmap-after (phpinspect-make-bmap))) - ;; Fresh - (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t :bmap bmap) - (phpinspect-parse-current-buffer)) +;; (setq buffer (phpinspect-claim-buffer (current-buffer))) +;; (let ((edtrack (phpinspect-buffer-edit-tracker buffer)) +;; (bmap (phpinspect-make-bmap)) +;; (bmap-after (phpinspect-make-bmap))) +;; ;; Fresh +;; (phpinspect-with-parse-context (phpinspect-make-pctx :incremental t :bmap bmap) +;; (phpinspect-parse-current-buffer)) - ;; (setq token-hits nil - ;; token-misses nil) - (message "Incremental parse after buffer edit:") - ;; Removes closing curly brace of __construct - (goto-char 9062) - (delete-char -1) +;; ;; (setq token-hits nil +;; ;; token-misses nil) +;; (message "Incremental parse after buffer edit:") +;; ;; Removes closing curly brace of __construct +;; (goto-char 9062) +;; (delete-char -1) - (garbage-collect) - ;; (profiler-start 'cpu) +;; (garbage-collect) +;; ;; (profiler-start 'cpu) - ;;(phpinspect-edtrack-register-edit edtrack 9061 9061 1) - (phpinspect-with-parse-context (phpinspect-make-pctx :bmap bmap-after :incremental t :previous-bmap bmap :edtrack edtrack) - (setq result (benchmark-run 1 (phpinspect-parse-current-buffer)))) +;; ;;(phpinspect-edtrack-register-edit edtrack 9061 9061 1) +;; (phpinspect-with-parse-context (phpinspect-make-pctx :bmap bmap-after :incremental t :previous-bmap bmap :edtrack edtrack) +;; (setq result (benchmark-run 1 (phpinspect-parse-current-buffer)))) - (message "Elapsed time: %f (%f in %d GC's)" (car result) (caddr result) (cadr result)) - (phpinspect-edtrack-clear edtrack) - (insert "{") +;; (message "Elapsed time: %f (%f in %d GC's)" (car result) (caddr result) (cadr result)) +;; (phpinspect-edtrack-clear edtrack) +;; (insert "{") - ;;(message "Hits: %s, Misses: %s" token-hits token-misses) +;; ;;(message "Hits: %s, Misses: %s" token-hits token-misses) - ;;(phpinspect-edtrack-register-edit edtrack 9061 9062 0) - ;; Mark region as edit without length deta - ;;(phpinspect-edtrack-register-edit edtrack 19552 19562 10) +;; ;;(phpinspect-edtrack-register-edit edtrack 9061 9062 0) +;; ;; Mark region as edit without length deta +;; ;;(phpinspect-edtrack-register-edit edtrack 19552 19562 10) - (garbage-collect) +;; (garbage-collect) - ;; (setq token-hits nil - ;; token-misses nil) +;; ;; (setq token-hits nil +;; ;; token-misses nil) - (message "Incremental parse after 2 more edits:") - (phpinspect-with-parse-context (phpinspect-make-pctx :bmap (phpinspect-make-bmap) - :incremental t - :previous-bmap bmap-after - :edtrack edtrack) - (setq result (benchmark-run 1 (phpinspect-parse-current-buffer)))) +;; (message "Incremental parse after 2 more edits:") +;; (phpinspect-with-parse-context (phpinspect-make-pctx :bmap (phpinspect-make-bmap) +;; :incremental t +;; :previous-bmap bmap-after +;; :edtrack edtrack) +;; (setq result (benchmark-run 1 (phpinspect-parse-current-buffer)))) - (message "Elapsed time: %f (%f in %d GC's)" (car result) (caddr result) (cadr result)) - ;;(message "Hits: %s, Misses: %s" token-hits token-misses) +;; (message "Elapsed time: %f (%f in %d GC's)" (car result) (caddr result) (cadr result)) +;; ;;(message "Hits: %s, Misses: %s" token-hits token-misses) - ;; (save-current-buffer - ;; (profiler-stop) - ;; (profiler-report) - ;; (profiler-report-write-profile (expand-file-name "profile.txt" here))) +;; ;; (save-current-buffer +;; ;; (profiler-stop) +;; ;; (profiler-report) +;; ;; (profiler-report-write-profile (expand-file-name "profile.txt" here))) - ))) +;; ))) - (with-temp-buffer - (insert-file-contents benchmark-file) +;; (with-temp-buffer +;; (insert-file-contents benchmark-file) - (garbage-collect) - (message "Bare (no token reuse) parse (warmup):") - (setq result (benchmark-run 1 (phpinspect-parse-current-buffer))) +;; (garbage-collect) +;; (message "Bare (no token reuse) parse (warmup):") +;; (setq result (benchmark-run 1 (phpinspect-parse-current-buffer))) - (message "Elapsed time: %f (%f in %d GC's)" (car result) (caddr result) (cadr result)) +;; (message "Elapsed time: %f (%f in %d GC's)" (car result) (caddr result) (cadr result)) - (garbage-collect) - (message "Bare (no token reuse) parse:") - (setq result (benchmark-run 1 (phpinspect-parse-current-buffer)))) +;; (garbage-collect) +;; (message "Bare (no token reuse) parse:") +;; (setq result (benchmark-run 1 (phpinspect-parse-current-buffer)))) - (message "Elapsed time: %f (%f in %d GC's)" (car result) (caddr result) (cadr result))) +;; (message "Elapsed time: %f (%f in %d GC's)" (car result) (caddr result) (cadr result))) diff --git a/phpinspect-bmap.el b/phpinspect-bmap.el index de8f28a716..d29ef1058e 100644 --- a/phpinspect-bmap.el +++ b/phpinspect-bmap.el @@ -77,7 +77,6 @@ map parsed tokens to metadata about them and vice versa." (last-meta nil :type phpinspect-meta) (last-token-start nil :type integer) - (mask 0 :type integer) (recycled-p nil :type boolean :documentation "Whether bmap contains recycled tokens") @@ -146,10 +145,10 @@ object and re-used instead of instantiating a new object." (define-inline phpinspect-bmap-token-starting-after (bmap point) (inline-letevals (bmap point) (inline-quote - (when-let ((root-meta (phpinspect-bmap-root-meta ,bmap))) + (let ((root-meta (phpinspect-bmap-root-meta ,bmap))) (phpinspect-meta-find-child-after-recursively root-meta ,point))))) -(defsubst phpinspect-bmap-tokens-overlapping (bmap point) +(defun phpinspect-bmap-tokens-overlapping (bmap point) (sort (phpinspect-meta-find-overlapping-children (phpinspect-bmap-root-meta bmap) point) #'phpinspect-meta-sort-width)) @@ -171,7 +170,8 @@ compatibility with tests and for easy refactoring later on." (defun phpinspect-bmap-last-token-before-point (bmap point) "Search backward in BMAP for last token ending before POINT." - (phpinspect-meta-find-child-before-recursively (phpinspect-bmap-root-meta bmap) point)) + (let ((root-meta (phpinspect-bmap-root-meta bmap))) + (phpinspect-meta-find-child-before-recursively root-meta point))) (define-inline phpinspect-bmap-recycle (bmap token-meta pos-delta &optional whitespace-before) "Re-use TOKEN-META as a token in BMAP, applying POS-DELTA. @@ -192,13 +192,13 @@ via `phpinspect-parse-context'." (setf (phpinspect-bmap-recycled-p ,bmap) t) - (phpinspect-meta-with-changeset ,token-meta - (phpinspect-meta-detach-parent ,token-meta) - (phpinspect-meta-shift ,token-meta ,pos-delta) - (dlet ((phpinspect-meta--point-offset-base nil)) - (phpinspect-bmap-register - ,bmap start end (phpinspect-meta-token ,token-meta) ,whitespace-before ,token-meta))))))) + (phpinspect-meta-detach-parent ,token-meta) + (phpinspect-meta-shift ,token-meta ,pos-delta) + + (dlet ((phpinspect-meta--point-offset-base nil)) + (phpinspect-bmap-register + ,bmap start end (phpinspect-meta-token ,token-meta) ,whitespace-before ,token-meta)))))) (defun phpinspect-make-region (start end) (list start end)) diff --git a/phpinspect-buffer.el b/phpinspect-buffer.el index 14515285e7..f7a9d1e6b0 100644 --- a/phpinspect-buffer.el +++ b/phpinspect-buffer.el @@ -32,6 +32,7 @@ (require 'phpinspect-util) (require 'phpinspect-typedef) (require 'phpinspect-token-predicates) +(require 'phpinspect-change) (phpinspect--declare-log-group 'buffer) @@ -40,12 +41,17 @@ buffer. This variable is only set for buffers where `phpinspect-mode' is active. Also see `phpinspect-buffer'.") + (cl-defstruct (phpinspect-buffer (:constructor phpinspect-make-buffer)) "An object containing phpinspect related metadata linked to an emacs buffer." (buffer nil :type buffer :documentation "The associated emacs buffer") + (shadow nil + :type buffer) + (-changes nil + :type list) (tree nil :documentation "Parsed token tree that resulted from last parse") @@ -56,11 +62,12 @@ emacs buffer." (-deletions nil) (-additions nil) (-tokens nil) + (last-change nil :type phpinspect-change) (token-index (make-hash-table :test 'eq :size 100 :rehash-size 1.5)) (-project nil - :type phpinspect-project) - (edit-tracker (phpinspect-make-edtrack) - :type phpinspect-edtrack)) + :type phpinspect-project)) + ;; (edit-tracker (phpinspect-make-edtrack) + ;; :type phpinspect-edtrack)) (defmacro phpinspect-buffer--query-with-cache (buffer label &rest body) (declare (indent 2)) @@ -79,7 +86,7 @@ emacs buffer." (defun phpinspect-buffer-tainted-p (buffer) "Whether or not BUFFER's current tree needs updating to incorporate edits." - (and (phpinspect-edtrack-taint-pool (phpinspect-buffer-edit-tracker buffer)) t)) + (not (phpi-shadow-synced-p (phpinspect-buffer-shadow buffer)))) (defun phpinspect-buffer-needs-parse-p (buffer) "Whether or not BUFFER needs to be parsed for an updated tree to be present." @@ -150,32 +157,39 @@ edits does not count as fresh (because incremental parsing has its flaws)." (cl-defmethod phpinspect-buffer-parse ((buffer phpinspect-buffer) &optional no-interrupt) "Parse the PHP code in the the emacs buffer that this object is linked with." - (let (tree) - (if (phpinspect-buffer-needs-parse-p buffer) - (with-current-buffer (phpinspect-buffer-buffer buffer) - (let* ((map (phpinspect-make-bmap)) - (buffer-map (phpinspect-buffer-map buffer)) - (ctx (phpinspect-make-pctx - :interrupt-predicate (unless no-interrupt #'phpinspect--input-pending-p) - :bmap map - :incremental t - :previous-bmap buffer-map - :edtrack (phpinspect-buffer-edit-tracker buffer)))) - (phpinspect-with-parse-context ctx - (phpinspect--log "Parsing buffer") - (let ((parsed (phpinspect-parse-current-buffer))) - ;; Inhibit quitting to guarantee data integrity - (let ((inhibit-quit t)) - (setf (phpinspect-buffer-tree buffer) parsed) - (phpinspect-edtrack-clear (phpinspect-buffer-edit-tracker buffer)) - (phpinspect-buffer--set-map buffer map buffer-map) - - ;; set return value - (setq tree parsed)))))) - - ;; Else: Just return last parse result - (setq tree (phpinspect-buffer-tree buffer)) - tree))) + (phpi-shadow-await-synced (phpinspect-buffer-shadow buffer) (not no-interrupt)) + (unless (phpinspect-buffer-map buffer) + (phpi-shadow-enqueue-task (phpinspect-buffer-shadow buffer) 'parse-fresh) + (phpi-shadow-await-synced (phpinspect-buffer-shadow buffer) (not no-interrupt))) + + (phpinspect-buffer-tree buffer)) + +;; (let (tree) + ;; (if (phpinspect-buffer-needs-parse-p buffer) + ;; (with-current-buffer (phpinspect-buffer-buffer buffer) + ;; (let* ((map (phpinspect-make-bmap)) + ;; (buffer-map (phpinspect-buffer-map buffer)) + ;; (ctx (phpinspect-make-pctx + ;; :interrupt-predicate (unless no-interrupt #'phpinspect--input-pending-p) + ;; :bmap map + ;; :incremental t + ;; :previous-bmap buffer-map + ;; :edtrack (phpinspect-buffer-edit-tracker buffer)))) + ;; (phpinspect-with-parse-context ctx + ;; (phpinspect--log "Parsing buffer") + ;; (let ((parsed (phpinspect-parse-current-buffer))) + ;; ;; Inhibit quitting to guarantee data integrity + ;; (let ((inhibit-quit t)) + ;; (setf (phpinspect-buffer-tree buffer) parsed) + ;; (phpinspect-edtrack-clear (phpinspect-buffer-edit-tracker buffer)) + ;; (phpinspect-buffer--set-map buffer map buffer-map) + + ;; ;; set return value + ;; (setq tree parsed)))))) + + ;; ;; Else: Just return last parse result + ;; (setq tree (phpinspect-buffer-tree buffer)) + ;; tree))) (cl-defmethod phpinspect-buffer-get-index-for-token ((buffer phpinspect-buffer) token) (gethash token (phpinspect-buffer-token-index buffer))) @@ -265,12 +279,26 @@ tokens that have been deleted from a buffer." (phpinspect-buffer-token-index buffer) (make-hash-table :test 'eq :size 100 :rehash-size 1.5)) - (phpinspect-edtrack-clear (phpinspect-buffer-edit-tracker buffer))) + (phpi-shadow-enqueue-task (phpinspect-buffer-shadow buffer) 'parse-fresh)) + +(defun phpinspect-buffer-state (buffer) + (interactive (list (or phpinspect-current-buffer + (error "Not a phpinspect buffer")))) + + (let ((shadow (phpinspect-buffer-shadow buffer))) + (pop-to-buffer (generate-new-buffer "phpinspect-buffer-state")) + (insert (format (concat "Buffer name: %s\nLast Shadow Error: %s\n" + "Shadow Thread Live: %s") + (phpinspect-with-current-buffer buffer (buffer-name)) + (thread-last-error (phpi-shadow-thread shadow)) + (phpi-shadow-thread-live-p shadow))) + (read-only-mode))) (defun phpinspect-buffer-reparse (buffer) "Discard BUFFER's current token tree and re-parse fully." (interactive (list (or phpinspect-current-buffer (error "Not a phpinspect buffer")))) (phpinspect-buffer-reset buffer) + (phpi-shadow-enqueue-task (phpinspect-buffer-shadow buffer) 'parse-fresh) (phpinspect-buffer-parse buffer 'no-interrupt)) (defun phpinspect-buffer-reindex (buffer) @@ -602,7 +630,7 @@ continuing execution." (setf (phpinspect-buffer--last-indexed-bmap buffer) map))))) -(defsubst phpinspect-buffer-parse-map (buffer) +(defun phpinspect-buffer-parse-map (buffer) (phpinspect-buffer-parse buffer) (phpinspect-buffer-map buffer)) @@ -623,8 +651,14 @@ continuing execution." (setq start (- start (length (match-string 0)))) (setq pre-change-length (+ pre-change-length (length (match-string 0)))))) - (phpinspect-edtrack-register-edit - (phpinspect-buffer-edit-tracker buffer) start end pre-change-length)) + ;;(message "Registering edit: %d, %d, %d" start end pre-change-length) + (phpi-shadow-enqueue-task + (phpinspect-buffer-shadow buffer) + (phpi-change-create (phpinspect-buffer-buffer buffer) + start end pre-change-length))) + + ;; (phpinspect-edtrack-register-edit + ;; (phpinspect-buffer-edit-tracker buffer) start end pre-change-length)) (defun phpinspect-buffer-tokens-enclosing-point (buffer point) "Return token metadata objects for tokens enclosing POINT in BUFFER." @@ -650,6 +684,7 @@ use." (phpinspect-meta-end meta))))) (defun phpinspect-buffer-root-meta (buffer) + (phpi-shadow-await-synced (phpinspect-buffer-shadow buffer)) (phpinspect-bmap-root-meta (phpinspect-buffer-map buffer))) (defun phpinspect-display-buffer-tree () @@ -684,6 +719,12 @@ use." (phpinspect-get-resolvecontext (phpinspect-buffer-project buffer) (phpinspect-buffer-parse-map buffer) point)) +(defun phpinspect-buffer-kill () + (when phpinspect-current-buffer + (kill-buffer + (phpinspect-buffer-shadow + (phpinspect-buffer-shadow + phpinspect-current-buffer))))) (defun phpinspect-claim-buffer (buffer &optional project) "Setup an instance of `phpinspect-buffer' for BUFFER. @@ -697,9 +738,182 @@ BUFFER must be a normal emacs buffer. If provided, PROJECT must be an instance of `phpinspect-project'." (with-current-buffer buffer (setq-local phpinspect-current-buffer - (phpinspect-make-buffer :buffer buffer :-project project)) + (phpinspect-make-buffer :buffer buffer :-project project)) + (setf (phpinspect-buffer-shadow phpinspect-current-buffer) + (phpinspect-make-shadow phpinspect-current-buffer)) + (add-hook 'after-change-functions #'phpinspect-after-change-function nil t) + (add-hook 'kill-buffer-hook #'phpinspect-buffer-kill) phpinspect-current-buffer)) + +;;;;;;;;;; SHADOWING ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defvar phpinspect--shadow-counter 0) + +(defvar phpinspect-shadow-pause-time 0.05) + +(define-error 'phpinspect-wakeup-shadow + "This error is used to wakeup the shadow thread.") + +(cl-defstruct (phpinspect-shadow (:constructor phpinspect-make-shadow-generated) + (:conc-name phpi-shadow-)) + (synced-p t :type boolean) + (origin nil :type phpinspect-buffer) + (buffer nil :type buffer) + (queue nil :type phpinspect--queue) + (thread nil :type thread) + (id nil :type integer)) + +(defun phpi-shadow-wakeup-thread (shadow) + (thread-signal (phpi-shadow-thread shadow) 'phpinspect-wakeup-shadow nil)) + +(defun phpi-shadow-thread-check-pause () + (ignore-error phpinspect-wakeup-shadow + (if (or (phpinspect--input-pending-p) + quit-flag) + (let* ((mx (make-mutex)) + (continue (make-condition-variable mx))) + (phpinspect-thread-pause phpinspect-shadow-pause-time mx continue)) + (thread-yield)))) + +(defun phpi-shadow-make-queue-subscription (shadow) + (lambda () + (setf (phpi-shadow-synced-p shadow) nil) + (phpi-shadow-wakeup-thread shadow))) + +(defun phpi-shadow--thread-make-parser-interrupt-predicate () + (lambda () (phpi-shadow-thread-check-pause) nil)) + +(defun phpi-shadow-process-change (shadow change) + (with-current-buffer (phpi-shadow-buffer shadow) + (phpi-change-apply change (current-buffer)) + + ;;(message "parsing") + + (let* ((buffer (phpi-shadow-origin shadow)) + (pctx (phpinspect-make-pctx + :incremental t + :previous-bmap (phpinspect-buffer-map buffer) + :bmap (phpinspect-make-bmap) + :change change + :interrupt-predicate (phpi-shadow--thread-make-parser-interrupt-predicate)))) + + (let (result) + ;; Parse new content + (with-current-buffer (phpi-shadow-buffer shadow) + (phpinspect-with-parse-context pctx + (setq result (phpinspect-parse-current-buffer)))) + + (setf (phpinspect-buffer-tree buffer) result)) + + ;;(message "setting map") + (phpinspect-buffer--set-map + buffer (phpinspect-pctx-bmap pctx) (phpinspect-pctx-previous-bmap pctx))))) + +(defun phpi-shadow-parse-fresh (shadow) + (with-current-buffer (phpi-shadow-buffer shadow) + ;;(message "parsing fresh") + (let* ((buffer (phpi-shadow-origin shadow)) + (pctx (phpinspect-make-pctx + :incremental t + :bmap (phpinspect-make-bmap) + :interrupt-predicate (phpi-shadow--thread-make-parser-interrupt-predicate)))) + + (let (result) + ;; Parse new content + (with-current-buffer (phpi-shadow-buffer shadow) + (phpinspect-with-parse-context pctx + (setq result (phpinspect-parse-current-buffer)))) + + (setf (phpinspect-buffer-tree buffer) result) + + ;;(message "Result: %s" result) + + (phpinspect-buffer--set-map + buffer (phpinspect-pctx-bmap pctx) nil))))) + +(defun phpinspect-visit-shadow-buffer (buffer) + (interactive (list (or phpinspect-current-buffer + (error "Not a phpinspect buffer")))) + (pop-to-buffer (phpi-shadow-buffer (phpinspect-buffer-shadow buffer)))) + +(defun phpi-shadow-make-thread-function (shadow) + ;;(message "making thread function") + (lambda () + (let ((inhibit-quit t)) + ;;(message "Func starting") + (while t + ;;(message "shadow thread working") + (if-let ((task (phpinspect-queue-dequeue (phpi-shadow-queue shadow)))) + (progn + (pcase task + ((pred phpinspect-change-p) + (phpi-shadow-process-change shadow task)) + ('parse-fresh + (phpi-shadow-parse-fresh shadow)) + (_ + (phpinspect-message + "Shadow thread received unsupported task type: %s" + (type-of task)))) + + ;; Rest after task completion + (phpi-shadow-thread-check-pause)) + + ;; No work to do, join main thread + (setf (phpi-shadow-synced-p shadow) t) + (ignore-error 'phpinspect-wakeup-shadow + (thread-join main-thread))))))) + +(defun phpi-shadow-thread-live-p (shadow) + (thread-live-p (phpi-shadow-thread shadow))) + +(defun phpi-shadow-await-synced (shadow &optional allow-interrupt) + (cl-assert (phpi-shadow-thread-live-p shadow)) + + (while (not (phpi-shadow-synced-p shadow)) + (when (and allow-interrupt (phpinspect--input-pending-p)) + (throw 'phpinspect-interrupted nil)) + + (unless (phpi-shadow-thread-live-p shadow) + (error "Shadow thread exited: %s" + (thread-last-error (phpi-shadow-thread shadow)))) + + (sleep-for 0.005))) + +(defun phpi-shadow-make-thread (shadow) + (make-thread + (phpi-shadow-make-thread-function shadow) + (format " **phpinspect-shadow-thread**<%d>" (phpi-shadow-id shadow)))) + +(defun phpinspect-make-shadow (origin) + (cl-assert (phpinspect-buffer-p origin)) + + (let* ((id (cl-incf phpinspect--shadow-counter)) + (shadow (phpinspect-make-shadow-generated + :origin origin + :buffer (generate-new-buffer + (format " **phpinspect-shadow**<%d>" id)) + :id id))) + + ;; Copy buffer contents + (with-current-buffer (phpi-shadow-buffer shadow) + (insert (phpinspect-with-current-buffer origin (buffer-string)))) + + + + (setf (phpi-shadow-queue shadow) + (phpinspect-make-queue (phpi-shadow-make-queue-subscription shadow)) + + (phpi-shadow-thread shadow) + (phpi-shadow-make-thread shadow)) + + ;(phpi-shadow-enqueue-task shadow 'parse-fresh) + + shadow)) + +(defun phpi-shadow-enqueue-task (shadow task) + (phpinspect-queue-enqueue (phpi-shadow-queue shadow) task)) + (provide 'phpinspect-buffer) diff --git a/phpinspect-change.el b/phpinspect-change.el new file mode 100644 index 0000000000..499d0fa35d --- /dev/null +++ b/phpinspect-change.el @@ -0,0 +1,178 @@ +;;; phpinspect-change.el --- A structure that represents buffer changes -*- lexical-binding: t; -*- + +;; Copyright (C) 2024 Hugo Thunnissen + +;; Author: Hugo Thunnissen <de...@hugot.nl> +;; Keywords: languages + +;; 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-bmap) + +(cl-defstruct (phpinspect-change (:constructor phpinspect-make-change) + (:conc-name phpi-change-)) + (synced-p t :type boolean) + (start nil :type integer) + (end nil :type integer) + (prev-length nil :type integer) + (content nil :type string)) + +(defun phpi-change-apply (change buffer) + (let ((start (phpi-change-start change)) + (pre-change-length (phpi-change-prev-length change)) + (content (phpi-change-content change))) + + ;;(message "Applying change: %s" content) + + (with-current-buffer buffer + (delete-region start (+ start pre-change-length)) + (goto-char start) + (when content + (insert content))))) + +(defun phpi-change-create (buffer start end pre-change-length) + (with-current-buffer buffer + (let (content) + (when (not (= start end)) + (setq content (buffer-substring-no-properties start end))) + + (phpinspect-make-change + :start start + :end end + :prev-length pre-change-length + :content content)))) + +(defun phpi-change-prev-end (change) + (+ (phpi-change-start change) (phpi-change-prev-length change))) + +(defun phpi-change-cur-length (change) + (- (phpi-change-end change) (phpi-change-start change))) + +(defun phpi-change-delta (change) + (- (phpi-change-cur-length change) (phpi-change-prev-length change))) + +(defun phpi-calculate-point (delta prev-end point) + ;;(message "delta %s, prev-end %s, point %s" delta prev-end point) + (let ((delta-region (if (> 0 delta) + (phpinspect-make-region (+ prev-end delta) prev-end) + (phpinspect-make-region prev-end (+ prev-end delta))))) + ;;(message "Delta region: %s " delta-region) + (if (> 0 delta) + (if (> prev-end point) + (if (phpinspect-region-overlaps-point delta-region point) + (phpinspect-region-start delta-region) + point) + (if (< prev-end point) + (+ point delta) + point)) + (if (< 0 delta) + (if (< prev-end point) + (if (phpinspect-region-overlaps-point delta-region point) + (progn + (message "WTF OVERLAP") + (+ (phpinspect-region-end delta-region) + (- (phpinspect-region-end delta-region) point))) + (message "+ pooint delta") + (+ point delta)) + (message "NOPERS") + point) + (message "WAT") + point)))) + +(defun phpi-change-post-position (change point) + (phpi-calculate-point + (phpi-change-delta change) + (phpi-change-prev-end change) + point)) + ;; (if (> point (phpi-change-end change)) + ;; (if (> (- point (phpi-change-prev-end change)) + ;; (phpi-change-delta change)) + ;; (- point (phpi-change-delta change)) + ;; (phpi-change-end change)) +;; point)) + +;; (defun phpi-calculate-pre-point (delta end point) +;; (message "delta %s, prev-end %s, point %s" delta end point) +;; (let ((delta-region (if (< 0 delta) +;; (phpinspect-make-region (- end delta) end) +;; (phpinspect-make-region end (- end delta))))) +;; (message "delta region: %s" delta-region) + ;; (if (< ( delta-region) point) + ;; (- point delta) + + + ;; (if (< (phpinspect-region-end delta-region) point) + ;; (- point delta) + + + ;; (if (< 0 delta) + ;; (phpinspect-region-start delta-region) + ;; point)) + ;; point)))) + + ;; (if (> 0 delta) + ;; (if (< (phpinspect-region-end delta-region) point) + ;; (- point delta) + ;; (if (phpinspect-region-overlaps-point delta-region point) + ;; end + ;; point)) + ;; (if (< 0 delta) + ;; (if (< (phpinspect-region-end delta-region) point) + ;; (- point delta) + ;; (if (< end point) + ;; end + ;; point)) + ;; point)))) + +(defun phpi-change-pre-position (change point) +;; (message "Start %d" point) + (if (<= (phpi-change-end change) point) + (- point (phpi-change-delta change)) + (if (and (< 0 (phpi-change-delta change)) + (> (phpi-change-end change) point) + (<= (phpi-change-prev-end change) point)) + (progn ;;(message "JAAAA: %s voor %s" (phpi-change-prev-end change) point) + (phpi-change-prev-end change)) + point))) + +(defun phpi-change-overlaps-point (change point) + (and (> (phpi-change-end change) point) + (<= (phpi-change-start change) point))) + +(defun phpi-change-overlaps-pre-point (change point) + (and (> (phpi-change-prev-end change) point) + (<= (phpi-change-start change) point))) + +(defun phpi-change-tainted-token-p (change meta) + (or (phpi-change-overlaps-pre-point change (phpinspect-meta-start meta)) + (phpi-change-overlaps-pre-point change (phpinspect-meta-end meta)) + (phpinspect-meta-overlaps-point meta (phpi-change-start change)) + (phpinspect-meta-overlaps-point meta (phpi-change-prev-end change)))) + +(defun phpi-change-tainted-region-p (change start end) + (or (phpi-change-overlaps-pre-point change start) + (phpi-change-overlaps-pre-point change end) + (and (> end (phpi-change-start change)) + (<= start (phpi-change-start change))) + (and (> end (phpi-change-prev-end change)) + (<= start (phpi-change-prev-end change))))) + +(provide 'phpinspect-change) +;;; phpinspect-change.el ends here diff --git a/phpinspect-completion.el b/phpinspect-completion.el index 22e5f5c5ca..08f633edf8 100644 --- a/phpinspect-completion.el +++ b/phpinspect-completion.el @@ -285,20 +285,18 @@ Completing words in a comment for example, is usually not useful." (and last-query (eq (phpinspect-completion-query-buffer last-query) (phpinspect-completion-query-buffer query)) - (let ((taints (phpinspect-edtrack-taint-pool - (phpinspect-buffer-edit-tracker - (phpinspect-completion-query-buffer query)))) + (let ((change (phpinspect-buffer-last-change + (phpinspect-completion-query-buffer query))) (atoms-start (phpinspect-with-current-buffer (phpinspect-completion-query-buffer query) (phpinspect--find-atoms-start (phpinspect-completion-query-point query))))) - (or (length= taints 0) - (and (length= taints 1) - (<= atoms-start + (or (not change) + (and (<= atoms-start (phpinspect-completion-query-point last-query)) - (>= (phpinspect-taint-end (car taints)) + (>= (phpi-change-end change) (phpinspect-completion-query-point last-query)) (>= 1 (abs (- (phpinspect-completion-query-point query) - (phpinspect-taint-end (car taints)))))))))) + (phpi-change-end change))))))))) (cl-defstruct (phpinspect--completion-parameters (:constructor phpinspect--make-completion-parameters)) @@ -474,7 +472,7 @@ Returns list of `phpinspect--completion'." (defun phpinspect-complete-at-point () - (catch 'phpinspect-parse-interrupted + (catch 'phpinspect-interrupted (let ((comp-list (phpinspect-completion-query-execute (phpinspect--get-completion-query))) strings) (phpinspect--log "Completion list: %s" comp-list) diff --git a/phpinspect-diagnose.el b/phpinspect-diagnose.el new file mode 100644 index 0000000000..b49f80eb9a --- /dev/null +++ b/phpinspect-diagnose.el @@ -0,0 +1,87 @@ +;;; phpinspect-diagnose.el --- Diagnose problems in phpinspect's internal state -*- lexical-binding: t; -*- + +;; Copyright (C) 2024 Hugo Thunnissen + +;; Author: Hugo Thunnissen <h...@yournextconcepts.com> +;; Keywords: languages + +;; 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-buffer) +(require 'phpinspect-meta) + +;;;###autoload +(defun phpinspect-buffer-diagnose-tree (buffer) + "Diagnose problems in BUFFER's token (metadata) tree." + (interactive (list phpinspect-current-buffer)) + (cl-assert (phpinspect-buffer-p buffer)) + + (phpinspect-meta-diagnose-parent-child-relations + (phpinspect-buffer-root-meta buffer)) + + (phpinspect-message "Finished diagnosis, no problems found")) + +(defun phpinspect-meta-children-as-string-safe (meta) + (let (result) + (phpinspect-splayt-traverse-lr (child (phpinspect-meta-children meta)) + (if (eq child meta) + (push "[self]" result ) + (push (phpinspect-meta-string-safe meta) result))) + (string-join result ", "))) + +(defun phpinspect-meta-string-safe (meta &optional start) + (setq start (or start 0)) + + (dlet ((phpinspect-meta--point-offset-base start)) + (if meta + (format "[start: %d, end: %d, token (possibly incomplete): %s, children: %s]" + (phpinspect-meta-start meta) + (phpinspect-meta-end meta) + (if (phpinspect-atom-p (phpinspect-meta-token meta)) + (seq-subseq (phpinspect-meta-token meta) 0 2) + (car (phpinspect-meta-token meta))) + (phpinspect-meta-children-as-string-safe meta)) + "[nil]"))) + +(defun phpinspect-meta-diagnose-parent-child-relations (meta) + "Find problems in parent-child relations of META and descendants." + (when meta + (let ((stack (list meta))) + (while-let ((current (pop stack))) + (message "checking") + ;; A token cannot be a parent of itself. + (when (eq (phpinspect-meta-parent current) current) + (let ((message + (format "Cyclic parent-child relation detected at (current): %s" + (phpinspect-meta-string-safe current)))) + (error message))) + + (phpinspect-splayt-traverse-lr (child (phpinspect-meta-children current)) + (when (eq child current) + (let ((message + (format "Cyclic parent-child relation detected at (child): %s" + (phpinspect-meta-string-safe child)))) + (error message))) + + + (push child stack)))))) + +(provide 'phpinspect-diagnose) +;;; phpinspect-diagnose.el ends here diff --git a/phpinspect-eldoc.el b/phpinspect-eldoc.el index ee81d60434..7be4f4809b 100644 --- a/phpinspect-eldoc.el +++ b/phpinspect-eldoc.el @@ -291,7 +291,7 @@ Ignores `eldoc-argument-case` and `eldoc-echo-area-use-multiline-p`. TODO: - Respect `eldoc-echo-area-use-multiline-p` " - (catch 'phpinspect-parse-interrupted + (catch 'phpinspect-interrupted (let ((resp (phpinspect-eldoc-query-execute (phpinspect-make-eldoc-query :buffer phpinspect-current-buffer diff --git a/phpinspect-parse-context.el b/phpinspect-parse-context.el index 2683211d45..ec27eab706 100644 --- a/phpinspect-parse-context.el +++ b/phpinspect-parse-context.el @@ -55,6 +55,7 @@ This is 2ms by default.") nil :documentation "The time at which the currently active parse cycle started. This slot is for private use and does not always have a value.") + (change nil :type phpinspect-change) (interrupt-predicate nil :documentation @@ -64,20 +65,20 @@ called after each parsed token to make the final decision of interrupting the parser. If this function returns a non-nil value, the parse process is interrupted and the symbol `phpinspect-parse-interrupted' is signaled.") - (changesets - nil - :type list - :documentation - "Restore points for metadata changes executed during this -parse. Usually populated through `phpinspect-meta-with-changeset'.") - (edtrack - nil - :type phpinspect-edtrack - :documentation - "When parsing incrementally, the edit tracker is used to determine -whether a token from a previous parse (in the buffer map that is -in the `previous-bmap' slot) can be recycled or is tainted/edited -and should not be recycled.") +;; (changesets +;; nil +;; :type list +;; :documentation +;; "Restore points for metadata changes executed during this +;; parse. Usually populated through `phpinspect-meta-with-changeset'.") +;; (edtrack +;; nil +;; :type phpinspect-edtrack +;; :documentation +;; "When parsing incrementally, the edit tracker is used to determine +;; whether a token from a previous parse (in the buffer map that is +;; in the `previous-bmap' slot) can be recycled or is tainted/edited +;; and should not be recycled.") (bmap nil :type phpinspect-bmap @@ -114,19 +115,8 @@ parsing incrementally. The error signal is not intercepted and will still need to be handled by the code using this macro." (declare (indent 1)) - (let ((completed (gensym)) - (result (gensym))) - `(dlet ((phpinspect-parse-context ,ctx)) - (let ((,result) - (,completed)) - (unwind-protect - (progn - (setq phpinspect-parse-context ,ctx - ,result (progn ,@body) - ,completed t) - ,result) - (progn - (unless ,completed (phpinspect-pctx-cancel ,ctx)))))))) + `(dlet ((phpinspect-parse-context ,ctx)) + (progn ,@body))) (defmacro phpinspect-pctx-save-whitespace (pctx &rest body) (declare (indent 1)) @@ -138,27 +128,27 @@ handled by the code using this macro." ,@body) (setf (phpinspect-pctx-whitespace-before ,pctx) ,save-sym))))) -(define-inline phpinspect-pctx-register-changeset (pctx changeset) - (inline-quote - (progn - (push ,changeset (phpinspect-pctx-changesets ,pctx))))) - -(define-inline phpinspect-meta-with-changeset (meta &rest body) - "Perform mutations on META in BODY, saving changes. - -Before BODY is executed, important slots of META are stored in a -changeset object and appended to the changesets slot of the -currently active parse context. The original state of META can be -restored by calling `phpinspect-pctx-cancel'." - (declare (indent 1)) - (inline-letevals (meta) - (push 'progn body) - (inline-quote - (progn - (when phpinspect-parse-context - (phpinspect-pctx-register-changeset - phpinspect-parse-context (phpinspect-make-changeset ,meta))) - ,body)))) +;; (define-inline phpinspect-pctx-register-changeset (pctx changeset) +;; (inline-quote +;; (progn +;; (push ,changeset (phpinspect-pctx-changesets ,pctx))))) + +;; (define-inline phpinspect-meta-with-changeset (meta &rest body) +;; "Perform mutations on META in BODY, saving changes. + +;; Before BODY is executed, important slots of META are stored in a +;; changeset object and appended to the changesets slot of the +;; currently active parse context. The original state of META can be +;; restored by calling `phpinspect-pctx-cancel'." +;; (declare (indent 1)) +;; (inline-letevals (meta) +;; (push 'progn body) +;; (inline-quote +;; (progn +;; (when phpinspect-parse-context +;; (phpinspect-pctx-register-changeset +;; phpinspect-parse-context (phpinspect-make-changeset ,meta))) +;; ,body)))) (define-inline phpinspect-pctx-check-interrupt (pctx) "Signal `phpinspect-parse-interrupted' when conditions are met. @@ -180,7 +170,6 @@ metadata will be reverted in a call to `pphinspect-pctx-cancel'." (when (and (time-less-p (phpinspect-pctx-interrupt-threshold ,pctx) (time-since (phpinspect-pctx--start-time ,pctx))) (funcall (phpinspect-pctx-interrupt-predicate ,pctx))) - (phpinspect-pctx-cancel ,pctx) (throw 'phpinspect-parse-interrupted nil)))))) (define-inline phpinspect-pctx-register-whitespace (pctx whitespace) @@ -193,17 +182,16 @@ metadata will be reverted in a call to `pphinspect-pctx-cancel'." (setf (phpinspect-pctx-whitespace-before pctx) "") whitespace)) -(defun phpinspect-pctx-cancel (pctx) - "Cancel PCTX, revert all changes made during its lifetime. - -Revert all changes made to the metadata tree while parsing -incrementally. This function is usually called by -`phpinspect-pctx-check-interrupt' when interrupt conditions are -met." - (phpinspect--log "Cancelling parse context") - (dolist (changeset (phpinspect-pctx-changesets pctx)) - (phpinspect-changeset-revert changeset)) - (setf (phpinspect-pctx-changesets pctx) nil)) +;; (defun phpinspect-pctx-cancel (pctx) +;; "Cancel PCTX, revert all changes made during its lifetime. + +;; Revert all changes made to the metadata tree while parsing +;; incrementally. This function is usually called by +;; `phpinspect-pctx-check-interrupt' when interrupt conditions are +;; met." +;; (dolist (changeset (phpinspect-pctx-changesets pctx)) +;; (phpinspect-changeset-revert changeset)) +;; (setf (phpinspect-pctx-changesets pctx) nil)) (provide 'phpinspect-parse-context) ;;; phpinspect-parse-context.el ends here diff --git a/phpinspect-parser.el b/phpinspect-parser.el index 59e35c697a..cfdcdae59b 100644 --- a/phpinspect-parser.el +++ b/phpinspect-parser.el @@ -24,7 +24,7 @@ ;;; Code: (require 'cl-lib) -(require 'phpinspect-edtrack) +(require 'phpinspect-change) (require 'phpinspect-bmap) (require 'phpinspect-meta) (require 'phpinspect-parse-context) @@ -136,7 +136,7 @@ text at point and returns the resulting token." (put (quote ,inline-name) 'definition-name (quote ,name)) (put (quote ,regexp-inline-name) 'definition-name (quote ,name))))) -(defun phpinspect--recycle-token (context taint-iterator point original-point token-meta tokens-rear &optional delimiter-predicate) +(defun phpinspect--recycle-token (context change point original-point token-meta tokens-rear &optional delimiter-predicate continue-condition) "Attempt to re-use TOKEN-META and any of its eligible righthand siblings." (declare (speed 3)) ;;(message "Recycle token called at %d, %s" (point) (phpinspect-meta-token token-meta)) @@ -154,7 +154,9 @@ text at point and returns the resulting token." ;; (setq token-meta (phpinspect-meta-find-child-starting-at token-meta original-point))) (if (or (not token-meta) - (phpinspect-taint-iterator-token-is-tainted-p taint-iterator token-meta)) + (phpinspect-root-p (phpinspect-meta-token token-meta)) + (phpinspect-incomplete-token-p (phpinspect-meta-token token-meta)) + (phpi-change-tainted-token-p change token-meta)) (progn ;; If the first passed token is tainted. Return tainted symbol to ;; signal failure to parser loop. Otherwise return re-used tokens. @@ -183,20 +185,25 @@ text at point and returns the resulting token." ;; right-sibling (dlet ((phpinspect-meta--point-offset-base nil)) (if-let (((not (and delimiter-predicate (funcall delimiter-predicate token)))) + (right-sibling right-sibling) ((setq phpinspect-meta--point-offset-base (+ original-point (- (phpinspect-meta-parent-offset right-sibling) parent-offset)))) - ((not (phpinspect-taint-iterator-region-is-tainted-p - taint-iterator current-end-position (+ delta (phpinspect-meta-start right-sibling)))))) - (progn + ((not (phpi-change-tainted-region-p + change current-end-position (+ delta (phpinspect-meta-start right-sibling))))) + ((progn + (goto-char (+ delta (phpinspect-meta-start right-sibling))) + (phpinspect-pctx-register-whitespace context (phpinspect-meta-whitespace-before right-sibling)) + + (if continue-condition (funcall continue-condition) t)))) ;;(message "using sibling %s" (phpinspect-meta-string right-sibling)) ;; There was a right sibling and it is eligible for ;; re-use. Set token-meta and "recurse". (setq first-iteration nil token-meta right-sibling point (+ delta (phpinspect-meta-start right-sibling)) - original-point (phpinspect-meta-start right-sibling))) + original-point (phpinspect-meta-start right-sibling)) ;; No eligible right sibling, break. (throw 'phpinspect--return tokens-rear)))))))))) @@ -261,8 +268,7 @@ is able to reuse an already parsed tree." (tokens-rear tokens) (root-start (point)) (previous-bmap (phpinspect-pctx-previous-bmap context)) - (edtrack (phpinspect-pctx-edtrack context)) - (taint-iterator (when edtrack (phpinspect-edtrack-make-taint-iterator edtrack))) + (change (phpinspect-pctx-change context)) (check-interrupt (phpinspect-pctx-interrupt-predicate context)) ;; Loop variables @@ -291,34 +297,37 @@ is able to reuse an already parsed tree." ;;(message "Start: %d" start-position) (cond ((and-let* - ((edtrack) + ((change) (previous-bmap) (result ;; Look for an already parsted token at POINT to ;; adopt into new tree. (or (phpinspect--recycle-token context - taint-iterator + change start-position (setq original-position - (phpinspect-edtrack-original-position-at-point edtrack start-position)) + (phpi-change-pre-position change start-position)) (phpinspect-bmap-token-starting-at previous-bmap original-position) tokens-rear - ,(if delimiter-predicate `(quote ,delimiter-predicate) 'nil)) + ,(if delimiter-predicate `(quote ,delimiter-predicate) 'nil) + continue-condition) ;; There is no token at POINT exactly. Attempt ;; to find any other adoptable token after ;; POINT. - (when-let - ((token-after (phpinspect-bmap-token-starting-after previous-bmap original-position)) - (start (phpinspect-meta-start token-after)) - ((not (phpinspect-taint-iterator-region-is-tainted-p - taint-iterator original-position (+ start (phpinspect-meta-width token-after))))) - ;;(current-start (+ start-position (- start original-position)))) - (current-start (phpinspect-edtrack-current-position-at-point edtrack start))) - ;; (message "YAAS: (%d,%d) '%s'" start current-start (buffer-substring current-start (point-max))) - (phpinspect--recycle-token - context taint-iterator current-start start token-after tokens-rear - ,(if delimiter-predicate `(quote ,delimiter-predicate) 'nil))))) + ;; (when-let + ;; ((token-after (phpinspect-bmap-token-starting-after previous-bmap original-position)) + ;; (start (phpinspect-meta-start token-after)) + ;; ((not (phpi-change-tainted-region-p + ;; change original-position (+ start (phpinspect-meta-width token-after))))) + ;; ;;(current-start (+ start-position (- start original-position)))) + ;; (current-start (+ start (- original-position start-position)))) + ;; ;; (message "YAAS: (%d,%d) '%s'" start current-start (buffer-substring current-start (point-max))) + ;; (phpinspect--recycle-token + ;; context change current-start start token-after tokens-rear + ;; ,(if delimiter-predicate `(quote ,delimiter-predicate) 'nil))) + + )) ;; `phpinspect--recycle-token' will return the symbol ;; 'tainted' when the token that it tried to reuse diff --git a/phpinspect-resolvecontext.el b/phpinspect-resolvecontext.el index 22db4ac63c..fc3ade61df 100644 --- a/phpinspect-resolvecontext.el +++ b/phpinspect-resolvecontext.el @@ -46,8 +46,9 @@ (inline-quote (or (phpinspect-return-p ,token) (phpinspect-end-of-statement-p ,token) + (phpinspect-fat-arrow-p ,token) (phpinspect-string-concatenator-p ,token) - (phpinspect-use-p ,token) + (phpinspect-use-p ,token) (phpinspect-function-p ,token))))) (cl-defstruct (phpinspect--resolvecontext diff --git a/phpinspect-shadow.el b/phpinspect-shadow.el new file mode 100644 index 0000000000..dd33e1f5b5 --- /dev/null +++ b/phpinspect-shadow.el @@ -0,0 +1,212 @@ +;;; phpinspect-shadow.el --- Shadow buffers for phpinspect buffers -*- lexical-binding: t; -*- + +;; Copyright (C) 2024 Hugo Thunnissen + +;; Author: Hugo Thunnissen <de...@hugot.nl> +;; Keywords: languages + +;; 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 'cl-macs) + +;; (defvar phpinspect--shadow-counter 0) + +;; (defvar phpinspect-shadow-pause-time 0.05) + +;; (define-error 'phpinspect-wakeup-shadow +;; "This error is used to wakeup the shadow thread.") + + +;; (cl-defstruct (phpinspect-shadow (:constructor phpinspect-make-shadow-generated) +;; (:conc-name phpi-shadow-)) +;; (origin nil :type phpinspect-buffer) +;; (buffer nil :type buffer) +;; (queue nil :type phpinspect--queue) +;; (thread nil :type thread) +;; (id nil :type integer)) + +;; (defun phpi-shadow-wakeup-thread (shadow) +;; (thread-signal (phpi-shadow-thread shadow) 'phpi-wakeup-shadow nil)) + +;; (defun phpi-shadow-thread-check-pause () +;; (ignore-error phpinspect-wakeup-shadow +;; (if (or (phpinspect--input-pending-p) +;; quit-flag) +;; (let* ((mx (make-mutex)) +;; (continue (make-condition-variable mx))) +;; (phpinspect-thread-pause phpinspect-shadow-pause-time mx continue)) +;; (thread-yield)))) + +;; (defun phpi-shadow-make-queue-subscription (shadow) +;; (lambda () +;; (setf (phpi-shadow-synced-p shadow) nil) +;; (phpi-shadow-wakeup-thread shadow))) + +;; (defun phpi-shadow--thread-make-parser-interrupt-predicate () +;; (lambda () (phpi-shadow-thread-check-pause) nil)) + +;; (defun phpi-shadow-process-change (shadow change) +;; (with-current-buffer (phpi-shadow-buffer shadow) +;; (phpi-change-apply change) + +;; (let ((buffer (phpi-shadow-origin shadow)) +;; (pctx (phpinspect-make-pctx +;; :incremental t +;; :previous-bmap (phpinspect-buffer-map buffer) +;; :bmap (phpinspect-make-bmap) +;; :change change +;; :interrupt-predicate (phpi-shadow--thread-make-parser-interrupt-predicate)))) + +;; ;; Parse new content +;; (with-current-buffer (phpi-shadow-buffer shadow) +;; (phpinspect-with-parse-context pctx +;; (setf (phpinspect-buffer-tree buffer) (phpinspect-parse-current-buffer)))) + +;; (phpinspect-buffer--set-map buffer (phpinspect-pctx-bmap pctx))))) + +;; (defun phpi-shadow-make-thread-function (shadow) +;; (lambda () +;; (let ((inhibit-quit t)) +;; (while t +;; (if-let ((task (phpinspect-queue-dequeue (phpi-shadow-queue shadow)))) +;; (progn +;; (pcase task +;; ((pred phpinspect-change-p) +;; (phpi-shadow-process-change shadow task)) +;; (_ +;; (phpinspect-message +;; "Shadow thread received unsupported task type: %s" +;; (type-of task)))) + +;; ;; Rest after task completion +;; (phpi-shadow-thread-check-pause)) + +;; ;; No work to do, join main thread +;; (setf (phpi-shadow-synced-p shadow) t) +;; (ignore-error 'phpinspect-wakeup-shadow +;; (thread-join main-thread))))))) + +;; (defun phpi-shadow-thead-live-p (shadow) +;; (thread-live-p (phpi-shadow-thread shadow))) + +;; (defun phpi-shadow-await-synced (shadow &optional allow-interrupt) +;; (cl-assert (phpi-shadow-thread-live-p shadow)) + +;; (while (not (phpi-shadow-synced-p shadow)) +;; (when (and allow-interupt (phpinspect--input-pending-p)) +;; (throw 'phpinspect-interrupted nil)) + +;; (sleep-for 0.005))) + +;; (defun phpi-shadow-make-thread (shadow) +;; (make-thread +;; (phpi-shadow-make-thread-function shadow) +;; (format " **phpinspect-shadow-thread**<%d>" (phpi-shadow-id shadow)))) + +;; (defun phpinspect-make-shadow (origin) +;; (let* ((id (cl-incf phpinspect--shadow-counter)) +;; (shadow (phpinspect-make-shadow-generated +;; :origin origin +;; :buffer (generate-new-buffer +;; (format " **phpinspect-shadow**<%d>" id)) +;; :id id))) + +;; ;; Copy buffer contents +;; (with-current-buffer (phpi-shadow-buffer shadow) +;; (insert (phpinspect-with-current-buffer origin (buffer-string)))) + +;; (setf (phpi-shadow-queue shadow) +;; (phpinspect-make-queue (phpi-shadow-make-queue-subscription shadow)) + +;; (phpi-shadow-thread shadow) +;; (phpi-shadow-make-thread shadow)))) + +;; (defun phpi-shadow-register-change (shadow change) +;; (phpinspect-queue-enqueue (phpi-shadow-queue shadow) change)) + +;; (cl-defstruct (phpinspect-change (:constructor phpinspect-make-change) +;; (:conc-name phpi-change-)) +;; (synced-p t :type boolean) +;; (start nil :type integer) +;; (end nil :type integer) +;; (prev-length nil :type integer) +;; (content nil :type string)) + +;; (defun phpi-change-apply (change buffer) +;; (let ((start (phpi-change-start change)) +;; (end (phpi-change-end change)) +;; (pre-change-length (phpi-change-prev-length change)) +;; (content (phpi-change-content change))) + +;; (with-current-buffer buffer +;; (delete-region start (+ start pre-change-length)) +;; (goto-char start) +;; (when content +;; (insert content))))) + +;; (defun phpi-change-create (buffer start end pre-change-length) +;; (with-current-buffer buffer +;; (let (content) +;; (when (not (= start end)) +;; (setq content (buffer-substring-no-properties start end))) + +;; (phpinspect-make-change +;; :start start +;; :end end +;; :prev-length pre-change-length +;; :content content)))) + +;; (defun phpi-change-prev-end (change) +;; (+ (phpi-change-start change) (phpi-change-prev-length change))) + +;; (defun phpi-change-cur-length (change) +;; (- (phpi-change-end change) (phpi-change-start change))) + +;; (defun phpi-change-delta (change) +;; (- (phpi-change-prev-length change) (phpi-change-cur-length change))) + +;; (defun phpi-change-post-position (change point) +;; (if (> point (phpi-change-end change)) +;; (if (> (phpi-change-prev-end change) point) +;; (phpi-change-end change) +;; (- point (phpi-change-delta change))) +;; point)) + +;; (defun phpi-change-pre-position (change point) +;; (if (> point (phpi-change-end change)) +;; (+ (phpi-change-delta change) point) +;; point)) + +;; (defun phpi-change-overlaps-point (change point) +;; (and (> (phpi-change-end change) point) +;; (<= (phpi-change-start change) point))) + +;; (defun phpi-change-overlaps-pre-point (change point) +;; (and (> (phpi-change-prev-end change) point) +;; (<= (phpi-change-start change) point))) + +;; (defun phpi-change-tainted-token-p (change meta) +;; (or (phpi-change-overlaps-pre-point change (phpinspect-meta-start meta)) +;; (phpi-change-overlaps-pre-point change (phpinspect-meta-end meta)) +;; (phpinspect-meta-overlaps-point meta (phpi-change-start change)) +;; (phpinspect-meta-overlaps-point meta (phpi-change-prev-end change)))) + +(provide 'phpinspect-shadow) +;;; phpinspect-shadow.el ends here diff --git a/phpinspect-token-predicates.el b/phpinspect-token-predicates.el index f512327e9f..b21cbfeeef 100644 --- a/phpinspect-token-predicates.el +++ b/phpinspect-token-predicates.el @@ -39,6 +39,9 @@ Type can be any of the token types returned by (defun phpinspect-string-concatenator-p (token) (phpinspect-token-type-p token :string-concatenator)) +(defun phpinspect-string-p (token) + (phpinspect-token-type-p token :string)) + (define-inline phpinspect-static-attrib-p (token) (inline-quote (phpinspect-token-type-p ,token :static-attrib))) diff --git a/phpinspect.el b/phpinspect.el index 31980118c1..8068b413ee 100644 --- a/phpinspect.el +++ b/phpinspect.el @@ -131,15 +131,12 @@ (when (and phpinspect-load-stubs (not phpinspect-stub-cache)) (phpinspect-load-stub-index)) - (setq phpinspect-current-buffer - (phpinspect-make-buffer :buffer (current-buffer))) + (phpinspect-claim-buffer (current-buffer)) (phpinspect-register-current-buffer (lambda () (phpinspect-buffer-reset phpinspect-current-buffer))) (add-hook 'kill-buffer-hook #'phpinspect-unregister-current-buffer) - (add-hook 'after-change-functions #'phpinspect-after-change-function) - (when (featurep 'company) (make-local-variable 'company-backends) (add-to-list 'company-backends #'phpinspect-company-backend)) @@ -353,7 +350,7 @@ Example configuration for `company-mode': arg))) (insert "("))) ((eq command 'candidates) - (catch 'phpinspect-parse-interrupted + (catch 'phpinspect-interrupted (let ((completion-list (phpinspect--suggest-at-point)) (candidates)) diff --git a/test/test-buffer.el b/test/test-buffer.el index 28551780a4..7de760b468 100644 --- a/test/test-buffer.el +++ b/test/test-buffer.el @@ -36,8 +36,8 @@ (with-temp-buffer (insert-file-contents (concat phpinspect-test-php-file-directory "/NamespacedClass.php")) (setq phpinspect-current-buffer - (phpinspect-make-buffer :buffer (current-buffer))) - (setq parsed (phpinspect-buffer-parse phpinspect-current-buffer)) + (phpinspect-claim-buffer (current-buffer))) + (setq parsed (phpinspect-buffer-parse phpinspect-current-buffer 'no-interrupt)) (let* ((class (seq-find #'phpinspect-class-p (seq-find #'phpinspect-namespace-p parsed))) @@ -98,8 +98,8 @@ (ert-deftest phpinspect-buffer-parse-incrementally () (let* ((document (phpinspect-make-document)) - (buffer (phpinspect-make-buffer - :buffer (phpinspect-document-buffer document))) + (buffer (phpinspect-claim-buffer + (phpinspect-document-buffer document))) (parsed)) ;; TODO: write tests for more complicated cases (multiple edits, etc.) (phpinspect-document-set-contents document "<?php function Bello() { echo 'Hello World!'; if ($name) { echo 'Hello ' . $name . '!';} }") @@ -155,7 +155,7 @@ (ert-deftest phpinspect-buffer-parse-incrementally-position-change () (with-temp-buffer - (let ((buffer (phpinspect-make-buffer :buffer (current-buffer)))) + (let ((buffer (phpinspect-claim-buffer (current-buffer)))) (insert "<?php declare(strict_types=1); @@ -166,12 +166,6 @@ class AccountStatisticsController { function __construct(){} }") - (setq-local phpinspect-test-buffer t) - (add-to-list 'after-change-functions - (lambda (start end pre-change-length) - (when (boundp 'phpinspect-test-buffer) - (phpinspect-buffer-register-edit buffer start end pre-change-length)))) - (let* ((bmap (phpinspect-buffer-parse-map buffer)) (class-location 67) (class (phpinspect-bmap-token-starting-at bmap class-location))) @@ -196,6 +190,7 @@ class AccountStatisticsController { (setq tokens-enclosing (phpinspect-bmap-tokens-overlapping bmap class-location)) (setq class (seq-find (lambda (meta) (phpinspect-class-p (phpinspect-meta-token meta))) tokens-enclosing)) + (should class) (should (= class-location (phpinspect-meta-start class))) (should (phpinspect-class-p (phpinspect-meta-token class))) @@ -227,8 +222,8 @@ class AccountStatisticsController { (ert-deftest phpinspect-buffer-parse-incrementally-multiedit () (let* ((document (phpinspect-make-document)) - (buffer (phpinspect-make-buffer - :buffer (phpinspect-document-buffer document))) + (buffer (phpinspect-claim-buffer + (phpinspect-document-buffer document))) parsed parsed-after current-tree) (phpinspect-document-set-contents @@ -256,8 +251,7 @@ class YYY { (phpinspect-document-setq-local document phpinspect-current-buffer buffer) (phpinspect-with-document-buffer document - (setq buffer-undo-list nil) - (add-hook 'after-change-functions #'phpinspect-after-change-function)) + (setq buffer-undo-list nil)) (setq parsed (phpinspect-buffer-parse buffer 'no-interrupt)) @@ -294,8 +288,7 @@ class YYY { (ert-deftest phpinspect-buffer-parse-incrementally-class-with-method () (with-temp-buffer - (let* ((buffer (phpinspect-make-buffer - :buffer (current-buffer)))) + (let* ((buffer (phpinspect-claim-buffer (current-buffer)))) (setq-local phpinspect-current-buffer buffer) @@ -314,7 +307,6 @@ class AAA { ") - (add-hook 'after-change-functions #'phpinspect-after-change-function) (phpinspect-buffer-parse buffer 'no-interrupt) (let ((switch t) @@ -336,9 +328,6 @@ class AAA { (let ((token (phpinspect-bmap-last-token-before-point (phpinspect-buffer-map buffer) (+ 68 delta)))) - ;; (message "Map:") - ;; (dolist (meta (mapcar #'phpinspect-meta-string (sort (phpinspect-meta-flatten (phpinspect-buffer-root-meta buffer)) #'phpinspect-meta-sort-start))) - ;; (message " - %s" meta)) (should token) (should (phpinspect-variable-p (phpinspect-meta-token token))) (should (string= "banana" (cadr (phpinspect-meta-token token)))) @@ -349,8 +338,7 @@ class AAA { (ert-deftest phpinspect-buffer-parse-incrementally-use () (with-temp-buffer - (let* ((buffer (phpinspect-make-buffer - :buffer (current-buffer)))) + (let* ((buffer (phpinspect-claim-buffer (current-buffer)))) (setq-local phpinspect-current-buffer buffer) @@ -367,7 +355,6 @@ use CCC; ") - (add-hook 'after-change-functions #'phpinspect-after-change-function) (phpinspect-buffer-parse buffer 'no-interrupt) (let ((switch nil) (delta 0)) @@ -377,15 +364,11 @@ use CCC; (progn (setq delta 0) (goto-char 44) - (insert "hh") - (should (phpinspect-edtrack-edits (phpinspect-buffer-edit-tracker buffer))) - (should (= 51 (phpinspect-edtrack-current-position-at-point (phpinspect-buffer-edit-tracker buffer) 49)))) + (insert "hh")) (progn (setq delta (- 2)) (goto-char 44) - (delete-char 2) - (should (phpinspect-edtrack-edits (phpinspect-buffer-edit-tracker buffer))) - (should (= 47 (phpinspect-edtrack-current-position-at-point (phpinspect-buffer-edit-tracker buffer) 49))))) + (delete-char 2))) (setq switch (not switch)) @@ -532,9 +515,9 @@ public $banana; const CONSTANT = 0; (ert-deftest phpinspect-buffer-index-typehinted-class-variables () (with-temp-buffer - (let ((buffer (phpinspect-make-buffer - :buffer (current-buffer) - :-project (phpinspect--make-project :autoload (phpinspect-make-autoloader))))) + (let ((buffer (phpinspect-claim-buffer + (current-buffer) + (phpinspect--make-project :autoload (phpinspect-make-autoloader))))) (insert "<?php declare(strict_types=1); @@ -600,9 +583,9 @@ class AccountStatisticsController { (ert-deftest phpinspect-buffer-parse-incrementally-unfinished-variable-scope () (with-temp-buffer - (let* ((buffer (phpinspect-make-buffer - :buffer (current-buffer) - :-project (phpinspect--make-dummy-project)))) + (let* ((buffer (phpinspect-claim-buffer + (current-buffer) + (phpinspect--make-dummy-project)))) (setq-local phpinspect-current-buffer buffer) @@ -620,7 +603,6 @@ class AAA { ") - (add-hook 'after-change-functions #'phpinspect-after-change-function) (phpinspect-buffer-parse buffer 'no-interrupt) ;; move to after class brace @@ -635,7 +617,7 @@ class AAA { (ert-deftest phpinspect-buffer-parse-incrementally-trait-config () (with-temp-buffer (let* ((project (phpinspect--make-dummy-composer-project-with-code)) - (buffer (phpinspect-make-buffer :-project project :buffer (current-buffer)))) + (buffer (phpinspect-claim-buffer (current-buffer) project))) (insert "<?php @@ -651,7 +633,6 @@ class Bar { project (phpinspect--make-type :name "\\App\\Foo") 'no-enqueue)) (setq-local phpinspect-current-buffer buffer) - (add-hook 'after-change-functions #'phpinspect-after-change-function) (phpinspect-buffer-parse buffer 'no-interrupt) (phpinspect-buffer-update-project-index buffer) @@ -682,12 +663,11 @@ class Bar { (ert-deftest phpinspect-buffer-parse-incrementally-class-block-scope () (with-temp-buffer (let* ((project (phpinspect--make-dummy-composer-project-with-code)) - (buffer (phpinspect-make-buffer :-project project :buffer (current-buffer)))) + (buffer (phpinspect-claim-buffer (current-buffer) project))) (insert "<?php class A { public function A() {} }") (setq-local phpinspect-current-buffer buffer) - (add-hook 'after-change-functions #'phpinspect-after-change-function) (let ((expected `(:root (:class (:class-declaration (:word "A")) @@ -715,13 +695,14 @@ class Bar { (backward-char) (insert " ") (setq result (phpinspect-buffer-parse buffer 'no-interrupt)) + (should result) (should (equal expected result)))))) (ert-deftest phpinspect-buffer-index-update-method-name () (with-temp-buffer (let* ((project (phpinspect--make-project :autoload (phpinspect-make-autoloader))) - (buffer (phpinspect-make-buffer :buffer (current-buffer) :-project project)) + (buffer (phpinspect-claim-buffer (current-buffer) project)) (class-type (phpinspect--make-type :name "\\NS\\TestClass" :fully-qualified t))) (insert "<?php namespace NS; @@ -731,7 +712,6 @@ class TestClass function testMe(): RelativeType {} }") (setq-local phpinspect-current-buffer buffer) - (add-hook 'after-change-functions #'phpinspect-after-change-function) (phpinspect-buffer-update-project-index buffer) (goto-char 59) @@ -751,10 +731,9 @@ class TestClass (ert-deftest phpinspect-buffer-parse-incrementally-comment () (with-temp-buffer (let* ((project (phpinspect--make-project :autoload (phpinspect-make-autoloader))) - (buffer (phpinspect-make-buffer :buffer (current-buffer) :-project project))) + (buffer (phpinspect-claim-buffer (current-buffer) project))) (insert "<?php\n\n// \n") (setq-local phpinspect-current-buffer buffer) - (add-hook 'after-change-functions #'phpinspect-after-change-function) (should (equal '(:root (:comment)) (phpinspect-buffer-parse buffer))) @@ -774,6 +753,7 @@ class TestClass (should (equal '(:root (:word "aaa") (:word "bbb") (:word "ccc")) (phpinspect-buffer-parse buffer))) (should-not (phpinspect-buffer--deletions buffer)) + (should (length= (phpinspect-buffer--additions buffer) 4)) (goto-char (- (point-max) 5)) diff --git a/test/test-changeset.el b/test/test-changeset.el index 8d21bc0c9d..aff48206b0 100644 --- a/test/test-changeset.el +++ b/test/test-changeset.el @@ -31,38 +31,38 @@ (require 'phpinspect-meta) (require 'phpinspect-parse-context) -(ert-deftest phpinspect-meta-with-changeset-revert-parent-relation () - (let ((parent (phpinspect-make-meta nil 1 20 "" 'parent)) - (child (phpinspect-make-meta nil 4 8 "" 'child)) - (pctx (phpinspect-make-pctx)) - (other-parent (phpinspect-make-meta nil 3 20 "" 'other-parent)) - parent-offset) - - (phpinspect-meta-set-parent child parent) - (setq parent-offset (phpinspect-meta-parent-offset child)) - - - (phpinspect-with-parse-context pctx - (phpinspect-meta-with-changeset child - (phpinspect-meta-detach-parent child) - (phpinspect-meta-set-parent child other-parent))) - - (phpinspect-changeset-revert (car (phpinspect-pctx-changesets pctx))) - - (should (eq parent (phpinspect-meta-parent child))) - (let ((children (phpinspect-splayt-to-list - (phpinspect-meta-children parent)))) - (should (length= children 1)) - (should (eq 'child (phpinspect-meta-token (car children)))) - - (should (= parent-offset (phpinspect-meta-parent-offset child))) - (should (= 4 (phpinspect-meta-start child))) - (should (= 8 (phpinspect-meta-end child))) - (should (= 4 (phpinspect-meta-width child))) - - (should (eq child (phpinspect-splayt-find - (phpinspect-meta-children parent) - (phpinspect-meta-parent-offset child))))))) +;; (ert-deftest phpinspect-meta-with-changeset-revert-parent-relation () +;; (let ((parent (phpinspect-make-meta nil 1 20 "" 'parent)) +;; (child (phpinspect-make-meta nil 4 8 "" 'child)) +;; (pctx (phpinspect-make-pctx)) +;; (other-parent (phpinspect-make-meta nil 3 20 "" 'other-parent)) +;; parent-offset) + +;; (phpinspect-meta-set-parent child parent) +;; (setq parent-offset (phpinspect-meta-parent-offset child)) + + +;; (phpinspect-with-parse-context pctx +;; (phpinspect-meta-with-changeset child +;; (phpinspect-meta-detach-parent child) +;; (phpinspect-meta-set-parent child other-parent))) + +;; (phpinspect-changeset-revert (car (phpinspect-pctx-changesets pctx))) + +;; (should (eq parent (phpinspect-meta-parent child))) +;; (let ((children (phpinspect-splayt-to-list +;; (phpinspect-meta-children parent)))) +;; (should (length= children 1)) +;; (should (eq 'child (phpinspect-meta-token (car children)))) + +;; (should (= parent-offset (phpinspect-meta-parent-offset child))) +;; (should (= 4 (phpinspect-meta-start child))) +;; (should (= 8 (phpinspect-meta-end child))) +;; (should (= 4 (phpinspect-meta-width child))) + +;; (should (eq child (phpinspect-splayt-find +;; (phpinspect-meta-children parent) +;; (phpinspect-meta-parent-offset child))))))) ;;; test-changeset.el ends here diff --git a/test/test-eldoc.el b/test/test-eldoc.el index 6153d325c0..a34767de2f 100644 --- a/test/test-eldoc.el +++ b/test/test-eldoc.el @@ -26,7 +26,7 @@ class Thing (phpinspect-project-root-function (lambda () "phpinspect-test")) (phpinspect-eldoc-word-width 100) (project (phpinspect--make-project :autoload (phpinspect-make-autoloader) :worker 'nil-worker)) - (buffer (phpinspect-make-buffer :buffer (current-buffer) :-project project)) + (buffer (phpinspect-claim-buffer (current-buffer) project)) second-arg-pos inside-nested-list-pos first-arg-pos) (setq-local phpinspect-current-buffer buffer) (insert php-code) @@ -104,7 +104,7 @@ class Thing (insert php-code) (backward-char) (setq-local phpinspect-current-buffer - (phpinspect-make-buffer :buffer (current-buffer) :-project project)) + (phpinspect-claim-buffer (current-buffer) project)) (phpinspect-buffer-parse phpinspect-current-buffer) (phpinspect-eldoc-function)))))) @@ -131,5 +131,5 @@ class Thing (with-temp-buffer (insert php-code) (setq-local phpinspect-current-buffer - (phpinspect-make-buffer :buffer (current-buffer))) + (phpinspect-claim-buffer (current-buffer))) (phpinspect-eldoc-function)))))) diff --git a/test/test-imports.el b/test/test-imports.el index d0c9c9be90..4c12b461b8 100644 --- a/test/test-imports.el +++ b/test/test-imports.el @@ -34,10 +34,9 @@ (ert-deftest phpinspect-fix-imports-single-namespaced-class () (let ((project (phpinspect--make-dummy-composer-project))) (with-temp-buffer - (let* ((buffer (phpinspect-make-buffer :buffer (current-buffer) - :-project project))) + (phpinspect-claim-buffer (current-buffer) project) - (insert "<?php + (insert "<?php namespace Not\\App; @@ -45,12 +44,9 @@ class Baz { private Foo $foo; public Bar $bar; }") - ;; Ensure buffer is made aware of changes - (setq phpinspect-current-buffer buffer) - (add-hook 'after-change-functions #'phpinspect-after-change-function) - (phpinspect-fix-imports) - (should (string= "<?php + (phpinspect-fix-imports) + (should (string= "<?php namespace Not\\App; @@ -61,16 +57,15 @@ class Baz { private Foo $foo; public Bar $bar; }" - (buffer-string))))))) + (buffer-string)))))) (ert-deftest phpinspect-fix-imports-no-remove-unused () (dlet ((phpinspect-imports-remove-unused nil)) (let ((project (phpinspect--make-dummy-composer-project))) (with-temp-buffer - (let* ((buffer (phpinspect-make-buffer :buffer (current-buffer) - :-project project))) + (phpinspect-claim-buffer (current-buffer) project) - (insert "<?php + (insert "<?php namespace Not\\App; @@ -80,12 +75,9 @@ class Baz { private Foo $foo; public Bar $bar; }") - ;; Ensure buffer is made aware of changes - (setq phpinspect-current-buffer buffer) - (add-hook 'after-change-functions #'phpinspect-after-change-function) - (phpinspect-fix-imports) - (should (string= "<?php + (phpinspect-fix-imports) + (should (string= "<?php namespace Not\\App; @@ -97,16 +89,15 @@ class Baz { private Foo $foo; public Bar $bar; }" - (buffer-string)))))))) + (buffer-string))))))) (ert-deftest phpinspect-fix-imports-multiple-namespaced-classes () (let ((project (phpinspect--make-dummy-composer-project))) (with-temp-buffer - (let* ((buffer (phpinspect-make-buffer :buffer (current-buffer) - :-project project))) + (phpinspect-claim-buffer (current-buffer) project) - (insert "<?php + (insert "<?php namespace Not\\App; @@ -117,12 +108,9 @@ class Bee { class Baz { private Foo $foo; }") - ;; Ensure buffer is made aware of changes - (setq phpinspect-current-buffer buffer) - (add-hook 'after-change-functions #'phpinspect-after-change-function) - (phpinspect-fix-imports) - (should (string= "<?php + (phpinspect-fix-imports) + (should (string= "<?php namespace Not\\App; @@ -136,13 +124,12 @@ class Bee { class Baz { private Foo $foo; }" - (buffer-string))))))) + (buffer-string)))))) (ert-deftest phpinspect-fix-imports-namespaced-class-and-enum () (let ((project (phpinspect--make-dummy-composer-project))) (with-temp-buffer - (let* ((buffer (phpinspect-make-buffer :buffer (current-buffer) - :-project project))) + (phpinspect-claim-buffer (current-buffer) project) (insert "<?php @@ -155,9 +142,6 @@ enum Bee: string { class Baz { private Foo $foo; }") - ;; Ensure buffer is made aware of changes - (setq phpinspect-current-buffer buffer) - (add-hook 'after-change-functions #'phpinspect-after-change-function) (phpinspect-fix-imports) (should (string= "<?php @@ -174,15 +158,14 @@ enum Bee: string { class Baz { private Foo $foo; }" - (buffer-string))))))) + (buffer-string)))))) (ert-deftest phpinspect-fix-imports-namespaced-class-and-function () (let ((project (phpinspect--make-dummy-composer-project))) (with-temp-buffer - (let* ((buffer (phpinspect-make-buffer :buffer (current-buffer) - :-project project))) + (phpinspect-claim-buffer (current-buffer) project) - (insert "<?php + (insert "<?php namespace Not\\App; @@ -191,12 +174,9 @@ function bar(): Bar {} class Baz { private Foo $foo; }") - ;; Ensure buffer is made aware of changes - (setq phpinspect-current-buffer buffer) - (add-hook 'after-change-functions #'phpinspect-after-change-function) - (phpinspect-fix-imports) - (should (string= "<?php + (phpinspect-fix-imports) + (should (string= "<?php namespace Not\\App; @@ -208,13 +188,12 @@ function bar(): Bar {} class Baz { private Foo $foo; }" - (buffer-string))))))) + (buffer-string)))))) (ert-deftest phpinspect-fix-imports-aliased () (let ((project (phpinspect--make-dummy-composer-project))) (with-temp-buffer - (let* ((buffer (phpinspect-make-buffer :buffer (current-buffer) - :-project project))) + (phpinspect-claim-buffer (current-buffer) project) (insert "<?php @@ -228,9 +207,6 @@ class Baz { private FooBar $foo; private Foo $notAliased; }") - ;; Ensure buffer is made aware of changes - (setq phpinspect-current-buffer buffer) - (add-hook 'after-change-functions #'phpinspect-after-change-function) (phpinspect-fix-imports) (should (string= "<?php @@ -247,13 +223,12 @@ class Baz { private FooBar $foo; private Foo $notAliased; }" - (buffer-string))))))) + (buffer-string)))))) (ert-deftest phpinspect-fix-imports-fully-qualified-names () (let ((project (phpinspect--make-dummy-composer-project))) (with-temp-buffer - (let* ((buffer (phpinspect-make-buffer :buffer (current-buffer) - :-project project))) + (phpinspect-claim-buffer (current-buffer) project) (insert "<?php @@ -264,10 +239,6 @@ function bar(): \\App\\Bar {} class Baz { private \\App\\Foo $foo; }") - ;; Ensure buffer is made aware of changes - (setq phpinspect-current-buffer buffer) - (add-hook 'after-change-functions #'phpinspect-after-change-function) - (phpinspect-fix-imports) (should (string= "<?php @@ -278,4 +249,4 @@ function bar(): \\App\\Bar {} class Baz { private \\App\\Foo $foo; }" - (buffer-string))))))) + (buffer-string)))))) diff --git a/test/test-parse-context.el b/test/test-parse-context.el index 7a73774e6c..300eb18697 100644 --- a/test/test-parse-context.el +++ b/test/test-parse-context.el @@ -28,23 +28,23 @@ (require 'phpinspect-meta) (require 'phpinspect-bmap) -(ert-deftest phpinspect-pctx-cancel () - (let ((meta (phpinspect-make-meta nil 10 20 " " 'token 'overlay nil)) - (pctx (phpinspect-make-pctx :bmap (phpinspect-make-bmap)))) - (phpinspect-with-parse-context pctx - (phpinspect-meta-with-changeset meta - (setf (phpinspect-meta-absolute-start meta) 222) - (setf (phpinspect-meta-absolute-end meta) 1234) - (phpinspect-meta-set-parent meta (phpinspect-make-meta nil 1 2000 "" 'parent-token)))) - - (should (= 222 (phpinspect-meta-start meta))) - (should (= 1234 (phpinspect-meta-end meta))) - (should (phpinspect-meta-parent meta)) - (should (= 221 (phpinspect-meta-parent-offset meta))) - - (phpinspect-pctx-cancel pctx) - - (should (= 10 (phpinspect-meta-start meta))) - (should (= 20 (phpinspect-meta-end meta))) - (should-not (phpinspect-meta-parent meta)) - (should-not (phpinspect-meta-parent-offset meta)))) +;; (ert-deftest phpinspect-pctx-cancel () +;; (let ((meta (phpinspect-make-meta nil 10 20 " " 'token 'overlay nil)) +;; (pctx (phpinspect-make-pctx :bmap (phpinspect-make-bmap)))) +;; (phpinspect-with-parse-context pctx +;; (phpinspect-meta-with-changeset meta +;; (setf (phpinspect-meta-absolute-start meta) 222) +;; (setf (phpinspect-meta-absolute-end meta) 1234) +;; (phpinspect-meta-set-parent meta (phpinspect-make-meta nil 1 2000 "" 'parent-token)))) + +;; (should (= 222 (phpinspect-meta-start meta))) +;; (should (= 1234 (phpinspect-meta-end meta))) +;; (should (phpinspect-meta-parent meta)) +;; (should (= 221 (phpinspect-meta-parent-offset meta))) + +;; (phpinspect-pctx-cancel pctx) + +;; (should (= 10 (phpinspect-meta-start meta))) +;; (should (= 20 (phpinspect-meta-end meta))) +;; (should-not (phpinspect-meta-parent meta)) +;; (should-not (phpinspect-meta-parent-offset meta)))) diff --git a/test/test-parser.el b/test/test-parser.el index 260b2c0f82..224aa485ba 100644 --- a/test/test-parser.el +++ b/test/test-parser.el @@ -61,78 +61,78 @@ class TestClass { (should (phpinspect-list-p (phpinspect-meta-token parent))) (should (phpinspect-block-p (phpinspect-meta-token (phpinspect-meta-parent parent))))))) -(ert-deftest phpinspect-parse-string-incrementally-single-edit () - (let ((ctx (phpinspect-make-pctx :incremental t :bmap (phpinspect-make-bmap)))) - (phpinspect-with-parse-context ctx - (phpinspect-parse-string " : 'abc' ")) - - (let* ((bmap (phpinspect-pctx-bmap ctx)) - (children (thread-last (phpinspect-bmap-root-meta bmap) - (phpinspect-meta-children) - (phpinspect-splayt-to-list))) - (string-meta (car children))) - - (should (length= children 1)) - (should (phpinspect-string-p (phpinspect-meta-token string-meta))) - (should (= 5 (phpinspect-meta-width string-meta))) - (should (= 5 (phpinspect-meta-start string-meta))) - (should (= 10 (phpinspect-meta-end string-meta))) - - (let ((edit-tracker (phpinspect-make-edtrack))) - (phpinspect-edtrack-register-edit edit-tracker 1 1 1) - - (let ((prev-string-meta string-meta) - (ctx (phpinspect-make-pctx :incremental t - :previous-bmap bmap - :bmap (phpinspect-make-bmap) - :edtrack edit-tracker))) - (phpinspect-with-parse-context ctx - (phpinspect-parse-string " : 'abc' ")) - - (setq children (thread-last (phpinspect-bmap-root-meta (phpinspect-pctx-bmap ctx)) - (phpinspect-meta-children) - (phpinspect-splayt-to-list)) - string-meta (car children)) - - ;;(message "%s" (mapcar #'phpinspect-meta-string children)) - - (should (length= children 1)) - (should (eq prev-string-meta string-meta)) - (should (phpinspect-string-p (phpinspect-meta-token string-meta))) - (should (= 5 (phpinspect-meta-width string-meta))) - (should (= 4 (phpinspect-meta-start string-meta))) - (should (= 9 (phpinspect-meta-end string-meta)))))))) - -(ert-deftest phpinspect-parse-string-incrementally-muti-edit () - (let ((ctx (phpinspect-make-pctx :incremental t :bmap (phpinspect-make-bmap)))) - (phpinspect-with-parse-context ctx - (phpinspect-parse-string " : 'abc' ")) - - (let ((edit-tracker (phpinspect-make-edtrack))) - (phpinspect-edtrack-register-edit edit-tracker 1 1 1) - (phpinspect-edtrack-register-edit edit-tracker 2 5 0) - - (let ((prev-string-meta (phpinspect-meta-first-child (phpinspect-bmap-root-meta (phpinspect-pctx-bmap ctx)))) - (ctx (phpinspect-make-pctx :incremental t - :previous-bmap (phpinspect-pctx-bmap ctx) - :bmap (phpinspect-make-bmap) - :edtrack edit-tracker))) - (phpinspect-with-parse-context ctx - (phpinspect-parse-string " : 'abc' ")) - - (let* ((children (thread-last (phpinspect-bmap-root-meta (phpinspect-pctx-bmap ctx)) - (phpinspect-meta-children) - (phpinspect-splayt-to-list))) - (string-meta (car children))) - - - ;;(message "%s" (mapcar #'phpinspect-meta-string children)) - (should (length= children 1)) - (should (eq prev-string-meta string-meta)) - (should (phpinspect-string-p (phpinspect-meta-token string-meta))) - (should (= 5 (phpinspect-meta-width string-meta))) - (should (= 7 (phpinspect-meta-start string-meta))) - (should (= 12 (phpinspect-meta-end string-meta)))))))) +;; (ert-deftest phpinspect-parse-string-incrementally-single-edit () +;; (let ((ctx (phpinspect-make-pctx :incremental t :bmap (phpinspect-make-bmap)))) +;; (phpinspect-with-parse-context ctx +;; (phpinspect-parse-string " : 'abc' ")) + +;; (let* ((bmap (phpinspect-pctx-bmap ctx)) +;; (children (thread-last (phpinspect-bmap-root-meta bmap) +;; (phpinspect-meta-children) +;; (phpinspect-splayt-to-list))) +;; (string-meta (car children))) + +;; (should (length= children 1)) +;; (should (phpinspect-string-p (phpinspect-meta-token string-meta))) +;; (should (= 5 (phpinspect-meta-width string-meta))) +;; (should (= 5 (phpinspect-meta-start string-meta))) +;; (should (= 10 (phpinspect-meta-end string-meta))) + +;; (let ((edit-tracker (phpinspect-make-edtrack))) +;; (phpinspect-edtrack-register-edit edit-tracker 1 1 1) + +;; (let ((prev-string-meta string-meta) +;; (ctx (phpinspect-make-pctx :incremental t +;; :previous-bmap bmap +;; :bmap (phpinspect-make-bmap) +;; :edtrack edit-tracker))) +;; (phpinspect-with-parse-context ctx +;; (phpinspect-parse-string " : 'abc' ")) + +;; (setq children (thread-last (phpinspect-bmap-root-meta (phpinspect-pctx-bmap ctx)) +;; (phpinspect-meta-children) +;; (phpinspect-splayt-to-list)) +;; string-meta (car children)) + +;; ;;(message "%s" (mapcar #'phpinspect-meta-string children)) + +;; (should (length= children 1)) +;; (should (eq prev-string-meta string-meta)) +;; (should (phpinspect-string-p (phpinspect-meta-token string-meta))) +;; (should (= 5 (phpinspect-meta-width string-meta))) +;; (should (= 4 (phpinspect-meta-start string-meta))) +;; (should (= 9 (phpinspect-meta-end string-meta)))))))) + +;; (ert-deftest phpinspect-parse-string-incrementally-muti-edit () +;; (let ((ctx (phpinspect-make-pctx :incremental t :bmap (phpinspect-make-bmap)))) +;; (phpinspect-with-parse-context ctx +;; (phpinspect-parse-string " : 'abc' ")) + +;; (let ((edit-tracker (phpinspect-make-edtrack))) +;; (phpinspect-edtrack-register-edit edit-tracker 1 1 1) +;; (phpinspect-edtrack-register-edit edit-tracker 2 5 0) + +;; (let ((prev-string-meta (phpinspect-meta-first-child (phpinspect-bmap-root-meta (phpinspect-pctx-bmap ctx)))) +;; (ctx (phpinspect-make-pctx :incremental t +;; :previous-bmap (phpinspect-pctx-bmap ctx) +;; :bmap (phpinspect-make-bmap) +;; :edtrack edit-tracker))) +;; (phpinspect-with-parse-context ctx +;; (phpinspect-parse-string " : 'abc' ")) + +;; (let* ((children (thread-last (phpinspect-bmap-root-meta (phpinspect-pctx-bmap ctx)) +;; (phpinspect-meta-children) +;; (phpinspect-splayt-to-list))) +;; (string-meta (car children))) + + +;; ;;(message "%s" (mapcar #'phpinspect-meta-string children)) +;; (should (length= children 1)) +;; (should (eq prev-string-meta string-meta)) +;; (should (phpinspect-string-p (phpinspect-meta-token string-meta))) +;; (should (= 5 (phpinspect-meta-width string-meta))) +;; (should (= 7 (phpinspect-meta-start string-meta))) +;; (should (= 12 (phpinspect-meta-end string-meta)))))))) (ert-deftest phpinspect-parse-comma () (let* ((code "(,)") diff --git a/test/test-shadow.el b/test/test-shadow.el new file mode 100644 index 0000000000..c2547df9d9 --- /dev/null +++ b/test/test-shadow.el @@ -0,0 +1,66 @@ +;;; test-shadow.el --- Tests for phpinspect-shadow.el -*- lexical-binding: t; -*- + +;; Copyright (C) 2024 Hugo Thunnissen + +;; Author: Hugo Thunnissen <de...@hugot.nl> +;; Keywords: + +;; 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-change) + +(ert-deftest phpinspect-change-post-position () + (let ((change (phpinspect-make-change + :start 1 + :end 11 + :prev-length 21))) + (should (= 11 (phpi-change-post-position change 21))) + (should (= 11 (phpi-change-post-position change 15))) + (should (= 11 (phpi-change-post-position change 11))) + (should (= 10 (phpi-change-post-position change 10))) + (should (= 20 (phpi-change-post-position change 31))))) + +(ert-deftest phpinspect-change-pre-position () + (let ((change (phpinspect-make-change + :start 1 + :end 11 + :prev-length 21))) + (should (= 31 (phpi-change-pre-position change 20))) + (should (= 26 (phpi-change-pre-position change 15))) + (should (= 11 (phpi-change-pre-position change 11))) + (should (= 10 (phpi-change-pre-position change 10))) + + (should (= 41 (phpi-change-pre-position change 30))))) + +(ert-deftest phpinspect-change-pre-position-shift-right () + (let ((change (phpinspect-make-change + :start 1 + :end 21 + :prev-length 10))) + (should (= 11 (phpi-change-pre-position change 20))) + (should (= 11 (phpi-change-pre-position change 15))) + (should (= 11 (phpi-change-pre-position change 11))) + (should (= 10 (phpi-change-pre-position change 10))) + + (should (= 20 (phpi-change-pre-position change 30))))) + + +(provide 'test-shadow) +;;; test-shadow.el ends here diff --git a/test/test-suggest.el b/test/test-suggest.el index 5edfb4cbb4..41dbd4b5f4 100644 --- a/test/test-suggest.el +++ b/test/test-suggest.el @@ -35,11 +35,10 @@ (with-temp-buffer (insert "<?php foreach ($array as $key => $value) {") - (let* ((buffer (phpinspect-make-buffer :buffer (current-buffer))) - - (rctx (phpinspect-get-resolvecontext - (phpinspect--make-dummy-project) (phpinspect-buffer-parse-map buffer) (point))) - (variables (phpinspect-suggest-variables-at-point rctx))) + (let* ((buffer (phpinspect-claim-buffer (current-buffer))) + (rctx (phpinspect-get-resolvecontext + (phpinspect--make-dummy-project) (phpinspect-buffer-parse-map buffer) (point))) + (variables (phpinspect-suggest-variables-at-point rctx))) (should (length= variables 3)) (should (equal (list "array" "key" "value") @@ -53,23 +52,22 @@ use App\\Foo; new ") - (let* ((buffer (phpinspect-make-buffer - :buffer (current-buffer) - :-project (phpinspect--make-dummy-composer-project-with-code))) - (rctx (phpinspect-buffer-get-resolvecontext buffer (point))) - (types (phpinspect-suggest-words-at-point rctx))) + (let* ((buffer (phpinspect-claim-buffer + (current-buffer) + (phpinspect--make-dummy-composer-project-with-code))) + (rctx (phpinspect-buffer-get-resolvecontext buffer (point))) + (types (phpinspect-suggest-words-at-point rctx))) (setq-local phpinspect-current-buffer buffer) - (add-hook 'after-change-functions #'phpinspect-after-change-function) (should (length= types 2)) (should (equal (list "\\App\\Baz" "\\App\\Foo") - (sort (mapcar #'phpinspect--type-name-string types) #'string<))) + (sort (mapcar #'phpinspect--type-name-string types) #'string<))) (insert "Fo") (setq rctx (phpinspect-buffer-get-resolvecontext buffer (point)) - types (phpinspect-suggest-words-at-point rctx)) + types (phpinspect-suggest-words-at-point rctx)) (should (length= types 2)) (should (equal (list "\\App\\Baz" "\\App\\Foo") - (sort (mapcar #'phpinspect--type-name-string types) #'string<)))))) + (sort (mapcar #'phpinspect--type-name-string types) #'string<)))))) (ert-deftest phpinspect-suggest-types-at-point-include-current-namespace () (with-temp-buffer @@ -81,14 +79,14 @@ use \\DateTime; new ") - (let* ((buffer (phpinspect-make-buffer - :buffer (current-buffer) - :-project (phpinspect--make-dummy-composer-project-with-code))) - (rctx (phpinspect-buffer-get-resolvecontext buffer (point))) - (types (phpinspect-suggest-words-at-point rctx))) - (should (length= types 6)) - (should (equal (list "\\App\\Bar" "\\App\\Barry" "\\App\\Baz" "\\App\\Foo" "\\App\\Harry" "\\DateTime") - (sort (mapcar #'phpinspect--type-name-string types) #'string<)))))) + (let* ((buffer (phpinspect-claim-buffer + (current-buffer) + (phpinspect--make-dummy-composer-project-with-code))) + (rctx (phpinspect-buffer-get-resolvecontext buffer (point))) + (types (phpinspect-suggest-words-at-point rctx))) + (should (length= types 6)) + (should (equal (list "\\App\\Bar" "\\App\\Barry" "\\App\\Baz" "\\App\\Foo" "\\App\\Harry" "\\DateTime") + (sort (mapcar #'phpinspect--type-name-string types) #'string<)))))) (ert-deftest phpinspect-suggest-keywords-at-point-class-body () (with-temp-buffer @@ -101,11 +99,11 @@ class Foo ") - (let* ((buffer (phpinspect-make-buffer - :buffer (current-buffer) - :-project (phpinspect--make-dummy-composer-project-with-code))) - (rctx (phpinspect-buffer-get-resolvecontext buffer (point))) - (words (phpinspect-suggest-words-at-point rctx))) + (let* ((buffer (phpinspect-claim-buffer + (current-buffer) + (phpinspect--make-dummy-composer-project-with-code))) + (rctx (phpinspect-buffer-get-resolvecontext buffer (point))) + (words (phpinspect-suggest-words-at-point rctx))) (should (equal (list "const" "function" "private" "protected" "public" "static") (sort (mapcar #'phpinspect-suggest-keyword-word words) #'string<)))))) @@ -121,12 +119,12 @@ class Foo public ") (let* ((buffer (phpinspect-claim-buffer - (current-buffer) - (phpinspect--make-dummy-composer-project-with-code))) - (rctx (phpinspect-buffer-get-resolvecontext buffer (point))) - (results (phpinspect-suggest-words-at-point rctx)) - (types (seq-filter #'phpinspect--type-p results)) - (words (seq-filter #'phpinspect-suggest-keyword-p results))) + (current-buffer) + (phpinspect--make-dummy-composer-project-with-code))) + (rctx (phpinspect-buffer-get-resolvecontext buffer (point))) + (results (phpinspect-suggest-words-at-point rctx)) + (types (seq-filter #'phpinspect--type-p results)) + (words (seq-filter #'phpinspect-suggest-keyword-p results))) (should (length= results (+ (length types) (length words)))) (should (equal (list "function" "static") (sort (mapcar #'phpinspect-suggest-keyword-word words) #'string<)))