From c21794dc74ce4f615ea6a15f867a434b114fcf72 Mon Sep 17 00:00:00 2001 From: deathaxe Date: Wed, 25 Sep 2024 19:24:33 +0200 Subject: [PATCH] [Go] Improve generic type support Addresses some issues described in #3512 with least effort. It may not address all theoretical edge cases though. Especially meta scopes don't follow guidelines by any means, so seriously fixing issues would probably end up in significant refactoring, which is not scope of this commit/PR. --- Go/Go.sublime-syntax | 38 +++++++++++++++++-- Go/tests/syntax_test_go.go | 75 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 3 deletions(-) diff --git a/Go/Go.sublime-syntax b/Go/Go.sublime-syntax index 38bacc87d9..9c5f7ccbe0 100644 --- a/Go/Go.sublime-syntax +++ b/Go/Go.sublime-syntax @@ -84,6 +84,9 @@ variables: keyword_or_ident: \b[[:alpha:]_][[:alnum:]_]*\b + # Heuristic to scope types, assuming they start with upper case + type_ident: \b[[:upper:]_][[:alnum:]_]*\b + # Sublime normalizes newlines from `\r\n` and `\r` into `\n`. Sublime's syntax # engine uses regexps line-by-line, so `$` is often equivalent to `\n`. For # semantic accuracy, we should use `\n` when possible. However, the last line @@ -122,8 +125,33 @@ variables: # # Known defect: fails to recognize multiline type argument lists. # We should convert from lookahead to branching. - type_argument_list: \[(?:{{noise}}|[^\[\]])*\] - + type_argument_list: |- + (?x: + \[ (?: + {{noise}} + | \[ (?: + {{noise}} + | \[ (?: + {{noise}} + | \[ (?: + {{noise}} + | \[ (?: + {{noise}} + | \[ (?: + {{noise}} + | [^\[\]] + )* \] + | [^\[\]] + )* \] + | [^\[\]] + )* \] + | [^\[\]] + )* \] + | [^\[\]] + )* \] + | [^\[\]] + )* \] + ) iface_entry_delim: (?://|;|\}|{{newline}}) struct_entry_delim: (?:"|`|{{iface_entry_delim}}) @@ -487,7 +515,7 @@ contexts: - match: '{{ident_anon}}(?!{{noise}}\()' scope: variable.language.anonymous.go pop: 1 - - match: '{{ident}}(?!{{noise}}\()' + - match: '{{ident}}(?!{{noise}}{{type_argument_list}}?\()' scope: variable.other.member.go pop: 1 - match: \( @@ -1254,6 +1282,10 @@ contexts: scope: variable.language.anonymous.go push: pop-parameter-type + - match: '{{type_ident}}' + scope: storage.type.go + push: pop-type-argument-list + - match: '{{ident}}' scope: variable.parameter.go push: pop-parameter-type diff --git a/Go/tests/syntax_test_go.go b/Go/tests/syntax_test_go.go index be5985f3a5..8106864b14 100644 --- a/Go/tests/syntax_test_go.go +++ b/Go/tests/syntax_test_go.go @@ -1211,6 +1211,16 @@ by accident, but if necessary, such support could be sacrificed. // ^^^ meta.type.go storage.type.go // ^ meta.type.go punctuation.section.parens.end.go + Method(Type[TypeArg]) +// ^^^^^^^^^^^^^^^^^^^^^ meta.type.go +// ^^^^^^ entity.name.function.go +// ^ punctuation.section.parens.begin.go +// ^^^^ storage.type.go +// ^ punctuation.section.brackets.begin.go +// ^^^^^^^ variable.other.type.go +// ^ punctuation.section.brackets.end.go +// ^ punctuation.section.parens.end.go + Inherit // ^^^^^^^ meta.type.go storage.type.go @@ -4824,6 +4834,16 @@ by accident, but if necessary, such support could be sacrificed. // ^^^^ variable.function.go ) + ident[Type[TypeArg]]() +// ^^^^^ variable.function.go +// ^ punctuation.section.brackets.begin.go +// ^^^^ variable.other.type.go +// ^ punctuation.section.brackets.begin.go +// ^^^^^^^ variable.other.go +// ^^ punctuation.section.brackets.end.go +// ^ punctuation.section.parens.begin.go +// ^ punctuation.section.parens.end.go + ident.ident() // ^^^^^ variable.other.go // ^ punctuation.accessor.dot.go @@ -4846,6 +4866,36 @@ by accident, but if necessary, such support could be sacrificed. // ^^^^^ variable.other.go // ^ punctuation.section.parens.end.go + ident.ident.ident[Type, Type](ident) +// ^^^^^ variable.other.go +// ^ punctuation.accessor.dot.go +// ^^^^^ variable.other.member.go +// ^ punctuation.accessor.dot.go +// ^^^^^ variable.function.go +// ^ punctuation.section.brackets.begin.go +// ^^^^ variable.other.type.go +// ^ punctuation.separator.go +// ^^^^ variable.other.type.go +// ^ punctuation.section.brackets.end.go +// ^ punctuation.section.parens.begin.go +// ^^^^^ variable.other.go +// ^ punctuation.section.parens.end.go + + ident.ident.ident[Type[TypeArg]](ident) +// ^^^^^ variable.other.go +// ^ punctuation.accessor.dot.go +// ^^^^^ variable.other.member.go +// ^ punctuation.accessor.dot.go +// ^^^^^ variable.function.go +// ^ punctuation.section.brackets.begin.go +// ^^^^ variable.other.type.go +// ^ punctuation.section.brackets.begin.go +// ^^^^^^^ variable.other.go +// ^^ punctuation.section.brackets.end.go +// ^ punctuation.section.parens.begin.go +// ^^^^^ variable.other.go +// ^ punctuation.section.parens.end.go + ident /**/ . /**/ // ^^^^^ variable.other.go // ^^^^ comment.block.go @@ -5031,6 +5081,19 @@ by accident, but if necessary, such support could be sacrificed. ) typ {} // ^^^ storage.type.go + func FuncName(param [][]Type) {} +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration.go +// ^^^^ keyword.declaration.function.go +// ^^^^^^^^ entity.name.function.go +// ^ punctuation.section.parens.begin.go +// ^^^^^ variable.parameter.go +// ^ punctuation.section.brackets.begin.go +// ^ punctuation.section.brackets.end.go +// ^ punctuation.section.brackets.begin.go +// ^ punctuation.section.brackets.end.go +// ^^^^ storage.type.go +// ^ punctuation.section.parens.end.go + /* ### Methods */ func (self Type) Method() {} @@ -5051,6 +5114,18 @@ by accident, but if necessary, such support could be sacrificed. // ^ punctuation.section.parens.begin.go // ^ punctuation.section.parens.end.go + func(Type, Type[TypeArg]) +// ^^^^ keyword.declaration.function.go +// ^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration.go +// ^ punctuation.section.parens.begin.go +// ^^^^ storage.type.go +// ^ punctuation.separator.go +// ^^^^ storage.type.go +// ^ punctuation.section.brackets.begin.go +// ^^^^^^^ variable.other.type.go +// ^ punctuation.section.brackets.end.go +// ^ punctuation.section.parens.end.go + func /**/ // ^^^^ keyword.declaration.function.go // ^^^^ comment.block.go