From eca557e73d4ee167ca9decd3f65794236d76e547 Mon Sep 17 00:00:00 2001
From: Daniel Jeong <wise0704@outlook.com>
Date: Wed, 2 Aug 2023 12:41:18 +0000
Subject: [PATCH] Event fields enhancement

- multiple event fields across multiple lines
- default value assignment of each
---
 grammars/csharp.tmLanguage      | 50 +++++++++++++++++++++++----------
 grammars/csharp.tmLanguage.cson | 33 ++++++++++++++--------
 src/csharp.tmLanguage.yml       | 19 ++++++++-----
 test/event.tests.ts             | 45 +++++++++++++++++++++++++++++
 4 files changed, 114 insertions(+), 33 deletions(-)

diff --git a/grammars/csharp.tmLanguage b/grammars/csharp.tmLanguage
index 6517b62..a4a17e5 100644
--- a/grammars/csharp.tmLanguage
+++ b/grammars/csharp.tmLanguage
@@ -1898,8 +1898,8 @@
   )\s+
 )
 (?&lt;interface_name&gt;\g&lt;type_name&gt;\s*\.\s*)?
-(?&lt;event_names&gt;\g&lt;identifier&gt;(?:\s*,\s*\g&lt;identifier&gt;)*)\s*
-(?=\{|;|//|/\*|$)</string>
+(\g&lt;identifier&gt;)\s* # first event name
+(?=\{|;|,|=|//|/\*|$)</string>
         <key>beginCaptures</key>
         <dict>
           <key>1</key>
@@ -1933,19 +1933,8 @@
           </dict>
           <key>9</key>
           <dict>
-            <key>patterns</key>
-            <array>
-              <dict>
-                <key>name</key>
-                <string>entity.name.variable.event.cs</string>
-                <key>match</key>
-                <string>@?[_[:alpha:]][_[:alnum:]]*</string>
-              </dict>
-              <dict>
-                <key>include</key>
-                <string>#punctuation-comma</string>
-              </dict>
-            </array>
+            <key>name</key>
+            <string>entity.name.variable.event.cs</string>
           </dict>
         </dict>
         <key>end</key>
@@ -1960,10 +1949,41 @@
             <key>include</key>
             <string>#event-accessors</string>
           </dict>
+          <dict>
+            <key>name</key>
+            <string>entity.name.variable.event.cs</string>
+            <key>match</key>
+            <string>@?[_[:alpha:]][_[:alnum:]]*</string>
+          </dict>
           <dict>
             <key>include</key>
             <string>#punctuation-comma</string>
           </dict>
+          <dict>
+            <key>begin</key>
+            <string>=</string>
+            <key>beginCaptures</key>
+            <dict>
+              <key>0</key>
+              <dict>
+                <key>name</key>
+                <string>keyword.operator.assignment.cs</string>
+              </dict>
+            </dict>
+            <key>end</key>
+            <string>(?&lt;=,)|(?=;)</string>
+            <key>patterns</key>
+            <array>
+              <dict>
+                <key>include</key>
+                <string>#expression</string>
+              </dict>
+              <dict>
+                <key>include</key>
+                <string>#punctuation-comma</string>
+              </dict>
+            </array>
+          </dict>
         </array>
       </dict>
       <key>property-accessors</key>
diff --git a/grammars/csharp.tmLanguage.cson b/grammars/csharp.tmLanguage.cson
index cc17d2a..eea1727 100644
--- a/grammars/csharp.tmLanguage.cson
+++ b/grammars/csharp.tmLanguage.cson
@@ -1226,8 +1226,8 @@ repository:
         )\\s+
       )
       (?<interface_name>\\g<type_name>\\s*\\.\\s*)?
-      (?<event_names>\\g<identifier>(?:\\s*,\\s*\\g<identifier>)*)\\s*
-      (?=\\{|;|//|/\\*|$)
+      (\\g<identifier>)\\s* # first event name
+      (?=\\{|;|,|=|//|/\\*|$)
     '''
     beginCaptures:
       "1":
@@ -1248,15 +1248,7 @@ repository:
           }
         ]
       "9":
-        patterns: [
-          {
-            name: "entity.name.variable.event.cs"
-            match: "@?[_[:alpha:]][_[:alnum:]]*"
-          }
-          {
-            include: "#punctuation-comma"
-          }
-        ]
+        name: "entity.name.variable.event.cs"
     end: "(?<=\\})|(?=;)"
     patterns: [
       {
@@ -1265,9 +1257,28 @@ repository:
       {
         include: "#event-accessors"
       }
+      {
+        name: "entity.name.variable.event.cs"
+        match: "@?[_[:alpha:]][_[:alnum:]]*"
+      }
       {
         include: "#punctuation-comma"
       }
+      {
+        begin: "="
+        beginCaptures:
+          "0":
+            name: "keyword.operator.assignment.cs"
+        end: "(?<=,)|(?=;)"
+        patterns: [
+          {
+            include: "#expression"
+          }
+          {
+            include: "#punctuation-comma"
+          }
+        ]
+      }
     ]
   "property-accessors":
     begin: "\\{"
diff --git a/src/csharp.tmLanguage.yml b/src/csharp.tmLanguage.yml
index 6947b02..d612064 100644
--- a/src/csharp.tmLanguage.yml
+++ b/src/csharp.tmLanguage.yml
@@ -690,8 +690,8 @@ repository:
         )\s+
       )
       (?<interface_name>\g<type_name>\s*\.\s*)?
-      (?<event_names>\g<identifier>(?:\s*,\s*\g<identifier>)*)\s*
-      (?=\{|;|//|/\*|$)
+      (\g<identifier>)\s* # first event name
+      (?=\{|;|,|=|//|/\*|$)
     beginCaptures:
       '1': { name: keyword.other.event.cs }
       '2':
@@ -706,16 +706,21 @@ repository:
         patterns:
         - include: '#type'
         - include: '#punctuation-accessor'
-      '9':
-        patterns:
-        - name: entity.name.variable.event.cs
-          match: '@?[_[:alpha:]][_[:alnum:]]*'
-        - include: '#punctuation-comma'
+      '9': { name: entity.name.variable.event.cs }
     end: (?<=\})|(?=;)
     patterns:
     - include: '#comment'
     - include: '#event-accessors'
+    - name: entity.name.variable.event.cs
+      match: '@?[_[:alpha:]][_[:alnum:]]*'
     - include: '#punctuation-comma'
+    - begin: '='
+      beginCaptures:
+        '0': { name: keyword.operator.assignment.cs }
+      end: (?<=,)|(?=;)
+      patterns:
+      - include: '#expression'
+      - include: '#punctuation-comma'
 
   property-accessors:
     begin: \{
diff --git a/test/event.tests.ts b/test/event.tests.ts
index 7833a21..6bd09c4 100644
--- a/test/event.tests.ts
+++ b/test/event.tests.ts
@@ -288,5 +288,50 @@ event EventHandler Event // comment
                 Token.Punctuation.CloseBrace,
             ]);
         });
+
+        it("declaration with default value (issue #118)", async () => {
+            const input = Input.InClass(`event EventHandler Event = null;`);
+            const tokens = await tokenize(input);
+
+            tokens.should.deep.equal([
+                Token.Keywords.Event,
+                Token.Type("EventHandler"),
+                Token.Identifiers.EventName("Event"),
+                Token.Operators.Assignment,
+                Token.Literals.Null,
+                Token.Punctuation.Semicolon,
+            ]);
+        });
+
+        it("multiple declarations with default value (issue #118)", async () => {
+            const input = Input.InClass(`
+event EventHandler Event1 = delegate { },
+                   Event2 = () => { }
+                   , Event3 = null;`);
+            const tokens = await tokenize(input);
+
+            tokens.should.deep.equal([
+                Token.Keywords.Event,
+                Token.Type("EventHandler"),
+                Token.Identifiers.EventName("Event1"),
+                Token.Operators.Assignment,
+                Token.Keywords.Delegate,
+                Token.Punctuation.OpenBrace,
+                Token.Punctuation.CloseBrace,
+                Token.Punctuation.Comma,
+                Token.Identifiers.EventName("Event2"),
+                Token.Operators.Assignment,
+                Token.Punctuation.OpenParen,
+                Token.Punctuation.CloseParen,
+                Token.Operators.Arrow,
+                Token.Punctuation.OpenBrace,
+                Token.Punctuation.CloseBrace,
+                Token.Punctuation.Comma,
+                Token.Identifiers.EventName("Event3"),
+                Token.Operators.Assignment,
+                Token.Literals.Null,
+                Token.Punctuation.Semicolon,
+            ]);
+        });
     });
 });