| 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 |