| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | |
| 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. | |
| 4 | |
| 5 library dart2js.serialization_test; | |
| 6 | |
| 7 import 'dart:io'; | |
| 8 import 'memory_compiler.dart'; | |
| 9 import 'package:async_helper/async_helper.dart'; | |
| 10 import 'package:compiler/src/commandline_options.dart'; | |
| 11 import 'package:compiler/src/common.dart'; | |
| 12 import 'package:compiler/src/constants/constructors.dart'; | |
| 13 import 'package:compiler/src/constants/expressions.dart'; | |
| 14 import 'package:compiler/src/dart_types.dart'; | |
| 15 import 'package:compiler/src/compiler.dart'; | |
| 16 import 'package:compiler/src/diagnostics/invariant.dart'; | |
| 17 import 'package:compiler/src/elements/elements.dart'; | |
| 18 import 'package:compiler/src/elements/visitor.dart'; | |
| 19 import 'package:compiler/src/ordered_typeset.dart'; | |
| 20 import 'package:compiler/src/serialization/element_serialization.dart'; | |
| 21 import 'package:compiler/src/serialization/equivalence.dart'; | |
| 22 import 'package:compiler/src/serialization/json_serializer.dart'; | |
| 23 import 'package:compiler/src/serialization/serialization.dart'; | |
| 24 import 'serialization_test_helper.dart'; | |
| 25 | |
| 26 main(List<String> arguments) { | |
| 27 // Ensure that we can print out constant expressions. | |
| 28 DEBUG_MODE = true; | |
| 29 | |
| 30 Uri entryPoint; | |
| 31 String outPath; | |
| 32 bool prettyPrint = false; | |
| 33 for (String arg in arguments) { | |
| 34 if (arg.startsWith('--')) { | |
| 35 if (arg.startsWith('--out=')) { | |
| 36 outPath = arg.substring('--out='.length); | |
| 37 } else if (arg == '--pretty-print') { | |
| 38 prettyPrint = true; | |
| 39 } else { | |
| 40 print("Unknown option $arg"); | |
| 41 } | |
| 42 } else { | |
| 43 if (entryPoint != null) { | |
| 44 print("Multiple entrypoints is not supported."); | |
| 45 } | |
| 46 entryPoint = Uri.parse(arg); | |
| 47 } | |
| 48 } | |
| 49 if (entryPoint == null) { | |
| 50 entryPoint = Uri.parse('dart:core'); | |
| 51 } | |
| 52 asyncTest(() async { | |
| 53 CompilationResult result = await runCompiler( | |
| 54 entryPoint: entryPoint, options: [Flags.analyzeAll]); | |
| 55 Compiler compiler = result.compiler; | |
| 56 testSerialization(compiler.libraryLoader.libraries, | |
| 57 outPath: outPath, | |
| 58 prettyPrint: prettyPrint); | |
| 59 }); | |
| 60 } | |
| 61 | |
| 62 void testSerialization(Iterable<LibraryElement> libraries1, | |
| 63 {String outPath, | |
| 64 bool prettyPrint}) { | |
| 65 Serializer serializer = new Serializer(); | |
| 66 for (LibraryElement library1 in libraries1) { | |
| 67 serializer.serialize(library1); | |
| 68 } | |
| 69 String text = serializer.toText(const JsonSerializationEncoder()); | |
| 70 String outText = text; | |
| 71 if (prettyPrint) { | |
| 72 outText = serializer.prettyPrint(); | |
| 73 } | |
| 74 if (outPath != null) { | |
| 75 new File(outPath).writeAsStringSync(outText); | |
| 76 } else if (prettyPrint) { | |
| 77 print(outText); | |
| 78 } | |
| 79 | |
| 80 Deserializer deserializer = new Deserializer.fromText( | |
| 81 new DeserializationContext(), | |
| 82 text, const JsonSerializationDecoder()); | |
| 83 List<LibraryElement> libraries2 = <LibraryElement>[]; | |
| 84 for (LibraryElement library1 in libraries1) { | |
| 85 LibraryElement library2 = | |
| 86 deserializer.lookupLibrary(library1.canonicalUri); | |
| 87 if (library2 == null) { | |
| 88 throw new ArgumentError('No library ${library1.canonicalUri} found.'); | |
| 89 } | |
| 90 checkLibraryContent('library1', 'library2', 'library', library1, library2); | |
| 91 libraries2.add(library2); | |
| 92 } | |
| 93 | |
| 94 Serializer serializer2 = new Serializer(); | |
| 95 for (LibraryElement library2 in libraries2) { | |
| 96 serializer2.serialize(library2); | |
| 97 } | |
| 98 String text2 = serializer2.toText(const JsonSerializationEncoder()); | |
| 99 | |
| 100 Deserializer deserializer3 = new Deserializer.fromText( | |
| 101 new DeserializationContext(), | |
| 102 text2, const JsonSerializationDecoder()); | |
| 103 for (LibraryElement library1 in libraries1) { | |
| 104 LibraryElement library2 = | |
| 105 deserializer.lookupLibrary(library1.canonicalUri); | |
| 106 if (library2 == null) { | |
| 107 throw new ArgumentError('No library ${library1.canonicalUri} found.'); | |
| 108 } | |
| 109 LibraryElement library3 = | |
| 110 deserializer3.lookupLibrary(library1.canonicalUri); | |
| 111 if (library3 == null) { | |
| 112 throw new ArgumentError('No library ${library1.canonicalUri} found.'); | |
| 113 } | |
| 114 checkLibraryContent('library1', 'library3', 'library', library1, library3); | |
| 115 checkLibraryContent('library2', 'library3', 'library', library2, library3); | |
| 116 } | |
| 117 } | |
| 118 | |
| 119 /// Check the equivalence of [library1] and [library2] and their content. | |
| 120 /// | |
| 121 /// Uses [object1], [object2] and [property] to provide context for failures. | |
| 122 checkLibraryContent( | |
| 123 Object object1, object2, String property, | |
| 124 LibraryElement library1, LibraryElement library2) { | |
| 125 checkElementProperties(object1, object2, property, library1, library2); | |
| 126 } | |
| 127 | |
| 128 /// Check the equivalence of [element1] and [element2] and their properties. | |
| 129 /// | |
| 130 /// Uses [object1], [object2] and [property] to provide context for failures. | |
| 131 checkElementProperties( | |
| 132 Object object1, object2, String property, | |
| 133 Element element1, Element element2) { | |
| 134 const ElementPropertyEquivalence().visit(element1, element2); | |
| 135 } | |
| 136 | |
| 137 /// Checks the equivalence of [constructor1] and [constructor2]. | |
| 138 void constantConstructorEquivalence(ConstantConstructor constructor1, | |
| 139 ConstantConstructor constructor2) { | |
| 140 const ConstantConstructorEquivalence().visit(constructor1, constructor2); | |
| 141 } | |
| 142 | |
| 143 /// Visitor that checks the equivalence of [ConstantConstructor]s. | |
| 144 class ConstantConstructorEquivalence | |
| 145 extends ConstantConstructorVisitor<dynamic, ConstantConstructor> { | |
| 146 const ConstantConstructorEquivalence(); | |
| 147 | |
| 148 @override | |
| 149 void visit(ConstantConstructor constructor1, | |
| 150 ConstantConstructor constructor2) { | |
| 151 if (identical(constructor1, constructor2)) return; | |
| 152 check(constructor1, constructor2, 'kind', | |
| 153 constructor1.kind, constructor2.kind); | |
| 154 constructor1.accept(this, constructor2); | |
| 155 } | |
| 156 | |
| 157 @override | |
| 158 visitGenerative( | |
| 159 GenerativeConstantConstructor constructor1, | |
| 160 GenerativeConstantConstructor constructor2) { | |
| 161 checkTypes( | |
| 162 constructor1, constructor2, 'type', | |
| 163 constructor1.type, constructor2.type); | |
| 164 check(constructor1, constructor2, 'defaultValues.length', | |
| 165 constructor1.defaultValues.length, | |
| 166 constructor2.defaultValues.length); | |
| 167 constructor1.defaultValues.forEach((k, v) { | |
| 168 checkConstants( | |
| 169 constructor1, constructor2, 'defaultValue[$k]', | |
| 170 v, constructor2.defaultValues[k]); | |
| 171 }); | |
| 172 check(constructor1, constructor2, 'fieldMap.length', | |
| 173 constructor1.fieldMap.length, | |
| 174 constructor2.fieldMap.length); | |
| 175 constructor1.fieldMap.forEach((k1, v1) { | |
| 176 bool matched = false; | |
| 177 constructor2.fieldMap.forEach((k2, v2) { | |
| 178 if (k1.name == k2.name && | |
| 179 k1.library.canonicalUri == k2.library.canonicalUri) { | |
| 180 checkElementIdentities( | |
| 181 constructor1, constructor2, 'fieldMap[${k1.name}].key', k1, k2); | |
| 182 checkConstants( | |
| 183 constructor1, constructor2, 'fieldMap[${k1.name}].value', v1, v2); | |
| 184 matched = true; | |
| 185 } | |
| 186 }); | |
| 187 if (!matched) { | |
| 188 throw 'Unmatched field $k1 = $v1'; | |
| 189 } | |
| 190 }); | |
| 191 checkConstants( | |
| 192 constructor1, constructor2, 'superConstructorInvocation', | |
| 193 constructor1.superConstructorInvocation, | |
| 194 constructor2.superConstructorInvocation); | |
| 195 } | |
| 196 | |
| 197 @override | |
| 198 visitRedirectingFactory( | |
| 199 RedirectingFactoryConstantConstructor constructor1, | |
| 200 RedirectingFactoryConstantConstructor constructor2) { | |
| 201 checkConstants( | |
| 202 constructor1, constructor2, 'targetConstructorInvocation', | |
| 203 constructor1.targetConstructorInvocation, | |
| 204 constructor2.targetConstructorInvocation); | |
| 205 } | |
| 206 | |
| 207 @override | |
| 208 visitRedirectingGenerative( | |
| 209 RedirectingGenerativeConstantConstructor constructor1, | |
| 210 RedirectingGenerativeConstantConstructor constructor2) { | |
| 211 check(constructor1, constructor2, 'defaultValues.length', | |
| 212 constructor1.defaultValues.length, | |
| 213 constructor2.defaultValues.length); | |
| 214 constructor1.defaultValues.forEach((k, v) { | |
| 215 checkConstants( | |
| 216 constructor1, constructor2, 'defaultValue[$k]', | |
| 217 v, constructor2.defaultValues[k]); | |
| 218 }); | |
| 219 checkConstants( | |
| 220 constructor1, constructor2, 'thisConstructorInvocation', | |
| 221 constructor1.thisConstructorInvocation, | |
| 222 constructor2.thisConstructorInvocation); | |
| 223 } | |
| 224 } | |
| 225 | |
| 226 /// Check the equivalence of the two lists of elements, [list1] and [list2]. | |
| 227 /// | |
| 228 /// Uses [object1], [object2] and [property] to provide context for failures. | |
| 229 checkElementLists(Object object1, Object object2, String property, | |
| 230 Iterable<Element> list1, Iterable<Element> list2) { | |
| 231 checkListEquivalence(object1, object2, property, | |
| 232 list1, list2, checkElementProperties); | |
| 233 } | |
| 234 | |
| 235 /// Visitor that checks for equivalence of [Element] properties. | |
| 236 class ElementPropertyEquivalence extends BaseElementVisitor<dynamic, Element> { | |
| 237 const ElementPropertyEquivalence(); | |
| 238 | |
| 239 void visit(Element element1, Element element2) { | |
| 240 if (element1 == null && element2 == null) return; | |
| 241 element1 = element1.declaration; | |
| 242 element2 = element2.declaration; | |
| 243 if (element1 == element2) return; | |
| 244 check(element1, element2, 'kind', element1.kind, element2.kind); | |
| 245 element1.accept(this, element2); | |
| 246 check(element1, element2, 'isSynthesized', | |
| 247 element1.isSynthesized, element2.isSynthesized); | |
| 248 } | |
| 249 | |
| 250 @override | |
| 251 void visitElement(Element e, Element arg) { | |
| 252 throw new UnsupportedError("Unsupported element $e"); | |
| 253 } | |
| 254 | |
| 255 @override | |
| 256 void visitLibraryElement(LibraryElement element1, LibraryElement element2) { | |
| 257 checkElementIdentities(null, null, null, element1, element2); | |
| 258 check(element1, element2, 'name', element1.name, element2.name); | |
| 259 check(element1, element2, 'libraryName', | |
| 260 element1.libraryName, element2.libraryName); | |
| 261 visitMembers(element1, element2); | |
| 262 visit(element1.entryCompilationUnit, element2.entryCompilationUnit); | |
| 263 | |
| 264 checkElementLists( | |
| 265 element1, element2, 'compilationUnits', | |
| 266 LibrarySerializer.getCompilationUnits(element1), | |
| 267 LibrarySerializer.getCompilationUnits(element2)); | |
| 268 | |
| 269 checkElementListIdentities( | |
| 270 element1, element2, 'imports', | |
| 271 LibrarySerializer.getImports(element1), | |
| 272 LibrarySerializer.getImports(element2)); | |
| 273 checkElementListIdentities( | |
| 274 element1, element2, 'exports', element1.exports, element2.exports); | |
| 275 | |
| 276 checkElementListIdentities( | |
| 277 element1, element2, 'importScope', | |
| 278 LibrarySerializer.getImportedElements(element1), | |
| 279 LibrarySerializer.getImportedElements(element2)); | |
| 280 | |
| 281 checkElementListIdentities( | |
| 282 element1, element2, 'exportScope', | |
| 283 LibrarySerializer.getExportedElements(element1), | |
| 284 LibrarySerializer.getExportedElements(element2)); | |
| 285 } | |
| 286 | |
| 287 @override | |
| 288 void visitCompilationUnitElement(CompilationUnitElement element1, | |
| 289 CompilationUnitElement element2) { | |
| 290 check(element1, element2, | |
| 291 'name', | |
| 292 element1.name, element2.name); | |
| 293 checkElementIdentities( | |
| 294 element1, element2, 'library', | |
| 295 element1.library, element2.library); | |
| 296 check(element1, element2, | |
| 297 'script.resourceUri', | |
| 298 element1.script.resourceUri, element2.script.resourceUri); | |
| 299 List<Element> members1 = <Element>[]; | |
| 300 List<Element> members2 = <Element>[]; | |
| 301 element1.forEachLocalMember((Element member) { | |
| 302 members1.add(member); | |
| 303 }); | |
| 304 element2.forEachLocalMember((Element member) { | |
| 305 members2.add(member); | |
| 306 }); | |
| 307 checkElementListIdentities( | |
| 308 element1, element2, 'localMembers', members1, members2); | |
| 309 } | |
| 310 | |
| 311 void visitMembers(ScopeContainerElement element1, | |
| 312 ScopeContainerElement element2) { | |
| 313 Set<String> names = new Set<String>(); | |
| 314 Iterable<Element> members1 = element1.isLibrary | |
| 315 ? LibrarySerializer.getMembers(element1) | |
| 316 : ClassSerializer.getMembers(element1); | |
| 317 Iterable<Element> members2 = element2.isLibrary | |
| 318 ? LibrarySerializer.getMembers(element2) | |
| 319 : ClassSerializer.getMembers(element2); | |
| 320 for (Element member in members1) { | |
| 321 names.add(member.name); | |
| 322 } | |
| 323 for (Element member in members2) { | |
| 324 names.add(member.name); | |
| 325 } | |
| 326 element1 = element1.implementation; | |
| 327 element2 = element2.implementation; | |
| 328 for (String name in names) { | |
| 329 Element member1 = element1.localLookup(name); | |
| 330 Element member2 = element2.localLookup(name); | |
| 331 if (member1 == null) { | |
| 332 String message = | |
| 333 'Missing member for $member2 in\n ${members1.join('\n ')}'; | |
| 334 if (member2.isAbstractField) { | |
| 335 // TODO(johnniwinther): Ensure abstract fields are handled correctly. | |
| 336 //print(message); | |
| 337 continue; | |
| 338 } else { | |
| 339 throw message; | |
| 340 } | |
| 341 } | |
| 342 if (member2 == null) { | |
| 343 String message = | |
| 344 'Missing member for $member1 in\n ${members2.join('\n ')}'; | |
| 345 if (member1.isAbstractField) { | |
| 346 // TODO(johnniwinther): Ensure abstract fields are handled correctly. | |
| 347 //print(message); | |
| 348 continue; | |
| 349 } else { | |
| 350 throw message; | |
| 351 } | |
| 352 } | |
| 353 visit(member1, member2); | |
| 354 } | |
| 355 } | |
| 356 | |
| 357 @override | |
| 358 void visitClassElement(ClassElement element1, ClassElement element2) { | |
| 359 checkElementIdentities(null, null, null, element1, element2); | |
| 360 check(element1, element2, 'name', | |
| 361 element1.name, element2.name); | |
| 362 check(element1, element2, 'sourcePosition', | |
| 363 element1.sourcePosition, element2.sourcePosition); | |
| 364 checkElementIdentities( | |
| 365 element1, element2, 'library', | |
| 366 element1.library, element2.library); | |
| 367 checkElementIdentities( | |
| 368 element1, element2, 'compilationUnit', | |
| 369 element1.compilationUnit, element2.compilationUnit); | |
| 370 check(element1, element2, 'isObject', | |
| 371 element1.isObject, element2.isObject); | |
| 372 checkTypeLists(element1, element2, 'typeVariables', | |
| 373 element1.typeVariables, element2.typeVariables); | |
| 374 check(element1, element2, 'isAbstract', | |
| 375 element1.isAbstract, element2.isAbstract); | |
| 376 check(element1, element2, 'isUnnamedMixinApplication', | |
| 377 element1.isUnnamedMixinApplication, element2.isUnnamedMixinApplication); | |
| 378 check(element1, element2, 'isEnumClass', | |
| 379 element1.isEnumClass, element2.isEnumClass); | |
| 380 if (element1.isEnumClass) { | |
| 381 EnumClassElement enum1 = element1; | |
| 382 EnumClassElement enum2 = element2; | |
| 383 checkElementLists(enum1, enum2, 'enumValues', | |
| 384 enum1.enumValues, enum2.enumValues); | |
| 385 } | |
| 386 if (!element1.isObject) { | |
| 387 checkTypes(element1, element2, 'supertype', | |
| 388 element1.supertype, element2.supertype); | |
| 389 } | |
| 390 check(element1, element2, 'hierarchyDepth', | |
| 391 element1.hierarchyDepth, element2.hierarchyDepth); | |
| 392 checkTypeLists( | |
| 393 element1, element2, 'allSupertypes', | |
| 394 element1.allSupertypes.toList(), | |
| 395 element2.allSupertypes.toList()); | |
| 396 OrderedTypeSet typeSet1 = element1.allSupertypesAndSelf; | |
| 397 OrderedTypeSet typeSet2 = element1.allSupertypesAndSelf; | |
| 398 checkListEquivalence( | |
| 399 element1, element2, 'allSupertypes', | |
| 400 typeSet1.levelOffsets, | |
| 401 typeSet2.levelOffsets, | |
| 402 check); | |
| 403 check(element1, element2, 'allSupertypesAndSelf.levels', | |
| 404 typeSet1.levels, typeSet2.levels); | |
| 405 checkTypeLists( | |
| 406 element1, element2, 'supertypes', | |
| 407 typeSet1.supertypes.toList(), | |
| 408 typeSet2.supertypes.toList()); | |
| 409 checkTypeLists( | |
| 410 element1, element2, 'types', | |
| 411 typeSet1.types.toList(), | |
| 412 typeSet2.types.toList()); | |
| 413 | |
| 414 checkTypeLists( | |
| 415 element1, element2, 'interfaces', | |
| 416 element1.interfaces.toList(), | |
| 417 element2.interfaces.toList()); | |
| 418 | |
| 419 List<ConstructorElement> getConstructors(ClassElement cls) { | |
| 420 return cls.implementation.constructors.map((c) => c.declaration).toList(); | |
| 421 } | |
| 422 | |
| 423 checkElementLists( | |
| 424 element1, element2, 'constructors', | |
| 425 getConstructors(element1), | |
| 426 getConstructors(element2)); | |
| 427 | |
| 428 visitMembers(element1, element2); | |
| 429 } | |
| 430 | |
| 431 @override | |
| 432 void visitFieldElement(FieldElement element1, FieldElement element2) { | |
| 433 checkElementIdentities(null, null, null, element1, element2); | |
| 434 check(element1, element2, 'name', | |
| 435 element1.name, element2.name); | |
| 436 check(element1, element2, 'sourcePosition', | |
| 437 element1.sourcePosition, element2.sourcePosition); | |
| 438 checkTypes( | |
| 439 element1, element2, 'type', | |
| 440 element1.type, element2.type); | |
| 441 check(element1, element2, 'isConst', | |
| 442 element1.isConst, element2.isConst); | |
| 443 check(element1, element2, 'isFinal', | |
| 444 element1.isFinal, element2.isFinal); | |
| 445 checkConstants( | |
| 446 element1, element2, 'constant', | |
| 447 element1.constant, element2.constant); | |
| 448 check(element1, element2, 'isTopLevel', | |
| 449 element1.isTopLevel, element2.isTopLevel); | |
| 450 check(element1, element2, 'isStatic', | |
| 451 element1.isStatic, element2.isStatic); | |
| 452 check(element1, element2, 'isInstanceMember', | |
| 453 element1.isInstanceMember, element2.isInstanceMember); | |
| 454 | |
| 455 checkElementIdentities( | |
| 456 element1, element2, 'library', | |
| 457 element1.library, element2.library); | |
| 458 checkElementIdentities( | |
| 459 element1, element2, 'compilationUnit', | |
| 460 element1.compilationUnit, element2.compilationUnit); | |
| 461 checkElementIdentities( | |
| 462 element1, element2, 'enclosingClass', | |
| 463 element1.enclosingClass, element2.enclosingClass); | |
| 464 } | |
| 465 | |
| 466 @override | |
| 467 void visitFunctionElement(FunctionElement element1, | |
| 468 FunctionElement element2) { | |
| 469 checkElementIdentities(null, null, null, element1, element2); | |
| 470 check(element1, element2, 'name', | |
| 471 element1.name, element2.name); | |
| 472 check(element1, element2, 'sourcePosition', | |
| 473 element1.sourcePosition, element2.sourcePosition); | |
| 474 checkTypes( | |
| 475 element1, element2, 'type', | |
| 476 element1.type, element2.type); | |
| 477 checkListEquivalence( | |
| 478 element1, element2, 'parameters', | |
| 479 element1.parameters, element2.parameters, | |
| 480 checkElementProperties); | |
| 481 check(element1, element2, 'isOperator', | |
| 482 element1.isOperator, element2.isOperator); | |
| 483 check( | |
| 484 element1, element2, 'asyncMarker', | |
| 485 element1.asyncMarker, | |
| 486 element2.asyncMarker); | |
| 487 | |
| 488 checkElementIdentities( | |
| 489 element1, element2, 'library', | |
| 490 element1.library, element2.library); | |
| 491 checkElementIdentities( | |
| 492 element1, element2, 'compilationUnit', | |
| 493 element1.compilationUnit, element2.compilationUnit); | |
| 494 checkElementIdentities( | |
| 495 element1, element2, 'enclosingClass', | |
| 496 element1.enclosingClass, element2.enclosingClass); | |
| 497 | |
| 498 check( | |
| 499 element1, element2, 'functionSignature.type', | |
| 500 element1.functionSignature.type, | |
| 501 element2.functionSignature.type, | |
| 502 areTypesEquivalent); | |
| 503 checkElementLists( | |
| 504 element1, element2, 'functionSignature.requiredParameters', | |
| 505 element1.functionSignature.requiredParameters, | |
| 506 element2.functionSignature.requiredParameters); | |
| 507 checkElementLists( | |
| 508 element1, element2, 'functionSignature.optionalParameters', | |
| 509 element1.functionSignature.optionalParameters, | |
| 510 element2.functionSignature.optionalParameters); | |
| 511 check( | |
| 512 element1, element2, 'functionSignature.requiredParameterCount', | |
| 513 element1.functionSignature.requiredParameterCount, | |
| 514 element2.functionSignature.requiredParameterCount); | |
| 515 check( | |
| 516 element1, element2, 'functionSignature.optionalParameterCount', | |
| 517 element1.functionSignature.optionalParameterCount, | |
| 518 element2.functionSignature.optionalParameterCount); | |
| 519 check( | |
| 520 element1, element2, 'functionSignature.optionalParametersAreNamed', | |
| 521 element1.functionSignature.optionalParametersAreNamed, | |
| 522 element2.functionSignature.optionalParametersAreNamed); | |
| 523 check( | |
| 524 element1, element2, 'functionSignature.hasOptionalParameters', | |
| 525 element1.functionSignature.hasOptionalParameters, | |
| 526 element2.functionSignature.hasOptionalParameters); | |
| 527 check( | |
| 528 element1, element2, 'functionSignature.parameterCount', | |
| 529 element1.functionSignature.parameterCount, | |
| 530 element2.functionSignature.parameterCount); | |
| 531 checkElementLists( | |
| 532 element1, element2, 'functionSignature.orderedOptionalParameters', | |
| 533 element1.functionSignature.orderedOptionalParameters, | |
| 534 element2.functionSignature.orderedOptionalParameters); | |
| 535 } | |
| 536 | |
| 537 @override | |
| 538 void visitConstructorElement(ConstructorElement element1, | |
| 539 ConstructorElement element2) { | |
| 540 checkElementIdentities(null, null, null, element1, element2); | |
| 541 checkElementIdentities( | |
| 542 element1, element2, 'enclosingClass', | |
| 543 element1.enclosingClass, element2.enclosingClass); | |
| 544 check( | |
| 545 element1, element2, 'name', | |
| 546 element1.name, element2.name); | |
| 547 check(element1, element2, 'sourcePosition', | |
| 548 element1.sourcePosition, element2.sourcePosition); | |
| 549 checkListEquivalence( | |
| 550 element1, element2, 'parameters', | |
| 551 element1.parameters, element2.parameters, | |
| 552 checkElementProperties); | |
| 553 checkTypes( | |
| 554 element1, element2, 'type', | |
| 555 element1.type, element2.type); | |
| 556 check(element1, element2, 'isConst', | |
| 557 element1.isConst, element2.isConst); | |
| 558 check(element1, element2, 'isExternal', | |
| 559 element1.isExternal, element2.isExternal); | |
| 560 if (element1.isConst && !element1.isExternal) { | |
| 561 constantConstructorEquivalence( | |
| 562 element1.constantConstructor, | |
| 563 element2.constantConstructor); | |
| 564 } | |
| 565 check(element1, element2, 'isRedirectingGenerative', | |
| 566 element1.isRedirectingGenerative, element2.isRedirectingGenerative); | |
| 567 check(element1, element2, 'isRedirectingFactory', | |
| 568 element1.isRedirectingFactory, element2.isRedirectingFactory); | |
| 569 checkElementIdentities(element1, element2, 'effectiveTarget', | |
| 570 element1.effectiveTarget, element2.effectiveTarget); | |
| 571 checkElementIdentities(element1, element2, 'definingConstructor', | |
| 572 element1.definingConstructor, element2.definingConstructor); | |
| 573 check( | |
| 574 element1, element2, 'effectiveTargetType', | |
| 575 element1.computeEffectiveTargetType(element1.enclosingClass.thisType), | |
| 576 element2.computeEffectiveTargetType(element2.enclosingClass.thisType), | |
| 577 areTypesEquivalent); | |
| 578 checkElementIdentities(element1, element2, 'immediateRedirectionTarget', | |
| 579 element1.immediateRedirectionTarget, | |
| 580 element2.immediateRedirectionTarget); | |
| 581 checkElementIdentities(element1, element2, 'redirectionDeferredPrefix', | |
| 582 element1.redirectionDeferredPrefix, element2.redirectionDeferredPrefix); | |
| 583 } | |
| 584 | |
| 585 @override | |
| 586 void visitAbstractFieldElement(AbstractFieldElement element1, | |
| 587 AbstractFieldElement element2) { | |
| 588 visit(element1.getter, element2.getter); | |
| 589 visit(element1.setter, element2.setter); | |
| 590 } | |
| 591 | |
| 592 @override | |
| 593 void visitTypeVariableElement(TypeVariableElement element1, | |
| 594 TypeVariableElement element2) { | |
| 595 checkElementIdentities(null, null, null, element1, element2); | |
| 596 check(element1, element2, 'name', element1.name, element2.name); | |
| 597 check(element1, element2, 'sourcePosition', | |
| 598 element1.sourcePosition, element2.sourcePosition); | |
| 599 check(element1, element2, 'index', element1.index, element2.index); | |
| 600 checkTypes( | |
| 601 element1, element2, 'type', | |
| 602 element1.type, element2.type); | |
| 603 checkTypes( | |
| 604 element1, element2, 'bound', | |
| 605 element1.bound, element2.bound); | |
| 606 } | |
| 607 | |
| 608 @override | |
| 609 void visitTypedefElement(TypedefElement element1, | |
| 610 TypedefElement element2) { | |
| 611 checkElementIdentities(null, null, null, element1, element2); | |
| 612 check(element1, element2, 'name', element1.name, element2.name); | |
| 613 check(element1, element2, 'sourcePosition', | |
| 614 element1.sourcePosition, element2.sourcePosition); | |
| 615 checkTypes( | |
| 616 element1, element2, 'alias', | |
| 617 element1.alias, element2.alias); | |
| 618 checkTypeLists( | |
| 619 element1, element2, 'typeVariables', | |
| 620 element1.typeVariables, element2.typeVariables); | |
| 621 checkElementIdentities( | |
| 622 element1, element2, 'library', | |
| 623 element1.library, element2.library); | |
| 624 checkElementIdentities( | |
| 625 element1, element2, 'compilationUnit', | |
| 626 element1.compilationUnit, element2.compilationUnit); | |
| 627 // TODO(johnniwinther): Check the equivalence of typedef parameters. | |
| 628 } | |
| 629 | |
| 630 @override | |
| 631 void visitParameterElement(ParameterElement element1, | |
| 632 ParameterElement element2) { | |
| 633 checkElementIdentities(null, null, null, element1, element2); | |
| 634 checkElementIdentities( | |
| 635 element1, element2, 'functionDeclaration', | |
| 636 element1.functionDeclaration, element2.functionDeclaration); | |
| 637 check(element1, element2, 'name', element1.name, element2.name); | |
| 638 check(element1, element2, 'sourcePosition', | |
| 639 element1.sourcePosition, element2.sourcePosition); | |
| 640 checkTypes( | |
| 641 element1, element2, 'type', | |
| 642 element1.type, element2.type); | |
| 643 check( | |
| 644 element1, element2, 'isOptional', | |
| 645 element1.isOptional, element2.isOptional); | |
| 646 check( | |
| 647 element1, element2, 'isNamed', | |
| 648 element1.isNamed, element2.isNamed); | |
| 649 check( | |
| 650 element1, element2, 'isFinal', | |
| 651 element1.isFinal, element2.isFinal); | |
| 652 check(element1, element2, 'name', element1.name, element2.name); | |
| 653 if (element1.isOptional) { | |
| 654 checkConstants( | |
| 655 element1, element2, 'constant', | |
| 656 element1.constant, element2.constant); | |
| 657 } | |
| 658 checkElementIdentities( | |
| 659 element1, element2, 'compilationUnit', | |
| 660 element1.compilationUnit, element2.compilationUnit); | |
| 661 } | |
| 662 | |
| 663 @override | |
| 664 void visitFieldParameterElement(InitializingFormalElement element1, | |
| 665 InitializingFormalElement element2) { | |
| 666 visitParameterElement(element1, element2); | |
| 667 checkElementIdentities( | |
| 668 element1, element2, 'fieldElement', | |
| 669 element1.fieldElement, element2.fieldElement); | |
| 670 } | |
| 671 | |
| 672 @override | |
| 673 void visitImportElement(ImportElement element1, ImportElement element2) { | |
| 674 check(element1, element2, 'uri', element1.uri, element2.uri); | |
| 675 check( | |
| 676 element1, element2, 'isDeferred', | |
| 677 element1.isDeferred, element2.isDeferred); | |
| 678 checkElementProperties( | |
| 679 element1, element2, 'prefix', | |
| 680 element1.prefix, element2.prefix); | |
| 681 checkElementIdentities( | |
| 682 element1, element2, 'importedLibrary', | |
| 683 element1.importedLibrary, element2.importedLibrary); | |
| 684 } | |
| 685 | |
| 686 @override | |
| 687 void visitExportElement(ExportElement element1, ExportElement element2) { | |
| 688 check(element1, element2, 'uri', element1.uri, element2.uri); | |
| 689 checkElementIdentities( | |
| 690 element1, element2, 'importedLibrary', | |
| 691 element1.exportedLibrary, element2.exportedLibrary); | |
| 692 } | |
| 693 | |
| 694 @override | |
| 695 void visitPrefixElement(PrefixElement element1, PrefixElement element2) { | |
| 696 check( | |
| 697 element1, element2, 'isDeferred', | |
| 698 element1.isDeferred, element2.isDeferred); | |
| 699 checkElementIdentities( | |
| 700 element1, element2, 'importedLibrary', | |
| 701 element1.deferredImport, element2.deferredImport); | |
| 702 // TODO(johnniwinther): Check members. | |
| 703 } | |
| 704 } | |
| OLD | NEW |