|
|
|
@ -83,6 +83,18 @@ linked with."
|
|
|
|
|
;; return
|
|
|
|
|
parsed))))
|
|
|
|
|
|
|
|
|
|
;; (cl-defmethod phpinspect-buffer-parse-incrementally ((buffer phpinspect-buffer) &optional edits)
|
|
|
|
|
;; (let* ((edits (or edits (phpinspect-edit-tracker-edits
|
|
|
|
|
;; (phpinspect-buffer-edit-tracker buffer))))
|
|
|
|
|
;; (edit (phpinspect-queue-dequeue edits)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(cl-defmethod phpinspect-buffer-register-edit
|
|
|
|
|
((buffer phpinspect-buffer) (start integer) (end integer) (pre-change-length integer))
|
|
|
|
|
(let ((contents (buffer-substring start end)))
|
|
|
|
|
(phpinspect-edit-tracker-register
|
|
|
|
|
(phpinspect-buffer-edit-tracker buffer) start end pre-change-length contents)))
|
|
|
|
|
|
|
|
|
|
(cl-defmethod phpinspect-buffer-queue-full-parse ((buffer phpinspect-buffer))
|
|
|
|
|
(phpinspect--log "Attempted to queue full parse"))
|
|
|
|
|
|
|
|
|
@ -95,147 +107,6 @@ linked with."
|
|
|
|
|
,@body)
|
|
|
|
|
(setf (phpinspect-buffer-tree buffer) ,tree-store-sym))))
|
|
|
|
|
|
|
|
|
|
;; (cl-defmethod phpinspect-buffer-reparse
|
|
|
|
|
;; ((buffer phpinspect-buffer) (meta phpinspect-token-meta) (edit phpinspect-edit))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(cl-defmethod phpinspect-buffer-parse-incrementally ((buffer phpinspect-buffer))
|
|
|
|
|
(let ((edits
|
|
|
|
|
(phpinspect-edit-tracker-edits (phpinspect-buffer-edit-tracker buffer)))
|
|
|
|
|
(buffer-tree (phpinspect-buffer-tree buffer)))
|
|
|
|
|
(seq-doseq (edit edits)
|
|
|
|
|
(let* ((edit-region (phpinspect-edit-region edit))
|
|
|
|
|
(edit-delta (phpinspect-edit-delta edit))
|
|
|
|
|
(parsed-start)
|
|
|
|
|
(parsed-end)
|
|
|
|
|
(metas (phpinspect-tree-find-smallest-overlapping-set
|
|
|
|
|
buffer-tree edit-region)))
|
|
|
|
|
(condition-case err
|
|
|
|
|
(dolist (meta metas)
|
|
|
|
|
(setq meta (gv-deref meta))
|
|
|
|
|
(let ((region (phpinspect-token-metadata-region meta))
|
|
|
|
|
(handler-function (symbol-function
|
|
|
|
|
(phpinspect-token-metadata-handler meta)))
|
|
|
|
|
(temp-tree (phpinspect-make-tree
|
|
|
|
|
;; We start parsing at the start of the token
|
|
|
|
|
:start (phpinspect-region-start region)
|
|
|
|
|
;; We expect to end parsing at the end of the
|
|
|
|
|
;; edit region, but this could not be the case
|
|
|
|
|
;; as some handlers ignore point-max.
|
|
|
|
|
:end (point-max)
|
|
|
|
|
:value 'temp-tree-root))
|
|
|
|
|
(parsed)
|
|
|
|
|
(parsed-tree))
|
|
|
|
|
(phpinspect-buffer-with-tree buffer temp-tree
|
|
|
|
|
(with-current-buffer (phpinspect-buffer-buffer buffer)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (phpinspect-region-start region))
|
|
|
|
|
(unless (looking-at
|
|
|
|
|
(phpinspect-handler-regexp
|
|
|
|
|
(phpinspect-token-metadata-handler meta)))
|
|
|
|
|
;; The token type changed, reparsing the parent is
|
|
|
|
|
;; required to determine its new nature.
|
|
|
|
|
(throw 'recurse-parent))
|
|
|
|
|
|
|
|
|
|
(setq parsed
|
|
|
|
|
(funcall handler-function (match-string 0)
|
|
|
|
|
(phpinspect-region-end edit-region)))
|
|
|
|
|
|
|
|
|
|
(phpinspect-set-token-metadata-when-current-buffer
|
|
|
|
|
parsed (phpinspect-region-start region) (point)
|
|
|
|
|
(phpinspect-token-metadata-handler meta)))))
|
|
|
|
|
|
|
|
|
|
(setq parsed-tree
|
|
|
|
|
(phpinspect-tree-detach
|
|
|
|
|
(seq-elt (phpinspect-tree-children temp-tree) 0)))
|
|
|
|
|
(cond ((> (phpinspect-tree-end parsed-tree)
|
|
|
|
|
(+ (phpinspect-region-end region) edit-delta))
|
|
|
|
|
;; Changes in edit region changed meaning of tokens
|
|
|
|
|
;; outside of it.
|
|
|
|
|
(throw 'recurse-parent))
|
|
|
|
|
((< (phpinspect-tree-end parsed-tree)
|
|
|
|
|
(+ (phpinspect-region-end region) edit-delta))
|
|
|
|
|
;; No edits after, but token did not grow to expected
|
|
|
|
|
;; size.
|
|
|
|
|
(unless (phpinspect-edit-tracker-edit-after edit)
|
|
|
|
|
(throw 'recurse-parent)))
|
|
|
|
|
((
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; (with-current-buffer (phpinspect-buffer-buffer buffer)
|
|
|
|
|
;; (let ((edits
|
|
|
|
|
;; (phpinspect-edit-tracker-edits (phpinspect-buffer-edit-tracker buffer)))
|
|
|
|
|
;; (buffer-tree (phpinspect-buffer-tree buffer)))
|
|
|
|
|
;; (unwind-protect
|
|
|
|
|
;; (progn
|
|
|
|
|
;; (seq-doseq (edit edits)
|
|
|
|
|
;; (let* ((edit-region (phpinspect-edit-region edit))
|
|
|
|
|
;; (metas (phpinspect-tree-find-smallest-overlapping-set
|
|
|
|
|
;; buffer-tree edit-region)))
|
|
|
|
|
;; (condition-case err
|
|
|
|
|
;; (dolist (meta metas)
|
|
|
|
|
;; (setq meta (gv-deref meta))
|
|
|
|
|
;; (let ((region (phpinspect-token-metadata-region meta))
|
|
|
|
|
;; (handler-function (symbol-function
|
|
|
|
|
;; (phpinspect-token-metadata-handler meta)))
|
|
|
|
|
;; (temp-tree (phpinspect-make-tree
|
|
|
|
|
;; ;; We start parsing at the start of the token
|
|
|
|
|
;; :start (phpinspect-region-start region)
|
|
|
|
|
;; ;; We expect to end parsing at the end of the edit region
|
|
|
|
|
;; :end (phpinspect-region-end edit-region)
|
|
|
|
|
;; :value 'temp-tree-root))
|
|
|
|
|
;; (parse-result)
|
|
|
|
|
;; (parse-result-tree))
|
|
|
|
|
;; (save-excursion
|
|
|
|
|
;; (goto-char (phpinspect-region-start region))
|
|
|
|
|
;; ;; Override buffer tree
|
|
|
|
|
;; (setf (phpinspect-buffer-tree buffer) temp-tree)
|
|
|
|
|
;; (setq parse-result (funcall handler-function))
|
|
|
|
|
|
|
|
|
|
;; (phpinspect-set-token-metadata-when-current-buffer
|
|
|
|
|
;; parse-result (phpinspect-region-start region) (point)
|
|
|
|
|
;; (phpinspect-token-metadata-handler meta))
|
|
|
|
|
|
|
|
|
|
;; (if (eq (phpinspect-tree-value temp-tree) 'temp-tree-root)
|
|
|
|
|
;; (setq parse-result-tree
|
|
|
|
|
;; (phpinspect-tree-detach
|
|
|
|
|
;; (seq-elt (phpinspect-tree-children temp-tree) 0)))
|
|
|
|
|
;; ;; New token width exceeds edit region.
|
|
|
|
|
;; (phpinspect-buffer-queue-full-parse buffer)
|
|
|
|
|
;; (throw 'break))
|
|
|
|
|
|
|
|
|
|
;; New token region encloses editen region, stop parsing.
|
|
|
|
|
;; (let* ((new-meta (gv-deref (phpinspect-tree-value parse-result-tree)))
|
|
|
|
|
;; (new-token (phpinspect-token-metadata-token new-meta)))
|
|
|
|
|
;; (if (and (phpinspect-incomplete-token-p new-token)
|
|
|
|
|
;; (phpinspect-edit-tracker-edit-after
|
|
|
|
|
;; (phpinspect-buffer-edit-tracker buffer) edit))
|
|
|
|
|
;; ;; The token is incomplete, and there are edits after this token
|
|
|
|
|
|
|
|
|
|
;; (when (phpinspect-region-encloses new-meta edit-region)
|
|
|
|
|
;; (throw 'break))))))
|
|
|
|
|
;; (break)))))
|
|
|
|
|
;; ;; Restore buffer tree
|
|
|
|
|
;; (setf (phpinspect-buffer-tree buffer) buffer-tree)))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; (if (< 1 (length metas))
|
|
|
|
|
;; (setq reparse-meta (phpinspect-tree-value
|
|
|
|
|
;; (phpinspect-tree-parent
|
|
|
|
|
;; (phpinspect-token-metadata-tree (car metas)))))
|
|
|
|
|
;; (setq reparse-meta (car metas)))
|
|
|
|
|
|
|
|
|
|
;; (if reparse-meta
|
|
|
|
|
;; (phpinspect-buffer-reparse buffer reparse-meta edit)
|
|
|
|
|
;; ;; Nothing found to reparse.. Just reparse entire buffer to be sure
|
|
|
|
|
;; (phpinspect--log "[WARNING] phpinspect-buffer-parse-incrementally: No reparsable tokens found, reparsing entire buffer.")
|
|
|
|
|
;; (phpinspect-buffer-parse buffer))))))
|
|
|
|
|
|
|
|
|
|
(cl-defmethod phpinspect-buffer-set-token-metadata
|
|
|
|
|
((buffer phpinspect-buffer) token (metadata phpinspect-token-metadata))
|
|
|
|
|
"Set the METADATA associated with TOKEN that was parsed in BUFFER"
|
|
|
|
@ -255,7 +126,6 @@ linked with."
|
|
|
|
|
metadata)))
|
|
|
|
|
(setf (phpinspect-token-metadata-tree metadata) tree-node))))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(cl-defmethod phpinspect-buffer-get-token-metadata ((buffer phpinspect-buffer) token)
|
|
|
|
|
(let ((ref (gethash token (phpinspect-buffer-metadata-map buffer))))
|
|
|
|
|
(when ref (gv-deref ref))))
|
|
|
|
@ -268,9 +138,12 @@ linked with."
|
|
|
|
|
(phpinspect-tree-traverse-overlappig (phpinspect-buffer-tree buffer) point)))
|
|
|
|
|
|
|
|
|
|
(cl-defstruct (phpinspect-edit-tracker (:constructor phpinspect-make-edit-tracker))
|
|
|
|
|
(edits (phpinspect-make-ll)))
|
|
|
|
|
(edits (phpinspect-make-queue)))
|
|
|
|
|
|
|
|
|
|
(cl-defstruct (phpinspect-edit (:constructor phpinspect-make-edit))
|
|
|
|
|
(contents ""
|
|
|
|
|
:type string
|
|
|
|
|
:documentation "The contents of the edit")
|
|
|
|
|
(region nil
|
|
|
|
|
:type phpinspect-region
|
|
|
|
|
:documentation
|
|
|
|
@ -280,98 +153,14 @@ linked with."
|
|
|
|
|
:documentation
|
|
|
|
|
"The change in width of the edit region"))
|
|
|
|
|
|
|
|
|
|
(cl-defmethod phpinspect-edit-concat ((edit1 phpinspect-edit) (edit2 phpinspect-edit))
|
|
|
|
|
"Absorb EDIT2 into EDIT1. Returns EDIT1."
|
|
|
|
|
(let ((min) (max) (delta)
|
|
|
|
|
(region1 (phpinspect-edit-region edit1))
|
|
|
|
|
(region2 (phpinspect-edit-region edit2)))
|
|
|
|
|
(if (< (phpinspect-region-start region1)
|
|
|
|
|
(phpinspect-region-start region2))
|
|
|
|
|
(setq min (phpinspect-region-start region1))
|
|
|
|
|
(setq min (phpinspect-region-start region2)))
|
|
|
|
|
|
|
|
|
|
(if (> (phpinspect-region-end region1)
|
|
|
|
|
(phpinspect-region-end region2))
|
|
|
|
|
(setq max (phpinspect-region-end region1))
|
|
|
|
|
(setq max (phpinspect-region-end region2)))
|
|
|
|
|
|
|
|
|
|
(setq delta (+ (phpinspect-edit-delta edit1)
|
|
|
|
|
(phpinspect-edit-delta edit2)))
|
|
|
|
|
|
|
|
|
|
(setf (phpinspect-edit-delta edit1) delta)
|
|
|
|
|
(setf (phpinspect-edit-region edit1) (phpinspect-make-region min max))
|
|
|
|
|
edit1))
|
|
|
|
|
|
|
|
|
|
(cl-defmethod phpinspect-edit-overlaps ((edit1 phpinspect-edit) (edit2 phpinspect-edit))
|
|
|
|
|
(phpinspect-region-overlaps (phpinspect-edit-region edit1)
|
|
|
|
|
(phpinspect-edit-region edit2)))
|
|
|
|
|
|
|
|
|
|
(cl-defmethod phpinspect-edit-could-overlap ((edit1 phpinspect-edit) (edit2 phpinspect-edit))
|
|
|
|
|
(> (phpinspect-region-end (phpinspect-edit-region edit1))
|
|
|
|
|
(phpinspect-region-start (phpinspect-edit-region edit2))))
|
|
|
|
|
|
|
|
|
|
(cl-defmethod phpinspect-edit-tracker-mark
|
|
|
|
|
((tracker phpinspect-edit-tracker) (start integer) (end integer) (pre-change-length integer))
|
|
|
|
|
(let* ((edits (phpinspect-edit-tracker-edits tracker))
|
|
|
|
|
(edit (phpinspect-make-edit :region (phpinspect-make-region start end)
|
|
|
|
|
:delta (- (- end start) pre-change-length)))
|
|
|
|
|
(first-in-range (seq-find (lambda (e) (phpinspect-edit-could-overlap edit e))
|
|
|
|
|
edits))
|
|
|
|
|
(insertion-link)
|
|
|
|
|
(first-overlapper)
|
|
|
|
|
(overlappers))
|
|
|
|
|
|
|
|
|
|
(when first-in-range
|
|
|
|
|
(if (phpinspect-edit-overlaps edit first-in-range)
|
|
|
|
|
(progn
|
|
|
|
|
;; If this is the first overlapper, we should insert before it.
|
|
|
|
|
(setq insertion-link (phpinspect-llnode-left
|
|
|
|
|
(phpinspect-ll-link edits first-in-range)))
|
|
|
|
|
(setq first-overlapper first-in-range))
|
|
|
|
|
;; If this is not an overlapper, we should insert after it, as the
|
|
|
|
|
;; entire region spans a range before the edit.
|
|
|
|
|
(setq insertion-link (phpinspect-ll-link edits first-in-range))))
|
|
|
|
|
|
|
|
|
|
(unless first-overlapper
|
|
|
|
|
(setq first-overlapper (seq-find (lambda (e) (phpinspect-edit-overlaps edit e))
|
|
|
|
|
(or insertion-link
|
|
|
|
|
(phpinspect-ll-link edits first-in-range)))))
|
|
|
|
|
|
|
|
|
|
(when first-overlapper
|
|
|
|
|
(setq overlappers
|
|
|
|
|
(seq-take-while (lambda (e) (phpinspect-edit-overlaps e edit))
|
|
|
|
|
(phpinspect-ll-link edits first-overlapper)))
|
|
|
|
|
|
|
|
|
|
;; Break overlappers away from edit list, as they're about to be replaced.
|
|
|
|
|
(setq overlappers (phpinspect-slice-detach overlappers)))
|
|
|
|
|
|
|
|
|
|
;; Absorb all overlapping edits into our newly created edit
|
|
|
|
|
(seq-doseq (overlap overlappers)
|
|
|
|
|
(phpinspect-edit-concat edit overlap))
|
|
|
|
|
|
|
|
|
|
(if insertion-link
|
|
|
|
|
(phpinspect-ll-insert-right insertion-link edit)
|
|
|
|
|
(phpinspect-ll-push edit edits))))
|
|
|
|
|
|
|
|
|
|
(cl-defmethod phpinspect-edit-tracker-unmark
|
|
|
|
|
((tracker phpinspect-edit-tracker) (start integer) (end integer))
|
|
|
|
|
(let* ((region (phpinspect-make-region start end))
|
|
|
|
|
(edits (phpinspect-edit-tracker-edits tracker))
|
|
|
|
|
(first-enclosing
|
|
|
|
|
(seq-find (lambda (e) (phpinspect-region-encloses
|
|
|
|
|
region (phpinspect-edit-region e)))
|
|
|
|
|
edits)))
|
|
|
|
|
(when first-enclosing
|
|
|
|
|
(phpinspect-slice-detach
|
|
|
|
|
(seq-take-while (lambda (e) (phpinspect-region-encloses
|
|
|
|
|
region (phpinspect-edit-region e)))
|
|
|
|
|
edits)))))
|
|
|
|
|
(cl-defmethod phpinspect-edit-tracker-register
|
|
|
|
|
((tracker phpinspect-edit-tracker) (start integer) (end integer)
|
|
|
|
|
(pre-change-length integer) (contents string))
|
|
|
|
|
(phpinspect-queue-enqueue
|
|
|
|
|
(phpinspect-edit-tracker-edits tracker)
|
|
|
|
|
(phpinspect-make-edit :region (phpinspect-make-region start end)
|
|
|
|
|
:delta (- (- end start) pre-change-length)
|
|
|
|
|
:contents contents)))
|
|
|
|
|
|
|
|
|
|
(cl-defmethod phpinspect-edit-tracker-edit-after
|
|
|
|
|
((tracker phpinspect-edit-tracker) (edit phpinspect-edit))
|
|
|
|
|
(phpinspect-llnode-value
|
|
|
|
|
(phpinspect-llnode-right
|
|
|
|
|
(phpinspect-ll-link
|
|
|
|
|
(phpinspect-edit-tracker-edits tracker) edit))))
|
|
|
|
|
|
|
|
|
|
(provide 'phpinspect-buffer)
|
|
|
|
|