Skip to content

Commit 8c27a38

Browse files
committed
Prefer defining variables before they are referenced
This reduces the number of finalizers needed.
1 parent 16768f5 commit 8c27a38

File tree

2 files changed

+91
-1
lines changed

2 files changed

+91
-1
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Used as input
2+
// { preserveReferences: true }
3+
export default (() => {
4+
const $0 = {
5+
name: 'variable 0'
6+
},
7+
$2 = {
8+
name: 'variable 2'
9+
},
10+
$1 = {
11+
name: 'variable 1',
12+
$0: $0,
13+
$2: $2
14+
}
15+
return {
16+
name: 'variable 2',
17+
$0: $0,
18+
$1: $1,
19+
var1: $1,
20+
variable1: $1,
21+
$2: $2
22+
}
23+
})()
24+
25+
// -------------------------------------------------------------------------------------------------
26+
27+
// Default output
28+
// { preserveReferences: false }
29+
const withoutPreserveReferences = {
30+
name: 'variable 2',
31+
$0: {
32+
name: 'variable 0'
33+
},
34+
$1: {
35+
name: 'variable 1',
36+
$0: {
37+
name: 'variable 0'
38+
},
39+
$2: {
40+
name: 'variable 2'
41+
}
42+
},
43+
var1: {
44+
name: 'variable 1',
45+
$0: {
46+
name: 'variable 0'
47+
},
48+
$2: {
49+
name: 'variable 2'
50+
}
51+
},
52+
variable1: {
53+
name: 'variable 1',
54+
$0: {
55+
name: 'variable 0'
56+
},
57+
$2: {
58+
name: 'variable 2'
59+
}
60+
},
61+
$2: {
62+
name: 'variable 2'
63+
}
64+
}

src/estree-util-value-to-estree.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@ interface Context {
191191
*/
192192
recursive: boolean
193193

194+
/**
195+
* A set of values that reference the value in this context.
196+
*/
197+
referencedBy: Set<unknown>
198+
194199
/**
195200
* The value this context belongs to.
196201
*/
@@ -208,6 +213,19 @@ interface Context {
208213
* The count of context a minus the count of context b.
209214
*/
210215
function compareContexts(a: Context, b: Context): number {
216+
const aReferencedByB = a.referencedBy.has(b.value)
217+
const bReferencedByA = b.referencedBy.has(a.value)
218+
219+
if (aReferencedByB) {
220+
if (bReferencedByA) {
221+
return a.count - b.count
222+
}
223+
return -1
224+
}
225+
if (bReferencedByA) {
226+
return 1
227+
}
228+
211229
return a.count - b.count
212230
}
213231

@@ -269,6 +287,9 @@ export function valueToEstree(value: unknown, options: Options = {}): Expression
269287
if (options.preserveReferences) {
270288
context.count += 1
271289
}
290+
for (const ancestor of stack) {
291+
context.referencedBy.add(ancestor)
292+
}
272293
if (stack.includes(val)) {
273294
if (!options.preserveReferences) {
274295
throw new Error(`Found circular reference: ${val}`, { cause: val })
@@ -281,7 +302,12 @@ export function valueToEstree(value: unknown, options: Options = {}): Expression
281302
return
282303
}
283304

284-
collectedContexts.set(val, { count: 1, recursive: false, value: val })
305+
collectedContexts.set(val, {
306+
count: 1,
307+
recursive: false,
308+
referencedBy: new Set(stack),
309+
value: val
310+
})
285311

286312
if (isTypedArray(val)) {
287313
return

0 commit comments

Comments
 (0)