@alloy-js/core 0.20.0-dev.3 → 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/src/utils.d.ts +1 -1
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +4 -4
- package/dist/src/write-output.d.ts +1 -1
- package/dist/src/write-output.d.ts.map +1 -1
- package/dist/src/write-output.js +31 -37
- 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/src/utils.tsx +4 -4
- package/src/write-output.ts +33 -45
- package/temp/api.json +5551 -3066
- 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,9 @@
|
|
|
1
1
|
import { isRef, Ref, shallowReactive } from "@vue/reactivity";
|
|
2
2
|
import { Context, effect, getContext, onCleanup } from "../reactivity.js";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { MemberContext } from "../context/member-scope.js";
|
|
5
5
|
import { ScopeContext } from "../context/scope.js";
|
|
6
|
-
import {
|
|
6
|
+
import { formatSymbolName, trace, TracePhase } from "../tracer.js";
|
|
7
7
|
import { OutputSymbol } from "./output-symbol.js";
|
|
8
8
|
|
|
9
9
|
export interface TakeSymbolCallback {
|
|
@@ -36,6 +36,15 @@ export function takeSymbols(cb?: (symbol: OutputSymbol) => void) {
|
|
|
36
36
|
export function emitSymbol(
|
|
37
37
|
symbol: OutputSymbol | Ref<OutputSymbol | undefined>,
|
|
38
38
|
) {
|
|
39
|
+
if (isRef(symbol)) {
|
|
40
|
+
trace(TracePhase.symbol.flow, () => `Emitting ref to symbol`);
|
|
41
|
+
} else {
|
|
42
|
+
trace(
|
|
43
|
+
TracePhase.symbol.flow,
|
|
44
|
+
() => `Emitting symbol ${formatSymbolName(symbol)}`,
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
39
48
|
let symbolTaker: Context | undefined;
|
|
40
49
|
let context = getContext()!.owner;
|
|
41
50
|
while (context) {
|
|
@@ -46,10 +55,13 @@ export function emitSymbol(
|
|
|
46
55
|
|
|
47
56
|
if (
|
|
48
57
|
context.context &&
|
|
49
|
-
(context.context[ScopeContext.id] ||
|
|
50
|
-
context.context[MemberScopeContext.id])
|
|
58
|
+
(context.context[ScopeContext.id] || context.context[MemberContext.id])
|
|
51
59
|
) {
|
|
52
60
|
// don't cross scope boundaries.
|
|
61
|
+
trace(
|
|
62
|
+
TracePhase.symbol.flow,
|
|
63
|
+
() => `Not emitting symbol across scope boundary`,
|
|
64
|
+
);
|
|
53
65
|
break;
|
|
54
66
|
}
|
|
55
67
|
|
|
@@ -57,6 +69,7 @@ export function emitSymbol(
|
|
|
57
69
|
}
|
|
58
70
|
|
|
59
71
|
if (!symbolTaker) {
|
|
72
|
+
trace(TracePhase.symbol.flow, () => `No symbol taker found, not emitting`);
|
|
60
73
|
return;
|
|
61
74
|
}
|
|
62
75
|
|
|
@@ -76,6 +89,11 @@ export function emitSymbol(
|
|
|
76
89
|
}
|
|
77
90
|
});
|
|
78
91
|
} else {
|
|
92
|
+
trace(
|
|
93
|
+
TracePhase.symbol.flow,
|
|
94
|
+
() =>
|
|
95
|
+
`Emitting symbol ${formatSymbolName(symbol)} taken by ${symbolTaker.componentOwner?.name ?? "unknown component"}`,
|
|
96
|
+
);
|
|
79
97
|
symbolTaker.takenSymbols!.add(symbol);
|
|
80
98
|
onCleanup(() => {
|
|
81
99
|
context!.takenSymbols!.delete(symbol);
|
|
@@ -85,16 +103,27 @@ export function emitSymbol(
|
|
|
85
103
|
|
|
86
104
|
export function moveTakenMembersTo(baseSymbol: OutputSymbol) {
|
|
87
105
|
const taken = takeSymbols();
|
|
88
|
-
|
|
89
106
|
effect(() => {
|
|
90
107
|
for (const symbol of taken) {
|
|
91
|
-
if (symbol.
|
|
92
|
-
symbol.
|
|
108
|
+
if (symbol.isTransient) {
|
|
109
|
+
symbol.moveMembersTo(baseSymbol);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
for (const refkey of symbol.refkeys) {
|
|
113
|
+
if (!baseSymbol.refkeys.includes(refkey)) {
|
|
114
|
+
baseSymbol.refkeys.push(refkey);
|
|
115
|
+
}
|
|
93
116
|
}
|
|
94
117
|
}
|
|
95
118
|
});
|
|
96
119
|
}
|
|
97
120
|
|
|
98
|
-
export function instantiateTakenMembersTo(
|
|
99
|
-
|
|
121
|
+
export function instantiateTakenMembersTo(
|
|
122
|
+
baseSymbol: OutputSymbol,
|
|
123
|
+
toSpaceKey: string,
|
|
124
|
+
fromSpaceKey: string,
|
|
125
|
+
) {
|
|
126
|
+
takeSymbols((symbol) => {
|
|
127
|
+
baseSymbol.type = symbol;
|
|
128
|
+
});
|
|
100
129
|
}
|
|
@@ -1,10 +1,37 @@
|
|
|
1
1
|
import { Ref, ShallowReactive, shallowRef } from "@vue/reactivity";
|
|
2
2
|
import { effect, onCleanup } from "../reactivity.js";
|
|
3
|
-
import type { Children } from "../runtime/component.js";
|
|
3
|
+
import type { Children, Component } from "../runtime/component.js";
|
|
4
4
|
import { OutputSymbol } from "./output-symbol.js";
|
|
5
5
|
import { takeSymbols } from "./symbol-flow.js";
|
|
6
6
|
|
|
7
|
-
export
|
|
7
|
+
export interface SymbolSlot extends Component<{}> {
|
|
8
|
+
/**
|
|
9
|
+
* A ref for the set of symbols taken by this slot. Undefined when the Slot component
|
|
10
|
+
* has not been rendered yet.
|
|
11
|
+
*/
|
|
12
|
+
ref: Ref<ShallowReactive<Set<OutputSymbol>> | undefined>;
|
|
13
|
+
/**
|
|
14
|
+
* A ref for the first symbol taken by this slot. Undefined when the Slot component
|
|
15
|
+
* has not been rendered yet or has not taken any symbols.
|
|
16
|
+
*/
|
|
17
|
+
firstSymbol: Ref<OutputSymbol | undefined>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Copy any members from taken symbols to the given symbol.
|
|
21
|
+
*/
|
|
22
|
+
copyMembersTo(baseSymbol: OutputSymbol): void;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Move any members from transient taken symbols to the given symbol.
|
|
26
|
+
*/
|
|
27
|
+
moveMembersTo(baseSymbol: OutputSymbol): void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create a component which accepts emitted symbols. The returned component has
|
|
31
|
+
* a `ref` property which is a ref to a reactive set of all symbols emitted by
|
|
32
|
+
* children of the component.
|
|
33
|
+
*/
|
|
34
|
+
export function createSymbolSlot(): SymbolSlot {
|
|
8
35
|
const symbolSlotRef: Ref<ShallowReactive<Set<OutputSymbol>> | undefined> =
|
|
9
36
|
shallowRef();
|
|
10
37
|
function SymbolSlot(props: { children: Children }) {
|
|
@@ -20,29 +47,40 @@ export function createSymbolSlot() {
|
|
|
20
47
|
|
|
21
48
|
SymbolSlot.ref = symbolSlotRef;
|
|
22
49
|
|
|
23
|
-
|
|
50
|
+
Object.defineProperty(SymbolSlot, "firstSymbol", {
|
|
51
|
+
get() {
|
|
52
|
+
const ref = shallowRef();
|
|
53
|
+
effect(() => {
|
|
54
|
+
ref.value = symbolSlotRef.value?.values().next().value;
|
|
55
|
+
});
|
|
56
|
+
return ref;
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
SymbolSlot.copyMembersTo = (baseSymbol: OutputSymbol) => {
|
|
24
61
|
effect(() => {
|
|
25
62
|
if (!symbolSlotRef.value) {
|
|
26
63
|
return;
|
|
27
64
|
}
|
|
28
65
|
|
|
29
66
|
for (const symbol of symbolSlotRef.value) {
|
|
30
|
-
symbol.
|
|
67
|
+
symbol.copyMembersTo(baseSymbol);
|
|
31
68
|
}
|
|
32
69
|
});
|
|
33
70
|
};
|
|
34
71
|
|
|
35
|
-
SymbolSlot.
|
|
72
|
+
SymbolSlot.moveMembersTo = (baseSymbol: OutputSymbol) => {
|
|
36
73
|
effect(() => {
|
|
37
74
|
if (!symbolSlotRef.value) {
|
|
38
75
|
return;
|
|
39
76
|
}
|
|
40
|
-
|
|
41
77
|
for (const symbol of symbolSlotRef.value) {
|
|
42
|
-
symbol.
|
|
78
|
+
if (symbol.isTransient) {
|
|
79
|
+
symbol.moveMembersTo(baseSymbol);
|
|
80
|
+
}
|
|
43
81
|
}
|
|
44
82
|
});
|
|
45
83
|
};
|
|
46
84
|
|
|
47
|
-
return SymbolSlot;
|
|
85
|
+
return SymbolSlot as any;
|
|
48
86
|
}
|
|
@@ -1,34 +1,64 @@
|
|
|
1
|
-
import type { NameConflictResolver } from "../binder.js";
|
|
1
|
+
import type { Binder, NameConflictResolver } from "../binder.js";
|
|
2
2
|
import { ReactiveUnionSet } from "../reactive-union-set.js";
|
|
3
|
+
import { Refkey } from "../refkey.js";
|
|
3
4
|
import { queueJob } from "../scheduler.js";
|
|
4
5
|
import {
|
|
5
|
-
formatScopeName,
|
|
6
6
|
formatSymbolName,
|
|
7
|
+
formatSymbolTableName,
|
|
7
8
|
trace,
|
|
8
9
|
TracePhase,
|
|
9
10
|
} from "../tracer.js";
|
|
10
|
-
import
|
|
11
|
+
import { OutputSpace } from "./output-space.js";
|
|
11
12
|
import type { OutputSymbol } from "./output-symbol.js";
|
|
12
13
|
|
|
13
|
-
export class SymbolTable extends ReactiveUnionSet<OutputSymbol> {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
for (const name of this
|
|
14
|
+
export abstract class SymbolTable extends ReactiveUnionSet<OutputSymbol> {
|
|
15
|
+
#namesToDeconflict: Set<string> = new Set();
|
|
16
|
+
#nameConflictResolver?: NameConflictResolver;
|
|
17
|
+
#deconflictNames = () => {
|
|
18
|
+
for (const name of this.#namesToDeconflict) {
|
|
18
19
|
const conflictedSymbols = [...this].filter(
|
|
19
|
-
(sym) => sym.originalName === name,
|
|
20
|
+
(sym) => sym.originalName === name && !sym.ignoreNameConflict,
|
|
20
21
|
);
|
|
21
|
-
if (this
|
|
22
|
-
this
|
|
22
|
+
if (this.#nameConflictResolver) {
|
|
23
|
+
this.#nameConflictResolver(name, conflictedSymbols);
|
|
23
24
|
} else {
|
|
24
25
|
defaultConflictHandler(name, conflictedSymbols);
|
|
25
26
|
}
|
|
26
|
-
this.
|
|
27
|
+
this.#namesToDeconflict.delete(name);
|
|
27
28
|
}
|
|
28
29
|
};
|
|
29
|
-
|
|
30
|
+
|
|
31
|
+
#binder: Binder | undefined;
|
|
32
|
+
|
|
33
|
+
get binder() {
|
|
34
|
+
return this.#binder;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
#key: string;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The key of this symbol table, e.g. "static" or "instance".
|
|
41
|
+
*/
|
|
42
|
+
get key() {
|
|
43
|
+
return this.#key;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
#symbolsByRefkey: ReadonlyMap<Refkey, OutputSymbol>;
|
|
47
|
+
/**
|
|
48
|
+
* The symbols defined within this scope, indexed by refkey.
|
|
49
|
+
*/
|
|
50
|
+
get symbolsByRefkey() {
|
|
51
|
+
return this.#symbolsByRefkey;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
#symbolNames: ReadonlyMap<string, OutputSymbol>;
|
|
55
|
+
get symbolNames() {
|
|
56
|
+
return this.#symbolNames;
|
|
57
|
+
}
|
|
58
|
+
|
|
30
59
|
constructor(
|
|
31
|
-
|
|
60
|
+
key: string,
|
|
61
|
+
binder?: Binder,
|
|
32
62
|
options: {
|
|
33
63
|
nameConflictResolver?: NameConflictResolver;
|
|
34
64
|
} = {},
|
|
@@ -37,26 +67,70 @@ export class SymbolTable extends ReactiveUnionSet<OutputSymbol> {
|
|
|
37
67
|
onAdd: (symbol) => {
|
|
38
68
|
trace(
|
|
39
69
|
TracePhase.symbol.addToScope,
|
|
40
|
-
() =>
|
|
70
|
+
() =>
|
|
71
|
+
`${formatSymbolName(symbol)} added to ${formatSymbolTableName(this)}`,
|
|
41
72
|
);
|
|
42
73
|
|
|
43
|
-
this.
|
|
74
|
+
this.#namesToDeconflict.add(symbol.name);
|
|
44
75
|
|
|
45
|
-
queueJob(this
|
|
76
|
+
queueJob(this.#deconflictNames);
|
|
46
77
|
|
|
47
78
|
return symbol;
|
|
48
79
|
},
|
|
49
|
-
onDelete(symbol) {
|
|
80
|
+
onDelete: (symbol) => {
|
|
50
81
|
trace(
|
|
51
82
|
TracePhase.symbol.removeFromScope,
|
|
52
|
-
() =>
|
|
83
|
+
() =>
|
|
84
|
+
`${formatSymbolName(symbol)} removed from ${formatSymbolTableName(this)}`,
|
|
53
85
|
);
|
|
54
86
|
},
|
|
55
87
|
});
|
|
56
88
|
|
|
57
|
-
this
|
|
89
|
+
this.#nameConflictResolver =
|
|
90
|
+
options.nameConflictResolver ?? binder?.nameConflictResolver;
|
|
91
|
+
this.#binder = binder;
|
|
92
|
+
this.#key = key;
|
|
93
|
+
this.#symbolsByRefkey = this.createIndex((s) => s.refkeys);
|
|
94
|
+
this.#symbolNames = this.createIndex((s) => {
|
|
95
|
+
return s.name;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
moveTo(target: SymbolTable): void {
|
|
100
|
+
trace(
|
|
101
|
+
TracePhase.scope.moveSymbols,
|
|
102
|
+
() =>
|
|
103
|
+
`${formatSymbolTableName(this)} -> ${formatSymbolTableName(target)}`,
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
target.addSubset(this, {
|
|
107
|
+
onAdd: (symbol) => {
|
|
108
|
+
symbol.spaces = [target as OutputSpace];
|
|
109
|
+
return symbol;
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
copyTo(
|
|
115
|
+
target: SymbolTable,
|
|
116
|
+
options: {
|
|
117
|
+
createRefkeys?(sourceSymbol: OutputSymbol): Refkey[];
|
|
118
|
+
} = {},
|
|
119
|
+
): void {
|
|
120
|
+
trace(
|
|
121
|
+
TracePhase.scope.copySymbols,
|
|
122
|
+
() =>
|
|
123
|
+
`${formatSymbolTableName(this)} copied to ${formatSymbolTableName(target)}`,
|
|
124
|
+
);
|
|
58
125
|
|
|
59
|
-
this
|
|
126
|
+
target.addSubset(this, {
|
|
127
|
+
onAdd: (symbol) => {
|
|
128
|
+
const copy = symbol.copy();
|
|
129
|
+
copy.spaces = [target as OutputSpace];
|
|
130
|
+
copy.refkeys = options.createRefkeys?.(symbol) ?? [];
|
|
131
|
+
return copy;
|
|
132
|
+
},
|
|
133
|
+
});
|
|
60
134
|
}
|
|
61
135
|
}
|
|
62
136
|
|
package/src/tracer.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { effect, ReactiveEffectRunner } from "@vue/reactivity";
|
|
2
2
|
import { untrack } from "./reactivity.js";
|
|
3
|
-
import type
|
|
3
|
+
import { isMemberRefkey, type Refkey } from "./refkey.js";
|
|
4
4
|
import { scheduler } from "./scheduler.js";
|
|
5
|
-
import { OutputScopeFlags, OutputSymbolFlags } from "./symbols/flags.js";
|
|
6
5
|
import { type OutputScope } from "./symbols/output-scope.js";
|
|
6
|
+
import type {
|
|
7
|
+
OutputDeclarationSpace,
|
|
8
|
+
OutputMemberSpace,
|
|
9
|
+
} from "./symbols/output-space.js";
|
|
7
10
|
import { type OutputSymbol } from "./symbols/output-symbol.js";
|
|
11
|
+
import { SymbolTable } from "./symbols/symbol-table.js";
|
|
8
12
|
|
|
9
13
|
// enable tracing for specific phases using a comma separated list of
|
|
10
14
|
// dotted identifiers, e.g. `scope.update,symbol.create`.
|
|
@@ -47,6 +51,11 @@ export const TracePhase = {
|
|
|
47
51
|
subarea: "copySymbols",
|
|
48
52
|
bg: { r: 0, g: 100, b: 100 },
|
|
49
53
|
},
|
|
54
|
+
moveSymbols: {
|
|
55
|
+
area: "scope",
|
|
56
|
+
subarea: "moveSymbols",
|
|
57
|
+
bg: { r: 0, g: 100, b: 100 },
|
|
58
|
+
},
|
|
50
59
|
},
|
|
51
60
|
symbol: {
|
|
52
61
|
update: {
|
|
@@ -274,24 +283,6 @@ function colorText(text: string, fmt?: TextFormat): string {
|
|
|
274
283
|
return `${prefix}${text}${reset}`;
|
|
275
284
|
}
|
|
276
285
|
|
|
277
|
-
/**
|
|
278
|
-
* Format flag values in a concise way, showing only the flags that are set
|
|
279
|
-
* @param flags The numeric flags value to format
|
|
280
|
-
* @param flagEnum The enum containing flag definitions
|
|
281
|
-
* @returns An array of flag names that are set
|
|
282
|
-
*/
|
|
283
|
-
function formatFlags<T extends Record<string, string | number>>(
|
|
284
|
-
flags: number,
|
|
285
|
-
flagEnum: T,
|
|
286
|
-
): string[] {
|
|
287
|
-
return Object.entries(flagEnum)
|
|
288
|
-
.filter(
|
|
289
|
-
([name, value]) =>
|
|
290
|
-
typeof value === "number" && value !== 0 && (flags & value) === value,
|
|
291
|
-
)
|
|
292
|
-
.map(([name]) => name);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
286
|
/**
|
|
296
287
|
* Format a symbol name with its ID in a blue-green color
|
|
297
288
|
* @param symbol The symbol to format
|
|
@@ -307,21 +298,6 @@ export function formatSymbolName(symbol: OutputSymbol): string {
|
|
|
307
298
|
});
|
|
308
299
|
}
|
|
309
300
|
|
|
310
|
-
/**
|
|
311
|
-
* Format the symbols in a member scope, showing their names and IDs
|
|
312
|
-
* @param scope The member scope containing the symbols to format
|
|
313
|
-
* @returns A formatted string representation of the member scope symbols
|
|
314
|
-
*/
|
|
315
|
-
function formatMemberScopeSymbols(scope: OutputScope): string {
|
|
316
|
-
if (!scope || scope.symbols.size === 0) {
|
|
317
|
-
return "none";
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
return Array.from(scope.symbols)
|
|
321
|
-
.map((symbol) => formatSymbolName(symbol))
|
|
322
|
-
.join(", ");
|
|
323
|
-
}
|
|
324
|
-
|
|
325
301
|
export function formatSymbol(symbol: OutputSymbol): string {
|
|
326
302
|
// Base display with name and ID
|
|
327
303
|
let result = formatSymbolName(symbol);
|
|
@@ -333,35 +309,19 @@ export function formatSymbol(symbol: OutputSymbol): string {
|
|
|
333
309
|
details.push(colorText(" !UNBOUND", { fg: { r: 255, g: 0, b: 0 } }));
|
|
334
310
|
}
|
|
335
311
|
|
|
336
|
-
// Show only enabled flags
|
|
337
|
-
const flagsInfo = formatFlags(symbol.flags, OutputSymbolFlags);
|
|
338
|
-
|
|
339
|
-
if (flagsInfo.length > 0) {
|
|
340
|
-
details.push(` flags: ${flagsInfo.join(", ")}`);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
312
|
// Show scope info with formatted name
|
|
344
313
|
if (symbol.scope) {
|
|
345
314
|
details.push(untrack(() => ` scope: ${formatScopeName(symbol.scope)}`));
|
|
346
315
|
}
|
|
347
316
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
untrack(() => {
|
|
351
|
-
const memberCount = symbol.instanceMemberScope!.symbols.size;
|
|
352
|
-
details.push(
|
|
353
|
-
` instance members: ${memberCount} - ${formatMemberScopeSymbols(symbol.instanceMemberScope!)}`,
|
|
354
|
-
);
|
|
355
|
-
});
|
|
317
|
+
for (const space of symbol.memberSpaces) {
|
|
318
|
+
details.push(untrack(() => formatSpaceSymbols(space)));
|
|
356
319
|
}
|
|
357
320
|
|
|
358
|
-
if (symbol.
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
` static members: ${memberCount} - ${formatMemberScopeSymbols(symbol.staticMemberScope!)}`,
|
|
363
|
-
);
|
|
364
|
-
});
|
|
321
|
+
if (symbol.ownerSymbol) {
|
|
322
|
+
details.push(
|
|
323
|
+
untrack(() => ` ownerSymbol: ${formatSymbolName(symbol.ownerSymbol!)}`),
|
|
324
|
+
);
|
|
365
325
|
}
|
|
366
326
|
|
|
367
327
|
// Show all refkeys with proper formatting
|
|
@@ -376,20 +336,37 @@ export function formatSymbol(symbol: OutputSymbol): string {
|
|
|
376
336
|
return result;
|
|
377
337
|
}
|
|
378
338
|
|
|
379
|
-
export function
|
|
380
|
-
|
|
339
|
+
export function formatSpaceSymbols(space: SymbolTable) {
|
|
340
|
+
return ` ${space.key} symbols (${space.size}): ${[...space].map((s) => s.name).join(", ")}`;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
export function formatScopeName(scope: OutputScope | undefined): string {
|
|
344
|
+
if (!scope) {
|
|
345
|
+
return "no scope";
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return colorText(`${scope.name}[${scope.id}]`, {
|
|
381
349
|
fg: {
|
|
382
350
|
r: 0,
|
|
383
351
|
g: 150,
|
|
384
352
|
b: 50,
|
|
385
353
|
},
|
|
386
354
|
});
|
|
355
|
+
}
|
|
387
356
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
357
|
+
export function formatSymbolTableName(table: SymbolTable): string {
|
|
358
|
+
// avoid instance of checks here in order to not create circular module imports.
|
|
359
|
+
const name =
|
|
360
|
+
"symbol" in table ?
|
|
361
|
+
formatSymbolName((table as OutputMemberSpace).symbol)
|
|
362
|
+
: formatScopeName((table as OutputDeclarationSpace).scope);
|
|
363
|
+
return colorText(`${name}:${table.key}`, {
|
|
364
|
+
fg: {
|
|
365
|
+
r: 0,
|
|
366
|
+
g: 125,
|
|
367
|
+
b: 25,
|
|
368
|
+
},
|
|
369
|
+
});
|
|
393
370
|
}
|
|
394
371
|
|
|
395
372
|
/**
|
|
@@ -397,7 +374,7 @@ export function formatScopeName(scope: OutputScope): string {
|
|
|
397
374
|
* @param scope The scope to format
|
|
398
375
|
* @returns A formatted string representation of the scope
|
|
399
376
|
*/
|
|
400
|
-
export function formatScope(scope:
|
|
377
|
+
export function formatScope(scope: OutputScope): string {
|
|
401
378
|
if (!scope) {
|
|
402
379
|
return "!Undefined scope!";
|
|
403
380
|
}
|
|
@@ -416,34 +393,22 @@ export function formatScope(scope: OutputSymbol["scope"]): string {
|
|
|
416
393
|
if (!scope.binder) {
|
|
417
394
|
details.push(colorText(" !UNBOUND", { fg: { r: 255, g: 0, b: 0 } }));
|
|
418
395
|
}
|
|
419
|
-
// Show only enabled flags
|
|
420
|
-
const flagsInfo = formatFlags(scope.flags, OutputScopeFlags);
|
|
421
|
-
|
|
422
|
-
if (flagsInfo.length > 0) {
|
|
423
|
-
details.push(` flags: ${flagsInfo.join(", ")}`);
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
// Show symbol count
|
|
427
|
-
const symbolCount = scope.symbols.size;
|
|
428
|
-
if (symbolCount > 0) {
|
|
429
|
-
details.push(` symbols: ${symbolCount}`);
|
|
430
|
-
}
|
|
431
396
|
|
|
432
397
|
// Show parent scope if present
|
|
433
398
|
if (scope.parent) {
|
|
434
399
|
details.push(` parent: ${formatScopeName(scope.parent)}`);
|
|
435
400
|
}
|
|
436
401
|
|
|
437
|
-
// Show owner if present (for member scopes)
|
|
438
|
-
if (scope.owner) {
|
|
439
|
-
details.push(` owner: ${formatSymbolName(scope.owner)}`);
|
|
440
|
-
}
|
|
441
|
-
|
|
442
402
|
// Show child scopes if present
|
|
443
403
|
if (scope.children && scope.children.size > 0) {
|
|
444
404
|
details.push(` children: ${scope.children.size}`);
|
|
445
405
|
}
|
|
446
406
|
|
|
407
|
+
// Show declaration spaces
|
|
408
|
+
for (const space of scope.spaces) {
|
|
409
|
+
details.push(` ${untrack(() => formatSpaceSymbols(space))}`);
|
|
410
|
+
}
|
|
411
|
+
|
|
447
412
|
if (details.length > 0) {
|
|
448
413
|
result += "\n" + details.join("\n");
|
|
449
414
|
}
|
|
@@ -464,7 +429,12 @@ export function formatRefkeys(refkeys: Refkey[] | Refkey | undefined) {
|
|
|
464
429
|
}
|
|
465
430
|
|
|
466
431
|
function formatRefkey(refkey: Refkey): string {
|
|
467
|
-
|
|
432
|
+
const text =
|
|
433
|
+
isMemberRefkey(refkey) ?
|
|
434
|
+
`memberRefkey[${formatRefkey(refkey.base)} -> ${formatRefkey(refkey.member)}]`
|
|
435
|
+
: `refkey[${refkey.key}]`;
|
|
436
|
+
|
|
437
|
+
return colorText(text, {
|
|
468
438
|
fg: {
|
|
469
439
|
r: 150,
|
|
470
440
|
g: 0,
|
package/src/utils.tsx
CHANGED
|
@@ -311,16 +311,16 @@ export interface OutputVisitor {
|
|
|
311
311
|
* @param sourceDirectory - The root directory to traverse.
|
|
312
312
|
* @param visitor - The visitor to call for each file and directory.
|
|
313
313
|
*/
|
|
314
|
-
export function traverseOutput(
|
|
314
|
+
export async function traverseOutput(
|
|
315
315
|
sourceDirectory: OutputDirectory,
|
|
316
316
|
visitor: OutputVisitor,
|
|
317
317
|
) {
|
|
318
|
-
visitor.visitDirectory(sourceDirectory);
|
|
318
|
+
await visitor.visitDirectory(sourceDirectory);
|
|
319
319
|
for (const item of sourceDirectory.contents) {
|
|
320
320
|
if (item.kind === "directory") {
|
|
321
|
-
traverseOutput(item, visitor);
|
|
321
|
+
await traverseOutput(item, visitor);
|
|
322
322
|
} else {
|
|
323
|
-
visitor.visitFile(item);
|
|
323
|
+
await visitor.visitFile(item);
|
|
324
324
|
}
|
|
325
325
|
}
|
|
326
326
|
}
|
package/src/write-output.ts
CHANGED
|
@@ -10,54 +10,42 @@ export async function writeOutput(
|
|
|
10
10
|
output: OutputDirectory,
|
|
11
11
|
basePath: string = "",
|
|
12
12
|
) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
13
|
+
return await traverseOutput(output, {
|
|
14
|
+
async visitDirectory(directory) {
|
|
15
|
+
const path = resolve(basePath, directory.path);
|
|
16
|
+
if (await AlloyHost.exists(path)) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
// eslint-disable-next-line no-console
|
|
20
|
+
console.log("create", relative(process.cwd(), path));
|
|
21
|
+
await AlloyHost.mkdir(path);
|
|
22
|
+
},
|
|
23
|
+
async visitFile(file) {
|
|
24
|
+
if ("contents" in file) {
|
|
25
|
+
const path = resolve(basePath, file.path);
|
|
26
|
+
if (await AlloyHost.exists(path)) {
|
|
27
|
+
// eslint-disable-next-line no-console
|
|
28
|
+
console.log("overwrite", relative(process.cwd(), path));
|
|
29
|
+
} else {
|
|
23
30
|
// eslint-disable-next-line no-console
|
|
24
31
|
console.log("create", relative(process.cwd(), path));
|
|
25
|
-
|
|
26
|
-
})(),
|
|
27
|
-
);
|
|
28
|
-
},
|
|
29
|
-
visitFile(file) {
|
|
30
|
-
ops.push(
|
|
31
|
-
(async () => {
|
|
32
|
-
if ("contents" in file) {
|
|
33
|
-
const path = resolve(basePath, file.path);
|
|
34
|
-
if (await AlloyHost.exists(path)) {
|
|
35
|
-
// eslint-disable-next-line no-console
|
|
36
|
-
console.log("overwrite", relative(process.cwd(), path));
|
|
37
|
-
} else {
|
|
38
|
-
// eslint-disable-next-line no-console
|
|
39
|
-
console.log("create", relative(process.cwd(), path));
|
|
40
|
-
}
|
|
32
|
+
}
|
|
41
33
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
})(),
|
|
58
|
-
);
|
|
34
|
+
await AlloyHost.write(path, file.contents);
|
|
35
|
+
} else {
|
|
36
|
+
// copy file
|
|
37
|
+
const source = resolve(basePath, file.sourcePath);
|
|
38
|
+
const target = resolve(basePath, file.path);
|
|
39
|
+
if (await AlloyHost.exists(target)) {
|
|
40
|
+
// eslint-disable-next-line no-console
|
|
41
|
+
console.log("copy over", relative(process.cwd(), target));
|
|
42
|
+
} else {
|
|
43
|
+
// eslint-disable-next-line no-console
|
|
44
|
+
console.log("copy", relative(process.cwd(), target));
|
|
45
|
+
}
|
|
46
|
+
await AlloyHost.mkdir(dirname(target));
|
|
47
|
+
await AlloyHost.write(target, AlloyHost.read(source).stream());
|
|
48
|
+
}
|
|
59
49
|
},
|
|
60
50
|
});
|
|
61
|
-
|
|
62
|
-
return Promise.all(ops);
|
|
63
51
|
}
|