From 0bba6d3a5536979ffc9ff330da2aa05a3bee1d7d Mon Sep 17 00:00:00 2001 From: Jesper Engberg Date: Fri, 15 May 2026 12:19:38 +0200 Subject: [PATCH] fix: accept newline type arguments without opening bracket --- TypeScript.YAML-tmLanguage | 6 +++++- TypeScript.tmLanguage | 18 +++++++++++++--- TypeScriptReact.tmLanguage | 18 +++++++++++++--- tests/baselines/Issue876.baseline.txt | 30 +++++++++++++++++++++++++++ tests/cases/Issue876.ts | 2 ++ 5 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 tests/baselines/Issue876.baseline.txt create mode 100644 tests/cases/Issue876.ts diff --git a/TypeScript.YAML-tmLanguage b/TypeScript.YAML-tmLanguage index 36fa5547..e32f3664 100644 --- a/TypeScript.YAML-tmLanguage +++ b/TypeScript.YAML-tmLanguage @@ -75,7 +75,7 @@ variables: typeArgumentsStart: (((keyof|infer|typeof|readonly)\s+)|(({{identifier}}|{{matchingBraces}}|{{matchingParenthesis}}|{{matchingBrackets}}|{{quotedStrings}})(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|))))) typeArgumentsInnerExpressionPart: '[^<>\(]|{{matchingParenthesis}}|(?<==)\>' typeArguments: '<\s*{{typeArgumentsStart}}({{typeArgumentsInnerExpressionPart}}|\<\s*{{typeArgumentsStart}}(({{typeArgumentsInnerExpressionPart}}|\<\s*{{typeArgumentsStart}}({{typeArgumentsInnerExpressionPart}})*(?))*(?)*(?' - possiblyMultilineTypeArgument: (<\s*[\{\[\(]\s*$) + possiblyMultilineTypeArgument: (<\s*([\{\[\(]\s*)?$) functionCallLookup: \s*(?:(\?\.\s*)|(\!))?(({{typeArguments}}\s*)?\() functionCallNamedTarget: (({{identifier}})(\s*{{propertyAccessPreIdentifier}}({{propertyIdentifier}}))*)|({{propertyAccessPreIdentifier}}{{propertyIdentifier}}) functionCallTarget: (({{functionCallNamedTarget}})|(?<=[\)])) @@ -988,6 +988,10 @@ repository: - include: '#comment' - include: '#class-or-interface-heritage' - include: '#type-parameters' + # prevent expressionWithoutIdentifiers>function-call from claiming identifier<\n as a call target in heritage clauses + - match: '({{identifier}})(?=\s*<\s*$)' + captures: + '1': { name: entity.other.inherited-class.ts } # match expressions before matching identifiers - include: '#expressionWithoutIdentifiers' # identifiers are treated as inherited class diff --git a/TypeScript.tmLanguage b/TypeScript.tmLanguage index 4d91f6ad..90d0ecf7 100644 --- a/TypeScript.tmLanguage +++ b/TypeScript.tmLanguage @@ -3120,6 +3120,18 @@ include #type-parameters + + match + ([_$[:alpha:]][_$[:alnum:]]*)(?=\s*<\s*$) + captures + + 1 + + name + entity.other.inherited-class.ts + + + include #expressionWithoutIdentifiers @@ -5033,9 +5045,9 @@ begin - (?=(((([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\)]))(<\s*[\{\[\(]\s*$)) + (?=(((([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\)]))(<\s*([\{\[\(]\s*)?$)) end - (?<=\>)(?!(((([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\)]))(<\s*[\{\[\(]\s*$)) + (?<=\>)(?!(((([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\)]))(<\s*([\{\[\(]\s*)?$)) patterns @@ -5044,7 +5056,7 @@ begin (?=(([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*)) end - (?=(<\s*[\{\[\(]\s*$)) + (?=(<\s*([\{\[\(]\s*)?$)) patterns diff --git a/TypeScriptReact.tmLanguage b/TypeScriptReact.tmLanguage index a7aec5da..5abe0e50 100644 --- a/TypeScriptReact.tmLanguage +++ b/TypeScriptReact.tmLanguage @@ -3142,6 +3142,18 @@ include #type-parameters + + match + ([_$[:alpha:]][_$[:alnum:]]*)(?=\s*<\s*$) + captures + + 1 + + name + entity.other.inherited-class.tsx + + + include #expressionWithoutIdentifiers @@ -5057,9 +5069,9 @@ begin - (?=(((([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\)]))(<\s*[\{\[\(]\s*$)) + (?=(((([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\)]))(<\s*([\{\[\(]\s*)?$)) end - (?<=\>)(?!(((([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\)]))(<\s*[\{\[\(]\s*$)) + (?<=\>)(?!(((([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*))|(?<=[\)]))(<\s*([\{\[\(]\s*)?$)) patterns @@ -5068,7 +5080,7 @@ begin (?=(([_$[:alpha:]][_$[:alnum:]]*)(\s*\??\.\s*(\#?[_$[:alpha:]][_$[:alnum:]]*))*)|(\??\.\s*\#?[_$[:alpha:]][_$[:alnum:]]*)) end - (?=(<\s*[\{\[\(]\s*$)) + (?=(<\s*([\{\[\(]\s*)?$)) patterns diff --git a/tests/baselines/Issue876.baseline.txt b/tests/baselines/Issue876.baseline.txt new file mode 100644 index 00000000..b7d8415f --- /dev/null +++ b/tests/baselines/Issue876.baseline.txt @@ -0,0 +1,30 @@ +original file +----------------------------------- +fn< + A>(); + +----------------------------------- + +Grammar: TypeScript.tmLanguage +----------------------------------- +>fn< + ^^ + source.ts meta.function-call.ts entity.name.function.ts + ^ + source.ts meta.type.parameters.ts punctuation.definition.typeparameters.begin.ts +> A>(); + ^^ + source.ts meta.type.parameters.ts + ^ + source.ts meta.type.parameters.ts entity.name.type.ts + ^ + source.ts meta.type.parameters.ts punctuation.definition.typeparameters.end.ts + ^ + source.ts meta.brace.round.ts + ^ + source.ts meta.brace.round.ts + ^ + source.ts punctuation.terminator.statement.ts +> + ^ + source.ts \ No newline at end of file diff --git a/tests/cases/Issue876.ts b/tests/cases/Issue876.ts new file mode 100644 index 00000000..52b21148 --- /dev/null +++ b/tests/cases/Issue876.ts @@ -0,0 +1,2 @@ +fn< + A>();