diff --git a/grammars/csharp.tmLanguage b/grammars/csharp.tmLanguage
index 6b6a385..633efa1 100644
--- a/grammars/csharp.tmLanguage
+++ b/grammars/csharp.tmLanguage
@@ -660,7 +660,7 @@
attribute-section
begin
- (\[)(assembly|module|field|event|method|param|property|return|type)?(\:)?
+ (\[)(assembly|module|event|field|method|param|property|return|type|typevar)?(\:)?
beginCaptures
1
@@ -2725,12 +2725,38 @@
include
#ref-modifier
+
+ include
+ #lambda-expression
+
include
#expression
+ lambda-expression
+
+ begin
+ (?=(?:\[.*\].*)?\(.*\).*=>)
+ end
+ (?=;)
+ patterns
+
+
+ include
+ #attribute-section
+
+
+ include
+ #parenthesized-parameter-list
+
+
+ include
+ #expression-body
+
+
+
expression-body
begin
@@ -7270,6 +7296,10 @@
include
#parameter
+
+ include
+ #parameter-identifier
+
include
#punctuation-comma
@@ -7333,6 +7363,13 @@
+ parameter-identifier
+
+ name
+ entity.name.variable.parameter.cs
+ match
+ (?<!\.)@?\b[_[:alpha:]][_[:alnum:]]*\b(?!\.)
+
argument-list
begin
diff --git a/grammars/csharp.tmLanguage.cson b/grammars/csharp.tmLanguage.cson
index 3f09e3e..c3252c7 100644
--- a/grammars/csharp.tmLanguage.cson
+++ b/grammars/csharp.tmLanguage.cson
@@ -441,7 +441,7 @@ repository:
}
]
"attribute-section":
- begin: "(\\[)(assembly|module|field|event|method|param|property|return|type)?(\\:)?"
+ begin: "(\\[)(assembly|module|event|field|method|param|property|return|type|typevar)?(\\:)?"
beginCaptures:
"1":
name: "punctuation.squarebracket.open.cs"
@@ -1738,10 +1738,27 @@ repository:
{
include: "#ref-modifier"
}
+ {
+ include: "#lambda-expression"
+ }
{
include: "#expression"
}
]
+ "lambda-expression":
+ begin: "(?=(?:\\[.*\\].*)?\\(.*\\).*=>)"
+ end: "(?=;)"
+ patterns: [
+ {
+ include: "#attribute-section"
+ }
+ {
+ include: "#parenthesized-parameter-list"
+ }
+ {
+ include: "#expression-body"
+ }
+ ]
"expression-body":
begin: "=>"
beginCaptures:
@@ -4383,6 +4400,9 @@ repository:
{
include: "#parameter"
}
+ {
+ include: "#parameter-identifier"
+ }
{
include: "#punctuation-comma"
}
@@ -4430,6 +4450,9 @@ repository:
]
"7":
name: "entity.name.variable.parameter.cs"
+ "parameter-identifier":
+ name: "entity.name.variable.parameter.cs"
+ match: "(?)
+ end: (?=;)
+ patterns:
+ - include: '#attribute-section'
+ - include: '#parenthesized-parameter-list'
+ - include: '#expression-body'
+
expression-body:
begin: =>
beginCaptures:
@@ -2823,6 +2832,7 @@ repository:
- include: '#comment'
- include: '#attribute-section'
- include: '#parameter'
+ - include: '#lambda-parameter'
- include: '#punctuation-comma'
- include: '#variable-initializer'
@@ -2865,6 +2875,10 @@ repository:
# '6': ? is a sub-expression. It's final value is not considered.
7: { name: entity.name.variable.parameter.cs }
+ lambda-parameter:
+ name: entity.name.variable.parameter.cs
+ match: '(? {
+ const input = Input.InMethod(`
+var concat = ([DisallowNull] string a, [DisallowNull] string b) => a + b;
+var inc = [return: NotNullIfNotNull(nameof(s))] (int? s) => s.HasValue ? s++ : null;
+Func parse = [ProvidesNullCheck] (s) => (s is not null) ? int.Parse(s) : null;
+`);
+ const tokens = await tokenize(input);
+
+ tokens.should.deep.equal([
+ Token.Keyword.Definition.Var,
+ Token.Identifier.LocalName("concat"),
+ Token.Operator.Assignment,
+ Token.Punctuation.OpenParen,
+ Token.Punctuation.OpenBracket,
+ Token.Type("DisallowNull"),
+ Token.Punctuation.CloseBracket,
+ Token.PrimitiveType.String,
+ Token.Identifier.ParameterName("a"),
+ Token.Punctuation.Comma,
+ Token.Punctuation.OpenBracket,
+ Token.Type("DisallowNull"),
+ Token.Punctuation.CloseBracket,
+ Token.PrimitiveType.String,
+ Token.Identifier.ParameterName("b"),
+ Token.Punctuation.CloseParen,
+ Token.Operator.Arrow,
+ Token.Variable.ReadWrite("a"),
+ Token.Operator.Arithmetic.Addition,
+ Token.Variable.ReadWrite("b"),
+ Token.Punctuation.Semicolon,
+
+ Token.Keyword.Definition.Var,
+ Token.Identifier.LocalName("inc"),
+ Token.Operator.Assignment,
+ Token.Punctuation.OpenBracket,
+ Token.Keyword.AttributeSpecifier("return"),
+ Token.Punctuation.Colon,
+ Token.Type("NotNullIfNotNull"),
+ Token.Punctuation.OpenParen,
+ Token.Operator.Expression.NameOf,
+ Token.Punctuation.OpenParen,
+ Token.Variable.ReadWrite("s"),
+ Token.Punctuation.CloseParen,
+ Token.Punctuation.CloseParen,
+ Token.Punctuation.CloseBracket,
+ Token.Punctuation.OpenParen,
+ Token.PrimitiveType.Int,
+ Token.Punctuation.QuestionMark,
+ Token.Identifier.ParameterName("s"),
+ Token.Punctuation.CloseParen,
+ Token.Operator.Arrow,
+ Token.Variable.Object("s"),
+ Token.Punctuation.Accessor,
+ Token.Variable.Property("HasValue"),
+ Token.Operator.Conditional.QuestionMark,
+ Token.Variable.ReadWrite("s"),
+ Token.Operator.Increment,
+ Token.Operator.Conditional.Colon,
+ Token.Literal.Null,
+ Token.Punctuation.Semicolon,
+
+ Token.Type("Func"),
+ Token.Punctuation.TypeParameter.Begin,
+ Token.PrimitiveType.String,
+ Token.Punctuation.QuestionMark,
+ Token.Punctuation.Comma,
+ Token.PrimitiveType.Int,
+ Token.Punctuation.QuestionMark,
+ Token.Punctuation.TypeParameter.End,
+ Token.Identifier.LocalName("parse"),
+ Token.Operator.Assignment,
+ Token.Punctuation.OpenBracket,
+ Token.Type("ProvidesNullCheck"),
+ Token.Punctuation.CloseBracket,
+ Token.Punctuation.OpenParen,
+ Token.Identifier.ParameterName("s"),
+ Token.Punctuation.CloseParen,
+ Token.Operator.Arrow,
+ Token.Punctuation.OpenParen,
+ Token.Variable.ReadWrite("s"),
+ Token.Operator.Pattern.Is,
+ Token.Operator.Pattern.Not,
+ Token.Literal.Null,
+ Token.Punctuation.CloseParen,
+ Token.Operator.Conditional.QuestionMark,
+ Token.PrimitiveType.Int,
+ Token.Punctuation.Accessor,
+ Token.Identifier.MethodName("Parse"),
+ Token.Punctuation.OpenParen,
+ Token.Variable.ReadWrite("s"),
+ Token.Punctuation.CloseParen,
+ Token.Operator.Conditional.Colon,
+ Token.Literal.Null,
+ Token.Punctuation.Semicolon
+ ]);
+ });
+
it("async lambda assigned to dotted name (issue #142)", async () => {
const input = Input.InMethod(
`Something.listener = async args => { return true; };`