@alloy-js/csharp 0.16.0 → 0.18.0-dev.10

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 (130) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/src/components/ClassDeclaration.d.ts +57 -0
  3. package/dist/src/components/ClassDeclaration.d.ts.map +1 -0
  4. package/dist/src/components/{Class.js → ClassDeclaration.js} +58 -69
  5. package/dist/src/components/ClassMethod.d.ts +25 -0
  6. package/dist/src/components/ClassMethod.d.ts.map +1 -0
  7. package/dist/src/components/ClassMethod.js +60 -0
  8. package/dist/src/components/Declaration.d.ts.map +1 -1
  9. package/dist/src/components/Declaration.js +4 -2
  10. package/dist/src/components/EnumDeclaration.d.ts +34 -0
  11. package/dist/src/components/EnumDeclaration.d.ts.map +1 -0
  12. package/dist/src/components/{Enum.js → EnumDeclaration.js} +36 -14
  13. package/dist/src/components/Namespace.d.ts.map +1 -1
  14. package/dist/src/components/Namespace.js +2 -2
  15. package/dist/src/components/Parameters.d.ts.map +1 -1
  16. package/dist/src/components/Parameters.js +3 -3
  17. package/dist/src/components/doc/comment.d.ts +70 -0
  18. package/dist/src/components/doc/comment.d.ts.map +1 -0
  19. package/dist/src/components/doc/comment.js +88 -0
  20. package/dist/src/components/doc/comment.test.d.ts +2 -0
  21. package/dist/src/components/doc/comment.test.d.ts.map +1 -0
  22. package/dist/src/components/doc/comment.test.js +348 -0
  23. package/dist/src/components/doc/from-markdown.d.ts +6 -0
  24. package/dist/src/components/doc/from-markdown.d.ts.map +1 -0
  25. package/dist/src/components/doc/from-markdown.js +58 -0
  26. package/dist/src/components/doc/from-markdown.test.d.ts +2 -0
  27. package/dist/src/components/doc/from-markdown.test.d.ts.map +1 -0
  28. package/dist/src/components/doc/from-markdown.test.js +83 -0
  29. package/dist/src/components/index.d.ts +7 -2
  30. package/dist/src/components/index.d.ts.map +1 -1
  31. package/dist/src/components/index.js +7 -2
  32. package/dist/src/components/interface/declaration.d.ts +34 -0
  33. package/dist/src/components/interface/declaration.d.ts.map +1 -0
  34. package/dist/src/components/interface/declaration.js +90 -0
  35. package/dist/src/components/interface/declaration.test.d.ts +2 -0
  36. package/dist/src/components/interface/declaration.test.d.ts.map +1 -0
  37. package/dist/src/components/interface/declaration.test.js +69 -0
  38. package/dist/src/components/interface/method.d.ts +18 -0
  39. package/dist/src/components/interface/method.d.ts.map +1 -0
  40. package/dist/src/components/interface/method.js +59 -0
  41. package/dist/src/components/interface/method.test.d.ts +2 -0
  42. package/dist/src/components/interface/method.test.d.ts.map +1 -0
  43. package/dist/src/components/interface/method.test.js +131 -0
  44. package/dist/src/components/interface/property.d.ts +21 -0
  45. package/dist/src/components/interface/property.d.ts.map +1 -0
  46. package/dist/src/components/interface/property.js +59 -0
  47. package/dist/src/components/interface/property.test.d.ts +2 -0
  48. package/dist/src/components/interface/property.test.d.ts.map +1 -0
  49. package/dist/src/components/interface/property.test.js +165 -0
  50. package/dist/src/components/stc/index.d.ts +2 -2
  51. package/dist/src/components/stc/index.d.ts.map +1 -1
  52. package/dist/src/components/stc/index.js +2 -2
  53. package/dist/src/modifiers.d.ts +13 -4
  54. package/dist/src/modifiers.d.ts.map +1 -1
  55. package/dist/src/modifiers.js +13 -27
  56. package/dist/src/name-policy.d.ts +1 -1
  57. package/dist/src/name-policy.d.ts.map +1 -1
  58. package/dist/src/name-policy.js +1 -0
  59. package/dist/src/symbols/csharp-output-symbol.d.ts +4 -4
  60. package/dist/src/symbols/csharp-output-symbol.d.ts.map +1 -1
  61. package/dist/src/symbols/csharp-output-symbol.js +13 -13
  62. package/dist/src/symbols/scopes.d.ts +6 -8
  63. package/dist/src/symbols/scopes.d.ts.map +1 -1
  64. package/dist/src/symbols/scopes.js +14 -19
  65. package/dist/test/class-declaration.test.d.ts +2 -0
  66. package/dist/test/class-declaration.test.d.ts.map +1 -0
  67. package/dist/test/{class.test.js → class-declaration.test.js} +123 -73
  68. package/dist/test/class-method.test.d.ts +2 -0
  69. package/dist/test/class-method.test.d.ts.map +1 -0
  70. package/dist/test/class-method.test.js +161 -0
  71. package/dist/test/enum.test.js +12 -12
  72. package/dist/test/namespace.test.js +8 -8
  73. package/dist/test/project-directory.test.d.ts +2 -0
  74. package/dist/test/project-directory.test.d.ts.map +1 -0
  75. package/dist/test/{projectdirectory.test.js → project-directory.test.js} +8 -8
  76. package/dist/test/sourcefile.test.js +4 -4
  77. package/dist/test/using.test.js +9 -9
  78. package/dist/test/utils.d.ts +3 -0
  79. package/dist/test/utils.d.ts.map +1 -1
  80. package/dist/test/utils.js +15 -0
  81. package/dist/test/vitest.setup.d.ts +2 -0
  82. package/dist/test/vitest.setup.d.ts.map +1 -0
  83. package/dist/test/vitest.setup.js +1 -0
  84. package/dist/tsconfig.tsbuildinfo +1 -1
  85. package/package.json +8 -7
  86. package/src/components/{Class.tsx → ClassDeclaration.tsx} +84 -98
  87. package/src/components/ClassMethod.tsx +94 -0
  88. package/src/components/Declaration.tsx +5 -2
  89. package/src/components/EnumDeclaration.tsx +99 -0
  90. package/src/components/Namespace.tsx +2 -6
  91. package/src/components/Parameters.tsx +2 -3
  92. package/src/components/doc/comment.test.tsx +337 -0
  93. package/src/components/doc/comment.tsx +152 -0
  94. package/src/components/doc/from-markdown.test.tsx +103 -0
  95. package/src/components/doc/from-markdown.tsx +58 -0
  96. package/src/components/index.ts +7 -2
  97. package/src/components/interface/declaration.test.tsx +56 -0
  98. package/src/components/interface/declaration.tsx +109 -0
  99. package/src/components/interface/method.test.tsx +120 -0
  100. package/src/components/interface/method.tsx +82 -0
  101. package/src/components/interface/property.test.tsx +144 -0
  102. package/src/components/interface/property.tsx +90 -0
  103. package/src/components/stc/index.ts +2 -2
  104. package/src/modifiers.ts +32 -37
  105. package/src/name-policy.ts +2 -0
  106. package/src/symbols/csharp-output-symbol.ts +13 -18
  107. package/src/symbols/reference.ts +1 -1
  108. package/src/symbols/scopes.ts +15 -34
  109. package/temp/api.json +3470 -649
  110. package/test/{class.test.tsx → class-declaration.test.tsx} +103 -99
  111. package/test/class-method.test.tsx +147 -0
  112. package/test/enum.test.tsx +11 -11
  113. package/test/namespace.test.tsx +4 -4
  114. package/test/{projectdirectory.test.tsx → project-directory.test.tsx} +4 -4
  115. package/test/sourcefile.test.tsx +2 -2
  116. package/test/using.test.tsx +9 -9
  117. package/test/utils.tsx +9 -0
  118. package/test/vitest.setup.ts +1 -0
  119. package/tsconfig.json +2 -1
  120. package/tsdoc-metadata.json +1 -1
  121. package/vitest.config.ts +3 -0
  122. package/dist/src/components/Class.d.ts +0 -36
  123. package/dist/src/components/Class.d.ts.map +0 -1
  124. package/dist/src/components/Enum.d.ts +0 -15
  125. package/dist/src/components/Enum.d.ts.map +0 -1
  126. package/dist/test/class.test.d.ts +0 -2
  127. package/dist/test/class.test.d.ts.map +0 -1
  128. package/dist/test/projectdirectory.test.d.ts +0 -2
  129. package/dist/test/projectdirectory.test.d.ts.map +0 -1
  130. package/src/components/Enum.tsx +0 -78
@@ -1,45 +1,81 @@
1
1
  import * as core from "@alloy-js/core";
2
2
  import {
3
- AccessModifier,
3
+ AccessModifiers,
4
+ computeModifiersPrefix,
4
5
  getAccessModifier,
5
- getMethodModifier,
6
- MethodModifier,
6
+ makeModifiers,
7
7
  } from "../modifiers.js";
8
8
  import { CSharpElements, useCSharpNamePolicy } from "../name-policy.js";
9
9
  import { CSharpOutputSymbol } from "../symbols/csharp-output-symbol.js";
10
- import { createCSharpMemberScope, useCSharpScope } from "../symbols/scopes.js";
11
- import { Name } from "./Name.js";
12
- import { ParameterProps, Parameters } from "./Parameters.js";
10
+ import { CSharpMemberScope, useCSharpScope } from "../symbols/scopes.js";
11
+ import { Name } from "./Name.jsx";
12
+ import { ParameterProps, Parameters } from "./Parameters.jsx";
13
+ import { DocWhen } from "./doc/comment.jsx";
14
+
15
+ export interface ClassModifiers {
16
+ readonly abstract?: boolean;
17
+ readonly partial?: boolean;
18
+ readonly sealed?: boolean;
19
+ readonly static?: boolean;
20
+ }
21
+
22
+ const getClassModifiers = makeModifiers<ClassModifiers>([
23
+ "abstract",
24
+ "partial",
25
+ "sealed",
26
+ "static",
27
+ ]);
13
28
 
14
29
  // properties for creating a class
15
- export interface ClassProps extends Omit<core.DeclarationProps, "nameKind"> {
30
+ export interface ClassDeclarationProps
31
+ extends Omit<core.DeclarationProps, "nameKind">,
32
+ AccessModifiers,
33
+ ClassModifiers {
16
34
  name: string;
35
+ /** Doc comment */
36
+ doc?: core.Children;
17
37
  refkey?: core.Refkey;
18
- accessModifier?: AccessModifier;
19
38
  typeParameters?: Record<string, core.Refkey>;
20
39
  }
21
40
 
22
- // a C# class declaration
23
- export function Class(props: ClassProps) {
41
+ /**
42
+ * CSharp class declaration.
43
+ * @example
44
+ * ```tsx
45
+ * <ClassDeclaration public name="MyClass">
46
+ * <ClassMember public name="MyField" type="int" />
47
+ * <ClassConstructor>
48
+ * <Parameter name="value" type="int" />
49
+ * this.MyField = value;
50
+ * </ClassConstructor>
51
+ * </ClassDeclaration>
52
+ * ```
53
+ * This will produce:
54
+ * ```csharp
55
+ * public class MyClass
56
+ * {
57
+ * public int MyField;
58
+ * public MyClass(int value)
59
+ * {
60
+ * this.MyField = value;
61
+ * }
62
+ * }
63
+ * ```
64
+ */
65
+ export function ClassDeclaration(props: ClassDeclarationProps) {
24
66
  const name = useCSharpNamePolicy().getName(props.name!, "class");
25
- const scope = useCSharpScope();
26
67
 
27
- const thisClassSymbol = scope.binder.createSymbol<CSharpOutputSymbol>({
28
- name,
29
- scope,
30
- refkey: props.refkey,
68
+ const thisClassSymbol = new CSharpOutputSymbol(name, {
69
+ refkeys: props.refkey,
31
70
  });
32
71
 
33
72
  // this creates a new scope for the class definition.
34
73
  // members will automatically "inherit" this scope so
35
74
  // that refkeys to them will produce the fully-qualified
36
75
  // name e.g. Foo.Bar.
37
- const thisClassScope = createCSharpMemberScope(
38
- scope.binder,
39
- scope,
40
- thisClassSymbol,
41
- "class-decl",
42
- );
76
+ const thisClassScope = new CSharpMemberScope("class-decl", {
77
+ owner: thisClassSymbol,
78
+ });
43
79
 
44
80
  let typeParams: core.Children;
45
81
  if (props.typeParameters) {
@@ -50,10 +86,9 @@ export function Class(props: ClassProps) {
50
86
  );
51
87
  // create a symbol for each type param so its
52
88
  // refkey resolves to the type param's name
53
- scope.binder.createSymbol<CSharpOutputSymbol>({
54
- name: entry[0],
89
+ new CSharpOutputSymbol(entry[0], {
55
90
  scope: thisClassScope,
56
- refkey: entry[1],
91
+ refkeys: entry[1],
57
92
  });
58
93
  }
59
94
  typeParams = (
@@ -67,9 +102,14 @@ export function Class(props: ClassProps) {
67
102
  );
68
103
  }
69
104
 
105
+ const modifiers = computeModifiersPrefix([
106
+ getAccessModifier(props),
107
+ getClassModifiers(props),
108
+ ]);
70
109
  return (
71
110
  <core.Declaration symbol={thisClassSymbol}>
72
- {getAccessModifier(props.accessModifier)}class <Name />
111
+ <DocWhen doc={props.doc} />
112
+ {modifiers}class <Name />
73
113
  {typeParams}
74
114
  {!props.children && ";"}
75
115
  {props.children && (
@@ -81,8 +121,7 @@ export function Class(props: ClassProps) {
81
121
  );
82
122
  }
83
123
 
84
- export interface ClassConstructorProps {
85
- accessModifier?: AccessModifier;
124
+ export interface ClassConstructorProps extends AccessModifiers {
86
125
  parameters?: Array<ParameterProps>;
87
126
  refkey?: core.Refkey;
88
127
  symbol?: core.OutputSymbol;
@@ -99,22 +138,19 @@ export function ClassConstructor(props: ClassConstructorProps) {
99
138
  }
100
139
 
101
140
  // fetch the class name from the scope
102
- const name = useCSharpNamePolicy().getName(scope.owner.name, "class-method");
103
- const ctorSymbol = scope.binder.createSymbol<CSharpOutputSymbol>({
104
- name: name,
141
+ const name = useCSharpNamePolicy().getName(scope.owner!.name, "class-method");
142
+ const ctorSymbol = new CSharpOutputSymbol(name, {
105
143
  scope,
106
- refkey: props.refkey ?? core.refkey(name),
144
+ refkeys: props.refkey ?? core.refkey(name),
107
145
  });
108
146
 
109
147
  // scope for ctor declaration
110
- const ctorDeclScope = createCSharpMemberScope(
111
- scope.binder,
112
- scope,
113
- ctorSymbol,
114
- "constructor-decl",
115
- );
148
+ const ctorDeclScope = new CSharpMemberScope("constructor-decl", {
149
+ owner: ctorSymbol,
150
+ });
151
+
152
+ const modifiers = computeModifiersPrefix([getAccessModifier(props)]);
116
153
 
117
- const accessModifier = getAccessModifier(props.accessModifier);
118
154
  const params =
119
155
  props.parameters ? <Parameters parameters={props.parameters} /> : "";
120
156
 
@@ -122,7 +158,7 @@ export function ClassConstructor(props: ClassConstructorProps) {
122
158
  return (
123
159
  <core.Declaration symbol={ctorSymbol}>
124
160
  <core.Scope value={ctorDeclScope}>
125
- {accessModifier}
161
+ {modifiers}
126
162
  <Name />({params})<core.Block newline>{props.children}</core.Block>
127
163
  </core.Scope>
128
164
  </core.Declaration>
@@ -130,17 +166,18 @@ export function ClassConstructor(props: ClassConstructorProps) {
130
166
  }
131
167
 
132
168
  // properties for creating a class member
133
- export interface ClassMemberProps {
169
+ export interface ClassMemberProps extends AccessModifiers {
134
170
  name: string;
135
171
  type: core.Children;
136
- accessModifier?: AccessModifier;
137
172
  refkey?: core.Refkey;
173
+ /** Doc comment */
174
+ doc?: core.Children;
138
175
  }
139
176
 
140
177
  // a C# class member (i.e. a field within a class like "private int count")
141
178
  export function ClassMember(props: ClassMemberProps) {
142
179
  let nameElement: CSharpElements = "class-member-private";
143
- if (props.accessModifier === "public") {
180
+ if (props.public) {
144
181
  nameElement = "class-member-public";
145
182
  }
146
183
  const name = useCSharpNamePolicy().getName(props.name, nameElement);
@@ -151,68 +188,17 @@ export function ClassMember(props: ClassMemberProps) {
151
188
  );
152
189
  }
153
190
 
154
- const memberSymbol = scope.binder.createSymbol<CSharpOutputSymbol>({
155
- name: name,
191
+ const memberSymbol = new CSharpOutputSymbol(name, {
156
192
  scope,
157
- refkey: props.refkey ?? core.refkey(props.name),
193
+ refkeys: props.refkey ?? core.refkey(props.name),
158
194
  });
159
195
 
196
+ const modifiers = computeModifiersPrefix([getAccessModifier(props)]);
160
197
  return (
161
198
  <core.Declaration symbol={memberSymbol}>
162
- {getAccessModifier(props.accessModifier)}
199
+ <DocWhen doc={props.doc} />
200
+ {modifiers}
163
201
  {props.type} <Name />
164
202
  </core.Declaration>
165
203
  );
166
204
  }
167
-
168
- // properties for creating a method
169
- export interface ClassMethodProps {
170
- name: string;
171
- refkey?: core.Refkey;
172
- children?: core.Children;
173
- accessModifier?: AccessModifier;
174
- methodModifier?: MethodModifier;
175
- parameters?: Array<ParameterProps>;
176
- returns?: core.Children;
177
- }
178
-
179
- // a C# class method
180
- export function ClassMethod(props: ClassMethodProps) {
181
- const name = useCSharpNamePolicy().getName(props.name!, "class-method");
182
- const scope = useCSharpScope();
183
- if (scope.kind !== "member" || scope.name !== "class-decl") {
184
- throw new Error("can't define a class method outside of a class scope");
185
- }
186
-
187
- const methodSymbol = scope.binder.createSymbol<CSharpOutputSymbol>({
188
- name: name,
189
- scope,
190
- refkey: props.refkey ?? core.refkey(props.name),
191
- });
192
-
193
- // scope for method declaration
194
- const methodScope = createCSharpMemberScope(
195
- scope.binder,
196
- scope,
197
- methodSymbol,
198
- "method-decl",
199
- );
200
-
201
- const accessModifier = getAccessModifier(props.accessModifier);
202
- const methodModifier = getMethodModifier(props.methodModifier);
203
- const params =
204
- props.parameters ? <Parameters parameters={props.parameters} /> : "";
205
- const returns = props.returns ?? "void";
206
-
207
- // note that scope wraps the method decl so that the params get the correct scope
208
- return (
209
- <core.Declaration symbol={methodSymbol}>
210
- <core.Scope value={methodScope}>
211
- {accessModifier}
212
- {methodModifier}
213
- {returns} <Name />({params})
214
- <core.Block newline>{props.children}</core.Block>
215
- </core.Scope>
216
- </core.Declaration>
217
- );
218
- }
@@ -0,0 +1,94 @@
1
+ import {
2
+ Block,
3
+ Children,
4
+ MemberDeclaration,
5
+ refkey,
6
+ Refkey,
7
+ Scope,
8
+ } from "@alloy-js/core";
9
+ import {
10
+ AccessModifiers,
11
+ computeModifiersPrefix,
12
+ getAccessModifier,
13
+ getAsyncModifier,
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 { ParameterProps, Parameters } from "./Parameters.jsx";
20
+ import { DocWhen } from "./doc/comment.jsx";
21
+
22
+ /** Method modifiers. Can only be one. */
23
+ export interface ClassMethodModifiers {
24
+ readonly abstract?: boolean;
25
+ readonly sealed?: boolean;
26
+ readonly static?: boolean;
27
+ readonly virtual?: boolean;
28
+ }
29
+
30
+ const getMethodModifier = makeModifiers<ClassMethodModifiers>([
31
+ "abstract",
32
+ "sealed",
33
+ "static",
34
+ "virtual",
35
+ ]);
36
+
37
+ // properties for creating a method
38
+ export interface ClassMethodProps
39
+ extends AccessModifiers,
40
+ ClassMethodModifiers {
41
+ name: string;
42
+ refkey?: Refkey;
43
+ children?: Children;
44
+ parameters?: Array<ParameterProps>;
45
+ returns?: Children;
46
+
47
+ /**
48
+ * If true, the method will be declared as an async method.
49
+ */
50
+ async?: boolean;
51
+
52
+ /** Doc comment */
53
+ doc?: Children;
54
+ }
55
+
56
+ // a C# class method
57
+ export function ClassMethod(props: ClassMethodProps) {
58
+ const name = useCSharpNamePolicy().getName(props.name, "class-method");
59
+ const scope = useCSharpScope();
60
+ if (scope.kind !== "member" || scope.name !== "class-decl") {
61
+ throw new Error("can't define a class method outside of a class scope");
62
+ }
63
+
64
+ const methodSymbol = new CSharpOutputSymbol(name, {
65
+ scope,
66
+ refkeys: props.refkey ?? refkey(props.name),
67
+ });
68
+
69
+ // scope for method declaration
70
+ const methodScope = new CSharpMemberScope("method-decl", {
71
+ owner: methodSymbol,
72
+ });
73
+
74
+ const params =
75
+ props.parameters ? <Parameters parameters={props.parameters} /> : "";
76
+ const returns = props.returns ?? (props.async ? "Task" : "void");
77
+
78
+ const modifiers = computeModifiersPrefix([
79
+ getAccessModifier(props),
80
+ getMethodModifier(props),
81
+ getAsyncModifier(props.async),
82
+ ]);
83
+ // note that scope wraps the method decl so that the params get the correct scope
84
+ return (
85
+ <MemberDeclaration symbol={methodSymbol}>
86
+ <Scope value={methodScope}>
87
+ <DocWhen doc={props.doc} />
88
+ {modifiers}
89
+ {returns} {name}({params})
90
+ {props.abstract ? ";" : <Block newline>{props.children}</Block>}
91
+ </Scope>
92
+ </MemberDeclaration>
93
+ );
94
+ }
@@ -1,5 +1,5 @@
1
1
  import * as core from "@alloy-js/core";
2
- import { createCSharpSymbol } from "../symbols/csharp-output-symbol.js";
2
+ import { CSharpOutputSymbol } from "../symbols/csharp-output-symbol.js";
3
3
 
4
4
  // properties for creating a declaration
5
5
  export interface DeclarationProps {
@@ -10,6 +10,9 @@ export interface DeclarationProps {
10
10
 
11
11
  // declares a symbol in the program (class, enum, interface etc)
12
12
  export function Declaration(props: DeclarationProps) {
13
- const sym = createCSharpSymbol(props);
13
+ const sym = new CSharpOutputSymbol(props.name, {
14
+ refkeys: props.refkey,
15
+ });
16
+
14
17
  return <core.Declaration symbol={sym}>{props.children}</core.Declaration>;
15
18
  }
@@ -0,0 +1,99 @@
1
+ import * as core from "@alloy-js/core";
2
+ import {
3
+ AccessModifiers,
4
+ computeModifiersPrefix,
5
+ getAccessModifier,
6
+ } from "../modifiers.js";
7
+ import { useCSharpNamePolicy } from "../name-policy.js";
8
+ import { CSharpOutputSymbol } from "../symbols/csharp-output-symbol.js";
9
+ import { CSharpMemberScope, useCSharpScope } from "../symbols/scopes.js";
10
+ import { Name } from "./Name.jsx";
11
+
12
+ // properties for creating an enum
13
+ export interface EnumDeclarationProps extends AccessModifiers {
14
+ name: string;
15
+ refkey?: core.Refkey;
16
+ children?: core.Children;
17
+ }
18
+
19
+ /**
20
+ * A C# enum declaration
21
+ * @example
22
+ * ```tsx
23
+ * <EnumDeclaration public name="Color">
24
+ * <EnumMember name="Red" />
25
+ * <EnumMember name="Green" />
26
+ * <EnumMember name="Blue" />
27
+ * </EnumDeclaration>
28
+ * ```
29
+ * This will produce:
30
+ * ```csharp
31
+ * public enum Color
32
+ * {
33
+ * Red,
34
+ * Green,
35
+ * Blue
36
+ * }
37
+ * ```
38
+ */
39
+ export function EnumDeclaration(props: EnumDeclarationProps) {
40
+ const name = useCSharpNamePolicy().getName(props.name!, "enum");
41
+ const scope = useCSharpScope();
42
+
43
+ const thisEnumSymbol = new CSharpOutputSymbol(name, {
44
+ scope,
45
+ refkeys: props.refkey ?? core.refkey(props.name),
46
+ });
47
+
48
+ // this creates a new scope for the enum definition.
49
+ // members will automatically "inherit" this scope so
50
+ // that refkeys to them will produce the fully-qualified
51
+ // name e.g. Foo.Bar.
52
+ const thisEnumScope = new CSharpMemberScope("enum-decl", {
53
+ parent: scope,
54
+ owner: thisEnumSymbol,
55
+ });
56
+
57
+ const modifiers = computeModifiersPrefix([getAccessModifier(props)]);
58
+
59
+ if (thisEnumScope.owner)
60
+ return (
61
+ <core.Declaration symbol={thisEnumSymbol}>
62
+ {modifiers}enum <Name />
63
+ {!props.children && ";"}
64
+ {props.children && (
65
+ <core.Scope value={thisEnumScope}>
66
+ <core.Block newline>{props.children}</core.Block>
67
+ </core.Scope>
68
+ )}
69
+ </core.Declaration>
70
+ );
71
+ }
72
+
73
+ // properties for creating a C# enum member
74
+ export interface EnumMemberProps {
75
+ name: string;
76
+ refkey?: core.Refkey;
77
+ }
78
+
79
+ // a member within a C# enum
80
+ export function EnumMember(props: EnumMemberProps) {
81
+ const scope = useCSharpScope();
82
+ if (scope.kind === "member" && scope.name !== "enum-decl") {
83
+ throw new Error(
84
+ "can't define an enum member outside of an enum-decl scope",
85
+ );
86
+ }
87
+
88
+ const name = useCSharpNamePolicy().getName(props.name, "enum-member");
89
+ const thisEnumValueSymbol = new CSharpOutputSymbol(name, {
90
+ scope,
91
+ refkeys: props.refkey ?? core.refkey(props.name),
92
+ });
93
+
94
+ return (
95
+ <core.Declaration symbol={thisEnumValueSymbol}>
96
+ <Name />
97
+ </core.Declaration>
98
+ );
99
+ }
@@ -1,5 +1,5 @@
1
1
  import * as core from "@alloy-js/core";
2
- import { createCSharpNamespaceScope } from "../symbols/scopes.js";
2
+ import { CSharpNamespaceScope } from "../symbols/scopes.js";
3
3
 
4
4
  // contains the info for the current namespace
5
5
  export interface NamespaceContext {
@@ -21,11 +21,7 @@ export interface NamespaceProps {
21
21
 
22
22
  // a C# namespace. contains one or more source files
23
23
  export function Namespace(props: NamespaceProps) {
24
- const scope = createCSharpNamespaceScope(
25
- core.useBinder(),
26
- core.useScope(),
27
- props.name,
28
- );
24
+ const scope = new CSharpNamespaceScope(props.name);
29
25
 
30
26
  const namespaceCtx: NamespaceContext = {
31
27
  name: props.name,
@@ -24,10 +24,9 @@ export function Parameter(props: ParameterProps) {
24
24
  );
25
25
  }
26
26
 
27
- const memberSymbol = scope.binder.createSymbol<CSharpOutputSymbol>({
28
- name: name,
27
+ const memberSymbol = new CSharpOutputSymbol(name, {
29
28
  scope,
30
- refkey: props.refkey ?? core.refkey(props.name),
29
+ refkeys: props.refkey ?? core.refkey(props.name),
31
30
  });
32
31
 
33
32
  return (