@alloy-js/core 0.20.0-dev.4 → 0.20.0-dev.6
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/binder.d.ts +62 -38
- package/dist/src/binder.d.ts.map +1 -1
- package/dist/src/binder.js +214 -173
- package/dist/src/components/Declaration.d.ts +2 -2
- package/dist/src/components/Declaration.d.ts.map +1 -1
- package/dist/src/components/Declaration.js +8 -2
- package/dist/src/components/MemberDeclaration.d.ts +2 -2
- package/dist/src/components/MemberDeclaration.d.ts.map +1 -1
- package/dist/src/components/MemberDeclaration.js +9 -5
- package/dist/src/components/MemberScope.d.ts +30 -13
- package/dist/src/components/MemberScope.d.ts.map +1 -1
- package/dist/src/components/MemberScope.js +37 -15
- package/dist/src/components/Output.d.ts.map +1 -1
- package/dist/src/components/Output.js +2 -5
- package/dist/src/components/ReferenceOrContent.d.ts +1 -1
- package/dist/src/components/ReferenceOrContent.d.ts.map +1 -1
- package/dist/src/components/Scope.d.ts +5 -5
- package/dist/src/components/Scope.d.ts.map +1 -1
- package/dist/src/components/Scope.js +9 -5
- package/dist/src/context/member-scope.d.ts +7 -8
- package/dist/src/context/member-scope.d.ts.map +1 -1
- package/dist/src/context/member-scope.js +5 -5
- package/dist/src/context/name-policy.d.ts.map +1 -1
- package/dist/src/context/name-policy.js +3 -0
- package/dist/src/context/scope.d.ts +1 -0
- package/dist/src/context/scope.d.ts.map +1 -1
- package/dist/src/context/scope.js +7 -0
- package/dist/src/inspect.browser.d.ts +5 -0
- package/dist/src/inspect.browser.d.ts.map +1 -0
- package/dist/src/inspect.browser.js +5 -0
- package/dist/src/inspect.d.ts +2 -0
- package/dist/src/inspect.d.ts.map +1 -0
- package/dist/src/inspect.js +1 -0
- package/dist/src/name-policy.d.ts +11 -0
- package/dist/src/name-policy.d.ts.map +1 -1
- package/dist/src/name-policy.js +3 -0
- package/dist/src/reactive-union-set.d.ts.map +1 -1
- package/dist/src/reactive-union-set.js +12 -8
- package/dist/src/refkey.d.ts +39 -3
- package/dist/src/refkey.d.ts.map +1 -1
- package/dist/src/refkey.js +52 -8
- package/dist/src/symbols/basic-scope.d.ts +14 -0
- package/dist/src/symbols/basic-scope.d.ts.map +1 -0
- package/dist/src/symbols/basic-scope.js +20 -0
- package/dist/src/symbols/basic-symbol.d.ts +19 -0
- package/dist/src/symbols/basic-symbol.d.ts.map +1 -0
- package/dist/src/symbols/basic-symbol.js +28 -0
- package/dist/src/symbols/index.d.ts +3 -1
- package/dist/src/symbols/index.d.ts.map +1 -1
- package/dist/src/symbols/index.js +3 -1
- package/dist/src/symbols/output-scope.d.ts +70 -41
- package/dist/src/symbols/output-scope.d.ts.map +1 -1
- package/dist/src/symbols/output-scope.js +98 -130
- package/dist/src/symbols/output-space.d.ts +25 -0
- package/dist/src/symbols/output-space.d.ts.map +1 -0
- package/dist/src/symbols/output-space.js +35 -0
- package/dist/src/symbols/output-symbol.d.ts +213 -37
- package/dist/src/symbols/output-symbol.d.ts.map +1 -1
- package/dist/src/symbols/output-symbol.js +323 -203
- package/dist/src/symbols/symbol-flow.d.ts +1 -1
- package/dist/src/symbols/symbol-flow.d.ts.map +1 -1
- package/dist/src/symbols/symbol-flow.js +22 -7
- package/dist/src/symbols/symbol-slot.d.ts +27 -9
- package/dist/src/symbols/symbol-slot.d.ts.map +1 -1
- package/dist/src/symbols/symbol-slot.js +20 -4
- package/dist/src/symbols/symbol-table.d.ts +19 -8
- package/dist/src/symbols/symbol-table.d.ts.map +1 -1
- package/dist/src/symbols/symbol-table.js +65 -16
- package/dist/src/tracer.d.ts +15 -3
- package/dist/src/tracer.d.ts.map +1 -1
- package/dist/src/tracer.js +39 -63
- package/dist/test/components/declaration.test.js +9 -14
- package/dist/test/components/reference-or-content.test.js +2 -2
- package/dist/test/symbols/output-scope.test.js +33 -198
- package/dist/test/symbols/output-symbol.test.js +139 -385
- package/dist/test/symbols/resolution.test.js +431 -114
- package/dist/test/symbols/symbol-table.test.d.ts +2 -0
- package/dist/test/symbols/symbol-table.test.d.ts.map +1 -0
- package/dist/test/symbols/symbol-table.test.js +14 -0
- package/dist/test/symbols/utils.d.ts +10 -24
- package/dist/test/symbols/utils.d.ts.map +1 -1
- package/dist/test/symbols/utils.js +23 -45
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -2
- package/src/binder.ts +348 -273
- package/src/components/Declaration.tsx +13 -3
- package/src/components/MemberDeclaration.tsx +15 -8
- package/src/components/MemberScope.tsx +61 -20
- package/src/components/Output.tsx +0 -4
- package/src/components/Scope.tsx +16 -9
- package/src/context/member-scope.ts +10 -10
- package/src/context/name-policy.ts +3 -0
- package/src/context/scope.ts +9 -0
- package/src/inspect.browser.ts +6 -0
- package/src/inspect.ts +1 -0
- package/src/name-policy.ts +14 -0
- package/src/reactive-union-set.ts +14 -8
- package/src/refkey.ts +88 -14
- package/src/symbols/basic-scope.ts +23 -0
- package/src/symbols/basic-symbol.ts +32 -0
- package/src/symbols/index.ts +3 -1
- package/src/symbols/output-scope.ts +131 -170
- package/src/symbols/output-space.ts +49 -0
- package/src/symbols/output-symbol.ts +434 -258
- package/src/symbols/symbol-flow.ts +38 -9
- package/src/symbols/symbol-slot.tsx +46 -8
- package/src/symbols/symbol-table.ts +95 -21
- package/src/tracer.ts +53 -83
- package/temp/api.json +5559 -3079
- package/test/components/declaration.test.tsx +6 -19
- package/test/components/reference-or-content.test.tsx +2 -2
- package/test/symbols/output-scope.test.ts +33 -125
- package/test/symbols/output-symbol.test.ts +128 -348
- package/test/symbols/resolution.test.ts +530 -117
- package/test/symbols/symbol-table.test.ts +15 -0
- package/test/symbols/utils.ts +38 -74
- package/tsdoc.json +4 -0
- package/dist/src/slot.d.ts +0 -15
- package/dist/src/slot.d.ts.map +0 -1
- package/dist/src/slot.js +0 -50
- package/dist/src/symbols/flags.d.ts +0 -70
- package/dist/src/symbols/flags.d.ts.map +0 -1
- package/dist/src/symbols/flags.js +0 -72
- package/dist/test/components/slot.test.d.ts +0 -2
- package/dist/test/components/slot.test.d.ts.map +0 -1
- package/dist/test/components/slot.test.js +0 -134
- package/src/slot.ts +0 -89
- package/src/symbols/flags.ts +0 -82
- package/test/components/slot.test.tsx +0 -174
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { useContext } from "../context.js";
|
|
2
2
|
import { BinderContext } from "../context/binder.js";
|
|
3
3
|
import { DeclarationContext } from "../context/declaration.js";
|
|
4
|
+
import { useScope } from "../context/scope.js";
|
|
4
5
|
import { onCleanup } from "../reactivity.js";
|
|
5
|
-
import { Refkey } from "../refkey.js";
|
|
6
|
+
import { Namekey, Refkey } from "../refkey.js";
|
|
6
7
|
import type { Children } from "../runtime/component.js";
|
|
8
|
+
import { BasicScope } from "../symbols/basic-scope.js";
|
|
9
|
+
import { BasicSymbol } from "../symbols/basic-symbol.js";
|
|
7
10
|
import { OutputSymbol } from "../symbols/output-symbol.js";
|
|
8
11
|
|
|
9
12
|
/**
|
|
@@ -27,7 +30,7 @@ export interface DeclarationPropsWithInfo {
|
|
|
27
30
|
/**
|
|
28
31
|
* The name of this declaration.
|
|
29
32
|
*/
|
|
30
|
-
name: string;
|
|
33
|
+
name: string | Namekey;
|
|
31
34
|
|
|
32
35
|
/**
|
|
33
36
|
* The unique key or array of unique keys for this declaration.
|
|
@@ -73,7 +76,14 @@ export function Declaration(props: DeclarationProps) {
|
|
|
73
76
|
if ("symbol" in props) {
|
|
74
77
|
declaration = props.symbol;
|
|
75
78
|
} else {
|
|
76
|
-
|
|
79
|
+
const scope = useScope();
|
|
80
|
+
if (!(scope instanceof BasicScope)) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
"Declaration component cannot create a symbol in a non-basic scope",
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
declaration = new BasicSymbol(props.name, scope.symbols, {
|
|
77
87
|
binder,
|
|
78
88
|
refkeys: [props.refkey ?? []].flat(),
|
|
79
89
|
metadata: props.metadata,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { useContext } from "../context.js";
|
|
2
2
|
import { BinderContext } from "../context/binder.js";
|
|
3
3
|
import { MemberDeclarationContext } from "../context/member-declaration.js";
|
|
4
|
-
import
|
|
4
|
+
import { useMemberContext } from "../context/member-scope.js";
|
|
5
|
+
import type { Namekey, Refkey } from "../refkey.js";
|
|
5
6
|
import type { Children } from "../runtime/component.js";
|
|
6
|
-
import {
|
|
7
|
+
import { BasicSymbol } from "../symbols/basic-symbol.js";
|
|
7
8
|
import { OutputSymbol } from "../symbols/output-symbol.js";
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -14,7 +15,7 @@ export interface MemberDeclarationPropsWithInfo {
|
|
|
14
15
|
/**
|
|
15
16
|
* The name of this declaration.
|
|
16
17
|
*/
|
|
17
|
-
name: string;
|
|
18
|
+
name: string | Namekey;
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* The refkey or array refkeys for this declaration.
|
|
@@ -87,13 +88,19 @@ export function MemberDeclaration(props: MemberDeclarationProps) {
|
|
|
87
88
|
);
|
|
88
89
|
}
|
|
89
90
|
|
|
90
|
-
|
|
91
|
+
const scopeContext = useMemberContext()!;
|
|
92
|
+
if (!(scopeContext.ownerSymbol instanceof BasicSymbol)) {
|
|
93
|
+
throw new Error(
|
|
94
|
+
"MemberDeclaration component cannot create a symbol in a non-basic scope",
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
const space =
|
|
98
|
+
infoProps.static ?
|
|
99
|
+
scopeContext.ownerSymbol.staticMembers
|
|
100
|
+
: scopeContext.ownerSymbol.instanceMembers;
|
|
101
|
+
declaration = new BasicSymbol(infoProps.name, space, {
|
|
91
102
|
refkeys: infoProps.refkey,
|
|
92
103
|
metadata: infoProps.metadata,
|
|
93
|
-
flags:
|
|
94
|
-
infoProps.static ?
|
|
95
|
-
OutputSymbolFlags.StaticMember
|
|
96
|
-
: OutputSymbolFlags.InstanceMember,
|
|
97
104
|
});
|
|
98
105
|
}
|
|
99
106
|
|
|
@@ -1,41 +1,82 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MemberContext } from "../context/member-scope.js";
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
4
|
+
import { ScopeContext } from "../context/scope.js";
|
|
2
5
|
import type { Children } from "../runtime/component.js";
|
|
6
|
+
import { OutputScope } from "../symbols/output-scope.js";
|
|
3
7
|
import type { OutputSymbol } from "../symbols/output-symbol.js";
|
|
4
|
-
|
|
8
|
+
import { Scope } from "./Scope.jsx";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Declare a member scope by providing an already created scope. The scope is
|
|
12
|
+
* exposed via {@link ScopeContext}.
|
|
13
|
+
*/
|
|
14
|
+
export interface MemberScopePropsWithValue {
|
|
15
|
+
/**
|
|
16
|
+
* The scope to use. If not provided, a new scope will be created.
|
|
17
|
+
*/
|
|
18
|
+
value: OutputScope;
|
|
19
|
+
|
|
20
|
+
children?: Children;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Create a member scope by providing a name and optional metadata.
|
|
25
|
+
*/
|
|
26
|
+
export interface MemberScopePropsWithInfo {
|
|
5
27
|
/**
|
|
6
|
-
* The name of
|
|
28
|
+
* The name of this scope.
|
|
7
29
|
*/
|
|
8
30
|
name?: string;
|
|
9
31
|
|
|
10
32
|
/**
|
|
11
|
-
* The symbol
|
|
12
|
-
|
|
13
|
-
|
|
33
|
+
* The symbol whose members provide the symbols for this scope.
|
|
34
|
+
*/
|
|
35
|
+
ownerSymbol: OutputSymbol;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Additional metadata for the scope.
|
|
14
39
|
*/
|
|
15
|
-
|
|
40
|
+
metadata?: Record<string, unknown>;
|
|
41
|
+
|
|
16
42
|
children?: Children;
|
|
17
43
|
}
|
|
18
44
|
|
|
45
|
+
export type MemberScopeProps =
|
|
46
|
+
| MemberScopePropsWithValue
|
|
47
|
+
| MemberScopePropsWithInfo;
|
|
48
|
+
|
|
19
49
|
/**
|
|
20
|
-
* Declare a member scope, which is a scope
|
|
21
|
-
*
|
|
22
|
-
* declarations and resolution of instance members.
|
|
50
|
+
* Declare a member scope, which is a lexical scope whose symbols are provided
|
|
51
|
+
* by the owner symbol.
|
|
23
52
|
*
|
|
24
53
|
* @remarks
|
|
25
54
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
55
|
+
* This is used to create members of a symbol, e.g. for class members and the
|
|
56
|
+
* like. In some languages, this scope may provide symbols which are can be
|
|
57
|
+
* referenced lexically, but in other languages, these members may not be in
|
|
58
|
+
* scope and instead must be referenced via the owner symbol itself.
|
|
30
59
|
*/
|
|
31
60
|
export function MemberScope(props: MemberScopeProps) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
61
|
+
if ("value" in props) {
|
|
62
|
+
const sym = props.value;
|
|
63
|
+
if (!sym.isMemberScope) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
"MemberScope must be passed a value that is a member scope.",
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const context: MemberContext = {
|
|
71
|
+
ownerSymbol:
|
|
72
|
+
"value" in props ? props.value.ownerSymbol! : props.ownerSymbol!,
|
|
35
73
|
};
|
|
74
|
+
|
|
36
75
|
return (
|
|
37
|
-
<
|
|
38
|
-
{
|
|
39
|
-
|
|
76
|
+
<Scope {...props}>
|
|
77
|
+
<MemberContext.Provider value={context}>
|
|
78
|
+
{props.children}
|
|
79
|
+
</MemberContext.Provider>
|
|
80
|
+
</Scope>
|
|
40
81
|
);
|
|
41
82
|
}
|
|
@@ -9,7 +9,6 @@ import { NamePolicy } from "../name-policy.js";
|
|
|
9
9
|
import { getContext } from "../reactivity.js";
|
|
10
10
|
import { PrintTreeOptions } from "../render.js";
|
|
11
11
|
import type { Children } from "../runtime/component.js";
|
|
12
|
-
import { extensionEffects } from "../slot.js";
|
|
13
12
|
import { SourceDirectory } from "./SourceDirectory.js";
|
|
14
13
|
|
|
15
14
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -71,9 +70,6 @@ export function Output(props: OutputProps) {
|
|
|
71
70
|
|
|
72
71
|
return (
|
|
73
72
|
<BinderContext.Provider value={binder}>
|
|
74
|
-
{() => {
|
|
75
|
-
extensionEffects.forEach((e) => e());
|
|
76
|
-
}}
|
|
77
73
|
{props.namePolicy ?
|
|
78
74
|
<NamePolicyContext.Provider value={props.namePolicy}>
|
|
79
75
|
{dir}
|
package/src/components/Scope.tsx
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { ScopeContext } from "../context/scope.js";
|
|
1
|
+
import { ScopeContext, useScope } from "../context/scope.js";
|
|
2
2
|
import type { Children } from "../runtime/component.js";
|
|
3
|
+
import { BasicScope } from "../symbols/basic-scope.js";
|
|
3
4
|
import { OutputScope } from "../symbols/output-scope.js";
|
|
5
|
+
import { OutputSymbol } from "../symbols/output-symbol.js";
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Declare a scope by providing an already created scope. The scope is merely
|
|
@@ -19,12 +21,6 @@ export interface ScopePropsWithValue {
|
|
|
19
21
|
* Create a scope by providing a name and optional metadata.
|
|
20
22
|
*/
|
|
21
23
|
export interface ScopePropsWithInfo {
|
|
22
|
-
/**
|
|
23
|
-
* The kind of scope. This may be used by application code to determine how
|
|
24
|
-
* to handle symbols in this scope. It is not used by the core framework.
|
|
25
|
-
*/
|
|
26
|
-
kind?: string;
|
|
27
|
-
|
|
28
24
|
/**
|
|
29
25
|
* The name of this scope.
|
|
30
26
|
*/
|
|
@@ -35,6 +31,11 @@ export interface ScopePropsWithInfo {
|
|
|
35
31
|
*/
|
|
36
32
|
metadata?: Record<string, unknown>;
|
|
37
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Create a member scope with the owner symbol providing the in-scope symbols.
|
|
36
|
+
*/
|
|
37
|
+
ownerSymbol?: OutputSymbol;
|
|
38
|
+
|
|
38
39
|
children?: Children;
|
|
39
40
|
}
|
|
40
41
|
|
|
@@ -51,9 +52,15 @@ export function Scope(props: ScopeProps) {
|
|
|
51
52
|
if ("value" in props) {
|
|
52
53
|
scope = props.value;
|
|
53
54
|
} else {
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
const parentScope = useScope();
|
|
56
|
+
if (parentScope && !(parentScope instanceof BasicScope)) {
|
|
57
|
+
throw new Error(
|
|
58
|
+
"Scope component can only make scopes within a BasicScope",
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
scope = new BasicScope(props.name ?? "", parentScope, {
|
|
56
62
|
metadata: props.metadata,
|
|
63
|
+
ownerSymbol: props.ownerSymbol,
|
|
57
64
|
});
|
|
58
65
|
}
|
|
59
66
|
|
|
@@ -3,19 +3,19 @@ import {
|
|
|
3
3
|
createNamedContext,
|
|
4
4
|
useContext,
|
|
5
5
|
} from "../context.js";
|
|
6
|
-
import
|
|
6
|
+
import { OutputSymbol } from "../symbols/output-symbol.js";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* The member
|
|
10
|
-
*
|
|
9
|
+
* The member context provides the symbol upon which new member symbols
|
|
10
|
+
* should be created.
|
|
11
11
|
*/
|
|
12
|
-
export interface
|
|
13
|
-
|
|
14
|
-
instanceMembers?: OutputScope;
|
|
12
|
+
export interface MemberContext {
|
|
13
|
+
ownerSymbol: OutputSymbol;
|
|
15
14
|
}
|
|
16
|
-
export const MemberScopeContext: ComponentContext<MemberScopeContext> =
|
|
17
|
-
createNamedContext("MemberScope");
|
|
18
15
|
|
|
19
|
-
export
|
|
20
|
-
|
|
16
|
+
export const MemberContext: ComponentContext<MemberContext> =
|
|
17
|
+
createNamedContext("MemberContext");
|
|
18
|
+
|
|
19
|
+
export function useMemberContext() {
|
|
20
|
+
return useContext(MemberContext);
|
|
21
21
|
}
|
package/src/context/scope.ts
CHANGED
|
@@ -11,3 +11,12 @@ export const ScopeContext: ComponentContext<OutputScope> =
|
|
|
11
11
|
export function useScope() {
|
|
12
12
|
return useContext(ScopeContext)!;
|
|
13
13
|
}
|
|
14
|
+
|
|
15
|
+
export function useMemberScope() {
|
|
16
|
+
const scope = useScope();
|
|
17
|
+
if (!scope.isMemberScope) {
|
|
18
|
+
throw new Error("Expected a member scope, but got a non-member scope.");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return scope;
|
|
22
|
+
}
|
package/src/inspect.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { inspect } from "util";
|
package/src/name-policy.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
|
+
export interface NamePolicyGetter {
|
|
2
|
+
(originalName: string): string;
|
|
3
|
+
}
|
|
1
4
|
export interface NamePolicy<TElements extends string> {
|
|
5
|
+
/**
|
|
6
|
+
* Apply the language policy to the provided name for the provided element
|
|
7
|
+
* type.
|
|
8
|
+
*/
|
|
2
9
|
getName(originalName: string, element: TElements): string;
|
|
10
|
+
/**
|
|
11
|
+
* Get a function that takes a name and applies the naming policy to it.
|
|
12
|
+
*/
|
|
13
|
+
for(element: TElements): NamePolicyGetter;
|
|
3
14
|
}
|
|
4
15
|
|
|
5
16
|
export function createNamePolicy<T extends string>(
|
|
@@ -9,5 +20,8 @@ export function createNamePolicy<T extends string>(
|
|
|
9
20
|
getName(name, element) {
|
|
10
21
|
return namer(name, element);
|
|
11
22
|
},
|
|
23
|
+
for(element) {
|
|
24
|
+
return (name) => namer(name, element);
|
|
25
|
+
},
|
|
12
26
|
};
|
|
13
27
|
}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
trigger,
|
|
9
9
|
TriggerOpTypes,
|
|
10
10
|
} from "@vue/reactivity";
|
|
11
|
-
import { effect } from "./reactivity.js";
|
|
11
|
+
import { effect, untrack } from "./reactivity.js";
|
|
12
12
|
|
|
13
13
|
export interface ReactiveUnionSetOptions<T> {
|
|
14
14
|
onAdd?: OnReactiveSetAddCallback<T>;
|
|
@@ -133,7 +133,7 @@ export class ReactiveUnionSet<T> extends Set<T> {
|
|
|
133
133
|
effect(() => {
|
|
134
134
|
for (const [prevSourceValue, prevTargetValue] of prevValues) {
|
|
135
135
|
if (!subset.has(prevSourceValue)) {
|
|
136
|
-
onDelete?.(prevSourceValue);
|
|
136
|
+
untrack(() => onDelete?.(prevSourceValue));
|
|
137
137
|
prevValues.delete(prevSourceValue);
|
|
138
138
|
this.delete(prevTargetValue);
|
|
139
139
|
}
|
|
@@ -142,7 +142,7 @@ export class ReactiveUnionSet<T> extends Set<T> {
|
|
|
142
142
|
for (const value of subset) {
|
|
143
143
|
if (!prevValues.has(value)) {
|
|
144
144
|
if (onAdd) {
|
|
145
|
-
const added = onAdd(value);
|
|
145
|
+
const added = untrack(() => onAdd(value));
|
|
146
146
|
prevValues.set(value, added);
|
|
147
147
|
} else {
|
|
148
148
|
this.add(value);
|
|
@@ -207,22 +207,28 @@ export class ReactiveUnionSet<T> extends Set<T> {
|
|
|
207
207
|
|
|
208
208
|
return shallowReadonly(set);
|
|
209
209
|
}
|
|
210
|
+
|
|
210
211
|
createIndex<U>(mapper: (value: T) => U | U[]): ReadonlyMap<U, T> {
|
|
211
212
|
const index = shallowReactive(new Map<U, T>());
|
|
212
213
|
this._indexes.push({
|
|
213
214
|
add: (value: T) => {
|
|
214
215
|
effect((oldValue) => {
|
|
215
|
-
|
|
216
|
-
|
|
216
|
+
if (oldValue) {
|
|
217
|
+
for (const id of [oldValue].flat()) {
|
|
218
|
+
index.delete(id as U);
|
|
219
|
+
}
|
|
217
220
|
}
|
|
218
221
|
|
|
219
|
-
|
|
222
|
+
// we filter to avoid overwriting existing values (first wins)
|
|
223
|
+
const mappedValues = [mapper(value)]
|
|
224
|
+
.flat()
|
|
225
|
+
.filter((v) => untrack(() => !index.has(v as U)));
|
|
220
226
|
|
|
221
|
-
for (const id of
|
|
227
|
+
for (const id of mappedValues) {
|
|
222
228
|
index.set(id as U, value as any);
|
|
223
229
|
}
|
|
224
230
|
|
|
225
|
-
return
|
|
231
|
+
return mappedValues;
|
|
226
232
|
});
|
|
227
233
|
},
|
|
228
234
|
delete: (value: T) => {
|
package/src/refkey.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { markRaw } from "@vue/reactivity";
|
|
2
2
|
|
|
3
|
-
const objectIds = new WeakMap<WeakKey,
|
|
3
|
+
const objectIds = new WeakMap<WeakKey, string>();
|
|
4
4
|
let objId = 0;
|
|
5
5
|
|
|
6
|
-
function getObjectKey(value: WeakKey) {
|
|
6
|
+
function getObjectKey(value: WeakKey): string {
|
|
7
7
|
if (objectIds.has(value)) {
|
|
8
8
|
return objectIds.get(value)!;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
const key =
|
|
11
|
+
const key = `o${objId++}`;
|
|
12
12
|
objectIds.set(value, key);
|
|
13
13
|
|
|
14
14
|
return key;
|
|
@@ -16,10 +16,34 @@ function getObjectKey(value: WeakKey) {
|
|
|
16
16
|
|
|
17
17
|
const RefkeySym: unique symbol = Symbol();
|
|
18
18
|
|
|
19
|
-
export type
|
|
19
|
+
export type RefkeyBase = {
|
|
20
|
+
[RefkeySym]: true;
|
|
21
|
+
};
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
export type Refkey = SymbolRefkey | MemberRefkey | Namekey;
|
|
24
|
+
|
|
25
|
+
export interface SymbolRefkey extends RefkeyBase {
|
|
26
|
+
key: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface NamekeyOptions {
|
|
30
|
+
ignoreNamePolicy?: boolean;
|
|
31
|
+
ignoreNameConflict?: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface Namekey<TOptions extends NamekeyOptions = NamekeyOptions>
|
|
35
|
+
extends SymbolRefkey {
|
|
36
|
+
name: string;
|
|
37
|
+
options: TOptions;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface MemberRefkey extends RefkeyBase {
|
|
41
|
+
base: Refkey;
|
|
42
|
+
member: Refkey;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function createSymbolRefkey(key: string): SymbolRefkey {
|
|
46
|
+
const refkey: SymbolRefkey = {
|
|
23
47
|
key,
|
|
24
48
|
[RefkeySym]: true,
|
|
25
49
|
};
|
|
@@ -37,13 +61,34 @@ export function isRefkey(value: unknown): value is Refkey {
|
|
|
37
61
|
);
|
|
38
62
|
}
|
|
39
63
|
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
|
|
64
|
+
export function isSymbolRefkey(value: unknown): value is SymbolRefkey {
|
|
65
|
+
return isRefkey(value) && Object.hasOwn(value, "key");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function isMemberRefkey(value: unknown): value is MemberRefkey {
|
|
69
|
+
return (
|
|
70
|
+
isRefkey(value) &&
|
|
71
|
+
Object.hasOwn(value, "base") &&
|
|
72
|
+
Object.hasOwn(value, "member")
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function isNamekey(value: unknown): value is Namekey {
|
|
77
|
+
return isRefkey(value) && Object.hasOwn(value, "name");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* This gets the key for a symbol refkey based on the value provided. Refkey values
|
|
82
|
+
* return the key of that refkey, objects get a unique key for that specific object,
|
|
83
|
+
* and otherwise the key is based on the value.
|
|
84
|
+
*/
|
|
85
|
+
function getKey(value: unknown): SymbolRefkey["key"] {
|
|
86
|
+
if (isSymbolRefkey(value)) {
|
|
87
|
+
return value.key;
|
|
43
88
|
} else if (typeof value === "object" && value !== null) {
|
|
44
89
|
return getObjectKey(value);
|
|
45
90
|
} else {
|
|
46
|
-
return
|
|
91
|
+
return `s${String(value)}`;
|
|
47
92
|
}
|
|
48
93
|
}
|
|
49
94
|
|
|
@@ -65,16 +110,41 @@ const knownRefkeys = new Map<string, Refkey>();
|
|
|
65
110
|
export function refkey(...args: unknown[]): Refkey {
|
|
66
111
|
const keys = args.length === 0 ? [getKey({})] : args.map((v) => getKey(v));
|
|
67
112
|
|
|
68
|
-
const compositeKey = keys.
|
|
113
|
+
const compositeKey = keys.join("\u2063");
|
|
69
114
|
if (knownRefkeys.has(compositeKey)) {
|
|
70
115
|
return knownRefkeys.get(compositeKey)!;
|
|
71
116
|
}
|
|
72
117
|
|
|
73
|
-
const key =
|
|
118
|
+
const key = createSymbolRefkey(compositeKey);
|
|
74
119
|
knownRefkeys.set(compositeKey, key);
|
|
75
120
|
return key;
|
|
76
121
|
}
|
|
77
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Create a namekey with the given name. The namekey is a unique refkey that
|
|
125
|
+
* represents a single symbol with the given name and the provided
|
|
126
|
+
* naming-related options.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```tsx
|
|
130
|
+
* const myClass = namekey("MyClass");
|
|
131
|
+
*
|
|
132
|
+
* return <>
|
|
133
|
+
* <ClassDeclaration name={myClass} />
|
|
134
|
+
* {myClass}
|
|
135
|
+
* </>
|
|
136
|
+
* ```
|
|
137
|
+
*
|
|
138
|
+
* Renders a class and a reference to that class.
|
|
139
|
+
*/
|
|
140
|
+
export function namekey(name: string, options: NamekeyOptions = {}): Namekey {
|
|
141
|
+
return {
|
|
142
|
+
key: getObjectKey({}),
|
|
143
|
+
name,
|
|
144
|
+
options,
|
|
145
|
+
[RefkeySym]: true,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
78
148
|
/**
|
|
79
149
|
* Create a refkey for an instantiation of a symbol.
|
|
80
150
|
*
|
|
@@ -97,6 +167,10 @@ export function refkey(...args: unknown[]): Refkey {
|
|
|
97
167
|
* instantiated variable refkey and the refkey of the inner member
|
|
98
168
|
* `refkey(rk1, rk3)`.
|
|
99
169
|
*/
|
|
100
|
-
export function memberRefkey(base: Refkey, member: Refkey):
|
|
101
|
-
return
|
|
170
|
+
export function memberRefkey(base: Refkey, member: Refkey): MemberRefkey {
|
|
171
|
+
return {
|
|
172
|
+
base,
|
|
173
|
+
member,
|
|
174
|
+
[RefkeySym]: true,
|
|
175
|
+
};
|
|
102
176
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { OutputScope } from "./output-scope.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* BasicScope is a kind of OutputScope that has a single declaration space named
|
|
5
|
+
* `symbols`. It is suitable for use in simple language implementations where
|
|
6
|
+
* there isn't much in the way of unique scope semantics.
|
|
7
|
+
*/
|
|
8
|
+
export class BasicScope extends OutputScope {
|
|
9
|
+
public static readonly defaultDeclarationSpace = "symbols";
|
|
10
|
+
public static readonly declarationSpaces = ["symbols"] as const;
|
|
11
|
+
|
|
12
|
+
get symbols() {
|
|
13
|
+
return this.spaceFor("symbols")!;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
get symbolNames() {
|
|
17
|
+
return this.spaceFor("symbols")!.symbolNames;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get symbolsByRefkey() {
|
|
21
|
+
return this.spaceFor("symbols")!.symbolsByRefkey;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { OutputSymbol } from "./output-symbol.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* BasicSymbol is a kind of OutputSymbol that has instance and static members.
|
|
5
|
+
* It is suitable for use in simple language implementations where there isn't
|
|
6
|
+
* much in the way of unique symbol semantics.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
*
|
|
10
|
+
* Instantiation is done by copying symbols from instance members to static
|
|
11
|
+
* members of the instantiation target.
|
|
12
|
+
*
|
|
13
|
+
*/
|
|
14
|
+
export class BasicSymbol extends OutputSymbol {
|
|
15
|
+
public static readonly memberSpaces = ["static", "instance"];
|
|
16
|
+
|
|
17
|
+
copy() {
|
|
18
|
+
const options = this.getCopyOptions();
|
|
19
|
+
const copiedSymbol = new BasicSymbol(this.name, undefined, options);
|
|
20
|
+
this.initializeCopy(copiedSymbol);
|
|
21
|
+
|
|
22
|
+
return copiedSymbol;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
get instanceMembers() {
|
|
26
|
+
return this.memberSpaceFor("instance")!;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get staticMembers() {
|
|
30
|
+
return this.memberSpaceFor("static")!;
|
|
31
|
+
}
|
|
32
|
+
}
|
package/src/symbols/index.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export * from "./
|
|
1
|
+
export * from "./basic-scope.js";
|
|
2
|
+
export * from "./basic-symbol.js";
|
|
2
3
|
export * from "./output-scope.js";
|
|
4
|
+
export * from "./output-space.js";
|
|
3
5
|
export * from "./output-symbol.js";
|
|
4
6
|
export * from "./symbol-flow.js";
|
|
5
7
|
export * from "./symbol-slot.js";
|