babel-plugin-react-compiler 0.0.0-experimental-3feb7e4-20240930 → 0.0.0-experimental-27e0f40-20241002
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/index.js +638 -278
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
@@ -119602,6 +119602,17 @@ function getOrInsertDefault(m, key, defaultValue) {
|
|
119602
119602
|
return defaultValue;
|
119603
119603
|
}
|
119604
119604
|
}
|
119605
|
+
function Set_equal(a, b) {
|
119606
|
+
if (a.size !== b.size) {
|
119607
|
+
return false;
|
119608
|
+
}
|
119609
|
+
for (const item of a) {
|
119610
|
+
if (!b.has(item)) {
|
119611
|
+
return false;
|
119612
|
+
}
|
119613
|
+
}
|
119614
|
+
return true;
|
119615
|
+
}
|
119605
119616
|
function Set_union(a, b) {
|
119606
119617
|
const union = new Set(a);
|
119607
119618
|
for (const item of b) {
|
@@ -119635,6 +119646,15 @@ function Iterable_some(iter, pred) {
|
|
119635
119646
|
}
|
119636
119647
|
return false;
|
119637
119648
|
}
|
119649
|
+
function Set_filter(source, fn) {
|
119650
|
+
const result = new Set();
|
119651
|
+
for (const entry of source) {
|
119652
|
+
if (fn(entry)) {
|
119653
|
+
result.add(entry);
|
119654
|
+
}
|
119655
|
+
}
|
119656
|
+
return result;
|
119657
|
+
}
|
119638
119658
|
function hasNode(input) {
|
119639
119659
|
return input.node != null;
|
119640
119660
|
}
|
@@ -144911,7 +144931,7 @@ class ReactiveScopeDependencyTree {
|
|
144911
144931
|
_ReactiveScopeDependencyTree_getOrCreateRoot
|
144912
144932
|
).call(this, dep.identifier);
|
144913
144933
|
for (const item of path) {
|
144914
|
-
let currChild = getOrMakeProperty
|
144934
|
+
let currChild = getOrMakeProperty(currNode, item.property);
|
144915
144935
|
const accessType = inConditional
|
144916
144936
|
? PropertyAccessType$1.ConditionalAccess
|
144917
144937
|
: item.optional
|
@@ -144922,7 +144942,7 @@ class ReactiveScopeDependencyTree {
|
|
144922
144942
|
}
|
144923
144943
|
const depType = inConditional
|
144924
144944
|
? PropertyAccessType$1.ConditionalDependency
|
144925
|
-
: isOptional(currNode.accessType)
|
144945
|
+
: isOptional$1(currNode.accessType)
|
144926
144946
|
? PropertyAccessType$1.OptionalDependency
|
144927
144947
|
: PropertyAccessType$1.UnconditionalDependency;
|
144928
144948
|
currNode.accessType = merge$1(currNode.accessType, depType);
|
@@ -144934,7 +144954,7 @@ class ReactiveScopeDependencyTree {
|
|
144934
144954
|
_ReactiveScopeDependencyTree_roots,
|
144935
144955
|
'f'
|
144936
144956
|
).entries()) {
|
144937
|
-
const deps = deriveMinimalDependenciesInSubtree
|
144957
|
+
const deps = deriveMinimalDependenciesInSubtree(rootNode, null);
|
144938
144958
|
CompilerError.invariant(
|
144939
144959
|
deps.every(
|
144940
144960
|
dep =>
|
@@ -145092,7 +145112,7 @@ var PropertyAccessType$1;
|
|
145092
145112
|
PropertyAccessType['OptionalDependency'] = 'OptionalDependency';
|
145093
145113
|
PropertyAccessType['UnconditionalDependency'] = 'UnconditionalDependency';
|
145094
145114
|
})(PropertyAccessType$1 || (PropertyAccessType$1 = {}));
|
145095
|
-
const MIN_ACCESS_TYPE
|
145115
|
+
const MIN_ACCESS_TYPE = PropertyAccessType$1.ConditionalAccess;
|
145096
145116
|
function isUnconditional(access) {
|
145097
145117
|
return (
|
145098
145118
|
access === PropertyAccessType$1.UnconditionalAccess ||
|
@@ -145106,7 +145126,7 @@ function isDependency$1(access) {
|
|
145106
145126
|
access === PropertyAccessType$1.UnconditionalDependency
|
145107
145127
|
);
|
145108
145128
|
}
|
145109
|
-
function isOptional(access) {
|
145129
|
+
function isOptional$1(access) {
|
145110
145130
|
return (
|
145111
145131
|
access === PropertyAccessType$1.OptionalAccess ||
|
145112
145132
|
access === PropertyAccessType$1.OptionalDependency
|
@@ -145116,7 +145136,7 @@ function merge$1(access1, access2) {
|
|
145116
145136
|
const resultIsUnconditional =
|
145117
145137
|
isUnconditional(access1) || isUnconditional(access2);
|
145118
145138
|
const resultIsDependency = isDependency$1(access1) || isDependency$1(access2);
|
145119
|
-
const resultIsOptional = isOptional(access1) || isOptional(access2);
|
145139
|
+
const resultIsOptional = isOptional$1(access1) || isOptional$1(access2);
|
145120
145140
|
if (resultIsUnconditional) {
|
145121
145141
|
if (resultIsDependency) {
|
145122
145142
|
return PropertyAccessType$1.UnconditionalDependency;
|
@@ -145153,10 +145173,10 @@ function prependPath(results, path) {
|
|
145153
145173
|
relativePath: [path, ...result.relativePath],
|
145154
145174
|
}));
|
145155
145175
|
}
|
145156
|
-
function deriveMinimalDependenciesInSubtree
|
145176
|
+
function deriveMinimalDependenciesInSubtree(dep, property) {
|
145157
145177
|
const results = [];
|
145158
145178
|
for (const [childName, childNode] of dep.properties) {
|
145159
|
-
const childResult = deriveMinimalDependenciesInSubtree
|
145179
|
+
const childResult = deriveMinimalDependenciesInSubtree(
|
145160
145180
|
childNode,
|
145161
145181
|
childName
|
145162
145182
|
);
|
@@ -145319,10 +145339,10 @@ function printSubtree$1(node, includeAccesses) {
|
|
145319
145339
|
}
|
145320
145340
|
return results;
|
145321
145341
|
}
|
145322
|
-
function getOrMakeProperty
|
145342
|
+
function getOrMakeProperty(node, property) {
|
145323
145343
|
let child = node.properties.get(property);
|
145324
145344
|
if (child == null) {
|
145325
|
-
child = {properties: new Map(), accessType: MIN_ACCESS_TYPE
|
145345
|
+
child = {properties: new Map(), accessType: MIN_ACCESS_TYPE};
|
145326
145346
|
node.properties.set(property, child);
|
145327
145347
|
}
|
145328
145348
|
return child;
|
@@ -154219,10 +154239,19 @@ function validateNoJSXInTryStatement(fn) {
|
|
154219
154239
|
throw errors;
|
154220
154240
|
}
|
154221
154241
|
}
|
154222
|
-
|
154223
|
-
|
154224
|
-
|
154225
|
-
|
154242
|
+
function collectHoistablePropertyLoads(
|
154243
|
+
fn,
|
154244
|
+
temporaries,
|
154245
|
+
hoistableFromOptionals
|
154246
|
+
) {
|
154247
|
+
const registry = new PropertyPathRegistry();
|
154248
|
+
const nodes = collectNonNullsInBlocks(
|
154249
|
+
fn,
|
154250
|
+
temporaries,
|
154251
|
+
hoistableFromOptionals,
|
154252
|
+
registry
|
154253
|
+
);
|
154254
|
+
propagateNonNull(fn, nodes, registry);
|
154226
154255
|
const nodesKeyedByScopeId = new Map();
|
154227
154256
|
for (const [_, block] of fn.body.blocks) {
|
154228
154257
|
if (block.terminal.kind === 'scope') {
|
@@ -154234,122 +154263,148 @@ function collectHoistablePropertyLoads(fn, temporaries) {
|
|
154234
154263
|
}
|
154235
154264
|
return nodesKeyedByScopeId;
|
154236
154265
|
}
|
154237
|
-
|
154238
|
-
const resolvedDependency = temporaries.get(object.identifier.id);
|
154239
|
-
let property;
|
154240
|
-
if (resolvedDependency == null) {
|
154241
|
-
property = {
|
154242
|
-
identifier: object.identifier,
|
154243
|
-
path: [{property: propertyName, optional: false}],
|
154244
|
-
};
|
154245
|
-
} else {
|
154246
|
-
property = {
|
154247
|
-
identifier: resolvedDependency.identifier,
|
154248
|
-
path: [
|
154249
|
-
...resolvedDependency.path,
|
154250
|
-
{property: propertyName, optional: false},
|
154251
|
-
],
|
154252
|
-
};
|
154253
|
-
}
|
154254
|
-
return property;
|
154255
|
-
}
|
154256
|
-
class Tree {
|
154266
|
+
class PropertyPathRegistry {
|
154257
154267
|
constructor() {
|
154258
|
-
_Tree_instances.add(this);
|
154259
154268
|
this.roots = new Map();
|
154260
154269
|
}
|
154261
|
-
|
154262
|
-
|
154263
|
-
reason:
|
154264
|
-
'[CollectHoistablePropertyLoads] Expected property node, found root node',
|
154265
|
-
loc: GeneratedSource,
|
154266
|
-
});
|
154267
|
-
let currNode = __classPrivateFieldGet(
|
154268
|
-
this,
|
154269
|
-
_Tree_instances,
|
154270
|
-
'm',
|
154271
|
-
_Tree_getOrCreateRoot
|
154272
|
-
).call(this, n.identifier);
|
154273
|
-
for (let i = 0; i < n.path.length - 1; i++) {
|
154274
|
-
currNode = assertNonNull(currNode.properties.get(n.path[i].property));
|
154275
|
-
}
|
154276
|
-
return __classPrivateFieldGet(_a, _a, 'm', _Tree_getOrCreateProperty).call(
|
154277
|
-
_a,
|
154278
|
-
currNode,
|
154279
|
-
n.path.at(-1).property
|
154280
|
-
);
|
154281
|
-
}
|
154282
|
-
}
|
154283
|
-
(_a = Tree),
|
154284
|
-
(_Tree_instances = new WeakSet()),
|
154285
|
-
(_Tree_getOrCreateRoot = function _Tree_getOrCreateRoot(identifier) {
|
154286
|
-
let rootNode = this.roots.get(identifier);
|
154270
|
+
getOrCreateIdentifier(identifier) {
|
154271
|
+
let rootNode = this.roots.get(identifier.id);
|
154287
154272
|
if (rootNode === undefined) {
|
154288
154273
|
rootNode = {
|
154289
|
-
root: identifier,
|
154274
|
+
root: identifier.id,
|
154290
154275
|
properties: new Map(),
|
154276
|
+
optionalProperties: new Map(),
|
154291
154277
|
fullPath: {identifier: identifier, path: []},
|
154278
|
+
hasOptional: false,
|
154292
154279
|
parent: null,
|
154293
154280
|
};
|
154294
|
-
this.roots.set(identifier, rootNode);
|
154281
|
+
this.roots.set(identifier.id, rootNode);
|
154295
154282
|
}
|
154296
154283
|
return rootNode;
|
154297
|
-
}
|
154298
|
-
(
|
154299
|
-
|
154300
|
-
property
|
154301
|
-
) {
|
154302
|
-
let child = node.properties.get(property);
|
154284
|
+
}
|
154285
|
+
static getOrCreatePropertyEntry(parent, entry) {
|
154286
|
+
const map = entry.optional ? parent.optionalProperties : parent.properties;
|
154287
|
+
let child = map.get(entry.property);
|
154303
154288
|
if (child == null) {
|
154304
154289
|
child = {
|
154305
154290
|
properties: new Map(),
|
154306
|
-
|
154291
|
+
optionalProperties: new Map(),
|
154292
|
+
parent: parent,
|
154307
154293
|
fullPath: {
|
154308
|
-
identifier:
|
154309
|
-
path:
|
154310
|
-
{property: property, optional: false},
|
154311
|
-
]),
|
154294
|
+
identifier: parent.fullPath.identifier,
|
154295
|
+
path: parent.fullPath.path.concat(entry),
|
154312
154296
|
},
|
154297
|
+
hasOptional: parent.hasOptional || entry.optional,
|
154313
154298
|
};
|
154314
|
-
|
154299
|
+
map.set(entry.property, child);
|
154315
154300
|
}
|
154316
154301
|
return child;
|
154317
|
-
}
|
154318
|
-
|
154302
|
+
}
|
154303
|
+
getOrCreateProperty(n) {
|
154304
|
+
let currNode = this.getOrCreateIdentifier(n.identifier);
|
154305
|
+
if (n.path.length === 0) {
|
154306
|
+
return currNode;
|
154307
|
+
}
|
154308
|
+
for (let i = 0; i < n.path.length - 1; i++) {
|
154309
|
+
currNode = PropertyPathRegistry.getOrCreatePropertyEntry(
|
154310
|
+
currNode,
|
154311
|
+
n.path[i]
|
154312
|
+
);
|
154313
|
+
}
|
154314
|
+
return PropertyPathRegistry.getOrCreatePropertyEntry(
|
154315
|
+
currNode,
|
154316
|
+
n.path.at(-1)
|
154317
|
+
);
|
154318
|
+
}
|
154319
|
+
}
|
154320
|
+
function addNonNullPropertyPath(
|
154321
|
+
source,
|
154322
|
+
sourceNode,
|
154323
|
+
instrId,
|
154324
|
+
knownImmutableIdentifiers,
|
154325
|
+
result
|
154326
|
+
) {
|
154327
|
+
const isMutableAtInstr =
|
154328
|
+
source.mutableRange.end > source.mutableRange.start + 1 &&
|
154329
|
+
source.scope != null &&
|
154330
|
+
inRange({id: instrId}, source.scope.range);
|
154331
|
+
if (
|
154332
|
+
!isMutableAtInstr ||
|
154333
|
+
knownImmutableIdentifiers.has(sourceNode.fullPath.identifier.id)
|
154334
|
+
) {
|
154335
|
+
result.add(sourceNode);
|
154336
|
+
}
|
154337
|
+
}
|
154338
|
+
function collectNonNullsInBlocks(
|
154339
|
+
fn,
|
154340
|
+
temporaries,
|
154341
|
+
hoistableFromOptionals,
|
154342
|
+
registry
|
154343
|
+
) {
|
154344
|
+
var _a;
|
154319
154345
|
const knownImmutableIdentifiers = new Set();
|
154320
154346
|
if (fn.fnType === 'Component' || fn.fnType === 'Hook') {
|
154321
154347
|
for (const p of fn.params) {
|
154322
154348
|
if (p.kind === 'Identifier') {
|
154323
|
-
knownImmutableIdentifiers.add(p.identifier);
|
154349
|
+
knownImmutableIdentifiers.add(p.identifier.id);
|
154324
154350
|
}
|
154325
154351
|
}
|
154326
154352
|
}
|
154327
|
-
const
|
154353
|
+
const knownNonNullIdentifiers = new Set();
|
154354
|
+
if (
|
154355
|
+
fn.fnType === 'Component' &&
|
154356
|
+
fn.params.length > 0 &&
|
154357
|
+
fn.params[0].kind === 'Identifier'
|
154358
|
+
) {
|
154359
|
+
const identifier = fn.params[0].identifier;
|
154360
|
+
knownNonNullIdentifiers.add(registry.getOrCreateIdentifier(identifier));
|
154361
|
+
}
|
154328
154362
|
const nodes = new Map();
|
154329
154363
|
for (const [_, block] of fn.body.blocks) {
|
154330
|
-
const assumedNonNullObjects = new Set();
|
154364
|
+
const assumedNonNullObjects = new Set(knownNonNullIdentifiers);
|
154365
|
+
const maybeOptionalChain = hoistableFromOptionals.get(block.id);
|
154366
|
+
if (maybeOptionalChain != null) {
|
154367
|
+
assumedNonNullObjects.add(
|
154368
|
+
registry.getOrCreateProperty(maybeOptionalChain)
|
154369
|
+
);
|
154370
|
+
}
|
154331
154371
|
for (const instr of block.instructions) {
|
154332
154372
|
if (instr.value.kind === 'PropertyLoad') {
|
154333
|
-
const
|
154334
|
-
instr.value.object
|
154335
|
-
|
154336
|
-
|
154373
|
+
const source =
|
154374
|
+
(_a = temporaries.get(instr.value.object.identifier.id)) !== null &&
|
154375
|
+
_a !== void 0
|
154376
|
+
? _a
|
154377
|
+
: {identifier: instr.value.object.identifier, path: []};
|
154378
|
+
addNonNullPropertyPath(
|
154379
|
+
instr.value.object.identifier,
|
154380
|
+
registry.getOrCreateProperty(source),
|
154381
|
+
instr.id,
|
154382
|
+
knownImmutableIdentifiers,
|
154383
|
+
assumedNonNullObjects
|
154337
154384
|
);
|
154338
|
-
|
154339
|
-
const
|
154340
|
-
const
|
154341
|
-
|
154342
|
-
|
154343
|
-
|
154344
|
-
|
154345
|
-
|
154346
|
-
|
154347
|
-
|
154348
|
-
|
154349
|
-
|
154350
|
-
|
154351
|
-
|
154352
|
-
|
154385
|
+
} else if (instr.value.kind === 'Destructure') {
|
154386
|
+
const source = instr.value.value.identifier.id;
|
154387
|
+
const sourceNode = temporaries.get(source);
|
154388
|
+
if (sourceNode != null) {
|
154389
|
+
addNonNullPropertyPath(
|
154390
|
+
instr.value.value.identifier,
|
154391
|
+
registry.getOrCreateProperty(sourceNode),
|
154392
|
+
instr.id,
|
154393
|
+
knownImmutableIdentifiers,
|
154394
|
+
assumedNonNullObjects
|
154395
|
+
);
|
154396
|
+
}
|
154397
|
+
} else if (instr.value.kind === 'ComputedLoad') {
|
154398
|
+
const source = instr.value.object.identifier.id;
|
154399
|
+
const sourceNode = temporaries.get(source);
|
154400
|
+
if (sourceNode != null) {
|
154401
|
+
addNonNullPropertyPath(
|
154402
|
+
instr.value.object.identifier,
|
154403
|
+
registry.getOrCreateProperty(sourceNode),
|
154404
|
+
instr.id,
|
154405
|
+
knownImmutableIdentifiers,
|
154406
|
+
assumedNonNullObjects
|
154407
|
+
);
|
154353
154408
|
}
|
154354
154409
|
}
|
154355
154410
|
}
|
@@ -154360,7 +154415,7 @@ function collectPropertyLoadsInBlocks(fn, temporaries) {
|
|
154360
154415
|
}
|
154361
154416
|
return nodes;
|
154362
154417
|
}
|
154363
|
-
function propagateNonNull(fn, nodes) {
|
154418
|
+
function propagateNonNull(fn, nodes, registry) {
|
154364
154419
|
const blockSuccessors = new Map();
|
154365
154420
|
const terminalPreds = new Set();
|
154366
154421
|
for (const [blockId, block] of fn.body.blocks) {
|
@@ -154371,13 +154426,8 @@ function propagateNonNull(fn, nodes) {
|
|
154371
154426
|
terminalPreds.add(blockId);
|
154372
154427
|
}
|
154373
154428
|
}
|
154374
|
-
function recursivelyPropagateNonNull(
|
154375
|
-
|
154376
|
-
direction,
|
154377
|
-
traversalState,
|
154378
|
-
nonNullObjectsByBlock
|
154379
|
-
) {
|
154380
|
-
var _b;
|
154429
|
+
function recursivelyPropagateNonNull(nodeId, direction, traversalState) {
|
154430
|
+
var _a;
|
154381
154431
|
if (traversalState.has(nodeId)) {
|
154382
154432
|
return false;
|
154383
154433
|
}
|
@@ -154391,8 +154441,8 @@ function propagateNonNull(fn, nodes) {
|
|
154391
154441
|
}
|
154392
154442
|
const neighbors = Array.from(
|
154393
154443
|
direction === 'backward'
|
154394
|
-
? (
|
154395
|
-
?
|
154444
|
+
? (_a = blockSuccessors.get(nodeId)) !== null && _a !== void 0
|
154445
|
+
? _a
|
154396
154446
|
: []
|
154397
154447
|
: node.block.preds
|
154398
154448
|
);
|
@@ -154402,8 +154452,7 @@ function propagateNonNull(fn, nodes) {
|
|
154402
154452
|
const neighborChanged = recursivelyPropagateNonNull(
|
154403
154453
|
pred,
|
154404
154454
|
direction,
|
154405
|
-
traversalState
|
154406
|
-
nonNullObjectsByBlock
|
154455
|
+
traversalState
|
154407
154456
|
);
|
154408
154457
|
changed || (changed = neighborChanged);
|
154409
154458
|
}
|
@@ -154411,35 +154460,33 @@ function propagateNonNull(fn, nodes) {
|
|
154411
154460
|
const neighborAccesses = Set_intersect(
|
154412
154461
|
Array.from(neighbors)
|
154413
154462
|
.filter(n => traversalState.get(n) === 'done')
|
154414
|
-
.map(n => assertNonNull(
|
154463
|
+
.map(n => assertNonNull(nodes.get(n)).assumedNonNullObjects)
|
154415
154464
|
);
|
154416
|
-
const prevObjects = assertNonNull(
|
154417
|
-
const
|
154418
|
-
|
154465
|
+
const prevObjects = assertNonNull(nodes.get(nodeId)).assumedNonNullObjects;
|
154466
|
+
const mergedObjects = Set_union(prevObjects, neighborAccesses);
|
154467
|
+
reduceMaybeOptionalChains(mergedObjects, registry);
|
154468
|
+
assertNonNull(nodes.get(nodeId)).assumedNonNullObjects = mergedObjects;
|
154419
154469
|
traversalState.set(nodeId, 'done');
|
154420
|
-
changed || (changed = prevObjects
|
154470
|
+
changed || (changed = !Set_equal(prevObjects, mergedObjects));
|
154421
154471
|
return changed;
|
154422
154472
|
}
|
154423
|
-
const fromEntry = new Map();
|
154424
|
-
const fromExit = new Map();
|
154425
|
-
for (const [blockId, blockInfo] of nodes) {
|
154426
|
-
fromEntry.set(blockId, blockInfo.assumedNonNullObjects);
|
154427
|
-
fromExit.set(blockId, blockInfo.assumedNonNullObjects);
|
154428
|
-
}
|
154429
154473
|
const traversalState = new Map();
|
154430
154474
|
const reversedBlocks = [...fn.body.blocks];
|
154431
154475
|
reversedBlocks.reverse();
|
154432
|
-
let i = 0;
|
154433
154476
|
let changed;
|
154477
|
+
let i = 0;
|
154434
154478
|
do {
|
154435
|
-
i
|
154479
|
+
CompilerError.invariant(i++ < 100, {
|
154480
|
+
reason:
|
154481
|
+
'[CollectHoistablePropertyLoads] fixed point iteration did not terminate after 100 loops',
|
154482
|
+
loc: GeneratedSource,
|
154483
|
+
});
|
154436
154484
|
changed = false;
|
154437
154485
|
for (const [blockId] of fn.body.blocks) {
|
154438
154486
|
const forwardChanged = recursivelyPropagateNonNull(
|
154439
154487
|
blockId,
|
154440
154488
|
'forward',
|
154441
|
-
traversalState
|
154442
|
-
fromEntry
|
154489
|
+
traversalState
|
154443
154490
|
);
|
154444
154491
|
changed || (changed = forwardChanged);
|
154445
154492
|
}
|
@@ -154448,33 +154495,12 @@ function propagateNonNull(fn, nodes) {
|
|
154448
154495
|
const backwardChanged = recursivelyPropagateNonNull(
|
154449
154496
|
blockId,
|
154450
154497
|
'backward',
|
154451
|
-
traversalState
|
154452
|
-
fromExit
|
154498
|
+
traversalState
|
154453
154499
|
);
|
154454
154500
|
changed || (changed = backwardChanged);
|
154455
154501
|
}
|
154456
154502
|
traversalState.clear();
|
154457
154503
|
} while (changed);
|
154458
|
-
CompilerError.invariant(i <= 2, {
|
154459
|
-
reason: 'require fixed-point iteration',
|
154460
|
-
description: `#iterations = ${i}`,
|
154461
|
-
loc: GeneratedSource,
|
154462
|
-
});
|
154463
|
-
CompilerError.invariant(
|
154464
|
-
fromEntry.size === fromExit.size && fromEntry.size === nodes.size,
|
154465
|
-
{
|
154466
|
-
reason:
|
154467
|
-
'bad sizes after calculating fromEntry + fromExit ' +
|
154468
|
-
`${fromEntry.size} ${fromExit.size} ${nodes.size}`,
|
154469
|
-
loc: GeneratedSource,
|
154470
|
-
}
|
154471
|
-
);
|
154472
|
-
for (const [id, node] of nodes) {
|
154473
|
-
node.assumedNonNullObjects = Set_union(
|
154474
|
-
assertNonNull(fromEntry.get(id)),
|
154475
|
-
assertNonNull(fromExit.get(id))
|
154476
|
-
);
|
154477
|
-
}
|
154478
154504
|
}
|
154479
154505
|
function assertNonNull(value, source) {
|
154480
154506
|
CompilerError.invariant(value != null, {
|
@@ -154484,67 +154510,156 @@ function assertNonNull(value, source) {
|
|
154484
154510
|
});
|
154485
154511
|
return value;
|
154486
154512
|
}
|
154487
|
-
|
154488
|
-
|
154489
|
-
|
154513
|
+
function reduceMaybeOptionalChains(nodes, registry) {
|
154514
|
+
let optionalChainNodes = Set_filter(nodes, n => n.hasOptional);
|
154515
|
+
if (optionalChainNodes.size === 0) {
|
154516
|
+
return;
|
154517
|
+
}
|
154518
|
+
let changed;
|
154519
|
+
do {
|
154520
|
+
changed = false;
|
154521
|
+
for (const original of optionalChainNodes) {
|
154522
|
+
let {identifier: identifier, path: origPath} = original.fullPath;
|
154523
|
+
let currNode = registry.getOrCreateIdentifier(identifier);
|
154524
|
+
for (let i = 0; i < origPath.length; i++) {
|
154525
|
+
const entry = origPath[i];
|
154526
|
+
const nextEntry =
|
154527
|
+
entry.optional && nodes.has(currNode)
|
154528
|
+
? {property: entry.property, optional: false}
|
154529
|
+
: entry;
|
154530
|
+
currNode = PropertyPathRegistry.getOrCreatePropertyEntry(
|
154531
|
+
currNode,
|
154532
|
+
nextEntry
|
154533
|
+
);
|
154534
|
+
}
|
154535
|
+
if (currNode !== original) {
|
154536
|
+
changed = true;
|
154537
|
+
optionalChainNodes.delete(original);
|
154538
|
+
optionalChainNodes.add(currNode);
|
154539
|
+
nodes.delete(original);
|
154540
|
+
nodes.add(currNode);
|
154541
|
+
}
|
154542
|
+
}
|
154543
|
+
} while (changed);
|
154544
|
+
}
|
154545
|
+
var _a,
|
154546
|
+
_ReactiveScopeDependencyTreeHIR_hoistableObjects,
|
154547
|
+
_ReactiveScopeDependencyTreeHIR_deps,
|
154548
|
+
_ReactiveScopeDependencyTreeHIR_getOrCreateRoot,
|
154549
|
+
_ReactiveScopeDependencyTreeHIR_debugImpl;
|
154490
154550
|
class ReactiveScopeDependencyTreeHIR {
|
154491
|
-
constructor() {
|
154492
|
-
|
154493
|
-
|
154551
|
+
constructor(hoistableObjects) {
|
154552
|
+
var _b;
|
154553
|
+
_ReactiveScopeDependencyTreeHIR_hoistableObjects.set(this, new Map());
|
154554
|
+
_ReactiveScopeDependencyTreeHIR_deps.set(this, new Map());
|
154555
|
+
for (const {path: path, identifier: identifier} of hoistableObjects) {
|
154556
|
+
let currNode = __classPrivateFieldGet(
|
154557
|
+
_a,
|
154558
|
+
_a,
|
154559
|
+
'm',
|
154560
|
+
_ReactiveScopeDependencyTreeHIR_getOrCreateRoot
|
154561
|
+
).call(
|
154562
|
+
_a,
|
154563
|
+
identifier,
|
154564
|
+
__classPrivateFieldGet(
|
154565
|
+
this,
|
154566
|
+
_ReactiveScopeDependencyTreeHIR_hoistableObjects,
|
154567
|
+
'f'
|
154568
|
+
),
|
154569
|
+
path.length > 0 && path[0].optional ? 'Optional' : 'NonNull'
|
154570
|
+
);
|
154571
|
+
for (let i = 0; i < path.length; i++) {
|
154572
|
+
const prevAccessType =
|
154573
|
+
(_b = currNode.properties.get(path[i].property)) === null ||
|
154574
|
+
_b === void 0
|
154575
|
+
? void 0
|
154576
|
+
: _b.accessType;
|
154577
|
+
const accessType =
|
154578
|
+
i + 1 < path.length && path[i + 1].optional ? 'Optional' : 'NonNull';
|
154579
|
+
CompilerError.invariant(
|
154580
|
+
prevAccessType == null || prevAccessType === accessType,
|
154581
|
+
{reason: 'Conflicting access types', loc: GeneratedSource}
|
154582
|
+
);
|
154583
|
+
let nextNode = currNode.properties.get(path[i].property);
|
154584
|
+
if (nextNode == null) {
|
154585
|
+
nextNode = {properties: new Map(), accessType: accessType};
|
154586
|
+
currNode.properties.set(path[i].property, nextNode);
|
154587
|
+
}
|
154588
|
+
currNode = nextNode;
|
154589
|
+
}
|
154590
|
+
}
|
154494
154591
|
}
|
154495
154592
|
addDependency(dep) {
|
154496
|
-
const {path: path} = dep;
|
154497
|
-
let
|
154498
|
-
|
154499
|
-
|
154593
|
+
const {identifier: identifier, path: path} = dep;
|
154594
|
+
let depCursor = __classPrivateFieldGet(
|
154595
|
+
_a,
|
154596
|
+
_a,
|
154500
154597
|
'm',
|
154501
154598
|
_ReactiveScopeDependencyTreeHIR_getOrCreateRoot
|
154502
|
-
).call(
|
154503
|
-
|
154504
|
-
|
154505
|
-
|
154506
|
-
|
154507
|
-
currChild.accessType = merge(currChild.accessType, accessType);
|
154508
|
-
currNode = currChild;
|
154509
|
-
}
|
154510
|
-
currNode.accessType = merge(
|
154511
|
-
currNode.accessType,
|
154512
|
-
PropertyAccessType.Dependency
|
154599
|
+
).call(
|
154600
|
+
_a,
|
154601
|
+
identifier,
|
154602
|
+
__classPrivateFieldGet(this, _ReactiveScopeDependencyTreeHIR_deps, 'f'),
|
154603
|
+
PropertyAccessType.UnconditionalAccess
|
154513
154604
|
);
|
154514
|
-
|
154515
|
-
markNodesNonNull(dep) {
|
154516
|
-
const accessType = PropertyAccessType.NonNullAccess;
|
154517
|
-
let currNode = __classPrivateFieldGet(
|
154605
|
+
let hoistableCursor = __classPrivateFieldGet(
|
154518
154606
|
this,
|
154519
|
-
|
154607
|
+
_ReactiveScopeDependencyTreeHIR_hoistableObjects,
|
154520
154608
|
'f'
|
154521
|
-
).get(
|
154522
|
-
|
154523
|
-
|
154524
|
-
|
154525
|
-
|
154526
|
-
|
154527
|
-
|
154528
|
-
|
154609
|
+
).get(identifier);
|
154610
|
+
for (const entry of path) {
|
154611
|
+
let nextHoistableCursor;
|
154612
|
+
let nextDepCursor;
|
154613
|
+
if (entry.optional) {
|
154614
|
+
if (hoistableCursor != null) {
|
154615
|
+
nextHoistableCursor =
|
154616
|
+
hoistableCursor === null || hoistableCursor === void 0
|
154617
|
+
? void 0
|
154618
|
+
: hoistableCursor.properties.get(entry.property);
|
154619
|
+
}
|
154620
|
+
let accessType;
|
154621
|
+
if (
|
154622
|
+
hoistableCursor != null &&
|
154623
|
+
hoistableCursor.accessType === 'NonNull'
|
154624
|
+
) {
|
154625
|
+
accessType = PropertyAccessType.UnconditionalAccess;
|
154626
|
+
} else {
|
154627
|
+
accessType = PropertyAccessType.OptionalAccess;
|
154628
|
+
}
|
154629
|
+
nextDepCursor = makeOrMergeProperty(
|
154630
|
+
depCursor,
|
154631
|
+
entry.property,
|
154632
|
+
accessType
|
154633
|
+
);
|
154634
|
+
} else if (
|
154635
|
+
hoistableCursor != null &&
|
154636
|
+
hoistableCursor.accessType === 'NonNull'
|
154637
|
+
) {
|
154638
|
+
nextHoistableCursor = hoistableCursor.properties.get(entry.property);
|
154639
|
+
nextDepCursor = makeOrMergeProperty(
|
154640
|
+
depCursor,
|
154641
|
+
entry.property,
|
154642
|
+
PropertyAccessType.UnconditionalAccess
|
154643
|
+
);
|
154644
|
+
} else {
|
154645
|
+
break;
|
154646
|
+
}
|
154647
|
+
depCursor = nextDepCursor;
|
154648
|
+
hoistableCursor = nextHoistableCursor;
|
154529
154649
|
}
|
154650
|
+
depCursor.accessType = merge(
|
154651
|
+
depCursor.accessType,
|
154652
|
+
PropertyAccessType.OptionalDependency
|
154653
|
+
);
|
154530
154654
|
}
|
154531
154655
|
deriveMinimalDependencies() {
|
154532
154656
|
const results = new Set();
|
154533
154657
|
for (const [rootId, rootNode] of __classPrivateFieldGet(
|
154534
154658
|
this,
|
154535
|
-
|
154659
|
+
_ReactiveScopeDependencyTreeHIR_deps,
|
154536
154660
|
'f'
|
154537
154661
|
).entries()) {
|
154538
|
-
|
154539
|
-
assertWellFormedTree(rootNode);
|
154540
|
-
}
|
154541
|
-
const deps = deriveMinimalDependenciesInSubtree(rootNode, []);
|
154542
|
-
for (const dep of deps) {
|
154543
|
-
results.add({
|
154544
|
-
identifier: rootId,
|
154545
|
-
path: dep.path.map(s => ({property: s, optional: false})),
|
154546
|
-
});
|
154547
|
-
}
|
154662
|
+
collectMinimalDependenciesInSubtree(rootNode, rootId, [], results);
|
154548
154663
|
}
|
154549
154664
|
return results;
|
154550
154665
|
}
|
@@ -154552,7 +154667,7 @@ class ReactiveScopeDependencyTreeHIR {
|
|
154552
154667
|
let res = [];
|
154553
154668
|
for (const [rootId, rootNode] of __classPrivateFieldGet(
|
154554
154669
|
this,
|
154555
|
-
|
154670
|
+
_ReactiveScopeDependencyTreeHIR_deps,
|
154556
154671
|
'f'
|
154557
154672
|
).entries()) {
|
154558
154673
|
const rootResults = printSubtree(rootNode, includeAccesses).map(
|
@@ -154562,100 +154677,106 @@ class ReactiveScopeDependencyTreeHIR {
|
|
154562
154677
|
}
|
154563
154678
|
return res.flat().join('\n');
|
154564
154679
|
}
|
154680
|
+
static debug(roots) {
|
154681
|
+
const buf = [`tree() [`];
|
154682
|
+
for (const [rootId, rootNode] of roots) {
|
154683
|
+
buf.push(`${printIdentifier(rootId)} (${rootNode.accessType}):`);
|
154684
|
+
__classPrivateFieldGet(
|
154685
|
+
this,
|
154686
|
+
_a,
|
154687
|
+
'm',
|
154688
|
+
_ReactiveScopeDependencyTreeHIR_debugImpl
|
154689
|
+
).call(this, buf, rootNode, 1);
|
154690
|
+
}
|
154691
|
+
buf.push(']');
|
154692
|
+
return buf.length > 2 ? buf.join('\n') : buf.join('');
|
154693
|
+
}
|
154565
154694
|
}
|
154566
|
-
(
|
154567
|
-
(
|
154695
|
+
(_a = ReactiveScopeDependencyTreeHIR),
|
154696
|
+
(_ReactiveScopeDependencyTreeHIR_hoistableObjects = new WeakMap()),
|
154697
|
+
(_ReactiveScopeDependencyTreeHIR_deps = new WeakMap()),
|
154568
154698
|
(_ReactiveScopeDependencyTreeHIR_getOrCreateRoot =
|
154569
154699
|
function _ReactiveScopeDependencyTreeHIR_getOrCreateRoot(
|
154570
154700
|
identifier,
|
154571
|
-
|
154701
|
+
roots,
|
154702
|
+
defaultAccessType
|
154572
154703
|
) {
|
154573
|
-
let rootNode =
|
154574
|
-
this,
|
154575
|
-
_ReactiveScopeDependencyTreeHIR_roots,
|
154576
|
-
'f'
|
154577
|
-
).get(identifier);
|
154704
|
+
let rootNode = roots.get(identifier);
|
154578
154705
|
if (rootNode === undefined) {
|
154579
|
-
rootNode = {
|
154580
|
-
|
154581
|
-
|
154582
|
-
|
154583
|
-
|
154584
|
-
|
154706
|
+
rootNode = {properties: new Map(), accessType: defaultAccessType};
|
154707
|
+
roots.set(identifier, rootNode);
|
154708
|
+
}
|
154709
|
+
return rootNode;
|
154710
|
+
}),
|
154711
|
+
(_ReactiveScopeDependencyTreeHIR_debugImpl =
|
154712
|
+
function _ReactiveScopeDependencyTreeHIR_debugImpl(buf, node, depth = 0) {
|
154713
|
+
for (const [property, childNode] of node.properties) {
|
154714
|
+
buf.push(
|
154715
|
+
`${' '.repeat(depth)}.${property} (${childNode.accessType}):`
|
154716
|
+
);
|
154585
154717
|
__classPrivateFieldGet(
|
154586
154718
|
this,
|
154587
|
-
|
154588
|
-
'
|
154589
|
-
|
154719
|
+
_a,
|
154720
|
+
'm',
|
154721
|
+
_ReactiveScopeDependencyTreeHIR_debugImpl
|
154722
|
+
).call(this, buf, childNode, depth + 1);
|
154590
154723
|
}
|
154591
|
-
return rootNode;
|
154592
154724
|
});
|
154593
154725
|
var PropertyAccessType;
|
154594
154726
|
(function (PropertyAccessType) {
|
154595
|
-
PropertyAccessType['
|
154596
|
-
PropertyAccessType['
|
154597
|
-
PropertyAccessType['
|
154598
|
-
PropertyAccessType['
|
154727
|
+
PropertyAccessType['OptionalAccess'] = 'OptionalAccess';
|
154728
|
+
PropertyAccessType['UnconditionalAccess'] = 'UnconditionalAccess';
|
154729
|
+
PropertyAccessType['OptionalDependency'] = 'OptionalDependency';
|
154730
|
+
PropertyAccessType['UnconditionalDependency'] = 'UnconditionalDependency';
|
154599
154731
|
})(PropertyAccessType || (PropertyAccessType = {}));
|
154600
|
-
|
154601
|
-
function isNonNull(access) {
|
154732
|
+
function isOptional(access) {
|
154602
154733
|
return (
|
154603
|
-
access === PropertyAccessType.
|
154604
|
-
access === PropertyAccessType.
|
154734
|
+
access === PropertyAccessType.OptionalAccess ||
|
154735
|
+
access === PropertyAccessType.OptionalDependency
|
154605
154736
|
);
|
154606
154737
|
}
|
154607
154738
|
function isDependency(access) {
|
154608
154739
|
return (
|
154609
|
-
access === PropertyAccessType.
|
154610
|
-
access === PropertyAccessType.
|
154740
|
+
access === PropertyAccessType.OptionalDependency ||
|
154741
|
+
access === PropertyAccessType.UnconditionalDependency
|
154611
154742
|
);
|
154612
154743
|
}
|
154613
154744
|
function merge(access1, access2) {
|
154614
|
-
const
|
154745
|
+
const resultIsUnconditional = !(isOptional(access1) && isOptional(access2));
|
154615
154746
|
const resultIsDependency = isDependency(access1) || isDependency(access2);
|
154616
|
-
if (
|
154747
|
+
if (resultIsUnconditional) {
|
154617
154748
|
if (resultIsDependency) {
|
154618
|
-
return PropertyAccessType.
|
154749
|
+
return PropertyAccessType.UnconditionalDependency;
|
154619
154750
|
} else {
|
154620
|
-
return PropertyAccessType.
|
154751
|
+
return PropertyAccessType.UnconditionalAccess;
|
154621
154752
|
}
|
154622
154753
|
} else {
|
154623
154754
|
if (resultIsDependency) {
|
154624
|
-
return PropertyAccessType.
|
154755
|
+
return PropertyAccessType.OptionalDependency;
|
154625
154756
|
} else {
|
154626
|
-
return PropertyAccessType.
|
154757
|
+
return PropertyAccessType.OptionalAccess;
|
154627
154758
|
}
|
154628
154759
|
}
|
154629
154760
|
}
|
154630
|
-
function
|
154631
|
-
|
154632
|
-
|
154633
|
-
|
154634
|
-
|
154635
|
-
|
154636
|
-
if (nonNullInChildren) {
|
154637
|
-
CompilerError.invariant(isNonNull(node.accessType), {
|
154638
|
-
reason:
|
154639
|
-
'[DeriveMinimialDependencies] Not well formed tree, unexpected non-null node',
|
154640
|
-
description: node.accessType,
|
154641
|
-
loc: GeneratedSource,
|
154642
|
-
});
|
154643
|
-
}
|
154644
|
-
}
|
154645
|
-
function deriveMinimalDependenciesInSubtree(node, path) {
|
154761
|
+
function collectMinimalDependenciesInSubtree(
|
154762
|
+
node,
|
154763
|
+
rootIdentifier,
|
154764
|
+
path,
|
154765
|
+
results
|
154766
|
+
) {
|
154646
154767
|
if (isDependency(node.accessType)) {
|
154647
|
-
|
154768
|
+
results.add({identifier: rootIdentifier, path: path});
|
154648
154769
|
} else {
|
154649
|
-
|
154650
|
-
|
154651
|
-
|
154652
|
-
|
154653
|
-
|
154654
|
-
|
154655
|
-
|
154656
|
-
|
154657
|
-
|
154658
|
-
|
154770
|
+
for (const [childName, childNode] of node.properties) {
|
154771
|
+
collectMinimalDependenciesInSubtree(
|
154772
|
+
childNode,
|
154773
|
+
rootIdentifier,
|
154774
|
+
[
|
154775
|
+
...path,
|
154776
|
+
{property: childName, optional: isOptional(childNode.accessType)},
|
154777
|
+
],
|
154778
|
+
results
|
154779
|
+
);
|
154659
154780
|
}
|
154660
154781
|
}
|
154661
154782
|
}
|
@@ -154670,14 +154791,202 @@ function printSubtree(node, includeAccesses) {
|
|
154670
154791
|
}
|
154671
154792
|
return results;
|
154672
154793
|
}
|
154673
|
-
function
|
154794
|
+
function makeOrMergeProperty(node, property, accessType) {
|
154674
154795
|
let child = node.properties.get(property);
|
154675
154796
|
if (child == null) {
|
154676
|
-
child = {properties: new Map(), accessType:
|
154797
|
+
child = {properties: new Map(), accessType: accessType};
|
154677
154798
|
node.properties.set(property, child);
|
154799
|
+
} else {
|
154800
|
+
child.accessType = merge(child.accessType, accessType);
|
154678
154801
|
}
|
154679
154802
|
return child;
|
154680
154803
|
}
|
154804
|
+
function collectOptionalChainSidemap(fn) {
|
154805
|
+
const context = {
|
154806
|
+
blocks: fn.body.blocks,
|
154807
|
+
seenOptionals: new Set(),
|
154808
|
+
processedInstrsInOptional: new Set(),
|
154809
|
+
temporariesReadInOptional: new Map(),
|
154810
|
+
hoistableObjects: new Map(),
|
154811
|
+
};
|
154812
|
+
for (const [_, block] of fn.body.blocks) {
|
154813
|
+
if (
|
154814
|
+
block.terminal.kind === 'optional' &&
|
154815
|
+
!context.seenOptionals.has(block.id)
|
154816
|
+
) {
|
154817
|
+
traverseOptionalBlock(block, context, null);
|
154818
|
+
}
|
154819
|
+
}
|
154820
|
+
return {
|
154821
|
+
temporariesReadInOptional: context.temporariesReadInOptional,
|
154822
|
+
processedInstrsInOptional: context.processedInstrsInOptional,
|
154823
|
+
hoistableObjects: context.hoistableObjects,
|
154824
|
+
};
|
154825
|
+
}
|
154826
|
+
function matchOptionalTestBlock(terminal, blocks) {
|
154827
|
+
const consequentBlock = assertNonNull(blocks.get(terminal.consequent));
|
154828
|
+
if (
|
154829
|
+
consequentBlock.instructions.length === 2 &&
|
154830
|
+
consequentBlock.instructions[0].value.kind === 'PropertyLoad' &&
|
154831
|
+
consequentBlock.instructions[1].value.kind === 'StoreLocal'
|
154832
|
+
) {
|
154833
|
+
const propertyLoad = consequentBlock.instructions[0];
|
154834
|
+
const storeLocal = consequentBlock.instructions[1].value;
|
154835
|
+
const storeLocalInstrId = consequentBlock.instructions[1].id;
|
154836
|
+
CompilerError.invariant(
|
154837
|
+
propertyLoad.value.object.identifier.id === terminal.test.identifier.id,
|
154838
|
+
{
|
154839
|
+
reason:
|
154840
|
+
'[OptionalChainDeps] Inconsistent optional chaining property load',
|
154841
|
+
description: `Test=${printIdentifier(terminal.test.identifier)} PropertyLoad base=${printIdentifier(propertyLoad.value.object.identifier)}`,
|
154842
|
+
loc: propertyLoad.loc,
|
154843
|
+
}
|
154844
|
+
);
|
154845
|
+
CompilerError.invariant(
|
154846
|
+
storeLocal.value.identifier.id === propertyLoad.lvalue.identifier.id,
|
154847
|
+
{
|
154848
|
+
reason: '[OptionalChainDeps] Unexpected storeLocal',
|
154849
|
+
loc: propertyLoad.loc,
|
154850
|
+
}
|
154851
|
+
);
|
154852
|
+
if (
|
154853
|
+
consequentBlock.terminal.kind !== 'goto' ||
|
154854
|
+
consequentBlock.terminal.variant !== GotoVariant.Break
|
154855
|
+
) {
|
154856
|
+
return null;
|
154857
|
+
}
|
154858
|
+
const alternate = assertNonNull(blocks.get(terminal.alternate));
|
154859
|
+
CompilerError.invariant(
|
154860
|
+
alternate.instructions.length === 2 &&
|
154861
|
+
alternate.instructions[0].value.kind === 'Primitive' &&
|
154862
|
+
alternate.instructions[1].value.kind === 'StoreLocal',
|
154863
|
+
{reason: 'Unexpected alternate structure', loc: terminal.loc}
|
154864
|
+
);
|
154865
|
+
return {
|
154866
|
+
consequentId: storeLocal.lvalue.place.identifier.id,
|
154867
|
+
property: propertyLoad.value.property,
|
154868
|
+
propertyId: propertyLoad.lvalue.identifier.id,
|
154869
|
+
storeLocalInstrId: storeLocalInstrId,
|
154870
|
+
consequentGoto: consequentBlock.terminal.block,
|
154871
|
+
};
|
154872
|
+
}
|
154873
|
+
return null;
|
154874
|
+
}
|
154875
|
+
function traverseOptionalBlock(optional, context, outerAlternate) {
|
154876
|
+
context.seenOptionals.add(optional.id);
|
154877
|
+
const maybeTest = context.blocks.get(optional.terminal.test);
|
154878
|
+
let test;
|
154879
|
+
let baseObject;
|
154880
|
+
if (maybeTest.terminal.kind === 'branch') {
|
154881
|
+
CompilerError.invariant(optional.terminal.optional, {
|
154882
|
+
reason: '[OptionalChainDeps] Expect base case to be always optional',
|
154883
|
+
loc: optional.terminal.loc,
|
154884
|
+
});
|
154885
|
+
if (
|
154886
|
+
maybeTest.instructions.length === 0 ||
|
154887
|
+
maybeTest.instructions[0].value.kind !== 'LoadLocal'
|
154888
|
+
) {
|
154889
|
+
return null;
|
154890
|
+
}
|
154891
|
+
const path = [];
|
154892
|
+
for (let i = 1; i < maybeTest.instructions.length; i++) {
|
154893
|
+
const instrVal = maybeTest.instructions[i].value;
|
154894
|
+
const prevInstr = maybeTest.instructions[i - 1];
|
154895
|
+
if (
|
154896
|
+
instrVal.kind === 'PropertyLoad' &&
|
154897
|
+
instrVal.object.identifier.id === prevInstr.lvalue.identifier.id
|
154898
|
+
) {
|
154899
|
+
path.push({property: instrVal.property, optional: false});
|
154900
|
+
} else {
|
154901
|
+
return null;
|
154902
|
+
}
|
154903
|
+
}
|
154904
|
+
CompilerError.invariant(
|
154905
|
+
maybeTest.terminal.test.identifier.id ===
|
154906
|
+
maybeTest.instructions.at(-1).lvalue.identifier.id,
|
154907
|
+
{
|
154908
|
+
reason: '[OptionalChainDeps] Unexpected test expression',
|
154909
|
+
loc: maybeTest.terminal.loc,
|
154910
|
+
}
|
154911
|
+
);
|
154912
|
+
baseObject = {
|
154913
|
+
identifier: maybeTest.instructions[0].value.place.identifier,
|
154914
|
+
path: path,
|
154915
|
+
};
|
154916
|
+
test = maybeTest.terminal;
|
154917
|
+
} else if (maybeTest.terminal.kind === 'optional') {
|
154918
|
+
const testBlock = context.blocks.get(maybeTest.terminal.fallthrough);
|
154919
|
+
if (testBlock.terminal.kind !== 'branch') {
|
154920
|
+
CompilerError.throwTodo({
|
154921
|
+
reason: `Unexpected terminal kind \`${testBlock.terminal.kind}\` for optional fallthrough block`,
|
154922
|
+
loc: maybeTest.terminal.loc,
|
154923
|
+
});
|
154924
|
+
}
|
154925
|
+
const innerOptional = traverseOptionalBlock(
|
154926
|
+
maybeTest,
|
154927
|
+
context,
|
154928
|
+
testBlock.terminal.alternate
|
154929
|
+
);
|
154930
|
+
if (innerOptional == null) {
|
154931
|
+
return null;
|
154932
|
+
}
|
154933
|
+
if (testBlock.terminal.test.identifier.id !== innerOptional) {
|
154934
|
+
return null;
|
154935
|
+
}
|
154936
|
+
if (!optional.terminal.optional) {
|
154937
|
+
context.hoistableObjects.set(
|
154938
|
+
optional.id,
|
154939
|
+
assertNonNull(context.temporariesReadInOptional.get(innerOptional))
|
154940
|
+
);
|
154941
|
+
}
|
154942
|
+
baseObject = assertNonNull(
|
154943
|
+
context.temporariesReadInOptional.get(innerOptional)
|
154944
|
+
);
|
154945
|
+
test = testBlock.terminal;
|
154946
|
+
} else {
|
154947
|
+
return null;
|
154948
|
+
}
|
154949
|
+
if (test.alternate === outerAlternate) {
|
154950
|
+
CompilerError.invariant(optional.instructions.length === 0, {
|
154951
|
+
reason:
|
154952
|
+
'[OptionalChainDeps] Unexpected instructions an inner optional block. ' +
|
154953
|
+
'This indicates that the compiler may be incorrectly concatenating two unrelated optional chains',
|
154954
|
+
loc: optional.terminal.loc,
|
154955
|
+
});
|
154956
|
+
}
|
154957
|
+
const matchConsequentResult = matchOptionalTestBlock(test, context.blocks);
|
154958
|
+
if (!matchConsequentResult) {
|
154959
|
+
return null;
|
154960
|
+
}
|
154961
|
+
CompilerError.invariant(
|
154962
|
+
matchConsequentResult.consequentGoto === optional.terminal.fallthrough,
|
154963
|
+
{
|
154964
|
+
reason: '[OptionalChainDeps] Unexpected optional goto-fallthrough',
|
154965
|
+
description: `${matchConsequentResult.consequentGoto} != ${optional.terminal.fallthrough}`,
|
154966
|
+
loc: optional.terminal.loc,
|
154967
|
+
}
|
154968
|
+
);
|
154969
|
+
const load = {
|
154970
|
+
identifier: baseObject.identifier,
|
154971
|
+
path: [
|
154972
|
+
...baseObject.path,
|
154973
|
+
{
|
154974
|
+
property: matchConsequentResult.property,
|
154975
|
+
optional: optional.terminal.optional,
|
154976
|
+
},
|
154977
|
+
],
|
154978
|
+
};
|
154979
|
+
context.processedInstrsInOptional.add(
|
154980
|
+
matchConsequentResult.storeLocalInstrId
|
154981
|
+
);
|
154982
|
+
context.processedInstrsInOptional.add(test.id);
|
154983
|
+
context.temporariesReadInOptional.set(
|
154984
|
+
matchConsequentResult.consequentId,
|
154985
|
+
load
|
154986
|
+
);
|
154987
|
+
context.temporariesReadInOptional.set(matchConsequentResult.propertyId, load);
|
154988
|
+
return matchConsequentResult.consequentId;
|
154989
|
+
}
|
154681
154990
|
var _Context_instances,
|
154682
154991
|
_Context_declarations,
|
154683
154992
|
_Context_reassignments,
|
@@ -154691,18 +155000,37 @@ function propagateScopeDependenciesHIR(fn) {
|
|
154691
155000
|
const usedOutsideDeclaringScope =
|
154692
155001
|
findTemporariesUsedOutsideDeclaringScope(fn);
|
154693
155002
|
const temporaries = collectTemporariesSidemap(fn, usedOutsideDeclaringScope);
|
154694
|
-
const
|
155003
|
+
const {
|
155004
|
+
temporariesReadInOptional: temporariesReadInOptional,
|
155005
|
+
processedInstrsInOptional: processedInstrsInOptional,
|
155006
|
+
hoistableObjects: hoistableObjects,
|
155007
|
+
} = collectOptionalChainSidemap(fn);
|
155008
|
+
const hoistablePropertyLoads = collectHoistablePropertyLoads(
|
155009
|
+
fn,
|
155010
|
+
temporaries,
|
155011
|
+
hoistableObjects
|
155012
|
+
);
|
154695
155013
|
const scopeDeps = collectDependencies(
|
154696
155014
|
fn,
|
154697
155015
|
usedOutsideDeclaringScope,
|
154698
|
-
temporaries
|
155016
|
+
new Map([...temporaries, ...temporariesReadInOptional]),
|
155017
|
+
processedInstrsInOptional
|
154699
155018
|
);
|
154700
155019
|
for (const [scope, deps] of scopeDeps) {
|
154701
|
-
|
155020
|
+
if (deps.length === 0) {
|
155021
|
+
continue;
|
155022
|
+
}
|
155023
|
+
const hoistables = hoistablePropertyLoads.get(scope.id);
|
155024
|
+
CompilerError.invariant(hoistables != null, {
|
155025
|
+
reason: '[PropagateScopeDependencies] Scope not found in tracked blocks',
|
155026
|
+
loc: GeneratedSource,
|
155027
|
+
});
|
155028
|
+
const tree = new ReactiveScopeDependencyTreeHIR(
|
155029
|
+
[...hoistables.assumedNonNullObjects].map(o => o.fullPath)
|
155030
|
+
);
|
154702
155031
|
for (const dep of deps) {
|
154703
155032
|
tree.addDependency(Object.assign({}, dep));
|
154704
155033
|
}
|
154705
|
-
recordHoistablePropertyReads(hoistablePropertyLoads, scope.id, tree);
|
154706
155034
|
const candidates = tree.deriveMinimalDependencies();
|
154707
155035
|
for (const candidateDep of candidates) {
|
154708
155036
|
if (
|
@@ -154779,7 +155107,12 @@ function collectTemporariesSidemap(fn, usedOutsideDeclaringScope) {
|
|
154779
155107
|
lvalue.identifier.declarationId
|
154780
155108
|
);
|
154781
155109
|
if (value.kind === 'PropertyLoad' && !usedOutside) {
|
154782
|
-
const property = getProperty(
|
155110
|
+
const property = getProperty(
|
155111
|
+
value.object,
|
155112
|
+
value.property,
|
155113
|
+
false,
|
155114
|
+
temporaries
|
155115
|
+
);
|
154783
155116
|
temporaries.set(lvalue.identifier.id, property);
|
154784
155117
|
} else if (
|
154785
155118
|
value.kind === 'LoadLocal' &&
|
@@ -154796,6 +155129,25 @@ function collectTemporariesSidemap(fn, usedOutsideDeclaringScope) {
|
|
154796
155129
|
}
|
154797
155130
|
return temporaries;
|
154798
155131
|
}
|
155132
|
+
function getProperty(object, propertyName, optional, temporaries) {
|
155133
|
+
const resolvedDependency = temporaries.get(object.identifier.id);
|
155134
|
+
let property;
|
155135
|
+
if (resolvedDependency == null) {
|
155136
|
+
property = {
|
155137
|
+
identifier: object.identifier,
|
155138
|
+
path: [{property: propertyName, optional: optional}],
|
155139
|
+
};
|
155140
|
+
} else {
|
155141
|
+
property = {
|
155142
|
+
identifier: resolvedDependency.identifier,
|
155143
|
+
path: [
|
155144
|
+
...resolvedDependency.path,
|
155145
|
+
{property: propertyName, optional: optional},
|
155146
|
+
],
|
155147
|
+
};
|
155148
|
+
}
|
155149
|
+
return property;
|
155150
|
+
}
|
154799
155151
|
class Context {
|
154800
155152
|
constructor(temporariesUsedOutsideScope, temporaries) {
|
154801
155153
|
_Context_instances.add(this);
|
@@ -154909,10 +155261,11 @@ class Context {
|
|
154909
155261
|
: {identifier: place.identifier, path: []}
|
154910
155262
|
);
|
154911
155263
|
}
|
154912
|
-
visitProperty(object, property) {
|
155264
|
+
visitProperty(object, property, optional) {
|
154913
155265
|
const nextDependency = getProperty(
|
154914
155266
|
object,
|
154915
155267
|
property,
|
155268
|
+
optional,
|
154916
155269
|
__classPrivateFieldGet(this, _Context_temporaries, 'f')
|
154917
155270
|
);
|
154918
155271
|
this.visitDependency(nextDependency);
|
@@ -155043,7 +155396,7 @@ function handleInstruction(instr, context) {
|
|
155043
155396
|
}
|
155044
155397
|
} else if (value.kind === 'PropertyLoad') {
|
155045
155398
|
if (context.isUsedOutsideDeclaringScope(lvalue)) {
|
155046
|
-
context.visitProperty(value.object, value.property);
|
155399
|
+
context.visitProperty(value.object, value.property, false);
|
155047
155400
|
}
|
155048
155401
|
} else if (value.kind === 'StoreLocal') {
|
155049
155402
|
context.visitOperand(value.value);
|
@@ -155074,7 +155427,12 @@ function handleInstruction(instr, context) {
|
|
155074
155427
|
}
|
155075
155428
|
context.declare(lvalue.identifier, {id: id, scope: context.currentScope});
|
155076
155429
|
}
|
155077
|
-
function collectDependencies(
|
155430
|
+
function collectDependencies(
|
155431
|
+
fn,
|
155432
|
+
usedOutsideDeclaringScope,
|
155433
|
+
temporaries,
|
155434
|
+
processedInstrsInOptional
|
155435
|
+
) {
|
155078
155436
|
const context = new Context(usedOutsideDeclaringScope, temporaries);
|
155079
155437
|
for (const param of fn.params) {
|
155080
155438
|
if (param.kind === 'Identifier') {
|
@@ -155111,25 +155469,27 @@ function collectDependencies(fn, usedOutsideDeclaringScope, temporaries) {
|
|
155111
155469
|
: scopeBlockInfo.pruned
|
155112
155470
|
);
|
155113
155471
|
}
|
155472
|
+
for (const phi of block.phis) {
|
155473
|
+
for (const operand of phi.operands) {
|
155474
|
+
const maybeOptionalChain = temporaries.get(operand[1].id);
|
155475
|
+
if (maybeOptionalChain) {
|
155476
|
+
context.visitDependency(maybeOptionalChain);
|
155477
|
+
}
|
155478
|
+
}
|
155479
|
+
}
|
155114
155480
|
for (const instr of block.instructions) {
|
155115
|
-
|
155481
|
+
if (!processedInstrsInOptional.has(instr.id)) {
|
155482
|
+
handleInstruction(instr, context);
|
155483
|
+
}
|
155116
155484
|
}
|
155117
|
-
|
155118
|
-
|
155485
|
+
if (!processedInstrsInOptional.has(block.terminal.id)) {
|
155486
|
+
for (const place of eachTerminalOperand(block.terminal)) {
|
155487
|
+
context.visitOperand(place);
|
155488
|
+
}
|
155119
155489
|
}
|
155120
155490
|
}
|
155121
155491
|
return context.deps;
|
155122
155492
|
}
|
155123
|
-
function recordHoistablePropertyReads(nodes, scopeId, tree) {
|
155124
|
-
const node = nodes.get(scopeId);
|
155125
|
-
CompilerError.invariant(node != null, {
|
155126
|
-
reason: '[PropagateScopeDependencies] Scope not found in tracked blocks',
|
155127
|
-
loc: GeneratedSource,
|
155128
|
-
});
|
155129
|
-
for (const item of node.assumedNonNullObjects) {
|
155130
|
-
tree.markNodesNonNull(Object.assign({}, item.fullPath));
|
155131
|
-
}
|
155132
|
-
}
|
155133
155493
|
function* run(
|
155134
155494
|
func,
|
155135
155495
|
config,
|