From 9aba762e16cb7e3e179aa2d11de1b9182a77ca6c Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 19 Dec 2025 23:53:49 +0000
Subject: [PATCH 1/2] Initial plan
From 3fdf1ef1f3fc3000b214854f94e5bd1f25fc92f6 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 20 Dec 2025 00:11:57 +0000
Subject: [PATCH 2/2] Add support for typevar attribute target specifier
- Added typevar to attribute-section pattern (placed before type to ensure proper matching)
- Added test cases for typevar attribute specifier
- All tests passing (895 tests)
Co-authored-by: JoeRobich <611219+JoeRobich@users.noreply.github.com>
---
grammars/csharp.tmLanguage | 2 +-
grammars/csharp.tmLanguage.cson | 2 +-
src/csharp.tmLanguage.yml | 2 +-
test/attribute.tests.ts | 31 +++++++++++++++++++++++++++++++
4 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/grammars/csharp.tmLanguage b/grammars/csharp.tmLanguage
index 3906d58..aeaeb81 100644
--- a/grammars/csharp.tmLanguage
+++ b/grammars/csharp.tmLanguage
@@ -668,7 +668,7 @@
attribute-section
begin
- (\[)(assembly|module|field|event|method|param|property|return|type)?(\:)?
+ (\[)(assembly|module|field|event|method|param|property|return|typevar|type)?(\:)?
beginCaptures
1
diff --git a/grammars/csharp.tmLanguage.cson b/grammars/csharp.tmLanguage.cson
index 0fb74a7..7fed1a0 100644
--- a/grammars/csharp.tmLanguage.cson
+++ b/grammars/csharp.tmLanguage.cson
@@ -447,7 +447,7 @@ repository:
}
]
"attribute-section":
- begin: "(\\[)(assembly|module|field|event|method|param|property|return|type)?(\\:)?"
+ begin: "(\\[)(assembly|module|field|event|method|param|property|return|typevar|type)?(\\:)?"
beginCaptures:
"1":
name: "punctuation.squarebracket.open.cs"
diff --git a/src/csharp.tmLanguage.yml b/src/csharp.tmLanguage.yml
index 4576f37..a012a52 100644
--- a/src/csharp.tmLanguage.yml
+++ b/src/csharp.tmLanguage.yml
@@ -189,7 +189,7 @@ repository:
- include: '#operator-assignment'
attribute-section:
- begin: (\[)(assembly|module|field|event|method|param|property|return|type)?(\:)?
+ begin: (\[)(assembly|module|field|event|method|param|property|return|typevar|type)?(\:)?
beginCaptures:
'1': { name: punctuation.squarebracket.open.cs }
'2': { name: keyword.other.attribute-specifier.cs }
diff --git a/test/attribute.tests.ts b/test/attribute.tests.ts
index e1f9def..cc367fb 100644
--- a/test/attribute.tests.ts
+++ b/test/attribute.tests.ts
@@ -253,5 +253,36 @@ describe("Attributes", () => {
Token.Punctuation.TypeParameter.End,
Token.Punctuation.CloseBracket]);
});
+
+ it("typevar attribute specifier", async () => {
+
+ const input = `[typevar: MyAttribute]`;
+ const tokens = await tokenize(input);
+
+ tokens.should.deep.equal([
+ Token.Punctuation.OpenBracket,
+ Token.Keyword.AttributeSpecifier("typevar"),
+ Token.Punctuation.Colon,
+ Token.Type("MyAttribute"),
+ Token.Punctuation.CloseBracket]);
+ });
+
+ it("typevar attribute specifier on generic type parameter", async () => {
+
+ const input = `class Foo<[typevar: MyAttribute] T>`;
+ const tokens = await tokenize(input);
+
+ tokens.should.deep.equal([
+ Token.Keyword.Definition.Class,
+ Token.Identifier.ClassName("Foo"),
+ Token.Punctuation.TypeParameter.Begin,
+ Token.Punctuation.OpenBracket,
+ Token.Keyword.AttributeSpecifier("typevar"),
+ Token.Punctuation.Colon,
+ Token.Type("MyAttribute"),
+ Token.Punctuation.CloseBracket,
+ Token.Identifier.TypeParameterName("T"),
+ Token.Punctuation.TypeParameter.End]);
+ });
});
});