@alloy-js/csharp 0.23.0-dev.8 → 0.23.0

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 (89) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/dev/src/components/method/method.test.js +64 -0
  3. package/dist/dev/src/components/method/method.test.js.map +1 -1
  4. package/dist/dev/src/components/namespace/namespace.js +2 -1
  5. package/dist/dev/src/components/namespace/namespace.js.map +1 -1
  6. package/dist/dev/src/components/namespace/namespace.test.js +13 -10
  7. package/dist/dev/src/components/namespace/namespace.test.js.map +1 -1
  8. package/dist/dev/src/components/namespace.ref.test.js +54 -42
  9. package/dist/dev/src/components/namespace.ref.test.js.map +1 -1
  10. package/dist/dev/src/components/property/property.js +101 -24
  11. package/dist/dev/src/components/property/property.js.map +1 -1
  12. package/dist/dev/src/components/property/property.test.js +140 -0
  13. package/dist/dev/src/components/property/property.test.js.map +1 -1
  14. package/dist/dev/src/components/source-file/source-file.js +12 -11
  15. package/dist/dev/src/components/source-file/source-file.js.map +1 -1
  16. package/dist/dev/src/identifier-utils.js +45 -0
  17. package/dist/dev/src/identifier-utils.js.map +1 -0
  18. package/dist/dev/src/index.js +2 -0
  19. package/dist/dev/src/index.js.map +1 -1
  20. package/dist/dev/src/keywords.js +39 -0
  21. package/dist/dev/src/keywords.js.map +1 -0
  22. package/dist/dev/src/name-policy.js +29 -6
  23. package/dist/dev/src/name-policy.js.map +1 -1
  24. package/dist/dev/src/name-policy.test.js +167 -0
  25. package/dist/dev/src/name-policy.test.js.map +1 -0
  26. package/dist/src/components/method/method.test.js +48 -0
  27. package/dist/src/components/method/method.test.js.map +1 -1
  28. package/dist/src/components/namespace/namespace.js +2 -1
  29. package/dist/src/components/namespace/namespace.js.map +1 -1
  30. package/dist/src/components/namespace/namespace.test.js +6 -3
  31. package/dist/src/components/namespace/namespace.test.js.map +1 -1
  32. package/dist/src/components/namespace.ref.test.js +24 -12
  33. package/dist/src/components/namespace.ref.test.js.map +1 -1
  34. package/dist/src/components/property/property.d.ts +42 -4
  35. package/dist/src/components/property/property.d.ts.map +1 -1
  36. package/dist/src/components/property/property.js +64 -11
  37. package/dist/src/components/property/property.js.map +1 -1
  38. package/dist/src/components/property/property.test.js +104 -0
  39. package/dist/src/components/property/property.test.js.map +1 -1
  40. package/dist/src/components/source-file/source-file.d.ts.map +1 -1
  41. package/dist/src/components/source-file/source-file.js +3 -2
  42. package/dist/src/components/source-file/source-file.js.map +1 -1
  43. package/dist/src/identifier-utils.d.ts +22 -0
  44. package/dist/src/identifier-utils.d.ts.map +1 -0
  45. package/dist/src/identifier-utils.js +45 -0
  46. package/dist/src/identifier-utils.js.map +1 -0
  47. package/dist/src/index.d.ts +2 -0
  48. package/dist/src/index.d.ts.map +1 -1
  49. package/dist/src/index.js +2 -0
  50. package/dist/src/index.js.map +1 -1
  51. package/dist/src/keywords.d.ts +32 -0
  52. package/dist/src/keywords.d.ts.map +1 -0
  53. package/dist/src/keywords.js +39 -0
  54. package/dist/src/keywords.js.map +1 -0
  55. package/dist/src/name-policy.d.ts +7 -0
  56. package/dist/src/name-policy.d.ts.map +1 -1
  57. package/dist/src/name-policy.js +29 -6
  58. package/dist/src/name-policy.js.map +1 -1
  59. package/dist/src/name-policy.test.d.ts +2 -0
  60. package/dist/src/name-policy.test.d.ts.map +1 -0
  61. package/dist/src/name-policy.test.js +167 -0
  62. package/dist/src/name-policy.test.js.map +1 -0
  63. package/dist/tsconfig.tsbuildinfo +1 -1
  64. package/docs/api/components/Property.md +30 -30
  65. package/docs/api/contexts/csharp-context.md +21 -0
  66. package/docs/api/contexts/index.md +3 -0
  67. package/docs/api/functions/createCSharpNamePolicy.md +4 -0
  68. package/docs/api/functions/index.md +5 -1
  69. package/docs/api/functions/isCSharpContextualKeyword.md +20 -0
  70. package/docs/api/functions/isCSharpKeyword.md +22 -0
  71. package/docs/api/functions/isValidCSharpIdentifier.md +20 -0
  72. package/docs/api/functions/sanitizeCSharpIdentifier.md +24 -0
  73. package/docs/api/index.md +3 -2
  74. package/docs/api/variables/csharpKeywords.md +11 -0
  75. package/docs/api/variables/index.md +1 -0
  76. package/package.json +8 -8
  77. package/src/components/method/method.test.tsx +36 -0
  78. package/src/components/namespace/namespace.test.tsx +6 -3
  79. package/src/components/namespace/namespace.tsx +2 -2
  80. package/src/components/namespace.ref.test.tsx +24 -12
  81. package/src/components/property/property.test.tsx +89 -0
  82. package/src/components/property/property.tsx +111 -16
  83. package/src/components/source-file/source-file.tsx +1 -4
  84. package/src/identifier-utils.ts +45 -0
  85. package/src/index.ts +2 -0
  86. package/src/keywords.ts +162 -0
  87. package/src/name-policy.test.ts +210 -0
  88. package/src/name-policy.ts +30 -6
  89. package/temp/api.json +253 -7
@@ -16,7 +16,7 @@ Properties for [Property](../property/) component
16
16
  doc={Children}
17
17
  extern
18
18
  file
19
- get
19
+ get={boolean | Children}
20
20
  init
21
21
  initializer={Children}
22
22
  internal
@@ -31,7 +31,7 @@ Properties for [Property](../property/) component
31
31
  refkey={Refkey}
32
32
  required
33
33
  sealed
34
- set
34
+ set={boolean | Children}
35
35
  static
36
36
  type={Children}
37
37
  virtual
@@ -50,7 +50,7 @@ Properties for [Property](../property/) component
50
50
  doc: Children,
51
51
  extern: boolean,
52
52
  file: boolean,
53
- get: boolean,
53
+ get: boolean | Children,
54
54
  init: boolean,
55
55
  initializer: Children,
56
56
  internal: boolean,
@@ -65,7 +65,7 @@ Properties for [Property](../property/) component
65
65
  refkey: Refkey,
66
66
  required: boolean,
67
67
  sealed: boolean,
68
- set: boolean,
68
+ set: boolean | Children,
69
69
  static: boolean,
70
70
  type: Children,
71
71
  virtual: boolean,
@@ -74,32 +74,32 @@ Properties for [Property](../property/) component
74
74
 
75
75
  ## Props
76
76
 
77
- | | | |
78
- | ----------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ |
79
- | abstract | optional boolean | |
80
- | attributes | optional [AttributesProp](../../types/attributesprop/) | Define attributes to attach |
81
- | doc | optional [Children](../../../core/types/children/) | Doc comment |
82
- | extern | optional boolean | |
83
- | file | optional boolean | |
84
- | get | optional boolean | If property should have a getter |
85
- | init | optional boolean | If property should only be set on the type creation |
86
- | initializer | optional [Children](../../../core/types/children/) | Property initializer |
87
- | internal | optional boolean | |
88
- | name | [Namekey](../../../core/types/namekey/) \| string | |
89
- | new | optional boolean | |
90
- | nullable | optional boolean | Property initializer |
91
- | override | optional boolean | |
92
- | private | optional boolean | |
93
- | protected | optional boolean | |
94
- | public | optional boolean | |
95
- | readonly | optional boolean | |
96
- | refkey | optional [Refkey](../../../core/types/refkey/) | |
97
- | required | optional boolean | Set required modifier on property <https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/required> |
98
- | sealed | optional boolean | |
99
- | set | optional boolean | If property should have a setter |
100
- | static | optional boolean | |
101
- | type | [Children](../../../core/types/children/) | Property type |
102
- | virtual | optional boolean | |
77
+ | | | |
78
+ | ----------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
79
+ | abstract | optional boolean | |
80
+ | attributes | optional [AttributesProp](../../types/attributesprop/) | Define attributes to attach |
81
+ | doc | optional [Children](../../../core/types/children/) | Doc comment |
82
+ | extern | optional boolean | |
83
+ | file | optional boolean | |
84
+ | get | optional boolean \| [Children](../../../core/types/children/) | If property should have a getter. Pass `true` for an auto-property getter (`get;`), or pass children for a getter with a body. |
85
+ | init | optional boolean | If property should only be set on the type creation |
86
+ | initializer | optional [Children](../../../core/types/children/) | Property initializer |
87
+ | internal | optional boolean | |
88
+ | name | [Namekey](../../../core/types/namekey/) \| string | |
89
+ | new | optional boolean | |
90
+ | nullable | optional boolean | Property initializer |
91
+ | override | optional boolean | |
92
+ | private | optional boolean | |
93
+ | protected | optional boolean | |
94
+ | public | optional boolean | |
95
+ | readonly | optional boolean | |
96
+ | refkey | optional [Refkey](../../../core/types/refkey/) | |
97
+ | required | optional boolean | Set required modifier on property <https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/required> |
98
+ | sealed | optional boolean | |
99
+ | set | optional boolean \| [Children](../../../core/types/children/) | If property should have a setter. Pass `true` for an auto-property setter (`set;`), or pass children for a setter with a body. |
100
+ | static | optional boolean | |
101
+ | type | [Children](../../../core/types/children/) | Property type |
102
+ | virtual | optional boolean | |
103
103
 
104
104
  ## Example
105
105
 
@@ -0,0 +1,21 @@
1
+ # csharp context
2
+
3
+ C# contextual keywords that are reserved in certain contexts. While not always reserved, treating them as keywords in generated code avoids subtle context-dependent issues.
4
+
5
+ ```ts
6
+ const csharpContextualKeywords: ReadonlySet<string>
7
+ ```
8
+
9
+ ## Accessor
10
+
11
+ ```ts
12
+ const myContext = useContext(csharpContext);
13
+ ```
14
+
15
+ ## Context interface
16
+
17
+ string
18
+
19
+ ## See also
20
+
21
+ * <https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/#contextual-keywords>
@@ -0,0 +1,3 @@
1
+ # csharp — contexts
2
+
3
+ - [csharp context](csharp-context.md) — C# contextual keywords that are reserved in certain contexts.
@@ -1,5 +1,9 @@
1
1
  # createCSharpNamePolicy
2
2
 
3
+ Creates the C# naming policy with case conversion and keyword escaping.
4
+
5
+ After applying the appropriate case conversion for each element kind, the resulting name is checked against C# reserved and contextual keywords. If it matches (case-sensitively), the name is prefixed with `@`.
6
+
3
7
  ```ts
4
8
  import { createCSharpNamePolicy } from "@alloy-js/csharp";
5
9
 
@@ -4,7 +4,7 @@
4
4
  - [accessibilityFromProps](accessibilityFromProps.md) — import { accessibilityFromProps } from "@alloy-js/csharp";
5
5
  - [computeModifiersPrefix](computeModifiersPrefix.md) — Resolve the modifier prefix
6
6
  - [createClassScope](createClassScope.md) — import { createClassScope } from "@alloy-js/csharp";
7
- - [createCSharpNamePolicy](createCSharpNamePolicy.md) — import { createCSharpNamePolicy } from "@alloy-js/csharp";
7
+ - [createCSharpNamePolicy](createCSharpNamePolicy.md) — Creates the C# naming policy with case conversion and keyword escaping.
8
8
  - [createCSharpNamespaceScope](createCSharpNamespaceScope.md) — import { createCSharpNamespaceScope } from "@alloy-js/csharp";
9
9
  - [createFieldSymbol](createFieldSymbol.md) — import { createFieldSymbol } from "@alloy-js/csharp";
10
10
  - [createLibrary](createLibrary.md) — import { createLibrary } from "@alloy-js/csharp";
@@ -19,9 +19,13 @@
19
19
  - [createVariableSymbol](createVariableSymbol.md) — import { createVariableSymbol } from "@alloy-js/csharp";
20
20
  - [getAccessModifier](getAccessModifier.md) — import { getAccessModifier } from "@alloy-js/csharp";
21
21
  - [getAsyncModifier](getAsyncModifier.md) — import { getAsyncModifier } from "@alloy-js/csharp";
22
+ - [isCSharpContextualKeyword](isCSharpContextualKeyword.md) — Returns true if the given name is a C# contextual keyword.
23
+ - [isCSharpKeyword](isCSharpKeyword.md) — Returns true if the given name is a C# reserved keyword.
24
+ - [isValidCSharpIdentifier](isValidCSharpIdentifier.md) — Checks whether the provided name is a valid C# identifier (without `@` prefix).
22
25
  - [makeModifiers](makeModifiers.md) — import { makeModifiers } from "@alloy-js/csharp";
23
26
  - [nonAccessibilityFromProps](nonAccessibilityFromProps.md) — import { nonAccessibilityFromProps } from "@alloy-js/csharp";
24
27
  - [ref](ref.md) — import { ref } from "@alloy-js/csharp";
28
+ - [sanitizeCSharpIdentifier](sanitizeCSharpIdentifier.md) — Transforms an arbitrary string into a valid C# identifier by replacing invalid characters.
25
29
  - [useCsharpFormatOptions](useCsharpFormatOptions.md) — import { useCsharpFormatOptions } from "@alloy-js/csharp";
26
30
  - [useCSharpNamePolicy](useCSharpNamePolicy.md) — import { useCSharpNamePolicy } from "@alloy-js/csharp";
27
31
  - [useCSharpScope](useCSharpScope.md) — import { useCSharpScope } from "@alloy-js/csharp";
@@ -0,0 +1,20 @@
1
+ # isCSharpContextualKeyword
2
+
3
+ Returns true if the given name is a C# contextual keyword. Contextual keywords are only reserved in specific language contexts and are generally valid as identifiers.
4
+
5
+ ```ts
6
+ import { isCSharpContextualKeyword } from "@alloy-js/csharp";
7
+
8
+
9
+ function isCSharpContextualKeyword(name: string): boolean;
10
+ ```
11
+
12
+ ## Parameters
13
+
14
+ | | | |
15
+ | ---- | ------ | - |
16
+ | name | string | |
17
+
18
+ ## Returns
19
+
20
+ boolean
@@ -0,0 +1,22 @@
1
+ # isCSharpKeyword
2
+
3
+ Returns true if the given name is a C# reserved keyword. The check is case-sensitive, matching C# language semantics.
4
+
5
+ Note: this only checks reserved keywords, not contextual keywords. Contextual keywords are only reserved in specific language contexts and are valid identifiers elsewhere (e.g., `value` is valid as a parameter name). Use [isCSharpContextualKeyword](../iscsharpcontextualkeyword/) to check contextual keywords separately.
6
+
7
+ ```ts
8
+ import { isCSharpKeyword } from "@alloy-js/csharp";
9
+
10
+
11
+ function isCSharpKeyword(name: string): boolean;
12
+ ```
13
+
14
+ ## Parameters
15
+
16
+ | | | |
17
+ | ---- | ------ | - |
18
+ | name | string | |
19
+
20
+ ## Returns
21
+
22
+ boolean
@@ -0,0 +1,20 @@
1
+ # isValidCSharpIdentifier
2
+
3
+ Checks whether the provided name is a valid C# identifier (without `@` prefix). Does not account for keyword conflicts — use [isCSharpKeyword](../iscsharpkeyword/) for that.
4
+
5
+ ```ts
6
+ import { isValidCSharpIdentifier } from "@alloy-js/csharp";
7
+
8
+
9
+ function isValidCSharpIdentifier(name: string): boolean;
10
+ ```
11
+
12
+ ## Parameters
13
+
14
+ | | | |
15
+ | ---- | ------ | - |
16
+ | name | string | |
17
+
18
+ ## Returns
19
+
20
+ boolean true if the name matches C# identifier rules (letter or underscore start, word chars after).
@@ -0,0 +1,24 @@
1
+ # sanitizeCSharpIdentifier
2
+
3
+ Transforms an arbitrary string into a valid C# identifier by replacing invalid characters. The result may still be a C# keyword — callers should combine with keyword escaping if needed.
4
+
5
+ * If the first character is not a letter or underscore, a `_` prefix is added.
6
+ * Subsequent non-word characters are replaced with `_`.
7
+ * Empty strings become `_`.
8
+
9
+ ```ts
10
+ import { sanitizeCSharpIdentifier } from "@alloy-js/csharp";
11
+
12
+
13
+ function sanitizeCSharpIdentifier(name: string): string;
14
+ ```
15
+
16
+ ## Parameters
17
+
18
+ | | | |
19
+ | ---- | ------ | - |
20
+ | name | string | |
21
+
22
+ ## Returns
23
+
24
+ string A string that satisfies C# identifier character rules.
package/docs/api/index.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # @alloy-js/csharp API Reference
2
2
 
3
3
  - [components](components/index.md) (53 items)
4
- - [functions](functions/index.md) (31 items)
4
+ - [contexts](contexts/index.md) (1 items)
5
+ - [functions](functions/index.md) (35 items)
5
6
  - [types](types/index.md) (60 items)
6
- - [variables](variables/index.md) (1 items)
7
+ - [variables](variables/index.md) (2 items)
@@ -0,0 +1,11 @@
1
+ # csharpKeywords
2
+
3
+ C# reserved keywords that cannot be used as identifiers without `@` prefix. These are case-sensitive in C#.
4
+
5
+ ```ts
6
+ csharpKeywords: ReadonlySet<string>
7
+ ```
8
+
9
+ ## See also
10
+
11
+ * <https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/>
@@ -1,3 +1,4 @@
1
1
  # csharp — variables
2
2
 
3
3
  - [Attribute](Attribute.md) — Render a csharp attribute.
4
+ - [csharpKeywords](csharpKeywords.md) — C# reserved keywords that cannot be used as identifiers without `@` prefix.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alloy-js/csharp",
3
- "version": "0.23.0-dev.8",
3
+ "version": "0.23.0",
4
4
  "description": "Alloy components for CSharp language.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -43,23 +43,23 @@
43
43
  "author": "jhendrix@microsoft.com",
44
44
  "license": "MIT",
45
45
  "dependencies": {
46
- "@alloy-js/core": "~0.22.0 || >= 0.23.0-dev.16",
47
- "@alloy-js/msbuild": "~0.22.0 || >= 0.23.0-dev.2",
48
46
  "change-case": "^5.4.4",
49
47
  "marked": "^16.1.1",
50
- "pathe": "^2.0.3"
48
+ "pathe": "^2.0.3",
49
+ "@alloy-js/core": "~0.23.0",
50
+ "@alloy-js/msbuild": "~0.23.0"
51
51
  },
52
52
  "devDependencies": {
53
- "@alloy-js/cli": "~0.22.0 || >= 0.23.0-dev.6",
54
- "@alloy-js/rollup-plugin": "~0.1.0 || >= 0.1.1-dev.2",
55
- "@alloy-js/typescript": "~0.22.0 || >= 0.23.0-dev.9",
56
53
  "@microsoft/api-extractor": "~7.52.8",
57
54
  "@rollup/plugin-typescript": "^12.1.2",
58
55
  "@types/js-yaml": "^4.0.9",
59
56
  "concurrently": "^9.2.0",
60
57
  "js-yaml": "^4.1.0",
61
58
  "typescript": "^5.8.3",
62
- "vitest": "3.2.4"
59
+ "vitest": "3.2.4",
60
+ "@alloy-js/rollup-plugin": "~0.1.1",
61
+ "@alloy-js/cli": "~0.23.0",
62
+ "@alloy-js/typescript": "~0.23.0"
63
63
  },
64
64
  "type": "module",
65
65
  "scripts": {
@@ -207,3 +207,39 @@ describe("format", () => {
207
207
  `);
208
208
  });
209
209
  });
210
+
211
+ describe("name policy deduplication", () => {
212
+ it("deduplicates parameters that collide after case conversion", () => {
213
+ const params = [
214
+ { name: "my-param", type: "int" },
215
+ { name: "myParam", type: "string" },
216
+ ];
217
+ expect(
218
+ <Wrapper>
219
+ <Method public name="MethodOne" parameters={params} />
220
+ </Wrapper>,
221
+ ).toRenderTo(`
222
+ public class TestClass
223
+ {
224
+ public void MethodOne(int myParam, string myParam_2) {}
225
+ }
226
+ `);
227
+ });
228
+
229
+ it("deduplicates parameters that are keywords", () => {
230
+ const params = [
231
+ { name: "string", type: "int" },
232
+ { name: "string", type: "bool" },
233
+ ];
234
+ expect(
235
+ <Wrapper>
236
+ <Method public name="MethodOne" parameters={params} />
237
+ </Wrapper>,
238
+ ).toRenderTo(`
239
+ public class TestClass
240
+ {
241
+ public void MethodOne(int @string, bool string_2) {}
242
+ }
243
+ `);
244
+ });
245
+ });
@@ -138,8 +138,10 @@ it("define nested namespace in sourcefile", () => {
138
138
  );
139
139
 
140
140
  expect(tree).toRenderTo(`
141
- namespace Base {
142
- namespace Namespace1.Namespace2 {
141
+ namespace Base
142
+ {
143
+ namespace Namespace1.Namespace2
144
+ {
143
145
  public class Model1;
144
146
  }
145
147
  }
@@ -170,7 +172,8 @@ it("contains a struct with a private field initialized by a constructor", () =>
170
172
  );
171
173
 
172
174
  expect(tree).toRenderTo(d`
173
- namespace TestNamespace.Test {
175
+ namespace TestNamespace.Test
176
+ {
174
177
  public struct MyStruct
175
178
  {
176
179
  private int _value;
@@ -38,8 +38,8 @@ export function Namespace(props: NamespaceProps) {
38
38
  <NamespaceName
39
39
  symbol={namespaceSymbol}
40
40
  relative={!!hasOuterNamespace}
41
- />{" "}
42
- <Block>
41
+ />
42
+ <Block newline>
43
43
  <NamespaceScopes symbol={namespaceSymbol} stopAt={nsContext?.symbol}>
44
44
  {props.children}
45
45
  </NamespaceScopes>
@@ -43,9 +43,11 @@ it("references types in a parent namespace", () => {
43
43
  );
44
44
 
45
45
  expect(tree).toRenderTo(`
46
- namespace Test {
46
+ namespace Test
47
+ {
47
48
  class TestClass;
48
- namespace Nested {
49
+ namespace Nested
50
+ {
49
51
  TestClass;
50
52
  }
51
53
  }
@@ -69,9 +71,11 @@ it("references types in a child namespace", () => {
69
71
  );
70
72
 
71
73
  expect(tree).toRenderTo(`
72
- namespace Test {
74
+ namespace Test
75
+ {
73
76
  Nested.TestClass;
74
- namespace Nested {
77
+ namespace Nested
78
+ {
75
79
  class TestClass;
76
80
  }
77
81
  }
@@ -96,10 +100,12 @@ it("references types in a different top-level namespace declared in the same fil
96
100
  expect(tree).toRenderTo(`
97
101
  using TestCode2;
98
102
 
99
- namespace TestCode1 {
103
+ namespace TestCode1
104
+ {
100
105
  TestClass
101
106
  }
102
- namespace TestCode2 {
107
+ namespace TestCode2
108
+ {
103
109
  class TestClass;
104
110
  }
105
111
  `);
@@ -125,12 +131,14 @@ it("references types in a different top-level namespace declared in a different
125
131
  "test.cs": `
126
132
  using TestCode2;
127
133
 
128
- namespace TestCode1 {
134
+ namespace TestCode1
135
+ {
129
136
  TestClass;
130
137
  }
131
138
  `,
132
139
  "other.cs": `
133
- namespace TestCode2 {
140
+ namespace TestCode2
141
+ {
134
142
  class TestClass;
135
143
  }
136
144
  `,
@@ -156,7 +164,8 @@ it("can be referenced by refkey", () => {
156
164
  expect(tree).toRenderTo(`
157
165
  using TestCode2;
158
166
 
159
- namespace TestCode2 {
167
+ namespace TestCode2
168
+ {
160
169
  class TestClass;
161
170
  }
162
171
  TestClass;
@@ -181,11 +190,14 @@ it("references types across sibling namespaces under the same parent", () => {
181
190
  );
182
191
 
183
192
  expect(tree).toRenderTo(`
184
- namespace Parent {
185
- namespace Models {
193
+ namespace Parent
194
+ {
195
+ namespace Models
196
+ {
186
197
  class User;
187
198
  }
188
- namespace Services {
199
+ namespace Services
200
+ {
189
201
  Models.User;
190
202
  }
191
203
  }
@@ -232,3 +232,92 @@ describe("format", () => {
232
232
  `);
233
233
  });
234
234
  });
235
+
236
+ describe("accessor bodies", () => {
237
+ it("renders get with body", () => {
238
+ expect(
239
+ <Wrapper>
240
+ <Property public name="Name" type="string" get={<>return _name;</>} />
241
+ </Wrapper>,
242
+ ).toRenderTo(`
243
+ public class TestClass
244
+ {
245
+ public string Name
246
+ {
247
+ get { return _name; }
248
+ }
249
+ }
250
+ `);
251
+ });
252
+
253
+ it("renders set with body", () => {
254
+ expect(
255
+ <Wrapper>
256
+ <Property
257
+ public
258
+ name="Value"
259
+ type="int"
260
+ get
261
+ set={<>_value = value;</>}
262
+ />
263
+ </Wrapper>,
264
+ ).toRenderTo(`
265
+ public class TestClass
266
+ {
267
+ public int Value
268
+ {
269
+ get;
270
+ set { _value = value; }
271
+ }
272
+ }
273
+ `);
274
+ });
275
+
276
+ it("renders both get and set with bodies", () => {
277
+ expect(
278
+ <Wrapper>
279
+ <Property
280
+ public
281
+ name="MinValue"
282
+ type="T"
283
+ get={<>return _minValue.HasValue ? _minValue.Value : default(T);</>}
284
+ set={<>_minValue = value;</>}
285
+ />
286
+ </Wrapper>,
287
+ ).toRenderTo(`
288
+ public class TestClass
289
+ {
290
+ public T MinValue
291
+ {
292
+ get { return _minValue.HasValue ? _minValue.Value : default(T); }
293
+ set { _minValue = value; }
294
+ }
295
+ }
296
+ `);
297
+ });
298
+
299
+ it("breaks long accessor body across lines", () => {
300
+ expect(
301
+ <TestNamespace printWidth={40}>
302
+ <ClassDeclaration name="Test">
303
+ <Property
304
+ public
305
+ name="Value"
306
+ type="int"
307
+ get={<>return _someVeryLongFieldName;</>}
308
+ />
309
+ </ClassDeclaration>
310
+ </TestNamespace>,
311
+ ).toRenderTo(`
312
+ class Test
313
+ {
314
+ public int Value
315
+ {
316
+ get {
317
+ return _someVeryLongFieldName;
318
+ }
319
+ }
320
+ }
321
+ `);
322
+ });
323
+ });