@alloy-js/csharp 0.18.0-dev.17 → 0.18.0-dev.18
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 +14 -1
- package/dist/src/components/ClassDeclaration.d.ts.map +1 -1
- package/dist/src/components/ClassDeclaration.js +12 -25
- package/dist/src/components/ClassMethod.d.ts +14 -0
- package/dist/src/components/ClassMethod.d.ts.map +1 -1
- package/dist/src/components/ClassMethod.js +11 -1
- package/dist/src/components/index.d.ts +1 -0
- package/dist/src/components/index.d.ts.map +1 -1
- package/dist/src/components/index.js +2 -1
- package/dist/src/components/interface/declaration.d.ts +14 -1
- package/dist/src/components/interface/declaration.d.ts.map +1 -1
- package/dist/src/components/interface/declaration.js +12 -25
- package/dist/src/components/interface/declaration.test.js +84 -0
- package/dist/src/components/interface/method.d.ts +14 -0
- package/dist/src/components/interface/method.d.ts.map +1 -1
- package/dist/src/components/interface/method.js +11 -1
- package/dist/src/components/interface/method.test.js +79 -0
- package/dist/src/components/type-parameters/type-parameter-constraints.d.ts +8 -0
- package/dist/src/components/type-parameters/type-parameter-constraints.d.ts.map +1 -0
- package/dist/src/components/type-parameters/type-parameter-constraints.js +44 -0
- package/dist/src/components/type-parameters/type-parameter-constraints.test.d.ts +2 -0
- package/dist/src/components/type-parameters/type-parameter-constraints.test.d.ts.map +1 -0
- package/dist/src/components/type-parameters/type-parameter-constraints.test.js +67 -0
- package/dist/src/components/type-parameters/type-parameter.d.ts +20 -0
- package/dist/src/components/type-parameters/type-parameter.d.ts.map +1 -0
- package/dist/src/components/type-parameters/type-parameter.js +22 -0
- package/dist/src/components/type-parameters/type-parameters.d.ts +17 -0
- package/dist/src/components/type-parameters/type-parameters.d.ts.map +1 -0
- package/dist/src/components/type-parameters/type-parameters.js +65 -0
- package/dist/src/components/type-parameters/type-parameters.test.d.ts +2 -0
- package/dist/src/components/type-parameters/type-parameters.test.d.ts.map +1 -0
- package/dist/src/components/type-parameters/type-parameters.test.js +26 -0
- package/dist/test/class-declaration.test.js +79 -33
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/components/ClassDeclaration.tsx +23 -27
- package/src/components/ClassMethod.tsx +25 -1
- package/src/components/index.ts +1 -0
- package/src/components/interface/declaration.test.tsx +87 -0
- package/src/components/interface/declaration.tsx +23 -27
- package/src/components/interface/method.test.tsx +78 -0
- package/src/components/interface/method.tsx +24 -1
- package/src/components/type-parameters/type-parameter-constraints.test.tsx +93 -0
- package/src/components/type-parameters/type-parameter-constraints.tsx +46 -0
- package/src/components/type-parameters/type-parameter.tsx +35 -0
- package/src/components/type-parameters/type-parameters.test.tsx +19 -0
- package/src/components/type-parameters/type-parameters.tsx +72 -0
- package/temp/api.json +211 -22
- package/test/class-declaration.test.tsx +75 -25
|
@@ -18,6 +18,9 @@ import { CSharpOutputSymbol } from "../symbols/csharp-output-symbol.js";
|
|
|
18
18
|
import { CSharpMemberScope, useCSharpScope } from "../symbols/scopes.js";
|
|
19
19
|
import { ParameterProps, Parameters } from "./Parameters.jsx";
|
|
20
20
|
import { DocWhen } from "./doc/comment.jsx";
|
|
21
|
+
import { TypeParameterConstraints } from "./type-parameters/type-parameter-constraints.jsx";
|
|
22
|
+
import { TypeParameterProps } from "./type-parameters/type-parameter.jsx";
|
|
23
|
+
import { TypeParameters } from "./type-parameters/type-parameters.jsx";
|
|
21
24
|
|
|
22
25
|
/** Method modifiers. Can only be one. */
|
|
23
26
|
export interface ClassMethodModifiers {
|
|
@@ -51,6 +54,20 @@ export interface ClassMethodProps
|
|
|
51
54
|
|
|
52
55
|
/** Doc comment */
|
|
53
56
|
doc?: Children;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Type parameters for the method
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```tsx
|
|
63
|
+
* <InterfaceMethod name="Test" typeParameters={["T"]} />
|
|
64
|
+
* ```
|
|
65
|
+
* This will produce:
|
|
66
|
+
* ```csharp
|
|
67
|
+
* public void Test<T>()
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
typeParameters?: (TypeParameterProps | string)[];
|
|
54
71
|
}
|
|
55
72
|
|
|
56
73
|
// a C# class method
|
|
@@ -86,7 +103,14 @@ export function ClassMethod(props: ClassMethodProps) {
|
|
|
86
103
|
<Scope value={methodScope}>
|
|
87
104
|
<DocWhen doc={props.doc} />
|
|
88
105
|
{modifiers}
|
|
89
|
-
{returns}
|
|
106
|
+
{returns}{" "}
|
|
107
|
+
{props.typeParameters && (
|
|
108
|
+
<TypeParameters parameters={props.typeParameters} />
|
|
109
|
+
)}
|
|
110
|
+
{name}({params})
|
|
111
|
+
{props.typeParameters && (
|
|
112
|
+
<TypeParameterConstraints parameters={props.typeParameters} />
|
|
113
|
+
)}
|
|
90
114
|
{props.abstract ? ";" : <Block newline>{props.children}</Block>}
|
|
91
115
|
</Scope>
|
|
92
116
|
</MemberDeclaration>
|
package/src/components/index.ts
CHANGED
|
@@ -15,5 +15,6 @@ export * from "./property/property.jsx";
|
|
|
15
15
|
export * from "./record/declaration.js";
|
|
16
16
|
export * from "./Reference.js";
|
|
17
17
|
export * from "./SourceFile.js";
|
|
18
|
+
export type { TypeParameterProps } from "./type-parameters/type-parameter.jsx";
|
|
18
19
|
export * from "./UsingDirective.js";
|
|
19
20
|
export * from "./var/declaration.jsx";
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { List, refkey } from "@alloy-js/core";
|
|
1
2
|
import { describe, expect, it } from "vitest";
|
|
2
3
|
import { TestNamespace } from "../../../test/utils.jsx";
|
|
4
|
+
import { SourceFile } from "../SourceFile.jsx";
|
|
5
|
+
import { TypeParameterProps } from "../type-parameters/type-parameter.jsx";
|
|
3
6
|
import { InterfaceDeclaration } from "./declaration.jsx";
|
|
7
|
+
import { InterfaceProperty } from "./property.jsx";
|
|
4
8
|
|
|
5
9
|
it("declares class with no members", () => {
|
|
6
10
|
expect(
|
|
@@ -54,3 +58,86 @@ it("specify doc comment", () => {
|
|
|
54
58
|
interface TestInterface;
|
|
55
59
|
`);
|
|
56
60
|
});
|
|
61
|
+
|
|
62
|
+
describe("with type parameters", () => {
|
|
63
|
+
it("reference parameters", () => {
|
|
64
|
+
const typeParameters: TypeParameterProps[] = [
|
|
65
|
+
{
|
|
66
|
+
name: "T",
|
|
67
|
+
refkey: refkey(),
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: "U",
|
|
71
|
+
refkey: refkey(),
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
expect(
|
|
76
|
+
<TestNamespace>
|
|
77
|
+
<SourceFile path="Test.cs">
|
|
78
|
+
<InterfaceDeclaration
|
|
79
|
+
public
|
|
80
|
+
name="Test"
|
|
81
|
+
typeParameters={typeParameters}
|
|
82
|
+
>
|
|
83
|
+
<List>
|
|
84
|
+
<InterfaceProperty
|
|
85
|
+
name="PropA"
|
|
86
|
+
type={typeParameters[0].refkey}
|
|
87
|
+
get
|
|
88
|
+
set
|
|
89
|
+
/>
|
|
90
|
+
<InterfaceProperty
|
|
91
|
+
name="PropB"
|
|
92
|
+
type={typeParameters[1].refkey}
|
|
93
|
+
get
|
|
94
|
+
set
|
|
95
|
+
/>
|
|
96
|
+
</List>
|
|
97
|
+
</InterfaceDeclaration>
|
|
98
|
+
</SourceFile>
|
|
99
|
+
</TestNamespace>,
|
|
100
|
+
).toRenderTo(`
|
|
101
|
+
namespace TestCode
|
|
102
|
+
{
|
|
103
|
+
public interface Test<T, U>
|
|
104
|
+
{
|
|
105
|
+
T PropA { get; set; }
|
|
106
|
+
U PropB { get; set; }
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
`);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("defines with constraints", () => {
|
|
113
|
+
const typeParameters: TypeParameterProps[] = [
|
|
114
|
+
{
|
|
115
|
+
name: "T",
|
|
116
|
+
constraints: "IFoo",
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: "U",
|
|
120
|
+
constraints: "IBar",
|
|
121
|
+
},
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
expect(
|
|
125
|
+
<TestNamespace>
|
|
126
|
+
<InterfaceDeclaration
|
|
127
|
+
public
|
|
128
|
+
name="Test"
|
|
129
|
+
typeParameters={typeParameters}
|
|
130
|
+
>
|
|
131
|
+
// Body
|
|
132
|
+
</InterfaceDeclaration>
|
|
133
|
+
</TestNamespace>,
|
|
134
|
+
).toRenderTo(`
|
|
135
|
+
public interface Test<T, U>
|
|
136
|
+
where T : IFoo
|
|
137
|
+
where U : IBar
|
|
138
|
+
{
|
|
139
|
+
// Body
|
|
140
|
+
}
|
|
141
|
+
`);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
@@ -10,6 +10,9 @@ import { CSharpOutputSymbol } from "../../symbols/csharp-output-symbol.js";
|
|
|
10
10
|
import { CSharpMemberScope } from "../../symbols/scopes.js";
|
|
11
11
|
import { DocWhen } from "../doc/comment.jsx";
|
|
12
12
|
import { Name } from "../Name.jsx";
|
|
13
|
+
import { TypeParameterConstraints } from "../type-parameters/type-parameter-constraints.jsx";
|
|
14
|
+
import { TypeParameterProps } from "../type-parameters/type-parameter.jsx";
|
|
15
|
+
import { TypeParameters } from "../type-parameters/type-parameters.jsx";
|
|
13
16
|
|
|
14
17
|
export interface InterfaceModifiers {
|
|
15
18
|
readonly partial?: boolean;
|
|
@@ -27,7 +30,20 @@ export interface InterfaceDeclarationProps
|
|
|
27
30
|
/** Doc comment */
|
|
28
31
|
doc?: core.Children;
|
|
29
32
|
refkey?: core.Refkey;
|
|
30
|
-
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Type parameters for the interface
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```tsx
|
|
39
|
+
* <InterfaceDeclaration name="IList" typeParameters={["T"]} />
|
|
40
|
+
* ```
|
|
41
|
+
* This will produce:
|
|
42
|
+
* ```csharp
|
|
43
|
+
* public interface IList<T>
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
typeParameters?: (TypeParameterProps | string)[];
|
|
31
47
|
}
|
|
32
48
|
|
|
33
49
|
/**
|
|
@@ -65,31 +81,6 @@ export function InterfaceDeclaration(props: InterfaceDeclarationProps) {
|
|
|
65
81
|
owner: thisInterfaceSymbol,
|
|
66
82
|
});
|
|
67
83
|
|
|
68
|
-
let typeParams: core.Children;
|
|
69
|
-
if (props.typeParameters) {
|
|
70
|
-
const typeParamNames = new Array<string>();
|
|
71
|
-
for (const entry of Object.entries(props.typeParameters)) {
|
|
72
|
-
typeParamNames.push(
|
|
73
|
-
useCSharpNamePolicy().getName(entry[0], "type-parameter"),
|
|
74
|
-
);
|
|
75
|
-
// create a symbol for each type param so its
|
|
76
|
-
// refkey resolves to the type param's name
|
|
77
|
-
new CSharpOutputSymbol(entry[0], {
|
|
78
|
-
scope: thisInterfaceScope,
|
|
79
|
-
refkeys: entry[1],
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
typeParams = (
|
|
83
|
-
<group>
|
|
84
|
-
{"<"}
|
|
85
|
-
<core.For each={typeParamNames} comma line>
|
|
86
|
-
{(name) => name}
|
|
87
|
-
</core.For>
|
|
88
|
-
{">"}
|
|
89
|
-
</group>
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
84
|
const modifiers = computeModifiersPrefix([
|
|
94
85
|
getAccessModifier(props),
|
|
95
86
|
getInterfaceModifiers(props),
|
|
@@ -98,7 +89,12 @@ export function InterfaceDeclaration(props: InterfaceDeclarationProps) {
|
|
|
98
89
|
<core.Declaration symbol={thisInterfaceSymbol}>
|
|
99
90
|
<DocWhen doc={props.doc} />
|
|
100
91
|
{modifiers}interface <Name />
|
|
101
|
-
{
|
|
92
|
+
{props.typeParameters && (
|
|
93
|
+
<TypeParameters parameters={props.typeParameters} />
|
|
94
|
+
)}
|
|
95
|
+
{props.typeParameters && (
|
|
96
|
+
<TypeParameterConstraints parameters={props.typeParameters} />
|
|
97
|
+
)}
|
|
102
98
|
{props.children ?
|
|
103
99
|
<core.Block newline>
|
|
104
100
|
<core.Scope value={thisInterfaceScope}>{props.children}</core.Scope>
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { refkey } from "@alloy-js/core";
|
|
1
2
|
import { Children } from "@alloy-js/core/jsx-runtime";
|
|
2
3
|
import { describe, expect, it } from "vitest";
|
|
3
4
|
import { TestNamespace } from "../../../test/utils.jsx";
|
|
5
|
+
import { SourceFile } from "../SourceFile.jsx";
|
|
6
|
+
import { TypeParameterProps } from "../type-parameters/type-parameter.jsx";
|
|
4
7
|
import { InterfaceDeclaration } from "./declaration.jsx";
|
|
5
8
|
import { InterfaceMethod } from "./method.jsx";
|
|
6
9
|
|
|
@@ -170,3 +173,78 @@ it("specify doc comment", () => {
|
|
|
170
173
|
}
|
|
171
174
|
`);
|
|
172
175
|
});
|
|
176
|
+
|
|
177
|
+
describe("with type parameters", () => {
|
|
178
|
+
it("reference parameters", () => {
|
|
179
|
+
const typeParameters: TypeParameterProps[] = [
|
|
180
|
+
{
|
|
181
|
+
name: "T",
|
|
182
|
+
refkey: refkey(),
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: "U",
|
|
186
|
+
refkey: refkey(),
|
|
187
|
+
},
|
|
188
|
+
];
|
|
189
|
+
|
|
190
|
+
expect(
|
|
191
|
+
<TestNamespace>
|
|
192
|
+
<SourceFile path="TestFile.cs">
|
|
193
|
+
<InterfaceDeclaration public name="TestInterface">
|
|
194
|
+
<InterfaceMethod
|
|
195
|
+
name="Test"
|
|
196
|
+
public
|
|
197
|
+
typeParameters={typeParameters}
|
|
198
|
+
parameters={[
|
|
199
|
+
{
|
|
200
|
+
name: "paramA",
|
|
201
|
+
type: typeParameters[0].refkey,
|
|
202
|
+
},
|
|
203
|
+
]}
|
|
204
|
+
returns={typeParameters[0].refkey}
|
|
205
|
+
/>
|
|
206
|
+
</InterfaceDeclaration>
|
|
207
|
+
</SourceFile>
|
|
208
|
+
</TestNamespace>,
|
|
209
|
+
).toRenderTo(`
|
|
210
|
+
namespace TestCode
|
|
211
|
+
{
|
|
212
|
+
public interface TestInterface
|
|
213
|
+
{
|
|
214
|
+
public T <T, U>Test(T paramA);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
`);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it("defines with constraints", () => {
|
|
221
|
+
const typeParameters: TypeParameterProps[] = [
|
|
222
|
+
{
|
|
223
|
+
name: "T",
|
|
224
|
+
constraints: "IFoo",
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
name: "U",
|
|
228
|
+
constraints: "IBar",
|
|
229
|
+
},
|
|
230
|
+
];
|
|
231
|
+
|
|
232
|
+
expect(
|
|
233
|
+
<Wrapper>
|
|
234
|
+
<InterfaceMethod public name="Test" typeParameters={typeParameters}>
|
|
235
|
+
// Body
|
|
236
|
+
</InterfaceMethod>
|
|
237
|
+
</Wrapper>,
|
|
238
|
+
).toRenderTo(`
|
|
239
|
+
public interface TestInterface
|
|
240
|
+
{
|
|
241
|
+
public void <T, U>Test()
|
|
242
|
+
where T : IFoo
|
|
243
|
+
where U : IBar
|
|
244
|
+
{
|
|
245
|
+
// Body
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
`);
|
|
249
|
+
});
|
|
250
|
+
});
|
|
@@ -17,6 +17,9 @@ import { CSharpOutputSymbol } from "../../symbols/csharp-output-symbol.js";
|
|
|
17
17
|
import { CSharpMemberScope, useCSharpScope } from "../../symbols/scopes.js";
|
|
18
18
|
import { ParameterProps, Parameters } from "../Parameters.jsx";
|
|
19
19
|
import { DocWhen } from "../doc/comment.jsx";
|
|
20
|
+
import { TypeParameterConstraints } from "../type-parameters/type-parameter-constraints.jsx";
|
|
21
|
+
import { TypeParameterProps } from "../type-parameters/type-parameter.jsx";
|
|
22
|
+
import { TypeParameters } from "../type-parameters/type-parameters.jsx";
|
|
20
23
|
|
|
21
24
|
/** Method modifiers. Can only be one. */
|
|
22
25
|
export interface InterfaceMethodModifiers {
|
|
@@ -33,6 +36,19 @@ export interface InterfaceMethodProps
|
|
|
33
36
|
refkey?: Refkey;
|
|
34
37
|
children?: Children;
|
|
35
38
|
parameters?: Array<ParameterProps>;
|
|
39
|
+
/**
|
|
40
|
+
* Type parameters for the method
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```tsx
|
|
44
|
+
* <InterfaceMethod name="Test" typeParameters={["T"]} />
|
|
45
|
+
* ```
|
|
46
|
+
* This will produce:
|
|
47
|
+
* ```csharp
|
|
48
|
+
* public void Test<T>()
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
typeParameters?: (TypeParameterProps | string)[];
|
|
36
52
|
returns?: Children;
|
|
37
53
|
|
|
38
54
|
/** Doc comment */
|
|
@@ -72,7 +88,14 @@ export function InterfaceMethod(props: InterfaceMethodProps) {
|
|
|
72
88
|
<Scope value={methodScope}>
|
|
73
89
|
<DocWhen doc={props.doc} />
|
|
74
90
|
{modifiers}
|
|
75
|
-
{props.returns ?? "void"}
|
|
91
|
+
{props.returns ?? "void"}{" "}
|
|
92
|
+
{props.typeParameters && (
|
|
93
|
+
<TypeParameters parameters={props.typeParameters} />
|
|
94
|
+
)}
|
|
95
|
+
{name}({params})
|
|
96
|
+
{props.typeParameters && (
|
|
97
|
+
<TypeParameterConstraints parameters={props.typeParameters} />
|
|
98
|
+
)}
|
|
76
99
|
{props.children ?
|
|
77
100
|
<Block newline>{props.children}</Block>
|
|
78
101
|
: ";"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { expect, it } from "vitest";
|
|
2
|
+
import { TypeParameterConstraints } from "./type-parameter-constraints.jsx";
|
|
3
|
+
|
|
4
|
+
it("renders nothing if there is no constraints", () => {
|
|
5
|
+
expect(<TypeParameterConstraints parameters={["A", "B"]} />).toRenderTo(``);
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
it("renders inline if there is only one", () => {
|
|
9
|
+
expect(
|
|
10
|
+
<>
|
|
11
|
+
{"code()"}
|
|
12
|
+
<TypeParameterConstraints
|
|
13
|
+
parameters={[{ name: "A", constraints: "string" }]}
|
|
14
|
+
/>
|
|
15
|
+
</>,
|
|
16
|
+
).toRenderTo(`
|
|
17
|
+
code() where A : string
|
|
18
|
+
`);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("renders multiple constraints", () => {
|
|
22
|
+
expect(
|
|
23
|
+
<>
|
|
24
|
+
{"code()"}
|
|
25
|
+
<TypeParameterConstraints
|
|
26
|
+
parameters={[{ name: "A", constraints: ["string", "int"] }]}
|
|
27
|
+
/>
|
|
28
|
+
</>,
|
|
29
|
+
).toRenderTo(`
|
|
30
|
+
code() where A : string, int
|
|
31
|
+
`);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("renders newline if constraint is very long", () => {
|
|
35
|
+
expect(
|
|
36
|
+
<>
|
|
37
|
+
{"code()"}
|
|
38
|
+
<TypeParameterConstraints
|
|
39
|
+
parameters={[
|
|
40
|
+
{
|
|
41
|
+
name: "ThisIsQuiteALongName",
|
|
42
|
+
constraints: "VeryLongBuilderFactorySingletonThatShouldBeSplit",
|
|
43
|
+
},
|
|
44
|
+
]}
|
|
45
|
+
/>
|
|
46
|
+
</>,
|
|
47
|
+
).toRenderTo(`
|
|
48
|
+
code()
|
|
49
|
+
where ThisIsQuiteALongName : VeryLongBuilderFactorySingletonThatShouldBeSplit
|
|
50
|
+
`);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("renders multiple constraints on new lines if they are very long", () => {
|
|
54
|
+
expect(
|
|
55
|
+
<>
|
|
56
|
+
{"code()"}
|
|
57
|
+
<TypeParameterConstraints
|
|
58
|
+
parameters={[
|
|
59
|
+
{
|
|
60
|
+
name: "A",
|
|
61
|
+
constraints: [
|
|
62
|
+
"IVeryLongBuilderFactorySingletonThatShouldBeSplitA",
|
|
63
|
+
"IVeryLongBuilderFactorySingletonThatShouldBeSplitB",
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
]}
|
|
67
|
+
/>
|
|
68
|
+
</>,
|
|
69
|
+
).toRenderTo(`
|
|
70
|
+
code()
|
|
71
|
+
where A :
|
|
72
|
+
IVeryLongBuilderFactorySingletonThatShouldBeSplitA,
|
|
73
|
+
IVeryLongBuilderFactorySingletonThatShouldBeSplitB
|
|
74
|
+
`);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("declare type parameters using parameters", () => {
|
|
78
|
+
expect(
|
|
79
|
+
<>
|
|
80
|
+
{"code()"}
|
|
81
|
+
<TypeParameterConstraints
|
|
82
|
+
parameters={[
|
|
83
|
+
{ name: "A", constraints: "string" },
|
|
84
|
+
{ name: "B", constraints: "string" },
|
|
85
|
+
]}
|
|
86
|
+
/>
|
|
87
|
+
</>,
|
|
88
|
+
).toRenderTo(`
|
|
89
|
+
code()
|
|
90
|
+
where A : string
|
|
91
|
+
where B : string
|
|
92
|
+
`);
|
|
93
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Children, code, For, Indent } from "@alloy-js/core";
|
|
2
|
+
import { TypeParameterProps } from "./type-parameter.jsx";
|
|
3
|
+
import { normalizeParameters } from "./type-parameters.jsx";
|
|
4
|
+
|
|
5
|
+
export interface TypeParameterConstraintsProps {
|
|
6
|
+
/** Parameters */
|
|
7
|
+
parameters: (TypeParameterProps | string)[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function TypeParameterConstraints(
|
|
11
|
+
props: TypeParameterConstraintsProps,
|
|
12
|
+
): Children {
|
|
13
|
+
const parameters = normalizeParameters(props.parameters);
|
|
14
|
+
if (!parameters.some((x) => x.constraints)) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return (
|
|
18
|
+
<group>
|
|
19
|
+
<Indent line>
|
|
20
|
+
<For each={parameters} hardline>
|
|
21
|
+
{(param) => <TypeParameterConstraint {...param} />}
|
|
22
|
+
</For>
|
|
23
|
+
</Indent>
|
|
24
|
+
</group>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function TypeParameterConstraint(props: TypeParameterProps): Children {
|
|
29
|
+
const constraints = arrayify(props.constraints);
|
|
30
|
+
return (
|
|
31
|
+
<>
|
|
32
|
+
where {code`${props.name} : `}
|
|
33
|
+
<group>
|
|
34
|
+
<Indent softline>
|
|
35
|
+
<For each={constraints} comma line>
|
|
36
|
+
{(constraint) => code`${constraint}`}
|
|
37
|
+
</For>
|
|
38
|
+
</Indent>
|
|
39
|
+
</group>
|
|
40
|
+
</>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function arrayify<T>(value: T | T[]): T[] {
|
|
45
|
+
return Array.isArray(value) ? value : [value];
|
|
46
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Children, MemberDeclaration, refkey, Refkey } from "@alloy-js/core";
|
|
2
|
+
import { useCSharpNamePolicy } from "../../name-policy.js";
|
|
3
|
+
import { CSharpOutputSymbol } from "../../symbols/csharp-output-symbol.js";
|
|
4
|
+
import { useCSharpScope } from "../../symbols/scopes.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Information for a TypeScript generic type parameter.
|
|
8
|
+
*/
|
|
9
|
+
export interface TypeParameterProps {
|
|
10
|
+
/**
|
|
11
|
+
* The name of the type parameter.
|
|
12
|
+
*/
|
|
13
|
+
readonly name: string;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The parameter constraint
|
|
17
|
+
*/
|
|
18
|
+
readonly constraints?: Children | Children[];
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A refkey or array of refkeys for this type parameter.
|
|
22
|
+
*/
|
|
23
|
+
readonly refkey?: Refkey | Refkey[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function TypeParameter(props: TypeParameterProps) {
|
|
27
|
+
const name = useCSharpNamePolicy().getName(props.name, "type-parameter");
|
|
28
|
+
const scope = useCSharpScope();
|
|
29
|
+
const symbol = new CSharpOutputSymbol(name, {
|
|
30
|
+
scope,
|
|
31
|
+
refkeys: props.refkey ?? refkey(props.name),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return <MemberDeclaration symbol={symbol}>{name}</MemberDeclaration>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { expect, it } from "vitest";
|
|
2
|
+
import { TestNamespace } from "../../../test/utils.jsx";
|
|
3
|
+
import { TypeParameters } from "./type-parameters.jsx";
|
|
4
|
+
|
|
5
|
+
it("declare type parameters using parameters names", () => {
|
|
6
|
+
expect(
|
|
7
|
+
<TestNamespace>
|
|
8
|
+
<TypeParameters parameters={["A", "B"]} />
|
|
9
|
+
</TestNamespace>,
|
|
10
|
+
).toRenderTo(`<A, B>`);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("declare type parameters using parameters", () => {
|
|
14
|
+
expect(
|
|
15
|
+
<TestNamespace>
|
|
16
|
+
<TypeParameters parameters={[{ name: "A" }, { name: "B" }]} />
|
|
17
|
+
</TestNamespace>,
|
|
18
|
+
).toRenderTo(`<A, B>`);
|
|
19
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { For, Indent, taggedComponent } from "@alloy-js/core";
|
|
2
|
+
import { TypeParameter, TypeParameterProps } from "./type-parameter.jsx";
|
|
3
|
+
|
|
4
|
+
export const typeParametersTag = Symbol.for("csharp.type-parameters");
|
|
5
|
+
|
|
6
|
+
export interface TypeParametersProps {
|
|
7
|
+
/** Parameters */
|
|
8
|
+
parameters: (TypeParameterProps | string)[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Represent type parameters
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* <A, B extends string>
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export const TypeParameters = taggedComponent(
|
|
20
|
+
typeParametersTag,
|
|
21
|
+
function TypeParameters(props: TypeParametersProps) {
|
|
22
|
+
const typeParameters = normalizeParameters(props.parameters);
|
|
23
|
+
|
|
24
|
+
// const typeParameters = normalizeAndDeclareParameters(props.parameters);
|
|
25
|
+
|
|
26
|
+
// onCleanup(() => {
|
|
27
|
+
// for (const param of typeParameters) {
|
|
28
|
+
// param.symbol.delete();
|
|
29
|
+
// }
|
|
30
|
+
// });
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<>
|
|
34
|
+
{"<"}
|
|
35
|
+
<group>
|
|
36
|
+
<Indent softline>
|
|
37
|
+
<For each={typeParameters} comma line>
|
|
38
|
+
{(param) => <TypeParameter {...param} />}
|
|
39
|
+
</For>
|
|
40
|
+
<ifBreak>,</ifBreak>
|
|
41
|
+
</Indent>
|
|
42
|
+
</group>
|
|
43
|
+
{">"}
|
|
44
|
+
</>
|
|
45
|
+
);
|
|
46
|
+
},
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
export function normalizeParameters(
|
|
50
|
+
parameters: (TypeParameterProps | string)[],
|
|
51
|
+
): TypeParameterProps[] {
|
|
52
|
+
return parameters.map((param) => {
|
|
53
|
+
if (typeof param === "string") {
|
|
54
|
+
return { name: param };
|
|
55
|
+
}
|
|
56
|
+
return param;
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// export function declareParameter(
|
|
61
|
+
// parameters: TypeParameterProps[],
|
|
62
|
+
// ): TypeParameterProps[] {
|
|
63
|
+
// return parameters.map((param) => {
|
|
64
|
+
// return {
|
|
65
|
+
// ...param,
|
|
66
|
+
// symbol: new CSharpOutputSymbol(entry[0], {
|
|
67
|
+
// scope: thisClassScope,
|
|
68
|
+
// refkeys: entry[1],
|
|
69
|
+
// }),
|
|
70
|
+
// };
|
|
71
|
+
// });
|
|
72
|
+
// }
|