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

Side by Side Diff: packages/analyzer/test/src/task/dart_test.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 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) 2015, 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 library test.src.task.dart_test;
6
7 import 'package:analyzer/src/context/cache.dart';
8 import 'package:analyzer/src/generated/ast.dart';
9 import 'package:analyzer/src/generated/constant.dart';
10 import 'package:analyzer/src/generated/element.dart';
11 import 'package:analyzer/src/generated/engine.dart'
12 show AnalysisOptionsImpl, CacheState;
13 import 'package:analyzer/src/generated/error.dart';
14 import 'package:analyzer/src/generated/resolver.dart';
15 import 'package:analyzer/src/generated/scanner.dart';
16 import 'package:analyzer/src/generated/sdk.dart';
17 import 'package:analyzer/src/generated/source.dart';
18 import 'package:analyzer/src/services/lint.dart';
19 import 'package:analyzer/src/task/dart.dart';
20 import 'package:analyzer/src/task/html.dart';
21 import 'package:analyzer/task/dart.dart';
22 import 'package:analyzer/task/general.dart';
23 import 'package:analyzer/task/model.dart';
24 import 'package:unittest/unittest.dart';
25
26 import '../../generated/resolver_test.dart';
27 import '../../generated/test_support.dart';
28 import '../../reflective_tests.dart';
29 import '../../utils.dart';
30 import '../context/abstract_context.dart';
31
32 main() {
33 initializeTestEnvironment();
34 runReflectiveTests(BuildCompilationUnitElementTaskTest);
35 runReflectiveTests(BuildDirectiveElementsTaskTest);
36 runReflectiveTests(BuildEnumMemberElementsTaskTest);
37 runReflectiveTests(BuildExportNamespaceTaskTest);
38 runReflectiveTests(BuildLibraryElementTaskTest);
39 runReflectiveTests(BuildPublicNamespaceTaskTest);
40 runReflectiveTests(BuildSourceExportClosureTaskTest);
41 runReflectiveTests(BuildSourceImportExportClosureTaskTest);
42 runReflectiveTests(BuildTypeProviderTaskTest);
43 runReflectiveTests(ComputeConstantDependenciesTaskTest);
44 runReflectiveTests(ComputeConstantValueTaskTest);
45 runReflectiveTests(ComputeInferableStaticVariableDependenciesTaskTest);
46 runReflectiveTests(ComputeLibraryCycleTaskTest);
47 runReflectiveTests(ContainingLibrariesTaskTest);
48 runReflectiveTests(DartErrorsTaskTest);
49 runReflectiveTests(EvaluateUnitConstantsTaskTest);
50 runReflectiveTests(GatherUsedImportedElementsTaskTest);
51 runReflectiveTests(GatherUsedLocalElementsTaskTest);
52 runReflectiveTests(GenerateHintsTaskTest);
53 runReflectiveTests(GenerateLintsTaskTest);
54 runReflectiveTests(InferInstanceMembersInUnitTaskTest);
55 runReflectiveTests(InferStaticVariableTypesInUnitTaskTest);
56 runReflectiveTests(InferStaticVariableTypeTaskTest);
57 runReflectiveTests(LibraryErrorsReadyTaskTest);
58 runReflectiveTests(LibraryUnitErrorsTaskTest);
59 runReflectiveTests(ParseDartTaskTest);
60 runReflectiveTests(PartiallyResolveUnitReferencesTaskTest);
61 runReflectiveTests(ResolveInstanceFieldsInUnitTaskTest);
62 runReflectiveTests(ResolveLibraryTypeNamesTaskTest);
63 runReflectiveTests(ResolveUnitTaskTest);
64 runReflectiveTests(ResolveUnitTypeNamesTaskTest);
65 runReflectiveTests(ResolveVariableReferencesTaskTest);
66 runReflectiveTests(ScanDartTaskTest);
67 runReflectiveTests(StrongModeInferenceTest);
68 runReflectiveTests(VerifyUnitTaskTest);
69 }
70
71 isInstanceOf isBuildCompilationUnitElementTask =
72 new isInstanceOf<BuildCompilationUnitElementTask>();
73 isInstanceOf isBuildDirectiveElementsTask =
74 new isInstanceOf<BuildDirectiveElementsTask>();
75 isInstanceOf isBuildEnumMemberElementsTask =
76 new isInstanceOf<BuildEnumMemberElementsTask>();
77 isInstanceOf isBuildExportNamespaceTask =
78 new isInstanceOf<BuildExportNamespaceTask>();
79 isInstanceOf isBuildLibraryElementTask =
80 new isInstanceOf<BuildLibraryElementTask>();
81 isInstanceOf isBuildPublicNamespaceTask =
82 new isInstanceOf<BuildPublicNamespaceTask>();
83 isInstanceOf isBuildSourceExportClosureTask =
84 new isInstanceOf<BuildSourceExportClosureTask>();
85 isInstanceOf isBuildSourceImportExportClosureTask =
86 new isInstanceOf<BuildSourceImportExportClosureTask>();
87 isInstanceOf isBuildTypeProviderTask =
88 new isInstanceOf<BuildTypeProviderTask>();
89 isInstanceOf isComputeConstantDependenciesTask =
90 new isInstanceOf<ComputeConstantDependenciesTask>();
91 isInstanceOf isComputeConstantValueTask =
92 new isInstanceOf<ComputeConstantValueTask>();
93 isInstanceOf isComputeInferableStaticVariableDependenciesTask =
94 new isInstanceOf<ComputeInferableStaticVariableDependenciesTask>();
95 isInstanceOf isContainingLibrariesTask =
96 new isInstanceOf<ContainingLibrariesTask>();
97 isInstanceOf isDartErrorsTask = new isInstanceOf<DartErrorsTask>();
98 isInstanceOf isEvaluateUnitConstantsTask =
99 new isInstanceOf<EvaluateUnitConstantsTask>();
100 isInstanceOf isGatherUsedImportedElementsTask =
101 new isInstanceOf<GatherUsedImportedElementsTask>();
102 isInstanceOf isGatherUsedLocalElementsTask =
103 new isInstanceOf<GatherUsedLocalElementsTask>();
104 isInstanceOf isGenerateHintsTask = new isInstanceOf<GenerateHintsTask>();
105 isInstanceOf isGenerateLintsTask = new isInstanceOf<GenerateLintsTask>();
106 isInstanceOf isInferInstanceMembersInUnitTask =
107 new isInstanceOf<InferInstanceMembersInUnitTask>();
108 isInstanceOf isInferStaticVariableTypesInUnitTask =
109 new isInstanceOf<InferStaticVariableTypesInUnitTask>();
110 isInstanceOf isInferStaticVariableTypeTask =
111 new isInstanceOf<InferStaticVariableTypeTask>();
112 isInstanceOf isLibraryErrorsReadyTask =
113 new isInstanceOf<LibraryErrorsReadyTask>();
114 isInstanceOf isLibraryUnitErrorsTask =
115 new isInstanceOf<LibraryUnitErrorsTask>();
116 isInstanceOf isParseDartTask = new isInstanceOf<ParseDartTask>();
117 isInstanceOf isPartiallyResolveUnitReferencesTask =
118 new isInstanceOf<PartiallyResolveUnitReferencesTask>();
119 isInstanceOf isResolveLibraryTypeNamesTask =
120 new isInstanceOf<ResolveLibraryTypeNamesTask>();
121 isInstanceOf isResolveUnitTask = new isInstanceOf<ResolveUnitTask>();
122 isInstanceOf isResolveUnitTypeNamesTask =
123 new isInstanceOf<ResolveUnitTypeNamesTask>();
124 isInstanceOf isResolveVariableReferencesTask =
125 new isInstanceOf<ResolveVariableReferencesTask>();
126 isInstanceOf isScanDartTask = new isInstanceOf<ScanDartTask>();
127 isInstanceOf isVerifyUnitTask = new isInstanceOf<VerifyUnitTask>();
128
129 final LintCode _testLintCode = new LintCode('test lint', 'test lint code');
130
131 @reflectiveTest
132 class BuildCompilationUnitElementTaskTest extends _AbstractDartTaskTest {
133 Source source;
134 LibrarySpecificUnit target;
135
136 test_perform_find_constants() {
137 _performBuildTask('''
138 const x = 1;
139 class C {
140 static const y = 1;
141 const C([p = 1]);
142 }
143 @x
144 f() {
145 const z = 1;
146 }
147 ''');
148 CompilationUnit unit = outputs[RESOLVED_UNIT1];
149 CompilationUnitElement unitElement = outputs[COMPILATION_UNIT_ELEMENT];
150 Annotation annotation = unit.declarations
151 .firstWhere((m) => m is FunctionDeclaration)
152 .metadata[0];
153 List<ConstantEvaluationTarget> expectedConstants = [
154 unitElement.accessors.firstWhere((e) => e.isGetter).variable,
155 unitElement.types[0].fields[0],
156 unitElement.functions[0].localVariables[0],
157 unitElement.types[0].constructors[0],
158 new ConstantEvaluationTarget_Annotation(
159 context, source, source, annotation),
160 unitElement.types[0].constructors[0].parameters[0]
161 ];
162 expect(
163 outputs[COMPILATION_UNIT_CONSTANTS].toSet(), expectedConstants.toSet());
164 }
165
166 test_perform_library() {
167 _performBuildTask(r'''
168 library lib;
169 import 'lib2.dart';
170 export 'lib3.dart';
171 part 'part.dart';
172 final x = '';
173 class A {
174 static final y = 0;
175 }
176 class B = Object with A;
177 ''');
178 expect(outputs, hasLength(3));
179 expect(outputs[COMPILATION_UNIT_CONSTANTS], isNotNull);
180 expect(outputs[COMPILATION_UNIT_ELEMENT], isNotNull);
181 expect(outputs[RESOLVED_UNIT1], isNotNull);
182 }
183
184 test_perform_reuseElement() {
185 _performBuildTask(r'''
186 library lib;
187 class A {}
188 class B = Object with A;
189 ''');
190 CompilationUnit unit = outputs[RESOLVED_UNIT1];
191 CompilationUnitElement unitElement = outputs[COMPILATION_UNIT_ELEMENT];
192 expect(unit, isNotNull);
193 expect(unitElement, isNotNull);
194 // invalidate RESOLVED_UNIT1
195 CacheEntry cacheEntry = analysisCache.get(target);
196 cacheEntry.setState(RESOLVED_UNIT1, CacheState.INVALID);
197 // compute again
198 computeResult(target, RESOLVED_UNIT1,
199 matcher: isBuildCompilationUnitElementTask);
200 expect(outputs[COMPILATION_UNIT_ELEMENT], same(unitElement));
201 expect(outputs[RESOLVED_UNIT1], isNot(same(unit)));
202 }
203
204 void _performBuildTask(String content) {
205 source = newSource('/test.dart', content);
206 target = new LibrarySpecificUnit(source, source);
207 computeResult(target, RESOLVED_UNIT1,
208 matcher: isBuildCompilationUnitElementTask);
209 }
210 }
211
212 @reflectiveTest
213 class BuildDirectiveElementsTaskTest extends _AbstractDartTaskTest {
214 test_perform() {
215 List<Source> sources = newSources({
216 '/libA.dart': '''
217 library libA;
218 import 'libB.dart';
219 export 'libC.dart';
220 ''',
221 '/libB.dart': '''
222 library libB;
223 ''',
224 '/libC.dart': '''
225 library libC;
226 '''
227 });
228 Source sourceA = sources[0];
229 Source sourceB = sources[1];
230 Source sourceC = sources[2];
231 // perform task
232 computeResult(sourceA, LIBRARY_ELEMENT2,
233 matcher: isBuildDirectiveElementsTask);
234 // prepare outputs
235 LibraryElement libraryElementA = outputs[LIBRARY_ELEMENT2];
236 LibraryElement libraryElementB = _getImportLibraryInput(sourceB);
237 LibraryElement libraryElementC = _getExportLibraryInput(sourceC);
238 // no errors
239 _assertErrorsWithCodes([]);
240 // validate directives
241 CompilationUnit libraryUnitA = context
242 .getCacheEntry(new LibrarySpecificUnit(sourceA, sourceA))
243 .getValue(RESOLVED_UNIT1);
244 {
245 ImportDirective importNode = libraryUnitA.directives[1];
246 ImportElement importElement = importNode.element;
247 expect(importElement, isNotNull);
248 expect(importElement.importedLibrary, libraryElementB);
249 expect(importElement.prefix, isNull);
250 expect(importElement.nameOffset, 14);
251 expect(importElement.uriOffset, 21);
252 expect(importElement.uriEnd, 32);
253 }
254 {
255 ExportDirective exportNode = libraryUnitA.directives[2];
256 ExportElement exportElement = exportNode.element;
257 expect(exportElement, isNotNull);
258 expect(exportElement.exportedLibrary, libraryElementC);
259 expect(exportElement.nameOffset, 34);
260 expect(exportElement.uriOffset, 41);
261 expect(exportElement.uriEnd, 52);
262 }
263 // validate LibraryElement
264 expect(libraryElementA.hasExtUri, isFalse);
265 // has an artificial "dart:core" import
266 {
267 List<ImportElement> imports = libraryElementA.imports;
268 expect(imports, hasLength(2));
269 expect(imports[1].importedLibrary.isDartCore, isTrue);
270 expect(imports[1].isSynthetic, isTrue);
271 }
272 }
273
274 test_perform_combinators() {
275 List<Source> sources = newSources({
276 '/libA.dart': '''
277 library libA;
278 import 'libB.dart' show A, B hide C, D;
279 ''',
280 '/libB.dart': '''
281 library libB;
282 '''
283 });
284 Source sourceA = sources[0];
285 // perform task
286 computeResult(sourceA, LIBRARY_ELEMENT2,
287 matcher: isBuildDirectiveElementsTask);
288 // prepare outputs
289 CompilationUnit libraryUnitA = context
290 .getCacheEntry(new LibrarySpecificUnit(sourceA, sourceA))
291 .getValue(RESOLVED_UNIT1);
292 // no errors
293 _assertErrorsWithCodes([]);
294 // validate directives
295 ImportDirective importNode = libraryUnitA.directives[1];
296 ImportElement importElement = importNode.element;
297 List<NamespaceCombinator> combinators = importElement.combinators;
298 expect(combinators, hasLength(2));
299 {
300 ShowElementCombinator combinator = combinators[0];
301 expect(combinator.offset, 33);
302 expect(combinator.end, 42);
303 expect(combinator.shownNames, ['A', 'B']);
304 }
305 {
306 HideElementCombinator combinator = combinators[1];
307 expect(combinator.hiddenNames, ['C', 'D']);
308 }
309 }
310
311 test_perform_dartCoreContext() {
312 List<Source> sources = newSources({'/libA.dart': ''});
313 Source source = sources[0];
314 // perform task
315 computeResult(source, LIBRARY_ELEMENT2,
316 matcher: isBuildDirectiveElementsTask);
317 // prepare outputs
318 LibraryElement libraryElement = outputs[LIBRARY_ELEMENT2];
319 // verify that dart:core has SDK context
320 {
321 LibraryElement coreLibrary = libraryElement.importedLibraries[0];
322 DartSdk dartSdk = context.sourceFactory.dartSdk;
323 expect(coreLibrary.context, same(dartSdk.context));
324 }
325 }
326
327 test_perform_error_exportOfNonLibrary() {
328 List<Source> sources = newSources({
329 '/libA.dart': '''
330 library libA;
331 export 'part.dart';
332 ''',
333 '/part.dart': '''
334 part of notLib;
335 '''
336 });
337 Source sourceA = sources[0];
338 // perform task
339 computeResult(sourceA, LIBRARY_ELEMENT2,
340 matcher: isBuildDirectiveElementsTask);
341 // validate errors
342 _assertErrorsWithCodes([CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY]);
343 }
344
345 test_perform_error_importOfNonLibrary() {
346 List<Source> sources = newSources({
347 '/libA.dart': '''
348 library libA;
349 import 'part.dart';
350 ''',
351 '/part.dart': '''
352 part of notLib;
353 '''
354 });
355 Source sourceA = sources[0];
356 // perform task
357 computeResult(sourceA, LIBRARY_ELEMENT2,
358 matcher: isBuildDirectiveElementsTask);
359 // validate errors
360 _assertErrorsWithCodes([CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY]);
361 }
362
363 test_perform_explicitDartCoreImport() {
364 List<Source> sources = newSources({
365 '/lib.dart': '''
366 library lib;
367 import 'dart:core' show List;
368 '''
369 });
370 Source source = sources[0];
371 // perform task
372 computeResult(source, LIBRARY_ELEMENT2,
373 matcher: isBuildDirectiveElementsTask);
374 // prepare outputs
375 LibraryElement libraryElement = outputs[LIBRARY_ELEMENT2];
376 // has an explicit "dart:core" import
377 {
378 List<ImportElement> imports = libraryElement.imports;
379 expect(imports, hasLength(1));
380 expect(imports[0].importedLibrary.isDartCore, isTrue);
381 expect(imports[0].isSynthetic, isFalse);
382 }
383 }
384
385 test_perform_hasExtUri() {
386 List<Source> sources = newSources({
387 '/lib.dart': '''
388 import 'dart-ext:doesNotExist.dart';
389 '''
390 });
391 Source source = sources[0];
392 // perform task
393 computeResult(source, LIBRARY_ELEMENT2,
394 matcher: isBuildDirectiveElementsTask);
395 // prepare outputs
396 LibraryElement libraryElement = outputs[LIBRARY_ELEMENT2];
397 expect(libraryElement.hasExtUri, isTrue);
398 }
399
400 test_perform_importPrefix() {
401 List<Source> sources = newSources({
402 '/libA.dart': '''
403 library libA;
404 import 'libB.dart' as pref;
405 import 'libC.dart' as pref;
406 ''',
407 '/libB.dart': '''
408 library libB;
409 ''',
410 '/libC.dart': '''
411 library libC;
412 '''
413 });
414 Source sourceA = sources[0];
415 Source sourceB = sources[1];
416 // perform task
417 computeResult(sourceA, LIBRARY_ELEMENT2,
418 matcher: isBuildDirectiveElementsTask);
419 // prepare outputs
420 CompilationUnit libraryUnitA = context
421 .getCacheEntry(new LibrarySpecificUnit(sourceA, sourceA))
422 .getValue(RESOLVED_UNIT1);
423 // validate directives
424 ImportDirective importNodeB = libraryUnitA.directives[1];
425 SimpleIdentifier prefixNodeB = importNodeB.prefix;
426 ImportElement importElementB = importNodeB.element;
427 PrefixElement prefixElement = importElementB.prefix;
428 expect(importElementB, isNotNull);
429 expect(importElementB.importedLibrary, _getImportLibraryInput(sourceB));
430 expect(prefixElement, isNotNull);
431 expect(importElementB.prefixOffset, prefixElement.nameOffset);
432 expect(prefixNodeB.staticElement, prefixElement);
433 // PrefixElement "pref" is shared
434 ImportDirective importNodeC = libraryUnitA.directives[2];
435 SimpleIdentifier prefixNodeC = importNodeC.prefix;
436 ImportElement importElementC = importNodeC.element;
437 expect(prefixNodeC.staticElement, prefixElement);
438 expect(importElementC.prefix, prefixElement);
439 }
440
441 void _assertErrorsWithCodes(List<ErrorCode> expectedErrorCodes) {
442 _fillErrorListener(BUILD_DIRECTIVES_ERRORS);
443 errorListener.assertErrorsWithCodes(expectedErrorCodes);
444 }
445
446 _getExportLibraryInput(Source source) {
447 var key = BuildDirectiveElementsTask.EXPORTS_LIBRARY_ELEMENT_INPUT_NAME;
448 return task.inputs[key][source];
449 }
450
451 _getImportLibraryInput(Source source) {
452 var key = BuildDirectiveElementsTask.IMPORTS_LIBRARY_ELEMENT_INPUT_NAME;
453 return task.inputs[key][source];
454 }
455 }
456
457 @reflectiveTest
458 class BuildEnumMemberElementsTaskTest extends _AbstractDartTaskTest {
459 test_perform() {
460 Source source = newSource(
461 '/test.dart',
462 '''
463 enum MyEnum {
464 A, B
465 }
466 ''');
467 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT2,
468 matcher: isBuildEnumMemberElementsTask);
469 CompilationUnit unit = outputs[RESOLVED_UNIT2];
470 // validate Element
471 ClassElement enumElement = unit.element.getEnum('MyEnum');
472 List<FieldElement> fields = enumElement.fields;
473 expect(fields, hasLength(4));
474 {
475 FieldElementImpl index = fields[0];
476 expect(index, isNotNull);
477 expect(index.name, 'index');
478 expect(index.isStatic, isFalse);
479 expect(index.evaluationResult, isNull);
480 _assertGetter(index);
481 }
482 {
483 ConstFieldElementImpl values = fields[1];
484 expect(values, isNotNull);
485 expect(values.name, 'values');
486 expect(values.isStatic, isTrue);
487 expect(values.evaluationResult, isNotNull);
488 _assertGetter(values);
489 }
490 {
491 ConstFieldElementImpl constant = fields[2];
492 expect(constant, isNotNull);
493 expect(constant.name, 'A');
494 expect(constant.isStatic, isTrue);
495 expect(constant.evaluationResult, isNotNull);
496 _assertGetter(constant);
497 }
498 {
499 ConstFieldElementImpl constant = fields[3];
500 expect(constant, isNotNull);
501 expect(constant.name, 'B');
502 expect(constant.isStatic, isTrue);
503 expect(constant.evaluationResult, isNotNull);
504 _assertGetter(constant);
505 }
506 // validate nodes
507 EnumDeclaration enumNode = unit.declarations[0];
508 expect(enumNode.name.staticElement, same(enumElement));
509 expect(enumNode.constants[0].element, same(enumElement.getField('A')));
510 expect(enumNode.constants[1].element, same(enumElement.getField('B')));
511 }
512
513 static void _assertGetter(FieldElement field) {
514 PropertyAccessorElement getter = field.getter;
515 expect(getter, isNotNull);
516 expect(getter.variable, same(field));
517 expect(getter.type, isNotNull);
518 }
519 }
520
521 @reflectiveTest
522 class BuildExportNamespaceTaskTest extends _AbstractDartTaskTest {
523 test_perform_entryPoint() {
524 Source sourceA = newSource(
525 '/a.dart',
526 '''
527 library lib_a;
528 export 'b.dart';
529 ''');
530 Source sourceB = newSource(
531 '/b.dart',
532 '''
533 library lib_b;
534 main() {}
535 ''');
536 computeResult(sourceA, LIBRARY_ELEMENT4,
537 matcher: isBuildExportNamespaceTask);
538 // validate
539 LibraryElement library = outputs[LIBRARY_ELEMENT4];
540 FunctionElement entryPoint = library.entryPoint;
541 expect(entryPoint, isNotNull);
542 expect(entryPoint.source, sourceB);
543 }
544
545 test_perform_hideCombinator() {
546 Source sourceA = newSource(
547 '/a.dart',
548 '''
549 library lib_a;
550 export 'b.dart' hide B1;
551 class A1 {}
552 class A2 {}
553 class _A3 {}
554 ''');
555 newSource(
556 '/b.dart',
557 '''
558 library lib_b;
559 class B1 {}
560 class B2 {}
561 class B3 {}
562 class _B4 {}
563 ''');
564 newSource(
565 '/c.dart',
566 '''
567 library lib_c;
568 class C1 {}
569 class C2 {}
570 class C3 {}
571 ''');
572 computeResult(sourceA, LIBRARY_ELEMENT4,
573 matcher: isBuildExportNamespaceTask);
574 // validate
575 LibraryElement library = outputs[LIBRARY_ELEMENT4];
576 Namespace namespace = library.exportNamespace;
577 Iterable<String> definedKeys = namespace.definedNames.keys;
578 expect(definedKeys, unorderedEquals(['A1', 'A2', 'B2', 'B3']));
579 }
580
581 test_perform_showCombinator() {
582 Source sourceA = newSource(
583 '/a.dart',
584 '''
585 library lib_a;
586 export 'b.dart' show B1;
587 class A1 {}
588 class A2 {}
589 class _A3 {}
590 ''');
591 newSource(
592 '/b.dart',
593 '''
594 library lib_b;
595 class B1 {}
596 class B2 {}
597 class _B3 {}
598 ''');
599 computeResult(sourceA, LIBRARY_ELEMENT4,
600 matcher: isBuildExportNamespaceTask);
601 // validate
602 LibraryElement library = outputs[LIBRARY_ELEMENT4];
603 Namespace namespace = library.exportNamespace;
604 Iterable<String> definedKeys = namespace.definedNames.keys;
605 expect(definedKeys, unorderedEquals(['A1', 'A2', 'B1']));
606 }
607
608 test_perform_showCombinator_setter() {
609 Source sourceA = newSource(
610 '/a.dart',
611 '''
612 library lib_a;
613 export 'b.dart' show topLevelB;
614 class A {}
615 ''');
616 newSource(
617 '/b.dart',
618 '''
619 library lib_b;
620 int topLevelB;
621 ''');
622 computeResult(sourceA, LIBRARY_ELEMENT4,
623 matcher: isBuildExportNamespaceTask);
624 // validate
625 LibraryElement library = outputs[LIBRARY_ELEMENT4];
626 Namespace namespace = library.exportNamespace;
627 Iterable<String> definedKeys = namespace.definedNames.keys;
628 expect(definedKeys, unorderedEquals(['A', 'topLevelB', 'topLevelB=']));
629 }
630 }
631
632 @reflectiveTest
633 class BuildLibraryElementTaskTest extends _AbstractDartTaskTest {
634 Source librarySource;
635 CompilationUnit libraryUnit;
636 CompilationUnitElement libraryUnitElement;
637 List<CompilationUnit> partUnits;
638
639 LibraryElement libraryElement;
640
641 test_perform() {
642 _performBuildTask({
643 '/lib.dart': '''
644 library lib;
645 part 'part1.dart';
646 part 'part2.dart';
647 ''',
648 '/part1.dart': '''
649 part of lib;
650 ''',
651 '/part2.dart': '''
652 part of lib;
653 '''
654 });
655 expect(outputs, hasLength(3));
656 // simple outputs
657 expect(outputs[BUILD_LIBRARY_ERRORS], isEmpty);
658 expect(outputs[IS_LAUNCHABLE], isFalse);
659 // LibraryElement output
660 expect(libraryElement, isNotNull);
661 expect(libraryElement.entryPoint, isNull);
662 expect(libraryElement.source, same(librarySource));
663 expect(libraryElement.definingCompilationUnit, libraryUnitElement);
664 expect(libraryElement.parts,
665 unorderedEquals([partUnits[0].element, partUnits[1].element]));
666 // LibraryElement references
667 expect((libraryUnit.directives[0] as LibraryDirective).element,
668 same(libraryElement));
669 expect((partUnits[0].directives[0] as PartOfDirective).element,
670 same(libraryElement));
671 expect((partUnits[1].directives[0] as PartOfDirective).element,
672 same(libraryElement));
673 // CompilationUnitElement(s)
674 CompilationUnitElement firstPart;
675 CompilationUnitElement secondPart;
676 if (partUnits[0].element.uri == 'part1.dart') {
677 firstPart = partUnits[0].element;
678 secondPart = partUnits[1].element;
679 } else {
680 firstPart = partUnits[1].element;
681 secondPart = partUnits[0].element;
682 }
683 expect(firstPart.uri, 'part1.dart');
684 expect(firstPart.uriOffset, 18);
685 expect(firstPart.uriEnd, 30);
686 expect(
687 (libraryUnit.directives[1] as PartDirective).element, same(firstPart));
688
689 expect(secondPart.uri, 'part2.dart');
690 expect(secondPart.uriOffset, 37);
691 expect(secondPart.uriEnd, 49);
692 expect(
693 (libraryUnit.directives[2] as PartDirective).element, same(secondPart));
694 }
695
696 test_perform_error_missingLibraryDirectiveWithPart_hasCommon() {
697 _performBuildTask({
698 '/lib.dart': '''
699 part 'partA.dart';
700 part 'partB.dart';
701 ''',
702 '/partA.dart': '''
703 part of my_lib;
704 ''',
705 '/partB.dart': '''
706 part of my_lib;
707 '''
708 });
709 _assertErrorsWithCodes(
710 [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]);
711 AnalysisError error = errorListener.errors[0];
712 expect(error.getProperty(ErrorProperty.PARTS_LIBRARY_NAME), 'my_lib');
713 }
714
715 test_perform_error_missingLibraryDirectiveWithPart_noCommon() {
716 _performBuildTask({
717 '/lib.dart': '''
718 part 'partA.dart';
719 part 'partB.dart';
720 ''',
721 '/partA.dart': '''
722 part of libA;
723 ''',
724 '/partB.dart': '''
725 part of libB;
726 '''
727 });
728 _assertErrorsWithCodes(
729 [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]);
730 AnalysisError error = errorListener.errors[0];
731 expect(error.getProperty(ErrorProperty.PARTS_LIBRARY_NAME), isNull);
732 }
733
734 test_perform_error_partDoesNotExist() {
735 _performBuildTask({
736 '/lib.dart': '''
737 library lib;
738 part 'part.dart';
739 '''
740 });
741 // we already report URI_DOES_NOT_EXIST, no need to report other errors
742 _assertErrorsWithCodes([]);
743 }
744
745 test_perform_error_partOfDifferentLibrary() {
746 _performBuildTask({
747 '/lib.dart': '''
748 library lib;
749 part 'part.dart';
750 ''',
751 '/part.dart': '''
752 part of someOtherLib;
753 '''
754 });
755 _assertErrorsWithCodes([StaticWarningCode.PART_OF_DIFFERENT_LIBRARY]);
756 }
757
758 test_perform_error_partOfNonPart() {
759 _performBuildTask({
760 '/lib.dart': '''
761 library lib;
762 part 'part.dart';
763 ''',
764 '/part.dart': '''
765 // no part of
766 '''
767 });
768 _assertErrorsWithCodes([CompileTimeErrorCode.PART_OF_NON_PART]);
769 }
770
771 test_perform_invalidUri_part() {
772 _performBuildTask({
773 '/lib.dart': '''
774 library lib;
775 part '//////////';
776 '''
777 });
778 expect(libraryElement.parts, isEmpty);
779 }
780
781 test_perform_isLaunchable_inDefiningUnit() {
782 _performBuildTask({
783 '/lib.dart': '''
784 library lib;
785 main() {
786 }
787 '''
788 });
789 expect(outputs[IS_LAUNCHABLE], isTrue);
790 expect(libraryElement.entryPoint, isNotNull);
791 }
792
793 test_perform_isLaunchable_inPartUnit() {
794 _performBuildTask({
795 '/lib.dart': '''
796 library lib;
797 part 'part.dart';
798 ''',
799 '/part.dart': '''
800 part of lib;
801 main() {
802 }
803 '''
804 });
805 expect(outputs[IS_LAUNCHABLE], isTrue);
806 expect(libraryElement.entryPoint, isNotNull);
807 }
808
809 test_perform_noSuchFilePart() {
810 _performBuildTask({
811 '/lib.dart': '''
812 library lib;
813 part 'no-such-file.dart';
814 '''
815 });
816 expect(libraryElement.parts, hasLength(1));
817 CompilationUnitElement part = libraryElement.parts[0];
818 expect(part, isNotNull);
819 expect(part.source, isNotNull);
820 expect(part.library, same(libraryElement));
821 expect(context.exists(part.source), isFalse);
822 }
823
824 test_perform_patchTopLevelAccessors() {
825 _performBuildTask({
826 '/lib.dart': '''
827 library lib;
828 part 'part1.dart';
829 part 'part2.dart';
830 ''',
831 '/part1.dart': '''
832 part of lib;
833 int get test => 0;
834 ''',
835 '/part2.dart': '''
836 part of lib;
837 void set test(_) {}
838 '''
839 });
840 CompilationUnitElement unitElement1 = partUnits[0].element;
841 CompilationUnitElement unitElement2 = partUnits[1].element;
842 PropertyAccessorElement getter = unitElement1.accessors[0];
843 PropertyAccessorElement setter = unitElement2.accessors[0];
844 PropertyInducingElement variable = getter.variable;
845 expect(getter.isGetter, isTrue);
846 expect(setter.isSetter, isTrue);
847 expect(variable, isNotNull);
848 expect(setter.variable, same(variable));
849 expect(unitElement1.topLevelVariables, [variable]);
850 expect(unitElement2.topLevelVariables, [variable]);
851 }
852
853 void _assertErrorsWithCodes(List<ErrorCode> expectedErrorCodes) {
854 _fillErrorListener(BUILD_LIBRARY_ERRORS);
855 errorListener.assertErrorsWithCodes(expectedErrorCodes);
856 }
857
858 void _performBuildTask(Map<String, String> sourceMap) {
859 List<Source> sources = newSources(sourceMap);
860 Source libSource = sources.first;
861 computeResult(libSource, LIBRARY_ELEMENT1,
862 matcher: isBuildLibraryElementTask);
863 libraryUnit = context
864 .getCacheEntry(new LibrarySpecificUnit(libSource, libSource))
865 .getValue(RESOLVED_UNIT1);
866 libraryUnitElement = libraryUnit.element;
867 librarySource = libraryUnitElement.source;
868 libraryElement = outputs[LIBRARY_ELEMENT1];
869 partUnits = task.inputs[BuildLibraryElementTask.PARTS_UNIT_INPUT];
870 }
871 }
872
873 @reflectiveTest
874 class BuildPublicNamespaceTaskTest extends _AbstractDartTaskTest {
875 test_perform() {
876 List<Source> sources = newSources({
877 '/lib.dart': '''
878 library lib;
879 part 'part.dart';
880 a() {}
881 _b() {}
882 ''',
883 '/part.dart': '''
884 part of lib;
885 _c() {}
886 d() {}
887 '''
888 });
889 computeResult(sources.first, LIBRARY_ELEMENT3,
890 matcher: isBuildPublicNamespaceTask);
891 // validate
892 LibraryElement library = outputs[LIBRARY_ELEMENT3];
893 Namespace namespace = library.publicNamespace;
894 expect(namespace.definedNames.keys, unorderedEquals(['a', 'd']));
895 }
896 }
897
898 @reflectiveTest
899 class BuildSourceExportClosureTaskTest extends _AbstractDartTaskTest {
900 test_perform_exportClosure() {
901 Source sourceA = newSource(
902 '/a.dart',
903 '''
904 library lib_a;
905 export 'b.dart';
906 ''');
907 Source sourceB = newSource(
908 '/b.dart',
909 '''
910 library lib_b;
911 export 'c.dart';
912 ''');
913 Source sourceC = newSource(
914 '/c.dart',
915 '''
916 library lib_c;
917 export 'a.dart';
918 ''');
919 Source sourceD = newSource(
920 '/d.dart',
921 '''
922 library lib_d;
923 ''');
924 // a.dart
925 {
926 computeResult(sourceA, EXPORT_SOURCE_CLOSURE,
927 matcher: isBuildSourceExportClosureTask);
928 List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE];
929 expect(closure, unorderedEquals([sourceA, sourceB, sourceC]));
930 }
931 // c.dart
932 {
933 computeResult(sourceC, EXPORT_SOURCE_CLOSURE,
934 matcher: isBuildSourceExportClosureTask);
935 List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE];
936 expect(closure, unorderedEquals([sourceA, sourceB, sourceC]));
937 }
938 // d.dart
939 {
940 computeResult(sourceD, EXPORT_SOURCE_CLOSURE,
941 matcher: isBuildSourceExportClosureTask);
942 List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE];
943 expect(closure, unorderedEquals([sourceD]));
944 }
945 }
946 }
947
948 @reflectiveTest
949 class BuildSourceImportExportClosureTaskTest extends _AbstractDartTaskTest {
950 test_perform_importExportClosure() {
951 Source sourceA = newSource(
952 '/a.dart',
953 '''
954 library lib_a;
955 ''');
956 Source sourceB = newSource(
957 '/b.dart',
958 '''
959 library lib_b;
960 export 'a.dart';
961 ''');
962 Source sourceC = newSource(
963 '/c.dart',
964 '''
965 library lib_c;
966 import 'b.dart';
967 ''');
968 Source coreSource = context.sourceFactory.resolveUri(null, 'dart:core');
969 // c.dart
970 {
971 computeResult(sourceC, IMPORT_EXPORT_SOURCE_CLOSURE,
972 matcher: isBuildSourceImportExportClosureTask);
973 List<Source> closure = outputs[IMPORT_EXPORT_SOURCE_CLOSURE];
974 expect(closure, contains(sourceA));
975 expect(closure, contains(sourceB));
976 expect(closure, contains(sourceC));
977 expect(closure, contains(coreSource));
978 }
979 // b.dart
980 {
981 computeResult(sourceB, IMPORT_EXPORT_SOURCE_CLOSURE,
982 matcher: isBuildSourceImportExportClosureTask);
983 List<Source> closure = outputs[IMPORT_EXPORT_SOURCE_CLOSURE];
984 expect(closure, contains(sourceA));
985 expect(closure, contains(sourceB));
986 expect(closure, contains(coreSource));
987 }
988 }
989
990 test_perform_isClient_false() {
991 Source sourceA = newSource(
992 '/a.dart',
993 '''
994 library lib_a;
995 import 'b.dart';
996 ''');
997 newSource(
998 '/b.dart',
999 '''
1000 library lib_b;
1001 ''');
1002 computeResult(sourceA, IS_CLIENT,
1003 matcher: isBuildSourceImportExportClosureTask);
1004 expect(outputs[IS_CLIENT], isFalse);
1005 }
1006
1007 test_perform_isClient_true_export_indirect() {
1008 newSource(
1009 '/exports_html.dart',
1010 '''
1011 library lib_exports_html;
1012 export 'dart:html';
1013 ''');
1014 Source source = newSource(
1015 '/test.dart',
1016 '''
1017 import 'exports_html.dart';
1018 ''');
1019 computeResult(source, IS_CLIENT,
1020 matcher: isBuildSourceImportExportClosureTask);
1021 expect(outputs[IS_CLIENT], isTrue);
1022 }
1023
1024 test_perform_isClient_true_import_direct() {
1025 Source sourceA = newSource(
1026 '/a.dart',
1027 '''
1028 library lib_a;
1029 import 'dart:html';
1030 ''');
1031 computeResult(sourceA, IS_CLIENT,
1032 matcher: isBuildSourceImportExportClosureTask);
1033 expect(outputs[IS_CLIENT], isTrue);
1034 }
1035
1036 test_perform_isClient_true_import_indirect() {
1037 Source sourceA = newSource(
1038 '/a.dart',
1039 '''
1040 library lib_a;
1041 import 'b.dart';
1042 ''');
1043 newSource(
1044 '/b.dart',
1045 '''
1046 library lib_b;
1047 import 'dart:html';
1048 ''');
1049 computeResult(sourceA, IS_CLIENT,
1050 matcher: isBuildSourceImportExportClosureTask);
1051 expect(outputs[IS_CLIENT], isTrue);
1052 }
1053 }
1054
1055 @reflectiveTest
1056 class BuildTypeProviderTaskTest extends _AbstractDartTaskTest {
1057 test_perform() {
1058 computeResult(AnalysisContextTarget.request, TYPE_PROVIDER,
1059 matcher: isBuildTypeProviderTask);
1060 // validate
1061 TypeProvider typeProvider = outputs[TYPE_PROVIDER];
1062 expect(typeProvider, isNotNull);
1063 expect(typeProvider.boolType, isNotNull);
1064 expect(typeProvider.intType, isNotNull);
1065 expect(typeProvider.futureType, isNotNull);
1066 }
1067 }
1068
1069 @reflectiveTest
1070 class ComputeConstantDependenciesTaskTest extends _AbstractDartTaskTest {
1071 Annotation findClassAnnotation(CompilationUnit unit, String className) {
1072 for (CompilationUnitMember member in unit.declarations) {
1073 if (member is ClassDeclaration && member.name.name == className) {
1074 expect(member.metadata, hasLength(1));
1075 return member.metadata[0];
1076 }
1077 }
1078 fail('Annotation not found');
1079 return null;
1080 }
1081
1082 test_annotation_with_args() {
1083 Source source = newSource(
1084 '/test.dart',
1085 '''
1086 const x = 1;
1087 @D(x) class C {}
1088 class D { const D(value); }
1089 ''');
1090 // First compute the resolved unit for the source.
1091 LibrarySpecificUnit librarySpecificUnit =
1092 new LibrarySpecificUnit(source, source);
1093 computeResult(librarySpecificUnit, RESOLVED_UNIT1);
1094 CompilationUnit unit = outputs[RESOLVED_UNIT1];
1095 // Find the elements for x and D's constructor, and the annotation on C.
1096 List<PropertyAccessorElement> accessors = unit.element.accessors;
1097 Element x = accessors
1098 .firstWhere((PropertyAccessorElement accessor) =>
1099 accessor.isGetter && accessor.name == 'x')
1100 .variable;
1101 List<ClassElement> types = unit.element.types;
1102 Element constructorForD =
1103 types.firstWhere((ClassElement cls) => cls.name == 'D').constructors[0];
1104 Annotation annotation = findClassAnnotation(unit, 'C');
1105 // Now compute the dependencies for the annotation, and check that it is
1106 // the set [x, constructorForD].
1107 // TODO(paulberry): test librarySource != source
1108 computeResult(
1109 new ConstantEvaluationTarget_Annotation(
1110 context, source, source, annotation),
1111 CONSTANT_DEPENDENCIES,
1112 matcher: isComputeConstantDependenciesTask);
1113 expect(
1114 outputs[CONSTANT_DEPENDENCIES].toSet(), [x, constructorForD].toSet());
1115 }
1116
1117 test_annotation_without_args() {
1118 Source source = newSource(
1119 '/test.dart',
1120 '''
1121 const x = 1;
1122 @x class C {}
1123 ''');
1124 // First compute the resolved unit for the source.
1125 LibrarySpecificUnit librarySpecificUnit =
1126 new LibrarySpecificUnit(source, source);
1127 computeResult(librarySpecificUnit, RESOLVED_UNIT1);
1128 CompilationUnit unit = outputs[RESOLVED_UNIT1];
1129 // Find the element for x and the annotation on C.
1130 List<PropertyAccessorElement> accessors = unit.element.accessors;
1131 Element x = accessors
1132 .firstWhere((PropertyAccessorElement accessor) =>
1133 accessor.isGetter && accessor.name == 'x')
1134 .variable;
1135 Annotation annotation = findClassAnnotation(unit, 'C');
1136 // Now compute the dependencies for the annotation, and check that it is
1137 // the list [x].
1138 computeResult(
1139 new ConstantEvaluationTarget_Annotation(
1140 context, source, source, annotation),
1141 CONSTANT_DEPENDENCIES,
1142 matcher: isComputeConstantDependenciesTask);
1143 expect(outputs[CONSTANT_DEPENDENCIES], [x]);
1144 }
1145
1146 test_enumConstant() {
1147 Source source = newSource(
1148 '/test.dart',
1149 '''
1150 enum E {A, B, C}
1151 ''');
1152 // First compute the resolved unit for the source.
1153 LibrarySpecificUnit librarySpecificUnit =
1154 new LibrarySpecificUnit(source, source);
1155 computeResult(librarySpecificUnit, RESOLVED_UNIT2);
1156 CompilationUnit unit = outputs[RESOLVED_UNIT2];
1157 // Find the element for 'A'
1158 EnumDeclaration enumDeclaration = unit.declarations[0];
1159 EnumConstantDeclaration constantDeclaration = enumDeclaration.constants[0];
1160 FieldElement constantElement = constantDeclaration.element;
1161 // Now compute the dependencies for the constant and check that there are
1162 // none.
1163 computeResult(constantElement, CONSTANT_DEPENDENCIES,
1164 matcher: isComputeConstantDependenciesTask);
1165 expect(outputs[CONSTANT_DEPENDENCIES], isEmpty);
1166 }
1167
1168 test_perform() {
1169 Source source = newSource(
1170 '/test.dart',
1171 '''
1172 const x = y;
1173 const y = 1;
1174 ''');
1175 // First compute the resolved unit for the source.
1176 LibrarySpecificUnit librarySpecificUnit =
1177 new LibrarySpecificUnit(source, source);
1178 computeResult(librarySpecificUnit, RESOLVED_UNIT1);
1179 CompilationUnit unit = outputs[RESOLVED_UNIT1];
1180 // Find the elements for the constants x and y.
1181 List<PropertyAccessorElement> accessors = unit.element.accessors;
1182 Element x = accessors
1183 .firstWhere((PropertyAccessorElement accessor) =>
1184 accessor.isGetter && accessor.name == 'x')
1185 .variable;
1186 Element y = accessors
1187 .firstWhere((PropertyAccessorElement accessor) =>
1188 accessor.isGetter && accessor.name == 'y')
1189 .variable;
1190 // Now compute the dependencies for x, and check that it is the list [y].
1191 computeResult(x, CONSTANT_DEPENDENCIES,
1192 matcher: isComputeConstantDependenciesTask);
1193 expect(outputs[CONSTANT_DEPENDENCIES], [y]);
1194 }
1195 }
1196
1197 @reflectiveTest
1198 class ComputeConstantValueTaskTest extends _AbstractDartTaskTest {
1199 EvaluationResultImpl computeClassAnnotation(
1200 Source source, CompilationUnit unit, String className) {
1201 for (CompilationUnitMember member in unit.declarations) {
1202 if (member is ClassDeclaration && member.name.name == className) {
1203 expect(member.metadata, hasLength(1));
1204 Annotation annotation = member.metadata[0];
1205 ConstantEvaluationTarget_Annotation target =
1206 new ConstantEvaluationTarget_Annotation(
1207 context, source, source, annotation);
1208 computeResult(target, CONSTANT_VALUE,
1209 matcher: isComputeConstantValueTask);
1210 expect(outputs[CONSTANT_VALUE], same(target));
1211 EvaluationResultImpl evaluationResult = (annotation.elementAnnotation
1212 as ElementAnnotationImpl).evaluationResult;
1213 return evaluationResult;
1214 }
1215 }
1216 fail('Annotation not found');
1217 return null;
1218 }
1219
1220 test_annotation_non_const_constructor() {
1221 // Calling a non-const constructor from an annotation that is illegal, but
1222 // shouldn't crash analysis.
1223 Source source = newSource(
1224 '/test.dart',
1225 '''
1226 class A {
1227 final int i;
1228 A(this.i);
1229 }
1230
1231 @A(5)
1232 class C {}
1233 ''');
1234 // First compute the resolved unit for the source.
1235 CompilationUnit unit = _resolveSource(source);
1236 // Compute the constant value of the annotation on C.
1237 EvaluationResultImpl evaluationResult =
1238 computeClassAnnotation(source, unit, 'C');
1239 // And check that it has no value stored in it.
1240 expect(evaluationResult, isNotNull);
1241 expect(evaluationResult.value, isNull);
1242 }
1243
1244 test_annotation_with_args() {
1245 Source source = newSource(
1246 '/test.dart',
1247 '''
1248 const x = 1;
1249 @D(x) class C {}
1250 class D {
1251 const D(this.value);
1252 final value;
1253 }
1254 ''');
1255 // First compute the resolved unit for the source.
1256 CompilationUnit unit = _resolveSource(source);
1257 // Compute the constant value of the annotation on C.
1258 EvaluationResultImpl evaluationResult =
1259 computeClassAnnotation(source, unit, 'C');
1260 // And check that it has the expected value.
1261 expect(evaluationResult, isNotNull);
1262 expect(evaluationResult.value, isNotNull);
1263 expect(evaluationResult.value.type, isNotNull);
1264 expect(evaluationResult.value.type.name, 'D');
1265 expect(evaluationResult.value.fields, contains('value'));
1266 expect(evaluationResult.value.fields['value'].intValue, 1);
1267 }
1268
1269 test_annotation_without_args() {
1270 Source source = newSource(
1271 '/test.dart',
1272 '''
1273 const x = 1;
1274 @x class C {}
1275 ''');
1276 // First compute the resolved unit for the source.
1277 CompilationUnit unit = _resolveSource(source);
1278 // Compute the constant value of the annotation on C.
1279 EvaluationResultImpl evaluationResult =
1280 computeClassAnnotation(source, unit, 'C');
1281 // And check that it has the expected value.
1282 expect(evaluationResult, isNotNull);
1283 expect(evaluationResult.value, isNotNull);
1284 expect(evaluationResult.value.intValue, 1);
1285 }
1286
1287 test_circular_reference() {
1288 _checkCircularities(
1289 'x',
1290 ['y'],
1291 '''
1292 const x = y + 1;
1293 const y = x + 1;
1294 ''');
1295 }
1296
1297 test_circular_reference_one_element() {
1298 // See dartbug.com/23490.
1299 _checkCircularities('x', [], 'const x = x;');
1300 }
1301
1302 test_circular_reference_strongly_connected_component() {
1303 // When there is a circularity, all elements in the strongly connected
1304 // component should be marked as having an error.
1305 _checkCircularities(
1306 'a',
1307 ['b', 'c', 'd'],
1308 '''
1309 const a = b;
1310 const b = c + d;
1311 const c = a;
1312 const d = a;
1313 ''');
1314 }
1315
1316 test_const_constructor_calls_implicit_super_constructor_implicitly() {
1317 // Note: the situation below is a compile-time error (since the synthetic
1318 // constructor for Base is non-const), but we need to handle it without
1319 // throwing an exception.
1320 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue(
1321 'x',
1322 '''
1323 class Base {}
1324 class Derived extends Base {
1325 const Derived();
1326 }
1327 const x = const Derived();
1328 ''');
1329 expect(evaluationResult, isNotNull);
1330 }
1331
1332 test_dependency() {
1333 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue(
1334 'x',
1335 '''
1336 const x = y + 1;
1337 const y = 1;
1338 ''');
1339 expect(evaluationResult, isNotNull);
1340 expect(evaluationResult.value, isNotNull);
1341 expect(evaluationResult.value.intValue, 2);
1342 }
1343
1344 test_external_const_factory() {
1345 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue(
1346 'x',
1347 '''
1348 const x = const C.foo();
1349
1350 class C extends B {
1351 external const factory C.foo();
1352 }
1353
1354 class B {}
1355 ''');
1356 expect(evaluationResult, isNotNull);
1357 }
1358
1359 test_simple_constant() {
1360 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue(
1361 'x',
1362 '''
1363 const x = 1;
1364 ''');
1365 expect(evaluationResult, isNotNull);
1366 expect(evaluationResult.value, isNotNull);
1367 expect(evaluationResult.value.intValue, 1);
1368 }
1369
1370 void _checkCircularities(
1371 String variableName, List<String> otherVariables, String content) {
1372 // Evaluating the first constant should produce an error.
1373 CompilationUnit unit = _resolveUnit(content);
1374 _expectCircularityError(_evaluateConstant(unit, variableName));
1375 // And all the other constants involved in the strongly connected component
1376 // should be set to the same error state.
1377 for (String otherVariableName in otherVariables) {
1378 PropertyInducingElement otherVariableElement =
1379 _findVariable(unit, otherVariableName);
1380 _expectCircularityError((otherVariableElement
1381 as TopLevelVariableElementImpl).evaluationResult);
1382 }
1383 }
1384
1385 EvaluationResultImpl _computeTopLevelVariableConstValue(
1386 String variableName, String content) {
1387 return _evaluateConstant(_resolveUnit(content), variableName);
1388 }
1389
1390 EvaluationResultImpl _evaluateConstant(
1391 CompilationUnit unit, String variableName) {
1392 // Find the element for the given constant.
1393 PropertyInducingElement variableElement = _findVariable(unit, variableName);
1394 // Now compute the value of the constant.
1395 computeResult(variableElement, CONSTANT_VALUE,
1396 matcher: isComputeConstantValueTask);
1397 expect(outputs[CONSTANT_VALUE], same(variableElement));
1398 EvaluationResultImpl evaluationResult =
1399 (variableElement as TopLevelVariableElementImpl).evaluationResult;
1400 return evaluationResult;
1401 }
1402
1403 void _expectCircularityError(EvaluationResultImpl evaluationResult) {
1404 expect(evaluationResult, isNotNull);
1405 expect(evaluationResult.value, isNull);
1406 expect(evaluationResult.errors, hasLength(1));
1407 expect(evaluationResult.errors[0].errorCode,
1408 CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT);
1409 }
1410
1411 PropertyInducingElement _findVariable(
1412 CompilationUnit unit, String variableName) {
1413 // Find the element for the given constant.
1414 return unit.element.topLevelVariables.firstWhere(
1415 (TopLevelVariableElement variable) => variable.name == variableName);
1416 }
1417
1418 CompilationUnit _resolveSource(Source source) {
1419 LibrarySpecificUnit librarySpecificUnit =
1420 new LibrarySpecificUnit(source, source);
1421 computeResult(librarySpecificUnit, RESOLVED_UNIT1);
1422 CompilationUnit unit = outputs[RESOLVED_UNIT1];
1423 return unit;
1424 }
1425
1426 CompilationUnit _resolveUnit(String content) =>
1427 _resolveSource(newSource('/test.dart', content));
1428 }
1429
1430 @reflectiveTest
1431 class ComputeInferableStaticVariableDependenciesTaskTest
1432 extends _AbstractDartTaskTest {
1433 @override
1434 void setUp() {
1435 super.setUp();
1436 // Variable dependencies are only available in strong mode.
1437 enableStrongMode();
1438 }
1439
1440 test_perform() {
1441 AnalysisTarget source = newSource(
1442 '/test.dart',
1443 '''
1444 const a = b;
1445 const b = 0;
1446 ''');
1447 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
1448 computeResult(target, RESOLVED_UNIT5);
1449 CompilationUnit unit = outputs[RESOLVED_UNIT5];
1450 TopLevelVariableElement elementA = unit.element.topLevelVariables[0];
1451 TopLevelVariableElement elementB = unit.element.topLevelVariables[1];
1452
1453 computeResult(elementA, INFERABLE_STATIC_VARIABLE_DEPENDENCIES,
1454 matcher: isComputeInferableStaticVariableDependenciesTask);
1455 expect(outputs, hasLength(1));
1456 List<VariableElement> dependencies =
1457 outputs[INFERABLE_STATIC_VARIABLE_DEPENDENCIES];
1458 expect(dependencies, unorderedEquals([elementB]));
1459 }
1460 }
1461
1462 @reflectiveTest
1463 class ComputeLibraryCycleTaskTest extends _AbstractDartTaskTest {
1464 @override
1465 void setUp() {
1466 super.setUp();
1467 enableStrongMode();
1468 }
1469
1470 void test_library_cycle_linear() {
1471 List<Source> sources = newSources({
1472 '/a.dart': '''
1473 ''',
1474 '/b.dart': '''
1475 import 'a.dart';
1476 '''
1477 });
1478 List<Map<ResultDescriptor, dynamic>> results =
1479 computeLibraryResultsMap(sources, LIBRARY_CYCLE);
1480 List<LibraryElement> component0 = results[0][LIBRARY_CYCLE];
1481 List<LibraryElement> component1 = results[1][LIBRARY_CYCLE];
1482 expect(component0, hasLength(1));
1483 expect(component1, hasLength(1));
1484
1485 List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS];
1486 List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS];
1487 expect(units0, hasLength(1));
1488 expect(units1, hasLength(1));
1489
1490 List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES];
1491 List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES];
1492 expect(dep0, hasLength(1)); // dart:core
1493 expect(dep1, hasLength(2)); // dart:core, a.dart
1494 }
1495
1496 void test_library_cycle_loop() {
1497 List<Source> sources = newSources({
1498 '/a.dart': '''
1499 import 'c.dart';
1500 ''',
1501 '/b.dart': '''
1502 import 'a.dart';
1503 ''',
1504 '/c.dart': '''
1505 import 'b.dart';
1506 '''
1507 });
1508 List<Map<ResultDescriptor, dynamic>> results =
1509 computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList();
1510 List<LibraryElement> component0 = results[0][LIBRARY_CYCLE];
1511 List<LibraryElement> component1 = results[1][LIBRARY_CYCLE];
1512 List<LibraryElement> component2 = results[2][LIBRARY_CYCLE];
1513
1514 expect(component0, hasLength(3));
1515 expect(component1, hasLength(3));
1516 expect(component2, hasLength(3));
1517
1518 List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS];
1519 List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS];
1520 List<CompilationUnitElement> units2 = results[2][LIBRARY_CYCLE_UNITS];
1521 expect(units0, hasLength(3));
1522 expect(units1, hasLength(3));
1523 expect(units2, hasLength(3));
1524
1525 List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES];
1526 List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES];
1527 List<CompilationUnitElement> dep2 = results[2][LIBRARY_CYCLE_DEPENDENCIES];
1528 expect(dep0, hasLength(1)); // dart:core
1529 expect(dep1, hasLength(1)); // dart:core
1530 expect(dep2, hasLength(1)); // dart:core
1531 }
1532
1533 void test_library_cycle_self_loop() {
1534 List<Source> sources = newSources({
1535 '/a.dart': '''
1536 import 'a.dart';
1537 '''
1538 });
1539 List<Map<ResultDescriptor, dynamic>> results =
1540 computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList();
1541 List<LibraryElement> component0 = results[0][LIBRARY_CYCLE];
1542 expect(component0, hasLength(1));
1543
1544 List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS];
1545 expect(units0, hasLength(1));
1546
1547 List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES];
1548 expect(dep0, hasLength(1)); // dart:core
1549 }
1550
1551 void test_library_cycle_singleton() {
1552 Source source = newSource(
1553 '/test.dart',
1554 '''
1555 import 'dart:core';
1556 ''');
1557 computeResult(new LibrarySpecificUnit(source, source), LIBRARY_CYCLE);
1558 List<LibraryElement> component = outputs[LIBRARY_CYCLE];
1559 List<CompilationUnitElement> units = outputs[LIBRARY_CYCLE_UNITS];
1560 List<CompilationUnitElement> deps = outputs[LIBRARY_CYCLE_DEPENDENCIES];
1561 expect(component, hasLength(1));
1562 expect(units, hasLength(1));
1563 expect(deps, hasLength(1));
1564 }
1565
1566 void test_library_cycle_tree() {
1567 List<Source> sources = newSources({
1568 '/a.dart': '''
1569 ''',
1570 '/b.dart': '''
1571 ''',
1572 '/c.dart': '''
1573 import 'a.dart';
1574 import 'b.dart';
1575 '''
1576 });
1577 List<Map<ResultDescriptor, dynamic>> results =
1578 computeLibraryResultsMap(sources, LIBRARY_CYCLE);
1579 List<LibraryElement> component0 = results[0][LIBRARY_CYCLE];
1580 List<LibraryElement> component1 = results[1][LIBRARY_CYCLE];
1581 List<LibraryElement> component2 = results[2][LIBRARY_CYCLE];
1582 expect(component0, hasLength(1));
1583 expect(component1, hasLength(1));
1584 expect(component2, hasLength(1));
1585
1586 List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS];
1587 List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS];
1588 List<CompilationUnitElement> units2 = results[2][LIBRARY_CYCLE_UNITS];
1589 expect(units0, hasLength(1));
1590 expect(units1, hasLength(1));
1591 expect(units2, hasLength(1));
1592
1593 List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES];
1594 List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES];
1595 List<CompilationUnitElement> dep2 = results[2][LIBRARY_CYCLE_DEPENDENCIES];
1596 expect(dep0, hasLength(1)); // dart:core
1597 expect(dep1, hasLength(1)); // dart:core,
1598 expect(dep2, hasLength(3)); // dart:core, a.dart, b.dart
1599 }
1600
1601 void test_library_double_loop() {
1602 List<Source> sources = newSources({
1603 '/a.dart': '''
1604 import 'b.dart';
1605 ''',
1606 '/b.dart': '''
1607 import 'a.dart';
1608 ''',
1609 '/c.dart': '''
1610 import 'd.dart' as foo;
1611 import 'a.dart' as bar;
1612 export 'b.dart';
1613 ''',
1614 '/d.dart': '''
1615 import 'c.dart' as foo;
1616 import 'b.dart' as bar;
1617 export 'a.dart';
1618 '''
1619 });
1620 List<Map<ResultDescriptor, dynamic>> results =
1621 computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList();
1622 List<LibraryElement> component0 = results[0][LIBRARY_CYCLE];
1623 List<LibraryElement> component1 = results[1][LIBRARY_CYCLE];
1624 List<LibraryElement> component2 = results[2][LIBRARY_CYCLE];
1625 List<LibraryElement> component3 = results[3][LIBRARY_CYCLE];
1626
1627 expect(component0, hasLength(2));
1628 expect(component1, hasLength(2));
1629 expect(component2, hasLength(2));
1630 expect(component3, hasLength(2));
1631
1632 List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS];
1633 List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS];
1634 List<CompilationUnitElement> units2 = results[2][LIBRARY_CYCLE_UNITS];
1635 List<CompilationUnitElement> units3 = results[3][LIBRARY_CYCLE_UNITS];
1636 expect(units0, hasLength(2));
1637 expect(units1, hasLength(2));
1638 expect(units2, hasLength(2));
1639 expect(units3, hasLength(2));
1640
1641 List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES];
1642 List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES];
1643 List<CompilationUnitElement> dep2 = results[2][LIBRARY_CYCLE_DEPENDENCIES];
1644 List<CompilationUnitElement> dep3 = results[3][LIBRARY_CYCLE_DEPENDENCIES];
1645 expect(dep0, hasLength(1)); // dart:core
1646 expect(dep1, hasLength(1)); // dart:core
1647 expect(dep3, hasLength(3)); // dart:core, a.dart, b.dart
1648 expect(dep3, hasLength(3)); // dart:core, a.dart, b.dart
1649 }
1650
1651 void test_library_double_loop_parts() {
1652 List<Source> sources = newSources({
1653 '/a.dart': '''
1654 import 'b.dart';
1655 part 'aa.dart';
1656 part 'ab.dart';
1657 ''',
1658 '/b.dart': '''
1659 import 'a.dart';
1660 ''',
1661 '/aa.dart': '''
1662 ''',
1663 '/ab.dart': '''
1664 ''',
1665 '/c.dart': '''
1666 import 'd.dart' as foo;
1667 import 'a.dart' as bar;
1668 export 'b.dart';
1669 ''',
1670 '/d.dart': '''
1671 import 'c.dart' as foo;
1672 import 'b.dart' as bar;
1673 export 'a.dart';
1674 part 'da.dart';
1675 part 'db.dart';
1676 ''',
1677 '/da.dart': '''
1678 ''',
1679 '/db.dart': '''
1680 '''
1681 });
1682 computeResult(
1683 new LibrarySpecificUnit(sources[0], sources[0]), LIBRARY_CYCLE);
1684 Map<ResultDescriptor, dynamic> results0 = outputs;
1685 computeResult(
1686 new LibrarySpecificUnit(sources[1], sources[1]), LIBRARY_CYCLE);
1687 Map<ResultDescriptor, dynamic> results1 = outputs;
1688 computeResult(
1689 new LibrarySpecificUnit(sources[0], sources[2]), LIBRARY_CYCLE);
1690 Map<ResultDescriptor, dynamic> results2 = outputs;
1691 computeResult(
1692 new LibrarySpecificUnit(sources[0], sources[3]), LIBRARY_CYCLE);
1693 Map<ResultDescriptor, dynamic> results3 = outputs;
1694 computeResult(
1695 new LibrarySpecificUnit(sources[4], sources[4]), LIBRARY_CYCLE);
1696 Map<ResultDescriptor, dynamic> results4 = outputs;
1697 computeResult(
1698 new LibrarySpecificUnit(sources[5], sources[5]), LIBRARY_CYCLE);
1699 Map<ResultDescriptor, dynamic> results5 = outputs;
1700 computeResult(
1701 new LibrarySpecificUnit(sources[5], sources[6]), LIBRARY_CYCLE);
1702 Map<ResultDescriptor, dynamic> results6 = outputs;
1703 computeResult(
1704 new LibrarySpecificUnit(sources[5], sources[7]), LIBRARY_CYCLE);
1705 Map<ResultDescriptor, dynamic> results7 = outputs;
1706
1707 List<LibraryElement> component0 = results0[LIBRARY_CYCLE];
1708 List<LibraryElement> component1 = results1[LIBRARY_CYCLE];
1709 List<LibraryElement> component2 = results2[LIBRARY_CYCLE];
1710 List<LibraryElement> component3 = results3[LIBRARY_CYCLE];
1711 List<LibraryElement> component4 = results4[LIBRARY_CYCLE];
1712 List<LibraryElement> component5 = results5[LIBRARY_CYCLE];
1713 List<LibraryElement> component6 = results6[LIBRARY_CYCLE];
1714 List<LibraryElement> component7 = results7[LIBRARY_CYCLE];
1715
1716 expect(component0, hasLength(2));
1717 expect(component1, hasLength(2));
1718 expect(component2, hasLength(2));
1719 expect(component3, hasLength(2));
1720 expect(component4, hasLength(2));
1721 expect(component5, hasLength(2));
1722 expect(component6, hasLength(2));
1723 expect(component7, hasLength(2));
1724
1725 List<CompilationUnitElement> units0 = results0[LIBRARY_CYCLE_UNITS];
1726 List<CompilationUnitElement> units1 = results1[LIBRARY_CYCLE_UNITS];
1727 List<CompilationUnitElement> units2 = results2[LIBRARY_CYCLE_UNITS];
1728 List<CompilationUnitElement> units3 = results3[LIBRARY_CYCLE_UNITS];
1729 List<CompilationUnitElement> units4 = results4[LIBRARY_CYCLE_UNITS];
1730 List<CompilationUnitElement> units5 = results5[LIBRARY_CYCLE_UNITS];
1731 List<CompilationUnitElement> units6 = results6[LIBRARY_CYCLE_UNITS];
1732 List<CompilationUnitElement> units7 = results7[LIBRARY_CYCLE_UNITS];
1733 expect(units0, hasLength(4));
1734 expect(units1, hasLength(4));
1735 expect(units2, hasLength(4));
1736 expect(units3, hasLength(4));
1737 expect(units4, hasLength(4));
1738 expect(units5, hasLength(4));
1739 expect(units6, hasLength(4));
1740 expect(units7, hasLength(4));
1741
1742 List<CompilationUnitElement> dep0 = results0[LIBRARY_CYCLE_DEPENDENCIES];
1743 List<CompilationUnitElement> dep1 = results1[LIBRARY_CYCLE_DEPENDENCIES];
1744 List<CompilationUnitElement> dep2 = results2[LIBRARY_CYCLE_DEPENDENCIES];
1745 List<CompilationUnitElement> dep3 = results3[LIBRARY_CYCLE_DEPENDENCIES];
1746 List<CompilationUnitElement> dep4 = results4[LIBRARY_CYCLE_DEPENDENCIES];
1747 List<CompilationUnitElement> dep5 = results5[LIBRARY_CYCLE_DEPENDENCIES];
1748 List<CompilationUnitElement> dep6 = results6[LIBRARY_CYCLE_DEPENDENCIES];
1749 List<CompilationUnitElement> dep7 = results7[LIBRARY_CYCLE_DEPENDENCIES];
1750 expect(dep0, hasLength(1)); // dart:core
1751 expect(dep1, hasLength(1)); // dart:core
1752 expect(dep2, hasLength(1)); // dart:core
1753 expect(dep3, hasLength(1)); // dart:core
1754 expect(dep4, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart
1755 expect(dep5, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart
1756 expect(dep6, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart
1757 expect(dep7, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart
1758 }
1759 }
1760
1761 @reflectiveTest
1762 class ContainingLibrariesTaskTest extends _AbstractDartTaskTest {
1763 test_perform_definingCompilationUnit() {
1764 AnalysisTarget library = newSource('/test.dart', 'library test;');
1765 computeResult(library, INCLUDED_PARTS);
1766 computeResult(library, CONTAINING_LIBRARIES,
1767 matcher: isContainingLibrariesTask);
1768 expect(outputs, hasLength(1));
1769 List<Source> containingLibraries = outputs[CONTAINING_LIBRARIES];
1770 expect(containingLibraries, unorderedEquals([library]));
1771 }
1772
1773 test_perform_partInMultipleLibraries() {
1774 AnalysisTarget library1 =
1775 newSource('/lib1.dart', 'library test; part "part.dart";');
1776 AnalysisTarget library2 =
1777 newSource('/lib2.dart', 'library test; part "part.dart";');
1778 AnalysisTarget part = newSource('/part.dart', 'part of test;');
1779 computeResult(library1, INCLUDED_PARTS);
1780 computeResult(library2, INCLUDED_PARTS);
1781 computeResult(part, SOURCE_KIND);
1782 computeResult(part, CONTAINING_LIBRARIES,
1783 matcher: isContainingLibrariesTask);
1784 expect(outputs, hasLength(1));
1785 List<Source> containingLibraries = outputs[CONTAINING_LIBRARIES];
1786 expect(containingLibraries, unorderedEquals([library1, library2]));
1787 }
1788
1789 test_perform_partInSingleLibrary() {
1790 AnalysisTarget library =
1791 newSource('/lib.dart', 'library test; part "part.dart";');
1792 AnalysisTarget part = newSource('/part.dart', 'part of test;');
1793 computeResult(library, INCLUDED_PARTS);
1794 computeResult(part, SOURCE_KIND);
1795 computeResult(part, CONTAINING_LIBRARIES,
1796 matcher: isContainingLibrariesTask);
1797 expect(outputs, hasLength(1));
1798 List<Source> containingLibraries = outputs[CONTAINING_LIBRARIES];
1799 expect(containingLibraries, unorderedEquals([library]));
1800 }
1801 }
1802
1803 @reflectiveTest
1804 class DartErrorsTaskTest extends _AbstractDartTaskTest {
1805 test_perform_definingCompilationUnit() {
1806 AnalysisTarget library =
1807 newSource('/test.dart', 'library test; import "dart:math";');
1808 computeResult(library, INCLUDED_PARTS);
1809 computeResult(library, DART_ERRORS, matcher: isDartErrorsTask);
1810 expect(outputs, hasLength(1));
1811 List<AnalysisError> errors = outputs[DART_ERRORS];
1812 expect(errors, hasLength(1));
1813 }
1814
1815 test_perform_partInSingleLibrary() {
1816 AnalysisTarget library = newSource(
1817 '/lib.dart', 'library test; import "dart:math"; part "part.dart";');
1818 AnalysisTarget part =
1819 newSource('/part.dart', 'part of test; class A extends A {}');
1820 computeResult(library, INCLUDED_PARTS);
1821 computeResult(library, DART_ERRORS);
1822 computeResult(part, DART_ERRORS, matcher: isDartErrorsTask);
1823 expect(outputs, hasLength(1));
1824 List<AnalysisError> errors = outputs[DART_ERRORS];
1825 // This should contain only the errors in the part file, not the ones in the
1826 // library.
1827 expect(errors, hasLength(1));
1828 }
1829 }
1830
1831 @reflectiveTest
1832 class EvaluateUnitConstantsTaskTest extends _AbstractDartTaskTest {
1833 test_perform() {
1834 Source source = newSource(
1835 '/test.dart',
1836 '''
1837 class C {
1838 const C();
1839 }
1840
1841 @x
1842 f() {}
1843
1844 const x = const C();
1845 ''');
1846 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
1847 computeResult(target, RESOLVED_UNIT, matcher: isEvaluateUnitConstantsTask);
1848 CompilationUnit unit = outputs[RESOLVED_UNIT];
1849 CompilationUnitElement unitElement = unit.element;
1850 expect(
1851 (unitElement.types[0].constructors[0] as ConstructorElementImpl)
1852 .isCycleFree,
1853 isTrue);
1854 expect(
1855 (unitElement.functions[0].metadata[0] as ElementAnnotationImpl)
1856 .evaluationResult,
1857 isNotNull);
1858 expect(
1859 (unitElement.topLevelVariables[0] as TopLevelVariableElementImpl)
1860 .evaluationResult,
1861 isNotNull);
1862 }
1863 }
1864
1865 @reflectiveTest
1866 class GatherUsedImportedElementsTaskTest extends _AbstractDartTaskTest {
1867 UsedImportedElements usedElements;
1868 Set<String> usedElementNames;
1869
1870 test_perform() {
1871 newSource(
1872 '/a.dart',
1873 r'''
1874 library lib_a;
1875 class A {}
1876 ''');
1877 newSource(
1878 '/b.dart',
1879 r'''
1880 library lib_b;
1881 class B {}
1882 ''');
1883 Source source = newSource(
1884 '/test.dart',
1885 r'''
1886 import 'a.dart';
1887 import 'b.dart';
1888 main() {
1889 new A();
1890 }''');
1891 _computeUsedElements(source);
1892 // validate
1893 expect(usedElementNames, unorderedEquals(['A']));
1894 }
1895
1896 void _computeUsedElements(Source source) {
1897 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
1898 computeResult(target, USED_IMPORTED_ELEMENTS,
1899 matcher: isGatherUsedImportedElementsTask);
1900 usedElements = outputs[USED_IMPORTED_ELEMENTS];
1901 usedElementNames = usedElements.elements.map((e) => e.name).toSet();
1902 }
1903 }
1904
1905 @reflectiveTest
1906 class GatherUsedLocalElementsTaskTest extends _AbstractDartTaskTest {
1907 UsedLocalElements usedElements;
1908 Set<String> usedElementNames;
1909
1910 fail_perform_forPart_afterLibraryUpdate() {
1911 Source libSource = newSource(
1912 '/my_lib.dart',
1913 '''
1914 library my_lib;
1915 part 'my_part.dart';
1916 foo() => null;
1917 class _LocalClass {}
1918 ''');
1919 Source partSource = newSource(
1920 '/my_part.dart',
1921 '''
1922 part of my_lib;
1923 bar() {
1924 print(_LocalClass);
1925 }
1926 ''');
1927 AnalysisTarget libTarget = new LibrarySpecificUnit(libSource, libSource);
1928 AnalysisTarget partTarget = new LibrarySpecificUnit(libSource, partSource);
1929 computeResult(libTarget, USED_LOCAL_ELEMENTS);
1930 computeResult(partTarget, USED_LOCAL_ELEMENTS);
1931 // _LocalClass is used in my_part.dart
1932 {
1933 UsedLocalElements usedElements =
1934 analysisCache.getValue(partTarget, USED_LOCAL_ELEMENTS);
1935 expect(usedElements.elements, contains(predicate((Element e) {
1936 return e.displayName == '_LocalClass';
1937 })));
1938 }
1939 // change my_lib.dart and recompute
1940 context.setContents(
1941 libSource,
1942 '''
1943 library my_lib;
1944 part 'my_part.dart';
1945 String foo() => null;
1946 class _LocalClass {}
1947 ''');
1948 computeResult(libTarget, USED_LOCAL_ELEMENTS);
1949 computeResult(partTarget, USED_LOCAL_ELEMENTS);
1950 // _LocalClass should still be used in my_part.dart
1951 {
1952 UsedLocalElements usedElements =
1953 analysisCache.getValue(partTarget, USED_LOCAL_ELEMENTS);
1954 expect(usedElements.elements, contains(predicate((Element e) {
1955 return e.displayName == '_LocalClass';
1956 })));
1957 }
1958 }
1959
1960 test_perform_localVariable() {
1961 Source source = newSource(
1962 '/test.dart',
1963 r'''
1964 main() {
1965 var v1 = 1;
1966 var v2 = 2;
1967 print(v2);
1968 }''');
1969 _computeUsedElements(source);
1970 // validate
1971 expect(usedElementNames, unorderedEquals(['v2']));
1972 }
1973
1974 test_perform_method() {
1975 Source source = newSource(
1976 '/test.dart',
1977 r'''
1978 class A {
1979 _m1() {}
1980 _m2() {}
1981 }
1982
1983 main(A a, p) {
1984 a._m2();
1985 p._m3();
1986 }
1987 ''');
1988 _computeUsedElements(source);
1989 // validate
1990 expect(usedElementNames, unorderedEquals(['A', 'a', 'p', '_m2']));
1991 expect(usedElements.members, unorderedEquals(['_m2', '_m3']));
1992 }
1993
1994 void _computeUsedElements(Source source) {
1995 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
1996 computeResult(target, USED_LOCAL_ELEMENTS,
1997 matcher: isGatherUsedLocalElementsTask);
1998 usedElements = outputs[USED_LOCAL_ELEMENTS];
1999 usedElementNames = usedElements.elements.map((e) => e.name).toSet();
2000 }
2001 }
2002
2003 @reflectiveTest
2004 class GenerateHintsTaskTest extends _AbstractDartTaskTest {
2005 test_perform_bestPractices_missingReturn() {
2006 Source source = newSource(
2007 '/test.dart',
2008 '''
2009 int main() {
2010 }
2011 ''');
2012 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
2013 computeResult(target, HINTS, matcher: isGenerateHintsTask);
2014 // validate
2015 _fillErrorListener(HINTS);
2016 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.MISSING_RETURN]);
2017 }
2018
2019 test_perform_dart2js() {
2020 AnalysisOptionsImpl options = new AnalysisOptionsImpl();
2021 options.dart2jsHint = true;
2022 prepareAnalysisContext(options);
2023 Source source = newSource(
2024 '/test.dart',
2025 '''
2026 main(p) {
2027 if (p is double) {
2028 print('double');
2029 }
2030 }
2031 ''');
2032 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
2033 computeResult(target, HINTS, matcher: isGenerateHintsTask);
2034 // validate
2035 _fillErrorListener(HINTS);
2036 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.IS_DOUBLE]);
2037 }
2038
2039 test_perform_deadCode() {
2040 Source source = newSource(
2041 '/test.dart',
2042 '''
2043 main() {
2044 if (false) {
2045 print('how?');
2046 }
2047 }
2048 ''');
2049 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
2050 computeResult(target, HINTS, matcher: isGenerateHintsTask);
2051 // validate
2052 _fillErrorListener(HINTS);
2053 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.DEAD_CODE]);
2054 }
2055
2056 test_perform_disabled() {
2057 context.analysisOptions =
2058 new AnalysisOptionsImpl.from(context.analysisOptions)..hint = false;
2059 Source source = newSource(
2060 '/test.dart',
2061 '''
2062 int main() {
2063 }
2064 ''');
2065 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
2066 computeResult(target, HINTS, matcher: isGenerateHintsTask);
2067 // validate
2068 _fillErrorListener(HINTS);
2069 errorListener.assertNoErrors();
2070 }
2071
2072 test_perform_imports_duplicateImport() {
2073 newSource(
2074 '/a.dart',
2075 r'''
2076 library lib_a;
2077 class A {}
2078 ''');
2079 Source source = newSource(
2080 '/test.dart',
2081 r'''
2082 import 'a.dart';
2083 import 'a.dart';
2084 main() {
2085 new A();
2086 }
2087 ''');
2088 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
2089 computeResult(target, HINTS, matcher: isGenerateHintsTask);
2090 // validate
2091 _fillErrorListener(HINTS);
2092 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.DUPLICATE_IMPORT]);
2093 }
2094
2095 test_perform_imports_unusedImport_one() {
2096 newSource(
2097 '/a.dart',
2098 r'''
2099 library lib_a;
2100 class A {}
2101 ''');
2102 newSource(
2103 '/b.dart',
2104 r'''
2105 library lib_b;
2106 class B {}
2107 ''');
2108 Source source = newSource(
2109 '/test.dart',
2110 r'''
2111 import 'a.dart';
2112 import 'b.dart';
2113 main() {
2114 new A();
2115 }''');
2116 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
2117 computeResult(target, HINTS, matcher: isGenerateHintsTask);
2118 // validate
2119 _fillErrorListener(HINTS);
2120 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.UNUSED_IMPORT]);
2121 }
2122
2123 test_perform_imports_unusedImport_zero() {
2124 newSource(
2125 '/a.dart',
2126 r'''
2127 library lib_a;
2128 class A {}
2129 ''');
2130 Source source = newSource(
2131 '/test.dart',
2132 r'''
2133 import 'a.dart';
2134 main() {
2135 new A();
2136 }''');
2137 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
2138 computeResult(target, HINTS, matcher: isGenerateHintsTask);
2139 // validate
2140 _fillErrorListener(HINTS);
2141 errorListener.assertNoErrors();
2142 }
2143
2144 test_perform_overrideVerifier() {
2145 Source source = newSource(
2146 '/test.dart',
2147 '''
2148 class A {}
2149 class B {
2150 @override
2151 m() {}
2152 }
2153 ''');
2154 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
2155 computeResult(target, HINTS, matcher: isGenerateHintsTask);
2156 // validate
2157 _fillErrorListener(HINTS);
2158 errorListener.assertErrorsWithCodes(
2159 <ErrorCode>[HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]);
2160 }
2161
2162 test_perform_todo() {
2163 Source source = newSource(
2164 '/test.dart',
2165 '''
2166 main() {
2167 // TODO(developer) foo bar
2168 }
2169 ''');
2170 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
2171 computeResult(target, HINTS, matcher: isGenerateHintsTask);
2172 // validate
2173 _fillErrorListener(HINTS);
2174 errorListener.assertErrorsWithCodes(<ErrorCode>[TodoCode.TODO]);
2175 }
2176
2177 test_perform_unusedLocalElements_class() {
2178 Source source = newSource(
2179 '/test.dart',
2180 '''
2181 class _A {}
2182 class _B {}
2183 main() {
2184 new _A();
2185 }
2186 ''');
2187 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
2188 computeResult(target, HINTS, matcher: isGenerateHintsTask);
2189 // validate
2190 _fillErrorListener(HINTS);
2191 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.UNUSED_ELEMENT]);
2192 }
2193
2194 test_perform_unusedLocalElements_localVariable() {
2195 Source source = newSource(
2196 '/test.dart',
2197 '''
2198 main() {
2199 var v = 42;
2200 }
2201 ''');
2202 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
2203 computeResult(target, HINTS, matcher: isGenerateHintsTask);
2204 // validate
2205 _fillErrorListener(HINTS);
2206 errorListener
2207 .assertErrorsWithCodes(<ErrorCode>[HintCode.UNUSED_LOCAL_VARIABLE]);
2208 }
2209
2210 test_perform_unusedLocalElements_method() {
2211 Source source = newSource(
2212 '/my_lib.dart',
2213 '''
2214 library my_lib;
2215 part 'my_part.dart';
2216 class A {
2217 _ma() {}
2218 _mb() {}
2219 _mc() {}
2220 }
2221 ''');
2222 newSource(
2223 '/my_part.dart',
2224 '''
2225 part of my_lib;
2226
2227 f(A a) {
2228 a._mb();
2229 }
2230 ''');
2231 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
2232 computeResult(target, HINTS, matcher: isGenerateHintsTask);
2233 // validate
2234 _fillErrorListener(HINTS);
2235 errorListener.assertErrorsWithCodes(
2236 <ErrorCode>[HintCode.UNUSED_ELEMENT, HintCode.UNUSED_ELEMENT]);
2237 }
2238 }
2239
2240 @reflectiveTest
2241 class GenerateLintsTaskTest extends _AbstractDartTaskTest {
2242 void enableLints() {
2243 AnalysisOptionsImpl options = context.analysisOptions;
2244 options.lint = true;
2245 context.analysisOptions = options;
2246 }
2247
2248 @override
2249 void setUp() {
2250 super.setUp();
2251 enableLints();
2252 }
2253
2254 @override
2255 void tearDown() {
2256 LintGenerator.LINTERS.clear();
2257 super.tearDown();
2258 }
2259
2260 test_camel_case_types() {
2261 Source source = newSource(
2262 '/test.dart',
2263 '''
2264 class a { }
2265 ''');
2266
2267 LintGenerator.LINTERS.clear();
2268 LintGenerator.LINTERS.add(new GenerateLintsTaskTest_TestLinter());
2269
2270 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
2271 computeResult(target, LINTS, matcher: isGenerateLintsTask);
2272 // validate
2273 _fillErrorListener(LINTS);
2274 errorListener.assertErrorsWithCodes(<ErrorCode>[_testLintCode]);
2275 }
2276 }
2277
2278 class GenerateLintsTaskTest_AstVisitor extends SimpleAstVisitor {
2279 Linter linter;
2280 GenerateLintsTaskTest_AstVisitor(this.linter);
2281
2282 @override
2283 visitClassDeclaration(ClassDeclaration node) {
2284 if (!new RegExp(r'^([_]*)([A-Z]+[a-z0-9]*)+$')
2285 .hasMatch(node.name.toString())) {
2286 linter.reporter.reportErrorForNode(_testLintCode, node, []);
2287 }
2288 }
2289 }
2290
2291 class GenerateLintsTaskTest_TestLinter extends Linter {
2292 @override
2293 AstVisitor getVisitor() => new GenerateLintsTaskTest_AstVisitor(this);
2294 }
2295
2296 @reflectiveTest
2297 class InferInstanceMembersInUnitTaskTest extends _AbstractDartTaskTest {
2298 void test_perform() {
2299 enableStrongMode();
2300 AnalysisTarget source = newSource(
2301 '/test.dart',
2302 '''
2303 class A {
2304 X f;
2305 Y m(Z x) {}
2306 }
2307 class B extends A {
2308 var f;
2309 m(x) {}
2310 }
2311 class X {}
2312 class Y {}
2313 class Z {}
2314 ''');
2315 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
2316 matcher: isInferInstanceMembersInUnitTask);
2317 CompilationUnit unit = outputs[RESOLVED_UNIT8];
2318 VariableDeclaration field = getFieldInClass(unit, 'B', 'f');
2319 MethodDeclaration method = getMethodInClass(unit, 'B', 'm');
2320 DartType typeX = getClass(unit, 'X').element.type;
2321 DartType typeY = getClass(unit, 'Y').element.type;
2322 DartType typeZ = getClass(unit, 'Z').element.type;
2323
2324 expect(field.element.type, typeX);
2325 expect(method.element.returnType, typeY);
2326 expect(method.element.parameters[0].type, typeZ);
2327 }
2328
2329 void test_perform_cross_library_const() {
2330 enableStrongMode();
2331 AnalysisTarget firstSource = newSource(
2332 '/first.dart',
2333 '''
2334 library first;
2335
2336 const a = 'hello';
2337 ''');
2338 AnalysisTarget secondSource = newSource(
2339 '/second.dart',
2340 '''
2341 import 'first.dart';
2342
2343 const b = a;
2344 class M {
2345 String c = a;
2346 }
2347 ''');
2348 computeResult(
2349 new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT8,
2350 matcher: isInferInstanceMembersInUnitTask);
2351 CompilationUnit firstUnit = outputs[RESOLVED_UNIT8];
2352 computeResult(
2353 new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT8);
2354 CompilationUnit secondUnit = outputs[RESOLVED_UNIT8];
2355
2356 VariableDeclaration variableA = getTopLevelVariable(firstUnit, 'a');
2357 VariableDeclaration variableB = getTopLevelVariable(secondUnit, 'b');
2358 VariableDeclaration variableC = getFieldInClass(secondUnit, 'M', 'c');
2359 InterfaceType stringType = context.typeProvider.stringType;
2360
2361 expect(variableA.element.type, stringType);
2362 expect(variableB.element.type, stringType);
2363 expect(variableB.initializer.staticType, stringType);
2364 expect(variableC.element.type, stringType);
2365 expect(variableC.initializer.staticType, stringType);
2366 }
2367
2368 void test_perform_reresolution() {
2369 enableStrongMode();
2370 AnalysisTarget source = newSource(
2371 '/test.dart',
2372 '''
2373 const topLevel = '';
2374 class C {
2375 String field = topLevel;
2376 }
2377 ''');
2378 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8);
2379 CompilationUnit unit = outputs[RESOLVED_UNIT8];
2380 VariableDeclaration topLevelDecl = getTopLevelVariable(unit, 'topLevel');
2381 VariableDeclaration fieldDecl = getFieldInClass(unit, 'C', 'field');
2382 VariableElement topLevel = topLevelDecl.name.staticElement;
2383 VariableElement field = fieldDecl.name.staticElement;
2384
2385 InterfaceType stringType = context.typeProvider.stringType;
2386 expect(topLevel.type, stringType);
2387 expect(field.type, stringType);
2388 expect(fieldDecl.initializer.staticType, stringType);
2389 }
2390 }
2391
2392 @reflectiveTest
2393 class InferStaticVariableTypesInUnitTaskTest extends _AbstractDartTaskTest {
2394 void test_perform_const_field() {
2395 enableStrongMode();
2396 AnalysisTarget source = newSource(
2397 '/test.dart',
2398 '''
2399 class M {
2400 static const X = "";
2401 }
2402 ''');
2403 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6,
2404 matcher: isInferStaticVariableTypesInUnitTask);
2405 CompilationUnit unit = outputs[RESOLVED_UNIT6];
2406 VariableDeclaration declaration = getFieldInClass(unit, 'M', 'X');
2407 InterfaceType stringType = context.typeProvider.stringType;
2408 expect(declaration.element.type, stringType);
2409 }
2410
2411 void test_perform_nestedDeclarations() {
2412 enableStrongMode();
2413 AnalysisTarget source = newSource(
2414 '/test.dart',
2415 '''
2416 var f = (int x) {
2417 int squared(int value) => value * value;
2418 var xSquared = squared(x);
2419 return xSquared;
2420 };
2421 ''');
2422 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6,
2423 matcher: isInferStaticVariableTypesInUnitTask);
2424 }
2425
2426 void test_perform_recursive() {
2427 enableStrongMode();
2428 AnalysisTarget firstSource = newSource(
2429 '/first.dart',
2430 '''
2431 import 'second.dart';
2432
2433 var a = new M();
2434 var c = b;
2435 ''');
2436 AnalysisTarget secondSource = newSource(
2437 '/second.dart',
2438 '''
2439 import 'first.dart';
2440
2441 var b = a;
2442 class M {}
2443 ''');
2444 computeResult(
2445 new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT6,
2446 matcher: isInferStaticVariableTypesInUnitTask);
2447 CompilationUnit firstUnit = outputs[RESOLVED_UNIT6];
2448 computeResult(
2449 new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT6);
2450 CompilationUnit secondUnit = outputs[RESOLVED_UNIT6];
2451
2452 VariableDeclaration variableA = getTopLevelVariable(firstUnit, 'a');
2453 VariableDeclaration variableB = getTopLevelVariable(secondUnit, 'b');
2454 VariableDeclaration variableC = getTopLevelVariable(firstUnit, 'c');
2455 ClassDeclaration classM = getClass(secondUnit, 'M');
2456 DartType typeM = classM.element.type;
2457
2458 expect(variableA.element.type, typeM);
2459 expect(variableB.element.type, typeM);
2460 expect(variableB.initializer.staticType, typeM);
2461 expect(variableC.element.type, typeM);
2462 expect(variableC.initializer.staticType, typeM);
2463 }
2464
2465 void test_perform_simple() {
2466 enableStrongMode();
2467 AnalysisTarget source = newSource(
2468 '/test.dart',
2469 '''
2470 var X = 1;
2471
2472 var Y = () {
2473 return 1 + X;
2474 };
2475 ''');
2476 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6,
2477 matcher: isInferStaticVariableTypesInUnitTask);
2478 CompilationUnit unit = outputs[RESOLVED_UNIT6];
2479 TopLevelVariableDeclaration declaration = unit.declarations[1];
2480 FunctionExpression function =
2481 declaration.variables.variables[0].initializer;
2482 BlockFunctionBody body = function.body;
2483 ReturnStatement statement = body.block.statements[0];
2484 Expression expression = statement.expression;
2485 InterfaceType intType = context.typeProvider.intType;
2486 expect(expression.staticType, intType);
2487 }
2488 }
2489
2490 @reflectiveTest
2491 class InferStaticVariableTypeTaskTest extends _AbstractDartTaskTest {
2492 void test_getDeclaration_staticField() {
2493 AnalysisTarget source = newSource(
2494 '/test.dart',
2495 '''
2496 class C {
2497 var field = '';
2498 }
2499 ''');
2500 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
2501 CompilationUnit unit = outputs[RESOLVED_UNIT5];
2502 VariableDeclaration declaration = getFieldInClass(unit, 'C', 'field');
2503 VariableElement variable = declaration.name.staticElement;
2504 InferStaticVariableTypeTask inferTask =
2505 new InferStaticVariableTypeTask(task.context, variable);
2506 expect(inferTask.getDeclaration(unit), declaration);
2507 }
2508
2509 void test_getDeclaration_topLevel() {
2510 AnalysisTarget source = newSource(
2511 '/test.dart',
2512 '''
2513 var topLevel = '';
2514 ''');
2515 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
2516 CompilationUnit unit = outputs[RESOLVED_UNIT5];
2517 VariableDeclaration declaration = getTopLevelVariable(unit, 'topLevel');
2518 VariableElement variable = declaration.name.staticElement;
2519 InferStaticVariableTypeTask inferTask =
2520 new InferStaticVariableTypeTask(task.context, variable);
2521 expect(inferTask.getDeclaration(unit), declaration);
2522 }
2523
2524 void test_perform() {
2525 enableStrongMode();
2526 AnalysisTarget source = newSource(
2527 '/test3.dart',
2528 '''
2529 var topLevel3 = '';
2530 class C {
2531 var field3 = topLevel3;
2532 }
2533 ''');
2534 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
2535 CompilationUnit unit = outputs[RESOLVED_UNIT5];
2536 VariableDeclaration topLevelDecl = getTopLevelVariable(unit, 'topLevel3');
2537 VariableDeclaration fieldDecl = getFieldInClass(unit, 'C', 'field3');
2538 VariableElement topLevel = topLevelDecl.name.staticElement;
2539 VariableElement field = fieldDecl.name.staticElement;
2540
2541 computeResult(field, INFERRED_STATIC_VARIABLE,
2542 matcher: isInferStaticVariableTypeTask);
2543 InterfaceType stringType = context.typeProvider.stringType;
2544 expect(topLevel.type, stringType);
2545 expect(field.type, stringType);
2546 expect(fieldDecl.initializer.staticType, stringType);
2547 }
2548
2549 void test_perform_const() {
2550 enableStrongMode();
2551 AnalysisTarget source = newSource(
2552 '/test.dart',
2553 '''
2554 const topLevel = "hello";
2555 class C {
2556 var field = topLevel;
2557 }
2558 ''');
2559 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
2560 CompilationUnit unit = outputs[RESOLVED_UNIT5];
2561 VariableElement topLevel =
2562 getTopLevelVariable(unit, 'topLevel').name.staticElement;
2563 VariableElement field =
2564 getFieldInClass(unit, 'C', 'field').name.staticElement;
2565
2566 computeResult(field, INFERRED_STATIC_VARIABLE,
2567 matcher: isInferStaticVariableTypeTask);
2568 InterfaceType stringType = context.typeProvider.stringType;
2569 expect(topLevel.type, stringType);
2570 expect(field.type, stringType);
2571 }
2572
2573 void test_perform_cycle() {
2574 enableStrongMode();
2575 AnalysisTarget source = newSource(
2576 '/test.dart',
2577 '''
2578 var piFirst = true;
2579 var pi = piFirst ? 3.14 : tau / 2;
2580 var tau = piFirst ? pi * 2 : 6.28;
2581 ''');
2582 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
2583 CompilationUnit unit = outputs[RESOLVED_UNIT5];
2584 VariableElement piFirst =
2585 getTopLevelVariable(unit, 'piFirst').name.staticElement;
2586 VariableElement pi = getTopLevelVariable(unit, 'pi').name.staticElement;
2587 VariableElement tau = getTopLevelVariable(unit, 'tau').name.staticElement;
2588
2589 computeResult(piFirst, INFERRED_STATIC_VARIABLE,
2590 matcher: isInferStaticVariableTypeTask);
2591 expect(piFirst.type, context.typeProvider.boolType);
2592 expect(pi.type.isDynamic, isTrue);
2593 expect(tau.type.isDynamic, isTrue);
2594 }
2595
2596 void test_perform_error() {
2597 enableStrongMode();
2598 AnalysisTarget source = newSource(
2599 '/test.dart',
2600 '''
2601 var a = '' / null;
2602 ''');
2603 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
2604 CompilationUnit unit = outputs[RESOLVED_UNIT5];
2605 VariableElement a = getTopLevelVariable(unit, 'a').name.staticElement;
2606
2607 computeResult(a, INFERRED_STATIC_VARIABLE,
2608 matcher: isInferStaticVariableTypeTask);
2609 expect(a.type.isDynamic, isTrue);
2610 }
2611
2612 void test_perform_null() {
2613 enableStrongMode();
2614 AnalysisTarget source = newSource(
2615 '/test.dart',
2616 '''
2617 var a = null;
2618 ''');
2619 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5);
2620 CompilationUnit unit = outputs[RESOLVED_UNIT5];
2621 VariableElement a = getTopLevelVariable(unit, 'a').name.staticElement;
2622
2623 computeResult(a, INFERRED_STATIC_VARIABLE,
2624 matcher: isInferStaticVariableTypeTask);
2625 expect(a.type.isDynamic, isTrue);
2626 }
2627 }
2628
2629 @reflectiveTest
2630 class LibraryErrorsReadyTaskTest extends _AbstractDartTaskTest {
2631 test_perform() {
2632 Source library = newSource(
2633 '/lib.dart',
2634 r'''
2635 library lib;
2636 part 'part1.dart';
2637 part 'part2.dart';
2638 X v1;
2639 ''');
2640 Source part1 = newSource(
2641 '/part1.dart',
2642 r'''
2643 part of lib;
2644 X v2;
2645 ''');
2646 Source part2 = newSource(
2647 '/part2.dart',
2648 r'''
2649 part of lib;
2650 X v3;
2651 ''');
2652 computeResult(library, LIBRARY_ERRORS_READY,
2653 matcher: isLibraryErrorsReadyTask);
2654 expect(outputs, hasLength(1));
2655 bool ready = outputs[LIBRARY_ERRORS_READY];
2656 expect(ready, isTrue);
2657 expect(context.getErrors(library).errors, hasLength(1));
2658 expect(context.getErrors(part1).errors, hasLength(1));
2659 expect(context.getErrors(part2).errors, hasLength(1));
2660 }
2661 }
2662
2663 @reflectiveTest
2664 class LibraryUnitErrorsTaskTest extends _AbstractDartTaskTest {
2665 test_perform_definingCompilationUnit() {
2666 AnalysisTarget library =
2667 newSource('/test.dart', 'library test; import "dart:math";');
2668 computeResult(
2669 new LibrarySpecificUnit(library, library), LIBRARY_UNIT_ERRORS,
2670 matcher: isLibraryUnitErrorsTask);
2671 expect(outputs, hasLength(1));
2672 List<AnalysisError> errors = outputs[LIBRARY_UNIT_ERRORS];
2673 expect(errors, hasLength(1));
2674 }
2675
2676 test_perform_partInSingleLibrary() {
2677 AnalysisTarget library =
2678 newSource('/lib.dart', 'library test; part "part.dart";');
2679 AnalysisTarget part = newSource('/part.dart', 'part of test;');
2680 computeResult(new LibrarySpecificUnit(library, part), LIBRARY_UNIT_ERRORS,
2681 matcher: isLibraryUnitErrorsTask);
2682 expect(outputs, hasLength(1));
2683 List<AnalysisError> errors = outputs[LIBRARY_UNIT_ERRORS];
2684 expect(errors, hasLength(0));
2685 }
2686 }
2687
2688 @reflectiveTest
2689 class ParseDartTaskTest extends _AbstractDartTaskTest {
2690 Source source;
2691
2692 test_perform() {
2693 _performParseTask(r'''
2694 part of lib;
2695 class B {}''');
2696 expect(outputs, hasLength(8));
2697 expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
2698 expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
2699 _assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
2700 expect(outputs[INCLUDED_PARTS], hasLength(0));
2701 expect(outputs[PARSE_ERRORS], hasLength(0));
2702 expect(outputs[PARSED_UNIT], isNotNull);
2703 expect(outputs[SOURCE_KIND], SourceKind.PART);
2704 expect(outputs[UNITS], hasLength(1));
2705 }
2706
2707 test_perform_computeSourceKind_noDirectives_hasContainingLibrary() {
2708 // Parse "lib.dart" to let the context know that "test.dart" is included.
2709 computeResult(
2710 newSource(
2711 '/lib.dart',
2712 r'''
2713 library lib;
2714 part 'test.dart';
2715 '''),
2716 PARSED_UNIT);
2717 // If there are no the "part of" directive, then it is not a part.
2718 _performParseTask('');
2719 expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
2720 }
2721
2722 test_perform_computeSourceKind_noDirectives_noContainingLibrary() {
2723 _performParseTask('');
2724 expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
2725 }
2726
2727 test_perform_doesNotExist() {
2728 _performParseTask(null);
2729 expect(outputs, hasLength(8));
2730 expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
2731 expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
2732 _assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
2733 expect(outputs[INCLUDED_PARTS], hasLength(0));
2734 expect(outputs[PARSE_ERRORS], hasLength(0));
2735 expect(outputs[PARSED_UNIT], isNotNull);
2736 expect(outputs[SOURCE_KIND], SourceKind.UNKNOWN);
2737 expect(outputs[UNITS], hasLength(1));
2738 }
2739
2740 test_perform_invalidDirectives() {
2741 _performParseTask(r'''
2742 library lib;
2743 import '/does/not/exist.dart';
2744 import '://invaliduri.dart';
2745 export '${a}lib3.dart';
2746 part 'part.dart';
2747 class A {}''');
2748 expect(outputs, hasLength(8));
2749 expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
2750 expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
2751 _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
2752 expect(outputs[INCLUDED_PARTS], hasLength(1));
2753 expect(outputs[PARSE_ERRORS], hasLength(2));
2754 expect(outputs[PARSED_UNIT], isNotNull);
2755 expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
2756 expect(outputs[UNITS], hasLength(2));
2757 }
2758
2759 test_perform_library() {
2760 _performParseTask(r'''
2761 library lib;
2762 import 'lib2.dart';
2763 export 'lib3.dart';
2764 part 'part.dart';
2765 class A {''');
2766 expect(outputs, hasLength(8));
2767 expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
2768 expect(outputs[EXPORTED_LIBRARIES], hasLength(1));
2769 _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
2770 expect(outputs[INCLUDED_PARTS], hasLength(1));
2771 expect(outputs[PARSE_ERRORS], hasLength(1));
2772 expect(outputs[PARSED_UNIT], isNotNull);
2773 expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
2774 expect(outputs[UNITS], hasLength(2));
2775 }
2776
2777 test_perform_library_selfReferenceAsPart() {
2778 _performParseTask(r'''
2779 library lib;
2780 part 'test.dart';
2781 ''');
2782 expect(outputs[INCLUDED_PARTS], unorderedEquals(<Source>[source]));
2783 }
2784
2785 test_perform_part() {
2786 _performParseTask(r'''
2787 part of lib;
2788 class B {}''');
2789 expect(outputs, hasLength(8));
2790 expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
2791 expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
2792 _assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
2793 expect(outputs[INCLUDED_PARTS], hasLength(0));
2794 expect(outputs[PARSE_ERRORS], hasLength(0));
2795 expect(outputs[PARSED_UNIT], isNotNull);
2796 expect(outputs[SOURCE_KIND], SourceKind.PART);
2797 expect(outputs[UNITS], hasLength(1));
2798 }
2799
2800 void _performParseTask(String content) {
2801 source = newSource('/test.dart', content);
2802 computeResult(source, PARSED_UNIT, matcher: isParseDartTask);
2803 }
2804
2805 static void _assertHasCore(List<Source> sources, int lenght) {
2806 expect(sources, hasLength(lenght));
2807 expect(sources, contains(predicate((Source s) {
2808 return s.fullName.endsWith('core.dart');
2809 })));
2810 }
2811 }
2812
2813 @reflectiveTest
2814 class PartiallyResolveUnitReferencesTaskTest extends _AbstractDartTaskTest {
2815 test_perform() {
2816 enableStrongMode();
2817 Source source = newSource(
2818 '/test.dart',
2819 '''
2820 int a = b;
2821 int b = c;
2822 var d = 0;
2823 class A {}
2824 class C {
2825 static final f = '';
2826 var g = 0;
2827 }
2828 ''');
2829 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
2830 computeResult(target, RESOLVED_UNIT5,
2831 matcher: isPartiallyResolveUnitReferencesTask);
2832 // Test the outputs
2833 expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(4));
2834 CompilationUnit unit = outputs[RESOLVED_UNIT5];
2835 expect(unit, same(outputs[RESOLVED_UNIT5]));
2836 // Test the state of the AST
2837 TopLevelVariableDeclaration a = unit.declarations[0];
2838 VariableDeclaration variableA = a.variables.variables[0];
2839 SimpleIdentifier initializer = variableA.initializer;
2840 expect(initializer.staticElement, isNotNull);
2841 }
2842
2843 test_perform_importExport() {
2844 newSource(
2845 '/a.dart',
2846 '''
2847 library a;
2848 class A<T> {
2849 T m() {}
2850 }
2851 ''');
2852 newSource(
2853 '/b.dart',
2854 '''
2855 library b;
2856 export 'a.dart';
2857 ''');
2858 Source sourceC = newSource(
2859 '/c.dart',
2860 '''
2861 library c;
2862 import 'b.dart';
2863 main() {
2864 new A<int>().m();
2865 }
2866 ''');
2867 computeResult(new LibrarySpecificUnit(sourceC, sourceC), RESOLVED_UNIT5,
2868 matcher: isPartiallyResolveUnitReferencesTask);
2869 // validate
2870 expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(0));
2871 CompilationUnit unit = outputs[RESOLVED_UNIT5];
2872 expect(unit, isNotNull);
2873
2874 FunctionDeclaration mainFunction = unit.declarations[0];
2875 expect(mainFunction.element, isNotNull);
2876 BlockFunctionBody body = mainFunction.functionExpression.body;
2877 List<Statement> statements = body.block.statements;
2878 ExpressionStatement statement = statements[0];
2879 MethodInvocation invocation = statement.expression;
2880 MethodElement methodElement = invocation.methodName.staticElement;
2881 expect(methodElement, isNull);
2882 }
2883
2884 test_perform_notResolved() {
2885 enableStrongMode();
2886 Source source = newSource(
2887 '/test.dart',
2888 '''
2889 int A;
2890 f1() {
2891 A;
2892 }
2893 var f2 = () {
2894 A;
2895 void f3() {
2896 A;
2897 }
2898 }
2899 class C {
2900 C() {
2901 A;
2902 }
2903 m() {
2904 A;
2905 }
2906 }
2907 ''');
2908 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
2909 computeResult(target, RESOLVED_UNIT5,
2910 matcher: isPartiallyResolveUnitReferencesTask);
2911 CompilationUnit unit = outputs[RESOLVED_UNIT5];
2912 NodeList<CompilationUnitMember> declarations = unit.declarations;
2913
2914 void expectReference(BlockFunctionBody body, bool isResolved) {
2915 ExpressionStatement statement = body.block.statements[0];
2916 SimpleIdentifier reference = statement.expression;
2917 expect(reference.staticElement, isResolved ? isNotNull : isNull);
2918 }
2919 //
2920 // The reference to 'A' in 'f1' should not be resolved.
2921 //
2922 FunctionDeclaration f1 = declarations[1];
2923 expectReference(f1.functionExpression.body, false);
2924 //
2925 // The references to 'A' in 'f2' should be resolved.
2926 //
2927 TopLevelVariableDeclaration f2 = declarations[2];
2928 FunctionExpression expression2 = f2.variables.variables[0].initializer;
2929 BlockFunctionBody body2 = expression2.body;
2930 expectReference(body2, true);
2931
2932 FunctionDeclarationStatement statement2 = body2.block.statements[1];
2933 BlockFunctionBody innerBody =
2934 statement2.functionDeclaration.functionExpression.body;
2935 expectReference(innerBody, true);
2936 //
2937 // The references to 'A' in 'C' should not be resolved.
2938 //
2939 ClassDeclaration c = declarations[3];
2940 NodeList<ClassMember> members = c.members;
2941
2942 ConstructorDeclaration constructor = members[0];
2943 expectReference(constructor.body, false);
2944
2945 MethodDeclaration method = members[1];
2946 expectReference(method.body, false);
2947 }
2948 }
2949
2950 @reflectiveTest
2951 class ResolveInstanceFieldsInUnitTaskTest extends _AbstractDartTaskTest {
2952 @override
2953 void setUp() {
2954 super.setUp();
2955 enableStrongMode();
2956 }
2957
2958 // Test inference of instance fields across units
2959 void test_perform_inference_cross_unit_instance() {
2960 List<Source> sources = newSources({
2961 '/a.dart': '''
2962 import 'b.dart';
2963 class A {
2964 final a2 = new B().b2;
2965 }
2966 ''',
2967 '/b.dart': '''
2968 class B {
2969 final b2 = 1;
2970 }
2971 ''',
2972 '/main.dart': '''
2973 import "a.dart";
2974
2975 test1() {
2976 int x = 0;
2977 x = new A().a2;
2978 }
2979 '''
2980 });
2981 InterfaceType intType = context.typeProvider.intType;
2982 DartType dynamicType = context.typeProvider.dynamicType;
2983
2984 computeResult(
2985 new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT7);
2986 CompilationUnit unit1 = outputs[RESOLVED_UNIT7];
2987
2988 // B.b2 shoud be resolved on the rhs, but not yet inferred.
2989 assertVariableDeclarationTypes(
2990 getFieldInClass(unit1, "B", "b2"), dynamicType, intType);
2991
2992 computeResult(
2993 new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7);
2994 CompilationUnit unit0 = outputs[RESOLVED_UNIT7];
2995
2996 // B.b2 should now be fully resolved and inferred.
2997 assertVariableDeclarationTypes(
2998 getFieldInClass(unit1, "B", "b2"), intType, intType);
2999
3000 // A.a2 should now be resolved on the rhs, but not yet inferred.
3001 assertVariableDeclarationTypes(
3002 getFieldInClass(unit0, "A", "a2"), dynamicType, intType);
3003
3004 computeResult(
3005 new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7);
3006 CompilationUnit unit2 = outputs[RESOLVED_UNIT7];
3007
3008 // A.a2 should now be fully resolved and inferred.
3009 assertVariableDeclarationTypes(
3010 getFieldInClass(unit0, "A", "a2"), intType, intType);
3011
3012 assertVariableDeclarationTypes(
3013 getFieldInClass(unit1, "B", "b2"), intType, intType);
3014 }
3015
3016 // Test inference of instance fields across units
3017 void test_perform_inference_cross_unit_instance_cyclic() {
3018 List<Source> sources = newSources({
3019 '/a.dart': '''
3020 import 'b.dart';
3021 class A {
3022 final a2 = new B().b2;
3023 }
3024 ''',
3025 '/b.dart': '''
3026 import 'a.dart';
3027 class B {
3028 final b2 = 1;
3029 }
3030 ''',
3031 '/main.dart': '''
3032 import "a.dart";
3033
3034 test1() {
3035 int x = 0;
3036 x = new A().a2;
3037 }
3038 '''
3039 });
3040 InterfaceType intType = context.typeProvider.intType;
3041 DartType dynamicType = context.typeProvider.dynamicType;
3042
3043 computeResult(
3044 new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7);
3045 CompilationUnit unit0 = outputs[RESOLVED_UNIT7];
3046
3047 // A.a2 should now be resolved on the rhs, but not yet inferred.
3048 assertVariableDeclarationTypes(
3049 getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
3050
3051 computeResult(
3052 new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7);
3053 CompilationUnit unit2 = outputs[RESOLVED_UNIT7];
3054
3055 // A.a2 should now be fully resolved and inferred.
3056 assertVariableDeclarationTypes(
3057 getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
3058 }
3059
3060 // Test inference of instance fields across units with cycles
3061 void test_perform_inference_cross_unit_static_instance() {
3062 List<Source> sources = newSources({
3063 '/a.dart': '''
3064 import 'b.dart';
3065 class A {
3066 static final a1 = B.b1;
3067 final a2 = new B().b2;
3068 }
3069 ''',
3070 '/b.dart': '''
3071 class B {
3072 static final b1 = 1;
3073 final b2 = 1;
3074 }
3075 ''',
3076 '/main.dart': '''
3077 import "a.dart";
3078
3079 test1() {
3080 int x = 0;
3081 // inference in A now works.
3082 x = A.a1;
3083 x = new A().a2;
3084 }
3085 '''
3086 });
3087 InterfaceType intType = context.typeProvider.intType;
3088 DartType dynamicType = context.typeProvider.dynamicType;
3089
3090 computeResult(
3091 new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT7);
3092 CompilationUnit unit1 = outputs[RESOLVED_UNIT7];
3093
3094 assertVariableDeclarationTypes(
3095 getFieldInClass(unit1, "B", "b1"), intType, intType);
3096 assertVariableDeclarationTypes(
3097 getFieldInClass(unit1, "B", "b2"), dynamicType, intType);
3098
3099 computeResult(
3100 new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7);
3101 CompilationUnit unit0 = outputs[RESOLVED_UNIT7];
3102
3103 assertVariableDeclarationTypes(
3104 getFieldInClass(unit0, "A", "a1"), intType, intType);
3105 assertVariableDeclarationTypes(
3106 getFieldInClass(unit0, "A", "a2"), dynamicType, intType);
3107
3108 assertVariableDeclarationTypes(
3109 getFieldInClass(unit1, "B", "b1"), intType, intType);
3110 assertVariableDeclarationTypes(
3111 getFieldInClass(unit1, "B", "b2"), intType, intType);
3112
3113 computeResult(
3114 new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7);
3115 CompilationUnit unit2 = outputs[RESOLVED_UNIT7];
3116
3117 assertVariableDeclarationTypes(
3118 getFieldInClass(unit0, "A", "a1"), intType, intType);
3119 assertVariableDeclarationTypes(
3120 getFieldInClass(unit0, "A", "a2"), intType, intType);
3121
3122 assertVariableDeclarationTypes(
3123 getFieldInClass(unit1, "B", "b1"), intType, intType);
3124 assertVariableDeclarationTypes(
3125 getFieldInClass(unit1, "B", "b2"), intType, intType);
3126 }
3127
3128 // Test inference between static and instance fields
3129 void test_perform_inference_instance() {
3130 List<Source> sources = newSources({
3131 '/a.dart': '''
3132 import 'b.dart';
3133 class A {
3134 final a2 = new B().b2;
3135 }
3136
3137 class B {
3138 final b2 = 1;
3139 }
3140 ''',
3141 '/main.dart': '''
3142 import "a.dart";
3143
3144 test1() {
3145 int x = 0;
3146 x = new A().a2;
3147 }
3148 '''
3149 });
3150 InterfaceType intType = context.typeProvider.intType;
3151 DartType dynamicType = context.typeProvider.dynamicType;
3152
3153 computeResult(
3154 new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7);
3155 CompilationUnit unit0 = outputs[RESOLVED_UNIT7];
3156
3157 // A.a2 should now be resolved on the rhs, but not yet inferred.
3158 assertVariableDeclarationTypes(
3159 getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
3160
3161 // B.b2 shoud be resolved on the rhs, but not yet inferred.
3162 assertVariableDeclarationTypes(
3163 getFieldInClass(unit0, "B", "b2"), dynamicType, intType);
3164
3165 computeResult(
3166 new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT7);
3167 CompilationUnit unit1 = outputs[RESOLVED_UNIT7];
3168
3169 // A.a2 should now be fully resolved and inferred.
3170 assertVariableDeclarationTypes(
3171 getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
3172
3173 // B.b2 should now be fully resolved and inferred.
3174 assertVariableDeclarationTypes(
3175 getFieldInClass(unit0, "B", "b2"), intType, intType);
3176 }
3177 }
3178
3179 @reflectiveTest
3180 class ResolveLibraryTypeNamesTaskTest extends _AbstractDartTaskTest {
3181 test_perform() {
3182 Source sourceLib = newSource(
3183 '/my_lib.dart',
3184 '''
3185 library my_lib;
3186 part 'my_part.dart';
3187 class A {}
3188 class B extends A {}
3189 ''');
3190 newSource(
3191 '/my_part.dart',
3192 '''
3193 part of my_lib;
3194 class C extends A {}
3195 ''');
3196 computeResult(sourceLib, LIBRARY_ELEMENT5,
3197 matcher: isResolveLibraryTypeNamesTask);
3198 // validate
3199 LibraryElement library = outputs[LIBRARY_ELEMENT5];
3200 {
3201 ClassElement classB = library.getType('B');
3202 expect(classB.supertype.displayName, 'A');
3203 }
3204 {
3205 ClassElement classC = library.getType('C');
3206 expect(classC.supertype.displayName, 'A');
3207 }
3208 }
3209
3210 test_perform_external() {
3211 Source sourceA = newSource(
3212 '/a.dart',
3213 '''
3214 library a;
3215 import 'b.dart';
3216 class A extends B {}
3217 ''');
3218 newSource(
3219 '/b.dart',
3220 '''
3221 library b;
3222 class B {}
3223 ''');
3224 // The reference A to B should be resolved, but there's no requirement that
3225 // the full class hierarchy be resolved.
3226 computeResult(sourceA, LIBRARY_ELEMENT5,
3227 matcher: isResolveLibraryTypeNamesTask);
3228 // validate
3229 LibraryElement library = outputs[LIBRARY_ELEMENT5];
3230 {
3231 ClassElement clazz = library.getType('A');
3232 expect(clazz.displayName, 'A');
3233 clazz = clazz.supertype.element;
3234 expect(clazz.displayName, 'B');
3235 }
3236 }
3237 }
3238
3239 @reflectiveTest
3240 class ResolveUnitTaskTest extends _AbstractDartTaskTest {
3241 void test_perform() {
3242 AnalysisTarget source = newSource(
3243 '/test.dart',
3244 '''
3245 void f() {
3246 var c = new C();
3247 c.m();
3248 }
3249 class C {
3250 void m() {
3251 f();
3252 }
3253 }
3254 ''');
3255 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9,
3256 matcher: isResolveUnitTask);
3257 CompilationUnit unit = outputs[RESOLVED_UNIT9];
3258
3259 FunctionDeclaration f = unit.declarations[0];
3260 _assertResolved(f.functionExpression.body);
3261
3262 MethodDeclaration m = (unit.declarations[1] as ClassDeclaration).members[0];
3263 _assertResolved(m.body);
3264
3265 expect(outputs[RESOLVE_UNIT_ERRORS], hasLength(0));
3266 }
3267
3268 void _assertResolved(FunctionBody body) {
3269 ResolutionVerifier verifier = new ResolutionVerifier();
3270 body.accept(verifier);
3271 verifier.assertResolved();
3272 }
3273 }
3274
3275 @reflectiveTest
3276 class ResolveUnitTypeNamesTaskTest extends _AbstractDartTaskTest {
3277 test_perform() {
3278 Source source = newSource(
3279 '/test.dart',
3280 '''
3281 class A {}
3282 class B extends A {}
3283 int f(String p) => p.length;
3284 ''');
3285 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
3286 computeResult(target, RESOLVED_UNIT3, matcher: isResolveUnitTypeNamesTask);
3287 // validate
3288 CompilationUnit unit = outputs[RESOLVED_UNIT3];
3289 {
3290 ClassDeclaration nodeA = unit.declarations[0];
3291 ClassDeclaration nodeB = unit.declarations[1];
3292 DartType extendsType = nodeB.extendsClause.superclass.type;
3293 expect(extendsType, nodeA.element.type);
3294 }
3295 {
3296 FunctionDeclaration functionNode = unit.declarations[2];
3297 DartType returnType = functionNode.returnType.type;
3298 List<FormalParameter> parameters =
3299 functionNode.functionExpression.parameters.parameters;
3300 expect(returnType.displayName, 'int');
3301 expect(parameters[0].element.type.displayName, 'String');
3302 }
3303 }
3304
3305 test_perform_errors() {
3306 Source source = newSource(
3307 '/test.dart',
3308 '''
3309 NoSuchClass f() => null;
3310 ''');
3311 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
3312 computeResult(target, RESOLVE_TYPE_NAMES_ERRORS,
3313 matcher: isResolveUnitTypeNamesTask);
3314 // validate
3315 _fillErrorListener(RESOLVE_TYPE_NAMES_ERRORS);
3316 errorListener
3317 .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]);
3318 }
3319
3320 test_perform_typedef() {
3321 Source source = newSource(
3322 '/test.dart',
3323 '''
3324 typedef int F(G g);
3325 typedef String G(int p);
3326 ''');
3327 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
3328 computeResult(target, RESOLVED_UNIT3, matcher: isResolveUnitTypeNamesTask);
3329 // validate
3330 CompilationUnit unit = outputs[RESOLVED_UNIT3];
3331 FunctionTypeAlias nodeF = unit.declarations[0];
3332 FunctionTypeAlias nodeG = unit.declarations[1];
3333 {
3334 FormalParameter parameter = nodeF.parameters.parameters[0];
3335 DartType parameterType = parameter.element.type;
3336 Element returnTypeElement = nodeF.returnType.type.element;
3337 expect(returnTypeElement.displayName, 'int');
3338 expect(parameterType.element, nodeG.element);
3339 }
3340 {
3341 FormalParameter parameter = nodeG.parameters.parameters[0];
3342 DartType parameterType = parameter.element.type;
3343 expect(nodeG.returnType.type.element.displayName, 'String');
3344 expect(parameterType.element.displayName, 'int');
3345 }
3346 }
3347
3348 test_perform_typedef_errors() {
3349 Source source = newSource(
3350 '/test.dart',
3351 '''
3352 typedef int F(NoSuchType p);
3353 ''');
3354 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
3355 computeResult(target, RESOLVE_TYPE_NAMES_ERRORS,
3356 matcher: isResolveUnitTypeNamesTask);
3357 // validate
3358 _fillErrorListener(RESOLVE_TYPE_NAMES_ERRORS);
3359 errorListener
3360 .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]);
3361 }
3362 }
3363
3364 @reflectiveTest
3365 class ResolveVariableReferencesTaskTest extends _AbstractDartTaskTest {
3366 /**
3367 * Verify that the mutated states of the given [variable] correspond to the
3368 * [mutatedInClosure] and [mutatedInScope] matchers.
3369 */
3370 void expectMutated(VariableElement variable, Matcher mutatedInClosure,
3371 Matcher mutatedInScope) {
3372 expect(variable.isPotentiallyMutatedInClosure, mutatedInClosure);
3373 expect(variable.isPotentiallyMutatedInScope, mutatedInScope);
3374 }
3375
3376 test_perform_buildClosureLibraryElements() {
3377 Source source = newSource(
3378 '/test.dart',
3379 '''
3380 main() {
3381 }
3382 ''');
3383 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
3384 computeResult(target, RESOLVED_UNIT4,
3385 matcher: isResolveVariableReferencesTask);
3386 }
3387
3388 test_perform_local() {
3389 Source source = newSource(
3390 '/test.dart',
3391 '''
3392 main() {
3393 var v1 = 1;
3394 var v2 = 1;
3395 var v3 = 1;
3396 var v4 = 1;
3397 v2 = 2;
3398 v4 = 2;
3399 localFunction() {
3400 v3 = 3;
3401 v4 = 3;
3402 }
3403 }
3404 ''');
3405 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
3406 computeResult(target, RESOLVED_UNIT4,
3407 matcher: isResolveVariableReferencesTask);
3408 // validate
3409 CompilationUnit unit = outputs[RESOLVED_UNIT4];
3410 FunctionElement main = unit.element.functions[0];
3411 expectMutated(main.localVariables[0], isFalse, isFalse);
3412 expectMutated(main.localVariables[1], isFalse, isTrue);
3413 expectMutated(main.localVariables[2], isTrue, isTrue);
3414 expectMutated(main.localVariables[3], isTrue, isTrue);
3415 }
3416
3417 test_perform_parameter() {
3418 Source source = newSource(
3419 '/test.dart',
3420 '''
3421 main(p1, p2, p3, p4) {
3422 p2 = 2;
3423 p4 = 2;
3424 localFunction() {
3425 p3 = 3;
3426 p4 = 3;
3427 }
3428 }
3429 ''');
3430 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
3431 computeResult(target, RESOLVED_UNIT4,
3432 matcher: isResolveVariableReferencesTask);
3433 // validate
3434 CompilationUnit unit = outputs[RESOLVED_UNIT4];
3435 FunctionElement main = unit.element.functions[0];
3436 expectMutated(main.parameters[0], isFalse, isFalse);
3437 expectMutated(main.parameters[1], isFalse, isTrue);
3438 expectMutated(main.parameters[2], isTrue, isTrue);
3439 expectMutated(main.parameters[3], isTrue, isTrue);
3440 }
3441 }
3442
3443 @reflectiveTest
3444 class ScanDartTaskTest extends _AbstractDartTaskTest {
3445 test_perform_errors() {
3446 _performScanTask('import "');
3447 expect(outputs, hasLength(3));
3448 expect(outputs[LINE_INFO], isNotNull);
3449 expect(outputs[SCAN_ERRORS], hasLength(1));
3450 expect(outputs[TOKEN_STREAM], isNotNull);
3451 }
3452
3453 test_perform_noErrors() {
3454 _performScanTask('class A {}');
3455 expect(outputs, hasLength(3));
3456 expect(outputs[LINE_INFO], isNotNull);
3457 expect(outputs[SCAN_ERRORS], hasLength(0));
3458 expect(outputs[TOKEN_STREAM], isNotNull);
3459 }
3460
3461 test_perform_script() {
3462 String scriptContent = '''
3463 void buttonPressed() {
3464 ''';
3465 String htmlContent = '''
3466 <!DOCTYPE html>
3467 <html>
3468 <head>
3469 <title>test page</title>
3470 <script type='application/dart'>$scriptContent</script>
3471 </head>
3472 <body>Test</body>
3473 </html>
3474 ''';
3475 Source source = newSource('/test.html', htmlContent);
3476 DartScript script =
3477 new DartScript(source, [new ScriptFragment(97, 5, 36, scriptContent)]);
3478
3479 computeResult(script, TOKEN_STREAM, matcher: isScanDartTask);
3480 expect(outputs[LINE_INFO], isNotNull);
3481 expect(outputs[SCAN_ERRORS], isEmpty);
3482 Token tokenStream = outputs[TOKEN_STREAM];
3483 expect(tokenStream, isNotNull);
3484 expect(tokenStream.lexeme, 'void');
3485 }
3486
3487 void _performScanTask(String content) {
3488 AnalysisTarget target = newSource('/test.dart', content);
3489 computeResult(target, TOKEN_STREAM, matcher: isScanDartTask);
3490 }
3491 }
3492
3493 @reflectiveTest
3494 class StrongModeInferenceTest extends _AbstractDartTaskTest {
3495 @override
3496 void setUp() {
3497 super.setUp();
3498 enableStrongMode();
3499 }
3500
3501 // Check that even within a static variable cycle, inferred
3502 // types get propagated to the members of the cycle.
3503 void test_perform_cycle() {
3504 AnalysisTarget source = newSource(
3505 '/test.dart',
3506 '''
3507 var piFirst = true;
3508 var pi = piFirst ? 3.14 : tau / 2;
3509 var tau = piFirst ? pi * 2 : 6.28;
3510 ''');
3511 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9);
3512 CompilationUnit unit = outputs[RESOLVED_UNIT9];
3513 VariableElement piFirst =
3514 getTopLevelVariable(unit, 'piFirst').name.staticElement;
3515 VariableElement pi = getTopLevelVariable(unit, 'pi').name.staticElement;
3516 VariableElement tau = getTopLevelVariable(unit, 'tau').name.staticElement;
3517 Expression piFirstUse = (getTopLevelVariable(unit, 'tau').initializer
3518 as ConditionalExpression).condition;
3519
3520 expect(piFirstUse.staticType, context.typeProvider.boolType);
3521 expect(piFirst.type, context.typeProvider.boolType);
3522 expect(pi.type.isDynamic, isTrue);
3523 expect(tau.type.isDynamic, isTrue);
3524 }
3525
3526 void test_perform_inference_cross_unit_cyclic() {
3527 AnalysisTarget firstSource = newSource(
3528 '/a.dart',
3529 '''
3530 import 'test.dart';
3531 var x = 2;
3532 class A { static var x = 2; }
3533 ''');
3534 AnalysisTarget secondSource = newSource(
3535 '/test.dart',
3536 '''
3537 import 'a.dart';
3538 var y = x;
3539 class B { static var y = A.x; }
3540
3541 test1() {
3542 int t = 3;
3543 t = x;
3544 t = y;
3545 t = A.x;
3546 t = B.y;
3547 }
3548 ''');
3549 computeResult(
3550 new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT9);
3551 CompilationUnit unit1 = outputs[RESOLVED_UNIT9];
3552 computeResult(
3553 new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT9);
3554 CompilationUnit unit2 = outputs[RESOLVED_UNIT9];
3555
3556 InterfaceType intType = context.typeProvider.intType;
3557
3558 assertVariableDeclarationTypes(
3559 getTopLevelVariable(unit1, "x"), intType, intType);
3560 assertVariableDeclarationTypes(
3561 getFieldInClass(unit1, "A", "x"), intType, intType);
3562
3563 assertVariableDeclarationTypes(
3564 getTopLevelVariable(unit2, "y"), intType, intType);
3565 assertVariableDeclarationTypes(
3566 getFieldInClass(unit2, "B", "y"), intType, intType);
3567
3568 List<Statement> statements =
3569 getStatementsInTopLevelFunction(unit2, "test1");
3570
3571 assertAssignmentStatementTypes(statements[1], intType, intType);
3572 assertAssignmentStatementTypes(statements[2], intType, intType);
3573 assertAssignmentStatementTypes(statements[3], intType, intType);
3574 assertAssignmentStatementTypes(statements[4], intType, intType);
3575 }
3576
3577 // Test that local variables in method bodies are inferred appropriately
3578 void test_perform_inference_cross_unit_instance() {
3579 List<Source> sources = newSources({
3580 '/a.dart': '''
3581 import 'b.dart';
3582 class A {
3583 final a2 = new B().b2;
3584 }
3585 ''',
3586 '/b.dart': '''
3587 class B {
3588 final b2 = 1;
3589 }
3590 ''',
3591 '/main.dart': '''
3592 import "a.dart";
3593
3594 test1() {
3595 int x = 0;
3596 x = new A().a2;
3597 }
3598 '''
3599 });
3600 List<dynamic> units =
3601 computeLibraryResults(sources, RESOLVED_UNIT9).toList();
3602 CompilationUnit unit0 = units[0];
3603 CompilationUnit unit1 = units[1];
3604 CompilationUnit unit2 = units[2];
3605
3606 InterfaceType intType = context.typeProvider.intType;
3607
3608 assertVariableDeclarationTypes(
3609 getFieldInClass(unit0, "A", "a2"), intType, intType);
3610
3611 assertVariableDeclarationTypes(
3612 getFieldInClass(unit1, "B", "b2"), intType, intType);
3613
3614 List<Statement> statements =
3615 getStatementsInTopLevelFunction(unit2, "test1");
3616
3617 assertAssignmentStatementTypes(statements[1], intType, intType);
3618 }
3619
3620 // Test inference interactions between local variables and fields
3621 void test_perform_inference_cross_unit_instance_member() {
3622 List<Source> sources = newSources({
3623 '/a.dart': '''
3624 import 'b.dart';
3625 var bar = new B();
3626 void foo() {
3627 String x = bar.f.z;
3628 }
3629 ''',
3630 '/b.dart': '''
3631 class C {
3632 var z = 3;
3633 }
3634
3635 class B {
3636 var f = new C();
3637 }
3638 ''',
3639 '/c.dart': '''
3640 import 'b.dart';
3641 var bar = new B();
3642 void foo() {
3643 String x = bar.f.z;
3644 }
3645 '''
3646 });
3647 List<dynamic> units =
3648 computeLibraryResults(sources, RESOLVED_UNIT9).toList();
3649 CompilationUnit unit0 = units[0];
3650 CompilationUnit unit1 = units[1];
3651 CompilationUnit unit2 = units[2];
3652
3653 InterfaceType intType = context.typeProvider.intType;
3654 InterfaceType stringType = context.typeProvider.stringType;
3655
3656 assertVariableDeclarationStatementTypes(
3657 getStatementsInTopLevelFunction(unit0, "foo")[0], stringType, intType);
3658 assertVariableDeclarationStatementTypes(
3659 getStatementsInTopLevelFunction(unit2, "foo")[0], stringType, intType);
3660 }
3661
3662 // Test inference interactions between local variables and top level
3663 // variables
3664 void test_perform_inference_cross_unit_non_cyclic() {
3665 AnalysisTarget firstSource = newSource(
3666 '/a.dart',
3667 '''
3668 var x = 2;
3669 class A { static var x = 2; }
3670 ''');
3671 AnalysisTarget secondSource = newSource(
3672 '/test.dart',
3673 '''
3674 import 'a.dart';
3675 var y = x;
3676 class B { static var y = A.x; }
3677
3678 test1() {
3679 x = /*severe:StaticTypeError*/"hi";
3680 y = /*severe:StaticTypeError*/"hi";
3681 A.x = /*severe:StaticTypeError*/"hi";
3682 B.y = /*severe:StaticTypeError*/"hi";
3683 }
3684 ''');
3685 computeResult(
3686 new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT9);
3687 CompilationUnit unit1 = outputs[RESOLVED_UNIT9];
3688 computeResult(
3689 new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT9);
3690 CompilationUnit unit2 = outputs[RESOLVED_UNIT9];
3691
3692 InterfaceType intType = context.typeProvider.intType;
3693 InterfaceType stringType = context.typeProvider.stringType;
3694
3695 assertVariableDeclarationTypes(
3696 getTopLevelVariable(unit1, "x"), intType, intType);
3697 assertVariableDeclarationTypes(
3698 getFieldInClass(unit1, "A", "x"), intType, intType);
3699
3700 assertVariableDeclarationTypes(
3701 getTopLevelVariable(unit2, "y"), intType, intType);
3702 assertVariableDeclarationTypes(
3703 getFieldInClass(unit2, "B", "y"), intType, intType);
3704
3705 List<Statement> statements =
3706 getStatementsInTopLevelFunction(unit2, "test1");
3707
3708 assertAssignmentStatementTypes(statements[0], intType, stringType);
3709 assertAssignmentStatementTypes(statements[1], intType, stringType);
3710 }
3711
3712 // Test that inference does not propagate from null
3713 void test_perform_inference_cross_unit_static_instance() {
3714 List<Source> sources = newSources({
3715 '/a.dart': '''
3716 import 'b.dart';
3717 class A {
3718 static final a1 = B.b1;
3719 final a2 = new B().b2;
3720 }
3721 ''',
3722 '/b.dart': '''
3723 class B {
3724 static final b1 = 1;
3725 final b2 = 1;
3726 }
3727 ''',
3728 '/main.dart': '''
3729 import "a.dart";
3730
3731 test1() {
3732 int x = 0;
3733 // inference in A now works.
3734 x = A.a1;
3735 x = new A().a2;
3736 }
3737 '''
3738 });
3739 List<dynamic> units =
3740 computeLibraryResults(sources, RESOLVED_UNIT9).toList();
3741 CompilationUnit unit0 = units[0];
3742 CompilationUnit unit1 = units[1];
3743 CompilationUnit unit2 = units[2];
3744
3745 InterfaceType intType = context.typeProvider.intType;
3746
3747 assertVariableDeclarationTypes(
3748 getFieldInClass(unit0, "A", "a1"), intType, intType);
3749 assertVariableDeclarationTypes(
3750 getFieldInClass(unit0, "A", "a2"), intType, intType);
3751
3752 assertVariableDeclarationTypes(
3753 getFieldInClass(unit1, "B", "b1"), intType, intType);
3754 assertVariableDeclarationTypes(
3755 getFieldInClass(unit1, "B", "b2"), intType, intType);
3756
3757 List<Statement> statements =
3758 getStatementsInTopLevelFunction(unit2, "test1");
3759
3760 assertAssignmentStatementTypes(statements[1], intType, intType);
3761 assertAssignmentStatementTypes(statements[2], intType, intType);
3762 }
3763
3764 // Test inference across units (non-cyclic)
3765 void test_perform_inference_local_variables() {
3766 AnalysisTarget source = newSource(
3767 '/test.dart',
3768 '''
3769 test() {
3770 int x = 3;
3771 x = "hi";
3772 var y = 3;
3773 y = "hi";
3774 }
3775 ''');
3776 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9);
3777 CompilationUnit unit = outputs[RESOLVED_UNIT9];
3778
3779 InterfaceType intType = context.typeProvider.intType;
3780 InterfaceType stringType = context.typeProvider.stringType;
3781
3782 List<Statement> statements = getStatementsInTopLevelFunction(unit, "test");
3783
3784 assertVariableDeclarationStatementTypes(statements[0], intType, intType);
3785 assertAssignmentStatementTypes(statements[1], intType, stringType);
3786 assertVariableDeclarationStatementTypes(statements[2], intType, intType);
3787 assertAssignmentStatementTypes(statements[3], intType, stringType);
3788 }
3789
3790 // Test inference across units (cyclic)
3791 void test_perform_inference_local_variables_fields() {
3792 AnalysisTarget source = newSource(
3793 '/test.dart',
3794 '''
3795 class A {
3796 int x = 0;
3797
3798 test1() {
3799 var a = x;
3800 a = "hi";
3801 a = 3;
3802 var b = y;
3803 b = "hi";
3804 b = 4;
3805 var c = z;
3806 c = "hi";
3807 c = 4;
3808 }
3809
3810 int y; // field def after use
3811 final z = 42; // should infer `int`
3812 }
3813 ''');
3814 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9);
3815 CompilationUnit unit = outputs[RESOLVED_UNIT9];
3816
3817 InterfaceType intType = context.typeProvider.intType;
3818 InterfaceType stringType = context.typeProvider.stringType;
3819
3820 List<Statement> statements = getStatementsInMethod(unit, "A", "test1");
3821
3822 assertVariableDeclarationStatementTypes(statements[0], intType, intType);
3823 assertAssignmentStatementTypes(statements[1], intType, stringType);
3824 assertAssignmentStatementTypes(statements[2], intType, intType);
3825
3826 assertVariableDeclarationStatementTypes(statements[3], intType, intType);
3827 assertAssignmentStatementTypes(statements[4], intType, stringType);
3828 assertAssignmentStatementTypes(statements[5], intType, intType);
3829
3830 assertVariableDeclarationStatementTypes(statements[6], intType, intType);
3831 assertAssignmentStatementTypes(statements[7], intType, stringType);
3832 assertAssignmentStatementTypes(statements[8], intType, intType);
3833
3834 assertVariableDeclarationTypes(
3835 getFieldInClass(unit, "A", "x"), intType, intType);
3836 assertVariableDeclarationTypes(
3837 getFieldInClass(unit, "A", "z"), intType, intType);
3838 }
3839
3840 // Test inference of instance fields across units
3841 void test_perform_inference_local_variables_topLevel() {
3842 AnalysisTarget source = newSource(
3843 '/test.dart',
3844 '''
3845 int x = 0;
3846
3847 test1() {
3848 var a = x;
3849 a = /*severe:StaticTypeError*/"hi";
3850 a = 3;
3851 var b = y;
3852 b = /*severe:StaticTypeError*/"hi";
3853 b = 4;
3854 var c = z;
3855 c = /*severe:StaticTypeError*/"hi";
3856 c = 4;
3857 }
3858
3859 int y = 0; // field def after use
3860 final z = 42; // should infer `int`
3861 ''');
3862 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9);
3863 CompilationUnit unit = outputs[RESOLVED_UNIT9];
3864
3865 InterfaceType intType = context.typeProvider.intType;
3866 InterfaceType stringType = context.typeProvider.stringType;
3867
3868 List<Statement> statements = getStatementsInTopLevelFunction(unit, "test1");
3869
3870 assertVariableDeclarationStatementTypes(statements[0], intType, intType);
3871 assertAssignmentStatementTypes(statements[1], intType, stringType);
3872 assertAssignmentStatementTypes(statements[2], intType, intType);
3873
3874 assertVariableDeclarationStatementTypes(statements[3], intType, intType);
3875 assertAssignmentStatementTypes(statements[4], intType, stringType);
3876 assertAssignmentStatementTypes(statements[5], intType, intType);
3877
3878 assertVariableDeclarationStatementTypes(statements[6], intType, intType);
3879 assertAssignmentStatementTypes(statements[7], intType, stringType);
3880 assertAssignmentStatementTypes(statements[8], intType, intType);
3881
3882 assertVariableDeclarationTypes(
3883 getTopLevelVariable(unit, "x"), intType, intType);
3884 assertVariableDeclarationTypes(
3885 getTopLevelVariable(unit, "y"), intType, intType);
3886 assertVariableDeclarationTypes(
3887 getTopLevelVariable(unit, "z"), intType, intType);
3888 }
3889
3890 // Test inference between static and instance fields
3891 void test_perform_inference_null() {
3892 AnalysisTarget source = newSource(
3893 '/test.dart',
3894 '''
3895 var x = null;
3896 var y = 3;
3897 class A {
3898 static var x = null;
3899 static var y = 3;
3900
3901 var x2 = null;
3902 var y2 = 3;
3903 }
3904
3905 test() {
3906 x = "hi";
3907 y = /*severe:StaticTypeError*/"hi";
3908 A.x = "hi";
3909 A.y = /*severe:StaticTypeError*/"hi";
3910 new A().x2 = "hi";
3911 new A().y2 = /*severe:StaticTypeError*/"hi";
3912 }
3913 ''');
3914 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9);
3915 CompilationUnit unit = outputs[RESOLVED_UNIT9];
3916
3917 InterfaceType intType = context.typeProvider.intType;
3918 InterfaceType stringType = context.typeProvider.stringType;
3919 DartType bottomType = context.typeProvider.bottomType;
3920 DartType dynamicType = context.typeProvider.dynamicType;
3921
3922 assertVariableDeclarationTypes(
3923 getTopLevelVariable(unit, "x"), dynamicType, bottomType);
3924 assertVariableDeclarationTypes(
3925 getTopLevelVariable(unit, "y"), intType, intType);
3926 assertVariableDeclarationTypes(
3927 getFieldInClass(unit, "A", "x"), dynamicType, bottomType);
3928 assertVariableDeclarationTypes(
3929 getFieldInClass(unit, "A", "y"), intType, intType);
3930 assertVariableDeclarationTypes(
3931 getFieldInClass(unit, "A", "x2"), dynamicType, bottomType);
3932 assertVariableDeclarationTypes(
3933 getFieldInClass(unit, "A", "y2"), intType, intType);
3934
3935 List<Statement> statements = getStatementsInTopLevelFunction(unit, "test");
3936
3937 assertAssignmentStatementTypes(statements[0], dynamicType, stringType);
3938 assertAssignmentStatementTypes(statements[1], intType, stringType);
3939 assertAssignmentStatementTypes(statements[2], dynamicType, stringType);
3940 assertAssignmentStatementTypes(statements[3], intType, stringType);
3941 assertAssignmentStatementTypes(statements[4], dynamicType, stringType);
3942 assertAssignmentStatementTypes(statements[5], intType, stringType);
3943 }
3944
3945 // Test inference between fields and method bodies
3946 void test_perform_local_explicit_disabled() {
3947 AnalysisTarget source = newSource(
3948 '/test.dart',
3949 '''
3950 test() {
3951 int x = 3;
3952 x = "hi";
3953 }
3954 ''');
3955 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9);
3956 CompilationUnit unit = outputs[RESOLVED_UNIT9];
3957
3958 InterfaceType intType = context.typeProvider.intType;
3959 InterfaceType stringType = context.typeProvider.stringType;
3960
3961 List<Statement> statements = getStatementsInTopLevelFunction(unit, "test");
3962 VariableDeclaration decl =
3963 (statements[0] as VariableDeclarationStatement).variables.variables[0];
3964 expect(decl.element.type, intType);
3965 expect(decl.initializer.staticType, intType);
3966
3967 ExpressionStatement statement = statements[1];
3968 AssignmentExpression assgn = statement.expression;
3969 expect(assgn.leftHandSide.staticType, intType);
3970 expect(assgn.rightHandSide.staticType, stringType);
3971 }
3972 }
3973
3974 @reflectiveTest
3975 class VerifyUnitTaskTest extends _AbstractDartTaskTest {
3976 test_perform_constantError() {
3977 Source source = newSource(
3978 '/test.dart',
3979 '''
3980 main(int p) {
3981 const v = p;
3982 }
3983 ''');
3984 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
3985 computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
3986 // validate
3987 _fillErrorListener(VERIFY_ERRORS);
3988 errorListener.assertErrorsWithCodes(<ErrorCode>[
3989 CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
3990 ]);
3991 }
3992
3993 test_perform_directiveError() {
3994 Source source = newSource(
3995 '/test.dart',
3996 '''
3997 import 'no-such-file.dart';
3998 ''');
3999 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
4000 computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
4001 // validate
4002 _fillErrorListener(VERIFY_ERRORS);
4003 errorListener.assertErrorsWithCodes(
4004 <ErrorCode>[CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
4005 }
4006
4007 void test_perform_reresolution() {
4008 enableStrongMode();
4009 AnalysisTarget source = newSource(
4010 '/test.dart',
4011 '''
4012 const topLevel = 3;
4013 class C {
4014 String field = topLevel;
4015 }
4016 ''');
4017 computeResult(new LibrarySpecificUnit(source, source), VERIFY_ERRORS);
4018 // validate
4019 _fillErrorListener(VERIFY_ERRORS);
4020 errorListener.assertErrorsWithCodes(
4021 <ErrorCode>[StaticTypeWarningCode.INVALID_ASSIGNMENT]);
4022 }
4023
4024 test_perform_verifyError() {
4025 Source source = newSource(
4026 '/test.dart',
4027 '''
4028 main() {
4029 if (42) {
4030 print('Not bool!');
4031 }
4032 }
4033 ''');
4034 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
4035 computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
4036 // validate
4037 _fillErrorListener(VERIFY_ERRORS);
4038 errorListener.assertErrorsWithCodes(
4039 <ErrorCode>[StaticTypeWarningCode.NON_BOOL_CONDITION]);
4040 }
4041 }
4042
4043 class _AbstractDartTaskTest extends AbstractContextTest {
4044 Source emptySource;
4045
4046 GatheringErrorListener errorListener = new GatheringErrorListener();
4047
4048 void assertAssignmentStatementTypes(
4049 Statement stmt, DartType leftType, DartType rightType) {
4050 AssignmentExpression assgn = (stmt as ExpressionStatement).expression;
4051 expect(assgn.leftHandSide.staticType, leftType);
4052 expect(assgn.rightHandSide.staticType, rightType);
4053 }
4054
4055 void assertIsInvalid(AnalysisTarget target, ResultDescriptor descriptor) {
4056 CacheEntry entry = context.getCacheEntry(target);
4057 expect(entry.isInvalid(descriptor), isTrue);
4058 }
4059
4060 void assertIsValid(AnalysisTarget target, ResultDescriptor descriptor) {
4061 CacheEntry entry = context.getCacheEntry(target);
4062 expect(entry.isValid(descriptor), isTrue);
4063 }
4064
4065 void assertSameResults(List<ResultDescriptor> descriptors) {
4066 descriptors.forEach((descriptor) {
4067 var oldResult = oldOutputs[descriptor];
4068 var newResult = outputs[descriptor];
4069 expect(newResult, same(oldResult), reason: descriptor.name);
4070 });
4071 }
4072
4073 void assertVariableDeclarationStatementTypes(
4074 Statement stmt, DartType varType, DartType initializerType) {
4075 VariableDeclaration decl =
4076 (stmt as VariableDeclarationStatement).variables.variables[0];
4077 assertVariableDeclarationTypes(decl, varType, initializerType);
4078 }
4079
4080 void assertVariableDeclarationTypes(
4081 VariableDeclaration decl, DartType varType, DartType initializerType) {
4082 expect(decl.element.type, varType);
4083 expect(decl.initializer.staticType, initializerType);
4084 }
4085
4086 List<dynamic> computeLibraryResults(
4087 List<Source> sources, ResultDescriptor result,
4088 {isInstanceOf matcher: null}) {
4089 dynamic compute(Source source) {
4090 computeResult(new LibrarySpecificUnit(source, source), result,
4091 matcher: matcher);
4092 return outputs[result];
4093 }
4094 return sources.map(compute).toList();
4095 }
4096
4097 List<Map<ResultDescriptor, dynamic>> computeLibraryResultsMap(
4098 List<Source> sources, ResultDescriptor result,
4099 {isInstanceOf matcher: null}) {
4100 Map<ResultDescriptor, dynamic> compute(Source source) {
4101 computeResult(new LibrarySpecificUnit(source, source), result,
4102 matcher: matcher);
4103 return outputs;
4104 }
4105 return sources.map(compute).toList();
4106 }
4107
4108 /**
4109 * Create a script object with a single fragment containing the given
4110 * [scriptContent].
4111 */
4112 DartScript createScript(String scriptContent) {
4113 String htmlContent = '''
4114 <!DOCTYPE html>
4115 <html>
4116 <head>
4117 <title>test page</title>
4118 <script type='application/dart'>$scriptContent</script>
4119 </head>
4120 <body>Test</body>
4121 </html>
4122 ''';
4123 Source source = newSource('/test.html', htmlContent);
4124 return new DartScript(
4125 source, [new ScriptFragment(97, 5, 36, scriptContent)]);
4126 }
4127
4128 /**
4129 * Enable strong mode in the current analysis context.
4130 */
4131 void enableStrongMode() {
4132 AnalysisOptionsImpl options = context.analysisOptions;
4133 options.strongMode = true;
4134 context.analysisOptions = options;
4135 }
4136
4137 /**
4138 * Return the declaration of the class with the given [className] in the given
4139 * compilation [unit].
4140 */
4141 ClassDeclaration getClass(CompilationUnit unit, String className) {
4142 NodeList<CompilationUnitMember> unitMembers = unit.declarations;
4143 for (CompilationUnitMember unitMember in unitMembers) {
4144 if (unitMember is ClassDeclaration && unitMember.name.name == className) {
4145 return unitMember;
4146 }
4147 }
4148 fail('No class named $className in ${unit.element.source}');
4149 return null;
4150 }
4151
4152 /**
4153 * Return the declaration of the field with the given [fieldName] in the class
4154 * with the given [className] in the given compilation [unit].
4155 */
4156 VariableDeclaration getFieldInClass(
4157 CompilationUnit unit, String className, String fieldName) {
4158 ClassDeclaration unitMember = getClass(unit, className);
4159 NodeList<ClassMember> classMembers = unitMember.members;
4160 for (ClassMember classMember in classMembers) {
4161 if (classMember is FieldDeclaration) {
4162 NodeList<VariableDeclaration> fields = classMember.fields.variables;
4163 for (VariableDeclaration field in fields) {
4164 if (field.name.name == fieldName) {
4165 return field;
4166 }
4167 }
4168 }
4169 }
4170 fail('No field named $fieldName in $className');
4171 return null;
4172 }
4173
4174 /**
4175 * Return the declaration of the method with the given [methodName] in the
4176 * class with the given [className] in the given compilation [unit].
4177 */
4178 MethodDeclaration getMethodInClass(
4179 CompilationUnit unit, String className, String methodName) {
4180 ClassDeclaration unitMember = getClass(unit, className);
4181 NodeList<ClassMember> classMembers = unitMember.members;
4182 for (ClassMember classMember in classMembers) {
4183 if (classMember is MethodDeclaration) {
4184 if (classMember.name.name == methodName) {
4185 return classMember;
4186 }
4187 }
4188 }
4189 fail('No method named $methodName in $className');
4190 return null;
4191 }
4192
4193 List<Statement> getStatementsInMethod(
4194 CompilationUnit unit, String className, String methodName) {
4195 MethodDeclaration method = getMethodInClass(unit, className, methodName);
4196 BlockFunctionBody body = method.body;
4197 return body.block.statements;
4198 }
4199
4200 List<Statement> getStatementsInTopLevelFunction(
4201 CompilationUnit unit, String functionName) {
4202 FunctionDeclaration function = getTopLevelFunction(unit, functionName);
4203 BlockFunctionBody body = function.functionExpression.body;
4204 return body.block.statements;
4205 }
4206
4207 /**
4208 * Return the declaration of the top-level function with the given
4209 * [functionName] in the given compilation [unit].
4210 */
4211 FunctionDeclaration getTopLevelFunction(
4212 CompilationUnit unit, String functionName) {
4213 NodeList<CompilationUnitMember> unitMembers = unit.declarations;
4214 for (CompilationUnitMember unitMember in unitMembers) {
4215 if (unitMember is FunctionDeclaration) {
4216 if (unitMember.name.name == functionName) {
4217 return unitMember;
4218 }
4219 }
4220 }
4221 return null;
4222 }
4223
4224 /**
4225 * Return the declaration of the top-level variable with the given
4226 * [variableName] in the given compilation [unit].
4227 */
4228 VariableDeclaration getTopLevelVariable(
4229 CompilationUnit unit, String variableName) {
4230 NodeList<CompilationUnitMember> unitMembers = unit.declarations;
4231 for (CompilationUnitMember unitMember in unitMembers) {
4232 if (unitMember is TopLevelVariableDeclaration) {
4233 NodeList<VariableDeclaration> variables =
4234 unitMember.variables.variables;
4235 for (VariableDeclaration variable in variables) {
4236 if (variable.name.name == variableName) {
4237 return variable;
4238 }
4239 }
4240 }
4241 }
4242 return null;
4243 }
4244
4245 void setUp() {
4246 super.setUp();
4247 emptySource = newSource('/test.dart');
4248 }
4249
4250 /**
4251 * Fill [errorListener] with [result] errors in the current [task].
4252 */
4253 void _fillErrorListener(ResultDescriptor<List<AnalysisError>> result) {
4254 List<AnalysisError> errors = task.outputs[result];
4255 expect(errors, isNotNull, reason: result.name);
4256 errorListener = new GatheringErrorListener();
4257 errorListener.addAll(errors);
4258 }
4259 }
OLDNEW
« no previous file with comments | « packages/analyzer/test/src/plugin/plugin_config_test.dart ('k') | packages/analyzer/test/src/task/dart_work_manager_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698