@alloy-js/csharp 0.19.0-dev.1 → 0.19.0-dev.4

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 (53) hide show
  1. package/dist/src/components/ClassDeclaration.d.ts +0 -8
  2. package/dist/src/components/ClassDeclaration.d.ts.map +1 -1
  3. package/dist/src/components/ClassDeclaration.js +0 -43
  4. package/dist/src/components/constructor/constructor.d.ts +17 -0
  5. package/dist/src/components/constructor/constructor.d.ts.map +1 -0
  6. package/dist/src/components/constructor/constructor.js +47 -0
  7. package/dist/src/components/constructor/constructor.test.d.ts +2 -0
  8. package/dist/src/components/constructor/constructor.test.d.ts.map +1 -0
  9. package/dist/src/components/constructor/constructor.test.js +54 -0
  10. package/dist/src/components/index.d.ts +3 -1
  11. package/dist/src/components/index.d.ts.map +1 -1
  12. package/dist/src/components/index.js +3 -1
  13. package/dist/src/components/{ClassMethod.d.ts → method/method.d.ts} +22 -8
  14. package/dist/src/components/method/method.d.ts.map +1 -0
  15. package/dist/src/components/{ClassMethod.js → method/method.js} +13 -13
  16. package/dist/src/components/method/method.test.d.ts +2 -0
  17. package/dist/src/components/method/method.test.d.ts.map +1 -0
  18. package/dist/{test/class-method.test.js → src/components/method/method.test.js} +33 -10
  19. package/dist/src/components/property/property.d.ts.map +1 -1
  20. package/dist/src/components/property/property.js +1 -1
  21. package/dist/src/components/stc/index.d.ts +3 -2
  22. package/dist/src/components/stc/index.d.ts.map +1 -1
  23. package/dist/src/components/stc/index.js +4 -3
  24. package/dist/src/components/struct/declaration.d.ts +68 -0
  25. package/dist/src/components/struct/declaration.d.ts.map +1 -0
  26. package/dist/src/components/struct/declaration.js +78 -0
  27. package/dist/src/components/struct/declaration.test.d.ts +2 -0
  28. package/dist/src/components/struct/declaration.test.d.ts.map +1 -0
  29. package/dist/src/components/struct/declaration.test.js +211 -0
  30. package/dist/src/name-policy.d.ts +1 -1
  31. package/dist/src/name-policy.d.ts.map +1 -1
  32. package/dist/src/name-policy.js +1 -0
  33. package/dist/test/class-declaration.test.js +6 -5
  34. package/dist/test/using.test.js +1 -1
  35. package/dist/tsconfig.tsbuildinfo +1 -1
  36. package/package.json +2 -2
  37. package/src/components/ClassDeclaration.tsx +0 -44
  38. package/src/components/constructor/constructor.test.tsx +41 -0
  39. package/src/components/constructor/constructor.tsx +67 -0
  40. package/src/components/index.ts +3 -1
  41. package/{test/class-method.test.tsx → src/components/method/method.test.tsx} +28 -15
  42. package/src/components/{ClassMethod.tsx → method/method.tsx} +44 -19
  43. package/src/components/property/property.tsx +3 -1
  44. package/src/components/stc/index.ts +3 -2
  45. package/src/components/struct/declaration.test.tsx +169 -0
  46. package/src/components/struct/declaration.tsx +129 -0
  47. package/src/name-policy.ts +2 -0
  48. package/temp/api.json +3544 -3163
  49. package/test/class-declaration.test.tsx +8 -7
  50. package/test/using.test.tsx +1 -1
  51. package/dist/src/components/ClassMethod.d.ts.map +0 -1
  52. package/dist/test/class-method.test.d.ts +0 -2
  53. package/dist/test/class-method.test.d.ts.map +0 -1
@@ -0,0 +1,41 @@
1
+ import { refkey } from "@alloy-js/core";
2
+ import { expect, it } from "vitest";
3
+ import { TestNamespace } from "../../../test/utils.jsx";
4
+ import { ClassDeclaration } from "../ClassDeclaration.jsx";
5
+ import { SourceFile } from "../SourceFile.jsx";
6
+ import { Constructor } from "./constructor.jsx";
7
+
8
+ it("reference constructor parameters in body", () => {
9
+ const paramNameRefkey = refkey();
10
+ const paramSizeRefkey = refkey();
11
+
12
+ const ctorParams = [
13
+ { name: "name", type: "string", refkey: paramNameRefkey },
14
+ { name: "size", type: "int", refkey: paramSizeRefkey },
15
+ ];
16
+
17
+ expect(
18
+ <TestNamespace>
19
+ <SourceFile path="Test.cs">
20
+ <ClassDeclaration public name="TestClass">
21
+ <Constructor public parameters={ctorParams}>
22
+ {paramNameRefkey};<hbr />
23
+ {paramSizeRefkey};
24
+ </Constructor>
25
+ </ClassDeclaration>
26
+ </SourceFile>
27
+ </TestNamespace>,
28
+ ).toRenderTo(`
29
+ namespace TestCode
30
+ {
31
+ public class TestClass
32
+ {
33
+ public TestClass(string name, int size)
34
+ {
35
+ name;
36
+ size;
37
+ }
38
+ }
39
+ }
40
+ `);
41
+ });
@@ -0,0 +1,67 @@
1
+ import {
2
+ Block,
3
+ Declaration,
4
+ Name,
5
+ Refkey,
6
+ refkey,
7
+ Scope,
8
+ } from "@alloy-js/core";
9
+ import { Children } from "@alloy-js/core/jsx-runtime";
10
+ import {
11
+ AccessModifiers,
12
+ computeModifiersPrefix,
13
+ getAccessModifier,
14
+ } from "../../modifiers.js";
15
+ import { useCSharpNamePolicy } from "../../name-policy.js";
16
+ import { CSharpOutputSymbol } from "../../symbols/csharp-output-symbol.js";
17
+ import { CSharpMemberScope, useCSharpScope } from "../../symbols/scopes.js";
18
+ import { ParameterProps, Parameters } from "../parameters/parameters.jsx";
19
+
20
+ /**
21
+ * Properties for {@link Constructor} component.
22
+ */
23
+ export interface ConstructorProps extends AccessModifiers {
24
+ /** Constructor parameters */
25
+ parameters?: ParameterProps[];
26
+
27
+ /** Refkey */
28
+ refkey?: Refkey;
29
+
30
+ /** Constructor body */
31
+ children?: Children;
32
+ }
33
+
34
+ export function Constructor(props: ConstructorProps) {
35
+ const scope = useCSharpScope();
36
+ if (
37
+ scope.kind !== "member" ||
38
+ (scope.name !== "class-decl" && scope.name !== "struct-decl")
39
+ ) {
40
+ throw new Error(
41
+ "can't define a class method outside of a class or struct scope",
42
+ );
43
+ }
44
+
45
+ const name = useCSharpNamePolicy().getName(scope.owner!.name, "class-method");
46
+ const ctorSymbol = new CSharpOutputSymbol(name, {
47
+ scope,
48
+ refkeys: props.refkey ?? refkey(name),
49
+ });
50
+
51
+ const ctorDeclScope = new CSharpMemberScope("constructor-decl", {
52
+ owner: ctorSymbol,
53
+ });
54
+
55
+ const modifiers = computeModifiersPrefix([getAccessModifier(props)]);
56
+
57
+ return (
58
+ <Declaration symbol={ctorSymbol}>
59
+ <Scope value={ctorDeclScope}>
60
+ {modifiers}
61
+ <Name />
62
+ <Parameters parameters={props.parameters} />
63
+ <Block newline>{props.children}</Block>
64
+ </Scope>
65
+ </Declaration>
66
+ );
67
+ }
@@ -1,6 +1,6 @@
1
1
  export * from "./attributes/attributes.jsx";
2
2
  export * from "./ClassDeclaration.jsx";
3
- export * from "./ClassMethod.jsx";
3
+ export * from "./constructor/constructor.jsx";
4
4
  export * from "./Declaration.js";
5
5
  export * from "./doc/comment.jsx";
6
6
  export * from "./doc/from-markdown.jsx";
@@ -8,6 +8,7 @@ export * from "./EnumDeclaration.jsx";
8
8
  export * from "./interface/declaration.js";
9
9
  export * from "./interface/method.js";
10
10
  export * from "./interface/property.js";
11
+ export * from "./method/method.jsx";
11
12
  export * from "./Name.js";
12
13
  export * from "./Namespace.js";
13
14
  export * from "./parameters/parameters.jsx";
@@ -16,6 +17,7 @@ export * from "./property/property.jsx";
16
17
  export * from "./record/declaration.js";
17
18
  export * from "./Reference.js";
18
19
  export * from "./SourceFile.js";
20
+ export * from "./struct/declaration.jsx";
19
21
  export type { TypeParameterProps } from "./type-parameters/type-parameter.jsx";
20
22
  export * from "./UsingDirective.js";
21
23
  export * from "./var/declaration.jsx";
@@ -1,7 +1,7 @@
1
1
  import { Children } from "@alloy-js/core/jsx-runtime";
2
2
  import { describe, expect, it } from "vitest";
3
- import { ClassDeclaration, ClassMethod } from "../src/index.js";
4
- import { TestNamespace } from "./utils.jsx";
3
+ import { TestNamespace } from "../../../test/utils.jsx";
4
+ import { ClassDeclaration, Method } from "../../index.js";
5
5
 
6
6
  const Wrapper = (props: { children: Children }) => (
7
7
  <TestNamespace>
@@ -18,7 +18,7 @@ describe("modifiers", () => {
18
18
  (accessModifier) => {
19
19
  expect(
20
20
  <Wrapper>
21
- <ClassMethod {...{ [accessModifier]: true }} name="MethodOne" />
21
+ <Method {...{ [accessModifier]: true }} name="MethodOne" />
22
22
  </Wrapper>,
23
23
  ).toRenderTo(`
24
24
  public class TestClass
@@ -36,7 +36,7 @@ describe("modifiers", () => {
36
36
  (methodModifier) => {
37
37
  expect(
38
38
  <Wrapper>
39
- <ClassMethod {...{ [methodModifier]: true }} name="MethodOne" />
39
+ <Method {...{ [methodModifier]: true }} name="MethodOne" />
40
40
  </Wrapper>,
41
41
  ).toRenderTo(`
42
42
  public class TestClass
@@ -50,7 +50,7 @@ describe("modifiers", () => {
50
50
  it("abstract exclude body", () => {
51
51
  expect(
52
52
  <Wrapper>
53
- <ClassMethod abstract name="MethodOne" />
53
+ <Method abstract name="MethodOne" />
54
54
  </Wrapper>,
55
55
  ).toRenderTo(`
56
56
  public class TestClass
@@ -64,7 +64,7 @@ describe("modifiers", () => {
64
64
  it("mark method async", () => {
65
65
  expect(
66
66
  <Wrapper>
67
- <ClassMethod async name="MethodOne" />
67
+ <Method async name="MethodOne" />
68
68
  </Wrapper>,
69
69
  ).toRenderTo(`
70
70
  public class TestClass
@@ -77,7 +77,7 @@ describe("modifiers", () => {
77
77
  it("combine modifiers", () => {
78
78
  expect(
79
79
  <Wrapper>
80
- <ClassMethod async returns="Task" public abstract name="MethodOne" />
80
+ <Method async returns="Task" public abstract name="MethodOne" />
81
81
  </Wrapper>,
82
82
  ).toRenderTo(`
83
83
  public class TestClass
@@ -91,7 +91,7 @@ describe("modifiers", () => {
91
91
  it("applies PascalCase naming policy", () => {
92
92
  expect(
93
93
  <Wrapper>
94
- <ClassMethod name="method_one" />
94
+ <Method name="method_one" />
95
95
  </Wrapper>,
96
96
  ).toRenderTo(`
97
97
  public class TestClass
@@ -113,12 +113,7 @@ it("defines params and return type", () => {
113
113
  ];
114
114
  const res = (
115
115
  <Wrapper>
116
- <ClassMethod
117
- public
118
- name="MethodOne"
119
- parameters={params}
120
- returns="string"
121
- />
116
+ <Method public name="MethodOne" parameters={params} returns="string" />
122
117
  </Wrapper>
123
118
  );
124
119
 
@@ -134,7 +129,7 @@ it("specify doc comment", () => {
134
129
  expect(
135
130
  <TestNamespace>
136
131
  <ClassDeclaration name="Test">
137
- <ClassMethod name="Method" doc="This is a test" />
132
+ <Method name="Method" doc="This is a test" />
138
133
  </ClassDeclaration>
139
134
  </TestNamespace>,
140
135
  ).toRenderTo(`
@@ -145,3 +140,21 @@ it("specify doc comment", () => {
145
140
  }
146
141
  `);
147
142
  });
143
+
144
+ it("use expression body form", () => {
145
+ expect(
146
+ <TestNamespace>
147
+ <ClassDeclaration name="Test">
148
+ <Method name="Method" doc="This is a test" expression>
149
+ this.MyProperty.Value;
150
+ </Method>
151
+ </ClassDeclaration>
152
+ </TestNamespace>,
153
+ ).toRenderTo(`
154
+ class Test
155
+ {
156
+ /// This is a test
157
+ void Method() => this.MyProperty.Value;
158
+ }
159
+ `);
160
+ });
@@ -12,26 +12,26 @@ import {
12
12
  getAccessModifier,
13
13
  getAsyncModifier,
14
14
  makeModifiers,
15
- } from "../modifiers.js";
16
- import { useCSharpNamePolicy } from "../name-policy.js";
17
- import { CSharpOutputSymbol } from "../symbols/csharp-output-symbol.js";
18
- import { CSharpMemberScope, useCSharpScope } from "../symbols/scopes.js";
19
- import { AttributeList, AttributesProp } from "./attributes/attributes.jsx";
20
- import { DocWhen } from "./doc/comment.jsx";
21
- import { ParameterProps, Parameters } from "./parameters/parameters.jsx";
22
- import { TypeParameterConstraints } from "./type-parameters/type-parameter-constraints.jsx";
23
- import { TypeParameterProps } from "./type-parameters/type-parameter.jsx";
24
- import { TypeParameters } from "./type-parameters/type-parameters.jsx";
15
+ } from "../../modifiers.js";
16
+ import { useCSharpNamePolicy } from "../../name-policy.js";
17
+ import { CSharpOutputSymbol } from "../../symbols/csharp-output-symbol.js";
18
+ import { CSharpMemberScope, useCSharpScope } from "../../symbols/scopes.js";
19
+ import { AttributeList, AttributesProp } from "../attributes/attributes.jsx";
20
+ import { DocWhen } from "../doc/comment.jsx";
21
+ import { ParameterProps, Parameters } from "../parameters/parameters.jsx";
22
+ import { TypeParameterConstraints } from "../type-parameters/type-parameter-constraints.jsx";
23
+ import { TypeParameterProps } from "../type-parameters/type-parameter.jsx";
24
+ import { TypeParameters } from "../type-parameters/type-parameters.jsx";
25
25
 
26
26
  /** Method modifiers. Can only be one. */
27
- export interface ClassMethodModifiers {
27
+ export interface MethodModifiers {
28
28
  readonly abstract?: boolean;
29
29
  readonly sealed?: boolean;
30
30
  readonly static?: boolean;
31
31
  readonly virtual?: boolean;
32
32
  }
33
33
 
34
- const getMethodModifier = makeModifiers<ClassMethodModifiers>([
34
+ const getMethodModifier = makeModifiers<MethodModifiers>([
35
35
  "abstract",
36
36
  "sealed",
37
37
  "static",
@@ -39,9 +39,7 @@ const getMethodModifier = makeModifiers<ClassMethodModifiers>([
39
39
  ]);
40
40
 
41
41
  // properties for creating a method
42
- export interface ClassMethodProps
43
- extends AccessModifiers,
44
- ClassMethodModifiers {
42
+ export interface MethodProps extends AccessModifiers, MethodModifiers {
45
43
  name: string;
46
44
  refkey?: Refkey;
47
45
  children?: Children;
@@ -87,14 +85,34 @@ export interface ClassMethodProps
87
85
  * ```
88
86
  */
89
87
  attributes?: AttributesProp;
88
+
89
+ /**
90
+ * Use expression syntax for the method.
91
+ * @example
92
+ * ```tsx
93
+ * <ClassMethod name="MyMethod" lambda>
94
+ * this.MyProperty.Value;
95
+ * </ClassMethod>
96
+ * ```
97
+ * This will produce:
98
+ * ```csharp
99
+ * public void MyMethod() => this.MyProperty.Value;
100
+ * ```
101
+ */
102
+ expression?: boolean;
90
103
  }
91
104
 
92
105
  // a C# class method
93
- export function ClassMethod(props: ClassMethodProps) {
106
+ export function Method(props: MethodProps) {
94
107
  const name = useCSharpNamePolicy().getName(props.name, "class-method");
95
108
  const scope = useCSharpScope();
96
- if (scope.kind !== "member" || scope.name !== "class-decl") {
97
- throw new Error("can't define a class method outside of a class scope");
109
+ if (
110
+ scope.kind !== "member" ||
111
+ (scope.name !== "class-decl" && scope.name !== "struct-decl")
112
+ ) {
113
+ throw new Error(
114
+ "can't define a class method outside of a class or struct scope",
115
+ );
98
116
  }
99
117
 
100
118
  const methodSymbol = new CSharpOutputSymbol(name, {
@@ -129,7 +147,14 @@ export function ClassMethod(props: ClassMethodProps) {
129
147
  {props.typeParameters && (
130
148
  <TypeParameterConstraints parameters={props.typeParameters} />
131
149
  )}
132
- {props.abstract ? ";" : <Block newline>{props.children}</Block>}
150
+ {props.abstract ?
151
+ ";"
152
+ : props.expression ?
153
+ <>
154
+ {" => "}
155
+ {props.children}
156
+ </>
157
+ : <Block newline>{props.children}</Block>}
133
158
  </Scope>
134
159
  </MemberDeclaration>
135
160
  );
@@ -122,7 +122,9 @@ export function Property(props: PropertyProps) {
122
122
  const scope = useCSharpScope();
123
123
  if (
124
124
  scope.kind !== "member" ||
125
- (scope.name !== "class-decl" && scope.name !== "record-decl")
125
+ (scope.name !== "class-decl" &&
126
+ scope.name !== "record-decl" &&
127
+ scope.name !== "struct-decl")
126
128
  ) {
127
129
  throw new Error(
128
130
  "can't define an interface method outside of an interface scope",
@@ -2,12 +2,13 @@ import * as core from "@alloy-js/core";
2
2
  import * as base from "../index.js";
3
3
 
4
4
  export const ClassDeclaration = core.stc(base.ClassDeclaration);
5
- export const ClassConstructor = core.stc(base.ClassConstructor);
5
+ export const Constructor = core.stc(base.Constructor);
6
6
  export const ClassMember = core.stc(base.ClassMember);
7
- export const ClassMethod = core.stc(base.ClassMethod);
7
+ export const ClassMethod = core.stc(base.Method);
8
8
  export const EnumDeclaration = core.stc(base.EnumDeclaration);
9
9
  export const EnumMember = core.stc(base.EnumMember);
10
10
  export const Parameter = core.stc(base.Parameter);
11
11
  export const Parameters = core.stc(base.Parameters);
12
12
  export const ProjectDirectory = core.stc(base.ProjectDirectory);
13
13
  export const UsingDirective = core.stc(base.UsingDirective);
14
+ export const StructDeclaration = core.stc(base.StructDeclaration);
@@ -0,0 +1,169 @@
1
+ import { List, refkey } from "@alloy-js/core";
2
+ import { describe, expect, it } from "vitest";
3
+ import { TestNamespace } from "../../../test/utils.jsx";
4
+ import { Attribute } from "../attributes/attributes.jsx";
5
+ import { Constructor } from "../constructor/constructor.jsx";
6
+ import { Method } from "../method/method.jsx";
7
+ import { Property } from "../property/property.jsx";
8
+ import { SourceFile } from "../SourceFile.jsx";
9
+ import { TypeParameterProps } from "../type-parameters/type-parameter.jsx";
10
+ import { StructDeclaration } from "./declaration.jsx";
11
+
12
+ it("declares struct with no members", () => {
13
+ expect(
14
+ <TestNamespace>
15
+ <StructDeclaration name="Test" />
16
+ </TestNamespace>,
17
+ ).toRenderTo(`
18
+ struct Test;
19
+ `);
20
+ });
21
+
22
+ describe("modifiers", () => {
23
+ it.each(["public", "private", "internal"])("%s", (mod) => {
24
+ expect(
25
+ <TestNamespace>
26
+ <StructDeclaration {...{ [mod]: true }} name="Test" />
27
+ </TestNamespace>,
28
+ ).toRenderTo(`
29
+ ${mod} struct Test;
30
+ `);
31
+ });
32
+
33
+ it.each(["partial"])("%s", (mod) => {
34
+ expect(
35
+ <TestNamespace>
36
+ <StructDeclaration {...{ [mod]: true }} name="Test" />
37
+ </TestNamespace>,
38
+ ).toRenderTo(`
39
+ ${mod} struct Test;
40
+ `);
41
+ });
42
+
43
+ it("combines modifiers", () => {
44
+ expect(
45
+ <TestNamespace>
46
+ <StructDeclaration public partial name="Test" />
47
+ </TestNamespace>,
48
+ ).toRenderTo(`
49
+ public partial struct Test;
50
+ `);
51
+ });
52
+ });
53
+
54
+ it("specify doc comment", () => {
55
+ expect(
56
+ <TestNamespace>
57
+ <StructDeclaration name="Test" doc="This is a test" />
58
+ </TestNamespace>,
59
+ ).toRenderTo(`
60
+ /// This is a test
61
+ struct Test;
62
+ `);
63
+ });
64
+
65
+ describe("with type parameters", () => {
66
+ it("reference parameters", () => {
67
+ const typeParameters: TypeParameterProps[] = [
68
+ {
69
+ name: "T",
70
+ refkey: refkey(),
71
+ },
72
+ {
73
+ name: "U",
74
+ refkey: refkey(),
75
+ },
76
+ ];
77
+
78
+ expect(
79
+ <TestNamespace>
80
+ <SourceFile path="Test.cs">
81
+ <StructDeclaration public name="Test" typeParameters={typeParameters}>
82
+ <List>
83
+ <Property name="PropA" type={typeParameters[0].refkey} get set />
84
+ <Property name="PropB" type={typeParameters[1].refkey} get set />
85
+ </List>
86
+ </StructDeclaration>
87
+ </SourceFile>
88
+ </TestNamespace>,
89
+ ).toRenderTo(`
90
+ namespace TestCode
91
+ {
92
+ public struct Test<T, U>
93
+ {
94
+ T PropA { get; set; }
95
+ U PropB { get; set; }
96
+ }
97
+ }
98
+ `);
99
+ });
100
+
101
+ it("defines with constraints", () => {
102
+ const typeParameters: TypeParameterProps[] = [
103
+ {
104
+ name: "T",
105
+ constraints: "IFoo",
106
+ },
107
+ {
108
+ name: "U",
109
+ constraints: "IBar",
110
+ },
111
+ ];
112
+
113
+ expect(
114
+ <TestNamespace>
115
+ <StructDeclaration public name="Test" typeParameters={typeParameters}>
116
+ // Body
117
+ </StructDeclaration>
118
+ </TestNamespace>,
119
+ ).toRenderTo(`
120
+ public struct Test<T, U>
121
+ where T : IFoo
122
+ where U : IBar
123
+ {
124
+ // Body
125
+ }
126
+ `);
127
+ });
128
+ });
129
+
130
+ it("specify attributes", () => {
131
+ expect(
132
+ <TestNamespace>
133
+ <StructDeclaration name="Test" attributes={[<Attribute name="Test" />]} />
134
+ </TestNamespace>,
135
+ ).toRenderTo(`
136
+ [Test]
137
+ struct Test;
138
+ `);
139
+ });
140
+
141
+ it("define methods", () => {
142
+ expect(
143
+ <TestNamespace>
144
+ <StructDeclaration name="Test">
145
+ <Method name="MethodOne" />
146
+ </StructDeclaration>
147
+ </TestNamespace>,
148
+ ).toRenderTo(`
149
+ struct Test
150
+ {
151
+ void MethodOne() {}
152
+ }
153
+ `);
154
+ });
155
+
156
+ it("define constructor", () => {
157
+ expect(
158
+ <TestNamespace>
159
+ <StructDeclaration name="Test">
160
+ <Constructor public />
161
+ </StructDeclaration>
162
+ </TestNamespace>,
163
+ ).toRenderTo(`
164
+ struct Test
165
+ {
166
+ public Test() {}
167
+ }
168
+ `);
169
+ });
@@ -0,0 +1,129 @@
1
+ import * as core from "@alloy-js/core";
2
+ import {
3
+ AccessModifiers,
4
+ computeModifiersPrefix,
5
+ getAccessModifier,
6
+ makeModifiers,
7
+ } from "../../modifiers.js";
8
+ import { useCSharpNamePolicy } from "../../name-policy.js";
9
+ import { CSharpOutputSymbol } from "../../symbols/csharp-output-symbol.js";
10
+ import { CSharpMemberScope } from "../../symbols/scopes.js";
11
+ import { AttributeList, AttributesProp } from "../attributes/attributes.jsx";
12
+ import { DocWhen } from "../doc/comment.jsx";
13
+ import { Name } from "../Name.jsx";
14
+ import { TypeParameterConstraints } from "../type-parameters/type-parameter-constraints.jsx";
15
+ import { TypeParameterProps } from "../type-parameters/type-parameter.jsx";
16
+ import { TypeParameters } from "../type-parameters/type-parameters.jsx";
17
+
18
+ export interface StructModifiers {
19
+ readonly new?: boolean;
20
+ readonly readonly?: boolean;
21
+ readonly ref?: boolean;
22
+ readonly partial?: boolean;
23
+ }
24
+
25
+ const getStructModifiers = makeModifiers<StructModifiers>([
26
+ "new",
27
+ "readonly",
28
+ "ref",
29
+ "partial",
30
+ ]);
31
+
32
+ // properties for creating a class
33
+ export interface StructDeclarationProps
34
+ extends Omit<core.DeclarationProps, "nameKind">,
35
+ AccessModifiers,
36
+ StructModifiers {
37
+ name: string;
38
+
39
+ /** Doc comment */
40
+ doc?: core.Children;
41
+ refkey?: core.Refkey;
42
+
43
+ /**
44
+ * Type parameters for the struct
45
+ *
46
+ * @example
47
+ * ```tsx
48
+ * <StructDeclaration name="IList" typeParameters={["T"]} />
49
+ * ```
50
+ * This will produce:
51
+ * ```csharp
52
+ * public struct IList<T>
53
+ * ```
54
+ */
55
+ typeParameters?: (TypeParameterProps | string)[];
56
+
57
+ /**
58
+ * Define attributes to attach
59
+ * @example
60
+ * ```tsx
61
+ * <StructDeclaration name="MyStruct" attributes={[
62
+ * <Attribute name="Test" />
63
+ * <Attribute name="Test2" args={["arg1", "arg2"]} />
64
+ * ]} />
65
+ * ```
66
+ * This will produce:
67
+ * ```csharp
68
+ * [Test]
69
+ * [Test2("arg1", "arg2")]
70
+ * public struct MyStruct
71
+ * ```
72
+ */
73
+ attributes?: AttributesProp;
74
+ }
75
+
76
+ /**
77
+ * CSharp struct declaration.
78
+ * @example
79
+ * ```tsx
80
+ * <StructDeclaration public name="IMyStruct">
81
+ * <StructMember public name="MyProperty" type="int" />
82
+ * <StructMethod public name="MyMethod" returnType="void">
83
+ * <Parameter name="value" type="int" />
84
+ * </StructMethod>
85
+ * </StructDeclaration>
86
+ * ```
87
+ * This will produce:
88
+ * ```csharp
89
+ * public struct MyIface
90
+ * {
91
+ * public int MyProperty { get; set; }
92
+ * public void MyMethod(int value);
93
+ * }
94
+ * ```
95
+ */
96
+ export function StructDeclaration(props: StructDeclarationProps) {
97
+ const name = useCSharpNamePolicy().getName(props.name!, "struct");
98
+
99
+ const thisStructSymbol = new CSharpOutputSymbol(name, {
100
+ refkeys: props.refkey,
101
+ });
102
+
103
+ const thisStructScope = new CSharpMemberScope("struct-decl", {
104
+ owner: thisStructSymbol,
105
+ });
106
+
107
+ const modifiers = computeModifiersPrefix([
108
+ getAccessModifier(props),
109
+ getStructModifiers(props),
110
+ ]);
111
+ return (
112
+ <core.Declaration symbol={thisStructSymbol}>
113
+ <DocWhen doc={props.doc} />
114
+ <AttributeList attributes={props.attributes} endline />
115
+ {modifiers}struct <Name />
116
+ {props.typeParameters && (
117
+ <TypeParameters parameters={props.typeParameters} />
118
+ )}
119
+ {props.typeParameters && (
120
+ <TypeParameterConstraints parameters={props.typeParameters} />
121
+ )}
122
+ {props.children ?
123
+ <core.Block newline>
124
+ <core.Scope value={thisStructScope}>{props.children}</core.Scope>
125
+ </core.Block>
126
+ : ";"}
127
+ </core.Declaration>
128
+ );
129
+ }
@@ -6,6 +6,7 @@ export type CSharpElements =
6
6
  | "class"
7
7
  | "constant"
8
8
  | "variable"
9
+ | "struct"
9
10
  | "enum"
10
11
  | "enum-member"
11
12
  | "function"
@@ -23,6 +24,7 @@ export function createCSharpNamePolicy(): core.NamePolicy<CSharpElements> {
23
24
  return core.createNamePolicy((name, element) => {
24
25
  switch (element) {
25
26
  case "class":
27
+ case "struct":
26
28
  case "enum":
27
29
  case "enum-member":
28
30
  case "interface":