@typespec/emitter-framework 0.17.0-dev.0 → 0.17.0-dev.2
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/csharp/components/class/declaration.d.ts +1 -1
- package/dist/src/csharp/components/class/declaration.d.ts.map +1 -1
- package/dist/src/csharp/components/class/declaration.js +1 -2
- package/dist/src/csharp/components/class/declaration.js.map +1 -1
- package/dist/src/csharp/components/extensible-enum/extensible-enum.d.ts +14 -0
- package/dist/src/csharp/components/extensible-enum/extensible-enum.d.ts.map +1 -0
- package/dist/src/csharp/components/extensible-enum/extensible-enum.js +188 -0
- package/dist/src/csharp/components/extensible-enum/extensible-enum.js.map +1 -0
- package/dist/src/csharp/components/extensible-enum/extensible-enum.test.d.ts +2 -0
- package/dist/src/csharp/components/extensible-enum/extensible-enum.test.d.ts.map +1 -0
- package/dist/src/csharp/components/extensible-enum/extensible-enum.test.js +258 -0
- package/dist/src/csharp/components/extensible-enum/extensible-enum.test.js.map +1 -0
- package/package.json +5 -6
- package/package.json.bak +7 -8
- package/src/csharp/components/class/declaration.tsx +3 -3
- package/src/csharp/components/extensible-enum/extensible-enum.test.tsx +240 -0
- package/src/csharp/components/extensible-enum/extensible-enum.tsx +164 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Children } from "@alloy-js/core";
|
|
2
2
|
import * as cs from "@alloy-js/csharp";
|
|
3
|
-
import {
|
|
3
|
+
import type { Interface, Model } from "@typespec/compiler";
|
|
4
4
|
export interface ClassDeclarationProps extends Omit<cs.ClassDeclarationProps, "name"> {
|
|
5
5
|
/** Set an alternative name for the class. Otherwise default to the type name. */
|
|
6
6
|
name?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"declaration.d.ts","sourceRoot":"","sources":["../../../../../src/csharp/components/class/declaration.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"declaration.d.ts","sourceRoot":"","sources":["../../../../../src/csharp/components/class/declaration.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAQ3D,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,EAAE,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACnF,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,IAAI,EAAE,KAAK,GAAG,SAAS,CAAC;IACxB,8FAA8F;IAC9F,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAYD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,QAAQ,CA6BvE"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { memo as _$memo, mergeProps as _$mergeProps, createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
|
|
2
2
|
import { For } from "@alloy-js/core";
|
|
3
3
|
import * as cs from "@alloy-js/csharp";
|
|
4
|
-
import { Method } from "@alloy-js/csharp";
|
|
5
4
|
import { isVoidType } from "@typespec/compiler";
|
|
6
5
|
import { useTsp } from "../../../core/index.js";
|
|
7
6
|
import { Property } from "../property/property.js";
|
|
@@ -66,7 +65,7 @@ function ClassMethods(props) {
|
|
|
66
65
|
const namePolicy = cs.useCSharpNamePolicy();
|
|
67
66
|
const abstractMethods = [];
|
|
68
67
|
for (const [name, method] of props.type.operations) {
|
|
69
|
-
abstractMethods.push(_$createComponent(Method, {
|
|
68
|
+
abstractMethods.push(_$createComponent(cs.Method, {
|
|
70
69
|
get name() {
|
|
71
70
|
return namePolicy.getName(name, "class-method");
|
|
72
71
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["For","cs","
|
|
1
|
+
{"version":3,"names":["For","cs","isVoidType","useTsp","Property","TypeExpression","getDocComments","declarationRefkeys","ClassDeclaration","props","$","namePolicy","useCSharpNamePolicy","className","name","getName","type","refkeys","refkey","_$createComponent","_$mergeProps","baseType","kind","baseModel","undefined","doc","children","_$memo","ClassProperties","jsonAttributes","ClassMethods","properties","Array","from","entries","filter","_","p","each","doubleHardline","property","abstractMethods","method","operations","push","Method","abstract","parameters","map","prop","returns","returnType"],"sources":["../../../../../src/csharp/components/class/declaration.tsx"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Children } from "@alloy-js/core";
|
|
2
|
+
import { type StructDeclarationProps } from "@alloy-js/csharp";
|
|
3
|
+
import type { Union } from "@typespec/compiler";
|
|
4
|
+
export interface EnumDeclarationProps extends Omit<StructDeclarationProps, "name"> {
|
|
5
|
+
/** Union that should be rendered as an extensible enum struct */
|
|
6
|
+
type: Union;
|
|
7
|
+
/** Name override */
|
|
8
|
+
name?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Render a struct designed to represent an extensible enum based on a TypeSpec union.
|
|
12
|
+
*/
|
|
13
|
+
export declare function ExtensibleEnumDeclaration(props: EnumDeclarationProps): Children;
|
|
14
|
+
//# sourceMappingURL=extensible-enum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensible-enum.d.ts","sourceRoot":"","sources":["../../../../../src/csharp/components/extensible-enum/extensible-enum.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAOL,KAAK,sBAAsB,EAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAGhD,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC;IAChF,iEAAiE;IACjE,IAAI,EAAE,KAAK,CAAC;IACZ,oBAAoB;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,oBAAoB,GAAG,QAAQ,CAY/E"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { memo as _$memo, mergeProps as _$mergeProps, createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
|
|
2
|
+
import { code, For, List, namekey, refkey } from "@alloy-js/core";
|
|
3
|
+
import { Constructor, Field, Method, Property, StructDeclaration, useCSharpNamePolicy } from "@alloy-js/csharp";
|
|
4
|
+
import { declarationRefkeys } from "../utils/refkey.js";
|
|
5
|
+
/**
|
|
6
|
+
* Render a struct designed to represent an extensible enum based on a TypeSpec union.
|
|
7
|
+
*/
|
|
8
|
+
export function ExtensibleEnumDeclaration(props) {
|
|
9
|
+
const {
|
|
10
|
+
variants,
|
|
11
|
+
kind
|
|
12
|
+
} = getExtensibleEnumVariantsFromUnion(props.type);
|
|
13
|
+
const refkeys = declarationRefkeys(props.refkey, props.type)[0];
|
|
14
|
+
return _$createComponent(ExtensibleEnumFromVariants, _$mergeProps(props, {
|
|
15
|
+
refkey: refkeys,
|
|
16
|
+
get name() {
|
|
17
|
+
return props.name ?? props.type.name ?? "Unnamed";
|
|
18
|
+
},
|
|
19
|
+
kind: kind,
|
|
20
|
+
variants: variants
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
function getExtensibleEnumVariantsFromUnion(union) {
|
|
24
|
+
const variants = [];
|
|
25
|
+
const kinds = new Set();
|
|
26
|
+
for (const member of union.variants.values()) {
|
|
27
|
+
switch (member.type.kind) {
|
|
28
|
+
case "String":
|
|
29
|
+
const name = typeof member.name === "string" ? member.name : member.type.value;
|
|
30
|
+
variants.push({
|
|
31
|
+
name,
|
|
32
|
+
value: member.type.value
|
|
33
|
+
});
|
|
34
|
+
kinds.add("string");
|
|
35
|
+
break;
|
|
36
|
+
case "Number":
|
|
37
|
+
const numName = typeof member.name === "string" ? member.name : `NumberValue_${member.type.value}`;
|
|
38
|
+
variants.push({
|
|
39
|
+
name: numName,
|
|
40
|
+
value: member.type.value.toString()
|
|
41
|
+
});
|
|
42
|
+
kinds.add("int32");
|
|
43
|
+
break;
|
|
44
|
+
default:
|
|
45
|
+
break;
|
|
46
|
+
// Ignore other types
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (kinds.size > 1) {
|
|
50
|
+
throw new Error("ExtensibleEnumUnion cannot have mixed kinds of variants.");
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
kind: [...kinds][0],
|
|
54
|
+
variants
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function ExtensibleEnumFromVariants(props) {
|
|
58
|
+
const valueRk = refkey();
|
|
59
|
+
const constructorRk = refkey();
|
|
60
|
+
const namepolicy = useCSharpNamePolicy();
|
|
61
|
+
const name = namepolicy.getName(props.name, "struct");
|
|
62
|
+
const type = props.kind === "string" ? "string" : "int";
|
|
63
|
+
return _$createComponent(StructDeclaration, _$mergeProps({
|
|
64
|
+
readonly: true
|
|
65
|
+
}, props, {
|
|
66
|
+
get name() {
|
|
67
|
+
return props.name;
|
|
68
|
+
},
|
|
69
|
+
interfaceTypes: [`IEquatable<${name}>`],
|
|
70
|
+
get children() {
|
|
71
|
+
return _$createComponent(List, {
|
|
72
|
+
doubleHardline: true,
|
|
73
|
+
get children() {
|
|
74
|
+
return [_$createComponent(Field, {
|
|
75
|
+
"private": true,
|
|
76
|
+
readonly: true,
|
|
77
|
+
name: "value",
|
|
78
|
+
refkey: valueRk,
|
|
79
|
+
type: type
|
|
80
|
+
}), _$createComponent(Constructor, {
|
|
81
|
+
refkey: constructorRk,
|
|
82
|
+
parameters: [{
|
|
83
|
+
name: "value",
|
|
84
|
+
type
|
|
85
|
+
}],
|
|
86
|
+
get children() {
|
|
87
|
+
return [valueRk, " = value;"];
|
|
88
|
+
}
|
|
89
|
+
}), _$createComponent(For, {
|
|
90
|
+
get each() {
|
|
91
|
+
return props.variants;
|
|
92
|
+
},
|
|
93
|
+
children: x => _$createComponent(Property, {
|
|
94
|
+
"public": true,
|
|
95
|
+
"static": true,
|
|
96
|
+
get name() {
|
|
97
|
+
return namepolicy.getName(x.name, "enum-member");
|
|
98
|
+
},
|
|
99
|
+
type: name,
|
|
100
|
+
get: true,
|
|
101
|
+
get initializer() {
|
|
102
|
+
return code`new ${constructorRk}(${props.kind === "string" ? `@"${x.value}"` : x.value})`;
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
}), _$createComponent(Method, {
|
|
106
|
+
"public": true,
|
|
107
|
+
get name() {
|
|
108
|
+
return namekey("Equals", {
|
|
109
|
+
ignoreNameConflict: true
|
|
110
|
+
});
|
|
111
|
+
},
|
|
112
|
+
parameters: [{
|
|
113
|
+
name: "other",
|
|
114
|
+
type: name
|
|
115
|
+
}],
|
|
116
|
+
returns: "bool",
|
|
117
|
+
expression: true,
|
|
118
|
+
get children() {
|
|
119
|
+
return props.kind === "string" ? code`string.Equals(${valueRk}, other.${valueRk}, StringComparison.InvariantCultureIgnoreCase)` : code`${valueRk} == other.${valueRk}`;
|
|
120
|
+
}
|
|
121
|
+
}), _$createComponent(Method, {
|
|
122
|
+
"public": true,
|
|
123
|
+
override: true,
|
|
124
|
+
returns: "bool",
|
|
125
|
+
name: "Equals",
|
|
126
|
+
parameters: [{
|
|
127
|
+
name: "obj",
|
|
128
|
+
type: "object?"
|
|
129
|
+
}],
|
|
130
|
+
expression: true,
|
|
131
|
+
children: code`obj is ${name} other && Equals(other)`
|
|
132
|
+
}), _$createComponent(Method, {
|
|
133
|
+
"public": true,
|
|
134
|
+
override: true,
|
|
135
|
+
returns: "int",
|
|
136
|
+
name: "GetHashCode",
|
|
137
|
+
expression: true,
|
|
138
|
+
children: code`${valueRk} != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(${valueRk}) : 0`
|
|
139
|
+
}), _$createComponent(Method, {
|
|
140
|
+
"public": true,
|
|
141
|
+
override: true,
|
|
142
|
+
name: "ToString",
|
|
143
|
+
returns: "string",
|
|
144
|
+
expression: true,
|
|
145
|
+
children: valueRk
|
|
146
|
+
}), _$createComponent(Method, {
|
|
147
|
+
"public": true,
|
|
148
|
+
"static": true,
|
|
149
|
+
returns: "bool",
|
|
150
|
+
get name() {
|
|
151
|
+
return namekey("operator ==", {
|
|
152
|
+
ignoreNamePolicy: true
|
|
153
|
+
});
|
|
154
|
+
},
|
|
155
|
+
parameters: [{
|
|
156
|
+
name: "left",
|
|
157
|
+
type: name
|
|
158
|
+
}, {
|
|
159
|
+
name: "right",
|
|
160
|
+
type: name
|
|
161
|
+
}],
|
|
162
|
+
expression: true,
|
|
163
|
+
children: code`left.Equals(right)`
|
|
164
|
+
}), _$createComponent(Method, {
|
|
165
|
+
"public": true,
|
|
166
|
+
"static": true,
|
|
167
|
+
returns: "bool",
|
|
168
|
+
get name() {
|
|
169
|
+
return namekey("operator !=", {
|
|
170
|
+
ignoreNamePolicy: true
|
|
171
|
+
});
|
|
172
|
+
},
|
|
173
|
+
parameters: [{
|
|
174
|
+
name: "left",
|
|
175
|
+
type: name
|
|
176
|
+
}, {
|
|
177
|
+
name: "right",
|
|
178
|
+
type: name
|
|
179
|
+
}],
|
|
180
|
+
expression: true,
|
|
181
|
+
children: code`!left.Equals(right)`
|
|
182
|
+
})];
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=extensible-enum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["code","For","List","namekey","refkey","Constructor","Field","Method","Property","StructDeclaration","useCSharpNamePolicy","declarationRefkeys","ExtensibleEnumDeclaration","props","variants","kind","getExtensibleEnumVariantsFromUnion","type","refkeys","_$createComponent","ExtensibleEnumFromVariants","_$mergeProps","name","union","kinds","Set","member","values","value","push","add","numName","toString","size","Error","valueRk","constructorRk","namepolicy","getName","readonly","interfaceTypes","children","doubleHardline","parameters","each","x","get","initializer","ignoreNameConflict","returns","expression","override","ignoreNamePolicy"],"sources":["../../../../../src/csharp/components/extensible-enum/extensible-enum.tsx"],"sourcesContent":[null],"mappings":";AAAA,SAASA,IAAI,EAAEC,GAAG,EAAEC,IAAI,EAAEC,OAAO,EAAEC,MAAM,QAAuB,gBAAgB;AAChF,SACEC,WAAW,EACXC,KAAK,EACLC,MAAM,EACNC,QAAQ,EACRC,iBAAiB,EACjBC,mBAAmB,QAEd,kBAAkB;AAEzB,SAASC,kBAAkB,QAAQ,oBAAoB;AASvD;AACA;AACA;AACA,OAAO,SAASC,yBAAyBA,CAACC,KAA2B,EAAY;EAC/E,MAAM;IAAEC,QAAQ;IAAEC;EAAK,CAAC,GAAGC,kCAAkC,CAACH,KAAK,CAACI,IAAI,CAAC;EACzE,MAAMC,OAAO,GAAGP,kBAAkB,CAACE,KAAK,CAACT,MAAM,EAAES,KAAK,CAACI,IAAI,CAAC,CAAC,CAAC,CAAC;EAC/D,OAAAE,iBAAA,CACGC,0BAA0B,EAAAC,YAAA,CACrBR,KAAK;IACTT,MAAM,EAAEc,OAAO;IAAA,IACfI,IAAIA,CAAA;MAAA,OAAET,KAAK,CAACS,IAAI,IAAIT,KAAK,CAACI,IAAI,CAACK,IAAI,IAAI,SAAS;IAAA;IAChDP,IAAI,EAAEA,IAAI;IACVD,QAAQ,EAAEA;EAAQ;AAGxB;AAEA,SAASE,kCAAkCA,CAACO,KAAY,EAGtD;EACA,MAAMT,QAAiC,GAAG,EAAE;EAC5C,MAAMU,KAAK,GAAG,IAAIC,GAAG,CAAqB,CAAC;EAC3C,KAAK,MAAMC,MAAM,IAAIH,KAAK,CAACT,QAAQ,CAACa,MAAM,CAAC,CAAC,EAAE;IAC5C,QAAQD,MAAM,CAACT,IAAI,CAACF,IAAI;MACtB,KAAK,QAAQ;QACX,MAAMO,IAAI,GAAG,OAAOI,MAAM,CAACJ,IAAI,KAAK,QAAQ,GAAGI,MAAM,CAACJ,IAAI,GAAGI,MAAM,CAACT,IAAI,CAACW,KAAK;QAC9Ed,QAAQ,CAACe,IAAI,CAAC;UAAEP,IAAI;UAAEM,KAAK,EAAEF,MAAM,CAACT,IAAI,CAACW;QAAM,CAAC,CAAC;QACjDJ,KAAK,CAACM,GAAG,CAAC,QAAQ,CAAC;QACnB;MACF,KAAK,QAAQ;QACX,MAAMC,OAAO,GACX,OAAOL,MAAM,CAACJ,IAAI,KAAK,QAAQ,GAAGI,MAAM,CAACJ,IAAI,GAAG,eAAeI,MAAM,CAACT,IAAI,CAACW,KAAK,EAAE;QACpFd,QAAQ,CAACe,IAAI,CAAC;UAAEP,IAAI,EAAES,OAAO;UAAEH,KAAK,EAAEF,MAAM,CAACT,IAAI,CAACW,KAAK,CAACI,QAAQ,CAAC;QAAE,CAAC,CAAC;QACrER,KAAK,CAACM,GAAG,CAAC,OAAO,CAAC;QAClB;MACF;QACE;MAAO;IACX;EACF;EACA,IAAIN,KAAK,CAACS,IAAI,GAAG,CAAC,EAAE;IAClB,MAAM,IAAIC,KAAK,CAAC,0DAA0D,CAAC;EAC7E;EACA,OAAO;IAAEnB,IAAI,EAAE,CAAC,GAAGS,KAAK,CAAC,CAAC,CAAC,CAAC;IAAEV;EAAS,CAAC;AAC1C;AAaA,SAASM,0BAA0BA,CAACP,KAAsC,EAAY;EACpF,MAAMsB,OAAO,GAAG/B,MAAM,CAAC,CAAC;EACxB,MAAMgC,aAAa,GAAGhC,MAAM,CAAC,CAAC;EAC9B,MAAMiC,UAAU,GAAG3B,mBAAmB,CAAC,CAAC;EACxC,MAAMY,IAAI,GAAGe,UAAU,CAACC,OAAO,CAACzB,KAAK,CAACS,IAAI,EAAE,QAAQ,CAAC;EACrD,MAAML,IAAI,GAAGJ,KAAK,CAACE,IAAI,KAAK,QAAQ,GAAG,QAAQ,GAAG,KAAK;EACvD,OAAAI,iBAAA,CACGV,iBAAiB,EAAAY,YAAA;IAChBkB,QAAQ;EAAA,GACJ1B,KAAK;IAAA,IACTS,IAAIA,CAAA;MAAA,OAAET,KAAK,CAACS,IAAI;IAAA;IAChBkB,cAAc,EAAE,CAAC,cAAclB,IAAI,GAAG,CAAC;IAAA,IAAAmB,SAAA;MAAA,OAAAtB,iBAAA,CAEtCjB,IAAI;QAACwC,cAAc;QAAA,IAAAD,SAAA;UAAA,QAAAtB,iBAAA,CACjBb,KAAK;YAAA;YAASiC,QAAQ;YAACjB,IAAI;YAASlB,MAAM,EAAE+B,OAAO;YAAElB,IAAI,EAAEA;UAAI,IAAAE,iBAAA,CAC/Dd,WAAW;YAACD,MAAM,EAAEgC,aAAa;YAAEO,UAAU,EAAE,CAAC;cAAErB,IAAI,EAAE,OAAO;cAAEL;YAAK,CAAC,CAAC;YAAA,IAAAwB,SAAA;cAAA,QACtEN,OAAO;YAAA;UAAA,IAAAhB,iBAAA,CAETlB,GAAG;YAAA,IAAC2C,IAAIA,CAAA;cAAA,OAAE/B,KAAK,CAACC,QAAQ;YAAA;YAAA2B,QAAA,EACrBI,CAAC,IAAA1B,iBAAA,CACAX,QAAQ;cAAA;cAAA;cAAA,IAGPc,IAAIA,CAAA;gBAAA,OAAEe,UAAU,CAACC,OAAO,CAACO,CAAC,CAACvB,IAAI,EAAE,aAAa,CAAC;cAAA;cAC/CL,IAAI,EAAEK,IAAI;cACVwB,GAAG;cAAA,IACHC,WAAWA,CAAA;gBAAA,OAAE/C,IAAI,OAAOoC,aAAa,IAAIvB,KAAK,CAACE,IAAI,KAAK,QAAQ,GAAG,KAAK8B,CAAC,CAACjB,KAAK,GAAG,GAAGiB,CAAC,CAACjB,KAAK,GAAG;cAAA;YAAA;UAElG,IAAAT,iBAAA,CAEFZ,MAAM;YAAA;YAAA,IAELe,IAAIA,CAAA;cAAA,OAAEnB,OAAO,CAAC,QAAQ,EAAE;gBAAE6C,kBAAkB,EAAE;cAAK,CAAC,CAAC;YAAA;YACrDL,UAAU,EAAE,CAAC;cAAErB,IAAI,EAAE,OAAO;cAAEL,IAAI,EAAEK;YAAK,CAAC,CAAC;YAC3C2B,OAAO;YACPC,UAAU;YAAA,IAAAT,SAAA;cAAA,OAET5B,KAAK,CAACE,IAAI,KAAK,QAAQ,GACpBf,IAAI,iBAAiBmC,OAAO,WAAWA,OAAO,gDAAgD,GAC9FnC,IAAI,GAAGmC,OAAO,aAAaA,OAAO,EAAE;YAAA;UAAA,IAAAhB,iBAAA,CAEzCZ,MAAM;YAAA;YAEL4C,QAAQ;YACRF,OAAO;YACP3B,IAAI;YACJqB,UAAU,EAAE,CAAC;cAAErB,IAAI,EAAE,KAAK;cAAEL,IAAI,EAAE;YAAU,CAAC,CAAC;YAC9CiC,UAAU;YAAAT,QAAA,EAETzC,IAAI,UAAUsB,IAAI;UAAyB,IAAAH,iBAAA,CAE7CZ,MAAM;YAAA;YAAQ4C,QAAQ;YAACF,OAAO;YAAO3B,IAAI;YAAe4B,UAAU;YAAAT,QAAA,EAChEzC,IAAI,GAAGmC,OAAO,oEAAoEA,OAAO;UAAO,IAAAhB,iBAAA,CAElGZ,MAAM;YAAA;YAAQ4C,QAAQ;YAAC7B,IAAI;YAAY2B,OAAO;YAAUC,UAAU;YAAAT,QAAA,EAChEN;UAAO,IAAAhB,iBAAA,CAETZ,MAAM;YAAA;YAAA;YAGL0C,OAAO;YAAA,IACP3B,IAAIA,CAAA;cAAA,OAAEnB,OAAO,CAAC,aAAa,EAAE;gBAAEiD,gBAAgB,EAAE;cAAK,CAAC,CAAC;YAAA;YACxDT,UAAU,EAAE,CACV;cAAErB,IAAI,EAAE,MAAM;cAAEL,IAAI,EAAEK;YAAK,CAAC,EAC5B;cAAEA,IAAI,EAAE,OAAO;cAAEL,IAAI,EAAEK;YAAK,CAAC,CAC9B;YACD4B,UAAU;YAAAT,QAAA,EAETzC,IAAI;UAAoB,IAAAmB,iBAAA,CAE1BZ,MAAM;YAAA;YAAA;YAGL0C,OAAO;YAAA,IACP3B,IAAIA,CAAA;cAAA,OAAEnB,OAAO,CAAC,aAAa,EAAE;gBAAEiD,gBAAgB,EAAE;cAAK,CAAC,CAAC;YAAA;YACxDT,UAAU,EAAE,CACV;cAAErB,IAAI,EAAE,MAAM;cAAEL,IAAI,EAAEK;YAAK,CAAC,EAC5B;cAAEA,IAAI,EAAE,OAAO;cAAEL,IAAI,EAAEK;YAAK,CAAC,CAC9B;YACD4B,UAAU;YAAAT,QAAA,EAETzC,IAAI;UAAqB;QAAA;MAAA;IAAA;EAAA;AAKpC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensible-enum.test.d.ts","sourceRoot":"","sources":["../../../../../src/csharp/components/extensible-enum/extensible-enum.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { createComponent as _$createComponent, createIntrinsic as _$createIntrinsic } from "@alloy-js/core/jsx-runtime";
|
|
2
|
+
import { Tester } from "#test/test-host.js";
|
|
3
|
+
import { createCSharpNamePolicy, SourceFile } from "@alloy-js/csharp";
|
|
4
|
+
import { t } from "@typespec/compiler/testing";
|
|
5
|
+
import { beforeEach, expect, it } from "vitest";
|
|
6
|
+
import { Output } from "../../../core/index.js";
|
|
7
|
+
import { TypeExpression } from "../type-expression.js";
|
|
8
|
+
import { ExtensibleEnumDeclaration } from "./extensible-enum.js";
|
|
9
|
+
let tester;
|
|
10
|
+
beforeEach(async () => {
|
|
11
|
+
tester = await Tester.createInstance();
|
|
12
|
+
});
|
|
13
|
+
function Wrapper(props) {
|
|
14
|
+
const policy = createCSharpNamePolicy();
|
|
15
|
+
return _$createComponent(Output, {
|
|
16
|
+
get program() {
|
|
17
|
+
return tester.program;
|
|
18
|
+
},
|
|
19
|
+
namePolicy: policy,
|
|
20
|
+
get children() {
|
|
21
|
+
return _$createComponent(SourceFile, {
|
|
22
|
+
path: "test.cs",
|
|
23
|
+
get children() {
|
|
24
|
+
return props.children;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
it("pass struct properties down", async () => {
|
|
31
|
+
const {
|
|
32
|
+
TestEnum
|
|
33
|
+
} = await tester.compile(t.code`
|
|
34
|
+
union ${t.union("TestEnum")} {
|
|
35
|
+
string,
|
|
36
|
+
a: "a",
|
|
37
|
+
}
|
|
38
|
+
`);
|
|
39
|
+
expect(_$createComponent(Wrapper, {
|
|
40
|
+
get children() {
|
|
41
|
+
return _$createComponent(ExtensibleEnumDeclaration, {
|
|
42
|
+
"public": true,
|
|
43
|
+
readonly: false,
|
|
44
|
+
partial: true,
|
|
45
|
+
type: TestEnum
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
})).toRenderTo(`
|
|
49
|
+
public partial struct TestEnum : IEquatable<TestEnum>
|
|
50
|
+
{
|
|
51
|
+
private readonly string _value;
|
|
52
|
+
|
|
53
|
+
TestEnum(string value)
|
|
54
|
+
{
|
|
55
|
+
_value = value;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public static TestEnum A { get; } = new TestEnum(@"a");
|
|
59
|
+
|
|
60
|
+
public bool Equals(TestEnum other) =>
|
|
61
|
+
string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase);
|
|
62
|
+
|
|
63
|
+
public override bool Equals(object? obj) => obj is TestEnum other && Equals(other);
|
|
64
|
+
|
|
65
|
+
public override int GetHashCode() =>
|
|
66
|
+
_value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0;
|
|
67
|
+
|
|
68
|
+
public override string ToString() => _value;
|
|
69
|
+
|
|
70
|
+
public static bool operator ==(TestEnum left, TestEnum right) => left.Equals(right);
|
|
71
|
+
|
|
72
|
+
public static bool operator !=(TestEnum left, TestEnum right) => !left.Equals(right);
|
|
73
|
+
}
|
|
74
|
+
`);
|
|
75
|
+
});
|
|
76
|
+
it("renders union with string variants", async () => {
|
|
77
|
+
const {
|
|
78
|
+
TestEnum
|
|
79
|
+
} = await tester.compile(t.code`
|
|
80
|
+
union ${t.union("TestEnum")} {
|
|
81
|
+
string,
|
|
82
|
+
up: "up",
|
|
83
|
+
down: "down",
|
|
84
|
+
}
|
|
85
|
+
`);
|
|
86
|
+
expect(_$createComponent(Wrapper, {
|
|
87
|
+
get children() {
|
|
88
|
+
return _$createComponent(ExtensibleEnumDeclaration, {
|
|
89
|
+
type: TestEnum
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
})).toRenderTo(`
|
|
93
|
+
readonly struct TestEnum : IEquatable<TestEnum>
|
|
94
|
+
{
|
|
95
|
+
private readonly string _value;
|
|
96
|
+
|
|
97
|
+
TestEnum(string value)
|
|
98
|
+
{
|
|
99
|
+
_value = value;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public static TestEnum Up { get; } = new TestEnum(@"up");
|
|
103
|
+
public static TestEnum Down { get; } = new TestEnum(@"down");
|
|
104
|
+
|
|
105
|
+
public bool Equals(TestEnum other) =>
|
|
106
|
+
string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase);
|
|
107
|
+
|
|
108
|
+
public override bool Equals(object? obj) => obj is TestEnum other && Equals(other);
|
|
109
|
+
|
|
110
|
+
public override int GetHashCode() =>
|
|
111
|
+
_value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0;
|
|
112
|
+
|
|
113
|
+
public override string ToString() => _value;
|
|
114
|
+
|
|
115
|
+
public static bool operator ==(TestEnum left, TestEnum right) => left.Equals(right);
|
|
116
|
+
|
|
117
|
+
public static bool operator !=(TestEnum left, TestEnum right) => !left.Equals(right);
|
|
118
|
+
}
|
|
119
|
+
`);
|
|
120
|
+
});
|
|
121
|
+
it("renders string-based enums with case-insensitive equality", async () => {
|
|
122
|
+
const {
|
|
123
|
+
WidgetColor
|
|
124
|
+
} = await tester.compile(t.code`
|
|
125
|
+
union ${t.union("WidgetColor")} {
|
|
126
|
+
Default: "default";
|
|
127
|
+
"blue-value": "blue";
|
|
128
|
+
"camelCase";
|
|
129
|
+
}
|
|
130
|
+
`);
|
|
131
|
+
const tree = _$createComponent(Wrapper, {
|
|
132
|
+
get children() {
|
|
133
|
+
return _$createComponent(ExtensibleEnumDeclaration, {
|
|
134
|
+
type: WidgetColor
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
await expect(tree).toRenderToAsync(`
|
|
139
|
+
readonly struct WidgetColor : IEquatable<WidgetColor>
|
|
140
|
+
{
|
|
141
|
+
private readonly string _value;
|
|
142
|
+
|
|
143
|
+
WidgetColor(string value)
|
|
144
|
+
{
|
|
145
|
+
_value = value;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
public static WidgetColor Default { get; } = new WidgetColor(@"default");
|
|
149
|
+
public static WidgetColor BlueValue { get; } = new WidgetColor(@"blue");
|
|
150
|
+
public static WidgetColor CamelCase { get; } = new WidgetColor(@"camelCase");
|
|
151
|
+
|
|
152
|
+
public bool Equals(WidgetColor other) =>
|
|
153
|
+
string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase);
|
|
154
|
+
|
|
155
|
+
public override bool Equals(object? obj) => obj is WidgetColor other && Equals(other);
|
|
156
|
+
|
|
157
|
+
public override int GetHashCode() =>
|
|
158
|
+
_value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0;
|
|
159
|
+
|
|
160
|
+
public override string ToString() => _value;
|
|
161
|
+
|
|
162
|
+
public static bool operator ==(WidgetColor left, WidgetColor right) => left.Equals(right);
|
|
163
|
+
|
|
164
|
+
public static bool operator !=(WidgetColor left, WidgetColor right) => !left.Equals(right);
|
|
165
|
+
}
|
|
166
|
+
`);
|
|
167
|
+
});
|
|
168
|
+
it("renders number-based enums with integer equality", async () => {
|
|
169
|
+
const {
|
|
170
|
+
WidgetSize
|
|
171
|
+
} = await tester.compile(t.code`
|
|
172
|
+
union ${t.union("WidgetSize")} {
|
|
173
|
+
Small: 1;
|
|
174
|
+
2;
|
|
175
|
+
}
|
|
176
|
+
`);
|
|
177
|
+
const tree = _$createComponent(Wrapper, {
|
|
178
|
+
get children() {
|
|
179
|
+
return _$createComponent(ExtensibleEnumDeclaration, {
|
|
180
|
+
type: WidgetSize
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
await expect(tree).toRenderToAsync(`
|
|
185
|
+
readonly struct WidgetSize : IEquatable<WidgetSize>
|
|
186
|
+
{
|
|
187
|
+
private readonly int _value;
|
|
188
|
+
|
|
189
|
+
WidgetSize(int value)
|
|
190
|
+
{
|
|
191
|
+
_value = value;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
public static WidgetSize Small { get; } = new WidgetSize(1);
|
|
195
|
+
public static WidgetSize NumberValue_2 { get; } = new WidgetSize(2);
|
|
196
|
+
|
|
197
|
+
public bool Equals(WidgetSize other) => _value == other._value;
|
|
198
|
+
|
|
199
|
+
public override bool Equals(object? obj) => obj is WidgetSize other && Equals(other);
|
|
200
|
+
|
|
201
|
+
public override int GetHashCode() =>
|
|
202
|
+
_value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0;
|
|
203
|
+
|
|
204
|
+
public override string ToString() => _value;
|
|
205
|
+
|
|
206
|
+
public static bool operator ==(WidgetSize left, WidgetSize right) => left.Equals(right);
|
|
207
|
+
|
|
208
|
+
public static bool operator !=(WidgetSize left, WidgetSize right) => !left.Equals(right);
|
|
209
|
+
}
|
|
210
|
+
`);
|
|
211
|
+
});
|
|
212
|
+
it("is referencable in TypeExpression by default", async () => {
|
|
213
|
+
const {
|
|
214
|
+
TestEnum
|
|
215
|
+
} = await tester.compile(t.code`
|
|
216
|
+
union ${t.union("TestEnum")} {
|
|
217
|
+
string,
|
|
218
|
+
a: "a",
|
|
219
|
+
}
|
|
220
|
+
`);
|
|
221
|
+
expect(_$createComponent(Wrapper, {
|
|
222
|
+
get children() {
|
|
223
|
+
return ["ref: ", _$createComponent(TypeExpression, {
|
|
224
|
+
type: TestEnum
|
|
225
|
+
}), _$createIntrinsic("hbr", {}), _$createComponent(ExtensibleEnumDeclaration, {
|
|
226
|
+
type: TestEnum
|
|
227
|
+
})];
|
|
228
|
+
}
|
|
229
|
+
})).toRenderTo(`
|
|
230
|
+
ref: TestEnum
|
|
231
|
+
readonly struct TestEnum : IEquatable<TestEnum>
|
|
232
|
+
{
|
|
233
|
+
private readonly string _value;
|
|
234
|
+
|
|
235
|
+
TestEnum(string value)
|
|
236
|
+
{
|
|
237
|
+
_value = value;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
public static TestEnum A { get; } = new TestEnum(@"a");
|
|
241
|
+
|
|
242
|
+
public bool Equals(TestEnum other) =>
|
|
243
|
+
string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase);
|
|
244
|
+
|
|
245
|
+
public override bool Equals(object? obj) => obj is TestEnum other && Equals(other);
|
|
246
|
+
|
|
247
|
+
public override int GetHashCode() =>
|
|
248
|
+
_value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0;
|
|
249
|
+
|
|
250
|
+
public override string ToString() => _value;
|
|
251
|
+
|
|
252
|
+
public static bool operator ==(TestEnum left, TestEnum right) => left.Equals(right);
|
|
253
|
+
|
|
254
|
+
public static bool operator !=(TestEnum left, TestEnum right) => !left.Equals(right);
|
|
255
|
+
}
|
|
256
|
+
`);
|
|
257
|
+
});
|
|
258
|
+
//# sourceMappingURL=extensible-enum.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Tester","createCSharpNamePolicy","SourceFile","t","beforeEach","expect","it","Output","TypeExpression","ExtensibleEnumDeclaration","tester","createInstance","Wrapper","props","policy","_$createComponent","program","namePolicy","children","path","TestEnum","compile","code","union","readonly","partial","type","toRenderTo","WidgetColor","tree","toRenderToAsync","WidgetSize","_$createIntrinsic"],"sources":["../../../../../src/csharp/components/extensible-enum/extensible-enum.test.tsx"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typespec/emitter-framework",
|
|
3
|
-
"version": "0.17.0-dev.
|
|
3
|
+
"version": "0.17.0-dev.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"@alloy-js/csharp": "^0.22.0",
|
|
49
49
|
"@alloy-js/python": "^0.3.0",
|
|
50
50
|
"@alloy-js/typescript": "^0.22.0",
|
|
51
|
-
"@typespec/compiler": "^1.9.0"
|
|
51
|
+
"@typespec/compiler": "^1.9.0 || >= 1.10.0-dev.7"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@alloy-js/cli": "^0.22.0",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"@alloy-js/python": "^0.3.0",
|
|
57
57
|
"@alloy-js/rollup-plugin": "^0.1.0",
|
|
58
58
|
"@alloy-js/typescript": "^0.22.0",
|
|
59
|
-
"@typespec/compiler": "^1.9.0",
|
|
59
|
+
"@typespec/compiler": "^1.9.0 || >= 1.10.0-dev.7",
|
|
60
60
|
"concurrently": "^9.1.2",
|
|
61
61
|
"pathe": "^2.0.3",
|
|
62
62
|
"prettier": "~3.8.0",
|
|
@@ -65,11 +65,10 @@
|
|
|
65
65
|
"tree-sitter-javascript": "^0.25.0",
|
|
66
66
|
"tree-sitter-python": "^0.25.0",
|
|
67
67
|
"tree-sitter-typescript": "^0.23.0",
|
|
68
|
-
"typescript": "~5.9.
|
|
69
|
-
"vitest": "^4.0.
|
|
68
|
+
"typescript": "~5.9.3",
|
|
69
|
+
"vitest": "^4.0.18",
|
|
70
70
|
"web-tree-sitter": "^0.26.3"
|
|
71
71
|
},
|
|
72
|
-
"dependencies": {},
|
|
73
72
|
"scripts": {
|
|
74
73
|
"build": "alloy build",
|
|
75
74
|
"clean": "rimraf ./dist",
|
package/package.json.bak
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typespec/emitter-framework",
|
|
3
|
-
"version": "0.17.0-dev.
|
|
3
|
+
"version": "0.17.0-dev.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"@alloy-js/csharp": "^0.22.0",
|
|
67
67
|
"@alloy-js/python": "^0.3.0",
|
|
68
68
|
"@alloy-js/typescript": "^0.22.0",
|
|
69
|
-
"@typespec/compiler": "^1.9.0"
|
|
69
|
+
"@typespec/compiler": "^1.9.0 || >= 1.10.0-dev.7"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@alloy-js/cli": "^0.22.0",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"@alloy-js/python": "^0.3.0",
|
|
75
75
|
"@alloy-js/rollup-plugin": "^0.1.0",
|
|
76
76
|
"@alloy-js/typescript": "^0.22.0",
|
|
77
|
-
"@typespec/compiler": "^1.9.0",
|
|
77
|
+
"@typespec/compiler": "^1.9.0 || >= 1.10.0-dev.7",
|
|
78
78
|
"concurrently": "^9.1.2",
|
|
79
79
|
"pathe": "^2.0.3",
|
|
80
80
|
"prettier": "~3.8.0",
|
|
@@ -83,9 +83,8 @@
|
|
|
83
83
|
"tree-sitter-javascript": "^0.25.0",
|
|
84
84
|
"tree-sitter-python": "^0.25.0",
|
|
85
85
|
"tree-sitter-typescript": "^0.23.0",
|
|
86
|
-
"typescript": "~5.9.
|
|
87
|
-
"vitest": "^4.0.
|
|
86
|
+
"typescript": "~5.9.3",
|
|
87
|
+
"vitest": "^4.0.18",
|
|
88
88
|
"web-tree-sitter": "^0.26.3"
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { For, type Children } from "@alloy-js/core";
|
|
2
2
|
import * as cs from "@alloy-js/csharp";
|
|
3
|
-
import {
|
|
4
|
-
import { isVoidType
|
|
3
|
+
import type { Interface, Model } from "@typespec/compiler";
|
|
4
|
+
import { isVoidType } from "@typespec/compiler";
|
|
5
5
|
import { useTsp } from "../../../core/index.js";
|
|
6
6
|
import { Property } from "../property/property.jsx";
|
|
7
7
|
import { TypeExpression } from "../type-expression.jsx";
|
|
@@ -77,7 +77,7 @@ function ClassMethods(props: ClassMethodsProps): Children {
|
|
|
77
77
|
const abstractMethods: Children = [];
|
|
78
78
|
for (const [name, method] of props.type.operations) {
|
|
79
79
|
abstractMethods.push(
|
|
80
|
-
<Method
|
|
80
|
+
<cs.Method
|
|
81
81
|
name={namePolicy.getName(name, "class-method")}
|
|
82
82
|
abstract
|
|
83
83
|
parameters={[...method.parameters.properties.entries()].map(([name, prop]) => {
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { Tester } from "#test/test-host.js";
|
|
2
|
+
import { type Children } from "@alloy-js/core";
|
|
3
|
+
import { createCSharpNamePolicy, SourceFile } from "@alloy-js/csharp";
|
|
4
|
+
import { t, type TesterInstance } from "@typespec/compiler/testing";
|
|
5
|
+
import { beforeEach, expect, it } from "vitest";
|
|
6
|
+
import { Output } from "../../../core/index.js";
|
|
7
|
+
import { TypeExpression } from "../type-expression.jsx";
|
|
8
|
+
import { ExtensibleEnumDeclaration } from "./extensible-enum.jsx";
|
|
9
|
+
|
|
10
|
+
let tester: TesterInstance;
|
|
11
|
+
|
|
12
|
+
beforeEach(async () => {
|
|
13
|
+
tester = await Tester.createInstance();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
function Wrapper(props: { children: Children }) {
|
|
17
|
+
const policy = createCSharpNamePolicy();
|
|
18
|
+
return (
|
|
19
|
+
<Output program={tester.program} namePolicy={policy}>
|
|
20
|
+
<SourceFile path="test.cs">{props.children}</SourceFile>
|
|
21
|
+
</Output>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
it("pass struct properties down", async () => {
|
|
26
|
+
const { TestEnum } = await tester.compile(t.code`
|
|
27
|
+
union ${t.union("TestEnum")} {
|
|
28
|
+
string,
|
|
29
|
+
a: "a",
|
|
30
|
+
}
|
|
31
|
+
`);
|
|
32
|
+
|
|
33
|
+
expect(
|
|
34
|
+
<Wrapper>
|
|
35
|
+
<ExtensibleEnumDeclaration public readonly={false} partial type={TestEnum} />
|
|
36
|
+
</Wrapper>,
|
|
37
|
+
).toRenderTo(`
|
|
38
|
+
public partial struct TestEnum : IEquatable<TestEnum>
|
|
39
|
+
{
|
|
40
|
+
private readonly string _value;
|
|
41
|
+
|
|
42
|
+
TestEnum(string value)
|
|
43
|
+
{
|
|
44
|
+
_value = value;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public static TestEnum A { get; } = new TestEnum(@"a");
|
|
48
|
+
|
|
49
|
+
public bool Equals(TestEnum other) =>
|
|
50
|
+
string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase);
|
|
51
|
+
|
|
52
|
+
public override bool Equals(object? obj) => obj is TestEnum other && Equals(other);
|
|
53
|
+
|
|
54
|
+
public override int GetHashCode() =>
|
|
55
|
+
_value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0;
|
|
56
|
+
|
|
57
|
+
public override string ToString() => _value;
|
|
58
|
+
|
|
59
|
+
public static bool operator ==(TestEnum left, TestEnum right) => left.Equals(right);
|
|
60
|
+
|
|
61
|
+
public static bool operator !=(TestEnum left, TestEnum right) => !left.Equals(right);
|
|
62
|
+
}
|
|
63
|
+
`);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("renders union with string variants", async () => {
|
|
67
|
+
const { TestEnum } = await tester.compile(t.code`
|
|
68
|
+
union ${t.union("TestEnum")} {
|
|
69
|
+
string,
|
|
70
|
+
up: "up",
|
|
71
|
+
down: "down",
|
|
72
|
+
}
|
|
73
|
+
`);
|
|
74
|
+
|
|
75
|
+
expect(
|
|
76
|
+
<Wrapper>
|
|
77
|
+
<ExtensibleEnumDeclaration type={TestEnum} />
|
|
78
|
+
</Wrapper>,
|
|
79
|
+
).toRenderTo(`
|
|
80
|
+
readonly struct TestEnum : IEquatable<TestEnum>
|
|
81
|
+
{
|
|
82
|
+
private readonly string _value;
|
|
83
|
+
|
|
84
|
+
TestEnum(string value)
|
|
85
|
+
{
|
|
86
|
+
_value = value;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public static TestEnum Up { get; } = new TestEnum(@"up");
|
|
90
|
+
public static TestEnum Down { get; } = new TestEnum(@"down");
|
|
91
|
+
|
|
92
|
+
public bool Equals(TestEnum other) =>
|
|
93
|
+
string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase);
|
|
94
|
+
|
|
95
|
+
public override bool Equals(object? obj) => obj is TestEnum other && Equals(other);
|
|
96
|
+
|
|
97
|
+
public override int GetHashCode() =>
|
|
98
|
+
_value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0;
|
|
99
|
+
|
|
100
|
+
public override string ToString() => _value;
|
|
101
|
+
|
|
102
|
+
public static bool operator ==(TestEnum left, TestEnum right) => left.Equals(right);
|
|
103
|
+
|
|
104
|
+
public static bool operator !=(TestEnum left, TestEnum right) => !left.Equals(right);
|
|
105
|
+
}
|
|
106
|
+
`);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("renders string-based enums with case-insensitive equality", async () => {
|
|
110
|
+
const { WidgetColor } = await tester.compile(t.code`
|
|
111
|
+
union ${t.union("WidgetColor")} {
|
|
112
|
+
Default: "default";
|
|
113
|
+
"blue-value": "blue";
|
|
114
|
+
"camelCase";
|
|
115
|
+
}
|
|
116
|
+
`);
|
|
117
|
+
|
|
118
|
+
const tree = (
|
|
119
|
+
<Wrapper>
|
|
120
|
+
<ExtensibleEnumDeclaration type={WidgetColor} />
|
|
121
|
+
</Wrapper>
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
await expect(tree).toRenderToAsync(`
|
|
125
|
+
readonly struct WidgetColor : IEquatable<WidgetColor>
|
|
126
|
+
{
|
|
127
|
+
private readonly string _value;
|
|
128
|
+
|
|
129
|
+
WidgetColor(string value)
|
|
130
|
+
{
|
|
131
|
+
_value = value;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
public static WidgetColor Default { get; } = new WidgetColor(@"default");
|
|
135
|
+
public static WidgetColor BlueValue { get; } = new WidgetColor(@"blue");
|
|
136
|
+
public static WidgetColor CamelCase { get; } = new WidgetColor(@"camelCase");
|
|
137
|
+
|
|
138
|
+
public bool Equals(WidgetColor other) =>
|
|
139
|
+
string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase);
|
|
140
|
+
|
|
141
|
+
public override bool Equals(object? obj) => obj is WidgetColor other && Equals(other);
|
|
142
|
+
|
|
143
|
+
public override int GetHashCode() =>
|
|
144
|
+
_value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0;
|
|
145
|
+
|
|
146
|
+
public override string ToString() => _value;
|
|
147
|
+
|
|
148
|
+
public static bool operator ==(WidgetColor left, WidgetColor right) => left.Equals(right);
|
|
149
|
+
|
|
150
|
+
public static bool operator !=(WidgetColor left, WidgetColor right) => !left.Equals(right);
|
|
151
|
+
}
|
|
152
|
+
`);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it("renders number-based enums with integer equality", async () => {
|
|
156
|
+
const { WidgetSize } = await tester.compile(t.code`
|
|
157
|
+
union ${t.union("WidgetSize")} {
|
|
158
|
+
Small: 1;
|
|
159
|
+
2;
|
|
160
|
+
}
|
|
161
|
+
`);
|
|
162
|
+
|
|
163
|
+
const tree = (
|
|
164
|
+
<Wrapper>
|
|
165
|
+
<ExtensibleEnumDeclaration type={WidgetSize} />
|
|
166
|
+
</Wrapper>
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
await expect(tree).toRenderToAsync(`
|
|
170
|
+
readonly struct WidgetSize : IEquatable<WidgetSize>
|
|
171
|
+
{
|
|
172
|
+
private readonly int _value;
|
|
173
|
+
|
|
174
|
+
WidgetSize(int value)
|
|
175
|
+
{
|
|
176
|
+
_value = value;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
public static WidgetSize Small { get; } = new WidgetSize(1);
|
|
180
|
+
public static WidgetSize NumberValue_2 { get; } = new WidgetSize(2);
|
|
181
|
+
|
|
182
|
+
public bool Equals(WidgetSize other) => _value == other._value;
|
|
183
|
+
|
|
184
|
+
public override bool Equals(object? obj) => obj is WidgetSize other && Equals(other);
|
|
185
|
+
|
|
186
|
+
public override int GetHashCode() =>
|
|
187
|
+
_value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0;
|
|
188
|
+
|
|
189
|
+
public override string ToString() => _value;
|
|
190
|
+
|
|
191
|
+
public static bool operator ==(WidgetSize left, WidgetSize right) => left.Equals(right);
|
|
192
|
+
|
|
193
|
+
public static bool operator !=(WidgetSize left, WidgetSize right) => !left.Equals(right);
|
|
194
|
+
}
|
|
195
|
+
`);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it("is referencable in TypeExpression by default", async () => {
|
|
199
|
+
const { TestEnum } = await tester.compile(t.code`
|
|
200
|
+
union ${t.union("TestEnum")} {
|
|
201
|
+
string,
|
|
202
|
+
a: "a",
|
|
203
|
+
}
|
|
204
|
+
`);
|
|
205
|
+
|
|
206
|
+
expect(
|
|
207
|
+
<Wrapper>
|
|
208
|
+
ref: <TypeExpression type={TestEnum} />
|
|
209
|
+
<hbr />
|
|
210
|
+
<ExtensibleEnumDeclaration type={TestEnum} />
|
|
211
|
+
</Wrapper>,
|
|
212
|
+
).toRenderTo(`
|
|
213
|
+
ref: TestEnum
|
|
214
|
+
readonly struct TestEnum : IEquatable<TestEnum>
|
|
215
|
+
{
|
|
216
|
+
private readonly string _value;
|
|
217
|
+
|
|
218
|
+
TestEnum(string value)
|
|
219
|
+
{
|
|
220
|
+
_value = value;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
public static TestEnum A { get; } = new TestEnum(@"a");
|
|
224
|
+
|
|
225
|
+
public bool Equals(TestEnum other) =>
|
|
226
|
+
string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase);
|
|
227
|
+
|
|
228
|
+
public override bool Equals(object? obj) => obj is TestEnum other && Equals(other);
|
|
229
|
+
|
|
230
|
+
public override int GetHashCode() =>
|
|
231
|
+
_value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0;
|
|
232
|
+
|
|
233
|
+
public override string ToString() => _value;
|
|
234
|
+
|
|
235
|
+
public static bool operator ==(TestEnum left, TestEnum right) => left.Equals(right);
|
|
236
|
+
|
|
237
|
+
public static bool operator !=(TestEnum left, TestEnum right) => !left.Equals(right);
|
|
238
|
+
}
|
|
239
|
+
`);
|
|
240
|
+
});
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { code, For, List, namekey, refkey, type Children } from "@alloy-js/core";
|
|
2
|
+
import {
|
|
3
|
+
Constructor,
|
|
4
|
+
Field,
|
|
5
|
+
Method,
|
|
6
|
+
Property,
|
|
7
|
+
StructDeclaration,
|
|
8
|
+
useCSharpNamePolicy,
|
|
9
|
+
type StructDeclarationProps,
|
|
10
|
+
} from "@alloy-js/csharp";
|
|
11
|
+
import type { Union } from "@typespec/compiler";
|
|
12
|
+
import { declarationRefkeys } from "../utils/refkey.js";
|
|
13
|
+
|
|
14
|
+
export interface EnumDeclarationProps extends Omit<StructDeclarationProps, "name"> {
|
|
15
|
+
/** Union that should be rendered as an extensible enum struct */
|
|
16
|
+
type: Union;
|
|
17
|
+
/** Name override */
|
|
18
|
+
name?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Render a struct designed to represent an extensible enum based on a TypeSpec union.
|
|
23
|
+
*/
|
|
24
|
+
export function ExtensibleEnumDeclaration(props: EnumDeclarationProps): Children {
|
|
25
|
+
const { variants, kind } = getExtensibleEnumVariantsFromUnion(props.type);
|
|
26
|
+
const refkeys = declarationRefkeys(props.refkey, props.type)[0];
|
|
27
|
+
return (
|
|
28
|
+
<ExtensibleEnumFromVariants
|
|
29
|
+
{...props}
|
|
30
|
+
refkey={refkeys}
|
|
31
|
+
name={props.name ?? props.type.name ?? "Unnamed"}
|
|
32
|
+
kind={kind}
|
|
33
|
+
variants={variants}
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getExtensibleEnumVariantsFromUnion(union: Union): {
|
|
39
|
+
kind: "string" | "int32";
|
|
40
|
+
variants: ExtensibleEnumVariant[];
|
|
41
|
+
} {
|
|
42
|
+
const variants: ExtensibleEnumVariant[] = [];
|
|
43
|
+
const kinds = new Set<"string" | "int32">();
|
|
44
|
+
for (const member of union.variants.values()) {
|
|
45
|
+
switch (member.type.kind) {
|
|
46
|
+
case "String":
|
|
47
|
+
const name = typeof member.name === "string" ? member.name : member.type.value;
|
|
48
|
+
variants.push({ name, value: member.type.value });
|
|
49
|
+
kinds.add("string");
|
|
50
|
+
break;
|
|
51
|
+
case "Number":
|
|
52
|
+
const numName =
|
|
53
|
+
typeof member.name === "string" ? member.name : `NumberValue_${member.type.value}`;
|
|
54
|
+
variants.push({ name: numName, value: member.type.value.toString() });
|
|
55
|
+
kinds.add("int32");
|
|
56
|
+
break;
|
|
57
|
+
default:
|
|
58
|
+
break; // Ignore other types
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (kinds.size > 1) {
|
|
62
|
+
throw new Error("ExtensibleEnumUnion cannot have mixed kinds of variants.");
|
|
63
|
+
}
|
|
64
|
+
return { kind: [...kinds][0], variants };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
interface ExtensibleEnumVariant {
|
|
68
|
+
name: string;
|
|
69
|
+
value: string | number;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
interface ExtensibleEnumFromVariantsProps extends Omit<StructDeclarationProps, "name"> {
|
|
73
|
+
name: string;
|
|
74
|
+
kind: "string" | "int32";
|
|
75
|
+
variants: ExtensibleEnumVariant[];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function ExtensibleEnumFromVariants(props: ExtensibleEnumFromVariantsProps): Children {
|
|
79
|
+
const valueRk = refkey();
|
|
80
|
+
const constructorRk = refkey();
|
|
81
|
+
const namepolicy = useCSharpNamePolicy();
|
|
82
|
+
const name = namepolicy.getName(props.name, "struct");
|
|
83
|
+
const type = props.kind === "string" ? "string" : "int";
|
|
84
|
+
return (
|
|
85
|
+
<StructDeclaration
|
|
86
|
+
readonly // We want this readonly by default
|
|
87
|
+
{...props}
|
|
88
|
+
name={props.name}
|
|
89
|
+
interfaceTypes={[`IEquatable<${name}>`]}
|
|
90
|
+
>
|
|
91
|
+
<List doubleHardline>
|
|
92
|
+
<Field private readonly name="value" refkey={valueRk} type={type} />
|
|
93
|
+
<Constructor refkey={constructorRk} parameters={[{ name: "value", type }]}>
|
|
94
|
+
{valueRk} = value;
|
|
95
|
+
</Constructor>
|
|
96
|
+
<For each={props.variants}>
|
|
97
|
+
{(x) => (
|
|
98
|
+
<Property
|
|
99
|
+
public
|
|
100
|
+
static
|
|
101
|
+
name={namepolicy.getName(x.name, "enum-member")}
|
|
102
|
+
type={name}
|
|
103
|
+
get
|
|
104
|
+
initializer={code`new ${constructorRk}(${props.kind === "string" ? `@"${x.value}"` : x.value})`}
|
|
105
|
+
/>
|
|
106
|
+
)}
|
|
107
|
+
</For>
|
|
108
|
+
<Method
|
|
109
|
+
public
|
|
110
|
+
name={namekey("Equals", { ignoreNameConflict: true })}
|
|
111
|
+
parameters={[{ name: "other", type: name }]}
|
|
112
|
+
returns="bool"
|
|
113
|
+
expression
|
|
114
|
+
>
|
|
115
|
+
{props.kind === "string"
|
|
116
|
+
? code`string.Equals(${valueRk}, other.${valueRk}, StringComparison.InvariantCultureIgnoreCase)`
|
|
117
|
+
: code`${valueRk} == other.${valueRk}`}
|
|
118
|
+
</Method>
|
|
119
|
+
<Method
|
|
120
|
+
public
|
|
121
|
+
override
|
|
122
|
+
returns="bool"
|
|
123
|
+
name="Equals"
|
|
124
|
+
parameters={[{ name: "obj", type: "object?" }]}
|
|
125
|
+
expression
|
|
126
|
+
>
|
|
127
|
+
{code`obj is ${name} other && Equals(other)`}
|
|
128
|
+
</Method>
|
|
129
|
+
<Method public override returns="int" name="GetHashCode" expression>
|
|
130
|
+
{code`${valueRk} != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(${valueRk}) : 0`}
|
|
131
|
+
</Method>
|
|
132
|
+
<Method public override name="ToString" returns="string" expression>
|
|
133
|
+
{valueRk}
|
|
134
|
+
</Method>
|
|
135
|
+
<Method
|
|
136
|
+
public
|
|
137
|
+
static
|
|
138
|
+
returns="bool"
|
|
139
|
+
name={namekey("operator ==", { ignoreNamePolicy: true })}
|
|
140
|
+
parameters={[
|
|
141
|
+
{ name: "left", type: name },
|
|
142
|
+
{ name: "right", type: name },
|
|
143
|
+
]}
|
|
144
|
+
expression
|
|
145
|
+
>
|
|
146
|
+
{code`left.Equals(right)`}
|
|
147
|
+
</Method>
|
|
148
|
+
<Method
|
|
149
|
+
public
|
|
150
|
+
static
|
|
151
|
+
returns="bool"
|
|
152
|
+
name={namekey("operator !=", { ignoreNamePolicy: true })}
|
|
153
|
+
parameters={[
|
|
154
|
+
{ name: "left", type: name },
|
|
155
|
+
{ name: "right", type: name },
|
|
156
|
+
]}
|
|
157
|
+
expression
|
|
158
|
+
>
|
|
159
|
+
{code`!left.Equals(right)`}
|
|
160
|
+
</Method>
|
|
161
|
+
</List>
|
|
162
|
+
</StructDeclaration>
|
|
163
|
+
);
|
|
164
|
+
}
|