@alloy-js/csharp 0.23.0-dev.7 → 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.
- package/CHANGELOG.md +19 -0
- package/dist/dev/src/components/constructor/constructor.js +69 -9
- package/dist/dev/src/components/constructor/constructor.js.map +1 -1
- package/dist/dev/src/components/constructor/constructor.test.js +117 -0
- package/dist/dev/src/components/constructor/constructor.test.js.map +1 -1
- package/dist/dev/src/components/method/method.test.js +64 -0
- package/dist/dev/src/components/method/method.test.js.map +1 -1
- package/dist/dev/src/components/namespace/namespace.js +2 -1
- package/dist/dev/src/components/namespace/namespace.js.map +1 -1
- package/dist/dev/src/components/namespace/namespace.test.js +13 -10
- package/dist/dev/src/components/namespace/namespace.test.js.map +1 -1
- package/dist/dev/src/components/namespace.ref.test.js +54 -42
- package/dist/dev/src/components/namespace.ref.test.js.map +1 -1
- package/dist/dev/src/components/property/property.js +101 -24
- package/dist/dev/src/components/property/property.js.map +1 -1
- package/dist/dev/src/components/property/property.test.js +140 -0
- package/dist/dev/src/components/property/property.test.js.map +1 -1
- package/dist/dev/src/components/source-file/source-file.js +12 -11
- package/dist/dev/src/components/source-file/source-file.js.map +1 -1
- package/dist/dev/src/identifier-utils.js +45 -0
- package/dist/dev/src/identifier-utils.js.map +1 -0
- package/dist/dev/src/index.js +2 -0
- package/dist/dev/src/index.js.map +1 -1
- package/dist/dev/src/keywords.js +39 -0
- package/dist/dev/src/keywords.js.map +1 -0
- package/dist/dev/src/name-policy.js +29 -6
- package/dist/dev/src/name-policy.js.map +1 -1
- package/dist/dev/src/name-policy.test.js +167 -0
- package/dist/dev/src/name-policy.test.js.map +1 -0
- package/dist/src/components/constructor/constructor.d.ts +32 -0
- package/dist/src/components/constructor/constructor.d.ts.map +1 -1
- package/dist/src/components/constructor/constructor.js +35 -3
- package/dist/src/components/constructor/constructor.js.map +1 -1
- package/dist/src/components/constructor/constructor.test.js +81 -0
- package/dist/src/components/constructor/constructor.test.js.map +1 -1
- package/dist/src/components/method/method.test.js +48 -0
- package/dist/src/components/method/method.test.js.map +1 -1
- package/dist/src/components/namespace/namespace.js +2 -1
- package/dist/src/components/namespace/namespace.js.map +1 -1
- package/dist/src/components/namespace/namespace.test.js +6 -3
- package/dist/src/components/namespace/namespace.test.js.map +1 -1
- package/dist/src/components/namespace.ref.test.js +24 -12
- package/dist/src/components/namespace.ref.test.js.map +1 -1
- package/dist/src/components/property/property.d.ts +42 -4
- package/dist/src/components/property/property.d.ts.map +1 -1
- package/dist/src/components/property/property.js +64 -11
- package/dist/src/components/property/property.js.map +1 -1
- package/dist/src/components/property/property.test.js +104 -0
- package/dist/src/components/property/property.test.js.map +1 -1
- package/dist/src/components/source-file/source-file.d.ts.map +1 -1
- package/dist/src/components/source-file/source-file.js +3 -2
- package/dist/src/components/source-file/source-file.js.map +1 -1
- package/dist/src/identifier-utils.d.ts +22 -0
- package/dist/src/identifier-utils.d.ts.map +1 -0
- package/dist/src/identifier-utils.js +45 -0
- package/dist/src/identifier-utils.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/keywords.d.ts +32 -0
- package/dist/src/keywords.d.ts.map +1 -0
- package/dist/src/keywords.js +39 -0
- package/dist/src/keywords.js.map +1 -0
- package/dist/src/name-policy.d.ts +7 -0
- package/dist/src/name-policy.d.ts.map +1 -1
- package/dist/src/name-policy.js +29 -6
- package/dist/src/name-policy.js.map +1 -1
- package/dist/src/name-policy.test.d.ts +2 -0
- package/dist/src/name-policy.test.d.ts.map +1 -0
- package/dist/src/name-policy.test.js +167 -0
- package/dist/src/name-policy.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/api/components/Constructor.md +17 -11
- package/docs/api/components/Property.md +30 -30
- package/docs/api/contexts/csharp-context.md +21 -0
- package/docs/api/contexts/index.md +3 -0
- package/docs/api/functions/createCSharpNamePolicy.md +4 -0
- package/docs/api/functions/index.md +5 -1
- package/docs/api/functions/isCSharpContextualKeyword.md +20 -0
- package/docs/api/functions/isCSharpKeyword.md +22 -0
- package/docs/api/functions/isValidCSharpIdentifier.md +20 -0
- package/docs/api/functions/sanitizeCSharpIdentifier.md +24 -0
- package/docs/api/index.md +3 -2
- package/docs/api/variables/csharpKeywords.md +11 -0
- package/docs/api/variables/index.md +1 -0
- package/package.json +8 -8
- package/src/components/constructor/constructor.test.tsx +64 -0
- package/src/components/constructor/constructor.tsx +81 -1
- package/src/components/method/method.test.tsx +36 -0
- package/src/components/namespace/namespace.test.tsx +6 -3
- package/src/components/namespace/namespace.tsx +2 -2
- package/src/components/namespace.ref.test.tsx +24 -12
- package/src/components/property/property.test.tsx +89 -0
- package/src/components/property/property.tsx +111 -16
- package/src/components/source-file/source-file.tsx +1 -4
- package/src/identifier-utils.ts +45 -0
- package/src/index.ts +2 -0
- package/src/keywords.ts +162 -0
- package/src/name-policy.test.ts +210 -0
- package/src/name-policy.ts +30 -6
- package/temp/api.json +317 -7
|
@@ -9,6 +9,7 @@ Properties for [Constructor](../constructor/) component.
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
<Constructor
|
|
12
|
+
baseConstructor={Children[]}
|
|
12
13
|
doc={Children}
|
|
13
14
|
file
|
|
14
15
|
internal
|
|
@@ -17,6 +18,7 @@ Properties for [Constructor](../constructor/) component.
|
|
|
17
18
|
protected
|
|
18
19
|
public
|
|
19
20
|
refkey={Refkey}
|
|
21
|
+
thisConstructor={Children[]}
|
|
20
22
|
>
|
|
21
23
|
{children}
|
|
22
24
|
</Constructor>
|
|
@@ -29,6 +31,7 @@ Properties for [Constructor](../constructor/) component.
|
|
|
29
31
|
|
|
30
32
|
|
|
31
33
|
Constructor({
|
|
34
|
+
baseConstructor: Children[],
|
|
32
35
|
doc: Children,
|
|
33
36
|
file: boolean,
|
|
34
37
|
internal: boolean,
|
|
@@ -37,19 +40,22 @@ Properties for [Constructor](../constructor/) component.
|
|
|
37
40
|
protected: boolean,
|
|
38
41
|
public: boolean,
|
|
39
42
|
refkey: Refkey,
|
|
43
|
+
thisConstructor: Children[],
|
|
40
44
|
}).children(children)
|
|
41
45
|
```
|
|
42
46
|
|
|
43
47
|
## Props
|
|
44
48
|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
49
|
+
| | | |
|
|
50
|
+
| --------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
51
|
+
| baseConstructor | optional [Children](../../../core/types/children/)\[] | Arguments to pass to the base class constructor. Renders `: base(args)` between parameter list and body. |
|
|
52
|
+
| children | optional [Children](../../../core/types/children/) | Constructor body |
|
|
53
|
+
| doc | optional [Children](../../../core/types/children/) | Doc comment |
|
|
54
|
+
| file | optional boolean | |
|
|
55
|
+
| internal | optional boolean | |
|
|
56
|
+
| parameters | optional [ParameterProps](../parameter/)\[] | Constructor parameters |
|
|
57
|
+
| private | optional boolean | |
|
|
58
|
+
| protected | optional boolean | |
|
|
59
|
+
| public | optional boolean | |
|
|
60
|
+
| refkey | optional [Refkey](../../../core/types/refkey/) | Refkey |
|
|
61
|
+
| thisConstructor | optional [Children](../../../core/types/children/)\[] | Arguments to pass to another constructor in the same class. Renders `: this(args)` between parameter list and body. |
|
|
@@ -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/)
|
|
81
|
-
| doc | optional [Children](../../../core/types/children/)
|
|
82
|
-
| extern | optional boolean
|
|
83
|
-
| file | optional boolean
|
|
84
|
-
| get | optional boolean
|
|
85
|
-
| init | optional boolean
|
|
86
|
-
| initializer | optional [Children](../../../core/types/children/)
|
|
87
|
-
| internal | optional boolean
|
|
88
|
-
| name | [Namekey](../../../core/types/namekey/) \| string
|
|
89
|
-
| new | optional boolean
|
|
90
|
-
| nullable | optional boolean
|
|
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
|
|
98
|
-
| sealed | optional boolean
|
|
99
|
-
| set | optional boolean
|
|
100
|
-
| static | optional boolean
|
|
101
|
-
| type | [Children](../../../core/types/children/)
|
|
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>
|
|
@@ -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) —
|
|
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
|
-
- [
|
|
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) (
|
|
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/>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alloy-js/csharp",
|
|
3
|
-
"version": "0.23.0
|
|
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": {
|
|
@@ -60,3 +60,67 @@ it("renders doc comment", () => {
|
|
|
60
60
|
}
|
|
61
61
|
`);
|
|
62
62
|
});
|
|
63
|
+
|
|
64
|
+
it("renders : base() initializer", () => {
|
|
65
|
+
expect(
|
|
66
|
+
<TestNamespace>
|
|
67
|
+
<ClassDeclaration public name="DerivedClass" baseType="BaseClass">
|
|
68
|
+
<Constructor
|
|
69
|
+
public
|
|
70
|
+
parameters={[{ name: "name", type: "string" }]}
|
|
71
|
+
baseConstructor={["name"]}
|
|
72
|
+
>
|
|
73
|
+
// body
|
|
74
|
+
</Constructor>
|
|
75
|
+
</ClassDeclaration>
|
|
76
|
+
</TestNamespace>,
|
|
77
|
+
).toRenderTo(`
|
|
78
|
+
public class DerivedClass : BaseClass
|
|
79
|
+
{
|
|
80
|
+
public DerivedClass(string name) : base(name)
|
|
81
|
+
{
|
|
82
|
+
// body
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
`);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("renders : this() initializer", () => {
|
|
89
|
+
expect(
|
|
90
|
+
<TestNamespace>
|
|
91
|
+
<ClassDeclaration public name="MyClass">
|
|
92
|
+
<Constructor public thisConstructor={["0", "0"]}>
|
|
93
|
+
// body
|
|
94
|
+
</Constructor>
|
|
95
|
+
</ClassDeclaration>
|
|
96
|
+
</TestNamespace>,
|
|
97
|
+
).toRenderTo(`
|
|
98
|
+
public class MyClass
|
|
99
|
+
{
|
|
100
|
+
public MyClass() : this(0, 0)
|
|
101
|
+
{
|
|
102
|
+
// body
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
`);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("renders : base() with no arguments", () => {
|
|
109
|
+
expect(
|
|
110
|
+
<TestNamespace>
|
|
111
|
+
<ClassDeclaration public name="DerivedClass" baseType="BaseClass">
|
|
112
|
+
<Constructor public baseConstructor={[]}>
|
|
113
|
+
// body
|
|
114
|
+
</Constructor>
|
|
115
|
+
</ClassDeclaration>
|
|
116
|
+
</TestNamespace>,
|
|
117
|
+
).toRenderTo(`
|
|
118
|
+
public class DerivedClass : BaseClass
|
|
119
|
+
{
|
|
120
|
+
public DerivedClass() : base()
|
|
121
|
+
{
|
|
122
|
+
// body
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
`);
|
|
126
|
+
});
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { MethodScope } from "#components/method-scope.jsx";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Block,
|
|
4
|
+
For,
|
|
5
|
+
Indent,
|
|
6
|
+
MemberDeclaration,
|
|
7
|
+
MemberName,
|
|
8
|
+
Refkey,
|
|
9
|
+
} from "@alloy-js/core";
|
|
3
10
|
import { Children } from "@alloy-js/core/jsx-runtime";
|
|
4
11
|
import {
|
|
5
12
|
AccessModifiers,
|
|
@@ -24,11 +31,51 @@ export interface ConstructorProps extends AccessModifiers {
|
|
|
24
31
|
/** Refkey */
|
|
25
32
|
refkey?: Refkey;
|
|
26
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Arguments to pass to the base class constructor.
|
|
36
|
+
* Renders `: base(args)` between parameter list and body.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```tsx
|
|
40
|
+
* <Constructor public baseConstructor={["name", "42"]}>
|
|
41
|
+
* ```
|
|
42
|
+
* This will produce:
|
|
43
|
+
* ```csharp
|
|
44
|
+
* public MyClass(...) : base(name, 42)
|
|
45
|
+
* {
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
baseConstructor?: Children[];
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Arguments to pass to another constructor in the same class.
|
|
53
|
+
* Renders `: this(args)` between parameter list and body.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```tsx
|
|
57
|
+
* <Constructor public thisConstructor={["0", "0"]}>
|
|
58
|
+
* ```
|
|
59
|
+
* This will produce:
|
|
60
|
+
* ```csharp
|
|
61
|
+
* public MyClass() : this(0, 0)
|
|
62
|
+
* {
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
thisConstructor?: Children[];
|
|
67
|
+
|
|
27
68
|
/** Constructor body */
|
|
28
69
|
children?: Children;
|
|
29
70
|
}
|
|
30
71
|
|
|
31
72
|
export function Constructor(props: ConstructorProps) {
|
|
73
|
+
if (props.baseConstructor && props.thisConstructor) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
"Cannot use both 'baseConstructor' and 'thisConstructor' on the same constructor",
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
32
79
|
const scope = useNamedTypeScope();
|
|
33
80
|
|
|
34
81
|
const name = scope.ownerSymbol.name;
|
|
@@ -39,6 +86,13 @@ export function Constructor(props: ConstructorProps) {
|
|
|
39
86
|
|
|
40
87
|
const modifiers = computeModifiersPrefix([getAccessModifier(props)]);
|
|
41
88
|
|
|
89
|
+
const initializer =
|
|
90
|
+
props.baseConstructor ?
|
|
91
|
+
<ConstructorInitializer keyword="base" args={props.baseConstructor} />
|
|
92
|
+
: props.thisConstructor ?
|
|
93
|
+
<ConstructorInitializer keyword="this" args={props.thisConstructor} />
|
|
94
|
+
: null;
|
|
95
|
+
|
|
42
96
|
return (
|
|
43
97
|
<MemberDeclaration symbol={ctorSymbol}>
|
|
44
98
|
<MethodScope>
|
|
@@ -46,8 +100,34 @@ export function Constructor(props: ConstructorProps) {
|
|
|
46
100
|
{modifiers}
|
|
47
101
|
<MemberName />
|
|
48
102
|
<Parameters parameters={props.parameters} />
|
|
103
|
+
{initializer}
|
|
49
104
|
<Block newline>{props.children}</Block>
|
|
50
105
|
</MethodScope>
|
|
51
106
|
</MemberDeclaration>
|
|
52
107
|
);
|
|
53
108
|
}
|
|
109
|
+
|
|
110
|
+
interface ConstructorInitializerProps {
|
|
111
|
+
keyword: "base" | "this";
|
|
112
|
+
args: Children[];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function ConstructorInitializer(props: ConstructorInitializerProps) {
|
|
116
|
+
return (
|
|
117
|
+
<group>
|
|
118
|
+
{" : "}
|
|
119
|
+
{props.keyword}(
|
|
120
|
+
<Indent nobreak>
|
|
121
|
+
<For each={props.args} joiner={", "}>
|
|
122
|
+
{(arg) => (
|
|
123
|
+
<>
|
|
124
|
+
<softline />
|
|
125
|
+
{arg}
|
|
126
|
+
</>
|
|
127
|
+
)}
|
|
128
|
+
</For>
|
|
129
|
+
</Indent>
|
|
130
|
+
<softline />)
|
|
131
|
+
</group>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
@@ -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
|
-
|
|
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>
|