OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import 'dart:io'; | 5 import 'dart:io'; |
6 import 'package:async_helper/async_helper.dart'; | 6 import 'package:async_helper/async_helper.dart'; |
7 import 'package:compiler/src/commandline_options.dart'; | 7 import 'package:compiler/src/commandline_options.dart'; |
8 import 'package:compiler/src/common.dart'; | 8 import 'package:compiler/src/common.dart'; |
9 import 'package:compiler/src/compiler.dart'; | 9 import 'package:compiler/src/compiler.dart'; |
10 import 'package:compiler/src/diagnostics/diagnostic_listener.dart'; | 10 import 'package:compiler/src/diagnostics/diagnostic_listener.dart'; |
11 import 'package:compiler/src/elements/elements.dart'; | 11 import 'package:compiler/src/elements/elements.dart'; |
12 import 'package:compiler/src/elements/entities.dart'; | 12 import 'package:compiler/src/elements/entities.dart'; |
13 import 'package:compiler/src/kernel/element_map.dart'; | 13 import 'package:compiler/src/kernel/element_map.dart'; |
14 import 'package:compiler/src/kernel/kernel_backend_strategy.dart'; | 14 import 'package:compiler/src/kernel/kernel_backend_strategy.dart'; |
15 import 'package:compiler/src/resolution/access_semantics.dart'; | 15 import 'package:compiler/src/resolution/access_semantics.dart'; |
16 import 'package:compiler/src/resolution/send_structure.dart'; | 16 import 'package:compiler/src/resolution/send_structure.dart'; |
17 import 'package:compiler/src/tree/nodes.dart' as ast; | 17 import 'package:compiler/src/tree/nodes.dart' as ast; |
18 import 'package:expect/expect.dart'; | 18 import 'package:expect/expect.dart'; |
19 import 'package:kernel/ast.dart' as ir; | 19 import 'package:kernel/ast.dart' as ir; |
20 import '../equivalence/id_equivalence.dart'; | 20 import '../equivalence/id_equivalence.dart'; |
21 import '../equivalence/id_equivalence_helper.dart'; | 21 import '../equivalence/id_equivalence_helper.dart'; |
22 | 22 |
23 const List<String> dataDirectories = const <String>[ | 23 const List<String> dataDirectories = const <String>[ |
24 '../closure/data', | 24 '../closure/data', |
25 '../inference/data', | 25 '../inference/data', |
26 '../jumps/data', | 26 '../jumps/data', |
27 ]; | 27 ]; |
28 | 28 |
29 main() { | 29 main(List<String> args) { |
30 asyncTest(() async { | 30 asyncTest(() async { |
31 for (String path in dataDirectories) { | 31 for (String path in dataDirectories) { |
32 Directory dataDir = new Directory.fromUri(Platform.script.resolve(path)); | 32 Directory dataDir = new Directory.fromUri(Platform.script.resolve(path)); |
33 await for (FileSystemEntity entity in dataDir.list()) { | 33 await for (FileSystemEntity entity in dataDir.list()) { |
| 34 if (args.isNotEmpty && !args.contains(entity.uri.pathSegments.last)) { |
| 35 continue; |
| 36 } |
34 print('Checking ${entity.uri}'); | 37 print('Checking ${entity.uri}'); |
35 String annotatedCode = | 38 String annotatedCode = |
36 await new File.fromUri(entity.uri).readAsString(); | 39 await new File.fromUri(entity.uri).readAsString(); |
37 IdData data1 = await computeData( | 40 IdData data1 = await computeData( |
38 annotatedCode, computeAstMemberData, compileFromSource, | 41 annotatedCode, computeAstMemberData, compileFromSource, |
39 options: [Flags.disableTypeInference]); | 42 options: [Flags.disableTypeInference]); |
40 IdData data2 = await computeData( | 43 IdData data2 = await computeData( |
41 annotatedCode, computeIrMemberData, compileFromDill, | 44 annotatedCode, computeIrMemberData, compileFromDill, |
42 options: [Flags.disableTypeInference]); | 45 options: [Flags.disableTypeInference]); |
43 data1.actualMap.forEach((Id id, ActualData actualData1) { | 46 data1.actualMap.forEach((Id id, ActualData actualData1) { |
44 String value1 = actualData1.value; | 47 IdValue value1 = actualData1.value; |
45 String value2 = data2.actualMap[id]?.value; | 48 IdValue value2 = data2.actualMap[id]?.value; |
46 if (value1 != value2) { | 49 if (value1 != value2) { |
47 reportHere(data1.compiler.reporter, actualData1.sourceSpan, | 50 reportHere(data1.compiler.reporter, actualData1.sourceSpan, |
48 '$id: from source:${value1},from dill:${value2}'); | 51 '$id: from source:${value1},from dill:${value2}'); |
49 print('--annotations diff----------------------------------------'); | 52 print('--annotations diff----------------------------------------'); |
50 print(data1.computeDiffCodeFor(data2)); | 53 print(data1.computeDiffCodeFor(data2)); |
51 print('----------------------------------------------------------'); | 54 print('----------------------------------------------------------'); |
52 } | 55 } |
53 Expect.equals(value1, value2, 'Value mismatch for $id'); | 56 Expect.equals(value1, value2, 'Value mismatch for $id'); |
54 }); | 57 }); |
55 data2.actualMap.forEach((Id id, ActualData actualData2) { | 58 data2.actualMap.forEach((Id id, ActualData actualData2) { |
56 String value2 = actualData2.value; | 59 IdValue value2 = actualData2.value; |
57 String value1 = data1.actualMap[id]?.value; | 60 IdValue value1 = data1.actualMap[id]?.value; |
58 if (value1 != value2) { | 61 if (value1 != value2) { |
59 reportHere(data2.compiler.reporter, actualData2.sourceSpan, | 62 reportHere(data2.compiler.reporter, actualData2.sourceSpan, |
60 '$id: from source:${value1},from dill:${value2}'); | 63 '$id: from source:${value1},from dill:${value2}'); |
61 print('--annotations diff----------------------------------------'); | 64 print('--annotations diff----------------------------------------'); |
62 print(data1.computeDiffCodeFor(data2)); | 65 print(data1.computeDiffCodeFor(data2)); |
63 print('----------------------------------------------------------'); | 66 print('----------------------------------------------------------'); |
64 } | 67 } |
65 Expect.equals(value1, value2, 'Value mismatch for $id'); | 68 Expect.equals(value1, value2, 'Value mismatch for $id'); |
66 }); | 69 }); |
67 } | 70 } |
(...skipping 29 matching lines...) Expand all Loading... |
97 } | 100 } |
98 | 101 |
99 String computeGetName(String propertyName) { | 102 String computeGetName(String propertyName) { |
100 return 'get:$propertyName'; | 103 return 'get:$propertyName'; |
101 } | 104 } |
102 | 105 |
103 String computeInvokeName(String propertyName) { | 106 String computeInvokeName(String propertyName) { |
104 return 'invoke:$propertyName'; | 107 return 'invoke:$propertyName'; |
105 } | 108 } |
106 | 109 |
| 110 String computeSetName(String propertyName) { |
| 111 return 'set:$propertyName'; |
| 112 } |
| 113 |
107 String get loopName => 'loop'; | 114 String get loopName => 'loop'; |
108 | 115 |
109 String get gotoName => 'goto'; | 116 String get gotoName => 'goto'; |
110 | 117 |
111 String get switchName => 'switch'; | 118 String get switchName => 'switch'; |
112 | 119 |
113 String get switchCaseName => 'case'; | 120 String get switchCaseName => 'case'; |
114 } | 121 } |
115 | 122 |
116 /// AST visitor for computing a descriptive mapping of the [Id]s in a member. | 123 /// AST visitor for computing a descriptive mapping of the [Id]s in a member. |
117 class ResolvedAstComputer extends AstDataExtractor with ComputerMixin { | 124 class ResolvedAstComputer extends AstDataExtractor with ComputerMixin { |
118 ResolvedAstComputer(DiagnosticReporter reporter, | 125 ResolvedAstComputer(DiagnosticReporter reporter, |
119 Map<Id, ActualData> actualMap, ResolvedAst resolvedAst) | 126 Map<Id, ActualData> actualMap, ResolvedAst resolvedAst) |
120 : super(reporter, actualMap, resolvedAst); | 127 : super(reporter, actualMap, resolvedAst); |
121 | 128 |
122 @override | 129 @override |
123 String computeNodeValue(ast.Node node, AstElement element) { | 130 String computeNodeValue(Id id, ast.Node node, AstElement element) { |
124 if (element != null && element.isLocal) { | 131 if (element != null && element.isLocal) { |
125 return computeLocalName(element.name); | 132 return computeLocalName(element.name); |
126 } | 133 } |
127 if (node is ast.Loop) { | 134 if (node is ast.Loop) { |
128 return loopName; | 135 return loopName; |
129 } else if (node is ast.GotoStatement) { | 136 } else if (node is ast.GotoStatement) { |
130 return gotoName; | 137 return gotoName; |
131 } else if (node is ast.SwitchStatement) { | 138 } else if (node is ast.SwitchStatement) { |
132 return switchName; | 139 return switchName; |
133 } else if (node is ast.SwitchCase) { | 140 } else if (node is ast.SwitchCase) { |
(...skipping 29 matching lines...) Expand all Loading... |
163 case SendStructureKind.BINARY: | 170 case SendStructureKind.BINARY: |
164 return computeInvokeName(sendStructure.operator.selectorName); | 171 return computeInvokeName(sendStructure.operator.selectorName); |
165 case SendStructureKind.EQUALS: | 172 case SendStructureKind.EQUALS: |
166 return computeInvokeName('=='); | 173 return computeInvokeName('=='); |
167 case SendStructureKind.NOT_EQUALS: | 174 case SendStructureKind.NOT_EQUALS: |
168 return computeInvokeName('!='); | 175 return computeInvokeName('!='); |
169 case SendStructureKind.INVOKE: | 176 case SendStructureKind.INVOKE: |
170 String dynamicName = getDynamicName(); | 177 String dynamicName = getDynamicName(); |
171 if (dynamicName != null) return computeInvokeName(dynamicName); | 178 if (dynamicName != null) return computeInvokeName(dynamicName); |
172 break; | 179 break; |
| 180 case SendStructureKind.SET: |
| 181 String dynamicName = getDynamicName(); |
| 182 if (dynamicName != null) return computeSetName(dynamicName); |
| 183 break; |
| 184 case SendStructureKind.POSTFIX: |
| 185 String dynamicName = getDynamicName(); |
| 186 if (dynamicName != null) { |
| 187 if (id.kind == IdKind.update) { |
| 188 return computeSetName(dynamicName); |
| 189 } else if (id.kind == IdKind.invoke) { |
| 190 return computeInvokeName( |
| 191 sendStructure.operator.binaryOperator.name); |
| 192 } else { |
| 193 return computeGetName(dynamicName); |
| 194 } |
| 195 } |
| 196 break; |
173 default: | 197 default: |
174 } | 198 } |
175 } | 199 } |
176 if (sendStructure != null) { | 200 if (sendStructure != null) { |
177 return '<unknown:$node (${node.runtimeType}) $sendStructure>'; | 201 return '<unknown:$node (${node.runtimeType}) $sendStructure>'; |
178 } | 202 } |
179 return '<unknown:$node (${node.runtimeType})>'; | 203 return '<unknown:$node (${node.runtimeType})>'; |
180 } | 204 } |
181 | 205 |
182 @override | 206 @override |
183 String computeElementValue(AstElement element) { | 207 String computeElementValue(Id id, AstElement element) { |
184 return computeMemberName(element.enclosingClass?.name, element.name); | 208 return computeMemberName(element.enclosingClass?.name, element.name); |
185 } | 209 } |
186 } | 210 } |
187 | 211 |
188 /// Compute a descriptive mapping of the [Id]s in [member] as a kernel based | 212 /// Compute a descriptive mapping of the [Id]s in [member] as a kernel based |
189 /// member. | 213 /// member. |
190 /// | 214 /// |
191 /// Fills [actualMap] with the data and [sourceSpanMap] with the source spans | 215 /// Fills [actualMap] with the data and [sourceSpanMap] with the source spans |
192 /// for the data origin. | 216 /// for the data origin. |
193 void computeIrMemberData( | 217 void computeIrMemberData( |
194 Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap, | 218 Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap, |
195 {bool verbose: false}) { | 219 {bool verbose: false}) { |
196 KernelBackendStrategy backendStrategy = compiler.backendStrategy; | 220 KernelBackendStrategy backendStrategy = compiler.backendStrategy; |
197 KernelToElementMapForBuilding elementMap = backendStrategy.elementMap; | 221 KernelToElementMapForBuilding elementMap = backendStrategy.elementMap; |
198 MemberDefinition definition = elementMap.getMemberDefinition(member); | 222 MemberDefinition definition = elementMap.getMemberDefinition(member); |
199 assert(definition.kind == MemberKind.regular, | 223 assert(definition.kind == MemberKind.regular, |
200 failedAt(member, "Unexpected member definition $definition")); | 224 failedAt(member, "Unexpected member definition $definition")); |
201 new IrComputer(actualMap).run(definition.node); | 225 new IrComputer(compiler.reporter, actualMap).run(definition.node); |
202 } | 226 } |
203 | 227 |
204 /// IR visitor for computing a descriptive mapping of the [Id]s in a member. | 228 /// IR visitor for computing a descriptive mapping of the [Id]s in a member. |
205 class IrComputer extends IrDataExtractor with ComputerMixin { | 229 class IrComputer extends IrDataExtractor with ComputerMixin { |
206 IrComputer(Map<Id, ActualData> actualMap) : super(actualMap); | 230 IrComputer(DiagnosticReporter reporter, Map<Id, ActualData> actualMap) |
| 231 : super(reporter, actualMap); |
207 | 232 |
208 @override | 233 @override |
209 String computeNodeValue(ir.TreeNode node) { | 234 String computeNodeValue(Id id, ir.TreeNode node) { |
210 if (node is ir.VariableDeclaration) { | 235 if (node is ir.VariableDeclaration) { |
211 return computeLocalName(node.name); | 236 return computeLocalName(node.name); |
212 } else if (node is ir.FunctionDeclaration) { | 237 } else if (node is ir.FunctionDeclaration) { |
213 return computeLocalName(node.variable.name); | 238 return computeLocalName(node.variable.name); |
214 } else if (node is ir.FunctionExpression) { | 239 } else if (node is ir.FunctionExpression) { |
215 return computeLocalName(''); | 240 return computeLocalName(''); |
216 } else if (node is ir.MethodInvocation) { | 241 } else if (node is ir.MethodInvocation) { |
217 return computeInvokeName(node.name.name); | 242 return computeInvokeName(node.name.name); |
218 } else if (node is ir.PropertyGet) { | 243 } else if (node is ir.PropertyGet) { |
219 return computeGetName(node.name.name); | 244 return computeGetName(node.name.name); |
| 245 } else if (node is ir.PropertySet) { |
| 246 return computeSetName(node.name.name); |
220 } else if (node is ir.VariableGet) { | 247 } else if (node is ir.VariableGet) { |
221 return computeGetName(node.variable.name); | 248 return computeGetName(node.variable.name); |
| 249 } else if (node is ir.VariableSet) { |
| 250 return computeSetName(node.variable.name); |
222 } else if (node is ir.DoStatement) { | 251 } else if (node is ir.DoStatement) { |
223 return loopName; | 252 return loopName; |
224 } else if (node is ir.ForStatement) { | 253 } else if (node is ir.ForStatement) { |
225 return loopName; | 254 return loopName; |
226 } else if (node is ir.ForInStatement) { | 255 } else if (node is ir.ForInStatement) { |
227 return loopName; | 256 return loopName; |
228 } else if (node is ir.WhileStatement) { | 257 } else if (node is ir.WhileStatement) { |
229 return loopName; | 258 return loopName; |
230 } else if (node is ir.BreakStatement) { | 259 } else if (node is ir.BreakStatement) { |
231 return gotoName; | 260 return gotoName; |
232 } else if (node is ir.ContinueSwitchStatement) { | 261 } else if (node is ir.ContinueSwitchStatement) { |
233 return gotoName; | 262 return gotoName; |
234 } else if (node is ir.SwitchStatement) { | 263 } else if (node is ir.SwitchStatement) { |
235 return switchName; | 264 return switchName; |
236 } else if (node is ir.SwitchCase) { | 265 } else if (node is ir.SwitchCase) { |
237 return switchCaseName; | 266 return switchCaseName; |
238 } | 267 } |
239 return '<unknown:$node (${node.runtimeType})>'; | 268 return '<unknown:$node (${node.runtimeType})>'; |
240 } | 269 } |
241 | 270 |
242 @override | 271 @override |
243 String computeMemberValue(ir.Member member) { | 272 String computeMemberValue(Id id, ir.Member member) { |
244 return computeMemberName(member.enclosingClass?.name, member.name.name); | 273 return computeMemberName(member.enclosingClass?.name, member.name.name); |
245 } | 274 } |
246 } | 275 } |
OLD | NEW |