emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] feature/jsx 9e4519f 1/3: Optimize js-jsx--matching-close-t


From: Jackson Ray Hamilton
Subject: [Emacs-diffs] feature/jsx 9e4519f 1/3: Optimize js-jsx--matching-close-tag-pos
Date: Sun, 7 Apr 2019 19:04:21 -0400 (EDT)

branch: feature/jsx
commit 9e4519fb043aee11e85ae9758a3916ccbfaa3035
Author: Jackson Ray Hamilton <address@hidden>
Commit: Jackson Ray Hamilton <address@hidden>

    Optimize js-jsx--matching-close-tag-pos
    
    This function’s performance was having a noticeable impact when
    editing large JSX structures.  Improve its performance
    slightly (elapsed time will be cut in half according to ELP).
    
    * lisp/progmodes/js.el (js-jsx--tag-re): Remove.
    (js-jsx--matched-tag-type): Simplify implementation with respect to
    the new implementation of js-jsx--matching-close-tag-pos.
    (js-jsx--self-closing-re): Simplify regexp slightly in sync with a
    generally simpler matching algorithm.
    (js-jsx--matching-close-tag-pos): Optimize matching algorithm by using
    multiple simple regexp searches, rather than one big complex search.
    
    * test/manual/indent/jsx-unclosed-2.jsx: Use the term “inequality” and
    add a test for a possible parsing foible.
---
 lisp/progmodes/js.el                  | 67 ++++++++++++++++-------------------
 test/manual/indent/jsx-unclosed-2.jsx |  7 +++-
 2 files changed, 37 insertions(+), 37 deletions(-)

diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index 2d29d4e..694a79f 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -1906,26 +1906,23 @@ For use by `syntax-propertize-extend-region-functions'."
                 (throw 'stop nil)))))))
     (if new-start (cons new-start end))))
 
-(defconst js-jsx--tag-re
-  (concat "<\\s-*\\("
-          "[/>]" ; JSXClosingElement, or JSXOpeningFragment, or 
JSXClosingFragment
-          "\\|"
-          js--dotted-name-re "\\s-*[" js--name-start-chars "{/>]" ; 
JSXOpeningElement
-          "\\)")
-  "Regexp unambiguously matching a JSXBoundaryElement.")
+(defconst js-jsx--tag-start-re
+  (concat js--dotted-name-re "\\s-*[" js--name-start-chars "{/>]")
+  "Regexp unambiguously matching a JSXOpeningElement.")
 
 (defun js-jsx--matched-tag-type ()
-  "Determine the tag type of the last match to `js-jsx--tag-re'.
+  "Determine if the last “<” was a JSXBoundaryElement and its type.
 Return `close' for a JSXClosingElement/JSXClosingFragment match,
 return `self-closing' for some self-closing JSXOpeningElements,
 else return `other'."
-  (let ((chars (vconcat (match-string 1))))
-    (cond
-     ((= (aref chars 0) ?/) 'close)
-     ((= (aref chars (1- (length chars))) ?/) 'self-closing)
-     (t 'other))))
+  (cond
+   ((= (char-after) ?/) (forward-char) 'close) ; 
JSXClosingElement/JSXClosingFragment
+   ((= (char-after) ?>) (forward-char) 'other) ; JSXOpeningFragment
+   ((looking-at js-jsx--tag-start-re) ; JSXOpeningElement
+    (goto-char (match-end 0))
+    (if (= (char-before) ?/) 'self-closing 'other))))
 
-(defconst js-jsx--self-closing-re "/\\s-*>"
+(defconst js-jsx--self-closing-re "/>"
   "Regexp matching the end of a self-closing JSXOpeningElement.")
 
 (defun js-jsx--matching-close-tag-pos ()
@@ -1934,29 +1931,27 @@ Assuming a JSXOpeningElement or a JSXOpeningFragment is
 immediately before point, find a matching JSXClosingElement or
 JSXClosingFragment, skipping over any nested JSXElements to find
 the match.  Return nil if a match can’t be found."
-  (let ((tag-stack 1) type tag-pos last-pos pos)
+  (let ((tag-stack 1) tag-pos type last-pos pos)
     (catch 'stop
-      (while (re-search-forward js-jsx--tag-re nil t)
-        (setq type (js-jsx--matched-tag-type)
-              tag-pos (match-beginning 0))
-        ;; Clear the stack of any JSXOpeningElements which turned out
-        ;; to be self-closing.
-        (when last-pos
-          (setq pos (point))
-          (goto-char last-pos)
-          (while (re-search-forward js-jsx--self-closing-re pos 'move)
-            (setq tag-stack (1- tag-stack))))
-        (if (eq type 'close)
-            (progn
-              (setq tag-stack (1- tag-stack))
-              (when (= tag-stack 0)
-                (throw 'stop tag-pos)))
-          ;; JSXOpeningElements that we know are self-closing aren’t
-          ;; added to the stack at all (since re-search-forward moves
-          ;; point after their self-closing syntax).
-          (unless (eq type 'self-closing)
-            (setq tag-stack (1+ tag-stack))))
-        (setq last-pos (point))))))
+      (while (and (re-search-forward "<" nil t) (not (eobp)))
+        (when (setq tag-pos (match-beginning 0)
+                    type (js-jsx--matched-tag-type))
+          (when last-pos
+            (setq pos (point))
+            (goto-char last-pos)
+            (while (re-search-forward js-jsx--self-closing-re pos 'move)
+              (setq tag-stack (1- tag-stack))))
+          (if (eq type 'close)
+              (progn
+                (setq tag-stack (1- tag-stack))
+                (when (= tag-stack 0)
+                  (throw 'stop tag-pos)))
+            ;; JSXOpeningElements that we know are self-closing aren’t
+            ;; added to the stack at all (because point is already
+            ;; past that syntax).
+            (unless (eq type 'self-closing)
+              (setq tag-stack (1+ tag-stack))))
+          (setq last-pos (point)))))))
 
 (defun js-jsx--enclosing-curly-pos ()
   "Return position of enclosing “{” in a “{/}” pair about point."
diff --git a/test/manual/indent/jsx-unclosed-2.jsx 
b/test/manual/indent/jsx-unclosed-2.jsx
index 8db25aa..9d80a2e 100644
--- a/test/manual/indent/jsx-unclosed-2.jsx
+++ b/test/manual/indent/jsx-unclosed-2.jsx
@@ -6,10 +6,15 @@
 // The following tests go below any comments to avoid including
 // misindented comments among the erroring lines.
 
-// Don’t misinterpret equality operators as JSX.
+// Don’t misinterpret inequality operators as JSX.
 for (; i < length;) void 0
 if (foo > bar) void 0
 
+// Don’t misintrepet inequalities within JSX, either.
+<div>
+  {foo < bar}
+</div>
+
 // Don’t even misinterpret unary operators as JSX.
 if (foo < await bar) void 0
 while (await foo > bar) void 0



reply via email to

[Prev in Thread] Current Thread [Next in Thread]