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

Side by Side Diff: packages/analyzer/test/generated/resolver_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) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library engine.resolver_test;
6
7 import 'dart:collection';
8
9 import 'package:analyzer/src/context/context.dart' as newContext;
10 import 'package:analyzer/src/generated/ast.dart';
11 import 'package:analyzer/src/generated/element.dart';
12 import 'package:analyzer/src/generated/element_resolver.dart';
13 import 'package:analyzer/src/generated/engine.dart';
14 import 'package:analyzer/src/generated/error.dart';
15 import 'package:analyzer/src/generated/java_core.dart';
16 import 'package:analyzer/src/generated/java_engine.dart';
17 import 'package:analyzer/src/generated/java_engine_io.dart';
18 import 'package:analyzer/src/generated/java_io.dart';
19 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
20 import 'package:analyzer/src/generated/resolver.dart';
21 import 'package:analyzer/src/generated/scanner.dart';
22 import 'package:analyzer/src/generated/sdk.dart';
23 import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
24 import 'package:analyzer/src/generated/source_io.dart';
25 import 'package:analyzer/src/generated/static_type_analyzer.dart';
26 import 'package:analyzer/src/generated/testing/ast_factory.dart';
27 import 'package:analyzer/src/generated/testing/element_factory.dart';
28 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
29 import 'package:analyzer/src/generated/testing/token_factory.dart';
30 import 'package:analyzer/src/generated/utilities_dart.dart';
31 import 'package:unittest/unittest.dart';
32
33 import '../reflective_tests.dart';
34 import '../utils.dart';
35 import 'test_support.dart';
36
37 main() {
38 initializeTestEnvironment();
39 runReflectiveTests(AnalysisDeltaTest);
40 runReflectiveTests(ChangeSetTest);
41 runReflectiveTests(EnclosedScopeTest);
42 runReflectiveTests(LibraryImportScopeTest);
43 runReflectiveTests(LibraryScopeTest);
44 runReflectiveTests(ScopeTest);
45 runReflectiveTests(ElementResolverTest);
46 runReflectiveTests(InheritanceManagerTest);
47 if (!AnalysisEngine.instance.useTaskModel) {
48 runReflectiveTests(LibraryElementBuilderTest);
49 }
50 if (!AnalysisEngine.instance.useTaskModel) {
51 runReflectiveTests(LibraryResolver2Test);
52 }
53 if (!AnalysisEngine.instance.useTaskModel) {
54 runReflectiveTests(LibraryResolverTest);
55 }
56 runReflectiveTests(LibraryTest);
57 runReflectiveTests(StaticTypeAnalyzerTest);
58 runReflectiveTests(StaticTypeAnalyzer2Test);
59 runReflectiveTests(SubtypeManagerTest);
60 runReflectiveTests(TypeOverrideManagerTest);
61 runReflectiveTests(TypeProviderImplTest);
62 runReflectiveTests(TypeResolverVisitorTest);
63 runReflectiveTests(CheckedModeCompileTimeErrorCodeTest);
64 runReflectiveTests(ErrorResolverTest);
65 runReflectiveTests(HintCodeTest);
66 runReflectiveTests(MemberMapTest);
67 runReflectiveTests(NonHintCodeTest);
68 runReflectiveTests(SimpleResolverTest);
69 runReflectiveTests(StrictModeTest);
70 runReflectiveTests(TypePropagationTest);
71 runReflectiveTests(StrongModeStaticTypeAnalyzer2Test);
72 runReflectiveTests(StrongModeTypePropagationTest);
73 }
74
75 /**
76 * The class `AnalysisContextFactory` defines utility methods used to create ana lysis contexts
77 * for testing purposes.
78 */
79 class AnalysisContextFactory {
80 static String _DART_MATH = "dart:math";
81
82 static String _DART_INTERCEPTORS = "dart:_interceptors";
83
84 static String _DART_JS_HELPER = "dart:_js_helper";
85
86 /**
87 * Create an analysis context that has a fake core library already resolved.
88 * Return the context that was created.
89 */
90 static InternalAnalysisContext contextWithCore() {
91 if (AnalysisEngine.instance.useTaskModel) {
92 NewAnalysisContextForTests context = new NewAnalysisContextForTests();
93 return initContextWithCore(context);
94 }
95 AnalysisContextForTests context = new AnalysisContextForTests();
96 return initContextWithCore(context);
97 }
98
99 /**
100 * Create an analysis context that uses the given [options] and has a fake
101 * core library already resolved. Return the context that was created.
102 */
103 static InternalAnalysisContext contextWithCoreAndOptions(
104 AnalysisOptions options) {
105 if (AnalysisEngine.instance.useTaskModel) {
106 NewAnalysisContextForTests context = new NewAnalysisContextForTests();
107 context._internalSetAnalysisOptions(options);
108 return initContextWithCore(context);
109 }
110 AnalysisContextForTests context = new AnalysisContextForTests();
111 context._internalSetAnalysisOptions(options);
112 return initContextWithCore(context);
113 }
114
115 /**
116 * Initialize the given analysis context with a fake core library already reso lved.
117 *
118 * @param context the context to be initialized (not `null`)
119 * @return the analysis context that was created
120 */
121 static InternalAnalysisContext initContextWithCore(
122 InternalAnalysisContext context) {
123 DirectoryBasedDartSdk sdk = new _AnalysisContextFactory_initContextWithCore(
124 new JavaFile("/fake/sdk"));
125 SourceFactory sourceFactory =
126 new SourceFactory([new DartUriResolver(sdk), new FileUriResolver()]);
127 context.sourceFactory = sourceFactory;
128 AnalysisContext coreContext = sdk.context;
129 //
130 // dart:core
131 //
132 TestTypeProvider provider = new TestTypeProvider();
133 CompilationUnitElementImpl coreUnit =
134 new CompilationUnitElementImpl("core.dart");
135 Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE);
136 coreContext.setContents(coreSource, "");
137 coreUnit.librarySource = coreUnit.source = coreSource;
138 ClassElementImpl proxyClassElement = ElementFactory.classElement2("_Proxy");
139 ClassElement objectClassElement = provider.objectType.element;
140 coreUnit.types = <ClassElement>[
141 provider.boolType.element,
142 provider.deprecatedType.element,
143 provider.doubleType.element,
144 provider.functionType.element,
145 provider.intType.element,
146 provider.iterableType.element,
147 provider.iteratorType.element,
148 provider.listType.element,
149 provider.mapType.element,
150 provider.nullType.element,
151 provider.numType.element,
152 objectClassElement,
153 proxyClassElement,
154 provider.stackTraceType.element,
155 provider.stringType.element,
156 provider.symbolType.element,
157 provider.typeType.element
158 ];
159 coreUnit.functions = <FunctionElement>[
160 ElementFactory.functionElement3("identical", provider.boolType.element,
161 <ClassElement>[objectClassElement, objectClassElement], null),
162 ElementFactory.functionElement3("print", VoidTypeImpl.instance.element,
163 <ClassElement>[objectClassElement], null)
164 ];
165 TopLevelVariableElement proxyTopLevelVariableElt = ElementFactory
166 .topLevelVariableElement3("proxy", true, false, proxyClassElement.type);
167 ConstTopLevelVariableElementImpl deprecatedTopLevelVariableElt =
168 ElementFactory.topLevelVariableElement3(
169 "deprecated", true, false, provider.deprecatedType);
170 deprecatedTopLevelVariableElt.constantInitializer = AstFactory
171 .instanceCreationExpression2(
172 Keyword.CONST,
173 AstFactory.typeName(provider.deprecatedType.element),
174 [AstFactory.string2('next release')]);
175 coreUnit.accessors = <PropertyAccessorElement>[
176 proxyTopLevelVariableElt.getter,
177 deprecatedTopLevelVariableElt.getter
178 ];
179 coreUnit.topLevelVariables = <TopLevelVariableElement>[
180 proxyTopLevelVariableElt,
181 deprecatedTopLevelVariableElt
182 ];
183 LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
184 coreContext, AstFactory.libraryIdentifier2(["dart", "core"]));
185 coreLibrary.definingCompilationUnit = coreUnit;
186 //
187 // dart:async
188 //
189 CompilationUnitElementImpl asyncUnit =
190 new CompilationUnitElementImpl("async.dart");
191 Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
192 coreContext.setContents(asyncSource, "");
193 asyncUnit.librarySource = asyncUnit.source = asyncSource;
194 // Future
195 ClassElementImpl futureElement =
196 ElementFactory.classElement2("Future", ["T"]);
197 // factory Future.value([value])
198 ConstructorElementImpl futureConstructor =
199 ElementFactory.constructorElement2(futureElement, "value");
200 futureConstructor.parameters = <ParameterElement>[
201 ElementFactory.positionalParameter2("value", provider.dynamicType)
202 ];
203 futureConstructor.factory = true;
204 (futureConstructor.type as FunctionTypeImpl).typeArguments =
205 futureElement.type.typeArguments;
206 futureElement.constructors = <ConstructorElement>[futureConstructor];
207 // Future then(onValue(T value), { Function onError });
208 List<ParameterElement> parameters = <ParameterElement>[
209 ElementFactory.requiredParameter2(
210 "value", futureElement.typeParameters[0].type)
211 ];
212 FunctionTypeAliasElementImpl aliasElement =
213 new FunctionTypeAliasElementImpl.forNode(null);
214 aliasElement.synthetic = true;
215 aliasElement.parameters = parameters;
216 aliasElement.returnType = provider.dynamicType;
217 aliasElement.enclosingElement = asyncUnit;
218 FunctionTypeImpl aliasType = new FunctionTypeImpl.forTypedef(aliasElement);
219 aliasElement.shareTypeParameters(futureElement.typeParameters);
220 aliasType.typeArguments = futureElement.type.typeArguments;
221 DartType futureDynamicType =
222 futureElement.type.substitute4([provider.dynamicType]);
223 MethodElement thenMethod = ElementFactory.methodElementWithParameters(
224 "then", futureElement.type.typeArguments, futureDynamicType, [
225 ElementFactory.requiredParameter2("onValue", aliasType),
226 ElementFactory.namedParameter2("onError", provider.functionType)
227 ]);
228 futureElement.methods = <MethodElement>[thenMethod];
229 // Completer
230 ClassElementImpl completerElement =
231 ElementFactory.classElement2("Completer", ["T"]);
232 ConstructorElementImpl completerConstructor =
233 ElementFactory.constructorElement2(completerElement, null);
234 (completerConstructor.type as FunctionTypeImpl).typeArguments =
235 completerElement.type.typeArguments;
236 completerElement.constructors = <ConstructorElement>[completerConstructor];
237 // StreamSubscription
238 ClassElementImpl streamSubscriptionElement =
239 ElementFactory.classElement2("StreamSubscription", ["T"]);
240 // Stream
241 ClassElementImpl streamElement =
242 ElementFactory.classElement2("Stream", ["T"]);
243 streamElement.constructors = <ConstructorElement>[
244 ElementFactory.constructorElement2(streamElement, null)
245 ];
246 DartType returnType = streamSubscriptionElement.type
247 .substitute4(streamElement.type.typeArguments);
248 List<DartType> parameterTypes = <DartType>[
249 ElementFactory
250 .functionElement3('onData', VoidTypeImpl.instance.element,
251 <TypeDefiningElement>[streamElement.typeParameters[0]], null)
252 .type,
253 ];
254 // TODO(brianwilkerson) This is missing the optional parameters.
255 MethodElementImpl listenMethod =
256 ElementFactory.methodElement('listen', returnType, parameterTypes);
257 streamElement.methods = <MethodElement>[listenMethod];
258
259 asyncUnit.types = <ClassElement>[
260 completerElement,
261 futureElement,
262 streamElement
263 ];
264 LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
265 coreContext, AstFactory.libraryIdentifier2(["dart", "async"]));
266 asyncLibrary.definingCompilationUnit = asyncUnit;
267 //
268 // dart:html
269 //
270 CompilationUnitElementImpl htmlUnit =
271 new CompilationUnitElementImpl("html_dartium.dart");
272 Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
273 coreContext.setContents(htmlSource, "");
274 htmlUnit.librarySource = htmlUnit.source = htmlSource;
275 ClassElementImpl elementElement = ElementFactory.classElement2("Element");
276 InterfaceType elementType = elementElement.type;
277 ClassElementImpl canvasElement =
278 ElementFactory.classElement("CanvasElement", elementType);
279 ClassElementImpl contextElement =
280 ElementFactory.classElement2("CanvasRenderingContext");
281 InterfaceType contextElementType = contextElement.type;
282 ClassElementImpl context2dElement = ElementFactory.classElement(
283 "CanvasRenderingContext2D", contextElementType);
284 canvasElement.methods = <MethodElement>[
285 ElementFactory.methodElement(
286 "getContext", contextElementType, [provider.stringType])
287 ];
288 canvasElement.accessors = <PropertyAccessorElement>[
289 ElementFactory.getterElement("context2D", false, context2dElement.type)
290 ];
291 canvasElement.fields = canvasElement.accessors
292 .map((PropertyAccessorElement accessor) => accessor.variable)
293 .toList();
294 ClassElementImpl documentElement =
295 ElementFactory.classElement("Document", elementType);
296 ClassElementImpl htmlDocumentElement =
297 ElementFactory.classElement("HtmlDocument", documentElement.type);
298 htmlDocumentElement.methods = <MethodElement>[
299 ElementFactory.methodElement(
300 "query", elementType, <DartType>[provider.stringType])
301 ];
302 htmlUnit.types = <ClassElement>[
303 ElementFactory.classElement("AnchorElement", elementType),
304 ElementFactory.classElement("BodyElement", elementType),
305 ElementFactory.classElement("ButtonElement", elementType),
306 canvasElement,
307 contextElement,
308 context2dElement,
309 ElementFactory.classElement("DivElement", elementType),
310 documentElement,
311 elementElement,
312 htmlDocumentElement,
313 ElementFactory.classElement("InputElement", elementType),
314 ElementFactory.classElement("SelectElement", elementType)
315 ];
316 htmlUnit.functions = <FunctionElement>[
317 ElementFactory.functionElement3("query", elementElement,
318 <ClassElement>[provider.stringType.element], ClassElement.EMPTY_LIST)
319 ];
320 TopLevelVariableElementImpl document = ElementFactory
321 .topLevelVariableElement3(
322 "document", false, true, htmlDocumentElement.type);
323 htmlUnit.topLevelVariables = <TopLevelVariableElement>[document];
324 htmlUnit.accessors = <PropertyAccessorElement>[document.getter];
325 LibraryElementImpl htmlLibrary = new LibraryElementImpl.forNode(
326 coreContext, AstFactory.libraryIdentifier2(["dart", "dom", "html"]));
327 htmlLibrary.definingCompilationUnit = htmlUnit;
328 //
329 // dart:math
330 //
331 CompilationUnitElementImpl mathUnit =
332 new CompilationUnitElementImpl("math.dart");
333 Source mathSource = sourceFactory.forUri(_DART_MATH);
334 coreContext.setContents(mathSource, "");
335 mathUnit.librarySource = mathUnit.source = mathSource;
336 FunctionElement cosElement = ElementFactory.functionElement3(
337 "cos",
338 provider.doubleType.element,
339 <ClassElement>[provider.numType.element],
340 ClassElement.EMPTY_LIST);
341 TopLevelVariableElement ln10Element = ElementFactory
342 .topLevelVariableElement3("LN10", true, false, provider.doubleType);
343 FunctionElement maxElement = ElementFactory.functionElement3(
344 "max",
345 provider.numType.element,
346 <ClassElement>[provider.numType.element, provider.numType.element],
347 ClassElement.EMPTY_LIST);
348 TopLevelVariableElement piElement = ElementFactory.topLevelVariableElement3(
349 "PI", true, false, provider.doubleType);
350 ClassElementImpl randomElement = ElementFactory.classElement2("Random");
351 randomElement.abstract = true;
352 ConstructorElementImpl randomConstructor =
353 ElementFactory.constructorElement2(randomElement, null);
354 randomConstructor.factory = true;
355 ParameterElementImpl seedParam = new ParameterElementImpl("seed", 0);
356 seedParam.parameterKind = ParameterKind.POSITIONAL;
357 seedParam.type = provider.intType;
358 randomConstructor.parameters = <ParameterElement>[seedParam];
359 randomElement.constructors = <ConstructorElement>[randomConstructor];
360 FunctionElement sinElement = ElementFactory.functionElement3(
361 "sin",
362 provider.doubleType.element,
363 <ClassElement>[provider.numType.element],
364 ClassElement.EMPTY_LIST);
365 FunctionElement sqrtElement = ElementFactory.functionElement3(
366 "sqrt",
367 provider.doubleType.element,
368 <ClassElement>[provider.numType.element],
369 ClassElement.EMPTY_LIST);
370 mathUnit.accessors = <PropertyAccessorElement>[
371 ln10Element.getter,
372 piElement.getter
373 ];
374 mathUnit.functions = <FunctionElement>[
375 cosElement,
376 maxElement,
377 sinElement,
378 sqrtElement
379 ];
380 mathUnit.topLevelVariables = <TopLevelVariableElement>[
381 ln10Element,
382 piElement
383 ];
384 mathUnit.types = <ClassElement>[randomElement];
385 LibraryElementImpl mathLibrary = new LibraryElementImpl.forNode(
386 coreContext, AstFactory.libraryIdentifier2(["dart", "math"]));
387 mathLibrary.definingCompilationUnit = mathUnit;
388 //
389 // Set empty sources for the rest of the libraries.
390 //
391 Source source = sourceFactory.forUri(_DART_INTERCEPTORS);
392 coreContext.setContents(source, "");
393 source = sourceFactory.forUri(_DART_JS_HELPER);
394 coreContext.setContents(source, "");
395 //
396 // Record the elements.
397 //
398 HashMap<Source, LibraryElement> elementMap =
399 new HashMap<Source, LibraryElement>();
400 elementMap[coreSource] = coreLibrary;
401 elementMap[asyncSource] = asyncLibrary;
402 elementMap[htmlSource] = htmlLibrary;
403 elementMap[mathSource] = mathLibrary;
404 context.recordLibraryElements(elementMap);
405 return context;
406 }
407
408 /**
409 * Create an analysis context that has a fake core library already resolved.
410 * Return the context that was created.
411 */
412 static AnalysisContextImpl oldContextWithCore() {
413 AnalysisContextForTests context = new AnalysisContextForTests();
414 return initContextWithCore(context);
415 }
416
417 /**
418 * Create an analysis context that uses the given [options] and has a fake
419 * core library already resolved. Return the context that was created.
420 */
421 static AnalysisContextImpl oldContextWithCoreAndOptions(
422 AnalysisOptions options) {
423 AnalysisContextForTests context = new AnalysisContextForTests();
424 context._internalSetAnalysisOptions(options);
425 return initContextWithCore(context);
426 }
427 }
428
429 /**
430 * Instances of the class `AnalysisContextForTests` implement an analysis contex t that has a
431 * fake SDK that is much smaller and faster for testing purposes.
432 */
433 class AnalysisContextForTests extends AnalysisContextImpl {
434 @override
435 void set analysisOptions(AnalysisOptions options) {
436 AnalysisOptions currentOptions = analysisOptions;
437 bool needsRecompute = currentOptions.analyzeFunctionBodiesPredicate !=
438 options.analyzeFunctionBodiesPredicate ||
439 currentOptions.generateImplicitErrors !=
440 options.generateImplicitErrors ||
441 currentOptions.generateSdkErrors != options.generateSdkErrors ||
442 currentOptions.dart2jsHint != options.dart2jsHint ||
443 (currentOptions.hint && !options.hint) ||
444 currentOptions.preserveComments != options.preserveComments ||
445 currentOptions.enableStrictCallChecks != options.enableStrictCallChecks;
446 if (needsRecompute) {
447 fail(
448 "Cannot set options that cause the sources to be reanalyzed in a test context");
449 }
450 super.analysisOptions = options;
451 }
452
453 @override
454 bool exists(Source source) =>
455 super.exists(source) || sourceFactory.dartSdk.context.exists(source);
456
457 @override
458 TimestampedData<String> getContents(Source source) {
459 if (source.isInSystemLibrary) {
460 return sourceFactory.dartSdk.context.getContents(source);
461 }
462 return super.getContents(source);
463 }
464
465 @override
466 int getModificationStamp(Source source) {
467 if (source.isInSystemLibrary) {
468 return sourceFactory.dartSdk.context.getModificationStamp(source);
469 }
470 return super.getModificationStamp(source);
471 }
472
473 /**
474 * Set the analysis options, even if they would force re-analysis. This method should only be
475 * invoked before the fake SDK is initialized.
476 *
477 * @param options the analysis options to be set
478 */
479 void _internalSetAnalysisOptions(AnalysisOptions options) {
480 super.analysisOptions = options;
481 }
482 }
483
484 /**
485 * Helper for creating and managing single [AnalysisContext].
486 */
487 class AnalysisContextHelper {
488 AnalysisContext context;
489
490 /**
491 * Creates new [AnalysisContext] using [AnalysisContextFactory].
492 */
493 AnalysisContextHelper([AnalysisOptionsImpl options]) {
494 if (options == null) {
495 options = new AnalysisOptionsImpl();
496 }
497 options.cacheSize = 256;
498 context = AnalysisContextFactory.contextWithCoreAndOptions(options);
499 }
500
501 Source addSource(String path, String code) {
502 Source source = new FileBasedSource(FileUtilities2.createFile(path));
503 if (path.endsWith(".dart") || path.endsWith(".html")) {
504 ChangeSet changeSet = new ChangeSet();
505 changeSet.addedSource(source);
506 context.applyChanges(changeSet);
507 }
508 context.setContents(source, code);
509 return source;
510 }
511
512 CompilationUnitElement getDefiningUnitElement(Source source) =>
513 context.getCompilationUnitElement(source, source);
514
515 CompilationUnit resolveDefiningUnit(Source source) {
516 LibraryElement libraryElement = context.computeLibraryElement(source);
517 return context.resolveCompilationUnit(source, libraryElement);
518 }
519
520 void runTasks() {
521 AnalysisResult result = context.performAnalysisTask();
522 while (result.changeNotices != null) {
523 result = context.performAnalysisTask();
524 }
525 }
526 }
527
528 @reflectiveTest
529 class AnalysisDeltaTest extends EngineTestCase {
530 TestSource source1 = new TestSource('/1.dart');
531 TestSource source2 = new TestSource('/2.dart');
532 TestSource source3 = new TestSource('/3.dart');
533
534 void test_getAddedSources() {
535 AnalysisDelta delta = new AnalysisDelta();
536 delta.setAnalysisLevel(source1, AnalysisLevel.ALL);
537 delta.setAnalysisLevel(source2, AnalysisLevel.ERRORS);
538 delta.setAnalysisLevel(source3, AnalysisLevel.NONE);
539 List<Source> addedSources = delta.addedSources;
540 expect(addedSources, hasLength(2));
541 expect(addedSources, unorderedEquals([source1, source2]));
542 }
543
544 void test_getAnalysisLevels() {
545 AnalysisDelta delta = new AnalysisDelta();
546 expect(delta.analysisLevels.length, 0);
547 }
548
549 void test_setAnalysisLevel() {
550 AnalysisDelta delta = new AnalysisDelta();
551 delta.setAnalysisLevel(source1, AnalysisLevel.ALL);
552 delta.setAnalysisLevel(source2, AnalysisLevel.ERRORS);
553 Map<Source, AnalysisLevel> levels = delta.analysisLevels;
554 expect(levels.length, 2);
555 expect(levels[source1], AnalysisLevel.ALL);
556 expect(levels[source2], AnalysisLevel.ERRORS);
557 }
558
559 void test_toString() {
560 AnalysisDelta delta = new AnalysisDelta();
561 delta.setAnalysisLevel(new TestSource(), AnalysisLevel.ALL);
562 String result = delta.toString();
563 expect(result, isNotNull);
564 expect(result.length > 0, isTrue);
565 }
566 }
567
568 @reflectiveTest
569 class ChangeSetTest extends EngineTestCase {
570 void test_changedContent() {
571 TestSource source = new TestSource();
572 String content = "";
573 ChangeSet changeSet = new ChangeSet();
574 changeSet.changedContent(source, content);
575 expect(changeSet.addedSources, hasLength(0));
576 expect(changeSet.changedSources, hasLength(0));
577 Map<Source, String> map = changeSet.changedContents;
578 expect(map, hasLength(1));
579 expect(map[source], same(content));
580 expect(changeSet.changedRanges, hasLength(0));
581 expect(changeSet.deletedSources, hasLength(0));
582 expect(changeSet.removedSources, hasLength(0));
583 expect(changeSet.removedContainers, hasLength(0));
584 }
585
586 void test_changedRange() {
587 TestSource source = new TestSource();
588 String content = "";
589 ChangeSet changeSet = new ChangeSet();
590 changeSet.changedRange(source, content, 1, 2, 3);
591 expect(changeSet.addedSources, hasLength(0));
592 expect(changeSet.changedSources, hasLength(0));
593 expect(changeSet.changedContents, hasLength(0));
594 Map<Source, ChangeSet_ContentChange> map = changeSet.changedRanges;
595 expect(map, hasLength(1));
596 ChangeSet_ContentChange change = map[source];
597 expect(change, isNotNull);
598 expect(change.contents, content);
599 expect(change.offset, 1);
600 expect(change.oldLength, 2);
601 expect(change.newLength, 3);
602 expect(changeSet.deletedSources, hasLength(0));
603 expect(changeSet.removedSources, hasLength(0));
604 expect(changeSet.removedContainers, hasLength(0));
605 }
606
607 void test_toString() {
608 ChangeSet changeSet = new ChangeSet();
609 changeSet.addedSource(new TestSource());
610 changeSet.changedSource(new TestSource());
611 changeSet.changedContent(new TestSource(), "");
612 changeSet.changedRange(new TestSource(), "", 0, 0, 0);
613 changeSet.deletedSource(new TestSource());
614 changeSet.removedSource(new TestSource());
615 changeSet
616 .removedContainer(new SourceContainer_ChangeSetTest_test_toString());
617 expect(changeSet.toString(), isNotNull);
618 }
619 }
620
621 @reflectiveTest
622 class CheckedModeCompileTimeErrorCodeTest extends ResolverTestCase {
623 void test_fieldFormalParameterAssignableToField_extends() {
624 // According to checked-mode type checking rules, a value of type B is
625 // assignable to a field of type A, because B extends A (and hence is a
626 // subtype of A).
627 Source source = addSource(r'''
628 class A {
629 const A();
630 }
631 class B extends A {
632 const B();
633 }
634 class C {
635 final A a;
636 const C(this.a);
637 }
638 var v = const C(const B());''');
639 computeLibrarySourceErrors(source);
640 assertNoErrors(source);
641 verify([source]);
642 }
643
644 void test_fieldFormalParameterAssignableToField_fieldType_unresolved_null() {
645 // Null always passes runtime type checks, even when the type is
646 // unresolved.
647 Source source = addSource(r'''
648 class A {
649 final Unresolved x;
650 const A(String this.x);
651 }
652 var v = const A(null);''');
653 computeLibrarySourceErrors(source);
654 assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
655 verify([source]);
656 }
657
658 void test_fieldFormalParameterAssignableToField_implements() {
659 // According to checked-mode type checking rules, a value of type B is
660 // assignable to a field of type A, because B implements A (and hence is a
661 // subtype of A).
662 Source source = addSource(r'''
663 class A {}
664 class B implements A {
665 const B();
666 }
667 class C {
668 final A a;
669 const C(this.a);
670 }
671 var v = const C(const B());''');
672 computeLibrarySourceErrors(source);
673 assertNoErrors(source);
674 verify([source]);
675 }
676
677 void test_fieldFormalParameterAssignableToField_list_dynamic() {
678 // [1, 2, 3] has type List<dynamic>, which is a subtype of List<int>.
679 Source source = addSource(r'''
680 class A {
681 const A(List<int> x);
682 }
683 var x = const A(const [1, 2, 3]);''');
684 computeLibrarySourceErrors(source);
685 assertNoErrors(source);
686 verify([source]);
687 }
688
689 void test_fieldFormalParameterAssignableToField_list_nonDynamic() {
690 // <int>[1, 2, 3] has type List<int>, which is a subtype of List<num>.
691 Source source = addSource(r'''
692 class A {
693 const A(List<num> x);
694 }
695 var x = const A(const <int>[1, 2, 3]);''');
696 computeLibrarySourceErrors(source);
697 assertNoErrors(source);
698 verify([source]);
699 }
700
701 void test_fieldFormalParameterAssignableToField_map_dynamic() {
702 // {1: 2} has type Map<dynamic, dynamic>, which is a subtype of
703 // Map<int, int>.
704 Source source = addSource(r'''
705 class A {
706 const A(Map<int, int> x);
707 }
708 var x = const A(const {1: 2});''');
709 computeLibrarySourceErrors(source);
710 assertNoErrors(source);
711 verify([source]);
712 }
713
714 void test_fieldFormalParameterAssignableToField_map_keyDifferent() {
715 // <int, int>{1: 2} has type Map<int, int>, which is a subtype of
716 // Map<num, int>.
717 Source source = addSource(r'''
718 class A {
719 const A(Map<num, int> x);
720 }
721 var x = const A(const <int, int>{1: 2});''');
722 computeLibrarySourceErrors(source);
723 assertNoErrors(source);
724 verify([source]);
725 }
726
727 void test_fieldFormalParameterAssignableToField_map_valueDifferent() {
728 // <int, int>{1: 2} has type Map<int, int>, which is a subtype of
729 // Map<int, num>.
730 Source source = addSource(r'''
731 class A {
732 const A(Map<int, num> x);
733 }
734 var x = const A(const <int, int>{1: 2});''');
735 computeLibrarySourceErrors(source);
736 assertNoErrors(source);
737 verify([source]);
738 }
739
740 void test_fieldFormalParameterAssignableToField_notype() {
741 // If a field is declared without a type, then any value may be assigned to
742 // it.
743 Source source = addSource(r'''
744 class A {
745 final x;
746 const A(this.x);
747 }
748 var v = const A(5);''');
749 computeLibrarySourceErrors(source);
750 assertNoErrors(source);
751 verify([source]);
752 }
753
754 void test_fieldFormalParameterAssignableToField_null() {
755 // Null is assignable to anything.
756 Source source = addSource(r'''
757 class A {
758 final int x;
759 const A(this.x);
760 }
761 var v = const A(null);''');
762 computeLibrarySourceErrors(source);
763 assertNoErrors(source);
764 verify([source]);
765 }
766
767 void test_fieldFormalParameterAssignableToField_typedef() {
768 // foo has the runtime type dynamic -> dynamic, so it should be assignable
769 // to A.f.
770 Source source = addSource(r'''
771 typedef String Int2String(int x);
772 class A {
773 final Int2String f;
774 const A(this.f);
775 }
776 foo(x) => 1;
777 var v = const A(foo);''');
778 computeLibrarySourceErrors(source);
779 assertNoErrors(source);
780 verify([source]);
781 }
782
783 void test_fieldFormalParameterAssignableToField_typeSubstitution() {
784 // foo has the runtime type dynamic -> dynamic, so it should be assignable
785 // to A.f.
786 Source source = addSource(r'''
787 class A<T> {
788 final T x;
789 const A(this.x);
790 }
791 var v = const A<int>(3);''');
792 computeLibrarySourceErrors(source);
793 assertNoErrors(source);
794 verify([source]);
795 }
796
797 void test_fieldFormalParameterNotAssignableToField() {
798 Source source = addSource(r'''
799 class A {
800 final int x;
801 const A(this.x);
802 }
803 var v = const A('foo');''');
804 computeLibrarySourceErrors(source);
805 assertErrors(source, [
806 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
807 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
808 ]);
809 verify([source]);
810 }
811
812 void test_fieldFormalParameterNotAssignableToField_extends() {
813 // According to checked-mode type checking rules, a value of type A is not
814 // assignable to a field of type B, because B extends A (the subtyping
815 // relationship is in the wrong direction).
816 Source source = addSource(r'''
817 class A {
818 const A();
819 }
820 class B extends A {
821 const B();
822 }
823 class C {
824 final B b;
825 const C(this.b);
826 }
827 var v = const C(const A());''');
828 computeLibrarySourceErrors(source);
829 assertErrors(source, [
830 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
831 ]);
832 verify([source]);
833 }
834
835 void test_fieldFormalParameterNotAssignableToField_fieldType() {
836 Source source = addSource(r'''
837 class A {
838 final int x;
839 const A(String this.x);
840 }
841 var v = const A('foo');''');
842 computeLibrarySourceErrors(source);
843 assertErrors(source, [
844 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
845 StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE
846 ]);
847 verify([source]);
848 }
849
850 void test_fieldFormalParameterNotAssignableToField_fieldType_unresolved() {
851 Source source = addSource(r'''
852 class A {
853 final Unresolved x;
854 const A(String this.x);
855 }
856 var v = const A('foo');''');
857 computeLibrarySourceErrors(source);
858 assertErrors(source, [
859 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
860 StaticWarningCode.UNDEFINED_CLASS
861 ]);
862 verify([source]);
863 }
864
865 void test_fieldFormalParameterNotAssignableToField_implements() {
866 // According to checked-mode type checking rules, a value of type A is not
867 // assignable to a field of type B, because B implements A (the subtyping
868 // relationship is in the wrong direction).
869 Source source = addSource(r'''
870 class A {
871 const A();
872 }
873 class B implements A {}
874 class C {
875 final B b;
876 const C(this.b);
877 }
878 var v = const C(const A());''');
879 computeLibrarySourceErrors(source);
880 assertErrors(source, [
881 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
882 ]);
883 verify([source]);
884 }
885
886 void test_fieldFormalParameterNotAssignableToField_list() {
887 // <num>[1, 2, 3] has type List<num>, which is not a subtype of List<int>.
888 Source source = addSource(r'''
889 class A {
890 const A(List<int> x);
891 }
892 var x = const A(const <num>[1, 2, 3]);''');
893 computeLibrarySourceErrors(source);
894 assertErrors(source, [
895 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
896 ]);
897 verify([source]);
898 }
899
900 void test_fieldFormalParameterNotAssignableToField_map_keyMismatch() {
901 // <num, int>{1: 2} has type Map<num, int>, which is not a subtype of
902 // Map<int, int>.
903 Source source = addSource(r'''
904 class A {
905 const A(Map<int, int> x);
906 }
907 var x = const A(const <num, int>{1: 2});''');
908 computeLibrarySourceErrors(source);
909 assertErrors(source, [
910 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
911 ]);
912 verify([source]);
913 }
914
915 void test_fieldFormalParameterNotAssignableToField_map_valueMismatch() {
916 // <int, num>{1: 2} has type Map<int, num>, which is not a subtype of
917 // Map<int, int>.
918 Source source = addSource(r'''
919 class A {
920 const A(Map<int, int> x);
921 }
922 var x = const A(const <int, num>{1: 2});''');
923 computeLibrarySourceErrors(source);
924 assertErrors(source, [
925 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
926 ]);
927 verify([source]);
928 }
929
930 void test_fieldFormalParameterNotAssignableToField_optional() {
931 Source source = addSource(r'''
932 class A {
933 final int x;
934 const A([this.x = 'foo']);
935 }
936 var v = const A();''');
937 computeLibrarySourceErrors(source);
938 assertErrors(source, [
939 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
940 StaticTypeWarningCode.INVALID_ASSIGNMENT
941 ]);
942 verify([source]);
943 }
944
945 void test_fieldFormalParameterNotAssignableToField_typedef() {
946 // foo has the runtime type String -> int, so it should not be assignable
947 // to A.f (A.f requires it to be int -> String).
948 Source source = addSource(r'''
949 typedef String Int2String(int x);
950 class A {
951 final Int2String f;
952 const A(this.f);
953 }
954 int foo(String x) => 1;
955 var v = const A(foo);''');
956 computeLibrarySourceErrors(source);
957 assertErrors(source, [
958 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
959 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
960 ]);
961 verify([source]);
962 }
963
964 void test_fieldInitializerNotAssignable() {
965 Source source = addSource(r'''
966 class A {
967 final int x;
968 const A() : x = '';
969 }''');
970 computeLibrarySourceErrors(source);
971 assertErrors(source, [
972 CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
973 StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE
974 ]);
975 verify([source]);
976 }
977
978 void test_fieldTypeMismatch() {
979 Source source = addSource(r'''
980 class A {
981 const A(x) : y = x;
982 final int y;
983 }
984 var v = const A('foo');''');
985 computeLibrarySourceErrors(source);
986 assertErrors(source, [
987 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
988 ]);
989 verify([source]);
990 }
991
992 void test_fieldTypeMismatch_generic() {
993 Source source = addSource(r'''
994 class C<T> {
995 final T x = y;
996 const C();
997 }
998 const int y = 1;
999 var v = const C<String>();
1000 ''');
1001 computeLibrarySourceErrors(source);
1002 assertErrors(source, [
1003 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
1004 StaticTypeWarningCode.INVALID_ASSIGNMENT
1005 ]);
1006 verify([source]);
1007 }
1008
1009 void test_fieldTypeMismatch_unresolved() {
1010 Source source = addSource(r'''
1011 class A {
1012 const A(x) : y = x;
1013 final Unresolved y;
1014 }
1015 var v = const A('foo');''');
1016 computeLibrarySourceErrors(source);
1017 assertErrors(source, [
1018 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
1019 StaticWarningCode.UNDEFINED_CLASS
1020 ]);
1021 verify([source]);
1022 }
1023
1024 void test_fieldTypeOk_generic() {
1025 Source source = addSource(r'''
1026 class C<T> {
1027 final T x = y;
1028 const C();
1029 }
1030 const int y = 1;
1031 var v = const C<int>();
1032 ''');
1033 computeLibrarySourceErrors(source);
1034 assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
1035 verify([source]);
1036 }
1037
1038 void test_fieldTypeOk_null() {
1039 Source source = addSource(r'''
1040 class A {
1041 const A(x) : y = x;
1042 final int y;
1043 }
1044 var v = const A(null);''');
1045 computeLibrarySourceErrors(source);
1046 assertNoErrors(source);
1047 verify([source]);
1048 }
1049
1050 void test_fieldTypeOk_unresolved_null() {
1051 // Null always passes runtime type checks, even when the type is
1052 // unresolved.
1053 Source source = addSource(r'''
1054 class A {
1055 const A(x) : y = x;
1056 final Unresolved y;
1057 }
1058 var v = const A(null);''');
1059 computeLibrarySourceErrors(source);
1060 assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
1061 verify([source]);
1062 }
1063
1064 void test_listElementTypeNotAssignable() {
1065 Source source = addSource("var v = const <String> [42];");
1066 computeLibrarySourceErrors(source);
1067 assertErrors(source, [
1068 CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
1069 StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
1070 ]);
1071 verify([source]);
1072 }
1073
1074 void test_mapKeyTypeNotAssignable() {
1075 Source source = addSource("var v = const <String, int > {1 : 2};");
1076 computeLibrarySourceErrors(source);
1077 assertErrors(source, [
1078 CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
1079 StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE
1080 ]);
1081 verify([source]);
1082 }
1083
1084 void test_mapValueTypeNotAssignable() {
1085 Source source = addSource("var v = const <String, String> {'a' : 2};");
1086 computeLibrarySourceErrors(source);
1087 assertErrors(source, [
1088 CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
1089 StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE
1090 ]);
1091 verify([source]);
1092 }
1093
1094 void test_parameterAssignable_null() {
1095 // Null is assignable to anything.
1096 Source source = addSource(r'''
1097 class A {
1098 const A(int x);
1099 }
1100 var v = const A(null);''');
1101 computeLibrarySourceErrors(source);
1102 assertNoErrors(source);
1103 verify([source]);
1104 }
1105
1106 void test_parameterAssignable_typeSubstitution() {
1107 Source source = addSource(r'''
1108 class A<T> {
1109 const A(T x);
1110 }
1111 var v = const A<int>(3);''');
1112 computeLibrarySourceErrors(source);
1113 assertNoErrors(source);
1114 verify([source]);
1115 }
1116
1117 void test_parameterAssignable_undefined_null() {
1118 // Null always passes runtime type checks, even when the type is
1119 // unresolved.
1120 Source source = addSource(r'''
1121 class A {
1122 const A(Unresolved x);
1123 }
1124 var v = const A(null);''');
1125 computeLibrarySourceErrors(source);
1126 assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
1127 verify([source]);
1128 }
1129
1130 void test_parameterNotAssignable() {
1131 Source source = addSource(r'''
1132 class A {
1133 const A(int x);
1134 }
1135 var v = const A('foo');''');
1136 computeLibrarySourceErrors(source);
1137 assertErrors(source, [
1138 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
1139 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
1140 ]);
1141 verify([source]);
1142 }
1143
1144 void test_parameterNotAssignable_typeSubstitution() {
1145 Source source = addSource(r'''
1146 class A<T> {
1147 const A(T x);
1148 }
1149 var v = const A<int>('foo');''');
1150 computeLibrarySourceErrors(source);
1151 assertErrors(source, [
1152 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
1153 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
1154 ]);
1155 verify([source]);
1156 }
1157
1158 void test_parameterNotAssignable_undefined() {
1159 Source source = addSource(r'''
1160 class A {
1161 const A(Unresolved x);
1162 }
1163 var v = const A('foo');''');
1164 computeLibrarySourceErrors(source);
1165 assertErrors(source, [
1166 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
1167 StaticWarningCode.UNDEFINED_CLASS
1168 ]);
1169 verify([source]);
1170 }
1171
1172 void test_redirectingConstructor_paramTypeMismatch() {
1173 Source source = addSource(r'''
1174 class A {
1175 const A.a1(x) : this.a2(x);
1176 const A.a2(String x);
1177 }
1178 var v = const A.a1(0);''');
1179 computeLibrarySourceErrors(source);
1180 assertErrors(source, [
1181 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
1182 ]);
1183 verify([source]);
1184 }
1185
1186 void test_topLevelVarAssignable_null() {
1187 Source source = addSource("const int x = null;");
1188 computeLibrarySourceErrors(source);
1189 assertNoErrors(source);
1190 verify([source]);
1191 }
1192
1193 void test_topLevelVarAssignable_undefined_null() {
1194 // Null always passes runtime type checks, even when the type is
1195 // unresolved.
1196 Source source = addSource("const Unresolved x = null;");
1197 computeLibrarySourceErrors(source);
1198 assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
1199 verify([source]);
1200 }
1201
1202 void test_topLevelVarNotAssignable() {
1203 Source source = addSource("const int x = 'foo';");
1204 computeLibrarySourceErrors(source);
1205 assertErrors(source, [
1206 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
1207 StaticTypeWarningCode.INVALID_ASSIGNMENT
1208 ]);
1209 verify([source]);
1210 }
1211
1212 void test_topLevelVarNotAssignable_undefined() {
1213 Source source = addSource("const Unresolved x = 'foo';");
1214 computeLibrarySourceErrors(source);
1215 assertErrors(source, [
1216 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
1217 StaticWarningCode.UNDEFINED_CLASS
1218 ]);
1219 verify([source]);
1220 }
1221 }
1222
1223 @reflectiveTest
1224 class ElementResolverTest extends EngineTestCase {
1225 /**
1226 * The error listener to which errors will be reported.
1227 */
1228 GatheringErrorListener _listener;
1229
1230 /**
1231 * The type provider used to access the types.
1232 */
1233 TestTypeProvider _typeProvider;
1234
1235 /**
1236 * The library containing the code being resolved.
1237 */
1238 LibraryElementImpl _definingLibrary;
1239
1240 /**
1241 * The resolver visitor that maintains the state for the resolver.
1242 */
1243 ResolverVisitor _visitor;
1244
1245 /**
1246 * The resolver being used to resolve the test cases.
1247 */
1248 ElementResolver _resolver;
1249
1250 void fail_visitExportDirective_combinators() {
1251 fail("Not yet tested");
1252 // Need to set up the exported library so that the identifier can be
1253 // resolved.
1254 ExportDirective directive = AstFactory.exportDirective2(null, [
1255 AstFactory.hideCombinator2(["A"])
1256 ]);
1257 _resolveNode(directive);
1258 _listener.assertNoErrors();
1259 }
1260
1261 void fail_visitFunctionExpressionInvocation() {
1262 fail("Not yet tested");
1263 _listener.assertNoErrors();
1264 }
1265
1266 void fail_visitImportDirective_combinators_noPrefix() {
1267 fail("Not yet tested");
1268 // Need to set up the imported library so that the identifier can be
1269 // resolved.
1270 ImportDirective directive = AstFactory.importDirective3(null, null, [
1271 AstFactory.showCombinator2(["A"])
1272 ]);
1273 _resolveNode(directive);
1274 _listener.assertNoErrors();
1275 }
1276
1277 void fail_visitImportDirective_combinators_prefix() {
1278 fail("Not yet tested");
1279 // Need to set up the imported library so that the identifiers can be
1280 // resolved.
1281 String prefixName = "p";
1282 _definingLibrary.imports = <ImportElement>[
1283 ElementFactory.importFor(null, ElementFactory.prefix(prefixName))
1284 ];
1285 ImportDirective directive = AstFactory.importDirective3(null, prefixName, [
1286 AstFactory.showCombinator2(["A"]),
1287 AstFactory.hideCombinator2(["B"])
1288 ]);
1289 _resolveNode(directive);
1290 _listener.assertNoErrors();
1291 }
1292
1293 void fail_visitRedirectingConstructorInvocation() {
1294 fail("Not yet tested");
1295 _listener.assertNoErrors();
1296 }
1297
1298 @override
1299 void setUp() {
1300 _listener = new GatheringErrorListener();
1301 _typeProvider = new TestTypeProvider();
1302 _resolver = _createResolver();
1303 }
1304
1305 void test_lookUpMethodInInterfaces() {
1306 InterfaceType intType = _typeProvider.intType;
1307 //
1308 // abstract class A { int operator[](int index); }
1309 //
1310 ClassElementImpl classA = ElementFactory.classElement2("A");
1311 MethodElement operator =
1312 ElementFactory.methodElement("[]", intType, [intType]);
1313 classA.methods = <MethodElement>[operator];
1314 //
1315 // class B implements A {}
1316 //
1317 ClassElementImpl classB = ElementFactory.classElement2("B");
1318 classB.interfaces = <InterfaceType>[classA.type];
1319 //
1320 // class C extends Object with B {}
1321 //
1322 ClassElementImpl classC = ElementFactory.classElement2("C");
1323 classC.mixins = <InterfaceType>[classB.type];
1324 //
1325 // class D extends C {}
1326 //
1327 ClassElementImpl classD = ElementFactory.classElement("D", classC.type);
1328 //
1329 // D a;
1330 // a[i];
1331 //
1332 SimpleIdentifier array = AstFactory.identifier3("a");
1333 array.staticType = classD.type;
1334 IndexExpression expression =
1335 AstFactory.indexExpression(array, AstFactory.identifier3("i"));
1336 expect(_resolveIndexExpression(expression), same(operator));
1337 _listener.assertNoErrors();
1338 }
1339
1340 void test_visitAssignmentExpression_compound() {
1341 InterfaceType intType = _typeProvider.intType;
1342 SimpleIdentifier leftHandSide = AstFactory.identifier3("a");
1343 leftHandSide.staticType = intType;
1344 AssignmentExpression assignment = AstFactory.assignmentExpression(
1345 leftHandSide, TokenType.PLUS_EQ, AstFactory.integer(1));
1346 _resolveNode(assignment);
1347 expect(
1348 assignment.staticElement, same(getMethod(_typeProvider.numType, "+")));
1349 _listener.assertNoErrors();
1350 }
1351
1352 void test_visitAssignmentExpression_simple() {
1353 AssignmentExpression expression = AstFactory.assignmentExpression(
1354 AstFactory.identifier3("x"), TokenType.EQ, AstFactory.integer(0));
1355 _resolveNode(expression);
1356 expect(expression.staticElement, isNull);
1357 _listener.assertNoErrors();
1358 }
1359
1360 void test_visitBinaryExpression_bangEq() {
1361 // String i;
1362 // var j;
1363 // i == j
1364 InterfaceType stringType = _typeProvider.stringType;
1365 SimpleIdentifier left = AstFactory.identifier3("i");
1366 left.staticType = stringType;
1367 BinaryExpression expression = AstFactory.binaryExpression(
1368 left, TokenType.BANG_EQ, AstFactory.identifier3("j"));
1369 _resolveNode(expression);
1370 var stringElement = stringType.element;
1371 expect(expression.staticElement, isNotNull);
1372 expect(
1373 expression.staticElement,
1374 stringElement.lookUpMethod(
1375 TokenType.EQ_EQ.lexeme, stringElement.library));
1376 expect(expression.propagatedElement, isNull);
1377 _listener.assertNoErrors();
1378 }
1379
1380 void test_visitBinaryExpression_eq() {
1381 // String i;
1382 // var j;
1383 // i == j
1384 InterfaceType stringType = _typeProvider.stringType;
1385 SimpleIdentifier left = AstFactory.identifier3("i");
1386 left.staticType = stringType;
1387 BinaryExpression expression = AstFactory.binaryExpression(
1388 left, TokenType.EQ_EQ, AstFactory.identifier3("j"));
1389 _resolveNode(expression);
1390 var stringElement = stringType.element;
1391 expect(
1392 expression.staticElement,
1393 stringElement.lookUpMethod(
1394 TokenType.EQ_EQ.lexeme, stringElement.library));
1395 expect(expression.propagatedElement, isNull);
1396 _listener.assertNoErrors();
1397 }
1398
1399 void test_visitBinaryExpression_plus() {
1400 // num i;
1401 // var j;
1402 // i + j
1403 InterfaceType numType = _typeProvider.numType;
1404 SimpleIdentifier left = AstFactory.identifier3("i");
1405 left.staticType = numType;
1406 BinaryExpression expression = AstFactory.binaryExpression(
1407 left, TokenType.PLUS, AstFactory.identifier3("j"));
1408 _resolveNode(expression);
1409 expect(expression.staticElement, getMethod(numType, "+"));
1410 expect(expression.propagatedElement, isNull);
1411 _listener.assertNoErrors();
1412 }
1413
1414 void test_visitBinaryExpression_plus_propagatedElement() {
1415 // var i = 1;
1416 // var j;
1417 // i + j
1418 InterfaceType numType = _typeProvider.numType;
1419 SimpleIdentifier left = AstFactory.identifier3("i");
1420 left.propagatedType = numType;
1421 BinaryExpression expression = AstFactory.binaryExpression(
1422 left, TokenType.PLUS, AstFactory.identifier3("j"));
1423 _resolveNode(expression);
1424 expect(expression.staticElement, isNull);
1425 expect(expression.propagatedElement, getMethod(numType, "+"));
1426 _listener.assertNoErrors();
1427 }
1428
1429 void test_visitBreakStatement_withLabel() {
1430 // loop: while (true) {
1431 // break loop;
1432 // }
1433 String label = "loop";
1434 LabelElementImpl labelElement =
1435 new LabelElementImpl(AstFactory.identifier3(label), false, false);
1436 BreakStatement breakStatement = AstFactory.breakStatement2(label);
1437 Expression condition = AstFactory.booleanLiteral(true);
1438 WhileStatement whileStatement =
1439 AstFactory.whileStatement(condition, breakStatement);
1440 expect(_resolveBreak(breakStatement, labelElement, whileStatement),
1441 same(labelElement));
1442 expect(breakStatement.target, same(whileStatement));
1443 _listener.assertNoErrors();
1444 }
1445
1446 void test_visitBreakStatement_withoutLabel() {
1447 BreakStatement statement = AstFactory.breakStatement();
1448 _resolveStatement(statement, null, null);
1449 _listener.assertNoErrors();
1450 }
1451
1452 void test_visitConstructorName_named() {
1453 ClassElementImpl classA = ElementFactory.classElement2("A");
1454 String constructorName = "a";
1455 ConstructorElement constructor =
1456 ElementFactory.constructorElement2(classA, constructorName);
1457 classA.constructors = <ConstructorElement>[constructor];
1458 ConstructorName name = AstFactory.constructorName(
1459 AstFactory.typeName(classA), constructorName);
1460 _resolveNode(name);
1461 expect(name.staticElement, same(constructor));
1462 _listener.assertNoErrors();
1463 }
1464
1465 void test_visitConstructorName_unnamed() {
1466 ClassElementImpl classA = ElementFactory.classElement2("A");
1467 String constructorName = null;
1468 ConstructorElement constructor =
1469 ElementFactory.constructorElement2(classA, constructorName);
1470 classA.constructors = <ConstructorElement>[constructor];
1471 ConstructorName name = AstFactory.constructorName(
1472 AstFactory.typeName(classA), constructorName);
1473 _resolveNode(name);
1474 expect(name.staticElement, same(constructor));
1475 _listener.assertNoErrors();
1476 }
1477
1478 void test_visitContinueStatement_withLabel() {
1479 // loop: while (true) {
1480 // continue loop;
1481 // }
1482 String label = "loop";
1483 LabelElementImpl labelElement =
1484 new LabelElementImpl(AstFactory.identifier3(label), false, false);
1485 ContinueStatement continueStatement = AstFactory.continueStatement(label);
1486 Expression condition = AstFactory.booleanLiteral(true);
1487 WhileStatement whileStatement =
1488 AstFactory.whileStatement(condition, continueStatement);
1489 expect(_resolveContinue(continueStatement, labelElement, whileStatement),
1490 same(labelElement));
1491 expect(continueStatement.target, same(whileStatement));
1492 _listener.assertNoErrors();
1493 }
1494
1495 void test_visitContinueStatement_withoutLabel() {
1496 ContinueStatement statement = AstFactory.continueStatement();
1497 _resolveStatement(statement, null, null);
1498 _listener.assertNoErrors();
1499 }
1500
1501 void test_visitEnumDeclaration() {
1502 ClassElementImpl enumElement =
1503 ElementFactory.enumElement(_typeProvider, ('E'));
1504 EnumDeclaration enumNode = AstFactory.enumDeclaration2('E', []);
1505 Annotation annotationNode =
1506 AstFactory.annotation(AstFactory.identifier3('a'));
1507 annotationNode.element = ElementFactory.classElement2('A');
1508 enumNode.metadata.add(annotationNode);
1509 enumNode.name.staticElement = enumElement;
1510 _resolveNode(enumNode);
1511 List<ElementAnnotation> metadata = enumElement.metadata;
1512 expect(metadata, hasLength(1));
1513 }
1514
1515 void test_visitExportDirective_noCombinators() {
1516 ExportDirective directive = AstFactory.exportDirective2(null);
1517 directive.element = ElementFactory
1518 .exportFor(ElementFactory.library(_definingLibrary.context, "lib"));
1519 _resolveNode(directive);
1520 _listener.assertNoErrors();
1521 }
1522
1523 void test_visitFieldFormalParameter() {
1524 String fieldName = "f";
1525 InterfaceType intType = _typeProvider.intType;
1526 FieldElementImpl fieldElement =
1527 ElementFactory.fieldElement(fieldName, false, false, false, intType);
1528 ClassElementImpl classA = ElementFactory.classElement2("A");
1529 classA.fields = <FieldElement>[fieldElement];
1530 FieldFormalParameter parameter =
1531 AstFactory.fieldFormalParameter2(fieldName);
1532 FieldFormalParameterElementImpl parameterElement =
1533 ElementFactory.fieldFormalParameter(parameter.identifier);
1534 parameterElement.field = fieldElement;
1535 parameterElement.type = intType;
1536 parameter.identifier.staticElement = parameterElement;
1537 _resolveInClass(parameter, classA);
1538 expect(parameter.element.type, same(intType));
1539 }
1540
1541 void test_visitImportDirective_noCombinators_noPrefix() {
1542 ImportDirective directive = AstFactory.importDirective3(null, null);
1543 directive.element = ElementFactory.importFor(
1544 ElementFactory.library(_definingLibrary.context, "lib"), null);
1545 _resolveNode(directive);
1546 _listener.assertNoErrors();
1547 }
1548
1549 void test_visitImportDirective_noCombinators_prefix() {
1550 String prefixName = "p";
1551 ImportElement importElement = ElementFactory.importFor(
1552 ElementFactory.library(_definingLibrary.context, "lib"),
1553 ElementFactory.prefix(prefixName));
1554 _definingLibrary.imports = <ImportElement>[importElement];
1555 ImportDirective directive = AstFactory.importDirective3(null, prefixName);
1556 directive.element = importElement;
1557 _resolveNode(directive);
1558 _listener.assertNoErrors();
1559 }
1560
1561 void test_visitImportDirective_withCombinators() {
1562 ShowCombinator combinator = AstFactory.showCombinator2(["A", "B", "C"]);
1563 ImportDirective directive =
1564 AstFactory.importDirective3(null, null, [combinator]);
1565 LibraryElementImpl library =
1566 ElementFactory.library(_definingLibrary.context, "lib");
1567 TopLevelVariableElementImpl varA =
1568 ElementFactory.topLevelVariableElement2("A");
1569 TopLevelVariableElementImpl varB =
1570 ElementFactory.topLevelVariableElement2("B");
1571 TopLevelVariableElementImpl varC =
1572 ElementFactory.topLevelVariableElement2("C");
1573 CompilationUnitElementImpl unit =
1574 library.definingCompilationUnit as CompilationUnitElementImpl;
1575 unit.accessors = <PropertyAccessorElement>[
1576 varA.getter,
1577 varA.setter,
1578 varB.getter,
1579 varC.setter
1580 ];
1581 unit.topLevelVariables = <TopLevelVariableElement>[varA, varB, varC];
1582 directive.element = ElementFactory.importFor(library, null);
1583 _resolveNode(directive);
1584 expect(combinator.shownNames[0].staticElement, same(varA));
1585 expect(combinator.shownNames[1].staticElement, same(varB));
1586 expect(combinator.shownNames[2].staticElement, same(varC));
1587 _listener.assertNoErrors();
1588 }
1589
1590 void test_visitIndexExpression_get() {
1591 ClassElementImpl classA = ElementFactory.classElement2("A");
1592 InterfaceType intType = _typeProvider.intType;
1593 MethodElement getter =
1594 ElementFactory.methodElement("[]", intType, [intType]);
1595 classA.methods = <MethodElement>[getter];
1596 SimpleIdentifier array = AstFactory.identifier3("a");
1597 array.staticType = classA.type;
1598 IndexExpression expression =
1599 AstFactory.indexExpression(array, AstFactory.identifier3("i"));
1600 expect(_resolveIndexExpression(expression), same(getter));
1601 _listener.assertNoErrors();
1602 }
1603
1604 void test_visitIndexExpression_set() {
1605 ClassElementImpl classA = ElementFactory.classElement2("A");
1606 InterfaceType intType = _typeProvider.intType;
1607 MethodElement setter =
1608 ElementFactory.methodElement("[]=", intType, [intType]);
1609 classA.methods = <MethodElement>[setter];
1610 SimpleIdentifier array = AstFactory.identifier3("a");
1611 array.staticType = classA.type;
1612 IndexExpression expression =
1613 AstFactory.indexExpression(array, AstFactory.identifier3("i"));
1614 AstFactory.assignmentExpression(
1615 expression, TokenType.EQ, AstFactory.integer(0));
1616 expect(_resolveIndexExpression(expression), same(setter));
1617 _listener.assertNoErrors();
1618 }
1619
1620 void test_visitInstanceCreationExpression_named() {
1621 ClassElementImpl classA = ElementFactory.classElement2("A");
1622 String constructorName = "a";
1623 ConstructorElement constructor =
1624 ElementFactory.constructorElement2(classA, constructorName);
1625 classA.constructors = <ConstructorElement>[constructor];
1626 ConstructorName name = AstFactory.constructorName(
1627 AstFactory.typeName(classA), constructorName);
1628 name.staticElement = constructor;
1629 InstanceCreationExpression creation =
1630 AstFactory.instanceCreationExpression(Keyword.NEW, name);
1631 _resolveNode(creation);
1632 expect(creation.staticElement, same(constructor));
1633 _listener.assertNoErrors();
1634 }
1635
1636 void test_visitInstanceCreationExpression_unnamed() {
1637 ClassElementImpl classA = ElementFactory.classElement2("A");
1638 String constructorName = null;
1639 ConstructorElement constructor =
1640 ElementFactory.constructorElement2(classA, constructorName);
1641 classA.constructors = <ConstructorElement>[constructor];
1642 ConstructorName name = AstFactory.constructorName(
1643 AstFactory.typeName(classA), constructorName);
1644 name.staticElement = constructor;
1645 InstanceCreationExpression creation =
1646 AstFactory.instanceCreationExpression(Keyword.NEW, name);
1647 _resolveNode(creation);
1648 expect(creation.staticElement, same(constructor));
1649 _listener.assertNoErrors();
1650 }
1651
1652 void test_visitInstanceCreationExpression_unnamed_namedParameter() {
1653 ClassElementImpl classA = ElementFactory.classElement2("A");
1654 String constructorName = null;
1655 ConstructorElementImpl constructor =
1656 ElementFactory.constructorElement2(classA, constructorName);
1657 String parameterName = "a";
1658 ParameterElement parameter = ElementFactory.namedParameter(parameterName);
1659 constructor.parameters = <ParameterElement>[parameter];
1660 classA.constructors = <ConstructorElement>[constructor];
1661 ConstructorName name = AstFactory.constructorName(
1662 AstFactory.typeName(classA), constructorName);
1663 name.staticElement = constructor;
1664 InstanceCreationExpression creation = AstFactory.instanceCreationExpression(
1665 Keyword.NEW,
1666 name,
1667 [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]);
1668 _resolveNode(creation);
1669 expect(creation.staticElement, same(constructor));
1670 expect(
1671 (creation.argumentList.arguments[0] as NamedExpression)
1672 .name
1673 .label
1674 .staticElement,
1675 same(parameter));
1676 _listener.assertNoErrors();
1677 }
1678
1679 void test_visitMethodInvocation() {
1680 InterfaceType numType = _typeProvider.numType;
1681 SimpleIdentifier left = AstFactory.identifier3("i");
1682 left.staticType = numType;
1683 String methodName = "abs";
1684 MethodInvocation invocation = AstFactory.methodInvocation(left, methodName);
1685 _resolveNode(invocation);
1686 expect(invocation.methodName.staticElement,
1687 same(getMethod(numType, methodName)));
1688 _listener.assertNoErrors();
1689 }
1690
1691 void test_visitMethodInvocation_namedParameter() {
1692 ClassElementImpl classA = ElementFactory.classElement2("A");
1693 String methodName = "m";
1694 String parameterName = "p";
1695 MethodElementImpl method = ElementFactory.methodElement(methodName, null);
1696 ParameterElement parameter = ElementFactory.namedParameter(parameterName);
1697 method.parameters = <ParameterElement>[parameter];
1698 classA.methods = <MethodElement>[method];
1699 SimpleIdentifier left = AstFactory.identifier3("i");
1700 left.staticType = classA.type;
1701 MethodInvocation invocation = AstFactory.methodInvocation(left, methodName,
1702 [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]);
1703 _resolveNode(invocation);
1704 expect(invocation.methodName.staticElement, same(method));
1705 expect(
1706 (invocation.argumentList.arguments[0] as NamedExpression)
1707 .name
1708 .label
1709 .staticElement,
1710 same(parameter));
1711 _listener.assertNoErrors();
1712 }
1713
1714 void test_visitPostfixExpression() {
1715 InterfaceType numType = _typeProvider.numType;
1716 SimpleIdentifier operand = AstFactory.identifier3("i");
1717 operand.staticType = numType;
1718 PostfixExpression expression =
1719 AstFactory.postfixExpression(operand, TokenType.PLUS_PLUS);
1720 _resolveNode(expression);
1721 expect(expression.staticElement, getMethod(numType, "+"));
1722 _listener.assertNoErrors();
1723 }
1724
1725 void test_visitPrefixedIdentifier_dynamic() {
1726 DartType dynamicType = _typeProvider.dynamicType;
1727 SimpleIdentifier target = AstFactory.identifier3("a");
1728 VariableElementImpl variable = ElementFactory.localVariableElement(target);
1729 variable.type = dynamicType;
1730 target.staticElement = variable;
1731 target.staticType = dynamicType;
1732 PrefixedIdentifier identifier =
1733 AstFactory.identifier(target, AstFactory.identifier3("b"));
1734 _resolveNode(identifier);
1735 expect(identifier.staticElement, isNull);
1736 expect(identifier.identifier.staticElement, isNull);
1737 _listener.assertNoErrors();
1738 }
1739
1740 void test_visitPrefixedIdentifier_nonDynamic() {
1741 ClassElementImpl classA = ElementFactory.classElement2("A");
1742 String getterName = "b";
1743 PropertyAccessorElement getter =
1744 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
1745 classA.accessors = <PropertyAccessorElement>[getter];
1746 SimpleIdentifier target = AstFactory.identifier3("a");
1747 VariableElementImpl variable = ElementFactory.localVariableElement(target);
1748 variable.type = classA.type;
1749 target.staticElement = variable;
1750 target.staticType = classA.type;
1751 PrefixedIdentifier identifier =
1752 AstFactory.identifier(target, AstFactory.identifier3(getterName));
1753 _resolveNode(identifier);
1754 expect(identifier.staticElement, same(getter));
1755 expect(identifier.identifier.staticElement, same(getter));
1756 _listener.assertNoErrors();
1757 }
1758
1759 void test_visitPrefixedIdentifier_staticClassMember_getter() {
1760 ClassElementImpl classA = ElementFactory.classElement2("A");
1761 // set accessors
1762 String propName = "b";
1763 PropertyAccessorElement getter =
1764 ElementFactory.getterElement(propName, false, _typeProvider.intType);
1765 PropertyAccessorElement setter =
1766 ElementFactory.setterElement(propName, false, _typeProvider.intType);
1767 classA.accessors = <PropertyAccessorElement>[getter, setter];
1768 // prepare "A.m"
1769 SimpleIdentifier target = AstFactory.identifier3("A");
1770 target.staticElement = classA;
1771 target.staticType = classA.type;
1772 PrefixedIdentifier identifier =
1773 AstFactory.identifier(target, AstFactory.identifier3(propName));
1774 // resolve
1775 _resolveNode(identifier);
1776 expect(identifier.staticElement, same(getter));
1777 expect(identifier.identifier.staticElement, same(getter));
1778 _listener.assertNoErrors();
1779 }
1780
1781 void test_visitPrefixedIdentifier_staticClassMember_method() {
1782 ClassElementImpl classA = ElementFactory.classElement2("A");
1783 // set methods
1784 String propName = "m";
1785 MethodElement method =
1786 ElementFactory.methodElement("m", _typeProvider.intType);
1787 classA.methods = <MethodElement>[method];
1788 // prepare "A.m"
1789 SimpleIdentifier target = AstFactory.identifier3("A");
1790 target.staticElement = classA;
1791 target.staticType = classA.type;
1792 PrefixedIdentifier identifier =
1793 AstFactory.identifier(target, AstFactory.identifier3(propName));
1794 AstFactory.assignmentExpression(
1795 identifier, TokenType.EQ, AstFactory.nullLiteral());
1796 // resolve
1797 _resolveNode(identifier);
1798 expect(identifier.staticElement, same(method));
1799 expect(identifier.identifier.staticElement, same(method));
1800 _listener.assertNoErrors();
1801 }
1802
1803 void test_visitPrefixedIdentifier_staticClassMember_setter() {
1804 ClassElementImpl classA = ElementFactory.classElement2("A");
1805 // set accessors
1806 String propName = "b";
1807 PropertyAccessorElement getter =
1808 ElementFactory.getterElement(propName, false, _typeProvider.intType);
1809 PropertyAccessorElement setter =
1810 ElementFactory.setterElement(propName, false, _typeProvider.intType);
1811 classA.accessors = <PropertyAccessorElement>[getter, setter];
1812 // prepare "A.b = null"
1813 SimpleIdentifier target = AstFactory.identifier3("A");
1814 target.staticElement = classA;
1815 target.staticType = classA.type;
1816 PrefixedIdentifier identifier =
1817 AstFactory.identifier(target, AstFactory.identifier3(propName));
1818 AstFactory.assignmentExpression(
1819 identifier, TokenType.EQ, AstFactory.nullLiteral());
1820 // resolve
1821 _resolveNode(identifier);
1822 expect(identifier.staticElement, same(setter));
1823 expect(identifier.identifier.staticElement, same(setter));
1824 _listener.assertNoErrors();
1825 }
1826
1827 void test_visitPrefixExpression() {
1828 InterfaceType numType = _typeProvider.numType;
1829 SimpleIdentifier operand = AstFactory.identifier3("i");
1830 operand.staticType = numType;
1831 PrefixExpression expression =
1832 AstFactory.prefixExpression(TokenType.PLUS_PLUS, operand);
1833 _resolveNode(expression);
1834 expect(expression.staticElement, getMethod(numType, "+"));
1835 _listener.assertNoErrors();
1836 }
1837
1838 void test_visitPropertyAccess_getter_identifier() {
1839 ClassElementImpl classA = ElementFactory.classElement2("A");
1840 String getterName = "b";
1841 PropertyAccessorElement getter =
1842 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
1843 classA.accessors = <PropertyAccessorElement>[getter];
1844 SimpleIdentifier target = AstFactory.identifier3("a");
1845 target.staticType = classA.type;
1846 PropertyAccess access = AstFactory.propertyAccess2(target, getterName);
1847 _resolveNode(access);
1848 expect(access.propertyName.staticElement, same(getter));
1849 _listener.assertNoErrors();
1850 }
1851
1852 void test_visitPropertyAccess_getter_super() {
1853 //
1854 // class A {
1855 // int get b;
1856 // }
1857 // class B {
1858 // ... super.m ...
1859 // }
1860 //
1861 ClassElementImpl classA = ElementFactory.classElement2("A");
1862 String getterName = "b";
1863 PropertyAccessorElement getter =
1864 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
1865 classA.accessors = <PropertyAccessorElement>[getter];
1866 SuperExpression target = AstFactory.superExpression();
1867 target.staticType = ElementFactory.classElement("B", classA.type).type;
1868 PropertyAccess access = AstFactory.propertyAccess2(target, getterName);
1869 AstFactory.methodDeclaration2(
1870 null,
1871 null,
1872 null,
1873 null,
1874 AstFactory.identifier3("m"),
1875 AstFactory.formalParameterList(),
1876 AstFactory.expressionFunctionBody(access));
1877 _resolveNode(access);
1878 expect(access.propertyName.staticElement, same(getter));
1879 _listener.assertNoErrors();
1880 }
1881
1882 void test_visitPropertyAccess_setter_this() {
1883 ClassElementImpl classA = ElementFactory.classElement2("A");
1884 String setterName = "b";
1885 PropertyAccessorElement setter =
1886 ElementFactory.setterElement(setterName, false, _typeProvider.intType);
1887 classA.accessors = <PropertyAccessorElement>[setter];
1888 ThisExpression target = AstFactory.thisExpression();
1889 target.staticType = classA.type;
1890 PropertyAccess access = AstFactory.propertyAccess2(target, setterName);
1891 AstFactory.assignmentExpression(
1892 access, TokenType.EQ, AstFactory.integer(0));
1893 _resolveNode(access);
1894 expect(access.propertyName.staticElement, same(setter));
1895 _listener.assertNoErrors();
1896 }
1897
1898 void test_visitSimpleIdentifier_classScope() {
1899 InterfaceType doubleType = _typeProvider.doubleType;
1900 String fieldName = "NAN";
1901 SimpleIdentifier node = AstFactory.identifier3(fieldName);
1902 _resolveInClass(node, doubleType.element);
1903 expect(node.staticElement, getGetter(doubleType, fieldName));
1904 _listener.assertNoErrors();
1905 }
1906
1907 void test_visitSimpleIdentifier_dynamic() {
1908 SimpleIdentifier node = AstFactory.identifier3("dynamic");
1909 _resolveIdentifier(node);
1910 expect(node.staticElement, same(_typeProvider.dynamicType.element));
1911 expect(node.staticType, same(_typeProvider.typeType));
1912 _listener.assertNoErrors();
1913 }
1914
1915 void test_visitSimpleIdentifier_lexicalScope() {
1916 SimpleIdentifier node = AstFactory.identifier3("i");
1917 VariableElementImpl element = ElementFactory.localVariableElement(node);
1918 expect(_resolveIdentifier(node, [element]), same(element));
1919 _listener.assertNoErrors();
1920 }
1921
1922 void test_visitSimpleIdentifier_lexicalScope_field_setter() {
1923 InterfaceType intType = _typeProvider.intType;
1924 ClassElementImpl classA = ElementFactory.classElement2("A");
1925 String fieldName = "a";
1926 FieldElement field =
1927 ElementFactory.fieldElement(fieldName, false, false, false, intType);
1928 classA.fields = <FieldElement>[field];
1929 classA.accessors = <PropertyAccessorElement>[field.getter, field.setter];
1930 SimpleIdentifier node = AstFactory.identifier3(fieldName);
1931 AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0));
1932 _resolveInClass(node, classA);
1933 Element element = node.staticElement;
1934 EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccessorElement,
1935 PropertyAccessorElement, element);
1936 expect((element as PropertyAccessorElement).isSetter, isTrue);
1937 _listener.assertNoErrors();
1938 }
1939
1940 void test_visitSuperConstructorInvocation() {
1941 ClassElementImpl superclass = ElementFactory.classElement2("A");
1942 ConstructorElementImpl superConstructor =
1943 ElementFactory.constructorElement2(superclass, null);
1944 superclass.constructors = <ConstructorElement>[superConstructor];
1945 ClassElementImpl subclass =
1946 ElementFactory.classElement("B", superclass.type);
1947 ConstructorElementImpl subConstructor =
1948 ElementFactory.constructorElement2(subclass, null);
1949 subclass.constructors = <ConstructorElement>[subConstructor];
1950 SuperConstructorInvocation invocation =
1951 AstFactory.superConstructorInvocation();
1952 _resolveInClass(invocation, subclass);
1953 expect(invocation.staticElement, superConstructor);
1954 _listener.assertNoErrors();
1955 }
1956
1957 void test_visitSuperConstructorInvocation_namedParameter() {
1958 ClassElementImpl superclass = ElementFactory.classElement2("A");
1959 ConstructorElementImpl superConstructor =
1960 ElementFactory.constructorElement2(superclass, null);
1961 String parameterName = "p";
1962 ParameterElement parameter = ElementFactory.namedParameter(parameterName);
1963 superConstructor.parameters = <ParameterElement>[parameter];
1964 superclass.constructors = <ConstructorElement>[superConstructor];
1965 ClassElementImpl subclass =
1966 ElementFactory.classElement("B", superclass.type);
1967 ConstructorElementImpl subConstructor =
1968 ElementFactory.constructorElement2(subclass, null);
1969 subclass.constructors = <ConstructorElement>[subConstructor];
1970 SuperConstructorInvocation invocation = AstFactory
1971 .superConstructorInvocation([
1972 AstFactory.namedExpression2(parameterName, AstFactory.integer(0))
1973 ]);
1974 _resolveInClass(invocation, subclass);
1975 expect(invocation.staticElement, superConstructor);
1976 expect(
1977 (invocation.argumentList.arguments[0] as NamedExpression)
1978 .name
1979 .label
1980 .staticElement,
1981 same(parameter));
1982 _listener.assertNoErrors();
1983 }
1984
1985 /**
1986 * Create the resolver used by the tests.
1987 *
1988 * @return the resolver that was created
1989 */
1990 ElementResolver _createResolver() {
1991 InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
1992 FileBasedSource source =
1993 new FileBasedSource(FileUtilities2.createFile("/test.dart"));
1994 CompilationUnitElementImpl definingCompilationUnit =
1995 new CompilationUnitElementImpl("test.dart");
1996 definingCompilationUnit.librarySource =
1997 definingCompilationUnit.source = source;
1998 _definingLibrary = ElementFactory.library(context, "test");
1999 _definingLibrary.definingCompilationUnit = definingCompilationUnit;
2000 Library library = new Library(context, _listener, source);
2001 library.libraryElement = _definingLibrary;
2002 _visitor = new ResolverVisitor(
2003 library.libraryElement, source, _typeProvider, library.errorListener,
2004 nameScope: library.libraryScope,
2005 inheritanceManager: library.inheritanceManager);
2006 try {
2007 return _visitor.elementResolver;
2008 } catch (exception) {
2009 throw new IllegalArgumentException(
2010 "Could not create resolver", exception);
2011 }
2012 }
2013
2014 /**
2015 * Return the element associated with the label of [statement] after the
2016 * resolver has resolved it. [labelElement] is the label element to be
2017 * defined in the statement's label scope, and [labelTarget] is the statement
2018 * the label resolves to.
2019 */
2020 Element _resolveBreak(BreakStatement statement, LabelElementImpl labelElement,
2021 Statement labelTarget) {
2022 _resolveStatement(statement, labelElement, labelTarget);
2023 return statement.label.staticElement;
2024 }
2025
2026 /**
2027 * Return the element associated with the label [statement] after the
2028 * resolver has resolved it. [labelElement] is the label element to be
2029 * defined in the statement's label scope, and [labelTarget] is the AST node
2030 * the label resolves to.
2031 *
2032 * @param statement the statement to be resolved
2033 * @param labelElement the label element to be defined in the statement's labe l scope
2034 * @return the element to which the statement's label was resolved
2035 */
2036 Element _resolveContinue(ContinueStatement statement,
2037 LabelElementImpl labelElement, AstNode labelTarget) {
2038 _resolveStatement(statement, labelElement, labelTarget);
2039 return statement.label.staticElement;
2040 }
2041
2042 /**
2043 * Return the element associated with the given identifier after the resolver has resolved the
2044 * identifier.
2045 *
2046 * @param node the expression to be resolved
2047 * @param definedElements the elements that are to be defined in the scope in which the element is
2048 * being resolved
2049 * @return the element to which the expression was resolved
2050 */
2051 Element _resolveIdentifier(Identifier node, [List<Element> definedElements]) {
2052 _resolveNode(node, definedElements);
2053 return node.staticElement;
2054 }
2055
2056 /**
2057 * Return the element associated with the given identifier after the resolver has resolved the
2058 * identifier.
2059 *
2060 * @param node the expression to be resolved
2061 * @param enclosingClass the element representing the class enclosing the iden tifier
2062 * @return the element to which the expression was resolved
2063 */
2064 void _resolveInClass(AstNode node, ClassElement enclosingClass) {
2065 try {
2066 Scope outerScope = _visitor.nameScope;
2067 try {
2068 _visitor.enclosingClass = enclosingClass;
2069 EnclosedScope innerScope = new ClassScope(
2070 new TypeParameterScope(outerScope, enclosingClass), enclosingClass);
2071 _visitor.nameScope = innerScope;
2072 node.accept(_resolver);
2073 } finally {
2074 _visitor.enclosingClass = null;
2075 _visitor.nameScope = outerScope;
2076 }
2077 } catch (exception) {
2078 throw new IllegalArgumentException("Could not resolve node", exception);
2079 }
2080 }
2081
2082 /**
2083 * Return the element associated with the given expression after the resolver has resolved the
2084 * expression.
2085 *
2086 * @param node the expression to be resolved
2087 * @param definedElements the elements that are to be defined in the scope in which the element is
2088 * being resolved
2089 * @return the element to which the expression was resolved
2090 */
2091 Element _resolveIndexExpression(IndexExpression node,
2092 [List<Element> definedElements]) {
2093 _resolveNode(node, definedElements);
2094 return node.staticElement;
2095 }
2096
2097 /**
2098 * Return the element associated with the given identifier after the resolver has resolved the
2099 * identifier.
2100 *
2101 * @param node the expression to be resolved
2102 * @param definedElements the elements that are to be defined in the scope in which the element is
2103 * being resolved
2104 * @return the element to which the expression was resolved
2105 */
2106 void _resolveNode(AstNode node, [List<Element> definedElements]) {
2107 try {
2108 Scope outerScope = _visitor.nameScope;
2109 try {
2110 EnclosedScope innerScope = new EnclosedScope(outerScope);
2111 if (definedElements != null) {
2112 for (Element element in definedElements) {
2113 innerScope.define(element);
2114 }
2115 }
2116 _visitor.nameScope = innerScope;
2117 node.accept(_resolver);
2118 } finally {
2119 _visitor.nameScope = outerScope;
2120 }
2121 } catch (exception) {
2122 throw new IllegalArgumentException("Could not resolve node", exception);
2123 }
2124 }
2125
2126 /**
2127 * Return the element associated with the label of the given statement after t he resolver has
2128 * resolved the statement.
2129 *
2130 * @param statement the statement to be resolved
2131 * @param labelElement the label element to be defined in the statement's labe l scope
2132 * @return the element to which the statement's label was resolved
2133 */
2134 void _resolveStatement(
2135 Statement statement, LabelElementImpl labelElement, AstNode labelTarget) {
2136 try {
2137 LabelScope outerScope = _visitor.labelScope;
2138 try {
2139 LabelScope innerScope;
2140 if (labelElement == null) {
2141 innerScope = outerScope;
2142 } else {
2143 innerScope = new LabelScope(
2144 outerScope, labelElement.name, labelTarget, labelElement);
2145 }
2146 _visitor.labelScope = innerScope;
2147 statement.accept(_resolver);
2148 } finally {
2149 _visitor.labelScope = outerScope;
2150 }
2151 } catch (exception) {
2152 throw new IllegalArgumentException("Could not resolve node", exception);
2153 }
2154 }
2155 }
2156
2157 @reflectiveTest
2158 class EnclosedScopeTest extends ResolverTestCase {
2159 void test_define_duplicate() {
2160 GatheringErrorListener listener = new GatheringErrorListener();
2161 Scope rootScope =
2162 new Scope_EnclosedScopeTest_test_define_duplicate(listener);
2163 EnclosedScope scope = new EnclosedScope(rootScope);
2164 VariableElement element1 =
2165 ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
2166 VariableElement element2 =
2167 ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
2168 scope.define(element1);
2169 scope.define(element2);
2170 listener.assertErrorsWithSeverities([ErrorSeverity.ERROR]);
2171 }
2172
2173 void test_define_normal() {
2174 GatheringErrorListener listener = new GatheringErrorListener();
2175 Scope rootScope = new Scope_EnclosedScopeTest_test_define_normal(listener);
2176 EnclosedScope outerScope = new EnclosedScope(rootScope);
2177 EnclosedScope innerScope = new EnclosedScope(outerScope);
2178 VariableElement element1 =
2179 ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
2180 VariableElement element2 =
2181 ElementFactory.localVariableElement(AstFactory.identifier3("v2"));
2182 outerScope.define(element1);
2183 innerScope.define(element2);
2184 listener.assertNoErrors();
2185 }
2186 }
2187
2188 @reflectiveTest
2189 class ErrorResolverTest extends ResolverTestCase {
2190 void test_breakLabelOnSwitchMember() {
2191 Source source = addSource(r'''
2192 class A {
2193 void m(int i) {
2194 switch (i) {
2195 l: case 0:
2196 break;
2197 case 1:
2198 break l;
2199 }
2200 }
2201 }''');
2202 computeLibrarySourceErrors(source);
2203 assertErrors(source, [ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER]);
2204 verify([source]);
2205 }
2206
2207 void test_continueLabelOnSwitch() {
2208 Source source = addSource(r'''
2209 class A {
2210 void m(int i) {
2211 l: switch (i) {
2212 case 0:
2213 continue l;
2214 }
2215 }
2216 }''');
2217 computeLibrarySourceErrors(source);
2218 assertErrors(source, [ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH]);
2219 verify([source]);
2220 }
2221
2222 void test_enclosingElement_invalidLocalFunction() {
2223 Source source = addSource(r'''
2224 class C {
2225 C() {
2226 int get x => 0;
2227 }
2228 }''');
2229 LibraryElement library = resolve2(source);
2230 expect(library, isNotNull);
2231 var unit = library.definingCompilationUnit;
2232 expect(unit, isNotNull);
2233 var types = unit.types;
2234 expect(types, isNotNull);
2235 expect(types, hasLength(1));
2236 var type = types[0];
2237 expect(type, isNotNull);
2238 var constructors = type.constructors;
2239 expect(constructors, isNotNull);
2240 expect(constructors, hasLength(1));
2241 ConstructorElement constructor = constructors[0];
2242 expect(constructor, isNotNull);
2243 List<FunctionElement> functions = constructor.functions;
2244 expect(functions, isNotNull);
2245 expect(functions, hasLength(1));
2246 expect(functions[0].enclosingElement, constructor);
2247 assertErrors(source, [ParserErrorCode.GETTER_IN_FUNCTION]);
2248 }
2249 }
2250
2251 @reflectiveTest
2252 class HintCodeTest extends ResolverTestCase {
2253 void fail_deadCode_statementAfterRehrow() {
2254 Source source = addSource(r'''
2255 f() {
2256 try {
2257 var one = 1;
2258 } catch (e) {
2259 rethrow;
2260 var two = 2;
2261 }
2262 }''');
2263 computeLibrarySourceErrors(source);
2264 assertErrors(source, [HintCode.DEAD_CODE]);
2265 verify([source]);
2266 }
2267
2268 void fail_deadCode_statementAfterThrow() {
2269 Source source = addSource(r'''
2270 f() {
2271 var one = 1;
2272 throw 'Stop here';
2273 var two = 2;
2274 }''');
2275 computeLibrarySourceErrors(source);
2276 assertErrors(source, [HintCode.DEAD_CODE]);
2277 verify([source]);
2278 }
2279
2280 void fail_isInt() {
2281 Source source = addSource("var v = 1 is int;");
2282 computeLibrarySourceErrors(source);
2283 assertErrors(source, [HintCode.IS_INT]);
2284 verify([source]);
2285 }
2286
2287 void fail_isNotInt() {
2288 Source source = addSource("var v = 1 is! int;");
2289 computeLibrarySourceErrors(source);
2290 assertErrors(source, [HintCode.IS_NOT_INT]);
2291 verify([source]);
2292 }
2293
2294 void fail_overrideEqualsButNotHashCode() {
2295 Source source = addSource(r'''
2296 class A {
2297 bool operator ==(x) {}
2298 }''');
2299 computeLibrarySourceErrors(source);
2300 assertErrors(source, [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]);
2301 verify([source]);
2302 }
2303
2304 void fail_unusedImport_as_equalPrefixes() {
2305 // See todo at ImportsVerifier.prefixElementMap.
2306 Source source = addSource(r'''
2307 library L;
2308 import 'lib1.dart' as one;
2309 import 'lib2.dart' as one;
2310 one.A a;''');
2311 Source source2 = addNamedSource(
2312 "/lib1.dart",
2313 r'''
2314 library lib1;
2315 class A {}''');
2316 Source source3 = addNamedSource(
2317 "/lib2.dart",
2318 r'''
2319 library lib2;
2320 class B {}''');
2321 computeLibrarySourceErrors(source);
2322 assertErrors(source, [HintCode.UNUSED_IMPORT]);
2323 assertNoErrors(source2);
2324 assertNoErrors(source3);
2325 verify([source, source2, source3]);
2326 }
2327
2328 void test_argumentTypeNotAssignable_functionType() {
2329 Source source = addSource(r'''
2330 m() {
2331 var a = new A();
2332 a.n(() => 0);
2333 }
2334 class A {
2335 n(void f(int i)) {}
2336 }''');
2337 computeLibrarySourceErrors(source);
2338 assertErrors(source, [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
2339 verify([source]);
2340 }
2341
2342 void test_argumentTypeNotAssignable_message() {
2343 // The implementation of HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE assumes that
2344 // StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE has the same message.
2345 expect(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE.message,
2346 HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE.message);
2347 }
2348
2349 void test_argumentTypeNotAssignable_type() {
2350 Source source = addSource(r'''
2351 m() {
2352 var i = '';
2353 n(i);
2354 }
2355 n(int i) {}''');
2356 computeLibrarySourceErrors(source);
2357 assertErrors(source, [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
2358 verify([source]);
2359 }
2360
2361 void test_deadCode_deadBlock_conditionalElse() {
2362 Source source = addSource(r'''
2363 f() {
2364 true ? 1 : 2;
2365 }''');
2366 computeLibrarySourceErrors(source);
2367 assertErrors(source, [HintCode.DEAD_CODE]);
2368 verify([source]);
2369 }
2370
2371 void test_deadCode_deadBlock_conditionalElse_nested() {
2372 // test that a dead else-statement can't generate additional violations
2373 Source source = addSource(r'''
2374 f() {
2375 true ? true : false && false;
2376 }''');
2377 computeLibrarySourceErrors(source);
2378 assertErrors(source, [HintCode.DEAD_CODE]);
2379 verify([source]);
2380 }
2381
2382 void test_deadCode_deadBlock_conditionalIf() {
2383 Source source = addSource(r'''
2384 f() {
2385 false ? 1 : 2;
2386 }''');
2387 computeLibrarySourceErrors(source);
2388 assertErrors(source, [HintCode.DEAD_CODE]);
2389 verify([source]);
2390 }
2391
2392 void test_deadCode_deadBlock_conditionalIf_nested() {
2393 // test that a dead then-statement can't generate additional violations
2394 Source source = addSource(r'''
2395 f() {
2396 false ? false && false : true;
2397 }''');
2398 computeLibrarySourceErrors(source);
2399 assertErrors(source, [HintCode.DEAD_CODE]);
2400 verify([source]);
2401 }
2402
2403 void test_deadCode_deadBlock_else() {
2404 Source source = addSource(r'''
2405 f() {
2406 if(true) {} else {}
2407 }''');
2408 computeLibrarySourceErrors(source);
2409 assertErrors(source, [HintCode.DEAD_CODE]);
2410 verify([source]);
2411 }
2412
2413 void test_deadCode_deadBlock_else_nested() {
2414 // test that a dead else-statement can't generate additional violations
2415 Source source = addSource(r'''
2416 f() {
2417 if(true) {} else {if (false) {}}
2418 }''');
2419 computeLibrarySourceErrors(source);
2420 assertErrors(source, [HintCode.DEAD_CODE]);
2421 verify([source]);
2422 }
2423
2424 void test_deadCode_deadBlock_if() {
2425 Source source = addSource(r'''
2426 f() {
2427 if(false) {}
2428 }''');
2429 computeLibrarySourceErrors(source);
2430 assertErrors(source, [HintCode.DEAD_CODE]);
2431 verify([source]);
2432 }
2433
2434 void test_deadCode_deadBlock_if_nested() {
2435 // test that a dead then-statement can't generate additional violations
2436 Source source = addSource(r'''
2437 f() {
2438 if(false) {if(false) {}}
2439 }''');
2440 computeLibrarySourceErrors(source);
2441 assertErrors(source, [HintCode.DEAD_CODE]);
2442 verify([source]);
2443 }
2444
2445 void test_deadCode_deadBlock_while() {
2446 Source source = addSource(r'''
2447 f() {
2448 while(false) {}
2449 }''');
2450 computeLibrarySourceErrors(source);
2451 assertErrors(source, [HintCode.DEAD_CODE]);
2452 verify([source]);
2453 }
2454
2455 void test_deadCode_deadBlock_while_nested() {
2456 // test that a dead while body can't generate additional violations
2457 Source source = addSource(r'''
2458 f() {
2459 while(false) {if(false) {}}
2460 }''');
2461 computeLibrarySourceErrors(source);
2462 assertErrors(source, [HintCode.DEAD_CODE]);
2463 verify([source]);
2464 }
2465
2466 void test_deadCode_deadCatch_catchFollowingCatch() {
2467 Source source = addSource(r'''
2468 class A {}
2469 f() {
2470 try {} catch (e) {} catch (e) {}
2471 }''');
2472 computeLibrarySourceErrors(source);
2473 assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
2474 verify([source]);
2475 }
2476
2477 void test_deadCode_deadCatch_catchFollowingCatch_nested() {
2478 // test that a dead catch clause can't generate additional violations
2479 Source source = addSource(r'''
2480 class A {}
2481 f() {
2482 try {} catch (e) {} catch (e) {if(false) {}}
2483 }''');
2484 computeLibrarySourceErrors(source);
2485 assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
2486 verify([source]);
2487 }
2488
2489 void test_deadCode_deadCatch_catchFollowingCatch_object() {
2490 Source source = addSource(r'''
2491 f() {
2492 try {} on Object catch (e) {} catch (e) {}
2493 }''');
2494 computeLibrarySourceErrors(source);
2495 assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
2496 verify([source]);
2497 }
2498
2499 void test_deadCode_deadCatch_catchFollowingCatch_object_nested() {
2500 // test that a dead catch clause can't generate additional violations
2501 Source source = addSource(r'''
2502 f() {
2503 try {} on Object catch (e) {} catch (e) {if(false) {}}
2504 }''');
2505 computeLibrarySourceErrors(source);
2506 assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
2507 verify([source]);
2508 }
2509
2510 void test_deadCode_deadCatch_onCatchSubtype() {
2511 Source source = addSource(r'''
2512 class A {}
2513 class B extends A {}
2514 f() {
2515 try {} on A catch (e) {} on B catch (e) {}
2516 }''');
2517 computeLibrarySourceErrors(source);
2518 assertErrors(source, [HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]);
2519 verify([source]);
2520 }
2521
2522 void test_deadCode_deadCatch_onCatchSubtype_nested() {
2523 // test that a dead catch clause can't generate additional violations
2524 Source source = addSource(r'''
2525 class A {}
2526 class B extends A {}
2527 f() {
2528 try {} on A catch (e) {} on B catch (e) {if(false) {}}
2529 }''');
2530 computeLibrarySourceErrors(source);
2531 assertErrors(source, [HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]);
2532 verify([source]);
2533 }
2534
2535 void test_deadCode_deadOperandLHS_and() {
2536 Source source = addSource(r'''
2537 f() {
2538 bool b = false && false;
2539 }''');
2540 computeLibrarySourceErrors(source);
2541 assertErrors(source, [HintCode.DEAD_CODE]);
2542 verify([source]);
2543 }
2544
2545 void test_deadCode_deadOperandLHS_and_nested() {
2546 Source source = addSource(r'''
2547 f() {
2548 bool b = false && (false && false);
2549 }''');
2550 computeLibrarySourceErrors(source);
2551 assertErrors(source, [HintCode.DEAD_CODE]);
2552 verify([source]);
2553 }
2554
2555 void test_deadCode_deadOperandLHS_or() {
2556 Source source = addSource(r'''
2557 f() {
2558 bool b = true || true;
2559 }''');
2560 computeLibrarySourceErrors(source);
2561 assertErrors(source, [HintCode.DEAD_CODE]);
2562 verify([source]);
2563 }
2564
2565 void test_deadCode_deadOperandLHS_or_nested() {
2566 Source source = addSource(r'''
2567 f() {
2568 bool b = true || (false && false);
2569 }''');
2570 computeLibrarySourceErrors(source);
2571 assertErrors(source, [HintCode.DEAD_CODE]);
2572 verify([source]);
2573 }
2574
2575 void test_deadCode_statementAfterBreak_inDefaultCase() {
2576 Source source = addSource(r'''
2577 f(v) {
2578 switch(v) {
2579 case 1:
2580 default:
2581 break;
2582 var a;
2583 }
2584 }''');
2585 computeLibrarySourceErrors(source);
2586 assertErrors(source, [HintCode.DEAD_CODE]);
2587 verify([source]);
2588 }
2589
2590 void test_deadCode_statementAfterBreak_inForEachStatement() {
2591 Source source = addSource(r'''
2592 f() {
2593 var list;
2594 for(var l in list) {
2595 break;
2596 var a;
2597 }
2598 }''');
2599 computeLibrarySourceErrors(source);
2600 assertErrors(source, [HintCode.DEAD_CODE]);
2601 verify([source]);
2602 }
2603
2604 void test_deadCode_statementAfterBreak_inForStatement() {
2605 Source source = addSource(r'''
2606 f() {
2607 for(;;) {
2608 break;
2609 var a;
2610 }
2611 }''');
2612 computeLibrarySourceErrors(source);
2613 assertErrors(source, [HintCode.DEAD_CODE]);
2614 verify([source]);
2615 }
2616
2617 void test_deadCode_statementAfterBreak_inSwitchCase() {
2618 Source source = addSource(r'''
2619 f(v) {
2620 switch(v) {
2621 case 1:
2622 break;
2623 var a;
2624 }
2625 }''');
2626 computeLibrarySourceErrors(source);
2627 assertErrors(source, [HintCode.DEAD_CODE]);
2628 verify([source]);
2629 }
2630
2631 void test_deadCode_statementAfterBreak_inWhileStatement() {
2632 Source source = addSource(r'''
2633 f(v) {
2634 while(v) {
2635 break;
2636 var a;
2637 }
2638 }''');
2639 computeLibrarySourceErrors(source);
2640 assertErrors(source, [HintCode.DEAD_CODE]);
2641 verify([source]);
2642 }
2643
2644 void test_deadCode_statementAfterContinue_inForEachStatement() {
2645 Source source = addSource(r'''
2646 f() {
2647 var list;
2648 for(var l in list) {
2649 continue;
2650 var a;
2651 }
2652 }''');
2653 computeLibrarySourceErrors(source);
2654 assertErrors(source, [HintCode.DEAD_CODE]);
2655 verify([source]);
2656 }
2657
2658 void test_deadCode_statementAfterContinue_inForStatement() {
2659 Source source = addSource(r'''
2660 f() {
2661 for(;;) {
2662 continue;
2663 var a;
2664 }
2665 }''');
2666 computeLibrarySourceErrors(source);
2667 assertErrors(source, [HintCode.DEAD_CODE]);
2668 verify([source]);
2669 }
2670
2671 void test_deadCode_statementAfterContinue_inWhileStatement() {
2672 Source source = addSource(r'''
2673 f(v) {
2674 while(v) {
2675 continue;
2676 var a;
2677 }
2678 }''');
2679 computeLibrarySourceErrors(source);
2680 assertErrors(source, [HintCode.DEAD_CODE]);
2681 verify([source]);
2682 }
2683
2684 void test_deadCode_statementAfterReturn_function() {
2685 Source source = addSource(r'''
2686 f() {
2687 var one = 1;
2688 return;
2689 var two = 2;
2690 }''');
2691 computeLibrarySourceErrors(source);
2692 assertErrors(source, [HintCode.DEAD_CODE]);
2693 verify([source]);
2694 }
2695
2696 void test_deadCode_statementAfterReturn_ifStatement() {
2697 Source source = addSource(r'''
2698 f(bool b) {
2699 if(b) {
2700 var one = 1;
2701 return;
2702 var two = 2;
2703 }
2704 }''');
2705 computeLibrarySourceErrors(source);
2706 assertErrors(source, [HintCode.DEAD_CODE]);
2707 verify([source]);
2708 }
2709
2710 void test_deadCode_statementAfterReturn_method() {
2711 Source source = addSource(r'''
2712 class A {
2713 m() {
2714 var one = 1;
2715 return;
2716 var two = 2;
2717 }
2718 }''');
2719 computeLibrarySourceErrors(source);
2720 assertErrors(source, [HintCode.DEAD_CODE]);
2721 verify([source]);
2722 }
2723
2724 void test_deadCode_statementAfterReturn_nested() {
2725 Source source = addSource(r'''
2726 f() {
2727 var one = 1;
2728 return;
2729 if(false) {}
2730 }''');
2731 computeLibrarySourceErrors(source);
2732 assertErrors(source, [HintCode.DEAD_CODE]);
2733 verify([source]);
2734 }
2735
2736 void test_deadCode_statementAfterReturn_twoReturns() {
2737 Source source = addSource(r'''
2738 f() {
2739 var one = 1;
2740 return;
2741 var two = 2;
2742 return;
2743 var three = 3;
2744 }''');
2745 computeLibrarySourceErrors(source);
2746 assertErrors(source, [HintCode.DEAD_CODE]);
2747 verify([source]);
2748 }
2749
2750 void test_deprecatedAnnotationUse_assignment() {
2751 Source source = addSource(r'''
2752 class A {
2753 @deprecated
2754 A operator+(A a) { return a; }
2755 }
2756 f(A a) {
2757 A b;
2758 a += b;
2759 }''');
2760 computeLibrarySourceErrors(source);
2761 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2762 verify([source]);
2763 }
2764
2765 void test_deprecatedAnnotationUse_Deprecated() {
2766 Source source = addSource(r'''
2767 class A {
2768 @Deprecated('0.9')
2769 m() {}
2770 n() {m();}
2771 }''');
2772 computeLibrarySourceErrors(source);
2773 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2774 verify([source]);
2775 }
2776
2777 void test_deprecatedAnnotationUse_deprecated() {
2778 Source source = addSource(r'''
2779 class A {
2780 @deprecated
2781 m() {}
2782 n() {m();}
2783 }''');
2784 computeLibrarySourceErrors(source);
2785 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2786 verify([source]);
2787 }
2788
2789 void test_deprecatedAnnotationUse_export() {
2790 Source source = addSource("export 'deprecated_library.dart';");
2791 addNamedSource(
2792 "/deprecated_library.dart",
2793 r'''
2794 @deprecated
2795 library deprecated_library;
2796 class A {}''');
2797 computeLibrarySourceErrors(source);
2798 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2799 verify([source]);
2800 }
2801
2802 void test_deprecatedAnnotationUse_getter() {
2803 Source source = addSource(r'''
2804 class A {
2805 @deprecated
2806 get m => 1;
2807 }
2808 f(A a) {
2809 return a.m;
2810 }''');
2811 computeLibrarySourceErrors(source);
2812 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2813 verify([source]);
2814 }
2815
2816 void test_deprecatedAnnotationUse_import() {
2817 Source source = addSource(r'''
2818 import 'deprecated_library.dart';
2819 f(A a) {}''');
2820 addNamedSource(
2821 "/deprecated_library.dart",
2822 r'''
2823 @deprecated
2824 library deprecated_library;
2825 class A {}''');
2826 computeLibrarySourceErrors(source);
2827 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2828 verify([source]);
2829 }
2830
2831 void test_deprecatedAnnotationUse_indexExpression() {
2832 Source source = addSource(r'''
2833 class A {
2834 @deprecated
2835 operator[](int i) {}
2836 }
2837 f(A a) {
2838 return a[1];
2839 }''');
2840 computeLibrarySourceErrors(source);
2841 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2842 verify([source]);
2843 }
2844
2845 void test_deprecatedAnnotationUse_instanceCreation() {
2846 Source source = addSource(r'''
2847 class A {
2848 @deprecated
2849 A(int i) {}
2850 }
2851 f() {
2852 A a = new A(1);
2853 }''');
2854 computeLibrarySourceErrors(source);
2855 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2856 verify([source]);
2857 }
2858
2859 void test_deprecatedAnnotationUse_instanceCreation_namedConstructor() {
2860 Source source = addSource(r'''
2861 class A {
2862 @deprecated
2863 A.named(int i) {}
2864 }
2865 f() {
2866 A a = new A.named(1);
2867 }''');
2868 computeLibrarySourceErrors(source);
2869 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2870 verify([source]);
2871 }
2872
2873 void test_deprecatedAnnotationUse_operator() {
2874 Source source = addSource(r'''
2875 class A {
2876 @deprecated
2877 operator+(A a) {}
2878 }
2879 f(A a) {
2880 A b;
2881 return a + b;
2882 }''');
2883 computeLibrarySourceErrors(source);
2884 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2885 verify([source]);
2886 }
2887
2888 void test_deprecatedAnnotationUse_setter() {
2889 Source source = addSource(r'''
2890 class A {
2891 @deprecated
2892 set s(v) {}
2893 }
2894 f(A a) {
2895 return a.s = 1;
2896 }''');
2897 computeLibrarySourceErrors(source);
2898 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2899 verify([source]);
2900 }
2901
2902 void test_deprecatedAnnotationUse_superConstructor() {
2903 Source source = addSource(r'''
2904 class A {
2905 @deprecated
2906 A() {}
2907 }
2908 class B extends A {
2909 B() : super() {}
2910 }''');
2911 computeLibrarySourceErrors(source);
2912 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2913 verify([source]);
2914 }
2915
2916 void test_deprecatedAnnotationUse_superConstructor_namedConstructor() {
2917 Source source = addSource(r'''
2918 class A {
2919 @deprecated
2920 A.named() {}
2921 }
2922 class B extends A {
2923 B() : super.named() {}
2924 }''');
2925 computeLibrarySourceErrors(source);
2926 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2927 verify([source]);
2928 }
2929
2930 void test_divisionOptimization_double() {
2931 Source source = addSource(r'''
2932 f(double x, double y) {
2933 var v = (x / y).toInt();
2934 }''');
2935 computeLibrarySourceErrors(source);
2936 assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
2937 verify([source]);
2938 }
2939
2940 void test_divisionOptimization_int() {
2941 Source source = addSource(r'''
2942 f(int x, int y) {
2943 var v = (x / y).toInt();
2944 }''');
2945 computeLibrarySourceErrors(source);
2946 assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
2947 verify([source]);
2948 }
2949
2950 void test_divisionOptimization_propagatedType() {
2951 // Tests the propagated type information of the '/' method
2952 Source source = addSource(r'''
2953 f(x, y) {
2954 x = 1;
2955 y = 1;
2956 var v = (x / y).toInt();
2957 }''');
2958 computeLibrarySourceErrors(source);
2959 assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
2960 verify([source]);
2961 }
2962
2963 void test_divisionOptimization_wrappedBinaryExpression() {
2964 Source source = addSource(r'''
2965 f(int x, int y) {
2966 var v = (((x / y))).toInt();
2967 }''');
2968 computeLibrarySourceErrors(source);
2969 assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
2970 verify([source]);
2971 }
2972
2973 void test_duplicateImport() {
2974 Source source = addSource(r'''
2975 library L;
2976 import 'lib1.dart';
2977 import 'lib1.dart';
2978 A a;''');
2979 addNamedSource(
2980 "/lib1.dart",
2981 r'''
2982 library lib1;
2983 class A {}''');
2984 computeLibrarySourceErrors(source);
2985 assertErrors(source, [HintCode.DUPLICATE_IMPORT]);
2986 verify([source]);
2987 }
2988
2989 void test_duplicateImport2() {
2990 Source source = addSource(r'''
2991 library L;
2992 import 'lib1.dart';
2993 import 'lib1.dart';
2994 import 'lib1.dart';
2995 A a;''');
2996 addNamedSource(
2997 "/lib1.dart",
2998 r'''
2999 library lib1;
3000 class A {}''');
3001 computeLibrarySourceErrors(source);
3002 assertErrors(
3003 source, [HintCode.DUPLICATE_IMPORT, HintCode.DUPLICATE_IMPORT]);
3004 verify([source]);
3005 }
3006
3007 void test_duplicateImport3() {
3008 Source source = addSource(r'''
3009 library L;
3010 import 'lib1.dart' as M show A hide B;
3011 import 'lib1.dart' as M show A hide B;
3012 M.A a;''');
3013 addNamedSource(
3014 "/lib1.dart",
3015 r'''
3016 library lib1;
3017 class A {}
3018 class B {}''');
3019 computeLibrarySourceErrors(source);
3020 assertErrors(source, [HintCode.DUPLICATE_IMPORT]);
3021 verify([source]);
3022 }
3023
3024 void test_importDeferredLibraryWithLoadFunction() {
3025 resolveWithErrors(<String>[
3026 r'''
3027 library lib1;
3028 loadLibrary() {}
3029 f() {}''',
3030 r'''
3031 library root;
3032 import 'lib1.dart' deferred as lib1;
3033 main() { lib1.f(); }'''
3034 ], <ErrorCode>[
3035 HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION
3036 ]);
3037 }
3038
3039 void test_invalidAssignment_instanceVariable() {
3040 Source source = addSource(r'''
3041 class A {
3042 int x;
3043 }
3044 f(var y) {
3045 A a;
3046 if(y is String) {
3047 a.x = y;
3048 }
3049 }''');
3050 computeLibrarySourceErrors(source);
3051 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
3052 verify([source]);
3053 }
3054
3055 void test_invalidAssignment_localVariable() {
3056 Source source = addSource(r'''
3057 f(var y) {
3058 if(y is String) {
3059 int x = y;
3060 }
3061 }''');
3062 computeLibrarySourceErrors(source);
3063 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
3064 verify([source]);
3065 }
3066
3067 void test_invalidAssignment_message() {
3068 // The implementation of HintCode.INVALID_ASSIGNMENT assumes that
3069 // StaticTypeWarningCode.INVALID_ASSIGNMENT has the same message.
3070 expect(StaticTypeWarningCode.INVALID_ASSIGNMENT.message,
3071 HintCode.INVALID_ASSIGNMENT.message);
3072 }
3073
3074 void test_invalidAssignment_staticVariable() {
3075 Source source = addSource(r'''
3076 class A {
3077 static int x;
3078 }
3079 f(var y) {
3080 if(y is String) {
3081 A.x = y;
3082 }
3083 }''');
3084 computeLibrarySourceErrors(source);
3085 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
3086 verify([source]);
3087 }
3088
3089 void test_invalidAssignment_variableDeclaration() {
3090 // 17971
3091 Source source = addSource(r'''
3092 class Point {
3093 final num x, y;
3094 Point(this.x, this.y);
3095 Point operator +(Point other) {
3096 return new Point(x+other.x, y+other.y);
3097 }
3098 }
3099 main() {
3100 var p1 = new Point(0, 0);
3101 var p2 = new Point(10, 10);
3102 int n = p1 + p2;
3103 }''');
3104 computeLibrarySourceErrors(source);
3105 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
3106 verify([source]);
3107 }
3108
3109 void test_isDouble() {
3110 AnalysisOptionsImpl options = new AnalysisOptionsImpl();
3111 options.dart2jsHint = true;
3112 resetWithOptions(options);
3113 Source source = addSource("var v = 1 is double;");
3114 computeLibrarySourceErrors(source);
3115 assertErrors(source, [HintCode.IS_DOUBLE]);
3116 verify([source]);
3117 }
3118
3119 void test_isNotDouble() {
3120 AnalysisOptionsImpl options = new AnalysisOptionsImpl();
3121 options.dart2jsHint = true;
3122 resetWithOptions(options);
3123 Source source = addSource("var v = 1 is! double;");
3124 computeLibrarySourceErrors(source);
3125 assertErrors(source, [HintCode.IS_NOT_DOUBLE]);
3126 verify([source]);
3127 }
3128
3129 void test_missingReturn_async() {
3130 Source source = addSource('''
3131 import 'dart:async';
3132 Future<int> f() async {}
3133 ''');
3134 computeLibrarySourceErrors(source);
3135 assertErrors(source, [HintCode.MISSING_RETURN]);
3136 verify([source]);
3137 }
3138
3139 void test_missingReturn_function() {
3140 Source source = addSource("int f() {}");
3141 computeLibrarySourceErrors(source);
3142 assertErrors(source, [HintCode.MISSING_RETURN]);
3143 verify([source]);
3144 }
3145
3146 void test_missingReturn_method() {
3147 Source source = addSource(r'''
3148 class A {
3149 int m() {}
3150 }''');
3151 computeLibrarySourceErrors(source);
3152 assertErrors(source, [HintCode.MISSING_RETURN]);
3153 verify([source]);
3154 }
3155
3156 void test_overrideOnNonOverridingGetter_invalid() {
3157 Source source = addSource(r'''
3158 library dart.core;
3159 const override = null;
3160 class A {
3161 }
3162 class B extends A {
3163 @override
3164 int get m => 1;
3165 }''');
3166 computeLibrarySourceErrors(source);
3167 assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER]);
3168 verify([source]);
3169 }
3170
3171 void test_overrideOnNonOverridingMethod_invalid() {
3172 Source source = addSource(r'''
3173 library dart.core;
3174 const override = null;
3175 class A {
3176 }
3177 class B extends A {
3178 @override
3179 int m() => 1;
3180 }''');
3181 computeLibrarySourceErrors(source);
3182 assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]);
3183 verify([source]);
3184 }
3185
3186 void test_overrideOnNonOverridingSetter_invalid() {
3187 Source source = addSource(r'''
3188 library dart.core;
3189 const override = null;
3190 class A {
3191 }
3192 class B extends A {
3193 @override
3194 set m(int x) {}
3195 }''');
3196 computeLibrarySourceErrors(source);
3197 assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER]);
3198 verify([source]);
3199 }
3200
3201 void test_typeCheck_type_is_Null() {
3202 Source source = addSource(r'''
3203 m(i) {
3204 bool b = i is Null;
3205 }''');
3206 computeLibrarySourceErrors(source);
3207 assertErrors(source, [HintCode.TYPE_CHECK_IS_NULL]);
3208 verify([source]);
3209 }
3210
3211 void test_typeCheck_type_not_Null() {
3212 Source source = addSource(r'''
3213 m(i) {
3214 bool b = i is! Null;
3215 }''');
3216 computeLibrarySourceErrors(source);
3217 assertErrors(source, [HintCode.TYPE_CHECK_IS_NOT_NULL]);
3218 verify([source]);
3219 }
3220
3221 void test_undefinedGetter() {
3222 Source source = addSource(r'''
3223 class A {}
3224 f(var a) {
3225 if(a is A) {
3226 return a.m;
3227 }
3228 }''');
3229 computeLibrarySourceErrors(source);
3230 assertErrors(source, [HintCode.UNDEFINED_GETTER]);
3231 }
3232
3233 void test_undefinedGetter_message() {
3234 // The implementation of HintCode.UNDEFINED_SETTER assumes that
3235 // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the
3236 // same, this verifies that assumption.
3237 expect(StaticWarningCode.UNDEFINED_GETTER.message,
3238 StaticTypeWarningCode.UNDEFINED_GETTER.message);
3239 }
3240
3241 void test_undefinedMethod() {
3242 Source source = addSource(r'''
3243 f() {
3244 var a = 'str';
3245 a.notAMethodOnString();
3246 }''');
3247 computeLibrarySourceErrors(source);
3248 assertErrors(source, [HintCode.UNDEFINED_METHOD]);
3249 }
3250
3251 void test_undefinedMethod_assignmentExpression() {
3252 Source source = addSource(r'''
3253 class A {}
3254 class B {
3255 f(var a, var a2) {
3256 a = new A();
3257 a2 = new A();
3258 a += a2;
3259 }
3260 }''');
3261 computeLibrarySourceErrors(source);
3262 assertErrors(source, [HintCode.UNDEFINED_METHOD]);
3263 }
3264
3265 void test_undefinedOperator_binaryExpression() {
3266 Source source = addSource(r'''
3267 class A {}
3268 f(var a) {
3269 if(a is A) {
3270 a + 1;
3271 }
3272 }''');
3273 computeLibrarySourceErrors(source);
3274 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
3275 }
3276
3277 void test_undefinedOperator_indexBoth() {
3278 Source source = addSource(r'''
3279 class A {}
3280 f(var a) {
3281 if(a is A) {
3282 a[0]++;
3283 }
3284 }''');
3285 computeLibrarySourceErrors(source);
3286 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
3287 }
3288
3289 void test_undefinedOperator_indexGetter() {
3290 Source source = addSource(r'''
3291 class A {}
3292 f(var a) {
3293 if(a is A) {
3294 a[0];
3295 }
3296 }''');
3297 computeLibrarySourceErrors(source);
3298 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
3299 }
3300
3301 void test_undefinedOperator_indexSetter() {
3302 Source source = addSource(r'''
3303 class A {}
3304 f(var a) {
3305 if(a is A) {
3306 a[0] = 1;
3307 }
3308 }''');
3309 computeLibrarySourceErrors(source);
3310 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
3311 }
3312
3313 void test_undefinedOperator_postfixExpression() {
3314 Source source = addSource(r'''
3315 class A {}
3316 f(var a) {
3317 if(a is A) {
3318 a++;
3319 }
3320 }''');
3321 computeLibrarySourceErrors(source);
3322 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
3323 }
3324
3325 void test_undefinedOperator_prefixExpression() {
3326 Source source = addSource(r'''
3327 class A {}
3328 f(var a) {
3329 if(a is A) {
3330 ++a;
3331 }
3332 }''');
3333 computeLibrarySourceErrors(source);
3334 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
3335 }
3336
3337 void test_undefinedSetter() {
3338 Source source = addSource(r'''
3339 class A {}
3340 f(var a) {
3341 if(a is A) {
3342 a.m = 0;
3343 }
3344 }''');
3345 computeLibrarySourceErrors(source);
3346 assertErrors(source, [HintCode.UNDEFINED_SETTER]);
3347 }
3348
3349 void test_undefinedSetter_message() {
3350 // The implementation of HintCode.UNDEFINED_SETTER assumes that
3351 // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the
3352 // same, this verifies that assumption.
3353 expect(StaticWarningCode.UNDEFINED_SETTER.message,
3354 StaticTypeWarningCode.UNDEFINED_SETTER.message);
3355 }
3356
3357 void test_unnecessaryCast_type_supertype() {
3358 Source source = addSource(r'''
3359 m(int i) {
3360 var b = i as Object;
3361 }''');
3362 computeLibrarySourceErrors(source);
3363 assertErrors(source, [HintCode.UNNECESSARY_CAST]);
3364 verify([source]);
3365 }
3366
3367 void test_unnecessaryCast_type_type() {
3368 Source source = addSource(r'''
3369 m(num i) {
3370 var b = i as num;
3371 }''');
3372 computeLibrarySourceErrors(source);
3373 assertErrors(source, [HintCode.UNNECESSARY_CAST]);
3374 verify([source]);
3375 }
3376
3377 void test_unnecessaryTypeCheck_null_is_Null() {
3378 Source source = addSource("bool b = null is Null;");
3379 computeLibrarySourceErrors(source);
3380 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
3381 verify([source]);
3382 }
3383
3384 void test_unnecessaryTypeCheck_null_not_Null() {
3385 Source source = addSource("bool b = null is! Null;");
3386 computeLibrarySourceErrors(source);
3387 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
3388 verify([source]);
3389 }
3390
3391 void test_unnecessaryTypeCheck_type_is_dynamic() {
3392 Source source = addSource(r'''
3393 m(i) {
3394 bool b = i is dynamic;
3395 }''');
3396 computeLibrarySourceErrors(source);
3397 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
3398 verify([source]);
3399 }
3400
3401 void test_unnecessaryTypeCheck_type_is_object() {
3402 Source source = addSource(r'''
3403 m(i) {
3404 bool b = i is Object;
3405 }''');
3406 computeLibrarySourceErrors(source);
3407 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
3408 verify([source]);
3409 }
3410
3411 void test_unnecessaryTypeCheck_type_not_dynamic() {
3412 Source source = addSource(r'''
3413 m(i) {
3414 bool b = i is! dynamic;
3415 }''');
3416 computeLibrarySourceErrors(source);
3417 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
3418 verify([source]);
3419 }
3420
3421 void test_unnecessaryTypeCheck_type_not_object() {
3422 Source source = addSource(r'''
3423 m(i) {
3424 bool b = i is! Object;
3425 }''');
3426 computeLibrarySourceErrors(source);
3427 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
3428 verify([source]);
3429 }
3430
3431 void test_unusedElement_class_isUsed_extends() {
3432 enableUnusedElement = true;
3433 Source source = addSource(r'''
3434 class _A {}
3435 class B extends _A {}
3436 ''');
3437 computeLibrarySourceErrors(source);
3438 assertNoErrors(source);
3439 verify([source]);
3440 }
3441
3442 void test_unusedElement_class_isUsed_implements() {
3443 enableUnusedElement = true;
3444 Source source = addSource(r'''
3445 class _A {}
3446 class B implements _A {}
3447 ''');
3448 computeLibrarySourceErrors(source);
3449 assertNoErrors(source);
3450 verify([source]);
3451 }
3452
3453 void test_unusedElement_class_isUsed_instanceCreation() {
3454 enableUnusedElement = true;
3455 Source source = addSource(r'''
3456 class _A {}
3457 main() {
3458 new _A();
3459 }''');
3460 computeLibrarySourceErrors(source);
3461 assertNoErrors(source);
3462 verify([source]);
3463 }
3464
3465 void test_unusedElement_class_isUsed_staticFieldAccess() {
3466 enableUnusedElement = true;
3467 Source source = addSource(r'''
3468 class _A {
3469 static const F = 42;
3470 }
3471 main() {
3472 _A.F;
3473 }''');
3474 computeLibrarySourceErrors(source);
3475 assertNoErrors(source);
3476 verify([source]);
3477 }
3478
3479 void test_unusedElement_class_isUsed_staticMethodInvocation() {
3480 enableUnusedElement = true;
3481 Source source = addSource(r'''
3482 class _A {
3483 static m() {}
3484 }
3485 main() {
3486 _A.m();
3487 }''');
3488 computeLibrarySourceErrors(source);
3489 assertNoErrors(source);
3490 verify([source]);
3491 }
3492
3493 void test_unusedElement_class_isUsed_typeArgument() {
3494 enableUnusedElement = true;
3495 Source source = addSource(r'''
3496 class _A {}
3497 main() {
3498 var v = new List<_A>();
3499 print(v);
3500 }''');
3501 computeLibrarySourceErrors(source);
3502 assertNoErrors(source);
3503 verify([source]);
3504 }
3505
3506 void test_unusedElement_class_notUsed_inClassMember() {
3507 enableUnusedElement = true;
3508 Source source = addSource(r'''
3509 class _A {
3510 static staticMethod() {
3511 new _A();
3512 }
3513 instanceMethod() {
3514 new _A();
3515 }
3516 }
3517 ''');
3518 computeLibrarySourceErrors(source);
3519 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3520 verify([source]);
3521 }
3522
3523 void test_unusedElement_class_notUsed_inConstructorName() {
3524 enableUnusedElement = true;
3525 Source source = addSource(r'''
3526 class _A {
3527 _A() {}
3528 _A.named() {}
3529 }
3530 ''');
3531 computeLibrarySourceErrors(source);
3532 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3533 verify([source]);
3534 }
3535
3536 void test_unusedElement_class_notUsed_isExpression() {
3537 enableUnusedElement = true;
3538 Source source = addSource(r'''
3539 class _A {}
3540 main(p) {
3541 if (p is _A) {
3542 }
3543 }
3544 ''');
3545 computeLibrarySourceErrors(source);
3546 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3547 verify([source]);
3548 }
3549
3550 void test_unusedElement_class_notUsed_noReference() {
3551 enableUnusedElement = true;
3552 Source source = addSource(r'''
3553 class _A {}
3554 main() {
3555 }''');
3556 computeLibrarySourceErrors(source);
3557 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3558 verify([source]);
3559 }
3560
3561 void test_unusedElement_class_notUsed_variableDeclaration() {
3562 enableUnusedElement = true;
3563 Source source = addSource(r'''
3564 class _A {}
3565 main() {
3566 _A v;
3567 print(v);
3568 }
3569 print(x) {}
3570 ''');
3571 computeLibrarySourceErrors(source);
3572 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3573 verify([source]);
3574 }
3575
3576 void test_unusedElement_enum_isUsed_fieldReference() {
3577 enableUnusedElement = true;
3578 Source source = addSource(r'''
3579 enum _MyEnum {A, B, C}
3580 main() {
3581 print(_MyEnum.B);
3582 }''');
3583 computeLibrarySourceErrors(source);
3584 assertNoErrors(source);
3585 verify([source]);
3586 }
3587
3588 void test_unusedElement_enum_notUsed_noReference() {
3589 enableUnusedElement = true;
3590 Source source = addSource(r'''
3591 enum _MyEnum {A, B, C}
3592 main() {
3593 }''');
3594 computeLibrarySourceErrors(source);
3595 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3596 verify([source]);
3597 }
3598
3599 void test_unusedElement_functionLocal_isUsed_closure() {
3600 enableUnusedElement = true;
3601 Source source = addSource(r'''
3602 main() {
3603 print(() {});
3604 }
3605 print(x) {}
3606 ''');
3607 computeLibrarySourceErrors(source);
3608 assertNoErrors(source);
3609 verify([source]);
3610 }
3611
3612 void test_unusedElement_functionLocal_isUsed_invocation() {
3613 enableUnusedElement = true;
3614 Source source = addSource(r'''
3615 main() {
3616 f() {}
3617 f();
3618 }''');
3619 computeLibrarySourceErrors(source);
3620 assertNoErrors(source);
3621 verify([source]);
3622 }
3623
3624 void test_unusedElement_functionLocal_isUsed_reference() {
3625 enableUnusedElement = true;
3626 Source source = addSource(r'''
3627 main() {
3628 f() {}
3629 print(f);
3630 }
3631 print(x) {}
3632 ''');
3633 computeLibrarySourceErrors(source);
3634 assertNoErrors(source);
3635 verify([source]);
3636 }
3637
3638 void test_unusedElement_functionLocal_notUsed_noReference() {
3639 enableUnusedElement = true;
3640 Source source = addSource(r'''
3641 main() {
3642 f() {}
3643 }''');
3644 computeLibrarySourceErrors(source);
3645 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3646 verify([source]);
3647 }
3648
3649 void test_unusedElement_functionLocal_notUsed_referenceFromItself() {
3650 enableUnusedElement = true;
3651 Source source = addSource(r'''
3652 main() {
3653 _f(int p) {
3654 _f(p - 1);
3655 }
3656 }''');
3657 computeLibrarySourceErrors(source);
3658 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3659 verify([source]);
3660 }
3661
3662 void test_unusedElement_functionTop_isUsed_invocation() {
3663 enableUnusedElement = true;
3664 Source source = addSource(r'''
3665 _f() {}
3666 main() {
3667 _f();
3668 }''');
3669 computeLibrarySourceErrors(source);
3670 assertNoErrors(source);
3671 verify([source]);
3672 }
3673
3674 void test_unusedElement_functionTop_isUsed_reference() {
3675 enableUnusedElement = true;
3676 Source source = addSource(r'''
3677 _f() {}
3678 main() {
3679 print(_f);
3680 }
3681 print(x) {}
3682 ''');
3683 computeLibrarySourceErrors(source);
3684 assertNoErrors(source);
3685 verify([source]);
3686 }
3687
3688 void test_unusedElement_functionTop_notUsed_noReference() {
3689 enableUnusedElement = true;
3690 Source source = addSource(r'''
3691 _f() {}
3692 main() {
3693 }''');
3694 computeLibrarySourceErrors(source);
3695 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3696 verify([source]);
3697 }
3698
3699 void test_unusedElement_functionTop_notUsed_referenceFromItself() {
3700 enableUnusedElement = true;
3701 Source source = addSource(r'''
3702 _f(int p) {
3703 _f(p - 1);
3704 }
3705 main() {
3706 }''');
3707 computeLibrarySourceErrors(source);
3708 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3709 verify([source]);
3710 }
3711
3712 void test_unusedElement_functionTypeAlias_isUsed_isExpression() {
3713 enableUnusedElement = true;
3714 Source source = addSource(r'''
3715 typedef _F(a, b);
3716 main(f) {
3717 if (f is _F) {
3718 print('F');
3719 }
3720 }''');
3721 computeLibrarySourceErrors(source);
3722 assertNoErrors(source);
3723 verify([source]);
3724 }
3725
3726 void test_unusedElement_functionTypeAlias_isUsed_reference() {
3727 enableUnusedElement = true;
3728 Source source = addSource(r'''
3729 typedef _F(a, b);
3730 main(_F f) {
3731 }''');
3732 computeLibrarySourceErrors(source);
3733 assertNoErrors(source);
3734 verify([source]);
3735 }
3736
3737 void test_unusedElement_functionTypeAlias_isUsed_typeArgument() {
3738 enableUnusedElement = true;
3739 Source source = addSource(r'''
3740 typedef _F(a, b);
3741 main() {
3742 var v = new List<_F>();
3743 print(v);
3744 }''');
3745 computeLibrarySourceErrors(source);
3746 assertNoErrors(source);
3747 verify([source]);
3748 }
3749
3750 void test_unusedElement_functionTypeAlias_isUsed_variableDeclaration() {
3751 enableUnusedElement = true;
3752 Source source = addSource(r'''
3753 typedef _F(a, b);
3754 class A {
3755 _F f;
3756 }''');
3757 computeLibrarySourceErrors(source);
3758 assertNoErrors(source);
3759 verify([source]);
3760 }
3761
3762 void test_unusedElement_functionTypeAlias_notUsed_noReference() {
3763 enableUnusedElement = true;
3764 Source source = addSource(r'''
3765 typedef _F(a, b);
3766 main() {
3767 }''');
3768 computeLibrarySourceErrors(source);
3769 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3770 verify([source]);
3771 }
3772
3773 void test_unusedElement_getter_isUsed_invocation_implicitThis() {
3774 enableUnusedElement = true;
3775 Source source = addSource(r'''
3776 class A {
3777 get _g => null;
3778 useGetter() {
3779 var v = _g;
3780 }
3781 }''');
3782 computeLibrarySourceErrors(source);
3783 assertNoErrors(source);
3784 verify([source]);
3785 }
3786
3787 void test_unusedElement_getter_isUsed_invocation_PrefixedIdentifier() {
3788 enableUnusedElement = true;
3789 Source source = addSource(r'''
3790 class A {
3791 get _g => null;
3792 }
3793 main(A a) {
3794 var v = a._g;
3795 }
3796 ''');
3797 computeLibrarySourceErrors(source);
3798 assertNoErrors(source);
3799 verify([source]);
3800 }
3801
3802 void test_unusedElement_getter_isUsed_invocation_PropertyAccess() {
3803 enableUnusedElement = true;
3804 Source source = addSource(r'''
3805 class A {
3806 get _g => null;
3807 }
3808 main() {
3809 var v = new A()._g;
3810 }
3811 ''');
3812 computeLibrarySourceErrors(source);
3813 assertNoErrors(source);
3814 verify([source]);
3815 }
3816
3817 void test_unusedElement_getter_notUsed_noReference() {
3818 enableUnusedElement = true;
3819 Source source = addSource(r'''
3820 class A {
3821 get _g => null;
3822 }''');
3823 computeLibrarySourceErrors(source);
3824 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3825 verify([source]);
3826 }
3827
3828 void test_unusedElement_getter_notUsed_referenceFromItself() {
3829 enableUnusedElement = true;
3830 Source source = addSource(r'''
3831 class A {
3832 get _g {
3833 return _g;
3834 }
3835 }''');
3836 computeLibrarySourceErrors(source);
3837 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3838 verify([source]);
3839 }
3840
3841 void test_unusedElement_method_isUsed_hasReference_implicitThis() {
3842 enableUnusedElement = true;
3843 Source source = addSource(r'''
3844 class A {
3845 _m() {}
3846 useMethod() {
3847 print(_m);
3848 }
3849 }
3850 print(x) {}
3851 ''');
3852 computeLibrarySourceErrors(source);
3853 assertNoErrors(source);
3854 verify([source]);
3855 }
3856
3857 void test_unusedElement_method_isUsed_hasReference_implicitThis_subclass() {
3858 enableUnusedElement = true;
3859 Source source = addSource(r'''
3860 class A {
3861 _m() {}
3862 useMethod() {
3863 print(_m);
3864 }
3865 }
3866 class B extends A {
3867 _m() {}
3868 }
3869 print(x) {}
3870 ''');
3871 computeLibrarySourceErrors(source);
3872 assertNoErrors(source);
3873 verify([source]);
3874 }
3875
3876 void test_unusedElement_method_isUsed_hasReference_PrefixedIdentifier() {
3877 enableUnusedElement = true;
3878 Source source = addSource(r'''
3879 class A {
3880 _m() {}
3881 }
3882 main(A a) {
3883 a._m;
3884 }''');
3885 computeLibrarySourceErrors(source);
3886 assertNoErrors(source);
3887 verify([source]);
3888 }
3889
3890 void test_unusedElement_method_isUsed_hasReference_PropertyAccess() {
3891 enableUnusedElement = true;
3892 Source source = addSource(r'''
3893 class A {
3894 _m() {}
3895 }
3896 main() {
3897 new A()._m;
3898 }''');
3899 computeLibrarySourceErrors(source);
3900 assertNoErrors(source);
3901 verify([source]);
3902 }
3903
3904 void test_unusedElement_method_isUsed_invocation_implicitThis() {
3905 enableUnusedElement = true;
3906 Source source = addSource(r'''
3907 class A {
3908 _m() {}
3909 useMethod() {
3910 _m();
3911 }
3912 }''');
3913 computeLibrarySourceErrors(source);
3914 assertNoErrors(source);
3915 verify([source]);
3916 }
3917
3918 void test_unusedElement_method_isUsed_invocation_implicitThis_subclass() {
3919 enableUnusedElement = true;
3920 Source source = addSource(r'''
3921 class A {
3922 _m() {}
3923 useMethod() {
3924 _m();
3925 }
3926 }
3927 class B extends A {
3928 _m() {}
3929 }''');
3930 computeLibrarySourceErrors(source);
3931 assertNoErrors(source);
3932 verify([source]);
3933 }
3934
3935 void test_unusedElement_method_isUsed_invocation_MemberElement() {
3936 enableUnusedElement = true;
3937 Source source = addSource(r'''
3938 class A<T> {
3939 _m(T t) {}
3940 }
3941 main(A<int> a) {
3942 a._m(0);
3943 }''');
3944 computeLibrarySourceErrors(source);
3945 assertNoErrors(source);
3946 verify([source]);
3947 }
3948
3949 void test_unusedElement_method_isUsed_invocation_propagated() {
3950 enableUnusedElement = true;
3951 Source source = addSource(r'''
3952 class A {
3953 _m() {}
3954 }
3955 main() {
3956 var a = new A();
3957 a._m();
3958 }''');
3959 computeLibrarySourceErrors(source);
3960 assertNoErrors(source);
3961 verify([source]);
3962 }
3963
3964 void test_unusedElement_method_isUsed_invocation_static() {
3965 enableUnusedElement = true;
3966 Source source = addSource(r'''
3967 class A {
3968 _m() {}
3969 }
3970 main() {
3971 A a = new A();
3972 a._m();
3973 }''');
3974 computeLibrarySourceErrors(source);
3975 assertNoErrors(source);
3976 verify([source]);
3977 }
3978
3979 void test_unusedElement_method_isUsed_invocation_subclass() {
3980 enableUnusedElement = true;
3981 Source source = addSource(r'''
3982 class A {
3983 _m() {}
3984 }
3985 class B extends A {
3986 _m() {}
3987 }
3988 main(A a) {
3989 a._m();
3990 }''');
3991 computeLibrarySourceErrors(source);
3992 assertNoErrors(source);
3993 verify([source]);
3994 }
3995
3996 void test_unusedElement_method_isUsed_notPrivate() {
3997 enableUnusedElement = true;
3998 Source source = addSource(r'''
3999 class A {
4000 m() {}
4001 }
4002 main() {
4003 }''');
4004 computeLibrarySourceErrors(source);
4005 assertNoErrors(source);
4006 verify([source]);
4007 }
4008
4009 void test_unusedElement_method_isUsed_staticInvocation() {
4010 enableUnusedElement = true;
4011 Source source = addSource(r'''
4012 class A {
4013 static _m() {}
4014 }
4015 main() {
4016 A._m();
4017 }''');
4018 computeLibrarySourceErrors(source);
4019 assertNoErrors(source);
4020 verify([source]);
4021 }
4022
4023 void test_unusedElement_method_notUsed_noReference() {
4024 enableUnusedElement = true;
4025 Source source = addSource(r'''
4026 class A {
4027 static _m() {}
4028 }''');
4029 computeLibrarySourceErrors(source);
4030 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
4031 verify([source]);
4032 }
4033
4034 void test_unusedElement_method_notUsed_referenceFromItself() {
4035 enableUnusedElement = true;
4036 Source source = addSource(r'''
4037 class A {
4038 static _m(int p) {
4039 _m(p - 1);
4040 }
4041 }''');
4042 computeLibrarySourceErrors(source);
4043 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
4044 verify([source]);
4045 }
4046
4047 void test_unusedElement_setter_isUsed_invocation_implicitThis() {
4048 enableUnusedElement = true;
4049 Source source = addSource(r'''
4050 class A {
4051 set _s(x) {}
4052 useSetter() {
4053 _s = 42;
4054 }
4055 }''');
4056 computeLibrarySourceErrors(source);
4057 assertNoErrors(source);
4058 verify([source]);
4059 }
4060
4061 void test_unusedElement_setter_isUsed_invocation_PrefixedIdentifier() {
4062 enableUnusedElement = true;
4063 Source source = addSource(r'''
4064 class A {
4065 set _s(x) {}
4066 }
4067 main(A a) {
4068 a._s = 42;
4069 }
4070 ''');
4071 computeLibrarySourceErrors(source);
4072 assertNoErrors(source);
4073 verify([source]);
4074 }
4075
4076 void test_unusedElement_setter_isUsed_invocation_PropertyAccess() {
4077 enableUnusedElement = true;
4078 Source source = addSource(r'''
4079 class A {
4080 set _s(x) {}
4081 }
4082 main() {
4083 new A()._s = 42;
4084 }
4085 ''');
4086 computeLibrarySourceErrors(source);
4087 assertNoErrors(source);
4088 verify([source]);
4089 }
4090
4091 void test_unusedElement_setter_notUsed_noReference() {
4092 enableUnusedElement = true;
4093 Source source = addSource(r'''
4094 class A {
4095 set _s(x) {}
4096 }''');
4097 computeLibrarySourceErrors(source);
4098 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
4099 verify([source]);
4100 }
4101
4102 void test_unusedElement_setter_notUsed_referenceFromItself() {
4103 enableUnusedElement = true;
4104 Source source = addSource(r'''
4105 class A {
4106 set _s(int x) {
4107 if (x > 5) {
4108 _s = x - 1;
4109 }
4110 }
4111 }''');
4112 computeLibrarySourceErrors(source);
4113 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
4114 verify([source]);
4115 }
4116
4117 void test_unusedField_isUsed_argument() {
4118 enableUnusedElement = true;
4119 Source source = addSource(r'''
4120 class A {
4121 int _f = 0;
4122 main() {
4123 print(++_f);
4124 }
4125 }
4126 print(x) {}''');
4127 computeLibrarySourceErrors(source);
4128 assertErrors(source);
4129 verify([source]);
4130 }
4131
4132 void test_unusedField_isUsed_reference_implicitThis() {
4133 enableUnusedElement = true;
4134 Source source = addSource(r'''
4135 class A {
4136 int _f;
4137 main() {
4138 print(_f);
4139 }
4140 }
4141 print(x) {}''');
4142 computeLibrarySourceErrors(source);
4143 assertErrors(source);
4144 verify([source]);
4145 }
4146
4147 void test_unusedField_isUsed_reference_implicitThis_expressionFunctionBody() {
4148 enableUnusedElement = true;
4149 Source source = addSource(r'''
4150 class A {
4151 int _f;
4152 m() => _f;
4153 }''');
4154 computeLibrarySourceErrors(source);
4155 assertErrors(source);
4156 verify([source]);
4157 }
4158
4159 void test_unusedField_isUsed_reference_implicitThis_subclass() {
4160 enableUnusedElement = true;
4161 Source source = addSource(r'''
4162 class A {
4163 int _f;
4164 main() {
4165 print(_f);
4166 }
4167 }
4168 class B extends A {
4169 int _f;
4170 }
4171 print(x) {}''');
4172 computeLibrarySourceErrors(source);
4173 assertErrors(source);
4174 verify([source]);
4175 }
4176
4177 void test_unusedField_isUsed_reference_qualified_propagatedElement() {
4178 enableUnusedElement = true;
4179 Source source = addSource(r'''
4180 class A {
4181 int _f;
4182 }
4183 main() {
4184 var a = new A();
4185 print(a._f);
4186 }
4187 print(x) {}''');
4188 computeLibrarySourceErrors(source);
4189 assertErrors(source);
4190 verify([source]);
4191 }
4192
4193 void test_unusedField_isUsed_reference_qualified_staticElement() {
4194 enableUnusedElement = true;
4195 Source source = addSource(r'''
4196 class A {
4197 int _f;
4198 }
4199 main() {
4200 A a = new A();
4201 print(a._f);
4202 }
4203 print(x) {}''');
4204 computeLibrarySourceErrors(source);
4205 assertErrors(source);
4206 verify([source]);
4207 }
4208
4209 void test_unusedField_isUsed_reference_qualified_unresolved() {
4210 enableUnusedElement = true;
4211 Source source = addSource(r'''
4212 class A {
4213 int _f;
4214 }
4215 main(a) {
4216 print(a._f);
4217 }
4218 print(x) {}''');
4219 computeLibrarySourceErrors(source);
4220 assertErrors(source);
4221 verify([source]);
4222 }
4223
4224 void test_unusedField_notUsed_compoundAssign() {
4225 enableUnusedElement = true;
4226 Source source = addSource(r'''
4227 class A {
4228 int _f;
4229 main() {
4230 _f += 2;
4231 }
4232 }''');
4233 computeLibrarySourceErrors(source);
4234 assertErrors(source, [HintCode.UNUSED_FIELD]);
4235 verify([source]);
4236 }
4237
4238 void test_unusedField_notUsed_noReference() {
4239 enableUnusedElement = true;
4240 Source source = addSource(r'''
4241 class A {
4242 int _f;
4243 }
4244 ''');
4245 computeLibrarySourceErrors(source);
4246 assertErrors(source, [HintCode.UNUSED_FIELD]);
4247 verify([source]);
4248 }
4249
4250 void test_unusedField_notUsed_postfixExpr() {
4251 enableUnusedElement = true;
4252 Source source = addSource(r'''
4253 class A {
4254 int _f = 0;
4255 main() {
4256 _f++;
4257 }
4258 }''');
4259 computeLibrarySourceErrors(source);
4260 assertErrors(source, [HintCode.UNUSED_FIELD]);
4261 verify([source]);
4262 }
4263
4264 void test_unusedField_notUsed_prefixExpr() {
4265 enableUnusedElement = true;
4266 Source source = addSource(r'''
4267 class A {
4268 int _f = 0;
4269 main() {
4270 ++_f;
4271 }
4272 }''');
4273 computeLibrarySourceErrors(source);
4274 assertErrors(source, [HintCode.UNUSED_FIELD]);
4275 verify([source]);
4276 }
4277
4278 void test_unusedField_notUsed_simpleAssignment() {
4279 enableUnusedElement = true;
4280 Source source = addSource(r'''
4281 class A {
4282 int _f;
4283 m() {
4284 _f = 1;
4285 }
4286 }
4287 main(A a) {
4288 a._f = 2;
4289 }
4290 ''');
4291 computeLibrarySourceErrors(source);
4292 assertErrors(source, [HintCode.UNUSED_FIELD]);
4293 verify([source]);
4294 }
4295
4296 void test_unusedImport() {
4297 Source source = addSource(r'''
4298 library L;
4299 import 'lib1.dart';''');
4300 Source source2 = addNamedSource("/lib1.dart", "library lib1;");
4301 computeLibrarySourceErrors(source);
4302 assertErrors(source, [HintCode.UNUSED_IMPORT]);
4303 assertNoErrors(source2);
4304 verify([source, source2]);
4305 }
4306
4307 void test_unusedImport_as() {
4308 Source source = addSource(r'''
4309 library L;
4310 import 'lib1.dart';
4311 import 'lib1.dart' as one;
4312 one.A a;''');
4313 Source source2 = addNamedSource(
4314 "/lib1.dart",
4315 r'''
4316 library lib1;
4317 class A {}''');
4318 computeLibrarySourceErrors(source);
4319 assertErrors(source, [HintCode.UNUSED_IMPORT]);
4320 assertNoErrors(source2);
4321 verify([source, source2]);
4322 }
4323
4324 void test_unusedImport_hide() {
4325 Source source = addSource(r'''
4326 library L;
4327 import 'lib1.dart';
4328 import 'lib1.dart' hide A;
4329 A a;''');
4330 Source source2 = addNamedSource(
4331 "/lib1.dart",
4332 r'''
4333 library lib1;
4334 class A {}''');
4335 computeLibrarySourceErrors(source);
4336 assertErrors(source, [HintCode.UNUSED_IMPORT]);
4337 assertNoErrors(source2);
4338 verify([source, source2]);
4339 }
4340
4341 void test_unusedImport_show() {
4342 Source source = addSource(r'''
4343 library L;
4344 import 'lib1.dart' show A;
4345 import 'lib1.dart' show B;
4346 A a;''');
4347 Source source2 = addNamedSource(
4348 "/lib1.dart",
4349 r'''
4350 library lib1;
4351 class A {}
4352 class B {}''');
4353 computeLibrarySourceErrors(source);
4354 assertErrors(source, [HintCode.UNUSED_IMPORT]);
4355 assertNoErrors(source2);
4356 verify([source, source2]);
4357 }
4358
4359 void test_unusedLocalVariable_inCatch_exception() {
4360 enableUnusedLocalVariable = true;
4361 Source source = addSource(r'''
4362 main() {
4363 try {
4364 } on String catch (exception) {
4365 }
4366 }''');
4367 computeLibrarySourceErrors(source);
4368 assertErrors(source, [HintCode.UNUSED_CATCH_CLAUSE]);
4369 verify([source]);
4370 }
4371
4372 void test_unusedLocalVariable_inCatch_exception_hasStack() {
4373 enableUnusedLocalVariable = true;
4374 Source source = addSource(r'''
4375 main() {
4376 try {
4377 } catch (exception, stack) {
4378 print(stack);
4379 }
4380 }''');
4381 computeLibrarySourceErrors(source);
4382 assertNoErrors(source);
4383 verify([source]);
4384 }
4385
4386 void test_unusedLocalVariable_inCatch_exception_noOnClause() {
4387 enableUnusedLocalVariable = true;
4388 Source source = addSource(r'''
4389 main() {
4390 try {
4391 } catch (exception) {
4392 }
4393 }''');
4394 computeLibrarySourceErrors(source);
4395 assertNoErrors(source);
4396 verify([source]);
4397 }
4398
4399 void test_unusedLocalVariable_inCatch_stackTrace() {
4400 enableUnusedLocalVariable = true;
4401 Source source = addSource(r'''
4402 main() {
4403 try {
4404 } catch (exception, stackTrace) {
4405 }
4406 }''');
4407 computeLibrarySourceErrors(source);
4408 assertErrors(source, [HintCode.UNUSED_CATCH_STACK]);
4409 verify([source]);
4410 }
4411
4412 void test_unusedLocalVariable_inCatch_stackTrace_used() {
4413 enableUnusedLocalVariable = true;
4414 Source source = addSource(r'''
4415 main() {
4416 try {
4417 } catch (exception, stackTrace) {
4418 print('exception at $stackTrace');
4419 }
4420 }
4421 print(x) {}''');
4422 computeLibrarySourceErrors(source);
4423 assertErrors(source);
4424 verify([source]);
4425 }
4426
4427 void test_unusedLocalVariable_inFor_underscore_ignored() {
4428 enableUnusedLocalVariable = true;
4429 Source source = addSource(r'''
4430 main() {
4431 for (var _ in [1,2,3]) {
4432 for (var __ in [4,5,6]) {
4433 // do something
4434 }
4435 }
4436 }''');
4437 computeLibrarySourceErrors(source);
4438 assertErrors(source);
4439 verify([source]);
4440 }
4441
4442 void test_unusedLocalVariable_inFunction() {
4443 enableUnusedLocalVariable = true;
4444 Source source = addSource(r'''
4445 main() {
4446 var v = 1;
4447 v = 2;
4448 }''');
4449 computeLibrarySourceErrors(source);
4450 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
4451 verify([source]);
4452 }
4453
4454 void test_unusedLocalVariable_inMethod() {
4455 enableUnusedLocalVariable = true;
4456 Source source = addSource(r'''
4457 class A {
4458 foo() {
4459 var v = 1;
4460 v = 2;
4461 }
4462 }''');
4463 computeLibrarySourceErrors(source);
4464 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
4465 verify([source]);
4466 }
4467
4468 void test_unusedLocalVariable_isInvoked() {
4469 enableUnusedLocalVariable = true;
4470 Source source = addSource(r'''
4471 typedef Foo();
4472 main() {
4473 Foo foo;
4474 foo();
4475 }''');
4476 computeLibrarySourceErrors(source);
4477 assertErrors(source);
4478 verify([source]);
4479 }
4480
4481 void test_unusedLocalVariable_isRead_notUsed_compoundAssign() {
4482 enableUnusedLocalVariable = true;
4483 Source source = addSource(r'''
4484 main() {
4485 var v = 1;
4486 v += 2;
4487 }''');
4488 computeLibrarySourceErrors(source);
4489 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
4490 verify([source]);
4491 }
4492
4493 void test_unusedLocalVariable_isRead_notUsed_postfixExpr() {
4494 enableUnusedLocalVariable = true;
4495 Source source = addSource(r'''
4496 main() {
4497 var v = 1;
4498 v++;
4499 }''');
4500 computeLibrarySourceErrors(source);
4501 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
4502 verify([source]);
4503 }
4504
4505 void test_unusedLocalVariable_isRead_notUsed_prefixExpr() {
4506 enableUnusedLocalVariable = true;
4507 Source source = addSource(r'''
4508 main() {
4509 var v = 1;
4510 ++v;
4511 }''');
4512 computeLibrarySourceErrors(source);
4513 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
4514 verify([source]);
4515 }
4516
4517 void test_unusedLocalVariable_isRead_usedArgument() {
4518 enableUnusedLocalVariable = true;
4519 Source source = addSource(r'''
4520 main() {
4521 var v = 1;
4522 print(++v);
4523 }
4524 print(x) {}''');
4525 computeLibrarySourceErrors(source);
4526 assertErrors(source);
4527 verify([source]);
4528 }
4529
4530 void test_unusedLocalVariable_isRead_usedInvocationTarget() {
4531 enableUnusedLocalVariable = true;
4532 Source source = addSource(r'''
4533 class A {
4534 foo() {}
4535 }
4536 main() {
4537 var a = new A();
4538 a.foo();
4539 }
4540 ''');
4541 computeLibrarySourceErrors(source);
4542 assertErrors(source);
4543 verify([source]);
4544 }
4545
4546 void test_useOfVoidResult_assignmentExpression_function() {
4547 Source source = addSource(r'''
4548 void f() {}
4549 class A {
4550 n() {
4551 var a;
4552 a = f();
4553 }
4554 }''');
4555 computeLibrarySourceErrors(source);
4556 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
4557 verify([source]);
4558 }
4559
4560 void test_useOfVoidResult_assignmentExpression_method() {
4561 Source source = addSource(r'''
4562 class A {
4563 void m() {}
4564 n() {
4565 var a;
4566 a = m();
4567 }
4568 }''');
4569 computeLibrarySourceErrors(source);
4570 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
4571 verify([source]);
4572 }
4573
4574 void test_useOfVoidResult_inForLoop() {
4575 Source source = addSource(r'''
4576 class A {
4577 void m() {}
4578 n() {
4579 for(var a = m();;) {}
4580 }
4581 }''');
4582 computeLibrarySourceErrors(source);
4583 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
4584 verify([source]);
4585 }
4586
4587 void test_useOfVoidResult_variableDeclaration_function() {
4588 Source source = addSource(r'''
4589 void f() {}
4590 class A {
4591 n() {
4592 var a = f();
4593 }
4594 }''');
4595 computeLibrarySourceErrors(source);
4596 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
4597 verify([source]);
4598 }
4599
4600 void test_useOfVoidResult_variableDeclaration_method() {
4601 Source source = addSource(r'''
4602 class A {
4603 void m() {}
4604 n() {
4605 var a = m();
4606 }
4607 }''');
4608 computeLibrarySourceErrors(source);
4609 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
4610 verify([source]);
4611 }
4612
4613 void test_useOfVoidResult_variableDeclaration_method2() {
4614 Source source = addSource(r'''
4615 class A {
4616 void m() {}
4617 n() {
4618 var a = m(), b = m();
4619 }
4620 }''');
4621 computeLibrarySourceErrors(source);
4622 assertErrors(
4623 source, [HintCode.USE_OF_VOID_RESULT, HintCode.USE_OF_VOID_RESULT]);
4624 verify([source]);
4625 }
4626 }
4627
4628 @reflectiveTest
4629 class InheritanceManagerTest extends EngineTestCase {
4630 /**
4631 * The type provider used to access the types.
4632 */
4633 TestTypeProvider _typeProvider;
4634
4635 /**
4636 * The library containing the code being resolved.
4637 */
4638 LibraryElementImpl _definingLibrary;
4639
4640 /**
4641 * The inheritance manager being tested.
4642 */
4643 InheritanceManager _inheritanceManager;
4644
4645 /**
4646 * The number of members that Object implements (as determined by [TestTypePro vider]).
4647 */
4648 int _numOfMembersInObject = 0;
4649
4650 @override
4651 void setUp() {
4652 _typeProvider = new TestTypeProvider();
4653 _inheritanceManager = _createInheritanceManager();
4654 InterfaceType objectType = _typeProvider.objectType;
4655 _numOfMembersInObject =
4656 objectType.methods.length + objectType.accessors.length;
4657 }
4658
4659 void test_getMapOfMembersInheritedFromClasses_accessor_extends() {
4660 // class A { int get g; }
4661 // class B extends A {}
4662 ClassElementImpl classA = ElementFactory.classElement2("A");
4663 String getterName = "g";
4664 PropertyAccessorElement getterG =
4665 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
4666 classA.accessors = <PropertyAccessorElement>[getterG];
4667 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
4668 MemberMap mapB =
4669 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
4670 MemberMap mapA =
4671 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
4672 expect(mapA.size, _numOfMembersInObject);
4673 expect(mapB.size, _numOfMembersInObject + 1);
4674 expect(mapB.get(getterName), same(getterG));
4675 _assertNoErrors(classA);
4676 _assertNoErrors(classB);
4677 }
4678
4679 void test_getMapOfMembersInheritedFromClasses_accessor_implements() {
4680 // class A { int get g; }
4681 // class B implements A {}
4682 ClassElementImpl classA = ElementFactory.classElement2("A");
4683 String getterName = "g";
4684 PropertyAccessorElement getterG =
4685 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
4686 classA.accessors = <PropertyAccessorElement>[getterG];
4687 ClassElementImpl classB = ElementFactory.classElement2("B");
4688 classB.interfaces = <InterfaceType>[classA.type];
4689 MemberMap mapB =
4690 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
4691 MemberMap mapA =
4692 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
4693 expect(mapA.size, _numOfMembersInObject);
4694 expect(mapB.size, _numOfMembersInObject);
4695 expect(mapB.get(getterName), isNull);
4696 _assertNoErrors(classA);
4697 _assertNoErrors(classB);
4698 }
4699
4700 void test_getMapOfMembersInheritedFromClasses_accessor_with() {
4701 // class A { int get g; }
4702 // class B extends Object with A {}
4703 ClassElementImpl classA = ElementFactory.classElement2("A");
4704 String getterName = "g";
4705 PropertyAccessorElement getterG =
4706 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
4707 classA.accessors = <PropertyAccessorElement>[getterG];
4708 ClassElementImpl classB = ElementFactory.classElement2("B");
4709 classB.mixins = <InterfaceType>[classA.type];
4710 MemberMap mapB =
4711 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
4712 MemberMap mapA =
4713 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
4714 expect(mapA.size, _numOfMembersInObject);
4715 expect(mapB.size, _numOfMembersInObject + 1);
4716 expect(mapB.get(getterName), same(getterG));
4717 _assertNoErrors(classA);
4718 _assertNoErrors(classB);
4719 }
4720
4721 void test_getMapOfMembersInheritedFromClasses_implicitExtends() {
4722 // class A {}
4723 ClassElementImpl classA = ElementFactory.classElement2("A");
4724 MemberMap mapA =
4725 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
4726 expect(mapA.size, _numOfMembersInObject);
4727 _assertNoErrors(classA);
4728 }
4729
4730 void test_getMapOfMembersInheritedFromClasses_method_extends() {
4731 // class A { int g(); }
4732 // class B extends A {}
4733 ClassElementImpl classA = ElementFactory.classElement2("A");
4734 String methodName = "m";
4735 MethodElement methodM =
4736 ElementFactory.methodElement(methodName, _typeProvider.intType);
4737 classA.methods = <MethodElement>[methodM];
4738 ClassElementImpl classB = ElementFactory.classElement2("B");
4739 classB.supertype = classA.type;
4740 MemberMap mapB =
4741 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
4742 MemberMap mapA =
4743 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
4744 expect(mapA.size, _numOfMembersInObject);
4745 expect(mapB.size, _numOfMembersInObject + 1);
4746 expect(mapB.get(methodName), same(methodM));
4747 _assertNoErrors(classA);
4748 _assertNoErrors(classB);
4749 }
4750
4751 void test_getMapOfMembersInheritedFromClasses_method_implements() {
4752 // class A { int g(); }
4753 // class B implements A {}
4754 ClassElementImpl classA = ElementFactory.classElement2("A");
4755 String methodName = "m";
4756 MethodElement methodM =
4757 ElementFactory.methodElement(methodName, _typeProvider.intType);
4758 classA.methods = <MethodElement>[methodM];
4759 ClassElementImpl classB = ElementFactory.classElement2("B");
4760 classB.interfaces = <InterfaceType>[classA.type];
4761 MemberMap mapB =
4762 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
4763 MemberMap mapA =
4764 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
4765 expect(mapA.size, _numOfMembersInObject);
4766 expect(mapB.size, _numOfMembersInObject);
4767 expect(mapB.get(methodName), isNull);
4768 _assertNoErrors(classA);
4769 _assertNoErrors(classB);
4770 }
4771
4772 void test_getMapOfMembersInheritedFromClasses_method_with() {
4773 // class A { int g(); }
4774 // class B extends Object with A {}
4775 ClassElementImpl classA = ElementFactory.classElement2("A");
4776 String methodName = "m";
4777 MethodElement methodM =
4778 ElementFactory.methodElement(methodName, _typeProvider.intType);
4779 classA.methods = <MethodElement>[methodM];
4780 ClassElementImpl classB = ElementFactory.classElement2("B");
4781 classB.mixins = <InterfaceType>[classA.type];
4782 MemberMap mapB =
4783 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
4784 MemberMap mapA =
4785 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
4786 expect(mapA.size, _numOfMembersInObject);
4787 expect(mapB.size, _numOfMembersInObject + 1);
4788 expect(mapB.get(methodName), same(methodM));
4789 _assertNoErrors(classA);
4790 _assertNoErrors(classB);
4791 }
4792
4793 void test_getMapOfMembersInheritedFromClasses_method_with_two_mixins() {
4794 // class A1 { int m(); }
4795 // class A2 { int m(); }
4796 // class B extends Object with A1, A2 {}
4797 ClassElementImpl classA1 = ElementFactory.classElement2("A1");
4798 String methodName = "m";
4799 MethodElement methodA1M =
4800 ElementFactory.methodElement(methodName, _typeProvider.intType);
4801 classA1.methods = <MethodElement>[methodA1M];
4802 ClassElementImpl classA2 = ElementFactory.classElement2("A2");
4803 MethodElement methodA2M =
4804 ElementFactory.methodElement(methodName, _typeProvider.intType);
4805 classA2.methods = <MethodElement>[methodA2M];
4806 ClassElementImpl classB = ElementFactory.classElement2("B");
4807 classB.mixins = <InterfaceType>[classA1.type, classA2.type];
4808 MemberMap mapB =
4809 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
4810 expect(mapB.get(methodName), same(methodA2M));
4811 _assertNoErrors(classA1);
4812 _assertNoErrors(classA2);
4813 _assertNoErrors(classB);
4814 }
4815
4816 void test_getMapOfMembersInheritedFromInterfaces_accessor_extends() {
4817 // class A { int get g; }
4818 // class B extends A {}
4819 ClassElementImpl classA = ElementFactory.classElement2("A");
4820 String getterName = "g";
4821 PropertyAccessorElement getterG =
4822 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
4823 classA.accessors = <PropertyAccessorElement>[getterG];
4824 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
4825 MemberMap mapB =
4826 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
4827 MemberMap mapA =
4828 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
4829 expect(mapA.size, _numOfMembersInObject);
4830 expect(mapB.size, _numOfMembersInObject + 1);
4831 expect(mapB.get(getterName), same(getterG));
4832 _assertNoErrors(classA);
4833 _assertNoErrors(classB);
4834 }
4835
4836 void test_getMapOfMembersInheritedFromInterfaces_accessor_implements() {
4837 // class A { int get g; }
4838 // class B implements A {}
4839 ClassElementImpl classA = ElementFactory.classElement2("A");
4840 String getterName = "g";
4841 PropertyAccessorElement getterG =
4842 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
4843 classA.accessors = <PropertyAccessorElement>[getterG];
4844 ClassElementImpl classB = ElementFactory.classElement2("B");
4845 classB.interfaces = <InterfaceType>[classA.type];
4846 MemberMap mapB =
4847 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
4848 MemberMap mapA =
4849 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
4850 expect(mapA.size, _numOfMembersInObject);
4851 expect(mapB.size, _numOfMembersInObject + 1);
4852 expect(mapB.get(getterName), same(getterG));
4853 _assertNoErrors(classA);
4854 _assertNoErrors(classB);
4855 }
4856
4857 void test_getMapOfMembersInheritedFromInterfaces_accessor_with() {
4858 // class A { int get g; }
4859 // class B extends Object with A {}
4860 ClassElementImpl classA = ElementFactory.classElement2("A");
4861 String getterName = "g";
4862 PropertyAccessorElement getterG =
4863 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
4864 classA.accessors = <PropertyAccessorElement>[getterG];
4865 ClassElementImpl classB = ElementFactory.classElement2("B");
4866 classB.mixins = <InterfaceType>[classA.type];
4867 MemberMap mapB =
4868 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
4869 MemberMap mapA =
4870 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
4871 expect(mapA.size, _numOfMembersInObject);
4872 expect(mapB.size, _numOfMembersInObject + 1);
4873 expect(mapB.get(getterName), same(getterG));
4874 _assertNoErrors(classA);
4875 _assertNoErrors(classB);
4876 }
4877
4878 void test_getMapOfMembersInheritedFromInterfaces_implicitExtends() {
4879 // class A {}
4880 ClassElementImpl classA = ElementFactory.classElement2("A");
4881 MemberMap mapA =
4882 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
4883 expect(mapA.size, _numOfMembersInObject);
4884 _assertNoErrors(classA);
4885 }
4886
4887 void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance _getter_method() {
4888 // class I1 { int m(); }
4889 // class I2 { int get m; }
4890 // class A implements I2, I1 {}
4891 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
4892 String methodName = "m";
4893 MethodElement methodM =
4894 ElementFactory.methodElement(methodName, _typeProvider.intType);
4895 classI1.methods = <MethodElement>[methodM];
4896 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
4897 PropertyAccessorElement getter =
4898 ElementFactory.getterElement(methodName, false, _typeProvider.intType);
4899 classI2.accessors = <PropertyAccessorElement>[getter];
4900 ClassElementImpl classA = ElementFactory.classElement2("A");
4901 classA.interfaces = <InterfaceType>[classI2.type, classI1.type];
4902 MemberMap mapA =
4903 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
4904 expect(mapA.size, _numOfMembersInObject);
4905 expect(mapA.get(methodName), isNull);
4906 _assertErrors(classA,
4907 [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
4908 }
4909
4910 void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance _int_str() {
4911 // class I1 { int m(); }
4912 // class I2 { String m(); }
4913 // class A implements I1, I2 {}
4914 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
4915 String methodName = "m";
4916 MethodElement methodM1 =
4917 ElementFactory.methodElement(methodName, null, [_typeProvider.intType]);
4918 classI1.methods = <MethodElement>[methodM1];
4919 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
4920 MethodElement methodM2 = ElementFactory.methodElement(
4921 methodName, null, [_typeProvider.stringType]);
4922 classI2.methods = <MethodElement>[methodM2];
4923 ClassElementImpl classA = ElementFactory.classElement2("A");
4924 classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
4925 MemberMap mapA =
4926 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
4927 expect(mapA.size, _numOfMembersInObject);
4928 expect(mapA.get(methodName), isNull);
4929 _assertErrors(
4930 classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
4931 }
4932
4933 void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance _method_getter() {
4934 // class I1 { int m(); }
4935 // class I2 { int get m; }
4936 // class A implements I1, I2 {}
4937 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
4938 String methodName = "m";
4939 MethodElement methodM =
4940 ElementFactory.methodElement(methodName, _typeProvider.intType);
4941 classI1.methods = <MethodElement>[methodM];
4942 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
4943 PropertyAccessorElement getter =
4944 ElementFactory.getterElement(methodName, false, _typeProvider.intType);
4945 classI2.accessors = <PropertyAccessorElement>[getter];
4946 ClassElementImpl classA = ElementFactory.classElement2("A");
4947 classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
4948 MemberMap mapA =
4949 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
4950 expect(mapA.size, _numOfMembersInObject);
4951 expect(mapA.get(methodName), isNull);
4952 _assertErrors(classA,
4953 [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
4954 }
4955
4956 void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance _numOfRequiredParams() {
4957 // class I1 { dynamic m(int, [int]); }
4958 // class I2 { dynamic m(int, int, int); }
4959 // class A implements I1, I2 {}
4960 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
4961 String methodName = "m";
4962 MethodElementImpl methodM1 =
4963 ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
4964 ParameterElementImpl parameter1 =
4965 new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
4966 parameter1.type = _typeProvider.intType;
4967 parameter1.parameterKind = ParameterKind.REQUIRED;
4968 ParameterElementImpl parameter2 =
4969 new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
4970 parameter2.type = _typeProvider.intType;
4971 parameter2.parameterKind = ParameterKind.POSITIONAL;
4972 methodM1.parameters = <ParameterElement>[parameter1, parameter2];
4973 classI1.methods = <MethodElement>[methodM1];
4974 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
4975 MethodElementImpl methodM2 =
4976 ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
4977 ParameterElementImpl parameter3 =
4978 new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
4979 parameter3.type = _typeProvider.intType;
4980 parameter3.parameterKind = ParameterKind.REQUIRED;
4981 ParameterElementImpl parameter4 =
4982 new ParameterElementImpl.forNode(AstFactory.identifier3("a4"));
4983 parameter4.type = _typeProvider.intType;
4984 parameter4.parameterKind = ParameterKind.REQUIRED;
4985 ParameterElementImpl parameter5 =
4986 new ParameterElementImpl.forNode(AstFactory.identifier3("a5"));
4987 parameter5.type = _typeProvider.intType;
4988 parameter5.parameterKind = ParameterKind.REQUIRED;
4989 methodM2.parameters = <ParameterElement>[
4990 parameter3,
4991 parameter4,
4992 parameter5
4993 ];
4994 classI2.methods = <MethodElement>[methodM2];
4995 ClassElementImpl classA = ElementFactory.classElement2("A");
4996 classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
4997 MemberMap mapA =
4998 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
4999 expect(mapA.size, _numOfMembersInObject);
5000 expect(mapA.get(methodName), isNull);
5001 _assertErrors(
5002 classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
5003 }
5004
5005 void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance _str_int() {
5006 // class I1 { int m(); }
5007 // class I2 { String m(); }
5008 // class A implements I2, I1 {}
5009 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5010 String methodName = "m";
5011 MethodElement methodM1 = ElementFactory.methodElement(
5012 methodName, null, [_typeProvider.stringType]);
5013 classI1.methods = <MethodElement>[methodM1];
5014 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5015 MethodElement methodM2 =
5016 ElementFactory.methodElement(methodName, null, [_typeProvider.intType]);
5017 classI2.methods = <MethodElement>[methodM2];
5018 ClassElementImpl classA = ElementFactory.classElement2("A");
5019 classA.interfaces = <InterfaceType>[classI2.type, classI1.type];
5020 MemberMap mapA =
5021 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5022 expect(mapA.size, _numOfMembersInObject);
5023 expect(mapA.get(methodName), isNull);
5024 _assertErrors(
5025 classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
5026 }
5027
5028 void test_getMapOfMembersInheritedFromInterfaces_method_extends() {
5029 // class A { int g(); }
5030 // class B extends A {}
5031 ClassElementImpl classA = ElementFactory.classElement2("A");
5032 String methodName = "m";
5033 MethodElement methodM =
5034 ElementFactory.methodElement(methodName, _typeProvider.intType);
5035 classA.methods = <MethodElement>[methodM];
5036 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5037 MemberMap mapB =
5038 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
5039 MemberMap mapA =
5040 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5041 expect(mapA.size, _numOfMembersInObject);
5042 expect(mapB.size, _numOfMembersInObject + 1);
5043 expect(mapB.get(methodName), same(methodM));
5044 _assertNoErrors(classA);
5045 _assertNoErrors(classB);
5046 }
5047
5048 void test_getMapOfMembersInheritedFromInterfaces_method_implements() {
5049 // class A { int g(); }
5050 // class B implements A {}
5051 ClassElementImpl classA = ElementFactory.classElement2("A");
5052 String methodName = "m";
5053 MethodElement methodM =
5054 ElementFactory.methodElement(methodName, _typeProvider.intType);
5055 classA.methods = <MethodElement>[methodM];
5056 ClassElementImpl classB = ElementFactory.classElement2("B");
5057 classB.interfaces = <InterfaceType>[classA.type];
5058 MemberMap mapB =
5059 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
5060 MemberMap mapA =
5061 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5062 expect(mapA.size, _numOfMembersInObject);
5063 expect(mapB.size, _numOfMembersInObject + 1);
5064 expect(mapB.get(methodName), same(methodM));
5065 _assertNoErrors(classA);
5066 _assertNoErrors(classB);
5067 }
5068
5069 void test_getMapOfMembersInheritedFromInterfaces_method_with() {
5070 // class A { int g(); }
5071 // class B extends Object with A {}
5072 ClassElementImpl classA = ElementFactory.classElement2("A");
5073 String methodName = "m";
5074 MethodElement methodM =
5075 ElementFactory.methodElement(methodName, _typeProvider.intType);
5076 classA.methods = <MethodElement>[methodM];
5077 ClassElementImpl classB = ElementFactory.classElement2("B");
5078 classB.mixins = <InterfaceType>[classA.type];
5079 MemberMap mapB =
5080 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
5081 MemberMap mapA =
5082 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5083 expect(mapA.size, _numOfMembersInObject);
5084 expect(mapB.size, _numOfMembersInObject + 1);
5085 expect(mapB.get(methodName), same(methodM));
5086 _assertNoErrors(classA);
5087 _assertNoErrors(classB);
5088 }
5089
5090 void test_getMapOfMembersInheritedFromInterfaces_union_differentNames() {
5091 // class I1 { int m1(); }
5092 // class I2 { int m2(); }
5093 // class A implements I1, I2 {}
5094 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5095 String methodName1 = "m1";
5096 MethodElement methodM1 =
5097 ElementFactory.methodElement(methodName1, _typeProvider.intType);
5098 classI1.methods = <MethodElement>[methodM1];
5099 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5100 String methodName2 = "m2";
5101 MethodElement methodM2 =
5102 ElementFactory.methodElement(methodName2, _typeProvider.intType);
5103 classI2.methods = <MethodElement>[methodM2];
5104 ClassElementImpl classA = ElementFactory.classElement2("A");
5105 classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
5106 MemberMap mapA =
5107 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5108 expect(mapA.size, _numOfMembersInObject + 2);
5109 expect(mapA.get(methodName1), same(methodM1));
5110 expect(mapA.get(methodName2), same(methodM2));
5111 _assertNoErrors(classA);
5112 }
5113
5114 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_gett ers() {
5115 // class I1 { int get g; }
5116 // class I2 { num get g; }
5117 // class A implements I1, I2 {}
5118 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5119 String accessorName = "g";
5120 PropertyAccessorElement getter1 = ElementFactory.getterElement(
5121 accessorName, false, _typeProvider.intType);
5122 classI1.accessors = <PropertyAccessorElement>[getter1];
5123 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5124 PropertyAccessorElement getter2 = ElementFactory.getterElement(
5125 accessorName, false, _typeProvider.numType);
5126 classI2.accessors = <PropertyAccessorElement>[getter2];
5127 ClassElementImpl classA = ElementFactory.classElement2("A");
5128 classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
5129 MemberMap mapA =
5130 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5131 expect(mapA.size, _numOfMembersInObject + 1);
5132 PropertyAccessorElement syntheticAccessor = ElementFactory.getterElement(
5133 accessorName, false, _typeProvider.dynamicType);
5134 expect(mapA.get(accessorName).type, syntheticAccessor.type);
5135 _assertNoErrors(classA);
5136 }
5137
5138 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_meth ods() {
5139 // class I1 { dynamic m(int); }
5140 // class I2 { dynamic m(num); }
5141 // class A implements I1, I2 {}
5142 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5143 String methodName = "m";
5144 MethodElementImpl methodM1 =
5145 ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
5146 ParameterElementImpl parameter1 =
5147 new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
5148 parameter1.type = _typeProvider.intType;
5149 parameter1.parameterKind = ParameterKind.REQUIRED;
5150 methodM1.parameters = <ParameterElement>[parameter1];
5151 classI1.methods = <MethodElement>[methodM1];
5152 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5153 MethodElementImpl methodM2 =
5154 ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
5155 ParameterElementImpl parameter2 =
5156 new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
5157 parameter2.type = _typeProvider.numType;
5158 parameter2.parameterKind = ParameterKind.REQUIRED;
5159 methodM2.parameters = <ParameterElement>[parameter2];
5160 classI2.methods = <MethodElement>[methodM2];
5161 ClassElementImpl classA = ElementFactory.classElement2("A");
5162 classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
5163 MemberMap mapA =
5164 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5165 expect(mapA.size, _numOfMembersInObject + 1);
5166 MethodElement syntheticMethod = ElementFactory.methodElement(
5167 methodName, _typeProvider.dynamicType, [_typeProvider.dynamicType]);
5168 expect(mapA.get(methodName).type, syntheticMethod.type);
5169 _assertNoErrors(classA);
5170 }
5171
5172 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_sett ers() {
5173 // class I1 { set s(int); }
5174 // class I2 { set s(num); }
5175 // class A implements I1, I2 {}
5176 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5177 String accessorName = "s";
5178 PropertyAccessorElement setter1 = ElementFactory.setterElement(
5179 accessorName, false, _typeProvider.intType);
5180 classI1.accessors = <PropertyAccessorElement>[setter1];
5181 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5182 PropertyAccessorElement setter2 = ElementFactory.setterElement(
5183 accessorName, false, _typeProvider.numType);
5184 classI2.accessors = <PropertyAccessorElement>[setter2];
5185 ClassElementImpl classA = ElementFactory.classElement2("A");
5186 classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
5187 MemberMap mapA =
5188 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5189 expect(mapA.size, _numOfMembersInObject + 1);
5190 PropertyAccessorElementImpl syntheticAccessor = ElementFactory
5191 .setterElement(accessorName, false, _typeProvider.dynamicType);
5192 syntheticAccessor.returnType = _typeProvider.dynamicType;
5193 expect(mapA.get("$accessorName=").type, syntheticAccessor.type);
5194 _assertNoErrors(classA);
5195 }
5196
5197 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_gett ers() {
5198 // class A {}
5199 // class B extends A {}
5200 // class C extends B {}
5201 // class I1 { A get g; }
5202 // class I2 { B get g; }
5203 // class I3 { C get g; }
5204 // class D implements I1, I2, I3 {}
5205 ClassElementImpl classA = ElementFactory.classElement2("A");
5206 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5207 ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
5208 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5209 String accessorName = "g";
5210 PropertyAccessorElement getter1 =
5211 ElementFactory.getterElement(accessorName, false, classA.type);
5212 classI1.accessors = <PropertyAccessorElement>[getter1];
5213 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5214 PropertyAccessorElement getter2 =
5215 ElementFactory.getterElement(accessorName, false, classB.type);
5216 classI2.accessors = <PropertyAccessorElement>[getter2];
5217 ClassElementImpl classI3 = ElementFactory.classElement2("I3");
5218 PropertyAccessorElement getter3 =
5219 ElementFactory.getterElement(accessorName, false, classC.type);
5220 classI3.accessors = <PropertyAccessorElement>[getter3];
5221 ClassElementImpl classD = ElementFactory.classElement2("D");
5222 classD.interfaces = <InterfaceType>[
5223 classI1.type,
5224 classI2.type,
5225 classI3.type
5226 ];
5227 MemberMap mapD =
5228 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD);
5229 expect(mapD.size, _numOfMembersInObject + 1);
5230 PropertyAccessorElement syntheticAccessor = ElementFactory.getterElement(
5231 accessorName, false, _typeProvider.dynamicType);
5232 expect(mapD.get(accessorName).type, syntheticAccessor.type);
5233 _assertNoErrors(classD);
5234 }
5235
5236 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_meth ods() {
5237 // class A {}
5238 // class B extends A {}
5239 // class C extends B {}
5240 // class I1 { dynamic m(A a); }
5241 // class I2 { dynamic m(B b); }
5242 // class I3 { dynamic m(C c); }
5243 // class D implements I1, I2, I3 {}
5244 ClassElementImpl classA = ElementFactory.classElement2("A");
5245 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5246 ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
5247 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5248 String methodName = "m";
5249 MethodElementImpl methodM1 =
5250 ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
5251 ParameterElementImpl parameter1 =
5252 new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
5253 parameter1.type = classA.type;
5254 parameter1.parameterKind = ParameterKind.REQUIRED;
5255 methodM1.parameters = <ParameterElement>[parameter1];
5256 classI1.methods = <MethodElement>[methodM1];
5257 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5258 MethodElementImpl methodM2 =
5259 ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
5260 ParameterElementImpl parameter2 =
5261 new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
5262 parameter2.type = classB.type;
5263 parameter2.parameterKind = ParameterKind.REQUIRED;
5264 methodM2.parameters = <ParameterElement>[parameter2];
5265 classI2.methods = <MethodElement>[methodM2];
5266 ClassElementImpl classI3 = ElementFactory.classElement2("I3");
5267 MethodElementImpl methodM3 =
5268 ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
5269 ParameterElementImpl parameter3 =
5270 new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
5271 parameter3.type = classC.type;
5272 parameter3.parameterKind = ParameterKind.REQUIRED;
5273 methodM3.parameters = <ParameterElement>[parameter3];
5274 classI3.methods = <MethodElement>[methodM3];
5275 ClassElementImpl classD = ElementFactory.classElement2("D");
5276 classD.interfaces = <InterfaceType>[
5277 classI1.type,
5278 classI2.type,
5279 classI3.type
5280 ];
5281 MemberMap mapD =
5282 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD);
5283 expect(mapD.size, _numOfMembersInObject + 1);
5284 MethodElement syntheticMethod = ElementFactory.methodElement(
5285 methodName, _typeProvider.dynamicType, [_typeProvider.dynamicType]);
5286 expect(mapD.get(methodName).type, syntheticMethod.type);
5287 _assertNoErrors(classD);
5288 }
5289
5290 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_sett ers() {
5291 // class A {}
5292 // class B extends A {}
5293 // class C extends B {}
5294 // class I1 { set s(A); }
5295 // class I2 { set s(B); }
5296 // class I3 { set s(C); }
5297 // class D implements I1, I2, I3 {}
5298 ClassElementImpl classA = ElementFactory.classElement2("A");
5299 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5300 ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
5301 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5302 String accessorName = "s";
5303 PropertyAccessorElement setter1 =
5304 ElementFactory.setterElement(accessorName, false, classA.type);
5305 classI1.accessors = <PropertyAccessorElement>[setter1];
5306 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5307 PropertyAccessorElement setter2 =
5308 ElementFactory.setterElement(accessorName, false, classB.type);
5309 classI2.accessors = <PropertyAccessorElement>[setter2];
5310 ClassElementImpl classI3 = ElementFactory.classElement2("I3");
5311 PropertyAccessorElement setter3 =
5312 ElementFactory.setterElement(accessorName, false, classC.type);
5313 classI3.accessors = <PropertyAccessorElement>[setter3];
5314 ClassElementImpl classD = ElementFactory.classElement2("D");
5315 classD.interfaces = <InterfaceType>[
5316 classI1.type,
5317 classI2.type,
5318 classI3.type
5319 ];
5320 MemberMap mapD =
5321 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD);
5322 expect(mapD.size, _numOfMembersInObject + 1);
5323 PropertyAccessorElementImpl syntheticAccessor = ElementFactory
5324 .setterElement(accessorName, false, _typeProvider.dynamicType);
5325 syntheticAccessor.returnType = _typeProvider.dynamicType;
5326 expect(mapD.get("$accessorName=").type, syntheticAccessor.type);
5327 _assertNoErrors(classD);
5328 }
5329
5330 void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods() {
5331 // class I1 { int m(); }
5332 // class I2 { int m([int]); }
5333 // class A implements I1, I2 {}
5334 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5335 String methodName = "m";
5336 MethodElement methodM1 =
5337 ElementFactory.methodElement(methodName, _typeProvider.intType);
5338 classI1.methods = <MethodElement>[methodM1];
5339 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5340 MethodElementImpl methodM2 =
5341 ElementFactory.methodElement(methodName, _typeProvider.intType);
5342 ParameterElementImpl parameter1 =
5343 new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
5344 parameter1.type = _typeProvider.intType;
5345 parameter1.parameterKind = ParameterKind.POSITIONAL;
5346 methodM2.parameters = <ParameterElement>[parameter1];
5347 classI2.methods = <MethodElement>[methodM2];
5348 ClassElementImpl classA = ElementFactory.classElement2("A");
5349 classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
5350 MemberMap mapA =
5351 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5352 expect(mapA.size, _numOfMembersInObject + 1);
5353 expect(mapA.get(methodName), same(methodM2));
5354 _assertNoErrors(classA);
5355 }
5356
5357 void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods() {
5358 // class I1 { int m(); }
5359 // class I2 { int m([int]); }
5360 // class I3 { int m([int, int]); }
5361 // class A implements I1, I2, I3 {}
5362 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5363 String methodName = "m";
5364 MethodElementImpl methodM1 =
5365 ElementFactory.methodElement(methodName, _typeProvider.intType);
5366 classI1.methods = <MethodElement>[methodM1];
5367 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5368 MethodElementImpl methodM2 =
5369 ElementFactory.methodElement(methodName, _typeProvider.intType);
5370 ParameterElementImpl parameter1 =
5371 new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
5372 parameter1.type = _typeProvider.intType;
5373 parameter1.parameterKind = ParameterKind.POSITIONAL;
5374 methodM1.parameters = <ParameterElement>[parameter1];
5375 classI2.methods = <MethodElement>[methodM2];
5376 ClassElementImpl classI3 = ElementFactory.classElement2("I3");
5377 MethodElementImpl methodM3 =
5378 ElementFactory.methodElement(methodName, _typeProvider.intType);
5379 ParameterElementImpl parameter2 =
5380 new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
5381 parameter2.type = _typeProvider.intType;
5382 parameter2.parameterKind = ParameterKind.POSITIONAL;
5383 ParameterElementImpl parameter3 =
5384 new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
5385 parameter3.type = _typeProvider.intType;
5386 parameter3.parameterKind = ParameterKind.POSITIONAL;
5387 methodM3.parameters = <ParameterElement>[parameter2, parameter3];
5388 classI3.methods = <MethodElement>[methodM3];
5389 ClassElementImpl classA = ElementFactory.classElement2("A");
5390 classA.interfaces = <InterfaceType>[
5391 classI1.type,
5392 classI2.type,
5393 classI3.type
5394 ];
5395 MemberMap mapA =
5396 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5397 expect(mapA.size, _numOfMembersInObject + 1);
5398 expect(mapA.get(methodName), same(methodM3));
5399 _assertNoErrors(classA);
5400 }
5401
5402 void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods() {
5403 // class I1 { int m(); }
5404 // class I2 { int m(); }
5405 // class I3 { int m([int]); }
5406 // class I4 { int m([int, int]); }
5407 // class A implements I1, I2, I3, I4 {}
5408 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5409 String methodName = "m";
5410 MethodElement methodM1 =
5411 ElementFactory.methodElement(methodName, _typeProvider.intType);
5412 classI1.methods = <MethodElement>[methodM1];
5413 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5414 MethodElement methodM2 =
5415 ElementFactory.methodElement(methodName, _typeProvider.intType);
5416 classI2.methods = <MethodElement>[methodM2];
5417 ClassElementImpl classI3 = ElementFactory.classElement2("I3");
5418 MethodElementImpl methodM3 =
5419 ElementFactory.methodElement(methodName, _typeProvider.intType);
5420 ParameterElementImpl parameter1 =
5421 new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
5422 parameter1.type = _typeProvider.intType;
5423 parameter1.parameterKind = ParameterKind.POSITIONAL;
5424 methodM3.parameters = <ParameterElement>[parameter1];
5425 classI3.methods = <MethodElement>[methodM3];
5426 ClassElementImpl classI4 = ElementFactory.classElement2("I4");
5427 MethodElementImpl methodM4 =
5428 ElementFactory.methodElement(methodName, _typeProvider.intType);
5429 ParameterElementImpl parameter2 =
5430 new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
5431 parameter2.type = _typeProvider.intType;
5432 parameter2.parameterKind = ParameterKind.POSITIONAL;
5433 ParameterElementImpl parameter3 =
5434 new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
5435 parameter3.type = _typeProvider.intType;
5436 parameter3.parameterKind = ParameterKind.POSITIONAL;
5437 methodM4.parameters = <ParameterElement>[parameter2, parameter3];
5438 classI4.methods = <MethodElement>[methodM4];
5439 ClassElementImpl classA = ElementFactory.classElement2("A");
5440 classA.interfaces = <InterfaceType>[
5441 classI1.type,
5442 classI2.type,
5443 classI3.type,
5444 classI4.type
5445 ];
5446 MemberMap mapA =
5447 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5448 expect(mapA.size, _numOfMembersInObject + 1);
5449 expect(mapA.get(methodName), same(methodM4));
5450 _assertNoErrors(classA);
5451 }
5452
5453 void test_lookupInheritance_interface_getter() {
5454 ClassElementImpl classA = ElementFactory.classElement2("A");
5455 String getterName = "g";
5456 PropertyAccessorElement getterG =
5457 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
5458 classA.accessors = <PropertyAccessorElement>[getterG];
5459 ClassElementImpl classB = ElementFactory.classElement2("B");
5460 classB.interfaces = <InterfaceType>[classA.type];
5461 expect(_inheritanceManager.lookupInheritance(classB, getterName),
5462 same(getterG));
5463 _assertNoErrors(classA);
5464 _assertNoErrors(classB);
5465 }
5466
5467 void test_lookupInheritance_interface_method() {
5468 ClassElementImpl classA = ElementFactory.classElement2("A");
5469 String methodName = "m";
5470 MethodElement methodM =
5471 ElementFactory.methodElement(methodName, _typeProvider.intType);
5472 classA.methods = <MethodElement>[methodM];
5473 ClassElementImpl classB = ElementFactory.classElement2("B");
5474 classB.interfaces = <InterfaceType>[classA.type];
5475 expect(_inheritanceManager.lookupInheritance(classB, methodName),
5476 same(methodM));
5477 _assertNoErrors(classA);
5478 _assertNoErrors(classB);
5479 }
5480
5481 void test_lookupInheritance_interface_setter() {
5482 ClassElementImpl classA = ElementFactory.classElement2("A");
5483 String setterName = "s";
5484 PropertyAccessorElement setterS =
5485 ElementFactory.setterElement(setterName, false, _typeProvider.intType);
5486 classA.accessors = <PropertyAccessorElement>[setterS];
5487 ClassElementImpl classB = ElementFactory.classElement2("B");
5488 classB.interfaces = <InterfaceType>[classA.type];
5489 expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
5490 same(setterS));
5491 _assertNoErrors(classA);
5492 _assertNoErrors(classB);
5493 }
5494
5495 void test_lookupInheritance_interface_staticMember() {
5496 ClassElementImpl classA = ElementFactory.classElement2("A");
5497 String methodName = "m";
5498 MethodElement methodM =
5499 ElementFactory.methodElement(methodName, _typeProvider.intType);
5500 (methodM as MethodElementImpl).static = true;
5501 classA.methods = <MethodElement>[methodM];
5502 ClassElementImpl classB = ElementFactory.classElement2("B");
5503 classB.interfaces = <InterfaceType>[classA.type];
5504 expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
5505 _assertNoErrors(classA);
5506 _assertNoErrors(classB);
5507 }
5508
5509 void test_lookupInheritance_interfaces_infiniteLoop() {
5510 ClassElementImpl classA = ElementFactory.classElement2("A");
5511 classA.interfaces = <InterfaceType>[classA.type];
5512 expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
5513 _assertNoErrors(classA);
5514 }
5515
5516 void test_lookupInheritance_interfaces_infiniteLoop2() {
5517 ClassElementImpl classA = ElementFactory.classElement2("A");
5518 ClassElementImpl classB = ElementFactory.classElement2("B");
5519 classA.interfaces = <InterfaceType>[classB.type];
5520 classB.interfaces = <InterfaceType>[classA.type];
5521 expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
5522 _assertNoErrors(classA);
5523 _assertNoErrors(classB);
5524 }
5525
5526 void test_lookupInheritance_interfaces_union2() {
5527 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5528 String methodName1 = "m1";
5529 MethodElement methodM1 =
5530 ElementFactory.methodElement(methodName1, _typeProvider.intType);
5531 classI1.methods = <MethodElement>[methodM1];
5532 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5533 String methodName2 = "m2";
5534 MethodElement methodM2 =
5535 ElementFactory.methodElement(methodName2, _typeProvider.intType);
5536 classI2.methods = <MethodElement>[methodM2];
5537 classI2.interfaces = <InterfaceType>[classI1.type];
5538 ClassElementImpl classA = ElementFactory.classElement2("A");
5539 classA.interfaces = <InterfaceType>[classI2.type];
5540 expect(_inheritanceManager.lookupInheritance(classA, methodName1),
5541 same(methodM1));
5542 expect(_inheritanceManager.lookupInheritance(classA, methodName2),
5543 same(methodM2));
5544 _assertNoErrors(classI1);
5545 _assertNoErrors(classI2);
5546 _assertNoErrors(classA);
5547 }
5548
5549 void test_lookupInheritance_mixin_getter() {
5550 ClassElementImpl classA = ElementFactory.classElement2("A");
5551 String getterName = "g";
5552 PropertyAccessorElement getterG =
5553 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
5554 classA.accessors = <PropertyAccessorElement>[getterG];
5555 ClassElementImpl classB = ElementFactory.classElement2("B");
5556 classB.mixins = <InterfaceType>[classA.type];
5557 expect(_inheritanceManager.lookupInheritance(classB, getterName),
5558 same(getterG));
5559 _assertNoErrors(classA);
5560 _assertNoErrors(classB);
5561 }
5562
5563 void test_lookupInheritance_mixin_method() {
5564 ClassElementImpl classA = ElementFactory.classElement2("A");
5565 String methodName = "m";
5566 MethodElement methodM =
5567 ElementFactory.methodElement(methodName, _typeProvider.intType);
5568 classA.methods = <MethodElement>[methodM];
5569 ClassElementImpl classB = ElementFactory.classElement2("B");
5570 classB.mixins = <InterfaceType>[classA.type];
5571 expect(_inheritanceManager.lookupInheritance(classB, methodName),
5572 same(methodM));
5573 _assertNoErrors(classA);
5574 _assertNoErrors(classB);
5575 }
5576
5577 void test_lookupInheritance_mixin_setter() {
5578 ClassElementImpl classA = ElementFactory.classElement2("A");
5579 String setterName = "s";
5580 PropertyAccessorElement setterS =
5581 ElementFactory.setterElement(setterName, false, _typeProvider.intType);
5582 classA.accessors = <PropertyAccessorElement>[setterS];
5583 ClassElementImpl classB = ElementFactory.classElement2("B");
5584 classB.mixins = <InterfaceType>[classA.type];
5585 expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
5586 same(setterS));
5587 _assertNoErrors(classA);
5588 _assertNoErrors(classB);
5589 }
5590
5591 void test_lookupInheritance_mixin_staticMember() {
5592 ClassElementImpl classA = ElementFactory.classElement2("A");
5593 String methodName = "m";
5594 MethodElement methodM =
5595 ElementFactory.methodElement(methodName, _typeProvider.intType);
5596 (methodM as MethodElementImpl).static = true;
5597 classA.methods = <MethodElement>[methodM];
5598 ClassElementImpl classB = ElementFactory.classElement2("B");
5599 classB.mixins = <InterfaceType>[classA.type];
5600 expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
5601 _assertNoErrors(classA);
5602 _assertNoErrors(classB);
5603 }
5604
5605 void test_lookupInheritance_noMember() {
5606 ClassElementImpl classA = ElementFactory.classElement2("A");
5607 expect(_inheritanceManager.lookupInheritance(classA, "a"), isNull);
5608 _assertNoErrors(classA);
5609 }
5610
5611 void test_lookupInheritance_superclass_getter() {
5612 ClassElementImpl classA = ElementFactory.classElement2("A");
5613 String getterName = "g";
5614 PropertyAccessorElement getterG =
5615 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
5616 classA.accessors = <PropertyAccessorElement>[getterG];
5617 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5618 expect(_inheritanceManager.lookupInheritance(classB, getterName),
5619 same(getterG));
5620 _assertNoErrors(classA);
5621 _assertNoErrors(classB);
5622 }
5623
5624 void test_lookupInheritance_superclass_infiniteLoop() {
5625 ClassElementImpl classA = ElementFactory.classElement2("A");
5626 classA.supertype = classA.type;
5627 expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
5628 _assertNoErrors(classA);
5629 }
5630
5631 void test_lookupInheritance_superclass_infiniteLoop2() {
5632 ClassElementImpl classA = ElementFactory.classElement2("A");
5633 ClassElementImpl classB = ElementFactory.classElement2("B");
5634 classA.supertype = classB.type;
5635 classB.supertype = classA.type;
5636 expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
5637 _assertNoErrors(classA);
5638 _assertNoErrors(classB);
5639 }
5640
5641 void test_lookupInheritance_superclass_method() {
5642 ClassElementImpl classA = ElementFactory.classElement2("A");
5643 String methodName = "m";
5644 MethodElement methodM =
5645 ElementFactory.methodElement(methodName, _typeProvider.intType);
5646 classA.methods = <MethodElement>[methodM];
5647 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5648 expect(_inheritanceManager.lookupInheritance(classB, methodName),
5649 same(methodM));
5650 _assertNoErrors(classA);
5651 _assertNoErrors(classB);
5652 }
5653
5654 void test_lookupInheritance_superclass_setter() {
5655 ClassElementImpl classA = ElementFactory.classElement2("A");
5656 String setterName = "s";
5657 PropertyAccessorElement setterS =
5658 ElementFactory.setterElement(setterName, false, _typeProvider.intType);
5659 classA.accessors = <PropertyAccessorElement>[setterS];
5660 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5661 expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
5662 same(setterS));
5663 _assertNoErrors(classA);
5664 _assertNoErrors(classB);
5665 }
5666
5667 void test_lookupInheritance_superclass_staticMember() {
5668 ClassElementImpl classA = ElementFactory.classElement2("A");
5669 String methodName = "m";
5670 MethodElement methodM =
5671 ElementFactory.methodElement(methodName, _typeProvider.intType);
5672 (methodM as MethodElementImpl).static = true;
5673 classA.methods = <MethodElement>[methodM];
5674 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5675 expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
5676 _assertNoErrors(classA);
5677 _assertNoErrors(classB);
5678 }
5679
5680 void test_lookupMember_getter() {
5681 ClassElementImpl classA = ElementFactory.classElement2("A");
5682 String getterName = "g";
5683 PropertyAccessorElement getterG =
5684 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
5685 classA.accessors = <PropertyAccessorElement>[getterG];
5686 expect(_inheritanceManager.lookupMember(classA, getterName), same(getterG));
5687 _assertNoErrors(classA);
5688 }
5689
5690 void test_lookupMember_getter_static() {
5691 ClassElementImpl classA = ElementFactory.classElement2("A");
5692 String getterName = "g";
5693 PropertyAccessorElement getterG =
5694 ElementFactory.getterElement(getterName, true, _typeProvider.intType);
5695 classA.accessors = <PropertyAccessorElement>[getterG];
5696 expect(_inheritanceManager.lookupMember(classA, getterName), isNull);
5697 _assertNoErrors(classA);
5698 }
5699
5700 void test_lookupMember_method() {
5701 ClassElementImpl classA = ElementFactory.classElement2("A");
5702 String methodName = "m";
5703 MethodElement methodM =
5704 ElementFactory.methodElement(methodName, _typeProvider.intType);
5705 classA.methods = <MethodElement>[methodM];
5706 expect(_inheritanceManager.lookupMember(classA, methodName), same(methodM));
5707 _assertNoErrors(classA);
5708 }
5709
5710 void test_lookupMember_method_static() {
5711 ClassElementImpl classA = ElementFactory.classElement2("A");
5712 String methodName = "m";
5713 MethodElement methodM =
5714 ElementFactory.methodElement(methodName, _typeProvider.intType);
5715 (methodM as MethodElementImpl).static = true;
5716 classA.methods = <MethodElement>[methodM];
5717 expect(_inheritanceManager.lookupMember(classA, methodName), isNull);
5718 _assertNoErrors(classA);
5719 }
5720
5721 void test_lookupMember_noMember() {
5722 ClassElementImpl classA = ElementFactory.classElement2("A");
5723 expect(_inheritanceManager.lookupMember(classA, "a"), isNull);
5724 _assertNoErrors(classA);
5725 }
5726
5727 void test_lookupMember_setter() {
5728 ClassElementImpl classA = ElementFactory.classElement2("A");
5729 String setterName = "s";
5730 PropertyAccessorElement setterS =
5731 ElementFactory.setterElement(setterName, false, _typeProvider.intType);
5732 classA.accessors = <PropertyAccessorElement>[setterS];
5733 expect(_inheritanceManager.lookupMember(classA, "$setterName="),
5734 same(setterS));
5735 _assertNoErrors(classA);
5736 }
5737
5738 void test_lookupMember_setter_static() {
5739 ClassElementImpl classA = ElementFactory.classElement2("A");
5740 String setterName = "s";
5741 PropertyAccessorElement setterS =
5742 ElementFactory.setterElement(setterName, true, _typeProvider.intType);
5743 classA.accessors = <PropertyAccessorElement>[setterS];
5744 expect(_inheritanceManager.lookupMember(classA, setterName), isNull);
5745 _assertNoErrors(classA);
5746 }
5747
5748 void test_lookupOverrides_noParentClasses() {
5749 ClassElementImpl classA = ElementFactory.classElement2("A");
5750 String methodName = "m";
5751 MethodElementImpl methodM =
5752 ElementFactory.methodElement(methodName, _typeProvider.intType);
5753 classA.methods = <MethodElement>[methodM];
5754 expect(
5755 _inheritanceManager.lookupOverrides(classA, methodName), hasLength(0));
5756 _assertNoErrors(classA);
5757 }
5758
5759 void test_lookupOverrides_overrideBaseClass() {
5760 ClassElementImpl classA = ElementFactory.classElement2("A");
5761 String methodName = "m";
5762 MethodElementImpl methodMinA =
5763 ElementFactory.methodElement(methodName, _typeProvider.intType);
5764 classA.methods = <MethodElement>[methodMinA];
5765 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5766 MethodElementImpl methodMinB =
5767 ElementFactory.methodElement(methodName, _typeProvider.intType);
5768 classB.methods = <MethodElement>[methodMinB];
5769 List<ExecutableElement> overrides =
5770 _inheritanceManager.lookupOverrides(classB, methodName);
5771 expect(overrides, unorderedEquals([methodMinA]));
5772 _assertNoErrors(classA);
5773 _assertNoErrors(classB);
5774 }
5775
5776 void test_lookupOverrides_overrideInterface() {
5777 ClassElementImpl classA = ElementFactory.classElement2("A");
5778 String methodName = "m";
5779 MethodElementImpl methodMinA =
5780 ElementFactory.methodElement(methodName, _typeProvider.intType);
5781 classA.methods = <MethodElement>[methodMinA];
5782 ClassElementImpl classB = ElementFactory.classElement2("B");
5783 classB.interfaces = <InterfaceType>[classA.type];
5784 MethodElementImpl methodMinB =
5785 ElementFactory.methodElement(methodName, _typeProvider.intType);
5786 classB.methods = <MethodElement>[methodMinB];
5787 List<ExecutableElement> overrides =
5788 _inheritanceManager.lookupOverrides(classB, methodName);
5789 expect(overrides, unorderedEquals([methodMinA]));
5790 _assertNoErrors(classA);
5791 _assertNoErrors(classB);
5792 }
5793
5794 void test_lookupOverrides_overrideTwoInterfaces() {
5795 ClassElementImpl classA = ElementFactory.classElement2("A");
5796 String methodName = "m";
5797 MethodElementImpl methodMinA =
5798 ElementFactory.methodElement(methodName, _typeProvider.intType);
5799 classA.methods = <MethodElement>[methodMinA];
5800 ClassElementImpl classB = ElementFactory.classElement2("B");
5801 MethodElementImpl methodMinB =
5802 ElementFactory.methodElement(methodName, _typeProvider.doubleType);
5803 classB.methods = <MethodElement>[methodMinB];
5804 ClassElementImpl classC = ElementFactory.classElement2("C");
5805 classC.interfaces = <InterfaceType>[classA.type, classB.type];
5806 MethodElementImpl methodMinC =
5807 ElementFactory.methodElement(methodName, _typeProvider.numType);
5808 classC.methods = <MethodElement>[methodMinC];
5809 List<ExecutableElement> overrides =
5810 _inheritanceManager.lookupOverrides(classC, methodName);
5811 expect(overrides, unorderedEquals([methodMinA, methodMinB]));
5812 _assertNoErrors(classA);
5813 _assertNoErrors(classB);
5814 _assertNoErrors(classC);
5815 }
5816
5817 void _assertErrors(ClassElement classElt,
5818 [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
5819 GatheringErrorListener errorListener = new GatheringErrorListener();
5820 HashSet<AnalysisError> actualErrors =
5821 _inheritanceManager.getErrors(classElt);
5822 if (actualErrors != null) {
5823 for (AnalysisError error in actualErrors) {
5824 errorListener.onError(error);
5825 }
5826 }
5827 errorListener.assertErrorsWithCodes(expectedErrorCodes);
5828 }
5829
5830 void _assertNoErrors(ClassElement classElt) {
5831 _assertErrors(classElt);
5832 }
5833
5834 /**
5835 * Create the inheritance manager used by the tests.
5836 *
5837 * @return the inheritance manager that was created
5838 */
5839 InheritanceManager _createInheritanceManager() {
5840 AnalysisContext context = AnalysisContextFactory.contextWithCore();
5841 FileBasedSource source =
5842 new FileBasedSource(FileUtilities2.createFile("/test.dart"));
5843 CompilationUnitElementImpl definingCompilationUnit =
5844 new CompilationUnitElementImpl("test.dart");
5845 definingCompilationUnit.librarySource =
5846 definingCompilationUnit.source = source;
5847 _definingLibrary = ElementFactory.library(context, "test");
5848 _definingLibrary.definingCompilationUnit = definingCompilationUnit;
5849 return new InheritanceManager(_definingLibrary);
5850 }
5851 }
5852
5853 @reflectiveTest
5854 class LibraryElementBuilderTest extends EngineTestCase {
5855 /**
5856 * The analysis context used to analyze sources.
5857 */
5858 InternalAnalysisContext _context;
5859
5860 /**
5861 * Add a source file to the content provider. The file path should be absolute .
5862 *
5863 * @param filePath the path of the file being added
5864 * @param contents the contents to be returned by the content provider for the specified file
5865 * @return the source object representing the added file
5866 */
5867 Source addSource(String filePath, String contents) {
5868 Source source = new FileBasedSource(FileUtilities2.createFile(filePath));
5869 _context.setContents(source, contents);
5870 return source;
5871 }
5872
5873 @override
5874 void setUp() {
5875 _context = AnalysisContextFactory.contextWithCore();
5876 }
5877
5878 @override
5879 void tearDown() {
5880 _context = null;
5881 super.tearDown();
5882 }
5883
5884 void test_accessorsAcrossFiles() {
5885 Source librarySource = addSource(
5886 "/lib.dart",
5887 r'''
5888 library lib;
5889 part 'first.dart';
5890 part 'second.dart';''');
5891 addSource(
5892 "/first.dart",
5893 r'''
5894 part of lib;
5895 int get V => 0;''');
5896 addSource(
5897 "/second.dart",
5898 r'''
5899 part of lib;
5900 void set V(int v) {}''');
5901 LibraryElement element = _buildLibrary(librarySource);
5902 expect(element, isNotNull);
5903 List<CompilationUnitElement> sourcedUnits = element.parts;
5904 expect(sourcedUnits, hasLength(2));
5905 List<PropertyAccessorElement> firstAccessors = sourcedUnits[0].accessors;
5906 expect(firstAccessors, hasLength(1));
5907 List<PropertyAccessorElement> secondAccessors = sourcedUnits[1].accessors;
5908 expect(secondAccessors, hasLength(1));
5909 expect(secondAccessors[0].variable, same(firstAccessors[0].variable));
5910 }
5911
5912 void test_empty() {
5913 Source librarySource = addSource("/lib.dart", "library lib;");
5914 LibraryElement element = _buildLibrary(librarySource);
5915 expect(element, isNotNull);
5916 expect(element.name, "lib");
5917 expect(element.entryPoint, isNull);
5918 expect(element.importedLibraries, hasLength(0));
5919 expect(element.imports, hasLength(0));
5920 expect(element.library, same(element));
5921 expect(element.prefixes, hasLength(0));
5922 expect(element.parts, hasLength(0));
5923 CompilationUnitElement unit = element.definingCompilationUnit;
5924 expect(unit, isNotNull);
5925 expect(unit.name, "lib.dart");
5926 expect(unit.library, element);
5927 expect(unit.accessors, hasLength(0));
5928 expect(unit.functions, hasLength(0));
5929 expect(unit.functionTypeAliases, hasLength(0));
5930 expect(unit.types, hasLength(0));
5931 expect(unit.topLevelVariables, hasLength(0));
5932 }
5933
5934 void test_libraryElement_docRange() {
5935 String code = r'''
5936 /// My dart doc.
5937 library lib;
5938
5939 class A {}''';
5940 Source librarySource = addSource("/lib.dart", code);
5941 LibraryElement element = _buildLibrary(librarySource);
5942 expect(element, isNotNull);
5943 SourceRange docRange = element.docRange;
5944 expect(docRange, isNotNull);
5945 expect(docRange.offset, code.indexOf('/// My dart doc.'));
5946 expect(docRange.length, '/// My dart doc.'.length);
5947 }
5948
5949 void test_missingLibraryDirectiveWithPart() {
5950 addSource("/a.dart", "part of lib;");
5951 Source librarySource = addSource("/lib.dart", "part 'a.dart';");
5952 LibraryElement element = _buildLibrary(
5953 librarySource, [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]);
5954 expect(element, isNotNull);
5955 }
5956
5957 void test_missingPartOfDirective() {
5958 addSource("/a.dart", "class A {}");
5959 Source librarySource = addSource(
5960 "/lib.dart",
5961 r'''
5962 library lib;
5963
5964 part 'a.dart';''');
5965 LibraryElement element =
5966 _buildLibrary(librarySource, [CompileTimeErrorCode.PART_OF_NON_PART]);
5967 expect(element, isNotNull);
5968 }
5969
5970 void test_multipleFiles() {
5971 Source librarySource = addSource(
5972 "/lib.dart",
5973 r'''
5974 library lib;
5975 part 'first.dart';
5976 part 'second.dart';
5977
5978 class A {}''');
5979 addSource(
5980 "/first.dart",
5981 r'''
5982 part of lib;
5983 class B {}''');
5984 addSource(
5985 "/second.dart",
5986 r'''
5987 part of lib;
5988 class C {}''');
5989 LibraryElement element = _buildLibrary(librarySource);
5990 expect(element, isNotNull);
5991 List<CompilationUnitElement> sourcedUnits = element.parts;
5992 expect(sourcedUnits, hasLength(2));
5993 _assertTypes(element.definingCompilationUnit, ["A"]);
5994 if (sourcedUnits[0].name == "first.dart") {
5995 _assertTypes(sourcedUnits[0], ["B"]);
5996 _assertTypes(sourcedUnits[1], ["C"]);
5997 } else {
5998 _assertTypes(sourcedUnits[0], ["C"]);
5999 _assertTypes(sourcedUnits[1], ["B"]);
6000 }
6001 }
6002
6003 void test_singleFile() {
6004 Source librarySource = addSource(
6005 "/lib.dart",
6006 r'''
6007 /// My dart doc.
6008 library lib;
6009
6010 class A {}''');
6011 LibraryElement element = _buildLibrary(librarySource);
6012 expect(element, isNotNull);
6013 _assertTypes(element.definingCompilationUnit, ["A"]);
6014 }
6015
6016 /**
6017 * Ensure that there are elements representing all of the types in the given a rray of type names.
6018 *
6019 * @param unit the compilation unit containing the types
6020 * @param typeNames the names of the types that should be found
6021 */
6022 void _assertTypes(CompilationUnitElement unit, List<String> typeNames) {
6023 expect(unit, isNotNull);
6024 List<ClassElement> types = unit.types;
6025 expect(types, hasLength(typeNames.length));
6026 for (ClassElement type in types) {
6027 expect(type, isNotNull);
6028 String actualTypeName = type.displayName;
6029 bool wasExpected = false;
6030 for (String expectedTypeName in typeNames) {
6031 if (expectedTypeName == actualTypeName) {
6032 wasExpected = true;
6033 }
6034 }
6035 if (!wasExpected) {
6036 fail("Found unexpected type $actualTypeName");
6037 }
6038 }
6039 }
6040
6041 /**
6042 * Build the element model for the library whose defining compilation unit has the given source.
6043 *
6044 * @param librarySource the source of the defining compilation unit for the li brary
6045 * @param expectedErrorCodes the errors that are expected to be found while bu ilding the element
6046 * model
6047 * @return the element model that was built for the library
6048 * @throws Exception if the element model could not be built
6049 */
6050 LibraryElement _buildLibrary(Source librarySource,
6051 [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
6052 LibraryResolver resolver = new LibraryResolver(_context);
6053 LibraryElementBuilder builder = new LibraryElementBuilder(
6054 resolver.analysisContext, resolver.errorListener);
6055 Library library = resolver.createLibrary(librarySource);
6056 LibraryElement element = builder.buildLibrary(library);
6057 GatheringErrorListener listener = new GatheringErrorListener();
6058 listener.addAll2(resolver.errorListener);
6059 listener.assertErrorsWithCodes(expectedErrorCodes);
6060 return element;
6061 }
6062 }
6063
6064 @reflectiveTest
6065 class LibraryImportScopeTest extends ResolverTestCase {
6066 void test_conflictingImports() {
6067 AnalysisContext context = AnalysisContextFactory.contextWithCore();
6068 String typeNameA = "A";
6069 String typeNameB = "B";
6070 String typeNameC = "C";
6071 ClassElement typeA = ElementFactory.classElement2(typeNameA);
6072 ClassElement typeB1 = ElementFactory.classElement2(typeNameB);
6073 ClassElement typeB2 = ElementFactory.classElement2(typeNameB);
6074 ClassElement typeC = ElementFactory.classElement2(typeNameC);
6075 LibraryElement importedLibrary1 = createTestLibrary(context, "imported1");
6076 (importedLibrary1.definingCompilationUnit as CompilationUnitElementImpl)
6077 .types = <ClassElement>[typeA, typeB1];
6078 ImportElementImpl import1 =
6079 ElementFactory.importFor(importedLibrary1, null);
6080 LibraryElement importedLibrary2 = createTestLibrary(context, "imported2");
6081 (importedLibrary2.definingCompilationUnit as CompilationUnitElementImpl)
6082 .types = <ClassElement>[typeB2, typeC];
6083 ImportElementImpl import2 =
6084 ElementFactory.importFor(importedLibrary2, null);
6085 LibraryElementImpl importingLibrary =
6086 createTestLibrary(context, "importing");
6087 importingLibrary.imports = <ImportElement>[import1, import2];
6088 {
6089 GatheringErrorListener errorListener = new GatheringErrorListener();
6090 Scope scope = new LibraryImportScope(importingLibrary, errorListener);
6091 expect(scope.lookup(AstFactory.identifier3(typeNameA), importingLibrary),
6092 typeA);
6093 errorListener.assertNoErrors();
6094 expect(scope.lookup(AstFactory.identifier3(typeNameC), importingLibrary),
6095 typeC);
6096 errorListener.assertNoErrors();
6097 Element element =
6098 scope.lookup(AstFactory.identifier3(typeNameB), importingLibrary);
6099 errorListener.assertErrorsWithCodes([StaticWarningCode.AMBIGUOUS_IMPORT]);
6100 EngineTestCase.assertInstanceOf((obj) => obj is MultiplyDefinedElement,
6101 MultiplyDefinedElement, element);
6102 List<Element> conflictingElements =
6103 (element as MultiplyDefinedElement).conflictingElements;
6104 expect(conflictingElements, hasLength(2));
6105 if (identical(conflictingElements[0], typeB1)) {
6106 expect(conflictingElements[1], same(typeB2));
6107 } else if (identical(conflictingElements[0], typeB2)) {
6108 expect(conflictingElements[1], same(typeB1));
6109 } else {
6110 expect(conflictingElements[0], same(typeB1));
6111 }
6112 }
6113 {
6114 GatheringErrorListener errorListener = new GatheringErrorListener();
6115 Scope scope = new LibraryImportScope(importingLibrary, errorListener);
6116 Identifier identifier = AstFactory.identifier3(typeNameB);
6117 AstFactory.methodDeclaration(null, AstFactory.typeName3(identifier), null,
6118 null, AstFactory.identifier3("foo"), null);
6119 Element element = scope.lookup(identifier, importingLibrary);
6120 errorListener.assertErrorsWithCodes([StaticWarningCode.AMBIGUOUS_IMPORT]);
6121 EngineTestCase.assertInstanceOf((obj) => obj is MultiplyDefinedElement,
6122 MultiplyDefinedElement, element);
6123 }
6124 }
6125
6126 void test_creation_empty() {
6127 LibraryElement definingLibrary = createDefaultTestLibrary();
6128 GatheringErrorListener errorListener = new GatheringErrorListener();
6129 new LibraryImportScope(definingLibrary, errorListener);
6130 }
6131
6132 void test_creation_nonEmpty() {
6133 AnalysisContext context = AnalysisContextFactory.contextWithCore();
6134 String importedTypeName = "A";
6135 ClassElement importedType =
6136 new ClassElementImpl.forNode(AstFactory.identifier3(importedTypeName));
6137 LibraryElement importedLibrary = createTestLibrary(context, "imported");
6138 (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
6139 .types = <ClassElement>[importedType];
6140 LibraryElementImpl definingLibrary =
6141 createTestLibrary(context, "importing");
6142 ImportElementImpl importElement = new ImportElementImpl(0);
6143 importElement.importedLibrary = importedLibrary;
6144 definingLibrary.imports = <ImportElement>[importElement];
6145 GatheringErrorListener errorListener = new GatheringErrorListener();
6146 Scope scope = new LibraryImportScope(definingLibrary, errorListener);
6147 expect(
6148 scope.lookup(AstFactory.identifier3(importedTypeName), definingLibrary),
6149 importedType);
6150 }
6151
6152 void test_getErrorListener() {
6153 LibraryElement definingLibrary = createDefaultTestLibrary();
6154 GatheringErrorListener errorListener = new GatheringErrorListener();
6155 LibraryImportScope scope =
6156 new LibraryImportScope(definingLibrary, errorListener);
6157 expect(scope.errorListener, errorListener);
6158 }
6159
6160 void test_nonConflictingImports_fromSdk() {
6161 AnalysisContext context = AnalysisContextFactory.contextWithCore();
6162 String typeName = "List";
6163 ClassElement type = ElementFactory.classElement2(typeName);
6164 LibraryElement importedLibrary = createTestLibrary(context, "lib");
6165 (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
6166 .types = <ClassElement>[type];
6167 ImportElementImpl importCore = ElementFactory.importFor(
6168 context.getLibraryElement(context.sourceFactory.forUri("dart:core")),
6169 null);
6170 ImportElementImpl importLib =
6171 ElementFactory.importFor(importedLibrary, null);
6172 LibraryElementImpl importingLibrary =
6173 createTestLibrary(context, "importing");
6174 importingLibrary.imports = <ImportElement>[importCore, importLib];
6175 GatheringErrorListener errorListener = new GatheringErrorListener();
6176 Scope scope = new LibraryImportScope(importingLibrary, errorListener);
6177 expect(
6178 scope.lookup(AstFactory.identifier3(typeName), importingLibrary), type);
6179 errorListener
6180 .assertErrorsWithCodes([StaticWarningCode.CONFLICTING_DART_IMPORT]);
6181 }
6182
6183 void test_nonConflictingImports_sameElement() {
6184 AnalysisContext context = AnalysisContextFactory.contextWithCore();
6185 String typeNameA = "A";
6186 String typeNameB = "B";
6187 ClassElement typeA = ElementFactory.classElement2(typeNameA);
6188 ClassElement typeB = ElementFactory.classElement2(typeNameB);
6189 LibraryElement importedLibrary = createTestLibrary(context, "imported");
6190 (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
6191 .types = <ClassElement>[typeA, typeB];
6192 ImportElementImpl import1 = ElementFactory.importFor(importedLibrary, null);
6193 ImportElementImpl import2 = ElementFactory.importFor(importedLibrary, null);
6194 LibraryElementImpl importingLibrary =
6195 createTestLibrary(context, "importing");
6196 importingLibrary.imports = <ImportElement>[import1, import2];
6197 GatheringErrorListener errorListener = new GatheringErrorListener();
6198 Scope scope = new LibraryImportScope(importingLibrary, errorListener);
6199 expect(scope.lookup(AstFactory.identifier3(typeNameA), importingLibrary),
6200 typeA);
6201 errorListener.assertNoErrors();
6202 expect(scope.lookup(AstFactory.identifier3(typeNameB), importingLibrary),
6203 typeB);
6204 errorListener.assertNoErrors();
6205 }
6206
6207 void test_prefixedAndNonPrefixed() {
6208 AnalysisContext context = AnalysisContextFactory.contextWithCore();
6209 String typeName = "C";
6210 String prefixName = "p";
6211 ClassElement prefixedType = ElementFactory.classElement2(typeName);
6212 ClassElement nonPrefixedType = ElementFactory.classElement2(typeName);
6213 LibraryElement prefixedLibrary =
6214 createTestLibrary(context, "import.prefixed");
6215 (prefixedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
6216 .types = <ClassElement>[prefixedType];
6217 ImportElementImpl prefixedImport = ElementFactory.importFor(
6218 prefixedLibrary, ElementFactory.prefix(prefixName));
6219 LibraryElement nonPrefixedLibrary =
6220 createTestLibrary(context, "import.nonPrefixed");
6221 (nonPrefixedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
6222 .types = <ClassElement>[nonPrefixedType];
6223 ImportElementImpl nonPrefixedImport =
6224 ElementFactory.importFor(nonPrefixedLibrary, null);
6225 LibraryElementImpl importingLibrary =
6226 createTestLibrary(context, "importing");
6227 importingLibrary.imports = <ImportElement>[
6228 prefixedImport,
6229 nonPrefixedImport
6230 ];
6231 GatheringErrorListener errorListener = new GatheringErrorListener();
6232 Scope scope = new LibraryImportScope(importingLibrary, errorListener);
6233 Element prefixedElement = scope.lookup(
6234 AstFactory.identifier5(prefixName, typeName), importingLibrary);
6235 errorListener.assertNoErrors();
6236 expect(prefixedElement, same(prefixedType));
6237 Element nonPrefixedElement =
6238 scope.lookup(AstFactory.identifier3(typeName), importingLibrary);
6239 errorListener.assertNoErrors();
6240 expect(nonPrefixedElement, same(nonPrefixedType));
6241 }
6242 }
6243
6244 @reflectiveTest
6245 class LibraryResolver2Test extends ResolverTestCase {
6246 LibraryResolver2 _resolver;
6247
6248 Source _coreLibrarySource;
6249
6250 Source _asyncLibrarySource;
6251
6252 @override
6253 void setUp() {
6254 super.setUp();
6255 _resolver = new LibraryResolver2(analysisContext2);
6256 _coreLibrarySource =
6257 analysisContext2.sourceFactory.forUri(DartSdk.DART_CORE);
6258 _asyncLibrarySource =
6259 analysisContext2.sourceFactory.forUri(DartSdk.DART_ASYNC);
6260 }
6261
6262 void test_imports_relative() {
6263 Source sourceA = addSource(r'''
6264 library libA;
6265 import 'libB.dart';
6266 class A {}''');
6267 Source sourceB = addNamedSource(
6268 "/libB.dart",
6269 r'''
6270 library libB;
6271 import 'test.dart
6272 class B {}''');
6273 List<ResolvableLibrary> cycle = new List<ResolvableLibrary>();
6274 ResolvableLibrary coreLib = _createResolvableLibrary(_coreLibrarySource);
6275 coreLib.libraryElement = analysisContext2
6276 .computeLibraryElement(_coreLibrarySource) as LibraryElementImpl;
6277 ResolvableLibrary asyncLib = _createResolvableLibrary(_asyncLibrarySource);
6278 asyncLib.libraryElement = analysisContext2
6279 .computeLibraryElement(_asyncLibrarySource) as LibraryElementImpl;
6280 ResolvableLibrary libA = _createResolvableLibrary(sourceA);
6281 ResolvableLibrary libB = _createResolvableLibrary(sourceB);
6282 libA.importedLibraries = <ResolvableLibrary>[coreLib, asyncLib, libB];
6283 libB.importedLibraries = <ResolvableLibrary>[coreLib, asyncLib, libA];
6284 cycle.add(libA);
6285 cycle.add(libB);
6286 LibraryElement library = _resolver.resolveLibrary(sourceA, cycle);
6287 List<LibraryElement> importedLibraries = library.importedLibraries;
6288 assertNamedElements(importedLibraries, ["dart.core", "libB"]);
6289 }
6290
6291 ResolvableLibrary _createResolvableLibrary(Source source) {
6292 CompilationUnit unit = analysisContext2.parseCompilationUnit(source);
6293 ResolvableLibrary resolvableLibrary = new ResolvableLibrary(source);
6294 resolvableLibrary.resolvableCompilationUnits = <ResolvableCompilationUnit>[
6295 new ResolvableCompilationUnit(source, unit)
6296 ];
6297 return resolvableLibrary;
6298 }
6299 }
6300
6301 @reflectiveTest
6302 class LibraryResolverTest extends ResolverTestCase {
6303 LibraryResolver _resolver;
6304
6305 @override
6306 void setUp() {
6307 super.setUp();
6308 _resolver = new LibraryResolver(analysisContext2);
6309 }
6310
6311 void test_imports_dart_html() {
6312 Source source = addSource(r'''
6313 library libA;
6314 import 'dart:html';
6315 class A {}''');
6316 LibraryElement library = _resolver.resolveLibrary(source, true);
6317 List<LibraryElement> importedLibraries = library.importedLibraries;
6318 assertNamedElements(importedLibraries, ["dart.core", "dart.dom.html"]);
6319 }
6320
6321 void test_imports_none() {
6322 Source source = addSource(r'''
6323 library libA;
6324 class A {}''');
6325 LibraryElement library = _resolver.resolveLibrary(source, true);
6326 List<LibraryElement> importedLibraries = library.importedLibraries;
6327 assertNamedElements(importedLibraries, ["dart.core"]);
6328 }
6329
6330 void test_imports_relative() {
6331 addNamedSource("/libB.dart", "library libB;");
6332 Source source = addSource(r'''
6333 library libA;
6334 import 'libB.dart';
6335 class A {}''');
6336 LibraryElement library = _resolver.resolveLibrary(source, true);
6337 List<LibraryElement> importedLibraries = library.importedLibraries;
6338 assertNamedElements(importedLibraries, ["dart.core", "libB"]);
6339 }
6340 }
6341
6342 @reflectiveTest
6343 class LibraryScopeTest extends ResolverTestCase {
6344 void test_creation_empty() {
6345 LibraryElement definingLibrary = createDefaultTestLibrary();
6346 GatheringErrorListener errorListener = new GatheringErrorListener();
6347 new LibraryScope(definingLibrary, errorListener);
6348 }
6349
6350 void test_creation_nonEmpty() {
6351 AnalysisContext context = AnalysisContextFactory.contextWithCore();
6352 String importedTypeName = "A";
6353 ClassElement importedType =
6354 new ClassElementImpl.forNode(AstFactory.identifier3(importedTypeName));
6355 LibraryElement importedLibrary = createTestLibrary(context, "imported");
6356 (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
6357 .types = <ClassElement>[importedType];
6358 LibraryElementImpl definingLibrary =
6359 createTestLibrary(context, "importing");
6360 ImportElementImpl importElement = new ImportElementImpl(0);
6361 importElement.importedLibrary = importedLibrary;
6362 definingLibrary.imports = <ImportElement>[importElement];
6363 GatheringErrorListener errorListener = new GatheringErrorListener();
6364 Scope scope = new LibraryScope(definingLibrary, errorListener);
6365 expect(
6366 scope.lookup(AstFactory.identifier3(importedTypeName), definingLibrary),
6367 importedType);
6368 }
6369
6370 void test_getErrorListener() {
6371 LibraryElement definingLibrary = createDefaultTestLibrary();
6372 GatheringErrorListener errorListener = new GatheringErrorListener();
6373 LibraryScope scope = new LibraryScope(definingLibrary, errorListener);
6374 expect(scope.errorListener, errorListener);
6375 }
6376 }
6377
6378 @reflectiveTest
6379 class LibraryTest extends EngineTestCase {
6380 /**
6381 * The error listener to which all errors will be reported.
6382 */
6383 GatheringErrorListener _errorListener;
6384
6385 /**
6386 * The analysis context to pass in to all libraries created by the tests.
6387 */
6388 InternalAnalysisContext _analysisContext;
6389
6390 /**
6391 * The library used by the tests.
6392 */
6393 Library _library;
6394
6395 @override
6396 void setUp() {
6397 _analysisContext = AnalysisContextFactory.contextWithCore();
6398 _errorListener = new GatheringErrorListener();
6399 _library = _createLibrary("/lib.dart");
6400 }
6401
6402 @override
6403 void tearDown() {
6404 _errorListener = null;
6405 _analysisContext = null;
6406 _library = null;
6407 super.tearDown();
6408 }
6409
6410 void test_getExplicitlyImportsCore() {
6411 expect(_library.explicitlyImportsCore, isFalse);
6412 _errorListener.assertNoErrors();
6413 }
6414
6415 void test_getExports() {
6416 expect(_library.exports, hasLength(0));
6417 _errorListener.assertNoErrors();
6418 }
6419
6420 void test_getImports() {
6421 expect(_library.imports, hasLength(0));
6422 _errorListener.assertNoErrors();
6423 }
6424
6425 void test_getImportsAndExports() {
6426 _library.importedLibraries = <Library>[_createLibrary("/imported.dart")];
6427 _library.exportedLibraries = <Library>[_createLibrary("/exported.dart")];
6428 expect(_library.importsAndExports, hasLength(2));
6429 _errorListener.assertNoErrors();
6430 }
6431
6432 void test_getLibraryScope() {
6433 LibraryElementImpl element = new LibraryElementImpl.forNode(
6434 _analysisContext, AstFactory.libraryIdentifier2(["lib"]));
6435 element.definingCompilationUnit =
6436 new CompilationUnitElementImpl("lib.dart");
6437 _library.libraryElement = element;
6438 expect(_library.libraryScope, isNotNull);
6439 _errorListener.assertNoErrors();
6440 }
6441
6442 void test_getLibrarySource() {
6443 expect(_library.librarySource, isNotNull);
6444 }
6445
6446 void test_setExplicitlyImportsCore() {
6447 _library.explicitlyImportsCore = true;
6448 expect(_library.explicitlyImportsCore, isTrue);
6449 _errorListener.assertNoErrors();
6450 }
6451
6452 void test_setExportedLibraries() {
6453 Library exportLibrary = _createLibrary("/exported.dart");
6454 _library.exportedLibraries = <Library>[exportLibrary];
6455 List<Library> exports = _library.exports;
6456 expect(exports, hasLength(1));
6457 expect(exports[0], same(exportLibrary));
6458 _errorListener.assertNoErrors();
6459 }
6460
6461 void test_setImportedLibraries() {
6462 Library importLibrary = _createLibrary("/imported.dart");
6463 _library.importedLibraries = <Library>[importLibrary];
6464 List<Library> imports = _library.imports;
6465 expect(imports, hasLength(1));
6466 expect(imports[0], same(importLibrary));
6467 _errorListener.assertNoErrors();
6468 }
6469
6470 void test_setLibraryElement() {
6471 LibraryElementImpl element = new LibraryElementImpl.forNode(
6472 _analysisContext, AstFactory.libraryIdentifier2(["lib"]));
6473 _library.libraryElement = element;
6474 expect(_library.libraryElement, same(element));
6475 }
6476
6477 Library _createLibrary(String definingCompilationUnitPath) => new Library(
6478 _analysisContext,
6479 _errorListener,
6480 new FileBasedSource(
6481 FileUtilities2.createFile(definingCompilationUnitPath)));
6482 }
6483
6484 @reflectiveTest
6485 class MemberMapTest {
6486 /**
6487 * The null type.
6488 */
6489 InterfaceType _nullType;
6490
6491 void setUp() {
6492 _nullType = new TestTypeProvider().nullType;
6493 }
6494
6495 void test_MemberMap_copyConstructor() {
6496 MethodElement m1 = ElementFactory.methodElement("m1", _nullType);
6497 MethodElement m2 = ElementFactory.methodElement("m2", _nullType);
6498 MethodElement m3 = ElementFactory.methodElement("m3", _nullType);
6499 MemberMap map = new MemberMap();
6500 map.put(m1.name, m1);
6501 map.put(m2.name, m2);
6502 map.put(m3.name, m3);
6503 MemberMap copy = new MemberMap.from(map);
6504 expect(copy.size, map.size);
6505 expect(copy.get(m1.name), m1);
6506 expect(copy.get(m2.name), m2);
6507 expect(copy.get(m3.name), m3);
6508 }
6509
6510 void test_MemberMap_override() {
6511 MethodElement m1 = ElementFactory.methodElement("m", _nullType);
6512 MethodElement m2 = ElementFactory.methodElement("m", _nullType);
6513 MemberMap map = new MemberMap();
6514 map.put(m1.name, m1);
6515 map.put(m2.name, m2);
6516 expect(map.size, 1);
6517 expect(map.get("m"), m2);
6518 }
6519
6520 void test_MemberMap_put() {
6521 MethodElement m1 = ElementFactory.methodElement("m1", _nullType);
6522 MemberMap map = new MemberMap();
6523 expect(map.size, 0);
6524 map.put(m1.name, m1);
6525 expect(map.size, 1);
6526 expect(map.get("m1"), m1);
6527 }
6528 }
6529
6530 /**
6531 * An analysis context that has a fake SDK that is much smaller and faster for
6532 * testing purposes.
6533 */
6534 class NewAnalysisContextForTests extends newContext.AnalysisContextImpl {
6535 @override
6536 void set analysisOptions(AnalysisOptions options) {
6537 AnalysisOptions currentOptions = analysisOptions;
6538 bool needsRecompute = currentOptions.analyzeFunctionBodiesPredicate !=
6539 options.analyzeFunctionBodiesPredicate ||
6540 currentOptions.generateImplicitErrors !=
6541 options.generateImplicitErrors ||
6542 currentOptions.generateSdkErrors != options.generateSdkErrors ||
6543 currentOptions.dart2jsHint != options.dart2jsHint ||
6544 (currentOptions.hint && !options.hint) ||
6545 currentOptions.preserveComments != options.preserveComments ||
6546 currentOptions.enableStrictCallChecks != options.enableStrictCallChecks;
6547 if (needsRecompute) {
6548 fail(
6549 "Cannot set options that cause the sources to be reanalyzed in a test context");
6550 }
6551 super.analysisOptions = options;
6552 }
6553
6554 @override
6555 bool exists(Source source) =>
6556 super.exists(source) || sourceFactory.dartSdk.context.exists(source);
6557
6558 @override
6559 TimestampedData<String> getContents(Source source) {
6560 if (source.isInSystemLibrary) {
6561 return sourceFactory.dartSdk.context.getContents(source);
6562 }
6563 return super.getContents(source);
6564 }
6565
6566 @override
6567 int getModificationStamp(Source source) {
6568 if (source.isInSystemLibrary) {
6569 return sourceFactory.dartSdk.context.getModificationStamp(source);
6570 }
6571 return super.getModificationStamp(source);
6572 }
6573
6574 /**
6575 * Set the analysis options, even if they would force re-analysis. This method should only be
6576 * invoked before the fake SDK is initialized.
6577 *
6578 * @param options the analysis options to be set
6579 */
6580 void _internalSetAnalysisOptions(AnalysisOptions options) {
6581 super.analysisOptions = options;
6582 }
6583 }
6584
6585 @reflectiveTest
6586 class NonHintCodeTest extends ResolverTestCase {
6587 void test_deadCode_deadBlock_conditionalElse_debugConst() {
6588 Source source = addSource(r'''
6589 const bool DEBUG = true;
6590 f() {
6591 DEBUG ? 1 : 2;
6592 }''');
6593 computeLibrarySourceErrors(source);
6594 assertNoErrors(source);
6595 verify([source]);
6596 }
6597
6598 void test_deadCode_deadBlock_conditionalIf_debugConst() {
6599 Source source = addSource(r'''
6600 const bool DEBUG = false;
6601 f() {
6602 DEBUG ? 1 : 2;
6603 }''');
6604 computeLibrarySourceErrors(source);
6605 assertNoErrors(source);
6606 verify([source]);
6607 }
6608
6609 void test_deadCode_deadBlock_else() {
6610 Source source = addSource(r'''
6611 const bool DEBUG = true;
6612 f() {
6613 if(DEBUG) {} else {}
6614 }''');
6615 computeLibrarySourceErrors(source);
6616 assertNoErrors(source);
6617 verify([source]);
6618 }
6619
6620 void test_deadCode_deadBlock_if_debugConst_prefixedIdentifier() {
6621 Source source = addSource(r'''
6622 class A {
6623 static const bool DEBUG = false;
6624 }
6625 f() {
6626 if(A.DEBUG) {}
6627 }''');
6628 computeLibrarySourceErrors(source);
6629 assertNoErrors(source);
6630 verify([source]);
6631 }
6632
6633 void test_deadCode_deadBlock_if_debugConst_prefixedIdentifier2() {
6634 Source source = addSource(r'''
6635 library L;
6636 import 'lib2.dart';
6637 f() {
6638 if(A.DEBUG) {}
6639 }''');
6640 addNamedSource(
6641 "/lib2.dart",
6642 r'''
6643 library lib2;
6644 class A {
6645 static const bool DEBUG = false;
6646 }''');
6647 computeLibrarySourceErrors(source);
6648 assertNoErrors(source);
6649 verify([source]);
6650 }
6651
6652 void test_deadCode_deadBlock_if_debugConst_propertyAccessor() {
6653 Source source = addSource(r'''
6654 library L;
6655 import 'lib2.dart' as LIB;
6656 f() {
6657 if(LIB.A.DEBUG) {}
6658 }''');
6659 addNamedSource(
6660 "/lib2.dart",
6661 r'''
6662 library lib2;
6663 class A {
6664 static const bool DEBUG = false;
6665 }''');
6666 computeLibrarySourceErrors(source);
6667 assertNoErrors(source);
6668 verify([source]);
6669 }
6670
6671 void test_deadCode_deadBlock_if_debugConst_simpleIdentifier() {
6672 Source source = addSource(r'''
6673 const bool DEBUG = false;
6674 f() {
6675 if(DEBUG) {}
6676 }''');
6677 computeLibrarySourceErrors(source);
6678 assertNoErrors(source);
6679 verify([source]);
6680 }
6681
6682 void test_deadCode_deadBlock_while_debugConst() {
6683 Source source = addSource(r'''
6684 const bool DEBUG = false;
6685 f() {
6686 while(DEBUG) {}
6687 }''');
6688 computeLibrarySourceErrors(source);
6689 assertNoErrors(source);
6690 verify([source]);
6691 }
6692
6693 void test_deadCode_deadCatch_onCatchSubtype() {
6694 Source source = addSource(r'''
6695 class A {}
6696 class B extends A {}
6697 f() {
6698 try {} on B catch (e) {} on A catch (e) {} catch (e) {}
6699 }''');
6700 computeLibrarySourceErrors(source);
6701 assertNoErrors(source);
6702 verify([source]);
6703 }
6704
6705 void test_deadCode_deadOperandLHS_and_debugConst() {
6706 Source source = addSource(r'''
6707 const bool DEBUG = false;
6708 f() {
6709 bool b = DEBUG && false;
6710 }''');
6711 computeLibrarySourceErrors(source);
6712 assertNoErrors(source);
6713 verify([source]);
6714 }
6715
6716 void test_deadCode_deadOperandLHS_or_debugConst() {
6717 Source source = addSource(r'''
6718 const bool DEBUG = true;
6719 f() {
6720 bool b = DEBUG || true;
6721 }''');
6722 computeLibrarySourceErrors(source);
6723 assertNoErrors(source);
6724 verify([source]);
6725 }
6726
6727 void test_divisionOptimization() {
6728 Source source = addSource(r'''
6729 f(int x, int y) {
6730 var v = x / y.toInt();
6731 }''');
6732 computeLibrarySourceErrors(source);
6733 assertNoErrors(source);
6734 verify([source]);
6735 }
6736
6737 void test_divisionOptimization_supressIfDivisionNotDefinedInCore() {
6738 Source source = addSource(r'''
6739 f(x, y) {
6740 var v = (x / y).toInt();
6741 }''');
6742 computeLibrarySourceErrors(source);
6743 assertNoErrors(source);
6744 verify([source]);
6745 }
6746
6747 void test_divisionOptimization_supressIfDivisionOverridden() {
6748 Source source = addSource(r'''
6749 class A {
6750 num operator /(x) { return x; }
6751 }
6752 f(A x, A y) {
6753 var v = (x / y).toInt();
6754 }''');
6755 computeLibrarySourceErrors(source);
6756 assertNoErrors(source);
6757 verify([source]);
6758 }
6759
6760 void test_duplicateImport_as() {
6761 Source source = addSource(r'''
6762 library L;
6763 import 'lib1.dart';
6764 import 'lib1.dart' as one;
6765 A a;
6766 one.A a2;''');
6767 addNamedSource(
6768 "/lib1.dart",
6769 r'''
6770 library lib1;
6771 class A {}''');
6772 computeLibrarySourceErrors(source);
6773 assertNoErrors(source);
6774 verify([source]);
6775 }
6776
6777 void test_duplicateImport_hide() {
6778 Source source = addSource(r'''
6779 library L;
6780 import 'lib1.dart';
6781 import 'lib1.dart' hide A;
6782 A a;
6783 B b;''');
6784 addNamedSource(
6785 "/lib1.dart",
6786 r'''
6787 library lib1;
6788 class A {}
6789 class B {}''');
6790 computeLibrarySourceErrors(source);
6791 assertNoErrors(source);
6792 verify([source]);
6793 }
6794
6795 void test_duplicateImport_show() {
6796 Source source = addSource(r'''
6797 library L;
6798 import 'lib1.dart';
6799 import 'lib1.dart' show A;
6800 A a;
6801 B b;''');
6802 addNamedSource(
6803 "/lib1.dart",
6804 r'''
6805 library lib1;
6806 class A {}
6807 class B {}''');
6808 computeLibrarySourceErrors(source);
6809 assertNoErrors(source);
6810 verify([source]);
6811 }
6812
6813 void test_importDeferredLibraryWithLoadFunction() {
6814 resolveWithErrors(<String>[
6815 r'''
6816 library lib1;
6817 f() {}''',
6818 r'''
6819 library root;
6820 import 'lib1.dart' deferred as lib1;
6821 main() { lib1.f(); }'''
6822 ], ErrorCode.EMPTY_LIST);
6823 }
6824
6825 void test_issue20904BuggyTypePromotionAtIfJoin_1() {
6826 // https://code.google.com/p/dart/issues/detail?id=20904
6827 Source source = addSource(r'''
6828 f(var message, var dynamic_) {
6829 if (message is Function) {
6830 message = dynamic_;
6831 }
6832 int s = message;
6833 }''');
6834 computeLibrarySourceErrors(source);
6835 assertNoErrors(source);
6836 verify([source]);
6837 }
6838
6839 void test_issue20904BuggyTypePromotionAtIfJoin_3() {
6840 // https://code.google.com/p/dart/issues/detail?id=20904
6841 Source source = addSource(r'''
6842 f(var message) {
6843 var dynamic_;
6844 if (message is Function) {
6845 message = dynamic_;
6846 } else {
6847 return;
6848 }
6849 int s = message;
6850 }''');
6851 computeLibrarySourceErrors(source);
6852 assertNoErrors(source);
6853 verify([source]);
6854 }
6855
6856 void test_issue20904BuggyTypePromotionAtIfJoin_4() {
6857 // https://code.google.com/p/dart/issues/detail?id=20904
6858 Source source = addSource(r'''
6859 f(var message) {
6860 if (message is Function) {
6861 message = '';
6862 } else {
6863 return;
6864 }
6865 String s = message;
6866 }''');
6867 computeLibrarySourceErrors(source);
6868 assertNoErrors(source);
6869 verify([source]);
6870 }
6871
6872 void test_missingReturn_emptyFunctionBody() {
6873 Source source = addSource(r'''
6874 abstract class A {
6875 int m();
6876 }''');
6877 computeLibrarySourceErrors(source);
6878 assertNoErrors(source);
6879 verify([source]);
6880 }
6881
6882 void test_missingReturn_expressionFunctionBody() {
6883 Source source = addSource("int f() => 0;");
6884 computeLibrarySourceErrors(source);
6885 assertNoErrors(source);
6886 verify([source]);
6887 }
6888
6889 void test_missingReturn_noReturnType() {
6890 Source source = addSource("f() {}");
6891 computeLibrarySourceErrors(source);
6892 assertNoErrors(source);
6893 verify([source]);
6894 }
6895
6896 void test_missingReturn_voidReturnType() {
6897 Source source = addSource("void f() {}");
6898 computeLibrarySourceErrors(source);
6899 assertNoErrors(source);
6900 verify([source]);
6901 }
6902
6903 void test_overrideEqualsButNotHashCode() {
6904 Source source = addSource(r'''
6905 class A {
6906 bool operator ==(x) { return x; }
6907 get hashCode => 0;
6908 }''');
6909 computeLibrarySourceErrors(source);
6910 assertNoErrors(source);
6911 verify([source]);
6912 }
6913
6914 void test_overrideOnNonOverridingGetter_inInterface() {
6915 Source source = addSource(r'''
6916 library dart.core;
6917 const override = null;
6918 class A {
6919 int get m => 0;
6920 }
6921 class B implements A {
6922 @override
6923 int get m => 1;
6924 }''');
6925 computeLibrarySourceErrors(source);
6926 assertNoErrors(source);
6927 verify([source]);
6928 }
6929
6930 void test_overrideOnNonOverridingGetter_inSuperclass() {
6931 Source source = addSource(r'''
6932 library dart.core;
6933 const override = null;
6934 class A {
6935 int get m => 0;
6936 }
6937 class B extends A {
6938 @override
6939 int get m => 1;
6940 }''');
6941 computeLibrarySourceErrors(source);
6942 assertNoErrors(source);
6943 verify([source]);
6944 }
6945
6946 void test_overrideOnNonOverridingMethod_inInterface() {
6947 Source source = addSource(r'''
6948 library dart.core;
6949 const override = null;
6950 class A {
6951 int m() => 0;
6952 }
6953 class B implements A {
6954 @override
6955 int m() => 1;
6956 }''');
6957 computeLibrarySourceErrors(source);
6958 assertNoErrors(source);
6959 verify([source]);
6960 }
6961
6962 void test_overrideOnNonOverridingMethod_inSuperclass() {
6963 Source source = addSource(r'''
6964 library dart.core;
6965 const override = null;
6966 class A {
6967 int m() => 0;
6968 }
6969 class B extends A {
6970 @override
6971 int m() => 1;
6972 }''');
6973 computeLibrarySourceErrors(source);
6974 assertNoErrors(source);
6975 verify([source]);
6976 }
6977
6978 void test_overrideOnNonOverridingSetter_inInterface() {
6979 Source source = addSource(r'''
6980 library dart.core;
6981 const override = null;
6982 class A {
6983 set m(int x) {}
6984 }
6985 class B implements A {
6986 @override
6987 set m(int x) {}
6988 }''');
6989 computeLibrarySourceErrors(source);
6990 assertNoErrors(source);
6991 verify([source]);
6992 }
6993
6994 void test_overrideOnNonOverridingSetter_inSuperclass() {
6995 Source source = addSource(r'''
6996 library dart.core;
6997 const override = null;
6998 class A {
6999 set m(int x) {}
7000 }
7001 class B extends A {
7002 @override
7003 set m(int x) {}
7004 }''');
7005 computeLibrarySourceErrors(source);
7006 assertNoErrors(source);
7007 verify([source]);
7008 }
7009
7010 void test_propagatedFieldType() {
7011 Source source = addSource(r'''
7012 class A { }
7013 class X<T> {
7014 final x = new List<T>();
7015 }
7016 class Z {
7017 final X<A> y = new X<A>();
7018 foo() {
7019 y.x.add(new A());
7020 }
7021 }''');
7022 computeLibrarySourceErrors(source);
7023 assertNoErrors(source);
7024 verify([source]);
7025 }
7026
7027 void test_proxy_annotation_prefixed() {
7028 Source source = addSource(r'''
7029 library L;
7030 @proxy
7031 class A {}
7032 f(var a) {
7033 a = new A();
7034 a.m();
7035 var x = a.g;
7036 a.s = 1;
7037 var y = a + a;
7038 a++;
7039 ++a;
7040 }''');
7041 computeLibrarySourceErrors(source);
7042 assertNoErrors(source);
7043 }
7044
7045 void test_proxy_annotation_prefixed2() {
7046 Source source = addSource(r'''
7047 library L;
7048 @proxy
7049 class A {}
7050 class B {
7051 f(var a) {
7052 a = new A();
7053 a.m();
7054 var x = a.g;
7055 a.s = 1;
7056 var y = a + a;
7057 a++;
7058 ++a;
7059 }
7060 }''');
7061 computeLibrarySourceErrors(source);
7062 assertNoErrors(source);
7063 }
7064
7065 void test_proxy_annotation_prefixed3() {
7066 Source source = addSource(r'''
7067 library L;
7068 class B {
7069 f(var a) {
7070 a = new A();
7071 a.m();
7072 var x = a.g;
7073 a.s = 1;
7074 var y = a + a;
7075 a++;
7076 ++a;
7077 }
7078 }
7079 @proxy
7080 class A {}''');
7081 computeLibrarySourceErrors(source);
7082 assertNoErrors(source);
7083 }
7084
7085 void test_undefinedGetter_inSubtype() {
7086 Source source = addSource(r'''
7087 class A {}
7088 class B extends A {
7089 get b => 0;
7090 }
7091 f(var a) {
7092 if(a is A) {
7093 return a.b;
7094 }
7095 }''');
7096 computeLibrarySourceErrors(source);
7097 assertNoErrors(source);
7098 }
7099
7100 void test_undefinedMethod_assignmentExpression_inSubtype() {
7101 Source source = addSource(r'''
7102 class A {}
7103 class B extends A {
7104 operator +(B b) {return new B();}
7105 }
7106 f(var a, var a2) {
7107 a = new A();
7108 a2 = new A();
7109 a += a2;
7110 }''');
7111 computeLibrarySourceErrors(source);
7112 assertNoErrors(source);
7113 }
7114
7115 void test_undefinedMethod_dynamic() {
7116 Source source = addSource(r'''
7117 class D<T extends dynamic> {
7118 fieldAccess(T t) => t.abc;
7119 methodAccess(T t) => t.xyz(1, 2, 'three');
7120 }''');
7121 computeLibrarySourceErrors(source);
7122 assertNoErrors(source);
7123 }
7124
7125 void test_undefinedMethod_inSubtype() {
7126 Source source = addSource(r'''
7127 class A {}
7128 class B extends A {
7129 b() {}
7130 }
7131 f() {
7132 var a = new A();
7133 a.b();
7134 }''');
7135 computeLibrarySourceErrors(source);
7136 assertNoErrors(source);
7137 }
7138
7139 void test_undefinedMethod_unionType_all() {
7140 Source source = addSource(r'''
7141 class A {
7142 int m(int x) => 0;
7143 }
7144 class B {
7145 String m() => '0';
7146 }
7147 f(A a, B b) {
7148 var ab;
7149 if (0 < 1) {
7150 ab = a;
7151 } else {
7152 ab = b;
7153 }
7154 ab.m();
7155 }''');
7156 computeLibrarySourceErrors(source);
7157 assertNoErrors(source);
7158 }
7159
7160 void test_undefinedMethod_unionType_some() {
7161 Source source = addSource(r'''
7162 class A {
7163 int m(int x) => 0;
7164 }
7165 class B {}
7166 f(A a, B b) {
7167 var ab;
7168 if (0 < 1) {
7169 ab = a;
7170 } else {
7171 ab = b;
7172 }
7173 ab.m(0);
7174 }''');
7175 computeLibrarySourceErrors(source);
7176 assertNoErrors(source);
7177 }
7178
7179 void test_undefinedOperator_binaryExpression_inSubtype() {
7180 Source source = addSource(r'''
7181 class A {}
7182 class B extends A {
7183 operator +(B b) {}
7184 }
7185 f(var a) {
7186 if(a is A) {
7187 a + 1;
7188 }
7189 }''');
7190 computeLibrarySourceErrors(source);
7191 assertNoErrors(source);
7192 }
7193
7194 void test_undefinedOperator_indexBoth_inSubtype() {
7195 Source source = addSource(r'''
7196 class A {}
7197 class B extends A {
7198 operator [](int index) {}
7199 }
7200 f(var a) {
7201 if(a is A) {
7202 a[0]++;
7203 }
7204 }''');
7205 computeLibrarySourceErrors(source);
7206 assertNoErrors(source);
7207 }
7208
7209 void test_undefinedOperator_indexGetter_inSubtype() {
7210 Source source = addSource(r'''
7211 class A {}
7212 class B extends A {
7213 operator [](int index) {}
7214 }
7215 f(var a) {
7216 if(a is A) {
7217 a[0];
7218 }
7219 }''');
7220 computeLibrarySourceErrors(source);
7221 assertNoErrors(source);
7222 }
7223
7224 void test_undefinedOperator_indexSetter_inSubtype() {
7225 Source source = addSource(r'''
7226 class A {}
7227 class B extends A {
7228 operator []=(i, v) {}
7229 }
7230 f(var a) {
7231 if(a is A) {
7232 a[0] = 1;
7233 }
7234 }''');
7235 computeLibrarySourceErrors(source);
7236 assertNoErrors(source);
7237 }
7238
7239 void test_undefinedOperator_postfixExpression() {
7240 Source source = addSource(r'''
7241 class A {}
7242 class B extends A {
7243 operator +(B b) {return new B();}
7244 }
7245 f(var a) {
7246 if(a is A) {
7247 a++;
7248 }
7249 }''');
7250 computeLibrarySourceErrors(source);
7251 assertNoErrors(source);
7252 }
7253
7254 void test_undefinedOperator_prefixExpression() {
7255 Source source = addSource(r'''
7256 class A {}
7257 class B extends A {
7258 operator +(B b) {return new B();}
7259 }
7260 f(var a) {
7261 if(a is A) {
7262 ++a;
7263 }
7264 }''');
7265 computeLibrarySourceErrors(source);
7266 assertNoErrors(source);
7267 }
7268
7269 void test_undefinedSetter_inSubtype() {
7270 Source source = addSource(r'''
7271 class A {}
7272 class B extends A {
7273 set b(x) {}
7274 }
7275 f(var a) {
7276 if(a is A) {
7277 a.b = 0;
7278 }
7279 }''');
7280 computeLibrarySourceErrors(source);
7281 assertNoErrors(source);
7282 }
7283
7284 void test_unnecessaryCast_13855_parameter_A() {
7285 // dartbug.com/13855, dartbug.com/13732
7286 Source source = addSource(r'''
7287 class A{
7288 a() {}
7289 }
7290 class B<E> {
7291 E e;
7292 m() {
7293 (e as A).a();
7294 }
7295 }''');
7296 computeLibrarySourceErrors(source);
7297 assertNoErrors(source);
7298 verify([source]);
7299 }
7300
7301 void test_unnecessaryCast_conditionalExpression() {
7302 Source source = addSource(r'''
7303 abstract class I {}
7304 class A implements I {}
7305 class B implements I {}
7306 I m(A a, B b) {
7307 return a == null ? b as I : a as I;
7308 }''');
7309 computeLibrarySourceErrors(source);
7310 assertNoErrors(source);
7311 verify([source]);
7312 }
7313
7314 void test_unnecessaryCast_dynamic_type() {
7315 Source source = addSource(r'''
7316 m(v) {
7317 var b = v as Object;
7318 }''');
7319 computeLibrarySourceErrors(source);
7320 assertNoErrors(source);
7321 verify([source]);
7322 }
7323
7324 void test_unnecessaryCast_generics() {
7325 // dartbug.com/18953
7326 Source source = addSource(r'''
7327 import 'dart:async';
7328 Future<int> f() => new Future.value(0);
7329 void g(bool c) {
7330 (c ? f(): new Future.value(0) as Future<int>).then((int value) {});
7331 }''');
7332 computeLibrarySourceErrors(source);
7333 assertNoErrors(source);
7334 verify([source]);
7335 }
7336
7337 void test_unnecessaryCast_type_dynamic() {
7338 Source source = addSource(r'''
7339 m(v) {
7340 var b = Object as dynamic;
7341 }''');
7342 computeLibrarySourceErrors(source);
7343 assertNoErrors(source);
7344 verify([source]);
7345 }
7346
7347 void test_unusedImport_annotationOnDirective() {
7348 Source source = addSource(r'''
7349 library L;
7350 @A()
7351 import 'lib1.dart';''');
7352 Source source2 = addNamedSource(
7353 "/lib1.dart",
7354 r'''
7355 library lib1;
7356 class A {
7357 const A() {}
7358 }''');
7359 computeLibrarySourceErrors(source);
7360 assertErrors(source);
7361 verify([source, source2]);
7362 }
7363
7364 void test_unusedImport_as_equalPrefixes() {
7365 // 18818
7366 Source source = addSource(r'''
7367 library L;
7368 import 'lib1.dart' as one;
7369 import 'lib2.dart' as one;
7370 one.A a;
7371 one.B b;''');
7372 Source source2 = addNamedSource(
7373 "/lib1.dart",
7374 r'''
7375 library lib1;
7376 class A {}''');
7377 Source source3 = addNamedSource(
7378 "/lib2.dart",
7379 r'''
7380 library lib2;
7381 class B {}''');
7382 computeLibrarySourceErrors(source);
7383 assertErrors(source);
7384 assertNoErrors(source2);
7385 assertNoErrors(source3);
7386 verify([source, source2, source3]);
7387 }
7388
7389 void test_unusedImport_core_library() {
7390 Source source = addSource(r'''
7391 library L;
7392 import 'dart:core';''');
7393 computeLibrarySourceErrors(source);
7394 assertNoErrors(source);
7395 verify([source]);
7396 }
7397
7398 void test_unusedImport_export() {
7399 Source source = addSource(r'''
7400 library L;
7401 import 'lib1.dart';
7402 Two two;''');
7403 addNamedSource(
7404 "/lib1.dart",
7405 r'''
7406 library lib1;
7407 export 'lib2.dart';
7408 class One {}''');
7409 addNamedSource(
7410 "/lib2.dart",
7411 r'''
7412 library lib2;
7413 class Two {}''');
7414 computeLibrarySourceErrors(source);
7415 assertNoErrors(source);
7416 verify([source]);
7417 }
7418
7419 void test_unusedImport_export2() {
7420 Source source = addSource(r'''
7421 library L;
7422 import 'lib1.dart';
7423 Three three;''');
7424 addNamedSource(
7425 "/lib1.dart",
7426 r'''
7427 library lib1;
7428 export 'lib2.dart';
7429 class One {}''');
7430 addNamedSource(
7431 "/lib2.dart",
7432 r'''
7433 library lib2;
7434 export 'lib3.dart';
7435 class Two {}''');
7436 addNamedSource(
7437 "/lib3.dart",
7438 r'''
7439 library lib3;
7440 class Three {}''');
7441 computeLibrarySourceErrors(source);
7442 assertNoErrors(source);
7443 verify([source]);
7444 }
7445
7446 void test_unusedImport_export_infiniteLoop() {
7447 Source source = addSource(r'''
7448 library L;
7449 import 'lib1.dart';
7450 Two two;''');
7451 addNamedSource(
7452 "/lib1.dart",
7453 r'''
7454 library lib1;
7455 export 'lib2.dart';
7456 class One {}''');
7457 addNamedSource(
7458 "/lib2.dart",
7459 r'''
7460 library lib2;
7461 export 'lib3.dart';
7462 class Two {}''');
7463 addNamedSource(
7464 "/lib3.dart",
7465 r'''
7466 library lib3;
7467 export 'lib2.dart';
7468 class Three {}''');
7469 computeLibrarySourceErrors(source);
7470 assertNoErrors(source);
7471 verify([source]);
7472 }
7473
7474 void test_unusedImport_metadata() {
7475 Source source = addSource(r'''
7476 library L;
7477 @A(x)
7478 import 'lib1.dart';
7479 class A {
7480 final int value;
7481 const A(this.value);
7482 }''');
7483 addNamedSource(
7484 "/lib1.dart",
7485 r'''
7486 library lib1;
7487 const x = 0;''');
7488 computeLibrarySourceErrors(source);
7489 assertNoErrors(source);
7490 verify([source]);
7491 }
7492
7493 void test_unusedImport_prefix_topLevelFunction() {
7494 Source source = addSource(r'''
7495 library L;
7496 import 'lib1.dart' hide topLevelFunction;
7497 import 'lib1.dart' as one show topLevelFunction;
7498 class A {
7499 static void x() {
7500 One o;
7501 one.topLevelFunction();
7502 }
7503 }''');
7504 addNamedSource(
7505 "/lib1.dart",
7506 r'''
7507 library lib1;
7508 class One {}
7509 topLevelFunction() {}''');
7510 computeLibrarySourceErrors(source);
7511 assertNoErrors(source);
7512 verify([source]);
7513 }
7514
7515 void test_useOfVoidResult_implicitReturnValue() {
7516 Source source = addSource(r'''
7517 f() {}
7518 class A {
7519 n() {
7520 var a = f();
7521 }
7522 }''');
7523 computeLibrarySourceErrors(source);
7524 assertNoErrors(source);
7525 verify([source]);
7526 }
7527
7528 void test_useOfVoidResult_nonVoidReturnValue() {
7529 Source source = addSource(r'''
7530 int f() => 1;
7531 g() {
7532 var a = f();
7533 }''');
7534 computeLibrarySourceErrors(source);
7535 assertNoErrors(source);
7536 verify([source]);
7537 }
7538 }
7539
7540 class PubSuggestionCodeTest extends ResolverTestCase {
7541 void test_import_package() {
7542 Source source = addSource("import 'package:somepackage/other.dart';");
7543 computeLibrarySourceErrors(source);
7544 assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
7545 }
7546
7547 void test_import_packageWithDotDot() {
7548 Source source = addSource("import 'package:somepackage/../other.dart';");
7549 computeLibrarySourceErrors(source);
7550 assertErrors(source, [
7551 CompileTimeErrorCode.URI_DOES_NOT_EXIST,
7552 HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
7553 ]);
7554 }
7555
7556 void test_import_packageWithLeadingDotDot() {
7557 Source source = addSource("import 'package:../other.dart';");
7558 computeLibrarySourceErrors(source);
7559 assertErrors(source, [
7560 CompileTimeErrorCode.URI_DOES_NOT_EXIST,
7561 HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
7562 ]);
7563 }
7564
7565 void test_import_referenceIntoLibDirectory() {
7566 cacheSource("/myproj/pubspec.yaml", "");
7567 cacheSource("/myproj/lib/other.dart", "");
7568 Source source =
7569 addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
7570 computeLibrarySourceErrors(source);
7571 assertErrors(
7572 source, [HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE]);
7573 }
7574
7575 void test_import_referenceIntoLibDirectory_no_pubspec() {
7576 cacheSource("/myproj/lib/other.dart", "");
7577 Source source =
7578 addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
7579 computeLibrarySourceErrors(source);
7580 assertNoErrors(source);
7581 }
7582
7583 void test_import_referenceOutOfLibDirectory() {
7584 cacheSource("/myproj/pubspec.yaml", "");
7585 cacheSource("/myproj/web/other.dart", "");
7586 Source source =
7587 addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
7588 computeLibrarySourceErrors(source);
7589 assertErrors(
7590 source, [HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE]);
7591 }
7592
7593 void test_import_referenceOutOfLibDirectory_no_pubspec() {
7594 cacheSource("/myproj/web/other.dart", "");
7595 Source source =
7596 addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
7597 computeLibrarySourceErrors(source);
7598 assertNoErrors(source);
7599 }
7600
7601 void test_import_valid_inside_lib1() {
7602 cacheSource("/myproj/pubspec.yaml", "");
7603 cacheSource("/myproj/lib/other.dart", "");
7604 Source source =
7605 addNamedSource("/myproj/lib/test.dart", "import 'other.dart';");
7606 computeLibrarySourceErrors(source);
7607 assertNoErrors(source);
7608 }
7609
7610 void test_import_valid_inside_lib2() {
7611 cacheSource("/myproj/pubspec.yaml", "");
7612 cacheSource("/myproj/lib/bar/other.dart", "");
7613 Source source = addNamedSource(
7614 "/myproj/lib/foo/test.dart", "import '../bar/other.dart';");
7615 computeLibrarySourceErrors(source);
7616 assertNoErrors(source);
7617 }
7618
7619 void test_import_valid_outside_lib() {
7620 cacheSource("/myproj/pubspec.yaml", "");
7621 cacheSource("/myproj/web/other.dart", "");
7622 Source source =
7623 addNamedSource("/myproj/lib2/test.dart", "import '../web/other.dart';");
7624 computeLibrarySourceErrors(source);
7625 assertNoErrors(source);
7626 }
7627 }
7628
7629 /**
7630 * An AST visitor used to verify that all of the nodes in an AST structure that
7631 * should have been resolved were resolved.
7632 */
7633 class ResolutionVerifier extends RecursiveAstVisitor<Object> {
7634 /**
7635 * A set containing nodes that are known to not be resolvable and should
7636 * therefore not cause the test to fail.
7637 */
7638 final Set<AstNode> _knownExceptions;
7639
7640 /**
7641 * A list containing all of the AST nodes that were not resolved.
7642 */
7643 List<AstNode> _unresolvedNodes = new List<AstNode>();
7644
7645 /**
7646 * A list containing all of the AST nodes that were resolved to an element of
7647 * the wrong type.
7648 */
7649 List<AstNode> _wrongTypedNodes = new List<AstNode>();
7650
7651 /**
7652 * Initialize a newly created verifier to verify that all of the identifiers
7653 * in the visited AST structures that are expected to have been resolved have
7654 * an element associated with them. Nodes in the set of [_knownExceptions] are
7655 * not expected to have been resolved, even if they normally would have been
7656 * expected to have been resolved.
7657 */
7658 ResolutionVerifier([this._knownExceptions]);
7659
7660 /**
7661 * Assert that all of the visited identifiers were resolved.
7662 */
7663 void assertResolved() {
7664 if (!_unresolvedNodes.isEmpty || !_wrongTypedNodes.isEmpty) {
7665 StringBuffer buffer = new StringBuffer();
7666 if (!_unresolvedNodes.isEmpty) {
7667 buffer.write("Failed to resolve ");
7668 buffer.write(_unresolvedNodes.length);
7669 buffer.writeln(" nodes:");
7670 _printNodes(buffer, _unresolvedNodes);
7671 }
7672 if (!_wrongTypedNodes.isEmpty) {
7673 buffer.write("Resolved ");
7674 buffer.write(_wrongTypedNodes.length);
7675 buffer.writeln(" to the wrong type of element:");
7676 _printNodes(buffer, _wrongTypedNodes);
7677 }
7678 fail(buffer.toString());
7679 }
7680 }
7681
7682 @override
7683 Object visitAnnotation(Annotation node) {
7684 node.visitChildren(this);
7685 ElementAnnotation elementAnnotation = node.elementAnnotation;
7686 if (elementAnnotation == null) {
7687 if (_knownExceptions == null || !_knownExceptions.contains(node)) {
7688 _unresolvedNodes.add(node);
7689 }
7690 } else if (elementAnnotation is! ElementAnnotation) {
7691 _wrongTypedNodes.add(node);
7692 }
7693 return null;
7694 }
7695
7696 @override
7697 Object visitBinaryExpression(BinaryExpression node) {
7698 node.visitChildren(this);
7699 if (!node.operator.isUserDefinableOperator) {
7700 return null;
7701 }
7702 DartType operandType = node.leftOperand.staticType;
7703 if (operandType == null || operandType.isDynamic) {
7704 return null;
7705 }
7706 return _checkResolved(
7707 node, node.staticElement, (node) => node is MethodElement);
7708 }
7709
7710 @override
7711 Object visitCommentReference(CommentReference node) => null;
7712
7713 @override
7714 Object visitCompilationUnit(CompilationUnit node) {
7715 node.visitChildren(this);
7716 return _checkResolved(
7717 node, node.element, (node) => node is CompilationUnitElement);
7718 }
7719
7720 @override
7721 Object visitExportDirective(ExportDirective node) =>
7722 _checkResolved(node, node.element, (node) => node is ExportElement);
7723
7724 @override
7725 Object visitFunctionDeclaration(FunctionDeclaration node) {
7726 node.visitChildren(this);
7727 if (node.element is LibraryElement) {
7728 _wrongTypedNodes.add(node);
7729 }
7730 return null;
7731 }
7732
7733 @override
7734 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
7735 node.visitChildren(this);
7736 // TODO(brianwilkerson) If we start resolving function expressions, then
7737 // conditionally check to see whether the node was resolved correctly.
7738 return null;
7739 //checkResolved(node, node.getElement(), FunctionElement.class);
7740 }
7741
7742 @override
7743 Object visitImportDirective(ImportDirective node) {
7744 // Not sure how to test the combinators given that it isn't an error if the
7745 // names are not defined.
7746 _checkResolved(node, node.element, (node) => node is ImportElement);
7747 SimpleIdentifier prefix = node.prefix;
7748 if (prefix == null) {
7749 return null;
7750 }
7751 return _checkResolved(
7752 prefix, prefix.staticElement, (node) => node is PrefixElement);
7753 }
7754
7755 @override
7756 Object visitIndexExpression(IndexExpression node) {
7757 node.visitChildren(this);
7758 DartType targetType = node.realTarget.staticType;
7759 if (targetType == null || targetType.isDynamic) {
7760 return null;
7761 }
7762 return _checkResolved(
7763 node, node.staticElement, (node) => node is MethodElement);
7764 }
7765
7766 @override
7767 Object visitLibraryDirective(LibraryDirective node) =>
7768 _checkResolved(node, node.element, (node) => node is LibraryElement);
7769
7770 @override
7771 Object visitNamedExpression(NamedExpression node) =>
7772 node.expression.accept(this);
7773
7774 @override
7775 Object visitPartDirective(PartDirective node) => _checkResolved(
7776 node, node.element, (node) => node is CompilationUnitElement);
7777
7778 @override
7779 Object visitPartOfDirective(PartOfDirective node) =>
7780 _checkResolved(node, node.element, (node) => node is LibraryElement);
7781
7782 @override
7783 Object visitPostfixExpression(PostfixExpression node) {
7784 node.visitChildren(this);
7785 if (!node.operator.isUserDefinableOperator) {
7786 return null;
7787 }
7788 DartType operandType = node.operand.staticType;
7789 if (operandType == null || operandType.isDynamic) {
7790 return null;
7791 }
7792 return _checkResolved(
7793 node, node.staticElement, (node) => node is MethodElement);
7794 }
7795
7796 @override
7797 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
7798 SimpleIdentifier prefix = node.prefix;
7799 prefix.accept(this);
7800 DartType prefixType = prefix.staticType;
7801 if (prefixType == null || prefixType.isDynamic) {
7802 return null;
7803 }
7804 return _checkResolved(node, node.staticElement, null);
7805 }
7806
7807 @override
7808 Object visitPrefixExpression(PrefixExpression node) {
7809 node.visitChildren(this);
7810 if (!node.operator.isUserDefinableOperator) {
7811 return null;
7812 }
7813 DartType operandType = node.operand.staticType;
7814 if (operandType == null || operandType.isDynamic) {
7815 return null;
7816 }
7817 return _checkResolved(
7818 node, node.staticElement, (node) => node is MethodElement);
7819 }
7820
7821 @override
7822 Object visitPropertyAccess(PropertyAccess node) {
7823 Expression target = node.realTarget;
7824 target.accept(this);
7825 DartType targetType = target.staticType;
7826 if (targetType == null || targetType.isDynamic) {
7827 return null;
7828 }
7829 return node.propertyName.accept(this);
7830 }
7831
7832 @override
7833 Object visitSimpleIdentifier(SimpleIdentifier node) {
7834 if (node.name == "void") {
7835 return null;
7836 }
7837 AstNode parent = node.parent;
7838 if (parent is MethodInvocation) {
7839 MethodInvocation invocation = parent;
7840 if (identical(invocation.methodName, node)) {
7841 Expression target = invocation.realTarget;
7842 DartType targetType = target == null ? null : target.staticType;
7843 if (targetType == null || targetType.isDynamic) {
7844 return null;
7845 }
7846 }
7847 }
7848 return _checkResolved(node, node.staticElement, null);
7849 }
7850
7851 Object _checkResolved(
7852 AstNode node, Element element, Predicate<Element> predicate) {
7853 if (element == null) {
7854 if (_knownExceptions == null || !_knownExceptions.contains(node)) {
7855 _unresolvedNodes.add(node);
7856 }
7857 } else if (predicate != null) {
7858 if (!predicate(element)) {
7859 _wrongTypedNodes.add(node);
7860 }
7861 }
7862 return null;
7863 }
7864
7865 String _getFileName(AstNode node) {
7866 // TODO (jwren) there are two copies of this method, one here and one in
7867 // StaticTypeVerifier, they should be resolved into a single method
7868 if (node != null) {
7869 AstNode root = node.root;
7870 if (root is CompilationUnit) {
7871 CompilationUnit rootCU = root;
7872 if (rootCU.element != null) {
7873 return rootCU.element.source.fullName;
7874 } else {
7875 return "<unknown file- CompilationUnit.getElement() returned null>";
7876 }
7877 } else {
7878 return "<unknown file- CompilationUnit.getRoot() is not a CompilationUni t>";
7879 }
7880 }
7881 return "<unknown file- ASTNode is null>";
7882 }
7883
7884 void _printNodes(StringBuffer buffer, List<AstNode> nodes) {
7885 for (AstNode identifier in nodes) {
7886 buffer.write(" ");
7887 buffer.write(identifier.toString());
7888 buffer.write(" (");
7889 buffer.write(_getFileName(identifier));
7890 buffer.write(" : ");
7891 buffer.write(identifier.offset);
7892 buffer.writeln(")");
7893 }
7894 }
7895 }
7896
7897 class ResolverTestCase extends EngineTestCase {
7898 /**
7899 * The analysis context used to parse the compilation units being resolved.
7900 */
7901 InternalAnalysisContext analysisContext2;
7902
7903 /**
7904 * Specifies if [assertErrors] should check for [HintCode.UNUSED_ELEMENT] and
7905 * [HintCode.UNUSED_FIELD].
7906 */
7907 bool enableUnusedElement = false;
7908
7909 /**
7910 * Specifies if [assertErrors] should check for [HintCode.UNUSED_LOCAL_VARIABL E].
7911 */
7912 bool enableUnusedLocalVariable = false;
7913
7914 AnalysisContext get analysisContext => analysisContext2;
7915
7916 /**
7917 * Return a type provider that can be used to test the results of resolution.
7918 *
7919 * @return a type provider
7920 * @throws AnalysisException if dart:core cannot be resolved
7921 */
7922 TypeProvider get typeProvider => analysisContext2.typeProvider;
7923
7924 /**
7925 * Return a type system that can be used to test the results of resolution.
7926 *
7927 * @return a type system
7928 */
7929 TypeSystem get typeSystem => analysisContext2.typeSystem;
7930
7931 /**
7932 * Add a source file to the content provider. The file path should be absolute .
7933 *
7934 * @param filePath the path of the file being added
7935 * @param contents the contents to be returned by the content provider for the specified file
7936 * @return the source object representing the added file
7937 */
7938 Source addNamedSource(String filePath, String contents) {
7939 Source source = cacheSource(filePath, contents);
7940 ChangeSet changeSet = new ChangeSet();
7941 changeSet.addedSource(source);
7942 analysisContext2.applyChanges(changeSet);
7943 return source;
7944 }
7945
7946 /**
7947 * Add a source file to the content provider.
7948 *
7949 * @param contents the contents to be returned by the content provider for the specified file
7950 * @return the source object representing the added file
7951 */
7952 Source addSource(String contents) => addNamedSource("/test.dart", contents);
7953
7954 /**
7955 * Assert that the number of errors reported against the given source matches the number of errors
7956 * that are given and that they have the expected error codes. The order in wh ich the errors were
7957 * gathered is ignored.
7958 *
7959 * @param source the source against which the errors should have been reported
7960 * @param expectedErrorCodes the error codes of the errors that should have be en reported
7961 * @throws AnalysisException if the reported errors could not be computed
7962 * @throws AssertionFailedError if a different number of errors have been repo rted than were
7963 * expected
7964 */
7965 void assertErrors(Source source,
7966 [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
7967 GatheringErrorListener errorListener = new GatheringErrorListener();
7968 for (AnalysisError error in analysisContext2.computeErrors(source)) {
7969 ErrorCode errorCode = error.errorCode;
7970 if (!enableUnusedElement &&
7971 (errorCode == HintCode.UNUSED_ELEMENT ||
7972 errorCode == HintCode.UNUSED_FIELD)) {
7973 continue;
7974 }
7975 if (!enableUnusedLocalVariable &&
7976 (errorCode == HintCode.UNUSED_CATCH_CLAUSE ||
7977 errorCode == HintCode.UNUSED_CATCH_STACK ||
7978 errorCode == HintCode.UNUSED_LOCAL_VARIABLE)) {
7979 continue;
7980 }
7981 errorListener.onError(error);
7982 }
7983 errorListener.assertErrorsWithCodes(expectedErrorCodes);
7984 }
7985
7986 /**
7987 * Assert that no errors have been reported against the given source.
7988 *
7989 * @param source the source against which no errors should have been reported
7990 * @throws AnalysisException if the reported errors could not be computed
7991 * @throws AssertionFailedError if any errors have been reported
7992 */
7993 void assertNoErrors(Source source) {
7994 assertErrors(source);
7995 }
7996
7997 /**
7998 * Cache the source file content in the source factory but don't add the sourc e to the analysis
7999 * context. The file path should be absolute.
8000 *
8001 * @param filePath the path of the file being cached
8002 * @param contents the contents to be returned by the content provider for the specified file
8003 * @return the source object representing the cached file
8004 */
8005 Source cacheSource(String filePath, String contents) {
8006 Source source = new FileBasedSource(FileUtilities2.createFile(filePath));
8007 analysisContext2.setContents(source, contents);
8008 return source;
8009 }
8010
8011 /**
8012 * Change the contents of the given [source] to the given [contents].
8013 */
8014 void changeSource(Source source, String contents) {
8015 analysisContext2.setContents(source, contents);
8016 ChangeSet changeSet = new ChangeSet();
8017 changeSet.changedSource(source);
8018 analysisContext2.applyChanges(changeSet);
8019 }
8020
8021 /**
8022 * Computes errors for the given [librarySource].
8023 * This assumes that the given [librarySource] and its parts have already
8024 * been added to the content provider using the method [addNamedSource].
8025 */
8026 void computeLibrarySourceErrors(Source librarySource) {
8027 analysisContext.computeErrors(librarySource);
8028 }
8029
8030 /**
8031 * Create a library element that represents a library named `"test"` containin g a single
8032 * empty compilation unit.
8033 *
8034 * @return the library element that was created
8035 */
8036 LibraryElementImpl createDefaultTestLibrary() =>
8037 createTestLibrary(AnalysisContextFactory.contextWithCore(), "test");
8038
8039 /**
8040 * Create a library element that represents a library with the given name cont aining a single
8041 * empty compilation unit.
8042 *
8043 * @param libraryName the name of the library to be created
8044 * @return the library element that was created
8045 */
8046 LibraryElementImpl createTestLibrary(
8047 AnalysisContext context, String libraryName,
8048 [List<String> typeNames]) {
8049 String fileName = "$libraryName.dart";
8050 FileBasedSource definingCompilationUnitSource =
8051 _createNamedSource(fileName);
8052 List<CompilationUnitElement> sourcedCompilationUnits;
8053 if (typeNames == null) {
8054 sourcedCompilationUnits = CompilationUnitElement.EMPTY_LIST;
8055 } else {
8056 int count = typeNames.length;
8057 sourcedCompilationUnits = new List<CompilationUnitElement>(count);
8058 for (int i = 0; i < count; i++) {
8059 String typeName = typeNames[i];
8060 ClassElementImpl type =
8061 new ClassElementImpl.forNode(AstFactory.identifier3(typeName));
8062 String fileName = "$typeName.dart";
8063 CompilationUnitElementImpl compilationUnit =
8064 new CompilationUnitElementImpl(fileName);
8065 compilationUnit.source = _createNamedSource(fileName);
8066 compilationUnit.librarySource = definingCompilationUnitSource;
8067 compilationUnit.types = <ClassElement>[type];
8068 sourcedCompilationUnits[i] = compilationUnit;
8069 }
8070 }
8071 CompilationUnitElementImpl compilationUnit =
8072 new CompilationUnitElementImpl(fileName);
8073 compilationUnit.librarySource =
8074 compilationUnit.source = definingCompilationUnitSource;
8075 LibraryElementImpl library = new LibraryElementImpl.forNode(
8076 context, AstFactory.libraryIdentifier2([libraryName]));
8077 library.definingCompilationUnit = compilationUnit;
8078 library.parts = sourcedCompilationUnits;
8079 return library;
8080 }
8081
8082 Expression findTopLevelConstantExpression(
8083 CompilationUnit compilationUnit, String name) =>
8084 findTopLevelDeclaration(compilationUnit, name).initializer;
8085
8086 VariableDeclaration findTopLevelDeclaration(
8087 CompilationUnit compilationUnit, String name) {
8088 for (CompilationUnitMember member in compilationUnit.declarations) {
8089 if (member is TopLevelVariableDeclaration) {
8090 for (VariableDeclaration variable in member.variables.variables) {
8091 if (variable.name.name == name) {
8092 return variable;
8093 }
8094 }
8095 }
8096 }
8097 return null;
8098 // Not found
8099 }
8100
8101 /**
8102 * In the rare cases we want to group several tests into single "test_" method , so need a way to
8103 * reset test instance to reuse it.
8104 */
8105 void reset() {
8106 analysisContext2 = AnalysisContextFactory.contextWithCore();
8107 }
8108
8109 /**
8110 * Reset the analysis context to have the given options applied.
8111 *
8112 * @param options the analysis options to be applied to the context
8113 */
8114 void resetWithOptions(AnalysisOptions options) {
8115 analysisContext2 =
8116 AnalysisContextFactory.contextWithCoreAndOptions(options);
8117 }
8118
8119 /**
8120 * Given a library and all of its parts, resolve the contents of the library a nd the contents of
8121 * the parts. This assumes that the sources for the library and its parts have already been added
8122 * to the content provider using the method [addNamedSource].
8123 *
8124 * @param librarySource the source for the compilation unit that defines the l ibrary
8125 * @return the element representing the resolved library
8126 * @throws AnalysisException if the analysis could not be performed
8127 */
8128 LibraryElement resolve2(Source librarySource) =>
8129 analysisContext2.computeLibraryElement(librarySource);
8130
8131 /**
8132 * Return the resolved compilation unit corresponding to the given source in t he given library.
8133 *
8134 * @param source the source of the compilation unit to be returned
8135 * @param library the library in which the compilation unit is to be resolved
8136 * @return the resolved compilation unit
8137 * @throws Exception if the compilation unit could not be resolved
8138 */
8139 CompilationUnit resolveCompilationUnit(
8140 Source source, LibraryElement library) =>
8141 analysisContext2.resolveCompilationUnit(source, library);
8142
8143 CompilationUnit resolveSource(String sourceText) =>
8144 resolveSource2("/test.dart", sourceText);
8145
8146 CompilationUnit resolveSource2(String fileName, String sourceText) {
8147 Source source = addNamedSource(fileName, sourceText);
8148 LibraryElement library = analysisContext.computeLibraryElement(source);
8149 return analysisContext.resolveCompilationUnit(source, library);
8150 }
8151
8152 Source resolveSources(List<String> sourceTexts) {
8153 for (int i = 0; i < sourceTexts.length; i++) {
8154 CompilationUnit unit =
8155 resolveSource2("/lib${i + 1}.dart", sourceTexts[i]);
8156 // reference the source if this is the last source
8157 if (i + 1 == sourceTexts.length) {
8158 return unit.element.source;
8159 }
8160 }
8161 return null;
8162 }
8163
8164 void resolveWithAndWithoutExperimental(
8165 List<String> strSources,
8166 List<ErrorCode> codesWithoutExperimental,
8167 List<ErrorCode> codesWithExperimental) {
8168 // Setup analysis context as non-experimental
8169 AnalysisOptionsImpl options = new AnalysisOptionsImpl();
8170 // options.enableDeferredLoading = false;
8171 resetWithOptions(options);
8172 // Analysis and assertions
8173 Source source = resolveSources(strSources);
8174 assertErrors(source, codesWithoutExperimental);
8175 verify([source]);
8176 // Setup analysis context as experimental
8177 reset();
8178 // Analysis and assertions
8179 source = resolveSources(strSources);
8180 assertErrors(source, codesWithExperimental);
8181 verify([source]);
8182 }
8183
8184 void resolveWithErrors(List<String> strSources, List<ErrorCode> codes) {
8185 // Analysis and assertions
8186 Source source = resolveSources(strSources);
8187 assertErrors(source, codes);
8188 verify([source]);
8189 }
8190
8191 @override
8192 void setUp() {
8193 reset();
8194 }
8195
8196 @override
8197 void tearDown() {
8198 analysisContext2 = null;
8199 super.tearDown();
8200 }
8201
8202 /**
8203 * Verify that all of the identifiers in the compilation units associated with
8204 * the given [sources] have been resolved.
8205 */
8206 void verify(List<Source> sources) {
8207 ResolutionVerifier verifier = new ResolutionVerifier();
8208 for (Source source in sources) {
8209 List<Source> libraries = analysisContext2.getLibrariesContaining(source);
8210 for (Source library in libraries) {
8211 analysisContext2
8212 .resolveCompilationUnit2(source, library)
8213 .accept(verifier);
8214 }
8215 }
8216 verifier.assertResolved();
8217 }
8218
8219 /**
8220 * @param code the code that assigns the value to the variable "v", no matter how. We check that
8221 * "v" has expected static and propagated type.
8222 */
8223 void _assertPropagatedAssignedType(String code, DartType expectedStaticType,
8224 DartType expectedPropagatedType) {
8225 SimpleIdentifier identifier = _findMarkedIdentifier(code, "v = ");
8226 expect(identifier.staticType, same(expectedStaticType));
8227 expect(identifier.propagatedType, same(expectedPropagatedType));
8228 }
8229
8230 /**
8231 * @param code the code that iterates using variable "v". We check that
8232 * "v" has expected static and propagated type.
8233 */
8234 void _assertPropagatedIterationType(String code, DartType expectedStaticType,
8235 DartType expectedPropagatedType) {
8236 SimpleIdentifier identifier = _findMarkedIdentifier(code, "v in ");
8237 expect(identifier.staticType, same(expectedStaticType));
8238 expect(identifier.propagatedType, same(expectedPropagatedType));
8239 }
8240
8241 /**
8242 * Check the static and propagated types of the expression marked with "; // m arker" comment.
8243 *
8244 * @param code source code to analyze, with the expression to check marked wit h "// marker".
8245 * @param expectedStaticType if non-null, check actual static type is equal to this.
8246 * @param expectedPropagatedType if non-null, check actual static type is equa l to this.
8247 * @throws Exception
8248 */
8249 void _assertTypeOfMarkedExpression(String code, DartType expectedStaticType,
8250 DartType expectedPropagatedType) {
8251 SimpleIdentifier identifier = _findMarkedIdentifier(code, "; // marker");
8252 if (expectedStaticType != null) {
8253 expect(identifier.staticType, expectedStaticType);
8254 }
8255 expect(identifier.propagatedType, expectedPropagatedType);
8256 }
8257
8258 /**
8259 * Create a source object representing a file with the given [fileName] and
8260 * give it an empty content. Return the source that was created.
8261 */
8262 FileBasedSource _createNamedSource(String fileName) {
8263 FileBasedSource source =
8264 new FileBasedSource(FileUtilities2.createFile(fileName));
8265 analysisContext2.setContents(source, "");
8266 return source;
8267 }
8268
8269 /**
8270 * Return the `SimpleIdentifier` marked by `marker`. The source code must have no
8271 * errors and be verifiable.
8272 *
8273 * @param code source code to analyze.
8274 * @param marker marker identifying sought after expression in source code.
8275 * @return expression marked by the marker.
8276 * @throws Exception
8277 */
8278 SimpleIdentifier _findMarkedIdentifier(String code, String marker) {
8279 try {
8280 Source source = addSource(code);
8281 LibraryElement library = resolve2(source);
8282 assertNoErrors(source);
8283 verify([source]);
8284 CompilationUnit unit = resolveCompilationUnit(source, library);
8285 // Could generalize this further by making [SimpleIdentifier.class] a
8286 // parameter.
8287 return EngineTestCase.findNode(
8288 unit, code, marker, (node) => node is SimpleIdentifier);
8289 } catch (exception) {
8290 // Is there a better exception to throw here? The point is that an
8291 // assertion failure here should be a failure, in both "test_*" and
8292 // "fail_*" tests. However, an assertion failure is success for the
8293 // purpose of "fail_*" tests, so without catching them here "fail_*" tests
8294 // can succeed by failing for the wrong reason.
8295 throw new JavaException("Unexexpected assertion failure: $exception");
8296 }
8297 }
8298 }
8299
8300 class Scope_EnclosedScopeTest_test_define_duplicate extends Scope {
8301 GatheringErrorListener listener;
8302
8303 Scope_EnclosedScopeTest_test_define_duplicate(this.listener) : super();
8304
8305 @override
8306 AnalysisErrorListener get errorListener => listener;
8307
8308 @override
8309 Element internalLookup(Identifier identifier, String name,
8310 LibraryElement referencingLibrary) =>
8311 null;
8312 }
8313
8314 class Scope_EnclosedScopeTest_test_define_normal extends Scope {
8315 GatheringErrorListener listener;
8316
8317 Scope_EnclosedScopeTest_test_define_normal(this.listener) : super();
8318
8319 @override
8320 AnalysisErrorListener get errorListener => listener;
8321
8322 @override
8323 Element internalLookup(Identifier identifier, String name,
8324 LibraryElement referencingLibrary) =>
8325 null;
8326 }
8327
8328 @reflectiveTest
8329 class ScopeTest extends ResolverTestCase {
8330 void test_define_duplicate() {
8331 GatheringErrorListener errorListener = new GatheringErrorListener();
8332 ScopeTest_TestScope scope = new ScopeTest_TestScope(errorListener);
8333 VariableElement element1 =
8334 ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
8335 VariableElement element2 =
8336 ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
8337 scope.define(element1);
8338 scope.define(element2);
8339 errorListener.assertErrorsWithSeverities([ErrorSeverity.ERROR]);
8340 }
8341
8342 void test_define_normal() {
8343 GatheringErrorListener errorListener = new GatheringErrorListener();
8344 ScopeTest_TestScope scope = new ScopeTest_TestScope(errorListener);
8345 VariableElement element1 =
8346 ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
8347 VariableElement element2 =
8348 ElementFactory.localVariableElement(AstFactory.identifier3("v2"));
8349 scope.define(element1);
8350 scope.define(element2);
8351 errorListener.assertNoErrors();
8352 }
8353
8354 void test_getErrorListener() {
8355 GatheringErrorListener errorListener = new GatheringErrorListener();
8356 ScopeTest_TestScope scope = new ScopeTest_TestScope(errorListener);
8357 expect(scope.errorListener, errorListener);
8358 }
8359
8360 void test_isPrivateName_nonPrivate() {
8361 expect(Scope.isPrivateName("Public"), isFalse);
8362 }
8363
8364 void test_isPrivateName_private() {
8365 expect(Scope.isPrivateName("_Private"), isTrue);
8366 }
8367 }
8368
8369 /**
8370 * A non-abstract subclass that can be used for testing purposes.
8371 */
8372 class ScopeTest_TestScope extends Scope {
8373 /**
8374 * The listener that is to be informed when an error is encountered.
8375 */
8376 final AnalysisErrorListener errorListener;
8377
8378 ScopeTest_TestScope(this.errorListener);
8379
8380 @override
8381 Element internalLookup(Identifier identifier, String name,
8382 LibraryElement referencingLibrary) =>
8383 localLookup(name, referencingLibrary);
8384 }
8385
8386 @reflectiveTest
8387 class SimpleResolverTest extends ResolverTestCase {
8388 void fail_getter_and_setter_fromMixins_property_access() {
8389 // TODO(paulberry): it appears that auxiliaryElements isn't properly set on
8390 // a SimpleIdentifier that's inside a property access. This bug should be
8391 // fixed.
8392 Source source = addSource('''
8393 class B {}
8394 class M1 {
8395 get x => null;
8396 set x(value) {}
8397 }
8398 class M2 {
8399 get x => null;
8400 set x(value) {}
8401 }
8402 class C extends B with M1, M2 {}
8403 void main() {
8404 new C().x += 1;
8405 }
8406 ''');
8407 LibraryElement library = resolve2(source);
8408 assertNoErrors(source);
8409 verify([source]);
8410 // Verify that both the getter and setter for "x" in "new C().x" refer to
8411 // the accessors defined in M2.
8412 FunctionDeclaration main =
8413 library.definingCompilationUnit.functions[0].computeNode();
8414 BlockFunctionBody body = main.functionExpression.body;
8415 ExpressionStatement stmt = body.block.statements[0];
8416 AssignmentExpression assignment = stmt.expression;
8417 PropertyAccess propertyAccess = assignment.leftHandSide;
8418 expect(
8419 propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
8420 expect(
8421 propertyAccess
8422 .propertyName.auxiliaryElements.staticElement.enclosingElement.name,
8423 'M2');
8424 }
8425
8426 void fail_staticInvocation() {
8427 Source source = addSource(r'''
8428 class A {
8429 static int get g => (a,b) => 0;
8430 }
8431 class B {
8432 f() {
8433 A.g(1,0);
8434 }
8435 }''');
8436 computeLibrarySourceErrors(source);
8437 assertNoErrors(source);
8438 verify([source]);
8439 }
8440
8441 void test_argumentResolution_required_matching() {
8442 Source source = addSource(r'''
8443 class A {
8444 void f() {
8445 g(1, 2, 3);
8446 }
8447 void g(a, b, c) {}
8448 }''');
8449 _validateArgumentResolution(source, [0, 1, 2]);
8450 }
8451
8452 void test_argumentResolution_required_tooFew() {
8453 Source source = addSource(r'''
8454 class A {
8455 void f() {
8456 g(1, 2);
8457 }
8458 void g(a, b, c) {}
8459 }''');
8460 _validateArgumentResolution(source, [0, 1]);
8461 }
8462
8463 void test_argumentResolution_required_tooMany() {
8464 Source source = addSource(r'''
8465 class A {
8466 void f() {
8467 g(1, 2, 3);
8468 }
8469 void g(a, b) {}
8470 }''');
8471 _validateArgumentResolution(source, [0, 1, -1]);
8472 }
8473
8474 void test_argumentResolution_requiredAndNamed_extra() {
8475 Source source = addSource(r'''
8476 class A {
8477 void f() {
8478 g(1, 2, c: 3, d: 4);
8479 }
8480 void g(a, b, {c}) {}
8481 }''');
8482 _validateArgumentResolution(source, [0, 1, 2, -1]);
8483 }
8484
8485 void test_argumentResolution_requiredAndNamed_matching() {
8486 Source source = addSource(r'''
8487 class A {
8488 void f() {
8489 g(1, 2, c: 3);
8490 }
8491 void g(a, b, {c}) {}
8492 }''');
8493 _validateArgumentResolution(source, [0, 1, 2]);
8494 }
8495
8496 void test_argumentResolution_requiredAndNamed_missing() {
8497 Source source = addSource(r'''
8498 class A {
8499 void f() {
8500 g(1, 2, d: 3);
8501 }
8502 void g(a, b, {c, d}) {}
8503 }''');
8504 _validateArgumentResolution(source, [0, 1, 3]);
8505 }
8506
8507 void test_argumentResolution_requiredAndPositional_fewer() {
8508 Source source = addSource(r'''
8509 class A {
8510 void f() {
8511 g(1, 2, 3);
8512 }
8513 void g(a, b, [c, d]) {}
8514 }''');
8515 _validateArgumentResolution(source, [0, 1, 2]);
8516 }
8517
8518 void test_argumentResolution_requiredAndPositional_matching() {
8519 Source source = addSource(r'''
8520 class A {
8521 void f() {
8522 g(1, 2, 3, 4);
8523 }
8524 void g(a, b, [c, d]) {}
8525 }''');
8526 _validateArgumentResolution(source, [0, 1, 2, 3]);
8527 }
8528
8529 void test_argumentResolution_requiredAndPositional_more() {
8530 Source source = addSource(r'''
8531 class A {
8532 void f() {
8533 g(1, 2, 3, 4);
8534 }
8535 void g(a, b, [c]) {}
8536 }''');
8537 _validateArgumentResolution(source, [0, 1, 2, -1]);
8538 }
8539
8540 void test_argumentResolution_setter_propagated() {
8541 Source source = addSource(r'''
8542 main() {
8543 var a = new A();
8544 a.sss = 0;
8545 }
8546 class A {
8547 set sss(x) {}
8548 }''');
8549 LibraryElement library = resolve2(source);
8550 CompilationUnitElement unit = library.definingCompilationUnit;
8551 // find "a.sss = 0"
8552 AssignmentExpression assignment;
8553 {
8554 FunctionElement mainElement = unit.functions[0];
8555 FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
8556 Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
8557 ExpressionStatement expressionStatement =
8558 statement as ExpressionStatement;
8559 assignment = expressionStatement.expression as AssignmentExpression;
8560 }
8561 // get parameter
8562 Expression rhs = assignment.rightHandSide;
8563 expect(rhs.staticParameterElement, isNull);
8564 ParameterElement parameter = rhs.propagatedParameterElement;
8565 expect(parameter, isNotNull);
8566 expect(parameter.displayName, "x");
8567 // validate
8568 ClassElement classA = unit.types[0];
8569 PropertyAccessorElement setter = classA.accessors[0];
8570 expect(setter.parameters[0], same(parameter));
8571 }
8572
8573 void test_argumentResolution_setter_propagated_propertyAccess() {
8574 Source source = addSource(r'''
8575 main() {
8576 var a = new A();
8577 a.b.sss = 0;
8578 }
8579 class A {
8580 B b = new B();
8581 }
8582 class B {
8583 set sss(x) {}
8584 }''');
8585 LibraryElement library = resolve2(source);
8586 CompilationUnitElement unit = library.definingCompilationUnit;
8587 // find "a.b.sss = 0"
8588 AssignmentExpression assignment;
8589 {
8590 FunctionElement mainElement = unit.functions[0];
8591 FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
8592 Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
8593 ExpressionStatement expressionStatement =
8594 statement as ExpressionStatement;
8595 assignment = expressionStatement.expression as AssignmentExpression;
8596 }
8597 // get parameter
8598 Expression rhs = assignment.rightHandSide;
8599 expect(rhs.staticParameterElement, isNull);
8600 ParameterElement parameter = rhs.propagatedParameterElement;
8601 expect(parameter, isNotNull);
8602 expect(parameter.displayName, "x");
8603 // validate
8604 ClassElement classB = unit.types[1];
8605 PropertyAccessorElement setter = classB.accessors[0];
8606 expect(setter.parameters[0], same(parameter));
8607 }
8608
8609 void test_argumentResolution_setter_static() {
8610 Source source = addSource(r'''
8611 main() {
8612 A a = new A();
8613 a.sss = 0;
8614 }
8615 class A {
8616 set sss(x) {}
8617 }''');
8618 LibraryElement library = resolve2(source);
8619 CompilationUnitElement unit = library.definingCompilationUnit;
8620 // find "a.sss = 0"
8621 AssignmentExpression assignment;
8622 {
8623 FunctionElement mainElement = unit.functions[0];
8624 FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
8625 Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
8626 ExpressionStatement expressionStatement =
8627 statement as ExpressionStatement;
8628 assignment = expressionStatement.expression as AssignmentExpression;
8629 }
8630 // get parameter
8631 Expression rhs = assignment.rightHandSide;
8632 ParameterElement parameter = rhs.staticParameterElement;
8633 expect(parameter, isNotNull);
8634 expect(parameter.displayName, "x");
8635 // validate
8636 ClassElement classA = unit.types[0];
8637 PropertyAccessorElement setter = classA.accessors[0];
8638 expect(setter.parameters[0], same(parameter));
8639 }
8640
8641 void test_argumentResolution_setter_static_propertyAccess() {
8642 Source source = addSource(r'''
8643 main() {
8644 A a = new A();
8645 a.b.sss = 0;
8646 }
8647 class A {
8648 B b = new B();
8649 }
8650 class B {
8651 set sss(x) {}
8652 }''');
8653 LibraryElement library = resolve2(source);
8654 CompilationUnitElement unit = library.definingCompilationUnit;
8655 // find "a.b.sss = 0"
8656 AssignmentExpression assignment;
8657 {
8658 FunctionElement mainElement = unit.functions[0];
8659 FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
8660 Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
8661 ExpressionStatement expressionStatement =
8662 statement as ExpressionStatement;
8663 assignment = expressionStatement.expression as AssignmentExpression;
8664 }
8665 // get parameter
8666 Expression rhs = assignment.rightHandSide;
8667 ParameterElement parameter = rhs.staticParameterElement;
8668 expect(parameter, isNotNull);
8669 expect(parameter.displayName, "x");
8670 // validate
8671 ClassElement classB = unit.types[1];
8672 PropertyAccessorElement setter = classB.accessors[0];
8673 expect(setter.parameters[0], same(parameter));
8674 }
8675
8676 void test_breakTarget_labeled() {
8677 // Verify that the target of the label is correctly found and is recorded
8678 // as the unlabeled portion of the statement.
8679 String text = r'''
8680 void f() {
8681 loop1: while (true) {
8682 loop2: for (int i = 0; i < 10; i++) {
8683 break loop1;
8684 break loop2;
8685 }
8686 }
8687 }
8688 ''';
8689 CompilationUnit unit = resolveSource(text);
8690 WhileStatement whileStatement = EngineTestCase.findNode(
8691 unit, text, 'while (true)', (n) => n is WhileStatement);
8692 ForStatement forStatement =
8693 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
8694 BreakStatement break1 = EngineTestCase.findNode(
8695 unit, text, 'break loop1', (n) => n is BreakStatement);
8696 BreakStatement break2 = EngineTestCase.findNode(
8697 unit, text, 'break loop2', (n) => n is BreakStatement);
8698 expect(break1.target, same(whileStatement));
8699 expect(break2.target, same(forStatement));
8700 }
8701
8702 void test_breakTarget_unlabeledBreakFromDo() {
8703 String text = r'''
8704 void f() {
8705 do {
8706 break;
8707 } while (true);
8708 }
8709 ''';
8710 CompilationUnit unit = resolveSource(text);
8711 DoStatement doStatement =
8712 EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement);
8713 BreakStatement breakStatement = EngineTestCase.findNode(
8714 unit, text, 'break', (n) => n is BreakStatement);
8715 expect(breakStatement.target, same(doStatement));
8716 }
8717
8718 void test_breakTarget_unlabeledBreakFromFor() {
8719 String text = r'''
8720 void f() {
8721 for (int i = 0; i < 10; i++) {
8722 break;
8723 }
8724 }
8725 ''';
8726 CompilationUnit unit = resolveSource(text);
8727 ForStatement forStatement =
8728 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
8729 BreakStatement breakStatement = EngineTestCase.findNode(
8730 unit, text, 'break', (n) => n is BreakStatement);
8731 expect(breakStatement.target, same(forStatement));
8732 }
8733
8734 void test_breakTarget_unlabeledBreakFromForEach() {
8735 String text = r'''
8736 void f() {
8737 for (x in []) {
8738 break;
8739 }
8740 }
8741 ''';
8742 CompilationUnit unit = resolveSource(text);
8743 ForEachStatement forStatement = EngineTestCase.findNode(
8744 unit, text, 'for', (n) => n is ForEachStatement);
8745 BreakStatement breakStatement = EngineTestCase.findNode(
8746 unit, text, 'break', (n) => n is BreakStatement);
8747 expect(breakStatement.target, same(forStatement));
8748 }
8749
8750 void test_breakTarget_unlabeledBreakFromSwitch() {
8751 String text = r'''
8752 void f() {
8753 while (true) {
8754 switch (0) {
8755 case 0:
8756 break;
8757 }
8758 }
8759 }
8760 ''';
8761 CompilationUnit unit = resolveSource(text);
8762 SwitchStatement switchStatement = EngineTestCase.findNode(
8763 unit, text, 'switch', (n) => n is SwitchStatement);
8764 BreakStatement breakStatement = EngineTestCase.findNode(
8765 unit, text, 'break', (n) => n is BreakStatement);
8766 expect(breakStatement.target, same(switchStatement));
8767 }
8768
8769 void test_breakTarget_unlabeledBreakFromWhile() {
8770 String text = r'''
8771 void f() {
8772 while (true) {
8773 break;
8774 }
8775 }
8776 ''';
8777 CompilationUnit unit = resolveSource(text);
8778 WhileStatement whileStatement = EngineTestCase.findNode(
8779 unit, text, 'while', (n) => n is WhileStatement);
8780 BreakStatement breakStatement = EngineTestCase.findNode(
8781 unit, text, 'break', (n) => n is BreakStatement);
8782 expect(breakStatement.target, same(whileStatement));
8783 }
8784
8785 void test_breakTarget_unlabeledBreakToOuterFunction() {
8786 // Verify that unlabeled break statements can't resolve to loops in an
8787 // outer function.
8788 String text = r'''
8789 void f() {
8790 while (true) {
8791 void g() {
8792 break;
8793 }
8794 }
8795 }
8796 ''';
8797 CompilationUnit unit = resolveSource(text);
8798 BreakStatement breakStatement = EngineTestCase.findNode(
8799 unit, text, 'break', (n) => n is BreakStatement);
8800 expect(breakStatement.target, isNull);
8801 }
8802
8803 void test_class_definesCall() {
8804 Source source = addSource(r'''
8805 class A {
8806 int call(int x) { return x; }
8807 }
8808 int f(A a) {
8809 return a(0);
8810 }''');
8811 computeLibrarySourceErrors(source);
8812 assertNoErrors(source);
8813 verify([source]);
8814 }
8815
8816 void test_class_extends_implements() {
8817 Source source = addSource(r'''
8818 class A extends B implements C {}
8819 class B {}
8820 class C {}''');
8821 computeLibrarySourceErrors(source);
8822 assertNoErrors(source);
8823 verify([source]);
8824 }
8825
8826 void test_commentReference_class() {
8827 Source source = addSource(r'''
8828 f() {}
8829 /** [A] [new A] [A.n] [new A.n] [m] [f] */
8830 class A {
8831 A() {}
8832 A.n() {}
8833 m() {}
8834 }''');
8835 computeLibrarySourceErrors(source);
8836 assertNoErrors(source);
8837 verify([source]);
8838 }
8839
8840 void test_commentReference_parameter() {
8841 Source source = addSource(r'''
8842 class A {
8843 A() {}
8844 A.n() {}
8845 /** [e] [f] */
8846 m(e, f()) {}
8847 }''');
8848 computeLibrarySourceErrors(source);
8849 assertNoErrors(source);
8850 verify([source]);
8851 }
8852
8853 void test_commentReference_singleLine() {
8854 Source source = addSource(r'''
8855 /// [A]
8856 class A {}''');
8857 computeLibrarySourceErrors(source);
8858 assertNoErrors(source);
8859 verify([source]);
8860 }
8861
8862 void test_continueTarget_labeled() {
8863 // Verify that the target of the label is correctly found and is recorded
8864 // as the unlabeled portion of the statement.
8865 String text = r'''
8866 void f() {
8867 loop1: while (true) {
8868 loop2: for (int i = 0; i < 10; i++) {
8869 continue loop1;
8870 continue loop2;
8871 }
8872 }
8873 }
8874 ''';
8875 CompilationUnit unit = resolveSource(text);
8876 WhileStatement whileStatement = EngineTestCase.findNode(
8877 unit, text, 'while (true)', (n) => n is WhileStatement);
8878 ForStatement forStatement =
8879 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
8880 ContinueStatement continue1 = EngineTestCase.findNode(
8881 unit, text, 'continue loop1', (n) => n is ContinueStatement);
8882 ContinueStatement continue2 = EngineTestCase.findNode(
8883 unit, text, 'continue loop2', (n) => n is ContinueStatement);
8884 expect(continue1.target, same(whileStatement));
8885 expect(continue2.target, same(forStatement));
8886 }
8887
8888 void test_continueTarget_unlabeledContinueFromDo() {
8889 String text = r'''
8890 void f() {
8891 do {
8892 continue;
8893 } while (true);
8894 }
8895 ''';
8896 CompilationUnit unit = resolveSource(text);
8897 DoStatement doStatement =
8898 EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement);
8899 ContinueStatement continueStatement = EngineTestCase.findNode(
8900 unit, text, 'continue', (n) => n is ContinueStatement);
8901 expect(continueStatement.target, same(doStatement));
8902 }
8903
8904 void test_continueTarget_unlabeledContinueFromFor() {
8905 String text = r'''
8906 void f() {
8907 for (int i = 0; i < 10; i++) {
8908 continue;
8909 }
8910 }
8911 ''';
8912 CompilationUnit unit = resolveSource(text);
8913 ForStatement forStatement =
8914 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
8915 ContinueStatement continueStatement = EngineTestCase.findNode(
8916 unit, text, 'continue', (n) => n is ContinueStatement);
8917 expect(continueStatement.target, same(forStatement));
8918 }
8919
8920 void test_continueTarget_unlabeledContinueFromForEach() {
8921 String text = r'''
8922 void f() {
8923 for (x in []) {
8924 continue;
8925 }
8926 }
8927 ''';
8928 CompilationUnit unit = resolveSource(text);
8929 ForEachStatement forStatement = EngineTestCase.findNode(
8930 unit, text, 'for', (n) => n is ForEachStatement);
8931 ContinueStatement continueStatement = EngineTestCase.findNode(
8932 unit, text, 'continue', (n) => n is ContinueStatement);
8933 expect(continueStatement.target, same(forStatement));
8934 }
8935
8936 void test_continueTarget_unlabeledContinueFromWhile() {
8937 String text = r'''
8938 void f() {
8939 while (true) {
8940 continue;
8941 }
8942 }
8943 ''';
8944 CompilationUnit unit = resolveSource(text);
8945 WhileStatement whileStatement = EngineTestCase.findNode(
8946 unit, text, 'while', (n) => n is WhileStatement);
8947 ContinueStatement continueStatement = EngineTestCase.findNode(
8948 unit, text, 'continue', (n) => n is ContinueStatement);
8949 expect(continueStatement.target, same(whileStatement));
8950 }
8951
8952 void test_continueTarget_unlabeledContinueSkipsSwitch() {
8953 String text = r'''
8954 void f() {
8955 while (true) {
8956 switch (0) {
8957 case 0:
8958 continue;
8959 }
8960 }
8961 }
8962 ''';
8963 CompilationUnit unit = resolveSource(text);
8964 WhileStatement whileStatement = EngineTestCase.findNode(
8965 unit, text, 'while', (n) => n is WhileStatement);
8966 ContinueStatement continueStatement = EngineTestCase.findNode(
8967 unit, text, 'continue', (n) => n is ContinueStatement);
8968 expect(continueStatement.target, same(whileStatement));
8969 }
8970
8971 void test_continueTarget_unlabeledContinueToOuterFunction() {
8972 // Verify that unlabeled continue statements can't resolve to loops in an
8973 // outer function.
8974 String text = r'''
8975 void f() {
8976 while (true) {
8977 void g() {
8978 continue;
8979 }
8980 }
8981 }
8982 ''';
8983 CompilationUnit unit = resolveSource(text);
8984 ContinueStatement continueStatement = EngineTestCase.findNode(
8985 unit, text, 'continue', (n) => n is ContinueStatement);
8986 expect(continueStatement.target, isNull);
8987 }
8988
8989 void test_empty() {
8990 Source source = addSource("");
8991 computeLibrarySourceErrors(source);
8992 assertNoErrors(source);
8993 verify([source]);
8994 }
8995
8996 void test_entryPoint_exported() {
8997 addNamedSource(
8998 "/two.dart",
8999 r'''
9000 library two;
9001 main() {}''');
9002 Source source = addNamedSource(
9003 "/one.dart",
9004 r'''
9005 library one;
9006 export 'two.dart';''');
9007 LibraryElement library = resolve2(source);
9008 expect(library, isNotNull);
9009 FunctionElement main = library.entryPoint;
9010 expect(main, isNotNull);
9011 expect(main.library, isNot(same(library)));
9012 assertNoErrors(source);
9013 verify([source]);
9014 }
9015
9016 void test_entryPoint_local() {
9017 Source source = addNamedSource(
9018 "/one.dart",
9019 r'''
9020 library one;
9021 main() {}''');
9022 LibraryElement library = resolve2(source);
9023 expect(library, isNotNull);
9024 FunctionElement main = library.entryPoint;
9025 expect(main, isNotNull);
9026 expect(main.library, same(library));
9027 assertNoErrors(source);
9028 verify([source]);
9029 }
9030
9031 void test_entryPoint_none() {
9032 Source source = addNamedSource("/one.dart", "library one;");
9033 LibraryElement library = resolve2(source);
9034 expect(library, isNotNull);
9035 expect(library.entryPoint, isNull);
9036 assertNoErrors(source);
9037 verify([source]);
9038 }
9039
9040 void test_enum_externalLibrary() {
9041 addNamedSource(
9042 "/my_lib.dart",
9043 r'''
9044 library my_lib;
9045 enum EEE {A, B, C}''');
9046 Source source = addSource(r'''
9047 import 'my_lib.dart';
9048 main() {
9049 EEE e = null;
9050 }''');
9051 computeLibrarySourceErrors(source);
9052 assertNoErrors(source);
9053 verify([source]);
9054 }
9055
9056 void test_extractedMethodAsConstant() {
9057 Source source = addSource(r'''
9058 abstract class Comparable<T> {
9059 int compareTo(T other);
9060 static int compare(Comparable a, Comparable b) => a.compareTo(b);
9061 }
9062 class A {
9063 void sort([compare = Comparable.compare]) {}
9064 }''');
9065 computeLibrarySourceErrors(source);
9066 assertNoErrors(source);
9067 verify([source]);
9068 }
9069
9070 void test_fieldFormalParameter() {
9071 Source source = addSource(r'''
9072 class A {
9073 int x;
9074 A(this.x) {}
9075 }''');
9076 computeLibrarySourceErrors(source);
9077 assertNoErrors(source);
9078 verify([source]);
9079 }
9080
9081 void test_forEachLoops_nonConflicting() {
9082 Source source = addSource(r'''
9083 f() {
9084 List list = [1,2,3];
9085 for (int x in list) {}
9086 for (int x in list) {}
9087 }''');
9088 computeLibrarySourceErrors(source);
9089 assertNoErrors(source);
9090 verify([source]);
9091 }
9092
9093 void test_forLoops_nonConflicting() {
9094 Source source = addSource(r'''
9095 f() {
9096 for (int i = 0; i < 3; i++) {
9097 }
9098 for (int i = 0; i < 3; i++) {
9099 }
9100 }''');
9101 computeLibrarySourceErrors(source);
9102 assertNoErrors(source);
9103 verify([source]);
9104 }
9105
9106 void test_functionTypeAlias() {
9107 Source source = addSource(r'''
9108 typedef bool P(e);
9109 class A {
9110 P p;
9111 m(e) {
9112 if (p(e)) {}
9113 }
9114 }''');
9115 computeLibrarySourceErrors(source);
9116 assertNoErrors(source);
9117 verify([source]);
9118 }
9119
9120 void test_getter_and_setter_fromMixins_bare_identifier() {
9121 Source source = addSource('''
9122 class B {}
9123 class M1 {
9124 get x => null;
9125 set x(value) {}
9126 }
9127 class M2 {
9128 get x => null;
9129 set x(value) {}
9130 }
9131 class C extends B with M1, M2 {
9132 void f() {
9133 x += 1;
9134 }
9135 }
9136 ''');
9137 LibraryElement library = resolve2(source);
9138 assertNoErrors(source);
9139 verify([source]);
9140 // Verify that both the getter and setter for "x" in C.f() refer to the
9141 // accessors defined in M2.
9142 ClassElement classC = library.definingCompilationUnit.types[3];
9143 MethodDeclaration f = classC.getMethod('f').computeNode();
9144 BlockFunctionBody body = f.body;
9145 ExpressionStatement stmt = body.block.statements[0];
9146 AssignmentExpression assignment = stmt.expression;
9147 SimpleIdentifier leftHandSide = assignment.leftHandSide;
9148 expect(leftHandSide.staticElement.enclosingElement.name, 'M2');
9149 expect(leftHandSide.auxiliaryElements.staticElement.enclosingElement.name,
9150 'M2');
9151 }
9152
9153 void test_getter_fromMixins_bare_identifier() {
9154 Source source = addSource('''
9155 class B {}
9156 class M1 {
9157 get x => null;
9158 }
9159 class M2 {
9160 get x => null;
9161 }
9162 class C extends B with M1, M2 {
9163 f() {
9164 return x;
9165 }
9166 }
9167 ''');
9168 LibraryElement library = resolve2(source);
9169 assertNoErrors(source);
9170 verify([source]);
9171 // Verify that the getter for "x" in C.f() refers to the getter defined in
9172 // M2.
9173 ClassElement classC = library.definingCompilationUnit.types[3];
9174 MethodDeclaration f = classC.getMethod('f').computeNode();
9175 BlockFunctionBody body = f.body;
9176 ReturnStatement stmt = body.block.statements[0];
9177 SimpleIdentifier x = stmt.expression;
9178 expect(x.staticElement.enclosingElement.name, 'M2');
9179 }
9180
9181 void test_getter_fromMixins_property_access() {
9182 Source source = addSource('''
9183 class B {}
9184 class M1 {
9185 get x => null;
9186 }
9187 class M2 {
9188 get x => null;
9189 }
9190 class C extends B with M1, M2 {}
9191 void main() {
9192 var y = new C().x;
9193 }
9194 ''');
9195 LibraryElement library = resolve2(source);
9196 assertNoErrors(source);
9197 verify([source]);
9198 // Verify that the getter for "x" in "new C().x" refers to the getter
9199 // defined in M2.
9200 FunctionDeclaration main =
9201 library.definingCompilationUnit.functions[0].computeNode();
9202 BlockFunctionBody body = main.functionExpression.body;
9203 VariableDeclarationStatement stmt = body.block.statements[0];
9204 PropertyAccess propertyAccess = stmt.variables.variables[0].initializer;
9205 expect(
9206 propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
9207 }
9208
9209 void test_getterAndSetterWithDifferentTypes() {
9210 Source source = addSource(r'''
9211 class A {
9212 int get f => 0;
9213 void set f(String s) {}
9214 }
9215 g (A a) {
9216 a.f = a.f.toString();
9217 }''');
9218 computeLibrarySourceErrors(source);
9219 assertErrors(
9220 source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
9221 verify([source]);
9222 }
9223
9224 void test_hasReferenceToSuper() {
9225 Source source = addSource(r'''
9226 class A {}
9227 class B {toString() => super.toString();}''');
9228 LibraryElement library = resolve2(source);
9229 expect(library, isNotNull);
9230 CompilationUnitElement unit = library.definingCompilationUnit;
9231 expect(unit, isNotNull);
9232 List<ClassElement> classes = unit.types;
9233 expect(classes, hasLength(2));
9234 expect(classes[0].hasReferenceToSuper, isFalse);
9235 expect(classes[1].hasReferenceToSuper, isTrue);
9236 assertNoErrors(source);
9237 verify([source]);
9238 }
9239
9240 void test_import_hide() {
9241 addNamedSource(
9242 "/lib1.dart",
9243 r'''
9244 library lib1;
9245 set foo(value) {}
9246 class A {}''');
9247 addNamedSource(
9248 "/lib2.dart",
9249 r'''
9250 library lib2;
9251 set foo(value) {}''');
9252 Source source = addNamedSource(
9253 "/lib3.dart",
9254 r'''
9255 import 'lib1.dart' hide foo;
9256 import 'lib2.dart';
9257
9258 main() {
9259 foo = 0;
9260 }
9261 A a;''');
9262 computeLibrarySourceErrors(source);
9263 assertNoErrors(source);
9264 verify([source]);
9265 }
9266
9267 void test_import_prefix() {
9268 addNamedSource(
9269 "/two.dart",
9270 r'''
9271 library two;
9272 f(int x) {
9273 return x * x;
9274 }''');
9275 Source source = addNamedSource(
9276 "/one.dart",
9277 r'''
9278 library one;
9279 import 'two.dart' as _two;
9280 main() {
9281 _two.f(0);
9282 }''');
9283 computeLibrarySourceErrors(source);
9284 assertNoErrors(source);
9285 verify([source]);
9286 }
9287
9288 void test_import_spaceInUri() {
9289 addNamedSource(
9290 "/sub folder/lib.dart",
9291 r'''
9292 library lib;
9293 foo() {}''');
9294 Source source = addNamedSource(
9295 "/app.dart",
9296 r'''
9297 import 'sub folder/lib.dart';
9298
9299 main() {
9300 foo();
9301 }''');
9302 computeLibrarySourceErrors(source);
9303 assertNoErrors(source);
9304 verify([source]);
9305 }
9306
9307 void test_indexExpression_typeParameters() {
9308 Source source = addSource(r'''
9309 f() {
9310 List<int> a;
9311 a[0];
9312 List<List<int>> b;
9313 b[0][0];
9314 List<List<List<int>>> c;
9315 c[0][0][0];
9316 }''');
9317 computeLibrarySourceErrors(source);
9318 assertNoErrors(source);
9319 verify([source]);
9320 }
9321
9322 void test_indexExpression_typeParameters_invalidAssignmentWarning() {
9323 Source source = addSource(r'''
9324 f() {
9325 List<List<int>> b;
9326 b[0][0] = 'hi';
9327 }''');
9328 computeLibrarySourceErrors(source);
9329 assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
9330 verify([source]);
9331 }
9332
9333 void test_indirectOperatorThroughCall() {
9334 Source source = addSource(r'''
9335 class A {
9336 B call() { return new B(); }
9337 }
9338
9339 class B {
9340 int operator [](int i) { return i; }
9341 }
9342
9343 A f = new A();
9344
9345 g(int x) {}
9346
9347 main() {
9348 g(f()[0]);
9349 }''');
9350 computeLibrarySourceErrors(source);
9351 assertNoErrors(source);
9352 verify([source]);
9353 }
9354
9355 void test_invoke_dynamicThroughGetter() {
9356 Source source = addSource(r'''
9357 class A {
9358 List get X => [() => 0];
9359 m(A a) {
9360 X.last;
9361 }
9362 }''');
9363 computeLibrarySourceErrors(source);
9364 assertNoErrors(source);
9365 verify([source]);
9366 }
9367
9368 void test_isValidMixin_badSuperclass() {
9369 Source source = addSource(r'''
9370 class A extends B {}
9371 class B {}''');
9372 LibraryElement library = resolve2(source);
9373 expect(library, isNotNull);
9374 CompilationUnitElement unit = library.definingCompilationUnit;
9375 expect(unit, isNotNull);
9376 List<ClassElement> classes = unit.types;
9377 expect(classes, hasLength(2));
9378 expect(classes[0].isValidMixin, isFalse);
9379 assertNoErrors(source);
9380 verify([source]);
9381 }
9382
9383 void test_isValidMixin_constructor() {
9384 Source source = addSource(r'''
9385 class A {
9386 A() {}
9387 }''');
9388 LibraryElement library = resolve2(source);
9389 expect(library, isNotNull);
9390 CompilationUnitElement unit = library.definingCompilationUnit;
9391 expect(unit, isNotNull);
9392 List<ClassElement> classes = unit.types;
9393 expect(classes, hasLength(1));
9394 expect(classes[0].isValidMixin, isFalse);
9395 assertNoErrors(source);
9396 verify([source]);
9397 }
9398
9399 void test_isValidMixin_super() {
9400 Source source = addSource(r'''
9401 class A {
9402 toString() {
9403 return super.toString();
9404 }
9405 }''');
9406 LibraryElement library = resolve2(source);
9407 expect(library, isNotNull);
9408 CompilationUnitElement unit = library.definingCompilationUnit;
9409 expect(unit, isNotNull);
9410 List<ClassElement> classes = unit.types;
9411 expect(classes, hasLength(1));
9412 expect(classes[0].isValidMixin, isFalse);
9413 assertNoErrors(source);
9414 verify([source]);
9415 }
9416
9417 void test_isValidMixin_valid() {
9418 Source source = addSource("class A {}");
9419 LibraryElement library = resolve2(source);
9420 expect(library, isNotNull);
9421 CompilationUnitElement unit = library.definingCompilationUnit;
9422 expect(unit, isNotNull);
9423 List<ClassElement> classes = unit.types;
9424 expect(classes, hasLength(1));
9425 expect(classes[0].isValidMixin, isTrue);
9426 assertNoErrors(source);
9427 verify([source]);
9428 }
9429
9430 void test_labels_switch() {
9431 Source source = addSource(r'''
9432 void doSwitch(int target) {
9433 switch (target) {
9434 l0: case 0:
9435 continue l1;
9436 l1: case 1:
9437 continue l0;
9438 default:
9439 continue l1;
9440 }
9441 }''');
9442 LibraryElement library = resolve2(source);
9443 expect(library, isNotNull);
9444 assertNoErrors(source);
9445 verify([source]);
9446 }
9447
9448 void test_localVariable_types_invoked() {
9449 Source source = addSource(r'''
9450 const A = null;
9451 main() {
9452 var myVar = (int p) => 'foo';
9453 myVar(42);
9454 }''');
9455 LibraryElement library = resolve2(source);
9456 expect(library, isNotNull);
9457 CompilationUnit unit =
9458 analysisContext.resolveCompilationUnit(source, library);
9459 expect(unit, isNotNull);
9460 List<bool> found = [false];
9461 List<CaughtException> thrownException = new List<CaughtException>(1);
9462 unit.accept(new _SimpleResolverTest_localVariable_types_invoked(
9463 this, found, thrownException));
9464 if (thrownException[0] != null) {
9465 throw new AnalysisException(
9466 "Exception", new CaughtException(thrownException[0], null));
9467 }
9468 expect(found[0], isTrue);
9469 }
9470
9471 void test_metadata_class() {
9472 Source source = addSource(r'''
9473 const A = null;
9474 @A class C<A> {}''');
9475 LibraryElement library = resolve2(source);
9476 expect(library, isNotNull);
9477 CompilationUnitElement unitElement = library.definingCompilationUnit;
9478 expect(unitElement, isNotNull);
9479 List<ClassElement> classes = unitElement.types;
9480 expect(classes, hasLength(1));
9481 List<ElementAnnotation> annotations = classes[0].metadata;
9482 expect(annotations, hasLength(1));
9483 assertNoErrors(source);
9484 verify([source]);
9485 CompilationUnit unit = resolveCompilationUnit(source, library);
9486 NodeList<CompilationUnitMember> declarations = unit.declarations;
9487 expect(declarations, hasLength(2));
9488 Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
9489 .variables
9490 .variables[0].name.staticElement;
9491 EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
9492 PropertyInducingElement, expectedElement);
9493 expectedElement = (expectedElement as PropertyInducingElement).getter;
9494 Element actualElement =
9495 (declarations[1] as ClassDeclaration).metadata[0].name.staticElement;
9496 expect(actualElement, same(expectedElement));
9497 }
9498
9499 void test_metadata_field() {
9500 Source source = addSource(r'''
9501 const A = null;
9502 class C {
9503 @A int f;
9504 }''');
9505 LibraryElement library = resolve2(source);
9506 expect(library, isNotNull);
9507 CompilationUnitElement unit = library.definingCompilationUnit;
9508 expect(unit, isNotNull);
9509 List<ClassElement> classes = unit.types;
9510 expect(classes, hasLength(1));
9511 FieldElement field = classes[0].fields[0];
9512 List<ElementAnnotation> annotations = field.metadata;
9513 expect(annotations, hasLength(1));
9514 assertNoErrors(source);
9515 verify([source]);
9516 }
9517
9518 void test_metadata_fieldFormalParameter() {
9519 Source source = addSource(r'''
9520 const A = null;
9521 class C {
9522 int f;
9523 C(@A this.f);
9524 }''');
9525 LibraryElement library = resolve2(source);
9526 expect(library, isNotNull);
9527 CompilationUnitElement unit = library.definingCompilationUnit;
9528 expect(unit, isNotNull);
9529 List<ClassElement> classes = unit.types;
9530 expect(classes, hasLength(1));
9531 List<ConstructorElement> constructors = classes[0].constructors;
9532 expect(constructors, hasLength(1));
9533 List<ParameterElement> parameters = constructors[0].parameters;
9534 expect(parameters, hasLength(1));
9535 List<ElementAnnotation> annotations = parameters[0].metadata;
9536 expect(annotations, hasLength(1));
9537 assertNoErrors(source);
9538 verify([source]);
9539 }
9540
9541 void test_metadata_function() {
9542 Source source = addSource(r'''
9543 const A = null;
9544 @A f() {}''');
9545 LibraryElement library = resolve2(source);
9546 expect(library, isNotNull);
9547 CompilationUnitElement unit = library.definingCompilationUnit;
9548 expect(unit, isNotNull);
9549 List<FunctionElement> functions = unit.functions;
9550 expect(functions, hasLength(1));
9551 List<ElementAnnotation> annotations = functions[0].metadata;
9552 expect(annotations, hasLength(1));
9553 assertNoErrors(source);
9554 verify([source]);
9555 }
9556
9557 void test_metadata_functionTypedParameter() {
9558 Source source = addSource(r'''
9559 const A = null;
9560 f(@A int p(int x)) {}''');
9561 LibraryElement library = resolve2(source);
9562 expect(library, isNotNull);
9563 CompilationUnitElement unit = library.definingCompilationUnit;
9564 expect(unit, isNotNull);
9565 List<FunctionElement> functions = unit.functions;
9566 expect(functions, hasLength(1));
9567 List<ParameterElement> parameters = functions[0].parameters;
9568 expect(parameters, hasLength(1));
9569 List<ElementAnnotation> annotations1 = parameters[0].metadata;
9570 expect(annotations1, hasLength(1));
9571 assertNoErrors(source);
9572 verify([source]);
9573 }
9574
9575 void test_metadata_libraryDirective() {
9576 Source source = addSource(r'''
9577 @A library lib;
9578 const A = null;''');
9579 LibraryElement library = resolve2(source);
9580 expect(library, isNotNull);
9581 List<ElementAnnotation> annotations = library.metadata;
9582 expect(annotations, hasLength(1));
9583 assertNoErrors(source);
9584 verify([source]);
9585 }
9586
9587 void test_metadata_method() {
9588 Source source = addSource(r'''
9589 const A = null;
9590 class C {
9591 @A void m() {}
9592 }''');
9593 LibraryElement library = resolve2(source);
9594 expect(library, isNotNull);
9595 CompilationUnitElement unit = library.definingCompilationUnit;
9596 expect(unit, isNotNull);
9597 List<ClassElement> classes = unit.types;
9598 expect(classes, hasLength(1));
9599 MethodElement method = classes[0].methods[0];
9600 List<ElementAnnotation> annotations = method.metadata;
9601 expect(annotations, hasLength(1));
9602 assertNoErrors(source);
9603 verify([source]);
9604 }
9605
9606 void test_metadata_namedParameter() {
9607 Source source = addSource(r'''
9608 const A = null;
9609 f({@A int p : 0}) {}''');
9610 LibraryElement library = resolve2(source);
9611 expect(library, isNotNull);
9612 CompilationUnitElement unit = library.definingCompilationUnit;
9613 expect(unit, isNotNull);
9614 List<FunctionElement> functions = unit.functions;
9615 expect(functions, hasLength(1));
9616 List<ParameterElement> parameters = functions[0].parameters;
9617 expect(parameters, hasLength(1));
9618 List<ElementAnnotation> annotations1 = parameters[0].metadata;
9619 expect(annotations1, hasLength(1));
9620 assertNoErrors(source);
9621 verify([source]);
9622 }
9623
9624 void test_metadata_positionalParameter() {
9625 Source source = addSource(r'''
9626 const A = null;
9627 f([@A int p = 0]) {}''');
9628 LibraryElement library = resolve2(source);
9629 expect(library, isNotNull);
9630 CompilationUnitElement unit = library.definingCompilationUnit;
9631 expect(unit, isNotNull);
9632 List<FunctionElement> functions = unit.functions;
9633 expect(functions, hasLength(1));
9634 List<ParameterElement> parameters = functions[0].parameters;
9635 expect(parameters, hasLength(1));
9636 List<ElementAnnotation> annotations1 = parameters[0].metadata;
9637 expect(annotations1, hasLength(1));
9638 assertNoErrors(source);
9639 verify([source]);
9640 }
9641
9642 void test_metadata_simpleParameter() {
9643 Source source = addSource(r'''
9644 const A = null;
9645 f(@A p1, @A int p2) {}''');
9646 LibraryElement library = resolve2(source);
9647 expect(library, isNotNull);
9648 CompilationUnitElement unit = library.definingCompilationUnit;
9649 expect(unit, isNotNull);
9650 List<FunctionElement> functions = unit.functions;
9651 expect(functions, hasLength(1));
9652 List<ParameterElement> parameters = functions[0].parameters;
9653 expect(parameters, hasLength(2));
9654 List<ElementAnnotation> annotations1 = parameters[0].metadata;
9655 expect(annotations1, hasLength(1));
9656 List<ElementAnnotation> annotations2 = parameters[1].metadata;
9657 expect(annotations2, hasLength(1));
9658 assertNoErrors(source);
9659 verify([source]);
9660 }
9661
9662 void test_metadata_typedef() {
9663 Source source = addSource(r'''
9664 const A = null;
9665 @A typedef F<A>();''');
9666 LibraryElement library = resolve2(source);
9667 expect(library, isNotNull);
9668 CompilationUnitElement unitElement = library.definingCompilationUnit;
9669 expect(unitElement, isNotNull);
9670 List<FunctionTypeAliasElement> aliases = unitElement.functionTypeAliases;
9671 expect(aliases, hasLength(1));
9672 List<ElementAnnotation> annotations = aliases[0].metadata;
9673 expect(annotations, hasLength(1));
9674 assertNoErrors(source);
9675 verify([source]);
9676 CompilationUnit unit = resolveCompilationUnit(source, library);
9677 NodeList<CompilationUnitMember> declarations = unit.declarations;
9678 expect(declarations, hasLength(2));
9679 Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
9680 .variables
9681 .variables[0].name.staticElement;
9682 EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
9683 PropertyInducingElement, expectedElement);
9684 expectedElement = (expectedElement as PropertyInducingElement).getter;
9685 Element actualElement =
9686 (declarations[1] as FunctionTypeAlias).metadata[0].name.staticElement;
9687 expect(actualElement, same(expectedElement));
9688 }
9689
9690 void test_method_fromMixin() {
9691 Source source = addSource(r'''
9692 class B {
9693 bar() => 1;
9694 }
9695 class A {
9696 foo() => 2;
9697 }
9698
9699 class C extends B with A {
9700 bar() => super.bar();
9701 foo() => super.foo();
9702 }''');
9703 computeLibrarySourceErrors(source);
9704 assertNoErrors(source);
9705 verify([source]);
9706 }
9707
9708 void test_method_fromMixins() {
9709 Source source = addSource('''
9710 class B {}
9711 class M1 {
9712 void f() {}
9713 }
9714 class M2 {
9715 void f() {}
9716 }
9717 class C extends B with M1, M2 {}
9718 void main() {
9719 new C().f();
9720 }
9721 ''');
9722 LibraryElement library = resolve2(source);
9723 assertNoErrors(source);
9724 verify([source]);
9725 // Verify that the "f" in "new C().f()" refers to the "f" defined in M2.
9726 FunctionDeclaration main =
9727 library.definingCompilationUnit.functions[0].computeNode();
9728 BlockFunctionBody body = main.functionExpression.body;
9729 ExpressionStatement stmt = body.block.statements[0];
9730 MethodInvocation expr = stmt.expression;
9731 expect(expr.methodName.staticElement.enclosingElement.name, 'M2');
9732 }
9733
9734 void test_method_fromMixins_bare_identifier() {
9735 Source source = addSource('''
9736 class B {}
9737 class M1 {
9738 void f() {}
9739 }
9740 class M2 {
9741 void f() {}
9742 }
9743 class C extends B with M1, M2 {
9744 void g() {
9745 f();
9746 }
9747 }
9748 ''');
9749 LibraryElement library = resolve2(source);
9750 assertNoErrors(source);
9751 verify([source]);
9752 // Verify that the call to f() in C.g() refers to the method defined in M2.
9753 ClassElement classC = library.definingCompilationUnit.types[3];
9754 MethodDeclaration g = classC.getMethod('g').computeNode();
9755 BlockFunctionBody body = g.body;
9756 ExpressionStatement stmt = body.block.statements[0];
9757 MethodInvocation invocation = stmt.expression;
9758 SimpleIdentifier methodName = invocation.methodName;
9759 expect(methodName.staticElement.enclosingElement.name, 'M2');
9760 }
9761
9762 void test_method_fromMixins_invked_from_outside_class() {
9763 Source source = addSource('''
9764 class B {}
9765 class M1 {
9766 void f() {}
9767 }
9768 class M2 {
9769 void f() {}
9770 }
9771 class C extends B with M1, M2 {}
9772 void main() {
9773 new C().f();
9774 }
9775 ''');
9776 LibraryElement library = resolve2(source);
9777 assertNoErrors(source);
9778 verify([source]);
9779 // Verify that the call to f() in "new C().f()" refers to the method
9780 // defined in M2.
9781 FunctionDeclaration main =
9782 library.definingCompilationUnit.functions[0].computeNode();
9783 BlockFunctionBody body = main.functionExpression.body;
9784 ExpressionStatement stmt = body.block.statements[0];
9785 MethodInvocation invocation = stmt.expression;
9786 expect(invocation.methodName.staticElement.enclosingElement.name, 'M2');
9787 }
9788
9789 void test_method_fromSuperclassMixin() {
9790 Source source = addSource(r'''
9791 class A {
9792 void m1() {}
9793 }
9794 class B extends Object with A {
9795 }
9796 class C extends B {
9797 }
9798 f(C c) {
9799 c.m1();
9800 }''');
9801 computeLibrarySourceErrors(source);
9802 assertNoErrors(source);
9803 verify([source]);
9804 }
9805
9806 void test_methodCascades() {
9807 Source source = addSource(r'''
9808 class A {
9809 void m1() {}
9810 void m2() {}
9811 void m() {
9812 A a = new A();
9813 a..m1()
9814 ..m2();
9815 }
9816 }''');
9817 computeLibrarySourceErrors(source);
9818 assertNoErrors(source);
9819 verify([source]);
9820 }
9821
9822 void test_methodCascades_withSetter() {
9823 Source source = addSource(r'''
9824 class A {
9825 String name;
9826 void m1() {}
9827 void m2() {}
9828 void m() {
9829 A a = new A();
9830 a..m1()
9831 ..name = 'name'
9832 ..m2();
9833 }
9834 }''');
9835 computeLibrarySourceErrors(source);
9836 // failing with error code: INVOCATION_OF_NON_FUNCTION
9837 assertNoErrors(source);
9838 verify([source]);
9839 }
9840
9841 void test_resolveAgainstNull() {
9842 Source source = addSource(r'''
9843 f(var p) {
9844 return null == p;
9845 }''');
9846 computeLibrarySourceErrors(source);
9847 assertNoErrors(source);
9848 }
9849
9850 void test_setter_fromMixins_bare_identifier() {
9851 Source source = addSource('''
9852 class B {}
9853 class M1 {
9854 set x(value) {}
9855 }
9856 class M2 {
9857 set x(value) {}
9858 }
9859 class C extends B with M1, M2 {
9860 void f() {
9861 x = 1;
9862 }
9863 }
9864 ''');
9865 LibraryElement library = resolve2(source);
9866 assertNoErrors(source);
9867 verify([source]);
9868 // Verify that the setter for "x" in C.f() refers to the setter defined in
9869 // M2.
9870 ClassElement classC = library.definingCompilationUnit.types[3];
9871 MethodDeclaration f = classC.getMethod('f').computeNode();
9872 BlockFunctionBody body = f.body;
9873 ExpressionStatement stmt = body.block.statements[0];
9874 AssignmentExpression assignment = stmt.expression;
9875 SimpleIdentifier leftHandSide = assignment.leftHandSide;
9876 expect(leftHandSide.staticElement.enclosingElement.name, 'M2');
9877 }
9878
9879 void test_setter_fromMixins_property_access() {
9880 Source source = addSource('''
9881 class B {}
9882 class M1 {
9883 set x(value) {}
9884 }
9885 class M2 {
9886 set x(value) {}
9887 }
9888 class C extends B with M1, M2 {}
9889 void main() {
9890 new C().x = 1;
9891 }
9892 ''');
9893 LibraryElement library = resolve2(source);
9894 assertNoErrors(source);
9895 verify([source]);
9896 // Verify that the setter for "x" in "new C().x" refers to the setter
9897 // defined in M2.
9898 FunctionDeclaration main =
9899 library.definingCompilationUnit.functions[0].computeNode();
9900 BlockFunctionBody body = main.functionExpression.body;
9901 ExpressionStatement stmt = body.block.statements[0];
9902 AssignmentExpression assignment = stmt.expression;
9903 PropertyAccess propertyAccess = assignment.leftHandSide;
9904 expect(
9905 propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
9906 }
9907
9908 void test_setter_inherited() {
9909 Source source = addSource(r'''
9910 class A {
9911 int get x => 0;
9912 set x(int p) {}
9913 }
9914 class B extends A {
9915 int get x => super.x == null ? 0 : super.x;
9916 int f() => x = 1;
9917 }''');
9918 computeLibrarySourceErrors(source);
9919 assertNoErrors(source);
9920 verify([source]);
9921 }
9922
9923 void test_setter_static() {
9924 Source source = addSource(r'''
9925 set s(x) {
9926 }
9927
9928 main() {
9929 s = 123;
9930 }''');
9931 computeLibrarySourceErrors(source);
9932 assertNoErrors(source);
9933 verify([source]);
9934 }
9935
9936 /**
9937 * Resolve the given source and verify that the arguments in a specific method invocation were
9938 * correctly resolved.
9939 *
9940 * The source is expected to be source for a compilation unit, the first decla ration is expected
9941 * to be a class, the first member of which is expected to be a method with a block body, and the
9942 * first statement in the body is expected to be an expression statement whose expression is a
9943 * method invocation. It is the arguments to that method invocation that are t ested. The method
9944 * invocation can contain errors.
9945 *
9946 * The arguments were resolved correctly if the number of expressions in the l ist matches the
9947 * length of the array of indices and if, for each index in the array of indic es, the parameter to
9948 * which the argument expression was resolved is the parameter in the invoked method's list of
9949 * parameters at that index. Arguments that should not be resolved to a parame ter because of an
9950 * error can be denoted by including a negative index in the array of indices.
9951 *
9952 * @param source the source to be resolved
9953 * @param indices the array of indices used to associate arguments with parame ters
9954 * @throws Exception if the source could not be resolved or if the structure o f the source is not
9955 * valid
9956 */
9957 void _validateArgumentResolution(Source source, List<int> indices) {
9958 LibraryElement library = resolve2(source);
9959 expect(library, isNotNull);
9960 ClassElement classElement = library.definingCompilationUnit.types[0];
9961 List<ParameterElement> parameters = classElement.methods[1].parameters;
9962 CompilationUnit unit = resolveCompilationUnit(source, library);
9963 expect(unit, isNotNull);
9964 ClassDeclaration classDeclaration =
9965 unit.declarations[0] as ClassDeclaration;
9966 MethodDeclaration methodDeclaration =
9967 classDeclaration.members[0] as MethodDeclaration;
9968 Block block = (methodDeclaration.body as BlockFunctionBody).block;
9969 ExpressionStatement statement = block.statements[0] as ExpressionStatement;
9970 MethodInvocation invocation = statement.expression as MethodInvocation;
9971 NodeList<Expression> arguments = invocation.argumentList.arguments;
9972 int argumentCount = arguments.length;
9973 expect(argumentCount, indices.length);
9974 for (int i = 0; i < argumentCount; i++) {
9975 Expression argument = arguments[i];
9976 ParameterElement element = argument.staticParameterElement;
9977 int index = indices[i];
9978 if (index < 0) {
9979 expect(element, isNull);
9980 } else {
9981 expect(element, same(parameters[index]));
9982 }
9983 }
9984 }
9985 }
9986
9987 class SourceContainer_ChangeSetTest_test_toString implements SourceContainer {
9988 @override
9989 bool contains(Source source) => false;
9990 }
9991
9992 /**
9993 * Like [StaticTypeAnalyzerTest], but as end-to-end tests.
9994 */
9995 @reflectiveTest
9996 class StaticTypeAnalyzer2Test extends _StaticTypeAnalyzer2TestShared {
9997 void test_FunctionExpressionInvocation_block() {
9998 String code = r'''
9999 main() {
10000 var foo = (() { return 1; })();
10001 }
10002 ''';
10003 _resolveTestUnit(code);
10004 SimpleIdentifier identifier = _findIdentifier('foo');
10005 VariableDeclaration declaration =
10006 identifier.getAncestor((node) => node is VariableDeclaration);
10007 expect(declaration.initializer.staticType.isDynamic, isTrue);
10008 expect(declaration.initializer.propagatedType, isNull);
10009 }
10010
10011 void test_FunctionExpressionInvocation_curried() {
10012 String code = r'''
10013 typedef int F();
10014 F f() => null;
10015 main() {
10016 var foo = f()();
10017 }
10018 ''';
10019 _resolveTestUnit(code);
10020 SimpleIdentifier identifier = _findIdentifier('foo');
10021 VariableDeclaration declaration =
10022 identifier.getAncestor((node) => node is VariableDeclaration);
10023 expect(declaration.initializer.staticType.name, 'int');
10024 expect(declaration.initializer.propagatedType, isNull);
10025 }
10026
10027 void test_FunctionExpressionInvocation_expression() {
10028 String code = r'''
10029 main() {
10030 var foo = (() => 1)();
10031 }
10032 ''';
10033 _resolveTestUnit(code);
10034 SimpleIdentifier identifier = _findIdentifier('foo');
10035 VariableDeclaration declaration =
10036 identifier.getAncestor((node) => node is VariableDeclaration);
10037 expect(declaration.initializer.staticType.name, 'int');
10038 expect(declaration.initializer.propagatedType, isNull);
10039 }
10040
10041 void test_MethodInvocation_nameType_localVariable() {
10042 String code = r"""
10043 typedef Foo();
10044 main() {
10045 Foo foo;
10046 foo();
10047 }
10048 """;
10049 _resolveTestUnit(code);
10050 // "foo" should be resolved to the "Foo" type
10051 SimpleIdentifier identifier = _findIdentifier("foo();");
10052 DartType type = identifier.staticType;
10053 expect(type, new isInstanceOf<FunctionType>());
10054 }
10055
10056 void test_MethodInvocation_nameType_parameter_FunctionTypeAlias() {
10057 String code = r"""
10058 typedef Foo();
10059 main(Foo foo) {
10060 foo();
10061 }
10062 """;
10063 _resolveTestUnit(code);
10064 // "foo" should be resolved to the "Foo" type
10065 SimpleIdentifier identifier = _findIdentifier("foo();");
10066 DartType type = identifier.staticType;
10067 expect(type, new isInstanceOf<FunctionType>());
10068 }
10069
10070 void test_MethodInvocation_nameType_parameter_propagatedType() {
10071 String code = r"""
10072 typedef Foo();
10073 main(p) {
10074 if (p is Foo) {
10075 p();
10076 }
10077 }
10078 """;
10079 _resolveTestUnit(code);
10080 SimpleIdentifier identifier = _findIdentifier("p()");
10081 expect(identifier.staticType, DynamicTypeImpl.instance);
10082 {
10083 FunctionType type = identifier.propagatedType;
10084 expect(type, isNotNull);
10085 expect(type.name, 'Foo');
10086 }
10087 }
10088 }
10089
10090 @reflectiveTest
10091 class StaticTypeAnalyzerTest extends EngineTestCase {
10092 /**
10093 * The error listener to which errors will be reported.
10094 */
10095 GatheringErrorListener _listener;
10096
10097 /**
10098 * The resolver visitor used to create the analyzer.
10099 */
10100 ResolverVisitor _visitor;
10101
10102 /**
10103 * The analyzer being used to analyze the test cases.
10104 */
10105 StaticTypeAnalyzer _analyzer;
10106
10107 /**
10108 * The type provider used to access the types.
10109 */
10110 TestTypeProvider _typeProvider;
10111
10112 void fail_visitFunctionExpressionInvocation() {
10113 fail("Not yet tested");
10114 _listener.assertNoErrors();
10115 }
10116
10117 void fail_visitMethodInvocation() {
10118 fail("Not yet tested");
10119 _listener.assertNoErrors();
10120 }
10121
10122 void fail_visitSimpleIdentifier() {
10123 fail("Not yet tested");
10124 _listener.assertNoErrors();
10125 }
10126
10127 @override
10128 void setUp() {
10129 _listener = new GatheringErrorListener();
10130 _typeProvider = new TestTypeProvider();
10131 _analyzer = _createAnalyzer();
10132 }
10133
10134 void test_flatten_derived() {
10135 // class Derived<T> extends Future<T> { ... }
10136 ClassElementImpl derivedClass =
10137 ElementFactory.classElement2('Derived', ['T']);
10138 derivedClass.supertype = _typeProvider.futureType
10139 .substitute4([derivedClass.typeParameters[0].type]);
10140 InterfaceType intType = _typeProvider.intType;
10141 DartType dynamicType = _typeProvider.dynamicType;
10142 InterfaceType derivedIntType = derivedClass.type.substitute4([intType]);
10143 // flatten(Derived) = dynamic
10144 InterfaceType derivedDynamicType =
10145 derivedClass.type.substitute4([dynamicType]);
10146 expect(_flatten(derivedDynamicType), dynamicType);
10147 // flatten(Derived<int>) = int
10148 expect(_flatten(derivedIntType), intType);
10149 // flatten(Derived<Derived>) = Derived
10150 expect(_flatten(derivedClass.type.substitute4([derivedDynamicType])),
10151 derivedDynamicType);
10152 // flatten(Derived<Derived<int>>) = Derived<int>
10153 expect(_flatten(derivedClass.type.substitute4([derivedIntType])),
10154 derivedIntType);
10155 }
10156
10157 void test_flatten_inhibit_recursion() {
10158 // class A extends B
10159 // class B extends A
10160 ClassElementImpl classA = ElementFactory.classElement2('A', []);
10161 ClassElementImpl classB = ElementFactory.classElement2('B', []);
10162 classA.supertype = classB.type;
10163 classB.supertype = classA.type;
10164 // flatten(A) = A and flatten(B) = B, since neither class contains Future
10165 // in its class hierarchy. Even though there is a loop in the class
10166 // hierarchy, flatten() should terminate.
10167 expect(_flatten(classA.type), classA.type);
10168 expect(_flatten(classB.type), classB.type);
10169 }
10170
10171 void test_flatten_related_derived_types() {
10172 InterfaceType intType = _typeProvider.intType;
10173 InterfaceType numType = _typeProvider.numType;
10174 // class Derived<T> extends Future<T>
10175 ClassElementImpl derivedClass =
10176 ElementFactory.classElement2('Derived', ['T']);
10177 derivedClass.supertype = _typeProvider.futureType
10178 .substitute4([derivedClass.typeParameters[0].type]);
10179 InterfaceType derivedType = derivedClass.type;
10180 // class A extends Derived<int> implements Derived<num> { ... }
10181 ClassElementImpl classA =
10182 ElementFactory.classElement('A', derivedType.substitute4([intType]));
10183 classA.interfaces = <InterfaceType>[
10184 derivedType.substitute4([numType])
10185 ];
10186 // class B extends Future<num> implements Future<int> { ... }
10187 ClassElementImpl classB =
10188 ElementFactory.classElement('B', derivedType.substitute4([numType]));
10189 classB.interfaces = <InterfaceType>[
10190 derivedType.substitute4([intType])
10191 ];
10192 // flatten(A) = flatten(B) = int, since int is more specific than num.
10193 // The code in flatten() that inhibits infinite recursion shouldn't be
10194 // fooled by the fact that Derived appears twice in the type hierarchy.
10195 expect(_flatten(classA.type), intType);
10196 expect(_flatten(classB.type), intType);
10197 }
10198
10199 void test_flatten_related_types() {
10200 InterfaceType futureType = _typeProvider.futureType;
10201 InterfaceType intType = _typeProvider.intType;
10202 InterfaceType numType = _typeProvider.numType;
10203 // class A extends Future<int> implements Future<num> { ... }
10204 ClassElementImpl classA =
10205 ElementFactory.classElement('A', futureType.substitute4([intType]));
10206 classA.interfaces = <InterfaceType>[
10207 futureType.substitute4([numType])
10208 ];
10209 // class B extends Future<num> implements Future<int> { ... }
10210 ClassElementImpl classB =
10211 ElementFactory.classElement('B', futureType.substitute4([numType]));
10212 classB.interfaces = <InterfaceType>[
10213 futureType.substitute4([intType])
10214 ];
10215 // flatten(A) = flatten(B) = int, since int is more specific than num.
10216 expect(_flatten(classA.type), intType);
10217 expect(_flatten(classB.type), intType);
10218 }
10219
10220 void test_flatten_simple() {
10221 InterfaceType intType = _typeProvider.intType;
10222 DartType dynamicType = _typeProvider.dynamicType;
10223 InterfaceType futureDynamicType = _typeProvider.futureDynamicType;
10224 InterfaceType futureIntType =
10225 _typeProvider.futureType.substitute4([intType]);
10226 InterfaceType futureFutureDynamicType =
10227 _typeProvider.futureType.substitute4([futureDynamicType]);
10228 InterfaceType futureFutureIntType =
10229 _typeProvider.futureType.substitute4([futureIntType]);
10230 // flatten(int) = int
10231 expect(_flatten(intType), intType);
10232 // flatten(dynamic) = dynamic
10233 expect(_flatten(dynamicType), dynamicType);
10234 // flatten(Future) = dynamic
10235 expect(_flatten(futureDynamicType), dynamicType);
10236 // flatten(Future<int>) = int
10237 expect(_flatten(futureIntType), intType);
10238 // flatten(Future<Future>) = dynamic
10239 expect(_flatten(futureFutureDynamicType), dynamicType);
10240 // flatten(Future<Future<int>>) = int
10241 expect(_flatten(futureFutureIntType), intType);
10242 }
10243
10244 void test_flatten_unrelated_types() {
10245 InterfaceType futureType = _typeProvider.futureType;
10246 InterfaceType intType = _typeProvider.intType;
10247 InterfaceType stringType = _typeProvider.stringType;
10248 // class A extends Future<int> implements Future<String> { ... }
10249 ClassElementImpl classA =
10250 ElementFactory.classElement('A', futureType.substitute4([intType]));
10251 classA.interfaces = <InterfaceType>[
10252 futureType.substitute4([stringType])
10253 ];
10254 // class B extends Future<String> implements Future<int> { ... }
10255 ClassElementImpl classB =
10256 ElementFactory.classElement('B', futureType.substitute4([stringType]));
10257 classB.interfaces = <InterfaceType>[
10258 futureType.substitute4([intType])
10259 ];
10260 // flatten(A) = A and flatten(B) = B, since neither string nor int is more
10261 // specific than the other.
10262 expect(_flatten(classA.type), classA.type);
10263 expect(_flatten(classB.type), classB.type);
10264 }
10265
10266 void test_visitAdjacentStrings() {
10267 // "a" "b"
10268 Expression node = AstFactory
10269 .adjacentStrings([_resolvedString("a"), _resolvedString("b")]);
10270 expect(_analyze(node), same(_typeProvider.stringType));
10271 _listener.assertNoErrors();
10272 }
10273
10274 void test_visitAsExpression() {
10275 // class A { ... this as B ... }
10276 // class B extends A {}
10277 ClassElement superclass = ElementFactory.classElement2("A");
10278 InterfaceType superclassType = superclass.type;
10279 ClassElement subclass = ElementFactory.classElement("B", superclassType);
10280 Expression node = AstFactory.asExpression(
10281 AstFactory.thisExpression(), AstFactory.typeName(subclass));
10282 expect(_analyze3(node, superclassType), same(subclass.type));
10283 _listener.assertNoErrors();
10284 }
10285
10286 void test_visitAssignmentExpression_compound() {
10287 // i += 1
10288 InterfaceType numType = _typeProvider.numType;
10289 SimpleIdentifier identifier = _resolvedVariable(_typeProvider.intType, "i");
10290 AssignmentExpression node = AstFactory.assignmentExpression(
10291 identifier, TokenType.PLUS_EQ, _resolvedInteger(1));
10292 MethodElement plusMethod = getMethod(numType, "+");
10293 node.staticElement = plusMethod;
10294 expect(_analyze(node), same(numType));
10295 _listener.assertNoErrors();
10296 }
10297
10298 void test_visitAssignmentExpression_compoundIfNull_differentTypes() {
10299 // double d; d ??= 0
10300 Expression node = AstFactory.assignmentExpression(
10301 _resolvedVariable(_typeProvider.doubleType, 'd'),
10302 TokenType.QUESTION_QUESTION_EQ,
10303 _resolvedInteger(0));
10304 expect(_analyze(node), same(_typeProvider.numType));
10305 _listener.assertNoErrors();
10306 }
10307
10308 void test_visitAssignmentExpression_compoundIfNull_sameTypes() {
10309 // int i; i ??= 0
10310 Expression node = AstFactory.assignmentExpression(
10311 _resolvedVariable(_typeProvider.intType, 'i'),
10312 TokenType.QUESTION_QUESTION_EQ,
10313 _resolvedInteger(0));
10314 expect(_analyze(node), same(_typeProvider.intType));
10315 _listener.assertNoErrors();
10316 }
10317
10318 void test_visitAssignmentExpression_simple() {
10319 // i = 0
10320 InterfaceType intType = _typeProvider.intType;
10321 Expression node = AstFactory.assignmentExpression(
10322 _resolvedVariable(intType, "i"), TokenType.EQ, _resolvedInteger(0));
10323 expect(_analyze(node), same(intType));
10324 _listener.assertNoErrors();
10325 }
10326
10327 void test_visitAwaitExpression_flattened() {
10328 // await e, where e has type Future<Future<int>>
10329 InterfaceType intType = _typeProvider.intType;
10330 InterfaceType futureIntType =
10331 _typeProvider.futureType.substitute4(<DartType>[intType]);
10332 InterfaceType futureFutureIntType =
10333 _typeProvider.futureType.substitute4(<DartType>[futureIntType]);
10334 Expression node =
10335 AstFactory.awaitExpression(_resolvedVariable(futureFutureIntType, 'e'));
10336 expect(_analyze(node), same(intType));
10337 _listener.assertNoErrors();
10338 }
10339
10340 void test_visitAwaitExpression_simple() {
10341 // await e, where e has type Future<int>
10342 InterfaceType intType = _typeProvider.intType;
10343 InterfaceType futureIntType =
10344 _typeProvider.futureType.substitute4(<DartType>[intType]);
10345 Expression node =
10346 AstFactory.awaitExpression(_resolvedVariable(futureIntType, 'e'));
10347 expect(_analyze(node), same(intType));
10348 _listener.assertNoErrors();
10349 }
10350
10351 void test_visitBinaryExpression_equals() {
10352 // 2 == 3
10353 Expression node = AstFactory.binaryExpression(
10354 _resolvedInteger(2), TokenType.EQ_EQ, _resolvedInteger(3));
10355 expect(_analyze(node), same(_typeProvider.boolType));
10356 _listener.assertNoErrors();
10357 }
10358
10359 void test_visitBinaryExpression_ifNull() {
10360 // 1 ?? 1.5
10361 Expression node = AstFactory.binaryExpression(
10362 _resolvedInteger(1), TokenType.QUESTION_QUESTION, _resolvedDouble(1.5));
10363 expect(_analyze(node), same(_typeProvider.numType));
10364 _listener.assertNoErrors();
10365 }
10366
10367 void test_visitBinaryExpression_logicalAnd() {
10368 // false && true
10369 Expression node = AstFactory.binaryExpression(
10370 AstFactory.booleanLiteral(false),
10371 TokenType.AMPERSAND_AMPERSAND,
10372 AstFactory.booleanLiteral(true));
10373 expect(_analyze(node), same(_typeProvider.boolType));
10374 _listener.assertNoErrors();
10375 }
10376
10377 void test_visitBinaryExpression_logicalOr() {
10378 // false || true
10379 Expression node = AstFactory.binaryExpression(
10380 AstFactory.booleanLiteral(false),
10381 TokenType.BAR_BAR,
10382 AstFactory.booleanLiteral(true));
10383 expect(_analyze(node), same(_typeProvider.boolType));
10384 _listener.assertNoErrors();
10385 }
10386
10387 void test_visitBinaryExpression_minusID_propagated() {
10388 // a - b
10389 BinaryExpression node = AstFactory.binaryExpression(
10390 _propagatedVariable(_typeProvider.intType, 'a'),
10391 TokenType.MINUS,
10392 _propagatedVariable(_typeProvider.doubleType, 'b'));
10393 node.propagatedElement = getMethod(_typeProvider.numType, "+");
10394 _analyze(node);
10395 expect(node.propagatedType, same(_typeProvider.doubleType));
10396 _listener.assertNoErrors();
10397 }
10398
10399 void test_visitBinaryExpression_notEquals() {
10400 // 2 != 3
10401 Expression node = AstFactory.binaryExpression(
10402 _resolvedInteger(2), TokenType.BANG_EQ, _resolvedInteger(3));
10403 expect(_analyze(node), same(_typeProvider.boolType));
10404 _listener.assertNoErrors();
10405 }
10406
10407 void test_visitBinaryExpression_plusID() {
10408 // 1 + 2.0
10409 BinaryExpression node = AstFactory.binaryExpression(
10410 _resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0));
10411 node.staticElement = getMethod(_typeProvider.numType, "+");
10412 expect(_analyze(node), same(_typeProvider.doubleType));
10413 _listener.assertNoErrors();
10414 }
10415
10416 void test_visitBinaryExpression_plusII() {
10417 // 1 + 2
10418 BinaryExpression node = AstFactory.binaryExpression(
10419 _resolvedInteger(1), TokenType.PLUS, _resolvedInteger(2));
10420 node.staticElement = getMethod(_typeProvider.numType, "+");
10421 expect(_analyze(node), same(_typeProvider.intType));
10422 _listener.assertNoErrors();
10423 }
10424
10425 void test_visitBinaryExpression_plusII_propagated() {
10426 // a + b
10427 BinaryExpression node = AstFactory.binaryExpression(
10428 _propagatedVariable(_typeProvider.intType, 'a'),
10429 TokenType.PLUS,
10430 _propagatedVariable(_typeProvider.intType, 'b'));
10431 node.propagatedElement = getMethod(_typeProvider.numType, "+");
10432 _analyze(node);
10433 expect(node.propagatedType, same(_typeProvider.intType));
10434 _listener.assertNoErrors();
10435 }
10436
10437 void test_visitBinaryExpression_slash() {
10438 // 2 / 2
10439 BinaryExpression node = AstFactory.binaryExpression(
10440 _resolvedInteger(2), TokenType.SLASH, _resolvedInteger(2));
10441 node.staticElement = getMethod(_typeProvider.numType, "/");
10442 expect(_analyze(node), same(_typeProvider.doubleType));
10443 _listener.assertNoErrors();
10444 }
10445
10446 void test_visitBinaryExpression_star_notSpecial() {
10447 // class A {
10448 // A operator *(double value);
10449 // }
10450 // (a as A) * 2.0
10451 ClassElementImpl classA = ElementFactory.classElement2("A");
10452 InterfaceType typeA = classA.type;
10453 MethodElement operator =
10454 ElementFactory.methodElement("*", typeA, [_typeProvider.doubleType]);
10455 classA.methods = <MethodElement>[operator];
10456 BinaryExpression node = AstFactory.binaryExpression(
10457 AstFactory.asExpression(
10458 AstFactory.identifier3("a"), AstFactory.typeName(classA)),
10459 TokenType.PLUS,
10460 _resolvedDouble(2.0));
10461 node.staticElement = operator;
10462 expect(_analyze(node), same(typeA));
10463 _listener.assertNoErrors();
10464 }
10465
10466 void test_visitBinaryExpression_starID() {
10467 // 1 * 2.0
10468 BinaryExpression node = AstFactory.binaryExpression(
10469 _resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0));
10470 node.staticElement = getMethod(_typeProvider.numType, "*");
10471 expect(_analyze(node), same(_typeProvider.doubleType));
10472 _listener.assertNoErrors();
10473 }
10474
10475 void test_visitBooleanLiteral_false() {
10476 // false
10477 Expression node = AstFactory.booleanLiteral(false);
10478 expect(_analyze(node), same(_typeProvider.boolType));
10479 _listener.assertNoErrors();
10480 }
10481
10482 void test_visitBooleanLiteral_true() {
10483 // true
10484 Expression node = AstFactory.booleanLiteral(true);
10485 expect(_analyze(node), same(_typeProvider.boolType));
10486 _listener.assertNoErrors();
10487 }
10488
10489 void test_visitCascadeExpression() {
10490 // a..length
10491 Expression node = AstFactory.cascadeExpression(
10492 _resolvedString("a"), [AstFactory.propertyAccess2(null, "length")]);
10493 expect(_analyze(node), same(_typeProvider.stringType));
10494 _listener.assertNoErrors();
10495 }
10496
10497 void test_visitConditionalExpression_differentTypes() {
10498 // true ? 1.0 : 0
10499 Expression node = AstFactory.conditionalExpression(
10500 AstFactory.booleanLiteral(true),
10501 _resolvedDouble(1.0),
10502 _resolvedInteger(0));
10503 expect(_analyze(node), same(_typeProvider.numType));
10504 _listener.assertNoErrors();
10505 }
10506
10507 void test_visitConditionalExpression_sameTypes() {
10508 // true ? 1 : 0
10509 Expression node = AstFactory.conditionalExpression(
10510 AstFactory.booleanLiteral(true),
10511 _resolvedInteger(1),
10512 _resolvedInteger(0));
10513 expect(_analyze(node), same(_typeProvider.intType));
10514 _listener.assertNoErrors();
10515 }
10516
10517 void test_visitDoubleLiteral() {
10518 // 4.33
10519 Expression node = AstFactory.doubleLiteral(4.33);
10520 expect(_analyze(node), same(_typeProvider.doubleType));
10521 _listener.assertNoErrors();
10522 }
10523
10524 void test_visitFunctionExpression_async_block() {
10525 // () async {}
10526 BlockFunctionBody body = AstFactory.blockFunctionBody2();
10527 body.keyword = TokenFactory.tokenFromString('async');
10528 FunctionExpression node =
10529 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
10530 DartType resultType = _analyze(node);
10531 _assertFunctionType(
10532 _typeProvider.futureDynamicType, null, null, null, resultType);
10533 _listener.assertNoErrors();
10534 }
10535
10536 void test_visitFunctionExpression_async_expression() {
10537 // () async => e, where e has type int
10538 InterfaceType intType = _typeProvider.intType;
10539 InterfaceType futureIntType =
10540 _typeProvider.futureType.substitute4(<DartType>[intType]);
10541 Expression expression = _resolvedVariable(intType, 'e');
10542 ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
10543 body.keyword = TokenFactory.tokenFromString('async');
10544 FunctionExpression node =
10545 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
10546 DartType resultType = _analyze(node);
10547 _assertFunctionType(futureIntType, null, null, null, resultType);
10548 _listener.assertNoErrors();
10549 }
10550
10551 void test_visitFunctionExpression_async_expression_flatten() {
10552 // () async => e, where e has type Future<int>
10553 InterfaceType intType = _typeProvider.intType;
10554 InterfaceType futureIntType =
10555 _typeProvider.futureType.substitute4(<DartType>[intType]);
10556 Expression expression = _resolvedVariable(futureIntType, 'e');
10557 ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
10558 body.keyword = TokenFactory.tokenFromString('async');
10559 FunctionExpression node =
10560 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
10561 DartType resultType = _analyze(node);
10562 _assertFunctionType(futureIntType, null, null, null, resultType);
10563 _listener.assertNoErrors();
10564 }
10565
10566 void test_visitFunctionExpression_async_expression_flatten_twice() {
10567 // () async => e, where e has type Future<Future<int>>
10568 InterfaceType intType = _typeProvider.intType;
10569 InterfaceType futureIntType =
10570 _typeProvider.futureType.substitute4(<DartType>[intType]);
10571 InterfaceType futureFutureIntType =
10572 _typeProvider.futureType.substitute4(<DartType>[futureIntType]);
10573 Expression expression = _resolvedVariable(futureFutureIntType, 'e');
10574 ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
10575 body.keyword = TokenFactory.tokenFromString('async');
10576 FunctionExpression node =
10577 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
10578 DartType resultType = _analyze(node);
10579 _assertFunctionType(futureIntType, null, null, null, resultType);
10580 _listener.assertNoErrors();
10581 }
10582
10583 void test_visitFunctionExpression_generator_async() {
10584 // () async* {}
10585 BlockFunctionBody body = AstFactory.blockFunctionBody2();
10586 body.keyword = TokenFactory.tokenFromString('async');
10587 body.star = TokenFactory.tokenFromType(TokenType.STAR);
10588 FunctionExpression node =
10589 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
10590 DartType resultType = _analyze(node);
10591 _assertFunctionType(
10592 _typeProvider.streamDynamicType, null, null, null, resultType);
10593 _listener.assertNoErrors();
10594 }
10595
10596 void test_visitFunctionExpression_generator_sync() {
10597 // () sync* {}
10598 BlockFunctionBody body = AstFactory.blockFunctionBody2();
10599 body.keyword = TokenFactory.tokenFromString('sync');
10600 body.star = TokenFactory.tokenFromType(TokenType.STAR);
10601 FunctionExpression node =
10602 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
10603 DartType resultType = _analyze(node);
10604 _assertFunctionType(
10605 _typeProvider.iterableDynamicType, null, null, null, resultType);
10606 _listener.assertNoErrors();
10607 }
10608
10609 void test_visitFunctionExpression_named_block() {
10610 // ({p1 : 0, p2 : 0}) {}
10611 DartType dynamicType = _typeProvider.dynamicType;
10612 FormalParameter p1 = AstFactory.namedFormalParameter(
10613 AstFactory.simpleFormalParameter3("p1"), _resolvedInteger(0));
10614 _setType(p1, dynamicType);
10615 FormalParameter p2 = AstFactory.namedFormalParameter(
10616 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
10617 _setType(p2, dynamicType);
10618 FunctionExpression node = _resolvedFunctionExpression(
10619 AstFactory.formalParameterList([p1, p2]),
10620 AstFactory.blockFunctionBody2());
10621 _analyze5(p1);
10622 _analyze5(p2);
10623 DartType resultType = _analyze(node);
10624 Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
10625 expectedNamedTypes["p1"] = dynamicType;
10626 expectedNamedTypes["p2"] = dynamicType;
10627 _assertFunctionType(
10628 dynamicType, null, null, expectedNamedTypes, resultType);
10629 _listener.assertNoErrors();
10630 }
10631
10632 void test_visitFunctionExpression_named_expression() {
10633 // ({p : 0}) -> 0;
10634 DartType dynamicType = _typeProvider.dynamicType;
10635 FormalParameter p = AstFactory.namedFormalParameter(
10636 AstFactory.simpleFormalParameter3("p"), _resolvedInteger(0));
10637 _setType(p, dynamicType);
10638 FunctionExpression node = _resolvedFunctionExpression(
10639 AstFactory.formalParameterList([p]),
10640 AstFactory.expressionFunctionBody(_resolvedInteger(0)));
10641 _analyze5(p);
10642 DartType resultType = _analyze(node);
10643 Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
10644 expectedNamedTypes["p"] = dynamicType;
10645 _assertFunctionType(
10646 _typeProvider.intType, null, null, expectedNamedTypes, resultType);
10647 _listener.assertNoErrors();
10648 }
10649
10650 void test_visitFunctionExpression_normal_block() {
10651 // (p1, p2) {}
10652 DartType dynamicType = _typeProvider.dynamicType;
10653 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
10654 _setType(p1, dynamicType);
10655 FormalParameter p2 = AstFactory.simpleFormalParameter3("p2");
10656 _setType(p2, dynamicType);
10657 FunctionExpression node = _resolvedFunctionExpression(
10658 AstFactory.formalParameterList([p1, p2]),
10659 AstFactory.blockFunctionBody2());
10660 _analyze5(p1);
10661 _analyze5(p2);
10662 DartType resultType = _analyze(node);
10663 _assertFunctionType(dynamicType, <DartType>[dynamicType, dynamicType], null,
10664 null, resultType);
10665 _listener.assertNoErrors();
10666 }
10667
10668 void test_visitFunctionExpression_normal_expression() {
10669 // (p1, p2) -> 0
10670 DartType dynamicType = _typeProvider.dynamicType;
10671 FormalParameter p = AstFactory.simpleFormalParameter3("p");
10672 _setType(p, dynamicType);
10673 FunctionExpression node = _resolvedFunctionExpression(
10674 AstFactory.formalParameterList([p]),
10675 AstFactory.expressionFunctionBody(_resolvedInteger(0)));
10676 _analyze5(p);
10677 DartType resultType = _analyze(node);
10678 _assertFunctionType(
10679 _typeProvider.intType, <DartType>[dynamicType], null, null, resultType);
10680 _listener.assertNoErrors();
10681 }
10682
10683 void test_visitFunctionExpression_normalAndNamed_block() {
10684 // (p1, {p2 : 0}) {}
10685 DartType dynamicType = _typeProvider.dynamicType;
10686 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
10687 _setType(p1, dynamicType);
10688 FormalParameter p2 = AstFactory.namedFormalParameter(
10689 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
10690 _setType(p2, dynamicType);
10691 FunctionExpression node = _resolvedFunctionExpression(
10692 AstFactory.formalParameterList([p1, p2]),
10693 AstFactory.blockFunctionBody2());
10694 _analyze5(p2);
10695 DartType resultType = _analyze(node);
10696 Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
10697 expectedNamedTypes["p2"] = dynamicType;
10698 _assertFunctionType(dynamicType, <DartType>[dynamicType], null,
10699 expectedNamedTypes, resultType);
10700 _listener.assertNoErrors();
10701 }
10702
10703 void test_visitFunctionExpression_normalAndNamed_expression() {
10704 // (p1, {p2 : 0}) -> 0
10705 DartType dynamicType = _typeProvider.dynamicType;
10706 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
10707 _setType(p1, dynamicType);
10708 FormalParameter p2 = AstFactory.namedFormalParameter(
10709 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
10710 _setType(p2, dynamicType);
10711 FunctionExpression node = _resolvedFunctionExpression(
10712 AstFactory.formalParameterList([p1, p2]),
10713 AstFactory.expressionFunctionBody(_resolvedInteger(0)));
10714 _analyze5(p2);
10715 DartType resultType = _analyze(node);
10716 Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
10717 expectedNamedTypes["p2"] = dynamicType;
10718 _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType], null,
10719 expectedNamedTypes, resultType);
10720 _listener.assertNoErrors();
10721 }
10722
10723 void test_visitFunctionExpression_normalAndPositional_block() {
10724 // (p1, [p2 = 0]) {}
10725 DartType dynamicType = _typeProvider.dynamicType;
10726 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
10727 _setType(p1, dynamicType);
10728 FormalParameter p2 = AstFactory.positionalFormalParameter(
10729 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
10730 _setType(p2, dynamicType);
10731 FunctionExpression node = _resolvedFunctionExpression(
10732 AstFactory.formalParameterList([p1, p2]),
10733 AstFactory.blockFunctionBody2());
10734 _analyze5(p1);
10735 _analyze5(p2);
10736 DartType resultType = _analyze(node);
10737 _assertFunctionType(dynamicType, <DartType>[dynamicType],
10738 <DartType>[dynamicType], null, resultType);
10739 _listener.assertNoErrors();
10740 }
10741
10742 void test_visitFunctionExpression_normalAndPositional_expression() {
10743 // (p1, [p2 = 0]) -> 0
10744 DartType dynamicType = _typeProvider.dynamicType;
10745 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
10746 _setType(p1, dynamicType);
10747 FormalParameter p2 = AstFactory.positionalFormalParameter(
10748 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
10749 _setType(p2, dynamicType);
10750 FunctionExpression node = _resolvedFunctionExpression(
10751 AstFactory.formalParameterList([p1, p2]),
10752 AstFactory.expressionFunctionBody(_resolvedInteger(0)));
10753 _analyze5(p1);
10754 _analyze5(p2);
10755 DartType resultType = _analyze(node);
10756 _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType],
10757 <DartType>[dynamicType], null, resultType);
10758 _listener.assertNoErrors();
10759 }
10760
10761 void test_visitFunctionExpression_positional_block() {
10762 // ([p1 = 0, p2 = 0]) {}
10763 DartType dynamicType = _typeProvider.dynamicType;
10764 FormalParameter p1 = AstFactory.positionalFormalParameter(
10765 AstFactory.simpleFormalParameter3("p1"), _resolvedInteger(0));
10766 _setType(p1, dynamicType);
10767 FormalParameter p2 = AstFactory.positionalFormalParameter(
10768 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
10769 _setType(p2, dynamicType);
10770 FunctionExpression node = _resolvedFunctionExpression(
10771 AstFactory.formalParameterList([p1, p2]),
10772 AstFactory.blockFunctionBody2());
10773 _analyze5(p1);
10774 _analyze5(p2);
10775 DartType resultType = _analyze(node);
10776 _assertFunctionType(dynamicType, null, <DartType>[dynamicType, dynamicType],
10777 null, resultType);
10778 _listener.assertNoErrors();
10779 }
10780
10781 void test_visitFunctionExpression_positional_expression() {
10782 // ([p1 = 0, p2 = 0]) -> 0
10783 DartType dynamicType = _typeProvider.dynamicType;
10784 FormalParameter p = AstFactory.positionalFormalParameter(
10785 AstFactory.simpleFormalParameter3("p"), _resolvedInteger(0));
10786 _setType(p, dynamicType);
10787 FunctionExpression node = _resolvedFunctionExpression(
10788 AstFactory.formalParameterList([p]),
10789 AstFactory.expressionFunctionBody(_resolvedInteger(0)));
10790 _analyze5(p);
10791 DartType resultType = _analyze(node);
10792 _assertFunctionType(
10793 _typeProvider.intType, null, <DartType>[dynamicType], null, resultType);
10794 _listener.assertNoErrors();
10795 }
10796
10797 void test_visitIndexExpression_getter() {
10798 // List a;
10799 // a[2]
10800 InterfaceType listType = _typeProvider.listType;
10801 SimpleIdentifier identifier = _resolvedVariable(listType, "a");
10802 IndexExpression node =
10803 AstFactory.indexExpression(identifier, _resolvedInteger(2));
10804 MethodElement indexMethod = listType.element.methods[0];
10805 node.staticElement = indexMethod;
10806 expect(_analyze(node), same(listType.typeArguments[0]));
10807 _listener.assertNoErrors();
10808 }
10809
10810 void test_visitIndexExpression_setter() {
10811 // List a;
10812 // a[2] = 0
10813 InterfaceType listType = _typeProvider.listType;
10814 SimpleIdentifier identifier = _resolvedVariable(listType, "a");
10815 IndexExpression node =
10816 AstFactory.indexExpression(identifier, _resolvedInteger(2));
10817 MethodElement indexMethod = listType.element.methods[1];
10818 node.staticElement = indexMethod;
10819 AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0));
10820 expect(_analyze(node), same(listType.typeArguments[0]));
10821 _listener.assertNoErrors();
10822 }
10823
10824 void test_visitIndexExpression_typeParameters() {
10825 // List<int> list = ...
10826 // list[0]
10827 InterfaceType intType = _typeProvider.intType;
10828 InterfaceType listType = _typeProvider.listType;
10829 // (int) -> E
10830 MethodElement methodElement = getMethod(listType, "[]");
10831 // "list" has type List<int>
10832 SimpleIdentifier identifier = AstFactory.identifier3("list");
10833 InterfaceType listOfIntType = listType.substitute4(<DartType>[intType]);
10834 identifier.staticType = listOfIntType;
10835 // list[0] has MethodElement element (int) -> E
10836 IndexExpression indexExpression =
10837 AstFactory.indexExpression(identifier, AstFactory.integer(0));
10838 MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType);
10839 indexExpression.staticElement = indexMethod;
10840 // analyze and assert result of the index expression
10841 expect(_analyze(indexExpression), same(intType));
10842 _listener.assertNoErrors();
10843 }
10844
10845 void test_visitIndexExpression_typeParameters_inSetterContext() {
10846 // List<int> list = ...
10847 // list[0] = 0;
10848 InterfaceType intType = _typeProvider.intType;
10849 InterfaceType listType = _typeProvider.listType;
10850 // (int, E) -> void
10851 MethodElement methodElement = getMethod(listType, "[]=");
10852 // "list" has type List<int>
10853 SimpleIdentifier identifier = AstFactory.identifier3("list");
10854 InterfaceType listOfIntType = listType.substitute4(<DartType>[intType]);
10855 identifier.staticType = listOfIntType;
10856 // list[0] has MethodElement element (int) -> E
10857 IndexExpression indexExpression =
10858 AstFactory.indexExpression(identifier, AstFactory.integer(0));
10859 MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType);
10860 indexExpression.staticElement = indexMethod;
10861 // list[0] should be in a setter context
10862 AstFactory.assignmentExpression(
10863 indexExpression, TokenType.EQ, AstFactory.integer(0));
10864 // analyze and assert result of the index expression
10865 expect(_analyze(indexExpression), same(intType));
10866 _listener.assertNoErrors();
10867 }
10868
10869 void test_visitInstanceCreationExpression_named() {
10870 // new C.m()
10871 ClassElementImpl classElement = ElementFactory.classElement2("C");
10872 String constructorName = "m";
10873 ConstructorElementImpl constructor =
10874 ElementFactory.constructorElement2(classElement, constructorName);
10875 constructor.returnType = classElement.type;
10876 FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
10877 constructor.type = constructorType;
10878 classElement.constructors = <ConstructorElement>[constructor];
10879 InstanceCreationExpression node = AstFactory.instanceCreationExpression2(
10880 null,
10881 AstFactory.typeName(classElement),
10882 [AstFactory.identifier3(constructorName)]);
10883 node.staticElement = constructor;
10884 expect(_analyze(node), same(classElement.type));
10885 _listener.assertNoErrors();
10886 }
10887
10888 void test_visitInstanceCreationExpression_typeParameters() {
10889 // new C<I>()
10890 ClassElementImpl elementC = ElementFactory.classElement2("C", ["E"]);
10891 ClassElementImpl elementI = ElementFactory.classElement2("I");
10892 ConstructorElementImpl constructor =
10893 ElementFactory.constructorElement2(elementC, null);
10894 elementC.constructors = <ConstructorElement>[constructor];
10895 constructor.returnType = elementC.type;
10896 FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
10897 constructor.type = constructorType;
10898 TypeName typeName =
10899 AstFactory.typeName(elementC, [AstFactory.typeName(elementI)]);
10900 typeName.type = elementC.type.substitute4(<DartType>[elementI.type]);
10901 InstanceCreationExpression node =
10902 AstFactory.instanceCreationExpression2(null, typeName);
10903 node.staticElement = constructor;
10904 InterfaceType interfaceType = _analyze(node) as InterfaceType;
10905 List<DartType> typeArgs = interfaceType.typeArguments;
10906 expect(typeArgs.length, 1);
10907 expect(typeArgs[0], elementI.type);
10908 _listener.assertNoErrors();
10909 }
10910
10911 void test_visitInstanceCreationExpression_unnamed() {
10912 // new C()
10913 ClassElementImpl classElement = ElementFactory.classElement2("C");
10914 ConstructorElementImpl constructor =
10915 ElementFactory.constructorElement2(classElement, null);
10916 constructor.returnType = classElement.type;
10917 FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
10918 constructor.type = constructorType;
10919 classElement.constructors = <ConstructorElement>[constructor];
10920 InstanceCreationExpression node = AstFactory.instanceCreationExpression2(
10921 null, AstFactory.typeName(classElement));
10922 node.staticElement = constructor;
10923 expect(_analyze(node), same(classElement.type));
10924 _listener.assertNoErrors();
10925 }
10926
10927 void test_visitIntegerLiteral() {
10928 // 42
10929 Expression node = _resolvedInteger(42);
10930 expect(_analyze(node), same(_typeProvider.intType));
10931 _listener.assertNoErrors();
10932 }
10933
10934 void test_visitIsExpression_negated() {
10935 // a is! String
10936 Expression node = AstFactory.isExpression(
10937 _resolvedString("a"), true, AstFactory.typeName4("String"));
10938 expect(_analyze(node), same(_typeProvider.boolType));
10939 _listener.assertNoErrors();
10940 }
10941
10942 void test_visitIsExpression_notNegated() {
10943 // a is String
10944 Expression node = AstFactory.isExpression(
10945 _resolvedString("a"), false, AstFactory.typeName4("String"));
10946 expect(_analyze(node), same(_typeProvider.boolType));
10947 _listener.assertNoErrors();
10948 }
10949
10950 void test_visitListLiteral_empty() {
10951 // []
10952 Expression node = AstFactory.listLiteral();
10953 DartType resultType = _analyze(node);
10954 _assertType2(
10955 _typeProvider.listType
10956 .substitute4(<DartType>[_typeProvider.dynamicType]),
10957 resultType);
10958 _listener.assertNoErrors();
10959 }
10960
10961 void test_visitListLiteral_nonEmpty() {
10962 // [0]
10963 Expression node = AstFactory.listLiteral([_resolvedInteger(0)]);
10964 DartType resultType = _analyze(node);
10965 _assertType2(
10966 _typeProvider.listType
10967 .substitute4(<DartType>[_typeProvider.dynamicType]),
10968 resultType);
10969 _listener.assertNoErrors();
10970 }
10971
10972 void test_visitMapLiteral_empty() {
10973 // {}
10974 Expression node = AstFactory.mapLiteral2();
10975 DartType resultType = _analyze(node);
10976 _assertType2(
10977 _typeProvider.mapType.substitute4(
10978 <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]),
10979 resultType);
10980 _listener.assertNoErrors();
10981 }
10982
10983 void test_visitMapLiteral_nonEmpty() {
10984 // {"k" : 0}
10985 Expression node = AstFactory
10986 .mapLiteral2([AstFactory.mapLiteralEntry("k", _resolvedInteger(0))]);
10987 DartType resultType = _analyze(node);
10988 _assertType2(
10989 _typeProvider.mapType.substitute4(
10990 <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]),
10991 resultType);
10992 _listener.assertNoErrors();
10993 }
10994
10995 void test_visitMethodInvocation_then() {
10996 // then()
10997 Expression node = AstFactory.methodInvocation(null, "then");
10998 _analyze(node);
10999 _listener.assertNoErrors();
11000 }
11001
11002 void test_visitNamedExpression() {
11003 // n: a
11004 Expression node = AstFactory.namedExpression2("n", _resolvedString("a"));
11005 expect(_analyze(node), same(_typeProvider.stringType));
11006 _listener.assertNoErrors();
11007 }
11008
11009 void test_visitNullLiteral() {
11010 // null
11011 Expression node = AstFactory.nullLiteral();
11012 expect(_analyze(node), same(_typeProvider.bottomType));
11013 _listener.assertNoErrors();
11014 }
11015
11016 void test_visitParenthesizedExpression() {
11017 // (0)
11018 Expression node = AstFactory.parenthesizedExpression(_resolvedInteger(0));
11019 expect(_analyze(node), same(_typeProvider.intType));
11020 _listener.assertNoErrors();
11021 }
11022
11023 void test_visitPostfixExpression_minusMinus() {
11024 // 0--
11025 PostfixExpression node = AstFactory.postfixExpression(
11026 _resolvedInteger(0), TokenType.MINUS_MINUS);
11027 expect(_analyze(node), same(_typeProvider.intType));
11028 _listener.assertNoErrors();
11029 }
11030
11031 void test_visitPostfixExpression_plusPlus() {
11032 // 0++
11033 PostfixExpression node =
11034 AstFactory.postfixExpression(_resolvedInteger(0), TokenType.PLUS_PLUS);
11035 expect(_analyze(node), same(_typeProvider.intType));
11036 _listener.assertNoErrors();
11037 }
11038
11039 void test_visitPrefixedIdentifier_getter() {
11040 DartType boolType = _typeProvider.boolType;
11041 PropertyAccessorElementImpl getter =
11042 ElementFactory.getterElement("b", false, boolType);
11043 PrefixedIdentifier node = AstFactory.identifier5("a", "b");
11044 node.identifier.staticElement = getter;
11045 expect(_analyze(node), same(boolType));
11046 _listener.assertNoErrors();
11047 }
11048
11049 void test_visitPrefixedIdentifier_setter() {
11050 DartType boolType = _typeProvider.boolType;
11051 FieldElementImpl field =
11052 ElementFactory.fieldElement("b", false, false, false, boolType);
11053 PropertyAccessorElement setter = field.setter;
11054 PrefixedIdentifier node = AstFactory.identifier5("a", "b");
11055 node.identifier.staticElement = setter;
11056 expect(_analyze(node), same(boolType));
11057 _listener.assertNoErrors();
11058 }
11059
11060 void test_visitPrefixedIdentifier_variable() {
11061 VariableElementImpl variable = ElementFactory.localVariableElement2("b");
11062 variable.type = _typeProvider.boolType;
11063 PrefixedIdentifier node = AstFactory.identifier5("a", "b");
11064 node.identifier.staticElement = variable;
11065 expect(_analyze(node), same(_typeProvider.boolType));
11066 _listener.assertNoErrors();
11067 }
11068
11069 void test_visitPrefixExpression_bang() {
11070 // !0
11071 PrefixExpression node =
11072 AstFactory.prefixExpression(TokenType.BANG, _resolvedInteger(0));
11073 expect(_analyze(node), same(_typeProvider.boolType));
11074 _listener.assertNoErrors();
11075 }
11076
11077 void test_visitPrefixExpression_minus() {
11078 // -0
11079 PrefixExpression node =
11080 AstFactory.prefixExpression(TokenType.MINUS, _resolvedInteger(0));
11081 MethodElement minusMethod = getMethod(_typeProvider.numType, "-");
11082 node.staticElement = minusMethod;
11083 expect(_analyze(node), same(_typeProvider.numType));
11084 _listener.assertNoErrors();
11085 }
11086
11087 void test_visitPrefixExpression_minusMinus() {
11088 // --0
11089 PrefixExpression node =
11090 AstFactory.prefixExpression(TokenType.MINUS_MINUS, _resolvedInteger(0));
11091 MethodElement minusMethod = getMethod(_typeProvider.numType, "-");
11092 node.staticElement = minusMethod;
11093 expect(_analyze(node), same(_typeProvider.intType));
11094 _listener.assertNoErrors();
11095 }
11096
11097 void test_visitPrefixExpression_not() {
11098 // !true
11099 Expression node = AstFactory.prefixExpression(
11100 TokenType.BANG, AstFactory.booleanLiteral(true));
11101 expect(_analyze(node), same(_typeProvider.boolType));
11102 _listener.assertNoErrors();
11103 }
11104
11105 void test_visitPrefixExpression_plusPlus() {
11106 // ++0
11107 PrefixExpression node =
11108 AstFactory.prefixExpression(TokenType.PLUS_PLUS, _resolvedInteger(0));
11109 MethodElement plusMethod = getMethod(_typeProvider.numType, "+");
11110 node.staticElement = plusMethod;
11111 expect(_analyze(node), same(_typeProvider.intType));
11112 _listener.assertNoErrors();
11113 }
11114
11115 void test_visitPrefixExpression_tilde() {
11116 // ~0
11117 PrefixExpression node =
11118 AstFactory.prefixExpression(TokenType.TILDE, _resolvedInteger(0));
11119 MethodElement tildeMethod = getMethod(_typeProvider.intType, "~");
11120 node.staticElement = tildeMethod;
11121 expect(_analyze(node), same(_typeProvider.intType));
11122 _listener.assertNoErrors();
11123 }
11124
11125 void test_visitPropertyAccess_propagated_getter() {
11126 DartType boolType = _typeProvider.boolType;
11127 PropertyAccessorElementImpl getter =
11128 ElementFactory.getterElement("b", false, boolType);
11129 PropertyAccess node =
11130 AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
11131 node.propertyName.propagatedElement = getter;
11132 expect(_analyze2(node, false), same(boolType));
11133 _listener.assertNoErrors();
11134 }
11135
11136 void test_visitPropertyAccess_propagated_setter() {
11137 DartType boolType = _typeProvider.boolType;
11138 FieldElementImpl field =
11139 ElementFactory.fieldElement("b", false, false, false, boolType);
11140 PropertyAccessorElement setter = field.setter;
11141 PropertyAccess node =
11142 AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
11143 node.propertyName.propagatedElement = setter;
11144 expect(_analyze2(node, false), same(boolType));
11145 _listener.assertNoErrors();
11146 }
11147
11148 void test_visitPropertyAccess_static_getter() {
11149 DartType boolType = _typeProvider.boolType;
11150 PropertyAccessorElementImpl getter =
11151 ElementFactory.getterElement("b", false, boolType);
11152 PropertyAccess node =
11153 AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
11154 node.propertyName.staticElement = getter;
11155 expect(_analyze(node), same(boolType));
11156 _listener.assertNoErrors();
11157 }
11158
11159 void test_visitPropertyAccess_static_setter() {
11160 DartType boolType = _typeProvider.boolType;
11161 FieldElementImpl field =
11162 ElementFactory.fieldElement("b", false, false, false, boolType);
11163 PropertyAccessorElement setter = field.setter;
11164 PropertyAccess node =
11165 AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
11166 node.propertyName.staticElement = setter;
11167 expect(_analyze(node), same(boolType));
11168 _listener.assertNoErrors();
11169 }
11170
11171 void test_visitSimpleIdentifier_dynamic() {
11172 // "dynamic"
11173 SimpleIdentifier identifier = AstFactory.identifier3('dynamic');
11174 DynamicElementImpl element = DynamicElementImpl.instance;
11175 identifier.staticElement = element;
11176 identifier.staticType = _typeProvider.typeType;
11177 expect(_analyze(identifier), same(_typeProvider.typeType));
11178 _listener.assertNoErrors();
11179 }
11180
11181 void test_visitSimpleStringLiteral() {
11182 // "a"
11183 Expression node = _resolvedString("a");
11184 expect(_analyze(node), same(_typeProvider.stringType));
11185 _listener.assertNoErrors();
11186 }
11187
11188 void test_visitStringInterpolation() {
11189 // "a${'b'}c"
11190 Expression node = AstFactory.string([
11191 AstFactory.interpolationString("a", "a"),
11192 AstFactory.interpolationExpression(_resolvedString("b")),
11193 AstFactory.interpolationString("c", "c")
11194 ]);
11195 expect(_analyze(node), same(_typeProvider.stringType));
11196 _listener.assertNoErrors();
11197 }
11198
11199 void test_visitSuperExpression() {
11200 // super
11201 InterfaceType superType = ElementFactory.classElement2("A").type;
11202 InterfaceType thisType = ElementFactory.classElement("B", superType).type;
11203 Expression node = AstFactory.superExpression();
11204 expect(_analyze3(node, thisType), same(thisType));
11205 _listener.assertNoErrors();
11206 }
11207
11208 void test_visitSymbolLiteral() {
11209 expect(_analyze(AstFactory.symbolLiteral(["a"])),
11210 same(_typeProvider.symbolType));
11211 }
11212
11213 void test_visitThisExpression() {
11214 // this
11215 InterfaceType thisType = ElementFactory
11216 .classElement("B", ElementFactory.classElement2("A").type)
11217 .type;
11218 Expression node = AstFactory.thisExpression();
11219 expect(_analyze3(node, thisType), same(thisType));
11220 _listener.assertNoErrors();
11221 }
11222
11223 void test_visitThrowExpression_withoutValue() {
11224 // throw
11225 Expression node = AstFactory.throwExpression();
11226 expect(_analyze(node), same(_typeProvider.bottomType));
11227 _listener.assertNoErrors();
11228 }
11229
11230 void test_visitThrowExpression_withValue() {
11231 // throw 0
11232 Expression node = AstFactory.throwExpression2(_resolvedInteger(0));
11233 expect(_analyze(node), same(_typeProvider.bottomType));
11234 _listener.assertNoErrors();
11235 }
11236
11237 /**
11238 * Return the type associated with the given expression after the static type analyzer has
11239 * computed a type for it.
11240 *
11241 * @param node the expression with which the type is associated
11242 * @return the type associated with the expression
11243 */
11244 DartType _analyze(Expression node) => _analyze4(node, null, true);
11245
11246 /**
11247 * Return the type associated with the given expression after the static or pr opagated type
11248 * analyzer has computed a type for it.
11249 *
11250 * @param node the expression with which the type is associated
11251 * @param useStaticType `true` if the static type is being requested, and `fal se` if
11252 * the propagated type is being requested
11253 * @return the type associated with the expression
11254 */
11255 DartType _analyze2(Expression node, bool useStaticType) =>
11256 _analyze4(node, null, useStaticType);
11257
11258 /**
11259 * Return the type associated with the given expression after the static type analyzer has
11260 * computed a type for it.
11261 *
11262 * @param node the expression with which the type is associated
11263 * @param thisType the type of 'this'
11264 * @return the type associated with the expression
11265 */
11266 DartType _analyze3(Expression node, InterfaceType thisType) =>
11267 _analyze4(node, thisType, true);
11268
11269 /**
11270 * Return the type associated with the given expression after the static type analyzer has
11271 * computed a type for it.
11272 *
11273 * @param node the expression with which the type is associated
11274 * @param thisType the type of 'this'
11275 * @param useStaticType `true` if the static type is being requested, and `fal se` if
11276 * the propagated type is being requested
11277 * @return the type associated with the expression
11278 */
11279 DartType _analyze4(
11280 Expression node, InterfaceType thisType, bool useStaticType) {
11281 try {
11282 _analyzer.thisType = thisType;
11283 } catch (exception) {
11284 throw new IllegalArgumentException(
11285 "Could not set type of 'this'", exception);
11286 }
11287 node.accept(_analyzer);
11288 if (useStaticType) {
11289 return node.staticType;
11290 } else {
11291 return node.propagatedType;
11292 }
11293 }
11294
11295 /**
11296 * Return the type associated with the given parameter after the static type a nalyzer has computed
11297 * a type for it.
11298 *
11299 * @param node the parameter with which the type is associated
11300 * @return the type associated with the parameter
11301 */
11302 DartType _analyze5(FormalParameter node) {
11303 node.accept(_analyzer);
11304 return (node.identifier.staticElement as ParameterElement).type;
11305 }
11306
11307 /**
11308 * Assert that the actual type is a function type with the expected characteri stics.
11309 *
11310 * @param expectedReturnType the expected return type of the function
11311 * @param expectedNormalTypes the expected types of the normal parameters
11312 * @param expectedOptionalTypes the expected types of the optional parameters
11313 * @param expectedNamedTypes the expected types of the named parameters
11314 * @param actualType the type being tested
11315 */
11316 void _assertFunctionType(
11317 DartType expectedReturnType,
11318 List<DartType> expectedNormalTypes,
11319 List<DartType> expectedOptionalTypes,
11320 Map<String, DartType> expectedNamedTypes,
11321 DartType actualType) {
11322 EngineTestCase.assertInstanceOf(
11323 (obj) => obj is FunctionType, FunctionType, actualType);
11324 FunctionType functionType = actualType as FunctionType;
11325 List<DartType> normalTypes = functionType.normalParameterTypes;
11326 if (expectedNormalTypes == null) {
11327 expect(normalTypes, hasLength(0));
11328 } else {
11329 int expectedCount = expectedNormalTypes.length;
11330 expect(normalTypes, hasLength(expectedCount));
11331 for (int i = 0; i < expectedCount; i++) {
11332 expect(normalTypes[i], same(expectedNormalTypes[i]));
11333 }
11334 }
11335 List<DartType> optionalTypes = functionType.optionalParameterTypes;
11336 if (expectedOptionalTypes == null) {
11337 expect(optionalTypes, hasLength(0));
11338 } else {
11339 int expectedCount = expectedOptionalTypes.length;
11340 expect(optionalTypes, hasLength(expectedCount));
11341 for (int i = 0; i < expectedCount; i++) {
11342 expect(optionalTypes[i], same(expectedOptionalTypes[i]));
11343 }
11344 }
11345 Map<String, DartType> namedTypes = functionType.namedParameterTypes;
11346 if (expectedNamedTypes == null) {
11347 expect(namedTypes, hasLength(0));
11348 } else {
11349 expect(namedTypes, hasLength(expectedNamedTypes.length));
11350 expectedNamedTypes.forEach((String name, DartType type) {
11351 expect(namedTypes[name], same(type));
11352 });
11353 }
11354 expect(functionType.returnType, equals(expectedReturnType));
11355 }
11356
11357 void _assertType(
11358 InterfaceTypeImpl expectedType, InterfaceTypeImpl actualType) {
11359 expect(actualType.displayName, expectedType.displayName);
11360 expect(actualType.element, expectedType.element);
11361 List<DartType> expectedArguments = expectedType.typeArguments;
11362 int length = expectedArguments.length;
11363 List<DartType> actualArguments = actualType.typeArguments;
11364 expect(actualArguments, hasLength(length));
11365 for (int i = 0; i < length; i++) {
11366 _assertType2(expectedArguments[i], actualArguments[i]);
11367 }
11368 }
11369
11370 void _assertType2(DartType expectedType, DartType actualType) {
11371 if (expectedType is InterfaceTypeImpl) {
11372 EngineTestCase.assertInstanceOf(
11373 (obj) => obj is InterfaceTypeImpl, InterfaceTypeImpl, actualType);
11374 _assertType(expectedType, actualType as InterfaceTypeImpl);
11375 }
11376 // TODO(brianwilkerson) Compare other kinds of types then make this a shared
11377 // utility method.
11378 }
11379
11380 /**
11381 * Create the analyzer used by the tests.
11382 *
11383 * @return the analyzer to be used by the tests
11384 */
11385 StaticTypeAnalyzer _createAnalyzer() {
11386 InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
11387 FileBasedSource source =
11388 new FileBasedSource(FileUtilities2.createFile("/lib.dart"));
11389 CompilationUnitElementImpl definingCompilationUnit =
11390 new CompilationUnitElementImpl("lib.dart");
11391 definingCompilationUnit.librarySource =
11392 definingCompilationUnit.source = source;
11393 LibraryElementImpl definingLibrary =
11394 new LibraryElementImpl.forNode(context, null);
11395 definingLibrary.definingCompilationUnit = definingCompilationUnit;
11396 Library library = new Library(context, _listener, source);
11397 library.libraryElement = definingLibrary;
11398 _visitor = new ResolverVisitor(
11399 library.libraryElement, source, _typeProvider, library.errorListener,
11400 nameScope: library.libraryScope,
11401 inheritanceManager: library.inheritanceManager);
11402 _visitor.overrideManager.enterScope();
11403 try {
11404 return _visitor.typeAnalyzer;
11405 } catch (exception) {
11406 throw new IllegalArgumentException(
11407 "Could not create analyzer", exception);
11408 }
11409 }
11410
11411 DartType _flatten(DartType type) =>
11412 StaticTypeAnalyzer.flattenFutures(_typeProvider, type);
11413
11414 /**
11415 * Return a simple identifier that has been resolved to a variable element wit h the given type.
11416 *
11417 * @param type the type of the variable being represented
11418 * @param variableName the name of the variable
11419 * @return a simple identifier that has been resolved to a variable element wi th the given type
11420 */
11421 SimpleIdentifier _propagatedVariable(
11422 InterfaceType type, String variableName) {
11423 SimpleIdentifier identifier = AstFactory.identifier3(variableName);
11424 VariableElementImpl element =
11425 ElementFactory.localVariableElement(identifier);
11426 element.type = type;
11427 identifier.staticType = _typeProvider.dynamicType;
11428 identifier.propagatedElement = element;
11429 identifier.propagatedType = type;
11430 return identifier;
11431 }
11432
11433 /**
11434 * Return an integer literal that has been resolved to the correct type.
11435 *
11436 * @param value the value of the literal
11437 * @return an integer literal that has been resolved to the correct type
11438 */
11439 DoubleLiteral _resolvedDouble(double value) {
11440 DoubleLiteral literal = AstFactory.doubleLiteral(value);
11441 literal.staticType = _typeProvider.doubleType;
11442 return literal;
11443 }
11444
11445 /**
11446 * Create a function expression that has an element associated with it, where the element has an
11447 * incomplete type associated with it (just like the one
11448 * [ElementBuilder.visitFunctionExpression] would have built if we had
11449 * run it).
11450 *
11451 * @param parameters the parameters to the function
11452 * @param body the body of the function
11453 * @return a resolved function expression
11454 */
11455 FunctionExpression _resolvedFunctionExpression(
11456 FormalParameterList parameters, FunctionBody body) {
11457 List<ParameterElement> parameterElements = new List<ParameterElement>();
11458 for (FormalParameter parameter in parameters.parameters) {
11459 ParameterElementImpl element =
11460 new ParameterElementImpl.forNode(parameter.identifier);
11461 element.parameterKind = parameter.kind;
11462 element.type = _typeProvider.dynamicType;
11463 parameter.identifier.staticElement = element;
11464 parameterElements.add(element);
11465 }
11466 FunctionExpression node = AstFactory.functionExpression2(parameters, body);
11467 FunctionElementImpl element = new FunctionElementImpl.forNode(null);
11468 element.parameters = parameterElements;
11469 element.type = new FunctionTypeImpl(element);
11470 node.element = element;
11471 return node;
11472 }
11473
11474 /**
11475 * Return an integer literal that has been resolved to the correct type.
11476 *
11477 * @param value the value of the literal
11478 * @return an integer literal that has been resolved to the correct type
11479 */
11480 IntegerLiteral _resolvedInteger(int value) {
11481 IntegerLiteral literal = AstFactory.integer(value);
11482 literal.staticType = _typeProvider.intType;
11483 return literal;
11484 }
11485
11486 /**
11487 * Return a string literal that has been resolved to the correct type.
11488 *
11489 * @param value the value of the literal
11490 * @return a string literal that has been resolved to the correct type
11491 */
11492 SimpleStringLiteral _resolvedString(String value) {
11493 SimpleStringLiteral string = AstFactory.string2(value);
11494 string.staticType = _typeProvider.stringType;
11495 return string;
11496 }
11497
11498 /**
11499 * Return a simple identifier that has been resolved to a variable element wit h the given type.
11500 *
11501 * @param type the type of the variable being represented
11502 * @param variableName the name of the variable
11503 * @return a simple identifier that has been resolved to a variable element wi th the given type
11504 */
11505 SimpleIdentifier _resolvedVariable(InterfaceType type, String variableName) {
11506 SimpleIdentifier identifier = AstFactory.identifier3(variableName);
11507 VariableElementImpl element =
11508 ElementFactory.localVariableElement(identifier);
11509 element.type = type;
11510 identifier.staticElement = element;
11511 identifier.staticType = type;
11512 return identifier;
11513 }
11514
11515 /**
11516 * Set the type of the given parameter to the given type.
11517 *
11518 * @param parameter the parameter whose type is to be set
11519 * @param type the new type of the given parameter
11520 */
11521 void _setType(FormalParameter parameter, DartType type) {
11522 SimpleIdentifier identifier = parameter.identifier;
11523 Element element = identifier.staticElement;
11524 if (element is! ParameterElement) {
11525 element = new ParameterElementImpl.forNode(identifier);
11526 identifier.staticElement = element;
11527 }
11528 (element as ParameterElementImpl).type = type;
11529 }
11530 }
11531
11532 /**
11533 * Instances of the class `StaticTypeVerifier` verify that all of the nodes in a n AST
11534 * structure that should have a static type associated with them do have a stati c type.
11535 */
11536 class StaticTypeVerifier extends GeneralizingAstVisitor<Object> {
11537 /**
11538 * A list containing all of the AST Expression nodes that were not resolved.
11539 */
11540 List<Expression> _unresolvedExpressions = new List<Expression>();
11541
11542 /**
11543 * A list containing all of the AST Expression nodes for which a propagated ty pe was computed but
11544 * where that type was not more specific than the static type.
11545 */
11546 List<Expression> _invalidlyPropagatedExpressions = new List<Expression>();
11547
11548 /**
11549 * A list containing all of the AST TypeName nodes that were not resolved.
11550 */
11551 List<TypeName> _unresolvedTypes = new List<TypeName>();
11552
11553 /**
11554 * Counter for the number of Expression nodes visited that are resolved.
11555 */
11556 int _resolvedExpressionCount = 0;
11557
11558 /**
11559 * Counter for the number of Expression nodes visited that have propagated typ e information.
11560 */
11561 int _propagatedExpressionCount = 0;
11562
11563 /**
11564 * Counter for the number of TypeName nodes visited that are resolved.
11565 */
11566 int _resolvedTypeCount = 0;
11567
11568 /**
11569 * Assert that all of the visited nodes have a static type associated with the m.
11570 */
11571 void assertResolved() {
11572 if (!_unresolvedExpressions.isEmpty || !_unresolvedTypes.isEmpty) {
11573 StringBuffer buffer = new StringBuffer();
11574 int unresolvedTypeCount = _unresolvedTypes.length;
11575 if (unresolvedTypeCount > 0) {
11576 buffer.write("Failed to resolve ");
11577 buffer.write(unresolvedTypeCount);
11578 buffer.write(" of ");
11579 buffer.write(_resolvedTypeCount + unresolvedTypeCount);
11580 buffer.writeln(" type names:");
11581 for (TypeName identifier in _unresolvedTypes) {
11582 buffer.write(" ");
11583 buffer.write(identifier.toString());
11584 buffer.write(" (");
11585 buffer.write(_getFileName(identifier));
11586 buffer.write(" : ");
11587 buffer.write(identifier.offset);
11588 buffer.writeln(")");
11589 }
11590 }
11591 int unresolvedExpressionCount = _unresolvedExpressions.length;
11592 if (unresolvedExpressionCount > 0) {
11593 buffer.writeln("Failed to resolve ");
11594 buffer.write(unresolvedExpressionCount);
11595 buffer.write(" of ");
11596 buffer.write(_resolvedExpressionCount + unresolvedExpressionCount);
11597 buffer.writeln(" expressions:");
11598 for (Expression expression in _unresolvedExpressions) {
11599 buffer.write(" ");
11600 buffer.write(expression.toString());
11601 buffer.write(" (");
11602 buffer.write(_getFileName(expression));
11603 buffer.write(" : ");
11604 buffer.write(expression.offset);
11605 buffer.writeln(")");
11606 }
11607 }
11608 int invalidlyPropagatedExpressionCount =
11609 _invalidlyPropagatedExpressions.length;
11610 if (invalidlyPropagatedExpressionCount > 0) {
11611 buffer.writeln("Incorrectly propagated ");
11612 buffer.write(invalidlyPropagatedExpressionCount);
11613 buffer.write(" of ");
11614 buffer.write(_propagatedExpressionCount);
11615 buffer.writeln(" expressions:");
11616 for (Expression expression in _invalidlyPropagatedExpressions) {
11617 buffer.write(" ");
11618 buffer.write(expression.toString());
11619 buffer.write(" [");
11620 buffer.write(expression.staticType.displayName);
11621 buffer.write(", ");
11622 buffer.write(expression.propagatedType.displayName);
11623 buffer.writeln("]");
11624 buffer.write(" ");
11625 buffer.write(_getFileName(expression));
11626 buffer.write(" : ");
11627 buffer.write(expression.offset);
11628 buffer.writeln(")");
11629 }
11630 }
11631 fail(buffer.toString());
11632 }
11633 }
11634
11635 @override
11636 Object visitBreakStatement(BreakStatement node) => null;
11637
11638 @override
11639 Object visitCommentReference(CommentReference node) => null;
11640
11641 @override
11642 Object visitContinueStatement(ContinueStatement node) => null;
11643
11644 @override
11645 Object visitExportDirective(ExportDirective node) => null;
11646
11647 @override
11648 Object visitExpression(Expression node) {
11649 node.visitChildren(this);
11650 DartType staticType = node.staticType;
11651 if (staticType == null) {
11652 _unresolvedExpressions.add(node);
11653 } else {
11654 _resolvedExpressionCount++;
11655 DartType propagatedType = node.propagatedType;
11656 if (propagatedType != null) {
11657 _propagatedExpressionCount++;
11658 if (!propagatedType.isMoreSpecificThan(staticType)) {
11659 _invalidlyPropagatedExpressions.add(node);
11660 }
11661 }
11662 }
11663 return null;
11664 }
11665
11666 @override
11667 Object visitImportDirective(ImportDirective node) => null;
11668
11669 @override
11670 Object visitLabel(Label node) => null;
11671
11672 @override
11673 Object visitLibraryIdentifier(LibraryIdentifier node) => null;
11674
11675 @override
11676 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
11677 // In cases where we have a prefixed identifier where the prefix is dynamic,
11678 // we don't want to assert that the node will have a type.
11679 if (node.staticType == null && node.prefix.staticType.isDynamic) {
11680 return null;
11681 }
11682 return super.visitPrefixedIdentifier(node);
11683 }
11684
11685 @override
11686 Object visitSimpleIdentifier(SimpleIdentifier node) {
11687 // In cases where identifiers are being used for something other than an
11688 // expressions, then they can be ignored.
11689 AstNode parent = node.parent;
11690 if (parent is MethodInvocation && identical(node, parent.methodName)) {
11691 return null;
11692 } else if (parent is RedirectingConstructorInvocation &&
11693 identical(node, parent.constructorName)) {
11694 return null;
11695 } else if (parent is SuperConstructorInvocation &&
11696 identical(node, parent.constructorName)) {
11697 return null;
11698 } else if (parent is ConstructorName && identical(node, parent.name)) {
11699 return null;
11700 } else if (parent is ConstructorFieldInitializer &&
11701 identical(node, parent.fieldName)) {
11702 return null;
11703 } else if (node.staticElement is PrefixElement) {
11704 // Prefixes don't have a type.
11705 return null;
11706 }
11707 return super.visitSimpleIdentifier(node);
11708 }
11709
11710 @override
11711 Object visitTypeName(TypeName node) {
11712 // Note: do not visit children from this node, the child SimpleIdentifier in
11713 // TypeName (i.e. "String") does not have a static type defined.
11714 if (node.type == null) {
11715 _unresolvedTypes.add(node);
11716 } else {
11717 _resolvedTypeCount++;
11718 }
11719 return null;
11720 }
11721
11722 String _getFileName(AstNode node) {
11723 // TODO (jwren) there are two copies of this method, one here and one in
11724 // ResolutionVerifier, they should be resolved into a single method
11725 if (node != null) {
11726 AstNode root = node.root;
11727 if (root is CompilationUnit) {
11728 CompilationUnit rootCU = root;
11729 if (rootCU.element != null) {
11730 return rootCU.element.source.fullName;
11731 } else {
11732 return "<unknown file- CompilationUnit.getElement() returned null>";
11733 }
11734 } else {
11735 return "<unknown file- CompilationUnit.getRoot() is not a CompilationUni t>";
11736 }
11737 }
11738 return "<unknown file- ASTNode is null>";
11739 }
11740 }
11741
11742 /**
11743 * The class `StrictModeTest` contains tests to ensure that the correct errors a nd warnings
11744 * are reported when the analysis engine is run in strict mode.
11745 */
11746 @reflectiveTest
11747 class StrictModeTest extends ResolverTestCase {
11748 void fail_for() {
11749 Source source = addSource(r'''
11750 int f(List<int> list) {
11751 num sum = 0;
11752 for (num i = 0; i < list.length; i++) {
11753 sum += list[i];
11754 }
11755 }''');
11756 computeLibrarySourceErrors(source);
11757 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11758 }
11759
11760 @override
11761 void setUp() {
11762 AnalysisOptionsImpl options = new AnalysisOptionsImpl();
11763 options.hint = false;
11764 resetWithOptions(options);
11765 }
11766
11767 void test_assert_is() {
11768 Source source = addSource(r'''
11769 int f(num n) {
11770 assert (n is int);
11771 return n & 0x0F;
11772 }''');
11773 computeLibrarySourceErrors(source);
11774 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11775 }
11776
11777 void test_conditional_and_is() {
11778 Source source = addSource(r'''
11779 int f(num n) {
11780 return (n is int && n > 0) ? n & 0x0F : 0;
11781 }''');
11782 computeLibrarySourceErrors(source);
11783 assertNoErrors(source);
11784 }
11785
11786 void test_conditional_is() {
11787 Source source = addSource(r'''
11788 int f(num n) {
11789 return (n is int) ? n & 0x0F : 0;
11790 }''');
11791 computeLibrarySourceErrors(source);
11792 assertNoErrors(source);
11793 }
11794
11795 void test_conditional_isNot() {
11796 Source source = addSource(r'''
11797 int f(num n) {
11798 return (n is! int) ? 0 : n & 0x0F;
11799 }''');
11800 computeLibrarySourceErrors(source);
11801 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11802 }
11803
11804 void test_conditional_or_is() {
11805 Source source = addSource(r'''
11806 int f(num n) {
11807 return (n is! int || n < 0) ? 0 : n & 0x0F;
11808 }''');
11809 computeLibrarySourceErrors(source);
11810 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11811 }
11812
11813 void test_forEach() {
11814 Source source = addSource(r'''
11815 int f(List<int> list) {
11816 num sum = 0;
11817 for (num n in list) {
11818 sum += n & 0x0F;
11819 }
11820 }''');
11821 computeLibrarySourceErrors(source);
11822 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11823 }
11824
11825 void test_if_and_is() {
11826 Source source = addSource(r'''
11827 int f(num n) {
11828 if (n is int && n > 0) {
11829 return n & 0x0F;
11830 }
11831 return 0;
11832 }''');
11833 computeLibrarySourceErrors(source);
11834 assertNoErrors(source);
11835 }
11836
11837 void test_if_is() {
11838 Source source = addSource(r'''
11839 int f(num n) {
11840 if (n is int) {
11841 return n & 0x0F;
11842 }
11843 return 0;
11844 }''');
11845 computeLibrarySourceErrors(source);
11846 assertNoErrors(source);
11847 }
11848
11849 void test_if_isNot() {
11850 Source source = addSource(r'''
11851 int f(num n) {
11852 if (n is! int) {
11853 return 0;
11854 } else {
11855 return n & 0x0F;
11856 }
11857 }''');
11858 computeLibrarySourceErrors(source);
11859 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11860 }
11861
11862 void test_if_isNot_abrupt() {
11863 Source source = addSource(r'''
11864 int f(num n) {
11865 if (n is! int) {
11866 return 0;
11867 }
11868 return n & 0x0F;
11869 }''');
11870 computeLibrarySourceErrors(source);
11871 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11872 }
11873
11874 void test_if_or_is() {
11875 Source source = addSource(r'''
11876 int f(num n) {
11877 if (n is! int || n < 0) {
11878 return 0;
11879 } else {
11880 return n & 0x0F;
11881 }
11882 }''');
11883 computeLibrarySourceErrors(source);
11884 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11885 }
11886
11887 void test_localVar() {
11888 Source source = addSource(r'''
11889 int f() {
11890 num n = 1234;
11891 return n & 0x0F;
11892 }''');
11893 computeLibrarySourceErrors(source);
11894 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11895 }
11896 }
11897
11898 /**
11899 * Strong mode static analyzer end to end tests
11900 */
11901 @reflectiveTest
11902 class StrongModeStaticTypeAnalyzer2Test extends _StaticTypeAnalyzer2TestShared {
11903 void setUp() {
11904 AnalysisOptionsImpl options = new AnalysisOptionsImpl();
11905 options.strongMode = true;
11906 resetWithOptions(options);
11907 }
11908
11909 void test_dynamicObjectGetter_hashCode() {
11910 String code = r'''
11911 main() {
11912 dynamic a = null;
11913 var foo = a.hashCode;
11914 }
11915 ''';
11916 _resolveTestUnit(code);
11917
11918 SimpleIdentifier identifier = _findIdentifier('foo');
11919 VariableDeclaration declaration =
11920 identifier.getAncestor((node) => node is VariableDeclaration);
11921 expect(declaration.initializer.staticType.name, 'int');
11922 expect(declaration.initializer.propagatedType, isNull);
11923 }
11924
11925 void test_dynamicObjectMethod_toString() {
11926 String code = r'''
11927 main() {
11928 dynamic a = null;
11929 var foo = a.toString();
11930 }
11931 ''';
11932 _resolveTestUnit(code);
11933
11934 SimpleIdentifier identifier = _findIdentifier('foo');
11935 VariableDeclaration declaration =
11936 identifier.getAncestor((node) => node is VariableDeclaration);
11937 expect(declaration.initializer.staticType.name, 'String');
11938 expect(declaration.initializer.propagatedType, isNull);
11939 }
11940
11941 void test_pseudoGeneric_max_doubleDouble() {
11942 String code = r'''
11943 import 'dart:math';
11944 main() {
11945 var foo = max(1.0, 2.0);
11946 }
11947 ''';
11948 _resolveTestUnit(code);
11949
11950 SimpleIdentifier identifier = _findIdentifier('foo');
11951 VariableDeclaration declaration =
11952 identifier.getAncestor((node) => node is VariableDeclaration);
11953 expect(declaration.initializer.staticType.name, 'double');
11954 expect(declaration.initializer.propagatedType, isNull);
11955 }
11956
11957 void test_pseudoGeneric_max_doubleInt() {
11958 String code = r'''
11959 import 'dart:math';
11960 main() {
11961 var foo = max(1.0, 2);
11962 }
11963 ''';
11964 _resolveTestUnit(code);
11965
11966 SimpleIdentifier identifier = _findIdentifier('foo');
11967 VariableDeclaration declaration =
11968 identifier.getAncestor((node) => node is VariableDeclaration);
11969 expect(declaration.initializer.staticType.name, 'num');
11970 expect(declaration.initializer.propagatedType, isNull);
11971 }
11972
11973 void test_pseudoGeneric_max_intDouble() {
11974 String code = r'''
11975 import 'dart:math';
11976 main() {
11977 var foo = max(1, 2.0);
11978 }
11979 ''';
11980 _resolveTestUnit(code);
11981
11982 SimpleIdentifier identifier = _findIdentifier('foo');
11983 VariableDeclaration declaration =
11984 identifier.getAncestor((node) => node is VariableDeclaration);
11985 expect(declaration.initializer.staticType.name, 'num');
11986 expect(declaration.initializer.propagatedType, isNull);
11987 }
11988
11989 void test_pseudoGeneric_max_intInt() {
11990 String code = r'''
11991 import 'dart:math';
11992 main() {
11993 var foo = max(1, 2);
11994 }
11995 ''';
11996 _resolveTestUnit(code);
11997
11998 SimpleIdentifier identifier = _findIdentifier('foo');
11999 VariableDeclaration declaration =
12000 identifier.getAncestor((node) => node is VariableDeclaration);
12001 expect(declaration.initializer.staticType.name, 'int');
12002 expect(declaration.initializer.propagatedType, isNull);
12003 }
12004
12005 void test_pseudoGeneric_then() {
12006 String code = r'''
12007 import 'dart:async';
12008 String toString(int x) => x.toString();
12009 main() {
12010 Future<int> bar = null;
12011 var foo = bar.then(toString);
12012 }
12013 ''';
12014 _resolveTestUnit(code);
12015
12016 SimpleIdentifier identifier = _findIdentifier('foo');
12017 VariableDeclaration declaration =
12018 identifier.getAncestor((node) => node is VariableDeclaration);
12019
12020 expect(declaration.initializer.staticType.toString(), "Future<String>");
12021 expect(declaration.initializer.propagatedType, isNull);
12022 }
12023
12024 void test_ternaryOperator_null_left() {
12025 String code = r'''
12026 main() {
12027 var foo = (true) ? null : 3;
12028 }
12029 ''';
12030 _resolveTestUnit(code);
12031
12032 SimpleIdentifier identifier = _findIdentifier('foo');
12033 VariableDeclaration declaration =
12034 identifier.getAncestor((node) => node is VariableDeclaration);
12035 expect(declaration.initializer.staticType.name, 'int');
12036 expect(declaration.initializer.propagatedType, isNull);
12037 }
12038
12039 void test_ternaryOperator_null_right() {
12040 String code = r'''
12041 main() {
12042 var foo = (true) ? 3 : null;
12043 }
12044 ''';
12045 _resolveTestUnit(code);
12046
12047 SimpleIdentifier identifier = _findIdentifier('foo');
12048 VariableDeclaration declaration =
12049 identifier.getAncestor((node) => node is VariableDeclaration);
12050 expect(declaration.initializer.staticType.name, 'int');
12051 expect(declaration.initializer.propagatedType, isNull);
12052 }
12053 }
12054
12055 @reflectiveTest
12056 class StrongModeTypePropagationTest extends ResolverTestCase {
12057 @override
12058 void setUp() {
12059 AnalysisOptionsImpl options = new AnalysisOptionsImpl();
12060 options.strongMode = true;
12061 resetWithOptions(options);
12062 }
12063
12064 void test_foreachInference_dynamic_disabled() {
12065 String code = r'''
12066 main() {
12067 var list = <int>[];
12068 for (dynamic v in list) {
12069 v; // marker
12070 }
12071 }''';
12072 _assertPropagatedIterationType(
12073 code, typeProvider.dynamicType, typeProvider.intType);
12074 _assertTypeOfMarkedExpression(
12075 code, typeProvider.dynamicType, typeProvider.intType);
12076 }
12077
12078 void test_foreachInference_reusedVar_disabled() {
12079 String code = r'''
12080 main() {
12081 var list = <int>[];
12082 var v;
12083 for (v in list) {
12084 v; // marker
12085 }
12086 }''';
12087 _assertPropagatedIterationType(
12088 code, typeProvider.dynamicType, typeProvider.intType);
12089 _assertTypeOfMarkedExpression(
12090 code, typeProvider.dynamicType, typeProvider.intType);
12091 }
12092
12093 void test_foreachInference_var() {
12094 String code = r'''
12095 main() {
12096 var list = <int>[];
12097 for (var v in list) {
12098 v; // marker
12099 }
12100 }''';
12101 _assertPropagatedIterationType(code, typeProvider.intType, null);
12102 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
12103 }
12104
12105 void test_foreachInference_var_iterable() {
12106 String code = r'''
12107 main() {
12108 Iterable<int> list = <int>[];
12109 for (var v in list) {
12110 v; // marker
12111 }
12112 }''';
12113 _assertPropagatedIterationType(code, typeProvider.intType, null);
12114 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
12115 }
12116
12117 void test_foreachInference_var_stream() {
12118 String code = r'''
12119 import 'dart:async';
12120 main() async {
12121 Stream<int> stream = null;
12122 await for (var v in stream) {
12123 v; // marker
12124 }
12125 }''';
12126 _assertPropagatedIterationType(code, typeProvider.intType, null);
12127 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
12128 }
12129
12130 void test_localVariableInference_bottom_disabled() {
12131 String code = r'''
12132 main() {
12133 var v = null;
12134 v; // marker
12135 }''';
12136 _assertPropagatedAssignedType(code, typeProvider.dynamicType, null);
12137 _assertTypeOfMarkedExpression(code, typeProvider.dynamicType, null);
12138 }
12139
12140 void test_localVariableInference_constant() {
12141 String code = r'''
12142 main() {
12143 var v = 3;
12144 v; // marker
12145 }''';
12146 _assertPropagatedAssignedType(code, typeProvider.intType, null);
12147 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
12148 }
12149
12150 void test_localVariableInference_declaredType_disabled() {
12151 String code = r'''
12152 main() {
12153 dynamic v = 3;
12154 v; // marker
12155 }''';
12156 _assertPropagatedAssignedType(
12157 code, typeProvider.dynamicType, typeProvider.intType);
12158 _assertTypeOfMarkedExpression(
12159 code, typeProvider.dynamicType, typeProvider.intType);
12160 }
12161
12162 void test_localVariableInference_noInitializer_disabled() {
12163 String code = r'''
12164 main() {
12165 var v;
12166 v = 3;
12167 v; // marker
12168 }''';
12169 _assertPropagatedAssignedType(
12170 code, typeProvider.dynamicType, typeProvider.intType);
12171 _assertTypeOfMarkedExpression(
12172 code, typeProvider.dynamicType, typeProvider.intType);
12173 }
12174
12175 void test_localVariableInference_transitive_field_inferred_lexical() {
12176 if (!AnalysisEngine.instance.useTaskModel) {
12177 return;
12178 }
12179 String code = r'''
12180 class A {
12181 final x = 3;
12182 f() {
12183 var v = x;
12184 return v; // marker
12185 }
12186 }
12187 main() {
12188 }
12189 ''';
12190 _assertPropagatedAssignedType(code, typeProvider.intType, null);
12191 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
12192 }
12193
12194 void test_localVariableInference_transitive_field_inferred_reversed() {
12195 if (!AnalysisEngine.instance.useTaskModel) {
12196 return;
12197 }
12198 String code = r'''
12199 class A {
12200 f() {
12201 var v = x;
12202 return v; // marker
12203 }
12204 final x = 3;
12205 }
12206 main() {
12207 }
12208 ''';
12209 _assertPropagatedAssignedType(code, typeProvider.intType, null);
12210 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
12211 }
12212
12213 void test_localVariableInference_transitive_field_lexical() {
12214 String code = r'''
12215 class A {
12216 int x = 3;
12217 f() {
12218 var v = x;
12219 return v; // marker
12220 }
12221 }
12222 main() {
12223 }
12224 ''';
12225 _assertPropagatedAssignedType(code, typeProvider.intType, null);
12226 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
12227 }
12228
12229 void test_localVariableInference_transitive_field_reversed() {
12230 String code = r'''
12231 class A {
12232 f() {
12233 var v = x;
12234 return v; // marker
12235 }
12236 int x = 3;
12237 }
12238 main() {
12239 }
12240 ''';
12241 _assertPropagatedAssignedType(code, typeProvider.intType, null);
12242 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
12243 }
12244
12245 void test_localVariableInference_transitive_list_local() {
12246 String code = r'''
12247 main() {
12248 var x = <int>[3];
12249 var v = x[0];
12250 v; // marker
12251 }''';
12252 _assertPropagatedAssignedType(code, typeProvider.intType, null);
12253 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
12254 }
12255
12256 void test_localVariableInference_transitive_local() {
12257 String code = r'''
12258 main() {
12259 var x = 3;
12260 var v = x;
12261 v; // marker
12262 }''';
12263 _assertPropagatedAssignedType(code, typeProvider.intType, null);
12264 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
12265 }
12266
12267 void test_localVariableInference_transitive_toplevel_inferred_lexical() {
12268 if (!AnalysisEngine.instance.useTaskModel) {
12269 return;
12270 }
12271 String code = r'''
12272 final x = 3;
12273 main() {
12274 var v = x;
12275 v; // marker
12276 }
12277 ''';
12278 _assertPropagatedAssignedType(code, typeProvider.intType, null);
12279 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
12280 }
12281
12282 void test_localVariableInference_transitive_toplevel_inferred_reversed() {
12283 if (!AnalysisEngine.instance.useTaskModel) {
12284 return;
12285 }
12286 String code = r'''
12287 main() {
12288 var v = x;
12289 v; // marker
12290 }
12291 final x = 3;
12292 ''';
12293 _assertPropagatedAssignedType(code, typeProvider.intType, null);
12294 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
12295 }
12296
12297 void test_localVariableInference_transitive_toplevel_lexical() {
12298 String code = r'''
12299 int x = 3;
12300 main() {
12301 var v = x;
12302 v; // marker
12303 }
12304 ''';
12305 _assertPropagatedAssignedType(code, typeProvider.intType, null);
12306 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
12307 }
12308
12309 void test_localVariableInference_transitive_toplevel_reversed() {
12310 String code = r'''
12311 main() {
12312 var v = x;
12313 v; // marker
12314 }
12315 int x = 3;
12316 ''';
12317 _assertPropagatedAssignedType(code, typeProvider.intType, null);
12318 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
12319 }
12320 }
12321
12322 @reflectiveTest
12323 class SubtypeManagerTest extends EngineTestCase {
12324 /**
12325 * The inheritance manager being tested.
12326 */
12327 SubtypeManager _subtypeManager;
12328
12329 /**
12330 * The compilation unit element containing all of the types setup in each test .
12331 */
12332 CompilationUnitElementImpl _definingCompilationUnit;
12333
12334 @override
12335 void setUp() {
12336 super.setUp();
12337 AnalysisContext context = AnalysisContextFactory.contextWithCore();
12338 FileBasedSource source =
12339 new FileBasedSource(FileUtilities2.createFile("/test.dart"));
12340 _definingCompilationUnit = new CompilationUnitElementImpl("test.dart");
12341 _definingCompilationUnit.librarySource =
12342 _definingCompilationUnit.source = source;
12343 LibraryElementImpl definingLibrary =
12344 ElementFactory.library(context, "test");
12345 definingLibrary.definingCompilationUnit = _definingCompilationUnit;
12346 _subtypeManager = new SubtypeManager();
12347 }
12348
12349 void test_computeAllSubtypes_infiniteLoop() {
12350 //
12351 // class A extends B
12352 // class B extends A
12353 //
12354 ClassElementImpl classA = ElementFactory.classElement2("A");
12355 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
12356 classA.supertype = classB.type;
12357 _definingCompilationUnit.types = <ClassElement>[classA, classB];
12358 HashSet<ClassElement> subtypesOfA =
12359 _subtypeManager.computeAllSubtypes(classA);
12360 List<ClassElement> arraySubtypesOfA = new List.from(subtypesOfA);
12361 expect(subtypesOfA, hasLength(2));
12362 expect(arraySubtypesOfA, unorderedEquals([classA, classB]));
12363 }
12364
12365 void test_computeAllSubtypes_manyRecursiveSubtypes() {
12366 //
12367 // class A
12368 // class B extends A
12369 // class C extends B
12370 // class D extends B
12371 // class E extends B
12372 //
12373 ClassElementImpl classA = ElementFactory.classElement2("A");
12374 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
12375 ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
12376 ClassElementImpl classD = ElementFactory.classElement("D", classB.type);
12377 ClassElementImpl classE = ElementFactory.classElement("E", classB.type);
12378 _definingCompilationUnit.types = <ClassElement>[
12379 classA,
12380 classB,
12381 classC,
12382 classD,
12383 classE
12384 ];
12385 HashSet<ClassElement> subtypesOfA =
12386 _subtypeManager.computeAllSubtypes(classA);
12387 List<ClassElement> arraySubtypesOfA = new List.from(subtypesOfA);
12388 HashSet<ClassElement> subtypesOfB =
12389 _subtypeManager.computeAllSubtypes(classB);
12390 List<ClassElement> arraySubtypesOfB = new List.from(subtypesOfB);
12391 expect(subtypesOfA, hasLength(4));
12392 expect(arraySubtypesOfA, unorderedEquals([classB, classC, classD, classE]));
12393 expect(subtypesOfB, hasLength(3));
12394 expect(arraySubtypesOfB, unorderedEquals([classC, classD, classE]));
12395 }
12396
12397 void test_computeAllSubtypes_noSubtypes() {
12398 //
12399 // class A
12400 //
12401 ClassElementImpl classA = ElementFactory.classElement2("A");
12402 _definingCompilationUnit.types = <ClassElement>[classA];
12403 HashSet<ClassElement> subtypesOfA =
12404 _subtypeManager.computeAllSubtypes(classA);
12405 expect(subtypesOfA, hasLength(0));
12406 }
12407
12408 void test_computeAllSubtypes_oneSubtype() {
12409 //
12410 // class A
12411 // class B extends A
12412 //
12413 ClassElementImpl classA = ElementFactory.classElement2("A");
12414 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
12415 _definingCompilationUnit.types = <ClassElement>[classA, classB];
12416 HashSet<ClassElement> subtypesOfA =
12417 _subtypeManager.computeAllSubtypes(classA);
12418 List<ClassElement> arraySubtypesOfA = new List.from(subtypesOfA);
12419 expect(subtypesOfA, hasLength(1));
12420 expect(arraySubtypesOfA, unorderedEquals([classB]));
12421 }
12422 }
12423
12424 @reflectiveTest
12425 class TypeOverrideManagerTest extends EngineTestCase {
12426 void test_exitScope_noScopes() {
12427 TypeOverrideManager manager = new TypeOverrideManager();
12428 try {
12429 manager.exitScope();
12430 fail("Expected IllegalStateException");
12431 } on IllegalStateException {
12432 // Expected
12433 }
12434 }
12435
12436 void test_exitScope_oneScope() {
12437 TypeOverrideManager manager = new TypeOverrideManager();
12438 manager.enterScope();
12439 manager.exitScope();
12440 try {
12441 manager.exitScope();
12442 fail("Expected IllegalStateException");
12443 } on IllegalStateException {
12444 // Expected
12445 }
12446 }
12447
12448 void test_exitScope_twoScopes() {
12449 TypeOverrideManager manager = new TypeOverrideManager();
12450 manager.enterScope();
12451 manager.exitScope();
12452 manager.enterScope();
12453 manager.exitScope();
12454 try {
12455 manager.exitScope();
12456 fail("Expected IllegalStateException");
12457 } on IllegalStateException {
12458 // Expected
12459 }
12460 }
12461
12462 void test_getType_enclosedOverride() {
12463 TypeOverrideManager manager = new TypeOverrideManager();
12464 LocalVariableElementImpl element =
12465 ElementFactory.localVariableElement2("v");
12466 InterfaceType type = ElementFactory.classElement2("C").type;
12467 manager.enterScope();
12468 manager.setType(element, type);
12469 manager.enterScope();
12470 expect(manager.getType(element), same(type));
12471 }
12472
12473 void test_getType_immediateOverride() {
12474 TypeOverrideManager manager = new TypeOverrideManager();
12475 LocalVariableElementImpl element =
12476 ElementFactory.localVariableElement2("v");
12477 InterfaceType type = ElementFactory.classElement2("C").type;
12478 manager.enterScope();
12479 manager.setType(element, type);
12480 expect(manager.getType(element), same(type));
12481 }
12482
12483 void test_getType_noOverride() {
12484 TypeOverrideManager manager = new TypeOverrideManager();
12485 manager.enterScope();
12486 expect(manager.getType(ElementFactory.localVariableElement2("v")), isNull);
12487 }
12488
12489 void test_getType_noScope() {
12490 TypeOverrideManager manager = new TypeOverrideManager();
12491 expect(manager.getType(ElementFactory.localVariableElement2("v")), isNull);
12492 }
12493 }
12494
12495 @reflectiveTest
12496 class TypePropagationTest extends ResolverTestCase {
12497 void fail_finalPropertyInducingVariable_classMember_instance() {
12498 addNamedSource(
12499 "/lib.dart",
12500 r'''
12501 class A {
12502 final v = 0;
12503 }''');
12504 String code = r'''
12505 import 'lib.dart';
12506 f(A a) {
12507 return a.v; // marker
12508 }''';
12509 _assertTypeOfMarkedExpression(
12510 code, typeProvider.dynamicType, typeProvider.intType);
12511 }
12512
12513 void fail_finalPropertyInducingVariable_classMember_instance_inherited() {
12514 addNamedSource(
12515 "/lib.dart",
12516 r'''
12517 class A {
12518 final v = 0;
12519 }''');
12520 String code = r'''
12521 import 'lib.dart';
12522 class B extends A {
12523 m() {
12524 return v; // marker
12525 }
12526 }''';
12527 _assertTypeOfMarkedExpression(
12528 code, typeProvider.dynamicType, typeProvider.intType);
12529 }
12530
12531 void fail_finalPropertyInducingVariable_classMember_instance_propagatedTarget( ) {
12532 addNamedSource(
12533 "/lib.dart",
12534 r'''
12535 class A {
12536 final v = 0;
12537 }''');
12538 String code = r'''
12539 import 'lib.dart';
12540 f(p) {
12541 if (p is A) {
12542 return p.v; // marker
12543 }
12544 }''';
12545 _assertTypeOfMarkedExpression(
12546 code, typeProvider.dynamicType, typeProvider.intType);
12547 }
12548
12549 void fail_finalPropertyInducingVariable_classMember_instance_unprefixed() {
12550 String code = r'''
12551 class A {
12552 final v = 0;
12553 m() {
12554 v; // marker
12555 }
12556 }''';
12557 _assertTypeOfMarkedExpression(
12558 code, typeProvider.dynamicType, typeProvider.intType);
12559 }
12560
12561 void fail_finalPropertyInducingVariable_classMember_static() {
12562 addNamedSource(
12563 "/lib.dart",
12564 r'''
12565 class A {
12566 static final V = 0;
12567 }''');
12568 String code = r'''
12569 import 'lib.dart';
12570 f() {
12571 return A.V; // marker
12572 }''';
12573 _assertTypeOfMarkedExpression(
12574 code, typeProvider.dynamicType, typeProvider.intType);
12575 }
12576
12577 void fail_finalPropertyInducingVariable_topLevelVaraible_prefixed() {
12578 addNamedSource("/lib.dart", "final V = 0;");
12579 String code = r'''
12580 import 'lib.dart' as p;
12581 f() {
12582 var v2 = p.V; // marker prefixed
12583 }''';
12584 _assertTypeOfMarkedExpression(
12585 code, typeProvider.dynamicType, typeProvider.intType);
12586 }
12587
12588 void fail_finalPropertyInducingVariable_topLevelVaraible_simple() {
12589 addNamedSource("/lib.dart", "final V = 0;");
12590 String code = r'''
12591 import 'lib.dart';
12592 f() {
12593 return V; // marker simple
12594 }''';
12595 _assertTypeOfMarkedExpression(
12596 code, typeProvider.dynamicType, typeProvider.intType);
12597 }
12598
12599 void fail_mergePropagatedTypesAtJoinPoint_1() {
12600 // https://code.google.com/p/dart/issues/detail?id=19929
12601 _assertTypeOfMarkedExpression(
12602 r'''
12603 f1(x) {
12604 var y = [];
12605 if (x) {
12606 y = 0;
12607 } else {
12608 y = '';
12609 }
12610 // Propagated type is [List] here: incorrect.
12611 // Best we can do is [Object]?
12612 return y; // marker
12613 }''',
12614 null,
12615 typeProvider.dynamicType);
12616 }
12617
12618 void fail_mergePropagatedTypesAtJoinPoint_2() {
12619 // https://code.google.com/p/dart/issues/detail?id=19929
12620 _assertTypeOfMarkedExpression(
12621 r'''
12622 f2(x) {
12623 var y = [];
12624 if (x) {
12625 y = 0;
12626 } else {
12627 }
12628 // Propagated type is [List] here: incorrect.
12629 // Best we can do is [Object]?
12630 return y; // marker
12631 }''',
12632 null,
12633 typeProvider.dynamicType);
12634 }
12635
12636 void fail_mergePropagatedTypesAtJoinPoint_3() {
12637 // https://code.google.com/p/dart/issues/detail?id=19929
12638 _assertTypeOfMarkedExpression(
12639 r'''
12640 f4(x) {
12641 var y = [];
12642 if (x) {
12643 y = 0;
12644 } else {
12645 y = 1.5;
12646 }
12647 // Propagated type is [List] here: incorrect.
12648 // A correct answer is the least upper bound of [int] and [double],
12649 // i.e. [num].
12650 return y; // marker
12651 }''',
12652 null,
12653 typeProvider.numType);
12654 }
12655
12656 void fail_mergePropagatedTypesAtJoinPoint_5() {
12657 // https://code.google.com/p/dart/issues/detail?id=19929
12658 _assertTypeOfMarkedExpression(
12659 r'''
12660 f6(x,y) {
12661 var z = [];
12662 if (x || (z = y) < 0) {
12663 } else {
12664 z = 0;
12665 }
12666 // Propagated type is [List] here: incorrect.
12667 // Best we can do is [Object]?
12668 return z; // marker
12669 }''',
12670 null,
12671 typeProvider.dynamicType);
12672 }
12673
12674 void fail_mergePropagatedTypesAtJoinPoint_7() {
12675 // https://code.google.com/p/dart/issues/detail?id=19929
12676 //
12677 // In general [continue]s are unsafe for the purposes of
12678 // [isAbruptTerminationStatement].
12679 //
12680 // This is like example 6, but less tricky: the code in the branch that
12681 // [continue]s is in effect after the [if].
12682 String code = r'''
12683 f() {
12684 var x = 0;
12685 var c = false;
12686 var d = true;
12687 while (d) {
12688 if (c) {
12689 d = false;
12690 } else {
12691 x = '';
12692 c = true;
12693 continue;
12694 }
12695 x; // marker
12696 }
12697 }''';
12698 DartType t = _findMarkedIdentifier(code, "; // marker").propagatedType;
12699 expect(typeProvider.intType.isSubtypeOf(t), isTrue);
12700 expect(typeProvider.stringType.isSubtypeOf(t), isTrue);
12701 }
12702
12703 void fail_mergePropagatedTypesAtJoinPoint_8() {
12704 // https://code.google.com/p/dart/issues/detail?id=19929
12705 //
12706 // In nested loops [breaks]s are unsafe for the purposes of
12707 // [isAbruptTerminationStatement].
12708 //
12709 // This is a combination of 6 and 7: we use an unlabeled [break]
12710 // like a continue for the outer loop / like a labeled [break] to
12711 // jump just above the [if].
12712 String code = r'''
12713 f() {
12714 var x = 0;
12715 var c = false;
12716 var d = true;
12717 while (d) {
12718 while (d) {
12719 if (c) {
12720 d = false;
12721 } else {
12722 x = '';
12723 c = true;
12724 break;
12725 }
12726 x; // marker
12727 }
12728 }
12729 }''';
12730 DartType t = _findMarkedIdentifier(code, "; // marker").propagatedType;
12731 expect(typeProvider.intType.isSubtypeOf(t), isTrue);
12732 expect(typeProvider.stringType.isSubtypeOf(t), isTrue);
12733 }
12734
12735 void fail_propagatedReturnType_functionExpression() {
12736 // TODO(scheglov) disabled because we don't resolve function expression
12737 String code = r'''
12738 main() {
12739 var v = (() {return 42;})();
12740 }''';
12741 _assertPropagatedAssignedType(
12742 code, typeProvider.dynamicType, typeProvider.intType);
12743 }
12744
12745 void test_as() {
12746 Source source = addSource(r'''
12747 class A {
12748 bool get g => true;
12749 }
12750 A f(var p) {
12751 if ((p as A).g) {
12752 return p;
12753 } else {
12754 return null;
12755 }
12756 }''');
12757 LibraryElement library = resolve2(source);
12758 assertNoErrors(source);
12759 verify([source]);
12760 CompilationUnit unit = resolveCompilationUnit(source, library);
12761 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
12762 InterfaceType typeA = classA.element.type;
12763 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
12764 BlockFunctionBody body =
12765 function.functionExpression.body as BlockFunctionBody;
12766 IfStatement ifStatement = body.block.statements[0] as IfStatement;
12767 ReturnStatement statement =
12768 (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
12769 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
12770 expect(variableName.propagatedType, same(typeA));
12771 }
12772
12773 void test_assert() {
12774 Source source = addSource(r'''
12775 class A {}
12776 A f(var p) {
12777 assert (p is A);
12778 return p;
12779 }''');
12780 LibraryElement library = resolve2(source);
12781 assertNoErrors(source);
12782 verify([source]);
12783 CompilationUnit unit = resolveCompilationUnit(source, library);
12784 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
12785 InterfaceType typeA = classA.element.type;
12786 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
12787 BlockFunctionBody body =
12788 function.functionExpression.body as BlockFunctionBody;
12789 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
12790 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
12791 expect(variableName.propagatedType, same(typeA));
12792 }
12793
12794 void test_assignment() {
12795 Source source = addSource(r'''
12796 f() {
12797 var v;
12798 v = 0;
12799 return v;
12800 }''');
12801 LibraryElement library = resolve2(source);
12802 assertNoErrors(source);
12803 verify([source]);
12804 CompilationUnit unit = resolveCompilationUnit(source, library);
12805 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
12806 BlockFunctionBody body =
12807 function.functionExpression.body as BlockFunctionBody;
12808 ReturnStatement statement = body.block.statements[2] as ReturnStatement;
12809 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
12810 expect(variableName.propagatedType, same(typeProvider.intType));
12811 }
12812
12813 void test_assignment_afterInitializer() {
12814 Source source = addSource(r'''
12815 f() {
12816 var v = 0;
12817 v = 1.0;
12818 return v;
12819 }''');
12820 LibraryElement library = resolve2(source);
12821 assertNoErrors(source);
12822 verify([source]);
12823 CompilationUnit unit = resolveCompilationUnit(source, library);
12824 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
12825 BlockFunctionBody body =
12826 function.functionExpression.body as BlockFunctionBody;
12827 ReturnStatement statement = body.block.statements[2] as ReturnStatement;
12828 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
12829 expect(variableName.propagatedType, same(typeProvider.doubleType));
12830 }
12831
12832 void test_assignment_null() {
12833 String code = r'''
12834 main() {
12835 int v; // declare
12836 v = null;
12837 return v; // return
12838 }''';
12839 CompilationUnit unit;
12840 {
12841 Source source = addSource(code);
12842 LibraryElement library = resolve2(source);
12843 assertNoErrors(source);
12844 verify([source]);
12845 unit = resolveCompilationUnit(source, library);
12846 }
12847 {
12848 SimpleIdentifier identifier = EngineTestCase.findNode(
12849 unit, code, "v; // declare", (node) => node is SimpleIdentifier);
12850 expect(identifier.staticType, same(typeProvider.intType));
12851 expect(identifier.propagatedType, same(null));
12852 }
12853 {
12854 SimpleIdentifier identifier = EngineTestCase.findNode(
12855 unit, code, "v = null;", (node) => node is SimpleIdentifier);
12856 expect(identifier.staticType, same(typeProvider.intType));
12857 expect(identifier.propagatedType, same(null));
12858 }
12859 {
12860 SimpleIdentifier identifier = EngineTestCase.findNode(
12861 unit, code, "v; // return", (node) => node is SimpleIdentifier);
12862 expect(identifier.staticType, same(typeProvider.intType));
12863 expect(identifier.propagatedType, same(null));
12864 }
12865 }
12866
12867 void test_CanvasElement_getContext() {
12868 String code = r'''
12869 import 'dart:html';
12870 main(CanvasElement canvas) {
12871 var context = canvas.getContext('2d');
12872 }''';
12873 Source source = addSource(code);
12874 LibraryElement library = resolve2(source);
12875 assertNoErrors(source);
12876 verify([source]);
12877 CompilationUnit unit = resolveCompilationUnit(source, library);
12878 SimpleIdentifier identifier = EngineTestCase.findNode(
12879 unit, code, "context", (node) => node is SimpleIdentifier);
12880 expect(identifier.propagatedType.name, "CanvasRenderingContext2D");
12881 }
12882
12883 void test_forEach() {
12884 String code = r'''
12885 main() {
12886 var list = <String> [];
12887 for (var e in list) {
12888 e;
12889 }
12890 }''';
12891 Source source = addSource(code);
12892 LibraryElement library = resolve2(source);
12893 assertNoErrors(source);
12894 verify([source]);
12895 CompilationUnit unit = resolveCompilationUnit(source, library);
12896 InterfaceType stringType = typeProvider.stringType;
12897 // in the declaration
12898 {
12899 SimpleIdentifier identifier = EngineTestCase.findNode(
12900 unit, code, "e in", (node) => node is SimpleIdentifier);
12901 expect(identifier.propagatedType, same(stringType));
12902 }
12903 // in the loop body
12904 {
12905 SimpleIdentifier identifier = EngineTestCase.findNode(
12906 unit, code, "e;", (node) => node is SimpleIdentifier);
12907 expect(identifier.propagatedType, same(stringType));
12908 }
12909 }
12910
12911 void test_forEach_async() {
12912 String code = r'''
12913 import 'dart:async';
12914 f(Stream<String> stream) async {
12915 await for (var e in stream) {
12916 e;
12917 }
12918 }''';
12919 Source source = addSource(code);
12920 LibraryElement library = resolve2(source);
12921 assertNoErrors(source);
12922 verify([source]);
12923 CompilationUnit unit = resolveCompilationUnit(source, library);
12924 InterfaceType stringType = typeProvider.stringType;
12925 // in the declaration
12926 {
12927 SimpleIdentifier identifier = EngineTestCase.findNode(
12928 unit, code, "e in", (node) => node is SimpleIdentifier);
12929 expect(identifier.propagatedType, same(stringType));
12930 }
12931 // in the loop body
12932 {
12933 SimpleIdentifier identifier = EngineTestCase.findNode(
12934 unit, code, "e;", (node) => node is SimpleIdentifier);
12935 expect(identifier.propagatedType, same(stringType));
12936 }
12937 }
12938
12939 void test_functionExpression_asInvocationArgument() {
12940 String code = r'''
12941 class MyMap<K, V> {
12942 forEach(f(K key, V value)) {}
12943 }
12944 f(MyMap<int, String> m) {
12945 m.forEach((k, v) {
12946 k;
12947 v;
12948 });
12949 }''';
12950 Source source = addSource(code);
12951 LibraryElement library = resolve2(source);
12952 assertNoErrors(source);
12953 verify([source]);
12954 CompilationUnit unit = resolveCompilationUnit(source, library);
12955 // k
12956 DartType intType = typeProvider.intType;
12957 FormalParameter kParameter = EngineTestCase.findNode(
12958 unit, code, "k, ", (node) => node is SimpleFormalParameter);
12959 expect(kParameter.identifier.propagatedType, same(intType));
12960 SimpleIdentifier kIdentifier = EngineTestCase.findNode(
12961 unit, code, "k;", (node) => node is SimpleIdentifier);
12962 expect(kIdentifier.propagatedType, same(intType));
12963 expect(kIdentifier.staticType, same(typeProvider.dynamicType));
12964 // v
12965 DartType stringType = typeProvider.stringType;
12966 FormalParameter vParameter = EngineTestCase.findNode(
12967 unit, code, "v)", (node) => node is SimpleFormalParameter);
12968 expect(vParameter.identifier.propagatedType, same(stringType));
12969 SimpleIdentifier vIdentifier = EngineTestCase.findNode(
12970 unit, code, "v;", (node) => node is SimpleIdentifier);
12971 expect(vIdentifier.propagatedType, same(stringType));
12972 expect(vIdentifier.staticType, same(typeProvider.dynamicType));
12973 }
12974
12975 void test_functionExpression_asInvocationArgument_fromInferredInvocation() {
12976 String code = r'''
12977 class MyMap<K, V> {
12978 forEach(f(K key, V value)) {}
12979 }
12980 f(MyMap<int, String> m) {
12981 var m2 = m;
12982 m2.forEach((k, v) {});
12983 }''';
12984 Source source = addSource(code);
12985 LibraryElement library = resolve2(source);
12986 assertNoErrors(source);
12987 verify([source]);
12988 CompilationUnit unit = resolveCompilationUnit(source, library);
12989 // k
12990 DartType intType = typeProvider.intType;
12991 FormalParameter kParameter = EngineTestCase.findNode(
12992 unit, code, "k, ", (node) => node is SimpleFormalParameter);
12993 expect(kParameter.identifier.propagatedType, same(intType));
12994 // v
12995 DartType stringType = typeProvider.stringType;
12996 FormalParameter vParameter = EngineTestCase.findNode(
12997 unit, code, "v)", (node) => node is SimpleFormalParameter);
12998 expect(vParameter.identifier.propagatedType, same(stringType));
12999 }
13000
13001 void test_functionExpression_asInvocationArgument_functionExpressionInvocation () {
13002 String code = r'''
13003 main() {
13004 (f(String value)) {} ((v) {
13005 v;
13006 });
13007 }''';
13008 Source source = addSource(code);
13009 LibraryElement library = resolve2(source);
13010 assertNoErrors(source);
13011 verify([source]);
13012 CompilationUnit unit = resolveCompilationUnit(source, library);
13013 // v
13014 DartType dynamicType = typeProvider.dynamicType;
13015 DartType stringType = typeProvider.stringType;
13016 FormalParameter vParameter = EngineTestCase.findNode(
13017 unit, code, "v)", (node) => node is FormalParameter);
13018 expect(vParameter.identifier.propagatedType, same(stringType));
13019 expect(vParameter.identifier.staticType, same(dynamicType));
13020 SimpleIdentifier vIdentifier = EngineTestCase.findNode(
13021 unit, code, "v;", (node) => node is SimpleIdentifier);
13022 expect(vIdentifier.propagatedType, same(stringType));
13023 expect(vIdentifier.staticType, same(dynamicType));
13024 }
13025
13026 void test_functionExpression_asInvocationArgument_keepIfLessSpecific() {
13027 String code = r'''
13028 class MyList {
13029 forEach(f(Object value)) {}
13030 }
13031 f(MyList list) {
13032 list.forEach((int v) {
13033 v;
13034 });
13035 }''';
13036 Source source = addSource(code);
13037 LibraryElement library = resolve2(source);
13038 assertNoErrors(source);
13039 verify([source]);
13040 CompilationUnit unit = resolveCompilationUnit(source, library);
13041 // v
13042 DartType intType = typeProvider.intType;
13043 FormalParameter vParameter = EngineTestCase.findNode(
13044 unit, code, "v)", (node) => node is SimpleFormalParameter);
13045 expect(vParameter.identifier.propagatedType, same(null));
13046 expect(vParameter.identifier.staticType, same(intType));
13047 SimpleIdentifier vIdentifier = EngineTestCase.findNode(
13048 unit, code, "v;", (node) => node is SimpleIdentifier);
13049 expect(vIdentifier.staticType, same(intType));
13050 expect(vIdentifier.propagatedType, same(null));
13051 }
13052
13053 void test_functionExpression_asInvocationArgument_notSubtypeOfStaticType() {
13054 String code = r'''
13055 class A {
13056 m(void f(int i)) {}
13057 }
13058 x() {
13059 A a = new A();
13060 a.m(() => 0);
13061 }''';
13062 Source source = addSource(code);
13063 LibraryElement library = resolve2(source);
13064 assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
13065 verify([source]);
13066 CompilationUnit unit = resolveCompilationUnit(source, library);
13067 // () => 0
13068 FunctionExpression functionExpression = EngineTestCase.findNode(
13069 unit, code, "() => 0)", (node) => node is FunctionExpression);
13070 expect((functionExpression.staticType as FunctionType).parameters.length,
13071 same(0));
13072 expect(functionExpression.propagatedType, same(null));
13073 }
13074
13075 void test_functionExpression_asInvocationArgument_replaceIfMoreSpecific() {
13076 String code = r'''
13077 class MyList<E> {
13078 forEach(f(E value)) {}
13079 }
13080 f(MyList<String> list) {
13081 list.forEach((Object v) {
13082 v;
13083 });
13084 }''';
13085 Source source = addSource(code);
13086 LibraryElement library = resolve2(source);
13087 assertNoErrors(source);
13088 verify([source]);
13089 CompilationUnit unit = resolveCompilationUnit(source, library);
13090 // v
13091 DartType stringType = typeProvider.stringType;
13092 FormalParameter vParameter = EngineTestCase.findNode(
13093 unit, code, "v)", (node) => node is SimpleFormalParameter);
13094 expect(vParameter.identifier.propagatedType, same(stringType));
13095 expect(vParameter.identifier.staticType, same(typeProvider.objectType));
13096 SimpleIdentifier vIdentifier = EngineTestCase.findNode(
13097 unit, code, "v;", (node) => node is SimpleIdentifier);
13098 expect(vIdentifier.propagatedType, same(stringType));
13099 }
13100
13101 void test_Future_then() {
13102 String code = r'''
13103 import 'dart:async';
13104 main(Future<int> firstFuture) {
13105 firstFuture.then((p1) {
13106 return 1.0;
13107 }).then((p2) {
13108 return new Future<String>.value('str');
13109 }).then((p3) {
13110 });
13111 }''';
13112 Source source = addSource(code);
13113 LibraryElement library = resolve2(source);
13114 assertNoErrors(source);
13115 verify([source]);
13116 CompilationUnit unit = resolveCompilationUnit(source, library);
13117 // p1
13118 FormalParameter p1 = EngineTestCase.findNode(
13119 unit, code, "p1) {", (node) => node is SimpleFormalParameter);
13120 expect(p1.identifier.propagatedType, same(typeProvider.intType));
13121 // p2
13122 FormalParameter p2 = EngineTestCase.findNode(
13123 unit, code, "p2) {", (node) => node is SimpleFormalParameter);
13124 expect(p2.identifier.propagatedType, same(typeProvider.doubleType));
13125 // p3
13126 FormalParameter p3 = EngineTestCase.findNode(
13127 unit, code, "p3) {", (node) => node is SimpleFormalParameter);
13128 expect(p3.identifier.propagatedType, same(typeProvider.stringType));
13129 }
13130
13131 void test_initializer() {
13132 Source source = addSource(r'''
13133 f() {
13134 var v = 0;
13135 return v;
13136 }''');
13137 LibraryElement library = resolve2(source);
13138 assertNoErrors(source);
13139 verify([source]);
13140 CompilationUnit unit = resolveCompilationUnit(source, library);
13141 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
13142 BlockFunctionBody body =
13143 function.functionExpression.body as BlockFunctionBody;
13144 NodeList<Statement> statements = body.block.statements;
13145 // Type of 'v' in declaration.
13146 {
13147 VariableDeclarationStatement statement =
13148 statements[0] as VariableDeclarationStatement;
13149 SimpleIdentifier variableName = statement.variables.variables[0].name;
13150 expect(variableName.staticType, same(typeProvider.dynamicType));
13151 expect(variableName.propagatedType, same(typeProvider.intType));
13152 }
13153 // Type of 'v' in reference.
13154 {
13155 ReturnStatement statement = statements[1] as ReturnStatement;
13156 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13157 expect(variableName.propagatedType, same(typeProvider.intType));
13158 }
13159 }
13160
13161 void test_initializer_dereference() {
13162 Source source = addSource(r'''
13163 f() {
13164 var v = 'String';
13165 v.
13166 }''');
13167 LibraryElement library = resolve2(source);
13168 CompilationUnit unit = resolveCompilationUnit(source, library);
13169 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
13170 BlockFunctionBody body =
13171 function.functionExpression.body as BlockFunctionBody;
13172 ExpressionStatement statement =
13173 body.block.statements[1] as ExpressionStatement;
13174 PrefixedIdentifier invocation = statement.expression as PrefixedIdentifier;
13175 SimpleIdentifier variableName = invocation.prefix;
13176 expect(variableName.propagatedType, same(typeProvider.stringType));
13177 }
13178
13179 void test_initializer_hasStaticType() {
13180 Source source = addSource(r'''
13181 f() {
13182 int v = 0;
13183 return v;
13184 }''');
13185 LibraryElement library = resolve2(source);
13186 assertNoErrors(source);
13187 verify([source]);
13188 CompilationUnit unit = resolveCompilationUnit(source, library);
13189 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
13190 BlockFunctionBody body =
13191 function.functionExpression.body as BlockFunctionBody;
13192 NodeList<Statement> statements = body.block.statements;
13193 // Type of 'v' in declaration.
13194 {
13195 VariableDeclarationStatement statement =
13196 statements[0] as VariableDeclarationStatement;
13197 SimpleIdentifier variableName = statement.variables.variables[0].name;
13198 expect(variableName.staticType, same(typeProvider.intType));
13199 expect(variableName.propagatedType, isNull);
13200 }
13201 // Type of 'v' in reference.
13202 {
13203 ReturnStatement statement = statements[1] as ReturnStatement;
13204 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13205 expect(variableName.staticType, same(typeProvider.intType));
13206 expect(variableName.propagatedType, isNull);
13207 }
13208 }
13209
13210 void test_initializer_hasStaticType_parameterized() {
13211 Source source = addSource(r'''
13212 f() {
13213 List<int> v = <int>[];
13214 return v;
13215 }''');
13216 LibraryElement library = resolve2(source);
13217 assertNoErrors(source);
13218 verify([source]);
13219 CompilationUnit unit = resolveCompilationUnit(source, library);
13220 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
13221 BlockFunctionBody body =
13222 function.functionExpression.body as BlockFunctionBody;
13223 NodeList<Statement> statements = body.block.statements;
13224 // Type of 'v' in declaration.
13225 {
13226 VariableDeclarationStatement statement =
13227 statements[0] as VariableDeclarationStatement;
13228 SimpleIdentifier variableName = statement.variables.variables[0].name;
13229 expect(variableName.staticType, isNotNull);
13230 expect(variableName.propagatedType, isNull);
13231 }
13232 // Type of 'v' in reference.
13233 {
13234 ReturnStatement statement = statements[1] as ReturnStatement;
13235 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13236 expect(variableName.staticType, isNotNull);
13237 expect(variableName.propagatedType, isNull);
13238 }
13239 }
13240
13241 void test_initializer_null() {
13242 String code = r'''
13243 main() {
13244 int v = null;
13245 return v; // marker
13246 }''';
13247 CompilationUnit unit;
13248 {
13249 Source source = addSource(code);
13250 LibraryElement library = resolve2(source);
13251 assertNoErrors(source);
13252 verify([source]);
13253 unit = resolveCompilationUnit(source, library);
13254 }
13255 {
13256 SimpleIdentifier identifier = EngineTestCase.findNode(
13257 unit, code, "v = null;", (node) => node is SimpleIdentifier);
13258 expect(identifier.staticType, same(typeProvider.intType));
13259 expect(identifier.propagatedType, same(null));
13260 }
13261 {
13262 SimpleIdentifier identifier = EngineTestCase.findNode(
13263 unit, code, "v; // marker", (node) => node is SimpleIdentifier);
13264 expect(identifier.staticType, same(typeProvider.intType));
13265 expect(identifier.propagatedType, same(null));
13266 }
13267 }
13268
13269 void test_is_conditional() {
13270 Source source = addSource(r'''
13271 class A {}
13272 A f(var p) {
13273 return (p is A) ? p : null;
13274 }''');
13275 LibraryElement library = resolve2(source);
13276 assertNoErrors(source);
13277 verify([source]);
13278 CompilationUnit unit = resolveCompilationUnit(source, library);
13279 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
13280 InterfaceType typeA = classA.element.type;
13281 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13282 BlockFunctionBody body =
13283 function.functionExpression.body as BlockFunctionBody;
13284 ReturnStatement statement = body.block.statements[0] as ReturnStatement;
13285 ConditionalExpression conditional =
13286 statement.expression as ConditionalExpression;
13287 SimpleIdentifier variableName =
13288 conditional.thenExpression as SimpleIdentifier;
13289 expect(variableName.propagatedType, same(typeA));
13290 }
13291
13292 void test_is_if() {
13293 Source source = addSource(r'''
13294 class A {}
13295 A f(var p) {
13296 if (p is A) {
13297 return p;
13298 } else {
13299 return null;
13300 }
13301 }''');
13302 LibraryElement library = resolve2(source);
13303 assertNoErrors(source);
13304 verify([source]);
13305 CompilationUnit unit = resolveCompilationUnit(source, library);
13306 // prepare A
13307 InterfaceType typeA;
13308 {
13309 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
13310 typeA = classA.element.type;
13311 }
13312 // verify "f"
13313 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13314 BlockFunctionBody body =
13315 function.functionExpression.body as BlockFunctionBody;
13316 IfStatement ifStatement = body.block.statements[0] as IfStatement;
13317 // "p is A"
13318 {
13319 IsExpression isExpression = ifStatement.condition;
13320 SimpleIdentifier variableName = isExpression.expression;
13321 expect(variableName.propagatedType, isNull);
13322 }
13323 // "return p;"
13324 {
13325 ReturnStatement statement =
13326 (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
13327 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13328 expect(variableName.propagatedType, same(typeA));
13329 }
13330 }
13331
13332 void test_is_if_lessSpecific() {
13333 Source source = addSource(r'''
13334 class A {}
13335 A f(A p) {
13336 if (p is String) {
13337 return p;
13338 } else {
13339 return null;
13340 }
13341 }''');
13342 LibraryElement library = resolve2(source);
13343 assertNoErrors(source);
13344 verify([source]);
13345 CompilationUnit unit = resolveCompilationUnit(source, library);
13346 // ClassDeclaration classA = (ClassDeclaration) unit.getDeclarations().get(0) ;
13347 // InterfaceType typeA = classA.getElement().getType();
13348 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13349 BlockFunctionBody body =
13350 function.functionExpression.body as BlockFunctionBody;
13351 IfStatement ifStatement = body.block.statements[0] as IfStatement;
13352 ReturnStatement statement =
13353 (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
13354 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13355 expect(variableName.propagatedType, same(null));
13356 }
13357
13358 void test_is_if_logicalAnd() {
13359 Source source = addSource(r'''
13360 class A {}
13361 A f(var p) {
13362 if (p is A && p != null) {
13363 return p;
13364 } else {
13365 return null;
13366 }
13367 }''');
13368 LibraryElement library = resolve2(source);
13369 assertNoErrors(source);
13370 verify([source]);
13371 CompilationUnit unit = resolveCompilationUnit(source, library);
13372 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
13373 InterfaceType typeA = classA.element.type;
13374 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13375 BlockFunctionBody body =
13376 function.functionExpression.body as BlockFunctionBody;
13377 IfStatement ifStatement = body.block.statements[0] as IfStatement;
13378 ReturnStatement statement =
13379 (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
13380 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13381 expect(variableName.propagatedType, same(typeA));
13382 }
13383
13384 void test_is_postConditional() {
13385 Source source = addSource(r'''
13386 class A {}
13387 A f(var p) {
13388 A a = (p is A) ? p : throw null;
13389 return p;
13390 }''');
13391 LibraryElement library = resolve2(source);
13392 assertNoErrors(source);
13393 verify([source]);
13394 CompilationUnit unit = resolveCompilationUnit(source, library);
13395 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
13396 InterfaceType typeA = classA.element.type;
13397 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13398 BlockFunctionBody body =
13399 function.functionExpression.body as BlockFunctionBody;
13400 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
13401 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13402 expect(variableName.propagatedType, same(typeA));
13403 }
13404
13405 void test_is_postIf() {
13406 Source source = addSource(r'''
13407 class A {}
13408 A f(var p) {
13409 if (p is A) {
13410 A a = p;
13411 } else {
13412 return null;
13413 }
13414 return p;
13415 }''');
13416 LibraryElement library = resolve2(source);
13417 assertNoErrors(source);
13418 verify([source]);
13419 CompilationUnit unit = resolveCompilationUnit(source, library);
13420 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
13421 InterfaceType typeA = classA.element.type;
13422 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13423 BlockFunctionBody body =
13424 function.functionExpression.body as BlockFunctionBody;
13425 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
13426 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13427 expect(variableName.propagatedType, same(typeA));
13428 }
13429
13430 void test_is_subclass() {
13431 Source source = addSource(r'''
13432 class A {}
13433 class B extends A {
13434 B m() => this;
13435 }
13436 A f(A p) {
13437 if (p is B) {
13438 return p.m();
13439 }
13440 return p;
13441 }''');
13442 LibraryElement library = resolve2(source);
13443 assertNoErrors(source);
13444 CompilationUnit unit = resolveCompilationUnit(source, library);
13445 FunctionDeclaration function = unit.declarations[2] as FunctionDeclaration;
13446 BlockFunctionBody body =
13447 function.functionExpression.body as BlockFunctionBody;
13448 IfStatement ifStatement = body.block.statements[0] as IfStatement;
13449 ReturnStatement statement =
13450 (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
13451 MethodInvocation invocation = statement.expression as MethodInvocation;
13452 expect(invocation.methodName.staticElement, isNotNull);
13453 expect(invocation.methodName.propagatedElement, isNull);
13454 }
13455
13456 void test_is_while() {
13457 Source source = addSource(r'''
13458 class A {}
13459 A f(var p) {
13460 while (p is A) {
13461 return p;
13462 }
13463 return p;
13464 }''');
13465 LibraryElement library = resolve2(source);
13466 assertNoErrors(source);
13467 verify([source]);
13468 CompilationUnit unit = resolveCompilationUnit(source, library);
13469 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
13470 InterfaceType typeA = classA.element.type;
13471 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13472 BlockFunctionBody body =
13473 function.functionExpression.body as BlockFunctionBody;
13474 WhileStatement whileStatement = body.block.statements[0] as WhileStatement;
13475 ReturnStatement statement =
13476 (whileStatement.body as Block).statements[0] as ReturnStatement;
13477 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13478 expect(variableName.propagatedType, same(typeA));
13479 }
13480
13481 void test_isNot_conditional() {
13482 Source source = addSource(r'''
13483 class A {}
13484 A f(var p) {
13485 return (p is! A) ? null : p;
13486 }''');
13487 LibraryElement library = resolve2(source);
13488 assertNoErrors(source);
13489 verify([source]);
13490 CompilationUnit unit = resolveCompilationUnit(source, library);
13491 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
13492 InterfaceType typeA = classA.element.type;
13493 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13494 BlockFunctionBody body =
13495 function.functionExpression.body as BlockFunctionBody;
13496 ReturnStatement statement = body.block.statements[0] as ReturnStatement;
13497 ConditionalExpression conditional =
13498 statement.expression as ConditionalExpression;
13499 SimpleIdentifier variableName =
13500 conditional.elseExpression as SimpleIdentifier;
13501 expect(variableName.propagatedType, same(typeA));
13502 }
13503
13504 void test_isNot_if() {
13505 Source source = addSource(r'''
13506 class A {}
13507 A f(var p) {
13508 if (p is! A) {
13509 return null;
13510 } else {
13511 return p;
13512 }
13513 }''');
13514 LibraryElement library = resolve2(source);
13515 assertNoErrors(source);
13516 verify([source]);
13517 CompilationUnit unit = resolveCompilationUnit(source, library);
13518 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
13519 InterfaceType typeA = classA.element.type;
13520 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13521 BlockFunctionBody body =
13522 function.functionExpression.body as BlockFunctionBody;
13523 IfStatement ifStatement = body.block.statements[0] as IfStatement;
13524 ReturnStatement statement =
13525 (ifStatement.elseStatement as Block).statements[0] as ReturnStatement;
13526 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13527 expect(variableName.propagatedType, same(typeA));
13528 }
13529
13530 void test_isNot_if_logicalOr() {
13531 Source source = addSource(r'''
13532 class A {}
13533 A f(var p) {
13534 if (p is! A || null == p) {
13535 return null;
13536 } else {
13537 return p;
13538 }
13539 }''');
13540 LibraryElement library = resolve2(source);
13541 assertNoErrors(source);
13542 CompilationUnit unit = resolveCompilationUnit(source, library);
13543 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
13544 InterfaceType typeA = classA.element.type;
13545 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13546 BlockFunctionBody body =
13547 function.functionExpression.body as BlockFunctionBody;
13548 IfStatement ifStatement = body.block.statements[0] as IfStatement;
13549 ReturnStatement statement =
13550 (ifStatement.elseStatement as Block).statements[0] as ReturnStatement;
13551 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13552 expect(variableName.propagatedType, same(typeA));
13553 }
13554
13555 void test_isNot_postConditional() {
13556 Source source = addSource(r'''
13557 class A {}
13558 A f(var p) {
13559 A a = (p is! A) ? throw null : p;
13560 return p;
13561 }''');
13562 LibraryElement library = resolve2(source);
13563 assertNoErrors(source);
13564 verify([source]);
13565 CompilationUnit unit = resolveCompilationUnit(source, library);
13566 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
13567 InterfaceType typeA = classA.element.type;
13568 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13569 BlockFunctionBody body =
13570 function.functionExpression.body as BlockFunctionBody;
13571 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
13572 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13573 expect(variableName.propagatedType, same(typeA));
13574 }
13575
13576 void test_isNot_postIf() {
13577 Source source = addSource(r'''
13578 class A {}
13579 A f(var p) {
13580 if (p is! A) {
13581 return null;
13582 }
13583 return p;
13584 }''');
13585 LibraryElement library = resolve2(source);
13586 assertNoErrors(source);
13587 verify([source]);
13588 CompilationUnit unit = resolveCompilationUnit(source, library);
13589 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
13590 InterfaceType typeA = classA.element.type;
13591 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13592 BlockFunctionBody body =
13593 function.functionExpression.body as BlockFunctionBody;
13594 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
13595 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13596 expect(variableName.propagatedType, same(typeA));
13597 }
13598
13599 void test_issue20904BuggyTypePromotionAtIfJoin_5() {
13600 // https://code.google.com/p/dart/issues/detail?id=20904
13601 //
13602 // This is not an example of the 20904 bug, but rather,
13603 // an example of something that one obvious fix changes inadvertently: we
13604 // want to avoid using type information from is-checks when it
13605 // loses precision. I can't see how to get a bad hint this way, since
13606 // it seems the propagated type is not used to generate hints when a
13607 // more precise type would cause no hint. For example, for code like the
13608 // following, when the propagated type of [x] is [A] -- as happens for the
13609 // fix these tests aim to warn against -- there is no warning for
13610
13611 // calling a method defined on [B] but not [A] (there aren't any, but
13612 // pretend), but there is for calling a method not defined on either.
13613 // By not overriding the propagated type via an is-check that loses
13614 // precision, we get more precise completion under an is-check. However,
13615 // I can only imagine strange code would make use of this feature.
13616 //
13617 // Here the is-check improves precision, so we use it.
13618 String code = r'''
13619 class A {}
13620 class B extends A {}
13621 f() {
13622 var a = new A();
13623 var b = new B();
13624 b; // B
13625 if (a is B) {
13626 return a; // marker
13627 }
13628 }''';
13629 DartType tB = _findMarkedIdentifier(code, "; // B").propagatedType;
13630 _assertTypeOfMarkedExpression(code, null, tB);
13631 }
13632
13633 void test_issue20904BuggyTypePromotionAtIfJoin_6() {
13634 // https://code.google.com/p/dart/issues/detail?id=20904
13635 //
13636 // The other half of the *_5() test.
13637 //
13638 // Here the is-check loses precision, so we don't use it.
13639 String code = r'''
13640 class A {}
13641 class B extends A {}
13642 f() {
13643 var b = new B();
13644 b; // B
13645 if (b is A) {
13646 return b; // marker
13647 }
13648 }''';
13649 DartType tB = _findMarkedIdentifier(code, "; // B").propagatedType;
13650 _assertTypeOfMarkedExpression(code, null, tB);
13651 }
13652
13653 void test_listLiteral_different() {
13654 Source source = addSource(r'''
13655 f() {
13656 var v = [0, '1', 2];
13657 return v[2];
13658 }''');
13659 LibraryElement library = resolve2(source);
13660 assertNoErrors(source);
13661 verify([source]);
13662 CompilationUnit unit = resolveCompilationUnit(source, library);
13663 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
13664 BlockFunctionBody body =
13665 function.functionExpression.body as BlockFunctionBody;
13666 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
13667 IndexExpression indexExpression = statement.expression as IndexExpression;
13668 expect(indexExpression.propagatedType, isNull);
13669 }
13670
13671 void test_listLiteral_same() {
13672 Source source = addSource(r'''
13673 f() {
13674 var v = [0, 1, 2];
13675 return v[2];
13676 }''');
13677 LibraryElement library = resolve2(source);
13678 assertNoErrors(source);
13679 verify([source]);
13680 CompilationUnit unit = resolveCompilationUnit(source, library);
13681 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
13682 BlockFunctionBody body =
13683 function.functionExpression.body as BlockFunctionBody;
13684 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
13685 IndexExpression indexExpression = statement.expression as IndexExpression;
13686 expect(indexExpression.propagatedType, isNull);
13687 Expression v = indexExpression.target;
13688 InterfaceType propagatedType = v.propagatedType as InterfaceType;
13689 expect(propagatedType.element, same(typeProvider.listType.element));
13690 List<DartType> typeArguments = propagatedType.typeArguments;
13691 expect(typeArguments, hasLength(1));
13692 expect(typeArguments[0], same(typeProvider.dynamicType));
13693 }
13694
13695 void test_mapLiteral_different() {
13696 Source source = addSource(r'''
13697 f() {
13698 var v = {'0' : 0, 1 : '1', '2' : 2};
13699 return v;
13700 }''');
13701 LibraryElement library = resolve2(source);
13702 assertNoErrors(source);
13703 verify([source]);
13704 CompilationUnit unit = resolveCompilationUnit(source, library);
13705 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
13706 BlockFunctionBody body =
13707 function.functionExpression.body as BlockFunctionBody;
13708 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
13709 SimpleIdentifier identifier = statement.expression as SimpleIdentifier;
13710 InterfaceType propagatedType = identifier.propagatedType as InterfaceType;
13711 expect(propagatedType.element, same(typeProvider.mapType.element));
13712 List<DartType> typeArguments = propagatedType.typeArguments;
13713 expect(typeArguments, hasLength(2));
13714 expect(typeArguments[0], same(typeProvider.dynamicType));
13715 expect(typeArguments[1], same(typeProvider.dynamicType));
13716 }
13717
13718 void test_mapLiteral_same() {
13719 Source source = addSource(r'''
13720 f() {
13721 var v = {'a' : 0, 'b' : 1, 'c' : 2};
13722 return v;
13723 }''');
13724 LibraryElement library = resolve2(source);
13725 assertNoErrors(source);
13726 verify([source]);
13727 CompilationUnit unit = resolveCompilationUnit(source, library);
13728 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
13729 BlockFunctionBody body =
13730 function.functionExpression.body as BlockFunctionBody;
13731 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
13732 SimpleIdentifier identifier = statement.expression as SimpleIdentifier;
13733 InterfaceType propagatedType = identifier.propagatedType as InterfaceType;
13734 expect(propagatedType.element, same(typeProvider.mapType.element));
13735 List<DartType> typeArguments = propagatedType.typeArguments;
13736 expect(typeArguments, hasLength(2));
13737 expect(typeArguments[0], same(typeProvider.dynamicType));
13738 expect(typeArguments[1], same(typeProvider.dynamicType));
13739 }
13740
13741 void test_mergePropagatedTypes_afterIfThen_different() {
13742 String code = r'''
13743 main() {
13744 var v = 0;
13745 if (v != null) {
13746 v = '';
13747 }
13748 return v;
13749 }''';
13750 {
13751 SimpleIdentifier identifier = _findMarkedIdentifier(code, "v;");
13752 expect(identifier.propagatedType, null);
13753 }
13754 {
13755 SimpleIdentifier identifier = _findMarkedIdentifier(code, "v = '';");
13756 expect(identifier.propagatedType, typeProvider.stringType);
13757 }
13758 }
13759
13760 void test_mergePropagatedTypes_afterIfThen_same() {
13761 _assertTypeOfMarkedExpression(
13762 r'''
13763 main() {
13764 var v = 1;
13765 if (v != null) {
13766 v = 2;
13767 }
13768 return v; // marker
13769 }''',
13770 null,
13771 typeProvider.intType);
13772 }
13773
13774 void test_mergePropagatedTypes_afterIfThenElse_different() {
13775 _assertTypeOfMarkedExpression(
13776 r'''
13777 main() {
13778 var v = 1;
13779 if (v != null) {
13780 v = 2;
13781 } else {
13782 v = '3';
13783 }
13784 return v; // marker
13785 }''',
13786 null,
13787 null);
13788 }
13789
13790 void test_mergePropagatedTypes_afterIfThenElse_same() {
13791 _assertTypeOfMarkedExpression(
13792 r'''
13793 main() {
13794 var v = 1;
13795 if (v != null) {
13796 v = 2;
13797 } else {
13798 v = 3;
13799 }
13800 return v; // marker
13801 }''',
13802 null,
13803 typeProvider.intType);
13804 }
13805
13806 void test_mergePropagatedTypesAtJoinPoint_4() {
13807 // https://code.google.com/p/dart/issues/detail?id=19929
13808 _assertTypeOfMarkedExpression(
13809 r'''
13810 f5(x) {
13811 var y = [];
13812 if (x) {
13813 y = 0;
13814 } else {
13815 return y;
13816 }
13817 // Propagated type is [int] here: correct.
13818 return y; // marker
13819 }''',
13820 null,
13821 typeProvider.intType);
13822 }
13823
13824 void test_mutatedOutsideScope() {
13825 // https://code.google.com/p/dart/issues/detail?id=22732
13826 Source source = addSource(r'''
13827 class Base {
13828 }
13829
13830 class Derived extends Base {
13831 get y => null;
13832 }
13833
13834 class C {
13835 void f() {
13836 Base x = null;
13837 if (x is Derived) {
13838 print(x.y); // BAD
13839 }
13840 x = null;
13841 }
13842 }
13843
13844 void g() {
13845 Base x = null;
13846 if (x is Derived) {
13847 print(x.y); // GOOD
13848 }
13849 x = null;
13850 }''');
13851 computeLibrarySourceErrors(source);
13852 assertNoErrors(source);
13853 }
13854
13855 void test_objectAccessInference_disabled_for_library_prefix() {
13856 String name = 'hashCode';
13857 addNamedSource(
13858 '/helper.dart',
13859 '''
13860 library helper;
13861 dynamic get $name => 42;
13862 ''');
13863 String code = '''
13864 import 'helper.dart' as helper;
13865 main() {
13866 helper.$name; // marker
13867 }''';
13868
13869 SimpleIdentifier id = _findMarkedIdentifier(code, "; // marker");
13870 PrefixedIdentifier prefixedId = id.parent;
13871 expect(id.staticType, typeProvider.dynamicType);
13872 expect(prefixedId.staticType, typeProvider.dynamicType);
13873 }
13874
13875 void test_objectAccessInference_disabled_for_local_getter() {
13876 String name = 'hashCode';
13877 String code = '''
13878 dynamic get $name => null;
13879 main() {
13880 $name; // marker
13881 }''';
13882
13883 SimpleIdentifier getter = _findMarkedIdentifier(code, "; // marker");
13884 expect(getter.staticType, typeProvider.dynamicType);
13885 }
13886
13887 void test_objectAccessInference_enabled_for_cascades() {
13888 String name = 'hashCode';
13889 String code = '''
13890 main() {
13891 dynamic obj;
13892 obj..$name..$name; // marker
13893 }''';
13894 PropertyAccess access = _findMarkedIdentifier(code, "; // marker").parent;
13895 expect(access.staticType, typeProvider.dynamicType);
13896 expect(access.realTarget.staticType, typeProvider.dynamicType);
13897 }
13898
13899 void test_objectMethodInference_disabled_for_library_prefix() {
13900 String name = 'toString';
13901 addNamedSource(
13902 '/helper.dart',
13903 '''
13904 library helper;
13905 dynamic $name = (int x) => x + 42');
13906 ''');
13907 String code = '''
13908 import 'helper.dart' as helper;
13909 main() {
13910 helper.$name(); // marker
13911 }''';
13912 SimpleIdentifier methodName = _findMarkedIdentifier(code, "(); // marker");
13913 MethodInvocation methodInvoke = methodName.parent;
13914 expect(methodName.staticType, null, reason: 'library prefix has no type');
13915 expect(methodInvoke.staticType, typeProvider.dynamicType);
13916 }
13917
13918 void test_objectMethodInference_disabled_for_local_function() {
13919 String name = 'toString';
13920 String code = '''
13921 main() {
13922 dynamic $name = () => null;
13923 $name(); // marker
13924 }''';
13925 SimpleIdentifier identifier = _findMarkedIdentifier(code, "$name = ");
13926 expect(identifier.staticType, typeProvider.dynamicType);
13927
13928 SimpleIdentifier methodName = _findMarkedIdentifier(code, "(); // marker");
13929 MethodInvocation methodInvoke = methodName.parent;
13930 expect(methodName.staticType, typeProvider.dynamicType);
13931 expect(methodInvoke.staticType, typeProvider.dynamicType);
13932 }
13933
13934 void test_objectMethodInference_enabled_for_cascades() {
13935 String name = 'toString';
13936 String code = '''
13937 main() {
13938 dynamic obj;
13939 obj..$name()..$name(); // marker
13940 }''';
13941 SimpleIdentifier methodName = _findMarkedIdentifier(code, "(); // marker");
13942 MethodInvocation methodInvoke = methodName.parent;
13943
13944 expect(methodInvoke.staticType, typeProvider.dynamicType);
13945 expect(methodInvoke.realTarget.staticType, typeProvider.dynamicType);
13946 }
13947
13948 void test_objectMethodOnDynamicExpression_doubleEquals() {
13949 // https://code.google.com/p/dart/issues/detail?id=20342
13950 //
13951 // This was not actually part of Issue 20342, since the spec specifies a
13952 // static type of [bool] for [==] comparison and the implementation
13953 // was already consistent with the spec there. But, it's another
13954 // [Object] method, so it's included here.
13955 _assertTypeOfMarkedExpression(
13956 r'''
13957 f1(x) {
13958 var v = (x == x);
13959 return v; // marker
13960 }''',
13961 null,
13962 typeProvider.boolType);
13963 }
13964
13965 void test_objectMethodOnDynamicExpression_hashCode() {
13966 // https://code.google.com/p/dart/issues/detail?id=20342
13967 _assertTypeOfMarkedExpression(
13968 r'''
13969 f1(x) {
13970 var v = x.hashCode;
13971 return v; // marker
13972 }''',
13973 null,
13974 typeProvider.intType);
13975 }
13976
13977 void test_objectMethodOnDynamicExpression_runtimeType() {
13978 // https://code.google.com/p/dart/issues/detail?id=20342
13979 _assertTypeOfMarkedExpression(
13980 r'''
13981 f1(x) {
13982 var v = x.runtimeType;
13983 return v; // marker
13984 }''',
13985 null,
13986 typeProvider.typeType);
13987 }
13988
13989 void test_objectMethodOnDynamicExpression_toString() {
13990 // https://code.google.com/p/dart/issues/detail?id=20342
13991 _assertTypeOfMarkedExpression(
13992 r'''
13993 f1(x) {
13994 var v = x.toString();
13995 return v; // marker
13996 }''',
13997 null,
13998 typeProvider.stringType);
13999 }
14000
14001 void test_propagatedReturnType_localFunction() {
14002 String code = r'''
14003 main() {
14004 f() => 42;
14005 var v = f();
14006 }''';
14007 _assertPropagatedAssignedType(
14008 code, typeProvider.dynamicType, typeProvider.intType);
14009 }
14010
14011 void test_query() {
14012 Source source = addSource(r'''
14013 import 'dart:html';
14014
14015 main() {
14016 var v1 = query('a');
14017 var v2 = query('A');
14018 var v3 = query('body:active');
14019 var v4 = query('button[foo="bar"]');
14020 var v5 = query('div.class');
14021 var v6 = query('input#id');
14022 var v7 = query('select#id');
14023 // invocation of method
14024 var m1 = document.query('div');
14025 // unsupported currently
14026 var b1 = query('noSuchTag');
14027 var b2 = query('DART_EDITOR_NO_SUCH_TYPE');
14028 var b3 = query('body div');
14029 return [v1, v2, v3, v4, v5, v6, v7, m1, b1, b2, b3];
14030 }''');
14031 LibraryElement library = resolve2(source);
14032 assertNoErrors(source);
14033 verify([source]);
14034 CompilationUnit unit = resolveCompilationUnit(source, library);
14035 FunctionDeclaration main = unit.declarations[0] as FunctionDeclaration;
14036 BlockFunctionBody body = main.functionExpression.body as BlockFunctionBody;
14037 ReturnStatement statement = body.block.statements[11] as ReturnStatement;
14038 NodeList<Expression> elements =
14039 (statement.expression as ListLiteral).elements;
14040 expect(elements[0].propagatedType.name, "AnchorElement");
14041 expect(elements[1].propagatedType.name, "AnchorElement");
14042 expect(elements[2].propagatedType.name, "BodyElement");
14043 expect(elements[3].propagatedType.name, "ButtonElement");
14044 expect(elements[4].propagatedType.name, "DivElement");
14045 expect(elements[5].propagatedType.name, "InputElement");
14046 expect(elements[6].propagatedType.name, "SelectElement");
14047 expect(elements[7].propagatedType.name, "DivElement");
14048 expect(elements[8].propagatedType.name, "Element");
14049 expect(elements[9].propagatedType.name, "Element");
14050 expect(elements[10].propagatedType.name, "Element");
14051 }
14052 }
14053
14054 @reflectiveTest
14055 class TypeProviderImplTest extends EngineTestCase {
14056 void test_creation() {
14057 //
14058 // Create a mock library element with the types expected to be in dart:core.
14059 // We cannot use either ElementFactory or TestTypeProvider (which uses
14060 // ElementFactory) because we side-effect the elements in ways that would
14061 // break other tests.
14062 //
14063 InterfaceType objectType = _classElement("Object", null).type;
14064 InterfaceType boolType = _classElement("bool", objectType).type;
14065 InterfaceType numType = _classElement("num", objectType).type;
14066 InterfaceType doubleType = _classElement("double", numType).type;
14067 InterfaceType functionType = _classElement("Function", objectType).type;
14068 InterfaceType futureType = _classElement("Future", objectType, ["T"]).type;
14069 InterfaceType intType = _classElement("int", numType).type;
14070 InterfaceType iterableType =
14071 _classElement("Iterable", objectType, ["T"]).type;
14072 InterfaceType listType = _classElement("List", objectType, ["E"]).type;
14073 InterfaceType mapType = _classElement("Map", objectType, ["K", "V"]).type;
14074 InterfaceType stackTraceType = _classElement("StackTrace", objectType).type;
14075 InterfaceType streamType = _classElement("Stream", objectType, ["T"]).type;
14076 InterfaceType stringType = _classElement("String", objectType).type;
14077 InterfaceType symbolType = _classElement("Symbol", objectType).type;
14078 InterfaceType typeType = _classElement("Type", objectType).type;
14079 CompilationUnitElementImpl coreUnit =
14080 new CompilationUnitElementImpl("core.dart");
14081 coreUnit.types = <ClassElement>[
14082 boolType.element,
14083 doubleType.element,
14084 functionType.element,
14085 intType.element,
14086 iterableType.element,
14087 listType.element,
14088 mapType.element,
14089 objectType.element,
14090 stackTraceType.element,
14091 stringType.element,
14092 symbolType.element,
14093 typeType.element
14094 ];
14095 CompilationUnitElementImpl asyncUnit =
14096 new CompilationUnitElementImpl("async.dart");
14097 asyncUnit.types = <ClassElement>[futureType.element, streamType.element];
14098 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
14099 LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
14100 context, AstFactory.libraryIdentifier2(["dart.core"]));
14101 coreLibrary.definingCompilationUnit = coreUnit;
14102 LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
14103 context, AstFactory.libraryIdentifier2(["dart.async"]));
14104 asyncLibrary.definingCompilationUnit = asyncUnit;
14105 //
14106 // Create a type provider and ensure that it can return the expected types.
14107 //
14108 TypeProviderImpl provider = new TypeProviderImpl(coreLibrary, asyncLibrary);
14109 expect(provider.boolType, same(boolType));
14110 expect(provider.bottomType, isNotNull);
14111 expect(provider.doubleType, same(doubleType));
14112 expect(provider.dynamicType, isNotNull);
14113 expect(provider.functionType, same(functionType));
14114 expect(provider.futureType, same(futureType));
14115 expect(provider.intType, same(intType));
14116 expect(provider.listType, same(listType));
14117 expect(provider.mapType, same(mapType));
14118 expect(provider.objectType, same(objectType));
14119 expect(provider.stackTraceType, same(stackTraceType));
14120 expect(provider.stringType, same(stringType));
14121 expect(provider.symbolType, same(symbolType));
14122 expect(provider.typeType, same(typeType));
14123 }
14124
14125 ClassElement _classElement(String typeName, InterfaceType superclassType,
14126 [List<String> parameterNames]) {
14127 ClassElementImpl element =
14128 new ClassElementImpl.forNode(AstFactory.identifier3(typeName));
14129 element.supertype = superclassType;
14130 InterfaceTypeImpl type = new InterfaceTypeImpl(element);
14131 element.type = type;
14132 if (parameterNames != null) {
14133 int count = parameterNames.length;
14134 if (count > 0) {
14135 List<TypeParameterElementImpl> typeParameters =
14136 new List<TypeParameterElementImpl>(count);
14137 List<TypeParameterTypeImpl> typeArguments =
14138 new List<TypeParameterTypeImpl>(count);
14139 for (int i = 0; i < count; i++) {
14140 TypeParameterElementImpl typeParameter =
14141 new TypeParameterElementImpl.forNode(
14142 AstFactory.identifier3(parameterNames[i]));
14143 typeParameters[i] = typeParameter;
14144 typeArguments[i] = new TypeParameterTypeImpl(typeParameter);
14145 typeParameter.type = typeArguments[i];
14146 }
14147 element.typeParameters = typeParameters;
14148 type.typeArguments = typeArguments;
14149 }
14150 }
14151 return element;
14152 }
14153 }
14154
14155 @reflectiveTest
14156 class TypeResolverVisitorTest extends EngineTestCase {
14157 /**
14158 * The error listener to which errors will be reported.
14159 */
14160 GatheringErrorListener _listener;
14161
14162 /**
14163 * The object representing the information about the library in which the type s are being
14164 * resolved.
14165 */
14166 Library _library;
14167
14168 /**
14169 * The type provider used to access the types.
14170 */
14171 TestTypeProvider _typeProvider;
14172
14173 /**
14174 * The visitor used to resolve types needed to form the type hierarchy.
14175 */
14176 TypeResolverVisitor _visitor;
14177
14178 void fail_visitConstructorDeclaration() {
14179 fail("Not yet tested");
14180 _listener.assertNoErrors();
14181 }
14182
14183 void fail_visitFunctionTypeAlias() {
14184 fail("Not yet tested");
14185 _listener.assertNoErrors();
14186 }
14187
14188 void fail_visitVariableDeclaration() {
14189 fail("Not yet tested");
14190 ClassElement type = ElementFactory.classElement2("A");
14191 VariableDeclaration node = AstFactory.variableDeclaration("a");
14192 AstFactory.variableDeclarationList(null, AstFactory.typeName(type), [node]);
14193 //resolve(node);
14194 expect(node.name.staticType, same(type.type));
14195 _listener.assertNoErrors();
14196 }
14197
14198 @override
14199 void setUp() {
14200 _listener = new GatheringErrorListener();
14201 InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
14202 Source librarySource =
14203 new FileBasedSource(FileUtilities2.createFile("/lib.dart"));
14204 _library = new Library(context, _listener, librarySource);
14205 LibraryElementImpl element = new LibraryElementImpl.forNode(
14206 context, AstFactory.libraryIdentifier2(["lib"]));
14207 element.definingCompilationUnit =
14208 new CompilationUnitElementImpl("lib.dart");
14209 _library.libraryElement = element;
14210 _typeProvider = new TestTypeProvider();
14211 _visitor = new TypeResolverVisitor(_library.libraryElement, librarySource,
14212 _typeProvider, _library.errorListener,
14213 nameScope: _library.libraryScope);
14214 }
14215
14216 void test_visitCatchClause_exception() {
14217 // catch (e)
14218 CatchClause clause = AstFactory.catchClause("e");
14219 SimpleIdentifier exceptionParameter = clause.exceptionParameter;
14220 exceptionParameter.staticElement =
14221 new LocalVariableElementImpl.forNode(exceptionParameter);
14222 _resolveCatchClause(clause, _typeProvider.dynamicType, null);
14223 _listener.assertNoErrors();
14224 }
14225
14226 void test_visitCatchClause_exception_stackTrace() {
14227 // catch (e, s)
14228 CatchClause clause = AstFactory.catchClause2("e", "s");
14229 SimpleIdentifier exceptionParameter = clause.exceptionParameter;
14230 exceptionParameter.staticElement =
14231 new LocalVariableElementImpl.forNode(exceptionParameter);
14232 SimpleIdentifier stackTraceParameter = clause.stackTraceParameter;
14233 stackTraceParameter.staticElement =
14234 new LocalVariableElementImpl.forNode(stackTraceParameter);
14235 _resolveCatchClause(
14236 clause, _typeProvider.dynamicType, _typeProvider.stackTraceType);
14237 _listener.assertNoErrors();
14238 }
14239
14240 void test_visitCatchClause_on_exception() {
14241 // on E catch (e)
14242 ClassElement exceptionElement = ElementFactory.classElement2("E");
14243 TypeName exceptionType = AstFactory.typeName(exceptionElement);
14244 CatchClause clause = AstFactory.catchClause4(exceptionType, "e");
14245 SimpleIdentifier exceptionParameter = clause.exceptionParameter;
14246 exceptionParameter.staticElement =
14247 new LocalVariableElementImpl.forNode(exceptionParameter);
14248 _resolveCatchClause(
14249 clause, exceptionElement.type, null, [exceptionElement]);
14250 _listener.assertNoErrors();
14251 }
14252
14253 void test_visitCatchClause_on_exception_stackTrace() {
14254 // on E catch (e, s)
14255 ClassElement exceptionElement = ElementFactory.classElement2("E");
14256 TypeName exceptionType = AstFactory.typeName(exceptionElement);
14257 (exceptionType.name as SimpleIdentifier).staticElement = exceptionElement;
14258 CatchClause clause = AstFactory.catchClause5(exceptionType, "e", "s");
14259 SimpleIdentifier exceptionParameter = clause.exceptionParameter;
14260 exceptionParameter.staticElement =
14261 new LocalVariableElementImpl.forNode(exceptionParameter);
14262 SimpleIdentifier stackTraceParameter = clause.stackTraceParameter;
14263 stackTraceParameter.staticElement =
14264 new LocalVariableElementImpl.forNode(stackTraceParameter);
14265 _resolveCatchClause(clause, exceptionElement.type,
14266 _typeProvider.stackTraceType, [exceptionElement]);
14267 _listener.assertNoErrors();
14268 }
14269
14270 void test_visitClassDeclaration() {
14271 // class A extends B with C implements D {}
14272 // class B {}
14273 // class C {}
14274 // class D {}
14275 ClassElement elementA = ElementFactory.classElement2("A");
14276 ClassElement elementB = ElementFactory.classElement2("B");
14277 ClassElement elementC = ElementFactory.classElement2("C");
14278 ClassElement elementD = ElementFactory.classElement2("D");
14279 ExtendsClause extendsClause =
14280 AstFactory.extendsClause(AstFactory.typeName(elementB));
14281 WithClause withClause =
14282 AstFactory.withClause([AstFactory.typeName(elementC)]);
14283 ImplementsClause implementsClause =
14284 AstFactory.implementsClause([AstFactory.typeName(elementD)]);
14285 ClassDeclaration declaration = AstFactory.classDeclaration(
14286 null, "A", null, extendsClause, withClause, implementsClause);
14287 declaration.name.staticElement = elementA;
14288 _resolveNode(declaration, [elementA, elementB, elementC, elementD]);
14289 expect(elementA.supertype, same(elementB.type));
14290 List<InterfaceType> mixins = elementA.mixins;
14291 expect(mixins, hasLength(1));
14292 expect(mixins[0], same(elementC.type));
14293 List<InterfaceType> interfaces = elementA.interfaces;
14294 expect(interfaces, hasLength(1));
14295 expect(interfaces[0], same(elementD.type));
14296 _listener.assertNoErrors();
14297 }
14298
14299 void test_visitClassDeclaration_instanceMemberCollidesWithClass() {
14300 // class A {}
14301 // class B extends A {
14302 // void A() {}
14303 // }
14304 ClassElementImpl elementA = ElementFactory.classElement2("A");
14305 ClassElementImpl elementB = ElementFactory.classElement2("B");
14306 elementB.methods = <MethodElement>[
14307 ElementFactory.methodElement("A", VoidTypeImpl.instance)
14308 ];
14309 ExtendsClause extendsClause =
14310 AstFactory.extendsClause(AstFactory.typeName(elementA));
14311 ClassDeclaration declaration =
14312 AstFactory.classDeclaration(null, "B", null, extendsClause, null, null);
14313 declaration.name.staticElement = elementB;
14314 _resolveNode(declaration, [elementA, elementB]);
14315 expect(elementB.supertype, same(elementA.type));
14316 _listener.assertNoErrors();
14317 }
14318
14319 void test_visitClassTypeAlias() {
14320 // class A = B with C implements D;
14321 ClassElement elementA = ElementFactory.classElement2("A");
14322 ClassElement elementB = ElementFactory.classElement2("B");
14323 ClassElement elementC = ElementFactory.classElement2("C");
14324 ClassElement elementD = ElementFactory.classElement2("D");
14325 WithClause withClause =
14326 AstFactory.withClause([AstFactory.typeName(elementC)]);
14327 ImplementsClause implementsClause =
14328 AstFactory.implementsClause([AstFactory.typeName(elementD)]);
14329 ClassTypeAlias alias = AstFactory.classTypeAlias("A", null, null,
14330 AstFactory.typeName(elementB), withClause, implementsClause);
14331 alias.name.staticElement = elementA;
14332 _resolveNode(alias, [elementA, elementB, elementC, elementD]);
14333 expect(elementA.supertype, same(elementB.type));
14334 List<InterfaceType> mixins = elementA.mixins;
14335 expect(mixins, hasLength(1));
14336 expect(mixins[0], same(elementC.type));
14337 List<InterfaceType> interfaces = elementA.interfaces;
14338 expect(interfaces, hasLength(1));
14339 expect(interfaces[0], same(elementD.type));
14340 _listener.assertNoErrors();
14341 }
14342
14343 void test_visitClassTypeAlias_constructorWithOptionalParams_ignored() {
14344 // class T {}
14345 // class B {
14346 // B.c1();
14347 // B.c2([T a0]);
14348 // B.c3({T a0});
14349 // }
14350 // class M {}
14351 // class C = B with M
14352 ClassElement classT = ElementFactory.classElement2('T', []);
14353 ClassElementImpl classB = ElementFactory.classElement2('B', []);
14354 ConstructorElementImpl constructorBc1 =
14355 ElementFactory.constructorElement2(classB, 'c1', []);
14356 ConstructorElementImpl constructorBc2 =
14357 ElementFactory.constructorElement2(classB, 'c2', [classT.type]);
14358 (constructorBc2.parameters[0] as ParameterElementImpl).parameterKind =
14359 ParameterKind.POSITIONAL;
14360 ConstructorElementImpl constructorBc3 =
14361 ElementFactory.constructorElement2(classB, 'c3', [classT.type]);
14362 (constructorBc3.parameters[0] as ParameterElementImpl).parameterKind =
14363 ParameterKind.NAMED;
14364 classB.constructors = [constructorBc1, constructorBc2, constructorBc3];
14365 ClassElement classM = ElementFactory.classElement2('M', []);
14366 WithClause withClause =
14367 AstFactory.withClause([AstFactory.typeName(classM, [])]);
14368 ClassElement classC = ElementFactory.classTypeAlias2('C', []);
14369 ClassTypeAlias alias = AstFactory.classTypeAlias(
14370 'C', null, null, AstFactory.typeName(classB, []), withClause, null);
14371 alias.name.staticElement = classC;
14372 _resolveNode(alias, [classT, classB, classM, classC]);
14373 expect(classC.constructors, hasLength(1));
14374 ConstructorElement constructor = classC.constructors[0];
14375 expect(constructor.isFactory, isFalse);
14376 expect(constructor.isSynthetic, isTrue);
14377 expect(constructor.name, 'c1');
14378 expect(constructor.functions, hasLength(0));
14379 expect(constructor.labels, hasLength(0));
14380 expect(constructor.localVariables, hasLength(0));
14381 expect(constructor.parameters, isEmpty);
14382 }
14383
14384 void test_visitClassTypeAlias_constructorWithParams() {
14385 // class T {}
14386 // class B {
14387 // B(T a0);
14388 // }
14389 // class M {}
14390 // class C = B with M
14391 ClassElement classT = ElementFactory.classElement2('T', []);
14392 ClassElementImpl classB = ElementFactory.classElement2('B', []);
14393 ConstructorElementImpl constructorB =
14394 ElementFactory.constructorElement2(classB, '', [classT.type]);
14395 classB.constructors = [constructorB];
14396 ClassElement classM = ElementFactory.classElement2('M', []);
14397 WithClause withClause =
14398 AstFactory.withClause([AstFactory.typeName(classM, [])]);
14399 ClassElement classC = ElementFactory.classTypeAlias2('C', []);
14400 ClassTypeAlias alias = AstFactory.classTypeAlias(
14401 'C', null, null, AstFactory.typeName(classB, []), withClause, null);
14402 alias.name.staticElement = classC;
14403 _resolveNode(alias, [classT, classB, classM, classC]);
14404 expect(classC.constructors, hasLength(1));
14405 ConstructorElement constructor = classC.constructors[0];
14406 expect(constructor.isFactory, isFalse);
14407 expect(constructor.isSynthetic, isTrue);
14408 expect(constructor.name, '');
14409 expect(constructor.functions, hasLength(0));
14410 expect(constructor.labels, hasLength(0));
14411 expect(constructor.localVariables, hasLength(0));
14412 expect(constructor.parameters, hasLength(1));
14413 expect(constructor.parameters[0].type, equals(classT.type));
14414 expect(constructor.parameters[0].name,
14415 equals(constructorB.parameters[0].name));
14416 }
14417
14418 void test_visitClassTypeAlias_defaultConstructor() {
14419 // class B {}
14420 // class M {}
14421 // class C = B with M
14422 ClassElementImpl classB = ElementFactory.classElement2('B', []);
14423 ConstructorElementImpl constructorB =
14424 ElementFactory.constructorElement2(classB, '', []);
14425 constructorB.setModifier(Modifier.SYNTHETIC, true);
14426 classB.constructors = [constructorB];
14427 ClassElement classM = ElementFactory.classElement2('M', []);
14428 WithClause withClause =
14429 AstFactory.withClause([AstFactory.typeName(classM, [])]);
14430 ClassElement classC = ElementFactory.classTypeAlias2('C', []);
14431 ClassTypeAlias alias = AstFactory.classTypeAlias(
14432 'C', null, null, AstFactory.typeName(classB, []), withClause, null);
14433 alias.name.staticElement = classC;
14434 _resolveNode(alias, [classB, classM, classC]);
14435 expect(classC.constructors, hasLength(1));
14436 ConstructorElement constructor = classC.constructors[0];
14437 expect(constructor.isFactory, isFalse);
14438 expect(constructor.isSynthetic, isTrue);
14439 expect(constructor.name, '');
14440 expect(constructor.functions, hasLength(0));
14441 expect(constructor.labels, hasLength(0));
14442 expect(constructor.localVariables, hasLength(0));
14443 expect(constructor.parameters, isEmpty);
14444 }
14445
14446 void test_visitFieldFormalParameter_functionType() {
14447 InterfaceType intType = _typeProvider.intType;
14448 TypeName intTypeName = AstFactory.typeName4("int");
14449 String innerParameterName = "a";
14450 SimpleFormalParameter parameter =
14451 AstFactory.simpleFormalParameter3(innerParameterName);
14452 parameter.identifier.staticElement =
14453 ElementFactory.requiredParameter(innerParameterName);
14454 String outerParameterName = "p";
14455 FormalParameter node = AstFactory.fieldFormalParameter(null, intTypeName,
14456 outerParameterName, AstFactory.formalParameterList([parameter]));
14457 node.identifier.staticElement =
14458 ElementFactory.requiredParameter(outerParameterName);
14459 DartType parameterType = _resolveFormalParameter(node, [intType.element]);
14460 EngineTestCase.assertInstanceOf(
14461 (obj) => obj is FunctionType, FunctionType, parameterType);
14462 FunctionType functionType = parameterType as FunctionType;
14463 expect(functionType.returnType, same(intType));
14464 expect(functionType.parameters, hasLength(1));
14465 _listener.assertNoErrors();
14466 }
14467
14468 void test_visitFieldFormalParameter_noType() {
14469 String parameterName = "p";
14470 FormalParameter node =
14471 AstFactory.fieldFormalParameter(Keyword.VAR, null, parameterName);
14472 node.identifier.staticElement =
14473 ElementFactory.requiredParameter(parameterName);
14474 expect(_resolveFormalParameter(node), same(_typeProvider.dynamicType));
14475 _listener.assertNoErrors();
14476 }
14477
14478 void test_visitFieldFormalParameter_type() {
14479 InterfaceType intType = _typeProvider.intType;
14480 TypeName intTypeName = AstFactory.typeName4("int");
14481 String parameterName = "p";
14482 FormalParameter node =
14483 AstFactory.fieldFormalParameter(null, intTypeName, parameterName);
14484 node.identifier.staticElement =
14485 ElementFactory.requiredParameter(parameterName);
14486 expect(_resolveFormalParameter(node, [intType.element]), same(intType));
14487 _listener.assertNoErrors();
14488 }
14489
14490 void test_visitFunctionDeclaration() {
14491 // R f(P p) {}
14492 // class R {}
14493 // class P {}
14494 ClassElement elementR = ElementFactory.classElement2('R');
14495 ClassElement elementP = ElementFactory.classElement2('P');
14496 FunctionElement elementF = ElementFactory.functionElement('f');
14497 FunctionDeclaration declaration = AstFactory.functionDeclaration(
14498 AstFactory.typeName4('R'),
14499 null,
14500 'f',
14501 AstFactory.functionExpression2(
14502 AstFactory.formalParameterList([
14503 AstFactory.simpleFormalParameter4(AstFactory.typeName4('P'), 'p')
14504 ]),
14505 null));
14506 declaration.name.staticElement = elementF;
14507 _resolveNode(declaration, [elementR, elementP]);
14508 expect(declaration.returnType.type, elementR.type);
14509 SimpleFormalParameter parameter =
14510 declaration.functionExpression.parameters.parameters[0];
14511 expect(parameter.type.type, elementP.type);
14512 _listener.assertNoErrors();
14513 }
14514
14515 void test_visitFunctionDeclaration_typeParameter() {
14516 // E f<E>(E e) {}
14517 TypeParameterElement elementE = ElementFactory.typeParameterElement('E');
14518 FunctionElementImpl elementF = ElementFactory.functionElement('f');
14519 elementF.typeParameters = <TypeParameterElement>[elementE];
14520 FunctionDeclaration declaration = AstFactory.functionDeclaration(
14521 AstFactory.typeName4('E'),
14522 null,
14523 'f',
14524 AstFactory.functionExpression2(
14525 AstFactory.formalParameterList([
14526 AstFactory.simpleFormalParameter4(AstFactory.typeName4('E'), 'e')
14527 ]),
14528 null));
14529 declaration.name.staticElement = elementF;
14530 _resolveNode(declaration, []);
14531 expect(declaration.returnType.type, elementE.type);
14532 SimpleFormalParameter parameter =
14533 declaration.functionExpression.parameters.parameters[0];
14534 expect(parameter.type.type, elementE.type);
14535 _listener.assertNoErrors();
14536 }
14537
14538 void test_visitFunctionTypedFormalParameter() {
14539 // R f(R g(P p)) {}
14540 // class R {}
14541 // class P {}
14542 ClassElement elementR = ElementFactory.classElement2('R');
14543 ClassElement elementP = ElementFactory.classElement2('P');
14544 FunctionElement elementF = ElementFactory.functionElement('f');
14545 ParameterElementImpl requiredParameter =
14546 ElementFactory.requiredParameter('p');
14547 FunctionTypedFormalParameter parameterDeclaration = AstFactory
14548 .functionTypedFormalParameter(AstFactory.typeName4('R'), 'g', [
14549 AstFactory.simpleFormalParameter4(AstFactory.typeName4('P'), 'p')
14550 ]);
14551 parameterDeclaration.identifier.staticElement = requiredParameter;
14552 FunctionDeclaration declaration = AstFactory.functionDeclaration(
14553 AstFactory.typeName4('R'),
14554 null,
14555 'f',
14556 AstFactory.functionExpression2(
14557 AstFactory.formalParameterList([parameterDeclaration]), null));
14558 declaration.name.staticElement = elementF;
14559 _resolveNode(declaration, [elementR, elementP]);
14560 expect(declaration.returnType.type, elementR.type);
14561 FunctionTypedFormalParameter parameter =
14562 declaration.functionExpression.parameters.parameters[0];
14563 expect(parameter.returnType.type, elementR.type);
14564 SimpleFormalParameter innerParameter = parameter.parameters.parameters[0];
14565 expect(innerParameter.type.type, elementP.type);
14566 _listener.assertNoErrors();
14567 }
14568
14569 void test_visitFunctionTypedFormalParameter_typeParameter() {
14570 // R f(R g<E>(E e)) {}
14571 // class R {}
14572 ClassElement elementR = ElementFactory.classElement2('R');
14573 TypeParameterElement elementE = ElementFactory.typeParameterElement('E');
14574 FunctionElement elementF = ElementFactory.functionElement('f');
14575 ParameterElementImpl requiredParameter =
14576 ElementFactory.requiredParameter('g');
14577 requiredParameter.typeParameters = <TypeParameterElement>[elementE];
14578 FunctionTypedFormalParameter parameterDeclaration = AstFactory
14579 .functionTypedFormalParameter(AstFactory.typeName4('R'), 'g', [
14580 AstFactory.simpleFormalParameter4(AstFactory.typeName4('E'), 'e')
14581 ]);
14582 parameterDeclaration.identifier.staticElement = requiredParameter;
14583 FunctionDeclaration declaration = AstFactory.functionDeclaration(
14584 AstFactory.typeName4('R'),
14585 null,
14586 'f',
14587 AstFactory.functionExpression2(
14588 AstFactory.formalParameterList([parameterDeclaration]), null));
14589 declaration.name.staticElement = elementF;
14590 _resolveNode(declaration, [elementR]);
14591 expect(declaration.returnType.type, elementR.type);
14592 FunctionTypedFormalParameter parameter =
14593 declaration.functionExpression.parameters.parameters[0];
14594 expect(parameter.returnType.type, elementR.type);
14595 SimpleFormalParameter innerParameter = parameter.parameters.parameters[0];
14596 expect(innerParameter.type.type, elementE.type);
14597 _listener.assertNoErrors();
14598 }
14599
14600 void test_visitMethodDeclaration() {
14601 // class A {
14602 // R m(P p) {}
14603 // }
14604 // class R {}
14605 // class P {}
14606 ClassElementImpl elementA = ElementFactory.classElement2('A');
14607 ClassElement elementR = ElementFactory.classElement2('R');
14608 ClassElement elementP = ElementFactory.classElement2('P');
14609 MethodElement elementM = ElementFactory.methodElement('m', null);
14610 elementA.methods = <MethodElement>[elementM];
14611 MethodDeclaration declaration = AstFactory.methodDeclaration(
14612 null,
14613 AstFactory.typeName4('R'),
14614 null,
14615 null,
14616 AstFactory.identifier3('m'),
14617 AstFactory.formalParameterList([
14618 AstFactory.simpleFormalParameter4(AstFactory.typeName4('P'), 'p')
14619 ]));
14620 declaration.name.staticElement = elementM;
14621 _resolveNode(declaration, [elementA, elementR, elementP]);
14622 expect(declaration.returnType.type, elementR.type);
14623 SimpleFormalParameter parameter = declaration.parameters.parameters[0];
14624 expect(parameter.type.type, elementP.type);
14625 _listener.assertNoErrors();
14626 }
14627
14628 void test_visitMethodDeclaration_typeParameter() {
14629 // class A {
14630 // E m<E>(E e) {}
14631 // }
14632 ClassElementImpl elementA = ElementFactory.classElement2('A');
14633 TypeParameterElement elementE = ElementFactory.typeParameterElement('E');
14634 MethodElementImpl elementM = ElementFactory.methodElement('m', null);
14635 elementM.typeParameters = <TypeParameterElement>[elementE];
14636 elementA.methods = <MethodElement>[elementM];
14637 MethodDeclaration declaration = AstFactory.methodDeclaration(
14638 null,
14639 AstFactory.typeName4('E'),
14640 null,
14641 null,
14642 AstFactory.identifier3('m'),
14643 AstFactory.formalParameterList([
14644 AstFactory.simpleFormalParameter4(AstFactory.typeName4('E'), 'e')
14645 ]));
14646 declaration.name.staticElement = elementM;
14647 _resolveNode(declaration, [elementA]);
14648 expect(declaration.returnType.type, elementE.type);
14649 SimpleFormalParameter parameter = declaration.parameters.parameters[0];
14650 expect(parameter.type.type, elementE.type);
14651 _listener.assertNoErrors();
14652 }
14653
14654 void test_visitSimpleFormalParameter_noType() {
14655 // p
14656 FormalParameter node = AstFactory.simpleFormalParameter3("p");
14657 node.identifier.staticElement =
14658 new ParameterElementImpl.forNode(AstFactory.identifier3("p"));
14659 expect(_resolveFormalParameter(node), same(_typeProvider.dynamicType));
14660 _listener.assertNoErrors();
14661 }
14662
14663 void test_visitSimpleFormalParameter_type() {
14664 // int p
14665 InterfaceType intType = _typeProvider.intType;
14666 ClassElement intElement = intType.element;
14667 FormalParameter node =
14668 AstFactory.simpleFormalParameter4(AstFactory.typeName(intElement), "p");
14669 SimpleIdentifier identifier = node.identifier;
14670 ParameterElementImpl element = new ParameterElementImpl.forNode(identifier);
14671 identifier.staticElement = element;
14672 expect(_resolveFormalParameter(node, [intElement]), same(intType));
14673 _listener.assertNoErrors();
14674 }
14675
14676 void test_visitTypeName_noParameters_noArguments() {
14677 ClassElement classA = ElementFactory.classElement2("A");
14678 TypeName typeName = AstFactory.typeName(classA);
14679 typeName.type = null;
14680 _resolveNode(typeName, [classA]);
14681 expect(typeName.type, same(classA.type));
14682 _listener.assertNoErrors();
14683 }
14684
14685 void test_visitTypeName_parameters_arguments() {
14686 ClassElement classA = ElementFactory.classElement2("A", ["E"]);
14687 ClassElement classB = ElementFactory.classElement2("B");
14688 TypeName typeName =
14689 AstFactory.typeName(classA, [AstFactory.typeName(classB)]);
14690 typeName.type = null;
14691 _resolveNode(typeName, [classA, classB]);
14692 InterfaceType resultType = typeName.type as InterfaceType;
14693 expect(resultType.element, same(classA));
14694 List<DartType> resultArguments = resultType.typeArguments;
14695 expect(resultArguments, hasLength(1));
14696 expect(resultArguments[0], same(classB.type));
14697 _listener.assertNoErrors();
14698 }
14699
14700 void test_visitTypeName_parameters_noArguments() {
14701 ClassElement classA = ElementFactory.classElement2("A", ["E"]);
14702 TypeName typeName = AstFactory.typeName(classA);
14703 typeName.type = null;
14704 _resolveNode(typeName, [classA]);
14705 InterfaceType resultType = typeName.type as InterfaceType;
14706 expect(resultType.element, same(classA));
14707 List<DartType> resultArguments = resultType.typeArguments;
14708 expect(resultArguments, hasLength(1));
14709 expect(resultArguments[0], same(DynamicTypeImpl.instance));
14710 _listener.assertNoErrors();
14711 }
14712
14713 void test_visitTypeName_void() {
14714 ClassElement classA = ElementFactory.classElement2("A");
14715 TypeName typeName = AstFactory.typeName4("void");
14716 _resolveNode(typeName, [classA]);
14717 expect(typeName.type, same(VoidTypeImpl.instance));
14718 _listener.assertNoErrors();
14719 }
14720
14721 /**
14722 * Analyze the given catch clause and assert that the types of the parameters have been set to the
14723 * given types. The types can be null if the catch clause does not have the co rresponding
14724 * parameter.
14725 *
14726 * @param node the catch clause to be analyzed
14727 * @param exceptionType the expected type of the exception parameter
14728 * @param stackTraceType the expected type of the stack trace parameter
14729 * @param definedElements the elements that are to be defined in the scope in which the element is
14730 * being resolved
14731 */
14732 void _resolveCatchClause(
14733 CatchClause node, DartType exceptionType, InterfaceType stackTraceType,
14734 [List<Element> definedElements]) {
14735 _resolveNode(node, definedElements);
14736 SimpleIdentifier exceptionParameter = node.exceptionParameter;
14737 if (exceptionParameter != null) {
14738 expect(exceptionParameter.staticType, same(exceptionType));
14739 }
14740 SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
14741 if (stackTraceParameter != null) {
14742 expect(stackTraceParameter.staticType, same(stackTraceType));
14743 }
14744 }
14745
14746 /**
14747 * Return the type associated with the given parameter after the static type a nalyzer has computed
14748 * a type for it.
14749 *
14750 * @param node the parameter with which the type is associated
14751 * @param definedElements the elements that are to be defined in the scope in which the element is
14752 * being resolved
14753 * @return the type associated with the parameter
14754 */
14755 DartType _resolveFormalParameter(FormalParameter node,
14756 [List<Element> definedElements]) {
14757 _resolveNode(node, definedElements);
14758 return (node.identifier.staticElement as ParameterElement).type;
14759 }
14760
14761 /**
14762 * Return the element associated with the given identifier after the resolver has resolved the
14763 * identifier.
14764 *
14765 * @param node the expression to be resolved
14766 * @param definedElements the elements that are to be defined in the scope in which the element is
14767 * being resolved
14768 * @return the element to which the expression was resolved
14769 */
14770 void _resolveNode(AstNode node, [List<Element> definedElements]) {
14771 if (definedElements != null) {
14772 for (Element element in definedElements) {
14773 _library.libraryScope.define(element);
14774 }
14775 }
14776 node.accept(_visitor);
14777 }
14778 }
14779
14780 class _AnalysisContextFactory_initContextWithCore
14781 extends DirectoryBasedDartSdk {
14782 _AnalysisContextFactory_initContextWithCore(JavaFile arg0) : super(arg0);
14783
14784 @override
14785 LibraryMap initialLibraryMap(bool useDart2jsPaths) {
14786 LibraryMap map = new LibraryMap();
14787 _addLibrary(map, DartSdk.DART_ASYNC, false, "async.dart");
14788 _addLibrary(map, DartSdk.DART_CORE, false, "core.dart");
14789 _addLibrary(map, DartSdk.DART_HTML, false, "html_dartium.dart");
14790 _addLibrary(map, AnalysisContextFactory._DART_MATH, false, "math.dart");
14791 _addLibrary(map, AnalysisContextFactory._DART_INTERCEPTORS, true,
14792 "_interceptors.dart");
14793 _addLibrary(
14794 map, AnalysisContextFactory._DART_JS_HELPER, true, "_js_helper.dart");
14795 return map;
14796 }
14797
14798 void _addLibrary(LibraryMap map, String uri, bool isInternal, String path) {
14799 SdkLibraryImpl library = new SdkLibraryImpl(uri);
14800 if (isInternal) {
14801 library.category = "Internal";
14802 }
14803 library.path = path;
14804 map.setLibrary(uri, library);
14805 }
14806 }
14807
14808 class _SimpleResolverTest_localVariable_types_invoked
14809 extends RecursiveAstVisitor<Object> {
14810 final SimpleResolverTest test;
14811
14812 List<bool> found;
14813
14814 List<CaughtException> thrownException;
14815
14816 _SimpleResolverTest_localVariable_types_invoked(
14817 this.test, this.found, this.thrownException)
14818 : super();
14819
14820 @override
14821 Object visitSimpleIdentifier(SimpleIdentifier node) {
14822 if (node.name == "myVar" && node.parent is MethodInvocation) {
14823 try {
14824 found[0] = true;
14825 // check static type
14826 DartType staticType = node.staticType;
14827 expect(staticType, same(test.typeProvider.dynamicType));
14828 // check propagated type
14829 FunctionType propagatedType = node.propagatedType as FunctionType;
14830 expect(propagatedType.returnType, test.typeProvider.stringType);
14831 } on AnalysisException catch (e, stackTrace) {
14832 thrownException[0] = new CaughtException(e, stackTrace);
14833 }
14834 }
14835 return null;
14836 }
14837 }
14838
14839 /**
14840 * Shared infrastructure for [StaticTypeAnalyzer2Test] and
14841 * [StrongModeStaticTypeAnalyzer2Test].
14842 */
14843 class _StaticTypeAnalyzer2TestShared extends ResolverTestCase {
14844 String testCode;
14845 Source testSource;
14846 CompilationUnit testUnit;
14847
14848 SimpleIdentifier _findIdentifier(String search) {
14849 SimpleIdentifier identifier = EngineTestCase.findNode(
14850 testUnit, testCode, search, (node) => node is SimpleIdentifier);
14851 return identifier;
14852 }
14853
14854 void _resolveTestUnit(String code) {
14855 testCode = code;
14856 testSource = addSource(testCode);
14857 LibraryElement library = resolve2(testSource);
14858 assertNoErrors(testSource);
14859 verify([testSource]);
14860 testUnit = resolveCompilationUnit(testSource, library);
14861 }
14862 }
OLDNEW
« no previous file with comments | « packages/analyzer/test/generated/parser_test.dart ('k') | packages/analyzer/test/generated/scanner_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698