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

Side by Side Diff: tests/try/poi/forget_element_test.dart

Issue 2232273004: Delete site/try (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 4 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
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
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.
4
5 // Test of Compiler.forgetElement.
6 library trydart.forget_element_test;
7
8 import 'package:compiler/src/elements/elements.dart' show
9 AstElement,
10 ClassElement,
11 Element,
12 FunctionElement,
13 LocalFunctionElement,
14 MetadataAnnotation,
15 ScopeContainerElement,
16 VariableElement;
17
18 import 'package:compiler/src/js_backend/js_backend.dart' show
19 JavaScriptBackend;
20
21 import 'package:compiler/src/tree/tree.dart' as tree;
22
23 import 'package:compiler/src/parser/partial_elements.dart' show
24 PartialMetadataAnnotation;
25
26 import 'package:compiler/src/elements/visitor.dart' show
27 ElementVisitor;
28
29 import 'package:compiler/src/compile_time_constants.dart' show
30 DartConstantCompiler;
31
32 import 'package:compiler/src/universe/universe.dart' show
33 Universe;
34
35 import 'package:compiler/src/dart_types.dart' show
36 DartType;
37
38 import 'compiler_test_case.dart';
39
40 import 'forget_element_assertion.dart' show
41 assertUnimplementedLocalMetadata;
42
43 class ForgetElementTestCase extends CompilerTestCase {
44 final int expectedClosureCount;
45
46 final int expectedMetadataCount;
47
48 final int expectedConstantCount;
49
50 final int expectedInitialValueCount;
51
52 final int expectedInitialDartValueCount;
53
54 final int additionalClosureClassMaps;
55
56 JavaScriptBackend get backend => compiler.backend;
57
58 DartConstantCompiler get dartConstants =>
59 backend.constantCompilerTask.dartConstantCompiler;
60
61 Universe get codegenUniverse => compiler.enqueuer.codegen.universe;
62
63 Universe get resolutionUniverse => compiler.enqueuer.resolution.universe;
64
65 ForgetElementTestCase(
66 String source,
67 {int closureCount: 0,
68 int metadataCount: 0,
69 int constantCount: 0,
70 int initialValueCount: 0,
71 int initialDartValueCount: null,
72 this.additionalClosureClassMaps: 0})
73 : this.expectedClosureCount = closureCount,
74 this.expectedMetadataCount = metadataCount,
75 this.expectedConstantCount = constantCount,
76 this.expectedInitialValueCount = initialValueCount,
77 // Sometimes these numbers aren't the same. Appears to happen with
78 // non-const fields, because those aren't compile-time constants in the
79 // strict language specification sense.
80 this.expectedInitialDartValueCount = (initialDartValueCount == null)
81 ? initialValueCount : initialDartValueCount,
82 super(source);
83
84 Future run() => compile().then((LibraryElement library) {
85
86 // Check that the compiler has recorded the expected number of closures.
87 Expect.equals(
88 expectedClosureCount, closuresInLibrary(library).length,
89 'closure count');
90
91 // Check that the compiler has recorded the expected number of metadata
92 // annotations.
93 Expect.equals(
94 expectedMetadataCount, metadataInLibrary(library).length,
95 'metadata count');
96
97 // Check that the compiler has recorded the expected number of
98 // constants. Since metadata is also constants, those must also be counted.
99 Expect.equals(
100 expectedConstantCount + expectedMetadataCount,
101 constantsIn(library).length,
102 'constant count');
103
104 // Check that the compiler has recorded the expected number of initial
105 // values.
106 Expect.equals(
107 expectedInitialValueCount,
108 elementsWithJsInitialValuesIn(library).length,
109 'number of fields with initial values (JS)');
110 Expect.equals(
111 expectedInitialDartValueCount,
112 elementsWithDartInitialValuesIn(library).length,
113 'number of fields with initial values (Dart)');
114
115 // Check that the compiler has recorded the expected number of closure
116 // class maps. There's always at least one, from main. Each top-level
117 // element also seems to induce one.
118 Expect.equals(
119 expectedClosureCount + additionalClosureClassMaps,
120 closureClassMapsIn(library).length - 1,
121 'closure class map count ${closureClassMapsIn(library)}');
122
123
124 // Forget about all elements.
125 library.forEachLocalMember(compiler.forgetElement);
126
127 // Check that all the closures were forgotten.
128 Expect.isTrue(closuresInLibrary(library).isEmpty, 'closures');
129
130 // Check that the metadata annotations were forgotten.
131 Expect.isTrue(metadataInLibrary(library).isEmpty, 'metadata');
132
133 // Check that the constants were forgotten.
134 Expect.isTrue(constantsIn(library).isEmpty, 'constants');
135
136 // Check that initial values were forgotten.
137 Expect.isTrue(
138 elementsWithJsInitialValuesIn(library).isEmpty,
139 'fields with initial values (JS)');
140 Expect.isTrue(
141 elementsWithDartInitialValuesIn(library).isEmpty,
142 'fields with initial values (Dart)');
143
144 // Check that closure class maps were forgotten.
145 Expect.isTrue(closureClassMapsIn(library).isEmpty, 'closure class maps');
146
147 // Check that istantiated types and classes were forgotten.
148 Expect.isTrue(
149 resolutionTypesIn(library).isEmpty, 'resolution instantiatedTypes');
150 Expect.isTrue(
151 resolutionClassesIn(library).isEmpty, 'resolution instantiatedClasses');
152 Expect.isTrue(
153 codegenTypesIn(library).isEmpty, 'codegen instantiatedTypes');
154 Expect.isTrue(
155 codegenClassesIn(library).isEmpty, 'codegen instantiatedClasses');
156
157 // Check that other members remembered by [Universe] were forgotten.
158 Expect.isTrue(
159 resolutionMembersIn(library).isEmpty, 'resolution misc members');
160 Expect.isTrue(
161 codegenMembersIn(library).isEmpty, 'codegen misc members');
162
163 // Check that classes remembered by the enqueuer have been forgotten.
164 Expect.isTrue(
165 codegenSeenClassesIn(library).isEmpty, 'codegen seen classes');
166 Expect.isTrue(
167 resolutionSeenClassesIn(library).isEmpty, 'resolution seen classes');
168 });
169
170 Iterable closuresInLibrary(LibraryElement library) {
171 return compiler.enqueuer.resolution.universe.allClosures.where(
172 (LocalFunctionElement closure) => closure.library == library);
173 }
174
175 Iterable metadataInLibrary(LibraryElement library) {
176 return backend.constants.metadataConstantMap.keys.where(
177 (MetadataAnnotation metadata) {
178 return metadata.annotatedElement.library == library;
179 });
180 }
181
182 Iterable<tree.Node> nodesIn(LibraryElement library) {
183 NodeCollector collector = new NodeCollector();
184 library.forEachLocalMember((e) {
185 if (e is AstElement && e.hasNode) {
186 e.node.accept(collector);
187 }
188
189 // Due to quirks of history, only parameter metadata is recorded in AST
190 // nodes, so they must be extracted from the elements.
191 for (MetadataAnnotation metadata in e.metadata) {
192 if (metadata is PartialMetadataAnnotation) {
193 if (metadata.cachedNode != null) {
194 metadata.cachedNode.accept(collector);
195 }
196 }
197 }
198 });
199
200 List<MetadataAnnotation> metadata =
201 (new MetadataCollector()..visit(library, null)).metadata;
202 return collector.nodes;
203 }
204
205 Iterable constantsIn(LibraryElement library) {
206 return nodesIn(library)
207 .map((node) => backend.constants.nodeConstantMap[node])
208 .where((constant) => constant != null);
209 }
210
211 Iterable elementsWithJsInitialValuesIn(LibraryElement library) {
212 return backend.constants.initialVariableValues.keys.where(
213 (VariableElement element) => element.library == library);
214 }
215
216 Iterable elementsWithDartInitialValuesIn(LibraryElement library) {
217 return dartConstants.initialVariableValues.keys.where(
218 (VariableElement element) => element.library == library);
219 }
220
221 Iterable closureClassMapsIn(LibraryElement library) {
222 Map cache = compiler.closureToClassMapper.closureMappingCache;
223 return nodesIn(library).where((node) => cache[node] != null);
224 }
225
226 Iterable codegenTypesIn(LibraryElement library) {
227 return codegenUniverse.instantiatedTypes.where(
228 (DartType type) => type.element.library == library);
229 }
230
231 Iterable codegenClassesIn(LibraryElement library) {
232 return codegenUniverse.directlyInstantiatedClasses.where(
233 (ClassElement cls) => cls.library == library);
234 }
235
236 Iterable codegenMembersIn(LibraryElement library) {
237 sameLibrary(e) => e.library == library;
238 return new Set()
239 ..addAll(codegenUniverse.closurizedMembers.where(sameLibrary))
240 ..addAll(codegenUniverse.fieldSetters.where(sameLibrary))
241 ..addAll(codegenUniverse.fieldGetters.where(sameLibrary));
242 }
243
244 Iterable resolutionTypesIn(LibraryElement library) {
245 return resolutionUniverse.instantiatedTypes.where(
246 (DartType type) => type.element.library == library);
247 }
248
249 Iterable resolutionClassesIn(LibraryElement library) {
250 return resolutionUniverse.directlyInstantiatedClasses.where(
251 (ClassElement cls) => cls.library == library);
252 }
253
254 Iterable resolutionMembersIn(LibraryElement library) {
255 sameLibrary(e) => e.library == library;
256 return new Set()
257 ..addAll(resolutionUniverse.closurizedMembers.where(sameLibrary))
258 ..addAll(resolutionUniverse.fieldSetters.where(sameLibrary))
259 ..addAll(resolutionUniverse.fieldGetters.where(sameLibrary));
260 }
261
262 Iterable codegenSeenClassesIn(LibraryElement library) {
263 return compiler.enqueuer.codegen.processedClasses.where(
264 (e) => e.library == library);
265 }
266
267 Iterable resolutionSeenClassesIn(LibraryElement library) {
268 return compiler.enqueuer.resolution.processedClasses.where(
269 (e) => e.library == library);
270 }
271 }
272
273 class NodeCollector extends tree.Visitor {
274 final List<tree.Node> nodes = <tree.Node>[];
275
276 void visitNode(tree.Node node) {
277 nodes.add(node);
278 node.visitChildren(this);
279 }
280 }
281
282 class MetadataCollector extends ElementVisitor {
283 final List<MetadataAnnotation> metadata = <MetadataAnnotation>[];
284
285 void visitElement(Element e, _) {
286 metadata.addAll(e.metadata.toList());
287 }
288
289 void visitScopeContainerElement(ScopeContainerElement e, _) {
290 super.visitScopeContainerElement(e);
291 e.forEachLocalMember(this.visit);
292 }
293
294 void visitFunctionElement(FunctionElement e, _) {
295 super.visitFunctionElement(e);
296 if (e.hasFunctionSignature) {
297 e.functionSignature.forEachParameter(this.visit);
298 }
299 }
300 }
301
302 void main() {
303 runTests(tests);
304 }
305
306 List<CompilerTestCase> get tests => <CompilerTestCase>[
307
308 // Edge case: empty body.
309 new ForgetElementTestCase(
310 'main() {}'),
311
312 // Edge case: simple arrow function.
313 new ForgetElementTestCase(
314 'main() => null;'),
315
316 // Test that a local closure is discarded correctly.
317 new ForgetElementTestCase(
318 'main() => (() => null)();',
319 closureCount: 1),
320
321 // Test that nested closures are discarded correctly.
322 new ForgetElementTestCase(
323 'main() => (() => (() => null)())();',
324 closureCount: 2),
325
326 // Test that nested closures are discarded correctly.
327 new ForgetElementTestCase(
328 'main() => (() => (() => (() => null)())())();',
329 closureCount: 3),
330
331 // Test that metadata on top-level function is discarded correctly.
332 new ForgetElementTestCase(
333 '@Constant() main() => null; $CONSTANT_CLASS',
334 metadataCount: 1),
335
336 // Test that metadata on top-level variable is discarded correctly.
337 new ForgetElementTestCase(
338 '@Constant() var x; main() => x; $CONSTANT_CLASS',
339 metadataCount: 1,
340 initialValueCount: 1,
341 initialDartValueCount: 0),
342
343 // Test that metadata on parameter on a local function is discarded
344 // correctly.
345 new ForgetElementTestCase(
346 'main() => ((@Constant() x) => x)(null); $CONSTANT_CLASS',
347 closureCount: 1,
348 metadataCount: 1),
349
350 // Test that a constant in a top-level method body is discarded
351 // correctly.
352 new ForgetElementTestCase(
353 'main() => const Constant(); $CONSTANT_CLASS',
354 constantCount: 1),
355
356 // Test that a constant in a nested function body is discarded
357 // correctly.
358 new ForgetElementTestCase(
359 'main() => (() => const Constant())(); $CONSTANT_CLASS',
360 constantCount: 1,
361 closureCount: 1),
362
363 // Test that a constant in a nested function body is discarded
364 // correctly.
365 new ForgetElementTestCase(
366 'main() => (() => (() => const Constant())())(); $CONSTANT_CLASS',
367 constantCount: 1,
368 closureCount: 2),
369
370 // Test that a constant in a top-level variable initializer is
371 // discarded correctly.
372 new ForgetElementTestCase(
373 'main() => x; var x = const Constant(); $CONSTANT_CLASS',
374 constantCount: 1,
375 initialValueCount: 1,
376 initialDartValueCount: 0,
377 additionalClosureClassMaps: 1),
378
379 // Test that a constant in a parameter initializer is discarded
380 // correctly.
381 new ForgetElementTestCase(
382 'main([x = const Constant()]) => x; $CONSTANT_CLASS',
383 constantCount: 1,
384 initialValueCount: 1),
385
386 // Test that a constant in a parameter initializer is discarded
387 // correctly (nested function).
388 new ForgetElementTestCase(
389 'main() => (([x = const Constant()]) => x)(); $CONSTANT_CLASS',
390 closureCount: 1,
391 constantCount: 1,
392 initialValueCount: 1),
393
394 // Test that a constant in a parameter initializer is discarded
395 // correctly (deeply nested function).
396 new ForgetElementTestCase(
397 'main() => (() => (([x = const Constant()]) => x)())();'
398 ' $CONSTANT_CLASS',
399 closureCount: 2,
400 constantCount: 1,
401 initialValueCount: 1),
402
403 // TODO(ahe): Add test for super sends [backend.aliasedSuperMembers].
404 ]..addAll(assertUnimplementedLocalMetadata());
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698