| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /// Equivalence test functions for data objects. | 5 /// Equivalence test functions for data objects. |
| 6 | 6 |
| 7 library dart2js.equivalence.functions; | 7 library dart2js.equivalence.functions; |
| 8 | 8 |
| 9 import 'package:expect/expect.dart'; | 9 import 'package:expect/expect.dart'; |
| 10 import 'package:compiler/src/common/resolution.dart'; | 10 import 'package:compiler/src/common/resolution.dart'; |
| 11 import 'package:compiler/src/common_elements.dart'; | 11 import 'package:compiler/src/common_elements.dart'; |
| 12 import 'package:compiler/src/compiler.dart'; | 12 import 'package:compiler/src/compiler.dart'; |
| 13 import 'package:compiler/src/elements/types.dart'; | 13 import 'package:compiler/src/elements/types.dart'; |
| 14 import 'package:compiler/src/elements/elements.dart'; | 14 import 'package:compiler/src/elements/elements.dart'; |
| 15 import 'package:compiler/src/elements/entities.dart'; | 15 import 'package:compiler/src/elements/entities.dart'; |
| 16 import 'package:compiler/src/enqueue.dart'; | 16 import 'package:compiler/src/enqueue.dart'; |
| 17 import 'package:compiler/src/js_backend/backend_usage.dart'; | 17 import 'package:compiler/src/js_backend/backend_usage.dart'; |
| 18 import 'package:compiler/src/js_backend/native_data.dart'; | 18 import 'package:compiler/src/js_backend/native_data.dart'; |
| 19 import 'package:compiler/src/js_backend/interceptor_data.dart'; | 19 import 'package:compiler/src/js_backend/interceptor_data.dart'; |
| 20 import 'package:compiler/src/serialization/equivalence.dart'; | 20 import 'package:compiler/src/serialization/equivalence.dart'; |
| 21 import 'package:compiler/src/universe/class_set.dart'; | 21 import 'package:compiler/src/universe/class_set.dart'; |
| 22 import 'package:compiler/src/universe/world_builder.dart'; | 22 import 'package:compiler/src/universe/world_builder.dart'; |
| 23 import 'package:compiler/src/world.dart'; | 23 import 'package:compiler/src/world.dart'; |
| 24 import 'check_helpers.dart'; | 24 import 'check_helpers.dart'; |
| 25 | 25 |
| 26 void checkClosedWorlds(ClosedWorld closedWorld1, ClosedWorld closedWorld2, | 26 void checkClosedWorlds(ClosedWorld closedWorld1, ClosedWorld closedWorld2, |
| 27 {TestStrategy strategy: const TestStrategy(), | 27 {TestStrategy strategy: const TestStrategy(), |
| 28 bool allowExtra: false, | 28 bool allowExtra: false, |
| 29 bool verbose: false}) { | 29 bool verbose: false, |
| 30 bool allowMissingClosureClasses: false}) { |
| 30 if (verbose) { | 31 if (verbose) { |
| 31 print(closedWorld1.dump()); | 32 print(closedWorld1.dump()); |
| 32 print(closedWorld2.dump()); | 33 print(closedWorld2.dump()); |
| 33 } | 34 } |
| 34 checkClassHierarchyNodes( | 35 checkClassHierarchyNodes( |
| 35 closedWorld1, | 36 closedWorld1, |
| 36 closedWorld2, | 37 closedWorld2, |
| 37 closedWorld1 | 38 closedWorld1 |
| 38 .getClassHierarchyNode(closedWorld1.commonElements.objectClass), | 39 .getClassHierarchyNode(closedWorld1.commonElements.objectClass), |
| 39 closedWorld2 | 40 closedWorld2 |
| 40 .getClassHierarchyNode(closedWorld2.commonElements.objectClass), | 41 .getClassHierarchyNode(closedWorld2.commonElements.objectClass), |
| 41 strategy.elementEquivalence, | 42 strategy.elementEquivalence, |
| 42 verbose: verbose); | 43 verbose: verbose, |
| 44 allowMissingClosureClasses: allowMissingClosureClasses); |
| 43 | 45 |
| 44 checkNativeData(closedWorld1.nativeData, closedWorld2.nativeData, | 46 checkNativeData(closedWorld1.nativeData, closedWorld2.nativeData, |
| 45 strategy: strategy, allowExtra: allowExtra, verbose: verbose); | 47 strategy: strategy, allowExtra: allowExtra, verbose: verbose); |
| 46 checkInterceptorData(closedWorld1.interceptorData, | 48 checkInterceptorData(closedWorld1.interceptorData, |
| 47 closedWorld2.interceptorData, strategy.elementEquivalence, | 49 closedWorld2.interceptorData, strategy.elementEquivalence, |
| 48 verbose: verbose); | 50 verbose: verbose); |
| 49 } | 51 } |
| 50 | 52 |
| 51 void checkNativeData(NativeDataImpl data1, NativeDataImpl data2, | 53 void checkNativeData(NativeDataImpl data1, NativeDataImpl data2, |
| 52 {TestStrategy strategy: const TestStrategy(), | 54 {TestStrategy strategy: const TestStrategy(), |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 data2.classesMixedIntoInterceptedClassesForTesting, | 147 data2.classesMixedIntoInterceptedClassesForTesting, |
| 146 elementEquivalence); | 148 elementEquivalence); |
| 147 } | 149 } |
| 148 | 150 |
| 149 void checkClassHierarchyNodes( | 151 void checkClassHierarchyNodes( |
| 150 ClosedWorld closedWorld1, | 152 ClosedWorld closedWorld1, |
| 151 ClosedWorld closedWorld2, | 153 ClosedWorld closedWorld2, |
| 152 ClassHierarchyNode node1, | 154 ClassHierarchyNode node1, |
| 153 ClassHierarchyNode node2, | 155 ClassHierarchyNode node2, |
| 154 bool elementEquivalence(Entity a, Entity b), | 156 bool elementEquivalence(Entity a, Entity b), |
| 155 {bool verbose: false}) { | 157 {bool verbose: false, |
| 158 bool allowMissingClosureClasses: false}) { |
| 156 if (verbose) { | 159 if (verbose) { |
| 157 print('Checking $node1 vs $node2'); | 160 print('Checking $node1 vs $node2'); |
| 158 } | 161 } |
| 159 ClassEntity cls1 = node1.cls; | 162 ClassEntity cls1 = node1.cls; |
| 160 ClassEntity cls2 = node2.cls; | 163 ClassEntity cls2 = node2.cls; |
| 161 Expect.isTrue(elementEquivalence(cls1, cls2), | 164 Expect.isTrue(elementEquivalence(cls1, cls2), |
| 162 "Element identity mismatch for ${cls1} vs ${cls2}."); | 165 "Element identity mismatch for ${cls1} vs ${cls2}."); |
| 163 Expect.equals( | 166 Expect.equals( |
| 164 node1.isDirectlyInstantiated, | 167 node1.isDirectlyInstantiated, |
| 165 node2.isDirectlyInstantiated, | 168 node2.isDirectlyInstantiated, |
| 166 "Value mismatch for 'isDirectlyInstantiated' " | 169 "Value mismatch for 'isDirectlyInstantiated' " |
| 167 "for ${cls1} vs ${cls2}."); | 170 "for ${cls1} vs ${cls2}."); |
| 168 Expect.equals( | 171 Expect.equals( |
| 169 node1.isIndirectlyInstantiated, | 172 node1.isIndirectlyInstantiated, |
| 170 node2.isIndirectlyInstantiated, | 173 node2.isIndirectlyInstantiated, |
| 171 "Value mismatch for 'isIndirectlyInstantiated' " | 174 "Value mismatch for 'isIndirectlyInstantiated' " |
| 172 "for ${node1.cls} vs ${node2.cls}."); | 175 "for ${node1.cls} vs ${node2.cls}."); |
| 173 // TODO(johnniwinther): Enforce a canonical and stable order on direct | 176 // TODO(johnniwinther): Enforce a canonical and stable order on direct |
| 174 // subclasses. | 177 // subclasses. |
| 175 for (ClassHierarchyNode child in node1.directSubclasses) { | 178 for (ClassHierarchyNode child in node1.directSubclasses) { |
| 176 bool found = false; | 179 bool found = false; |
| 177 for (ClassHierarchyNode other in node2.directSubclasses) { | 180 for (ClassHierarchyNode other in node2.directSubclasses) { |
| 178 ClassEntity child1 = child.cls; | 181 ClassEntity child1 = child.cls; |
| 179 ClassEntity child2 = other.cls; | 182 ClassEntity child2 = other.cls; |
| 180 if (elementEquivalence(child1, child2)) { | 183 if (elementEquivalence(child1, child2)) { |
| 181 checkClassHierarchyNodes( | 184 checkClassHierarchyNodes( |
| 182 closedWorld1, closedWorld2, child, other, elementEquivalence, | 185 closedWorld1, closedWorld2, child, other, elementEquivalence, |
| 183 verbose: verbose); | 186 verbose: verbose, |
| 187 allowMissingClosureClasses: allowMissingClosureClasses); |
| 184 found = true; | 188 found = true; |
| 185 break; | 189 break; |
| 186 } | 190 } |
| 187 } | 191 } |
| 188 if (!found) { | 192 if (!found && (!child.cls.isClosure || !allowMissingClosureClasses)) { |
| 189 if (child.isInstantiated) { | 193 if (child.isInstantiated) { |
| 190 print('Missing subclass ${child.cls} of ${node1.cls} ' | 194 print('Missing subclass ${child.cls} of ${node1.cls} ' |
| 191 'in ${node2.directSubclasses}'); | 195 'in ${node2.directSubclasses}'); |
| 192 print(closedWorld1.dump( | 196 print(closedWorld1.dump( |
| 193 verbose ? closedWorld1.commonElements.objectClass : node1.cls)); | 197 verbose ? closedWorld1.commonElements.objectClass : node1.cls)); |
| 194 print(closedWorld2.dump( | 198 print(closedWorld2.dump( |
| 195 verbose ? closedWorld2.commonElements.objectClass : node2.cls)); | 199 verbose ? closedWorld2.commonElements.objectClass : node2.cls)); |
| 196 } | 200 } |
| 197 Expect.isFalse( | 201 Expect.isFalse( |
| 198 child.isInstantiated, | 202 child.isInstantiated, |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 backendUsage1.isFunctionApplyUsed, | 665 backendUsage1.isFunctionApplyUsed, |
| 662 backendUsage1.isFunctionApplyUsed, | 666 backendUsage1.isFunctionApplyUsed, |
| 663 "JavaScriptBackend.hasFunctionApplySupport mismatch"); | 667 "JavaScriptBackend.hasFunctionApplySupport mismatch"); |
| 664 Expect.equals( | 668 Expect.equals( |
| 665 backendUsage1.isRuntimeTypeUsed, | 669 backendUsage1.isRuntimeTypeUsed, |
| 666 backendUsage2.isRuntimeTypeUsed, | 670 backendUsage2.isRuntimeTypeUsed, |
| 667 "JavaScriptBackend.hasRuntimeTypeSupport mismatch"); | 671 "JavaScriptBackend.hasRuntimeTypeSupport mismatch"); |
| 668 Expect.equals(backendUsage1.isIsolateInUse, backendUsage2.isIsolateInUse, | 672 Expect.equals(backendUsage1.isIsolateInUse, backendUsage2.isIsolateInUse, |
| 669 "JavaScriptBackend.hasIsolateSupport mismatch"); | 673 "JavaScriptBackend.hasIsolateSupport mismatch"); |
| 670 } | 674 } |
| OLD | NEW |