emacs-elpa-diffs
[Top][All Lists]
Advanced

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

[nongnu] elpa/typescript-mode b99d893a46 1/2: fix(fontlock): fix special


From: ELPA Syncer
Subject: [nongnu] elpa/typescript-mode b99d893a46 1/2: fix(fontlock): fix special forms/ternary mistaken for method declarations
Date: Mon, 15 Aug 2022 15:59:16 -0400 (EDT)

branch: elpa/typescript-mode
commit b99d893a46222e455670d90a337a2d0cd42d8432
Author: Matus Goljer <matus.goljer@gmail.com>
Commit: Matus Goljer <matus.goljer@gmail.com>

    fix(fontlock): fix special forms/ternary mistaken for method declarations
    
    Sometimes a special form such as
    
        if (...) {..}
    
    or a ternary
    
        a ? b(...) : c
    
    might look like a method declaration and then the insides of the
    parentheses get fontified as variables.  Here we add a heuristic to
    discard these cases.  It's not 100% but works in most real-life
    situations.
---
 typescript-mode-general-tests.el | 16 ++++++++++++++++
 typescript-mode.el               | 30 ++++++++++++++++++++++++++++--
 2 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/typescript-mode-general-tests.el b/typescript-mode-general-tests.el
index ff8220b2f5..8522eedeec 100644
--- a/typescript-mode-general-tests.el
+++ b/typescript-mode-general-tests.el
@@ -846,6 +846,22 @@ bbb: Bar,
     (should (eq (get-face-at "aaa") 'font-lock-variable-name-face))
     (should (eq (get-face-at "bbb") 'font-lock-variable-name-face))))
 
+(ert-deftest font-lock/funargs--method--no-fontification-in-ternary ()
+  "Do not apply fontification on a function call inside a ternary
+operator, which might look like method with return type
+declaration."
+  (test-with-fontified-buffer
+      "true ? funcall(helloWorld) : false"
+    (should (eq (get-face-at "helloWorld") nil))))
+
+(ert-deftest font-lock/funargs--method--no-fontification-in-special-form ()
+  "Do not apply fontification inside a special form paren-form,
+such as inside of if/while/switch etc.  These look like method
+declarations without a return type annotation but are not."
+  (test-with-fontified-buffer
+      "if (hello && world) { }"
+    (should (eq (get-face-at "world") nil))))
+
 (defun flyspell-predicate-test (search-for)
   "This function runs a test on
 `typescript--flyspell-mode-predicate'.  `SEARCH-FOR' is a string
diff --git a/typescript-mode.el b/typescript-mode.el
index 47d5c4bd09..47f8fa90f6 100644
--- a/typescript-mode.el
+++ b/typescript-mode.el
@@ -1974,8 +1974,34 @@ and searches for the next token to be highlighted."
               (is-method-def
                (ignore-errors
                  (up-list)
-                 (looking-at-p
-                  (rx (* (or whitespace ?\n)) (or ":" "{"))))))
+                 (and
+                  (or
+                   ;; After the "argument list" is a bracket, this is
+                   ;; either a special form (if, while...) or a method
+                   ;; declaration.
+                   (looking-at-p (rx (* (or whitespace ?\n)) "{"))
+                   ;; After the "argument list" is a colon, this is
+                   ;; either a method declaration with a return type
+                   ;; annotation or ternary form.  We need to discard
+                   ;; the ternary form case.
+                   (and
+                    (looking-at-p (rx (* (or whitespace ?\n)) ":"))
+                    (save-excursion
+                      (backward-sexp 2)
+                      (skip-syntax-backward " >")
+                      (not (eq (char-before) ??)))))
+                  ;; HACK: here we check the fontification of
+                  ;; the "function name".  Because the keywords
+                  ;; are fontified before this check runs, a
+                  ;; keyword would already have been fontified
+                  ;; and therefore we can conclude it is not a
+                  ;; function/method definition.
+                  (save-excursion
+                    (backward-sexp)
+                    (backward-word)
+                    (not (memq
+                          'font-lock-keyword-face
+                          (face-at-point nil t))))))))
           (if is-method-def
               (prog1 (point) (goto-char point-orig))
             (point)))



reply via email to

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