[gtksourceview] typescript.lang: Add support for decorators



commit 09c84a8ea5f1ac928ec02f7a5723e1f714ba5fb6
Author: Jeffery To <jeffery to gmail com>
Date:   Tue Nov 12 03:11:21 2019 +0800

    typescript.lang: Add support for decorators
    
    This adds support for TypeScript's "experimental" decorators[1]. The
    syntax is based on the pre-2019 stage 2 proposal[2][3] with some
    TypeScript-specific additions (parameter decorators, type arguments for
    generic decorator functions).
    
    Fixes #88.
    
    [1]: https://www.typescriptlang.org/docs/handbook/decorators.html
    [2]: https://github.com/tc39/proposal-decorators/tree/master/previous
    [3]: https://tc39.es/proposal-decorators/#sec-syntax

 .../typescript-js-functions-classes.lang           | 18 ++++
 data/language-specs/typescript-js-statements.lang  |  1 +
 data/language-specs/typescript.lang                | 96 +++++++++++++++++++++-
 tests/syntax-highlighting/file.ts                  | 21 +++++
 tests/syntax-highlighting/file.tsx                 | 21 +++++
 5 files changed, 153 insertions(+), 4 deletions(-)
---
diff --git a/data/language-specs/typescript-js-functions-classes.lang 
b/data/language-specs/typescript-js-functions-classes.lang
index 75957749..24e6c113 100644
--- a/data/language-specs/typescript-js-functions-classes.lang
+++ b/data/language-specs/typescript-js-functions-classes.lang
@@ -53,6 +53,10 @@
     <!-- replaces js-fn:_function-parameters-content -->
     <context id="function-parameters-content">
       <include>
+        <!-- decorators are valid for class declaration methods only -->
+        <context ref="typescript:ordered-decorators"/>
+        <!-- accessibility modifiers are valid for class
+             expression/declaration constructors only -->
         <context ref="_ordered-accessibility-modifier"/>
         <context ref="js:ordered-rest-syntax"/>
         <context ref="js:ordered-assignment-target"/>
@@ -72,8 +76,14 @@
 
         <context id="_function-first-parameter-content">
           <include>
+            <!-- decorators are valid for class declaration methods only -->
+            <context ref="typescript:ordered-decorators"/>
+            <!-- accessibility modifiers are valid for class
+                 expression/declaration constructors only -->
             <context ref="_ordered-accessibility-modifier"/>
             <context ref="js:ordered-rest-syntax"/>
+            <!-- this parameters are valid for class
+                 expression/declaration methods only -->
             <context ref="typescript:ordered-this-parameter-or-assignment-target"/>
             <context ref="typescript:ordered-optional-modifier"/>
             <context ref="typescript:ordered-type-annotation"/>
@@ -313,6 +323,14 @@
       </include>
     </context> <!-- /class-body-member-content -->
 
+    <!-- replaces js-fn:_class-body-content -->
+    <context id="class-body-content">
+      <include>
+        <context ref="typescript:decorators"/>
+        <context ref="js-fn:_class-body-content" original="true"/>
+      </include>
+    </context> <!-- /class-body-content -->
+
     <!-- ## Class expression -->
 
     <!-- replaces js-fn:_class-expression-content -->
diff --git a/data/language-specs/typescript-js-statements.lang 
b/data/language-specs/typescript-js-statements.lang
index 259a43ae..87f6cf71 100644
--- a/data/language-specs/typescript-js-statements.lang
+++ b/data/language-specs/typescript-js-statements.lang
@@ -529,6 +529,7 @@
     <!-- replaces js-st:statements -->
     <context id="statements">
       <include>
+        <context ref="typescript:decorators"/>
         <context ref="_ambient-declarations"/>
         <context ref="_const-declarations"/>
         <context ref="_enum-declarations"/>
diff --git a/data/language-specs/typescript.lang b/data/language-specs/typescript.lang
index bfa4b60f..f6327dc4 100644
--- a/data/language-specs/typescript.lang
+++ b/data/language-specs/typescript.lang
@@ -51,6 +51,8 @@
     <!-- General -->
     <style id="optional-modifier"                             name="Optional Modifier"/>
     <style id="definite-assignment-assertion"                 name="Definite Assignment Assertion"/>
+    <style id="decorator"                                     name="Decorator"/>
+    <style id="decorator-operator"                            name="Decorator Operator"/>
     <style id="type-annotation"                               name="Type Annotation"/>
 
     <!-- Type literals -->
@@ -97,10 +99,6 @@
 
          Supported level: TypeScript 3.6
 
-         Not supported yet:
-         * Decorators: Still an experimental feature of TypeScript and
-           a Stage 2 proposal for ECMAScript
-
          Naming conventions described in javascript.lang
     -->
 
@@ -333,6 +331,95 @@
       </include>
     </context> <!-- /ordered-this-parameter-or-assignment-target -->
 
+    <!-- ## Decorators
+
+         @sealed
+         @decorators.required
+         @configurable(false)
+         @(isDebug ? annotate : hideOutput)
+    -->
+
+    <context id="_choice-decorator-primary-expression-parenthesized-expression" end-parent="true">
+      <start>\(</start>
+      <end>\)</end>
+      <include>
+        <context ref="js:comments"/>
+
+        <context id="_decorator-primary-expression-parenthesized-expression-content">
+          <include>
+            <context ref="js-expr:expression-with-comma"/>
+          </include>
+        </context> <!-- /_decorator-primary-expression-parenthesized-expression-content -->
+
+      </include>
+    </context> <!-- /_choice-decorator-primary-expression-parenthesized-expression -->
+
+    <context id="_decorator-primary-expression" once-only="true">
+      <start>\%{js:before-next-token}</start>
+      <end>\%{js:before-next-token}</end>
+      <include>
+        <context ref="js:comments"/>
+
+        <context id="_decorator-primary-expression-content">
+          <include>
+            <context ref="_choice-decorator-primary-expression-parenthesized-expression"/>
+            <context ref="js:choice-identifier"/>
+          </include>
+        </context> <!-- /_decorator-primary-expression-content -->
+
+      </include>
+    </context> <!-- /_decorator-primary-expression -->
+
+    <context id="_ordered-decorator-primary-expression" once-only="true">
+      <start>\%{js:before-next-token}</start>
+      <end>\%{js:before-next-token}</end>
+      <include>
+        <context ref="_decorator-primary-expression"/>
+      </include>
+    </context> <!-- /_ordered-decorator-primary-expression -->
+
+    <context id="_decorator-dot-property-accessors">
+      <start>\.</start>
+      <end>\%{js:before-next-token}</end>
+      <include>
+        <context ref="js:comments"/>
+
+        <context id="_decorator-dot-property-accessor-content">
+          <include>
+            <context ref="js:identifier"/>
+          </include>
+        </context> <!-- /_decorator-dot-property-accessor-content -->
+
+      </include>
+    </context>
+
+    <context id="decorators" style-ref="decorator">
+      <start>@</start>
+      <end>\%{js:before-next-token}</end>
+      <include>
+        <context sub-pattern="0" where="start" style-ref="decorator-operator"/>
+        <context ref="js:comments"/>
+
+        <context id="_decorator-content">
+          <include>
+            <context ref="_ordered-decorator-primary-expression"/>
+            <context ref="_decorator-dot-property-accessors"/>
+            <context ref="typescript-js-expr:_function-call-type-arguments-lists"/>
+            <context ref="js-expr:_function-arguments-lists"/>
+          </include>
+        </context> <!-- /_decorator-content -->
+
+      </include>
+    </context> <!-- /decorators -->
+
+    <context id="ordered-decorators" once-only="true">
+      <start>\%{js:before-next-token}</start>
+      <end>\%{js:before-next-token}</end>
+      <include>
+        <context ref="decorators"/>
+      </include>
+    </context> <!-- /ordered-decorators -->
+
 
     <!-- # Types -->
 
@@ -639,6 +726,7 @@
     <replace id="js-fn:_class-extends-clause-content" ref="typescript-js-fn:class-extends-clause-content"/>
 
     <replace id="js-fn:_class-body-member-content" ref="typescript-js-fn:class-body-member-content"/>
+    <replace id="js-fn:_class-body-content" ref="typescript-js-fn:class-body-content"/>
 
     <replace id="js-fn:_class-expression-content" ref="typescript-js-fn:class-expression-content"/>
     <replace id="js-fn:choice-class-expression" ref="typescript-js-fn:choice-class-expression"/>
diff --git a/tests/syntax-highlighting/file.ts b/tests/syntax-highlighting/file.ts
index 513bae2a..07f9ef08 100644
--- a/tests/syntax-highlighting/file.ts
+++ b/tests/syntax-highlighting/file.ts
@@ -265,6 +265,27 @@ let a: string;
 /// <reference-path
 
 
+/* Decorators (experimental, stage 2 proposal) */
+
+// Class decorator
+@sealed
+class Greeter {
+    // Property decorator
+    @(Deco) /* comment */ . /* comment */ utils /* comment */ () /* comment */ . /* comment */ format /* 
comment */ ("Hello, %s")
+    greeting: string;
+
+    // Method decorator
+    @ /* comment */ (foo = 'bar', false || validate)
+    greet(@required name: string) { // Parameter decorator
+        return "Hello " + name + ", " + this.greeting;
+    }
+
+    // Accessor decorator
+    @configurable<string>(false) /* comment */
+    get x() { return this._x; }
+}
+
+
 /* Ambient declaration */
 
 declare let a;
diff --git a/tests/syntax-highlighting/file.tsx b/tests/syntax-highlighting/file.tsx
index f28c1874..35962a15 100644
--- a/tests/syntax-highlighting/file.tsx
+++ b/tests/syntax-highlighting/file.tsx
@@ -368,6 +368,27 @@ let a: string;
 /// <reference-path
 
 
+/* Decorators (experimental, stage 2 proposal) */
+
+// Class decorator
+@sealed
+class Greeter {
+    // Property decorator
+    @(Deco) /* comment */ . /* comment */ utils /* comment */ () /* comment */ . /* comment */ format /* 
comment */ ("Hello, %s")
+    greeting: string;
+
+    // Method decorator
+    @ /* comment */ (foo = 'bar', false || validate)
+    greet(@required name: string) { // Parameter decorator
+        return "Hello " + name + ", " + this.greeting;
+    }
+
+    // Accessor decorator
+    @configurable<string>(false) /* comment */
+    get x() { return this._x; }
+}
+
+
 /* Ambient declaration */
 
 declare let a;


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