@typespec/emitter-framework 0.9.0-dev.1 → 0.9.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.
Files changed (41) hide show
  1. package/dist/src/csharp/components/class-declaration.d.ts +9 -0
  2. package/dist/src/csharp/components/class-declaration.d.ts.map +1 -0
  3. package/dist/src/csharp/components/class-declaration.js +97 -0
  4. package/dist/src/csharp/components/enum-declaration.d.ts +9 -0
  5. package/dist/src/csharp/components/enum-declaration.d.ts.map +1 -0
  6. package/dist/src/csharp/components/enum-declaration.js +52 -0
  7. package/dist/src/csharp/components/index.d.ts +3 -0
  8. package/dist/src/csharp/components/index.d.ts.map +1 -0
  9. package/dist/src/csharp/components/index.js +2 -0
  10. package/dist/src/csharp/components/type-expression.d.ts +11 -0
  11. package/dist/src/csharp/components/type-expression.d.ts.map +1 -0
  12. package/dist/src/csharp/components/type-expression.js +129 -0
  13. package/dist/src/csharp/components/utils/refkey.d.ts +23 -0
  14. package/dist/src/csharp/components/utils/refkey.d.ts.map +1 -0
  15. package/dist/src/csharp/components/utils/refkey.js +35 -0
  16. package/dist/src/csharp/index.d.ts +2 -0
  17. package/dist/src/csharp/index.d.ts.map +1 -0
  18. package/dist/src/csharp/index.js +1 -0
  19. package/dist/test/csharp/components/class-declaration.test.d.ts +2 -0
  20. package/dist/test/csharp/components/class-declaration.test.d.ts.map +1 -0
  21. package/dist/test/csharp/components/class-declaration.test.js +421 -0
  22. package/dist/test/csharp/components/enum-declaration.test.d.ts +2 -0
  23. package/dist/test/csharp/components/enum-declaration.test.d.ts.map +1 -0
  24. package/dist/test/csharp/components/enum-declaration.test.js +355 -0
  25. package/dist/test/csharp/test-host.d.ts +11 -0
  26. package/dist/test/csharp/test-host.d.ts.map +1 -0
  27. package/dist/test/csharp/test-host.js +32 -0
  28. package/dist/test/csharp/utils.d.ts +3 -0
  29. package/dist/test/csharp/utils.d.ts.map +1 -0
  30. package/dist/test/csharp/utils.js +6 -0
  31. package/package.json +2 -1
  32. package/src/csharp/components/class-declaration.tsx +87 -0
  33. package/src/csharp/components/enum-declaration.tsx +48 -0
  34. package/src/csharp/components/index.ts +2 -0
  35. package/src/csharp/components/type-expression.tsx +112 -0
  36. package/src/csharp/components/utils/refkey.ts +36 -0
  37. package/src/csharp/index.ts +1 -0
  38. package/test/csharp/components/class-declaration.test.tsx +344 -0
  39. package/test/csharp/components/enum-declaration.test.tsx +296 -0
  40. package/test/csharp/test-host.ts +42 -0
  41. package/test/csharp/utils.ts +8 -0
@@ -0,0 +1,9 @@
1
+ import * as ay from "@alloy-js/core";
2
+ import * as cs from "@alloy-js/csharp";
3
+ import { Interface, Model } from "@typespec/compiler";
4
+ export interface ClassDeclarationProps extends Omit<cs.ClassProps, "name"> {
5
+ name?: string;
6
+ type: Model | Interface;
7
+ }
8
+ export declare function ClassDeclaration(props: ClassDeclarationProps): ay.Children;
9
+ //# sourceMappingURL=class-declaration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"class-declaration.d.ts","sourceRoot":"","sources":["../../../../src/csharp/components/class-declaration.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAKtD,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,KAAK,GAAG,SAAS,CAAC;CACzB;AAUD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,EAAE,CAAC,QAAQ,CAgB1E"}
@@ -0,0 +1,97 @@
1
+ import { memo as _$memo, createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
2
+ import * as ay from "@alloy-js/core";
3
+ import * as cs from "@alloy-js/csharp";
4
+ import { useTsp } from "../../core/index.js";
5
+ import { TypeExpression } from "./type-expression.js";
6
+ import { declarationRefkeys } from "./utils/refkey.js";
7
+ export function ClassDeclaration(props) {
8
+ const {
9
+ $
10
+ } = useTsp();
11
+ const namePolicy = cs.useCSharpNamePolicy();
12
+ const className = props.name ?? namePolicy.getName(props.type.name, "class");
13
+ const refkeys = declarationRefkeys(props.refkey, props.type)[0]; // TODO: support multiple refkeys for declarations in alloy
14
+
15
+ return [_$createComponent(cs.Class, {
16
+ name: className,
17
+ get accessModifier() {
18
+ return props.accessModifier;
19
+ },
20
+ refkey: refkeys,
21
+ get children() {
22
+ return [_$memo(() => _$memo(() => !!$.model.is(props.type))() && _$createComponent(ClassProperties, {
23
+ get type() {
24
+ return props.type;
25
+ }
26
+ })), _$memo(() => _$memo(() => props.type.kind === "Interface")() && _$createComponent(ClassMethods, {
27
+ get type() {
28
+ return props.type;
29
+ }
30
+ }))];
31
+ }
32
+ })];
33
+ }
34
+ function ClassProperties(props) {
35
+ const namePolicy = cs.useCSharpNamePolicy();
36
+ const classProperties = [];
37
+ for (const [name, prop] of props.type.properties) {
38
+ classProperties.push([_$createComponent(cs.ClassMember, {
39
+ get name() {
40
+ return namePolicy.getName(name, "class-member-public");
41
+ },
42
+ get type() {
43
+ return _$createComponent(TypeExpression, {
44
+ get type() {
45
+ return prop.type;
46
+ }
47
+ });
48
+ },
49
+ accessModifier: "public"
50
+ }), " ", _$createComponent(ay.Block, {
51
+ newline: true,
52
+ get children() {
53
+ return _$createComponent(ay.StatementList, {
54
+ children: ["get", "set"]
55
+ });
56
+ }
57
+ })]);
58
+ }
59
+ return _$createComponent(ay.For, {
60
+ each: classProperties,
61
+ hardline: true,
62
+ children: c => c
63
+ });
64
+ }
65
+ function ClassMethods(props) {
66
+ const namePolicy = cs.useCSharpNamePolicy();
67
+ const abstractMethods = [];
68
+ for (const [name, prop] of props.type.operations) {
69
+ abstractMethods.push(_$createComponent(cs.ClassMethod, {
70
+ get name() {
71
+ return namePolicy.getName(name, "class-method");
72
+ },
73
+ methodModifier: "abstract",
74
+ get parameters() {
75
+ return [...prop.parameters.properties.entries()].map(([name, prop]) => {
76
+ return {
77
+ name: namePolicy.getName(name, "type-parameter"),
78
+ type: _$createComponent(TypeExpression, {
79
+ get type() {
80
+ return prop.type;
81
+ }
82
+ })
83
+ };
84
+ });
85
+ },
86
+ accessModifier: "public",
87
+ get returns() {
88
+ return _$createComponent(TypeExpression, {
89
+ get type() {
90
+ return prop.returnType;
91
+ }
92
+ });
93
+ }
94
+ }));
95
+ }
96
+ return [abstractMethods];
97
+ }
@@ -0,0 +1,9 @@
1
+ import * as ay from "@alloy-js/core";
2
+ import * as cs from "@alloy-js/csharp";
3
+ import { Enum, Union } from "@typespec/compiler";
4
+ export interface EnumDeclarationProps extends Omit<cs.EnumProps, "name"> {
5
+ name?: string;
6
+ type: Union | Enum;
7
+ }
8
+ export declare function EnumDeclaration(props: EnumDeclarationProps): ay.Children;
9
+ //# sourceMappingURL=enum-declaration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enum-declaration.d.ts","sourceRoot":"","sources":["../../../../src/csharp/components/enum-declaration.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAKjD,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC;CACpB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,EAAE,CAAC,QAAQ,CAmCxE"}
@@ -0,0 +1,52 @@
1
+ import { memo as _$memo, createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
2
+ import * as ay from "@alloy-js/core";
3
+ import * as cs from "@alloy-js/csharp";
4
+ import { useTsp } from "../../core/index.js";
5
+ import { reportDiagnostic } from "../../lib.js";
6
+ import { declarationRefkeys, efRefkey } from "./utils/refkey.js";
7
+ export function EnumDeclaration(props) {
8
+ const {
9
+ $
10
+ } = useTsp();
11
+ let type;
12
+ if ($.union.is(props.type)) {
13
+ if (!$.union.isValidEnum(props.type)) {
14
+ throw new Error("The provided union type cannot be represented as an enum");
15
+ }
16
+ type = $.enum.createFromUnion(props.type);
17
+ } else {
18
+ type = props.type;
19
+ }
20
+ if (!props.type.name) {
21
+ reportDiagnostic($.program, {
22
+ code: "type-declaration-missing-name",
23
+ target: props.type
24
+ });
25
+ }
26
+ const refkeys = declarationRefkeys(props.refkey, props.type)[0]; // TODO: support multiple refkeys for declarations in alloy
27
+ const name = props.name ?? cs.useCSharpNamePolicy().getName(props.type.name, "enum");
28
+ const members = Array.from(type.members.entries());
29
+ return _$createComponent(cs.Enum, {
30
+ name: name,
31
+ refkey: refkeys,
32
+ get accessModifier() {
33
+ return props.accessModifier ?? "public";
34
+ },
35
+ get children() {
36
+ return _$createComponent(ay.For, {
37
+ each: members,
38
+ joiner: ",\n",
39
+ children: ([key, value]) => {
40
+ return _$createComponent(cs.EnumMember, {
41
+ get name() {
42
+ return cs.useCSharpNamePolicy().getName(key, "enum-member");
43
+ },
44
+ get refkey() {
45
+ return _$memo(() => !!$.union.is(props.type))() ? efRefkey(props.type.variants.get(key)) : efRefkey(value);
46
+ }
47
+ });
48
+ }
49
+ });
50
+ }
51
+ });
52
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./class-declaration.jsx";
2
+ export * from "./enum-declaration.jsx";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/csharp/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./class-declaration.js";
2
+ export * from "./enum-declaration.js";
@@ -0,0 +1,11 @@
1
+ import { Children } from "@alloy-js/core";
2
+ import { IntrinsicType, Scalar, Type } from "@typespec/compiler";
3
+ import { Typekit } from "@typespec/compiler/typekit";
4
+ export interface TypeExpressionProps {
5
+ type: Type;
6
+ }
7
+ export declare function TypeExpression(props: TypeExpressionProps): Children;
8
+ declare const intrinsicNameToCSharpType: Map<string, string | null>;
9
+ export declare function getScalarIntrinsicExpression($: Typekit, type: Scalar | IntrinsicType): string | null;
10
+ export { intrinsicNameToCSharpType };
11
+ //# sourceMappingURL=type-expression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-expression.d.ts","sourceRoot":"","sources":["../../../../src/csharp/components/type-expression.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAKrD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,QAAQ,CASnE;AAED,QAAA,MAAM,yBAAyB,4BAqC7B,CAAC;AAEH,wBAAgB,4BAA4B,CAC1C,CAAC,EAAE,OAAO,EACV,IAAI,EAAE,MAAM,GAAG,aAAa,GAC3B,MAAM,GAAG,IAAI,CAoBf;AA0BD,OAAO,EAAE,yBAAyB,EAAE,CAAC"}
@@ -0,0 +1,129 @@
1
+ import { createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
2
+ import { Reference } from "@alloy-js/csharp";
3
+ import { useTsp } from "../../core/index.js";
4
+ import { reportTypescriptDiagnostic } from "../../typescript/lib.js";
5
+ import { efRefkey } from "./utils/refkey.js";
6
+ export function TypeExpression(props) {
7
+ const {
8
+ $
9
+ } = useTsp();
10
+ if (isDeclaration($, props.type)) {
11
+ return _$createComponent(Reference, {
12
+ get refkey() {
13
+ return efRefkey(props.type);
14
+ }
15
+ });
16
+ }
17
+ if ($.scalar.is(props.type)) {
18
+ return getScalarIntrinsicExpression($, props.type);
19
+ }
20
+ throw new Error("not implemented");
21
+ }
22
+ const intrinsicNameToCSharpType = new Map([
23
+ // Core types
24
+ ["unknown", "object"],
25
+ // Matches C#'s `object`
26
+ ["string", "string"],
27
+ // Matches C#'s `string`
28
+ ["boolean", "bool"],
29
+ // Matches C#'s `bool`
30
+ ["null", "null"],
31
+ // Matches C#'s `null`
32
+ ["void", "void"],
33
+ // Matches C#'s `void`
34
+ ["never", null],
35
+ // No direct equivalent in C#
36
+ ["bytes", "byte[]"],
37
+ // Matches C#'s `byte[]`
38
+
39
+ // Numeric types
40
+ ["numeric", "decimal"],
41
+ // Parent type for all numeric types, use most precise
42
+ ["integer", "int"],
43
+ // Broad integer category, maps to `int`
44
+ ["float", "float"],
45
+ // Broad float category, maps to `float`
46
+ ["decimal", "decimal"],
47
+ // Broad decimal category, maps to `decimal`
48
+ ["decimal128", "decimal"],
49
+ // C#'s decimal is 128-bit
50
+ ["int64", "long"],
51
+ // 64-bit signed integer
52
+ ["int32", "int"],
53
+ // 32-bit signed integer
54
+ ["int16", "short"],
55
+ // 16-bit signed integer
56
+ ["int8", "sbyte"],
57
+ // 8-bit signed integer
58
+ ["safeint", "int"],
59
+ // Safe integer, use int as default
60
+ ["uint64", "ulong"],
61
+ // 64-bit unsigned integer
62
+ ["uint32", "uint"],
63
+ // 32-bit unsigned integer
64
+ ["uint16", "ushort"],
65
+ // 16-bit unsigned integer
66
+ ["uint8", "byte"],
67
+ // 8-bit unsigned integer
68
+ ["float32", "float"],
69
+ // 32-bit floating point
70
+ ["float64", "double"],
71
+ // 64-bit floating point
72
+
73
+ // Date and time types
74
+ ["plainDate", "DateOnly"],
75
+ // Use .NET 6+ DateOnly for plain calendar dates
76
+ ["plainTime", "TimeOnly"],
77
+ // Use .NET 6+ TimeOnly for plain clock times
78
+ ["utcDateTime", "DateTimeOffset"],
79
+ // Use DateTimeOffset for UTC date-times
80
+ ["offsetDateTime", "DateTimeOffset"],
81
+ // Use DateTimeOffset for timezone-specific date-times
82
+ ["duration", "TimeSpan"],
83
+ // Duration as TimeSpan
84
+
85
+ // String types
86
+ ["url", "Uri"] // Matches C#'s `Uri`
87
+ ]);
88
+ export function getScalarIntrinsicExpression($, type) {
89
+ let intrinsicName;
90
+ if ($.scalar.isUtcDateTime(type) || $.scalar.extendsUtcDateTime(type)) {
91
+ return "DateTimeOffset";
92
+ }
93
+ if ($.scalar.is(type)) {
94
+ intrinsicName = $.scalar.getStdBase(type)?.name ?? "";
95
+ } else {
96
+ intrinsicName = type.name;
97
+ }
98
+ const csType = intrinsicNameToCSharpType.get(intrinsicName);
99
+ if (!csType) {
100
+ reportTypescriptDiagnostic($.program, {
101
+ code: "typescript-unsupported-scalar",
102
+ target: type
103
+ });
104
+ return "object"; // Fallback to object if unsupported
105
+ }
106
+ return csType;
107
+ }
108
+ function isDeclaration($, type) {
109
+ switch (type.kind) {
110
+ case "Namespace":
111
+ case "Interface":
112
+ case "Enum":
113
+ case "Operation":
114
+ case "EnumMember":
115
+ return true;
116
+ case "UnionVariant":
117
+ return false;
118
+ case "Model":
119
+ if ($.array.is(type) || $.record.is(type)) {
120
+ return false;
121
+ }
122
+ return Boolean(type.name);
123
+ case "Union":
124
+ return Boolean(type.name);
125
+ default:
126
+ return false;
127
+ }
128
+ }
129
+ export { intrinsicNameToCSharpType };
@@ -0,0 +1,23 @@
1
+ import { type Refkey } from "@alloy-js/core";
2
+ /**
3
+ * A wrapper around `refkey` that uses a custom symbol to avoid collisions with
4
+ * other libraries that use `refkey`.
5
+ *
6
+ * @remarks
7
+ *
8
+ * The underlying refkey function is called with the {@link refKeyPrefix} symbol as the first argument.
9
+ *
10
+ * @param args The parameters of the refkey.
11
+ * @returns A refkey object that can be used to identify the value.
12
+ */
13
+ export declare function efRefkey(...args: unknown[]): Refkey;
14
+ /**
15
+ * Creates a refkey for a declaration by combining the provided refkey with an internal
16
+ * refkey generated from the provided arguments.
17
+ *
18
+ * @param refkey The refkey provided by the user to be passed as is.
19
+ * @param args The parameters of the refkey.
20
+ * @returns An array of refkeys that can be passed to an Alloy declaration.
21
+ */
22
+ export declare function declarationRefkeys(refkey?: Refkey | Refkey[], ...args: unknown[]): Refkey[];
23
+ //# sourceMappingURL=refkey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refkey.d.ts","sourceRoot":"","sources":["../../../../../src/csharp/components/utils/refkey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAIjE;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAKnD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,CAK3F"}
@@ -0,0 +1,35 @@
1
+ import { refkey as ayRefkey } from "@alloy-js/core";
2
+ const refKeyPrefix = Symbol.for("emitter-framework:csharp");
3
+
4
+ /**
5
+ * A wrapper around `refkey` that uses a custom symbol to avoid collisions with
6
+ * other libraries that use `refkey`.
7
+ *
8
+ * @remarks
9
+ *
10
+ * The underlying refkey function is called with the {@link refKeyPrefix} symbol as the first argument.
11
+ *
12
+ * @param args The parameters of the refkey.
13
+ * @returns A refkey object that can be used to identify the value.
14
+ */
15
+ export function efRefkey(...args) {
16
+ if (args.length === 0) {
17
+ return ayRefkey(); // Generates a unique refkey
18
+ }
19
+ return ayRefkey(refKeyPrefix, ...args);
20
+ }
21
+
22
+ /**
23
+ * Creates a refkey for a declaration by combining the provided refkey with an internal
24
+ * refkey generated from the provided arguments.
25
+ *
26
+ * @param refkey The refkey provided by the user to be passed as is.
27
+ * @param args The parameters of the refkey.
28
+ * @returns An array of refkeys that can be passed to an Alloy declaration.
29
+ */
30
+ export function declarationRefkeys(refkey, ...args) {
31
+ if (refkey) {
32
+ return [refkey, efRefkey(...args)].flat();
33
+ }
34
+ return [efRefkey(...args)];
35
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./components/index.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/csharp/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1 @@
1
+ export * from "./components/index.js";
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=class-declaration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"class-declaration.test.d.ts","sourceRoot":"","sources":["../../../../test/csharp/components/class-declaration.test.tsx"],"names":[],"mappings":""}