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