OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library dart2js.serialization.class_members_test; |
| 6 |
| 7 import 'dart:async'; |
| 8 import 'package:async_helper/async_helper.dart'; |
| 9 import 'package:compiler/src/common/names.dart'; |
| 10 import 'package:compiler/src/commandline_options.dart'; |
| 11 import 'package:compiler/src/compiler.dart'; |
| 12 import 'package:compiler/src/elements/elements.dart'; |
| 13 import 'package:compiler/src/filenames.dart'; |
| 14 import 'package:compiler/src/resolution/class_members.dart'; |
| 15 import 'package:compiler/src/serialization/equivalence.dart'; |
| 16 import '../memory_compiler.dart'; |
| 17 import 'helper.dart'; |
| 18 import 'test_helper.dart'; |
| 19 |
| 20 |
| 21 main(List<String> args) { |
| 22 Arguments arguments = new Arguments.from(args); |
| 23 asyncTest(() async { |
| 24 SerializedData serializedData = |
| 25 await serializeDartCore(arguments: arguments); |
| 26 if (arguments.filename != null) { |
| 27 Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename)); |
| 28 await checkClassMembers( |
| 29 serializedData, entryPoint, verbose: arguments.verbose); |
| 30 } else { |
| 31 await checkClassMembers( |
| 32 serializedData, Uris.dart_core, verbose: arguments.verbose); |
| 33 } |
| 34 }); |
| 35 } |
| 36 |
| 37 Future checkClassMembers( |
| 38 SerializedData serializedData, |
| 39 Uri entryPoint, |
| 40 {bool verbose: false}) async { |
| 41 |
| 42 Compiler compilerNormal = compilerFor( |
| 43 options: [Flags.analyzeAll]); |
| 44 await compilerNormal.run(entryPoint); |
| 45 |
| 46 Compiler compilerDeserialized = compilerFor( |
| 47 memorySourceFiles: serializedData.toMemorySourceFiles(), |
| 48 resolutionInputs: serializedData.toUris(), |
| 49 options: [Flags.analyzeAll]); |
| 50 await compilerDeserialized.run(entryPoint); |
| 51 |
| 52 checkAllMembers(compilerNormal, compilerDeserialized, verbose: true); |
| 53 } |
| 54 |
| 55 void checkAllMembers( |
| 56 Compiler compiler1, |
| 57 Compiler compiler2, |
| 58 {bool verbose: false}) { |
| 59 checkLoadedLibraryMembers( |
| 60 compiler1, |
| 61 compiler2, |
| 62 (Element member1) => member1 is ClassElement, |
| 63 checkMembers, |
| 64 verbose: verbose); |
| 65 } |
| 66 |
| 67 |
| 68 /// Check equivalence of members of [class1] and [class2]. |
| 69 void checkMembers( |
| 70 Compiler compiler1, ClassMemberMixin class1, |
| 71 Compiler compiler2, ClassMemberMixin class2, |
| 72 {bool verbose: false}) { |
| 73 if (verbose) { |
| 74 print('Checking $class1 vs $class2'); |
| 75 } |
| 76 MembersCreator.computeAllClassMembers(compiler1.resolution, class1); |
| 77 MembersCreator.computeAllClassMembers(compiler2.resolution, class2); |
| 78 |
| 79 check(class1, class2, 'interfaceMemberAreClassMembers', |
| 80 class1.interfaceMembersAreClassMembers, |
| 81 class2.interfaceMembersAreClassMembers); |
| 82 class1.forEachClassMember((Member member1) { |
| 83 Name name1 = member1.name; |
| 84 Name name2 = convertName(name1, compiler2); |
| 85 checkMember(class1, class2, 'classMember:$name1', |
| 86 member1, class2.lookupClassMember(name2)); |
| 87 }); |
| 88 |
| 89 class1.forEachInterfaceMember((MemberSignature member1) { |
| 90 Name name1 = member1.name; |
| 91 Name name2 = convertName(name1, compiler2); |
| 92 checkMemberSignature(class1, class2, 'interfaceMember:$name1', |
| 93 member1, class2.lookupInterfaceMember(name2)); |
| 94 }); |
| 95 } |
| 96 |
| 97 Name convertName(Name name, Compiler compiler) { |
| 98 if (name.isPrivate) { |
| 99 LibraryElement library = |
| 100 compiler.libraryLoader.lookupLibrary(name.library.canonicalUri); |
| 101 if (!areElementsEquivalent(name.library, library)) { |
| 102 throw 'Libraries ${name.library} and ${library} are not equivalent'; |
| 103 } |
| 104 name = new Name(name.text, library, isSetter: name.isSetter); |
| 105 } |
| 106 return name; |
| 107 } |
| 108 |
| 109 void checkMember(ClassElement class1, ClassElement class2, String property, |
| 110 Member member1, Member member2) { |
| 111 if (member2 == null) { |
| 112 print('$class1 class members:'); |
| 113 class1.forEachClassMember((m) => print(' ${m.name} $m')); |
| 114 print('$class2 class members:'); |
| 115 class2.forEachClassMember((m) => print(' ${m.name} $m')); |
| 116 throw "No member ${member1.name} in $class2 for $property"; |
| 117 } |
| 118 checkMemberSignature(class1, class2, property, member1, member2); |
| 119 checkElementIdentities(class1, class2, '$property.element', |
| 120 member1.element, member2.element); |
| 121 check(class1, class2, '$property.declarer', |
| 122 member1.declarer, member2.declarer, areTypesEquivalent); |
| 123 check(class1, class2, '$property.isStatic', |
| 124 member1.isStatic, member2.isStatic); |
| 125 check(class1, class2, '$property.isDeclaredByField', |
| 126 member1.isDeclaredByField, member2.isDeclaredByField); |
| 127 check(class1, class2, '$property.isAbstract', |
| 128 member1.isAbstract, member2.isAbstract); |
| 129 if (member1.isAbstract && member1.implementation != null) { |
| 130 checkMember(class1, class2, '$property.implementation', |
| 131 member1.implementation, member2.implementation); |
| 132 } |
| 133 } |
| 134 |
| 135 void checkMemberSignature(ClassElement class1, ClassElement class2, |
| 136 String property, |
| 137 MemberSignature member1, MemberSignature member2) { |
| 138 if (member2 == null) { |
| 139 print('$class1 interface members:'); |
| 140 class1.forEachInterfaceMember((m) => print(' ${m.name} $m')); |
| 141 print('$class2 interface members:'); |
| 142 class2.forEachInterfaceMember((m) => print(' ${m.name} $m')); |
| 143 throw "No member ${member1.name} in $class2 for $property"; |
| 144 } |
| 145 check(class1, class2, '$property.name', |
| 146 member1.name, member2.name, areNamesEquivalent); |
| 147 check(class1, class2, '$property.type', |
| 148 member1.type, member2.type, areTypesEquivalent); |
| 149 check(class1, class2, '$property.functionType', |
| 150 member1.functionType, member2.functionType, areTypesEquivalent); |
| 151 check(class1, class2, '$property.isGetter', |
| 152 member1.isGetter, member2.isGetter); |
| 153 check(class1, class2, '$property.isSetter', |
| 154 member1.isSetter, member2.isSetter); |
| 155 check(class1, class2, '$property.isMethod', |
| 156 member1.isMethod, member2.isMethod); |
| 157 } |
OLD | NEW |