From d0e9a89926a3ecbe84a31719e4b4b487b77854f4 Mon Sep 17 00:00:00 2001 From: sslinky Date: Fri, 17 Jan 2025 14:15:01 +0800 Subject: [PATCH 01/35] Spelling --- snippets/vba.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/snippets/vba.json b/snippets/vba.json index ec4e546..68300fa 100644 --- a/snippets/vba.json +++ b/snippets/vba.json @@ -5,7 +5,7 @@ "body": [ "Private m${1:PropertyName} As ${2:PropertyType}", "Public Property Let $1(var As $2)", - "Attribute $1.VB_Description = \"${3:Dosctring}.\"", + "Attribute $1.VB_Description = \"${3:docstring}.\"", "' $3.", " m$1 = var", "End Property", @@ -23,7 +23,7 @@ "body": [ "Private m${1:PropertyName} As ${2:PropertyType}", "Public Property Set $1(var As $2)", - "Attribute $1.VB_Description = \"${3:Dosctring}.\"", + "Attribute $1.VB_Description = \"${3:docstring}.\"", "' $3.", " Set m$1 = var", "End Property", @@ -40,7 +40,7 @@ "description": "Property get only", "body": [ "Public Property Get ${1:PropertyName}() As ${2:PropertyType}", - "Attribute $1.VB_Description = \"${3:Dosctring}.\"", + "Attribute $1.VB_Description = \"${3:docstring}.\"", "' $3.", " $0", "End Property", @@ -52,7 +52,7 @@ "description": "Subroutine", "body": [ "${1:Public }Sub ${2:Identifier}($3)", - "Attribute $2.VB_Description = \"${4:Dosctring}.\"", + "Attribute $2.VB_Description = \"${4:docstring}.\"", "' $4.", "'", "' Args:", @@ -70,7 +70,7 @@ "description": "Function", "body": [ "${1:Public }Function ${2:Identifier}($3) As ${4:Variant}", - "Attribute $2.VB_Description = \"${5:Dosctring}.\"", + "Attribute $2.VB_Description = \"${5:docstring}.\"", "' $5.", "'", "' Args:", From c7f2d45fff31dcb31001892ada6db734c7f60d5b Mon Sep 17 00:00:00 2001 From: sslinky Date: Fri, 17 Jan 2025 16:18:42 +0800 Subject: [PATCH 02/35] Semantic token not required here --- server/src/project/elements/typing.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/src/project/elements/typing.ts b/server/src/project/elements/typing.ts index 5b9d98d..ba28953 100644 --- a/server/src/project/elements/typing.ts +++ b/server/src/project/elements/typing.ts @@ -107,11 +107,11 @@ export class DeclarationStatementElement exte } -export class VariableDeclarationElement extends BaseContextSyntaxElement implements HasDiagnosticCapability, HasSymbolInformationCapability, HasSemanticTokenCapability { +export class VariableDeclarationElement extends BaseContextSyntaxElement implements HasDiagnosticCapability, HasSymbolInformationCapability { //, HasSemanticTokenCapability { identifierCapability: IdentifierCapability; diagnosticCapability: DiagnosticCapability; symbolInformationCapability: SymbolInformationCapability; - semanticTokenCapability: SemanticTokenCapability; + // semanticTokenCapability: SemanticTokenCapability; private _isPublic: boolean; get isPublic(): boolean { return this._isPublic; } @@ -121,7 +121,7 @@ export class VariableDeclarationElement extends BaseContextSyntaxElement ctx.ambiguousIdentifier()}); } } From 2383df72256457fff217cba141498733bcb37056 Mon Sep 17 00:00:00 2001 From: sslinky Date: Fri, 17 Jan 2025 16:19:49 +0800 Subject: [PATCH 03/35] Add method attributes --- client/src/syntaxes/vba.tmLanguage.yaml | 26 ++++++- test/textmate/unit/methodAttributes.vba | 96 +++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 test/textmate/unit/methodAttributes.vba diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index 49465bc..e8f0248 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -614,7 +614,23 @@ repository: - include: "#types" patterns: - include: "#arguments" - + + methodAttribute: + name: source.method.attribute.vba + match: (?i)^\s*(Attribute)\s+([a-z][a-z0-9_]*)(\.VB_(?:Description|UserMemId))\s+(=)\s+(.*) + captures: + 1: + name: entity.other.attribute-name.vba + 2: + name: entity.name.function.vba + 3: + name: entity.other.attribute-name.vba + 4: + name: keyword.operator.comparison.vba + 5: + patterns: + - include: "#literals" + methodClose: name: storage.type.method.close.vba match: (?i)^\s*End\s+(Sub|Function|Property) @@ -644,8 +660,10 @@ repository: block: patterns: + - include: "#testing" - include: "#variableDeclarations" - include: "#variableAssignment" + - include: "#methodAttribute" - include: "#methodClose" - include: "#language" @@ -695,14 +713,14 @@ repository: - include: "#types" constDeclaration: name: storage.const-declaration.vba - match: ^\s*((?i)(?:(?:Public|Private)\s+)?Const)\s+([A-Z][A-Z0-9_]*)([&%#!@$^])?((?i)\s+As\s+[A-Z][A-Z0-9_]*)?(.*) + match: (?i)^\s*((?:(?:Public|Private)\s+)?Const)\s+([a-z][a-z0-9_]*)([&%#!@$^])?(\s+As\s+[a-z][a-z0-9_]*)?(.*) captures: 1: # Public|Private Const name: storage.type.vba 2: # CONSTNAME - name: variable.other.constant.vba + name: variable.other.constant 3: # Type hint? name: support.type.primitive.vba @@ -956,6 +974,8 @@ repository: match: ^brackethighlighter.unmatched$ - name: constant.other.reference.link match: ^constant.other.reference.link$ + - name: constant.other.identifier.vba + match: ^constant.other.identifier.vba$ - name: string.other.link match: ^string.other.link$ - name: entity.name.tag.yaml diff --git a/test/textmate/unit/methodAttributes.vba b/test/textmate/unit/methodAttributes.vba new file mode 100644 index 0000000..b148536 --- /dev/null +++ b/test/textmate/unit/methodAttributes.vba @@ -0,0 +1,96 @@ +' SYNTAX TEST "source.vba" "comments" + +Public Function Identifier() As Variant +Attribute Identifier.VB_Description = "Docstring." +' <-------------------------------------------------- source.method.attribute.vba +' <--------- entity.other.attribute-name.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^^^ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^^^^^^^^^^^^ string.quoted.double.vba + +Attribute Identifier.VB_UserMemId = 0 +' <------------------------------------- source.method.attribute.vba +' <--------- entity.other.attribute-name.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^ constant.numeric.vba + +End Function + +Public Sub Identifier() +Attribute Identifier.VB_Description = "Docstring." +' <-------------------------------------------------- source.method.attribute.vba +' <--------- entity.other.attribute-name.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^^^ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^^^^^^^^^^^^ string.quoted.double.vba + +Attribute Identifier.VB_UserMemId = 0 +' <------------------------------------- source.method.attribute.vba +' <--------- entity.other.attribute-name.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^ constant.numeric.vba + +End Sub + +Public Property Let Identifier(var As PropertyType) +Attribute Identifier.VB_Description = "Docstring." +' <-------------------------------------------------- source.method.attribute.vba +' <--------- entity.other.attribute-name.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^^^ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^^^^^^^^^^^^ string.quoted.double.vba + +Attribute Identifier.VB_UserMemId = 0 +' <------------------------------------- source.method.attribute.vba +' <--------- entity.other.attribute-name.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^ constant.numeric.vba + +End Property + +Public Property Get Identifier() As PropertyType +Attribute Identifier.VB_Description = "Docstring." +' <-------------------------------------------------- source.method.attribute.vba +' <--------- entity.other.attribute-name.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^^^ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^^^^^^^^^^^^ string.quoted.double.vba + +Attribute Identifier.VB_UserMemId = 0 +' <------------------------------------- source.method.attribute.vba +' <--------- entity.other.attribute-name.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^ constant.numeric.vba + +End Property + +Public Property Let Identifier(var As PropertyType) +Attribute Identifier.VB_Description = "Docstring." +' <-------------------------------------------------- source.method.attribute.vba +' <--------- entity.other.attribute-name.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^^^ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^^^^^^^^^^^^ string.quoted.double.vba + +Attribute Identifier.VB_UserMemId = 0 +' <------------------------------------- source.method.attribute.vba +' <--------- entity.other.attribute-name.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^ constant.numeric.vba + +End Property \ No newline at end of file From 57a23a91454e5d49e3a9a221846503560a31a0ae Mon Sep 17 00:00:00 2001 From: sslinky Date: Fri, 17 Jan 2025 16:19:58 +0800 Subject: [PATCH 04/35] Update tests --- test/textmate/unit/classHeaders.vba | 57 ++++++++++++++++++++ test/textmate/unit/{module => }/comments.vba | 0 test/textmate/unit/module/classHeaders.vba | 57 -------------------- test/textmate/unit/module/moduleHeaders.vba | 10 ---- test/textmate/unit/moduleHeaders.vba | 10 ++++ 5 files changed, 67 insertions(+), 67 deletions(-) create mode 100644 test/textmate/unit/classHeaders.vba rename test/textmate/unit/{module => }/comments.vba (100%) delete mode 100644 test/textmate/unit/module/classHeaders.vba delete mode 100644 test/textmate/unit/module/moduleHeaders.vba create mode 100644 test/textmate/unit/moduleHeaders.vba diff --git a/test/textmate/unit/classHeaders.vba b/test/textmate/unit/classHeaders.vba new file mode 100644 index 0000000..368bdc5 --- /dev/null +++ b/test/textmate/unit/classHeaders.vba @@ -0,0 +1,57 @@ +' SYNTAX TEST "source.vba" "class headers" + + +VERSION 1.0 CLASS +' <---------------- entity.other.attribute-name.block.vba +' ^^^ constant.numeric.vba + +BEGIN +' <----- entity.other.attribute-name.block.vba + + MultiUse = -1 'True +' ^^^^^^^^^^^^^^^^^^^^ entity.other.attribute-name.block.vba +' ^ keyword.operator.comparison.vba +' ^^ constant.numeric.vba +' ^^^^^ comment.line.apostrophe.vba + +END +' <--- entity.other.attribute-name.block.vba + +Attribute VB_Name = "ClassName" +' <------------------------------ meta.attribute.vba +' <---------------- entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^^^^^^^^^^^ string.quoted.double.vba + +Attribute VB_Description = "Class description goes here" +' <------------------------------------------------------- meta.attribute.vba +' <-------------------- entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.vba + +Attribute VB_GlobalNameSpace = False +' <----------------------------------- meta.attribute.vba +' <------------------------ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^^^^^ constant.language.boolean.vba + +Attribute VB_Creatable = False +' <----------------------------- meta.attribute.vba +' <------------------ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^^^^^ constant.language.boolean.vba + +Attribute VB_PredeclaredId = False +' <--------------------------------- meta.attribute.vba +' <------------------------- entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^^^^^ constant.language.boolean.vba + +Attribute VB_Exposed = False +' <--------------------------- meta.attribute.vba +' <------------------- entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^^^^^ constant.language.boolean.vba + +Option Explicit +' <--------------- keyword.control.vba \ No newline at end of file diff --git a/test/textmate/unit/module/comments.vba b/test/textmate/unit/comments.vba similarity index 100% rename from test/textmate/unit/module/comments.vba rename to test/textmate/unit/comments.vba diff --git a/test/textmate/unit/module/classHeaders.vba b/test/textmate/unit/module/classHeaders.vba deleted file mode 100644 index 563ccb0..0000000 --- a/test/textmate/unit/module/classHeaders.vba +++ /dev/null @@ -1,57 +0,0 @@ -// SYNTAX TEST "source.vba" "class headers" - - -VERSION 1.0 CLASS -// <---------------- entity.other.attribute-name.block.vba -// ^^^ constant.numeric.vba - -BEGIN -// <----- entity.other.attribute-name.block.vba - - MultiUse = -1 'True -// ^^^^^^^^^^^^^^^^^^^^ entity.other.attribute-name.block.vba -// ^ keyword.operator.comparison.vba -// ^^ constant.numeric.vba -// ^^^^^ comment.line.apostrophe.vba - -END -// <--- entity.other.attribute-name.block.vba - -Attribute VB_Name = "ClassName" -// <------------------------------ meta.attribute.vba -// <---------------- entity.other.attribute-name.vba -// ^ keyword.operator.comparison.vba -// ^^^^^^^^^^^ string.quoted.double.vba - -Attribute VB_Description = "Class description goes here" -// <------------------------------------------------------- meta.attribute.vba -// <-------------------- entity.other.attribute-name.vba -// ^ keyword.operator.comparison.vba -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.vba - -Attribute VB_GlobalNameSpace = False -// <----------------------------------- meta.attribute.vba -// <------------------------ entity.other.attribute-name.vba -// ^ keyword.operator.comparison.vba -// ^^^^^ constant.language.boolean.vba - -Attribute VB_Creatable = False -// <----------------------------- meta.attribute.vba -// <------------------ entity.other.attribute-name.vba -// ^ keyword.operator.comparison.vba -// ^^^^^ constant.language.boolean.vba - -Attribute VB_PredeclaredId = False -// <--------------------------------- meta.attribute.vba -// <------------------------- entity.other.attribute-name.vba -// ^ keyword.operator.comparison.vba -// ^^^^^ constant.language.boolean.vba - -Attribute VB_Exposed = False -// <--------------------------- meta.attribute.vba -// <------------------- entity.other.attribute-name.vba -// ^ keyword.operator.comparison.vba -// ^^^^^ constant.language.boolean.vba - -Option Explicit -// <--------------- keyword.control.vba \ No newline at end of file diff --git a/test/textmate/unit/module/moduleHeaders.vba b/test/textmate/unit/module/moduleHeaders.vba deleted file mode 100644 index 40b04d3..0000000 --- a/test/textmate/unit/module/moduleHeaders.vba +++ /dev/null @@ -1,10 +0,0 @@ -// SYNTAX TEST "source.vba" "module headers" - -Attribute VB_Name = "ModuleName" -// <------------------------------- meta.attribute.vba -// <----------------- entity.other.attribute-name.vba -// ^ keyword.operator.comparison.vba -// ^^^^^^^^^^^^ string.quoted.double.vba - -Option Explicit -// <--------------- keyword.control.vba \ No newline at end of file diff --git a/test/textmate/unit/moduleHeaders.vba b/test/textmate/unit/moduleHeaders.vba new file mode 100644 index 0000000..83abf81 --- /dev/null +++ b/test/textmate/unit/moduleHeaders.vba @@ -0,0 +1,10 @@ +' SYNTAX TEST "source.vba" "module headers" + +Attribute VB_Name = "ModuleName" +' <------------------------------- meta.attribute.vba +' <----------------- entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^^^^^^^^^^^^ string.quoted.double.vba + +Option Explicit +' <--------------- keyword.control.vba \ No newline at end of file From e87fb6a80d0b213064b17681b677afdb98b5cb36 Mon Sep 17 00:00:00 2001 From: sslinky Date: Fri, 17 Jan 2025 16:36:55 +0800 Subject: [PATCH 05/35] "Me" now language variable --- client/src/syntaxes/vba.tmLanguage.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index e8f0248..ed7b4f1 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -38,7 +38,7 @@ repository: - include: "#lineContinuation" lineContinuation: - name: support.vba + name: keyword.control.line-continuation.vba match: \s*_\s*\n syntaxLines: @@ -68,6 +68,7 @@ repository: - include: "#literals" - include: "#operators" - include: "#keywords" + - include: "#variables" - include: "#functionCall" - include: "#objectModel" - include: "#subCall" @@ -274,6 +275,10 @@ repository: name: invalid.illegal.vba match: "^#.*" + variables: + name: variable.language.me.vba + match: (?i)\s+(Me)(?=\.|\s) + labels: # name: variable.other.constant.label.vba match: '(?i)^(\s*[a-z][a-z0-9_]*|\d+):' From f14fcc3bf1106eb43b74e8309a415bfdf91c257a Mon Sep 17 00:00:00 2001 From: sslinky Date: Fri, 17 Jan 2025 23:38:00 +0800 Subject: [PATCH 06/35] Allow for type hints on number literals --- client/src/syntaxes/vba.tmLanguage.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index ed7b4f1..405299c 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -90,7 +90,7 @@ repository: match: "(?i)(true|false)" number: name: constant.numeric.vba - match: "-?\\d+\\.?\\d*" + match: -?\d+\.?\d*[%&@!#]? hexadecimal: name: constant.numeric.hex.vba match: "(?i)&H[0-9a-f]+(&)?" From 753898e2494fbb1242e9bc6fee2a4d7bdfb1290e Mon Sep 17 00:00:00 2001 From: sslinky Date: Sat, 18 Jan 2025 00:07:41 +0800 Subject: [PATCH 07/35] Fixed attributes leaking to language --- client/src/syntaxes/vba.tmLanguage.yaml | 14 ++++++++-- test/textmate/unit/classHeaders.vba | 36 ++++++++++++++----------- test/textmate/unit/moduleHeaders.vba | 9 ++++--- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index 405299c..e95b745 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -456,8 +456,18 @@ repository: - include: "#moduleOption" repository: moduleAttribute: - patterns: - - include: "#attribute" + name: meta.attribute.vba + match: (?i)^\s*(Attribute)\s+(VB_\w+)\s+(=)\s+(.*)$ + captures: + 1: # Attribute + name: keyword.attribute.vba + 2: # VB_Name + name: entity.other.attribute-name.vba + 3: # = + name: keyword.operator.comparison.vba + 4: # "Sam" + patterns: + - include: "#literals" moduleAttributeBlock: name: entity.other.attribute-name.block.vba begin: (?i)^VERSION diff --git a/test/textmate/unit/classHeaders.vba b/test/textmate/unit/classHeaders.vba index 368bdc5..a399bab 100644 --- a/test/textmate/unit/classHeaders.vba +++ b/test/textmate/unit/classHeaders.vba @@ -10,8 +10,8 @@ BEGIN MultiUse = -1 'True ' ^^^^^^^^^^^^^^^^^^^^ entity.other.attribute-name.block.vba -' ^ keyword.operator.comparison.vba -' ^^ constant.numeric.vba +' ^ keyword.operator.comparison.vba +' ^^ constant.numeric.vba ' ^^^^^ comment.line.apostrophe.vba END @@ -19,39 +19,45 @@ END Attribute VB_Name = "ClassName" ' <------------------------------ meta.attribute.vba -' <---------------- entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba +' <--------- keyword.attribute.vba +' ^^^^^^^ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba ' ^^^^^^^^^^^ string.quoted.double.vba Attribute VB_Description = "Class description goes here" ' <------------------------------------------------------- meta.attribute.vba -' <-------------------- entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba -' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.vba +' <--------- keyword.attribute.vba +' ^^^^^^^^^^^^^^ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.vba Attribute VB_GlobalNameSpace = False ' <----------------------------------- meta.attribute.vba -' <------------------------ entity.other.attribute-name.vba +' <--------- keyword.attribute.vba +' ^^^^^^^^^^^^^^^^^^ entity.other.attribute-name.vba ' ^ keyword.operator.comparison.vba ' ^^^^^ constant.language.boolean.vba Attribute VB_Creatable = False ' <----------------------------- meta.attribute.vba -' <------------------ entity.other.attribute-name.vba +' <--------- keyword.attribute.vba +' ^^^^^^^^^^^^ entity.other.attribute-name.vba ' ^ keyword.operator.comparison.vba -' ^^^^^ constant.language.boolean.vba +' ^^^^^ constant.language.boolean.vba Attribute VB_PredeclaredId = False ' <--------------------------------- meta.attribute.vba -' <------------------------- entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba +' <--------- keyword.attribute.vba +' ^^^^^^^^^^^^^^^^ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba ' ^^^^^ constant.language.boolean.vba Attribute VB_Exposed = False ' <--------------------------- meta.attribute.vba -' <------------------- entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba -' ^^^^^ constant.language.boolean.vba +' <--------- keyword.attribute.vba +' ^^^^^^^^^^ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^^^^^ constant.language.boolean.vba Option Explicit ' <--------------- keyword.control.vba \ No newline at end of file diff --git a/test/textmate/unit/moduleHeaders.vba b/test/textmate/unit/moduleHeaders.vba index 83abf81..c8569f9 100644 --- a/test/textmate/unit/moduleHeaders.vba +++ b/test/textmate/unit/moduleHeaders.vba @@ -1,10 +1,11 @@ ' SYNTAX TEST "source.vba" "module headers" Attribute VB_Name = "ModuleName" -' <------------------------------- meta.attribute.vba -' <----------------- entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba -' ^^^^^^^^^^^^ string.quoted.double.vba +' <------------------------------- meta.attribute.vba +' <--------- keyword.attribute.vba +' ^^^^^^^ entity.other.attribute-name.vba +' ^ keyword.operator.comparison.vba +' ^^^^^^^^^^^^ string.quoted.double.vba Option Explicit ' <--------------- keyword.control.vba \ No newline at end of file From c17991353bbbf96e3576a59a05dbe02e252439b5 Mon Sep 17 00:00:00 2001 From: sslinky Date: Sat, 18 Jan 2025 00:08:54 +0800 Subject: [PATCH 08/35] Correct title --- test/textmate/unit/methodAttributes.vba | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/textmate/unit/methodAttributes.vba b/test/textmate/unit/methodAttributes.vba index b148536..91eba76 100644 --- a/test/textmate/unit/methodAttributes.vba +++ b/test/textmate/unit/methodAttributes.vba @@ -1,4 +1,4 @@ -' SYNTAX TEST "source.vba" "comments" +' SYNTAX TEST "source.vba" "method attributes" Public Function Identifier() As Variant Attribute Identifier.VB_Description = "Docstring." From bd92401c699a43430246abef5e23895019588baf Mon Sep 17 00:00:00 2001 From: sslinky Date: Mon, 20 Jan 2025 21:54:56 +0800 Subject: [PATCH 09/35] Arguments as a signature treated separately to args passed to method --- client/src/syntaxes/vba.tmLanguage.yaml | 84 +++++++++---- test/textmate/snapshot/class.cls.snap | 24 +++- test/textmate/snapshot/module.bas.snap | 4 +- test/textmate/unit/methodSignatures.vba | 152 ++++++++++++++++++++++++ 4 files changed, 235 insertions(+), 29 deletions(-) create mode 100644 test/textmate/unit/methodSignatures.vba diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index e95b745..0579546 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -351,23 +351,59 @@ repository: match: (?i)\b(debug)(\.([a-z][a-z0-9_]*)) types: - patterns: - - include: "#language" - - include: "#primativeType" - - include: "#objectType" - repository: - primativeType: - name: support.type.primitive.vba - match: (?i)(?<=\bAs)(?:\s+|\s+_\s*\n)+(boolean|byte|currency|date|decimal|double|integer|long(long|ptr)?|single|string|variant)\b - objectType: - name: support.type.object.vba - match: (?i)(?<=\bAs)((?:\s+(?:\s*_\s*\n)*)New)?(?:\s+(?:\s*_\s*\n)*)([A-Z][A-Z0-9_]*)\b - captures: - 1: - name: keyword.storage.new.vba - 2: + name: meta.variables.type.vba + # As New? Type + match: (?i)(As)\s+(New\s)?\s*([A-Z][a-z0-9_.]*) + captures: + 1: + name: keyword.control.as.vba + 2: + name: keyword.storage.new.vba + 3: + patterns: + - include: "#AsTypePrimative" + - include: "#AsTypeObject" + repository: + AsTypePrimative: + name: support.type.primitive.vba + match: (?i)(boolean|byte|currency|date|decimal|double|integer|long(long|ptr)?|single|string|variant)\b + AsTypeObject: name: support.type.object.vba + match: (?i)([A-Z][A-Z0-9_]*) + + argumentsSignature: + name: meta.arguments.signature.vba + match: (?i)(?:(,)|(=)|(\s*_\s*\n)|(as\s+(?:\s*_\s*\n)*[a-z][a-z0-9_.]*)|(".*"|True|False|\d+(?:\.\d+)?[%&@!#$]?)|([a-z][a-z0-9_.]*[%&@!#$]?(?:\(\))?)) + captures: + 1: # , + name: punctuation.separator.vba + 2: # = + name: keyword.operator.assignment.vba + 3: # _ + name: punctuation.line-continuation.vba + 4: # As Type? + patterns: + - include: "#types" + 5: # "foo" + patterns: + - include: "#literals" + 6: + patterns: + - include: "#keywords" + - include: "#argumentsVariableSignature" + repository: + argumentsVariableSignature: + match: (?i)(?:(Optional|ParamArray|ByRef|ByVal)|(.*)) + captures: + 1: # Optional? ByVal|ByRef? + name: storage.type.modifier.vba + 2: # Identifier + name: variable.parameter.vba + # TODO: This needs to be repurposed to sub / function CALL rather than signature. + # Will need to separate arguments by comma, take line endings into account, and ignore commas inside parentheses. + # someSub someVar, "someLiteral", someFunc(1, 2, 3), _ + # someNextLineFunc() arguments: # Rules that have no match will never return a name in the hierarchy. # This name doesn't do anything but leaving this as usage notes. @@ -399,8 +435,10 @@ repository: - include: "#language" argsLiteral: + # Should ideally only match on something that could be considered a literal. + # This kludge will at least not consume unmatched close parentheses. name: meta.arguments.argsLiteral.vba - match: ((?:[^\n",]|"(?:\\.|[^\n"\\])*")+|"(?:\\.|[^\n"\\])*") + match: ((?:[^(",\n()]|"(?:\\.|[^\n"\\])*"|\([^)]*\))+|"(?:\\.|[^\n"\\])*") captures: 1: patterns: @@ -408,13 +446,15 @@ repository: paramArray: name: meta.args.paramarray.vba - match: (?i),?\s*(ParamArray)\s+([a-z][a-z0-9_]*)(?:\(\))(\s+As\s+Variant)? + match: (?i)(,)?\s*(ParamArray)\s+([a-z][a-z0-9_]*)(?:\(\))(\s+As\s+Variant)? captures: 1: - name: storage.type.modifier.array.vba + name: punctuation.separator.vba 2: - name: variable.parameter.vba + name: storage.type.modifier.array.vba 3: + name: variable.parameter.vba + 4: patterns: - include: "#types" @@ -586,7 +626,7 @@ repository: patterns: - include: "#types" patterns: - - include: "#arguments" + - include: "#argumentsSignature" inlineMethod: name: source.inline-method.please-dont.vba @@ -598,7 +638,7 @@ repository: name: entity.name.function.vba 3: # Arguments? patterns: - - include: "#arguments" + - include: "#argumentsSignature" 4: # Return type? patterns: - include: "#types" @@ -628,7 +668,7 @@ repository: patterns: - include: "#types" patterns: - - include: "#arguments" + - include: "#argumentsSignature" methodAttribute: name: source.method.attribute.vba diff --git a/test/textmate/snapshot/class.cls.snap b/test/textmate/snapshot/class.cls.snap index 31d0110..ff44dbe 100644 --- a/test/textmate/snapshot/class.cls.snap +++ b/test/textmate/snapshot/class.cls.snap @@ -14,37 +14,49 @@ >END #^^^ source.vba entity.other.attribute-name.block.vba >Attribute VB_Name = "ClassName" -#^^^^^^^^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba +#^^^^^^^^^ source.vba meta.attribute.vba keyword.attribute.vba +# ^ source.vba meta.attribute.vba +# ^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba # ^ source.vba meta.attribute.vba # ^ source.vba meta.attribute.vba keyword.operator.comparison.vba # ^ source.vba meta.attribute.vba # ^^^^^^^^^^^ source.vba meta.attribute.vba string.quoted.double.vba >Attribute VB_Description = "Class description goes here" -#^^^^^^^^^^^^^^^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba +#^^^^^^^^^ source.vba meta.attribute.vba keyword.attribute.vba +# ^ source.vba meta.attribute.vba +# ^^^^^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba # ^ source.vba meta.attribute.vba # ^ source.vba meta.attribute.vba keyword.operator.comparison.vba # ^ source.vba meta.attribute.vba # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.vba meta.attribute.vba string.quoted.double.vba >Attribute VB_GlobalNameSpace = False -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba +#^^^^^^^^^ source.vba meta.attribute.vba keyword.attribute.vba +# ^ source.vba meta.attribute.vba +# ^^^^^^^^^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba # ^ source.vba meta.attribute.vba # ^ source.vba meta.attribute.vba keyword.operator.comparison.vba # ^ source.vba meta.attribute.vba # ^^^^^ source.vba meta.attribute.vba constant.language.boolean.vba >Attribute VB_Creatable = False -#^^^^^^^^^^^^^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba +#^^^^^^^^^ source.vba meta.attribute.vba keyword.attribute.vba +# ^ source.vba meta.attribute.vba +# ^^^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba # ^ source.vba meta.attribute.vba # ^ source.vba meta.attribute.vba keyword.operator.comparison.vba # ^ source.vba meta.attribute.vba # ^^^^^ source.vba meta.attribute.vba constant.language.boolean.vba >Attribute VB_PredeclaredId = False -#^^^^^^^^^^^^^^^^^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba +#^^^^^^^^^ source.vba meta.attribute.vba keyword.attribute.vba +# ^ source.vba meta.attribute.vba +# ^^^^^^^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba # ^ source.vba meta.attribute.vba # ^ source.vba meta.attribute.vba keyword.operator.comparison.vba # ^ source.vba meta.attribute.vba # ^^^^^ source.vba meta.attribute.vba constant.language.boolean.vba >Attribute VB_Exposed = False -#^^^^^^^^^^^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba +#^^^^^^^^^ source.vba meta.attribute.vba keyword.attribute.vba +# ^ source.vba meta.attribute.vba +# ^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba # ^ source.vba meta.attribute.vba # ^ source.vba meta.attribute.vba keyword.operator.comparison.vba # ^ source.vba meta.attribute.vba diff --git a/test/textmate/snapshot/module.bas.snap b/test/textmate/snapshot/module.bas.snap index 05a4dde..e0cce43 100644 --- a/test/textmate/snapshot/module.bas.snap +++ b/test/textmate/snapshot/module.bas.snap @@ -1,5 +1,7 @@ >Attribute VB_Name = "ModuleName" -#^^^^^^^^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba +#^^^^^^^^^ source.vba meta.attribute.vba keyword.attribute.vba +# ^ source.vba meta.attribute.vba +# ^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba # ^ source.vba meta.attribute.vba # ^ source.vba meta.attribute.vba keyword.operator.comparison.vba # ^ source.vba meta.attribute.vba diff --git a/test/textmate/unit/methodSignatures.vba b/test/textmate/unit/methodSignatures.vba new file mode 100644 index 0000000..4b9b777 --- /dev/null +++ b/test/textmate/unit/methodSignatures.vba @@ -0,0 +1,152 @@ +' SYNTAX TEST "source.vba" "method signatures" + +' Inline sub +Sub Foo(): Debug.Print "Hello, World!": End Sub +' <----------------------------------------------- source.inline-method.please-dont.vba +' <--- storage.type.method.vba +' ^^^ entity.name.function.vba +' ^^^^^^^ storage.type.method.close.vba + +' Standard sub +Public Sub Foo(ByVal x As Long, ByRef y As Long, ParamArray vars() As Variant) +' <------------------------------------------------------------------------------ source.method.signature.vba +' <---------- storage.type.method.vba +' ^^^ entity.name.function.vba +' ^ punctuation.definition.parameters.begin.vba +' ^^^^^ storage.type.modifier.vba +' ^ variable.parameter.vba +' ^^ keyword.control.as.vba +' ^^^^ support.type.primitive.vba +' ^ punctuation.separator.vba +' ^^^^^ storage.type.modifier.vba +' ^ variable.parameter.vba +' ^^ keyword.control.as.vba +' ^^^^ support.type.primitive.vba +' ^ punctuation.separator.vba +' ^^^^^^^^^^ storage.type.modifier.vba +' ^^^^ variable.parameter.vba +' ^^ keyword.control.as.vba +' ^^^^^^^ support.type.primitive.vba +' ^ punctuation.definition.parameters.end.vba +End Sub +'<-------- storage.type.method.close.vba + + +' Inline Function +Function Foo() As String: Foo = "Hello, World!": End Function +' <------------------------------------------------------------- source.inline-method.please-dont.vba +' <-------- storage.type.method.vba +' ^^^ entity.name.function.vba +' ^^ keyword.control.as.vba +' ^^^^^^ support.type.primitive.vba +' ^^^^^^^^^^^^ storage.type.method.close.vba + +' Standard function +Public Function Foo(ByVal x As Long, ByRef y As Long, ParamArray vars() As Variant) As Object +' <--------------------------------------------------------------------------------------------- source.method.signature.vba +' <--------------- storage.type.method.vba +' ^^^ entity.name.function.vba +' ^ punctuation.definition.parameters.begin.vba +' ^^^^^ storage.type.modifier.vba +' ^ variable.parameter.vba +' ^^ keyword.control.as.vba +' ^^^^ support.type.primitive.vba +' ^ punctuation.separator.vba +' ^^^^^ storage.type.modifier.vba +' ^ variable.parameter.vba +' ^^ keyword.control.as.vba +' ^^^^ support.type.primitive.vba +' ^ punctuation.separator.vba +' ^^^^^^^^^^ storage.type.modifier.vba +' ^^^^ variable.parameter.vba +' ^^ keyword.control.as.vba +' ^^^^^^^ support.type.primitive.vba +' ^ punctuation.definition.parameters.end.vba +' ^^ keyword.control.as.vba +' ^^^^^^ support.type.object.vba +End Function +'<------------- storage.type.method.close.vba + +' Multi-Line Sub +Public Sub Foo(Optional Bar As String, _ +' <---------- storage.type.method.vba +' ^^^ entity.name.function.vba +' ^ punctuation.definition.parameters.begin.vba +' ^^^^^^^^ storage.type.modifier.vba +' ^^^ variable.parameter.vba +' ^^ keyword.control.as.vba +' ^^^^^^ support.type.primitive.vba +' ^ punctuation.separator.vba +' ^ punctuation.line-continuation.vba + Optional Biz As String = "Biz", _ +' ^^^^^^^^ storage.type.modifier.vba +' ^^^ variable.parameter.vba +' ^^ keyword.control.as.vba +' ^^^^^^ support.type.primitive.vba +' ^ keyword.operator.assignment.vba +' ^^^^^ string.quoted.double.vba +' ^ punctuation.separator.vba +' ^ punctuation.line-continuation.vba + Optional ByVal Zip As Boolean = True) +' ^^^^^^^^ ^^^^^ storage.type.modifier.vba +' ^^^ variable.parameter.vba +' ^^ keyword.control.as.vba +' ^^^^^^^ support.type.primitive.vba +' ^ keyword.operator.assignment.vba +' ^^^^ constant.language.boolean.vba +' ^ punctuation.definition.parameters.end.vba +End Sub +'<-------- storage.type.method.close.vba + +' Crazy sub - due to limitations with textMate, it does not seem possible to format +' types when using line continuations. This is because matches work on a single line, +' and it appears begin/end matches operate process "patterns" line-by-line too. An inner +' begin/end rule will only be given a line at a time to process. +Public Sub Foo( _ +' <---------- storage.type.method.vba +' ^^^ entity.name.function.vba +' ^ punctuation.definition.parameters.begin.vba +' ^ punctuation.line-continuation.vba + Optional baz As String = "Something", _ +' ^^^^^^^^ storage.type.modifier.vba +' ^^^ variable.parameter.vba +' ^^ keyword.control.as.vba +' ^^^^^^ support.type.primitive.vba +' ^ keyword.operator.assignment.vba +' ^^^^^^^^^^^ string.quoted.double.vba +' ^ punctuation.separator.vba +' ^ punctuation.line-continuation.vba + biz _ +' ^^^ variable.parameter.vba +' ^ punctuation.line-continuation.vba + As String, _ +' ^^ keyword.control.as.vba +' ^^^^^^ support.type.primitive.vba +' ^ punctuation.separator.vba +' ^ punctuation.line-continuation.vba + Optional _ +' ^^^^^^^^ storage.type.modifier.vba +' ^ punctuation.line-continuation.vba + ByRef _ +' ^^^^^ storage.type.modifier.vba +' ^ punctuation.line-continuation.vba + bix As _ +' ^^^ variable.parameter.vba +' ^^ keyword.control.as.vba +' ^ punctuation.line-continuation.vba + String, _ +' ^^^^^^ variable.parameter.vba +' ^ punctuation.separator.vba +' ^ punctuation.line-continuation.vba + bax _ +' ^^^ variable.parameter.vba +' ^ punctuation.line-continuation.vba + As _ +' ^^ keyword.control.as.vba +' ^ punctuation.line-continuation.vba + Object) +' ^^^^^^ variable.parameter.vba +' ^ punctuation.definition.parameters.end.vba + +End Sub +'<-------- storage.type.method.close.vba From 745426c965bfc61982cb71678d7b852f5d4e3d3f Mon Sep 17 00:00:00 2001 From: sslinky Date: Tue, 21 Jan 2025 09:32:25 +0800 Subject: [PATCH 10/35] Fixes #32 --- server/src/antlr/vbapre.g4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/antlr/vbapre.g4 b/server/src/antlr/vbapre.g4 index 5e77e1a..64bd1ff 100644 --- a/server/src/antlr/vbapre.g4 +++ b/server/src/antlr/vbapre.g4 @@ -219,9 +219,9 @@ NOT // Any non-whitespace or new line characters. ANYCHARS - : ANYCHAR + : ANYCHAR+ ; fragment ANYCHAR - : . + : ~[\r\n\u2028\u2029 \t\u0019\u3000] ; \ No newline at end of file From 032b3aa94b44f9792ea7ba6e5be0961cf049f6f0 Mon Sep 17 00:00:00 2001 From: sslinky Date: Wed, 22 Jan 2025 11:55:20 +0800 Subject: [PATCH 11/35] Fix indentation bug --- server/src/antlr/vbapre.g4 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/server/src/antlr/vbapre.g4 b/server/src/antlr/vbapre.g4 index 64bd1ff..760b037 100644 --- a/server/src/antlr/vbapre.g4 +++ b/server/src/antlr/vbapre.g4 @@ -38,23 +38,23 @@ compilerConditionalStatement ; compilerIfStatement - : IF WS? booleanExpression WS? THEN endOfStatement + : WS? IF WS? booleanExpression WS? THEN endOfStatement ; compilerElseIfStatement - : ELSEIF WS? booleanExpression WS? THEN endOfStatement + : WS? ELSEIF WS? booleanExpression WS? THEN endOfStatement ; compilerElseStatement - : ELSE endOfStatement + : WS? ELSE endOfStatement ; compilerEndIfStatement - : ENDIF endOfStatement? + : WS? ENDIF endOfStatement? ; compilerBlockContent - : (anyOtherLine | endOfLine)+ + : (anyOtherLine | endOfLine | compilerIfBlock)+ ; // ************************* @@ -81,7 +81,7 @@ anyWord ; anyOtherLine - : (WS* anyWord)+ //endOfLine? + : (WS* anyWord)+ ; endOfLine @@ -93,7 +93,7 @@ endOfLineNoWs ; endOfStatement - : (endOfLine | COLON)+ + : (endOfLine | WS? COLON WS? )+ ; commentBody: COMMENT; @@ -169,7 +169,7 @@ LINE_CONTINUATION ; WS - : NBSP NBSP* + : NBSP+ ; fragment NBSP From 25fac200f4f7ef2dee290623cb5de57c6040fe90 Mon Sep 17 00:00:00 2001 From: sslinky Date: Thu, 23 Jan 2025 22:36:04 +0800 Subject: [PATCH 12/35] IdentifierCapability now handles TerminalNodes as well as rule contexts. --- server/src/capabilities/capabilities.ts | 4 ++-- server/src/extensions/parserExtensions.ts | 26 +++++++++++++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/server/src/capabilities/capabilities.ts b/server/src/capabilities/capabilities.ts index 25293d7..5f4af4e 100644 --- a/server/src/capabilities/capabilities.ts +++ b/server/src/capabilities/capabilities.ts @@ -106,14 +106,14 @@ interface IdentifierArgs { export class IdentifierCapability extends BaseCapability { - nameContext?: ParserRuleContext | TerminalNode | null; + nameContext: ParserRuleContext | TerminalNode; range: Range; name: string; constructor(args: IdentifierArgs) { super(args.element); - this.nameContext = (args.getNameContext ?? (() => args.element.context.rule))(); + this.nameContext = ((args.getNameContext ?? (() => args.element.context.rule))() ?? args.element.context.rule); if (!!this.nameContext) { // Use the context to set the values. diff --git a/server/src/extensions/parserExtensions.ts b/server/src/extensions/parserExtensions.ts index 10e67ee..52c61d6 100644 --- a/server/src/extensions/parserExtensions.ts +++ b/server/src/extensions/parserExtensions.ts @@ -28,11 +28,15 @@ declare module 'antlr4ng' { interface ParserRuleContext { /** Convert the node to a range. */ toRange(doc: TextDocument): Range; + startIndex(): number; + stopIndex(): number; } interface TerminalNode { /** Convert the node to a range. */ toRange(doc: TextDocument): Range; + startIndex(): number; + stopIndex(): number; } } @@ -108,16 +112,30 @@ ParserRuleContext.prototype.toRange = function (doc: TextDocument): Range { ); }; +ParserRuleContext.prototype.startIndex = function (): number { + return this.start?.start ?? 0; +} + +ParserRuleContext.prototype.stopIndex = function (): number { + return this.stop?.stop ?? this.startIndex(); +} + TerminalNode.prototype.toRange = function (doc: TextDocument): Range { - const startIndex = this.getPayload()?.start ?? 0; - const stopIndex = this.getPayload()?.stop ?? startIndex; return Range.create( - doc.positionAt(startIndex), - doc.positionAt(stopIndex + 1) + doc.positionAt(this.startIndex()), + doc.positionAt(this.stopIndex() + 1) ); }; +TerminalNode.prototype.startIndex = function (): number { + return this.getPayload()?.start ?? 0; +} + +TerminalNode.prototype.stopIndex = function (): number { + return this.getPayload()?.stop ?? this.startIndex(); +} + CompilerConditionalStatementContext.prototype.vbaExpression = function (): string { return (this.compilerIfStatement() ?? this.compilerElseIfStatement())! From 953a2d19ea70f3bffcea7c8c5c39d53f2d82e971 Mon Sep 17 00:00:00 2001 From: sslinky Date: Thu, 23 Jan 2025 22:37:50 +0800 Subject: [PATCH 13/35] SemanticTokenCapability generates token lazily instead of in constructor --- server/src/capabilities/capabilities.ts | 35 ++++++++++++++++--------- server/src/project/elements/base.ts | 8 +++--- server/src/project/elements/typing.ts | 1 - 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/server/src/capabilities/capabilities.ts b/server/src/capabilities/capabilities.ts index 5f4af4e..c64c81a 100644 --- a/server/src/capabilities/capabilities.ts +++ b/server/src/capabilities/capabilities.ts @@ -14,7 +14,7 @@ import { ParserRuleContext, TerminalNode } from 'antlr4ng'; // Project import { SemanticToken } from '../capabilities/semanticTokens'; import { FoldingRange, FoldingRangeKind } from '../capabilities/folding'; -import { BaseContextSyntaxElement, BaseIdentifyableSyntaxElement, HasSemanticTokenCapability } from '../project/elements/base'; +import { BaseContextSyntaxElement, BaseIdentifyableSyntaxElement, Context, HasSemanticTokenCapability } from '../project/elements/base'; abstract class BaseCapability { @@ -52,28 +52,39 @@ export class DiagnosticCapability extends BaseCapability { export class SemanticTokenCapability extends BaseCapability { - semanticToken: SemanticToken; - - constructor(element: BaseContextSyntaxElement & HasSemanticTokenCapability, tokenType: SemanticTokenTypes, tokenModifiers: SemanticTokenModifiers[], range?: Range, tokLength?: number) { - super(element); + private tokenType: SemanticTokenTypes; + private tokenModifiers: SemanticTokenModifiers[]; + private overrideRange?: Range; + private overrideLength?: number; + get semanticToken(): SemanticToken { + const element = this.element as BaseContextSyntaxElement & HasSemanticTokenCapability; const context = !!element.identifierCapability - ? element.identifierCapability.element.context + ? new Context(element.identifierCapability.nameContext, element.context.document) : element.context; - const startLine = range?.start.line ?? context.range.start.line; - const startChar = range?.start.character ?? context.range.start.character; - const textLength = tokLength ?? context.text.length; + const range = this.overrideRange ?? context.range; + const startLine = range.start.line; + const startChar = range.start.character; + const textLength = this.overrideLength ?? context.text.length; - this.semanticToken = new SemanticToken( + return new SemanticToken( element, startLine, startChar, textLength, - tokenType, - tokenModifiers + this.tokenType, + this.tokenModifiers ); } + + constructor(element: BaseContextSyntaxElement & HasSemanticTokenCapability, tokenType: SemanticTokenTypes, tokenModifiers: SemanticTokenModifiers[], overrideRange?: Range, overrideLength?: number) { + super(element); + this.tokenType = tokenType; + this.tokenModifiers = tokenModifiers; + this.overrideRange = overrideRange; + this.overrideLength = overrideLength; + } } diff --git a/server/src/project/elements/base.ts b/server/src/project/elements/base.ts index ad6e8ee..f3da4c9 100644 --- a/server/src/project/elements/base.ts +++ b/server/src/project/elements/base.ts @@ -3,7 +3,7 @@ import { Position, Range } from 'vscode-languageserver'; import { TextDocument } from 'vscode-languageserver-textdocument'; // Antlr -import { ParserRuleContext } from 'antlr4ng'; +import { ParserRuleContext, TerminalNode } from 'antlr4ng'; // Project import { @@ -93,7 +93,7 @@ export abstract class BaseIdentifyableSyntaxElement // Utilities // --------------------------------------------------------- -export class Context { +export class Context { rule: T; document: TextDocument; range: Range; @@ -102,8 +102,8 @@ export class Context { return this.rule.getText(); } - get startIndex() { return this.rule.start?.start ?? 0; } - get stopIndex() { return this.rule.stop?.stop ?? 0; } + get startIndex() { return this.rule.startIndex(); } + get stopIndex() { return this.rule.stopIndex(); } constructor(context: T, document: TextDocument) { this.rule = context; diff --git a/server/src/project/elements/typing.ts b/server/src/project/elements/typing.ts index ba28953..4454e51 100644 --- a/server/src/project/elements/typing.ts +++ b/server/src/project/elements/typing.ts @@ -70,7 +70,6 @@ export class TypeDeclarationElement extends BaseTypeDeclarationElement ctx.udtDeclaration().untypedName() }); - this.symbolInformationCapability = new SymbolInformationCapability(this, SymbolKind.Struct); } } From 3968882a1810a38ef3ccdf230aed560c5fd24e17 Mon Sep 17 00:00:00 2001 From: sslinky Date: Tue, 28 Jan 2025 21:52:41 +0800 Subject: [PATCH 14/35] Fix and test logic blocks --- client/src/syntaxes/vba.tmLanguage.yaml | 39 ++++++-- test/textmate/unit/logicFlow.vba | 125 ++++++++++++++++++++++++ 2 files changed, 155 insertions(+), 9 deletions(-) create mode 100644 test/textmate/unit/logicFlow.vba diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index 0579546..a38cfae 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -79,6 +79,7 @@ repository: - include: "#comments" - include: "#string" - include: "#boolean" + - include: "#nothing" - include: "#number" - include: "#hexadecimal" repository: @@ -88,6 +89,9 @@ repository: boolean: name: constant.language.boolean.vba match: "(?i)(true|false)" + nothing: + name: constant.language.null.vba + match: (?i)\bnothing\b number: name: constant.numeric.vba match: -?\d+\.?\d*[%&@!#]? @@ -144,16 +148,32 @@ repository: patterns: - include: "#inlineIfElse" - include: "#inlineIf" - - include: "#flowDecision" + - include: "#blockIf" + - include: "#blockIfEnd" - include: "#forEachLoop" - include: "#flowLoop" - include: "#flowCall" - include: "#flowPauseExit" - include: "#flowBranch" repository: - flowDecision: - name: keyword.control.flow.decision.vba - match: (?i)(^|\s+)(#if|then|#elseif|[#]?else|[#]?end if|select case|case|switch|end select)\b + blockIf: + name: meta.flow.block-if-else.vba + match: (?i)(?:^|\s+)((?:[#]?else\s+)?[#]?if)(.*?)(then) + captures: + 1: + name: keyword.control.flow.block-decision.vba + 2: + patterns: + - include: "#expression" + - include: "#functionCall" + 3: + name: keyword.control.flow.block-decision.vba + blockIfEnd: + name: meta.flow.block-if-else.vba + match: (?i)([#]?end\s+if) + captures: + 1: + name: keyword.control.flow.block-decision.vba flowLoop: name: keyword.control.flow.loop.vba @@ -197,7 +217,7 @@ repository: inlineIf: name: meta.flow.inline-if.vba - match: (?i)\s*((?:else)?if)\s+(.*?)\s+(then) + match: (?i)\s*((?:else\s+)?if)\s+(.*?)\s+(then)\s+([^'\n]*) captures: 1: name: keyword.control.flow.decision.vba @@ -698,16 +718,17 @@ repository: # (?:\b(addressof|typeof)\b) # This match just made up of the operators matchs. Don't look at it too hard. - match: (?i)(.*?)\s+((?:[*&\/\+-]|\bMod\b)|(?:[<>=]|\b(is|like)\b)|(?:[&+])|(?:\b(and|eqv|imp|not|or|xor)\b)|(?:\b(addressof|typeof)\b))\s+(.*) + name: meta.expression.vba + match: (?i)(?:(.*?)\s+)?((?:[*&\/\+-]|\bMod\b)|(?:[<>=]|\b(?:is|like)\b)|(?:[&+])|(?:\b(?:and|eqv|imp|not|or|xor)\b)|(?:\b(?:addressof|typeof)\b))\s+(.*) captures: - 1: # Left sided of expression + 1: # Left side of expression? patterns: - include: "#functionCall" - include: "#literal" 2: # Operator patterns: - include: "#operators" - 3: # Operator + 3: # Right side of expression patterns: - include: "#literals" - include: "#functionCall" @@ -801,7 +822,7 @@ repository: name: keyword.operator.assignment.vba 5: patterns: - - include: "#functionCall" + - include: "#expression" - include: "#language" functionCall: diff --git a/test/textmate/unit/logicFlow.vba b/test/textmate/unit/logicFlow.vba new file mode 100644 index 0000000..0fb8378 --- /dev/null +++ b/test/textmate/unit/logicFlow.vba @@ -0,0 +1,125 @@ +' SYNTAX TEST "source.vba" "logic flow" + +Attribute VB_Name = "Logic" +' Copyright 2024 Sam Vanderslink +' +' Permission is hereby granted, free of charge, to any person obtaining a copy +' of this software and associated documentation files (the "Software"), to deal +' in the Software without restriction, including without limitation the rights +' to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +' copies of the Software, and to permit persons to whom the Software is +' furnished to do so, subject to the following conditions: +' +' The above copyright notice and this permission notice shall be included in +' all copies or substantial portions of the Software. +' +' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +' FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +' IN THE SOFTWARE. + +Option Explicit + + +Public Sub Foo() +' Variable positive + If condition Then +' ^^^^^^^^^^^^^^^^^ meta.flow.block-if-else.vba +' ^^ keyword.control.flow.block-decision.vba +' ^^^^ keyword.control.flow.block-decision.vba + Else If condition Then +' ^^^^^^^^^^^^^^^^^ meta.flow.block-if-else.vba +' ^^^^^^^ keyword.control.flow.block-decision.vba +' ^^^^ keyword.control.flow.block-decision.vba + End If +' ^^^^^^ meta.flow.block-if-else.vba +' ^^^^^^ keyword.control.flow.block-decision.vba + +' Variable negative + If Not condition Then +' ^^^^^^^^^^^^^^^^^^^^^ meta.flow.block-if-else.vba +' ^^ keyword.control.flow.block-decision.vba +' ^^^ keyword.operator.logical.vba +' ^^^^ keyword.control.flow.block-decision.vba + Else If Not condition Then +' ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.flow.block-if-else.vba +' ^^^^^^^ keyword.control.flow.block-decision.vba +' ^^^ keyword.operator.logical.vba +' ^^^^ keyword.control.flow.block-decision.vba + End If +' ^^^^^^ meta.flow.block-if-else.vba +' ^^^^^^ keyword.control.flow.block-decision.vba + +' Function positive + If condition() Then +' ^^^^^^^^^^^^^^^^^^^ meta.flow.block-if-else.vba +' ^^ keyword.control.flow.block-decision.vba +' ^^^^^^^^^^^ meta.function.call.vba +' ^^^^ keyword.control.flow.block-decision.vba + Else If condition() Then +' ^^^^^^^^^^^^^^^^^^^^^^^^ meta.flow.block-if-else.vba +' ^^^^^^^ keyword.control.flow.block-decision.vba +' ^^^^^^^^^^^ meta.function.call.vba +' ^^^^ keyword.control.flow.block-decision.vba + End If +' ^^^^^^ meta.flow.block-if-else.vba +' ^^^^^^ keyword.control.flow.block-decision.vba + +' Function negative + If Not condition() Then +' ^^^^^^^^^^^^^^^^^^^^^^^ meta.flow.block-if-else.vba +' ^^ keyword.control.flow.block-decision.vba +' ^^^ keyword.operator.logical.vba +' ^^^^^^^^^^^ meta.function.call.vba +' ^^^^ keyword.control.flow.block-decision.vba + Else If Not condition() Then +' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.flow.block-if-else.vba +' ^^^^^^^ keyword.control.flow.block-decision.vba +' ^^^ keyword.operator.logical.vba +' ^^^^^^^^^^^ meta.function.call.vba +' ^^^^ keyword.control.flow.block-decision.vba + End If +' ^^^^^^ meta.flow.block-if-else.vba +' ^^^^^^ keyword.control.flow.block-decision.vba + +' Literal + If Not True Then +' ^^^^^^^^^^^^^^^^ meta.flow.block-if-else.vba +' ^^ keyword.control.flow.block-decision.vba +' ^^^ keyword.operator.logical.vba +' ^^^^ constant.language.boolean.vba +' ^^^^ keyword.control.flow.block-decision.vba + Else If Not False Then +' ^^^^^^^^^^^^^^^^^^^^^^ meta.flow.block-if-else.vba +' ^^^^^^^ keyword.control.flow.block-decision.vba +' ^^^ keyword.operator.logical.vba +' ^^^^^ constant.language.boolean.vba +' ^^^^ keyword.control.flow.block-decision.vba + + End If +' ^^^^^^ meta.flow.block-if-else.vba +' ^^^^^^ keyword.control.flow.block-decision.vba + +' Expression + If Not condition = 5 Then +' ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.flow.block-if-else.vba +' ^^ keyword.control.flow.block-decision.vba +' ^^^ keyword.operator.logical.vba +' ^ keyword.operator.comparison.vba +' ^ constant.numeric.vba +' ^^^^ keyword.control.flow.block-decision.vba + Else If Not GetValue(x) = GetOtherValue("foo") Then +' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.flow.block-if-else.vba +' ^^^^^^^ keyword.control.flow.block-decision.vba +' ^^^ keyword.operator.logical.vba +' ^^^^^^^^^^^ meta.function.call.vba +' ^ keyword.operator.comparison.vba +' ^^^^^^^^^^^^^^^^^^^^ meta.function.call.vba +' ^^^^ keyword.control.flow.block-decision.vba + End If +' ^^^^^^ meta.flow.block-if-else.vba +' ^^^^^^ keyword.control.flow.block-decision.vba +End Sub \ No newline at end of file From 72e11cf2d8dd3c4cd2f270faa032596cd4d5ae3d Mon Sep 17 00:00:00 2001 From: sslinky Date: Tue, 4 Feb 2025 14:16:56 +0800 Subject: [PATCH 15/35] Comments shouldn't consume line ending --- client/src/syntaxes/vba.tmLanguage.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index a38cfae..ed10c2d 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -489,12 +489,12 @@ repository: # Capturing it there prevents the end pattern being matched. name: comment.block.vba begin: (?i)(\s*'|(?<=^\d*?|:)\s*Rem\b).*\s_\s* - end: \n + end: (?=\n) patterns: - include: "#lineContinuation" apostropheComments: name: comment.line.apostrophe.vba - match: (?i)\s*'.* + match: (?i)\s*'[^\n]* remarkComments: name: comment.line.remark.vba match: (?i)(?<=^\d*?|:)\s*Rem\b.* From baf28b071478592d8de9ec9f24d001a9968fb425 Mon Sep 17 00:00:00 2001 From: sslinky Date: Tue, 4 Feb 2025 14:18:11 +0800 Subject: [PATCH 16/35] Separator pattern --- client/src/syntaxes/vba.tmLanguage.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index ed10c2d..7f7e386 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -396,7 +396,8 @@ repository: match: (?i)(?:(,)|(=)|(\s*_\s*\n)|(as\s+(?:\s*_\s*\n)*[a-z][a-z0-9_.]*)|(".*"|True|False|\d+(?:\.\d+)?[%&@!#$]?)|([a-z][a-z0-9_.]*[%&@!#$]?(?:\(\))?)) captures: 1: # , - name: punctuation.separator.vba + patterns: + - include: "#separator" 2: # = name: keyword.operator.assignment.vba 3: # _ @@ -757,9 +758,9 @@ repository: patterns: - include: "#block" - # blockAttribute: - # patterns: - # - include: "#attribute" + separator: + name: punctuation.separator.vba + match: ',' variableDeclarations: patterns: From cc34c0c4227faa8dbac23100af05216ba2f149bf Mon Sep 17 00:00:00 2001 From: sslinky Date: Tue, 4 Feb 2025 14:20:07 +0800 Subject: [PATCH 17/35] Comments aren't literals --- client/src/syntaxes/vba.tmLanguage.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index 7f7e386..66eebad 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -76,7 +76,6 @@ repository: literals: patterns: - - include: "#comments" - include: "#string" - include: "#boolean" - include: "#nothing" From 838008bbef45c86114922afd9b7ff6eac104ca13 Mon Sep 17 00:00:00 2001 From: sslinky Date: Tue, 4 Feb 2025 14:22:49 +0800 Subject: [PATCH 18/35] Line cont. must begin with space --- client/src/syntaxes/vba.tmLanguage.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index 66eebad..7b9c442 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -39,7 +39,7 @@ repository: lineContinuation: name: keyword.control.line-continuation.vba - match: \s*_\s*\n + match: (?<=\s)_\s*\n syntaxLines: name: meta.syntax-lines.vba From b60ca64e7106a8ad702274e08b062740a938fdab Mon Sep 17 00:00:00 2001 From: sslinky Date: Tue, 4 Feb 2025 14:25:17 +0800 Subject: [PATCH 19/35] Fixed variable assignment to handle property chaining --- client/src/syntaxes/vba.tmLanguage.yaml | 40 ++++++++++++++++++++----- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index 7b9c442..288309d 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -809,22 +809,48 @@ repository: patterns: - include: "#language" - # TODO: Redo this so it can take into account chaining, e.g.: - # MyClass.MyProp = SomeObject.Foo(20) variableAssignment: - match: (?i)((Get|Let|Set)\s+)?([a-z.][a-z0-9._]*)(\s*=\s*)(.*) + match: (?i)(?:(Get|Let|Set)\s+)?(?:([a-z][a-z0-9_]*))?(\.(?:(?:[a-z][a-z0-9_]*)?\.)*)?([a-z][a-z0-9_]*)?(\s*=\s*)(.*) captures: - 2: + 1: # Get|Let|Set name: keyword.control.vba - 3: + 2: # Variable name name: variable.other.assignment.vba - 4: + 3: # Properties + patterns: + - include: "#propertyChain" + 4: # Property name + name: support.variable.property.vba + 5: # = name: keyword.operator.assignment.vba - 5: + 6: # Expression patterns: - include: "#expression" + - include: "#functionCall" + - include: "#variable" - include: "#language" + propertyChain: + match: (?i)(\.)([a-z][a-z0-9_]*)* + captures: + 1: + name: punctuation.accessor.vba + 2: + name: support.variable.property.vba + + variable: + name: meta.variable-or-property.vba + match: (?i)(?:(?:(Me)|([a-z][a-z0-9_]*)))((?:\.(?:[a-z][a-z0-9_]*))+)? + captures: + 1: + patterns: + - include: "#kw-storageMe" + 2: + name: variable.other.object.vba + 3: + patterns: + - include: "#propertyChain" + functionCall: name: meta.function.call.vba begin: (?i)([a-z][a-z0-9_]*)\( From e53263c2c0d7ef8adf48929bf16bebbddfbb3843 Mon Sep 17 00:00:00 2001 From: sslinky Date: Tue, 4 Feb 2025 16:45:14 +0800 Subject: [PATCH 20/35] Bug fix inline if --- client/src/syntaxes/vba.tmLanguage.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index 288309d..b858740 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -216,7 +216,7 @@ repository: inlineIf: name: meta.flow.inline-if.vba - match: (?i)\s*((?:else\s+)?if)\s+(.*?)\s+(then)\s+([^'\n]*) + match: (?i)\s*((?:else\s+)?if)\s+(.*?)\s+(then)\s+([^'\n]+) captures: 1: name: keyword.control.flow.decision.vba From d06cd5f27a3042e362326ca863c26b3ba5a531e9 Mon Sep 17 00:00:00 2001 From: sslinky Date: Thu, 6 Feb 2025 09:41:49 +0800 Subject: [PATCH 21/35] Expression now multi-line --- client/src/syntaxes/vba.tmLanguage.yaml | 30 +++++---------- test/textmate/unit/expressions.vba | 50 +++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 test/textmate/unit/expressions.vba diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index b858740..8a78af1 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -711,28 +711,16 @@ repository: match: (?i)^\s*End\s+(Sub|Function|Property) expression: - # (?:[*&\/\+-]|\bMod\b)| - # (?:[<>=]|\b(is|like)\b)| - # (?:[&+])| - # (?:\b(and|eqv|imp|not|or|xor)\b)| - # (?:\b(addressof|typeof)\b) - - # This match just made up of the operators matchs. Don't look at it too hard. + # Begins and ends without consuming anything. name: meta.expression.vba - match: (?i)(?:(.*?)\s+)?((?:[*&\/\+-]|\bMod\b)|(?:[<>=]|\b(?:is|like)\b)|(?:[&+])|(?:\b(?:and|eqv|imp|not|or|xor)\b)|(?:\b(?:addressof|typeof)\b))\s+(.*) - captures: - 1: # Left side of expression? - patterns: - - include: "#functionCall" - - include: "#literal" - 2: # Operator - patterns: - - include: "#operators" - 3: # Right side of expression - patterns: - - include: "#literals" - - include: "#functionCall" - - include: "#expression" + begin: (?=.) + end: (?=\n|\sThen|\)|'|,) + patterns: + - include: "#literals" + - include: "#operators" + - include: "#functionCall" + - include: "#variable" + - include: "#lineContinuation" block: patterns: diff --git a/test/textmate/unit/expressions.vba b/test/textmate/unit/expressions.vba new file mode 100644 index 0000000..3c22fa4 --- /dev/null +++ b/test/textmate/unit/expressions.vba @@ -0,0 +1,50 @@ +' SYNTAX TEST "source.vba" "expressions" + +' Expressions as part of other statements. + +Sub Test() + foo = bar ' Comment +' ^^^ meta.expression.vba +' ^^^^^^^^^ comment.line.apostrophe.vba - meta.expression.vba + foo.bar = "' Not comment" +' ^^^^^^^^^^^^^^^ meta.expression.vba + foo.bar = bar.foo +' ^^^^^^^ meta.expression.vba + foo = bar And Not True +' ^^^^^^^^^^^^^^^^ meta.expression.vba + foo = bar Or Not foo = 12 +' ^^^^^^^^^^^^^^^^^^^ meta.expression.vba + foo = Not bar +' ^^^^^^^ meta.expression.vba + foo = _ +' ^ meta.expression.vba + foo.bar.baz() _ +' ^^^^^^^^^^^^^^^ meta.expression.vba + + bar.foo.biz _ +' ^^^^^^^^^^^^^^^ meta.expression.vba +' ^ keyword.operator.arithmetic.vba + * 3 +' ^^^ meta.expression.vba +' ^ keyword.operator.arithmetic.vba + + foo = Not Me.Bar( _ +' ^^^^^^^^^^^^^ meta.expression.vba +' ^^^ keyword.operator.logical.vba +' ^^ meta.function.call.vba variable.language.me.vba +' ^^^ meta.function.call.vba entity.name.function.call.vba + foo, x = 3, False) ' Comment +' ^^^^^^^^^^^^^^^^^ meta.expression.vba +' ^^^ ^^^^^ ^^^^^ meta.expression.vba meta.expression.vba +' ^^^ variable.other.object.vba +' ^ variable.other.object.vba +' ^ keyword.operator.comparison.vba +' ^ constant.numeric.vba +' ^^^^^ constant.language.boolean.vba +' ^^^^^^^^^ comment.line.apostrophe.vba - meta.expression.vba + + If condA And Not Foo(condB) Then +' ^^^^^^^^^^^^^^^^^^^^^^^^ meta.expression.vba +' ^^^ ^^^ keyword.operator.logical.vba +' ^^^^^ meta.expression.vba meta.expression.vba variable.other.object.vba + End If +End Sub \ No newline at end of file From 7896b59c83e2fe76459c56cc8c0f3e3e37ddfcac Mon Sep 17 00:00:00 2001 From: sslinky Date: Thu, 6 Feb 2025 09:45:45 +0800 Subject: [PATCH 22/35] Reworked attributes --- client/src/syntaxes/vba.tmLanguage.yaml | 30 +++++- test/textmate/unit/methodAttributes.vba | 120 ++++++++++++------------ test/textmate/unit/moduleHeaders.vba | 4 +- 3 files changed, 87 insertions(+), 67 deletions(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index 8a78af1..fd96265 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -511,10 +511,18 @@ repository: moduleHeader: patterns: + - include: "#moduleVersion" - include: "#moduleAttributeBlock" - include: "#moduleAttribute" - include: "#moduleOption" repository: + moduleVersion: + name: entity.other.attribute-name.block.vba + match: (?i)^VERSION\s+([.\d]+)\s+CLASS + captures: + 1: + patterns: + - include: "#literals" moduleAttribute: name: meta.attribute.vba match: (?i)^\s*(Attribute)\s+(VB_\w+)\s+(=)\s+(.*)$ @@ -522,25 +530,37 @@ repository: 1: # Attribute name: keyword.attribute.vba 2: # VB_Name - name: entity.other.attribute-name.vba + name: support.variable.property.vba 3: # = - name: keyword.operator.comparison.vba + name: keyword.operator.assignment.vba 4: # "Sam" patterns: - include: "#literals" moduleAttributeBlock: name: entity.other.attribute-name.block.vba - begin: (?i)^VERSION + begin: (?i)^BEGIN end: (?i)^END patterns: - include: "#comments" - - include: "#literals" - - include: "#operators" + - include: "#attributeAssignment" moduleOption: name: keyword.control.vba match: (?i)^\s*Option\s+(Explicit|Base|Private\s+Module)\b + attributeAssignment: + name: meta.attribute-assignment.vba + match: (?i)([a-z.][a-z0-9._]*)(\s*=\s*)(.*) + captures: + 1: + name: support.variable.property.vba + 2: + name: keyword.operator.assignment.vba + 3: + patterns: + - include: "#literals" + - include: "#comments" + enum: name: meta.enum.declaration.vba begin: (?i)^\s*((?:(?:Public|Private)\s+)?\s*Enum)\s+([a-z][a-z0-9_]+)(\s+(?:'|Rem).*)? diff --git a/test/textmate/unit/methodAttributes.vba b/test/textmate/unit/methodAttributes.vba index 91eba76..31a8ccf 100644 --- a/test/textmate/unit/methodAttributes.vba +++ b/test/textmate/unit/methodAttributes.vba @@ -2,95 +2,95 @@ Public Function Identifier() As Variant Attribute Identifier.VB_Description = "Docstring." -' <-------------------------------------------------- source.method.attribute.vba -' <--------- entity.other.attribute-name.vba -' ^^^^^^^^^^ entity.name.function.vba -' ^^^^^^^^^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba -' ^^^^^^^^^^^^ string.quoted.double.vba +' <-------------------------------------------------- source.method.attribute.vba +' <--------- keyword.attribute.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba +' ^^^^^^^^^^^^ string.quoted.double.vba Attribute Identifier.VB_UserMemId = 0 -' <------------------------------------- source.method.attribute.vba -' <--------- entity.other.attribute-name.vba -' ^^^^^^^^^^ entity.name.function.vba -' ^^^^^^^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba -' ^ constant.numeric.vba +' <------------------------------------- source.method.attribute.vba +' <--------- keyword.attribute.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba +' ^ constant.numeric.vba End Function Public Sub Identifier() Attribute Identifier.VB_Description = "Docstring." -' <-------------------------------------------------- source.method.attribute.vba -' <--------- entity.other.attribute-name.vba -' ^^^^^^^^^^ entity.name.function.vba -' ^^^^^^^^^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba -' ^^^^^^^^^^^^ string.quoted.double.vba +' <-------------------------------------------------- source.method.attribute.vba +' <--------- keyword.attribute.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba +' ^^^^^^^^^^^^ string.quoted.double.vba Attribute Identifier.VB_UserMemId = 0 -' <------------------------------------- source.method.attribute.vba -' <--------- entity.other.attribute-name.vba -' ^^^^^^^^^^ entity.name.function.vba -' ^^^^^^^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba -' ^ constant.numeric.vba +' <------------------------------------- source.method.attribute.vba +' <--------- keyword.attribute.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba +' ^ constant.numeric.vba End Sub Public Property Let Identifier(var As PropertyType) Attribute Identifier.VB_Description = "Docstring." -' <-------------------------------------------------- source.method.attribute.vba -' <--------- entity.other.attribute-name.vba -' ^^^^^^^^^^ entity.name.function.vba -' ^^^^^^^^^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba -' ^^^^^^^^^^^^ string.quoted.double.vba +' <-------------------------------------------------- source.method.attribute.vba +' <--------- keyword.attribute.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba +' ^^^^^^^^^^^^ string.quoted.double.vba Attribute Identifier.VB_UserMemId = 0 -' <------------------------------------- source.method.attribute.vba -' <--------- entity.other.attribute-name.vba -' ^^^^^^^^^^ entity.name.function.vba -' ^^^^^^^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba -' ^ constant.numeric.vba +' <------------------------------------- source.method.attribute.vba +' <--------- keyword.attribute.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba +' ^ constant.numeric.vba End Property Public Property Get Identifier() As PropertyType Attribute Identifier.VB_Description = "Docstring." -' <-------------------------------------------------- source.method.attribute.vba -' <--------- entity.other.attribute-name.vba -' ^^^^^^^^^^ entity.name.function.vba -' ^^^^^^^^^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba -' ^^^^^^^^^^^^ string.quoted.double.vba +' <-------------------------------------------------- source.method.attribute.vba +' <--------- keyword.attribute.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba +' ^^^^^^^^^^^^ string.quoted.double.vba Attribute Identifier.VB_UserMemId = 0 -' <------------------------------------- source.method.attribute.vba -' <--------- entity.other.attribute-name.vba -' ^^^^^^^^^^ entity.name.function.vba -' ^^^^^^^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba -' ^ constant.numeric.vba +' <------------------------------------- source.method.attribute.vba +' <--------- keyword.attribute.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba +' ^ constant.numeric.vba End Property Public Property Let Identifier(var As PropertyType) Attribute Identifier.VB_Description = "Docstring." -' <-------------------------------------------------- source.method.attribute.vba -' <--------- entity.other.attribute-name.vba -' ^^^^^^^^^^ entity.name.function.vba -' ^^^^^^^^^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba -' ^^^^^^^^^^^^ string.quoted.double.vba +' <-------------------------------------------------- source.method.attribute.vba +' <--------- keyword.attribute.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba +' ^^^^^^^^^^^^ string.quoted.double.vba Attribute Identifier.VB_UserMemId = 0 -' <------------------------------------- source.method.attribute.vba -' <--------- entity.other.attribute-name.vba -' ^^^^^^^^^^ entity.name.function.vba -' ^^^^^^^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba -' ^ constant.numeric.vba +' <------------------------------------- source.method.attribute.vba +' <--------- keyword.attribute.vba +' ^^^^^^^^^^ entity.name.function.vba +' ^^^^^^^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba +' ^ constant.numeric.vba End Property \ No newline at end of file diff --git a/test/textmate/unit/moduleHeaders.vba b/test/textmate/unit/moduleHeaders.vba index c8569f9..764dafe 100644 --- a/test/textmate/unit/moduleHeaders.vba +++ b/test/textmate/unit/moduleHeaders.vba @@ -3,8 +3,8 @@ Attribute VB_Name = "ModuleName" ' <------------------------------- meta.attribute.vba ' <--------- keyword.attribute.vba -' ^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba +' ^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba ' ^^^^^^^^^^^^ string.quoted.double.vba Option Explicit From 4559f07ac088de7969b5a635e05697b95bb5b73d Mon Sep 17 00:00:00 2001 From: sslinky Date: Thu, 6 Feb 2025 09:46:08 +0800 Subject: [PATCH 23/35] Added TM notes --- client/src/syntaxes/vba.tmLanguage.yaml | 41 +++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index fd96265..732cafd 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -8,6 +8,47 @@ fileTypes: patterns: - include: "#fileStructure" + +# --- Notes ------------------------------------------------------------------------------------ +# * TextMate will only evaluate a single line at a time. For syntax spanning multiple lines, +# a begin/end rule is the only option. +# * TextMate will always fail gracefully. You can misspell a key or name, write an invalid +# regex pattern, or summon Beetlejuice. It will still run, it just won't work as expected. +# +# --- Match Rules ------------------------------------------------------------------------------ +# * Match rules contain a match key. +# * Matches are always consumed but can be passed down to captures key. +# * Patterns, begin, end, beginCaptures, and endCaptures keys will be ignored. +# * Repository key contains more rules but you can only call down the tree or to a top level. + +# --- Begin/End Rules -------------------------------------------------------------------------- +# * Begin/end rules contain a begin key and (usually) an end key. +# * Rules missing an end key will match to the end of the document (or capture - see tips). +# * Similar to match/captures, you can pair begin/beginCaptures and end/endCaptures. +# * Repository key is ignored and rules within are not accessible from anywhere. + +# --- Empty Rules ------------------------------------------------------------------------------ +# * Empty rules are used to organise rule flow with a patterns key, and optionally, repository. +# * They will never consume any content as they have no regex. +# * These rules cannot assign scope, so the name key wil be ignored. This may help to organise +# * your grammar, but can make it more difficult to test and debug. + +# --- Tips and Tricks -------------------------------------------------------------------------- +# * It can be advantageous to match without consuming anything, e.g., multi-level begin/end +# rules. You can cascade ends with (?=.) to match anything without consuming. +# Similarly, you may wish to end at [':\n] but consuming will cause comments to fail. +# * You can strategically consume content to skip it matching elsewhere, e.g., line continuation +# on a comment. Begin on ' and end on \n. If you consume the continuation _\s*\n then the +# comment will continue until the next line that doesn't have the continuation pattern. +# * Begin/End rules run until ended or until they reach the end of their scope of operation. +# This means passing a capture group from (begin|end)?capture down to a begin/end will _always +# end at the end of the what was captured!_. This cannot be more than to the end of the line. +# +# "Put conventional logic aside and enjoy. Well... I say, 'enjoy.'" +# - Garth Marenghi +# ---------------------------------------------------------------------------------------------- + + repository: fileStructure: patterns: From e675ce048d1c1eaaa8e628b6889c56ac759df738 Mon Sep 17 00:00:00 2001 From: sslinky Date: Thu, 6 Feb 2025 09:47:44 +0800 Subject: [PATCH 24/35] Bug fix begin/end broken at top level --- client/src/syntaxes/vba.tmLanguage.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index 732cafd..9a4942f 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -58,10 +58,10 @@ repository: - include: "#labels" # Handle labels first so they aren't handled by lines. - include: "#inlineMethod" # Try not to be too sad people can, and do, do this. - include: "#methodSignature" - - include: "#continuations" # Consume continuations so they "continue" other matches. - include: "#enum" - include: "#struct" - - include: "#syntaxLines" # Split document lines into syntax lines. + - include: "#variableDeclarations" + - include: "#main" continuations: name: meta.has-continuation.vba From acdaef1998d86172811ae248ca92ec767349d374 Mon Sep 17 00:00:00 2001 From: sslinky Date: Thu, 6 Feb 2025 09:48:30 +0800 Subject: [PATCH 25/35] Fix variable declaration --- client/src/syntaxes/vba.tmLanguage.yaml | 38 ++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index 9a4942f..4044a3e 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -816,26 +816,26 @@ repository: - include: "#variableDeclaration" repository: variableDeclaration: - name: storage.var-declaration.vba - match: (?i)^\s*(Dim|Public|Private|Global)\s+([a-z][a-z0-9_]*)([&%#!@$^])?(\(.*\))?(\s+As(?:\s+New)?\s+[A-Z][A-Z0-9_]*)? - captures: + name: meta.variable.declaration.vba + begin: (?i)(public|private|dim\s+)(?!const) + end: (?=[':\n]|Rem) + beginCaptures: 1: - # Dim|Private - name: storage.type.vba - 2: - # varName - name: variable.other.readwrite.vba - 3: - # Type hint? - name: support.type.primitive.vba - 4: - # Array bounds? - patterns: - - include: "#language" - 5: - # As Type - patterns: - - include: "#types" + name: storage.modifier.declare-variable.vba + patterns: + - include: "#lineContinuation" + - include: "#separator" + - match: (?i)([a-z][a-z0-9_]*)([&%#!@$^])?(?:\s+(as)\s+([a-z][a-z0-9_.]*))? + captures: + 1: + name: variable.other.read-write.vba + 2: + name: storage.type.$2.vba + 3: + name: keyword.control.as.vba + 4: + name: support.type.$4.vba + constDeclaration: name: storage.const-declaration.vba match: (?i)^\s*((?:(?:Public|Private)\s+)?Const)\s+([a-z][a-z0-9_]*)([&%#!@$^])?(\s+As\s+[a-z][a-z0-9_]*)?(.*) From d332c686f065698482a6df36ed1c6d53ea3b4031 Mon Sep 17 00:00:00 2001 From: sslinky Date: Thu, 6 Feb 2025 09:49:29 +0800 Subject: [PATCH 26/35] Method attribute scopes --- client/src/syntaxes/vba.tmLanguage.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index 4044a3e..f6807ba 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -756,13 +756,13 @@ repository: match: (?i)^\s*(Attribute)\s+([a-z][a-z0-9_]*)(\.VB_(?:Description|UserMemId))\s+(=)\s+(.*) captures: 1: - name: entity.other.attribute-name.vba + name: keyword.attribute.vba 2: name: entity.name.function.vba 3: - name: entity.other.attribute-name.vba + name: support.variable.property.vba 4: - name: keyword.operator.comparison.vba + name: keyword.operator.assignment.vba 5: patterns: - include: "#literals" From e1f9090b4667c87359b154dc76770aa77b617ffd Mon Sep 17 00:00:00 2001 From: sslinky Date: Thu, 6 Feb 2025 09:50:51 +0800 Subject: [PATCH 27/35] Fix key words --- client/src/syntaxes/vba.tmLanguage.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index f6807ba..075f889 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -174,15 +174,15 @@ repository: repository: kw-controlAs: name: keyword.control.as.vba - match: "(?i)\\bas\\b" + match: (?i)\bas\b kw-controlTo: - name: keyword.control.as.vba - match: "(?i)\\bto\\b" + name: keyword.control.to.vba + match: (?i)\bto\b kw-storageMe: - name: keyword.storage.me.vba - match: "(?i)\\bme\\b" + name: variable.language.me.vba + match: (?i)\bme\b kw-flow: patterns: From 91247fe32f6a62dbc6703049e277dc9293a74b37 Mon Sep 17 00:00:00 2001 From: sslinky Date: Thu, 6 Feb 2025 09:51:39 +0800 Subject: [PATCH 28/35] Add multi-line support --- client/src/syntaxes/vba.tmLanguage.yaml | 150 +++++++++--------------- test/textmate/unit/classHeaders.vba | 27 +++-- test/textmate/unit/params.vba | 74 ++++++++++++ 3 files changed, 142 insertions(+), 109 deletions(-) create mode 100644 test/textmate/unit/params.vba diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index 075f889..ddd9478 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -82,17 +82,6 @@ repository: name: keyword.control.line-continuation.vba match: (?<=\s)_\s*\n - syntaxLines: - name: meta.syntax-lines.vba - match: ((?:[^\n"':]|"(?:\\.|[^\n"\\])*")+|"(?:\\.|[^\n"\\])*")(?:('.*)*)? - captures: - 1: # Split line - patterns: - - include: "#main" - 2: # Comments - patterns: - - include: "#comments" - main: patterns: - include: "#declareFunctionSignature" @@ -109,10 +98,11 @@ repository: - include: "#literals" - include: "#operators" - include: "#keywords" - - include: "#variables" + - include: "#kw-storageMe" - include: "#functionCall" - include: "#objectModel" - include: "#subCall" + - include: "#subCallNoArgs" literals: @@ -335,10 +325,6 @@ repository: name: invalid.illegal.vba match: "^#.*" - variables: - name: variable.language.me.vba - match: (?i)\s+(Me)(?=\.|\s) - labels: # name: variable.other.constant.label.vba match: '(?i)^(\s*[a-z][a-z0-9_]*|\d+):' @@ -461,63 +447,15 @@ repository: 2: # Identifier name: variable.parameter.vba - # TODO: This needs to be repurposed to sub / function CALL rather than signature. - # Will need to separate arguments by comma, take line endings into account, and ignore commas inside parentheses. - # someSub someVar, "someLiteral", someFunc(1, 2, 3), _ - # someNextLineFunc() arguments: - # Rules that have no match will never return a name in the hierarchy. - # This name doesn't do anything but leaving this as usage notes. - name: source.args.vba + name: meta.arguments.vba + begin: (\s+|\(\s*) + end: (?=[\n')]) patterns: - include: "#lineContinuation" - - include: "#paramArray" - include: "#functionCall" - - include: "#argsVariable" - - include: "#language" - - include: "#argsLiteral" - repository: - argsVariable: - name: meta.arguments.argsVariable.vba - match: (?i),?\s*((?:Optional\s+)?(?:(?:ByVal|ByRef)\s+)?)?([a-z][a-z0-9_]*)(\(\))?(?:\s+(as\s+[a-z][a-z0-9_]*))?(\s*=\s*[^,)]+)? - # Attempted replacing \s with (?:\s+|\s*_\s*\n) to consume a space or a line ending but it refuses to play the game. - # match: ~~ doesn't work (?i),?(?:\s+|\s*_\s*\n)*((?:Optional(?:\s+|\s*_\s*\n)+)?(?:(?:ByVal|ByRef)(?:\s+|\s*_\s*\n)+)?)?([a-z][a-z0-9_]*)(?:(?:\s+|\s*_\s*\n)+(as(?:\s+|\s*_\s*\n)+[a-z][a-z0-9_]*))?((?:\s+|\s*_\s*\n)*=(?:\s+|\s*_\s*\n)*[^,\n)]+)? - # match: ~~ all broken (?i),?(?:\s*_\s*\n)*((?:Optional(?:\s+(?:\s*_\s*\n)*))?(?:(?:ByVal|ByRef)(?:\s+(?:\s*_\s*\n)*))?)?([a-z][a-z0-9_]*)(?:(?:\s+(?:\s*_\s*\n)*)(as\(?:\s+(?:\s*_\s*\n)*)[a-z][a-z0-9_]*))?((?:\s*_\s*\n)*=(?:\s*_\s*\n)*[^,)]+)? - captures: - 1: # Optional? ByVal|ByRef? - name: storage.type.modifier.vba - 2: # Identifier - name: variable.parameter.vba - 3: # As Type? - patterns: - - include: "#types" - 4: - patterns: - - include: "#language" - - argsLiteral: - # Should ideally only match on something that could be considered a literal. - # This kludge will at least not consume unmatched close parentheses. - name: meta.arguments.argsLiteral.vba - match: ((?:[^(",\n()]|"(?:\\.|[^\n"\\])*"|\([^)]*\))+|"(?:\\.|[^\n"\\])*") - captures: - 1: - patterns: - - include: "#literals" - - paramArray: - name: meta.args.paramarray.vba - match: (?i)(,)?\s*(ParamArray)\s+([a-z][a-z0-9_]*)(?:\(\))(\s+As\s+Variant)? - captures: - 1: - name: punctuation.separator.vba - 2: - name: storage.type.modifier.array.vba - 3: - name: variable.parameter.vba - 4: - patterns: - - include: "#types" + - include: "#separator" + - include: "#expression" comments: patterns: @@ -796,12 +734,9 @@ repository: blockLines: name: source.methodlines.vba match: (?:(^(?:\s*[a-z0-9]*?:\s*)(?:\s+'.*)?$)|(.*):) - # match: (?:(^(?:\s*[a-z0-9]*?:\s*)(?:\s+'.*)?$)|(.*):) captures: 1: # label name: source.methodlines.label.vba - # patterns: - # - include: "#labels" 2: # colon separated line patterns: - include: "#block" @@ -859,25 +794,23 @@ repository: - include: "#language" variableAssignment: - match: (?i)(?:(Get|Let|Set)\s+)?(?:([a-z][a-z0-9_]*))?(\.(?:(?:[a-z][a-z0-9_]*)?\.)*)?([a-z][a-z0-9_]*)?(\s*=\s*)(.*) - captures: - 1: # Get|Let|Set + name: meta.variable-assignment.vba + begin: (?i)(?:(Let|Set)\s+)?((?:[a-z][a-z0-9_]*)?(?:\.(?:(?:[a-z][a-z0-9_]*)?\.)*)?(?:[a-z][a-z0-9_]*)?)(\s*=\s*) + end: (?=[':\n]) + beginCaptures: + 1: # Let|Set name: keyword.control.vba - 2: # Variable name - name: variable.other.assignment.vba - 3: # Properties - patterns: - - include: "#propertyChain" - 4: # Property name - name: support.variable.property.vba - 5: # = - name: keyword.operator.assignment.vba - 6: # Expression + 2: # Variable property chain name patterns: - - include: "#expression" - - include: "#functionCall" - include: "#variable" - - include: "#language" + 3: # = + name: keyword.operator.assignment.vba + patterns: + - include: "#expression" + - include: "#functionCall" + - include: "#variable" + - include: "#language" + - include: "#lineContinuation" propertyChain: match: (?i)(\.)([a-z][a-z0-9_]*)* @@ -902,31 +835,56 @@ repository: functionCall: name: meta.function.call.vba - begin: (?i)([a-z][a-z0-9_]*)\( - end: \) + begin: (?i)(?:([a-z][a-z0-9_]*)(?=\.))?(\.(?:(?:[a-z][a-z0-9_]*)?\.)*)?([a-z][a-z0-9_]*)([&%#!@$^])?(?=\() + end: (\)|(?=')) beginCaptures: 1: + patterns: + - include: "#kw-storageMe" + - include: "#variable" + 2: + patterns: + - include: "#propertyChain" + 3: name: entity.name.function.call.vba + 4: + name: support.type.primitive.vba patterns: # These calls need to be back to a top level group because # textMate does not seem to support a repository in a begin/end - include: "#arguments" - - include: "#lineContinuation" subCall: name: meta.sub-call.vba - begin: (?i)([a-z][a-z0-9._]*)\s+(.*) + begin: (?i)(?:([a-z][a-z0-9_]*)(?=\.))?(\.(?:(?:[a-z][a-z0-9_]*)?\.)*)?([a-z][a-z0-9_]*)\s*(?=\s[^,'\n]) + end: (?=[\n']) beginCaptures: 1: - name: entity.name.function.call.vba + patterns: + - include: "#kw-storageMe" + - include: "#variable" 2: patterns: - - include: "#arguments" - end: \n + - include: "#propertyChain" + 3: + name: entity.name.function.call.vba patterns: - # - include: "#subCallMultiLine" - include: "#arguments" + subCallNoArgs: + name: meta.sub-call.vba + match: (?i)(?:([a-z][a-z0-9_]*)(?=\.))?(\.(?:(?:[a-z][a-z0-9_]*)?\.)*)?([a-z][a-z0-9_]*) + captures: + 1: + patterns: + - include: "#kw-storageMe" + - include: "#variable" + 2: + patterns: + - include: "#propertyChain" + 3: + name: entity.name.function.call.vba + testing: patterns: - name: keyword.control diff --git a/test/textmate/unit/classHeaders.vba b/test/textmate/unit/classHeaders.vba index a399bab..91a5184 100644 --- a/test/textmate/unit/classHeaders.vba +++ b/test/textmate/unit/classHeaders.vba @@ -10,7 +10,8 @@ BEGIN MultiUse = -1 'True ' ^^^^^^^^^^^^^^^^^^^^ entity.other.attribute-name.block.vba -' ^ keyword.operator.comparison.vba +' ^^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba ' ^^ constant.numeric.vba ' ^^^^^ comment.line.apostrophe.vba @@ -20,43 +21,43 @@ END Attribute VB_Name = "ClassName" ' <------------------------------ meta.attribute.vba ' <--------- keyword.attribute.vba -' ^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba +' ^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba ' ^^^^^^^^^^^ string.quoted.double.vba Attribute VB_Description = "Class description goes here" ' <------------------------------------------------------- meta.attribute.vba ' <--------- keyword.attribute.vba -' ^^^^^^^^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba +' ^^^^^^^^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.vba Attribute VB_GlobalNameSpace = False ' <----------------------------------- meta.attribute.vba ' <--------- keyword.attribute.vba -' ^^^^^^^^^^^^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba +' ^^^^^^^^^^^^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba ' ^^^^^ constant.language.boolean.vba Attribute VB_Creatable = False ' <----------------------------- meta.attribute.vba ' <--------- keyword.attribute.vba -' ^^^^^^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba +' ^^^^^^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba ' ^^^^^ constant.language.boolean.vba Attribute VB_PredeclaredId = False ' <--------------------------------- meta.attribute.vba ' <--------- keyword.attribute.vba -' ^^^^^^^^^^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba +' ^^^^^^^^^^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba ' ^^^^^ constant.language.boolean.vba Attribute VB_Exposed = False ' <--------------------------- meta.attribute.vba ' <--------- keyword.attribute.vba -' ^^^^^^^^^^ entity.other.attribute-name.vba -' ^ keyword.operator.comparison.vba +' ^^^^^^^^^^ support.variable.property.vba +' ^ keyword.operator.assignment.vba ' ^^^^^ constant.language.boolean.vba Option Explicit diff --git a/test/textmate/unit/params.vba b/test/textmate/unit/params.vba new file mode 100644 index 0000000..c40d4a1 --- /dev/null +++ b/test/textmate/unit/params.vba @@ -0,0 +1,74 @@ +' SYNTAX TEST "source.vba" "params" + +' Parameters passed to method calls. + +Sub SubCallTesting() + Foo bar, True, "abc,123", func(123, &H0000) ' Comment +' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.sub-call.vba +' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.arguments.vba +' ^^^ entity.name.function.call.vba +' ^^^ meta.variable-or-property.vba variable.other.object.vba +' ^ ^ ^ ^ punctuation.separator.vba +' ^^^^ constant.language.boolean.vba +' ^^^^^^^^^ string.quoted.double.vba +' ^^^^^^^^^^^^^^^^^ meta.function.call.vba +' ^^^ constant.numeric.vba +' ^^^^^^ constant.numeric.hex.vba +' ^^^^^^^^ comment.line.apostrophe.vba - meta.sub-call.vba + + Foo bar, _ +' ^^^^^^^^^^ meta.sub-call.vba +' ^^^ meta.arguments.vba meta.variable-or-property.vba variable.other.object.vba +' ^ meta.arguments.vba punctuation.separator.vba +' ^ meta.arguments.vba keyword.control.line-continuation.vba + True, _ +' ^^^^ meta.arguments.vba constant.language.boolean.vba + "abc,123", _ +' ^^^^^^^^^ meta.arguments.vba string.quoted.double.vba +' ^ meta.arguments.vba punctuation.separator.vba +' ^ meta.arguments.vba keyword.control.line-continuation.vba + func(123, &H0000) +' ^^^^^^^^^^^^^^^^^ meta.function.call.vba +' ^^^^^^^^^^^ meta.arguments.vba meta.arguments.vba +' ^^^ constant.numeric.vba +' ^ meta.arguments.vba punctuation.separator.vba +' ^^^^^^ constant.numeric.hex.vba +End Sub + +Sub FuncCallTesting() + x = Foo(bar, True, "abc,123", Func&(123, &H0000)) ' Comment +' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.call.vba +' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.arguments.vba +' ^ ^ ^ ^ punctuation.separator.vba +' ^^^ meta.variable-or-property.vba variable.other.object.vba +' ^^^^ constant.language.boolean.vba +' ^^^^^^^^^ string.quoted.double.vba +' ^^^^^^^^^^^^^^^^^^ meta.function.call.vba +' ^^^^ entity.name.function.call.vba +' ^ support.type.primitive.vba +' ^^^ constant.numeric.vba +' ^^^^^^ constant.numeric.hex.vba +' ^^^^^^^^ comment.line.apostrophe.vba - meta.function.call.vba + + x = Foo(bar, _ +' ^^^ meta.function.call.vba entity.name.function.call.vba +' ^^^ meta.function.call.vba meta.arguments.vba variable.other.object.vba +' ^ meta.function.call.vba meta.arguments.vba punctuation.separator.vba +' ^ meta.function.call.vba meta.arguments.vba keyword.control.line-continuation.vba + True, _ +' ^^^^ meta.function.call.vba meta.arguments.vba constant.language.boolean.vba +' ^ meta.function.call.vba meta.arguments.vba punctuation.separator.vba +' ^ meta.function.call.vba meta.arguments.vba keyword.control.line-continuation.vba + "abc,123", _ +' ^^^^^^^^^ meta.function.call.vba meta.arguments.vba string.quoted.double.vba +' ^ meta.function.call.vba meta.arguments.vba punctuation.separator.vba +' ^ meta.function.call.vba meta.arguments.vba keyword.control.line-continuation.vba + func&(123, &H0000)) ' Comment +' ^^^^^^^^^^^^^^^^^ meta.function.call.vba meta.arguments.vba meta.function.call.vba +' ^^^^ meta.function.call.vba meta.arguments.vba meta.function.call.vba entity.name.function.call.vba +' ^ meta.function.call.vba meta.arguments.vba meta.function.call.vba support.type.primitive.vba +' ^^^ meta.function.call.vba meta.arguments.vba meta.function.call.vba meta.arguments.vba constant.numeric.vba +' ^ meta.function.call.vba meta.arguments.vba meta.function.call.vba meta.arguments.vba punctuation.separator.vba +' ^^^^^^ meta.function.call.vba meta.arguments.vba meta.function.call.vba meta.arguments.vba constant.numeric.hex.vba +' ^^^^^^^^^ comment.line.apostrophe.vba - meta.function.call.vba +End Sub \ No newline at end of file From fcf00560f567ca3803d5c19b5071bd35b04770b2 Mon Sep 17 00:00:00 2001 From: sslinky Date: Thu, 6 Feb 2025 12:33:52 +0800 Subject: [PATCH 29/35] Bug fix variable declaration --- client/src/syntaxes/vba.tmLanguage.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index ddd9478..61a042b 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -752,8 +752,8 @@ repository: repository: variableDeclaration: name: meta.variable.declaration.vba - begin: (?i)(public|private|dim\s+)(?!const) - end: (?=[':\n]|Rem) + begin: (?i)(global|public|private|dim\s+)(?!const) + end: (?=[':\n]) beginCaptures: 1: name: storage.modifier.declare-variable.vba From 096c596960ccf0bc55d6ff9340b0791850c67d80 Mon Sep 17 00:00:00 2001 From: sslinky Date: Thu, 6 Feb 2025 15:13:06 +0800 Subject: [PATCH 30/35] Update and test variable declarations --- client/src/syntaxes/vba.tmLanguage.yaml | 6 ++- test/textmate/unit/declarations.vba | 70 +++++++++++++++++++++++++ test/textmate/unit/expressions.vba | 5 +- test/textmate/unit/methodSignatures.vba | 26 ++++----- test/textmate/unit/params.vba | 8 +-- 5 files changed, 94 insertions(+), 21 deletions(-) create mode 100644 test/textmate/unit/declarations.vba diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index 61a042b..2d41672 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -828,7 +828,11 @@ repository: patterns: - include: "#kw-storageMe" 2: - name: variable.other.object.vba + patterns: + - name: variable.other.constant + match: ([A-Z][A-Z0-9_]*) + - name: variable.other.readwrite.vba + match: (?i)([a-z][a-z0-9_]*) 3: patterns: - include: "#propertyChain" diff --git a/test/textmate/unit/declarations.vba b/test/textmate/unit/declarations.vba new file mode 100644 index 0000000..098678d --- /dev/null +++ b/test/textmate/unit/declarations.vba @@ -0,0 +1,70 @@ +' SYNTAX TEST "source.vba" "declarations" + +' Variable, constant, and function declarations. + + +Dim x As Long, y As Long, z ' Comment +'<------------------------------- meta.variable.declaration.vba +'<--- storage.modifier.declare-variable.vba +' ^ ^ ^ variable.other.readwrite.vba +' ^^ ^^ keyword.control.as.vba +' ^^^^ ^^^^ support.type.primitive.Long.vba +' ^ ^ punctuation.separator.vba +' ^^^^^^^^^ comment.line.apostrophe.vba - meta.variable.declaration.vba +Private x As Long, y As Long, z ' Comment +'<------------------------------- meta.variable.declaration.vba +'<------- storage.modifier.declare-variable.vba +' ^ ^ ^ variable.other.readwrite.vba +' ^^ ^^ keyword.control.as.vba +' ^^^^ ^^^^ support.type.primitive.Long.vba +' ^ ^ punctuation.separator.vba +' ^^^^^^^^^ comment.line.apostrophe.vba - meta.variable.declaration.vba +Public x As Long, y As Long, z ' Comment +'<------------------------------- meta.variable.declaration.vba +'<------ storage.modifier.declare-variable.vba +' ^ ^ ^ variable.other.readwrite.vba +' ^^ ^^ keyword.control.as.vba +' ^^^^ ^^^^ support.type.primitive.Long.vba +' ^ ^ punctuation.separator.vba +' ^^^^^^^^^ comment.line.apostrophe.vba - meta.variable.declaration.vba +Global x As Long, y As Long, z ' Comment +'<------------------------------- meta.variable.declaration.vba +'<------ storage.modifier.declare-variable.vba +' ^ ^ ^ variable.other.readwrite.vba +' ^^ ^^ keyword.control.as.vba +' ^^^^ ^^^^ support.type.primitive.Long.vba +' ^ ^ punctuation.separator.vba +' ^^^^^^^^^ comment.line.apostrophe.vba - meta.variable.declaration.vba + + Const X As Long = 0, Y As Long = 0, Z = 0 ' Comment +' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.const.declaration.vba +' ^^^^^ storage.type.vba +' ^ ^ ^ variable.other.constant +' ^^ ^^ keyword.control.as.vba +' ^^^^ ^^^^ support.type.primitive.Long.vba +' ^ ^ punctuation.separator.vba +' ^^^^^^^^^ comment.line.apostrophe.vba - meta.variable.declaration.vba +Private Const X As Long = 0, Y As Long = 0, Z = 0 ' Comment +' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.const.declaration.vba +' ^^^^^ storage.type.vba +' ^ ^ ^ variable.other.constant +' ^^ ^^ keyword.control.as.vba +' ^^^^ ^^^^ support.type.primitive.Long.vba +' ^ ^ punctuation.separator.vba +' ^^^^^^^^^ comment.line.apostrophe.vba - meta.variable.declaration.vba +Public Const X As Long = 0, Y As Long = 0, Z = 0 ' Comment +' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.const.declaration.vba +' ^^^^^ storage.type.vba +' ^ ^ ^ variable.other.constant +' ^^ ^^ keyword.control.as.vba +' ^^^^ ^^^^ support.type.primitive.Long.vba +' ^ ^ punctuation.separator.vba +' ^^^^^^^^^ comment.line.apostrophe.vba - meta.variable.declaration.vba +Global Const X As Long = 0, Y As Long = 0, Z = 0 ' Comment +' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.const.declaration.vba +' ^^^^^ storage.type.vba +' ^ ^ ^ variable.other.constant +' ^^ ^^ keyword.control.as.vba +' ^^^^ ^^^^ support.type.primitive.Long.vba +' ^ ^ punctuation.separator.vba +' ^^^^^^^^^ comment.line.apostrophe.vba - meta.variable.declaration.vba diff --git a/test/textmate/unit/expressions.vba b/test/textmate/unit/expressions.vba index 3c22fa4..1d8abb3 100644 --- a/test/textmate/unit/expressions.vba +++ b/test/textmate/unit/expressions.vba @@ -35,8 +35,7 @@ Sub Test() foo, x = 3, False) ' Comment ' ^^^^^^^^^^^^^^^^^ meta.expression.vba ' ^^^ ^^^^^ ^^^^^ meta.expression.vba meta.expression.vba -' ^^^ variable.other.object.vba -' ^ variable.other.object.vba +' ^^^ ^ variable.other.readwrite.vba ' ^ keyword.operator.comparison.vba ' ^ constant.numeric.vba ' ^^^^^ constant.language.boolean.vba @@ -45,6 +44,6 @@ Sub Test() If condA And Not Foo(condB) Then ' ^^^^^^^^^^^^^^^^^^^^^^^^ meta.expression.vba ' ^^^ ^^^ keyword.operator.logical.vba -' ^^^^^ meta.expression.vba meta.expression.vba variable.other.object.vba +' ^^^^^ meta.expression.vba meta.expression.vba variable.other.readwrite.vba End If End Sub \ No newline at end of file diff --git a/test/textmate/unit/methodSignatures.vba b/test/textmate/unit/methodSignatures.vba index 4b9b777..d21a3f3 100644 --- a/test/textmate/unit/methodSignatures.vba +++ b/test/textmate/unit/methodSignatures.vba @@ -16,17 +16,17 @@ Public Sub Foo(ByVal x As Long, ByRef y As Long, ParamArray vars() As Variant) ' ^^^^^ storage.type.modifier.vba ' ^ variable.parameter.vba ' ^^ keyword.control.as.vba -' ^^^^ support.type.primitive.vba +' ^^^^ support.type.primitive.Long.vba ' ^ punctuation.separator.vba ' ^^^^^ storage.type.modifier.vba ' ^ variable.parameter.vba ' ^^ keyword.control.as.vba -' ^^^^ support.type.primitive.vba +' ^^^^ support.type.primitive.Long.vba ' ^ punctuation.separator.vba ' ^^^^^^^^^^ storage.type.modifier.vba ' ^^^^ variable.parameter.vba ' ^^ keyword.control.as.vba -' ^^^^^^^ support.type.primitive.vba +' ^^^^^^^ support.type.primitive.Variant.vba ' ^ punctuation.definition.parameters.end.vba End Sub '<-------- storage.type.method.close.vba @@ -38,7 +38,7 @@ Function Foo() As String: Foo = "Hello, World!": End Function ' <-------- storage.type.method.vba ' ^^^ entity.name.function.vba ' ^^ keyword.control.as.vba -' ^^^^^^ support.type.primitive.vba +' ^^^^^^ support.type.primitive.String.vba ' ^^^^^^^^^^^^ storage.type.method.close.vba ' Standard function @@ -50,20 +50,20 @@ Public Function Foo(ByVal x As Long, ByRef y As Long, ParamArray vars() As Varia ' ^^^^^ storage.type.modifier.vba ' ^ variable.parameter.vba ' ^^ keyword.control.as.vba -' ^^^^ support.type.primitive.vba +' ^^^^ support.type.primitive.Long.vba ' ^ punctuation.separator.vba ' ^^^^^ storage.type.modifier.vba ' ^ variable.parameter.vba ' ^^ keyword.control.as.vba -' ^^^^ support.type.primitive.vba +' ^^^^ support.type.primitive.Long.vba ' ^ punctuation.separator.vba ' ^^^^^^^^^^ storage.type.modifier.vba ' ^^^^ variable.parameter.vba ' ^^ keyword.control.as.vba -' ^^^^^^^ support.type.primitive.vba +' ^^^^^^^ support.type.primitive.Variant.vba ' ^ punctuation.definition.parameters.end.vba ' ^^ keyword.control.as.vba -' ^^^^^^ support.type.object.vba +' ^^^^^^ support.type.object.Object.vba End Function '<------------- storage.type.method.close.vba @@ -75,14 +75,14 @@ Public Sub Foo(Optional Bar As String, _ ' ^^^^^^^^ storage.type.modifier.vba ' ^^^ variable.parameter.vba ' ^^ keyword.control.as.vba -' ^^^^^^ support.type.primitive.vba +' ^^^^^^ support.type.primitive.String.vba ' ^ punctuation.separator.vba ' ^ punctuation.line-continuation.vba Optional Biz As String = "Biz", _ ' ^^^^^^^^ storage.type.modifier.vba ' ^^^ variable.parameter.vba ' ^^ keyword.control.as.vba -' ^^^^^^ support.type.primitive.vba +' ^^^^^^ support.type.primitive.String.vba ' ^ keyword.operator.assignment.vba ' ^^^^^ string.quoted.double.vba ' ^ punctuation.separator.vba @@ -91,7 +91,7 @@ Public Sub Foo(Optional Bar As String, _ ' ^^^^^^^^ ^^^^^ storage.type.modifier.vba ' ^^^ variable.parameter.vba ' ^^ keyword.control.as.vba -' ^^^^^^^ support.type.primitive.vba +' ^^^^^^^ support.type.primitive.Boolean.vba ' ^ keyword.operator.assignment.vba ' ^^^^ constant.language.boolean.vba ' ^ punctuation.definition.parameters.end.vba @@ -111,7 +111,7 @@ Public Sub Foo( _ ' ^^^^^^^^ storage.type.modifier.vba ' ^^^ variable.parameter.vba ' ^^ keyword.control.as.vba -' ^^^^^^ support.type.primitive.vba +' ^^^^^^ support.type.primitive.String.vba ' ^ keyword.operator.assignment.vba ' ^^^^^^^^^^^ string.quoted.double.vba ' ^ punctuation.separator.vba @@ -121,7 +121,7 @@ Public Sub Foo( _ ' ^ punctuation.line-continuation.vba As String, _ ' ^^ keyword.control.as.vba -' ^^^^^^ support.type.primitive.vba +' ^^^^^^ support.type.primitive.String.vba ' ^ punctuation.separator.vba ' ^ punctuation.line-continuation.vba Optional _ diff --git a/test/textmate/unit/params.vba b/test/textmate/unit/params.vba index c40d4a1..562b466 100644 --- a/test/textmate/unit/params.vba +++ b/test/textmate/unit/params.vba @@ -7,7 +7,7 @@ Sub SubCallTesting() ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.sub-call.vba ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.arguments.vba ' ^^^ entity.name.function.call.vba -' ^^^ meta.variable-or-property.vba variable.other.object.vba +' ^^^ meta.variable-or-property.vba variable.other.readwrite.vba ' ^ ^ ^ ^ punctuation.separator.vba ' ^^^^ constant.language.boolean.vba ' ^^^^^^^^^ string.quoted.double.vba @@ -18,7 +18,7 @@ Sub SubCallTesting() Foo bar, _ ' ^^^^^^^^^^ meta.sub-call.vba -' ^^^ meta.arguments.vba meta.variable-or-property.vba variable.other.object.vba +' ^^^ meta.arguments.vba meta.variable-or-property.vba variable.other.readwrite.vba ' ^ meta.arguments.vba punctuation.separator.vba ' ^ meta.arguments.vba keyword.control.line-continuation.vba True, _ @@ -40,7 +40,7 @@ Sub FuncCallTesting() ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.call.vba ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.arguments.vba ' ^ ^ ^ ^ punctuation.separator.vba -' ^^^ meta.variable-or-property.vba variable.other.object.vba +' ^^^ meta.variable-or-property.vba variable.other.readwrite.vba ' ^^^^ constant.language.boolean.vba ' ^^^^^^^^^ string.quoted.double.vba ' ^^^^^^^^^^^^^^^^^^ meta.function.call.vba @@ -52,7 +52,7 @@ Sub FuncCallTesting() x = Foo(bar, _ ' ^^^ meta.function.call.vba entity.name.function.call.vba -' ^^^ meta.function.call.vba meta.arguments.vba variable.other.object.vba +' ^^^ meta.function.call.vba meta.arguments.vba variable.other.readwrite.vba ' ^ meta.function.call.vba meta.arguments.vba punctuation.separator.vba ' ^ meta.function.call.vba meta.arguments.vba keyword.control.line-continuation.vba True, _ From 70b3e0dcf766cde47789195b10a9707056c56dbb Mon Sep 17 00:00:00 2001 From: sslinky Date: Thu, 6 Feb 2025 15:52:50 +0800 Subject: [PATCH 31/35] Add multi-line variable declaration support --- client/src/syntaxes/vba.tmLanguage.yaml | 36 +++++++++++++++++-------- test/textmate/unit/declarations.vba | 36 +++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index 2d41672..388b0c2 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -411,10 +411,10 @@ repository: - include: "#AsTypeObject" repository: AsTypePrimative: - name: support.type.primitive.vba + name: support.type.primitive.$1.vba match: (?i)(boolean|byte|currency|date|decimal|double|integer|long(long|ptr)?|single|string|variant)\b AsTypeObject: - name: support.type.object.vba + name: support.type.object.$1.vba match: (?i)([A-Z][A-Z0-9_]*) argumentsSignature: @@ -760,18 +760,33 @@ repository: patterns: - include: "#lineContinuation" - include: "#separator" - - match: (?i)([a-z][a-z0-9_]*)([&%#!@$^])?(?:\s+(as)\s+([a-z][a-z0-9_.]*))? + - include: "#types" + - include: "#variable" + + constDeclaration: + name: meta.const.declaration.vba + begin: (?i)(?:(global|public|private)\s+)?(const) + end: (?=[':\n]) + beginCaptures: + 1: + name: storage.modifier.vba + 2: + name: storage.type.vba + patterns: + - include: "#lineContinuation" + - include: "#separator" + - include: "#types" + - include: "#variable" + - match: (=)\s+([^,'_\n]*) captures: 1: - name: variable.other.read-write.vba + name: keyword.operator.assignment.vba 2: - name: storage.type.$2.vba - 3: - name: keyword.control.as.vba - 4: - name: support.type.$4.vba + patterns: + - include: "#literals" - constDeclaration: + + constDeclaration2: name: storage.const-declaration.vba match: (?i)^\s*((?:(?:Public|Private)\s+)?Const)\s+([a-z][a-z0-9_]*)([&%#!@$^])?(\s+As\s+[a-z][a-z0-9_]*)?(.*) captures: @@ -865,7 +880,6 @@ repository: beginCaptures: 1: patterns: - - include: "#kw-storageMe" - include: "#variable" 2: patterns: diff --git a/test/textmate/unit/declarations.vba b/test/textmate/unit/declarations.vba index 098678d..18ae445 100644 --- a/test/textmate/unit/declarations.vba +++ b/test/textmate/unit/declarations.vba @@ -68,3 +68,39 @@ Global Const X As Long = 0, Y As Long = 0, Z = 0 ' Comment ' ^^^^ ^^^^ support.type.primitive.Long.vba ' ^ ^ punctuation.separator.vba ' ^^^^^^^^^ comment.line.apostrophe.vba - meta.variable.declaration.vba +Dim x As Long, _ +'<--- meta.variable.declaration.vba storage.modifier.declare-variable.vba +' ^ meta.variable.declaration.vba variable.other.readwrite.vba +' ^^ meta.variable.declaration.vba keyword.control.as.vba +' ^^^^ meta.variable.declaration.vba support.type.primitive.Long.vba +' ^ meta.variable.declaration.vba punctuation.separator.vba +' ^ meta.variable.declaration.vba keyword.control.line-continuation.vba + y As Long, _ +' ^ meta.variable.declaration.vba variable.other.readwrite.vba +' ^^ meta.variable.declaration.vba keyword.control.as.vba +' ^^^^ meta.variable.declaration.vba support.type.primitive.Long.vba +' ^ meta.variable.declaration.vba punctuation.separator.vba +' ^ meta.variable.declaration.vba keyword.control.line-continuation.vba + z ' Comment +' ^ meta.variable.declaration.vba variable.other.readwrite.vba +' ^^^^^^^^^ comment.line.apostrophe.vba - meta.variable.declaration.vba +Const X As Long = 0, _ +'<----- meta.const.declaration.vba storage.type.vba +' ^ meta.const.declaration.vba variable.other.constant +' ^^ meta.const.declaration.vba keyword.control.as.vba +' ^^^^ meta.const.declaration.vba support.type.primitive.Long.vba +' ^ meta.const.declaration.vba keyword.operator.assignment.vba +' ^ meta.const.declaration.vba constant.numeric.vba +' ^ meta.const.declaration.vba keyword.control.line-continuation.vba + Y As Long = 0, _ +' ^ meta.const.declaration.vba variable.other.constant +' ^^ meta.const.declaration.vba keyword.control.as.vba +' ^^^^ meta.const.declaration.vba support.type.primitive.Long.vba +' ^ meta.const.declaration.vba keyword.operator.assignment.vba +' ^ meta.const.declaration.vba constant.numeric.vba +' ^ meta.const.declaration.vba keyword.control.line-continuation.vba + Z = 0 ' Comment +' ^ meta.const.declaration.vba variable.other.constant +' ^ meta.const.declaration.vba keyword.operator.assignment.vba +' ^ meta.const.declaration.vba constant.numeric.vba +' ^^^^^^^^^ comment.line.apostrophe.vba - meta.variable.declaration.vba \ No newline at end of file From d54317c47d4108994b782721e6bddc594fb020a1 Mon Sep 17 00:00:00 2001 From: sslinky Date: Fri, 7 Feb 2025 00:19:14 +0800 Subject: [PATCH 32/35] Added multi-line support for method signatures --- client/src/syntaxes/vba.tmLanguage.yaml | 160 ++++++++++++++---------- test/textmate/snapshot/class.cls.snap | 41 +++--- test/textmate/snapshot/module.bas.snap | 4 +- test/textmate/unit/methodSignatures.vba | 69 +++++----- 4 files changed, 148 insertions(+), 126 deletions(-) diff --git a/client/src/syntaxes/vba.tmLanguage.yaml b/client/src/syntaxes/vba.tmLanguage.yaml index 388b0c2..67f664e 100644 --- a/client/src/syntaxes/vba.tmLanguage.yaml +++ b/client/src/syntaxes/vba.tmLanguage.yaml @@ -56,7 +56,6 @@ repository: - include: "#comments" # Handle comments here so they aren't broken by other stuff. - include: "#strings" # Handle strings here so they aren't broken by other stuff. - include: "#labels" # Handle labels first so they aren't handled by lines. - - include: "#inlineMethod" # Try not to be too sad people can, and do, do this. - include: "#methodSignature" - include: "#enum" - include: "#struct" @@ -103,6 +102,8 @@ repository: - include: "#objectModel" - include: "#subCall" - include: "#subCallNoArgs" + - name: keyword.control.line-separator.vba + match: ':' literals: @@ -183,6 +184,7 @@ repository: - include: "#forEachLoop" - include: "#flowLoop" - include: "#flowCall" + - include: "#methodClose" - include: "#flowPauseExit" - include: "#flowBranch" repository: @@ -264,7 +266,7 @@ repository: flowPauseExit: name: keyword.control.flow.other.vba - match: "(?i)\\b(doevents|end(?! property)|exit\\s+sub|exit\\s+function|exit\\s+property|stop)\\b" + match: "(?i)\\b(doevents|end(?! (sub|property|function))|exit\\s+sub|exit\\s+function|exit\\s+property|stop)\\b" flowBranch: patterns: @@ -409,43 +411,94 @@ repository: patterns: - include: "#AsTypePrimative" - include: "#AsTypeObject" - repository: - AsTypePrimative: - name: support.type.primitive.$1.vba - match: (?i)(boolean|byte|currency|date|decimal|double|integer|long(long|ptr)?|single|string|variant)\b - AsTypeObject: - name: support.type.object.$1.vba - match: (?i)([A-Z][A-Z0-9_]*) + AsTypePrimative: + name: support.type.primitive.$1.vba + match: (?i)(boolean|byte|currency|date|decimal|double|integer|long(long|ptr)?|single|string|variant)\b + AsTypeObject: + name: support.type.object.$1.vba + match: (?i)([a-z][a-z0-9._]*) argumentsSignature: name: meta.arguments.signature.vba - match: (?i)(?:(,)|(=)|(\s*_\s*\n)|(as\s+(?:\s*_\s*\n)*[a-z][a-z0-9_.]*)|(".*"|True|False|\d+(?:\.\d+)?[%&@!#$]?)|([a-z][a-z0-9_.]*[%&@!#$]?(?:\(\))?)) - captures: - 1: # , - patterns: - - include: "#separator" - 2: # = - name: keyword.operator.assignment.vba - 3: # _ - name: punctuation.line-continuation.vba - 4: # As Type? - patterns: - - include: "#types" - 5: # "foo" - patterns: - - include: "#literals" - 6: + begin: (?=[^ ():_]) + end: (?=\)) + patterns: + - include: "#separator" + - include: "#lineContinuation" + - include: "#argumentSignatureFromParamArray" + - include: "#argumentSignatureFromOptional" + - include: "#argumentSignatureFromBy" + - include: "#argumentSignatureFromParam" + + argumentSignatureFromParamArray: + name: meta.argument-signature.paramarray.vba + begin: (?i)paramarray + end: (?=[,):'\n]) + beginCaptures: + 0: + name: storage.type.modifier.vba + patterns: + - include: "#argumentSignatureFromParam" + - include: "#lineContinuation" + + argumentSignatureFromOptional: + name: meta.argument-signature.optional.vba + begin: (?i)optional + end: (?=[,):'\n]) + beginCaptures: + 0: + name: storage.type.modifier.vba + patterns: + - include: "#argumentSignatureFromBy" + - include: "#argumentSignatureFromParam" + - include: "#lineContinuation" + + argumentSignatureFromBy: + name: meta.argument-signature.by.vba + begin: (?i)(byref|byval) + end: (?=[,):'\n]) + beginCaptures: + 0: + name: storage.type.modifier.vba + patterns: + - include: "#argumentSignatureFromParam" + - include: "#lineContinuation" + + argumentSignatureFromParam: + name: meta.argument-signature.param.vba + begin: (?i)[a-z][a-z0-9]*(\(\))? + end: (?=[,):'\n]) + beginCaptures: + 0: + name: variable.parameter.vba + patterns: + - include: "#argumentSignatureFromTypeAs" + - include: "#lineContinuation" + + argumentSignatureFromTypeAs: + name: meta.argument-signature.as.vba + begin: (?i)\bas\b + end: (?=[,):'\n]) + beginCaptures: + 0: patterns: - include: "#keywords" - - include: "#argumentsVariableSignature" - repository: - argumentsVariableSignature: - match: (?i)(?:(Optional|ParamArray|ByRef|ByVal)|(.*)) - captures: - 1: # Optional? ByVal|ByRef? - name: storage.type.modifier.vba - 2: # Identifier - name: variable.parameter.vba + patterns: + - include: "#argumentSignatureFromTypeName" + - include: "#lineContinuation" + + argumentSignatureFromTypeName: + name: meta.argument-signature.type.vba + begin: (?i)([a-z][a-z0-9._]*) + end: (?=[,):'\n]) + beginCaptures: + 0: + patterns: + - include: "#AsTypePrimative" + - include: "#AsTypeObject" + patterns: + - include: "#variableAssignment" + - include: "#lineContinuation" arguments: name: meta.arguments.vba @@ -647,47 +700,22 @@ repository: patterns: - include: "#argumentsSignature" - inlineMethod: - name: source.inline-method.please-dont.vba - match: (?i)^\s*((?:Public|Private)?\b\s*(?:(?:Sub|Function)|Property\s+(?:Let|Get|Set)))\s+([a-z][a-z0-9_]*)\s*\((.+)?\)(\s+as\s+[a-z][a-z0-9_]*)?:(.*)?:\s*(End\s+(?:Sub|Function|Property)) - captures: - 1: # Method type - name: storage.type.method.vba - 2: # Identifier - name: entity.name.function.vba - 3: # Arguments? - patterns: - - include: "#argumentsSignature" - 4: # Return type? - patterns: - - include: "#types" - 5: # Method lines - patterns: - - include: "#fileStructure" - 6: # End method - name: storage.type.method.close.vba - - - methodSignature: name: source.method.signature.vba begin: (?i)^\s*((?:Public|Private)?\b\s*(?:(?:Sub|Function)|Property\s+(?:Let|Get|Set)))\s+([a-z][a-z0-9_]*)\s*(\() - end: (?i)\s*(\))\s+(as\s+[a-z][a-z0-9_]*)? + end: (?i)(?<=\))(\s+as\s+[a-z][a-z0-9_]*)? beginCaptures: 1: name: storage.type.method.vba 2: # name name: entity.name.function.vba - 3: - name: punctuation.definition.parameters.begin.vba endCaptures: - 1: - name: punctuation.definition.parameters.end.vba - 2: # return type + 1: # return type patterns: - include: "#types" patterns: - include: "#argumentsSignature" + - include: "#lineContinuation" methodAttribute: name: source.method.attribute.vba @@ -707,13 +735,13 @@ repository: methodClose: name: storage.type.method.close.vba - match: (?i)^\s*End\s+(Sub|Function|Property) + match: (?i)End\s+(Sub|Function|Property) expression: # Begins and ends without consuming anything. name: meta.expression.vba begin: (?=.) - end: (?=\n|\sThen|\)|'|,) + end: (?=\n|\sThen|\)|'|,|:) patterns: - include: "#literals" - include: "#operators" @@ -811,7 +839,7 @@ repository: variableAssignment: name: meta.variable-assignment.vba begin: (?i)(?:(Let|Set)\s+)?((?:[a-z][a-z0-9_]*)?(?:\.(?:(?:[a-z][a-z0-9_]*)?\.)*)?(?:[a-z][a-z0-9_]*)?)(\s*=\s*) - end: (?=[':\n]) + end: (?=[',:)\n]) beginCaptures: 1: # Let|Set name: keyword.control.vba @@ -845,7 +873,7 @@ repository: 2: patterns: - name: variable.other.constant - match: ([A-Z][A-Z0-9_]*) + match: ([A-Z][A-Z0-9_]*)\b - name: variable.other.readwrite.vba match: (?i)([a-z][a-z0-9_]*) 3: diff --git a/test/textmate/snapshot/class.cls.snap b/test/textmate/snapshot/class.cls.snap index ff44dbe..6da11df 100644 --- a/test/textmate/snapshot/class.cls.snap +++ b/test/textmate/snapshot/class.cls.snap @@ -1,64 +1,63 @@ >VERSION 1.0 CLASS -#^^^^^^^ source.vba entity.other.attribute-name.block.vba -# ^ source.vba entity.other.attribute-name.block.vba +#^^^^^^^^ source.vba entity.other.attribute-name.block.vba # ^^^ source.vba entity.other.attribute-name.block.vba constant.numeric.vba -# ^^^^^^^ source.vba entity.other.attribute-name.block.vba +# ^^^^^^ source.vba entity.other.attribute-name.block.vba >BEGIN -#^^^^^^ source.vba entity.other.attribute-name.block.vba +#^^^^^ source.vba entity.other.attribute-name.block.vba > MultiUse = -1 'True -#^^^^^^^^^^^ source.vba entity.other.attribute-name.block.vba -# ^ source.vba entity.other.attribute-name.block.vba keyword.operator.comparison.vba -# ^ source.vba entity.other.attribute-name.block.vba -# ^^ source.vba entity.other.attribute-name.block.vba constant.numeric.vba -# ^^^^^^^ source.vba entity.other.attribute-name.block.vba comment.line.apostrophe.vba +#^^ source.vba entity.other.attribute-name.block.vba +# ^^^^^^^^ source.vba entity.other.attribute-name.block.vba meta.attribute-assignment.vba support.variable.property.vba +# ^^^ source.vba entity.other.attribute-name.block.vba meta.attribute-assignment.vba keyword.operator.assignment.vba +# ^^ source.vba entity.other.attribute-name.block.vba meta.attribute-assignment.vba constant.numeric.vba +# ^^^^^^^ source.vba entity.other.attribute-name.block.vba meta.attribute-assignment.vba comment.line.apostrophe.vba >END #^^^ source.vba entity.other.attribute-name.block.vba >Attribute VB_Name = "ClassName" #^^^^^^^^^ source.vba meta.attribute.vba keyword.attribute.vba # ^ source.vba meta.attribute.vba -# ^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba +# ^^^^^^^ source.vba meta.attribute.vba support.variable.property.vba # ^ source.vba meta.attribute.vba -# ^ source.vba meta.attribute.vba keyword.operator.comparison.vba +# ^ source.vba meta.attribute.vba keyword.operator.assignment.vba # ^ source.vba meta.attribute.vba # ^^^^^^^^^^^ source.vba meta.attribute.vba string.quoted.double.vba >Attribute VB_Description = "Class description goes here" #^^^^^^^^^ source.vba meta.attribute.vba keyword.attribute.vba # ^ source.vba meta.attribute.vba -# ^^^^^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba +# ^^^^^^^^^^^^^^ source.vba meta.attribute.vba support.variable.property.vba # ^ source.vba meta.attribute.vba -# ^ source.vba meta.attribute.vba keyword.operator.comparison.vba +# ^ source.vba meta.attribute.vba keyword.operator.assignment.vba # ^ source.vba meta.attribute.vba # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.vba meta.attribute.vba string.quoted.double.vba >Attribute VB_GlobalNameSpace = False #^^^^^^^^^ source.vba meta.attribute.vba keyword.attribute.vba # ^ source.vba meta.attribute.vba -# ^^^^^^^^^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba +# ^^^^^^^^^^^^^^^^^^ source.vba meta.attribute.vba support.variable.property.vba # ^ source.vba meta.attribute.vba -# ^ source.vba meta.attribute.vba keyword.operator.comparison.vba +# ^ source.vba meta.attribute.vba keyword.operator.assignment.vba # ^ source.vba meta.attribute.vba # ^^^^^ source.vba meta.attribute.vba constant.language.boolean.vba >Attribute VB_Creatable = False #^^^^^^^^^ source.vba meta.attribute.vba keyword.attribute.vba # ^ source.vba meta.attribute.vba -# ^^^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba +# ^^^^^^^^^^^^ source.vba meta.attribute.vba support.variable.property.vba # ^ source.vba meta.attribute.vba -# ^ source.vba meta.attribute.vba keyword.operator.comparison.vba +# ^ source.vba meta.attribute.vba keyword.operator.assignment.vba # ^ source.vba meta.attribute.vba # ^^^^^ source.vba meta.attribute.vba constant.language.boolean.vba >Attribute VB_PredeclaredId = False #^^^^^^^^^ source.vba meta.attribute.vba keyword.attribute.vba # ^ source.vba meta.attribute.vba -# ^^^^^^^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba +# ^^^^^^^^^^^^^^^^ source.vba meta.attribute.vba support.variable.property.vba # ^ source.vba meta.attribute.vba -# ^ source.vba meta.attribute.vba keyword.operator.comparison.vba +# ^ source.vba meta.attribute.vba keyword.operator.assignment.vba # ^ source.vba meta.attribute.vba # ^^^^^ source.vba meta.attribute.vba constant.language.boolean.vba >Attribute VB_Exposed = False #^^^^^^^^^ source.vba meta.attribute.vba keyword.attribute.vba # ^ source.vba meta.attribute.vba -# ^^^^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba +# ^^^^^^^^^^ source.vba meta.attribute.vba support.variable.property.vba # ^ source.vba meta.attribute.vba -# ^ source.vba meta.attribute.vba keyword.operator.comparison.vba +# ^ source.vba meta.attribute.vba keyword.operator.assignment.vba # ^ source.vba meta.attribute.vba # ^^^^^ source.vba meta.attribute.vba constant.language.boolean.vba > diff --git a/test/textmate/snapshot/module.bas.snap b/test/textmate/snapshot/module.bas.snap index e0cce43..31d7ec0 100644 --- a/test/textmate/snapshot/module.bas.snap +++ b/test/textmate/snapshot/module.bas.snap @@ -1,9 +1,9 @@ >Attribute VB_Name = "ModuleName" #^^^^^^^^^ source.vba meta.attribute.vba keyword.attribute.vba # ^ source.vba meta.attribute.vba -# ^^^^^^^ source.vba meta.attribute.vba entity.other.attribute-name.vba +# ^^^^^^^ source.vba meta.attribute.vba support.variable.property.vba # ^ source.vba meta.attribute.vba -# ^ source.vba meta.attribute.vba keyword.operator.comparison.vba +# ^ source.vba meta.attribute.vba keyword.operator.assignment.vba # ^ source.vba meta.attribute.vba # ^^^^^^^^^^^^ source.vba meta.attribute.vba string.quoted.double.vba > diff --git a/test/textmate/unit/methodSignatures.vba b/test/textmate/unit/methodSignatures.vba index d21a3f3..daa1a79 100644 --- a/test/textmate/unit/methodSignatures.vba +++ b/test/textmate/unit/methodSignatures.vba @@ -2,17 +2,16 @@ ' Inline sub Sub Foo(): Debug.Print "Hello, World!": End Sub -' <----------------------------------------------- source.inline-method.please-dont.vba -' <--- storage.type.method.vba -' ^^^ entity.name.function.vba -' ^^^^^^^ storage.type.method.close.vba +'<-------- source.method.signature.vba +' <--- storage.type.method.vba +' ^^^ entity.name.function.vba +' ^^^^^^^ storage.type.method.close.vba ' Standard sub Public Sub Foo(ByVal x As Long, ByRef y As Long, ParamArray vars() As Variant) ' <------------------------------------------------------------------------------ source.method.signature.vba ' <---------- storage.type.method.vba ' ^^^ entity.name.function.vba -' ^ punctuation.definition.parameters.begin.vba ' ^^^^^ storage.type.modifier.vba ' ^ variable.parameter.vba ' ^^ keyword.control.as.vba @@ -27,26 +26,23 @@ Public Sub Foo(ByVal x As Long, ByRef y As Long, ParamArray vars() As Variant) ' ^^^^ variable.parameter.vba ' ^^ keyword.control.as.vba ' ^^^^^^^ support.type.primitive.Variant.vba -' ^ punctuation.definition.parameters.end.vba End Sub -'<-------- storage.type.method.close.vba ' Inline Function Function Foo() As String: Foo = "Hello, World!": End Function -' <------------------------------------------------------------- source.inline-method.please-dont.vba -' <-------- storage.type.method.vba -' ^^^ entity.name.function.vba -' ^^ keyword.control.as.vba -' ^^^^^^ support.type.primitive.String.vba -' ^^^^^^^^^^^^ storage.type.method.close.vba +' <-------------- source.method.signature.vba +' <-------- storage.type.method.vba +' ^^^ entity.name.function.vba +' ^^ keyword.control.as.vba +' ^^^^^^ support.type.primitive.String.vba +' ^^^^^^^^^^^^ storage.type.method.close.vba ' Standard function Public Function Foo(ByVal x As Long, ByRef y As Long, ParamArray vars() As Variant) As Object ' <--------------------------------------------------------------------------------------------- source.method.signature.vba ' <--------------- storage.type.method.vba ' ^^^ entity.name.function.vba -' ^ punctuation.definition.parameters.begin.vba ' ^^^^^ storage.type.modifier.vba ' ^ variable.parameter.vba ' ^^ keyword.control.as.vba @@ -61,7 +57,6 @@ Public Function Foo(ByVal x As Long, ByRef y As Long, ParamArray vars() As Varia ' ^^^^ variable.parameter.vba ' ^^ keyword.control.as.vba ' ^^^^^^^ support.type.primitive.Variant.vba -' ^ punctuation.definition.parameters.end.vba ' ^^ keyword.control.as.vba ' ^^^^^^ support.type.object.Object.vba End Function @@ -71,13 +66,12 @@ End Function Public Sub Foo(Optional Bar As String, _ ' <---------- storage.type.method.vba ' ^^^ entity.name.function.vba -' ^ punctuation.definition.parameters.begin.vba ' ^^^^^^^^ storage.type.modifier.vba ' ^^^ variable.parameter.vba ' ^^ keyword.control.as.vba ' ^^^^^^ support.type.primitive.String.vba ' ^ punctuation.separator.vba -' ^ punctuation.line-continuation.vba +' ^ keyword.control.line-continuation.vba Optional Biz As String = "Biz", _ ' ^^^^^^^^ storage.type.modifier.vba ' ^^^ variable.parameter.vba @@ -86,7 +80,7 @@ Public Sub Foo(Optional Bar As String, _ ' ^ keyword.operator.assignment.vba ' ^^^^^ string.quoted.double.vba ' ^ punctuation.separator.vba -' ^ punctuation.line-continuation.vba +' ^ keyword.control.line-continuation.vba Optional ByVal Zip As Boolean = True) ' ^^^^^^^^ ^^^^^ storage.type.modifier.vba ' ^^^ variable.parameter.vba @@ -94,7 +88,6 @@ Public Sub Foo(Optional Bar As String, _ ' ^^^^^^^ support.type.primitive.Boolean.vba ' ^ keyword.operator.assignment.vba ' ^^^^ constant.language.boolean.vba -' ^ punctuation.definition.parameters.end.vba End Sub '<-------- storage.type.method.close.vba @@ -105,48 +98,50 @@ End Sub Public Sub Foo( _ ' <---------- storage.type.method.vba ' ^^^ entity.name.function.vba -' ^ punctuation.definition.parameters.begin.vba -' ^ punctuation.line-continuation.vba - Optional baz As String = "Something", _ +' ^ keyword.control.line-continuation.vba + Optional baz As String _ ' ^^^^^^^^ storage.type.modifier.vba ' ^^^ variable.parameter.vba ' ^^ keyword.control.as.vba ' ^^^^^^ support.type.primitive.String.vba -' ^ keyword.operator.assignment.vba -' ^^^^^^^^^^^ string.quoted.double.vba -' ^ punctuation.separator.vba -' ^ punctuation.line-continuation.vba +' ^ keyword.control.line-continuation.vba + = _ +' ^ keyword.operator.assignment.vba +' ^ keyword.control.line-continuation.vba + "Something", _ +' ^^^^^^^^^^^ string.quoted.double.vba +' ^ punctuation.separator.vba +' ^ keyword.control.line-continuation.vba biz _ ' ^^^ variable.parameter.vba -' ^ punctuation.line-continuation.vba +' ^ keyword.control.line-continuation.vba As String, _ ' ^^ keyword.control.as.vba ' ^^^^^^ support.type.primitive.String.vba ' ^ punctuation.separator.vba -' ^ punctuation.line-continuation.vba +' ^ keyword.control.line-continuation.vba Optional _ ' ^^^^^^^^ storage.type.modifier.vba -' ^ punctuation.line-continuation.vba +' ^ keyword.control.line-continuation.vba ByRef _ ' ^^^^^ storage.type.modifier.vba -' ^ punctuation.line-continuation.vba +' ^ keyword.control.line-continuation.vba bix As _ ' ^^^ variable.parameter.vba ' ^^ keyword.control.as.vba -' ^ punctuation.line-continuation.vba +' ^ keyword.control.line-continuation.vba String, _ -' ^^^^^^ variable.parameter.vba +' ^^^^^^ support.type.primitive.String.vba ' ^ punctuation.separator.vba -' ^ punctuation.line-continuation.vba +' ^ keyword.control.line-continuation.vba bax _ ' ^^^ variable.parameter.vba -' ^ punctuation.line-continuation.vba +' ^ keyword.control.line-continuation.vba As _ ' ^^ keyword.control.as.vba -' ^ punctuation.line-continuation.vba +' ^ keyword.control.line-continuation.vba Object) -' ^^^^^^ variable.parameter.vba -' ^ punctuation.definition.parameters.end.vba +' ^^^^^^ support.type.object.Object.vba End Sub '<-------- storage.type.method.close.vba From f7050a17a51fa58fce7a21488c588cb216193b45 Mon Sep 17 00:00:00 2001 From: sslinky Date: Fri, 7 Feb 2025 08:15:58 +0800 Subject: [PATCH 33/35] Dev TM grammars --- .gitignore | 1 + package.json | 1 + 2 files changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 14d4ba0..cfa0b08 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ #folder is available **/out/* !client/out/*.tmp +client/src/syntaxes/dev* .antlr node_modules diff --git a/package.json b/package.json index 25b828d..e4294be 100644 --- a/package.json +++ b/package.json @@ -124,6 +124,7 @@ "lint": "eslint ./client/src ./server/src --ext .ts,.tsx", "postinstall": "cd client && npm install && cd ../server && npm install && cd ..", "textMate": "npx js-yaml client/src/syntaxes/vba.tmLanguage.yaml > client/out/vba.tmLanguage.json", + "devMate": "npx js-yaml client/src/syntaxes/dev.tmLanguage.yaml > client/out/vba.tmLanguage.json", "antlr4ng": "antlr4ng -Dlanguage=TypeScript -visitor ./server/src/antlr/vba.g4 -o ./server/src/antlr/out/", "antlr4ngPre": "antlr4ng -Dlanguage=TypeScript -visitor ./server/src/antlr/vbapre.g4 -o ./server/src/antlr/out/", "test": "npm run tmSnapTest && npm run tmUnitTest && npm run vsctest", From 5baa3979baad217fbd832e51efc54cee1c8d7354 Mon Sep 17 00:00:00 2001 From: sslinky Date: Fri, 7 Feb 2025 09:33:13 +0800 Subject: [PATCH 34/35] Bug fix module missing name diagnostic --- server/src/capabilities/capabilities.ts | 4 +++- server/src/project/elements/module.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/server/src/capabilities/capabilities.ts b/server/src/capabilities/capabilities.ts index c64c81a..264eecf 100644 --- a/server/src/capabilities/capabilities.ts +++ b/server/src/capabilities/capabilities.ts @@ -120,13 +120,15 @@ export class IdentifierCapability extends BaseCapability { nameContext: ParserRuleContext | TerminalNode; range: Range; name: string; + isDefaultMode: boolean; constructor(args: IdentifierArgs) { super(args.element); this.nameContext = ((args.getNameContext ?? (() => args.element.context.rule))() ?? args.element.context.rule); + this.isDefaultMode = !(!!args.getNameContext && !!args.getNameContext()); - if (!!this.nameContext) { + if (!this.isDefaultMode) { // Use the context to set the values. this.name = (args.formatName ?? ((name: string) => name))(this.nameContext.getText()); this.range = this.nameContext.toRange(args.element.context.document); diff --git a/server/src/project/elements/module.ts b/server/src/project/elements/module.ts index ca40024..1570ac2 100644 --- a/server/src/project/elements/module.ts +++ b/server/src/project/elements/module.ts @@ -44,7 +44,7 @@ abstract class BaseModuleElement extends BaseIdenti // Helpers protected addMissingAttributesDiagnostics(diagnostics: Diagnostic[]): void { - if (!!this.identifierCapability.nameContext) return; + if (!this.identifierCapability.isDefaultMode) return; diagnostics.push(new MissingAttributeDiagnostic( Range.create(this.context.range.start, this.context.range.start), 'VB_NAME' From 95786effee1c3b4e95c04d66e287794fe6f248e1 Mon Sep 17 00:00:00 2001 From: sslinky Date: Fri, 7 Feb 2025 09:38:42 +0800 Subject: [PATCH 35/35] 1.4.8 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3bb690f..62d4e9f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vba-lsp", - "version": "1.4.7", + "version": "1.4.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "vba-lsp", - "version": "1.4.7", + "version": "1.4.8", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index e4294be..5154e5f 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "icon": "images/vba-lsp-icon.png", "author": "SSlinky", "license": "MIT", - "version": "1.4.7", + "version": "1.4.8", "repository": { "type": "git", "url": "https://github.com/SSlinky/VBA-LanguageServer"