Skip to content

Commit 5ccdfb8

Browse files
Merge pull request dotnet#57 from kiootic/out-var
Add support for out variable declaration
2 parents 4d0e50c + 7d55167 commit 5ccdfb8

File tree

4 files changed

+172
-9
lines changed

4 files changed

+172
-9
lines changed

grammars/csharp.tmLanguage

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3549,7 +3549,7 @@
35493549
</dict>
35503550
<dict>
35513551
<key>include</key>
3552-
<string>#declaration-expression</string>
3552+
<string>#declaration-expression-tuple</string>
35533553
</dict>
35543554
<dict>
35553555
<key>include</key>
@@ -3605,7 +3605,7 @@
36053605
</dict>
36063606
<dict>
36073607
<key>include</key>
3608-
<string>#declaration-expression</string>
3608+
<string>#declaration-expression-tuple</string>
36093609
</dict>
36103610
<dict>
36113611
<key>include</key>
@@ -3627,7 +3627,54 @@
36273627
</dict>
36283628
</array>
36293629
</dict>
3630-
<key>declaration-expression</key>
3630+
<key>declaration-expression-local</key>
3631+
<dict>
3632+
<key>match</key>
3633+
<string>(?x) # e.g. int x OR var x
3634+
(?:
3635+
\b(var)\b|
3636+
(?&lt;type-name&gt;
3637+
(?:
3638+
(?:(?&lt;identifier&gt;[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification
3639+
(?&lt;name-and-type-args&gt; # identifier + type arguments (if any)
3640+
\g&lt;identifier&gt;\s*
3641+
(?&lt;type-args&gt;\s*&lt;(?:[^&lt;&gt;]|\g&lt;type-args&gt;)+&gt;\s*)?
3642+
)
3643+
(?:\s*\.\s*\g&lt;name-and-type-args&gt;)* # Are there any more names being dotted into?
3644+
(?:\s*\*\s*)* # pointer suffix?
3645+
(?:\s*\?\s*)? # nullable suffix?
3646+
(?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix?
3647+
)|
3648+
(?&lt;tuple&gt;\s*\((?:[^\(\)]|\g&lt;tuple&gt;)+\))
3649+
)
3650+
)\s+
3651+
\b(\g&lt;identifier&gt;)\b\s*
3652+
(?=[,)\]])</string>
3653+
<key>captures</key>
3654+
<dict>
3655+
<key>1</key>
3656+
<dict>
3657+
<key>name</key>
3658+
<string>keyword.other.var.cs</string>
3659+
</dict>
3660+
<key>2</key>
3661+
<dict>
3662+
<key>patterns</key>
3663+
<array>
3664+
<dict>
3665+
<key>include</key>
3666+
<string>#type</string>
3667+
</dict>
3668+
</array>
3669+
</dict>
3670+
<key>7</key>
3671+
<dict>
3672+
<key>name</key>
3673+
<string>entity.name.variable.local.cs</string>
3674+
</dict>
3675+
</dict>
3676+
</dict>
3677+
<key>declaration-expression-tuple</key>
36313678
<dict>
36323679
<key>match</key>
36333680
<string>(?x) # e.g. int x OR var x
@@ -5108,6 +5155,10 @@
51085155
<key>match</key>
51095156
<string>\b(ref|out)\b</string>
51105157
</dict>
5158+
<dict>
5159+
<key>include</key>
5160+
<string>#declaration-expression-local</string>
5161+
</dict>
51115162
<dict>
51125163
<key>include</key>
51135164
<string>#expression</string>

grammars/csharp.tmLanguage.cson

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2156,7 +2156,7 @@ repository:
21562156
include: "#tuple-declaration-deconstruction-element-list"
21572157
}
21582158
{
2159-
include: "#declaration-expression"
2159+
include: "#declaration-expression-tuple"
21602160
}
21612161
{
21622162
include: "#punctuation-comma"
@@ -2189,7 +2189,7 @@ repository:
21892189
include: "#tuple-deconstruction-element-list"
21902190
}
21912191
{
2192-
include: "#declaration-expression"
2192+
include: "#declaration-expression-tuple"
21932193
}
21942194
{
21952195
include: "#punctuation-comma"
@@ -2205,7 +2205,41 @@ repository:
22052205
name: "variable.other.readwrite.cs"
22062206
}
22072207
]
2208-
"declaration-expression":
2208+
"declaration-expression-local":
2209+
match: '''
2210+
(?x) # e.g. int x OR var x
2211+
(?:
2212+
\\b(var)\\b|
2213+
(?<type-name>
2214+
(?:
2215+
(?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification
2216+
(?<name-and-type-args> # identifier + type arguments (if any)
2217+
\\g<identifier>\\s*
2218+
(?<type-args>\\s*<(?:[^<>]|\\g<type-args>)+>\\s*)?
2219+
)
2220+
(?:\\s*\\.\\s*\\g<name-and-type-args>)* # Are there any more names being dotted into?
2221+
(?:\\s*\\*\\s*)* # pointer suffix?
2222+
(?:\\s*\\?\\s*)? # nullable suffix?
2223+
(?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?
2224+
)|
2225+
(?<tuple>\\s*\\((?:[^\\(\\)]|\\g<tuple>)+\\))
2226+
)
2227+
)\\s+
2228+
\\b(\\g<identifier>)\\b\\s*
2229+
(?=[,)\\]])
2230+
'''
2231+
captures:
2232+
"1":
2233+
name: "keyword.other.var.cs"
2234+
"2":
2235+
patterns: [
2236+
{
2237+
include: "#type"
2238+
}
2239+
]
2240+
"7":
2241+
name: "entity.name.variable.local.cs"
2242+
"declaration-expression-tuple":
22092243
match: '''
22102244
(?x) # e.g. int x OR var x
22112245
(?:
@@ -3062,6 +3096,9 @@ repository:
30623096
name: "storage.modifier.cs"
30633097
match: "\\b(ref|out)\\b"
30643098
}
3099+
{
3100+
include: "#declaration-expression-local"
3101+
}
30653102
{
30663103
include: "#expression"
30673104
}

src/csharp.tmLanguage.yml

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,7 @@ repository:
13161316
patterns:
13171317
- include: '#comment'
13181318
- include: '#tuple-declaration-deconstruction-element-list'
1319-
- include: '#declaration-expression'
1319+
- include: '#declaration-expression-tuple'
13201320
- include: '#punctuation-comma'
13211321
- match: |-
13221322
(?x) # e.g. x
@@ -1335,7 +1335,7 @@ repository:
13351335
patterns:
13361336
- include: '#comment'
13371337
- include: '#tuple-deconstruction-element-list'
1338-
- include: '#declaration-expression'
1338+
- include: '#declaration-expression-tuple'
13391339
- include: '#punctuation-comma'
13401340
- match: |-
13411341
(?x) # e.g. x
@@ -1344,7 +1344,40 @@ repository:
13441344
captures:
13451345
'1': { name: variable.other.readwrite.cs }
13461346
1347-
declaration-expression:
1347+
declaration-expression-local:
1348+
match: |-
1349+
(?x) # e.g. int x OR var x
1350+
(?:
1351+
\b(var)\b|
1352+
(?<type-name>
1353+
(?:
1354+
(?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification
1355+
(?<name-and-type-args> # identifier + type arguments (if any)
1356+
\g<identifier>\s*
1357+
(?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)?
1358+
)
1359+
(?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into?
1360+
(?:\s*\*\s*)* # pointer suffix?
1361+
(?:\s*\?\s*)? # nullable suffix?
1362+
(?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix?
1363+
)|
1364+
(?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\))
1365+
)
1366+
)\s+
1367+
\b(\g<identifier>)\b\s*
1368+
(?=[,)\]])
1369+
captures:
1370+
'1': { name: keyword.other.var.cs }
1371+
'2':
1372+
patterns:
1373+
- include: '#type'
1374+
# '3': ?<identifier> is a sub-expression. It's final value is not considered.
1375+
# '4': ?<name-and-type-args> is a sub-expression. It's final value is not considered.
1376+
# '5': ?<type-args> is a sub-expression. It's final value is not considered.
1377+
# '6': ?<tuple> is a sub-expression. It's final value is not considered.
1378+
'7': { name: entity.name.variable.local.cs }
1379+
1380+
declaration-expression-tuple:
13481381
match: |-
13491382
(?x) # e.g. int x OR var x
13501383
(?:
@@ -1964,6 +1997,7 @@ repository:
19641997
patterns:
19651998
- name: storage.modifier.cs
19661999
match: \b(ref|out)\b
2000+
- include: '#declaration-expression-local'
19672001
- include: '#expression'
19682002

19692003
query-expression:

test/expressions.tests.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,6 +1392,28 @@ class C
13921392
]);
13931393
});
13941394

1395+
it("out argument declaration", () => {
1396+
const input = Input.InMethod(`var o = P[out int x, out var y];`);
1397+
const tokens = tokenize(input);
1398+
1399+
tokens.should.deep.equal([
1400+
Token.Keywords.Var,
1401+
Token.Identifiers.LocalName("o"),
1402+
Token.Operators.Assignment,
1403+
Token.Variables.Property("P"),
1404+
Token.Punctuation.OpenBracket,
1405+
Token.Keywords.Modifiers.Out,
1406+
Token.PrimitiveType.Int,
1407+
Token.Identifiers.LocalName("x"),
1408+
Token.Punctuation.Comma,
1409+
Token.Keywords.Modifiers.Out,
1410+
Token.Keywords.Var,
1411+
Token.Identifiers.LocalName("y"),
1412+
Token.Punctuation.CloseBracket,
1413+
Token.Punctuation.Semicolon
1414+
]);
1415+
});
1416+
13951417
it("member of generic with no arguments", () => {
13961418
const input = Input.InMethod(`var o = C<int>.P[];`);
13971419
const tokens = tokenize(input);
@@ -1828,6 +1850,25 @@ long total = (data["bonusGame"]["win"].AsLong) * data["bonusGame"]["betMult"].As
18281850
]);
18291851
});
18301852

1853+
it("out argument declaration", () => {
1854+
const input = Input.InMethod(`M(out int x, out var y);`);
1855+
const tokens = tokenize(input);
1856+
1857+
tokens.should.deep.equal([
1858+
Token.Identifiers.MethodName("M"),
1859+
Token.Punctuation.OpenParen,
1860+
Token.Keywords.Modifiers.Out,
1861+
Token.PrimitiveType.Int,
1862+
Token.Identifiers.LocalName("x"),
1863+
Token.Punctuation.Comma,
1864+
Token.Keywords.Modifiers.Out,
1865+
Token.Keywords.Var,
1866+
Token.Identifiers.LocalName("y"),
1867+
Token.Punctuation.CloseParen,
1868+
Token.Punctuation.Semicolon
1869+
]);
1870+
});
1871+
18311872
it("generic with no arguments", () => {
18321873
const input = Input.InMethod(`M<int>();`);
18331874
const tokens = tokenize(input);

0 commit comments

Comments
 (0)