@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
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
isValidCSharpIdentifier,
|
|
4
|
+
sanitizeCSharpIdentifier,
|
|
5
|
+
} from "./identifier-utils.js";
|
|
6
|
+
import {
|
|
7
|
+
csharpContextualKeywords,
|
|
8
|
+
csharpKeywords,
|
|
9
|
+
isCSharpContextualKeyword,
|
|
10
|
+
isCSharpKeyword,
|
|
11
|
+
} from "./keywords.js";
|
|
12
|
+
import { createCSharpNamePolicy } from "./name-policy.js";
|
|
13
|
+
|
|
14
|
+
describe("isCSharpKeyword", () => {
|
|
15
|
+
it("recognizes reserved keywords", () => {
|
|
16
|
+
expect(isCSharpKeyword("class")).toBe(true);
|
|
17
|
+
expect(isCSharpKeyword("interface")).toBe(true);
|
|
18
|
+
expect(isCSharpKeyword("string")).toBe(true);
|
|
19
|
+
expect(isCSharpKeyword("int")).toBe(true);
|
|
20
|
+
expect(isCSharpKeyword("void")).toBe(true);
|
|
21
|
+
expect(isCSharpKeyword("return")).toBe(true);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("does not match contextual keywords", () => {
|
|
25
|
+
expect(isCSharpKeyword("async")).toBe(false);
|
|
26
|
+
expect(isCSharpKeyword("value")).toBe(false);
|
|
27
|
+
expect(isCSharpKeyword("var")).toBe(false);
|
|
28
|
+
expect(isCSharpKeyword("record")).toBe(false);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("is case-sensitive — PascalCase versions are not keywords", () => {
|
|
32
|
+
expect(isCSharpKeyword("Class")).toBe(false);
|
|
33
|
+
expect(isCSharpKeyword("String")).toBe(false);
|
|
34
|
+
expect(isCSharpKeyword("Int")).toBe(false);
|
|
35
|
+
expect(isCSharpKeyword("Void")).toBe(false);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("rejects non-keywords", () => {
|
|
39
|
+
expect(isCSharpKeyword("MyClass")).toBe(false);
|
|
40
|
+
expect(isCSharpKeyword("foo")).toBe(false);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("keyword sets are non-empty", () => {
|
|
44
|
+
expect(csharpKeywords.size).toBeGreaterThan(70);
|
|
45
|
+
expect(csharpContextualKeywords.size).toBeGreaterThan(30);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe("isCSharpContextualKeyword", () => {
|
|
50
|
+
it("recognizes contextual keywords", () => {
|
|
51
|
+
expect(isCSharpContextualKeyword("async")).toBe(true);
|
|
52
|
+
expect(isCSharpContextualKeyword("await")).toBe(true);
|
|
53
|
+
expect(isCSharpContextualKeyword("value")).toBe(true);
|
|
54
|
+
expect(isCSharpContextualKeyword("var")).toBe(true);
|
|
55
|
+
expect(isCSharpContextualKeyword("record")).toBe(true);
|
|
56
|
+
expect(isCSharpContextualKeyword("required")).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("does not match reserved keywords", () => {
|
|
60
|
+
expect(isCSharpContextualKeyword("class")).toBe(false);
|
|
61
|
+
expect(isCSharpContextualKeyword("int")).toBe(false);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe("isValidCSharpIdentifier", () => {
|
|
66
|
+
it("accepts valid identifiers", () => {
|
|
67
|
+
expect(isValidCSharpIdentifier("MyClass")).toBe(true);
|
|
68
|
+
expect(isValidCSharpIdentifier("_private")).toBe(true);
|
|
69
|
+
expect(isValidCSharpIdentifier("name123")).toBe(true);
|
|
70
|
+
expect(isValidCSharpIdentifier("a")).toBe(true);
|
|
71
|
+
expect(isValidCSharpIdentifier("_")).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("rejects invalid identifiers", () => {
|
|
75
|
+
expect(isValidCSharpIdentifier("123start")).toBe(false);
|
|
76
|
+
expect(isValidCSharpIdentifier("has-dash")).toBe(false);
|
|
77
|
+
expect(isValidCSharpIdentifier("has space")).toBe(false);
|
|
78
|
+
expect(isValidCSharpIdentifier("")).toBe(false);
|
|
79
|
+
expect(isValidCSharpIdentifier("foo.bar")).toBe(false);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("does not check for keywords (only character rules)", () => {
|
|
83
|
+
// "class" has valid characters, even though it's a keyword
|
|
84
|
+
expect(isValidCSharpIdentifier("class")).toBe(true);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
describe("sanitizeCSharpIdentifier", () => {
|
|
89
|
+
it("passes through valid identifiers unchanged", () => {
|
|
90
|
+
expect(sanitizeCSharpIdentifier("ValidName")).toBe("ValidName");
|
|
91
|
+
expect(sanitizeCSharpIdentifier("_private")).toBe("_private");
|
|
92
|
+
expect(sanitizeCSharpIdentifier("name123")).toBe("name123");
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("prefixes underscore when first char is a digit", () => {
|
|
96
|
+
expect(sanitizeCSharpIdentifier("1foo")).toBe("_1foo");
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("replaces non-word characters with underscore", () => {
|
|
100
|
+
expect(sanitizeCSharpIdentifier("foo-bar")).toBe("foo_bar");
|
|
101
|
+
expect(sanitizeCSharpIdentifier("has space")).toBe("has_space");
|
|
102
|
+
expect(sanitizeCSharpIdentifier("a.b.c")).toBe("a_b_c");
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("handles leading special characters", () => {
|
|
106
|
+
expect(sanitizeCSharpIdentifier("$foo")).toBe("_foo");
|
|
107
|
+
expect(sanitizeCSharpIdentifier("-bar")).toBe("_bar");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("handles empty string", () => {
|
|
111
|
+
expect(sanitizeCSharpIdentifier("")).toBe("_");
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe("createCSharpNamePolicy keyword escaping", () => {
|
|
116
|
+
const policy = createCSharpNamePolicy();
|
|
117
|
+
|
|
118
|
+
describe("PascalCase elements avoid most keyword conflicts naturally", () => {
|
|
119
|
+
it("class element: 'string' becomes 'String' (not a keyword, no escape)", () => {
|
|
120
|
+
expect(policy.getName("string", "class")).toBe("String");
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("class element: 'class' becomes 'Class' (not a keyword, no escape)", () => {
|
|
124
|
+
expect(policy.getName("class", "class")).toBe("Class");
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("class-property element: 'value' becomes 'Value' (not a keyword, no escape)", () => {
|
|
128
|
+
expect(policy.getName("value", "class-property")).toBe("Value");
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe("camelCase elements may hit keywords and get @-escaped", () => {
|
|
133
|
+
it("parameter: 'string' stays 'string' → gets @-escaped", () => {
|
|
134
|
+
expect(policy.getName("string", "parameter")).toBe("@string");
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it("variable: 'int' stays 'int' → gets @-escaped", () => {
|
|
138
|
+
expect(policy.getName("int", "variable")).toBe("@int");
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("parameter: 'return' stays 'return' → gets @-escaped", () => {
|
|
142
|
+
expect(policy.getName("return", "parameter")).toBe("@return");
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("variable: 'value' stays 'value' — contextual keyword, not escaped", () => {
|
|
146
|
+
expect(policy.getName("value", "variable")).toBe("value");
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("parameter: 'async' stays 'async' — contextual keyword, not escaped", () => {
|
|
150
|
+
expect(policy.getName("async", "parameter")).toBe("async");
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe("non-keyword names pass through normally", () => {
|
|
155
|
+
it("parameter: 'myParam' stays 'myParam'", () => {
|
|
156
|
+
expect(policy.getName("myParam", "parameter")).toBe("myParam");
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("class: 'my-model' becomes 'MyModel'", () => {
|
|
160
|
+
expect(policy.getName("my-model", "class")).toBe("MyModel");
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it("parameter: 'some-param' becomes 'someParam'", () => {
|
|
164
|
+
expect(policy.getName("some-param", "parameter")).toBe("someParam");
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
describe("namespace handling", () => {
|
|
169
|
+
it("applies PascalCase", () => {
|
|
170
|
+
expect(policy.getName("my-service", "namespace")).toBe("MyService");
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it("single segment works", () => {
|
|
174
|
+
expect(policy.getName("system", "namespace")).toBe("System");
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it("escapes keyword segments", () => {
|
|
178
|
+
// "namespace" as a namespace segment → PascalCase → "Namespace" → not a keyword
|
|
179
|
+
expect(policy.getName("namespace", "namespace")).toBe("Namespace");
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe("constant and private member escaping", () => {
|
|
184
|
+
it("constant: 'class' becomes 'CLASS' (not a keyword)", () => {
|
|
185
|
+
expect(policy.getName("class", "constant")).toBe("CLASS");
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it("class-member-private: 'value' becomes '_value' (not a keyword)", () => {
|
|
189
|
+
expect(policy.getName("value", "class-member-private")).toBe("_value");
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
describe("identifier sanitization", () => {
|
|
194
|
+
it("sanitizes names starting with digits", () => {
|
|
195
|
+
expect(policy.getName("123foo", "class")).toBe("_123foo");
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it("sanitizes names starting with digits for camelCase elements", () => {
|
|
199
|
+
expect(policy.getName("123param", "parameter")).toBe("_123param");
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it("sanitizes empty string", () => {
|
|
203
|
+
expect(policy.getName("", "class")).toBe("_");
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it("sanitizes namespace starting with digits", () => {
|
|
207
|
+
expect(policy.getName("123service", "namespace")).toBe("_123service");
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
});
|
package/src/name-policy.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as core from "@alloy-js/core";
|
|
2
2
|
import * as changecase from "change-case";
|
|
3
|
+
import { sanitizeCSharpIdentifier } from "./identifier-utils.js";
|
|
4
|
+
import { isCSharpKeyword } from "./keywords.js";
|
|
3
5
|
|
|
4
6
|
// the context in which the name policy should be applied
|
|
5
7
|
export type CSharpElements =
|
|
@@ -20,10 +22,27 @@ export type CSharpElements =
|
|
|
20
22
|
| "type-parameter"
|
|
21
23
|
| "namespace";
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Prefixes the name with `@` if it is a C# keyword.
|
|
27
|
+
* This is the idiomatic C# way to use reserved words as identifiers.
|
|
28
|
+
* The check is case-sensitive, matching C# language semantics.
|
|
29
|
+
*/
|
|
30
|
+
function escapeIfKeyword(name: string): string {
|
|
31
|
+
return isCSharpKeyword(name) ? `@${name}` : name;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Creates the C# naming policy with case conversion and keyword escaping.
|
|
36
|
+
*
|
|
37
|
+
* After applying the appropriate case conversion for each element kind,
|
|
38
|
+
* the resulting name is checked against C# reserved and contextual keywords.
|
|
39
|
+
* If it matches (case-sensitively), the name is prefixed with `@`.
|
|
40
|
+
*/
|
|
24
41
|
export function createCSharpNamePolicy(): core.NamePolicy<CSharpElements> {
|
|
25
42
|
return core.createNamePolicy((name, element) => {
|
|
43
|
+
let result: string;
|
|
26
44
|
switch (element) {
|
|
45
|
+
case "namespace":
|
|
27
46
|
case "class":
|
|
28
47
|
case "struct":
|
|
29
48
|
case "enum":
|
|
@@ -34,15 +53,20 @@ export function createCSharpNamePolicy(): core.NamePolicy<CSharpElements> {
|
|
|
34
53
|
case "class-method":
|
|
35
54
|
case "type-parameter":
|
|
36
55
|
case "class-property":
|
|
37
|
-
|
|
38
|
-
|
|
56
|
+
result = changecase.pascalCase(name);
|
|
57
|
+
break;
|
|
39
58
|
case "constant":
|
|
40
|
-
|
|
59
|
+
result = changecase.constantCase(name);
|
|
60
|
+
break;
|
|
41
61
|
case "class-member-private":
|
|
42
|
-
|
|
62
|
+
result = `_${changecase.camelCase(name)}`;
|
|
63
|
+
break;
|
|
43
64
|
default:
|
|
44
|
-
|
|
65
|
+
result = changecase.camelCase(name);
|
|
66
|
+
break;
|
|
45
67
|
}
|
|
68
|
+
|
|
69
|
+
return escapeIfKeyword(sanitizeCSharpIdentifier(result));
|
|
46
70
|
});
|
|
47
71
|
}
|
|
48
72
|
|
package/temp/api.json
CHANGED
|
@@ -2305,6 +2305,38 @@
|
|
|
2305
2305
|
"name": "ConstructorProps",
|
|
2306
2306
|
"preserveMemberOrder": false,
|
|
2307
2307
|
"members": [
|
|
2308
|
+
{
|
|
2309
|
+
"kind": "PropertySignature",
|
|
2310
|
+
"canonicalReference": "@alloy-js/csharp!ConstructorProps#baseConstructor:member",
|
|
2311
|
+
"docComment": "/**\n * Arguments to pass to the base class constructor.\n * Renders `: base(args)` between parameter list and body.\n *\n * @example\n * ```tsx\n * <Constructor public baseConstructor={[\"name\", \"42\"]}>\n * ```\n *\n * This will produce:\n * ```csharp\n * public MyClass(...) : base(name, 42)\n * {\n * }\n * ```\n *\n */\n",
|
|
2312
|
+
"excerptTokens": [
|
|
2313
|
+
{
|
|
2314
|
+
"kind": "Content",
|
|
2315
|
+
"text": "baseConstructor?: "
|
|
2316
|
+
},
|
|
2317
|
+
{
|
|
2318
|
+
"kind": "Reference",
|
|
2319
|
+
"text": "Children",
|
|
2320
|
+
"canonicalReference": "@alloy-js/core!Children:type"
|
|
2321
|
+
},
|
|
2322
|
+
{
|
|
2323
|
+
"kind": "Content",
|
|
2324
|
+
"text": "[]"
|
|
2325
|
+
},
|
|
2326
|
+
{
|
|
2327
|
+
"kind": "Content",
|
|
2328
|
+
"text": ";"
|
|
2329
|
+
}
|
|
2330
|
+
],
|
|
2331
|
+
"isReadonly": false,
|
|
2332
|
+
"isOptional": true,
|
|
2333
|
+
"releaseTag": "Public",
|
|
2334
|
+
"name": "baseConstructor",
|
|
2335
|
+
"propertyTypeTokenRange": {
|
|
2336
|
+
"startIndex": 1,
|
|
2337
|
+
"endIndex": 3
|
|
2338
|
+
}
|
|
2339
|
+
},
|
|
2308
2340
|
{
|
|
2309
2341
|
"kind": "PropertySignature",
|
|
2310
2342
|
"canonicalReference": "@alloy-js/csharp!ConstructorProps#children:member",
|
|
@@ -2420,6 +2452,38 @@
|
|
|
2420
2452
|
"startIndex": 1,
|
|
2421
2453
|
"endIndex": 2
|
|
2422
2454
|
}
|
|
2455
|
+
},
|
|
2456
|
+
{
|
|
2457
|
+
"kind": "PropertySignature",
|
|
2458
|
+
"canonicalReference": "@alloy-js/csharp!ConstructorProps#thisConstructor:member",
|
|
2459
|
+
"docComment": "/**\n * Arguments to pass to another constructor in the same class.\n * Renders `: this(args)` between parameter list and body.\n *\n * @example\n * ```tsx\n * <Constructor public thisConstructor={[\"0\", \"0\"]}>\n * ```\n *\n * This will produce:\n * ```csharp\n * public MyClass() : this(0, 0)\n * {\n * }\n * ```\n *\n */\n",
|
|
2460
|
+
"excerptTokens": [
|
|
2461
|
+
{
|
|
2462
|
+
"kind": "Content",
|
|
2463
|
+
"text": "thisConstructor?: "
|
|
2464
|
+
},
|
|
2465
|
+
{
|
|
2466
|
+
"kind": "Reference",
|
|
2467
|
+
"text": "Children",
|
|
2468
|
+
"canonicalReference": "@alloy-js/core!Children:type"
|
|
2469
|
+
},
|
|
2470
|
+
{
|
|
2471
|
+
"kind": "Content",
|
|
2472
|
+
"text": "[]"
|
|
2473
|
+
},
|
|
2474
|
+
{
|
|
2475
|
+
"kind": "Content",
|
|
2476
|
+
"text": ";"
|
|
2477
|
+
}
|
|
2478
|
+
],
|
|
2479
|
+
"isReadonly": false,
|
|
2480
|
+
"isOptional": true,
|
|
2481
|
+
"releaseTag": "Public",
|
|
2482
|
+
"name": "thisConstructor",
|
|
2483
|
+
"propertyTypeTokenRange": {
|
|
2484
|
+
"startIndex": 1,
|
|
2485
|
+
"endIndex": 3
|
|
2486
|
+
}
|
|
2423
2487
|
}
|
|
2424
2488
|
],
|
|
2425
2489
|
"extendsTokenRanges": [
|
|
@@ -2496,7 +2560,7 @@
|
|
|
2496
2560
|
{
|
|
2497
2561
|
"kind": "Function",
|
|
2498
2562
|
"canonicalReference": "@alloy-js/csharp!createCSharpNamePolicy:function(1)",
|
|
2499
|
-
"docComment": "",
|
|
2563
|
+
"docComment": "/**\n * Creates the C# naming policy with case conversion and keyword escaping.\n *\n * After applying the appropriate case conversion for each element kind,\n * the resulting name is checked against C# reserved and contextual keywords.\n * If it matches (case-sensitively), the name is prefixed with `@`.\n */\n",
|
|
2500
2564
|
"excerptTokens": [
|
|
2501
2565
|
{
|
|
2502
2566
|
"kind": "Content",
|
|
@@ -3560,6 +3624,34 @@
|
|
|
3560
3624
|
},
|
|
3561
3625
|
"implementsTokenRanges": []
|
|
3562
3626
|
},
|
|
3627
|
+
{
|
|
3628
|
+
"kind": "Variable",
|
|
3629
|
+
"canonicalReference": "@alloy-js/csharp!csharpContextualKeywords:var",
|
|
3630
|
+
"docComment": "/**\n * C# contextual keywords that are reserved in certain contexts.\n * While not always reserved, treating them as keywords in generated code\n * avoids subtle context-dependent issues.\n *\n * @see\n *\n * https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/#contextual-keywords\n */\n",
|
|
3631
|
+
"excerptTokens": [
|
|
3632
|
+
{
|
|
3633
|
+
"kind": "Content",
|
|
3634
|
+
"text": "csharpContextualKeywords: "
|
|
3635
|
+
},
|
|
3636
|
+
{
|
|
3637
|
+
"kind": "Reference",
|
|
3638
|
+
"text": "ReadonlySet",
|
|
3639
|
+
"canonicalReference": "!ReadonlySet:interface"
|
|
3640
|
+
},
|
|
3641
|
+
{
|
|
3642
|
+
"kind": "Content",
|
|
3643
|
+
"text": "<string>"
|
|
3644
|
+
}
|
|
3645
|
+
],
|
|
3646
|
+
"fileUrlPath": "src/keywords.ts",
|
|
3647
|
+
"isReadonly": true,
|
|
3648
|
+
"releaseTag": "Public",
|
|
3649
|
+
"name": "csharpContextualKeywords",
|
|
3650
|
+
"variableTypeTokenRange": {
|
|
3651
|
+
"startIndex": 1,
|
|
3652
|
+
"endIndex": 3
|
|
3653
|
+
}
|
|
3654
|
+
},
|
|
3563
3655
|
{
|
|
3564
3656
|
"kind": "TypeAlias",
|
|
3565
3657
|
"canonicalReference": "@alloy-js/csharp!CSharpElements:type",
|
|
@@ -3667,6 +3759,34 @@
|
|
|
3667
3759
|
"endIndex": 8
|
|
3668
3760
|
}
|
|
3669
3761
|
},
|
|
3762
|
+
{
|
|
3763
|
+
"kind": "Variable",
|
|
3764
|
+
"canonicalReference": "@alloy-js/csharp!csharpKeywords:var",
|
|
3765
|
+
"docComment": "/**\n * C# reserved keywords that cannot be used as identifiers without `@` prefix.\n * These are case-sensitive in C#.\n *\n * @see\n *\n * https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/\n */\n",
|
|
3766
|
+
"excerptTokens": [
|
|
3767
|
+
{
|
|
3768
|
+
"kind": "Content",
|
|
3769
|
+
"text": "csharpKeywords: "
|
|
3770
|
+
},
|
|
3771
|
+
{
|
|
3772
|
+
"kind": "Reference",
|
|
3773
|
+
"text": "ReadonlySet",
|
|
3774
|
+
"canonicalReference": "!ReadonlySet:interface"
|
|
3775
|
+
},
|
|
3776
|
+
{
|
|
3777
|
+
"kind": "Content",
|
|
3778
|
+
"text": "<string>"
|
|
3779
|
+
}
|
|
3780
|
+
],
|
|
3781
|
+
"fileUrlPath": "src/keywords.ts",
|
|
3782
|
+
"isReadonly": true,
|
|
3783
|
+
"releaseTag": "Public",
|
|
3784
|
+
"name": "csharpKeywords",
|
|
3785
|
+
"variableTypeTokenRange": {
|
|
3786
|
+
"startIndex": 1,
|
|
3787
|
+
"endIndex": 3
|
|
3788
|
+
}
|
|
3789
|
+
},
|
|
3670
3790
|
{
|
|
3671
3791
|
"kind": "Class",
|
|
3672
3792
|
"canonicalReference": "@alloy-js/csharp!CSharpLexicalScope:class",
|
|
@@ -10492,6 +10612,141 @@
|
|
|
10492
10612
|
],
|
|
10493
10613
|
"extendsTokenRanges": []
|
|
10494
10614
|
},
|
|
10615
|
+
{
|
|
10616
|
+
"kind": "Function",
|
|
10617
|
+
"canonicalReference": "@alloy-js/csharp!isCSharpContextualKeyword:function(1)",
|
|
10618
|
+
"docComment": "/**\n * Returns true if the given name is a C# contextual keyword.\n * Contextual keywords are only reserved in specific language contexts\n * and are generally valid as identifiers.\n */\n",
|
|
10619
|
+
"excerptTokens": [
|
|
10620
|
+
{
|
|
10621
|
+
"kind": "Content",
|
|
10622
|
+
"text": "export declare function isCSharpContextualKeyword(name: "
|
|
10623
|
+
},
|
|
10624
|
+
{
|
|
10625
|
+
"kind": "Content",
|
|
10626
|
+
"text": "string"
|
|
10627
|
+
},
|
|
10628
|
+
{
|
|
10629
|
+
"kind": "Content",
|
|
10630
|
+
"text": "): "
|
|
10631
|
+
},
|
|
10632
|
+
{
|
|
10633
|
+
"kind": "Content",
|
|
10634
|
+
"text": "boolean"
|
|
10635
|
+
},
|
|
10636
|
+
{
|
|
10637
|
+
"kind": "Content",
|
|
10638
|
+
"text": ";"
|
|
10639
|
+
}
|
|
10640
|
+
],
|
|
10641
|
+
"fileUrlPath": "src/keywords.ts",
|
|
10642
|
+
"returnTypeTokenRange": {
|
|
10643
|
+
"startIndex": 3,
|
|
10644
|
+
"endIndex": 4
|
|
10645
|
+
},
|
|
10646
|
+
"releaseTag": "Public",
|
|
10647
|
+
"overloadIndex": 1,
|
|
10648
|
+
"parameters": [
|
|
10649
|
+
{
|
|
10650
|
+
"parameterName": "name",
|
|
10651
|
+
"parameterTypeTokenRange": {
|
|
10652
|
+
"startIndex": 1,
|
|
10653
|
+
"endIndex": 2
|
|
10654
|
+
},
|
|
10655
|
+
"isOptional": false
|
|
10656
|
+
}
|
|
10657
|
+
],
|
|
10658
|
+
"name": "isCSharpContextualKeyword"
|
|
10659
|
+
},
|
|
10660
|
+
{
|
|
10661
|
+
"kind": "Function",
|
|
10662
|
+
"canonicalReference": "@alloy-js/csharp!isCSharpKeyword:function(1)",
|
|
10663
|
+
"docComment": "/**\n * Returns true if the given name is a C# reserved keyword.\n * The check is case-sensitive, matching C# language semantics.\n *\n * Note: this only checks reserved keywords, not contextual keywords.\n * Contextual keywords are only reserved in specific language contexts\n * and are valid identifiers elsewhere (e.g., `value` is valid as a parameter name).\n * Use {@link isCSharpContextualKeyword} to check contextual keywords separately.\n */\n",
|
|
10664
|
+
"excerptTokens": [
|
|
10665
|
+
{
|
|
10666
|
+
"kind": "Content",
|
|
10667
|
+
"text": "export declare function isCSharpKeyword(name: "
|
|
10668
|
+
},
|
|
10669
|
+
{
|
|
10670
|
+
"kind": "Content",
|
|
10671
|
+
"text": "string"
|
|
10672
|
+
},
|
|
10673
|
+
{
|
|
10674
|
+
"kind": "Content",
|
|
10675
|
+
"text": "): "
|
|
10676
|
+
},
|
|
10677
|
+
{
|
|
10678
|
+
"kind": "Content",
|
|
10679
|
+
"text": "boolean"
|
|
10680
|
+
},
|
|
10681
|
+
{
|
|
10682
|
+
"kind": "Content",
|
|
10683
|
+
"text": ";"
|
|
10684
|
+
}
|
|
10685
|
+
],
|
|
10686
|
+
"fileUrlPath": "src/keywords.ts",
|
|
10687
|
+
"returnTypeTokenRange": {
|
|
10688
|
+
"startIndex": 3,
|
|
10689
|
+
"endIndex": 4
|
|
10690
|
+
},
|
|
10691
|
+
"releaseTag": "Public",
|
|
10692
|
+
"overloadIndex": 1,
|
|
10693
|
+
"parameters": [
|
|
10694
|
+
{
|
|
10695
|
+
"parameterName": "name",
|
|
10696
|
+
"parameterTypeTokenRange": {
|
|
10697
|
+
"startIndex": 1,
|
|
10698
|
+
"endIndex": 2
|
|
10699
|
+
},
|
|
10700
|
+
"isOptional": false
|
|
10701
|
+
}
|
|
10702
|
+
],
|
|
10703
|
+
"name": "isCSharpKeyword"
|
|
10704
|
+
},
|
|
10705
|
+
{
|
|
10706
|
+
"kind": "Function",
|
|
10707
|
+
"canonicalReference": "@alloy-js/csharp!isValidCSharpIdentifier:function(1)",
|
|
10708
|
+
"docComment": "/**\n * Checks whether the provided name is a valid C# identifier (without `@` prefix).\n * Does not account for keyword conflicts — use {@link isCSharpKeyword} for that.\n *\n * @param name - The name to validate.\n *\n * @returns true if the name matches C# identifier rules (letter or underscore start, word chars after).\n */\n",
|
|
10709
|
+
"excerptTokens": [
|
|
10710
|
+
{
|
|
10711
|
+
"kind": "Content",
|
|
10712
|
+
"text": "export declare function isValidCSharpIdentifier(name: "
|
|
10713
|
+
},
|
|
10714
|
+
{
|
|
10715
|
+
"kind": "Content",
|
|
10716
|
+
"text": "string"
|
|
10717
|
+
},
|
|
10718
|
+
{
|
|
10719
|
+
"kind": "Content",
|
|
10720
|
+
"text": "): "
|
|
10721
|
+
},
|
|
10722
|
+
{
|
|
10723
|
+
"kind": "Content",
|
|
10724
|
+
"text": "boolean"
|
|
10725
|
+
},
|
|
10726
|
+
{
|
|
10727
|
+
"kind": "Content",
|
|
10728
|
+
"text": ";"
|
|
10729
|
+
}
|
|
10730
|
+
],
|
|
10731
|
+
"fileUrlPath": "src/identifier-utils.ts",
|
|
10732
|
+
"returnTypeTokenRange": {
|
|
10733
|
+
"startIndex": 3,
|
|
10734
|
+
"endIndex": 4
|
|
10735
|
+
},
|
|
10736
|
+
"releaseTag": "Public",
|
|
10737
|
+
"overloadIndex": 1,
|
|
10738
|
+
"parameters": [
|
|
10739
|
+
{
|
|
10740
|
+
"parameterName": "name",
|
|
10741
|
+
"parameterTypeTokenRange": {
|
|
10742
|
+
"startIndex": 1,
|
|
10743
|
+
"endIndex": 2
|
|
10744
|
+
},
|
|
10745
|
+
"isOptional": false
|
|
10746
|
+
}
|
|
10747
|
+
],
|
|
10748
|
+
"name": "isValidCSharpIdentifier"
|
|
10749
|
+
},
|
|
10495
10750
|
{
|
|
10496
10751
|
"kind": "Interface",
|
|
10497
10752
|
"canonicalReference": "@alloy-js/csharp!LeixcalScopePropsWithScopeInfo:interface",
|
|
@@ -14558,7 +14813,7 @@
|
|
|
14558
14813
|
{
|
|
14559
14814
|
"kind": "PropertySignature",
|
|
14560
14815
|
"canonicalReference": "@alloy-js/csharp!PropertyProps#get:member",
|
|
14561
|
-
"docComment": "/**\n * If property should have a getter\n */\n",
|
|
14816
|
+
"docComment": "/**\n * If property should have a getter. Pass `true` for an auto-property getter (`get;`),\n * or pass children for a getter with a body.\n *\n * @example\n *\n * auto-property\n * ```tsx\n * <Property name=\"Name\" type=\"string\" get set />\n * ```\n *\n * Produces: `string Name { get; set; }`\n *\n * @example\n *\n * with body\n * ```tsx\n * <Property name=\"Name\" type=\"string\" get={<>return _name;</>} set />\n * ```\n *\n * Produces:\n * ```csharp\n * string Name\n * {\n * get { return _name; }\n * set;\n * }\n * ```\n *\n */\n",
|
|
14562
14817
|
"excerptTokens": [
|
|
14563
14818
|
{
|
|
14564
14819
|
"kind": "Content",
|
|
@@ -14566,7 +14821,12 @@
|
|
|
14566
14821
|
},
|
|
14567
14822
|
{
|
|
14568
14823
|
"kind": "Content",
|
|
14569
|
-
"text": "boolean"
|
|
14824
|
+
"text": "boolean | "
|
|
14825
|
+
},
|
|
14826
|
+
{
|
|
14827
|
+
"kind": "Reference",
|
|
14828
|
+
"text": "Children",
|
|
14829
|
+
"canonicalReference": "@alloy-js/core!Children:type"
|
|
14570
14830
|
},
|
|
14571
14831
|
{
|
|
14572
14832
|
"kind": "Content",
|
|
@@ -14579,7 +14839,7 @@
|
|
|
14579
14839
|
"name": "get",
|
|
14580
14840
|
"propertyTypeTokenRange": {
|
|
14581
14841
|
"startIndex": 1,
|
|
14582
|
-
"endIndex":
|
|
14842
|
+
"endIndex": 3
|
|
14583
14843
|
}
|
|
14584
14844
|
},
|
|
14585
14845
|
{
|
|
@@ -14727,7 +14987,7 @@
|
|
|
14727
14987
|
{
|
|
14728
14988
|
"kind": "PropertySignature",
|
|
14729
14989
|
"canonicalReference": "@alloy-js/csharp!PropertyProps#set:member",
|
|
14730
|
-
"docComment": "/**\n * If property should have a setter\n */\n",
|
|
14990
|
+
"docComment": "/**\n * If property should have a setter. Pass `true` for an auto-property setter (`set;`),\n * or pass children for a setter with a body.\n *\n * @example\n *\n * with body\n * ```tsx\n * <Property name=\"Value\" type=\"int\" get set={<>_value = value;</>} />\n * ```\n *\n * Produces:\n * ```csharp\n * int Value\n * {\n * get;\n * set { _value = value; }\n * }\n * ```\n *\n */\n",
|
|
14731
14991
|
"excerptTokens": [
|
|
14732
14992
|
{
|
|
14733
14993
|
"kind": "Content",
|
|
@@ -14735,7 +14995,12 @@
|
|
|
14735
14995
|
},
|
|
14736
14996
|
{
|
|
14737
14997
|
"kind": "Content",
|
|
14738
|
-
"text": "boolean"
|
|
14998
|
+
"text": "boolean | "
|
|
14999
|
+
},
|
|
15000
|
+
{
|
|
15001
|
+
"kind": "Reference",
|
|
15002
|
+
"text": "Children",
|
|
15003
|
+
"canonicalReference": "@alloy-js/core!Children:type"
|
|
14739
15004
|
},
|
|
14740
15005
|
{
|
|
14741
15006
|
"kind": "Content",
|
|
@@ -14748,7 +15013,7 @@
|
|
|
14748
15013
|
"name": "set",
|
|
14749
15014
|
"propertyTypeTokenRange": {
|
|
14750
15015
|
"startIndex": 1,
|
|
14751
|
-
"endIndex":
|
|
15016
|
+
"endIndex": 3
|
|
14752
15017
|
}
|
|
14753
15018
|
},
|
|
14754
15019
|
{
|
|
@@ -15539,6 +15804,51 @@
|
|
|
15539
15804
|
"endIndex": 9
|
|
15540
15805
|
}
|
|
15541
15806
|
},
|
|
15807
|
+
{
|
|
15808
|
+
"kind": "Function",
|
|
15809
|
+
"canonicalReference": "@alloy-js/csharp!sanitizeCSharpIdentifier:function(1)",
|
|
15810
|
+
"docComment": "/**\n * Transforms an arbitrary string into a valid C# identifier by replacing\n * invalid characters. The result may still be a C# keyword — callers\n * should combine with keyword escaping if needed.\n *\n * - If the first character is not a letter or underscore, a `_` prefix is added.\n * - Subsequent non-word characters are replaced with `_`.\n * - Empty strings become `_`.\n *\n * @param name - The string to sanitize.\n *\n * @returns A string that satisfies C# identifier character rules.\n */\n",
|
|
15811
|
+
"excerptTokens": [
|
|
15812
|
+
{
|
|
15813
|
+
"kind": "Content",
|
|
15814
|
+
"text": "export declare function sanitizeCSharpIdentifier(name: "
|
|
15815
|
+
},
|
|
15816
|
+
{
|
|
15817
|
+
"kind": "Content",
|
|
15818
|
+
"text": "string"
|
|
15819
|
+
},
|
|
15820
|
+
{
|
|
15821
|
+
"kind": "Content",
|
|
15822
|
+
"text": "): "
|
|
15823
|
+
},
|
|
15824
|
+
{
|
|
15825
|
+
"kind": "Content",
|
|
15826
|
+
"text": "string"
|
|
15827
|
+
},
|
|
15828
|
+
{
|
|
15829
|
+
"kind": "Content",
|
|
15830
|
+
"text": ";"
|
|
15831
|
+
}
|
|
15832
|
+
],
|
|
15833
|
+
"fileUrlPath": "src/identifier-utils.ts",
|
|
15834
|
+
"returnTypeTokenRange": {
|
|
15835
|
+
"startIndex": 3,
|
|
15836
|
+
"endIndex": 4
|
|
15837
|
+
},
|
|
15838
|
+
"releaseTag": "Public",
|
|
15839
|
+
"overloadIndex": 1,
|
|
15840
|
+
"parameters": [
|
|
15841
|
+
{
|
|
15842
|
+
"parameterName": "name",
|
|
15843
|
+
"parameterTypeTokenRange": {
|
|
15844
|
+
"startIndex": 1,
|
|
15845
|
+
"endIndex": 2
|
|
15846
|
+
},
|
|
15847
|
+
"isOptional": false
|
|
15848
|
+
}
|
|
15849
|
+
],
|
|
15850
|
+
"name": "sanitizeCSharpIdentifier"
|
|
15851
|
+
},
|
|
15542
15852
|
{
|
|
15543
15853
|
"kind": "Function",
|
|
15544
15854
|
"canonicalReference": "@alloy-js/csharp!SourceFile:function(1)",
|