@alloy-js/csharp 0.23.0-dev.7 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/dev/src/components/constructor/constructor.js +69 -9
- package/dist/dev/src/components/constructor/constructor.js.map +1 -1
- package/dist/dev/src/components/constructor/constructor.test.js +117 -0
- package/dist/dev/src/components/constructor/constructor.test.js.map +1 -1
- package/dist/dev/src/components/method/method.test.js +64 -0
- package/dist/dev/src/components/method/method.test.js.map +1 -1
- package/dist/dev/src/components/namespace/namespace.js +2 -1
- package/dist/dev/src/components/namespace/namespace.js.map +1 -1
- package/dist/dev/src/components/namespace/namespace.test.js +13 -10
- package/dist/dev/src/components/namespace/namespace.test.js.map +1 -1
- package/dist/dev/src/components/namespace.ref.test.js +54 -42
- package/dist/dev/src/components/namespace.ref.test.js.map +1 -1
- package/dist/dev/src/components/property/property.js +101 -24
- package/dist/dev/src/components/property/property.js.map +1 -1
- package/dist/dev/src/components/property/property.test.js +140 -0
- package/dist/dev/src/components/property/property.test.js.map +1 -1
- package/dist/dev/src/components/source-file/source-file.js +12 -11
- package/dist/dev/src/components/source-file/source-file.js.map +1 -1
- package/dist/dev/src/identifier-utils.js +45 -0
- package/dist/dev/src/identifier-utils.js.map +1 -0
- package/dist/dev/src/index.js +2 -0
- package/dist/dev/src/index.js.map +1 -1
- package/dist/dev/src/keywords.js +39 -0
- package/dist/dev/src/keywords.js.map +1 -0
- package/dist/dev/src/name-policy.js +29 -6
- package/dist/dev/src/name-policy.js.map +1 -1
- package/dist/dev/src/name-policy.test.js +167 -0
- package/dist/dev/src/name-policy.test.js.map +1 -0
- package/dist/src/components/constructor/constructor.d.ts +32 -0
- package/dist/src/components/constructor/constructor.d.ts.map +1 -1
- package/dist/src/components/constructor/constructor.js +35 -3
- package/dist/src/components/constructor/constructor.js.map +1 -1
- package/dist/src/components/constructor/constructor.test.js +81 -0
- package/dist/src/components/constructor/constructor.test.js.map +1 -1
- package/dist/src/components/method/method.test.js +48 -0
- package/dist/src/components/method/method.test.js.map +1 -1
- package/dist/src/components/namespace/namespace.js +2 -1
- package/dist/src/components/namespace/namespace.js.map +1 -1
- package/dist/src/components/namespace/namespace.test.js +6 -3
- package/dist/src/components/namespace/namespace.test.js.map +1 -1
- package/dist/src/components/namespace.ref.test.js +24 -12
- package/dist/src/components/namespace.ref.test.js.map +1 -1
- package/dist/src/components/property/property.d.ts +42 -4
- package/dist/src/components/property/property.d.ts.map +1 -1
- package/dist/src/components/property/property.js +64 -11
- package/dist/src/components/property/property.js.map +1 -1
- package/dist/src/components/property/property.test.js +104 -0
- package/dist/src/components/property/property.test.js.map +1 -1
- package/dist/src/components/source-file/source-file.d.ts.map +1 -1
- package/dist/src/components/source-file/source-file.js +3 -2
- package/dist/src/components/source-file/source-file.js.map +1 -1
- package/dist/src/identifier-utils.d.ts +22 -0
- package/dist/src/identifier-utils.d.ts.map +1 -0
- package/dist/src/identifier-utils.js +45 -0
- package/dist/src/identifier-utils.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/keywords.d.ts +32 -0
- package/dist/src/keywords.d.ts.map +1 -0
- package/dist/src/keywords.js +39 -0
- package/dist/src/keywords.js.map +1 -0
- package/dist/src/name-policy.d.ts +7 -0
- package/dist/src/name-policy.d.ts.map +1 -1
- package/dist/src/name-policy.js +29 -6
- package/dist/src/name-policy.js.map +1 -1
- package/dist/src/name-policy.test.d.ts +2 -0
- package/dist/src/name-policy.test.d.ts.map +1 -0
- package/dist/src/name-policy.test.js +167 -0
- package/dist/src/name-policy.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/api/components/Constructor.md +17 -11
- package/docs/api/components/Property.md +30 -30
- package/docs/api/contexts/csharp-context.md +21 -0
- package/docs/api/contexts/index.md +3 -0
- package/docs/api/functions/createCSharpNamePolicy.md +4 -0
- package/docs/api/functions/index.md +5 -1
- package/docs/api/functions/isCSharpContextualKeyword.md +20 -0
- package/docs/api/functions/isCSharpKeyword.md +22 -0
- package/docs/api/functions/isValidCSharpIdentifier.md +20 -0
- package/docs/api/functions/sanitizeCSharpIdentifier.md +24 -0
- package/docs/api/index.md +3 -2
- package/docs/api/variables/csharpKeywords.md +11 -0
- package/docs/api/variables/index.md +1 -0
- package/package.json +8 -8
- package/src/components/constructor/constructor.test.tsx +64 -0
- package/src/components/constructor/constructor.tsx +81 -1
- package/src/components/method/method.test.tsx +36 -0
- package/src/components/namespace/namespace.test.tsx +6 -3
- package/src/components/namespace/namespace.tsx +2 -2
- package/src/components/namespace.ref.test.tsx +24 -12
- package/src/components/property/property.test.tsx +89 -0
- package/src/components/property/property.tsx +111 -16
- package/src/components/source-file/source-file.tsx +1 -4
- package/src/identifier-utils.ts +45 -0
- package/src/index.ts +2 -0
- package/src/keywords.ts +162 -0
- package/src/name-policy.test.ts +210 -0
- package/src/name-policy.ts +30 -6
- package/temp/api.json +317 -7
|
@@ -43,9 +43,11 @@ it("references types in a parent namespace", () => {
|
|
|
43
43
|
);
|
|
44
44
|
|
|
45
45
|
expect(tree).toRenderTo(`
|
|
46
|
-
namespace Test
|
|
46
|
+
namespace Test
|
|
47
|
+
{
|
|
47
48
|
class TestClass;
|
|
48
|
-
namespace Nested
|
|
49
|
+
namespace Nested
|
|
50
|
+
{
|
|
49
51
|
TestClass;
|
|
50
52
|
}
|
|
51
53
|
}
|
|
@@ -69,9 +71,11 @@ it("references types in a child namespace", () => {
|
|
|
69
71
|
);
|
|
70
72
|
|
|
71
73
|
expect(tree).toRenderTo(`
|
|
72
|
-
namespace Test
|
|
74
|
+
namespace Test
|
|
75
|
+
{
|
|
73
76
|
Nested.TestClass;
|
|
74
|
-
namespace Nested
|
|
77
|
+
namespace Nested
|
|
78
|
+
{
|
|
75
79
|
class TestClass;
|
|
76
80
|
}
|
|
77
81
|
}
|
|
@@ -96,10 +100,12 @@ it("references types in a different top-level namespace declared in the same fil
|
|
|
96
100
|
expect(tree).toRenderTo(`
|
|
97
101
|
using TestCode2;
|
|
98
102
|
|
|
99
|
-
namespace TestCode1
|
|
103
|
+
namespace TestCode1
|
|
104
|
+
{
|
|
100
105
|
TestClass
|
|
101
106
|
}
|
|
102
|
-
namespace TestCode2
|
|
107
|
+
namespace TestCode2
|
|
108
|
+
{
|
|
103
109
|
class TestClass;
|
|
104
110
|
}
|
|
105
111
|
`);
|
|
@@ -125,12 +131,14 @@ it("references types in a different top-level namespace declared in a different
|
|
|
125
131
|
"test.cs": `
|
|
126
132
|
using TestCode2;
|
|
127
133
|
|
|
128
|
-
namespace TestCode1
|
|
134
|
+
namespace TestCode1
|
|
135
|
+
{
|
|
129
136
|
TestClass;
|
|
130
137
|
}
|
|
131
138
|
`,
|
|
132
139
|
"other.cs": `
|
|
133
|
-
namespace TestCode2
|
|
140
|
+
namespace TestCode2
|
|
141
|
+
{
|
|
134
142
|
class TestClass;
|
|
135
143
|
}
|
|
136
144
|
`,
|
|
@@ -156,7 +164,8 @@ it("can be referenced by refkey", () => {
|
|
|
156
164
|
expect(tree).toRenderTo(`
|
|
157
165
|
using TestCode2;
|
|
158
166
|
|
|
159
|
-
namespace TestCode2
|
|
167
|
+
namespace TestCode2
|
|
168
|
+
{
|
|
160
169
|
class TestClass;
|
|
161
170
|
}
|
|
162
171
|
TestClass;
|
|
@@ -181,11 +190,14 @@ it("references types across sibling namespaces under the same parent", () => {
|
|
|
181
190
|
);
|
|
182
191
|
|
|
183
192
|
expect(tree).toRenderTo(`
|
|
184
|
-
namespace Parent
|
|
185
|
-
|
|
193
|
+
namespace Parent
|
|
194
|
+
{
|
|
195
|
+
namespace Models
|
|
196
|
+
{
|
|
186
197
|
class User;
|
|
187
198
|
}
|
|
188
|
-
namespace Services
|
|
199
|
+
namespace Services
|
|
200
|
+
{
|
|
189
201
|
Models.User;
|
|
190
202
|
}
|
|
191
203
|
}
|
|
@@ -232,3 +232,92 @@ describe("format", () => {
|
|
|
232
232
|
`);
|
|
233
233
|
});
|
|
234
234
|
});
|
|
235
|
+
|
|
236
|
+
describe("accessor bodies", () => {
|
|
237
|
+
it("renders get with body", () => {
|
|
238
|
+
expect(
|
|
239
|
+
<Wrapper>
|
|
240
|
+
<Property public name="Name" type="string" get={<>return _name;</>} />
|
|
241
|
+
</Wrapper>,
|
|
242
|
+
).toRenderTo(`
|
|
243
|
+
public class TestClass
|
|
244
|
+
{
|
|
245
|
+
public string Name
|
|
246
|
+
{
|
|
247
|
+
get { return _name; }
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
`);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it("renders set with body", () => {
|
|
254
|
+
expect(
|
|
255
|
+
<Wrapper>
|
|
256
|
+
<Property
|
|
257
|
+
public
|
|
258
|
+
name="Value"
|
|
259
|
+
type="int"
|
|
260
|
+
get
|
|
261
|
+
set={<>_value = value;</>}
|
|
262
|
+
/>
|
|
263
|
+
</Wrapper>,
|
|
264
|
+
).toRenderTo(`
|
|
265
|
+
public class TestClass
|
|
266
|
+
{
|
|
267
|
+
public int Value
|
|
268
|
+
{
|
|
269
|
+
get;
|
|
270
|
+
set { _value = value; }
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
`);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it("renders both get and set with bodies", () => {
|
|
277
|
+
expect(
|
|
278
|
+
<Wrapper>
|
|
279
|
+
<Property
|
|
280
|
+
public
|
|
281
|
+
name="MinValue"
|
|
282
|
+
type="T"
|
|
283
|
+
get={<>return _minValue.HasValue ? _minValue.Value : default(T);</>}
|
|
284
|
+
set={<>_minValue = value;</>}
|
|
285
|
+
/>
|
|
286
|
+
</Wrapper>,
|
|
287
|
+
).toRenderTo(`
|
|
288
|
+
public class TestClass
|
|
289
|
+
{
|
|
290
|
+
public T MinValue
|
|
291
|
+
{
|
|
292
|
+
get { return _minValue.HasValue ? _minValue.Value : default(T); }
|
|
293
|
+
set { _minValue = value; }
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
`);
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
it("breaks long accessor body across lines", () => {
|
|
300
|
+
expect(
|
|
301
|
+
<TestNamespace printWidth={40}>
|
|
302
|
+
<ClassDeclaration name="Test">
|
|
303
|
+
<Property
|
|
304
|
+
public
|
|
305
|
+
name="Value"
|
|
306
|
+
type="int"
|
|
307
|
+
get={<>return _someVeryLongFieldName;</>}
|
|
308
|
+
/>
|
|
309
|
+
</ClassDeclaration>
|
|
310
|
+
</TestNamespace>,
|
|
311
|
+
).toRenderTo(`
|
|
312
|
+
class Test
|
|
313
|
+
{
|
|
314
|
+
public int Value
|
|
315
|
+
{
|
|
316
|
+
get {
|
|
317
|
+
return _someVeryLongFieldName;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
`);
|
|
322
|
+
});
|
|
323
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
Block,
|
|
2
3
|
Children,
|
|
3
4
|
createSymbolSlot,
|
|
4
5
|
List,
|
|
@@ -54,11 +55,49 @@ export interface PropertyProps extends AccessModifiers, PropertyModifiers {
|
|
|
54
55
|
/** Property type */
|
|
55
56
|
type: Children;
|
|
56
57
|
|
|
57
|
-
/**
|
|
58
|
-
|
|
58
|
+
/**
|
|
59
|
+
* If property should have a getter. Pass `true` for an auto-property getter (`get;`),
|
|
60
|
+
* or pass children for a getter with a body.
|
|
61
|
+
*
|
|
62
|
+
* @example auto-property
|
|
63
|
+
* ```tsx
|
|
64
|
+
* <Property name="Name" type="string" get set />
|
|
65
|
+
* ```
|
|
66
|
+
* Produces: `string Name { get; set; }`
|
|
67
|
+
*
|
|
68
|
+
* @example with body
|
|
69
|
+
* ```tsx
|
|
70
|
+
* <Property name="Name" type="string" get={<>return _name;</>} set />
|
|
71
|
+
* ```
|
|
72
|
+
* Produces:
|
|
73
|
+
* ```csharp
|
|
74
|
+
* string Name
|
|
75
|
+
* {
|
|
76
|
+
* get { return _name; }
|
|
77
|
+
* set;
|
|
78
|
+
* }
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
get?: boolean | Children;
|
|
59
82
|
|
|
60
|
-
/**
|
|
61
|
-
|
|
83
|
+
/**
|
|
84
|
+
* If property should have a setter. Pass `true` for an auto-property setter (`set;`),
|
|
85
|
+
* or pass children for a setter with a body.
|
|
86
|
+
*
|
|
87
|
+
* @example with body
|
|
88
|
+
* ```tsx
|
|
89
|
+
* <Property name="Value" type="int" get set={<>_value = value;</>} />
|
|
90
|
+
* ```
|
|
91
|
+
* Produces:
|
|
92
|
+
* ```csharp
|
|
93
|
+
* int Value
|
|
94
|
+
* {
|
|
95
|
+
* get;
|
|
96
|
+
* set { _value = value; }
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
set?: boolean | Children;
|
|
62
101
|
|
|
63
102
|
/** If property should only be set on the type creation */
|
|
64
103
|
init?: boolean;
|
|
@@ -133,14 +172,42 @@ export function Property(props: PropertyProps) {
|
|
|
133
172
|
`Cannot use 'init' and 'set' together on property '${name}'`,
|
|
134
173
|
);
|
|
135
174
|
}
|
|
136
|
-
|
|
175
|
+
|
|
176
|
+
const hasAccessorBody =
|
|
177
|
+
(props.get && props.get !== true) || (props.set && props.set !== true);
|
|
178
|
+
|
|
137
179
|
return (
|
|
138
180
|
<MemberDeclaration symbol={propertySymbol}>
|
|
139
181
|
<DocWhen doc={props.doc} />
|
|
140
182
|
<AttributeList attributes={props.attributes} endline />
|
|
141
183
|
{modifiers}
|
|
142
184
|
<TypeSlot>{props.type}</TypeSlot>
|
|
143
|
-
{props.nullable && "?"} <MemberName />
|
|
185
|
+
{props.nullable && "?"} <MemberName />
|
|
186
|
+
{hasAccessorBody ?
|
|
187
|
+
<AccessorBlock get={props.get} set={props.set} init={props.init} />
|
|
188
|
+
: <AutoAccessors
|
|
189
|
+
get={props.get}
|
|
190
|
+
set={props.set}
|
|
191
|
+
init={props.init}
|
|
192
|
+
initializer={props.initializer}
|
|
193
|
+
/>
|
|
194
|
+
}
|
|
195
|
+
</MemberDeclaration>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
interface AutoAccessorsProps {
|
|
200
|
+
get?: boolean | Children;
|
|
201
|
+
set?: boolean | Children;
|
|
202
|
+
init?: boolean;
|
|
203
|
+
initializer?: Children;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function AutoAccessors(props: AutoAccessorsProps) {
|
|
207
|
+
return (
|
|
208
|
+
<group>
|
|
209
|
+
{" "}
|
|
210
|
+
{"{ "}
|
|
144
211
|
<List joiner=" ">
|
|
145
212
|
{props.get && "get;"}
|
|
146
213
|
{props.set && "set;"}
|
|
@@ -148,20 +215,48 @@ export function Property(props: PropertyProps) {
|
|
|
148
215
|
</List>
|
|
149
216
|
{" }"}
|
|
150
217
|
{props.initializer && (
|
|
151
|
-
|
|
218
|
+
<>
|
|
219
|
+
{" ="}
|
|
220
|
+
<indent>
|
|
221
|
+
<line />
|
|
222
|
+
{props.initializer};
|
|
223
|
+
</indent>
|
|
224
|
+
</>
|
|
152
225
|
)}
|
|
153
|
-
</
|
|
226
|
+
</group>
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
interface AccessorBlockProps {
|
|
231
|
+
get?: boolean | Children;
|
|
232
|
+
set?: boolean | Children;
|
|
233
|
+
init?: boolean;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function AccessorBlock(props: AccessorBlockProps) {
|
|
237
|
+
return (
|
|
238
|
+
<Block newline>
|
|
239
|
+
<List hardline>
|
|
240
|
+
{props.get && <Accessor keyword="get" body={props.get} />}
|
|
241
|
+
{props.set && <Accessor keyword="set" body={props.set} />}
|
|
242
|
+
{props.init && "init;"}
|
|
243
|
+
</List>
|
|
244
|
+
</Block>
|
|
154
245
|
);
|
|
155
246
|
}
|
|
156
247
|
|
|
157
|
-
|
|
248
|
+
interface AccessorProps {
|
|
249
|
+
keyword: string;
|
|
250
|
+
body: boolean | Children;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function Accessor(props: AccessorProps) {
|
|
254
|
+
if (props.body === true) {
|
|
255
|
+
return <>{props.keyword};</>;
|
|
256
|
+
}
|
|
158
257
|
return (
|
|
159
|
-
|
|
160
|
-
{
|
|
161
|
-
|
|
162
|
-
<line />
|
|
163
|
-
{props.children};
|
|
164
|
-
</indent>
|
|
165
|
-
</group>
|
|
258
|
+
<>
|
|
259
|
+
{props.keyword} <Block inline>{props.body}</Block>
|
|
260
|
+
</>
|
|
166
261
|
);
|
|
167
262
|
}
|
|
@@ -105,10 +105,7 @@ export function SourceFile(props: SourceFileProps) {
|
|
|
105
105
|
: <>
|
|
106
106
|
namespace <NamespaceName symbol={nsSymbol} />
|
|
107
107
|
{sourceFileScope.hasBlockNamespace ?
|
|
108
|
-
|
|
109
|
-
{" "}
|
|
110
|
-
<Block>{content}</Block>
|
|
111
|
-
</>
|
|
108
|
+
<Block newline>{content}</Block>
|
|
112
109
|
: <>
|
|
113
110
|
;<hbr />
|
|
114
111
|
<hbr />
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks whether the provided name is a valid C# identifier (without `@` prefix).
|
|
3
|
+
* Does not account for keyword conflicts — use {@link isCSharpKeyword} for that.
|
|
4
|
+
*
|
|
5
|
+
* @param name - The name to validate.
|
|
6
|
+
* @returns true if the name matches C# identifier rules (letter or underscore start, word chars after).
|
|
7
|
+
*/
|
|
8
|
+
export function isValidCSharpIdentifier(name: string): boolean {
|
|
9
|
+
return /^[A-Za-z_]\w*$/.test(name);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Transforms an arbitrary string into a valid C# identifier by replacing
|
|
14
|
+
* invalid characters. The result may still be a C# keyword — callers
|
|
15
|
+
* should combine with keyword escaping if needed.
|
|
16
|
+
*
|
|
17
|
+
* - If the first character is not a letter or underscore, a `_` prefix is added.
|
|
18
|
+
* - Subsequent non-word characters are replaced with `_`.
|
|
19
|
+
* - Empty strings become `_`.
|
|
20
|
+
*
|
|
21
|
+
* @param name - The string to sanitize.
|
|
22
|
+
* @returns A string that satisfies C# identifier character rules.
|
|
23
|
+
*/
|
|
24
|
+
export function sanitizeCSharpIdentifier(name: string): string {
|
|
25
|
+
if (name.length === 0) return "_";
|
|
26
|
+
|
|
27
|
+
const chars: string[] = [];
|
|
28
|
+
for (let i = 0; i < name.length; i++) {
|
|
29
|
+
const ch = name[i];
|
|
30
|
+
if (i === 0) {
|
|
31
|
+
if (/[A-Za-z_]/.test(ch)) {
|
|
32
|
+
chars.push(ch);
|
|
33
|
+
} else {
|
|
34
|
+
chars.push("_");
|
|
35
|
+
// Keep the original char if it's a word char (e.g., digit)
|
|
36
|
+
if (/\w/.test(ch)) {
|
|
37
|
+
chars.push(ch);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
chars.push(/\w/.test(ch) ? ch : "_");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return chars.join("");
|
|
45
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,8 @@ export * from "./access.jsx";
|
|
|
2
2
|
export * from "./components/index.js";
|
|
3
3
|
export * from "./contexts/format-options.js";
|
|
4
4
|
export * from "./create-library.js";
|
|
5
|
+
export * from "./identifier-utils.js";
|
|
6
|
+
export * from "./keywords.js";
|
|
5
7
|
export * from "./modifiers.js";
|
|
6
8
|
export * from "./name-policy.js";
|
|
7
9
|
export * from "./scopes/index.js";
|
package/src/keywords.ts
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* C# reserved keywords that cannot be used as identifiers without `@` prefix.
|
|
3
|
+
* These are case-sensitive in C#.
|
|
4
|
+
*
|
|
5
|
+
* @see https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/
|
|
6
|
+
*/
|
|
7
|
+
export const csharpKeywords: ReadonlySet<string> = new Set([
|
|
8
|
+
"abstract",
|
|
9
|
+
"as",
|
|
10
|
+
"base",
|
|
11
|
+
"bool",
|
|
12
|
+
"break",
|
|
13
|
+
"byte",
|
|
14
|
+
"case",
|
|
15
|
+
"catch",
|
|
16
|
+
"char",
|
|
17
|
+
"checked",
|
|
18
|
+
"class",
|
|
19
|
+
"const",
|
|
20
|
+
"continue",
|
|
21
|
+
"decimal",
|
|
22
|
+
"default",
|
|
23
|
+
"delegate",
|
|
24
|
+
"do",
|
|
25
|
+
"double",
|
|
26
|
+
"else",
|
|
27
|
+
"enum",
|
|
28
|
+
"event",
|
|
29
|
+
"explicit",
|
|
30
|
+
"extern",
|
|
31
|
+
"false",
|
|
32
|
+
"finally",
|
|
33
|
+
"fixed",
|
|
34
|
+
"float",
|
|
35
|
+
"for",
|
|
36
|
+
"foreach",
|
|
37
|
+
"goto",
|
|
38
|
+
"if",
|
|
39
|
+
"implicit",
|
|
40
|
+
"in",
|
|
41
|
+
"int",
|
|
42
|
+
"interface",
|
|
43
|
+
"internal",
|
|
44
|
+
"is",
|
|
45
|
+
"lock",
|
|
46
|
+
"long",
|
|
47
|
+
"namespace",
|
|
48
|
+
"new",
|
|
49
|
+
"null",
|
|
50
|
+
"object",
|
|
51
|
+
"operator",
|
|
52
|
+
"out",
|
|
53
|
+
"override",
|
|
54
|
+
"params",
|
|
55
|
+
"private",
|
|
56
|
+
"protected",
|
|
57
|
+
"public",
|
|
58
|
+
"readonly",
|
|
59
|
+
"ref",
|
|
60
|
+
"return",
|
|
61
|
+
"sbyte",
|
|
62
|
+
"sealed",
|
|
63
|
+
"short",
|
|
64
|
+
"sizeof",
|
|
65
|
+
"stackalloc",
|
|
66
|
+
"static",
|
|
67
|
+
"string",
|
|
68
|
+
"struct",
|
|
69
|
+
"switch",
|
|
70
|
+
"this",
|
|
71
|
+
"throw",
|
|
72
|
+
"true",
|
|
73
|
+
"try",
|
|
74
|
+
"typeof",
|
|
75
|
+
"uint",
|
|
76
|
+
"ulong",
|
|
77
|
+
"unchecked",
|
|
78
|
+
"unsafe",
|
|
79
|
+
"ushort",
|
|
80
|
+
"using",
|
|
81
|
+
"virtual",
|
|
82
|
+
"void",
|
|
83
|
+
"volatile",
|
|
84
|
+
"while",
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* C# contextual keywords that are reserved in certain contexts.
|
|
89
|
+
* While not always reserved, treating them as keywords in generated code
|
|
90
|
+
* avoids subtle context-dependent issues.
|
|
91
|
+
*
|
|
92
|
+
* @see https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/#contextual-keywords
|
|
93
|
+
*/
|
|
94
|
+
export const csharpContextualKeywords: ReadonlySet<string> = new Set([
|
|
95
|
+
"add",
|
|
96
|
+
"allows",
|
|
97
|
+
"alias",
|
|
98
|
+
"and",
|
|
99
|
+
"ascending",
|
|
100
|
+
"args",
|
|
101
|
+
"async",
|
|
102
|
+
"await",
|
|
103
|
+
"by",
|
|
104
|
+
"descending",
|
|
105
|
+
"dynamic",
|
|
106
|
+
"equals",
|
|
107
|
+
"field",
|
|
108
|
+
"file",
|
|
109
|
+
"from",
|
|
110
|
+
"get",
|
|
111
|
+
"global",
|
|
112
|
+
"group",
|
|
113
|
+
"init",
|
|
114
|
+
"into",
|
|
115
|
+
"join",
|
|
116
|
+
"let",
|
|
117
|
+
"managed",
|
|
118
|
+
"nameof",
|
|
119
|
+
"nint",
|
|
120
|
+
"not",
|
|
121
|
+
"notnull",
|
|
122
|
+
"nuint",
|
|
123
|
+
"on",
|
|
124
|
+
"or",
|
|
125
|
+
"orderby",
|
|
126
|
+
"partial",
|
|
127
|
+
"record",
|
|
128
|
+
"remove",
|
|
129
|
+
"required",
|
|
130
|
+
"scoped",
|
|
131
|
+
"select",
|
|
132
|
+
"set",
|
|
133
|
+
"unmanaged",
|
|
134
|
+
"value",
|
|
135
|
+
"var",
|
|
136
|
+
"when",
|
|
137
|
+
"where",
|
|
138
|
+
"with",
|
|
139
|
+
"yield",
|
|
140
|
+
]);
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Returns true if the given name is a C# reserved keyword.
|
|
144
|
+
* The check is case-sensitive, matching C# language semantics.
|
|
145
|
+
*
|
|
146
|
+
* Note: this only checks reserved keywords, not contextual keywords.
|
|
147
|
+
* Contextual keywords are only reserved in specific language contexts
|
|
148
|
+
* and are valid identifiers elsewhere (e.g., `value` is valid as a parameter name).
|
|
149
|
+
* Use {@link isCSharpContextualKeyword} to check contextual keywords separately.
|
|
150
|
+
*/
|
|
151
|
+
export function isCSharpKeyword(name: string): boolean {
|
|
152
|
+
return csharpKeywords.has(name);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Returns true if the given name is a C# contextual keyword.
|
|
157
|
+
* Contextual keywords are only reserved in specific language contexts
|
|
158
|
+
* and are generally valid as identifiers.
|
|
159
|
+
*/
|
|
160
|
+
export function isCSharpContextualKeyword(name: string): boolean {
|
|
161
|
+
return csharpContextualKeywords.has(name);
|
|
162
|
+
}
|