Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Side by Side Diff: pkg/compiler/lib/src/serialization/equivalence.dart

Issue 2663033004: Prepare equivalence strategies for testing entities. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 /// Functions for asserting equivalence across serialization. 5 /// Functions for asserting equivalence across serialization.
6 6
7 library dart2js.serialization.equivalence; 7 library dart2js.serialization.equivalence;
8 8
9 import '../closure.dart'; 9 import '../closure.dart';
10 import '../common/resolution.dart'; 10 import '../common/resolution.dart';
11 import '../constants/expressions.dart'; 11 import '../constants/expressions.dart';
12 import '../constants/values.dart'; 12 import '../constants/values.dart';
13 import '../elements/resolution_types.dart'; 13 import '../elements/resolution_types.dart';
14 import '../elements/elements.dart'; 14 import '../elements/elements.dart';
15 import '../elements/entities.dart';
15 import '../elements/types.dart'; 16 import '../elements/types.dart';
16 import '../elements/visitor.dart'; 17 import '../elements/visitor.dart';
17 import '../js_backend/backend_serialization.dart' 18 import '../js_backend/backend_serialization.dart'
18 show NativeBehaviorSerialization; 19 show NativeBehaviorSerialization;
19 import '../native/native.dart' show NativeBehavior; 20 import '../native/native.dart' show NativeBehavior;
20 import '../resolution/access_semantics.dart'; 21 import '../resolution/access_semantics.dart';
21 import '../resolution/send_structure.dart'; 22 import '../resolution/send_structure.dart';
22 import '../resolution/tree_elements.dart'; 23 import '../resolution/tree_elements.dart';
23 import '../tokens/token.dart'; 24 import '../tokens/token.dart';
24 import '../tree/nodes.dart'; 25 import '../tree/nodes.dart';
25 import '../universe/selector.dart'; 26 import '../universe/selector.dart';
26 import '../universe/feature.dart'; 27 import '../universe/feature.dart';
27 import '../universe/use.dart'; 28 import '../universe/use.dart';
28 import '../util/util.dart'; 29 import '../util/util.dart';
29 import 'resolved_ast_serialization.dart'; 30 import 'resolved_ast_serialization.dart';
30 31
32 typedef bool Equivalence<E>(E a, E b, {TestStrategy strategy});
33
31 /// Equality based equivalence function. 34 /// Equality based equivalence function.
32 bool equality(a, b) => a == b; 35 bool equality(a, b) => a == b;
33 36
34 /// Returns `true` if the elements in [a] and [b] are pair-wise equivalent 37 /// Returns `true` if the elements in [a] and [b] are pair-wise equivalent
35 /// according to [elementEquivalence]. 38 /// according to [elementEquivalence].
36 bool areListsEquivalent(List a, List b, 39 bool areListsEquivalent(List a, List b,
37 [bool elementEquivalence(a, b) = equality]) { 40 [bool elementEquivalence(a, b) = equality]) {
38 if (a.length != b.length) return false; 41 if (a.length != b.length) return false;
39 for (int i = 0; i < a.length && i < b.length; i++) { 42 for (int i = 0; i < a.length && i < b.length; i++) {
40 if (!elementEquivalence(a[i], b[i])) { 43 if (!elementEquivalence(a[i], b[i])) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 } 87 }
85 } 88 }
86 if (!found) { 89 if (!found) {
87 return false; 90 return false;
88 } 91 }
89 } 92 }
90 return remaining.isEmpty; 93 return remaining.isEmpty;
91 } 94 }
92 95
93 /// Returns `true` if elements [a] and [b] are equivalent. 96 /// Returns `true` if elements [a] and [b] are equivalent.
94 bool areElementsEquivalent(Element a, Element b) { 97 bool areElementsEquivalent(Element a, Element b, {TestStrategy strategy}) {
95 if (identical(a, b)) return true; 98 if (identical(a, b)) return true;
96 if (a == null || b == null) return false; 99 if (a == null || b == null) return false;
97 return const ElementIdentityEquivalence().visit(a, b); 100 return new ElementIdentityEquivalence(strategy ?? const TestStrategy())
101 .visit(a, b);
98 } 102 }
99 103
100 /// Returns `true` if types [a] and [b] are equivalent. 104 /// Returns `true` if types [a] and [b] are equivalent.
101 bool areTypesEquivalent(DartType a, DartType b) { 105 bool areTypesEquivalent(DartType a, DartType b, {TestStrategy strategy}) {
102 if (identical(a, b)) return true; 106 if (identical(a, b)) return true;
103 if (a == null || b == null) return false; 107 if (a == null || b == null) return false;
104 return const TypeEquivalence().visit(a, b); 108 return new TypeEquivalence(strategy ?? const TestStrategy()).visit(a, b);
105 } 109 }
106 110
107 /// Returns `true` if constants [exp1] and [exp2] are equivalent. 111 /// Returns `true` if constants [exp1] and [exp2] are equivalent.
108 bool areConstantsEquivalent(ConstantExpression exp1, ConstantExpression exp2) { 112 bool areConstantsEquivalent(ConstantExpression exp1, ConstantExpression exp2,
113 {TestStrategy strategy}) {
109 if (identical(exp1, exp2)) return true; 114 if (identical(exp1, exp2)) return true;
110 if (exp1 == null || exp2 == null) return false; 115 if (exp1 == null || exp2 == null) return false;
111 return const ConstantEquivalence().visit(exp1, exp2); 116 return new ConstantEquivalence(strategy ?? const TestStrategy())
117 .visit(exp1, exp2);
112 } 118 }
113 119
114 /// Returns `true` if constant values [value1] and [value2] are equivalent. 120 /// Returns `true` if constant values [value1] and [value2] are equivalent.
115 bool areConstantValuesEquivalent(ConstantValue value1, ConstantValue value2) { 121 bool areConstantValuesEquivalent(ConstantValue value1, ConstantValue value2,
122 {TestStrategy strategy}) {
116 if (identical(value1, value2)) return true; 123 if (identical(value1, value2)) return true;
117 if (value1 == null || value2 == null) return false; 124 if (value1 == null || value2 == null) return false;
118 return const ConstantValueEquivalence().visit(value1, value2); 125 return new ConstantValueEquivalence(strategy ?? const TestStrategy())
126 .visit(value1, value2);
119 } 127 }
120 128
121 /// Returns `true` if the lists of elements, [a] and [b], are equivalent. 129 /// Returns `true` if the lists of elements, [a] and [b], are equivalent.
122 bool areElementListsEquivalent(List<Element> a, List<Element> b) { 130 bool areElementListsEquivalent(List<Element> a, List<Element> b) {
123 return areListsEquivalent(a, b, areElementsEquivalent); 131 return areListsEquivalent(a, b, areElementsEquivalent);
124 } 132 }
125 133
126 /// Returns `true` if the lists of types, [a] and [b], are equivalent. 134 /// Returns `true` if the lists of types, [a] and [b], are equivalent.
127 bool areTypeListsEquivalent( 135 bool areTypeListsEquivalent(
128 List<ResolutionDartType> a, List<ResolutionDartType> b) { 136 List<ResolutionDartType> a, List<ResolutionDartType> b) {
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 bool areNodesEquivalent(Node node1, Node node2) { 333 bool areNodesEquivalent(Node node1, Node node2) {
326 if (identical(node1, node2)) return true; 334 if (identical(node1, node2)) return true;
327 if (node1 == null || node2 == null) return false; 335 if (node1 == null || node2 == null) return false;
328 return node1.accept1(const NodeEquivalenceVisitor(), node2); 336 return node1.accept1(const NodeEquivalenceVisitor(), node2);
329 } 337 }
330 338
331 /// Strategy for testing equivalence. 339 /// Strategy for testing equivalence.
332 /// 340 ///
333 /// Use this strategy to determine equivalence without failing on inequivalence. 341 /// Use this strategy to determine equivalence without failing on inequivalence.
334 class TestStrategy { 342 class TestStrategy {
335 const TestStrategy(); 343 final Equivalence<Entity> elementEquivalence;
344 final Equivalence<DartType> typeEquivalence;
345 final Equivalence<ConstantExpression> constantEquivalence;
346 final Equivalence<ConstantValue> constantValueEquivalence;
347
348 const TestStrategy(
349 {this.elementEquivalence: areElementsEquivalent,
350 this.typeEquivalence: areTypesEquivalent,
351 this.constantEquivalence: areConstantsEquivalent,
352 this.constantValueEquivalence: areConstantValuesEquivalent});
353
354 /// An equivalence [TestStrategy] that doesn't throw on inequivalence.
355 TestStrategy get testOnly => this;
336 356
337 bool test(var object1, var object2, String property, var value1, var value2, 357 bool test(var object1, var object2, String property, var value1, var value2,
338 [bool equivalence(a, b) = equality]) { 358 [bool equivalence(a, b) = equality]) {
339 return equivalence(value1, value2); 359 return equivalence(value1, value2);
340 } 360 }
341 361
342 bool testLists( 362 bool testLists(
343 Object object1, Object object2, String property, List list1, List list2, 363 Object object1, Object object2, String property, List list1, List list2,
344 [bool elementEquivalence(a, b) = equality]) { 364 [bool elementEquivalence(a, b) = equality]) {
345 return areListsEquivalent(list1, list2, elementEquivalence); 365 return areListsEquivalent(list1, list2, elementEquivalence);
346 } 366 }
347 367
348 bool testSets( 368 bool testSets(
349 var object1, var object2, String property, Iterable set1, Iterable set2, 369 var object1, var object2, String property, Iterable set1, Iterable set2,
350 [bool elementEquivalence(a, b) = equality]) { 370 [bool elementEquivalence(a, b) = equality]) {
351 return areSetsEquivalent(set1, set2, elementEquivalence); 371 return areSetsEquivalent(set1, set2, elementEquivalence);
352 } 372 }
353 373
354 bool testMaps(var object1, var object2, String property, Map map1, Map map2, 374 bool testMaps(var object1, var object2, String property, Map map1, Map map2,
355 [bool keyEquivalence(a, b) = equality, 375 [bool keyEquivalence(a, b) = equality,
356 bool valueEquivalence(a, b) = equality]) { 376 bool valueEquivalence(a, b) = equality]) {
357 return areMapsEquivalent(map1, map2, keyEquivalence, valueEquivalence); 377 return areMapsEquivalent(map1, map2, keyEquivalence, valueEquivalence);
358 } 378 }
359 379
360 bool testElements(Object object1, Object object2, String property, 380 bool testElements(Object object1, Object object2, String property,
361 Element element1, Element element2) { 381 Entity element1, Entity element2) {
362 return areElementsEquivalent(element1, element2); 382 return test(object1, object2, property, element1, element2,
383 (a, b) => elementEquivalence(a, b, strategy: this));
363 } 384 }
364 385
365 bool testTypes(Object object1, Object object2, String property, 386 bool testTypes(Object object1, Object object2, String property,
366 ResolutionDartType type1, ResolutionDartType type2) { 387 DartType type1, DartType type2) {
367 return areTypesEquivalent(type1, type2); 388 return test(object1, object2, property, type1, type2,
389 (a, b) => typeEquivalence(a, b, strategy: this));
368 } 390 }
369 391
370 bool testConstants(Object object1, Object object2, String property, 392 bool testConstants(Object object1, Object object2, String property,
371 ConstantExpression exp1, ConstantExpression exp2) { 393 ConstantExpression exp1, ConstantExpression exp2) {
372 return areConstantsEquivalent(exp1, exp2); 394 return test(object1, object2, property, exp1, exp2,
395 (a, b) => constantEquivalence(a, b, strategy: this));
373 } 396 }
374 397
375 bool testConstantValues(Object object1, Object object2, String property, 398 bool testConstantValues(Object object1, Object object2, String property,
376 ConstantValue value1, ConstantValue value2) { 399 ConstantValue value1, ConstantValue value2) {
377 return areConstantValuesEquivalent(value1, value2); 400 return test(object1, object2, property, value1, value2,
401 (a, b) => constantValueEquivalence(a, b, strategy: this));
378 } 402 }
379 403
380 bool testTypeLists(Object object1, Object object2, String property, 404 bool testTypeLists(Object object1, Object object2, String property,
381 List<ResolutionDartType> list1, List<ResolutionDartType> list2) { 405 List<DartType> list1, List<DartType> list2) {
382 return areTypeListsEquivalent(list1, list2); 406 return testLists(object1, object2, property, list1, list2,
407 (a, b) => typeEquivalence(a, b, strategy: this));
383 } 408 }
384 409
385 bool testConstantLists(Object object1, Object object2, String property, 410 bool testConstantLists(Object object1, Object object2, String property,
386 List<ConstantExpression> list1, List<ConstantExpression> list2) { 411 List<ConstantExpression> list1, List<ConstantExpression> list2) {
387 return areConstantListsEquivalent(list1, list2); 412 return testLists(object1, object2, property, list1, list2,
413 (a, b) => constantEquivalence(a, b, strategy: this));
388 } 414 }
389 415
390 bool testConstantValueLists(Object object1, Object object2, String property, 416 bool testConstantValueLists(Object object1, Object object2, String property,
391 List<ConstantValue> list1, List<ConstantValue> list2) { 417 List<ConstantValue> list1, List<ConstantValue> list2) {
392 return areConstantValueListsEquivalent(list1, list2); 418 return testLists(object1, object2, property, list1, list2,
419 (a, b) => constantValueEquivalence(a, b, strategy: this));
393 } 420 }
394 421
395 bool testNodes( 422 bool testNodes(
396 Object object1, Object object2, String property, Node node1, Node node2) { 423 Object object1, Object object2, String property, Node node1, Node node2) {
397 return areNodesEquivalent(node1, node2); 424 return areNodesEquivalent(node1, node2);
398 } 425 }
399 } 426 }
400 427
401 /// Visitor that checks for equivalence of [Element]s. 428 /// Visitor that checks for equivalence of [Element]s.
402 class ElementIdentityEquivalence extends BaseElementVisitor<bool, Element> { 429 class ElementIdentityEquivalence extends BaseElementVisitor<bool, Element> {
(...skipping 1645 matching lines...) Expand 10 before | Expand all | Expand 10 after
2048 } 2075 }
2049 2076
2050 bool areMetadataAnnotationsEquivalent( 2077 bool areMetadataAnnotationsEquivalent(
2051 MetadataAnnotation metadata1, MetadataAnnotation metadata2) { 2078 MetadataAnnotation metadata1, MetadataAnnotation metadata2) {
2052 if (metadata1 == metadata2) return true; 2079 if (metadata1 == metadata2) return true;
2053 if (metadata1 == null || metadata2 == null) return false; 2080 if (metadata1 == null || metadata2 == null) return false;
2054 return areElementsEquivalent( 2081 return areElementsEquivalent(
2055 metadata1.annotatedElement, metadata2.annotatedElement) && 2082 metadata1.annotatedElement, metadata2.annotatedElement) &&
2056 areConstantsEquivalent(metadata1.constant, metadata2.constant); 2083 areConstantsEquivalent(metadata1.constant, metadata2.constant);
2057 } 2084 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698