[vscode] Fix modifiers highlighting

Prior to this change, declarations with multiple modifiers like
`resource flexible struct{}` would result in only the last modifier
being highlighted as such.

Change-Id: Ic84d49d03b6bc89a61e7627d8781cec7956de753
Reviewed-on: https://fuchsia-review.googlesource.com/c/fidl-misc/+/661810
Reviewed-by: Mitchell Kember <mkember@google.com>
diff --git a/vscode-language-fidl/syntaxes/fidl.tmLanguage.json b/vscode-language-fidl/syntaxes/fidl.tmLanguage.json
index 4f4cc7e..f639f2a 100644
--- a/vscode-language-fidl/syntaxes/fidl.tmLanguage.json
+++ b/vscode-language-fidl/syntaxes/fidl.tmLanguage.json
@@ -426,16 +426,16 @@
             "patterns": [
                 {
                     "name": "meta.type-constructor-inline.fidl",
-                    "begin": "(?:(?:\\b(strict)\\b|\\b(flexible)\\b|\\b(resource)\\b)\\s*)*\\s*(?:\\b(union)\\b|\\b(struct)\\b|\\b(table)\\b|\\b(enum)\\b|\\b(bits)\\b)\\s*(?:(:)\\s*(\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*))?\\s*{",
+                    "begin": "((?:(?:\\bstrict\\b|\\bflexible\\b|\\bresource\\b)\\s*)*)\\s*(?:\\b(union)\\b|\\b(struct)\\b|\\b(table)\\b|\\b(enum)\\b|\\b(bits)\\b)\\s*(?:(:)\\s*(\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*))?\\s*{",
                     "beginCaptures": {
                         "1": {
                             "name": "storage.type.modifier"
                         },
                         "2": {
-                            "name": "storage.type.modifier"
+                            "name": "keyword.control"
                         },
                         "3": {
-                            "name": "storage.type.modifier"
+                            "name": "keyword.control"
                         },
                         "4": {
                             "name": "keyword.control"
@@ -447,15 +447,9 @@
                             "name": "keyword.control"
                         },
                         "7": {
-                            "name": "keyword.control"
-                        },
-                        "8": {
-                            "name": "keyword.control"
-                        },
-                        "9": {
                             "name": "punctuation.separator"
                         },
-                        "10": {
+                        "8": {
                             "name": "entity.name.type"
                         }
                     },
@@ -522,7 +516,7 @@
             "patterns": [
                 {
                     "name": "meta.type-constructor-inline-arg.fidl",
-                    "begin": "(\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)\\s*<\\s*(?:(?:\\b(strict)\\b|\\b(flexible)\\b|\\b(resource)\\b)\\s*)*\\s*(?:\\b(union)\\b|\\b(struct)\\b|\\b(table)\\b|\\b(enum)\\b|\\b(bits)\\b)\\s*(?:(:)\\s*(\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*))?\\s*{",
+                    "begin": "(\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*)\\s*<\\s*((?:(?:\\bstrict\\b|\\bflexible\\b|\\bresource\\b)\\s*)*)\\s*(?:\\b(union)\\b|\\b(struct)\\b|\\b(table)\\b|\\b(enum)\\b|\\b(bits)\\b)\\s*(?:(:)\\s*(\\b[a-zA-Z_][0-9a-zA-Z_]*\\b(?:\\.\\b[a-zA-Z_][0-9a-zA-Z_]*\\b)*))?\\s*{",
                     "beginCaptures": {
                         "1": {
                             "name": "entity.name.type"
@@ -531,10 +525,10 @@
                             "name": "storage.type.modifier"
                         },
                         "3": {
-                            "name": "storage.type.modifier"
+                            "name": "keyword.control"
                         },
                         "4": {
-                            "name": "storage.type.modifier"
+                            "name": "keyword.control"
                         },
                         "5": {
                             "name": "keyword.control"
@@ -546,15 +540,9 @@
                             "name": "keyword.control"
                         },
                         "8": {
-                            "name": "keyword.control"
-                        },
-                        "9": {
-                            "name": "keyword.control"
-                        },
-                        "10": {
                             "name": "punctuation.separator"
                         },
-                        "11": {
+                        "9": {
                             "name": "entity.name.type"
                         }
                     },
diff --git a/vscode-language-fidl/test.test.fidl b/vscode-language-fidl/test.test.fidl
index 5bddb69..e7ef5ce 100644
--- a/vscode-language-fidl/test.test.fidl
+++ b/vscode-language-fidl/test.test.fidl
@@ -30,10 +30,10 @@
 
 // hi
 type Foo = struct {};
-type Foo2 = resource struct {};
-type Bar = resource flexible union {};
-
-type Foo = flexible enum : uint32 {}; //
+type Bar = resource struct {};
+type Baz = resource flexible union {};
+type Qux = resource flexible strict table {};
+type Yay = flexible enum : uint32 {}; //
 
 @foobar
 type Foo = struct {
diff --git a/vscode-language-fidl/tools/generate-syntax.ts b/vscode-language-fidl/tools/generate-syntax.ts
index a0e5b29..da6c2fb 100644
--- a/vscode-language-fidl/tools/generate-syntax.ts
+++ b/vscode-language-fidl/tools/generate-syntax.ts
@@ -229,10 +229,6 @@
   return word(named(keyword, name));
 }
 
-function modifier_keyword(modifier: string) {
-  return keyword(modifier, "storage.type.modifier");
-}
-
 function separator(sep: string) {
   return named(sep, "punctuation.separator");
 }
@@ -266,13 +262,13 @@
   IDENTIFIER
 ), "entity.other.attribute-name");
 
-const MODIFIERS = zero_or_more(
+const MODIFIERS = named(zero_or_more(
   one_of(
-    modifier_keyword("strict"),
-    modifier_keyword("flexible"),
-    modifier_keyword("resource")
+    word("strict"),
+    word("flexible"),
+    word("resource"),
   )
-);
+), "storage.type.modifier");
 
 const ORDINAL = seq(NUMERIC_LITERAL, separator(":"));
 
@@ -324,8 +320,13 @@
 NUMERIC_CONSTANT.assert("0");
 NUMERIC_CONSTANT.assert("ABC");
 
-MODIFIERS.assert("strict resource");
+MODIFIERS.assert("strict");
 MODIFIERS.assert("flexible");
+MODIFIERS.assert("resource");
+MODIFIERS.assert("strict resource");
+MODIFIERS.assert("flexible resource");
+MODIFIERS.assert("resource strict");
+MODIFIERS.assert("resource flexible");
 
 TYPE_PARAMETERS.assert("<Foo, 3>");
 TYPE_PARAMETERS.assert("<Foo>");