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