@alloy-js/csharp 0.21.0-dev.15 → 0.21.0-dev.17
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/dist/src/components/var/declaration.d.ts +6 -2
- package/dist/src/components/var/declaration.d.ts.map +1 -1
- package/dist/src/components/var/declaration.js +4 -1
- package/dist/src/components/var/declaration.js.map +1 -1
- package/dist/src/components/var/declaration.test.js +19 -2
- package/dist/src/components/var/declaration.test.js.map +1 -1
- package/dist/src/create-library.d.ts.map +1 -1
- package/dist/src/create-library.js +45 -37
- package/dist/src/create-library.js.map +1 -1
- package/dist/src/create-library.test.js +26 -0
- package/dist/src/create-library.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/components/var/declaration.test.tsx +15 -1
- package/src/components/var/declaration.tsx +12 -3
- package/src/create-library.test.tsx +20 -0
- package/src/create-library.ts +72 -46
- package/temp/api.json +85 -27
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { List, namekey, refkey } from "@alloy-js/core";
|
|
2
|
-
import { expect, it } from "vitest";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
3
|
import { TestNamespace } from "../../../test/utils.jsx";
|
|
4
4
|
import { VarDeclaration } from "./declaration.jsx";
|
|
5
5
|
|
|
@@ -66,3 +66,17 @@ it("links namekey", () => {
|
|
|
66
66
|
var testVar2 = testVar;
|
|
67
67
|
`);
|
|
68
68
|
});
|
|
69
|
+
|
|
70
|
+
describe("modifiers", () => {
|
|
71
|
+
it.each(["const", "using"])("%s", (mod) => {
|
|
72
|
+
expect(
|
|
73
|
+
<TestNamespace>
|
|
74
|
+
<VarDeclaration {...{ [mod]: true }} name="test" type="object">
|
|
75
|
+
a
|
|
76
|
+
</VarDeclaration>
|
|
77
|
+
</TestNamespace>,
|
|
78
|
+
).toRenderTo(`
|
|
79
|
+
${mod} object test = a;
|
|
80
|
+
`);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
@@ -7,11 +7,13 @@ import {
|
|
|
7
7
|
Namekey,
|
|
8
8
|
Refkey,
|
|
9
9
|
} from "@alloy-js/core";
|
|
10
|
+
import { computeModifiersPrefix, makeModifiers } from "../../modifiers.js";
|
|
10
11
|
import { createVariableSymbol } from "../../symbols/factories.js";
|
|
11
12
|
|
|
12
13
|
/** Props for {@link VarDeclaration} component */
|
|
13
14
|
export interface VarDeclarationProps
|
|
14
|
-
extends Omit<DeclarationProps, "nameKind"
|
|
15
|
+
extends Omit<DeclarationProps, "nameKind">,
|
|
16
|
+
VarModifiers {
|
|
15
17
|
/** Variable name */
|
|
16
18
|
name: string | Namekey;
|
|
17
19
|
/** Type of the variable declaration. If not specified, defaults to "var" */
|
|
@@ -20,11 +22,18 @@ export interface VarDeclarationProps
|
|
|
20
22
|
refkey?: Refkey;
|
|
21
23
|
/** Variable value */
|
|
22
24
|
children?: Children;
|
|
25
|
+
}
|
|
23
26
|
|
|
27
|
+
export interface VarModifiers {
|
|
24
28
|
/** Constant variable. Add the const modifier. */
|
|
25
|
-
const?: boolean;
|
|
29
|
+
readonly const?: boolean;
|
|
30
|
+
|
|
31
|
+
/** Disposable variable. Add the using modifier. */
|
|
32
|
+
readonly using?: boolean;
|
|
26
33
|
}
|
|
27
34
|
|
|
35
|
+
const getModifiers = makeModifiers<VarModifiers>(["const", "using"]);
|
|
36
|
+
|
|
28
37
|
/**
|
|
29
38
|
* Render a variable declaration
|
|
30
39
|
*
|
|
@@ -60,7 +69,7 @@ export function VarDeclaration(props: VarDeclarationProps) {
|
|
|
60
69
|
}
|
|
61
70
|
return (
|
|
62
71
|
<Declaration symbol={sym}>
|
|
63
|
-
{props
|
|
72
|
+
{computeModifiersPrefix([getModifiers(props)])}
|
|
64
73
|
<TypeSlot>{props.type ?? "var"}</TypeSlot> <Name /> ={" "}
|
|
65
74
|
<ValueSlot>{props.children}</ValueSlot>;
|
|
66
75
|
</Declaration>
|
|
@@ -191,3 +191,23 @@ it("has built-ins available", () => {
|
|
|
191
191
|
var directoryName = info.DirectoryName?.Length;
|
|
192
192
|
`);
|
|
193
193
|
});
|
|
194
|
+
|
|
195
|
+
it("can render multiple times", () => {
|
|
196
|
+
const System = createLibrary("System", {
|
|
197
|
+
String: {
|
|
198
|
+
kind: "class",
|
|
199
|
+
members: {},
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
expect(<TestNamespace>{System.String}</TestNamespace>).toRenderTo(`
|
|
203
|
+
using System;
|
|
204
|
+
|
|
205
|
+
String
|
|
206
|
+
`);
|
|
207
|
+
|
|
208
|
+
expect(<TestNamespace>{System.String}</TestNamespace>).toRenderTo(`
|
|
209
|
+
using System;
|
|
210
|
+
|
|
211
|
+
String
|
|
212
|
+
`);
|
|
213
|
+
});
|
package/src/create-library.ts
CHANGED
|
@@ -96,16 +96,15 @@ export type LibraryFrom<T> = {
|
|
|
96
96
|
} & LibrarySymbolReference;
|
|
97
97
|
|
|
98
98
|
interface InternalContext {
|
|
99
|
-
binder
|
|
100
|
-
ownerSymbol(): NamedTypeSymbol;
|
|
99
|
+
ownerSymbol(binder: Binder | undefined): NamedTypeSymbol;
|
|
101
100
|
}
|
|
102
101
|
|
|
103
102
|
export function createLibrary<T extends Record<string, Descriptor>>(
|
|
104
103
|
rootNs: string,
|
|
105
104
|
props: T,
|
|
106
105
|
): LibraryFrom<T> {
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
const ownerSymbolPerBinder = new WeakMap<Binder, NamespaceSymbol>();
|
|
107
|
+
|
|
109
108
|
const namespaceNames = rootNs.split(".");
|
|
110
109
|
|
|
111
110
|
return createSymbolEntry(
|
|
@@ -115,33 +114,24 @@ export function createLibrary<T extends Record<string, Descriptor>>(
|
|
|
115
114
|
members: props,
|
|
116
115
|
},
|
|
117
116
|
{
|
|
118
|
-
binder
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if (ownerSymbol!.members.symbolNames.has(name)) {
|
|
133
|
-
ownerSymbol = ownerSymbol!.members.symbolNames.get(
|
|
134
|
-
name,
|
|
135
|
-
)! as NamespaceSymbol;
|
|
136
|
-
} else {
|
|
137
|
-
ownerSymbol = new NamespaceSymbol(name, ownerSymbol!, {
|
|
138
|
-
binder,
|
|
139
|
-
refkeys: refkey(),
|
|
140
|
-
});
|
|
117
|
+
ownerSymbol(binder: Binder | undefined) {
|
|
118
|
+
return mapGet(ownerSymbolPerBinder, binder, () => {
|
|
119
|
+
let ownerSymbol = getGlobalNamespace(binder);
|
|
120
|
+
for (const name of namespaceNames.slice(0, -1)) {
|
|
121
|
+
if (ownerSymbol!.members.symbolNames.has(name)) {
|
|
122
|
+
ownerSymbol = ownerSymbol!.members.symbolNames.get(
|
|
123
|
+
name,
|
|
124
|
+
)! as NamespaceSymbol;
|
|
125
|
+
} else {
|
|
126
|
+
ownerSymbol = new NamespaceSymbol(name, ownerSymbol!, {
|
|
127
|
+
binder,
|
|
128
|
+
refkeys: refkey(),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
141
131
|
}
|
|
142
|
-
}
|
|
143
132
|
|
|
144
|
-
|
|
133
|
+
return ownerSymbol;
|
|
134
|
+
});
|
|
145
135
|
},
|
|
146
136
|
},
|
|
147
137
|
) as LibraryFrom<T>;
|
|
@@ -152,24 +142,26 @@ function createSymbolEntry(
|
|
|
152
142
|
descriptor: Descriptor,
|
|
153
143
|
context: InternalContext,
|
|
154
144
|
): LibrarySymbolReference {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
function getSymbol() {
|
|
158
|
-
if (symbol) return symbol;
|
|
145
|
+
const symbols = new WeakMap<Binder, CSharpSymbol>();
|
|
159
146
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
147
|
+
function getSymbol(binder: Binder | undefined) {
|
|
148
|
+
// We cache symbols per binder to ensure we only create one symbol. We also
|
|
149
|
+
// track an unbound symbol for cases where there is no binder (mostly
|
|
150
|
+
// tests).
|
|
151
|
+
return mapGet(symbols, binder, () =>
|
|
152
|
+
createSymbolFromDescriptor(
|
|
153
|
+
name,
|
|
154
|
+
binder,
|
|
155
|
+
descriptor,
|
|
156
|
+
context,
|
|
157
|
+
initializeMembers,
|
|
158
|
+
),
|
|
165
159
|
);
|
|
166
|
-
return symbol;
|
|
167
160
|
}
|
|
168
161
|
|
|
169
162
|
const newContext: InternalContext = {
|
|
170
|
-
binder
|
|
171
|
-
|
|
172
|
-
return getSymbol() as NamedTypeSymbol;
|
|
163
|
+
ownerSymbol(binder) {
|
|
164
|
+
return getSymbol(binder) as NamedTypeSymbol;
|
|
173
165
|
},
|
|
174
166
|
};
|
|
175
167
|
|
|
@@ -182,10 +174,10 @@ function createSymbolEntry(
|
|
|
182
174
|
|
|
183
175
|
const obj: LibrarySymbolReference & Record<string, unknown> = {
|
|
184
176
|
[REFKEYABLE]() {
|
|
185
|
-
return getSymbol().refkeys[0];
|
|
177
|
+
return getSymbol(useBinder()).refkeys[0];
|
|
186
178
|
},
|
|
187
179
|
[TO_SYMBOL]() {
|
|
188
|
-
return getSymbol();
|
|
180
|
+
return getSymbol(useBinder());
|
|
189
181
|
},
|
|
190
182
|
};
|
|
191
183
|
|
|
@@ -209,12 +201,12 @@ function createSymbolEntry(
|
|
|
209
201
|
|
|
210
202
|
function createSymbolFromDescriptor(
|
|
211
203
|
name: string,
|
|
204
|
+
binder: Binder | undefined,
|
|
212
205
|
descriptor: Descriptor,
|
|
213
206
|
context: InternalContext,
|
|
214
207
|
lazyMemberInitializer: () => void,
|
|
215
208
|
): CSharpSymbol {
|
|
216
|
-
const ownerSymbol = context.ownerSymbol();
|
|
217
|
-
const binder = context.binder();
|
|
209
|
+
const ownerSymbol = context.ownerSymbol(binder);
|
|
218
210
|
|
|
219
211
|
switch (descriptor.kind) {
|
|
220
212
|
case "namespace":
|
|
@@ -268,3 +260,37 @@ function createSymbolFromDescriptor(
|
|
|
268
260
|
throw "Unsupported";
|
|
269
261
|
}
|
|
270
262
|
}
|
|
263
|
+
|
|
264
|
+
const defaultsPerMap = new WeakMap<object, unknown>();
|
|
265
|
+
|
|
266
|
+
function mapGet<T extends WeakKey, V>(
|
|
267
|
+
map: WeakMap<T, V>,
|
|
268
|
+
key: T | undefined,
|
|
269
|
+
): V | undefined;
|
|
270
|
+
function mapGet<T extends WeakKey, V>(
|
|
271
|
+
map: WeakMap<T, V>,
|
|
272
|
+
key: T | undefined,
|
|
273
|
+
init: () => V,
|
|
274
|
+
): V;
|
|
275
|
+
function mapGet<T extends WeakKey, V>(
|
|
276
|
+
map: WeakMap<T, V>,
|
|
277
|
+
key: T | undefined,
|
|
278
|
+
init?: () => V,
|
|
279
|
+
): V | undefined {
|
|
280
|
+
if (key === undefined) {
|
|
281
|
+
// Use a per-map default store when callers request a value for an undefined key.
|
|
282
|
+
let value = defaultsPerMap.get(map as unknown as object) as V | undefined;
|
|
283
|
+
if (value === undefined && init) {
|
|
284
|
+
value = init();
|
|
285
|
+
defaultsPerMap.set(map as unknown as object, value);
|
|
286
|
+
}
|
|
287
|
+
return value;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
let value = map.get(key);
|
|
291
|
+
if (value === undefined && init) {
|
|
292
|
+
value = init();
|
|
293
|
+
map.set(key, value);
|
|
294
|
+
}
|
|
295
|
+
return value;
|
|
296
|
+
}
|
package/temp/api.json
CHANGED
|
@@ -16856,6 +16856,15 @@
|
|
|
16856
16856
|
"kind": "Content",
|
|
16857
16857
|
"text": ", \"nameKind\">"
|
|
16858
16858
|
},
|
|
16859
|
+
{
|
|
16860
|
+
"kind": "Content",
|
|
16861
|
+
"text": ", "
|
|
16862
|
+
},
|
|
16863
|
+
{
|
|
16864
|
+
"kind": "Reference",
|
|
16865
|
+
"text": "VarModifiers",
|
|
16866
|
+
"canonicalReference": "@alloy-js/csharp!VarModifiers:interface"
|
|
16867
|
+
},
|
|
16859
16868
|
{
|
|
16860
16869
|
"kind": "Content",
|
|
16861
16870
|
"text": " "
|
|
@@ -16894,33 +16903,6 @@
|
|
|
16894
16903
|
"endIndex": 2
|
|
16895
16904
|
}
|
|
16896
16905
|
},
|
|
16897
|
-
{
|
|
16898
|
-
"kind": "PropertySignature",
|
|
16899
|
-
"canonicalReference": "@alloy-js/csharp!VarDeclarationProps#const:member",
|
|
16900
|
-
"docComment": "/**\n * Constant variable. Add the const modifier.\n */\n",
|
|
16901
|
-
"excerptTokens": [
|
|
16902
|
-
{
|
|
16903
|
-
"kind": "Content",
|
|
16904
|
-
"text": "const?: "
|
|
16905
|
-
},
|
|
16906
|
-
{
|
|
16907
|
-
"kind": "Content",
|
|
16908
|
-
"text": "boolean"
|
|
16909
|
-
},
|
|
16910
|
-
{
|
|
16911
|
-
"kind": "Content",
|
|
16912
|
-
"text": ";"
|
|
16913
|
-
}
|
|
16914
|
-
],
|
|
16915
|
-
"isReadonly": false,
|
|
16916
|
-
"isOptional": true,
|
|
16917
|
-
"releaseTag": "Public",
|
|
16918
|
-
"name": "const",
|
|
16919
|
-
"propertyTypeTokenRange": {
|
|
16920
|
-
"startIndex": 1,
|
|
16921
|
-
"endIndex": 2
|
|
16922
|
-
}
|
|
16923
|
-
},
|
|
16924
16906
|
{
|
|
16925
16907
|
"kind": "PropertySignature",
|
|
16926
16908
|
"canonicalReference": "@alloy-js/csharp!VarDeclarationProps#name:member",
|
|
@@ -17014,8 +16996,84 @@
|
|
|
17014
16996
|
{
|
|
17015
16997
|
"startIndex": 1,
|
|
17016
16998
|
"endIndex": 5
|
|
16999
|
+
},
|
|
17000
|
+
{
|
|
17001
|
+
"startIndex": 6,
|
|
17002
|
+
"endIndex": 7
|
|
17017
17003
|
}
|
|
17018
17004
|
]
|
|
17005
|
+
},
|
|
17006
|
+
{
|
|
17007
|
+
"kind": "Interface",
|
|
17008
|
+
"canonicalReference": "@alloy-js/csharp!VarModifiers:interface",
|
|
17009
|
+
"docComment": "",
|
|
17010
|
+
"excerptTokens": [
|
|
17011
|
+
{
|
|
17012
|
+
"kind": "Content",
|
|
17013
|
+
"text": "export interface VarModifiers "
|
|
17014
|
+
}
|
|
17015
|
+
],
|
|
17016
|
+
"fileUrlPath": "src/components/var/declaration.tsx",
|
|
17017
|
+
"releaseTag": "Public",
|
|
17018
|
+
"name": "VarModifiers",
|
|
17019
|
+
"preserveMemberOrder": false,
|
|
17020
|
+
"members": [
|
|
17021
|
+
{
|
|
17022
|
+
"kind": "PropertySignature",
|
|
17023
|
+
"canonicalReference": "@alloy-js/csharp!VarModifiers#const:member",
|
|
17024
|
+
"docComment": "/**\n * Constant variable. Add the const modifier.\n */\n",
|
|
17025
|
+
"excerptTokens": [
|
|
17026
|
+
{
|
|
17027
|
+
"kind": "Content",
|
|
17028
|
+
"text": "readonly const?: "
|
|
17029
|
+
},
|
|
17030
|
+
{
|
|
17031
|
+
"kind": "Content",
|
|
17032
|
+
"text": "boolean"
|
|
17033
|
+
},
|
|
17034
|
+
{
|
|
17035
|
+
"kind": "Content",
|
|
17036
|
+
"text": ";"
|
|
17037
|
+
}
|
|
17038
|
+
],
|
|
17039
|
+
"isReadonly": true,
|
|
17040
|
+
"isOptional": true,
|
|
17041
|
+
"releaseTag": "Public",
|
|
17042
|
+
"name": "const",
|
|
17043
|
+
"propertyTypeTokenRange": {
|
|
17044
|
+
"startIndex": 1,
|
|
17045
|
+
"endIndex": 2
|
|
17046
|
+
}
|
|
17047
|
+
},
|
|
17048
|
+
{
|
|
17049
|
+
"kind": "PropertySignature",
|
|
17050
|
+
"canonicalReference": "@alloy-js/csharp!VarModifiers#using:member",
|
|
17051
|
+
"docComment": "/**\n * Disposable variable. Add the using modifier.\n */\n",
|
|
17052
|
+
"excerptTokens": [
|
|
17053
|
+
{
|
|
17054
|
+
"kind": "Content",
|
|
17055
|
+
"text": "readonly using?: "
|
|
17056
|
+
},
|
|
17057
|
+
{
|
|
17058
|
+
"kind": "Content",
|
|
17059
|
+
"text": "boolean"
|
|
17060
|
+
},
|
|
17061
|
+
{
|
|
17062
|
+
"kind": "Content",
|
|
17063
|
+
"text": ";"
|
|
17064
|
+
}
|
|
17065
|
+
],
|
|
17066
|
+
"isReadonly": true,
|
|
17067
|
+
"isOptional": true,
|
|
17068
|
+
"releaseTag": "Public",
|
|
17069
|
+
"name": "using",
|
|
17070
|
+
"propertyTypeTokenRange": {
|
|
17071
|
+
"startIndex": 1,
|
|
17072
|
+
"endIndex": 2
|
|
17073
|
+
}
|
|
17074
|
+
}
|
|
17075
|
+
],
|
|
17076
|
+
"extendsTokenRanges": []
|
|
17019
17077
|
}
|
|
17020
17078
|
]
|
|
17021
17079
|
}
|