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

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

Issue 1881743004: Add deep equivalence test for Send/NewStructures. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 '../common/resolution.dart'; 9 import '../common/resolution.dart';
10 import '../constants/expressions.dart'; 10 import '../constants/expressions.dart';
11 import '../dart_types.dart'; 11 import '../dart_types.dart';
12 import '../elements/elements.dart'; 12 import '../elements/elements.dart';
13 import '../elements/visitor.dart'; 13 import '../elements/visitor.dart';
14 import '../resolution/access_semantics.dart';
14 import '../resolution/send_structure.dart'; 15 import '../resolution/send_structure.dart';
15 import '../resolution/tree_elements.dart'; 16 import '../resolution/tree_elements.dart';
16 import '../tokens/token.dart'; 17 import '../tokens/token.dart';
17 import '../tree/nodes.dart'; 18 import '../tree/nodes.dart';
18 import '../universe/selector.dart'; 19 import '../universe/selector.dart';
19 import '../universe/use.dart'; 20 import '../universe/use.dart';
20 import 'resolved_ast_serialization.dart'; 21 import 'resolved_ast_serialization.dart';
21 22
22 /// Equality based equivalence function. 23 /// Equality based equivalence function.
23 bool equality(a, b) => a == b; 24 bool equality(a, b) => a == b;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 a.isEmpty == b.isEmpty; 132 a.isEmpty == b.isEmpty;
132 } 133 }
133 134
134 /// Returns `true` if the map literal uses [a] and [b] are equivalent. 135 /// Returns `true` if the map literal uses [a] and [b] are equivalent.
135 bool areMapLiteralUsesEquivalent(MapLiteralUse a, MapLiteralUse b) { 136 bool areMapLiteralUsesEquivalent(MapLiteralUse a, MapLiteralUse b) {
136 return areTypesEquivalent(a.type, b.type) && 137 return areTypesEquivalent(a.type, b.type) &&
137 a.isConstant == b.isConstant && 138 a.isConstant == b.isConstant &&
138 a.isEmpty == b.isEmpty; 139 a.isEmpty == b.isEmpty;
139 } 140 }
140 141
142 /// Returns `true` if the access semantics [a] and [b] are equivalent.
143 bool areAccessSemanticsEquivalent(AccessSemantics a, AccessSemantics b) {
144 if (a.kind != b.kind) return false;
145 switch (a.kind) {
146 case AccessKind.EXPRESSION:
147 case AccessKind.THIS:
148 // No additional properties.
149 return true;
150 case AccessKind.THIS_PROPERTY:
151 case AccessKind.DYNAMIC_PROPERTY:
152 case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
153 return areNamesEquivalent(a.name, b.name);
154 case AccessKind.CLASS_TYPE_LITERAL:
155 case AccessKind.TYPEDEF_TYPE_LITERAL:
156 case AccessKind.DYNAMIC_TYPE_LITERAL:
157 return areConstantsEquivalent(a.constant, b.constant);
158 case AccessKind.LOCAL_FUNCTION:
159 case AccessKind.LOCAL_VARIABLE:
160 case AccessKind.FINAL_LOCAL_VARIABLE:
161 case AccessKind.PARAMETER:
162 case AccessKind.FINAL_PARAMETER:
163 case AccessKind.STATIC_FIELD:
164 case AccessKind.FINAL_STATIC_FIELD:
165 case AccessKind.STATIC_METHOD:
166 case AccessKind.STATIC_GETTER:
167 case AccessKind.STATIC_SETTER:
168 case AccessKind.TOPLEVEL_FIELD:
169 case AccessKind.FINAL_TOPLEVEL_FIELD:
170 case AccessKind.TOPLEVEL_METHOD:
171 case AccessKind.TOPLEVEL_GETTER:
172 case AccessKind.TOPLEVEL_SETTER:
173 case AccessKind.SUPER_FIELD:
174 case AccessKind.SUPER_FINAL_FIELD:
175 case AccessKind.SUPER_METHOD:
176 case AccessKind.SUPER_GETTER:
177 case AccessKind.SUPER_SETTER:
178 case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
179 case AccessKind.UNRESOLVED:
180 case AccessKind.UNRESOLVED_SUPER:
181 case AccessKind.INVALID:
182 return areElementsEquivalent(a.element, b.element);
183 case AccessKind.COMPOUND:
184 CompoundAccessSemantics compoundAccess1 = a;
185 CompoundAccessSemantics compoundAccess2 = b;
186 return compoundAccess1.compoundAccessKind ==
187 compoundAccess2.compoundAccessKind &&
188 areElementsEquivalent(
189 compoundAccess1.getter, compoundAccess2.getter) &&
190 areElementsEquivalent(compoundAccess1.setter, compoundAccess2.setter);
191 case AccessKind.CONSTANT:
192 throw new UnsupportedError('Unsupported access kind: ${a.kind}');
193 }
194 }
195
141 /// Returns `true` if the send structures [a] and [b] are equivalent. 196 /// Returns `true` if the send structures [a] and [b] are equivalent.
142 bool areSendStructuresEquivalent(SendStructure a, SendStructure b) { 197 bool areSendStructuresEquivalent(SendStructure a, SendStructure b) {
143 if (identical(a, b)) return true; 198 if (identical(a, b)) return true;
144 if (a == null || b == null) return false; 199 if (a == null || b == null) return false;
145 if (a.kind != b.kind) return false; 200 if (a.kind != b.kind) return false;
146 // TODO(johnniwinther): Compute a deep equivalence. 201 switch (a.kind) {
147 return true; 202 case SendStructureKind.IF_NULL:
203 case SendStructureKind.LOGICAL_AND:
204 case SendStructureKind.LOGICAL_OR:
205 case SendStructureKind.NOT:
206 case SendStructureKind.INVALID_UNARY:
207 case SendStructureKind.INVALID_BINARY:
208 // No additional properties.
209 return true;
210 case SendStructureKind.IS:
211 IsStructure structure1 = a;
212 IsStructure structure2 = b;
213 return areTypesEquivalent(structure1.type, structure1.type);
214 case SendStructureKind.IS_NOT:
215 IsNotStructure structure1 = a;
216 IsNotStructure structure2 = b;
217 return areTypesEquivalent(structure1.type, structure1.type);
Siggi Cherem (dart-lang) 2016/04/12 17:33:42 consider combining similar cases. No need to add c
Johnni Winther 2016/04/13 07:59:11 Done.
218 case SendStructureKind.AS:
219 AsStructure structure1 = a;
220 AsStructure structure2 = b;
221 return areTypesEquivalent(structure1.type, structure1.type);
222 case SendStructureKind.INVOKE:
223 InvokeStructure structure1 = a;
224 InvokeStructure structure2 = b;
225 return areAccessSemanticsEquivalent(
226 structure1.semantics, structure2.semantics) &&
227 areSelectorsEquivalent(structure1.selector, structure2.selector);
228 case SendStructureKind.INCOMPATIBLE_INVOKE:
229 IncompatibleInvokeStructure structure1 = a;
230 IncompatibleInvokeStructure structure2 = b;
231 return areAccessSemanticsEquivalent(
232 structure1.semantics, structure2.semantics) &&
233 areSelectorsEquivalent(structure1.selector, structure2.selector);
234 case SendStructureKind.GET:
235 GetStructure structure1 = a;
236 GetStructure structure2 = b;
237 return areAccessSemanticsEquivalent(
238 structure1.semantics, structure2.semantics);
239 case SendStructureKind.SET:
240 SetStructure structure1 = a;
241 SetStructure structure2 = b;
242 return areAccessSemanticsEquivalent(
243 structure1.semantics, structure2.semantics);
244 case SendStructureKind.UNARY:
245 UnaryStructure structure1 = a;
246 UnaryStructure structure2 = b;
247 return areAccessSemanticsEquivalent(
248 structure1.semantics, structure2.semantics) &&
249 structure1.operator == structure2.operator;
250 case SendStructureKind.INDEX:
251 IndexStructure structure1 = a;
252 IndexStructure structure2 = b;
253 return areAccessSemanticsEquivalent(
254 structure1.semantics, structure2.semantics);
255 case SendStructureKind.EQUALS:
256 EqualsStructure structure1 = a;
257 EqualsStructure structure2 = b;
258 return areAccessSemanticsEquivalent(
259 structure1.semantics, structure2.semantics);
260 case SendStructureKind.NOT_EQUALS:
261 NotEqualsStructure structure1 = a;
262 NotEqualsStructure structure2 = b;
263 return areAccessSemanticsEquivalent(
264 structure1.semantics, structure2.semantics);
265 case SendStructureKind.BINARY:
266 BinaryStructure structure1 = a;
267 BinaryStructure structure2 = b;
268 return areAccessSemanticsEquivalent(
269 structure1.semantics, structure2.semantics) &&
270 structure1.operator == structure2.operator;
271 case SendStructureKind.INDEX_SET:
272 IndexSetStructure structure1 = a;
273 IndexSetStructure structure2 = b;
274 return areAccessSemanticsEquivalent(
275 structure1.semantics, structure2.semantics);
276 case SendStructureKind.INDEX_PREFIX:
277 IndexPrefixStructure structure1 = a;
278 IndexPrefixStructure structure2 = b;
279 return areAccessSemanticsEquivalent(
280 structure1.semantics, structure2.semantics) &&
281 structure1.operator == structure2.operator;
282 case SendStructureKind.INDEX_POSTFIX:
283 IndexPostfixStructure structure1 = a;
284 IndexPostfixStructure structure2 = b;
285 return areAccessSemanticsEquivalent(
286 structure1.semantics, structure2.semantics) &&
287 structure1.operator == structure2.operator;
288 case SendStructureKind.COMPOUND:
289 CompoundStructure structure1 = a;
290 CompoundStructure structure2 = b;
291 return areAccessSemanticsEquivalent(
292 structure1.semantics, structure2.semantics) &&
293 structure1.operator == structure2.operator;
294 case SendStructureKind.SET_IF_NULL:
295 SetIfNullStructure structure1 = a;
296 SetIfNullStructure structure2 = b;
297 return areAccessSemanticsEquivalent(
298 structure1.semantics, structure2.semantics);
299 case SendStructureKind.COMPOUND_INDEX_SET:
300 CompoundIndexSetStructure structure1 = a;
301 CompoundIndexSetStructure structure2 = b;
302 return areAccessSemanticsEquivalent(
303 structure1.semantics, structure2.semantics) &&
304 structure1.operator == structure2.operator;
305 case SendStructureKind.INDEX_SET_IF_NULL:
306 IndexSetIfNullStructure structure1 = a;
307 IndexSetIfNullStructure structure2 = b;
308 return areAccessSemanticsEquivalent(
309 structure1.semantics, structure2.semantics);
310 case SendStructureKind.PREFIX:
311 PrefixStructure structure1 = a;
312 PrefixStructure structure2 = b;
313 return areAccessSemanticsEquivalent(
314 structure1.semantics, structure2.semantics) &&
315 structure1.operator == structure2.operator;
316 case SendStructureKind.POSTFIX:
317 PostfixStructure structure1 = a;
318 PostfixStructure structure2 = b;
319 return areAccessSemanticsEquivalent(
320 structure1.semantics, structure2.semantics) &&
321 structure1.operator == structure2.operator;
322 case SendStructureKind.DEFERRED_PREFIX:
323 DeferredPrefixStructure structure1 = a;
324 DeferredPrefixStructure structure2 = b;
325 return areElementsEquivalent(structure1.prefix, structure2.prefix) &&
326 areSendStructuresEquivalent(
327 structure1.sendStructure, structure2.sendStructure);
328 }
148 } 329 }
149 330
150 /// Returns `true` if the new structures [a] and [b] are equivalent. 331 /// Returns `true` if the new structures [a] and [b] are equivalent.
151 bool areNewStructuresEquivalent(NewStructure a, NewStructure b) { 332 bool areNewStructuresEquivalent(NewStructure a, NewStructure b) {
152 if (identical(a, b)) return true; 333 if (identical(a, b)) return true;
153 if (a == null || b == null) return false; 334 if (a == null || b == null) return false;
154 if (a.kind != b.kind) return false; 335 if (a.kind != b.kind) return false;
155 // TODO(johnniwinther): Compute a deep equivalence. 336 switch (a.kind) {
156 return true; 337 case NewStructureKind.NEW_INVOKE:
338 NewInvokeStructure structure1 = a;
339 NewInvokeStructure structure2 = b;
340 return structure1.semantics.kind == structure2.semantics.kind &&
341 areElementsEquivalent(
342 structure1.semantics.element, structure2.semantics.element) &&
343 areTypesEquivalent(
344 structure1.semantics.type, structure2.semantics.type) &&
345 areSelectorsEquivalent(structure1.selector, structure2.selector);
346 case NewStructureKind.CONST_INVOKE:
347 ConstInvokeStructure structure1 = a;
348 ConstInvokeStructure structure2 = b;
349 return structure1.constantInvokeKind == structure2.constantInvokeKind &&
350 areConstantsEquivalent(structure1.constant, structure2.constant);
351 case NewStructureKind.LATE_CONST:
352 throw new UnsupportedError('Unsupported NewStructure kind ${a.kind}.');
353 }
157 } 354 }
158 355
159 /// Strategy for testing equivalence. 356 /// Strategy for testing equivalence.
160 /// 357 ///
161 /// Use this strategy to determine equivalence without failing on inequivalence. 358 /// Use this strategy to determine equivalence without failing on inequivalence.
162 class TestStrategy { 359 class TestStrategy {
163 const TestStrategy(); 360 const TestStrategy();
164 361
165 bool test(var object1, var object2, String property, var value1, var value2, 362 bool test(var object1, var object2, String property, var value1, var value2,
166 [bool equivalence(a, b) = equality]) { 363 [bool equivalence(a, b) = equality]) {
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 int index = indices1.nodeIndices[node1]; 995 int index = indices1.nodeIndices[node1];
799 RedirectingFactoryBody node2 = indices2.nodeList[index]; 996 RedirectingFactoryBody node2 = indices2.nodeList[index];
800 success = strategy.testElements( 997 success = strategy.testElements(
801 node1, 998 node1,
802 node2, 999 node2,
803 'getRedirectingTargetConstructor($index)', 1000 'getRedirectingTargetConstructor($index)',
804 elements1.getRedirectingTargetConstructor(node1), 1001 elements1.getRedirectingTargetConstructor(node1),
805 elements2.getRedirectingTargetConstructor(node2)); 1002 elements2.getRedirectingTargetConstructor(node2));
806 } 1003 }
807 } 1004 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698