@alloy-js/csharp 0.19.0 → 0.20.0-dev.1
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/dist/src/components/{ClassDeclaration.d.ts → class/declaration.d.ts} +29 -11
- package/dist/src/components/class/declaration.d.ts.map +1 -0
- package/dist/src/components/{ClassDeclaration.js → class/declaration.js} +22 -14
- package/dist/src/components/class/declaration.test.d.ts +2 -0
- package/dist/src/components/class/declaration.test.d.ts.map +1 -0
- package/dist/{test/class-declaration.test.js → src/components/class/declaration.test.js} +190 -100
- package/dist/src/components/constructor/constructor.test.js +1 -1
- package/dist/src/components/field/field.test.js +1 -1
- package/dist/src/components/index.d.ts +1 -1
- package/dist/src/components/index.d.ts.map +1 -1
- package/dist/src/components/index.js +1 -1
- package/dist/src/components/parameters/parameters.d.ts.map +1 -1
- package/dist/src/components/parameters/parameters.js +1 -1
- package/dist/src/components/property/property.test.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/{test/class-declaration.test.tsx → src/components/class/declaration.test.tsx} +204 -125
- package/src/components/{ClassDeclaration.tsx → class/declaration.tsx} +53 -22
- package/src/components/constructor/constructor.test.tsx +1 -1
- package/src/components/field/field.test.tsx +1 -1
- package/src/components/index.ts +1 -1
- package/src/components/parameters/parameters.tsx +3 -1
- package/src/components/property/property.test.tsx +1 -1
- package/temp/api.json +41 -9
- package/dist/src/components/ClassDeclaration.d.ts.map +0 -1
- package/dist/test/class-declaration.test.d.ts +0 -2
- package/dist/test/class-declaration.test.d.ts.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alloy-js/csharp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0-dev.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -14,19 +14,19 @@
|
|
|
14
14
|
"author": "jhendrix@microsoft.com",
|
|
15
15
|
"license": "MIT",
|
|
16
16
|
"dependencies": {
|
|
17
|
+
"@alloy-js/core": "~0.19.0 || >= 0.20.0-dev.0",
|
|
17
18
|
"change-case": "^5.4.4",
|
|
18
19
|
"marked": "^15.0.12",
|
|
19
|
-
"pathe": "^2.0.3"
|
|
20
|
-
"@alloy-js/core": "~0.19.0"
|
|
20
|
+
"pathe": "^2.0.3"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
+
"@alloy-js/cli": "~0.19.0 || >= 0.20.0-dev.0",
|
|
24
|
+
"@alloy-js/rollup-plugin": "~0.1.0 || >= 0.1.1-dev.0",
|
|
23
25
|
"@microsoft/api-extractor": "~7.52.8",
|
|
24
26
|
"@rollup/plugin-typescript": "^12.1.2",
|
|
25
27
|
"concurrently": "^9.1.2",
|
|
26
28
|
"typescript": "^5.8.3",
|
|
27
|
-
"vitest": "^3.2.4"
|
|
28
|
-
"@alloy-js/rollup-plugin": "~0.1.0",
|
|
29
|
-
"@alloy-js/cli": "~0.19.0"
|
|
29
|
+
"vitest": "^3.2.4"
|
|
30
30
|
},
|
|
31
31
|
"type": "module",
|
|
32
32
|
"scripts": {
|
|
@@ -1,21 +1,40 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
Children,
|
|
3
|
+
code,
|
|
4
|
+
createNamePolicy,
|
|
5
|
+
List,
|
|
6
|
+
NamePolicyContext,
|
|
7
|
+
Output,
|
|
8
|
+
refkey,
|
|
9
|
+
render,
|
|
10
|
+
} from "@alloy-js/core";
|
|
3
11
|
import * as coretest from "@alloy-js/core/testing";
|
|
4
12
|
import { describe, expect, it } from "vitest";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
13
|
+
import { findFile, TestNamespace, toSourceText } from "../../../test/utils.jsx";
|
|
14
|
+
import { createCSharpNamePolicy } from "../../name-policy.js";
|
|
15
|
+
import { Attribute } from "../attributes/attributes.jsx";
|
|
16
|
+
import { Field } from "../field/field.jsx";
|
|
17
|
+
import { Method } from "../method/method.jsx";
|
|
18
|
+
import { Namespace } from "../Namespace.jsx";
|
|
19
|
+
import { Property } from "../property/property.jsx";
|
|
20
|
+
import { SourceFile } from "../SourceFile.jsx";
|
|
21
|
+
import { Constructor, EnumDeclaration, EnumMember } from "../stc/index.js";
|
|
22
|
+
import { TypeParameterProps } from "../type-parameters/type-parameter.jsx";
|
|
23
|
+
import { ClassDeclaration } from "./declaration.jsx";
|
|
24
|
+
|
|
25
|
+
function Wrapper({ children }: { children: Children }) {
|
|
26
|
+
return (
|
|
27
|
+
<TestNamespace>
|
|
28
|
+
<SourceFile path="Test.cs">{children}</SourceFile>
|
|
29
|
+
</TestNamespace>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
13
32
|
|
|
14
33
|
it("declares class with no members", () => {
|
|
15
34
|
expect(
|
|
16
|
-
<
|
|
35
|
+
<TestNamespace>
|
|
17
36
|
<ClassDeclaration name="TestClass" />
|
|
18
|
-
</
|
|
37
|
+
</TestNamespace>,
|
|
19
38
|
).toRenderTo(`
|
|
20
39
|
class TestClass;
|
|
21
40
|
`);
|
|
@@ -24,9 +43,9 @@ it("declares class with no members", () => {
|
|
|
24
43
|
describe("modifiers", () => {
|
|
25
44
|
it.each(["public", "private"])("%s", (mod) => {
|
|
26
45
|
expect(
|
|
27
|
-
<
|
|
46
|
+
<TestNamespace>
|
|
28
47
|
<ClassDeclaration {...{ [mod]: true }} name="TestClass" />
|
|
29
|
-
</
|
|
48
|
+
</TestNamespace>,
|
|
30
49
|
).toRenderTo(`
|
|
31
50
|
${mod} class TestClass;
|
|
32
51
|
`);
|
|
@@ -34,9 +53,9 @@ describe("modifiers", () => {
|
|
|
34
53
|
|
|
35
54
|
it.each(["partial", "abstract", "static", "sealed"])("%s", (mod) => {
|
|
36
55
|
expect(
|
|
37
|
-
<
|
|
56
|
+
<TestNamespace>
|
|
38
57
|
<ClassDeclaration {...{ [mod]: true }} name="TestClass" />
|
|
39
|
-
</
|
|
58
|
+
</TestNamespace>,
|
|
40
59
|
).toRenderTo(`
|
|
41
60
|
${mod} class TestClass;
|
|
42
61
|
`);
|
|
@@ -44,9 +63,9 @@ describe("modifiers", () => {
|
|
|
44
63
|
|
|
45
64
|
it("combines modifiers", () => {
|
|
46
65
|
expect(
|
|
47
|
-
<
|
|
66
|
+
<TestNamespace>
|
|
48
67
|
<ClassDeclaration public abstract partial name="TestClass" />
|
|
49
|
-
</
|
|
68
|
+
</TestNamespace>,
|
|
50
69
|
).toRenderTo(`
|
|
51
70
|
public abstract partial class TestClass;
|
|
52
71
|
`);
|
|
@@ -56,9 +75,9 @@ describe("modifiers", () => {
|
|
|
56
75
|
describe("base", () => {
|
|
57
76
|
it("define base class", () => {
|
|
58
77
|
expect(
|
|
59
|
-
<
|
|
60
|
-
<
|
|
61
|
-
</
|
|
78
|
+
<TestNamespace>
|
|
79
|
+
<ClassDeclaration name="TestClass" baseType="Foo" />
|
|
80
|
+
</TestNamespace>,
|
|
62
81
|
).toRenderTo(`
|
|
63
82
|
class TestClass : Foo;
|
|
64
83
|
`);
|
|
@@ -66,12 +85,9 @@ describe("base", () => {
|
|
|
66
85
|
|
|
67
86
|
it("define multiple interface types", () => {
|
|
68
87
|
expect(
|
|
69
|
-
<
|
|
70
|
-
<
|
|
71
|
-
|
|
72
|
-
interfaceTypes={["Foo", "Bar"]}
|
|
73
|
-
/>
|
|
74
|
-
</utils.TestNamespace>,
|
|
88
|
+
<TestNamespace>
|
|
89
|
+
<ClassDeclaration name="TestClass" interfaceTypes={["Foo", "Bar"]} />
|
|
90
|
+
</TestNamespace>,
|
|
75
91
|
).toRenderTo(`
|
|
76
92
|
class TestClass : Foo, Bar;
|
|
77
93
|
`);
|
|
@@ -79,13 +95,13 @@ describe("base", () => {
|
|
|
79
95
|
|
|
80
96
|
it("define base class and multiple interface types", () => {
|
|
81
97
|
expect(
|
|
82
|
-
<
|
|
83
|
-
<
|
|
98
|
+
<TestNamespace>
|
|
99
|
+
<ClassDeclaration
|
|
84
100
|
name="TestClass"
|
|
85
101
|
baseType="BaseClass"
|
|
86
102
|
interfaceTypes={["Foo", "Bar"]}
|
|
87
103
|
/>
|
|
88
|
-
</
|
|
104
|
+
</TestNamespace>,
|
|
89
105
|
).toRenderTo(`
|
|
90
106
|
class TestClass : BaseClass, Foo, Bar;
|
|
91
107
|
`);
|
|
@@ -93,13 +109,13 @@ describe("base", () => {
|
|
|
93
109
|
});
|
|
94
110
|
|
|
95
111
|
it("declares class with some members", () => {
|
|
96
|
-
const res =
|
|
97
|
-
<
|
|
112
|
+
const res = toSourceText(
|
|
113
|
+
<ClassDeclaration public name="TestClass">
|
|
98
114
|
<List>
|
|
99
115
|
<Field public name="MemberOne" type="string" />
|
|
100
116
|
<Field public name="MemberTwo" type="int" />
|
|
101
117
|
</List>
|
|
102
|
-
</
|
|
118
|
+
</ClassDeclaration>,
|
|
103
119
|
);
|
|
104
120
|
|
|
105
121
|
expect(res).toBe(coretest.d`
|
|
@@ -115,13 +131,13 @@ it("declares class with some members", () => {
|
|
|
115
131
|
});
|
|
116
132
|
|
|
117
133
|
it("declares class with some methods", () => {
|
|
118
|
-
const res =
|
|
119
|
-
<
|
|
120
|
-
<
|
|
121
|
-
<
|
|
122
|
-
<
|
|
123
|
-
</
|
|
124
|
-
</
|
|
134
|
+
const res = toSourceText(
|
|
135
|
+
<ClassDeclaration public name="TestClass">
|
|
136
|
+
<List>
|
|
137
|
+
<Method public name="MethodOne" />
|
|
138
|
+
<Method private virtual name="MethodTwo" />
|
|
139
|
+
</List>
|
|
140
|
+
</ClassDeclaration>,
|
|
125
141
|
);
|
|
126
142
|
|
|
127
143
|
expect(res).toBe(coretest.d`
|
|
@@ -137,9 +153,9 @@ it("declares class with some methods", () => {
|
|
|
137
153
|
});
|
|
138
154
|
|
|
139
155
|
it("uses refkeys for members, params, and return type", () => {
|
|
140
|
-
const inputTypeRefkey =
|
|
141
|
-
const testResultTypeRefkey =
|
|
142
|
-
const enumTypeRefkey =
|
|
156
|
+
const inputTypeRefkey = refkey();
|
|
157
|
+
const testResultTypeRefkey = refkey();
|
|
158
|
+
const enumTypeRefkey = refkey();
|
|
143
159
|
|
|
144
160
|
const params = [
|
|
145
161
|
{
|
|
@@ -152,48 +168,40 @@ it("uses refkeys for members, params, and return type", () => {
|
|
|
152
168
|
},
|
|
153
169
|
];
|
|
154
170
|
|
|
155
|
-
const res =
|
|
156
|
-
<
|
|
157
|
-
<
|
|
158
|
-
<
|
|
159
|
-
<
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
<csharp.EnumMember name="One" />
|
|
166
|
-
<csharp.EnumMember name="Two" />
|
|
167
|
-
</core.List>
|
|
168
|
-
</csharp.EnumDeclaration>
|
|
171
|
+
const res = render(
|
|
172
|
+
<Output namePolicy={createCSharpNamePolicy()}>
|
|
173
|
+
<Namespace name="TestCode">
|
|
174
|
+
<SourceFile path="Test.cs">
|
|
175
|
+
<EnumDeclaration public name="TestEnum" refkey={enumTypeRefkey}>
|
|
176
|
+
<List comma hardline>
|
|
177
|
+
<EnumMember name="One" />
|
|
178
|
+
<EnumMember name="Two" />
|
|
179
|
+
</List>
|
|
180
|
+
</EnumDeclaration>
|
|
169
181
|
<hbr />
|
|
170
|
-
<
|
|
171
|
-
public
|
|
172
|
-
name="TestInput"
|
|
173
|
-
refkey={inputTypeRefkey}
|
|
174
|
-
/>
|
|
182
|
+
<ClassDeclaration public name="TestInput" refkey={inputTypeRefkey} />
|
|
175
183
|
<hbr />
|
|
176
|
-
<
|
|
184
|
+
<ClassDeclaration
|
|
177
185
|
public
|
|
178
186
|
name="TestResult"
|
|
179
187
|
refkey={testResultTypeRefkey}
|
|
180
188
|
/>
|
|
181
189
|
<hbr />
|
|
182
|
-
<
|
|
190
|
+
<ClassDeclaration public name="TestClass">
|
|
183
191
|
<Field private name="MemberOne" type={enumTypeRefkey} />
|
|
184
192
|
<hbr />
|
|
185
|
-
<
|
|
193
|
+
<Method
|
|
186
194
|
public
|
|
187
195
|
name="MethodOne"
|
|
188
196
|
parameters={params}
|
|
189
197
|
returns={testResultTypeRefkey}
|
|
190
198
|
>
|
|
191
199
|
return new {testResultTypeRefkey}();
|
|
192
|
-
</
|
|
193
|
-
</
|
|
194
|
-
</
|
|
195
|
-
</
|
|
196
|
-
</
|
|
200
|
+
</Method>
|
|
201
|
+
</ClassDeclaration>
|
|
202
|
+
</SourceFile>
|
|
203
|
+
</Namespace>
|
|
204
|
+
</Output>,
|
|
197
205
|
);
|
|
198
206
|
|
|
199
207
|
expect(findFile(res, "Test.cs").contents).toBe(coretest.d`
|
|
@@ -232,7 +240,7 @@ describe("with type parameters", () => {
|
|
|
232
240
|
];
|
|
233
241
|
|
|
234
242
|
expect(
|
|
235
|
-
<
|
|
243
|
+
<TestNamespace>
|
|
236
244
|
<SourceFile path="Test.cs">
|
|
237
245
|
<ClassDeclaration
|
|
238
246
|
public
|
|
@@ -245,7 +253,7 @@ describe("with type parameters", () => {
|
|
|
245
253
|
</List>
|
|
246
254
|
</ClassDeclaration>
|
|
247
255
|
</SourceFile>
|
|
248
|
-
</
|
|
256
|
+
</TestNamespace>,
|
|
249
257
|
).toRenderTo(`
|
|
250
258
|
namespace TestCode
|
|
251
259
|
{
|
|
@@ -271,7 +279,7 @@ describe("with type parameters", () => {
|
|
|
271
279
|
];
|
|
272
280
|
|
|
273
281
|
expect(
|
|
274
|
-
<
|
|
282
|
+
<TestNamespace>
|
|
275
283
|
<ClassDeclaration
|
|
276
284
|
public
|
|
277
285
|
name="TestClass"
|
|
@@ -279,7 +287,7 @@ describe("with type parameters", () => {
|
|
|
279
287
|
>
|
|
280
288
|
// Body
|
|
281
289
|
</ClassDeclaration>
|
|
282
|
-
</
|
|
290
|
+
</TestNamespace>,
|
|
283
291
|
).toRenderTo(`
|
|
284
292
|
public class TestClass<T, U>
|
|
285
293
|
where T : IFoo
|
|
@@ -293,25 +301,26 @@ describe("with type parameters", () => {
|
|
|
293
301
|
|
|
294
302
|
it("declares class with invalid members", () => {
|
|
295
303
|
const decl = (
|
|
296
|
-
<
|
|
297
|
-
<
|
|
298
|
-
<
|
|
299
|
-
</
|
|
304
|
+
<ClassDeclaration public name="TestClass">
|
|
305
|
+
<EnumMember name="One" />,<hbr />
|
|
306
|
+
<EnumMember name="Two" />
|
|
307
|
+
</ClassDeclaration>
|
|
300
308
|
);
|
|
301
309
|
|
|
302
|
-
expect(() =>
|
|
310
|
+
expect(() => toSourceText(decl)).toThrow(
|
|
303
311
|
"can't define an enum member outside of an enum-decl scope",
|
|
304
312
|
);
|
|
305
313
|
});
|
|
306
314
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
<
|
|
311
|
-
|
|
312
|
-
|
|
315
|
+
describe("constructor", () => {
|
|
316
|
+
it("declares with constructor", () => {
|
|
317
|
+
const res = toSourceText(
|
|
318
|
+
<ClassDeclaration public name="TestClass">
|
|
319
|
+
<Constructor public />
|
|
320
|
+
</ClassDeclaration>,
|
|
321
|
+
);
|
|
313
322
|
|
|
314
|
-
|
|
323
|
+
expect(res).toBe(coretest.d`
|
|
315
324
|
namespace TestCode
|
|
316
325
|
{
|
|
317
326
|
public class TestClass
|
|
@@ -320,43 +329,43 @@ it("declares class with constructor", () => {
|
|
|
320
329
|
}
|
|
321
330
|
}
|
|
322
331
|
`);
|
|
323
|
-
});
|
|
332
|
+
});
|
|
324
333
|
|
|
325
|
-
it("declares
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
334
|
+
it("declares with constructor params and assigns values to fields", () => {
|
|
335
|
+
const thisNameRefkey = refkey();
|
|
336
|
+
const thisSizeRefkey = refkey();
|
|
337
|
+
const paramNameRefkey = refkey();
|
|
338
|
+
const paramSizeRefkey = refkey();
|
|
330
339
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
340
|
+
const ctorParams = [
|
|
341
|
+
{
|
|
342
|
+
name: "name",
|
|
343
|
+
type: "string",
|
|
344
|
+
refkey: paramNameRefkey,
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
name: "size",
|
|
348
|
+
type: "int",
|
|
349
|
+
refkey: paramSizeRefkey,
|
|
350
|
+
},
|
|
351
|
+
];
|
|
343
352
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
353
|
+
const res = toSourceText(
|
|
354
|
+
<ClassDeclaration public name="TestClass">
|
|
355
|
+
<Field private name="name" type="string" refkey={thisNameRefkey} />
|
|
356
|
+
<hbr />
|
|
357
|
+
<Field private name="size" type="int" refkey={thisSizeRefkey} />
|
|
358
|
+
<hbr />
|
|
359
|
+
<Constructor public parameters={ctorParams}>
|
|
360
|
+
{thisNameRefkey} = {paramNameRefkey};<hbr />
|
|
361
|
+
{thisSizeRefkey} = {paramSizeRefkey};
|
|
362
|
+
</Constructor>
|
|
363
|
+
</ClassDeclaration>,
|
|
364
|
+
);
|
|
356
365
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
366
|
+
// TODO: assignments to members should have this. prefix
|
|
367
|
+
// e.g. this.name = name;
|
|
368
|
+
expect(res).toBe(coretest.d`
|
|
360
369
|
namespace TestCode
|
|
361
370
|
{
|
|
362
371
|
public class TestClass
|
|
@@ -371,13 +380,83 @@ it("declares class with constructor params and assigns values to fields", () =>
|
|
|
371
380
|
}
|
|
372
381
|
}
|
|
373
382
|
`);
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
it("declares primary constructor with args", () => {
|
|
386
|
+
const paramNameRefkey = refkey();
|
|
387
|
+
const paramSizeRefkey = refkey();
|
|
388
|
+
|
|
389
|
+
const ctorParams = [
|
|
390
|
+
{
|
|
391
|
+
name: "name",
|
|
392
|
+
type: "string",
|
|
393
|
+
refkey: paramNameRefkey,
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
name: "size",
|
|
397
|
+
type: "int",
|
|
398
|
+
refkey: paramSizeRefkey,
|
|
399
|
+
},
|
|
400
|
+
];
|
|
401
|
+
|
|
402
|
+
expect(
|
|
403
|
+
<Wrapper>
|
|
404
|
+
<ClassDeclaration
|
|
405
|
+
public
|
|
406
|
+
name="TestClass"
|
|
407
|
+
primaryConstructor={ctorParams}
|
|
408
|
+
>
|
|
409
|
+
<Property
|
|
410
|
+
name="PrettyName"
|
|
411
|
+
type="string"
|
|
412
|
+
get
|
|
413
|
+
initializer={code`$"{${paramNameRefkey}} {${paramSizeRefkey}}"`}
|
|
414
|
+
/>
|
|
415
|
+
</ClassDeclaration>
|
|
416
|
+
</Wrapper>,
|
|
417
|
+
).toRenderTo(`
|
|
418
|
+
namespace TestCode
|
|
419
|
+
{
|
|
420
|
+
public class TestClass(string name, int size)
|
|
421
|
+
{
|
|
422
|
+
string PrettyName { get; } = $"{name} {size}";
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
`);
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
it("primary constructor params conflict with method", () => {
|
|
429
|
+
const ctorParams = [{ name: "name", type: "string" }];
|
|
430
|
+
|
|
431
|
+
expect(
|
|
432
|
+
<Wrapper>
|
|
433
|
+
<NamePolicyContext.Provider value={createNamePolicy((x) => x)}>
|
|
434
|
+
<ClassDeclaration
|
|
435
|
+
public
|
|
436
|
+
name="TestClass"
|
|
437
|
+
primaryConstructor={ctorParams}
|
|
438
|
+
>
|
|
439
|
+
<Field name="name" type="string" />
|
|
440
|
+
</ClassDeclaration>
|
|
441
|
+
</NamePolicyContext.Provider>
|
|
442
|
+
</Wrapper>,
|
|
443
|
+
).toRenderTo(`
|
|
444
|
+
namespace TestCode
|
|
445
|
+
{
|
|
446
|
+
public class TestClass(string name)
|
|
447
|
+
{
|
|
448
|
+
string name_2;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
`);
|
|
452
|
+
});
|
|
374
453
|
});
|
|
375
454
|
|
|
376
455
|
it("specify doc comment", () => {
|
|
377
456
|
expect(
|
|
378
|
-
<
|
|
457
|
+
<TestNamespace>
|
|
379
458
|
<ClassDeclaration name="Test" doc="This is a test" />
|
|
380
|
-
</
|
|
459
|
+
</TestNamespace>,
|
|
381
460
|
).toRenderTo(`
|
|
382
461
|
/// This is a test
|
|
383
462
|
class Test;
|
|
@@ -386,11 +465,11 @@ it("specify doc comment", () => {
|
|
|
386
465
|
|
|
387
466
|
it("supports class member doc comments", () => {
|
|
388
467
|
expect(
|
|
389
|
-
<
|
|
468
|
+
<TestNamespace>
|
|
390
469
|
<ClassDeclaration name="Test" doc="This is a test">
|
|
391
470
|
<Field name="Member" public type="int" doc="This is a member" />
|
|
392
471
|
</ClassDeclaration>
|
|
393
|
-
</
|
|
472
|
+
</TestNamespace>,
|
|
394
473
|
).toRenderTo(`
|
|
395
474
|
/// This is a test
|
|
396
475
|
class Test
|
|
@@ -403,9 +482,9 @@ it("supports class member doc comments", () => {
|
|
|
403
482
|
|
|
404
483
|
it("specify attributes", () => {
|
|
405
484
|
expect(
|
|
406
|
-
<
|
|
485
|
+
<TestNamespace>
|
|
407
486
|
<ClassDeclaration name="Test" attributes={[<Attribute name="Test" />]} />
|
|
408
|
-
</
|
|
487
|
+
</TestNamespace>,
|
|
409
488
|
).toRenderTo(`
|
|
410
489
|
[Test]
|
|
411
490
|
class Test;
|
|
@@ -1,20 +1,28 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
Block,
|
|
3
|
+
Children,
|
|
4
|
+
Declaration,
|
|
5
|
+
DeclarationProps,
|
|
6
|
+
join,
|
|
7
|
+
Name,
|
|
8
|
+
Refkey,
|
|
9
|
+
Scope,
|
|
10
|
+
} from "@alloy-js/core";
|
|
3
11
|
import {
|
|
4
12
|
AccessModifiers,
|
|
5
13
|
computeModifiersPrefix,
|
|
6
14
|
getAccessModifier,
|
|
7
15
|
makeModifiers,
|
|
8
|
-
} from "
|
|
9
|
-
import { useCSharpNamePolicy } from "
|
|
10
|
-
import { CSharpOutputSymbol } from "
|
|
11
|
-
import { CSharpMemberScope } from "
|
|
12
|
-
import { AttributeList, AttributesProp } from "
|
|
13
|
-
import { DocWhen } from "
|
|
14
|
-
import {
|
|
15
|
-
import { TypeParameterConstraints } from "
|
|
16
|
-
import { TypeParameterProps } from "
|
|
17
|
-
import { TypeParameters } from "
|
|
16
|
+
} from "../../modifiers.js";
|
|
17
|
+
import { useCSharpNamePolicy } from "../../name-policy.js";
|
|
18
|
+
import { CSharpOutputSymbol } from "../../symbols/csharp-output-symbol.js";
|
|
19
|
+
import { CSharpMemberScope } from "../../symbols/scopes.js";
|
|
20
|
+
import { AttributeList, AttributesProp } from "../attributes/attributes.jsx";
|
|
21
|
+
import { DocWhen } from "../doc/comment.jsx";
|
|
22
|
+
import { ParameterProps, Parameters } from "../parameters/parameters.jsx";
|
|
23
|
+
import { TypeParameterConstraints } from "../type-parameters/type-parameter-constraints.jsx";
|
|
24
|
+
import { TypeParameterProps } from "../type-parameters/type-parameter.jsx";
|
|
25
|
+
import { TypeParameters } from "../type-parameters/type-parameters.jsx";
|
|
18
26
|
|
|
19
27
|
export interface ClassModifiers {
|
|
20
28
|
readonly abstract?: boolean;
|
|
@@ -32,13 +40,13 @@ const getClassModifiers = makeModifiers<ClassModifiers>([
|
|
|
32
40
|
|
|
33
41
|
// properties for creating a class
|
|
34
42
|
export interface ClassDeclarationProps
|
|
35
|
-
extends Omit<
|
|
43
|
+
extends Omit<DeclarationProps, "nameKind">,
|
|
36
44
|
AccessModifiers,
|
|
37
45
|
ClassModifiers {
|
|
38
46
|
name: string;
|
|
39
47
|
/** Doc comment */
|
|
40
|
-
doc?:
|
|
41
|
-
refkey?:
|
|
48
|
+
doc?: Children;
|
|
49
|
+
refkey?: Refkey;
|
|
42
50
|
|
|
43
51
|
/**
|
|
44
52
|
* Type parameters for the class
|
|
@@ -55,10 +63,10 @@ export interface ClassDeclarationProps
|
|
|
55
63
|
typeParameters?: (string | TypeParameterProps)[];
|
|
56
64
|
|
|
57
65
|
/** Base class that this class extends */
|
|
58
|
-
baseType?:
|
|
66
|
+
baseType?: Children;
|
|
59
67
|
|
|
60
68
|
/** Interfaces this class implements */
|
|
61
|
-
interfaceTypes?:
|
|
69
|
+
interfaceTypes?: Children[];
|
|
62
70
|
|
|
63
71
|
/**
|
|
64
72
|
* Define attributes to attach
|
|
@@ -77,6 +85,24 @@ export interface ClassDeclarationProps
|
|
|
77
85
|
* ```
|
|
78
86
|
*/
|
|
79
87
|
attributes?: AttributesProp;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Set the primary constructor parameters
|
|
91
|
+
* @example
|
|
92
|
+
* ```tsx
|
|
93
|
+
* <ClassDeclaration name="MyClass" primaryConstructor={[
|
|
94
|
+
* {name: "value", type: "int"}
|
|
95
|
+
* ]}>
|
|
96
|
+
* ```
|
|
97
|
+
* This will produce:
|
|
98
|
+
* ```csharp
|
|
99
|
+
* public class MyClass(int value)
|
|
100
|
+
* {
|
|
101
|
+
*
|
|
102
|
+
* }
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
primaryConstructor?: ParameterProps[];
|
|
80
106
|
}
|
|
81
107
|
|
|
82
108
|
/**
|
|
@@ -129,23 +155,28 @@ export function ClassDeclaration(props: ClassDeclarationProps) {
|
|
|
129
155
|
getClassModifiers(props),
|
|
130
156
|
]);
|
|
131
157
|
return (
|
|
132
|
-
<
|
|
158
|
+
<Declaration symbol={thisClassSymbol}>
|
|
133
159
|
<DocWhen doc={props.doc} />
|
|
134
160
|
<AttributeList attributes={props.attributes} endline />
|
|
135
161
|
{modifiers}class <Name />
|
|
136
162
|
{props.typeParameters && (
|
|
137
163
|
<TypeParameters parameters={props.typeParameters} />
|
|
138
164
|
)}
|
|
165
|
+
{props.primaryConstructor && (
|
|
166
|
+
<Scope value={thisClassScope}>
|
|
167
|
+
<Parameters parameters={props.primaryConstructor} />
|
|
168
|
+
</Scope>
|
|
169
|
+
)}
|
|
139
170
|
{base}
|
|
140
171
|
{props.typeParameters && (
|
|
141
172
|
<TypeParameterConstraints parameters={props.typeParameters} />
|
|
142
173
|
)}
|
|
143
174
|
{!props.children && ";"}
|
|
144
175
|
{props.children && (
|
|
145
|
-
<
|
|
146
|
-
<
|
|
147
|
-
</
|
|
176
|
+
<Block newline>
|
|
177
|
+
<Scope value={thisClassScope}>{props.children}</Scope>
|
|
178
|
+
</Block>
|
|
148
179
|
)}
|
|
149
|
-
</
|
|
180
|
+
</Declaration>
|
|
150
181
|
);
|
|
151
182
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { refkey } from "@alloy-js/core";
|
|
2
2
|
import { expect, it } from "vitest";
|
|
3
3
|
import { TestNamespace } from "../../../test/utils.jsx";
|
|
4
|
-
import { ClassDeclaration } from "../
|
|
4
|
+
import { ClassDeclaration } from "../class/declaration.jsx";
|
|
5
5
|
import { SourceFile } from "../SourceFile.jsx";
|
|
6
6
|
import { Constructor } from "./constructor.jsx";
|
|
7
7
|
|