Skip to content

Commit 5ca75df

Browse files
committed
Field syntax highlighting improvements and tests.
1 parent 32d3ef4 commit 5ca75df

File tree

4 files changed

+188
-19
lines changed

4 files changed

+188
-19
lines changed

syntaxes/csharp.json

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,43 @@
7171
}
7272
]
7373
},
74+
"field-declaration": {
75+
"patterns": [
76+
{
77+
"begin": "(?=(?:(?:(?:private|public|volatile|internal|protected|static|readonly|const)\\s*)*)(?:[\\w\\s,<>\\[\\]]+?)(?:[\\w]+)\\s*(?:;|=|=>))",
78+
"end": "(?=;)",
79+
"patterns": [
80+
{
81+
"match": "^\\s*((?:(?:private|public|volatile|internal|protected|static|readonly|const)\\s*)*)\\s*([\\w\\s,<>\\[\\]]+?)\\s*([\\w]+)\\s*(?=;|=)",
82+
"captures": {
83+
"1" : {
84+
"patterns": [
85+
{
86+
"include": "#storage-modifiers"
87+
}
88+
]
89+
},
90+
"2" : {
91+
"name": "storage.type.cs"
92+
},
93+
"3": {
94+
"name": "entity.name.variable.cs"
95+
}
96+
}
97+
},
98+
{
99+
"begin": "(?==>?)",
100+
"end": "(?=;)",
101+
"patterns": [
102+
{
103+
"include": "#code"
104+
}
105+
]
106+
}
107+
]
108+
}
109+
]
110+
},
74111
"variable": {
75112
"patterns": [
76113
{
@@ -123,8 +160,8 @@
123160
}
124161
]
125162
},
126-
"genericConstraints": {
127-
"begin": "(where)\\s*(\\w+)\\s*:",
163+
"generic-constraints": {
164+
"begin": "(where)\\s+(\\w+)\\s*:",
128165
"end": "(?={)",
129166
"beginCaptures": {
130167
"1": {
@@ -148,15 +185,15 @@
148185
}
149186
},
150187
{
151-
"match": "([\\w<>]+)\\s*(?=,|where|{)",
188+
"match": "([\\w<>,\\[\\]]+)\\s*(?=,|where|{)",
152189
"captures": {
153190
"1": {
154191
"name": "storage.type.cs"
155192
}
156193
}
157194
},
158195
{
159-
"include": "#genericConstraints"
196+
"include": "#generic-constraints"
160197
}
161198
]
162199
},
@@ -203,7 +240,7 @@
203240
]
204241
},
205242
{
206-
"include": "#genericConstraints"
243+
"include": "#generic-constraints"
207244
},
208245
{
209246
"begin": "{",
@@ -216,15 +253,25 @@
216253
"name": "meta.class.body.cs",
217254
"patterns": [
218255
{
219-
"include": "#method"
220-
},
221-
{
222-
"include": "#code"
256+
"include": "#type-body"
223257
}
224258
]
225259
}
226260
]
227261
},
262+
"type-body": {
263+
"patterns": [
264+
{
265+
"include": "#field-declaration"
266+
},
267+
{
268+
"include": "#method"
269+
},
270+
{
271+
"include": "#code"
272+
}
273+
]
274+
},
228275
"code": {
229276
"patterns": [
230277
{

test/syntaxes/class.tests.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ const input = `
100100
namespace TestNamespace
101101
{
102102
class PublicClass<T> where T : ISomething { }
103-
class PublicClass<T, X> : List<T>, ISomething where T : ICar, new() where X : struct { }
103+
class PublicClass<T, X> : Dictionary<T, List<string>[]>, ISomething where T : ICar, new() where X : struct { }
104104
}`;
105105
let tokens: Token[] = TokenizerUtil.tokenize(input);
106106

@@ -112,15 +112,15 @@ namespace TestNamespace
112112

113113
tokens.should.contain(Tokens.ClassKeyword("class", 5, 5));
114114
tokens.should.contain(Tokens.ClassIdentifier("PublicClass", 5, 11));
115-
tokens.should.contain(Tokens.Type("List<T>", 5, 31));
116-
tokens.should.contain(Tokens.Type("ISomething", 5, 40));
117-
tokens.should.contain(Tokens.Keyword("where", 5, 51));
118-
tokens.should.contain(Tokens.Type("T", 5, 57));
119-
tokens.should.contain(Tokens.Type("ICar", 5, 61));
120-
tokens.should.contain(Tokens.Keyword("new", 5, 67));
115+
tokens.should.contain(Tokens.Type("Dictionary<T, List<string>[]>", 5, 31));
116+
tokens.should.contain(Tokens.Type("ISomething", 5, 62));
121117
tokens.should.contain(Tokens.Keyword("where", 5, 73));
122-
tokens.should.contain(Tokens.Type("X", 5, 79));
123-
tokens.should.contain(Tokens.Keyword("struct", 5, 83));
118+
tokens.should.contain(Tokens.Type("T", 5, 79));
119+
tokens.should.contain(Tokens.Type("ICar", 5, 83));
120+
tokens.should.contain(Tokens.Keyword("new", 5, 89));
121+
tokens.should.contain(Tokens.Keyword("where", 5, 95));
122+
tokens.should.contain(Tokens.Type("X", 5, 101));
123+
tokens.should.contain(Tokens.Keyword("struct", 5, 105));
124124

125125
});
126126

test/syntaxes/field.tests.ts

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import { should } from 'chai';
2+
import { Tokens, Token } from './utils/tokenizer';
3+
import { TokenizerUtil } from'./utils/tokenizerUtil';
4+
5+
describe("Grammar", function() {
6+
before(function() {
7+
should();
8+
});
9+
10+
describe("Field", function() {
11+
it("declaration", function() {
12+
13+
const input = `
14+
public class Tester
15+
{
16+
private List _field;
17+
private List field;
18+
private List field123;
19+
}`;
20+
21+
let tokens: Token[] = TokenizerUtil.tokenize(input);
22+
23+
tokens.should.contain(Tokens.StorageModifierKeyword("private", 4, 5));
24+
tokens.should.contain(Tokens.Type("List", 4, 13));
25+
tokens.should.contain(Tokens.FieldIdentifier("_field", 4, 18));
26+
27+
tokens.should.contain(Tokens.FieldIdentifier("field", 5, 18));
28+
tokens.should.contain(Tokens.FieldIdentifier("field123", 6, 18));
29+
});
30+
31+
32+
it("modifiers", function() {
33+
34+
const input = `
35+
public class Tester
36+
{
37+
private static readonly List _field;
38+
readonly string _field;
39+
}`;
40+
41+
let tokens: Token[] = TokenizerUtil.tokenize(input);
42+
43+
tokens.should.contain(Tokens.StorageModifierKeyword("private", 4, 5));
44+
tokens.should.contain(Tokens.StorageModifierKeyword("static", 4, 13));
45+
tokens.should.contain(Tokens.StorageModifierKeyword("readonly", 4, 20));
46+
tokens.should.contain(Tokens.Type("List", 4, 29));
47+
tokens.should.contain(Tokens.FieldIdentifier("_field", 4, 34));
48+
});
49+
50+
it("types", function() {
51+
52+
const input = `
53+
public class Tester
54+
{
55+
string field123;
56+
string[] field123;
57+
}`;
58+
59+
let tokens: Token[] = TokenizerUtil.tokenize(input);
60+
61+
tokens.should.contain(Tokens.Type("string", 4, 5));
62+
tokens.should.contain(Tokens.FieldIdentifier("field123", 4, 12));
63+
64+
tokens.should.contain(Tokens.Type("string[]", 5, 5));
65+
tokens.should.contain(Tokens.FieldIdentifier("field123", 5, 14));
66+
});
67+
68+
it("assignment", function() {
69+
70+
const input = `
71+
public class Tester
72+
{
73+
private string field = "hello";
74+
const bool field = true;
75+
}`;
76+
77+
let tokens: Token[] = TokenizerUtil.tokenize(input);
78+
79+
tokens.should.contain(Tokens.StorageModifierKeyword("private", 4, 5));
80+
tokens.should.contain(Tokens.Type("string", 4, 13));
81+
tokens.should.contain(Tokens.FieldIdentifier("field", 4, 20));
82+
tokens.should.contain(Tokens.StringQuoted("hello", 4, 29));
83+
84+
tokens.should.contain(Tokens.StorageModifierKeyword("const", 5, 5));
85+
tokens.should.contain(Tokens.Type("bool", 5, 13));
86+
tokens.should.contain(Tokens.FieldIdentifier("field", 5, 20));
87+
tokens.should.contain(Tokens.LanguageConstant("true", 5, 28));
88+
});
89+
90+
it("expression body", function() {
91+
92+
const input = `
93+
public class Tester
94+
{
95+
private string field => "hello";
96+
const bool field => true;
97+
}`;
98+
99+
let tokens: Token[] = TokenizerUtil.tokenize(input);
100+
101+
tokens.should.contain(Tokens.StorageModifierKeyword("private", 4, 5));
102+
tokens.should.contain(Tokens.Type("string", 4, 13));
103+
tokens.should.contain(Tokens.FieldIdentifier("field", 4, 20));
104+
tokens.should.contain(Tokens.StringQuoted("hello", 4, 30));
105+
106+
tokens.should.contain(Tokens.StorageModifierKeyword("const", 5, 5));
107+
tokens.should.contain(Tokens.Type("bool", 5, 13));
108+
tokens.should.contain(Tokens.FieldIdentifier("field", 5, 20));
109+
tokens.should.contain(Tokens.LanguageConstant("true", 5, 29));
110+
});
111+
});
112+
});
113+
114+

test/syntaxes/utils/tokenizer.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,13 @@ export namespace Tokens {
7878

7979
export const Keyword = (text: string, line?: number, column?: number) =>
8080
createToken(text, "keyword.other.cs", line, column);
81-
}
8281

82+
export const FieldIdentifier = (text: string, line?: number, column?: number) =>
83+
createToken(text, "entity.name.variable.cs", line, column);
84+
85+
export const StringQuoted = (text: string, line?: number, column?: number) =>
86+
createToken(text, "string.quoted.double.cs", line, column);
87+
88+
export const LanguageConstant = (text: string, line?: number, column?: number) =>
89+
createToken(text, "constant.language.cs", line, column);
90+
}

0 commit comments

Comments
 (0)