@alloy-js/csharp 0.21.0-dev.17 → 0.21.0-dev.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alloy-js/csharp",
3
- "version": "0.21.0-dev.17",
3
+ "version": "0.21.0-dev.18",
4
4
  "description": "Alloy components for CSharp language.",
5
5
  "exports": {
6
6
  ".": {
@@ -1,3 +1,4 @@
1
+ import { namekey } from "@alloy-js/core";
1
2
  import { expect, it } from "vitest";
2
3
  import { Attribute, AttributeList } from "./attributes.jsx";
3
4
 
@@ -7,6 +8,15 @@ it("define attribute", () => {
7
8
  `);
8
9
  });
9
10
 
11
+ it("define attribute whose name ending with 'Attribute'", () => {
12
+ expect(<Attribute name="TestAttribute" />).toRenderTo(`
13
+ [Test]
14
+ `);
15
+ expect(<Attribute name={namekey("TestAttribute")} />).toRenderTo(`
16
+ [Test]
17
+ `);
18
+ });
19
+
10
20
  it("define attribute with single arg", () => {
11
21
  expect(<Attribute name="Test" args={[`"abc"`]} />).toRenderTo(`
12
22
  [Test("abc")]
@@ -3,6 +3,7 @@ import {
3
3
  findKeyedChildren,
4
4
  For,
5
5
  Indent,
6
+ Refkey,
6
7
  taggedComponent,
7
8
  } from "@alloy-js/core";
8
9
 
@@ -54,7 +55,7 @@ function renderAttribute(attr: string | AttributeProps | Children): Children {
54
55
 
55
56
  export interface AttributeProps {
56
57
  /** Attribute name */
57
- name: Children;
58
+ name: string | Refkey;
58
59
 
59
60
  /** Argument */
60
61
  args?: Children[];
@@ -81,7 +82,7 @@ export const Attribute = taggedComponent(
81
82
  (props: AttributeProps) => {
82
83
  return (
83
84
  <group>
84
- [{props.name}
85
+ [{normalizeAttributeName(props.name)}
85
86
  {props.args && props.args.length > 0 && (
86
87
  <>
87
88
  (
@@ -98,3 +99,15 @@ export const Attribute = taggedComponent(
98
99
  );
99
100
  },
100
101
  );
102
+
103
+ function normalizeAttributeName(name: string | Refkey) {
104
+ const nameStr =
105
+ typeof name === "string" ? name
106
+ : typeof name === "object" && "name" in name ? name.name
107
+ : undefined;
108
+
109
+ if (nameStr !== undefined && nameStr.endsWith("Attribute")) {
110
+ return nameStr.substring(0, nameStr.length - "Attribute".length);
111
+ }
112
+ return name;
113
+ }
@@ -148,3 +148,40 @@ it("can attach attributes", () => {
148
148
  }
149
149
  `);
150
150
  });
151
+
152
+ it("can add modifiers: in | out | ref", () => {
153
+ expect(
154
+ <Wrapper>
155
+ <Method
156
+ name="MethodOne"
157
+ parameters={[
158
+ {
159
+ name: "param1",
160
+ type: "T1",
161
+ ref: true,
162
+ },
163
+ {
164
+ name: "param2",
165
+ type: "T2",
166
+ in: true,
167
+ },
168
+ {
169
+ name: "param3",
170
+ type: "T3",
171
+ out: true,
172
+ },
173
+ {
174
+ name: "param4",
175
+ type: "T4",
176
+ refReadonly: true,
177
+ },
178
+ ]}
179
+ />
180
+ </Wrapper>,
181
+ ).toRenderTo(`
182
+ public class TestClass
183
+ {
184
+ void MethodOne(ref T1 param1, in T2 param2, out T3 param3, ref readonly T4 param4) {}
185
+ }
186
+ `);
187
+ });
@@ -22,6 +22,27 @@ export interface ParameterProps {
22
22
 
23
23
  refkey?: Refkey;
24
24
 
25
+ /**
26
+ * Parameter modifier: The argument must be initialized before calling the method. The method can't assign a new value to the parameter. The compiler might create a temporary variable to hold a copy of the argument to in parameters.
27
+ * @see https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/method-parameters#in-parameter-modifier
28
+ * */
29
+ in?: boolean;
30
+ /**
31
+ * Parameter modifier: The calling method isn't required to initialize the argument before calling the method. The method must assign a value to the parameter.
32
+ * @see https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/method-parameters#out-parameter-modifier
33
+ * */
34
+ out?: boolean;
35
+ /**
36
+ * Parameter modifier: The argument must be initialized before calling the method. The method can assign a new value to the parameter, but isn't required to do so.
37
+ * @see https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/method-parameters#ref-parameter-modifier
38
+ */
39
+ ref?: boolean;
40
+ /**
41
+ * Parameter modifier: The argument must be initialized before calling the method. The method can't assign a new value to the parameter.
42
+ * @see https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/method-parameters#ref-readonly-modifier
43
+ */
44
+ refReadonly?: boolean;
45
+
25
46
  /**
26
47
  * Define attributes to attach
27
48
  * @example
@@ -48,9 +69,26 @@ export function Parameter(props: ParameterProps) {
48
69
  isNullable: props.optional,
49
70
  });
50
71
 
72
+ // Only one of in, out, ref, ref readonly can be specified
73
+ const modifiers: (keyof ParameterProps)[] = (
74
+ ["in", "out", "ref", "refReadonly"] as (keyof ParameterProps)[]
75
+ ).filter((k) => props[k]);
76
+
77
+ if (modifiers.length > 1) {
78
+ throw new Error(
79
+ `Only one of 'in', 'out', 'ref', 'ref readonly' can be specified for parameter '${
80
+ typeof props.name === "string" ? props.name : props.name.name
81
+ }'`,
82
+ );
83
+ }
84
+ const modifier =
85
+ modifiers.length === 0 ? ""
86
+ : modifiers[0] === "refReadonly" ? "ref readonly "
87
+ : modifiers[0] + " ";
51
88
  return (
52
89
  <Declaration symbol={memberSymbol}>
53
90
  <AttributeList attributes={props.attributes} endline />
91
+ <>{modifier}</>
54
92
  <TypeSlot>{props.type}</TypeSlot>
55
93
  {props.optional ? "?" : ""} <Name />
56
94
  {props.default ? code` = ${props.default}` : ""}
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  Binder,
3
3
  LibrarySymbolReference,
4
+ namekey,
4
5
  refkey,
5
6
  REFKEYABLE,
6
7
  TO_SYMBOL,
@@ -123,7 +124,7 @@ export function createLibrary<T extends Record<string, Descriptor>>(
123
124
  name,
124
125
  )! as NamespaceSymbol;
125
126
  } else {
126
- ownerSymbol = new NamespaceSymbol(name, ownerSymbol!, {
127
+ ownerSymbol = new NamespaceSymbol(namekey(name), ownerSymbol!, {
127
128
  binder,
128
129
  refkeys: refkey(),
129
130
  });
@@ -213,24 +214,33 @@ function createSymbolFromDescriptor(
213
214
  if (ownerSymbol.members.symbolNames.has(name)) {
214
215
  return ownerSymbol.members.symbolNames.get(name)! as NamespaceSymbol;
215
216
  }
216
- return new NamespaceSymbol(name, ownerSymbol as NamespaceSymbol, {
217
- binder,
218
- refkeys: refkey(),
219
- lazyMemberInitializer,
220
- });
217
+ return new NamespaceSymbol(
218
+ namekey(name),
219
+ ownerSymbol as NamespaceSymbol,
220
+ {
221
+ binder,
222
+ refkeys: refkey(),
223
+ lazyMemberInitializer,
224
+ },
225
+ );
221
226
  case "class":
222
227
  case "enum":
223
228
  case "interface":
224
229
  case "struct":
225
230
  case "record":
226
- return new NamedTypeSymbol(name, ownerSymbol.members, descriptor.kind, {
227
- binder,
228
- refkeys: refkey(),
229
- lazyMemberInitializer,
230
- });
231
+ return new NamedTypeSymbol(
232
+ namekey(name),
233
+ ownerSymbol.members,
234
+ descriptor.kind,
235
+ {
236
+ binder,
237
+ refkeys: refkey(),
238
+ lazyMemberInitializer,
239
+ },
240
+ );
231
241
  case "method":
232
242
  return new MethodSymbol(
233
- name,
243
+ namekey(name),
234
244
  ownerSymbol.members,
235
245
  descriptor.methodKind,
236
246
  {
@@ -240,7 +250,7 @@ function createSymbolFromDescriptor(
240
250
  );
241
251
  case "field":
242
252
  case "property":
243
- return new CSharpSymbol(name, ownerSymbol.members, {
253
+ return new CSharpSymbol(namekey(name), ownerSymbol.members, {
244
254
  binder,
245
255
  refkeys: refkey(),
246
256
  type:
@@ -252,7 +262,7 @@ function createSymbolFromDescriptor(
252
262
  lazyMemberInitializer,
253
263
  });
254
264
  case "generic":
255
- return new CSharpSymbol(name, ownerSymbol.members, {
265
+ return new CSharpSymbol(namekey(name), ownerSymbol.members, {
256
266
  binder,
257
267
  refkeys: refkey(),
258
268
  });
package/temp/api.json CHANGED
@@ -1857,10 +1857,14 @@
1857
1857
  "kind": "Content",
1858
1858
  "text": "name: "
1859
1859
  },
1860
+ {
1861
+ "kind": "Content",
1862
+ "text": "string | "
1863
+ },
1860
1864
  {
1861
1865
  "kind": "Reference",
1862
- "text": "Children",
1863
- "canonicalReference": "@alloy-js/core!Children:type"
1866
+ "text": "Refkey",
1867
+ "canonicalReference": "@alloy-js/core!Refkey:type"
1864
1868
  },
1865
1869
  {
1866
1870
  "kind": "Content",
@@ -1873,7 +1877,7 @@
1873
1877
  "name": "name",
1874
1878
  "propertyTypeTokenRange": {
1875
1879
  "startIndex": 1,
1876
- "endIndex": 2
1880
+ "endIndex": 3
1877
1881
  }
1878
1882
  }
1879
1883
  ],
@@ -13690,6 +13694,33 @@
13690
13694
  "endIndex": 2
13691
13695
  }
13692
13696
  },
13697
+ {
13698
+ "kind": "PropertySignature",
13699
+ "canonicalReference": "@alloy-js/csharp!ParameterProps#in:member",
13700
+ "docComment": "/**\n * Parameter modifier: The argument must be initialized before calling the method. The method can't assign a new value to the parameter. The compiler might create a temporary variable to hold a copy of the argument to in parameters.\n *\n * @see\n *\n * https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/method-parameters#in-parameter-modifier\n */\n",
13701
+ "excerptTokens": [
13702
+ {
13703
+ "kind": "Content",
13704
+ "text": "in?: "
13705
+ },
13706
+ {
13707
+ "kind": "Content",
13708
+ "text": "boolean"
13709
+ },
13710
+ {
13711
+ "kind": "Content",
13712
+ "text": ";"
13713
+ }
13714
+ ],
13715
+ "isReadonly": false,
13716
+ "isOptional": true,
13717
+ "releaseTag": "Public",
13718
+ "name": "in",
13719
+ "propertyTypeTokenRange": {
13720
+ "startIndex": 1,
13721
+ "endIndex": 2
13722
+ }
13723
+ },
13693
13724
  {
13694
13725
  "kind": "PropertySignature",
13695
13726
  "canonicalReference": "@alloy-js/csharp!ParameterProps#name:member",
@@ -13749,6 +13780,60 @@
13749
13780
  "endIndex": 2
13750
13781
  }
13751
13782
  },
13783
+ {
13784
+ "kind": "PropertySignature",
13785
+ "canonicalReference": "@alloy-js/csharp!ParameterProps#out:member",
13786
+ "docComment": "/**\n * Parameter modifier: The calling method isn't required to initialize the argument before calling the method. The method must assign a value to the parameter.\n *\n * @see\n *\n * https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/method-parameters#out-parameter-modifier\n */\n",
13787
+ "excerptTokens": [
13788
+ {
13789
+ "kind": "Content",
13790
+ "text": "out?: "
13791
+ },
13792
+ {
13793
+ "kind": "Content",
13794
+ "text": "boolean"
13795
+ },
13796
+ {
13797
+ "kind": "Content",
13798
+ "text": ";"
13799
+ }
13800
+ ],
13801
+ "isReadonly": false,
13802
+ "isOptional": true,
13803
+ "releaseTag": "Public",
13804
+ "name": "out",
13805
+ "propertyTypeTokenRange": {
13806
+ "startIndex": 1,
13807
+ "endIndex": 2
13808
+ }
13809
+ },
13810
+ {
13811
+ "kind": "PropertySignature",
13812
+ "canonicalReference": "@alloy-js/csharp!ParameterProps#ref:member",
13813
+ "docComment": "/**\n * Parameter modifier: The argument must be initialized before calling the method. The method can assign a new value to the parameter, but isn't required to do so.\n *\n * @see\n *\n * https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/method-parameters#ref-parameter-modifier\n */\n",
13814
+ "excerptTokens": [
13815
+ {
13816
+ "kind": "Content",
13817
+ "text": "ref?: "
13818
+ },
13819
+ {
13820
+ "kind": "Content",
13821
+ "text": "boolean"
13822
+ },
13823
+ {
13824
+ "kind": "Content",
13825
+ "text": ";"
13826
+ }
13827
+ ],
13828
+ "isReadonly": false,
13829
+ "isOptional": true,
13830
+ "releaseTag": "Public",
13831
+ "name": "ref",
13832
+ "propertyTypeTokenRange": {
13833
+ "startIndex": 1,
13834
+ "endIndex": 2
13835
+ }
13836
+ },
13752
13837
  {
13753
13838
  "kind": "PropertySignature",
13754
13839
  "canonicalReference": "@alloy-js/csharp!ParameterProps#refkey:member",
@@ -13777,6 +13862,33 @@
13777
13862
  "endIndex": 2
13778
13863
  }
13779
13864
  },
13865
+ {
13866
+ "kind": "PropertySignature",
13867
+ "canonicalReference": "@alloy-js/csharp!ParameterProps#refReadonly:member",
13868
+ "docComment": "/**\n * Parameter modifier: The argument must be initialized before calling the method. The method can't assign a new value to the parameter.\n *\n * @see\n *\n * https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/method-parameters#ref-readonly-modifier\n */\n",
13869
+ "excerptTokens": [
13870
+ {
13871
+ "kind": "Content",
13872
+ "text": "refReadonly?: "
13873
+ },
13874
+ {
13875
+ "kind": "Content",
13876
+ "text": "boolean"
13877
+ },
13878
+ {
13879
+ "kind": "Content",
13880
+ "text": ";"
13881
+ }
13882
+ ],
13883
+ "isReadonly": false,
13884
+ "isOptional": true,
13885
+ "releaseTag": "Public",
13886
+ "name": "refReadonly",
13887
+ "propertyTypeTokenRange": {
13888
+ "startIndex": 1,
13889
+ "endIndex": 2
13890
+ }
13891
+ },
13780
13892
  {
13781
13893
  "kind": "PropertySignature",
13782
13894
  "canonicalReference": "@alloy-js/csharp!ParameterProps#type:member",