| Index: pkg/compiler/lib/src/serialization/equivalence.dart
|
| diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/pkg/compiler/lib/src/serialization/equivalence.dart
|
| index d68ce3ec08c45f06ff0209e175957289a3a24dcd..b3b4bbcb0cb65348d939e2756b01d3135af3e19a 100644
|
| --- a/pkg/compiler/lib/src/serialization/equivalence.dart
|
| +++ b/pkg/compiler/lib/src/serialization/equivalence.dart
|
| @@ -790,6 +790,40 @@ class TreeElementsEquivalenceVisitor extends Visitor {
|
| this.indices1, this.indices2, this.elements1, this.elements2,
|
| [this.strategy = const TestStrategy()]);
|
|
|
| + bool testJumpTargets(
|
| + Node node1, Node node2, String property, JumpTarget a, JumpTarget b) {
|
| + if (identical(a, b)) return true;
|
| + if (a == null || b == null) return false;
|
| + return strategy.testElements(a, b, 'executableContext', a.executableContext,
|
| + b.executableContext) &&
|
| + strategy.test(a, b, 'nestingLevel', a.nestingLevel, b.nestingLevel) &&
|
| + strategy.test(a, b, 'statement', indices1.nodeIndices[a.statement],
|
| + indices2.nodeIndices[b.statement]) &&
|
| + strategy.test(
|
| + a, b, 'isBreakTarget', a.isBreakTarget, b.isBreakTarget) &&
|
| + strategy.test(
|
| + a, b, 'isContinueTarget', a.isContinueTarget, b.isContinueTarget) &&
|
| + strategy.testLists(a, b, 'labels', a.labels.toList(), b.labels.toList(),
|
| + (a, b) {
|
| + return indices1.nodeIndices[a.label] == indices2.nodeIndices[b.label];
|
| + });
|
| + }
|
| +
|
| + bool testLabelDefinitions(Node node1, Node node2, String property,
|
| + LabelDefinition a, LabelDefinition b) {
|
| + if (identical(a, b)) return true;
|
| + if (a == null || b == null) return false;
|
| + return strategy.test(a, b, 'label', indices1.nodeIndices[a.label],
|
| + indices2.nodeIndices[b.label]) &&
|
| + strategy.test(a, b, 'labelName', a.labelName, b.labelName) &&
|
| + strategy.test(a, b, 'target', indices1.nodeIndices[a.target.statement],
|
| + indices2.nodeIndices[b.target.statement]) &&
|
| + strategy.test(
|
| + a, b, 'isBreakTarget', a.isBreakTarget, b.isBreakTarget) &&
|
| + strategy.test(
|
| + a, b, 'isContinueTarget', a.isContinueTarget, b.isContinueTarget);
|
| + }
|
| +
|
| visitNode(Node node1) {
|
| if (!success) return;
|
| int index = indices1.nodeIndices[node1];
|
| @@ -808,7 +842,13 @@ class TreeElementsEquivalenceVisitor extends Visitor {
|
| strategy.testConstants(node1, node2, 'getConstant($index)',
|
| elements1.getConstant(node1), elements2.getConstant(node2)) &&
|
| strategy.testTypes(node1, node2, 'typesCache[$index]',
|
| - elements1.typesCache[node1], elements2.typesCache[node2]);
|
| + elements1.typesCache[node1], elements2.typesCache[node2]) &&
|
| + testJumpTargets(
|
| + node1,
|
| + node2,
|
| + 'getTargetDefinition($index)',
|
| + elements1.getTargetDefinition(node1),
|
| + elements2.getTargetDefinition(node2));
|
|
|
| node1.visitChildren(this);
|
| }
|
| @@ -915,6 +955,36 @@ class TreeElementsEquivalenceVisitor extends Visitor {
|
| elements1.getRedirectingTargetConstructor(node1),
|
| elements2.getRedirectingTargetConstructor(node2));
|
| }
|
| +
|
| + @override
|
| + visitGotoStatement(GotoStatement node1) {
|
| + visitStatement(node1);
|
| + if (!success) return;
|
| + int index = indices1.nodeIndices[node1];
|
| + GotoStatement node2 = indices2.nodeList[index];
|
| + success = testJumpTargets(node1, node2, 'getTargetOf($index)',
|
| + elements1.getTargetOf(node1), elements2.getTargetOf(node2));
|
| + if (!success) return;
|
| + if (node1.target == null && node2.target == null) {
|
| + return;
|
| + }
|
| + success = testLabelDefinitions(node1, node2, 'getTarget($index)',
|
| + elements1.getTargetLabel(node1), elements2.getTargetLabel(node2));
|
| + }
|
| +
|
| + @override
|
| + visitLabel(Label node1) {
|
| + visitNode(node1);
|
| + if (!success) return;
|
| + int index = indices1.nodeIndices[node1];
|
| + Label node2 = indices2.nodeList[index];
|
| + success = testLabelDefinitions(
|
| + node1,
|
| + node2,
|
| + 'getLabelDefinition($index)',
|
| + elements1.getLabelDefinition(node1),
|
| + elements2.getLabelDefinition(node2));
|
| + }
|
| }
|
|
|
| class NodeEquivalenceVisitor implements Visitor1<bool, Node> {
|
|
|