Index: tests/compiler/dart2js/equivalence/id_equivalence_test.dart |
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_test.dart b/tests/compiler/dart2js/equivalence/id_equivalence_test.dart |
index ac63757b0710e0832246e14d1ddbd698be849830..a2b183ca0e92b4b27d599181b69e2631387cce01 100644 |
--- a/tests/compiler/dart2js/equivalence/id_equivalence_test.dart |
+++ b/tests/compiler/dart2js/equivalence/id_equivalence_test.dart |
@@ -4,11 +4,15 @@ |
import 'dart:io'; |
import 'package:async_helper/async_helper.dart'; |
+import 'package:compiler/src/common.dart'; |
import 'package:compiler/src/compiler.dart'; |
-import 'package:compiler/src/commandline_options.dart'; |
+import 'package:compiler/src/diagnostics/diagnostic_listener.dart'; |
import 'package:compiler/src/elements/elements.dart'; |
import 'package:compiler/src/elements/entities.dart'; |
-import 'package:compiler/src/kernel/kernel.dart'; |
+import 'package:compiler/src/kernel/element_map.dart'; |
+import 'package:compiler/src/kernel/kernel_backend_strategy.dart'; |
+import 'package:compiler/src/resolution/access_semantics.dart'; |
+import 'package:compiler/src/resolution/send_structure.dart'; |
import 'package:compiler/src/tree/nodes.dart' as ast; |
import 'package:expect/expect.dart'; |
import 'package:kernel/ast.dart' as ir; |
@@ -16,6 +20,7 @@ import '../equivalence/id_equivalence.dart'; |
import '../equivalence/id_equivalence_helper.dart'; |
const List<String> dataDirectories = const <String>[ |
+ '../closure/data', |
'../inference/data', |
]; |
@@ -27,57 +32,148 @@ main() { |
print('Checking ${entity.uri}'); |
String annotatedCode = |
await new File.fromUri(entity.uri).readAsString(); |
- await checkCode(annotatedCode, checkMemberEquivalence, |
- options: [Flags.useKernel]); |
+ IdData data1 = await computeData( |
+ annotatedCode, computeAstMemberData, compileFromSource); |
+ IdData data2 = await computeData( |
+ annotatedCode, computeIrMemberData, compileFromDill); |
+ data1.actualMap.forEach((Id id, String value1) { |
+ String value2 = data2.actualMap[id]; |
+ if (value1 != value2) { |
+ reportHere(data1.compiler.reporter, data1.sourceSpanMap[id], |
+ '$id: from source:${value1},from dill:${value2}'); |
+ } |
+ Expect.equals(value1, value2, 'Value mismatch for $id'); |
+ }); |
+ data2.actualMap.forEach((Id id, String value2) { |
+ String value1 = data1.actualMap[id]; |
+ if (value1 != value2) { |
+ reportHere(data2.compiler.reporter, data2.sourceSpanMap[id], |
+ '$id: from source:${value1},from dill:${value2}'); |
+ } |
+ Expect.equals(value1, value2, 'Value mismatch for $id'); |
+ }); |
} |
} |
}); |
} |
-/// Check that the ids in [expectedMap] map to equivalent nodes/elements in |
-/// the AST and kernel IR. |
-void checkMemberEquivalence( |
- Compiler compiler, Map<Id, String> expectedMap, MemberEntity _member) { |
+/// Compute a descriptive mapping of the [Id]s in [_member] as a |
+/// [MemberElement]. |
+/// |
+/// Fills [actualMap] with the data and [sourceSpanMap] with the source spans |
+/// for the data origin. |
+void computeAstMemberData(Compiler compiler, MemberEntity _member, |
+ Map<Id, String> actualMap, Map<Id, SourceSpan> sourceSpanMap) { |
MemberElement member = _member; |
ResolvedAst resolvedAst = member.resolvedAst; |
if (resolvedAst.kind != ResolvedAstKind.PARSED) return; |
- Map<Id, ast.Node> astMap = <Id, ast.Node>{}; |
- Map<Id, Element> elementMap = <Id, Element>{}; |
- AstIdFinder astFinder = new AstIdFinder(resolvedAst.elements); |
- for (Id id in expectedMap.keys.toList()) { |
- var result = astFinder.find(resolvedAst.node, id); |
- if (result is ast.Node) { |
- astMap[id] = result; |
- } else if (result is AstElement) { |
- elementMap[id] = result; |
+ new ResolvedAstComputer( |
+ compiler.reporter, actualMap, sourceSpanMap, resolvedAst) |
+ .run(); |
+} |
+ |
+/// Mixin used for0computing a descriptive mapping of the [Id]s in a member. |
+class ComputerMixin { |
+ String computeMemberName(String className, String memberName) { |
+ if (className != null) { |
+ return 'member:$className.$memberName'; |
} |
+ return 'member:$memberName'; |
+ } |
+ |
+ String computeLocalName(String localName) { |
+ return 'local:$localName'; |
+ } |
+ |
+ String computeDynamicGetName(String propertyName) { |
+ return 'dynamic-get:$propertyName'; |
+ } |
+ |
+ String computeDynamicInvokeName(String propertyName) { |
+ return 'dynamic-invoke:$propertyName'; |
} |
+} |
- Kernel kernel = compiler.backend.kernelTask.kernel; |
- Map<Id, ir.Node> irMap = <Id, ir.Node>{}; |
- ir.Node node = kernel.elementToIr(member); |
- IrIdFinder irFinder = new IrIdFinder(); |
- for (Id id in expectedMap.keys.toList()) { |
- ir.Node result = irFinder.find(node, id); |
- if (result != null) { |
- irMap[id] = result; |
+/// AST visitor for computing a descriptive mapping of the [Id]s in a member. |
+class ResolvedAstComputer extends AbstractResolvedAstComputer |
+ with ComputerMixin { |
+ ResolvedAstComputer(DiagnosticReporter reporter, Map<Id, String> actualMap, |
+ Map<Id, SourceSpan> spannableMap, ResolvedAst resolvedAst) |
+ : super(reporter, actualMap, spannableMap, resolvedAst); |
+ |
+ @override |
+ String computeNodeValue(ast.Node node, AstElement element) { |
+ if (element != null && element.isLocal) { |
+ return computeLocalName(element.name); |
} |
+ if (node is ast.Send) { |
+ dynamic sendStructure = elements.getSendStructure(node); |
+ if (sendStructure == null) return null; |
+ |
+ String getDynamicName() { |
+ switch (sendStructure.semantics.kind) { |
+ case AccessKind.DYNAMIC_PROPERTY: |
+ DynamicAccess access = sendStructure.semantics; |
+ return access.name.text; |
+ default: |
+ return null; |
+ } |
+ } |
+ |
+ switch (sendStructure.kind) { |
+ case SendStructureKind.GET: |
+ String dynamicName = getDynamicName(); |
+ if (dynamicName != null) return computeDynamicGetName(dynamicName); |
+ break; |
+ case SendStructureKind.INVOKE: |
+ String dynamicName = getDynamicName(); |
+ if (dynamicName != null) return computeDynamicInvokeName(dynamicName); |
+ break; |
+ default: |
+ } |
+ } |
+ return '<unknown:$node>'; |
} |
- elementMap.forEach((Id id, _element) { |
- AstElement element = _element; |
- ir.Node irNode = irMap[id]; |
- Expect.equals(kernel.elementToIr(element), irNode, |
- "Element mismatch on $id = $element"); |
- expectedMap.remove(id); |
- irMap.remove(id); |
- }); |
- astMap.forEach((Id id, ast.Node astNode) { |
- ir.Node irNode = irMap[id]; |
- Expect.equals( |
- kernel.nodeToAst[irNode], astNode, "Node mismatch on $id = $astNode"); |
- expectedMap.remove(id); |
- irMap.remove(id); |
- }); |
- Expect.isTrue(irMap.isEmpty, "Extra IR ids: $irMap"); |
+ @override |
+ String computeElementValue(AstElement element) { |
+ return computeMemberName(element.enclosingClass?.name, element.name); |
+ } |
+} |
+ |
+/// Compute a descriptive mapping of the [Id]s in [member] as a kernel based |
+/// member. |
+/// |
+/// Fills [actualMap] with the data and [sourceSpanMap] with the source spans |
+/// for the data origin. |
+void computeIrMemberData(Compiler compiler, MemberEntity member, |
+ Map<Id, String> actualMap, Map<Id, Spannable> spannableMap) { |
+ KernelBackendStrategy backendStrategy = compiler.backendStrategy; |
+ KernelToElementMap elementMap = backendStrategy.elementMap; |
+ new IrComputer(actualMap, spannableMap).run(elementMap.getMemberNode(member)); |
+} |
+ |
+/// IR visitor for computing a descriptive mapping of the [Id]s in a member. |
+class IrComputer extends AbstractIrComputer with ComputerMixin { |
+ IrComputer(Map<Id, String> actualMap, Map<Id, SourceSpan> spannableMap) |
+ : super(actualMap, spannableMap); |
+ |
+ @override |
+ String computeNodeValue(ir.TreeNode node) { |
+ if (node is ir.VariableDeclaration) { |
+ return computeLocalName(node.name); |
+ } else if (node is ir.FunctionDeclaration) { |
+ return computeLocalName(node.variable.name); |
+ } else if (node is ir.MethodInvocation) { |
+ return computeDynamicInvokeName(node.name.name); |
+ } else if (node is ir.PropertyGet) { |
+ return computeDynamicGetName(node.name.name); |
+ } |
+ return '<unknown:$node>'; |
+ } |
+ |
+ @override |
+ String computeMemberValue(ir.Member member) { |
+ return computeMemberName(member.enclosingClass?.name, member.name.name); |
+ } |
} |