@alloy-js/csharp 0.19.0-dev.2 → 0.19.0-dev.5

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 (52) hide show
  1. package/dist/src/components/ClassDeclaration.d.ts +0 -16
  2. package/dist/src/components/ClassDeclaration.d.ts.map +1 -1
  3. package/dist/src/components/ClassDeclaration.js +1 -74
  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/field/field.d.ts +12 -0
  11. package/dist/src/components/field/field.d.ts.map +1 -0
  12. package/dist/src/components/field/field.js +34 -0
  13. package/dist/src/components/field/field.test.d.ts +2 -0
  14. package/dist/src/components/field/field.test.d.ts.map +1 -0
  15. package/dist/src/components/field/field.test.js +37 -0
  16. package/dist/src/components/index.d.ts +3 -1
  17. package/dist/src/components/index.d.ts.map +1 -1
  18. package/dist/src/components/index.js +3 -1
  19. package/dist/src/components/{ClassMethod.d.ts → method/method.d.ts} +8 -8
  20. package/dist/src/components/method/method.d.ts.map +1 -0
  21. package/dist/src/components/{ClassMethod.js → method/method.js} +12 -12
  22. package/dist/src/components/method/method.test.d.ts +2 -0
  23. package/dist/src/components/method/method.test.d.ts.map +1 -0
  24. package/dist/{test/class-method.test.js → src/components/method/method.test.js} +11 -11
  25. package/dist/src/components/stc/index.d.ts +3 -3
  26. package/dist/src/components/stc/index.d.ts.map +1 -1
  27. package/dist/src/components/stc/index.js +3 -3
  28. package/dist/src/components/struct/declaration.d.ts +2 -0
  29. package/dist/src/components/struct/declaration.d.ts.map +1 -1
  30. package/dist/src/components/struct/declaration.js +6 -2
  31. package/dist/src/components/struct/declaration.test.js +85 -1
  32. package/dist/test/class-declaration.test.js +14 -12
  33. package/dist/test/using.test.js +1 -1
  34. package/dist/tsconfig.tsbuildinfo +1 -1
  35. package/package.json +1 -1
  36. package/src/components/ClassDeclaration.tsx +2 -84
  37. package/src/components/constructor/constructor.test.tsx +41 -0
  38. package/src/components/constructor/constructor.tsx +67 -0
  39. package/src/components/field/field.test.tsx +24 -0
  40. package/src/components/field/field.tsx +50 -0
  41. package/src/components/index.ts +3 -1
  42. package/{test/class-method.test.tsx → src/components/method/method.test.tsx} +12 -17
  43. package/src/components/{ClassMethod.tsx → method/method.tsx} +21 -18
  44. package/src/components/stc/index.ts +3 -3
  45. package/src/components/struct/declaration.test.tsx +63 -1
  46. package/src/components/struct/declaration.tsx +11 -0
  47. package/temp/api.json +2148 -2153
  48. package/test/class-declaration.test.tsx +16 -33
  49. package/test/using.test.tsx +1 -1
  50. package/dist/src/components/ClassMethod.d.ts.map +0 -1
  51. package/dist/test/class-method.test.d.ts +0 -2
  52. package/dist/test/class-method.test.d.ts.map +0 -1
@@ -6,13 +6,12 @@ import {
6
6
  getAccessModifier,
7
7
  makeModifiers,
8
8
  } from "../modifiers.js";
9
- import { CSharpElements, useCSharpNamePolicy } from "../name-policy.js";
9
+ import { useCSharpNamePolicy } from "../name-policy.js";
10
10
  import { CSharpOutputSymbol } from "../symbols/csharp-output-symbol.js";
11
- import { CSharpMemberScope, useCSharpScope } from "../symbols/scopes.js";
11
+ import { CSharpMemberScope } from "../symbols/scopes.js";
12
12
  import { AttributeList, AttributesProp } from "./attributes/attributes.jsx";
13
13
  import { DocWhen } from "./doc/comment.jsx";
14
14
  import { Name } from "./Name.jsx";
15
- import { ParameterProps, Parameters } from "./parameters/parameters.jsx";
16
15
  import { TypeParameterConstraints } from "./type-parameters/type-parameter-constraints.jsx";
17
16
  import { TypeParameterProps } from "./type-parameters/type-parameter.jsx";
18
17
  import { TypeParameters } from "./type-parameters/type-parameters.jsx";
@@ -150,84 +149,3 @@ export function ClassDeclaration(props: ClassDeclarationProps) {
150
149
  </core.Declaration>
151
150
  );
152
151
  }
153
-
154
- export interface ClassConstructorProps extends AccessModifiers {
155
- parameters?: Array<ParameterProps>;
156
- refkey?: core.Refkey;
157
- symbol?: core.OutputSymbol;
158
- children?: core.Children;
159
- }
160
-
161
- // a C# class constructor
162
- export function ClassConstructor(props: ClassConstructorProps) {
163
- const scope = useCSharpScope();
164
- if (scope.kind !== "member" || scope.name !== "class-decl") {
165
- throw new Error(
166
- "can't define a class constructor outside of a class-decl scope",
167
- );
168
- }
169
-
170
- // fetch the class name from the scope
171
- const name = useCSharpNamePolicy().getName(scope.owner!.name, "class-method");
172
- const ctorSymbol = new CSharpOutputSymbol(name, {
173
- scope,
174
- refkeys: props.refkey ?? core.refkey(name),
175
- });
176
-
177
- // scope for ctor declaration
178
- const ctorDeclScope = new CSharpMemberScope("constructor-decl", {
179
- owner: ctorSymbol,
180
- });
181
-
182
- const modifiers = computeModifiersPrefix([getAccessModifier(props)]);
183
-
184
- // note that scope wraps the ctor decl so that the params get the correct scope
185
- return (
186
- <core.Declaration symbol={ctorSymbol}>
187
- <core.Scope value={ctorDeclScope}>
188
- {modifiers}
189
- <Name />
190
- <Parameters parameters={props.parameters} />
191
- <core.Block newline>{props.children}</core.Block>
192
- </core.Scope>
193
- </core.Declaration>
194
- );
195
- }
196
-
197
- // properties for creating a class member
198
- export interface ClassMemberProps extends AccessModifiers {
199
- name: string;
200
- type: core.Children;
201
- refkey?: core.Refkey;
202
- /** Doc comment */
203
- doc?: core.Children;
204
- }
205
-
206
- // a C# class member (i.e. a field within a class like "private int count")
207
- export function ClassMember(props: ClassMemberProps) {
208
- let nameElement: CSharpElements = "class-member-private";
209
- if (props.public) {
210
- nameElement = "class-member-public";
211
- }
212
- const name = useCSharpNamePolicy().getName(props.name, nameElement);
213
- const scope = useCSharpScope();
214
- if (scope.kind !== "member" || scope.name !== "class-decl") {
215
- throw new Error(
216
- "can't define a class member outside of a class-decl scope",
217
- );
218
- }
219
-
220
- const memberSymbol = new CSharpOutputSymbol(name, {
221
- scope,
222
- refkeys: props.refkey ?? core.refkey(props.name),
223
- });
224
-
225
- const modifiers = computeModifiersPrefix([getAccessModifier(props)]);
226
- return (
227
- <core.Declaration symbol={memberSymbol}>
228
- <DocWhen doc={props.doc} />
229
- {modifiers}
230
- {props.type} <Name />
231
- </core.Declaration>
232
- );
233
- }
@@ -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
+ }
@@ -0,0 +1,24 @@
1
+ import { StatementList } 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 { Field } from "./field.jsx";
6
+
7
+ it("declares some field", () => {
8
+ expect(
9
+ <TestNamespace>
10
+ <ClassDeclaration public name="TestClass">
11
+ <StatementList>
12
+ <Field public name="MemberOne" type="string" />
13
+ <Field private name="MemberTwo" type="int" />
14
+ </StatementList>
15
+ </ClassDeclaration>
16
+ </TestNamespace>,
17
+ ).toRenderTo(`
18
+ public class TestClass
19
+ {
20
+ public string MemberOne;
21
+ private int memberTwo;
22
+ }
23
+ `);
24
+ });
@@ -0,0 +1,50 @@
1
+ import { Children, Declaration, Name, refkey, Refkey } from "@alloy-js/core";
2
+ import {
3
+ AccessModifiers,
4
+ computeModifiersPrefix,
5
+ getAccessModifier,
6
+ } from "../../modifiers.js";
7
+ import { CSharpElements, useCSharpNamePolicy } from "../../name-policy.js";
8
+ import { CSharpOutputSymbol } from "../../symbols/csharp-output-symbol.js";
9
+ import { useCSharpScope } from "../../symbols/scopes.js";
10
+ import { DocWhen } from "../doc/comment.jsx";
11
+
12
+ export interface FieldProps extends AccessModifiers {
13
+ name: string;
14
+ type: Children;
15
+ refkey?: Refkey;
16
+ /** Doc comment */
17
+ doc?: Children;
18
+ }
19
+
20
+ /** Render a c# field */
21
+ export function Field(props: FieldProps) {
22
+ let nameElement: CSharpElements = "class-member-private";
23
+ if (props.public) {
24
+ nameElement = "class-member-public";
25
+ }
26
+ const name = useCSharpNamePolicy().getName(props.name, nameElement);
27
+ const scope = useCSharpScope();
28
+ if (
29
+ scope.kind !== "member" ||
30
+ (scope.name !== "class-decl" && scope.name !== "struct-decl")
31
+ ) {
32
+ throw new Error(
33
+ "can't define a class member outside of a class or struct scope",
34
+ );
35
+ }
36
+
37
+ const memberSymbol = new CSharpOutputSymbol(name, {
38
+ scope,
39
+ refkeys: props.refkey ?? refkey(props.name),
40
+ });
41
+
42
+ const modifiers = computeModifiersPrefix([getAccessModifier(props)]);
43
+ return (
44
+ <Declaration symbol={memberSymbol}>
45
+ <DocWhen doc={props.doc} />
46
+ {modifiers}
47
+ {props.type} <Name />
48
+ </Declaration>
49
+ );
50
+ }
@@ -1,13 +1,15 @@
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";
7
7
  export * from "./EnumDeclaration.jsx";
8
+ export * from "./field/field.jsx";
8
9
  export * from "./interface/declaration.js";
9
10
  export * from "./interface/method.js";
10
11
  export * from "./interface/property.js";
12
+ export * from "./method/method.jsx";
11
13
  export * from "./Name.js";
12
14
  export * from "./Namespace.js";
13
15
  export * from "./parameters/parameters.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(`
@@ -150,9 +145,9 @@ it("use expression body form", () => {
150
145
  expect(
151
146
  <TestNamespace>
152
147
  <ClassDeclaration name="Test">
153
- <ClassMethod name="Method" doc="This is a test" expression>
148
+ <Method name="Method" doc="This is a test" expression>
154
149
  this.MyProperty.Value;
155
- </ClassMethod>
150
+ </Method>
156
151
  </ClassDeclaration>
157
152
  </TestNamespace>,
158
153
  ).toRenderTo(`
@@ -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;
@@ -105,11 +103,16 @@ export interface ClassMethodProps
105
103
  }
106
104
 
107
105
  // a C# class method
108
- export function ClassMethod(props: ClassMethodProps) {
106
+ export function Method(props: MethodProps) {
109
107
  const name = useCSharpNamePolicy().getName(props.name, "class-method");
110
108
  const scope = useCSharpScope();
111
- if (scope.kind !== "member" || scope.name !== "class-decl") {
112
- 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
+ );
113
116
  }
114
117
 
115
118
  const methodSymbol = new CSharpOutputSymbol(name, {
@@ -2,9 +2,9 @@ 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);
6
- export const ClassMember = core.stc(base.ClassMember);
7
- export const ClassMethod = core.stc(base.ClassMethod);
5
+ export const Constructor = core.stc(base.Constructor);
6
+ export const Field = core.stc(base.Field);
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);
@@ -1,7 +1,10 @@
1
- import { List, refkey } from "@alloy-js/core";
1
+ import { List, refkey, StatementList } from "@alloy-js/core";
2
2
  import { describe, expect, it } from "vitest";
3
3
  import { TestNamespace } from "../../../test/utils.jsx";
4
4
  import { Attribute } from "../attributes/attributes.jsx";
5
+ import { Constructor } from "../constructor/constructor.jsx";
6
+ import { Field } from "../field/field.jsx";
7
+ import { Method } from "../method/method.jsx";
5
8
  import { Property } from "../property/property.jsx";
6
9
  import { SourceFile } from "../SourceFile.jsx";
7
10
  import { TypeParameterProps } from "../type-parameters/type-parameter.jsx";
@@ -135,3 +138,62 @@ it("specify attributes", () => {
135
138
  struct Test;
136
139
  `);
137
140
  });
141
+
142
+ it("define methods", () => {
143
+ expect(
144
+ <TestNamespace>
145
+ <StructDeclaration name="Test">
146
+ <Method name="MethodOne" />
147
+ </StructDeclaration>
148
+ </TestNamespace>,
149
+ ).toRenderTo(`
150
+ struct Test
151
+ {
152
+ void MethodOne() {}
153
+ }
154
+ `);
155
+ });
156
+
157
+ it("define constructor", () => {
158
+ expect(
159
+ <TestNamespace>
160
+ <StructDeclaration name="Test">
161
+ <Constructor public />
162
+ </StructDeclaration>
163
+ </TestNamespace>,
164
+ ).toRenderTo(`
165
+ struct Test
166
+ {
167
+ public Test() {}
168
+ }
169
+ `);
170
+ });
171
+
172
+ it("defines fields", () => {
173
+ expect(
174
+ <TestNamespace>
175
+ <StructDeclaration public name="TestClass">
176
+ <StatementList>
177
+ <Field public name="MemberOne" type="string" />
178
+ <Field private name="MemberTwo" type="int" />
179
+ </StatementList>
180
+ </StructDeclaration>
181
+ </TestNamespace>,
182
+ ).toRenderTo(`
183
+ public struct TestClass
184
+ {
185
+ public string MemberOne;
186
+ private int memberTwo;
187
+ }
188
+ `);
189
+ });
190
+
191
+ it("define multiple interface types", () => {
192
+ expect(
193
+ <TestNamespace>
194
+ <StructDeclaration name="Test" interfaceTypes={["Foo", "Bar"]} />
195
+ </TestNamespace>,
196
+ ).toRenderTo(`
197
+ struct Test : Foo, Bar;
198
+ `);
199
+ });
@@ -1,4 +1,5 @@
1
1
  import * as core from "@alloy-js/core";
2
+ import { join } from "@alloy-js/core";
2
3
  import {
3
4
  AccessModifiers,
4
5
  computeModifiersPrefix,
@@ -71,6 +72,9 @@ export interface StructDeclarationProps
71
72
  * ```
72
73
  */
73
74
  attributes?: AttributesProp;
75
+
76
+ /** Interfaces this struct implements */
77
+ interfaceTypes?: core.Children[];
74
78
  }
75
79
 
76
80
  /**
@@ -108,6 +112,12 @@ export function StructDeclaration(props: StructDeclarationProps) {
108
112
  getAccessModifier(props),
109
113
  getStructModifiers(props),
110
114
  ]);
115
+
116
+ const base =
117
+ props.interfaceTypes && props.interfaceTypes.length > 0 ?
118
+ <> : {join(props.interfaceTypes, { joiner: ", " })}</>
119
+ : null;
120
+
111
121
  return (
112
122
  <core.Declaration symbol={thisStructSymbol}>
113
123
  <DocWhen doc={props.doc} />
@@ -116,6 +126,7 @@ export function StructDeclaration(props: StructDeclarationProps) {
116
126
  {props.typeParameters && (
117
127
  <TypeParameters parameters={props.typeParameters} />
118
128
  )}
129
+ {base}
119
130
  {props.typeParameters && (
120
131
  <TypeParameterConstraints parameters={props.typeParameters} />
121
132
  )}