Skip to content

Commit fb1064a

Browse files
committed
Treat ( followed by new line as parameter context for arrow, falling back to expression
Handles #481, #498, #507, #524, #539, #550
1 parent 1d2625a commit fb1064a

File tree

7 files changed

+484
-35
lines changed

7 files changed

+484
-35
lines changed

TypeScript.YAML-tmLanguage

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ variables:
2020
typeArgumentsStart: ({{typeParamersStart}}|(\'[^\']*\')|(\"[^\"]*\")|(\`[^\`]*\`))
2121
typeArgumentsInnerExpressionPart: '[^<>\(]|{{matchingParenthesis}}'
2222
typeArguments: (<\s*{{typeArgumentsStart}}({{typeArgumentsInnerExpressionPart}}|\<\s*{{typeArgumentsStart}}({{typeArgumentsInnerExpressionPart}})*\>)*>\s*)
23+
returnTypeOfArrow: '\s*([^<>\(\)]|\<[^<>]+\>|\([^\(\)]+\))+'
2324
arrowLookup: |-
2425
# sure shot arrow functions even if => is on new line
2526
(
@@ -36,7 +37,7 @@ variables:
3637
(
3738
{{typeParameters}}? # typeparameters
3839
\(\s*([_$[:alpha:]\{\[]([^()]|\((\s*[^()]*)?\))*)?\) # parameteres
39-
(\s*:\s*([^<>\(\)]|\<[^<>]+\>|\([^\(\)]+\))+)? # return type
40+
(\s*:{{returnTypeOfArrow}})? # return type
4041
\s*=> # arrow operator
4142
)
4243
functionOrArrowLookup: |-
@@ -47,6 +48,7 @@ variables:
4748
({{identifier}}\s*=>)
4849
)) |
4950
((async\s*)?(
51+
([\(]\s*$) | # during lookup treat ( followed by line end as arrow
5052
{{arrowLookup}}
5153
))
5254
)
@@ -66,6 +68,7 @@ variables:
6668
))
6769
))
6870
))
71+
arrowFunctionEnd: (?==>|\{|(^\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\s+))
6972

7073
patterns:
7174
- include: '#directives'
@@ -147,6 +150,7 @@ repository:
147150
- include: '#function-call'
148151
- include: '#literal'
149152
- include: '#support-objects'
153+
- include: '#paren-expression-possibly-arrow'
150154
- include: '#paren-expression'
151155

152156
expressionPunctuations:
@@ -548,7 +552,7 @@ repository:
548552
)
549553
beginCaptures:
550554
'1': { name: storage.modifier.async.ts }
551-
end: (?==>|\{|(^\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\s+))
555+
end: '{{arrowFunctionEnd}}'
552556
patterns:
553557
- include: '#comment'
554558
- include: '#type-parameters'
@@ -603,6 +607,10 @@ repository:
603607
endCaptures:
604608
'0': { name: punctuation.definition.parameters.end.ts }
605609
patterns:
610+
- include: '#function-parameters-body'
611+
612+
function-parameters-body:
613+
patterns:
606614
- include: '#comment'
607615
- include: '#decorator'
608616
- include: '#destructuring-parameter'
@@ -1084,6 +1092,23 @@ repository:
10841092
- include: '#class-declaration'
10851093
- include: '#type'
10861094

1095+
# when ( is followed by end of line, it could be arrow parameter decarations, so inside this match as if parameter falling back to expression
1096+
# but do this only from expression and as last resort
1097+
paren-expression-possibly-arrow:
1098+
patterns:
1099+
- begin: (\()(?=\s*$)
1100+
beginCaptures:
1101+
'1': {name: meta.brace.round.ts }
1102+
end: \)
1103+
endCaptures:
1104+
'0': {name: meta.brace.round.ts }
1105+
patterns:
1106+
- include: '#expressionWithoutIdentifiers'
1107+
- include: '#function-parameters-body'
1108+
- include: '#identifiers'
1109+
- include: '#expressionPunctuations'
1110+
- include: '#possibly-arrow-return-type'
1111+
10871112
paren-expression:
10881113
begin: \(
10891114
beginCaptures:
@@ -1093,7 +1118,6 @@ repository:
10931118
'0': {name: meta.brace.round.ts }
10941119
patterns:
10951120
- include: '#expression'
1096-
- include: '#punctuation-comma'
10971121

10981122
#cast expression
10991123
cast:
@@ -1645,7 +1669,21 @@ repository:
16451669
begin: '(?<=\))\s*(:)'
16461670
beginCaptures:
16471671
'1': { name: keyword.operator.type.annotation.ts }
1648-
end: (?==>|\{|(^\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\s+))
1672+
end: '{{arrowFunctionEnd}}'
1673+
patterns:
1674+
- include: '#arrow-return-type-body'
1675+
1676+
#This is the check if the exoression '): something =>'' can be matched as return type of arrow
1677+
possibly-arrow-return-type:
1678+
begin: (?<=\))\s*(:)(?={{returnTypeOfArrow}}\s*=>)
1679+
beginCaptures:
1680+
'1': { name: meta.arrow.ts meta.return.type.arrow.ts keyword.operator.type.annotation.ts }
1681+
end: '{{arrowFunctionEnd}}'
1682+
contentName: meta.arrow.ts meta.return.type.arrow.ts
1683+
patterns:
1684+
- include: '#arrow-return-type-body'
1685+
1686+
arrow-return-type-body:
16491687
patterns:
16501688
# TODO: handle the fn and constructor type specifically.
16511689
# Handle returning of object type specifically here so as to not confuse it with the start of function block

TypeScript.tmLanguage

Lines changed: 110 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,10 @@
275275
<key>include</key>
276276
<string>#support-objects</string>
277277
</dict>
278+
<dict>
279+
<key>include</key>
280+
<string>#paren-expression-possibly-arrow</string>
281+
</dict>
278282
<dict>
279283
<key>include</key>
280284
<string>#paren-expression</string>
@@ -414,6 +418,7 @@
414418
([_$[:alpha:]][_$[:alnum:]]*\s*=&gt;)
415419
)) |
416420
((async\s*)?(
421+
([\(]\s*$) | # during lookup treat ( followed by line end as arrow
417422
# sure shot arrow functions even if =&gt; is on new line
418423
(
419424
[(]\s*
@@ -429,7 +434,7 @@
429434
(
430435
(&lt;\s*([_$[:alpha:]]|(\{[^\{\}]*\})|(\([^\(\)]*\))|(\[[^\[\]]*\]))([^=&lt;&gt;]|=[^&lt;]|\&lt;\s*([_$[:alpha:]]|(\{[^\{\}]*\})|(\([^\(\)]*\))|(\[[^\[\]]*\]))([^=&lt;&gt;]|=[^&lt;])*\&gt;)*&gt;\s*)? # typeparameters
431436
\(\s*([_$[:alpha:]\{\[]([^()]|\((\s*[^()]*)?\))*)?\) # parameteres
432-
(\s*:\s*([^&lt;&gt;\(\)]|\&lt;[^&lt;&gt;]+\&gt;|\([^\(\)]+\))+)? # return type
437+
(\s*:\s*([^&lt;&gt;\(\)]|\&lt;[^&lt;&gt;]+\&gt;|\([^\(\)]+\))+)? # return type
433438
\s*=&gt; # arrow operator
434439
)
435440
))
@@ -802,6 +807,7 @@
802807
([_$[:alpha:]][_$[:alnum:]]*\s*=&gt;)
803808
)) |
804809
((async\s*)?(
810+
([\(]\s*$) | # during lookup treat ( followed by line end as arrow
805811
# sure shot arrow functions even if =&gt; is on new line
806812
(
807813
[(]\s*
@@ -817,7 +823,7 @@
817823
(
818824
(&lt;\s*([_$[:alpha:]]|(\{[^\{\}]*\})|(\([^\(\)]*\))|(\[[^\[\]]*\]))([^=&lt;&gt;]|=[^&lt;]|\&lt;\s*([_$[:alpha:]]|(\{[^\{\}]*\})|(\([^\(\)]*\))|(\[[^\[\]]*\]))([^=&lt;&gt;]|=[^&lt;])*\&gt;)*&gt;\s*)? # typeparameters
819825
\(\s*([_$[:alpha:]\{\[]([^()]|\((\s*[^()]*)?\))*)?\) # parameteres
820-
(\s*:\s*([^&lt;&gt;\(\)]|\&lt;[^&lt;&gt;]+\&gt;|\([^\(\)]+\))+)? # return type
826+
(\s*:\s*([^&lt;&gt;\(\)]|\&lt;[^&lt;&gt;]+\&gt;|\([^\(\)]+\))+)? # return type
821827
\s*=&gt; # arrow operator
822828
)
823829
))
@@ -1188,6 +1194,7 @@
11881194
([_$[:alpha:]][_$[:alnum:]]*\s*=&gt;)
11891195
)) |
11901196
((async\s*)?(
1197+
([\(]\s*$) | # during lookup treat ( followed by line end as arrow
11911198
# sure shot arrow functions even if =&gt; is on new line
11921199
(
11931200
[(]\s*
@@ -1203,7 +1210,7 @@
12031210
(
12041211
(&lt;\s*([_$[:alpha:]]|(\{[^\{\}]*\})|(\([^\(\)]*\))|(\[[^\[\]]*\]))([^=&lt;&gt;]|=[^&lt;]|\&lt;\s*([_$[:alpha:]]|(\{[^\{\}]*\})|(\([^\(\)]*\))|(\[[^\[\]]*\]))([^=&lt;&gt;]|=[^&lt;])*\&gt;)*&gt;\s*)? # typeparameters
12051212
\(\s*([_$[:alpha:]\{\[]([^()]|\((\s*[^()]*)?\))*)?\) # parameteres
1206-
(\s*:\s*([^&lt;&gt;\(\)]|\&lt;[^&lt;&gt;]+\&gt;|\([^\(\)]+\))+)? # return type
1213+
(\s*:\s*([^&lt;&gt;\(\)]|\&lt;[^&lt;&gt;]+\&gt;|\([^\(\)]+\))+)? # return type
12071214
\s*=&gt; # arrow operator
12081215
)
12091216
))
@@ -1644,7 +1651,7 @@
16441651
(
16451652
(&lt;\s*([_$[:alpha:]]|(\{[^\{\}]*\})|(\([^\(\)]*\))|(\[[^\[\]]*\]))([^=&lt;&gt;]|=[^&lt;]|\&lt;\s*([_$[:alpha:]]|(\{[^\{\}]*\})|(\([^\(\)]*\))|(\[[^\[\]]*\]))([^=&lt;&gt;]|=[^&lt;])*\&gt;)*&gt;\s*)? # typeparameters
16461653
\(\s*([_$[:alpha:]\{\[]([^()]|\((\s*[^()]*)?\))*)?\) # parameteres
1647-
(\s*:\s*([^&lt;&gt;\(\)]|\&lt;[^&lt;&gt;]+\&gt;|\([^\(\)]+\))+)? # return type
1654+
(\s*:\s*([^&lt;&gt;\(\)]|\&lt;[^&lt;&gt;]+\&gt;|\([^\(\)]+\))+)? # return type
16481655
\s*=&gt; # arrow operator
16491656
)
16501657
)
@@ -1831,6 +1838,16 @@
18311838
<string>punctuation.definition.parameters.end.ts</string>
18321839
</dict>
18331840
</dict>
1841+
<key>patterns</key>
1842+
<array>
1843+
<dict>
1844+
<key>include</key>
1845+
<string>#function-parameters-body</string>
1846+
</dict>
1847+
</array>
1848+
</dict>
1849+
<key>function-parameters-body</key>
1850+
<dict>
18341851
<key>patterns</key>
18351852
<array>
18361853
<dict>
@@ -3100,6 +3117,7 @@
31003117
([_$[:alpha:]][_$[:alnum:]]*\s*=&gt;)
31013118
)) |
31023119
((async\s*)?(
3120+
([\(]\s*$) | # during lookup treat ( followed by line end as arrow
31033121
# sure shot arrow functions even if =&gt; is on new line
31043122
(
31053123
[(]\s*
@@ -3115,7 +3133,7 @@
31153133
(
31163134
(&lt;\s*([_$[:alpha:]]|(\{[^\{\}]*\})|(\([^\(\)]*\))|(\[[^\[\]]*\]))([^=&lt;&gt;]|=[^&lt;]|\&lt;\s*([_$[:alpha:]]|(\{[^\{\}]*\})|(\([^\(\)]*\))|(\[[^\[\]]*\]))([^=&lt;&gt;]|=[^&lt;])*\&gt;)*&gt;\s*)? # typeparameters
31173135
\(\s*([_$[:alpha:]\{\[]([^()]|\((\s*[^()]*)?\))*)?\) # parameteres
3118-
(\s*:\s*([^&lt;&gt;\(\)]|\&lt;[^&lt;&gt;]+\&gt;|\([^\(\)]+\))+)? # return type
3136+
(\s*:\s*([^&lt;&gt;\(\)]|\&lt;[^&lt;&gt;]+\&gt;|\([^\(\)]+\))+)? # return type
31193137
\s*=&gt; # arrow operator
31203138
)
31213139
))
@@ -3383,6 +3401,57 @@
33833401
</dict>
33843402
</array>
33853403
</dict>
3404+
<key>paren-expression-possibly-arrow</key>
3405+
<dict>
3406+
<key>patterns</key>
3407+
<array>
3408+
<dict>
3409+
<key>begin</key>
3410+
<string>(\()(?=\s*$)</string>
3411+
<key>beginCaptures</key>
3412+
<dict>
3413+
<key>1</key>
3414+
<dict>
3415+
<key>name</key>
3416+
<string>meta.brace.round.ts</string>
3417+
</dict>
3418+
</dict>
3419+
<key>end</key>
3420+
<string>\)</string>
3421+
<key>endCaptures</key>
3422+
<dict>
3423+
<key>0</key>
3424+
<dict>
3425+
<key>name</key>
3426+
<string>meta.brace.round.ts</string>
3427+
</dict>
3428+
</dict>
3429+
<key>patterns</key>
3430+
<array>
3431+
<dict>
3432+
<key>include</key>
3433+
<string>#expressionWithoutIdentifiers</string>
3434+
</dict>
3435+
<dict>
3436+
<key>include</key>
3437+
<string>#function-parameters-body</string>
3438+
</dict>
3439+
<dict>
3440+
<key>include</key>
3441+
<string>#identifiers</string>
3442+
</dict>
3443+
<dict>
3444+
<key>include</key>
3445+
<string>#expressionPunctuations</string>
3446+
</dict>
3447+
</array>
3448+
</dict>
3449+
<dict>
3450+
<key>include</key>
3451+
<string>#possibly-arrow-return-type</string>
3452+
</dict>
3453+
</array>
3454+
</dict>
33863455
<key>paren-expression</key>
33873456
<dict>
33883457
<key>begin</key>
@@ -3411,10 +3480,6 @@
34113480
<key>include</key>
34123481
<string>#expression</string>
34133482
</dict>
3414-
<dict>
3415-
<key>include</key>
3416-
<string>#punctuation-comma</string>
3417-
</dict>
34183483
</array>
34193484
</dict>
34203485
<key>cast</key>
@@ -4337,6 +4402,7 @@
43374402
([_$[:alpha:]][_$[:alnum:]]*\s*=&gt;)
43384403
)) |
43394404
((async\s*)?(
4405+
([\(]\s*$) | # during lookup treat ( followed by line end as arrow
43404406
# sure shot arrow functions even if =&gt; is on new line
43414407
(
43424408
[(]\s*
@@ -4352,7 +4418,7 @@
43524418
(
43534419
(&lt;\s*([_$[:alpha:]]|(\{[^\{\}]*\})|(\([^\(\)]*\))|(\[[^\[\]]*\]))([^=&lt;&gt;]|=[^&lt;]|\&lt;\s*([_$[:alpha:]]|(\{[^\{\}]*\})|(\([^\(\)]*\))|(\[[^\[\]]*\]))([^=&lt;&gt;]|=[^&lt;])*\&gt;)*&gt;\s*)? # typeparameters
43544420
\(\s*([_$[:alpha:]\{\[]([^()]|\((\s*[^()]*)?\))*)?\) # parameteres
4355-
(\s*:\s*([^&lt;&gt;\(\)]|\&lt;[^&lt;&gt;]+\&gt;|\([^\(\)]+\))+)? # return type
4421+
(\s*:\s*([^&lt;&gt;\(\)]|\&lt;[^&lt;&gt;]+\&gt;|\([^\(\)]+\))+)? # return type
43564422
\s*=&gt; # arrow operator
43574423
)
43584424
))
@@ -4627,6 +4693,40 @@
46274693
</dict>
46284694
<key>end</key>
46294695
<string>(?==&gt;|\{|(^\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\s+))</string>
4696+
<key>patterns</key>
4697+
<array>
4698+
<dict>
4699+
<key>include</key>
4700+
<string>#arrow-return-type-body</string>
4701+
</dict>
4702+
</array>
4703+
</dict>
4704+
<key>possibly-arrow-return-type</key>
4705+
<dict>
4706+
<key>begin</key>
4707+
<string>(?&lt;=\))\s*(:)(?=\s*([^&lt;&gt;\(\)]|\&lt;[^&lt;&gt;]+\&gt;|\([^\(\)]+\))+\s*=&gt;)</string>
4708+
<key>beginCaptures</key>
4709+
<dict>
4710+
<key>1</key>
4711+
<dict>
4712+
<key>name</key>
4713+
<string>meta.arrow.ts meta.return.type.arrow.ts keyword.operator.type.annotation.ts</string>
4714+
</dict>
4715+
</dict>
4716+
<key>end</key>
4717+
<string>(?==&gt;|\{|(^\s*(export|function|class|interface|let|var|const|import|enum|namespace|module|type|abstract|declare)\s+))</string>
4718+
<key>contentName</key>
4719+
<string>meta.arrow.ts meta.return.type.arrow.ts</string>
4720+
<key>patterns</key>
4721+
<array>
4722+
<dict>
4723+
<key>include</key>
4724+
<string>#arrow-return-type-body</string>
4725+
</dict>
4726+
</array>
4727+
</dict>
4728+
<key>arrow-return-type-body</key>
4729+
<dict>
46304730
<key>patterns</key>
46314731
<array>
46324732
<dict>

0 commit comments

Comments
 (0)