Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Side by Side Diff: tests/compiler/dart2js/equivalence/id_equivalence_helper.dart

Issue 2951723002: Add closure_test for kernel based members (Closed)
Patch Set: Cleanup Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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:async';
6 import 'package:compiler/src/commandline_options.dart';
5 import 'package:compiler/src/common.dart'; 7 import 'package:compiler/src/common.dart';
6 import 'package:compiler/src/common_elements.dart'; 8 import 'package:compiler/src/common_elements.dart';
7 import 'package:compiler/src/compiler.dart'; 9 import 'package:compiler/src/compiler.dart';
8 import 'package:compiler/src/elements/elements.dart'; 10 import 'package:compiler/src/elements/elements.dart';
9 import 'package:compiler/src/elements/entities.dart'; 11 import 'package:compiler/src/elements/entities.dart';
10 import 'package:compiler/src/resolution/tree_elements.dart'; 12 import 'package:compiler/src/resolution/tree_elements.dart';
11 import 'package:compiler/src/tree/nodes.dart'; 13 import 'package:compiler/src/tree/nodes.dart' as ast;
12 import 'package:expect/expect.dart'; 14 import 'package:expect/expect.dart';
15 import 'package:kernel/ast.dart' as ir;
13 16
14 import '../annotated_code_helper.dart'; 17 import '../annotated_code_helper.dart';
15 import '../memory_compiler.dart'; 18 import '../memory_compiler.dart';
16 import '../equivalence/id_equivalence.dart'; 19 import '../equivalence/id_equivalence.dart';
20 import '../kernel/compiler_helper.dart';
17 21
18 typedef void CheckMemberFunction( 22 /// Function that compiles [code] with [options] and returns the [Compiler] obje ct.
19 Compiler compiler, Map<Id, String> expectedMap, MemberEntity member); 23 typedef Future<Compiler> CompileFunction(
24 AnnotatedCode code, Uri mainUri, List<String> options);
20 25
21 /// Compiles the [annotatedCode] with the provided [options] and calls 26 /// Function that computes a data mapping for [member].
22 /// [checkMember] for each member in the code providing the map from [Id] to 27 ///
23 /// annotation. Any [Id] left in the map will be reported as missing. 28 /// Fills [actualMap] with the data and [sourceSpanMap] with the source spans
24 checkCode(String annotatedCode, CheckMemberFunction checkMember, 29 /// for the data origin.
30 typedef void ComputeMemberDataFunction(Compiler compiler, MemberEntity member,
31 Map<Id, String> actualMap, Map<Id, SourceSpan> sourceSpanMap);
32
33 /// Compile [code] from .dart sources.
34 Future<Compiler> compileFromSource(
35 AnnotatedCode code, Uri mainUri, List<String> options) async {
36 Compiler compiler = compilerFor(
37 memorySourceFiles: {'main.dart': code.sourceCode}, options: options);
38 compiler.stopAfterTypeInference = true;
39 await compiler.run(mainUri);
40 return compiler;
41 }
42
43 /// Compile [code] from .dill sources.
44 Future<Compiler> compileFromDill(
45 AnnotatedCode code, Uri mainUri, List<String> options) async {
46 Compiler compiler = await compileWithDill(
47 mainUri,
48 {'main.dart': code.sourceCode},
49 [Flags.disableTypeInference]..addAll(options),
50 beforeRun: (Compiler compiler) {
51 compiler.stopAfterTypeInference = true;
52 });
53 return compiler;
54 }
55
56 /// Compute expected and actual data for all members defined in [annotatedCode].
57 ///
58 /// Actual data is computed using [computeMemberData] and [code] is compiled
59 /// using [compileFunction].
60 Future<IdData> computeData(
61 String annotatedCode,
62 ComputeMemberDataFunction computeMemberData,
63 CompileFunction compileFunction,
25 {List<String> options: const <String>[]}) async { 64 {List<String> options: const <String>[]}) async {
26 AnnotatedCode code = 65 AnnotatedCode code =
27 new AnnotatedCode.fromText(annotatedCode, commentStart, commentEnd); 66 new AnnotatedCode.fromText(annotatedCode, commentStart, commentEnd);
28 Map<Id, String> expectedMap = computeExpectedMap(code); 67 Map<Id, String> expectedMap = computeExpectedMap(code);
29 Compiler compiler = compilerFor( 68 Map<Id, String> actualMap = <Id, String>{};
30 memorySourceFiles: {'main.dart': code.sourceCode}, options: options); 69 Map<Id, SourceSpan> sourceSpanMap = <Id, SourceSpan>{};
31 compiler.stopAfterTypeInference = true;
32 Uri mainUri = Uri.parse('memory:main.dart'); 70 Uri mainUri = Uri.parse('memory:main.dart');
33 await compiler.run(mainUri); 71 Compiler compiler = await compileFunction(code, mainUri, options);
34 ElementEnvironment elementEnvironment = 72 ElementEnvironment elementEnvironment =
35 compiler.backendClosedWorldForTesting.elementEnvironment; 73 compiler.backendClosedWorldForTesting.elementEnvironment;
36 LibraryEntity mainLibrary = elementEnvironment.mainLibrary; 74 LibraryEntity mainLibrary = elementEnvironment.mainLibrary;
37 elementEnvironment.forEachClass(mainLibrary, (ClassEntity cls) { 75 elementEnvironment.forEachClass(mainLibrary, (ClassEntity cls) {
38 elementEnvironment.forEachClassMember(cls, 76 elementEnvironment.forEachClassMember(cls,
39 (ClassEntity declarer, MemberEntity member) { 77 (ClassEntity declarer, MemberEntity member) {
40 if (cls == declarer) { 78 if (cls == declarer) {
41 checkMember(compiler, expectedMap, member); 79 computeMemberData(compiler, member, actualMap, sourceSpanMap);
42 } 80 }
43 }); 81 });
44 }); 82 });
45 elementEnvironment.forEachLibraryMember(mainLibrary, (MemberEntity member) { 83 elementEnvironment.forEachLibraryMember(mainLibrary, (MemberEntity member) {
46 checkMember(compiler, expectedMap, member); 84 computeMemberData(compiler, member, actualMap, sourceSpanMap);
47 }); 85 });
48 expectedMap.forEach((Id id, String expected) { 86 return new IdData(compiler, elementEnvironment, mainUri, expectedMap,
87 actualMap, sourceSpanMap);
88 }
89
90 /// Data collected by [computeData].
91 class IdData {
92 final Compiler compiler;
93 final ElementEnvironment elementEnvironment;
94 final Uri mainUri;
95 final Map<Id, String> expectedMap;
96 final Map<Id, String> actualMap;
97 final Map<Id, SourceSpan> sourceSpanMap;
98
99 IdData(this.compiler, this.elementEnvironment, this.mainUri, this.expectedMap,
100 this.actualMap, this.sourceSpanMap);
101 }
102
103 /// Compiles the [annotatedCode] with the provided [options] and calls
104 /// [computeMemberData] for each member. The result is checked against the
105 /// expected data derived from [annotatedCode].
106 Future checkCode(
107 String annotatedCode,
108 ComputeMemberDataFunction computeMemberData,
109 CompileFunction compileFunction,
110 {List<String> options: const <String>[]}) async {
111 IdData data = await computeData(
112 annotatedCode, computeMemberData, compileFunction,
113 options: options);
114
115 data.actualMap.forEach((Id id, String actual) {
116 String expected = data.expectedMap.remove(id);
117 if (actual != expected) {
118 reportHere(data.compiler.reporter, data.sourceSpanMap[id],
119 'expected:${expected},actual:${actual}');
120 }
121 Expect.equals(expected, actual);
122 });
123
124 data.expectedMap.forEach((Id id, String expected) {
49 reportHere( 125 reportHere(
50 compiler.reporter, 126 data.compiler.reporter,
51 computeSpannable(elementEnvironment, mainUri, id), 127 computeSpannable(data.elementEnvironment, data.mainUri, id),
52 'expected:${expected},actual:null'); 128 'expected:${expected},actual:null');
53 }); 129 });
54 Expect.isTrue(expectedMap.isEmpty, "Ids not found: $expectedMap."); 130 Expect.isTrue(
131 data.expectedMap.isEmpty, "Ids not found: ${data.expectedMap}.");
55 } 132 }
56 133
134 /// Compute a [Spannable] from an [id] in the library [mainUri].
57 Spannable computeSpannable( 135 Spannable computeSpannable(
58 ElementEnvironment elementEnvironment, Uri mainUri, Id id) { 136 ElementEnvironment elementEnvironment, Uri mainUri, Id id) {
59 if (id is NodeId) { 137 if (id is NodeId) {
60 return new SourceSpan(mainUri, id.value, id.value + 1); 138 return new SourceSpan(mainUri, id.value, id.value + 1);
61 } else if (id is ElementId) { 139 } else if (id is ElementId) {
62 LibraryEntity library = elementEnvironment.lookupLibrary(mainUri); 140 LibraryEntity library = elementEnvironment.lookupLibrary(mainUri);
63 if (id.className != null) { 141 if (id.className != null) {
64 ClassEntity cls = 142 ClassEntity cls =
65 elementEnvironment.lookupClass(library, id.className, required: true); 143 elementEnvironment.lookupClass(library, id.className, required: true);
66 return elementEnvironment.lookupClassMember(cls, id.memberName); 144 return elementEnvironment.lookupClassMember(cls, id.memberName);
67 } else { 145 } else {
68 return elementEnvironment.lookupLibraryMember(library, id.memberName); 146 return elementEnvironment.lookupLibraryMember(library, id.memberName);
69 } 147 }
70 } 148 }
71 throw new UnsupportedError('Unsupported id $id.'); 149 throw new UnsupportedError('Unsupported id $id.');
72 } 150 }
73 151
152 /// Compute the expectancy map from [code].
74 Map<Id, String> computeExpectedMap(AnnotatedCode code) { 153 Map<Id, String> computeExpectedMap(AnnotatedCode code) {
75 Map<Id, String> map = <Id, String>{}; 154 Map<Id, String> map = <Id, String>{};
76 for (Annotation annotation in code.annotations) { 155 for (Annotation annotation in code.annotations) {
77 String text = annotation.text; 156 String text = annotation.text;
78 int colonPos = text.indexOf(':'); 157 int colonPos = text.indexOf(':');
79 Id id; 158 Id id;
80 String expected; 159 String expected;
81 if (colonPos == -1) { 160 if (colonPos == -1) {
82 id = new NodeId(annotation.offset); 161 id = new NodeId(annotation.offset);
83 expected = text; 162 expected = text;
84 } else { 163 } else {
85 id = new ElementId(text.substring(0, colonPos)); 164 id = new ElementId(text.substring(0, colonPos));
86 expected = text.substring(colonPos + 1); 165 expected = text.substring(colonPos + 1);
87 } 166 }
88 map[id] = expected; 167 map[id] = expected;
89 } 168 }
90 return map; 169 return map;
91 } 170 }
92 171
93 abstract class AbstractResolvedAstChecker extends Visitor 172 /// Mixin used for computing [Id] data.
94 with AstEnumeratorMixin { 173 abstract class ComputerMixin {
174 Map<Id, String> get actualMap;
175 Map<Id, SourceSpan> get sourceSpanMap;
176
177 void registerValue(SourceSpan sourceSpan, Id id, String value) {
178 if (id != null && value != null) {
179 sourceSpanMap[id] = sourceSpan;
180 actualMap[id] = value;
181 }
182 }
183 }
184
185 /// Abstract AST visitor for computing [Id] data.
186 abstract class AbstractResolvedAstComputer extends ast.Visitor
187 with AstEnumeratorMixin, ComputerMixin {
95 final DiagnosticReporter reporter; 188 final DiagnosticReporter reporter;
96 final Map<Id, String> expectedMap; 189 final Map<Id, String> actualMap;
190 final Map<Id, SourceSpan> sourceSpanMap;
97 final ResolvedAst resolvedAst; 191 final ResolvedAst resolvedAst;
98 192
99 AbstractResolvedAstChecker(this.reporter, this.expectedMap, this.resolvedAst); 193 AbstractResolvedAstComputer(
194 this.reporter, this.actualMap, this.sourceSpanMap, this.resolvedAst);
100 195
101 TreeElements get elements => resolvedAst.elements; 196 TreeElements get elements => resolvedAst.elements;
102 197
103 void check() { 198 void computeForElement(AstElement element) {
104 resolvedAst.node.accept(this); 199 ElementId id = computeElementId(element);
200 if (id == null) return;
201 String value = computeElementValue(element);
202 registerValue(element.sourcePosition, id, value);
105 } 203 }
106 204
107 visitNode(Node node) { 205 void computeForNode(ast.Node node, AstElement element) {
108 node.visitChildren(this); 206 NodeId id = computeNodeId(node, element);
109 } 207 if (id == null) return;
110 208 String value = computeNodeValue(node, element);
111 void checkElement(AstElement element) { 209 SourceSpan sourceSpan = new SourceSpan(resolvedAst.sourceUri,
112 ElementId id = computeElementId(element); 210 node.getBeginToken().charOffset, node.getEndToken().charEnd);
113 String expected = annotationForId(id); 211 registerValue(sourceSpan, id, value);
114 String value = computeElementValue(element);
115 checkValue(element, expected, value);
116 } 212 }
117 213
118 String computeElementValue(AstElement element); 214 String computeElementValue(AstElement element);
119 215
120 String annotationForId(Id id) { 216 String computeNodeValue(ast.Node node, AstElement element);
121 if (id == null) return null; 217
122 return expectedMap.remove(id); 218 void run() {
219 resolvedAst.node.accept(this);
123 } 220 }
124 221
125 void checkValue(Spannable spannable, String expected, String value) { 222 visitNode(ast.Node node) {
126 if (value != null || expected != null) { 223 node.visitChildren(this);
127 if (value != expected) {
128 reportHere(reporter, spannable, 'expected:${expected},actual:${value}');
129 }
130 Expect.equals(expected, value);
131 }
132 } 224 }
133 225
134 void checkNode(Node node, AstElement element) { 226 visitVariableDefinitions(ast.VariableDefinitions node) {
135 NodeId id = computeNodeId(node, element); 227 for (ast.Node child in node.definitions) {
136 String expected = annotationForId(id);
137 String value = computeNodeValue(node, element);
138 checkValue(node, expected, value);
139 }
140
141 String computeNodeValue(Node node, [AstElement element]);
142
143 visitVariableDefinitions(VariableDefinitions node) {
144 for (Node child in node.definitions) {
145 AstElement element = elements[child]; 228 AstElement element = elements[child];
146 if (element == null) { 229 if (element == null) {
147 reportHere(reporter, child, 'No element for variable.'); 230 reportHere(reporter, child, 'No element for variable.');
148 } else if (!element.isLocal) { 231 } else if (!element.isLocal) {
149 checkElement(element); 232 computeForElement(element);
150 } else { 233 } else {
151 checkNode(child, element); 234 computeForNode(child, element);
152 } 235 }
153 } 236 }
154 visitNode(node); 237 visitNode(node);
155 } 238 }
156 239
157 visitFunctionExpression(FunctionExpression node) { 240 visitFunctionExpression(ast.FunctionExpression node) {
158 AstElement element = elements.getFunctionDefinition(node); 241 AstElement element = elements.getFunctionDefinition(node);
159 if (!element.isLocal) { 242 if (!element.isLocal) {
160 checkElement(element); 243 computeForElement(element);
161 } else { 244 } else {
162 checkNode(node, element); 245 computeForNode(node, element);
163 } 246 }
164 visitNode(node); 247 visitNode(node);
165 } 248 }
166 249
167 visitSend(Send node) { 250 visitSend(ast.Send node) {
168 checkNode(node, null); 251 computeForNode(node, null);
169 visitNode(node); 252 visitNode(node);
170 } 253 }
171 254
172 visitSendSet(SendSet node) { 255 visitSendSet(ast.SendSet node) {
173 checkNode(node, null); 256 computeForNode(node, null);
174 visitNode(node); 257 visitNode(node);
175 } 258 }
176 } 259 }
260
261 /// Abstract IR visitor for computing [Id] data.
262 abstract class AbstractIrComputer extends ir.Visitor
263 with IrEnumeratorMixin, ComputerMixin {
264 final Map<Id, String> actualMap;
265 final Map<Id, SourceSpan> sourceSpanMap;
266
267 AbstractIrComputer(this.actualMap, this.sourceSpanMap);
268
269 void computeForMember(ir.Member member) {
270 ElementId id = computeElementId(member);
271 if (id == null) return;
272 String value = computeMemberValue(member);
273 registerValue(computeSpannable(member), id, value);
274 }
275
276 void computeForNode(ir.TreeNode node) {
277 NodeId id = computeNodeId(node);
278 if (id == null) return;
279 String value = computeNodeValue(node);
280 registerValue(computeSpannable(node), id, value);
281 }
282
283 Spannable computeSpannable(ir.TreeNode node) {
284 return new SourceSpan(
285 Uri.parse(node.location.file), node.fileOffset, node.fileOffset + 1);
286 }
287
288 String computeMemberValue(ir.Member member);
289
290 String computeNodeValue(ir.TreeNode node);
291
292 void run(ir.Node root) {
293 root.accept(this);
294 }
295
296 defaultNode(ir.Node node) {
297 node.visitChildren(this);
298 }
299
300 defaultMember(ir.Member node) {
301 computeForMember(node);
302 super.defaultMember(node);
303 }
304
305 visitMethodInvocation(ir.MethodInvocation node) {
306 computeForNode(node);
307 super.visitMethodInvocation(node);
308 }
309
310 visitPropertyGet(ir.PropertyGet node) {
311 computeForNode(node);
312 super.visitPropertyGet(node);
313 }
314
315 visitVariableDeclaration(ir.VariableDeclaration node) {
316 computeForNode(node);
317 super.visitVariableDeclaration(node);
318 }
319
320 visitFunctionDeclaration(ir.FunctionDeclaration node) {
321 computeForNode(node);
322 super.visitFunctionDeclaration(node);
323 }
324 }
OLDNEW
« no previous file with comments | « tests/compiler/dart2js/equivalence/id_equivalence.dart ('k') | tests/compiler/dart2js/equivalence/id_equivalence_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698