[gtksourceview: 1/3] javascript.lang (and family): Highlight constructor in class bodies only



commit af64a99725f23b6dbc63598b36f06d8971682a05
Author: Jeffery To <jeffery to gmail com>
Date:   Tue Jul 7 05:30:50 2020 +0800

    javascript.lang (and family): Highlight constructor in class bodies only
    
    Previously, "constructor" would be highlighted as a built-in method in
    all places where a property name is expected, e.g. in object literals
    and object destructuring.
    
    This change causes "constructor" to be highlighted inside class bodies
    only.
    
    Also do not highlight "constructor" if it is combined with other method
    keywords (get, set, async, etc.).

 .../javascript-functions-classes.lang              | 22 ++++++++++++++
 data/language-specs/javascript-literals.lang       | 10 -------
 .../typescript-js-functions-classes.lang           | 22 ++++++++++++++
 tests/syntax-highlighting/file.j                   | 24 +++++++++++++++
 tests/syntax-highlighting/file.js                  | 24 +++++++++++++++
 tests/syntax-highlighting/file.jsx                 | 24 +++++++++++++++
 tests/syntax-highlighting/file.ts                  | 35 ++++++++++++++++++++++
 tests/syntax-highlighting/file.tsx                 | 35 ++++++++++++++++++++++
 8 files changed, 186 insertions(+), 10 deletions(-)
---
diff --git a/data/language-specs/javascript-functions-classes.lang 
b/data/language-specs/javascript-functions-classes.lang
index 3999e8b0..94f872db 100644
--- a/data/language-specs/javascript-functions-classes.lang
+++ b/data/language-specs/javascript-functions-classes.lang
@@ -383,6 +383,25 @@
       </include>
     </context> <!-- /_choice-class-body-keyword-named-method-member -->
 
+    <context id="_choice-class-body-constructor-member" style-ref="js:function-expression" end-parent="true">
+      <start extended="true">
+        \%{js:keyword-start} constructor \%{js:keyword-end}
+      </start>
+      <end>\%{js:before-next-token}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="js:built-in-method"/>
+        <context ref="js:embedded-lang-hooks"/>
+        <context ref="js:comments"/>
+
+        <context id="_class-body-constructor-member-content">
+          <include>
+            <context ref="choice-method-definition"/>
+          </include>
+        </context> <!-- /_class-body-constructor-member-content -->
+
+      </include>
+    </context> <!-- /_choice-class-body-constructor-member -->
+
     <context id="_class-body-members">
       <start>\%{js:before-next-token}</start>
       <end>\%{js:before-next-token}</end>
@@ -395,6 +414,9 @@
             <!-- try to match before and after modifier -->
             <context ref="_choice-class-body-keyword-named-method-member"/>
 
+            <!-- should not be combined with modifier, but cannot prevent it -->
+            <context ref="_choice-class-body-constructor-member"/>
+
             <context ref="_ordered-class-body-member-modifier"/>
 
             <context ref="choice-method-keyword-method-definition"/>
diff --git a/data/language-specs/javascript-literals.lang b/data/language-specs/javascript-literals.lang
index 2736bc95..bccbbc9c 100644
--- a/data/language-specs/javascript-literals.lang
+++ b/data/language-specs/javascript-literals.lang
@@ -285,16 +285,6 @@
 
             <context ref="choice-number"/>
             <context ref="choice-string"/>
-
-            <define-regex id="_special-property-names" extended="true">
-              \%{js:keyword-start} constructor \%{js:keyword-end}
-            </define-regex> <!-- /_special-property-names -->
-
-            <context id="_choice-special-property-name" style-ref="js:built-in-method" end-parent="true">
-              <start>(?=\%{_special-property-names})</start>
-              <end>\%{_special-property-names}</end>
-            </context> <!-- /_choice-special-property-name -->
-
             <context ref="js:choice-identifier-name"/>
           </include>
         </context> <!-- /_property-name-content -->
diff --git a/data/language-specs/typescript-js-functions-classes.lang 
b/data/language-specs/typescript-js-functions-classes.lang
index fb7c61b3..cbab1b70 100644
--- a/data/language-specs/typescript-js-functions-classes.lang
+++ b/data/language-specs/typescript-js-functions-classes.lang
@@ -410,6 +410,26 @@
       </include>
     </context> <!-- /_choice-class-body-keyword-named-property-or-method -->
 
+    <context id="_choice-class-body-constructor-member" style-ref="js:function-expression" end-parent="true">
+      <start extended="true">
+        \%{js:keyword-start} constructor \%{js:keyword-end}
+        (?= \%{js:optional-whitespace-or-comments} \( )
+      </start>
+      <end>\%{js:before-next-token}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="js:built-in-method"/>
+        <context ref="js:comments"/>
+
+        <context id="_class-body-constructor-member-content">
+          <include>
+            <context ref="_ordered-class-body-method-parameters-list"/>
+            <context ref="js-fn:_last-function-body"/>
+          </include>
+        </context> <!-- /_class-body-constructor-member-content -->
+
+      </include>
+    </context> <!-- /_choice-class-body-constructor-member -->
+
     <!-- modifier order:
          * accessibility ("public" / "protected" / "private")
          * "abstract" / "static" (mutually exclusive)
@@ -444,6 +464,8 @@
         <context ref="_choice-class-body-index-member"/>
         <context ref="_choice-class-body-private-field"/>
         <context ref="_choice-class-body-method-keyword-method-definition"/>
+        <!-- should not be combined with some modifiers, but cannot prevent it -->
+        <context ref="_choice-class-body-constructor-member"/>
 
         <context ref="js-fn:ordered-property-accessor-keyword"/>
         <context ref="js-lit:ordered-property-name"/>
diff --git a/tests/syntax-highlighting/file.j b/tests/syntax-highlighting/file.j
index 3910d7c2..aeb1ccd5 100644
--- a/tests/syntax-highlighting/file.j
+++ b/tests/syntax-highlighting/file.j
@@ -752,6 +752,18 @@ a = class {
     set
     (v) { this.val = v; }
 };
+// Properties/methods called "constructor"
+a = class {
+    *constructor() { this._value = null; }
+    get constructor() { this._value = null; }
+    set constructor() { this._value = null; }
+    async constructor() { this._value = null; }
+    async *constructor() { this._value = null; }
+};
+// Incorrectly highlighted as built-in method
+a = class {
+    static constructor() { this._value = null; }
+};
 
 
 /*
@@ -1010,6 +1022,18 @@ class Foo {
     set
     (v) { this.val = v; }
 }
+// Properties/methods called "constructor"
+class Foo {
+    *constructor() { this._value = null; }
+    get constructor() { this._value = null; }
+    set constructor() { this._value = null; }
+    async constructor() { this._value = null; }
+    async *constructor() { this._value = null; }
+}
+// Incorrectly highlighted as built-in method
+class Foo {
+    static constructor() { this._value = null; }
+}
 
 
 /* Continue statement */
diff --git a/tests/syntax-highlighting/file.js b/tests/syntax-highlighting/file.js
index 3fc84f5f..7a93b3b5 100644
--- a/tests/syntax-highlighting/file.js
+++ b/tests/syntax-highlighting/file.js
@@ -451,6 +451,18 @@ a = class {
     set
     (v) { this.val = v; }
 };
+// Properties/methods called "constructor"
+a = class {
+    *constructor() { this._value = null; }
+    get constructor() { this._value = null; }
+    set constructor() { this._value = null; }
+    async constructor() { this._value = null; }
+    async *constructor() { this._value = null; }
+};
+// Incorrectly highlighted as built-in method
+a = class {
+    static constructor() { this._value = null; }
+};
 
 
 /*
@@ -709,6 +721,18 @@ class Foo {
     set
     (v) { this.val = v; }
 }
+// Properties/methods called "constructor"
+class Foo {
+    *constructor() { this._value = null; }
+    get constructor() { this._value = null; }
+    set constructor() { this._value = null; }
+    async constructor() { this._value = null; }
+    async *constructor() { this._value = null; }
+}
+// Incorrectly highlighted as built-in method
+class Foo {
+    static constructor() { this._value = null; }
+}
 
 
 /* Continue statement */
diff --git a/tests/syntax-highlighting/file.jsx b/tests/syntax-highlighting/file.jsx
index f4364bda..57884099 100644
--- a/tests/syntax-highlighting/file.jsx
+++ b/tests/syntax-highlighting/file.jsx
@@ -512,6 +512,18 @@ a = class {
     set
     (v) { this.val = v; }
 };
+// Properties/methods called "constructor"
+a = class {
+    *constructor() { this._value = null; }
+    get constructor() { this._value = null; }
+    set constructor() { this._value = null; }
+    async constructor() { this._value = null; }
+    async *constructor() { this._value = null; }
+};
+// Incorrectly highlighted as built-in method
+a = class {
+    static constructor() { this._value = null; }
+};
 
 
 /*
@@ -770,6 +782,18 @@ class Foo {
     set
     (v) { this.val = v; }
 }
+// Properties/methods called "constructor"
+class Foo {
+    *constructor() { this._value = null; }
+    get constructor() { this._value = null; }
+    set constructor() { this._value = null; }
+    async constructor() { this._value = null; }
+    async *constructor() { this._value = null; }
+}
+// Incorrectly highlighted as built-in method
+class Foo {
+    static constructor() { this._value = null; }
+}
 
 
 /* Continue statement */
diff --git a/tests/syntax-highlighting/file.ts b/tests/syntax-highlighting/file.ts
index 4271c154..004c0e19 100644
--- a/tests/syntax-highlighting/file.ts
+++ b/tests/syntax-highlighting/file.ts
@@ -486,6 +486,7 @@ class MyClass extends Super implements Super.Sub {}
 a = class {
     property;
     property = 1;
+    constructor = 1;
 };
 
 // Type annotation
@@ -660,6 +661,16 @@ a = class {
     abstract #privateprop;
     declare #privateprop;
 };
+// Constructor not highlighted as built-in method
+a = class {
+    constructor
+    () {}
+};
+// "abstract" and "declare" do not apply to constructors
+a = class {
+    abstract constructor() {}
+    declare constructor() {}
+};
 
 
 /* Expression */
@@ -1224,6 +1235,18 @@ a = class {
     set
     (v) { this.val = v; }
 };
+// Properties/methods called "constructor"
+a = class {
+    *constructor() { this._value = null; }
+    get constructor() { this._value = null; }
+    set constructor() { this._value = null; }
+    async constructor() { this._value = null; }
+    async *constructor() { this._value = null; }
+};
+// Incorrectly highlighted as built-in method
+a = class {
+    static constructor() { this._value = null; }
+};
 
 
 /*
@@ -1482,6 +1505,18 @@ class Foo {
     set
     (v) { this.val = v; }
 }
+// Properties/methods called "constructor"
+class Foo {
+    *constructor() { this._value = null; }
+    get constructor() { this._value = null; }
+    set constructor() { this._value = null; }
+    async constructor() { this._value = null; }
+    async *constructor() { this._value = null; }
+}
+// Incorrectly highlighted as built-in method
+class Foo {
+    static constructor() { this._value = null; }
+}
 
 
 /* Continue statement */
diff --git a/tests/syntax-highlighting/file.tsx b/tests/syntax-highlighting/file.tsx
index 8783a8a1..165d75b7 100644
--- a/tests/syntax-highlighting/file.tsx
+++ b/tests/syntax-highlighting/file.tsx
@@ -603,6 +603,7 @@ class MyClass extends Super implements Super.Sub {}
 a = class {
     property;
     property = 1;
+    constructor = 1;
 };
 
 // Type annotation
@@ -777,6 +778,16 @@ a = class {
     abstract #privateprop;
     declare #privateprop;
 };
+// Constructor not highlighted as built-in method
+a = class {
+    constructor
+    () {}
+};
+// "abstract" and "declare" do not apply to constructors
+a = class {
+    abstract constructor() {}
+    declare constructor() {}
+};
 
 
 /* Expression */
@@ -1343,6 +1354,18 @@ a = class {
     set
     (v) { this.val = v; }
 };
+// Properties/methods called "constructor"
+a = class {
+    *constructor() { this._value = null; }
+    get constructor() { this._value = null; }
+    set constructor() { this._value = null; }
+    async constructor() { this._value = null; }
+    async *constructor() { this._value = null; }
+};
+// Incorrectly highlighted as built-in method
+a = class {
+    static constructor() { this._value = null; }
+};
 
 
 /*
@@ -1601,6 +1624,18 @@ class Foo {
     set
     (v) { this.val = v; }
 }
+// Properties/methods called "constructor"
+class Foo {
+    *constructor() { this._value = null; }
+    get constructor() { this._value = null; }
+    set constructor() { this._value = null; }
+    async constructor() { this._value = null; }
+    async *constructor() { this._value = null; }
+}
+// Incorrectly highlighted as built-in method
+class Foo {
+    static constructor() { this._value = null; }
+}
 
 
 /* Continue statement */


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