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

Side by Side Diff: mojo/public/dart/third_party/analyzer/test/generated/resolver_test.dart

Issue 1346773002: Stop running pub get at gclient sync time and fix build bugs (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 3 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(StrongModeTypePropagationTest);
72 }
73
74 /**
75 * The class `AnalysisContextFactory` defines utility methods used to create ana lysis contexts
76 * for testing purposes.
77 */
78 class AnalysisContextFactory {
79 static String _DART_MATH = "dart:math";
80
81 static String _DART_INTERCEPTORS = "dart:_interceptors";
82
83 static String _DART_JS_HELPER = "dart:_js_helper";
84
85 /**
86 * Create an analysis context that has a fake core library already resolved.
87 * Return the context that was created.
88 */
89 static InternalAnalysisContext contextWithCore() {
90 if (AnalysisEngine.instance.useTaskModel) {
91 NewAnalysisContextForTests context = new NewAnalysisContextForTests();
92 return initContextWithCore(context);
93 }
94 AnalysisContextForTests context = new AnalysisContextForTests();
95 return initContextWithCore(context);
96 }
97
98 /**
99 * Create an analysis context that uses the given [options] and has a fake
100 * core library already resolved. Return the context that was created.
101 */
102 static InternalAnalysisContext contextWithCoreAndOptions(
103 AnalysisOptions options) {
104 if (AnalysisEngine.instance.useTaskModel) {
105 NewAnalysisContextForTests context = new NewAnalysisContextForTests();
106 context._internalSetAnalysisOptions(options);
107 return initContextWithCore(context);
108 }
109 AnalysisContextForTests context = new AnalysisContextForTests();
110 context._internalSetAnalysisOptions(options);
111 return initContextWithCore(context);
112 }
113
114 /**
115 * Initialize the given analysis context with a fake core library already reso lved.
116 *
117 * @param context the context to be initialized (not `null`)
118 * @return the analysis context that was created
119 */
120 static InternalAnalysisContext initContextWithCore(
121 InternalAnalysisContext context) {
122 DirectoryBasedDartSdk sdk = new _AnalysisContextFactory_initContextWithCore(
123 new JavaFile("/fake/sdk"));
124 SourceFactory sourceFactory =
125 new SourceFactory([new DartUriResolver(sdk), new FileUriResolver()]);
126 context.sourceFactory = sourceFactory;
127 AnalysisContext coreContext = sdk.context;
128 //
129 // dart:core
130 //
131 TestTypeProvider provider = new TestTypeProvider();
132 CompilationUnitElementImpl coreUnit =
133 new CompilationUnitElementImpl("core.dart");
134 Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE);
135 coreContext.setContents(coreSource, "");
136 coreUnit.librarySource = coreUnit.source = coreSource;
137 ClassElementImpl proxyClassElement = ElementFactory.classElement2("_Proxy");
138 ClassElement objectClassElement = provider.objectType.element;
139 coreUnit.types = <ClassElement>[
140 provider.boolType.element,
141 provider.deprecatedType.element,
142 provider.doubleType.element,
143 provider.functionType.element,
144 provider.intType.element,
145 provider.iterableType.element,
146 provider.iteratorType.element,
147 provider.listType.element,
148 provider.mapType.element,
149 provider.nullType.element,
150 provider.numType.element,
151 objectClassElement,
152 proxyClassElement,
153 provider.stackTraceType.element,
154 provider.stringType.element,
155 provider.symbolType.element,
156 provider.typeType.element
157 ];
158 coreUnit.functions = <FunctionElement>[
159 ElementFactory.functionElement3("identical", provider.boolType.element,
160 <ClassElement>[objectClassElement, objectClassElement], null),
161 ElementFactory.functionElement3("print", VoidTypeImpl.instance.element,
162 <ClassElement>[objectClassElement], null)
163 ];
164 TopLevelVariableElement proxyTopLevelVariableElt = ElementFactory
165 .topLevelVariableElement3("proxy", true, false, proxyClassElement.type);
166 ConstTopLevelVariableElementImpl deprecatedTopLevelVariableElt =
167 ElementFactory.topLevelVariableElement3(
168 "deprecated", true, false, provider.deprecatedType);
169 deprecatedTopLevelVariableElt.constantInitializer = AstFactory
170 .instanceCreationExpression2(
171 Keyword.CONST,
172 AstFactory.typeName(provider.deprecatedType.element),
173 [AstFactory.string2('next release')]);
174 coreUnit.accessors = <PropertyAccessorElement>[
175 proxyTopLevelVariableElt.getter,
176 deprecatedTopLevelVariableElt.getter
177 ];
178 coreUnit.topLevelVariables = <TopLevelVariableElement>[
179 proxyTopLevelVariableElt,
180 deprecatedTopLevelVariableElt
181 ];
182 LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
183 coreContext, AstFactory.libraryIdentifier2(["dart", "core"]));
184 coreLibrary.definingCompilationUnit = coreUnit;
185 //
186 // dart:async
187 //
188 CompilationUnitElementImpl asyncUnit =
189 new CompilationUnitElementImpl("async.dart");
190 Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
191 coreContext.setContents(asyncSource, "");
192 asyncUnit.librarySource = asyncUnit.source = asyncSource;
193 // Future
194 ClassElementImpl futureElement =
195 ElementFactory.classElement2("Future", ["T"]);
196 InterfaceType futureType = futureElement.type;
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 MethodElement thenMethod = ElementFactory.methodElementWithParameters(
222 "then", futureElement.type.typeArguments, futureType, [
223 ElementFactory.requiredParameter2("onValue", aliasType),
224 ElementFactory.namedParameter2("onError", provider.functionType)
225 ]);
226 futureElement.methods = <MethodElement>[thenMethod];
227 // Completer
228 ClassElementImpl completerElement =
229 ElementFactory.classElement2("Completer", ["T"]);
230 ConstructorElementImpl completerConstructor =
231 ElementFactory.constructorElement2(completerElement, null);
232 (completerConstructor.type as FunctionTypeImpl).typeArguments =
233 completerElement.type.typeArguments;
234 completerElement.constructors = <ConstructorElement>[completerConstructor];
235 // StreamSubscription
236 ClassElementImpl streamSubscriptionElement =
237 ElementFactory.classElement2("StreamSubscription", ["T"]);
238 // Stream
239 ClassElementImpl streamElement =
240 ElementFactory.classElement2("Stream", ["T"]);
241 streamElement.constructors = <ConstructorElement>[
242 ElementFactory.constructorElement2(streamElement, null)
243 ];
244 DartType returnType = streamSubscriptionElement.type
245 .substitute4(streamElement.type.typeArguments);
246 List<DartType> parameterTypes = <DartType>[
247 ElementFactory
248 .functionElement3('onData', VoidTypeImpl.instance.element,
249 <TypeDefiningElement>[streamElement.typeParameters[0]], null)
250 .type,
251 ];
252 // TODO(brianwilkerson) This is missing the optional parameters.
253 MethodElementImpl listenMethod =
254 ElementFactory.methodElement('listen', returnType, parameterTypes);
255 streamElement.methods = <MethodElement>[listenMethod];
256
257 asyncUnit.types = <ClassElement>[
258 completerElement,
259 futureElement,
260 streamElement
261 ];
262 LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
263 coreContext, AstFactory.libraryIdentifier2(["dart", "async"]));
264 asyncLibrary.definingCompilationUnit = asyncUnit;
265 //
266 // dart:html
267 //
268 CompilationUnitElementImpl htmlUnit =
269 new CompilationUnitElementImpl("html_dartium.dart");
270 Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
271 coreContext.setContents(htmlSource, "");
272 htmlUnit.librarySource = htmlUnit.source = htmlSource;
273 ClassElementImpl elementElement = ElementFactory.classElement2("Element");
274 InterfaceType elementType = elementElement.type;
275 ClassElementImpl canvasElement =
276 ElementFactory.classElement("CanvasElement", elementType);
277 ClassElementImpl contextElement =
278 ElementFactory.classElement2("CanvasRenderingContext");
279 InterfaceType contextElementType = contextElement.type;
280 ClassElementImpl context2dElement = ElementFactory.classElement(
281 "CanvasRenderingContext2D", contextElementType);
282 canvasElement.methods = <MethodElement>[
283 ElementFactory.methodElement(
284 "getContext", contextElementType, [provider.stringType])
285 ];
286 canvasElement.accessors = <PropertyAccessorElement>[
287 ElementFactory.getterElement("context2D", false, context2dElement.type)
288 ];
289 canvasElement.fields = canvasElement.accessors
290 .map((PropertyAccessorElement accessor) => accessor.variable)
291 .toList();
292 ClassElementImpl documentElement =
293 ElementFactory.classElement("Document", elementType);
294 ClassElementImpl htmlDocumentElement =
295 ElementFactory.classElement("HtmlDocument", documentElement.type);
296 htmlDocumentElement.methods = <MethodElement>[
297 ElementFactory.methodElement(
298 "query", elementType, <DartType>[provider.stringType])
299 ];
300 htmlUnit.types = <ClassElement>[
301 ElementFactory.classElement("AnchorElement", elementType),
302 ElementFactory.classElement("BodyElement", elementType),
303 ElementFactory.classElement("ButtonElement", elementType),
304 canvasElement,
305 contextElement,
306 context2dElement,
307 ElementFactory.classElement("DivElement", elementType),
308 documentElement,
309 elementElement,
310 htmlDocumentElement,
311 ElementFactory.classElement("InputElement", elementType),
312 ElementFactory.classElement("SelectElement", elementType)
313 ];
314 htmlUnit.functions = <FunctionElement>[
315 ElementFactory.functionElement3("query", elementElement,
316 <ClassElement>[provider.stringType.element], ClassElement.EMPTY_LIST)
317 ];
318 TopLevelVariableElementImpl document = ElementFactory
319 .topLevelVariableElement3(
320 "document", false, true, htmlDocumentElement.type);
321 htmlUnit.topLevelVariables = <TopLevelVariableElement>[document];
322 htmlUnit.accessors = <PropertyAccessorElement>[document.getter];
323 LibraryElementImpl htmlLibrary = new LibraryElementImpl.forNode(
324 coreContext, AstFactory.libraryIdentifier2(["dart", "dom", "html"]));
325 htmlLibrary.definingCompilationUnit = htmlUnit;
326 //
327 // dart:math
328 //
329 CompilationUnitElementImpl mathUnit =
330 new CompilationUnitElementImpl("math.dart");
331 Source mathSource = sourceFactory.forUri(_DART_MATH);
332 coreContext.setContents(mathSource, "");
333 mathUnit.librarySource = mathUnit.source = mathSource;
334 FunctionElement cosElement = ElementFactory.functionElement3(
335 "cos",
336 provider.doubleType.element,
337 <ClassElement>[provider.numType.element],
338 ClassElement.EMPTY_LIST);
339 TopLevelVariableElement ln10Element = ElementFactory
340 .topLevelVariableElement3("LN10", true, false, provider.doubleType);
341 TopLevelVariableElement piElement = ElementFactory.topLevelVariableElement3(
342 "PI", true, false, provider.doubleType);
343 ClassElementImpl randomElement = ElementFactory.classElement2("Random");
344 randomElement.abstract = true;
345 ConstructorElementImpl randomConstructor =
346 ElementFactory.constructorElement2(randomElement, null);
347 randomConstructor.factory = true;
348 ParameterElementImpl seedParam = new ParameterElementImpl("seed", 0);
349 seedParam.parameterKind = ParameterKind.POSITIONAL;
350 seedParam.type = provider.intType;
351 randomConstructor.parameters = <ParameterElement>[seedParam];
352 randomElement.constructors = <ConstructorElement>[randomConstructor];
353 FunctionElement sinElement = ElementFactory.functionElement3(
354 "sin",
355 provider.doubleType.element,
356 <ClassElement>[provider.numType.element],
357 ClassElement.EMPTY_LIST);
358 FunctionElement sqrtElement = ElementFactory.functionElement3(
359 "sqrt",
360 provider.doubleType.element,
361 <ClassElement>[provider.numType.element],
362 ClassElement.EMPTY_LIST);
363 mathUnit.accessors = <PropertyAccessorElement>[
364 ln10Element.getter,
365 piElement.getter
366 ];
367 mathUnit.functions = <FunctionElement>[cosElement, sinElement, sqrtElement];
368 mathUnit.topLevelVariables = <TopLevelVariableElement>[
369 ln10Element,
370 piElement
371 ];
372 mathUnit.types = <ClassElement>[randomElement];
373 LibraryElementImpl mathLibrary = new LibraryElementImpl.forNode(
374 coreContext, AstFactory.libraryIdentifier2(["dart", "math"]));
375 mathLibrary.definingCompilationUnit = mathUnit;
376 //
377 // Set empty sources for the rest of the libraries.
378 //
379 Source source = sourceFactory.forUri(_DART_INTERCEPTORS);
380 coreContext.setContents(source, "");
381 source = sourceFactory.forUri(_DART_JS_HELPER);
382 coreContext.setContents(source, "");
383 //
384 // Record the elements.
385 //
386 HashMap<Source, LibraryElement> elementMap =
387 new HashMap<Source, LibraryElement>();
388 elementMap[coreSource] = coreLibrary;
389 elementMap[asyncSource] = asyncLibrary;
390 elementMap[htmlSource] = htmlLibrary;
391 elementMap[mathSource] = mathLibrary;
392 context.recordLibraryElements(elementMap);
393 return context;
394 }
395
396 /**
397 * Create an analysis context that has a fake core library already resolved.
398 * Return the context that was created.
399 */
400 static AnalysisContextImpl oldContextWithCore() {
401 AnalysisContextForTests context = new AnalysisContextForTests();
402 return initContextWithCore(context);
403 }
404
405 /**
406 * Create an analysis context that uses the given [options] and has a fake
407 * core library already resolved. Return the context that was created.
408 */
409 static AnalysisContextImpl oldContextWithCoreAndOptions(
410 AnalysisOptions options) {
411 AnalysisContextForTests context = new AnalysisContextForTests();
412 context._internalSetAnalysisOptions(options);
413 return initContextWithCore(context);
414 }
415 }
416
417 /**
418 * Instances of the class `AnalysisContextForTests` implement an analysis contex t that has a
419 * fake SDK that is much smaller and faster for testing purposes.
420 */
421 class AnalysisContextForTests extends AnalysisContextImpl {
422 @override
423 void set analysisOptions(AnalysisOptions options) {
424 AnalysisOptions currentOptions = analysisOptions;
425 bool needsRecompute = currentOptions.analyzeFunctionBodiesPredicate !=
426 options.analyzeFunctionBodiesPredicate ||
427 currentOptions.generateImplicitErrors !=
428 options.generateImplicitErrors ||
429 currentOptions.generateSdkErrors != options.generateSdkErrors ||
430 currentOptions.dart2jsHint != options.dart2jsHint ||
431 (currentOptions.hint && !options.hint) ||
432 currentOptions.preserveComments != options.preserveComments ||
433 currentOptions.enableStrictCallChecks != options.enableStrictCallChecks;
434 if (needsRecompute) {
435 fail(
436 "Cannot set options that cause the sources to be reanalyzed in a test context");
437 }
438 super.analysisOptions = options;
439 }
440
441 @override
442 bool exists(Source source) =>
443 super.exists(source) || sourceFactory.dartSdk.context.exists(source);
444
445 @override
446 TimestampedData<String> getContents(Source source) {
447 if (source.isInSystemLibrary) {
448 return sourceFactory.dartSdk.context.getContents(source);
449 }
450 return super.getContents(source);
451 }
452
453 @override
454 int getModificationStamp(Source source) {
455 if (source.isInSystemLibrary) {
456 return sourceFactory.dartSdk.context.getModificationStamp(source);
457 }
458 return super.getModificationStamp(source);
459 }
460
461 /**
462 * Set the analysis options, even if they would force re-analysis. This method should only be
463 * invoked before the fake SDK is initialized.
464 *
465 * @param options the analysis options to be set
466 */
467 void _internalSetAnalysisOptions(AnalysisOptions options) {
468 super.analysisOptions = options;
469 }
470 }
471
472 /**
473 * Helper for creating and managing single [AnalysisContext].
474 */
475 class AnalysisContextHelper {
476 AnalysisContext context;
477
478 /**
479 * Creates new [AnalysisContext] using [AnalysisContextFactory].
480 */
481 AnalysisContextHelper([AnalysisOptionsImpl options]) {
482 if (options == null) {
483 options = new AnalysisOptionsImpl();
484 }
485 options.cacheSize = 256;
486 context = AnalysisContextFactory.contextWithCoreAndOptions(options);
487 }
488
489 Source addSource(String path, String code) {
490 Source source = new FileBasedSource(FileUtilities2.createFile(path));
491 if (path.endsWith(".dart") || path.endsWith(".html")) {
492 ChangeSet changeSet = new ChangeSet();
493 changeSet.addedSource(source);
494 context.applyChanges(changeSet);
495 }
496 context.setContents(source, code);
497 return source;
498 }
499
500 CompilationUnitElement getDefiningUnitElement(Source source) =>
501 context.getCompilationUnitElement(source, source);
502
503 CompilationUnit resolveDefiningUnit(Source source) {
504 LibraryElement libraryElement = context.computeLibraryElement(source);
505 return context.resolveCompilationUnit(source, libraryElement);
506 }
507
508 void runTasks() {
509 AnalysisResult result = context.performAnalysisTask();
510 while (result.changeNotices != null) {
511 result = context.performAnalysisTask();
512 }
513 }
514 }
515
516 @reflectiveTest
517 class AnalysisDeltaTest extends EngineTestCase {
518 TestSource source1 = new TestSource('/1.dart');
519 TestSource source2 = new TestSource('/2.dart');
520 TestSource source3 = new TestSource('/3.dart');
521
522 void test_getAddedSources() {
523 AnalysisDelta delta = new AnalysisDelta();
524 delta.setAnalysisLevel(source1, AnalysisLevel.ALL);
525 delta.setAnalysisLevel(source2, AnalysisLevel.ERRORS);
526 delta.setAnalysisLevel(source3, AnalysisLevel.NONE);
527 List<Source> addedSources = delta.addedSources;
528 expect(addedSources, hasLength(2));
529 expect(addedSources, unorderedEquals([source1, source2]));
530 }
531
532 void test_getAnalysisLevels() {
533 AnalysisDelta delta = new AnalysisDelta();
534 expect(delta.analysisLevels.length, 0);
535 }
536
537 void test_setAnalysisLevel() {
538 AnalysisDelta delta = new AnalysisDelta();
539 delta.setAnalysisLevel(source1, AnalysisLevel.ALL);
540 delta.setAnalysisLevel(source2, AnalysisLevel.ERRORS);
541 Map<Source, AnalysisLevel> levels = delta.analysisLevels;
542 expect(levels.length, 2);
543 expect(levels[source1], AnalysisLevel.ALL);
544 expect(levels[source2], AnalysisLevel.ERRORS);
545 }
546
547 void test_toString() {
548 AnalysisDelta delta = new AnalysisDelta();
549 delta.setAnalysisLevel(new TestSource(), AnalysisLevel.ALL);
550 String result = delta.toString();
551 expect(result, isNotNull);
552 expect(result.length > 0, isTrue);
553 }
554 }
555
556 @reflectiveTest
557 class ChangeSetTest extends EngineTestCase {
558 void test_changedContent() {
559 TestSource source = new TestSource();
560 String content = "";
561 ChangeSet changeSet = new ChangeSet();
562 changeSet.changedContent(source, content);
563 expect(changeSet.addedSources, hasLength(0));
564 expect(changeSet.changedSources, hasLength(0));
565 Map<Source, String> map = changeSet.changedContents;
566 expect(map, hasLength(1));
567 expect(map[source], same(content));
568 expect(changeSet.changedRanges, hasLength(0));
569 expect(changeSet.deletedSources, hasLength(0));
570 expect(changeSet.removedSources, hasLength(0));
571 expect(changeSet.removedContainers, hasLength(0));
572 }
573
574 void test_changedRange() {
575 TestSource source = new TestSource();
576 String content = "";
577 ChangeSet changeSet = new ChangeSet();
578 changeSet.changedRange(source, content, 1, 2, 3);
579 expect(changeSet.addedSources, hasLength(0));
580 expect(changeSet.changedSources, hasLength(0));
581 expect(changeSet.changedContents, hasLength(0));
582 Map<Source, ChangeSet_ContentChange> map = changeSet.changedRanges;
583 expect(map, hasLength(1));
584 ChangeSet_ContentChange change = map[source];
585 expect(change, isNotNull);
586 expect(change.contents, content);
587 expect(change.offset, 1);
588 expect(change.oldLength, 2);
589 expect(change.newLength, 3);
590 expect(changeSet.deletedSources, hasLength(0));
591 expect(changeSet.removedSources, hasLength(0));
592 expect(changeSet.removedContainers, hasLength(0));
593 }
594
595 void test_toString() {
596 ChangeSet changeSet = new ChangeSet();
597 changeSet.addedSource(new TestSource());
598 changeSet.changedSource(new TestSource());
599 changeSet.changedContent(new TestSource(), "");
600 changeSet.changedRange(new TestSource(), "", 0, 0, 0);
601 changeSet.deletedSource(new TestSource());
602 changeSet.removedSource(new TestSource());
603 changeSet
604 .removedContainer(new SourceContainer_ChangeSetTest_test_toString());
605 expect(changeSet.toString(), isNotNull);
606 }
607 }
608
609 @reflectiveTest
610 class CheckedModeCompileTimeErrorCodeTest extends ResolverTestCase {
611 void test_fieldFormalParameterAssignableToField_extends() {
612 // According to checked-mode type checking rules, a value of type B is
613 // assignable to a field of type A, because B extends A (and hence is a
614 // subtype of A).
615 Source source = addSource(r'''
616 class A {
617 const A();
618 }
619 class B extends A {
620 const B();
621 }
622 class C {
623 final A a;
624 const C(this.a);
625 }
626 var v = const C(const B());''');
627 computeLibrarySourceErrors(source);
628 assertNoErrors(source);
629 verify([source]);
630 }
631
632 void test_fieldFormalParameterAssignableToField_fieldType_unresolved_null() {
633 // Null always passes runtime type checks, even when the type is
634 // unresolved.
635 Source source = addSource(r'''
636 class A {
637 final Unresolved x;
638 const A(String this.x);
639 }
640 var v = const A(null);''');
641 computeLibrarySourceErrors(source);
642 assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
643 verify([source]);
644 }
645
646 void test_fieldFormalParameterAssignableToField_implements() {
647 // According to checked-mode type checking rules, a value of type B is
648 // assignable to a field of type A, because B implements A (and hence is a
649 // subtype of A).
650 Source source = addSource(r'''
651 class A {}
652 class B implements A {
653 const B();
654 }
655 class C {
656 final A a;
657 const C(this.a);
658 }
659 var v = const C(const B());''');
660 computeLibrarySourceErrors(source);
661 assertNoErrors(source);
662 verify([source]);
663 }
664
665 void test_fieldFormalParameterAssignableToField_list_dynamic() {
666 // [1, 2, 3] has type List<dynamic>, which is a subtype of List<int>.
667 Source source = addSource(r'''
668 class A {
669 const A(List<int> x);
670 }
671 var x = const A(const [1, 2, 3]);''');
672 computeLibrarySourceErrors(source);
673 assertNoErrors(source);
674 verify([source]);
675 }
676
677 void test_fieldFormalParameterAssignableToField_list_nonDynamic() {
678 // <int>[1, 2, 3] has type List<int>, which is a subtype of List<num>.
679 Source source = addSource(r'''
680 class A {
681 const A(List<num> x);
682 }
683 var x = const A(const <int>[1, 2, 3]);''');
684 computeLibrarySourceErrors(source);
685 assertNoErrors(source);
686 verify([source]);
687 }
688
689 void test_fieldFormalParameterAssignableToField_map_dynamic() {
690 // {1: 2} has type Map<dynamic, dynamic>, which is a subtype of
691 // Map<int, int>.
692 Source source = addSource(r'''
693 class A {
694 const A(Map<int, int> x);
695 }
696 var x = const A(const {1: 2});''');
697 computeLibrarySourceErrors(source);
698 assertNoErrors(source);
699 verify([source]);
700 }
701
702 void test_fieldFormalParameterAssignableToField_map_keyDifferent() {
703 // <int, int>{1: 2} has type Map<int, int>, which is a subtype of
704 // Map<num, int>.
705 Source source = addSource(r'''
706 class A {
707 const A(Map<num, int> x);
708 }
709 var x = const A(const <int, int>{1: 2});''');
710 computeLibrarySourceErrors(source);
711 assertNoErrors(source);
712 verify([source]);
713 }
714
715 void test_fieldFormalParameterAssignableToField_map_valueDifferent() {
716 // <int, int>{1: 2} has type Map<int, int>, which is a subtype of
717 // Map<int, num>.
718 Source source = addSource(r'''
719 class A {
720 const A(Map<int, num> x);
721 }
722 var x = const A(const <int, int>{1: 2});''');
723 computeLibrarySourceErrors(source);
724 assertNoErrors(source);
725 verify([source]);
726 }
727
728 void test_fieldFormalParameterAssignableToField_notype() {
729 // If a field is declared without a type, then any value may be assigned to
730 // it.
731 Source source = addSource(r'''
732 class A {
733 final x;
734 const A(this.x);
735 }
736 var v = const A(5);''');
737 computeLibrarySourceErrors(source);
738 assertNoErrors(source);
739 verify([source]);
740 }
741
742 void test_fieldFormalParameterAssignableToField_null() {
743 // Null is assignable to anything.
744 Source source = addSource(r'''
745 class A {
746 final int x;
747 const A(this.x);
748 }
749 var v = const A(null);''');
750 computeLibrarySourceErrors(source);
751 assertNoErrors(source);
752 verify([source]);
753 }
754
755 void test_fieldFormalParameterAssignableToField_typedef() {
756 // foo has the runtime type dynamic -> dynamic, so it should be assignable
757 // to A.f.
758 Source source = addSource(r'''
759 typedef String Int2String(int x);
760 class A {
761 final Int2String f;
762 const A(this.f);
763 }
764 foo(x) => 1;
765 var v = const A(foo);''');
766 computeLibrarySourceErrors(source);
767 assertNoErrors(source);
768 verify([source]);
769 }
770
771 void test_fieldFormalParameterAssignableToField_typeSubstitution() {
772 // foo has the runtime type dynamic -> dynamic, so it should be assignable
773 // to A.f.
774 Source source = addSource(r'''
775 class A<T> {
776 final T x;
777 const A(this.x);
778 }
779 var v = const A<int>(3);''');
780 computeLibrarySourceErrors(source);
781 assertNoErrors(source);
782 verify([source]);
783 }
784
785 void test_fieldFormalParameterNotAssignableToField() {
786 Source source = addSource(r'''
787 class A {
788 final int x;
789 const A(this.x);
790 }
791 var v = const A('foo');''');
792 computeLibrarySourceErrors(source);
793 assertErrors(source, [
794 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
795 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
796 ]);
797 verify([source]);
798 }
799
800 void test_fieldFormalParameterNotAssignableToField_extends() {
801 // According to checked-mode type checking rules, a value of type A is not
802 // assignable to a field of type B, because B extends A (the subtyping
803 // relationship is in the wrong direction).
804 Source source = addSource(r'''
805 class A {
806 const A();
807 }
808 class B extends A {
809 const B();
810 }
811 class C {
812 final B b;
813 const C(this.b);
814 }
815 var v = const C(const A());''');
816 computeLibrarySourceErrors(source);
817 assertErrors(source, [
818 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
819 ]);
820 verify([source]);
821 }
822
823 void test_fieldFormalParameterNotAssignableToField_fieldType() {
824 Source source = addSource(r'''
825 class A {
826 final int x;
827 const A(String this.x);
828 }
829 var v = const A('foo');''');
830 computeLibrarySourceErrors(source);
831 assertErrors(source, [
832 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
833 StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE
834 ]);
835 verify([source]);
836 }
837
838 void test_fieldFormalParameterNotAssignableToField_fieldType_unresolved() {
839 Source source = addSource(r'''
840 class A {
841 final Unresolved x;
842 const A(String this.x);
843 }
844 var v = const A('foo');''');
845 computeLibrarySourceErrors(source);
846 assertErrors(source, [
847 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
848 StaticWarningCode.UNDEFINED_CLASS
849 ]);
850 verify([source]);
851 }
852
853 void test_fieldFormalParameterNotAssignableToField_implements() {
854 // According to checked-mode type checking rules, a value of type A is not
855 // assignable to a field of type B, because B implements A (the subtyping
856 // relationship is in the wrong direction).
857 Source source = addSource(r'''
858 class A {
859 const A();
860 }
861 class B implements A {}
862 class C {
863 final B b;
864 const C(this.b);
865 }
866 var v = const C(const A());''');
867 computeLibrarySourceErrors(source);
868 assertErrors(source, [
869 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
870 ]);
871 verify([source]);
872 }
873
874 void test_fieldFormalParameterNotAssignableToField_list() {
875 // <num>[1, 2, 3] has type List<num>, which is not a subtype of List<int>.
876 Source source = addSource(r'''
877 class A {
878 const A(List<int> x);
879 }
880 var x = const A(const <num>[1, 2, 3]);''');
881 computeLibrarySourceErrors(source);
882 assertErrors(source, [
883 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
884 ]);
885 verify([source]);
886 }
887
888 void test_fieldFormalParameterNotAssignableToField_map_keyMismatch() {
889 // <num, int>{1: 2} has type Map<num, int>, which is not a subtype of
890 // Map<int, int>.
891 Source source = addSource(r'''
892 class A {
893 const A(Map<int, int> x);
894 }
895 var x = const A(const <num, int>{1: 2});''');
896 computeLibrarySourceErrors(source);
897 assertErrors(source, [
898 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
899 ]);
900 verify([source]);
901 }
902
903 void test_fieldFormalParameterNotAssignableToField_map_valueMismatch() {
904 // <int, num>{1: 2} has type Map<int, num>, which is not a subtype of
905 // Map<int, int>.
906 Source source = addSource(r'''
907 class A {
908 const A(Map<int, int> x);
909 }
910 var x = const A(const <int, num>{1: 2});''');
911 computeLibrarySourceErrors(source);
912 assertErrors(source, [
913 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
914 ]);
915 verify([source]);
916 }
917
918 void test_fieldFormalParameterNotAssignableToField_optional() {
919 Source source = addSource(r'''
920 class A {
921 final int x;
922 const A([this.x = 'foo']);
923 }
924 var v = const A();''');
925 computeLibrarySourceErrors(source);
926 assertErrors(source, [
927 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
928 StaticTypeWarningCode.INVALID_ASSIGNMENT
929 ]);
930 verify([source]);
931 }
932
933 void test_fieldFormalParameterNotAssignableToField_typedef() {
934 // foo has the runtime type String -> int, so it should not be assignable
935 // to A.f (A.f requires it to be int -> String).
936 Source source = addSource(r'''
937 typedef String Int2String(int x);
938 class A {
939 final Int2String f;
940 const A(this.f);
941 }
942 int foo(String x) => 1;
943 var v = const A(foo);''');
944 computeLibrarySourceErrors(source);
945 assertErrors(source, [
946 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
947 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
948 ]);
949 verify([source]);
950 }
951
952 void test_fieldInitializerNotAssignable() {
953 Source source = addSource(r'''
954 class A {
955 final int x;
956 const A() : x = '';
957 }''');
958 computeLibrarySourceErrors(source);
959 assertErrors(source, [
960 CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
961 StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE
962 ]);
963 verify([source]);
964 }
965
966 void test_fieldTypeMismatch() {
967 Source source = addSource(r'''
968 class A {
969 const A(x) : y = x;
970 final int y;
971 }
972 var v = const A('foo');''');
973 computeLibrarySourceErrors(source);
974 assertErrors(source, [
975 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
976 ]);
977 verify([source]);
978 }
979
980 void test_fieldTypeMismatch_generic() {
981 Source source = addSource(r'''
982 class C<T> {
983 final T x = y;
984 const C();
985 }
986 const y = 1;
987 var v = const C<String>();
988 ''');
989 computeLibrarySourceErrors(source);
990 assertErrors(source, [
991 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
992 HintCode.INVALID_ASSIGNMENT
993 ]);
994 verify([source]);
995 }
996
997 void test_fieldTypeMismatch_unresolved() {
998 Source source = addSource(r'''
999 class A {
1000 const A(x) : y = x;
1001 final Unresolved y;
1002 }
1003 var v = const A('foo');''');
1004 computeLibrarySourceErrors(source);
1005 assertErrors(source, [
1006 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
1007 StaticWarningCode.UNDEFINED_CLASS
1008 ]);
1009 verify([source]);
1010 }
1011
1012 void test_fieldTypeOk_generic() {
1013 Source source = addSource(r'''
1014 class C<T> {
1015 final T x = y;
1016 const C();
1017 }
1018 const y = 1;
1019 var v = const C<int>();
1020 ''');
1021 computeLibrarySourceErrors(source);
1022 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
1023 verify([source]);
1024 }
1025
1026 void test_fieldTypeOk_null() {
1027 Source source = addSource(r'''
1028 class A {
1029 const A(x) : y = x;
1030 final int y;
1031 }
1032 var v = const A(null);''');
1033 computeLibrarySourceErrors(source);
1034 assertNoErrors(source);
1035 verify([source]);
1036 }
1037
1038 void test_fieldTypeOk_unresolved_null() {
1039 // Null always passes runtime type checks, even when the type is
1040 // unresolved.
1041 Source source = addSource(r'''
1042 class A {
1043 const A(x) : y = x;
1044 final Unresolved y;
1045 }
1046 var v = const A(null);''');
1047 computeLibrarySourceErrors(source);
1048 assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
1049 verify([source]);
1050 }
1051
1052 void test_listElementTypeNotAssignable() {
1053 Source source = addSource("var v = const <String> [42];");
1054 computeLibrarySourceErrors(source);
1055 assertErrors(source, [
1056 CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
1057 StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
1058 ]);
1059 verify([source]);
1060 }
1061
1062 void test_mapKeyTypeNotAssignable() {
1063 Source source = addSource("var v = const <String, int > {1 : 2};");
1064 computeLibrarySourceErrors(source);
1065 assertErrors(source, [
1066 CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
1067 StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE
1068 ]);
1069 verify([source]);
1070 }
1071
1072 void test_mapValueTypeNotAssignable() {
1073 Source source = addSource("var v = const <String, String> {'a' : 2};");
1074 computeLibrarySourceErrors(source);
1075 assertErrors(source, [
1076 CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
1077 StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE
1078 ]);
1079 verify([source]);
1080 }
1081
1082 void test_parameterAssignable_null() {
1083 // Null is assignable to anything.
1084 Source source = addSource(r'''
1085 class A {
1086 const A(int x);
1087 }
1088 var v = const A(null);''');
1089 computeLibrarySourceErrors(source);
1090 assertNoErrors(source);
1091 verify([source]);
1092 }
1093
1094 void test_parameterAssignable_typeSubstitution() {
1095 Source source = addSource(r'''
1096 class A<T> {
1097 const A(T x);
1098 }
1099 var v = const A<int>(3);''');
1100 computeLibrarySourceErrors(source);
1101 assertNoErrors(source);
1102 verify([source]);
1103 }
1104
1105 void test_parameterAssignable_undefined_null() {
1106 // Null always passes runtime type checks, even when the type is
1107 // unresolved.
1108 Source source = addSource(r'''
1109 class A {
1110 const A(Unresolved x);
1111 }
1112 var v = const A(null);''');
1113 computeLibrarySourceErrors(source);
1114 assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
1115 verify([source]);
1116 }
1117
1118 void test_parameterNotAssignable() {
1119 Source source = addSource(r'''
1120 class A {
1121 const A(int x);
1122 }
1123 var v = const A('foo');''');
1124 computeLibrarySourceErrors(source);
1125 assertErrors(source, [
1126 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
1127 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
1128 ]);
1129 verify([source]);
1130 }
1131
1132 void test_parameterNotAssignable_typeSubstitution() {
1133 Source source = addSource(r'''
1134 class A<T> {
1135 const A(T x);
1136 }
1137 var v = const A<int>('foo');''');
1138 computeLibrarySourceErrors(source);
1139 assertErrors(source, [
1140 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
1141 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
1142 ]);
1143 verify([source]);
1144 }
1145
1146 void test_parameterNotAssignable_undefined() {
1147 Source source = addSource(r'''
1148 class A {
1149 const A(Unresolved x);
1150 }
1151 var v = const A('foo');''');
1152 computeLibrarySourceErrors(source);
1153 assertErrors(source, [
1154 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
1155 StaticWarningCode.UNDEFINED_CLASS
1156 ]);
1157 verify([source]);
1158 }
1159
1160 void test_redirectingConstructor_paramTypeMismatch() {
1161 Source source = addSource(r'''
1162 class A {
1163 const A.a1(x) : this.a2(x);
1164 const A.a2(String x);
1165 }
1166 var v = const A.a1(0);''');
1167 computeLibrarySourceErrors(source);
1168 assertErrors(source, [
1169 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
1170 ]);
1171 verify([source]);
1172 }
1173
1174 void test_topLevelVarAssignable_null() {
1175 Source source = addSource("const int x = null;");
1176 computeLibrarySourceErrors(source);
1177 assertNoErrors(source);
1178 verify([source]);
1179 }
1180
1181 void test_topLevelVarAssignable_undefined_null() {
1182 // Null always passes runtime type checks, even when the type is
1183 // unresolved.
1184 Source source = addSource("const Unresolved x = null;");
1185 computeLibrarySourceErrors(source);
1186 assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
1187 verify([source]);
1188 }
1189
1190 void test_topLevelVarNotAssignable() {
1191 Source source = addSource("const int x = 'foo';");
1192 computeLibrarySourceErrors(source);
1193 assertErrors(source, [
1194 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
1195 StaticTypeWarningCode.INVALID_ASSIGNMENT
1196 ]);
1197 verify([source]);
1198 }
1199
1200 void test_topLevelVarNotAssignable_undefined() {
1201 Source source = addSource("const Unresolved x = 'foo';");
1202 computeLibrarySourceErrors(source);
1203 assertErrors(source, [
1204 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
1205 StaticWarningCode.UNDEFINED_CLASS
1206 ]);
1207 verify([source]);
1208 }
1209 }
1210
1211 @reflectiveTest
1212 class ElementResolverTest extends EngineTestCase {
1213 /**
1214 * The error listener to which errors will be reported.
1215 */
1216 GatheringErrorListener _listener;
1217
1218 /**
1219 * The type provider used to access the types.
1220 */
1221 TestTypeProvider _typeProvider;
1222
1223 /**
1224 * The library containing the code being resolved.
1225 */
1226 LibraryElementImpl _definingLibrary;
1227
1228 /**
1229 * The resolver visitor that maintains the state for the resolver.
1230 */
1231 ResolverVisitor _visitor;
1232
1233 /**
1234 * The resolver being used to resolve the test cases.
1235 */
1236 ElementResolver _resolver;
1237
1238 void fail_visitExportDirective_combinators() {
1239 fail("Not yet tested");
1240 // Need to set up the exported library so that the identifier can be
1241 // resolved.
1242 ExportDirective directive = AstFactory.exportDirective2(null, [
1243 AstFactory.hideCombinator2(["A"])
1244 ]);
1245 _resolveNode(directive);
1246 _listener.assertNoErrors();
1247 }
1248
1249 void fail_visitFunctionExpressionInvocation() {
1250 fail("Not yet tested");
1251 _listener.assertNoErrors();
1252 }
1253
1254 void fail_visitImportDirective_combinators_noPrefix() {
1255 fail("Not yet tested");
1256 // Need to set up the imported library so that the identifier can be
1257 // resolved.
1258 ImportDirective directive = AstFactory.importDirective3(null, null, [
1259 AstFactory.showCombinator2(["A"])
1260 ]);
1261 _resolveNode(directive);
1262 _listener.assertNoErrors();
1263 }
1264
1265 void fail_visitImportDirective_combinators_prefix() {
1266 fail("Not yet tested");
1267 // Need to set up the imported library so that the identifiers can be
1268 // resolved.
1269 String prefixName = "p";
1270 _definingLibrary.imports = <ImportElement>[
1271 ElementFactory.importFor(null, ElementFactory.prefix(prefixName))
1272 ];
1273 ImportDirective directive = AstFactory.importDirective3(null, prefixName, [
1274 AstFactory.showCombinator2(["A"]),
1275 AstFactory.hideCombinator2(["B"])
1276 ]);
1277 _resolveNode(directive);
1278 _listener.assertNoErrors();
1279 }
1280
1281 void fail_visitRedirectingConstructorInvocation() {
1282 fail("Not yet tested");
1283 _listener.assertNoErrors();
1284 }
1285
1286 @override
1287 void setUp() {
1288 _listener = new GatheringErrorListener();
1289 _typeProvider = new TestTypeProvider();
1290 _resolver = _createResolver();
1291 }
1292
1293 void test_lookUpMethodInInterfaces() {
1294 InterfaceType intType = _typeProvider.intType;
1295 //
1296 // abstract class A { int operator[](int index); }
1297 //
1298 ClassElementImpl classA = ElementFactory.classElement2("A");
1299 MethodElement operator =
1300 ElementFactory.methodElement("[]", intType, [intType]);
1301 classA.methods = <MethodElement>[operator];
1302 //
1303 // class B implements A {}
1304 //
1305 ClassElementImpl classB = ElementFactory.classElement2("B");
1306 classB.interfaces = <InterfaceType>[classA.type];
1307 //
1308 // class C extends Object with B {}
1309 //
1310 ClassElementImpl classC = ElementFactory.classElement2("C");
1311 classC.mixins = <InterfaceType>[classB.type];
1312 //
1313 // class D extends C {}
1314 //
1315 ClassElementImpl classD = ElementFactory.classElement("D", classC.type);
1316 //
1317 // D a;
1318 // a[i];
1319 //
1320 SimpleIdentifier array = AstFactory.identifier3("a");
1321 array.staticType = classD.type;
1322 IndexExpression expression =
1323 AstFactory.indexExpression(array, AstFactory.identifier3("i"));
1324 expect(_resolveIndexExpression(expression), same(operator));
1325 _listener.assertNoErrors();
1326 }
1327
1328 void test_visitAssignmentExpression_compound() {
1329 InterfaceType intType = _typeProvider.intType;
1330 SimpleIdentifier leftHandSide = AstFactory.identifier3("a");
1331 leftHandSide.staticType = intType;
1332 AssignmentExpression assignment = AstFactory.assignmentExpression(
1333 leftHandSide, TokenType.PLUS_EQ, AstFactory.integer(1));
1334 _resolveNode(assignment);
1335 expect(
1336 assignment.staticElement, same(getMethod(_typeProvider.numType, "+")));
1337 _listener.assertNoErrors();
1338 }
1339
1340 void test_visitAssignmentExpression_simple() {
1341 AssignmentExpression expression = AstFactory.assignmentExpression(
1342 AstFactory.identifier3("x"), TokenType.EQ, AstFactory.integer(0));
1343 _resolveNode(expression);
1344 expect(expression.staticElement, isNull);
1345 _listener.assertNoErrors();
1346 }
1347
1348 void test_visitBinaryExpression_bangEq() {
1349 // String i;
1350 // var j;
1351 // i == j
1352 InterfaceType stringType = _typeProvider.stringType;
1353 SimpleIdentifier left = AstFactory.identifier3("i");
1354 left.staticType = stringType;
1355 BinaryExpression expression = AstFactory.binaryExpression(
1356 left, TokenType.BANG_EQ, AstFactory.identifier3("j"));
1357 _resolveNode(expression);
1358 var stringElement = stringType.element;
1359 expect(expression.staticElement, isNotNull);
1360 expect(
1361 expression.staticElement,
1362 stringElement.lookUpMethod(
1363 TokenType.EQ_EQ.lexeme, stringElement.library));
1364 expect(expression.propagatedElement, isNull);
1365 _listener.assertNoErrors();
1366 }
1367
1368 void test_visitBinaryExpression_eq() {
1369 // String i;
1370 // var j;
1371 // i == j
1372 InterfaceType stringType = _typeProvider.stringType;
1373 SimpleIdentifier left = AstFactory.identifier3("i");
1374 left.staticType = stringType;
1375 BinaryExpression expression = AstFactory.binaryExpression(
1376 left, TokenType.EQ_EQ, AstFactory.identifier3("j"));
1377 _resolveNode(expression);
1378 var stringElement = stringType.element;
1379 expect(
1380 expression.staticElement,
1381 stringElement.lookUpMethod(
1382 TokenType.EQ_EQ.lexeme, stringElement.library));
1383 expect(expression.propagatedElement, isNull);
1384 _listener.assertNoErrors();
1385 }
1386
1387 void test_visitBinaryExpression_plus() {
1388 // num i;
1389 // var j;
1390 // i + j
1391 InterfaceType numType = _typeProvider.numType;
1392 SimpleIdentifier left = AstFactory.identifier3("i");
1393 left.staticType = numType;
1394 BinaryExpression expression = AstFactory.binaryExpression(
1395 left, TokenType.PLUS, AstFactory.identifier3("j"));
1396 _resolveNode(expression);
1397 expect(expression.staticElement, getMethod(numType, "+"));
1398 expect(expression.propagatedElement, isNull);
1399 _listener.assertNoErrors();
1400 }
1401
1402 void test_visitBinaryExpression_plus_propagatedElement() {
1403 // var i = 1;
1404 // var j;
1405 // i + j
1406 InterfaceType numType = _typeProvider.numType;
1407 SimpleIdentifier left = AstFactory.identifier3("i");
1408 left.propagatedType = numType;
1409 BinaryExpression expression = AstFactory.binaryExpression(
1410 left, TokenType.PLUS, AstFactory.identifier3("j"));
1411 _resolveNode(expression);
1412 expect(expression.staticElement, isNull);
1413 expect(expression.propagatedElement, getMethod(numType, "+"));
1414 _listener.assertNoErrors();
1415 }
1416
1417 void test_visitBreakStatement_withLabel() {
1418 // loop: while (true) {
1419 // break loop;
1420 // }
1421 String label = "loop";
1422 LabelElementImpl labelElement =
1423 new LabelElementImpl(AstFactory.identifier3(label), false, false);
1424 BreakStatement breakStatement = AstFactory.breakStatement2(label);
1425 Expression condition = AstFactory.booleanLiteral(true);
1426 WhileStatement whileStatement =
1427 AstFactory.whileStatement(condition, breakStatement);
1428 expect(_resolveBreak(breakStatement, labelElement, whileStatement),
1429 same(labelElement));
1430 expect(breakStatement.target, same(whileStatement));
1431 _listener.assertNoErrors();
1432 }
1433
1434 void test_visitBreakStatement_withoutLabel() {
1435 BreakStatement statement = AstFactory.breakStatement();
1436 _resolveStatement(statement, null, null);
1437 _listener.assertNoErrors();
1438 }
1439
1440 void test_visitConstructorName_named() {
1441 ClassElementImpl classA = ElementFactory.classElement2("A");
1442 String constructorName = "a";
1443 ConstructorElement constructor =
1444 ElementFactory.constructorElement2(classA, constructorName);
1445 classA.constructors = <ConstructorElement>[constructor];
1446 ConstructorName name = AstFactory.constructorName(
1447 AstFactory.typeName(classA), constructorName);
1448 _resolveNode(name);
1449 expect(name.staticElement, same(constructor));
1450 _listener.assertNoErrors();
1451 }
1452
1453 void test_visitConstructorName_unnamed() {
1454 ClassElementImpl classA = ElementFactory.classElement2("A");
1455 String constructorName = null;
1456 ConstructorElement constructor =
1457 ElementFactory.constructorElement2(classA, constructorName);
1458 classA.constructors = <ConstructorElement>[constructor];
1459 ConstructorName name = AstFactory.constructorName(
1460 AstFactory.typeName(classA), constructorName);
1461 _resolveNode(name);
1462 expect(name.staticElement, same(constructor));
1463 _listener.assertNoErrors();
1464 }
1465
1466 void test_visitContinueStatement_withLabel() {
1467 // loop: while (true) {
1468 // continue loop;
1469 // }
1470 String label = "loop";
1471 LabelElementImpl labelElement =
1472 new LabelElementImpl(AstFactory.identifier3(label), false, false);
1473 ContinueStatement continueStatement = AstFactory.continueStatement(label);
1474 Expression condition = AstFactory.booleanLiteral(true);
1475 WhileStatement whileStatement =
1476 AstFactory.whileStatement(condition, continueStatement);
1477 expect(_resolveContinue(continueStatement, labelElement, whileStatement),
1478 same(labelElement));
1479 expect(continueStatement.target, same(whileStatement));
1480 _listener.assertNoErrors();
1481 }
1482
1483 void test_visitContinueStatement_withoutLabel() {
1484 ContinueStatement statement = AstFactory.continueStatement();
1485 _resolveStatement(statement, null, null);
1486 _listener.assertNoErrors();
1487 }
1488
1489 void test_visitEnumDeclaration() {
1490 ClassElementImpl enumElement =
1491 ElementFactory.enumElement(_typeProvider, ('E'));
1492 EnumDeclaration enumNode = AstFactory.enumDeclaration2('E', []);
1493 Annotation annotationNode =
1494 AstFactory.annotation(AstFactory.identifier3('a'));
1495 annotationNode.element = ElementFactory.classElement2('A');
1496 enumNode.metadata.add(annotationNode);
1497 enumNode.name.staticElement = enumElement;
1498 _resolveNode(enumNode);
1499 List<ElementAnnotation> metadata = enumElement.metadata;
1500 expect(metadata, hasLength(1));
1501 }
1502
1503 void test_visitExportDirective_noCombinators() {
1504 ExportDirective directive = AstFactory.exportDirective2(null);
1505 directive.element = ElementFactory
1506 .exportFor(ElementFactory.library(_definingLibrary.context, "lib"));
1507 _resolveNode(directive);
1508 _listener.assertNoErrors();
1509 }
1510
1511 void test_visitFieldFormalParameter() {
1512 String fieldName = "f";
1513 InterfaceType intType = _typeProvider.intType;
1514 FieldElementImpl fieldElement =
1515 ElementFactory.fieldElement(fieldName, false, false, false, intType);
1516 ClassElementImpl classA = ElementFactory.classElement2("A");
1517 classA.fields = <FieldElement>[fieldElement];
1518 FieldFormalParameter parameter =
1519 AstFactory.fieldFormalParameter2(fieldName);
1520 FieldFormalParameterElementImpl parameterElement =
1521 ElementFactory.fieldFormalParameter(parameter.identifier);
1522 parameterElement.field = fieldElement;
1523 parameterElement.type = intType;
1524 parameter.identifier.staticElement = parameterElement;
1525 _resolveInClass(parameter, classA);
1526 expect(parameter.element.type, same(intType));
1527 }
1528
1529 void test_visitImportDirective_noCombinators_noPrefix() {
1530 ImportDirective directive = AstFactory.importDirective3(null, null);
1531 directive.element = ElementFactory.importFor(
1532 ElementFactory.library(_definingLibrary.context, "lib"), null);
1533 _resolveNode(directive);
1534 _listener.assertNoErrors();
1535 }
1536
1537 void test_visitImportDirective_noCombinators_prefix() {
1538 String prefixName = "p";
1539 ImportElement importElement = ElementFactory.importFor(
1540 ElementFactory.library(_definingLibrary.context, "lib"),
1541 ElementFactory.prefix(prefixName));
1542 _definingLibrary.imports = <ImportElement>[importElement];
1543 ImportDirective directive = AstFactory.importDirective3(null, prefixName);
1544 directive.element = importElement;
1545 _resolveNode(directive);
1546 _listener.assertNoErrors();
1547 }
1548
1549 void test_visitImportDirective_withCombinators() {
1550 ShowCombinator combinator = AstFactory.showCombinator2(["A", "B", "C"]);
1551 ImportDirective directive =
1552 AstFactory.importDirective3(null, null, [combinator]);
1553 LibraryElementImpl library =
1554 ElementFactory.library(_definingLibrary.context, "lib");
1555 TopLevelVariableElementImpl varA =
1556 ElementFactory.topLevelVariableElement2("A");
1557 TopLevelVariableElementImpl varB =
1558 ElementFactory.topLevelVariableElement2("B");
1559 TopLevelVariableElementImpl varC =
1560 ElementFactory.topLevelVariableElement2("C");
1561 CompilationUnitElementImpl unit =
1562 library.definingCompilationUnit as CompilationUnitElementImpl;
1563 unit.accessors = <PropertyAccessorElement>[
1564 varA.getter,
1565 varA.setter,
1566 varB.getter,
1567 varC.setter
1568 ];
1569 unit.topLevelVariables = <TopLevelVariableElement>[varA, varB, varC];
1570 directive.element = ElementFactory.importFor(library, null);
1571 _resolveNode(directive);
1572 expect(combinator.shownNames[0].staticElement, same(varA));
1573 expect(combinator.shownNames[1].staticElement, same(varB));
1574 expect(combinator.shownNames[2].staticElement, same(varC));
1575 _listener.assertNoErrors();
1576 }
1577
1578 void test_visitIndexExpression_get() {
1579 ClassElementImpl classA = ElementFactory.classElement2("A");
1580 InterfaceType intType = _typeProvider.intType;
1581 MethodElement getter =
1582 ElementFactory.methodElement("[]", intType, [intType]);
1583 classA.methods = <MethodElement>[getter];
1584 SimpleIdentifier array = AstFactory.identifier3("a");
1585 array.staticType = classA.type;
1586 IndexExpression expression =
1587 AstFactory.indexExpression(array, AstFactory.identifier3("i"));
1588 expect(_resolveIndexExpression(expression), same(getter));
1589 _listener.assertNoErrors();
1590 }
1591
1592 void test_visitIndexExpression_set() {
1593 ClassElementImpl classA = ElementFactory.classElement2("A");
1594 InterfaceType intType = _typeProvider.intType;
1595 MethodElement setter =
1596 ElementFactory.methodElement("[]=", intType, [intType]);
1597 classA.methods = <MethodElement>[setter];
1598 SimpleIdentifier array = AstFactory.identifier3("a");
1599 array.staticType = classA.type;
1600 IndexExpression expression =
1601 AstFactory.indexExpression(array, AstFactory.identifier3("i"));
1602 AstFactory.assignmentExpression(
1603 expression, TokenType.EQ, AstFactory.integer(0));
1604 expect(_resolveIndexExpression(expression), same(setter));
1605 _listener.assertNoErrors();
1606 }
1607
1608 void test_visitInstanceCreationExpression_named() {
1609 ClassElementImpl classA = ElementFactory.classElement2("A");
1610 String constructorName = "a";
1611 ConstructorElement constructor =
1612 ElementFactory.constructorElement2(classA, constructorName);
1613 classA.constructors = <ConstructorElement>[constructor];
1614 ConstructorName name = AstFactory.constructorName(
1615 AstFactory.typeName(classA), constructorName);
1616 name.staticElement = constructor;
1617 InstanceCreationExpression creation =
1618 AstFactory.instanceCreationExpression(Keyword.NEW, name);
1619 _resolveNode(creation);
1620 expect(creation.staticElement, same(constructor));
1621 _listener.assertNoErrors();
1622 }
1623
1624 void test_visitInstanceCreationExpression_unnamed() {
1625 ClassElementImpl classA = ElementFactory.classElement2("A");
1626 String constructorName = null;
1627 ConstructorElement constructor =
1628 ElementFactory.constructorElement2(classA, constructorName);
1629 classA.constructors = <ConstructorElement>[constructor];
1630 ConstructorName name = AstFactory.constructorName(
1631 AstFactory.typeName(classA), constructorName);
1632 name.staticElement = constructor;
1633 InstanceCreationExpression creation =
1634 AstFactory.instanceCreationExpression(Keyword.NEW, name);
1635 _resolveNode(creation);
1636 expect(creation.staticElement, same(constructor));
1637 _listener.assertNoErrors();
1638 }
1639
1640 void test_visitInstanceCreationExpression_unnamed_namedParameter() {
1641 ClassElementImpl classA = ElementFactory.classElement2("A");
1642 String constructorName = null;
1643 ConstructorElementImpl constructor =
1644 ElementFactory.constructorElement2(classA, constructorName);
1645 String parameterName = "a";
1646 ParameterElement parameter = ElementFactory.namedParameter(parameterName);
1647 constructor.parameters = <ParameterElement>[parameter];
1648 classA.constructors = <ConstructorElement>[constructor];
1649 ConstructorName name = AstFactory.constructorName(
1650 AstFactory.typeName(classA), constructorName);
1651 name.staticElement = constructor;
1652 InstanceCreationExpression creation = AstFactory.instanceCreationExpression(
1653 Keyword.NEW,
1654 name,
1655 [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]);
1656 _resolveNode(creation);
1657 expect(creation.staticElement, same(constructor));
1658 expect(
1659 (creation.argumentList.arguments[0] as NamedExpression)
1660 .name
1661 .label
1662 .staticElement,
1663 same(parameter));
1664 _listener.assertNoErrors();
1665 }
1666
1667 void test_visitMethodInvocation() {
1668 InterfaceType numType = _typeProvider.numType;
1669 SimpleIdentifier left = AstFactory.identifier3("i");
1670 left.staticType = numType;
1671 String methodName = "abs";
1672 MethodInvocation invocation = AstFactory.methodInvocation(left, methodName);
1673 _resolveNode(invocation);
1674 expect(invocation.methodName.staticElement,
1675 same(getMethod(numType, methodName)));
1676 _listener.assertNoErrors();
1677 }
1678
1679 void test_visitMethodInvocation_namedParameter() {
1680 ClassElementImpl classA = ElementFactory.classElement2("A");
1681 String methodName = "m";
1682 String parameterName = "p";
1683 MethodElementImpl method = ElementFactory.methodElement(methodName, null);
1684 ParameterElement parameter = ElementFactory.namedParameter(parameterName);
1685 method.parameters = <ParameterElement>[parameter];
1686 classA.methods = <MethodElement>[method];
1687 SimpleIdentifier left = AstFactory.identifier3("i");
1688 left.staticType = classA.type;
1689 MethodInvocation invocation = AstFactory.methodInvocation(left, methodName,
1690 [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]);
1691 _resolveNode(invocation);
1692 expect(invocation.methodName.staticElement, same(method));
1693 expect(
1694 (invocation.argumentList.arguments[0] as NamedExpression)
1695 .name
1696 .label
1697 .staticElement,
1698 same(parameter));
1699 _listener.assertNoErrors();
1700 }
1701
1702 void test_visitPostfixExpression() {
1703 InterfaceType numType = _typeProvider.numType;
1704 SimpleIdentifier operand = AstFactory.identifier3("i");
1705 operand.staticType = numType;
1706 PostfixExpression expression =
1707 AstFactory.postfixExpression(operand, TokenType.PLUS_PLUS);
1708 _resolveNode(expression);
1709 expect(expression.staticElement, getMethod(numType, "+"));
1710 _listener.assertNoErrors();
1711 }
1712
1713 void test_visitPrefixedIdentifier_dynamic() {
1714 DartType dynamicType = _typeProvider.dynamicType;
1715 SimpleIdentifier target = AstFactory.identifier3("a");
1716 VariableElementImpl variable = ElementFactory.localVariableElement(target);
1717 variable.type = dynamicType;
1718 target.staticElement = variable;
1719 target.staticType = dynamicType;
1720 PrefixedIdentifier identifier =
1721 AstFactory.identifier(target, AstFactory.identifier3("b"));
1722 _resolveNode(identifier);
1723 expect(identifier.staticElement, isNull);
1724 expect(identifier.identifier.staticElement, isNull);
1725 _listener.assertNoErrors();
1726 }
1727
1728 void test_visitPrefixedIdentifier_nonDynamic() {
1729 ClassElementImpl classA = ElementFactory.classElement2("A");
1730 String getterName = "b";
1731 PropertyAccessorElement getter =
1732 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
1733 classA.accessors = <PropertyAccessorElement>[getter];
1734 SimpleIdentifier target = AstFactory.identifier3("a");
1735 VariableElementImpl variable = ElementFactory.localVariableElement(target);
1736 variable.type = classA.type;
1737 target.staticElement = variable;
1738 target.staticType = classA.type;
1739 PrefixedIdentifier identifier =
1740 AstFactory.identifier(target, AstFactory.identifier3(getterName));
1741 _resolveNode(identifier);
1742 expect(identifier.staticElement, same(getter));
1743 expect(identifier.identifier.staticElement, same(getter));
1744 _listener.assertNoErrors();
1745 }
1746
1747 void test_visitPrefixedIdentifier_staticClassMember_getter() {
1748 ClassElementImpl classA = ElementFactory.classElement2("A");
1749 // set accessors
1750 String propName = "b";
1751 PropertyAccessorElement getter =
1752 ElementFactory.getterElement(propName, false, _typeProvider.intType);
1753 PropertyAccessorElement setter =
1754 ElementFactory.setterElement(propName, false, _typeProvider.intType);
1755 classA.accessors = <PropertyAccessorElement>[getter, setter];
1756 // prepare "A.m"
1757 SimpleIdentifier target = AstFactory.identifier3("A");
1758 target.staticElement = classA;
1759 target.staticType = classA.type;
1760 PrefixedIdentifier identifier =
1761 AstFactory.identifier(target, AstFactory.identifier3(propName));
1762 // resolve
1763 _resolveNode(identifier);
1764 expect(identifier.staticElement, same(getter));
1765 expect(identifier.identifier.staticElement, same(getter));
1766 _listener.assertNoErrors();
1767 }
1768
1769 void test_visitPrefixedIdentifier_staticClassMember_method() {
1770 ClassElementImpl classA = ElementFactory.classElement2("A");
1771 // set methods
1772 String propName = "m";
1773 MethodElement method =
1774 ElementFactory.methodElement("m", _typeProvider.intType);
1775 classA.methods = <MethodElement>[method];
1776 // prepare "A.m"
1777 SimpleIdentifier target = AstFactory.identifier3("A");
1778 target.staticElement = classA;
1779 target.staticType = classA.type;
1780 PrefixedIdentifier identifier =
1781 AstFactory.identifier(target, AstFactory.identifier3(propName));
1782 AstFactory.assignmentExpression(
1783 identifier, TokenType.EQ, AstFactory.nullLiteral());
1784 // resolve
1785 _resolveNode(identifier);
1786 expect(identifier.staticElement, same(method));
1787 expect(identifier.identifier.staticElement, same(method));
1788 _listener.assertNoErrors();
1789 }
1790
1791 void test_visitPrefixedIdentifier_staticClassMember_setter() {
1792 ClassElementImpl classA = ElementFactory.classElement2("A");
1793 // set accessors
1794 String propName = "b";
1795 PropertyAccessorElement getter =
1796 ElementFactory.getterElement(propName, false, _typeProvider.intType);
1797 PropertyAccessorElement setter =
1798 ElementFactory.setterElement(propName, false, _typeProvider.intType);
1799 classA.accessors = <PropertyAccessorElement>[getter, setter];
1800 // prepare "A.b = null"
1801 SimpleIdentifier target = AstFactory.identifier3("A");
1802 target.staticElement = classA;
1803 target.staticType = classA.type;
1804 PrefixedIdentifier identifier =
1805 AstFactory.identifier(target, AstFactory.identifier3(propName));
1806 AstFactory.assignmentExpression(
1807 identifier, TokenType.EQ, AstFactory.nullLiteral());
1808 // resolve
1809 _resolveNode(identifier);
1810 expect(identifier.staticElement, same(setter));
1811 expect(identifier.identifier.staticElement, same(setter));
1812 _listener.assertNoErrors();
1813 }
1814
1815 void test_visitPrefixExpression() {
1816 InterfaceType numType = _typeProvider.numType;
1817 SimpleIdentifier operand = AstFactory.identifier3("i");
1818 operand.staticType = numType;
1819 PrefixExpression expression =
1820 AstFactory.prefixExpression(TokenType.PLUS_PLUS, operand);
1821 _resolveNode(expression);
1822 expect(expression.staticElement, getMethod(numType, "+"));
1823 _listener.assertNoErrors();
1824 }
1825
1826 void test_visitPropertyAccess_getter_identifier() {
1827 ClassElementImpl classA = ElementFactory.classElement2("A");
1828 String getterName = "b";
1829 PropertyAccessorElement getter =
1830 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
1831 classA.accessors = <PropertyAccessorElement>[getter];
1832 SimpleIdentifier target = AstFactory.identifier3("a");
1833 target.staticType = classA.type;
1834 PropertyAccess access = AstFactory.propertyAccess2(target, getterName);
1835 _resolveNode(access);
1836 expect(access.propertyName.staticElement, same(getter));
1837 _listener.assertNoErrors();
1838 }
1839
1840 void test_visitPropertyAccess_getter_super() {
1841 //
1842 // class A {
1843 // int get b;
1844 // }
1845 // class B {
1846 // ... super.m ...
1847 // }
1848 //
1849 ClassElementImpl classA = ElementFactory.classElement2("A");
1850 String getterName = "b";
1851 PropertyAccessorElement getter =
1852 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
1853 classA.accessors = <PropertyAccessorElement>[getter];
1854 SuperExpression target = AstFactory.superExpression();
1855 target.staticType = ElementFactory.classElement("B", classA.type).type;
1856 PropertyAccess access = AstFactory.propertyAccess2(target, getterName);
1857 AstFactory.methodDeclaration2(
1858 null,
1859 null,
1860 null,
1861 null,
1862 AstFactory.identifier3("m"),
1863 AstFactory.formalParameterList(),
1864 AstFactory.expressionFunctionBody(access));
1865 _resolveNode(access);
1866 expect(access.propertyName.staticElement, same(getter));
1867 _listener.assertNoErrors();
1868 }
1869
1870 void test_visitPropertyAccess_setter_this() {
1871 ClassElementImpl classA = ElementFactory.classElement2("A");
1872 String setterName = "b";
1873 PropertyAccessorElement setter =
1874 ElementFactory.setterElement(setterName, false, _typeProvider.intType);
1875 classA.accessors = <PropertyAccessorElement>[setter];
1876 ThisExpression target = AstFactory.thisExpression();
1877 target.staticType = classA.type;
1878 PropertyAccess access = AstFactory.propertyAccess2(target, setterName);
1879 AstFactory.assignmentExpression(
1880 access, TokenType.EQ, AstFactory.integer(0));
1881 _resolveNode(access);
1882 expect(access.propertyName.staticElement, same(setter));
1883 _listener.assertNoErrors();
1884 }
1885
1886 void test_visitSimpleIdentifier_classScope() {
1887 InterfaceType doubleType = _typeProvider.doubleType;
1888 String fieldName = "NAN";
1889 SimpleIdentifier node = AstFactory.identifier3(fieldName);
1890 _resolveInClass(node, doubleType.element);
1891 expect(node.staticElement, getGetter(doubleType, fieldName));
1892 _listener.assertNoErrors();
1893 }
1894
1895 void test_visitSimpleIdentifier_dynamic() {
1896 SimpleIdentifier node = AstFactory.identifier3("dynamic");
1897 _resolveIdentifier(node);
1898 expect(node.staticElement, same(_typeProvider.dynamicType.element));
1899 expect(node.staticType, same(_typeProvider.typeType));
1900 _listener.assertNoErrors();
1901 }
1902
1903 void test_visitSimpleIdentifier_lexicalScope() {
1904 SimpleIdentifier node = AstFactory.identifier3("i");
1905 VariableElementImpl element = ElementFactory.localVariableElement(node);
1906 expect(_resolveIdentifier(node, [element]), same(element));
1907 _listener.assertNoErrors();
1908 }
1909
1910 void test_visitSimpleIdentifier_lexicalScope_field_setter() {
1911 InterfaceType intType = _typeProvider.intType;
1912 ClassElementImpl classA = ElementFactory.classElement2("A");
1913 String fieldName = "a";
1914 FieldElement field =
1915 ElementFactory.fieldElement(fieldName, false, false, false, intType);
1916 classA.fields = <FieldElement>[field];
1917 classA.accessors = <PropertyAccessorElement>[field.getter, field.setter];
1918 SimpleIdentifier node = AstFactory.identifier3(fieldName);
1919 AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0));
1920 _resolveInClass(node, classA);
1921 Element element = node.staticElement;
1922 EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccessorElement,
1923 PropertyAccessorElement, element);
1924 expect((element as PropertyAccessorElement).isSetter, isTrue);
1925 _listener.assertNoErrors();
1926 }
1927
1928 void test_visitSuperConstructorInvocation() {
1929 ClassElementImpl superclass = ElementFactory.classElement2("A");
1930 ConstructorElementImpl superConstructor =
1931 ElementFactory.constructorElement2(superclass, null);
1932 superclass.constructors = <ConstructorElement>[superConstructor];
1933 ClassElementImpl subclass =
1934 ElementFactory.classElement("B", superclass.type);
1935 ConstructorElementImpl subConstructor =
1936 ElementFactory.constructorElement2(subclass, null);
1937 subclass.constructors = <ConstructorElement>[subConstructor];
1938 SuperConstructorInvocation invocation =
1939 AstFactory.superConstructorInvocation();
1940 _resolveInClass(invocation, subclass);
1941 expect(invocation.staticElement, superConstructor);
1942 _listener.assertNoErrors();
1943 }
1944
1945 void test_visitSuperConstructorInvocation_namedParameter() {
1946 ClassElementImpl superclass = ElementFactory.classElement2("A");
1947 ConstructorElementImpl superConstructor =
1948 ElementFactory.constructorElement2(superclass, null);
1949 String parameterName = "p";
1950 ParameterElement parameter = ElementFactory.namedParameter(parameterName);
1951 superConstructor.parameters = <ParameterElement>[parameter];
1952 superclass.constructors = <ConstructorElement>[superConstructor];
1953 ClassElementImpl subclass =
1954 ElementFactory.classElement("B", superclass.type);
1955 ConstructorElementImpl subConstructor =
1956 ElementFactory.constructorElement2(subclass, null);
1957 subclass.constructors = <ConstructorElement>[subConstructor];
1958 SuperConstructorInvocation invocation = AstFactory
1959 .superConstructorInvocation([
1960 AstFactory.namedExpression2(parameterName, AstFactory.integer(0))
1961 ]);
1962 _resolveInClass(invocation, subclass);
1963 expect(invocation.staticElement, superConstructor);
1964 expect(
1965 (invocation.argumentList.arguments[0] as NamedExpression)
1966 .name
1967 .label
1968 .staticElement,
1969 same(parameter));
1970 _listener.assertNoErrors();
1971 }
1972
1973 /**
1974 * Create the resolver used by the tests.
1975 *
1976 * @return the resolver that was created
1977 */
1978 ElementResolver _createResolver() {
1979 InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
1980 FileBasedSource source =
1981 new FileBasedSource(FileUtilities2.createFile("/test.dart"));
1982 CompilationUnitElementImpl definingCompilationUnit =
1983 new CompilationUnitElementImpl("test.dart");
1984 definingCompilationUnit.librarySource =
1985 definingCompilationUnit.source = source;
1986 _definingLibrary = ElementFactory.library(context, "test");
1987 _definingLibrary.definingCompilationUnit = definingCompilationUnit;
1988 Library library = new Library(context, _listener, source);
1989 library.libraryElement = _definingLibrary;
1990 _visitor = new ResolverVisitor(
1991 library.libraryElement, source, _typeProvider, library.errorListener,
1992 nameScope: library.libraryScope,
1993 inheritanceManager: library.inheritanceManager);
1994 try {
1995 return _visitor.elementResolver;
1996 } catch (exception) {
1997 throw new IllegalArgumentException(
1998 "Could not create resolver", exception);
1999 }
2000 }
2001
2002 /**
2003 * Return the element associated with the label of [statement] after the
2004 * resolver has resolved it. [labelElement] is the label element to be
2005 * defined in the statement's label scope, and [labelTarget] is the statement
2006 * the label resolves to.
2007 */
2008 Element _resolveBreak(BreakStatement statement, LabelElementImpl labelElement,
2009 Statement labelTarget) {
2010 _resolveStatement(statement, labelElement, labelTarget);
2011 return statement.label.staticElement;
2012 }
2013
2014 /**
2015 * Return the element associated with the label [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 AST node
2018 * the label resolves to.
2019 *
2020 * @param statement the statement to be resolved
2021 * @param labelElement the label element to be defined in the statement's labe l scope
2022 * @return the element to which the statement's label was resolved
2023 */
2024 Element _resolveContinue(ContinueStatement statement,
2025 LabelElementImpl labelElement, AstNode labelTarget) {
2026 _resolveStatement(statement, labelElement, labelTarget);
2027 return statement.label.staticElement;
2028 }
2029
2030 /**
2031 * Return the element associated with the given identifier after the resolver has resolved the
2032 * identifier.
2033 *
2034 * @param node the expression to be resolved
2035 * @param definedElements the elements that are to be defined in the scope in which the element is
2036 * being resolved
2037 * @return the element to which the expression was resolved
2038 */
2039 Element _resolveIdentifier(Identifier node, [List<Element> definedElements]) {
2040 _resolveNode(node, definedElements);
2041 return node.staticElement;
2042 }
2043
2044 /**
2045 * Return the element associated with the given identifier after the resolver has resolved the
2046 * identifier.
2047 *
2048 * @param node the expression to be resolved
2049 * @param enclosingClass the element representing the class enclosing the iden tifier
2050 * @return the element to which the expression was resolved
2051 */
2052 void _resolveInClass(AstNode node, ClassElement enclosingClass) {
2053 try {
2054 Scope outerScope = _visitor.nameScope;
2055 try {
2056 _visitor.enclosingClass = enclosingClass;
2057 EnclosedScope innerScope = new ClassScope(
2058 new TypeParameterScope(outerScope, enclosingClass), enclosingClass);
2059 _visitor.nameScope = innerScope;
2060 node.accept(_resolver);
2061 } finally {
2062 _visitor.enclosingClass = null;
2063 _visitor.nameScope = outerScope;
2064 }
2065 } catch (exception) {
2066 throw new IllegalArgumentException("Could not resolve node", exception);
2067 }
2068 }
2069
2070 /**
2071 * Return the element associated with the given expression after the resolver has resolved the
2072 * expression.
2073 *
2074 * @param node the expression to be resolved
2075 * @param definedElements the elements that are to be defined in the scope in which the element is
2076 * being resolved
2077 * @return the element to which the expression was resolved
2078 */
2079 Element _resolveIndexExpression(IndexExpression node,
2080 [List<Element> definedElements]) {
2081 _resolveNode(node, definedElements);
2082 return node.staticElement;
2083 }
2084
2085 /**
2086 * Return the element associated with the given identifier after the resolver has resolved the
2087 * identifier.
2088 *
2089 * @param node the expression to be resolved
2090 * @param definedElements the elements that are to be defined in the scope in which the element is
2091 * being resolved
2092 * @return the element to which the expression was resolved
2093 */
2094 void _resolveNode(AstNode node, [List<Element> definedElements]) {
2095 try {
2096 Scope outerScope = _visitor.nameScope;
2097 try {
2098 EnclosedScope innerScope = new EnclosedScope(outerScope);
2099 if (definedElements != null) {
2100 for (Element element in definedElements) {
2101 innerScope.define(element);
2102 }
2103 }
2104 _visitor.nameScope = innerScope;
2105 node.accept(_resolver);
2106 } finally {
2107 _visitor.nameScope = outerScope;
2108 }
2109 } catch (exception) {
2110 throw new IllegalArgumentException("Could not resolve node", exception);
2111 }
2112 }
2113
2114 /**
2115 * Return the element associated with the label of the given statement after t he resolver has
2116 * resolved the statement.
2117 *
2118 * @param statement the statement to be resolved
2119 * @param labelElement the label element to be defined in the statement's labe l scope
2120 * @return the element to which the statement's label was resolved
2121 */
2122 void _resolveStatement(
2123 Statement statement, LabelElementImpl labelElement, AstNode labelTarget) {
2124 try {
2125 LabelScope outerScope = _visitor.labelScope;
2126 try {
2127 LabelScope innerScope;
2128 if (labelElement == null) {
2129 innerScope = outerScope;
2130 } else {
2131 innerScope = new LabelScope(
2132 outerScope, labelElement.name, labelTarget, labelElement);
2133 }
2134 _visitor.labelScope = innerScope;
2135 statement.accept(_resolver);
2136 } finally {
2137 _visitor.labelScope = outerScope;
2138 }
2139 } catch (exception) {
2140 throw new IllegalArgumentException("Could not resolve node", exception);
2141 }
2142 }
2143 }
2144
2145 @reflectiveTest
2146 class EnclosedScopeTest extends ResolverTestCase {
2147 void test_define_duplicate() {
2148 GatheringErrorListener listener = new GatheringErrorListener();
2149 Scope rootScope =
2150 new Scope_EnclosedScopeTest_test_define_duplicate(listener);
2151 EnclosedScope scope = new EnclosedScope(rootScope);
2152 VariableElement element1 =
2153 ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
2154 VariableElement element2 =
2155 ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
2156 scope.define(element1);
2157 scope.define(element2);
2158 listener.assertErrorsWithSeverities([ErrorSeverity.ERROR]);
2159 }
2160
2161 void test_define_normal() {
2162 GatheringErrorListener listener = new GatheringErrorListener();
2163 Scope rootScope = new Scope_EnclosedScopeTest_test_define_normal(listener);
2164 EnclosedScope outerScope = new EnclosedScope(rootScope);
2165 EnclosedScope innerScope = new EnclosedScope(outerScope);
2166 VariableElement element1 =
2167 ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
2168 VariableElement element2 =
2169 ElementFactory.localVariableElement(AstFactory.identifier3("v2"));
2170 outerScope.define(element1);
2171 innerScope.define(element2);
2172 listener.assertNoErrors();
2173 }
2174 }
2175
2176 @reflectiveTest
2177 class ErrorResolverTest extends ResolverTestCase {
2178 void test_breakLabelOnSwitchMember() {
2179 Source source = addSource(r'''
2180 class A {
2181 void m(int i) {
2182 switch (i) {
2183 l: case 0:
2184 break;
2185 case 1:
2186 break l;
2187 }
2188 }
2189 }''');
2190 computeLibrarySourceErrors(source);
2191 assertErrors(source, [ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER]);
2192 verify([source]);
2193 }
2194
2195 void test_continueLabelOnSwitch() {
2196 Source source = addSource(r'''
2197 class A {
2198 void m(int i) {
2199 l: switch (i) {
2200 case 0:
2201 continue l;
2202 }
2203 }
2204 }''');
2205 computeLibrarySourceErrors(source);
2206 assertErrors(source, [ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH]);
2207 verify([source]);
2208 }
2209
2210 void test_enclosingElement_invalidLocalFunction() {
2211 Source source = addSource(r'''
2212 class C {
2213 C() {
2214 int get x => 0;
2215 }
2216 }''');
2217 LibraryElement library = resolve2(source);
2218 expect(library, isNotNull);
2219 var unit = library.definingCompilationUnit;
2220 expect(unit, isNotNull);
2221 var types = unit.types;
2222 expect(types, isNotNull);
2223 expect(types, hasLength(1));
2224 var type = types[0];
2225 expect(type, isNotNull);
2226 var constructors = type.constructors;
2227 expect(constructors, isNotNull);
2228 expect(constructors, hasLength(1));
2229 ConstructorElement constructor = constructors[0];
2230 expect(constructor, isNotNull);
2231 List<FunctionElement> functions = constructor.functions;
2232 expect(functions, isNotNull);
2233 expect(functions, hasLength(1));
2234 expect(functions[0].enclosingElement, constructor);
2235 assertErrors(source, [ParserErrorCode.GETTER_IN_FUNCTION]);
2236 }
2237 }
2238
2239 @reflectiveTest
2240 class HintCodeTest extends ResolverTestCase {
2241 void fail_deadCode_statementAfterRehrow() {
2242 Source source = addSource(r'''
2243 f() {
2244 try {
2245 var one = 1;
2246 } catch (e) {
2247 rethrow;
2248 var two = 2;
2249 }
2250 }''');
2251 computeLibrarySourceErrors(source);
2252 assertErrors(source, [HintCode.DEAD_CODE]);
2253 verify([source]);
2254 }
2255
2256 void fail_deadCode_statementAfterThrow() {
2257 Source source = addSource(r'''
2258 f() {
2259 var one = 1;
2260 throw 'Stop here';
2261 var two = 2;
2262 }''');
2263 computeLibrarySourceErrors(source);
2264 assertErrors(source, [HintCode.DEAD_CODE]);
2265 verify([source]);
2266 }
2267
2268 void fail_isInt() {
2269 Source source = addSource("var v = 1 is int;");
2270 computeLibrarySourceErrors(source);
2271 assertErrors(source, [HintCode.IS_INT]);
2272 verify([source]);
2273 }
2274
2275 void fail_isNotInt() {
2276 Source source = addSource("var v = 1 is! int;");
2277 computeLibrarySourceErrors(source);
2278 assertErrors(source, [HintCode.IS_NOT_INT]);
2279 verify([source]);
2280 }
2281
2282 void fail_overrideEqualsButNotHashCode() {
2283 Source source = addSource(r'''
2284 class A {
2285 bool operator ==(x) {}
2286 }''');
2287 computeLibrarySourceErrors(source);
2288 assertErrors(source, [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]);
2289 verify([source]);
2290 }
2291
2292 void fail_unusedImport_as_equalPrefixes() {
2293 // See todo at ImportsVerifier.prefixElementMap.
2294 Source source = addSource(r'''
2295 library L;
2296 import 'lib1.dart' as one;
2297 import 'lib2.dart' as one;
2298 one.A a;''');
2299 Source source2 = addNamedSource(
2300 "/lib1.dart",
2301 r'''
2302 library lib1;
2303 class A {}''');
2304 Source source3 = addNamedSource(
2305 "/lib2.dart",
2306 r'''
2307 library lib2;
2308 class B {}''');
2309 computeLibrarySourceErrors(source);
2310 assertErrors(source, [HintCode.UNUSED_IMPORT]);
2311 assertNoErrors(source2);
2312 assertNoErrors(source3);
2313 verify([source, source2, source3]);
2314 }
2315
2316 void test_argumentTypeNotAssignable_functionType() {
2317 Source source = addSource(r'''
2318 m() {
2319 var a = new A();
2320 a.n(() => 0);
2321 }
2322 class A {
2323 n(void f(int i)) {}
2324 }''');
2325 computeLibrarySourceErrors(source);
2326 assertErrors(source, [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
2327 verify([source]);
2328 }
2329
2330 void test_argumentTypeNotAssignable_message() {
2331 // The implementation of HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE assumes that
2332 // StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE has the same message.
2333 expect(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE.message,
2334 HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE.message);
2335 }
2336
2337 void test_argumentTypeNotAssignable_type() {
2338 Source source = addSource(r'''
2339 m() {
2340 var i = '';
2341 n(i);
2342 }
2343 n(int i) {}''');
2344 computeLibrarySourceErrors(source);
2345 assertErrors(source, [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
2346 verify([source]);
2347 }
2348
2349 void test_deadCode_deadBlock_conditionalElse() {
2350 Source source = addSource(r'''
2351 f() {
2352 true ? 1 : 2;
2353 }''');
2354 computeLibrarySourceErrors(source);
2355 assertErrors(source, [HintCode.DEAD_CODE]);
2356 verify([source]);
2357 }
2358
2359 void test_deadCode_deadBlock_conditionalElse_nested() {
2360 // test that a dead else-statement can't generate additional violations
2361 Source source = addSource(r'''
2362 f() {
2363 true ? true : false && false;
2364 }''');
2365 computeLibrarySourceErrors(source);
2366 assertErrors(source, [HintCode.DEAD_CODE]);
2367 verify([source]);
2368 }
2369
2370 void test_deadCode_deadBlock_conditionalIf() {
2371 Source source = addSource(r'''
2372 f() {
2373 false ? 1 : 2;
2374 }''');
2375 computeLibrarySourceErrors(source);
2376 assertErrors(source, [HintCode.DEAD_CODE]);
2377 verify([source]);
2378 }
2379
2380 void test_deadCode_deadBlock_conditionalIf_nested() {
2381 // test that a dead then-statement can't generate additional violations
2382 Source source = addSource(r'''
2383 f() {
2384 false ? false && false : true;
2385 }''');
2386 computeLibrarySourceErrors(source);
2387 assertErrors(source, [HintCode.DEAD_CODE]);
2388 verify([source]);
2389 }
2390
2391 void test_deadCode_deadBlock_else() {
2392 Source source = addSource(r'''
2393 f() {
2394 if(true) {} else {}
2395 }''');
2396 computeLibrarySourceErrors(source);
2397 assertErrors(source, [HintCode.DEAD_CODE]);
2398 verify([source]);
2399 }
2400
2401 void test_deadCode_deadBlock_else_nested() {
2402 // test that a dead else-statement can't generate additional violations
2403 Source source = addSource(r'''
2404 f() {
2405 if(true) {} else {if (false) {}}
2406 }''');
2407 computeLibrarySourceErrors(source);
2408 assertErrors(source, [HintCode.DEAD_CODE]);
2409 verify([source]);
2410 }
2411
2412 void test_deadCode_deadBlock_if() {
2413 Source source = addSource(r'''
2414 f() {
2415 if(false) {}
2416 }''');
2417 computeLibrarySourceErrors(source);
2418 assertErrors(source, [HintCode.DEAD_CODE]);
2419 verify([source]);
2420 }
2421
2422 void test_deadCode_deadBlock_if_nested() {
2423 // test that a dead then-statement can't generate additional violations
2424 Source source = addSource(r'''
2425 f() {
2426 if(false) {if(false) {}}
2427 }''');
2428 computeLibrarySourceErrors(source);
2429 assertErrors(source, [HintCode.DEAD_CODE]);
2430 verify([source]);
2431 }
2432
2433 void test_deadCode_deadBlock_while() {
2434 Source source = addSource(r'''
2435 f() {
2436 while(false) {}
2437 }''');
2438 computeLibrarySourceErrors(source);
2439 assertErrors(source, [HintCode.DEAD_CODE]);
2440 verify([source]);
2441 }
2442
2443 void test_deadCode_deadBlock_while_nested() {
2444 // test that a dead while body can't generate additional violations
2445 Source source = addSource(r'''
2446 f() {
2447 while(false) {if(false) {}}
2448 }''');
2449 computeLibrarySourceErrors(source);
2450 assertErrors(source, [HintCode.DEAD_CODE]);
2451 verify([source]);
2452 }
2453
2454 void test_deadCode_deadCatch_catchFollowingCatch() {
2455 Source source = addSource(r'''
2456 class A {}
2457 f() {
2458 try {} catch (e) {} catch (e) {}
2459 }''');
2460 computeLibrarySourceErrors(source);
2461 assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
2462 verify([source]);
2463 }
2464
2465 void test_deadCode_deadCatch_catchFollowingCatch_nested() {
2466 // test that a dead catch clause can't generate additional violations
2467 Source source = addSource(r'''
2468 class A {}
2469 f() {
2470 try {} catch (e) {} catch (e) {if(false) {}}
2471 }''');
2472 computeLibrarySourceErrors(source);
2473 assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
2474 verify([source]);
2475 }
2476
2477 void test_deadCode_deadCatch_catchFollowingCatch_object() {
2478 Source source = addSource(r'''
2479 f() {
2480 try {} on Object catch (e) {} catch (e) {}
2481 }''');
2482 computeLibrarySourceErrors(source);
2483 assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
2484 verify([source]);
2485 }
2486
2487 void test_deadCode_deadCatch_catchFollowingCatch_object_nested() {
2488 // test that a dead catch clause can't generate additional violations
2489 Source source = addSource(r'''
2490 f() {
2491 try {} on Object catch (e) {} catch (e) {if(false) {}}
2492 }''');
2493 computeLibrarySourceErrors(source);
2494 assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
2495 verify([source]);
2496 }
2497
2498 void test_deadCode_deadCatch_onCatchSubtype() {
2499 Source source = addSource(r'''
2500 class A {}
2501 class B extends A {}
2502 f() {
2503 try {} on A catch (e) {} on B catch (e) {}
2504 }''');
2505 computeLibrarySourceErrors(source);
2506 assertErrors(source, [HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]);
2507 verify([source]);
2508 }
2509
2510 void test_deadCode_deadCatch_onCatchSubtype_nested() {
2511 // test that a dead catch clause can't generate additional violations
2512 Source source = addSource(r'''
2513 class A {}
2514 class B extends A {}
2515 f() {
2516 try {} on A catch (e) {} on B catch (e) {if(false) {}}
2517 }''');
2518 computeLibrarySourceErrors(source);
2519 assertErrors(source, [HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]);
2520 verify([source]);
2521 }
2522
2523 void test_deadCode_deadOperandLHS_and() {
2524 Source source = addSource(r'''
2525 f() {
2526 bool b = false && false;
2527 }''');
2528 computeLibrarySourceErrors(source);
2529 assertErrors(source, [HintCode.DEAD_CODE]);
2530 verify([source]);
2531 }
2532
2533 void test_deadCode_deadOperandLHS_and_nested() {
2534 Source source = addSource(r'''
2535 f() {
2536 bool b = false && (false && false);
2537 }''');
2538 computeLibrarySourceErrors(source);
2539 assertErrors(source, [HintCode.DEAD_CODE]);
2540 verify([source]);
2541 }
2542
2543 void test_deadCode_deadOperandLHS_or() {
2544 Source source = addSource(r'''
2545 f() {
2546 bool b = true || true;
2547 }''');
2548 computeLibrarySourceErrors(source);
2549 assertErrors(source, [HintCode.DEAD_CODE]);
2550 verify([source]);
2551 }
2552
2553 void test_deadCode_deadOperandLHS_or_nested() {
2554 Source source = addSource(r'''
2555 f() {
2556 bool b = true || (false && false);
2557 }''');
2558 computeLibrarySourceErrors(source);
2559 assertErrors(source, [HintCode.DEAD_CODE]);
2560 verify([source]);
2561 }
2562
2563 void test_deadCode_statementAfterBreak_inDefaultCase() {
2564 Source source = addSource(r'''
2565 f(v) {
2566 switch(v) {
2567 case 1:
2568 default:
2569 break;
2570 var a;
2571 }
2572 }''');
2573 computeLibrarySourceErrors(source);
2574 assertErrors(source, [HintCode.DEAD_CODE]);
2575 verify([source]);
2576 }
2577
2578 void test_deadCode_statementAfterBreak_inForEachStatement() {
2579 Source source = addSource(r'''
2580 f() {
2581 var list;
2582 for(var l in list) {
2583 break;
2584 var a;
2585 }
2586 }''');
2587 computeLibrarySourceErrors(source);
2588 assertErrors(source, [HintCode.DEAD_CODE]);
2589 verify([source]);
2590 }
2591
2592 void test_deadCode_statementAfterBreak_inForStatement() {
2593 Source source = addSource(r'''
2594 f() {
2595 for(;;) {
2596 break;
2597 var a;
2598 }
2599 }''');
2600 computeLibrarySourceErrors(source);
2601 assertErrors(source, [HintCode.DEAD_CODE]);
2602 verify([source]);
2603 }
2604
2605 void test_deadCode_statementAfterBreak_inSwitchCase() {
2606 Source source = addSource(r'''
2607 f(v) {
2608 switch(v) {
2609 case 1:
2610 break;
2611 var a;
2612 }
2613 }''');
2614 computeLibrarySourceErrors(source);
2615 assertErrors(source, [HintCode.DEAD_CODE]);
2616 verify([source]);
2617 }
2618
2619 void test_deadCode_statementAfterBreak_inWhileStatement() {
2620 Source source = addSource(r'''
2621 f(v) {
2622 while(v) {
2623 break;
2624 var a;
2625 }
2626 }''');
2627 computeLibrarySourceErrors(source);
2628 assertErrors(source, [HintCode.DEAD_CODE]);
2629 verify([source]);
2630 }
2631
2632 void test_deadCode_statementAfterContinue_inForEachStatement() {
2633 Source source = addSource(r'''
2634 f() {
2635 var list;
2636 for(var l in list) {
2637 continue;
2638 var a;
2639 }
2640 }''');
2641 computeLibrarySourceErrors(source);
2642 assertErrors(source, [HintCode.DEAD_CODE]);
2643 verify([source]);
2644 }
2645
2646 void test_deadCode_statementAfterContinue_inForStatement() {
2647 Source source = addSource(r'''
2648 f() {
2649 for(;;) {
2650 continue;
2651 var a;
2652 }
2653 }''');
2654 computeLibrarySourceErrors(source);
2655 assertErrors(source, [HintCode.DEAD_CODE]);
2656 verify([source]);
2657 }
2658
2659 void test_deadCode_statementAfterContinue_inWhileStatement() {
2660 Source source = addSource(r'''
2661 f(v) {
2662 while(v) {
2663 continue;
2664 var a;
2665 }
2666 }''');
2667 computeLibrarySourceErrors(source);
2668 assertErrors(source, [HintCode.DEAD_CODE]);
2669 verify([source]);
2670 }
2671
2672 void test_deadCode_statementAfterReturn_function() {
2673 Source source = addSource(r'''
2674 f() {
2675 var one = 1;
2676 return;
2677 var two = 2;
2678 }''');
2679 computeLibrarySourceErrors(source);
2680 assertErrors(source, [HintCode.DEAD_CODE]);
2681 verify([source]);
2682 }
2683
2684 void test_deadCode_statementAfterReturn_ifStatement() {
2685 Source source = addSource(r'''
2686 f(bool b) {
2687 if(b) {
2688 var one = 1;
2689 return;
2690 var two = 2;
2691 }
2692 }''');
2693 computeLibrarySourceErrors(source);
2694 assertErrors(source, [HintCode.DEAD_CODE]);
2695 verify([source]);
2696 }
2697
2698 void test_deadCode_statementAfterReturn_method() {
2699 Source source = addSource(r'''
2700 class A {
2701 m() {
2702 var one = 1;
2703 return;
2704 var two = 2;
2705 }
2706 }''');
2707 computeLibrarySourceErrors(source);
2708 assertErrors(source, [HintCode.DEAD_CODE]);
2709 verify([source]);
2710 }
2711
2712 void test_deadCode_statementAfterReturn_nested() {
2713 Source source = addSource(r'''
2714 f() {
2715 var one = 1;
2716 return;
2717 if(false) {}
2718 }''');
2719 computeLibrarySourceErrors(source);
2720 assertErrors(source, [HintCode.DEAD_CODE]);
2721 verify([source]);
2722 }
2723
2724 void test_deadCode_statementAfterReturn_twoReturns() {
2725 Source source = addSource(r'''
2726 f() {
2727 var one = 1;
2728 return;
2729 var two = 2;
2730 return;
2731 var three = 3;
2732 }''');
2733 computeLibrarySourceErrors(source);
2734 assertErrors(source, [HintCode.DEAD_CODE]);
2735 verify([source]);
2736 }
2737
2738 void test_deprecatedAnnotationUse_assignment() {
2739 Source source = addSource(r'''
2740 class A {
2741 @deprecated
2742 A operator+(A a) { return a; }
2743 }
2744 f(A a) {
2745 A b;
2746 a += b;
2747 }''');
2748 computeLibrarySourceErrors(source);
2749 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2750 verify([source]);
2751 }
2752
2753 void test_deprecatedAnnotationUse_Deprecated() {
2754 Source source = addSource(r'''
2755 class A {
2756 @Deprecated('0.9')
2757 m() {}
2758 n() {m();}
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
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_export() {
2778 Source source = addSource("export 'deprecated_library.dart';");
2779 addNamedSource(
2780 "/deprecated_library.dart",
2781 r'''
2782 @deprecated
2783 library deprecated_library;
2784 class A {}''');
2785 computeLibrarySourceErrors(source);
2786 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2787 verify([source]);
2788 }
2789
2790 void test_deprecatedAnnotationUse_getter() {
2791 Source source = addSource(r'''
2792 class A {
2793 @deprecated
2794 get m => 1;
2795 }
2796 f(A a) {
2797 return a.m;
2798 }''');
2799 computeLibrarySourceErrors(source);
2800 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2801 verify([source]);
2802 }
2803
2804 void test_deprecatedAnnotationUse_import() {
2805 Source source = addSource(r'''
2806 import 'deprecated_library.dart';
2807 f(A a) {}''');
2808 addNamedSource(
2809 "/deprecated_library.dart",
2810 r'''
2811 @deprecated
2812 library deprecated_library;
2813 class A {}''');
2814 computeLibrarySourceErrors(source);
2815 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2816 verify([source]);
2817 }
2818
2819 void test_deprecatedAnnotationUse_indexExpression() {
2820 Source source = addSource(r'''
2821 class A {
2822 @deprecated
2823 operator[](int i) {}
2824 }
2825 f(A a) {
2826 return a[1];
2827 }''');
2828 computeLibrarySourceErrors(source);
2829 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2830 verify([source]);
2831 }
2832
2833 void test_deprecatedAnnotationUse_instanceCreation() {
2834 Source source = addSource(r'''
2835 class A {
2836 @deprecated
2837 A(int i) {}
2838 }
2839 f() {
2840 A a = new A(1);
2841 }''');
2842 computeLibrarySourceErrors(source);
2843 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2844 verify([source]);
2845 }
2846
2847 void test_deprecatedAnnotationUse_instanceCreation_namedConstructor() {
2848 Source source = addSource(r'''
2849 class A {
2850 @deprecated
2851 A.named(int i) {}
2852 }
2853 f() {
2854 A a = new A.named(1);
2855 }''');
2856 computeLibrarySourceErrors(source);
2857 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2858 verify([source]);
2859 }
2860
2861 void test_deprecatedAnnotationUse_operator() {
2862 Source source = addSource(r'''
2863 class A {
2864 @deprecated
2865 operator+(A a) {}
2866 }
2867 f(A a) {
2868 A b;
2869 return a + b;
2870 }''');
2871 computeLibrarySourceErrors(source);
2872 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2873 verify([source]);
2874 }
2875
2876 void test_deprecatedAnnotationUse_setter() {
2877 Source source = addSource(r'''
2878 class A {
2879 @deprecated
2880 set s(v) {}
2881 }
2882 f(A a) {
2883 return a.s = 1;
2884 }''');
2885 computeLibrarySourceErrors(source);
2886 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2887 verify([source]);
2888 }
2889
2890 void test_deprecatedAnnotationUse_superConstructor() {
2891 Source source = addSource(r'''
2892 class A {
2893 @deprecated
2894 A() {}
2895 }
2896 class B extends A {
2897 B() : super() {}
2898 }''');
2899 computeLibrarySourceErrors(source);
2900 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2901 verify([source]);
2902 }
2903
2904 void test_deprecatedAnnotationUse_superConstructor_namedConstructor() {
2905 Source source = addSource(r'''
2906 class A {
2907 @deprecated
2908 A.named() {}
2909 }
2910 class B extends A {
2911 B() : super.named() {}
2912 }''');
2913 computeLibrarySourceErrors(source);
2914 assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
2915 verify([source]);
2916 }
2917
2918 void test_divisionOptimization_double() {
2919 Source source = addSource(r'''
2920 f(double x, double y) {
2921 var v = (x / y).toInt();
2922 }''');
2923 computeLibrarySourceErrors(source);
2924 assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
2925 verify([source]);
2926 }
2927
2928 void test_divisionOptimization_int() {
2929 Source source = addSource(r'''
2930 f(int x, int y) {
2931 var v = (x / y).toInt();
2932 }''');
2933 computeLibrarySourceErrors(source);
2934 assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
2935 verify([source]);
2936 }
2937
2938 void test_divisionOptimization_propagatedType() {
2939 // Tests the propagated type information of the '/' method
2940 Source source = addSource(r'''
2941 f(x, y) {
2942 x = 1;
2943 y = 1;
2944 var v = (x / y).toInt();
2945 }''');
2946 computeLibrarySourceErrors(source);
2947 assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
2948 verify([source]);
2949 }
2950
2951 void test_divisionOptimization_wrappedBinaryExpression() {
2952 Source source = addSource(r'''
2953 f(int x, int y) {
2954 var v = (((x / y))).toInt();
2955 }''');
2956 computeLibrarySourceErrors(source);
2957 assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
2958 verify([source]);
2959 }
2960
2961 void test_duplicateImport() {
2962 Source source = addSource(r'''
2963 library L;
2964 import 'lib1.dart';
2965 import 'lib1.dart';
2966 A a;''');
2967 addNamedSource(
2968 "/lib1.dart",
2969 r'''
2970 library lib1;
2971 class A {}''');
2972 computeLibrarySourceErrors(source);
2973 assertErrors(source, [HintCode.DUPLICATE_IMPORT]);
2974 verify([source]);
2975 }
2976
2977 void test_duplicateImport2() {
2978 Source source = addSource(r'''
2979 library L;
2980 import 'lib1.dart';
2981 import 'lib1.dart';
2982 import 'lib1.dart';
2983 A a;''');
2984 addNamedSource(
2985 "/lib1.dart",
2986 r'''
2987 library lib1;
2988 class A {}''');
2989 computeLibrarySourceErrors(source);
2990 assertErrors(
2991 source, [HintCode.DUPLICATE_IMPORT, HintCode.DUPLICATE_IMPORT]);
2992 verify([source]);
2993 }
2994
2995 void test_duplicateImport3() {
2996 Source source = addSource(r'''
2997 library L;
2998 import 'lib1.dart' as M show A hide B;
2999 import 'lib1.dart' as M show A hide B;
3000 M.A a;''');
3001 addNamedSource(
3002 "/lib1.dart",
3003 r'''
3004 library lib1;
3005 class A {}
3006 class B {}''');
3007 computeLibrarySourceErrors(source);
3008 assertErrors(source, [HintCode.DUPLICATE_IMPORT]);
3009 verify([source]);
3010 }
3011
3012 void test_importDeferredLibraryWithLoadFunction() {
3013 resolveWithErrors(<String>[
3014 r'''
3015 library lib1;
3016 loadLibrary() {}
3017 f() {}''',
3018 r'''
3019 library root;
3020 import 'lib1.dart' deferred as lib1;
3021 main() { lib1.f(); }'''
3022 ], <ErrorCode>[
3023 HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION
3024 ]);
3025 }
3026
3027 void test_invalidAssignment_instanceVariable() {
3028 Source source = addSource(r'''
3029 class A {
3030 int x;
3031 }
3032 f(var y) {
3033 A a;
3034 if(y is String) {
3035 a.x = y;
3036 }
3037 }''');
3038 computeLibrarySourceErrors(source);
3039 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
3040 verify([source]);
3041 }
3042
3043 void test_invalidAssignment_localVariable() {
3044 Source source = addSource(r'''
3045 f(var y) {
3046 if(y is String) {
3047 int x = y;
3048 }
3049 }''');
3050 computeLibrarySourceErrors(source);
3051 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
3052 verify([source]);
3053 }
3054
3055 void test_invalidAssignment_message() {
3056 // The implementation of HintCode.INVALID_ASSIGNMENT assumes that
3057 // StaticTypeWarningCode.INVALID_ASSIGNMENT has the same message.
3058 expect(StaticTypeWarningCode.INVALID_ASSIGNMENT.message,
3059 HintCode.INVALID_ASSIGNMENT.message);
3060 }
3061
3062 void test_invalidAssignment_staticVariable() {
3063 Source source = addSource(r'''
3064 class A {
3065 static int x;
3066 }
3067 f(var y) {
3068 if(y is String) {
3069 A.x = y;
3070 }
3071 }''');
3072 computeLibrarySourceErrors(source);
3073 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
3074 verify([source]);
3075 }
3076
3077 void test_invalidAssignment_variableDeclaration() {
3078 // 17971
3079 Source source = addSource(r'''
3080 class Point {
3081 final num x, y;
3082 Point(this.x, this.y);
3083 Point operator +(Point other) {
3084 return new Point(x+other.x, y+other.y);
3085 }
3086 }
3087 main() {
3088 var p1 = new Point(0, 0);
3089 var p2 = new Point(10, 10);
3090 int n = p1 + p2;
3091 }''');
3092 computeLibrarySourceErrors(source);
3093 assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
3094 verify([source]);
3095 }
3096
3097 void test_isDouble() {
3098 AnalysisOptionsImpl options = new AnalysisOptionsImpl();
3099 options.dart2jsHint = true;
3100 resetWithOptions(options);
3101 Source source = addSource("var v = 1 is double;");
3102 computeLibrarySourceErrors(source);
3103 assertErrors(source, [HintCode.IS_DOUBLE]);
3104 verify([source]);
3105 }
3106
3107 void test_isNotDouble() {
3108 AnalysisOptionsImpl options = new AnalysisOptionsImpl();
3109 options.dart2jsHint = true;
3110 resetWithOptions(options);
3111 Source source = addSource("var v = 1 is! double;");
3112 computeLibrarySourceErrors(source);
3113 assertErrors(source, [HintCode.IS_NOT_DOUBLE]);
3114 verify([source]);
3115 }
3116
3117 void test_missingReturn_async() {
3118 Source source = addSource('''
3119 import 'dart:async';
3120 Future<int> f() async {}
3121 ''');
3122 computeLibrarySourceErrors(source);
3123 assertErrors(source, [HintCode.MISSING_RETURN]);
3124 verify([source]);
3125 }
3126
3127 void test_missingReturn_function() {
3128 Source source = addSource("int f() {}");
3129 computeLibrarySourceErrors(source);
3130 assertErrors(source, [HintCode.MISSING_RETURN]);
3131 verify([source]);
3132 }
3133
3134 void test_missingReturn_method() {
3135 Source source = addSource(r'''
3136 class A {
3137 int m() {}
3138 }''');
3139 computeLibrarySourceErrors(source);
3140 assertErrors(source, [HintCode.MISSING_RETURN]);
3141 verify([source]);
3142 }
3143
3144 void test_overrideOnNonOverridingGetter_invalid() {
3145 Source source = addSource(r'''
3146 library dart.core;
3147 const override = null;
3148 class A {
3149 }
3150 class B extends A {
3151 @override
3152 int get m => 1;
3153 }''');
3154 computeLibrarySourceErrors(source);
3155 assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER]);
3156 verify([source]);
3157 }
3158
3159 void test_overrideOnNonOverridingMethod_invalid() {
3160 Source source = addSource(r'''
3161 library dart.core;
3162 const override = null;
3163 class A {
3164 }
3165 class B extends A {
3166 @override
3167 int m() => 1;
3168 }''');
3169 computeLibrarySourceErrors(source);
3170 assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]);
3171 verify([source]);
3172 }
3173
3174 void test_overrideOnNonOverridingSetter_invalid() {
3175 Source source = addSource(r'''
3176 library dart.core;
3177 const override = null;
3178 class A {
3179 }
3180 class B extends A {
3181 @override
3182 set m(int x) {}
3183 }''');
3184 computeLibrarySourceErrors(source);
3185 assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER]);
3186 verify([source]);
3187 }
3188
3189 void test_typeCheck_type_is_Null() {
3190 Source source = addSource(r'''
3191 m(i) {
3192 bool b = i is Null;
3193 }''');
3194 computeLibrarySourceErrors(source);
3195 assertErrors(source, [HintCode.TYPE_CHECK_IS_NULL]);
3196 verify([source]);
3197 }
3198
3199 void test_typeCheck_type_not_Null() {
3200 Source source = addSource(r'''
3201 m(i) {
3202 bool b = i is! Null;
3203 }''');
3204 computeLibrarySourceErrors(source);
3205 assertErrors(source, [HintCode.TYPE_CHECK_IS_NOT_NULL]);
3206 verify([source]);
3207 }
3208
3209 void test_undefinedGetter() {
3210 Source source = addSource(r'''
3211 class A {}
3212 f(var a) {
3213 if(a is A) {
3214 return a.m;
3215 }
3216 }''');
3217 computeLibrarySourceErrors(source);
3218 assertErrors(source, [HintCode.UNDEFINED_GETTER]);
3219 }
3220
3221 void test_undefinedGetter_message() {
3222 // The implementation of HintCode.UNDEFINED_SETTER assumes that
3223 // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the
3224 // same, this verifies that assumption.
3225 expect(StaticWarningCode.UNDEFINED_GETTER.message,
3226 StaticTypeWarningCode.UNDEFINED_GETTER.message);
3227 }
3228
3229 void test_undefinedMethod() {
3230 Source source = addSource(r'''
3231 f() {
3232 var a = 'str';
3233 a.notAMethodOnString();
3234 }''');
3235 computeLibrarySourceErrors(source);
3236 assertErrors(source, [HintCode.UNDEFINED_METHOD]);
3237 }
3238
3239 void test_undefinedMethod_assignmentExpression() {
3240 Source source = addSource(r'''
3241 class A {}
3242 class B {
3243 f(var a, var a2) {
3244 a = new A();
3245 a2 = new A();
3246 a += a2;
3247 }
3248 }''');
3249 computeLibrarySourceErrors(source);
3250 assertErrors(source, [HintCode.UNDEFINED_METHOD]);
3251 }
3252
3253 void test_undefinedOperator_binaryExpression() {
3254 Source source = addSource(r'''
3255 class A {}
3256 f(var a) {
3257 if(a is A) {
3258 a + 1;
3259 }
3260 }''');
3261 computeLibrarySourceErrors(source);
3262 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
3263 }
3264
3265 void test_undefinedOperator_indexBoth() {
3266 Source source = addSource(r'''
3267 class A {}
3268 f(var a) {
3269 if(a is A) {
3270 a[0]++;
3271 }
3272 }''');
3273 computeLibrarySourceErrors(source);
3274 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
3275 }
3276
3277 void test_undefinedOperator_indexGetter() {
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_indexSetter() {
3290 Source source = addSource(r'''
3291 class A {}
3292 f(var a) {
3293 if(a is A) {
3294 a[0] = 1;
3295 }
3296 }''');
3297 computeLibrarySourceErrors(source);
3298 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
3299 }
3300
3301 void test_undefinedOperator_postfixExpression() {
3302 Source source = addSource(r'''
3303 class A {}
3304 f(var a) {
3305 if(a is A) {
3306 a++;
3307 }
3308 }''');
3309 computeLibrarySourceErrors(source);
3310 assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
3311 }
3312
3313 void test_undefinedOperator_prefixExpression() {
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_undefinedSetter() {
3326 Source source = addSource(r'''
3327 class A {}
3328 f(var a) {
3329 if(a is A) {
3330 a.m = 0;
3331 }
3332 }''');
3333 computeLibrarySourceErrors(source);
3334 assertErrors(source, [HintCode.UNDEFINED_SETTER]);
3335 }
3336
3337 void test_undefinedSetter_message() {
3338 // The implementation of HintCode.UNDEFINED_SETTER assumes that
3339 // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the
3340 // same, this verifies that assumption.
3341 expect(StaticWarningCode.UNDEFINED_SETTER.message,
3342 StaticTypeWarningCode.UNDEFINED_SETTER.message);
3343 }
3344
3345 void test_unnecessaryCast_type_supertype() {
3346 Source source = addSource(r'''
3347 m(int i) {
3348 var b = i as Object;
3349 }''');
3350 computeLibrarySourceErrors(source);
3351 assertErrors(source, [HintCode.UNNECESSARY_CAST]);
3352 verify([source]);
3353 }
3354
3355 void test_unnecessaryCast_type_type() {
3356 Source source = addSource(r'''
3357 m(num i) {
3358 var b = i as num;
3359 }''');
3360 computeLibrarySourceErrors(source);
3361 assertErrors(source, [HintCode.UNNECESSARY_CAST]);
3362 verify([source]);
3363 }
3364
3365 void test_unnecessaryTypeCheck_null_is_Null() {
3366 Source source = addSource("bool b = null is Null;");
3367 computeLibrarySourceErrors(source);
3368 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
3369 verify([source]);
3370 }
3371
3372 void test_unnecessaryTypeCheck_null_not_Null() {
3373 Source source = addSource("bool b = null is! Null;");
3374 computeLibrarySourceErrors(source);
3375 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
3376 verify([source]);
3377 }
3378
3379 void test_unnecessaryTypeCheck_type_is_dynamic() {
3380 Source source = addSource(r'''
3381 m(i) {
3382 bool b = i is dynamic;
3383 }''');
3384 computeLibrarySourceErrors(source);
3385 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
3386 verify([source]);
3387 }
3388
3389 void test_unnecessaryTypeCheck_type_is_object() {
3390 Source source = addSource(r'''
3391 m(i) {
3392 bool b = i is Object;
3393 }''');
3394 computeLibrarySourceErrors(source);
3395 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
3396 verify([source]);
3397 }
3398
3399 void test_unnecessaryTypeCheck_type_not_dynamic() {
3400 Source source = addSource(r'''
3401 m(i) {
3402 bool b = i is! dynamic;
3403 }''');
3404 computeLibrarySourceErrors(source);
3405 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
3406 verify([source]);
3407 }
3408
3409 void test_unnecessaryTypeCheck_type_not_object() {
3410 Source source = addSource(r'''
3411 m(i) {
3412 bool b = i is! Object;
3413 }''');
3414 computeLibrarySourceErrors(source);
3415 assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
3416 verify([source]);
3417 }
3418
3419 void test_unusedElement_class_isUsed_extends() {
3420 enableUnusedElement = true;
3421 Source source = addSource(r'''
3422 class _A {}
3423 class B extends _A {}
3424 ''');
3425 computeLibrarySourceErrors(source);
3426 assertNoErrors(source);
3427 verify([source]);
3428 }
3429
3430 void test_unusedElement_class_isUsed_implements() {
3431 enableUnusedElement = true;
3432 Source source = addSource(r'''
3433 class _A {}
3434 class B implements _A {}
3435 ''');
3436 computeLibrarySourceErrors(source);
3437 assertNoErrors(source);
3438 verify([source]);
3439 }
3440
3441 void test_unusedElement_class_isUsed_instanceCreation() {
3442 enableUnusedElement = true;
3443 Source source = addSource(r'''
3444 class _A {}
3445 main() {
3446 new _A();
3447 }''');
3448 computeLibrarySourceErrors(source);
3449 assertNoErrors(source);
3450 verify([source]);
3451 }
3452
3453 void test_unusedElement_class_isUsed_staticFieldAccess() {
3454 enableUnusedElement = true;
3455 Source source = addSource(r'''
3456 class _A {
3457 static const F = 42;
3458 }
3459 main() {
3460 _A.F;
3461 }''');
3462 computeLibrarySourceErrors(source);
3463 assertNoErrors(source);
3464 verify([source]);
3465 }
3466
3467 void test_unusedElement_class_isUsed_staticMethodInvocation() {
3468 enableUnusedElement = true;
3469 Source source = addSource(r'''
3470 class _A {
3471 static m() {}
3472 }
3473 main() {
3474 _A.m();
3475 }''');
3476 computeLibrarySourceErrors(source);
3477 assertNoErrors(source);
3478 verify([source]);
3479 }
3480
3481 void test_unusedElement_class_isUsed_typeArgument() {
3482 enableUnusedElement = true;
3483 Source source = addSource(r'''
3484 class _A {}
3485 main() {
3486 var v = new List<_A>();
3487 print(v);
3488 }''');
3489 computeLibrarySourceErrors(source);
3490 assertNoErrors(source);
3491 verify([source]);
3492 }
3493
3494 void test_unusedElement_class_notUsed_inClassMember() {
3495 enableUnusedElement = true;
3496 Source source = addSource(r'''
3497 class _A {
3498 static staticMethod() {
3499 new _A();
3500 }
3501 instanceMethod() {
3502 new _A();
3503 }
3504 }
3505 ''');
3506 computeLibrarySourceErrors(source);
3507 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3508 verify([source]);
3509 }
3510
3511 void test_unusedElement_class_notUsed_inConstructorName() {
3512 enableUnusedElement = true;
3513 Source source = addSource(r'''
3514 class _A {
3515 _A() {}
3516 _A.named() {}
3517 }
3518 ''');
3519 computeLibrarySourceErrors(source);
3520 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3521 verify([source]);
3522 }
3523
3524 void test_unusedElement_class_notUsed_isExpression() {
3525 enableUnusedElement = true;
3526 Source source = addSource(r'''
3527 class _A {}
3528 main(p) {
3529 if (p is _A) {
3530 }
3531 }
3532 ''');
3533 computeLibrarySourceErrors(source);
3534 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3535 verify([source]);
3536 }
3537
3538 void test_unusedElement_class_notUsed_noReference() {
3539 enableUnusedElement = true;
3540 Source source = addSource(r'''
3541 class _A {}
3542 main() {
3543 }''');
3544 computeLibrarySourceErrors(source);
3545 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3546 verify([source]);
3547 }
3548
3549 void test_unusedElement_class_notUsed_variableDeclaration() {
3550 enableUnusedElement = true;
3551 Source source = addSource(r'''
3552 class _A {}
3553 main() {
3554 _A v;
3555 print(v);
3556 }
3557 print(x) {}
3558 ''');
3559 computeLibrarySourceErrors(source);
3560 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3561 verify([source]);
3562 }
3563
3564 void test_unusedElement_enum_isUsed_fieldReference() {
3565 enableUnusedElement = true;
3566 Source source = addSource(r'''
3567 enum _MyEnum {A, B, C}
3568 main() {
3569 print(_MyEnum.B);
3570 }''');
3571 computeLibrarySourceErrors(source);
3572 assertNoErrors(source);
3573 verify([source]);
3574 }
3575
3576 void test_unusedElement_enum_notUsed_noReference() {
3577 enableUnusedElement = true;
3578 Source source = addSource(r'''
3579 enum _MyEnum {A, B, C}
3580 main() {
3581 }''');
3582 computeLibrarySourceErrors(source);
3583 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3584 verify([source]);
3585 }
3586
3587 void test_unusedElement_functionLocal_isUsed_closure() {
3588 enableUnusedElement = true;
3589 Source source = addSource(r'''
3590 main() {
3591 print(() {});
3592 }
3593 print(x) {}
3594 ''');
3595 computeLibrarySourceErrors(source);
3596 assertNoErrors(source);
3597 verify([source]);
3598 }
3599
3600 void test_unusedElement_functionLocal_isUsed_invocation() {
3601 enableUnusedElement = true;
3602 Source source = addSource(r'''
3603 main() {
3604 f() {}
3605 f();
3606 }''');
3607 computeLibrarySourceErrors(source);
3608 assertNoErrors(source);
3609 verify([source]);
3610 }
3611
3612 void test_unusedElement_functionLocal_isUsed_reference() {
3613 enableUnusedElement = true;
3614 Source source = addSource(r'''
3615 main() {
3616 f() {}
3617 print(f);
3618 }
3619 print(x) {}
3620 ''');
3621 computeLibrarySourceErrors(source);
3622 assertNoErrors(source);
3623 verify([source]);
3624 }
3625
3626 void test_unusedElement_functionLocal_notUsed_noReference() {
3627 enableUnusedElement = true;
3628 Source source = addSource(r'''
3629 main() {
3630 f() {}
3631 }''');
3632 computeLibrarySourceErrors(source);
3633 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3634 verify([source]);
3635 }
3636
3637 void test_unusedElement_functionLocal_notUsed_referenceFromItself() {
3638 enableUnusedElement = true;
3639 Source source = addSource(r'''
3640 main() {
3641 _f(int p) {
3642 _f(p - 1);
3643 }
3644 }''');
3645 computeLibrarySourceErrors(source);
3646 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3647 verify([source]);
3648 }
3649
3650 void test_unusedElement_functionTop_isUsed_invocation() {
3651 enableUnusedElement = true;
3652 Source source = addSource(r'''
3653 _f() {}
3654 main() {
3655 _f();
3656 }''');
3657 computeLibrarySourceErrors(source);
3658 assertNoErrors(source);
3659 verify([source]);
3660 }
3661
3662 void test_unusedElement_functionTop_isUsed_reference() {
3663 enableUnusedElement = true;
3664 Source source = addSource(r'''
3665 _f() {}
3666 main() {
3667 print(_f);
3668 }
3669 print(x) {}
3670 ''');
3671 computeLibrarySourceErrors(source);
3672 assertNoErrors(source);
3673 verify([source]);
3674 }
3675
3676 void test_unusedElement_functionTop_notUsed_noReference() {
3677 enableUnusedElement = true;
3678 Source source = addSource(r'''
3679 _f() {}
3680 main() {
3681 }''');
3682 computeLibrarySourceErrors(source);
3683 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3684 verify([source]);
3685 }
3686
3687 void test_unusedElement_functionTop_notUsed_referenceFromItself() {
3688 enableUnusedElement = true;
3689 Source source = addSource(r'''
3690 _f(int p) {
3691 _f(p - 1);
3692 }
3693 main() {
3694 }''');
3695 computeLibrarySourceErrors(source);
3696 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3697 verify([source]);
3698 }
3699
3700 void test_unusedElement_functionTypeAlias_isUsed_isExpression() {
3701 enableUnusedElement = true;
3702 Source source = addSource(r'''
3703 typedef _F(a, b);
3704 main(f) {
3705 if (f is _F) {
3706 print('F');
3707 }
3708 }''');
3709 computeLibrarySourceErrors(source);
3710 assertNoErrors(source);
3711 verify([source]);
3712 }
3713
3714 void test_unusedElement_functionTypeAlias_isUsed_reference() {
3715 enableUnusedElement = true;
3716 Source source = addSource(r'''
3717 typedef _F(a, b);
3718 main(_F f) {
3719 }''');
3720 computeLibrarySourceErrors(source);
3721 assertNoErrors(source);
3722 verify([source]);
3723 }
3724
3725 void test_unusedElement_functionTypeAlias_isUsed_typeArgument() {
3726 enableUnusedElement = true;
3727 Source source = addSource(r'''
3728 typedef _F(a, b);
3729 main() {
3730 var v = new List<_F>();
3731 print(v);
3732 }''');
3733 computeLibrarySourceErrors(source);
3734 assertNoErrors(source);
3735 verify([source]);
3736 }
3737
3738 void test_unusedElement_functionTypeAlias_isUsed_variableDeclaration() {
3739 enableUnusedElement = true;
3740 Source source = addSource(r'''
3741 typedef _F(a, b);
3742 class A {
3743 _F f;
3744 }''');
3745 computeLibrarySourceErrors(source);
3746 assertNoErrors(source);
3747 verify([source]);
3748 }
3749
3750 void test_unusedElement_functionTypeAlias_notUsed_noReference() {
3751 enableUnusedElement = true;
3752 Source source = addSource(r'''
3753 typedef _F(a, b);
3754 main() {
3755 }''');
3756 computeLibrarySourceErrors(source);
3757 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3758 verify([source]);
3759 }
3760
3761 void test_unusedElement_getter_isUsed_invocation_implicitThis() {
3762 enableUnusedElement = true;
3763 Source source = addSource(r'''
3764 class A {
3765 get _g => null;
3766 useGetter() {
3767 var v = _g;
3768 }
3769 }''');
3770 computeLibrarySourceErrors(source);
3771 assertNoErrors(source);
3772 verify([source]);
3773 }
3774
3775 void test_unusedElement_getter_isUsed_invocation_PrefixedIdentifier() {
3776 enableUnusedElement = true;
3777 Source source = addSource(r'''
3778 class A {
3779 get _g => null;
3780 }
3781 main(A a) {
3782 var v = a._g;
3783 }
3784 ''');
3785 computeLibrarySourceErrors(source);
3786 assertNoErrors(source);
3787 verify([source]);
3788 }
3789
3790 void test_unusedElement_getter_isUsed_invocation_PropertyAccess() {
3791 enableUnusedElement = true;
3792 Source source = addSource(r'''
3793 class A {
3794 get _g => null;
3795 }
3796 main() {
3797 var v = new A()._g;
3798 }
3799 ''');
3800 computeLibrarySourceErrors(source);
3801 assertNoErrors(source);
3802 verify([source]);
3803 }
3804
3805 void test_unusedElement_getter_notUsed_noReference() {
3806 enableUnusedElement = true;
3807 Source source = addSource(r'''
3808 class A {
3809 get _g => null;
3810 }''');
3811 computeLibrarySourceErrors(source);
3812 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3813 verify([source]);
3814 }
3815
3816 void test_unusedElement_getter_notUsed_referenceFromItself() {
3817 enableUnusedElement = true;
3818 Source source = addSource(r'''
3819 class A {
3820 get _g {
3821 return _g;
3822 }
3823 }''');
3824 computeLibrarySourceErrors(source);
3825 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
3826 verify([source]);
3827 }
3828
3829 void test_unusedElement_method_isUsed_hasReference_implicitThis() {
3830 enableUnusedElement = true;
3831 Source source = addSource(r'''
3832 class A {
3833 _m() {}
3834 useMethod() {
3835 print(_m);
3836 }
3837 }
3838 print(x) {}
3839 ''');
3840 computeLibrarySourceErrors(source);
3841 assertNoErrors(source);
3842 verify([source]);
3843 }
3844
3845 void test_unusedElement_method_isUsed_hasReference_implicitThis_subclass() {
3846 enableUnusedElement = true;
3847 Source source = addSource(r'''
3848 class A {
3849 _m() {}
3850 useMethod() {
3851 print(_m);
3852 }
3853 }
3854 class B extends A {
3855 _m() {}
3856 }
3857 print(x) {}
3858 ''');
3859 computeLibrarySourceErrors(source);
3860 assertNoErrors(source);
3861 verify([source]);
3862 }
3863
3864 void test_unusedElement_method_isUsed_hasReference_PrefixedIdentifier() {
3865 enableUnusedElement = true;
3866 Source source = addSource(r'''
3867 class A {
3868 _m() {}
3869 }
3870 main(A a) {
3871 a._m;
3872 }''');
3873 computeLibrarySourceErrors(source);
3874 assertNoErrors(source);
3875 verify([source]);
3876 }
3877
3878 void test_unusedElement_method_isUsed_hasReference_PropertyAccess() {
3879 enableUnusedElement = true;
3880 Source source = addSource(r'''
3881 class A {
3882 _m() {}
3883 }
3884 main() {
3885 new A()._m;
3886 }''');
3887 computeLibrarySourceErrors(source);
3888 assertNoErrors(source);
3889 verify([source]);
3890 }
3891
3892 void test_unusedElement_method_isUsed_invocation_implicitThis() {
3893 enableUnusedElement = true;
3894 Source source = addSource(r'''
3895 class A {
3896 _m() {}
3897 useMethod() {
3898 _m();
3899 }
3900 }''');
3901 computeLibrarySourceErrors(source);
3902 assertNoErrors(source);
3903 verify([source]);
3904 }
3905
3906 void test_unusedElement_method_isUsed_invocation_implicitThis_subclass() {
3907 enableUnusedElement = true;
3908 Source source = addSource(r'''
3909 class A {
3910 _m() {}
3911 useMethod() {
3912 _m();
3913 }
3914 }
3915 class B extends A {
3916 _m() {}
3917 }''');
3918 computeLibrarySourceErrors(source);
3919 assertNoErrors(source);
3920 verify([source]);
3921 }
3922
3923 void test_unusedElement_method_isUsed_invocation_MemberElement() {
3924 enableUnusedElement = true;
3925 Source source = addSource(r'''
3926 class A<T> {
3927 _m(T t) {}
3928 }
3929 main(A<int> a) {
3930 a._m(0);
3931 }''');
3932 computeLibrarySourceErrors(source);
3933 assertNoErrors(source);
3934 verify([source]);
3935 }
3936
3937 void test_unusedElement_method_isUsed_invocation_propagated() {
3938 enableUnusedElement = true;
3939 Source source = addSource(r'''
3940 class A {
3941 _m() {}
3942 }
3943 main() {
3944 var a = new A();
3945 a._m();
3946 }''');
3947 computeLibrarySourceErrors(source);
3948 assertNoErrors(source);
3949 verify([source]);
3950 }
3951
3952 void test_unusedElement_method_isUsed_invocation_static() {
3953 enableUnusedElement = true;
3954 Source source = addSource(r'''
3955 class A {
3956 _m() {}
3957 }
3958 main() {
3959 A a = new A();
3960 a._m();
3961 }''');
3962 computeLibrarySourceErrors(source);
3963 assertNoErrors(source);
3964 verify([source]);
3965 }
3966
3967 void test_unusedElement_method_isUsed_invocation_subclass() {
3968 enableUnusedElement = true;
3969 Source source = addSource(r'''
3970 class A {
3971 _m() {}
3972 }
3973 class B extends A {
3974 _m() {}
3975 }
3976 main(A a) {
3977 a._m();
3978 }''');
3979 computeLibrarySourceErrors(source);
3980 assertNoErrors(source);
3981 verify([source]);
3982 }
3983
3984 void test_unusedElement_method_isUsed_notPrivate() {
3985 enableUnusedElement = true;
3986 Source source = addSource(r'''
3987 class A {
3988 m() {}
3989 }
3990 main() {
3991 }''');
3992 computeLibrarySourceErrors(source);
3993 assertNoErrors(source);
3994 verify([source]);
3995 }
3996
3997 void test_unusedElement_method_isUsed_staticInvocation() {
3998 enableUnusedElement = true;
3999 Source source = addSource(r'''
4000 class A {
4001 static _m() {}
4002 }
4003 main() {
4004 A._m();
4005 }''');
4006 computeLibrarySourceErrors(source);
4007 assertNoErrors(source);
4008 verify([source]);
4009 }
4010
4011 void test_unusedElement_method_notUsed_noReference() {
4012 enableUnusedElement = true;
4013 Source source = addSource(r'''
4014 class A {
4015 static _m() {}
4016 }''');
4017 computeLibrarySourceErrors(source);
4018 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
4019 verify([source]);
4020 }
4021
4022 void test_unusedElement_method_notUsed_referenceFromItself() {
4023 enableUnusedElement = true;
4024 Source source = addSource(r'''
4025 class A {
4026 static _m(int p) {
4027 _m(p - 1);
4028 }
4029 }''');
4030 computeLibrarySourceErrors(source);
4031 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
4032 verify([source]);
4033 }
4034
4035 void test_unusedElement_setter_isUsed_invocation_implicitThis() {
4036 enableUnusedElement = true;
4037 Source source = addSource(r'''
4038 class A {
4039 set _s(x) {}
4040 useSetter() {
4041 _s = 42;
4042 }
4043 }''');
4044 computeLibrarySourceErrors(source);
4045 assertNoErrors(source);
4046 verify([source]);
4047 }
4048
4049 void test_unusedElement_setter_isUsed_invocation_PrefixedIdentifier() {
4050 enableUnusedElement = true;
4051 Source source = addSource(r'''
4052 class A {
4053 set _s(x) {}
4054 }
4055 main(A a) {
4056 a._s = 42;
4057 }
4058 ''');
4059 computeLibrarySourceErrors(source);
4060 assertNoErrors(source);
4061 verify([source]);
4062 }
4063
4064 void test_unusedElement_setter_isUsed_invocation_PropertyAccess() {
4065 enableUnusedElement = true;
4066 Source source = addSource(r'''
4067 class A {
4068 set _s(x) {}
4069 }
4070 main() {
4071 new A()._s = 42;
4072 }
4073 ''');
4074 computeLibrarySourceErrors(source);
4075 assertNoErrors(source);
4076 verify([source]);
4077 }
4078
4079 void test_unusedElement_setter_notUsed_noReference() {
4080 enableUnusedElement = true;
4081 Source source = addSource(r'''
4082 class A {
4083 set _s(x) {}
4084 }''');
4085 computeLibrarySourceErrors(source);
4086 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
4087 verify([source]);
4088 }
4089
4090 void test_unusedElement_setter_notUsed_referenceFromItself() {
4091 enableUnusedElement = true;
4092 Source source = addSource(r'''
4093 class A {
4094 set _s(int x) {
4095 if (x > 5) {
4096 _s = x - 1;
4097 }
4098 }
4099 }''');
4100 computeLibrarySourceErrors(source);
4101 assertErrors(source, [HintCode.UNUSED_ELEMENT]);
4102 verify([source]);
4103 }
4104
4105 void test_unusedField_isUsed_argument() {
4106 enableUnusedElement = true;
4107 Source source = addSource(r'''
4108 class A {
4109 int _f = 0;
4110 main() {
4111 print(++_f);
4112 }
4113 }
4114 print(x) {}''');
4115 computeLibrarySourceErrors(source);
4116 assertErrors(source);
4117 verify([source]);
4118 }
4119
4120 void test_unusedField_isUsed_reference_implicitThis() {
4121 enableUnusedElement = true;
4122 Source source = addSource(r'''
4123 class A {
4124 int _f;
4125 main() {
4126 print(_f);
4127 }
4128 }
4129 print(x) {}''');
4130 computeLibrarySourceErrors(source);
4131 assertErrors(source);
4132 verify([source]);
4133 }
4134
4135 void test_unusedField_isUsed_reference_implicitThis_expressionFunctionBody() {
4136 enableUnusedElement = true;
4137 Source source = addSource(r'''
4138 class A {
4139 int _f;
4140 m() => _f;
4141 }''');
4142 computeLibrarySourceErrors(source);
4143 assertErrors(source);
4144 verify([source]);
4145 }
4146
4147 void test_unusedField_isUsed_reference_implicitThis_subclass() {
4148 enableUnusedElement = true;
4149 Source source = addSource(r'''
4150 class A {
4151 int _f;
4152 main() {
4153 print(_f);
4154 }
4155 }
4156 class B extends A {
4157 int _f;
4158 }
4159 print(x) {}''');
4160 computeLibrarySourceErrors(source);
4161 assertErrors(source);
4162 verify([source]);
4163 }
4164
4165 void test_unusedField_isUsed_reference_qualified_propagatedElement() {
4166 enableUnusedElement = true;
4167 Source source = addSource(r'''
4168 class A {
4169 int _f;
4170 }
4171 main() {
4172 var a = new A();
4173 print(a._f);
4174 }
4175 print(x) {}''');
4176 computeLibrarySourceErrors(source);
4177 assertErrors(source);
4178 verify([source]);
4179 }
4180
4181 void test_unusedField_isUsed_reference_qualified_staticElement() {
4182 enableUnusedElement = true;
4183 Source source = addSource(r'''
4184 class A {
4185 int _f;
4186 }
4187 main() {
4188 A a = new A();
4189 print(a._f);
4190 }
4191 print(x) {}''');
4192 computeLibrarySourceErrors(source);
4193 assertErrors(source);
4194 verify([source]);
4195 }
4196
4197 void test_unusedField_isUsed_reference_qualified_unresolved() {
4198 enableUnusedElement = true;
4199 Source source = addSource(r'''
4200 class A {
4201 int _f;
4202 }
4203 main(a) {
4204 print(a._f);
4205 }
4206 print(x) {}''');
4207 computeLibrarySourceErrors(source);
4208 assertErrors(source);
4209 verify([source]);
4210 }
4211
4212 void test_unusedField_notUsed_compoundAssign() {
4213 enableUnusedElement = true;
4214 Source source = addSource(r'''
4215 class A {
4216 int _f;
4217 main() {
4218 _f += 2;
4219 }
4220 }''');
4221 computeLibrarySourceErrors(source);
4222 assertErrors(source, [HintCode.UNUSED_FIELD]);
4223 verify([source]);
4224 }
4225
4226 void test_unusedField_notUsed_noReference() {
4227 enableUnusedElement = true;
4228 Source source = addSource(r'''
4229 class A {
4230 int _f;
4231 }
4232 ''');
4233 computeLibrarySourceErrors(source);
4234 assertErrors(source, [HintCode.UNUSED_FIELD]);
4235 verify([source]);
4236 }
4237
4238 void test_unusedField_notUsed_postfixExpr() {
4239 enableUnusedElement = true;
4240 Source source = addSource(r'''
4241 class A {
4242 int _f = 0;
4243 main() {
4244 _f++;
4245 }
4246 }''');
4247 computeLibrarySourceErrors(source);
4248 assertErrors(source, [HintCode.UNUSED_FIELD]);
4249 verify([source]);
4250 }
4251
4252 void test_unusedField_notUsed_prefixExpr() {
4253 enableUnusedElement = true;
4254 Source source = addSource(r'''
4255 class A {
4256 int _f = 0;
4257 main() {
4258 ++_f;
4259 }
4260 }''');
4261 computeLibrarySourceErrors(source);
4262 assertErrors(source, [HintCode.UNUSED_FIELD]);
4263 verify([source]);
4264 }
4265
4266 void test_unusedField_notUsed_simpleAssignment() {
4267 enableUnusedElement = true;
4268 Source source = addSource(r'''
4269 class A {
4270 int _f;
4271 m() {
4272 _f = 1;
4273 }
4274 }
4275 main(A a) {
4276 a._f = 2;
4277 }
4278 ''');
4279 computeLibrarySourceErrors(source);
4280 assertErrors(source, [HintCode.UNUSED_FIELD]);
4281 verify([source]);
4282 }
4283
4284 void test_unusedImport() {
4285 Source source = addSource(r'''
4286 library L;
4287 import 'lib1.dart';''');
4288 Source source2 = addNamedSource("/lib1.dart", "library lib1;");
4289 computeLibrarySourceErrors(source);
4290 assertErrors(source, [HintCode.UNUSED_IMPORT]);
4291 assertNoErrors(source2);
4292 verify([source, source2]);
4293 }
4294
4295 void test_unusedImport_as() {
4296 Source source = addSource(r'''
4297 library L;
4298 import 'lib1.dart';
4299 import 'lib1.dart' as one;
4300 one.A a;''');
4301 Source source2 = addNamedSource(
4302 "/lib1.dart",
4303 r'''
4304 library lib1;
4305 class A {}''');
4306 computeLibrarySourceErrors(source);
4307 assertErrors(source, [HintCode.UNUSED_IMPORT]);
4308 assertNoErrors(source2);
4309 verify([source, source2]);
4310 }
4311
4312 void test_unusedImport_hide() {
4313 Source source = addSource(r'''
4314 library L;
4315 import 'lib1.dart';
4316 import 'lib1.dart' hide A;
4317 A a;''');
4318 Source source2 = addNamedSource(
4319 "/lib1.dart",
4320 r'''
4321 library lib1;
4322 class A {}''');
4323 computeLibrarySourceErrors(source);
4324 assertErrors(source, [HintCode.UNUSED_IMPORT]);
4325 assertNoErrors(source2);
4326 verify([source, source2]);
4327 }
4328
4329 void test_unusedImport_show() {
4330 Source source = addSource(r'''
4331 library L;
4332 import 'lib1.dart' show A;
4333 import 'lib1.dart' show B;
4334 A a;''');
4335 Source source2 = addNamedSource(
4336 "/lib1.dart",
4337 r'''
4338 library lib1;
4339 class A {}
4340 class B {}''');
4341 computeLibrarySourceErrors(source);
4342 assertErrors(source, [HintCode.UNUSED_IMPORT]);
4343 assertNoErrors(source2);
4344 verify([source, source2]);
4345 }
4346
4347 void test_unusedLocalVariable_inCatch_exception() {
4348 enableUnusedLocalVariable = true;
4349 Source source = addSource(r'''
4350 main() {
4351 try {
4352 } on String catch (exception) {
4353 }
4354 }''');
4355 computeLibrarySourceErrors(source);
4356 assertErrors(source, [HintCode.UNUSED_CATCH_CLAUSE]);
4357 verify([source]);
4358 }
4359
4360 void test_unusedLocalVariable_inCatch_exception_hasStack() {
4361 enableUnusedLocalVariable = true;
4362 Source source = addSource(r'''
4363 main() {
4364 try {
4365 } catch (exception, stack) {
4366 print(stack);
4367 }
4368 }''');
4369 computeLibrarySourceErrors(source);
4370 assertNoErrors(source);
4371 verify([source]);
4372 }
4373
4374 void test_unusedLocalVariable_inCatch_exception_noOnClause() {
4375 enableUnusedLocalVariable = true;
4376 Source source = addSource(r'''
4377 main() {
4378 try {
4379 } catch (exception) {
4380 }
4381 }''');
4382 computeLibrarySourceErrors(source);
4383 assertNoErrors(source);
4384 verify([source]);
4385 }
4386
4387 void test_unusedLocalVariable_inCatch_stackTrace() {
4388 enableUnusedLocalVariable = true;
4389 Source source = addSource(r'''
4390 main() {
4391 try {
4392 } catch (exception, stackTrace) {
4393 }
4394 }''');
4395 computeLibrarySourceErrors(source);
4396 assertErrors(source, [HintCode.UNUSED_CATCH_STACK]);
4397 verify([source]);
4398 }
4399
4400 void test_unusedLocalVariable_inCatch_stackTrace_used() {
4401 enableUnusedLocalVariable = true;
4402 Source source = addSource(r'''
4403 main() {
4404 try {
4405 } catch (exception, stackTrace) {
4406 print('exception at $stackTrace');
4407 }
4408 }
4409 print(x) {}''');
4410 computeLibrarySourceErrors(source);
4411 assertErrors(source);
4412 verify([source]);
4413 }
4414
4415 void test_unusedLocalVariable_inFor_underscore_ignored() {
4416 enableUnusedLocalVariable = true;
4417 Source source = addSource(r'''
4418 main() {
4419 for (var _ in [1,2,3]) {
4420 for (var __ in [4,5,6]) {
4421 // do something
4422 }
4423 }
4424 }''');
4425 computeLibrarySourceErrors(source);
4426 assertErrors(source);
4427 verify([source]);
4428 }
4429
4430 void test_unusedLocalVariable_inFunction() {
4431 enableUnusedLocalVariable = true;
4432 Source source = addSource(r'''
4433 main() {
4434 var v = 1;
4435 v = 2;
4436 }''');
4437 computeLibrarySourceErrors(source);
4438 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
4439 verify([source]);
4440 }
4441
4442 void test_unusedLocalVariable_inMethod() {
4443 enableUnusedLocalVariable = true;
4444 Source source = addSource(r'''
4445 class A {
4446 foo() {
4447 var v = 1;
4448 v = 2;
4449 }
4450 }''');
4451 computeLibrarySourceErrors(source);
4452 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
4453 verify([source]);
4454 }
4455
4456 void test_unusedLocalVariable_isInvoked() {
4457 enableUnusedLocalVariable = true;
4458 Source source = addSource(r'''
4459 typedef Foo();
4460 main() {
4461 Foo foo;
4462 foo();
4463 }''');
4464 computeLibrarySourceErrors(source);
4465 assertErrors(source);
4466 verify([source]);
4467 }
4468
4469 void test_unusedLocalVariable_isRead_notUsed_compoundAssign() {
4470 enableUnusedLocalVariable = true;
4471 Source source = addSource(r'''
4472 main() {
4473 var v = 1;
4474 v += 2;
4475 }''');
4476 computeLibrarySourceErrors(source);
4477 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
4478 verify([source]);
4479 }
4480
4481 void test_unusedLocalVariable_isRead_notUsed_postfixExpr() {
4482 enableUnusedLocalVariable = true;
4483 Source source = addSource(r'''
4484 main() {
4485 var v = 1;
4486 v++;
4487 }''');
4488 computeLibrarySourceErrors(source);
4489 assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
4490 verify([source]);
4491 }
4492
4493 void test_unusedLocalVariable_isRead_notUsed_prefixExpr() {
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_usedArgument() {
4506 enableUnusedLocalVariable = true;
4507 Source source = addSource(r'''
4508 main() {
4509 var v = 1;
4510 print(++v);
4511 }
4512 print(x) {}''');
4513 computeLibrarySourceErrors(source);
4514 assertErrors(source);
4515 verify([source]);
4516 }
4517
4518 void test_unusedLocalVariable_isRead_usedInvocationTarget() {
4519 enableUnusedLocalVariable = true;
4520 Source source = addSource(r'''
4521 class A {
4522 foo() {}
4523 }
4524 main() {
4525 var a = new A();
4526 a.foo();
4527 }
4528 ''');
4529 computeLibrarySourceErrors(source);
4530 assertErrors(source);
4531 verify([source]);
4532 }
4533
4534 void test_useOfVoidResult_assignmentExpression_function() {
4535 Source source = addSource(r'''
4536 void f() {}
4537 class A {
4538 n() {
4539 var a;
4540 a = f();
4541 }
4542 }''');
4543 computeLibrarySourceErrors(source);
4544 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
4545 verify([source]);
4546 }
4547
4548 void test_useOfVoidResult_assignmentExpression_method() {
4549 Source source = addSource(r'''
4550 class A {
4551 void m() {}
4552 n() {
4553 var a;
4554 a = m();
4555 }
4556 }''');
4557 computeLibrarySourceErrors(source);
4558 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
4559 verify([source]);
4560 }
4561
4562 void test_useOfVoidResult_inForLoop() {
4563 Source source = addSource(r'''
4564 class A {
4565 void m() {}
4566 n() {
4567 for(var a = m();;) {}
4568 }
4569 }''');
4570 computeLibrarySourceErrors(source);
4571 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
4572 verify([source]);
4573 }
4574
4575 void test_useOfVoidResult_variableDeclaration_function() {
4576 Source source = addSource(r'''
4577 void f() {}
4578 class A {
4579 n() {
4580 var a = f();
4581 }
4582 }''');
4583 computeLibrarySourceErrors(source);
4584 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
4585 verify([source]);
4586 }
4587
4588 void test_useOfVoidResult_variableDeclaration_method() {
4589 Source source = addSource(r'''
4590 class A {
4591 void m() {}
4592 n() {
4593 var a = m();
4594 }
4595 }''');
4596 computeLibrarySourceErrors(source);
4597 assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
4598 verify([source]);
4599 }
4600
4601 void test_useOfVoidResult_variableDeclaration_method2() {
4602 Source source = addSource(r'''
4603 class A {
4604 void m() {}
4605 n() {
4606 var a = m(), b = m();
4607 }
4608 }''');
4609 computeLibrarySourceErrors(source);
4610 assertErrors(
4611 source, [HintCode.USE_OF_VOID_RESULT, HintCode.USE_OF_VOID_RESULT]);
4612 verify([source]);
4613 }
4614 }
4615
4616 @reflectiveTest
4617 class InheritanceManagerTest extends EngineTestCase {
4618 /**
4619 * The type provider used to access the types.
4620 */
4621 TestTypeProvider _typeProvider;
4622
4623 /**
4624 * The library containing the code being resolved.
4625 */
4626 LibraryElementImpl _definingLibrary;
4627
4628 /**
4629 * The inheritance manager being tested.
4630 */
4631 InheritanceManager _inheritanceManager;
4632
4633 /**
4634 * The number of members that Object implements (as determined by [TestTypePro vider]).
4635 */
4636 int _numOfMembersInObject = 0;
4637
4638 @override
4639 void setUp() {
4640 _typeProvider = new TestTypeProvider();
4641 _inheritanceManager = _createInheritanceManager();
4642 InterfaceType objectType = _typeProvider.objectType;
4643 _numOfMembersInObject =
4644 objectType.methods.length + objectType.accessors.length;
4645 }
4646
4647 void test_getMapOfMembersInheritedFromClasses_accessor_extends() {
4648 // class A { int get g; }
4649 // class B extends A {}
4650 ClassElementImpl classA = ElementFactory.classElement2("A");
4651 String getterName = "g";
4652 PropertyAccessorElement getterG =
4653 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
4654 classA.accessors = <PropertyAccessorElement>[getterG];
4655 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
4656 MemberMap mapB =
4657 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
4658 MemberMap mapA =
4659 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
4660 expect(mapA.size, _numOfMembersInObject);
4661 expect(mapB.size, _numOfMembersInObject + 1);
4662 expect(mapB.get(getterName), same(getterG));
4663 _assertNoErrors(classA);
4664 _assertNoErrors(classB);
4665 }
4666
4667 void test_getMapOfMembersInheritedFromClasses_accessor_implements() {
4668 // class A { int get g; }
4669 // class B implements A {}
4670 ClassElementImpl classA = ElementFactory.classElement2("A");
4671 String getterName = "g";
4672 PropertyAccessorElement getterG =
4673 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
4674 classA.accessors = <PropertyAccessorElement>[getterG];
4675 ClassElementImpl classB = ElementFactory.classElement2("B");
4676 classB.interfaces = <InterfaceType>[classA.type];
4677 MemberMap mapB =
4678 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
4679 MemberMap mapA =
4680 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
4681 expect(mapA.size, _numOfMembersInObject);
4682 expect(mapB.size, _numOfMembersInObject);
4683 expect(mapB.get(getterName), isNull);
4684 _assertNoErrors(classA);
4685 _assertNoErrors(classB);
4686 }
4687
4688 void test_getMapOfMembersInheritedFromClasses_accessor_with() {
4689 // class A { int get g; }
4690 // class B extends Object with A {}
4691 ClassElementImpl classA = ElementFactory.classElement2("A");
4692 String getterName = "g";
4693 PropertyAccessorElement getterG =
4694 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
4695 classA.accessors = <PropertyAccessorElement>[getterG];
4696 ClassElementImpl classB = ElementFactory.classElement2("B");
4697 classB.mixins = <InterfaceType>[classA.type];
4698 MemberMap mapB =
4699 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
4700 MemberMap mapA =
4701 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
4702 expect(mapA.size, _numOfMembersInObject);
4703 expect(mapB.size, _numOfMembersInObject + 1);
4704 expect(mapB.get(getterName), same(getterG));
4705 _assertNoErrors(classA);
4706 _assertNoErrors(classB);
4707 }
4708
4709 void test_getMapOfMembersInheritedFromClasses_implicitExtends() {
4710 // class A {}
4711 ClassElementImpl classA = ElementFactory.classElement2("A");
4712 MemberMap mapA =
4713 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
4714 expect(mapA.size, _numOfMembersInObject);
4715 _assertNoErrors(classA);
4716 }
4717
4718 void test_getMapOfMembersInheritedFromClasses_method_extends() {
4719 // class A { int g(); }
4720 // class B extends A {}
4721 ClassElementImpl classA = ElementFactory.classElement2("A");
4722 String methodName = "m";
4723 MethodElement methodM =
4724 ElementFactory.methodElement(methodName, _typeProvider.intType);
4725 classA.methods = <MethodElement>[methodM];
4726 ClassElementImpl classB = ElementFactory.classElement2("B");
4727 classB.supertype = classA.type;
4728 MemberMap mapB =
4729 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
4730 MemberMap mapA =
4731 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
4732 expect(mapA.size, _numOfMembersInObject);
4733 expect(mapB.size, _numOfMembersInObject + 1);
4734 expect(mapB.get(methodName), same(methodM));
4735 _assertNoErrors(classA);
4736 _assertNoErrors(classB);
4737 }
4738
4739 void test_getMapOfMembersInheritedFromClasses_method_implements() {
4740 // class A { int g(); }
4741 // class B implements A {}
4742 ClassElementImpl classA = ElementFactory.classElement2("A");
4743 String methodName = "m";
4744 MethodElement methodM =
4745 ElementFactory.methodElement(methodName, _typeProvider.intType);
4746 classA.methods = <MethodElement>[methodM];
4747 ClassElementImpl classB = ElementFactory.classElement2("B");
4748 classB.interfaces = <InterfaceType>[classA.type];
4749 MemberMap mapB =
4750 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
4751 MemberMap mapA =
4752 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
4753 expect(mapA.size, _numOfMembersInObject);
4754 expect(mapB.size, _numOfMembersInObject);
4755 expect(mapB.get(methodName), isNull);
4756 _assertNoErrors(classA);
4757 _assertNoErrors(classB);
4758 }
4759
4760 void test_getMapOfMembersInheritedFromClasses_method_with() {
4761 // class A { int g(); }
4762 // class B extends Object with A {}
4763 ClassElementImpl classA = ElementFactory.classElement2("A");
4764 String methodName = "m";
4765 MethodElement methodM =
4766 ElementFactory.methodElement(methodName, _typeProvider.intType);
4767 classA.methods = <MethodElement>[methodM];
4768 ClassElementImpl classB = ElementFactory.classElement2("B");
4769 classB.mixins = <InterfaceType>[classA.type];
4770 MemberMap mapB =
4771 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
4772 MemberMap mapA =
4773 _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
4774 expect(mapA.size, _numOfMembersInObject);
4775 expect(mapB.size, _numOfMembersInObject + 1);
4776 expect(mapB.get(methodName), same(methodM));
4777 _assertNoErrors(classA);
4778 _assertNoErrors(classB);
4779 }
4780
4781 void test_getMapOfMembersInheritedFromClasses_method_with_two_mixins() {
4782 // class A1 { int m(); }
4783 // class A2 { int m(); }
4784 // class B extends Object with A1, A2 {}
4785 ClassElementImpl classA1 = ElementFactory.classElement2("A1");
4786 String methodName = "m";
4787 MethodElement methodA1M =
4788 ElementFactory.methodElement(methodName, _typeProvider.intType);
4789 classA1.methods = <MethodElement>[methodA1M];
4790 ClassElementImpl classA2 = ElementFactory.classElement2("A2");
4791 MethodElement methodA2M =
4792 ElementFactory.methodElement(methodName, _typeProvider.intType);
4793 classA2.methods = <MethodElement>[methodA2M];
4794 ClassElementImpl classB = ElementFactory.classElement2("B");
4795 classB.mixins = <InterfaceType>[classA1.type, classA2.type];
4796 MemberMap mapB =
4797 _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
4798 expect(mapB.get(methodName), same(methodA2M));
4799 _assertNoErrors(classA1);
4800 _assertNoErrors(classA2);
4801 _assertNoErrors(classB);
4802 }
4803
4804 void test_getMapOfMembersInheritedFromInterfaces_accessor_extends() {
4805 // class A { int get g; }
4806 // class B extends A {}
4807 ClassElementImpl classA = ElementFactory.classElement2("A");
4808 String getterName = "g";
4809 PropertyAccessorElement getterG =
4810 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
4811 classA.accessors = <PropertyAccessorElement>[getterG];
4812 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
4813 MemberMap mapB =
4814 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
4815 MemberMap mapA =
4816 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
4817 expect(mapA.size, _numOfMembersInObject);
4818 expect(mapB.size, _numOfMembersInObject + 1);
4819 expect(mapB.get(getterName), same(getterG));
4820 _assertNoErrors(classA);
4821 _assertNoErrors(classB);
4822 }
4823
4824 void test_getMapOfMembersInheritedFromInterfaces_accessor_implements() {
4825 // class A { int get g; }
4826 // class B implements A {}
4827 ClassElementImpl classA = ElementFactory.classElement2("A");
4828 String getterName = "g";
4829 PropertyAccessorElement getterG =
4830 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
4831 classA.accessors = <PropertyAccessorElement>[getterG];
4832 ClassElementImpl classB = ElementFactory.classElement2("B");
4833 classB.interfaces = <InterfaceType>[classA.type];
4834 MemberMap mapB =
4835 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
4836 MemberMap mapA =
4837 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
4838 expect(mapA.size, _numOfMembersInObject);
4839 expect(mapB.size, _numOfMembersInObject + 1);
4840 expect(mapB.get(getterName), same(getterG));
4841 _assertNoErrors(classA);
4842 _assertNoErrors(classB);
4843 }
4844
4845 void test_getMapOfMembersInheritedFromInterfaces_accessor_with() {
4846 // class A { int get g; }
4847 // class B extends Object with A {}
4848 ClassElementImpl classA = ElementFactory.classElement2("A");
4849 String getterName = "g";
4850 PropertyAccessorElement getterG =
4851 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
4852 classA.accessors = <PropertyAccessorElement>[getterG];
4853 ClassElementImpl classB = ElementFactory.classElement2("B");
4854 classB.mixins = <InterfaceType>[classA.type];
4855 MemberMap mapB =
4856 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
4857 MemberMap mapA =
4858 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
4859 expect(mapA.size, _numOfMembersInObject);
4860 expect(mapB.size, _numOfMembersInObject + 1);
4861 expect(mapB.get(getterName), same(getterG));
4862 _assertNoErrors(classA);
4863 _assertNoErrors(classB);
4864 }
4865
4866 void test_getMapOfMembersInheritedFromInterfaces_implicitExtends() {
4867 // class A {}
4868 ClassElementImpl classA = ElementFactory.classElement2("A");
4869 MemberMap mapA =
4870 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
4871 expect(mapA.size, _numOfMembersInObject);
4872 _assertNoErrors(classA);
4873 }
4874
4875 void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance _getter_method() {
4876 // class I1 { int m(); }
4877 // class I2 { int get m; }
4878 // class A implements I2, I1 {}
4879 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
4880 String methodName = "m";
4881 MethodElement methodM =
4882 ElementFactory.methodElement(methodName, _typeProvider.intType);
4883 classI1.methods = <MethodElement>[methodM];
4884 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
4885 PropertyAccessorElement getter =
4886 ElementFactory.getterElement(methodName, false, _typeProvider.intType);
4887 classI2.accessors = <PropertyAccessorElement>[getter];
4888 ClassElementImpl classA = ElementFactory.classElement2("A");
4889 classA.interfaces = <InterfaceType>[classI2.type, classI1.type];
4890 MemberMap mapA =
4891 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
4892 expect(mapA.size, _numOfMembersInObject);
4893 expect(mapA.get(methodName), isNull);
4894 _assertErrors(classA,
4895 [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
4896 }
4897
4898 void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance _int_str() {
4899 // class I1 { int m(); }
4900 // class I2 { String m(); }
4901 // class A implements I1, I2 {}
4902 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
4903 String methodName = "m";
4904 MethodElement methodM1 =
4905 ElementFactory.methodElement(methodName, null, [_typeProvider.intType]);
4906 classI1.methods = <MethodElement>[methodM1];
4907 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
4908 MethodElement methodM2 = ElementFactory.methodElement(
4909 methodName, null, [_typeProvider.stringType]);
4910 classI2.methods = <MethodElement>[methodM2];
4911 ClassElementImpl classA = ElementFactory.classElement2("A");
4912 classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
4913 MemberMap mapA =
4914 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
4915 expect(mapA.size, _numOfMembersInObject);
4916 expect(mapA.get(methodName), isNull);
4917 _assertErrors(
4918 classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
4919 }
4920
4921 void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance _method_getter() {
4922 // class I1 { int m(); }
4923 // class I2 { int get m; }
4924 // class A implements I1, I2 {}
4925 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
4926 String methodName = "m";
4927 MethodElement methodM =
4928 ElementFactory.methodElement(methodName, _typeProvider.intType);
4929 classI1.methods = <MethodElement>[methodM];
4930 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
4931 PropertyAccessorElement getter =
4932 ElementFactory.getterElement(methodName, false, _typeProvider.intType);
4933 classI2.accessors = <PropertyAccessorElement>[getter];
4934 ClassElementImpl classA = ElementFactory.classElement2("A");
4935 classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
4936 MemberMap mapA =
4937 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
4938 expect(mapA.size, _numOfMembersInObject);
4939 expect(mapA.get(methodName), isNull);
4940 _assertErrors(classA,
4941 [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
4942 }
4943
4944 void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance _numOfRequiredParams() {
4945 // class I1 { dynamic m(int, [int]); }
4946 // class I2 { dynamic m(int, int, int); }
4947 // class A implements I1, I2 {}
4948 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
4949 String methodName = "m";
4950 MethodElementImpl methodM1 =
4951 ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
4952 ParameterElementImpl parameter1 =
4953 new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
4954 parameter1.type = _typeProvider.intType;
4955 parameter1.parameterKind = ParameterKind.REQUIRED;
4956 ParameterElementImpl parameter2 =
4957 new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
4958 parameter2.type = _typeProvider.intType;
4959 parameter2.parameterKind = ParameterKind.POSITIONAL;
4960 methodM1.parameters = <ParameterElement>[parameter1, parameter2];
4961 classI1.methods = <MethodElement>[methodM1];
4962 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
4963 MethodElementImpl methodM2 =
4964 ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
4965 ParameterElementImpl parameter3 =
4966 new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
4967 parameter3.type = _typeProvider.intType;
4968 parameter3.parameterKind = ParameterKind.REQUIRED;
4969 ParameterElementImpl parameter4 =
4970 new ParameterElementImpl.forNode(AstFactory.identifier3("a4"));
4971 parameter4.type = _typeProvider.intType;
4972 parameter4.parameterKind = ParameterKind.REQUIRED;
4973 ParameterElementImpl parameter5 =
4974 new ParameterElementImpl.forNode(AstFactory.identifier3("a5"));
4975 parameter5.type = _typeProvider.intType;
4976 parameter5.parameterKind = ParameterKind.REQUIRED;
4977 methodM2.parameters = <ParameterElement>[
4978 parameter3,
4979 parameter4,
4980 parameter5
4981 ];
4982 classI2.methods = <MethodElement>[methodM2];
4983 ClassElementImpl classA = ElementFactory.classElement2("A");
4984 classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
4985 MemberMap mapA =
4986 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
4987 expect(mapA.size, _numOfMembersInObject);
4988 expect(mapA.get(methodName), isNull);
4989 _assertErrors(
4990 classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
4991 }
4992
4993 void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance _str_int() {
4994 // class I1 { int m(); }
4995 // class I2 { String m(); }
4996 // class A implements I2, I1 {}
4997 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
4998 String methodName = "m";
4999 MethodElement methodM1 = ElementFactory.methodElement(
5000 methodName, null, [_typeProvider.stringType]);
5001 classI1.methods = <MethodElement>[methodM1];
5002 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5003 MethodElement methodM2 =
5004 ElementFactory.methodElement(methodName, null, [_typeProvider.intType]);
5005 classI2.methods = <MethodElement>[methodM2];
5006 ClassElementImpl classA = ElementFactory.classElement2("A");
5007 classA.interfaces = <InterfaceType>[classI2.type, classI1.type];
5008 MemberMap mapA =
5009 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5010 expect(mapA.size, _numOfMembersInObject);
5011 expect(mapA.get(methodName), isNull);
5012 _assertErrors(
5013 classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
5014 }
5015
5016 void test_getMapOfMembersInheritedFromInterfaces_method_extends() {
5017 // class A { int g(); }
5018 // class B extends A {}
5019 ClassElementImpl classA = ElementFactory.classElement2("A");
5020 String methodName = "m";
5021 MethodElement methodM =
5022 ElementFactory.methodElement(methodName, _typeProvider.intType);
5023 classA.methods = <MethodElement>[methodM];
5024 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5025 MemberMap mapB =
5026 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
5027 MemberMap mapA =
5028 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5029 expect(mapA.size, _numOfMembersInObject);
5030 expect(mapB.size, _numOfMembersInObject + 1);
5031 expect(mapB.get(methodName), same(methodM));
5032 _assertNoErrors(classA);
5033 _assertNoErrors(classB);
5034 }
5035
5036 void test_getMapOfMembersInheritedFromInterfaces_method_implements() {
5037 // class A { int g(); }
5038 // class B implements A {}
5039 ClassElementImpl classA = ElementFactory.classElement2("A");
5040 String methodName = "m";
5041 MethodElement methodM =
5042 ElementFactory.methodElement(methodName, _typeProvider.intType);
5043 classA.methods = <MethodElement>[methodM];
5044 ClassElementImpl classB = ElementFactory.classElement2("B");
5045 classB.interfaces = <InterfaceType>[classA.type];
5046 MemberMap mapB =
5047 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
5048 MemberMap mapA =
5049 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5050 expect(mapA.size, _numOfMembersInObject);
5051 expect(mapB.size, _numOfMembersInObject + 1);
5052 expect(mapB.get(methodName), same(methodM));
5053 _assertNoErrors(classA);
5054 _assertNoErrors(classB);
5055 }
5056
5057 void test_getMapOfMembersInheritedFromInterfaces_method_with() {
5058 // class A { int g(); }
5059 // class B extends Object with A {}
5060 ClassElementImpl classA = ElementFactory.classElement2("A");
5061 String methodName = "m";
5062 MethodElement methodM =
5063 ElementFactory.methodElement(methodName, _typeProvider.intType);
5064 classA.methods = <MethodElement>[methodM];
5065 ClassElementImpl classB = ElementFactory.classElement2("B");
5066 classB.mixins = <InterfaceType>[classA.type];
5067 MemberMap mapB =
5068 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
5069 MemberMap mapA =
5070 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5071 expect(mapA.size, _numOfMembersInObject);
5072 expect(mapB.size, _numOfMembersInObject + 1);
5073 expect(mapB.get(methodName), same(methodM));
5074 _assertNoErrors(classA);
5075 _assertNoErrors(classB);
5076 }
5077
5078 void test_getMapOfMembersInheritedFromInterfaces_union_differentNames() {
5079 // class I1 { int m1(); }
5080 // class I2 { int m2(); }
5081 // class A implements I1, I2 {}
5082 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5083 String methodName1 = "m1";
5084 MethodElement methodM1 =
5085 ElementFactory.methodElement(methodName1, _typeProvider.intType);
5086 classI1.methods = <MethodElement>[methodM1];
5087 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5088 String methodName2 = "m2";
5089 MethodElement methodM2 =
5090 ElementFactory.methodElement(methodName2, _typeProvider.intType);
5091 classI2.methods = <MethodElement>[methodM2];
5092 ClassElementImpl classA = ElementFactory.classElement2("A");
5093 classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
5094 MemberMap mapA =
5095 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5096 expect(mapA.size, _numOfMembersInObject + 2);
5097 expect(mapA.get(methodName1), same(methodM1));
5098 expect(mapA.get(methodName2), same(methodM2));
5099 _assertNoErrors(classA);
5100 }
5101
5102 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_gett ers() {
5103 // class I1 { int get g; }
5104 // class I2 { num get g; }
5105 // class A implements I1, I2 {}
5106 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5107 String accessorName = "g";
5108 PropertyAccessorElement getter1 = ElementFactory.getterElement(
5109 accessorName, false, _typeProvider.intType);
5110 classI1.accessors = <PropertyAccessorElement>[getter1];
5111 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5112 PropertyAccessorElement getter2 = ElementFactory.getterElement(
5113 accessorName, false, _typeProvider.numType);
5114 classI2.accessors = <PropertyAccessorElement>[getter2];
5115 ClassElementImpl classA = ElementFactory.classElement2("A");
5116 classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
5117 MemberMap mapA =
5118 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5119 expect(mapA.size, _numOfMembersInObject + 1);
5120 PropertyAccessorElement syntheticAccessor = ElementFactory.getterElement(
5121 accessorName, false, _typeProvider.dynamicType);
5122 expect(mapA.get(accessorName).type, syntheticAccessor.type);
5123 _assertNoErrors(classA);
5124 }
5125
5126 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_meth ods() {
5127 // class I1 { dynamic m(int); }
5128 // class I2 { dynamic m(num); }
5129 // class A implements I1, I2 {}
5130 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5131 String methodName = "m";
5132 MethodElementImpl methodM1 =
5133 ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
5134 ParameterElementImpl parameter1 =
5135 new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
5136 parameter1.type = _typeProvider.intType;
5137 parameter1.parameterKind = ParameterKind.REQUIRED;
5138 methodM1.parameters = <ParameterElement>[parameter1];
5139 classI1.methods = <MethodElement>[methodM1];
5140 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5141 MethodElementImpl methodM2 =
5142 ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
5143 ParameterElementImpl parameter2 =
5144 new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
5145 parameter2.type = _typeProvider.numType;
5146 parameter2.parameterKind = ParameterKind.REQUIRED;
5147 methodM2.parameters = <ParameterElement>[parameter2];
5148 classI2.methods = <MethodElement>[methodM2];
5149 ClassElementImpl classA = ElementFactory.classElement2("A");
5150 classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
5151 MemberMap mapA =
5152 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5153 expect(mapA.size, _numOfMembersInObject + 1);
5154 MethodElement syntheticMethod = ElementFactory.methodElement(
5155 methodName, _typeProvider.dynamicType, [_typeProvider.dynamicType]);
5156 expect(mapA.get(methodName).type, syntheticMethod.type);
5157 _assertNoErrors(classA);
5158 }
5159
5160 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_sett ers() {
5161 // class I1 { set s(int); }
5162 // class I2 { set s(num); }
5163 // class A implements I1, I2 {}
5164 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5165 String accessorName = "s";
5166 PropertyAccessorElement setter1 = ElementFactory.setterElement(
5167 accessorName, false, _typeProvider.intType);
5168 classI1.accessors = <PropertyAccessorElement>[setter1];
5169 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5170 PropertyAccessorElement setter2 = ElementFactory.setterElement(
5171 accessorName, false, _typeProvider.numType);
5172 classI2.accessors = <PropertyAccessorElement>[setter2];
5173 ClassElementImpl classA = ElementFactory.classElement2("A");
5174 classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
5175 MemberMap mapA =
5176 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5177 expect(mapA.size, _numOfMembersInObject + 1);
5178 PropertyAccessorElementImpl syntheticAccessor = ElementFactory
5179 .setterElement(accessorName, false, _typeProvider.dynamicType);
5180 syntheticAccessor.returnType = _typeProvider.dynamicType;
5181 expect(mapA.get("$accessorName=").type, syntheticAccessor.type);
5182 _assertNoErrors(classA);
5183 }
5184
5185 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_gett ers() {
5186 // class A {}
5187 // class B extends A {}
5188 // class C extends B {}
5189 // class I1 { A get g; }
5190 // class I2 { B get g; }
5191 // class I3 { C get g; }
5192 // class D implements I1, I2, I3 {}
5193 ClassElementImpl classA = ElementFactory.classElement2("A");
5194 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5195 ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
5196 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5197 String accessorName = "g";
5198 PropertyAccessorElement getter1 =
5199 ElementFactory.getterElement(accessorName, false, classA.type);
5200 classI1.accessors = <PropertyAccessorElement>[getter1];
5201 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5202 PropertyAccessorElement getter2 =
5203 ElementFactory.getterElement(accessorName, false, classB.type);
5204 classI2.accessors = <PropertyAccessorElement>[getter2];
5205 ClassElementImpl classI3 = ElementFactory.classElement2("I3");
5206 PropertyAccessorElement getter3 =
5207 ElementFactory.getterElement(accessorName, false, classC.type);
5208 classI3.accessors = <PropertyAccessorElement>[getter3];
5209 ClassElementImpl classD = ElementFactory.classElement2("D");
5210 classD.interfaces = <InterfaceType>[
5211 classI1.type,
5212 classI2.type,
5213 classI3.type
5214 ];
5215 MemberMap mapD =
5216 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD);
5217 expect(mapD.size, _numOfMembersInObject + 1);
5218 PropertyAccessorElement syntheticAccessor = ElementFactory.getterElement(
5219 accessorName, false, _typeProvider.dynamicType);
5220 expect(mapD.get(accessorName).type, syntheticAccessor.type);
5221 _assertNoErrors(classD);
5222 }
5223
5224 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_meth ods() {
5225 // class A {}
5226 // class B extends A {}
5227 // class C extends B {}
5228 // class I1 { dynamic m(A a); }
5229 // class I2 { dynamic m(B b); }
5230 // class I3 { dynamic m(C c); }
5231 // class D implements I1, I2, I3 {}
5232 ClassElementImpl classA = ElementFactory.classElement2("A");
5233 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5234 ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
5235 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5236 String methodName = "m";
5237 MethodElementImpl methodM1 =
5238 ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
5239 ParameterElementImpl parameter1 =
5240 new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
5241 parameter1.type = classA.type;
5242 parameter1.parameterKind = ParameterKind.REQUIRED;
5243 methodM1.parameters = <ParameterElement>[parameter1];
5244 classI1.methods = <MethodElement>[methodM1];
5245 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5246 MethodElementImpl methodM2 =
5247 ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
5248 ParameterElementImpl parameter2 =
5249 new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
5250 parameter2.type = classB.type;
5251 parameter2.parameterKind = ParameterKind.REQUIRED;
5252 methodM2.parameters = <ParameterElement>[parameter2];
5253 classI2.methods = <MethodElement>[methodM2];
5254 ClassElementImpl classI3 = ElementFactory.classElement2("I3");
5255 MethodElementImpl methodM3 =
5256 ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
5257 ParameterElementImpl parameter3 =
5258 new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
5259 parameter3.type = classC.type;
5260 parameter3.parameterKind = ParameterKind.REQUIRED;
5261 methodM3.parameters = <ParameterElement>[parameter3];
5262 classI3.methods = <MethodElement>[methodM3];
5263 ClassElementImpl classD = ElementFactory.classElement2("D");
5264 classD.interfaces = <InterfaceType>[
5265 classI1.type,
5266 classI2.type,
5267 classI3.type
5268 ];
5269 MemberMap mapD =
5270 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD);
5271 expect(mapD.size, _numOfMembersInObject + 1);
5272 MethodElement syntheticMethod = ElementFactory.methodElement(
5273 methodName, _typeProvider.dynamicType, [_typeProvider.dynamicType]);
5274 expect(mapD.get(methodName).type, syntheticMethod.type);
5275 _assertNoErrors(classD);
5276 }
5277
5278 void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_sett ers() {
5279 // class A {}
5280 // class B extends A {}
5281 // class C extends B {}
5282 // class I1 { set s(A); }
5283 // class I2 { set s(B); }
5284 // class I3 { set s(C); }
5285 // class D implements I1, I2, I3 {}
5286 ClassElementImpl classA = ElementFactory.classElement2("A");
5287 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5288 ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
5289 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5290 String accessorName = "s";
5291 PropertyAccessorElement setter1 =
5292 ElementFactory.setterElement(accessorName, false, classA.type);
5293 classI1.accessors = <PropertyAccessorElement>[setter1];
5294 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5295 PropertyAccessorElement setter2 =
5296 ElementFactory.setterElement(accessorName, false, classB.type);
5297 classI2.accessors = <PropertyAccessorElement>[setter2];
5298 ClassElementImpl classI3 = ElementFactory.classElement2("I3");
5299 PropertyAccessorElement setter3 =
5300 ElementFactory.setterElement(accessorName, false, classC.type);
5301 classI3.accessors = <PropertyAccessorElement>[setter3];
5302 ClassElementImpl classD = ElementFactory.classElement2("D");
5303 classD.interfaces = <InterfaceType>[
5304 classI1.type,
5305 classI2.type,
5306 classI3.type
5307 ];
5308 MemberMap mapD =
5309 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD);
5310 expect(mapD.size, _numOfMembersInObject + 1);
5311 PropertyAccessorElementImpl syntheticAccessor = ElementFactory
5312 .setterElement(accessorName, false, _typeProvider.dynamicType);
5313 syntheticAccessor.returnType = _typeProvider.dynamicType;
5314 expect(mapD.get("$accessorName=").type, syntheticAccessor.type);
5315 _assertNoErrors(classD);
5316 }
5317
5318 void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods() {
5319 // class I1 { int m(); }
5320 // class I2 { int m([int]); }
5321 // class A implements I1, I2 {}
5322 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5323 String methodName = "m";
5324 MethodElement methodM1 =
5325 ElementFactory.methodElement(methodName, _typeProvider.intType);
5326 classI1.methods = <MethodElement>[methodM1];
5327 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5328 MethodElementImpl methodM2 =
5329 ElementFactory.methodElement(methodName, _typeProvider.intType);
5330 ParameterElementImpl parameter1 =
5331 new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
5332 parameter1.type = _typeProvider.intType;
5333 parameter1.parameterKind = ParameterKind.POSITIONAL;
5334 methodM2.parameters = <ParameterElement>[parameter1];
5335 classI2.methods = <MethodElement>[methodM2];
5336 ClassElementImpl classA = ElementFactory.classElement2("A");
5337 classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
5338 MemberMap mapA =
5339 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5340 expect(mapA.size, _numOfMembersInObject + 1);
5341 expect(mapA.get(methodName), same(methodM2));
5342 _assertNoErrors(classA);
5343 }
5344
5345 void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods() {
5346 // class I1 { int m(); }
5347 // class I2 { int m([int]); }
5348 // class I3 { int m([int, int]); }
5349 // class A implements I1, I2, I3 {}
5350 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5351 String methodName = "m";
5352 MethodElementImpl methodM1 =
5353 ElementFactory.methodElement(methodName, _typeProvider.intType);
5354 classI1.methods = <MethodElement>[methodM1];
5355 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5356 MethodElementImpl methodM2 =
5357 ElementFactory.methodElement(methodName, _typeProvider.intType);
5358 ParameterElementImpl parameter1 =
5359 new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
5360 parameter1.type = _typeProvider.intType;
5361 parameter1.parameterKind = ParameterKind.POSITIONAL;
5362 methodM1.parameters = <ParameterElement>[parameter1];
5363 classI2.methods = <MethodElement>[methodM2];
5364 ClassElementImpl classI3 = ElementFactory.classElement2("I3");
5365 MethodElementImpl methodM3 =
5366 ElementFactory.methodElement(methodName, _typeProvider.intType);
5367 ParameterElementImpl parameter2 =
5368 new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
5369 parameter2.type = _typeProvider.intType;
5370 parameter2.parameterKind = ParameterKind.POSITIONAL;
5371 ParameterElementImpl parameter3 =
5372 new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
5373 parameter3.type = _typeProvider.intType;
5374 parameter3.parameterKind = ParameterKind.POSITIONAL;
5375 methodM3.parameters = <ParameterElement>[parameter2, parameter3];
5376 classI3.methods = <MethodElement>[methodM3];
5377 ClassElementImpl classA = ElementFactory.classElement2("A");
5378 classA.interfaces = <InterfaceType>[
5379 classI1.type,
5380 classI2.type,
5381 classI3.type
5382 ];
5383 MemberMap mapA =
5384 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5385 expect(mapA.size, _numOfMembersInObject + 1);
5386 expect(mapA.get(methodName), same(methodM3));
5387 _assertNoErrors(classA);
5388 }
5389
5390 void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods() {
5391 // class I1 { int m(); }
5392 // class I2 { int m(); }
5393 // class I3 { int m([int]); }
5394 // class I4 { int m([int, int]); }
5395 // class A implements I1, I2, I3, I4 {}
5396 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5397 String methodName = "m";
5398 MethodElement methodM1 =
5399 ElementFactory.methodElement(methodName, _typeProvider.intType);
5400 classI1.methods = <MethodElement>[methodM1];
5401 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5402 MethodElement methodM2 =
5403 ElementFactory.methodElement(methodName, _typeProvider.intType);
5404 classI2.methods = <MethodElement>[methodM2];
5405 ClassElementImpl classI3 = ElementFactory.classElement2("I3");
5406 MethodElementImpl methodM3 =
5407 ElementFactory.methodElement(methodName, _typeProvider.intType);
5408 ParameterElementImpl parameter1 =
5409 new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
5410 parameter1.type = _typeProvider.intType;
5411 parameter1.parameterKind = ParameterKind.POSITIONAL;
5412 methodM3.parameters = <ParameterElement>[parameter1];
5413 classI3.methods = <MethodElement>[methodM3];
5414 ClassElementImpl classI4 = ElementFactory.classElement2("I4");
5415 MethodElementImpl methodM4 =
5416 ElementFactory.methodElement(methodName, _typeProvider.intType);
5417 ParameterElementImpl parameter2 =
5418 new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
5419 parameter2.type = _typeProvider.intType;
5420 parameter2.parameterKind = ParameterKind.POSITIONAL;
5421 ParameterElementImpl parameter3 =
5422 new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
5423 parameter3.type = _typeProvider.intType;
5424 parameter3.parameterKind = ParameterKind.POSITIONAL;
5425 methodM4.parameters = <ParameterElement>[parameter2, parameter3];
5426 classI4.methods = <MethodElement>[methodM4];
5427 ClassElementImpl classA = ElementFactory.classElement2("A");
5428 classA.interfaces = <InterfaceType>[
5429 classI1.type,
5430 classI2.type,
5431 classI3.type,
5432 classI4.type
5433 ];
5434 MemberMap mapA =
5435 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
5436 expect(mapA.size, _numOfMembersInObject + 1);
5437 expect(mapA.get(methodName), same(methodM4));
5438 _assertNoErrors(classA);
5439 }
5440
5441 void test_lookupInheritance_interface_getter() {
5442 ClassElementImpl classA = ElementFactory.classElement2("A");
5443 String getterName = "g";
5444 PropertyAccessorElement getterG =
5445 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
5446 classA.accessors = <PropertyAccessorElement>[getterG];
5447 ClassElementImpl classB = ElementFactory.classElement2("B");
5448 classB.interfaces = <InterfaceType>[classA.type];
5449 expect(_inheritanceManager.lookupInheritance(classB, getterName),
5450 same(getterG));
5451 _assertNoErrors(classA);
5452 _assertNoErrors(classB);
5453 }
5454
5455 void test_lookupInheritance_interface_method() {
5456 ClassElementImpl classA = ElementFactory.classElement2("A");
5457 String methodName = "m";
5458 MethodElement methodM =
5459 ElementFactory.methodElement(methodName, _typeProvider.intType);
5460 classA.methods = <MethodElement>[methodM];
5461 ClassElementImpl classB = ElementFactory.classElement2("B");
5462 classB.interfaces = <InterfaceType>[classA.type];
5463 expect(_inheritanceManager.lookupInheritance(classB, methodName),
5464 same(methodM));
5465 _assertNoErrors(classA);
5466 _assertNoErrors(classB);
5467 }
5468
5469 void test_lookupInheritance_interface_setter() {
5470 ClassElementImpl classA = ElementFactory.classElement2("A");
5471 String setterName = "s";
5472 PropertyAccessorElement setterS =
5473 ElementFactory.setterElement(setterName, false, _typeProvider.intType);
5474 classA.accessors = <PropertyAccessorElement>[setterS];
5475 ClassElementImpl classB = ElementFactory.classElement2("B");
5476 classB.interfaces = <InterfaceType>[classA.type];
5477 expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
5478 same(setterS));
5479 _assertNoErrors(classA);
5480 _assertNoErrors(classB);
5481 }
5482
5483 void test_lookupInheritance_interface_staticMember() {
5484 ClassElementImpl classA = ElementFactory.classElement2("A");
5485 String methodName = "m";
5486 MethodElement methodM =
5487 ElementFactory.methodElement(methodName, _typeProvider.intType);
5488 (methodM as MethodElementImpl).static = true;
5489 classA.methods = <MethodElement>[methodM];
5490 ClassElementImpl classB = ElementFactory.classElement2("B");
5491 classB.interfaces = <InterfaceType>[classA.type];
5492 expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
5493 _assertNoErrors(classA);
5494 _assertNoErrors(classB);
5495 }
5496
5497 void test_lookupInheritance_interfaces_infiniteLoop() {
5498 ClassElementImpl classA = ElementFactory.classElement2("A");
5499 classA.interfaces = <InterfaceType>[classA.type];
5500 expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
5501 _assertNoErrors(classA);
5502 }
5503
5504 void test_lookupInheritance_interfaces_infiniteLoop2() {
5505 ClassElementImpl classA = ElementFactory.classElement2("A");
5506 ClassElementImpl classB = ElementFactory.classElement2("B");
5507 classA.interfaces = <InterfaceType>[classB.type];
5508 classB.interfaces = <InterfaceType>[classA.type];
5509 expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
5510 _assertNoErrors(classA);
5511 _assertNoErrors(classB);
5512 }
5513
5514 void test_lookupInheritance_interfaces_union2() {
5515 ClassElementImpl classI1 = ElementFactory.classElement2("I1");
5516 String methodName1 = "m1";
5517 MethodElement methodM1 =
5518 ElementFactory.methodElement(methodName1, _typeProvider.intType);
5519 classI1.methods = <MethodElement>[methodM1];
5520 ClassElementImpl classI2 = ElementFactory.classElement2("I2");
5521 String methodName2 = "m2";
5522 MethodElement methodM2 =
5523 ElementFactory.methodElement(methodName2, _typeProvider.intType);
5524 classI2.methods = <MethodElement>[methodM2];
5525 classI2.interfaces = <InterfaceType>[classI1.type];
5526 ClassElementImpl classA = ElementFactory.classElement2("A");
5527 classA.interfaces = <InterfaceType>[classI2.type];
5528 expect(_inheritanceManager.lookupInheritance(classA, methodName1),
5529 same(methodM1));
5530 expect(_inheritanceManager.lookupInheritance(classA, methodName2),
5531 same(methodM2));
5532 _assertNoErrors(classI1);
5533 _assertNoErrors(classI2);
5534 _assertNoErrors(classA);
5535 }
5536
5537 void test_lookupInheritance_mixin_getter() {
5538 ClassElementImpl classA = ElementFactory.classElement2("A");
5539 String getterName = "g";
5540 PropertyAccessorElement getterG =
5541 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
5542 classA.accessors = <PropertyAccessorElement>[getterG];
5543 ClassElementImpl classB = ElementFactory.classElement2("B");
5544 classB.mixins = <InterfaceType>[classA.type];
5545 expect(_inheritanceManager.lookupInheritance(classB, getterName),
5546 same(getterG));
5547 _assertNoErrors(classA);
5548 _assertNoErrors(classB);
5549 }
5550
5551 void test_lookupInheritance_mixin_method() {
5552 ClassElementImpl classA = ElementFactory.classElement2("A");
5553 String methodName = "m";
5554 MethodElement methodM =
5555 ElementFactory.methodElement(methodName, _typeProvider.intType);
5556 classA.methods = <MethodElement>[methodM];
5557 ClassElementImpl classB = ElementFactory.classElement2("B");
5558 classB.mixins = <InterfaceType>[classA.type];
5559 expect(_inheritanceManager.lookupInheritance(classB, methodName),
5560 same(methodM));
5561 _assertNoErrors(classA);
5562 _assertNoErrors(classB);
5563 }
5564
5565 void test_lookupInheritance_mixin_setter() {
5566 ClassElementImpl classA = ElementFactory.classElement2("A");
5567 String setterName = "s";
5568 PropertyAccessorElement setterS =
5569 ElementFactory.setterElement(setterName, false, _typeProvider.intType);
5570 classA.accessors = <PropertyAccessorElement>[setterS];
5571 ClassElementImpl classB = ElementFactory.classElement2("B");
5572 classB.mixins = <InterfaceType>[classA.type];
5573 expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
5574 same(setterS));
5575 _assertNoErrors(classA);
5576 _assertNoErrors(classB);
5577 }
5578
5579 void test_lookupInheritance_mixin_staticMember() {
5580 ClassElementImpl classA = ElementFactory.classElement2("A");
5581 String methodName = "m";
5582 MethodElement methodM =
5583 ElementFactory.methodElement(methodName, _typeProvider.intType);
5584 (methodM as MethodElementImpl).static = true;
5585 classA.methods = <MethodElement>[methodM];
5586 ClassElementImpl classB = ElementFactory.classElement2("B");
5587 classB.mixins = <InterfaceType>[classA.type];
5588 expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
5589 _assertNoErrors(classA);
5590 _assertNoErrors(classB);
5591 }
5592
5593 void test_lookupInheritance_noMember() {
5594 ClassElementImpl classA = ElementFactory.classElement2("A");
5595 expect(_inheritanceManager.lookupInheritance(classA, "a"), isNull);
5596 _assertNoErrors(classA);
5597 }
5598
5599 void test_lookupInheritance_superclass_getter() {
5600 ClassElementImpl classA = ElementFactory.classElement2("A");
5601 String getterName = "g";
5602 PropertyAccessorElement getterG =
5603 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
5604 classA.accessors = <PropertyAccessorElement>[getterG];
5605 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5606 expect(_inheritanceManager.lookupInheritance(classB, getterName),
5607 same(getterG));
5608 _assertNoErrors(classA);
5609 _assertNoErrors(classB);
5610 }
5611
5612 void test_lookupInheritance_superclass_infiniteLoop() {
5613 ClassElementImpl classA = ElementFactory.classElement2("A");
5614 classA.supertype = classA.type;
5615 expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
5616 _assertNoErrors(classA);
5617 }
5618
5619 void test_lookupInheritance_superclass_infiniteLoop2() {
5620 ClassElementImpl classA = ElementFactory.classElement2("A");
5621 ClassElementImpl classB = ElementFactory.classElement2("B");
5622 classA.supertype = classB.type;
5623 classB.supertype = classA.type;
5624 expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
5625 _assertNoErrors(classA);
5626 _assertNoErrors(classB);
5627 }
5628
5629 void test_lookupInheritance_superclass_method() {
5630 ClassElementImpl classA = ElementFactory.classElement2("A");
5631 String methodName = "m";
5632 MethodElement methodM =
5633 ElementFactory.methodElement(methodName, _typeProvider.intType);
5634 classA.methods = <MethodElement>[methodM];
5635 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5636 expect(_inheritanceManager.lookupInheritance(classB, methodName),
5637 same(methodM));
5638 _assertNoErrors(classA);
5639 _assertNoErrors(classB);
5640 }
5641
5642 void test_lookupInheritance_superclass_setter() {
5643 ClassElementImpl classA = ElementFactory.classElement2("A");
5644 String setterName = "s";
5645 PropertyAccessorElement setterS =
5646 ElementFactory.setterElement(setterName, false, _typeProvider.intType);
5647 classA.accessors = <PropertyAccessorElement>[setterS];
5648 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5649 expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
5650 same(setterS));
5651 _assertNoErrors(classA);
5652 _assertNoErrors(classB);
5653 }
5654
5655 void test_lookupInheritance_superclass_staticMember() {
5656 ClassElementImpl classA = ElementFactory.classElement2("A");
5657 String methodName = "m";
5658 MethodElement methodM =
5659 ElementFactory.methodElement(methodName, _typeProvider.intType);
5660 (methodM as MethodElementImpl).static = true;
5661 classA.methods = <MethodElement>[methodM];
5662 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5663 expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
5664 _assertNoErrors(classA);
5665 _assertNoErrors(classB);
5666 }
5667
5668 void test_lookupMember_getter() {
5669 ClassElementImpl classA = ElementFactory.classElement2("A");
5670 String getterName = "g";
5671 PropertyAccessorElement getterG =
5672 ElementFactory.getterElement(getterName, false, _typeProvider.intType);
5673 classA.accessors = <PropertyAccessorElement>[getterG];
5674 expect(_inheritanceManager.lookupMember(classA, getterName), same(getterG));
5675 _assertNoErrors(classA);
5676 }
5677
5678 void test_lookupMember_getter_static() {
5679 ClassElementImpl classA = ElementFactory.classElement2("A");
5680 String getterName = "g";
5681 PropertyAccessorElement getterG =
5682 ElementFactory.getterElement(getterName, true, _typeProvider.intType);
5683 classA.accessors = <PropertyAccessorElement>[getterG];
5684 expect(_inheritanceManager.lookupMember(classA, getterName), isNull);
5685 _assertNoErrors(classA);
5686 }
5687
5688 void test_lookupMember_method() {
5689 ClassElementImpl classA = ElementFactory.classElement2("A");
5690 String methodName = "m";
5691 MethodElement methodM =
5692 ElementFactory.methodElement(methodName, _typeProvider.intType);
5693 classA.methods = <MethodElement>[methodM];
5694 expect(_inheritanceManager.lookupMember(classA, methodName), same(methodM));
5695 _assertNoErrors(classA);
5696 }
5697
5698 void test_lookupMember_method_static() {
5699 ClassElementImpl classA = ElementFactory.classElement2("A");
5700 String methodName = "m";
5701 MethodElement methodM =
5702 ElementFactory.methodElement(methodName, _typeProvider.intType);
5703 (methodM as MethodElementImpl).static = true;
5704 classA.methods = <MethodElement>[methodM];
5705 expect(_inheritanceManager.lookupMember(classA, methodName), isNull);
5706 _assertNoErrors(classA);
5707 }
5708
5709 void test_lookupMember_noMember() {
5710 ClassElementImpl classA = ElementFactory.classElement2("A");
5711 expect(_inheritanceManager.lookupMember(classA, "a"), isNull);
5712 _assertNoErrors(classA);
5713 }
5714
5715 void test_lookupMember_setter() {
5716 ClassElementImpl classA = ElementFactory.classElement2("A");
5717 String setterName = "s";
5718 PropertyAccessorElement setterS =
5719 ElementFactory.setterElement(setterName, false, _typeProvider.intType);
5720 classA.accessors = <PropertyAccessorElement>[setterS];
5721 expect(_inheritanceManager.lookupMember(classA, "$setterName="),
5722 same(setterS));
5723 _assertNoErrors(classA);
5724 }
5725
5726 void test_lookupMember_setter_static() {
5727 ClassElementImpl classA = ElementFactory.classElement2("A");
5728 String setterName = "s";
5729 PropertyAccessorElement setterS =
5730 ElementFactory.setterElement(setterName, true, _typeProvider.intType);
5731 classA.accessors = <PropertyAccessorElement>[setterS];
5732 expect(_inheritanceManager.lookupMember(classA, setterName), isNull);
5733 _assertNoErrors(classA);
5734 }
5735
5736 void test_lookupOverrides_noParentClasses() {
5737 ClassElementImpl classA = ElementFactory.classElement2("A");
5738 String methodName = "m";
5739 MethodElementImpl methodM =
5740 ElementFactory.methodElement(methodName, _typeProvider.intType);
5741 classA.methods = <MethodElement>[methodM];
5742 expect(
5743 _inheritanceManager.lookupOverrides(classA, methodName), hasLength(0));
5744 _assertNoErrors(classA);
5745 }
5746
5747 void test_lookupOverrides_overrideBaseClass() {
5748 ClassElementImpl classA = ElementFactory.classElement2("A");
5749 String methodName = "m";
5750 MethodElementImpl methodMinA =
5751 ElementFactory.methodElement(methodName, _typeProvider.intType);
5752 classA.methods = <MethodElement>[methodMinA];
5753 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
5754 MethodElementImpl methodMinB =
5755 ElementFactory.methodElement(methodName, _typeProvider.intType);
5756 classB.methods = <MethodElement>[methodMinB];
5757 List<ExecutableElement> overrides =
5758 _inheritanceManager.lookupOverrides(classB, methodName);
5759 expect(overrides, unorderedEquals([methodMinA]));
5760 _assertNoErrors(classA);
5761 _assertNoErrors(classB);
5762 }
5763
5764 void test_lookupOverrides_overrideInterface() {
5765 ClassElementImpl classA = ElementFactory.classElement2("A");
5766 String methodName = "m";
5767 MethodElementImpl methodMinA =
5768 ElementFactory.methodElement(methodName, _typeProvider.intType);
5769 classA.methods = <MethodElement>[methodMinA];
5770 ClassElementImpl classB = ElementFactory.classElement2("B");
5771 classB.interfaces = <InterfaceType>[classA.type];
5772 MethodElementImpl methodMinB =
5773 ElementFactory.methodElement(methodName, _typeProvider.intType);
5774 classB.methods = <MethodElement>[methodMinB];
5775 List<ExecutableElement> overrides =
5776 _inheritanceManager.lookupOverrides(classB, methodName);
5777 expect(overrides, unorderedEquals([methodMinA]));
5778 _assertNoErrors(classA);
5779 _assertNoErrors(classB);
5780 }
5781
5782 void test_lookupOverrides_overrideTwoInterfaces() {
5783 ClassElementImpl classA = ElementFactory.classElement2("A");
5784 String methodName = "m";
5785 MethodElementImpl methodMinA =
5786 ElementFactory.methodElement(methodName, _typeProvider.intType);
5787 classA.methods = <MethodElement>[methodMinA];
5788 ClassElementImpl classB = ElementFactory.classElement2("B");
5789 MethodElementImpl methodMinB =
5790 ElementFactory.methodElement(methodName, _typeProvider.doubleType);
5791 classB.methods = <MethodElement>[methodMinB];
5792 ClassElementImpl classC = ElementFactory.classElement2("C");
5793 classC.interfaces = <InterfaceType>[classA.type, classB.type];
5794 MethodElementImpl methodMinC =
5795 ElementFactory.methodElement(methodName, _typeProvider.numType);
5796 classC.methods = <MethodElement>[methodMinC];
5797 List<ExecutableElement> overrides =
5798 _inheritanceManager.lookupOverrides(classC, methodName);
5799 expect(overrides, unorderedEquals([methodMinA, methodMinB]));
5800 _assertNoErrors(classA);
5801 _assertNoErrors(classB);
5802 _assertNoErrors(classC);
5803 }
5804
5805 void _assertErrors(ClassElement classElt,
5806 [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
5807 GatheringErrorListener errorListener = new GatheringErrorListener();
5808 HashSet<AnalysisError> actualErrors =
5809 _inheritanceManager.getErrors(classElt);
5810 if (actualErrors != null) {
5811 for (AnalysisError error in actualErrors) {
5812 errorListener.onError(error);
5813 }
5814 }
5815 errorListener.assertErrorsWithCodes(expectedErrorCodes);
5816 }
5817
5818 void _assertNoErrors(ClassElement classElt) {
5819 _assertErrors(classElt);
5820 }
5821
5822 /**
5823 * Create the inheritance manager used by the tests.
5824 *
5825 * @return the inheritance manager that was created
5826 */
5827 InheritanceManager _createInheritanceManager() {
5828 AnalysisContext context = AnalysisContextFactory.contextWithCore();
5829 FileBasedSource source =
5830 new FileBasedSource(FileUtilities2.createFile("/test.dart"));
5831 CompilationUnitElementImpl definingCompilationUnit =
5832 new CompilationUnitElementImpl("test.dart");
5833 definingCompilationUnit.librarySource =
5834 definingCompilationUnit.source = source;
5835 _definingLibrary = ElementFactory.library(context, "test");
5836 _definingLibrary.definingCompilationUnit = definingCompilationUnit;
5837 return new InheritanceManager(_definingLibrary);
5838 }
5839 }
5840
5841 @reflectiveTest
5842 class LibraryElementBuilderTest extends EngineTestCase {
5843 /**
5844 * The analysis context used to analyze sources.
5845 */
5846 InternalAnalysisContext _context;
5847
5848 /**
5849 * Add a source file to the content provider. The file path should be absolute .
5850 *
5851 * @param filePath the path of the file being added
5852 * @param contents the contents to be returned by the content provider for the specified file
5853 * @return the source object representing the added file
5854 */
5855 Source addSource(String filePath, String contents) {
5856 Source source = new FileBasedSource(FileUtilities2.createFile(filePath));
5857 _context.setContents(source, contents);
5858 return source;
5859 }
5860
5861 @override
5862 void setUp() {
5863 _context = AnalysisContextFactory.contextWithCore();
5864 }
5865
5866 @override
5867 void tearDown() {
5868 _context = null;
5869 super.tearDown();
5870 }
5871
5872 void test_accessorsAcrossFiles() {
5873 Source librarySource = addSource(
5874 "/lib.dart",
5875 r'''
5876 library lib;
5877 part 'first.dart';
5878 part 'second.dart';''');
5879 addSource(
5880 "/first.dart",
5881 r'''
5882 part of lib;
5883 int get V => 0;''');
5884 addSource(
5885 "/second.dart",
5886 r'''
5887 part of lib;
5888 void set V(int v) {}''');
5889 LibraryElement element = _buildLibrary(librarySource);
5890 expect(element, isNotNull);
5891 List<CompilationUnitElement> sourcedUnits = element.parts;
5892 expect(sourcedUnits, hasLength(2));
5893 List<PropertyAccessorElement> firstAccessors = sourcedUnits[0].accessors;
5894 expect(firstAccessors, hasLength(1));
5895 List<PropertyAccessorElement> secondAccessors = sourcedUnits[1].accessors;
5896 expect(secondAccessors, hasLength(1));
5897 expect(secondAccessors[0].variable, same(firstAccessors[0].variable));
5898 }
5899
5900 void test_empty() {
5901 Source librarySource = addSource("/lib.dart", "library lib;");
5902 LibraryElement element = _buildLibrary(librarySource);
5903 expect(element, isNotNull);
5904 expect(element.name, "lib");
5905 expect(element.entryPoint, isNull);
5906 expect(element.importedLibraries, hasLength(0));
5907 expect(element.imports, hasLength(0));
5908 expect(element.library, same(element));
5909 expect(element.prefixes, hasLength(0));
5910 expect(element.parts, hasLength(0));
5911 CompilationUnitElement unit = element.definingCompilationUnit;
5912 expect(unit, isNotNull);
5913 expect(unit.name, "lib.dart");
5914 expect(unit.library, element);
5915 expect(unit.accessors, hasLength(0));
5916 expect(unit.functions, hasLength(0));
5917 expect(unit.functionTypeAliases, hasLength(0));
5918 expect(unit.types, hasLength(0));
5919 expect(unit.topLevelVariables, hasLength(0));
5920 }
5921
5922 void test_missingLibraryDirectiveWithPart() {
5923 addSource("/a.dart", "part of lib;");
5924 Source librarySource = addSource("/lib.dart", "part 'a.dart';");
5925 LibraryElement element = _buildLibrary(
5926 librarySource, [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]);
5927 expect(element, isNotNull);
5928 }
5929
5930 void test_missingPartOfDirective() {
5931 addSource("/a.dart", "class A {}");
5932 Source librarySource = addSource(
5933 "/lib.dart",
5934 r'''
5935 library lib;
5936
5937 part 'a.dart';''');
5938 LibraryElement element =
5939 _buildLibrary(librarySource, [CompileTimeErrorCode.PART_OF_NON_PART]);
5940 expect(element, isNotNull);
5941 }
5942
5943 void test_multipleFiles() {
5944 Source librarySource = addSource(
5945 "/lib.dart",
5946 r'''
5947 library lib;
5948 part 'first.dart';
5949 part 'second.dart';
5950
5951 class A {}''');
5952 addSource(
5953 "/first.dart",
5954 r'''
5955 part of lib;
5956 class B {}''');
5957 addSource(
5958 "/second.dart",
5959 r'''
5960 part of lib;
5961 class C {}''');
5962 LibraryElement element = _buildLibrary(librarySource);
5963 expect(element, isNotNull);
5964 List<CompilationUnitElement> sourcedUnits = element.parts;
5965 expect(sourcedUnits, hasLength(2));
5966 _assertTypes(element.definingCompilationUnit, ["A"]);
5967 if (sourcedUnits[0].name == "first.dart") {
5968 _assertTypes(sourcedUnits[0], ["B"]);
5969 _assertTypes(sourcedUnits[1], ["C"]);
5970 } else {
5971 _assertTypes(sourcedUnits[0], ["C"]);
5972 _assertTypes(sourcedUnits[1], ["B"]);
5973 }
5974 }
5975
5976 void test_singleFile() {
5977 Source librarySource = addSource(
5978 "/lib.dart",
5979 r'''
5980 library lib;
5981
5982 class A {}''');
5983 LibraryElement element = _buildLibrary(librarySource);
5984 expect(element, isNotNull);
5985 _assertTypes(element.definingCompilationUnit, ["A"]);
5986 }
5987
5988 /**
5989 * Ensure that there are elements representing all of the types in the given a rray of type names.
5990 *
5991 * @param unit the compilation unit containing the types
5992 * @param typeNames the names of the types that should be found
5993 */
5994 void _assertTypes(CompilationUnitElement unit, List<String> typeNames) {
5995 expect(unit, isNotNull);
5996 List<ClassElement> types = unit.types;
5997 expect(types, hasLength(typeNames.length));
5998 for (ClassElement type in types) {
5999 expect(type, isNotNull);
6000 String actualTypeName = type.displayName;
6001 bool wasExpected = false;
6002 for (String expectedTypeName in typeNames) {
6003 if (expectedTypeName == actualTypeName) {
6004 wasExpected = true;
6005 }
6006 }
6007 if (!wasExpected) {
6008 fail("Found unexpected type $actualTypeName");
6009 }
6010 }
6011 }
6012
6013 /**
6014 * Build the element model for the library whose defining compilation unit has the given source.
6015 *
6016 * @param librarySource the source of the defining compilation unit for the li brary
6017 * @param expectedErrorCodes the errors that are expected to be found while bu ilding the element
6018 * model
6019 * @return the element model that was built for the library
6020 * @throws Exception if the element model could not be built
6021 */
6022 LibraryElement _buildLibrary(Source librarySource,
6023 [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
6024 LibraryResolver resolver = new LibraryResolver(_context);
6025 LibraryElementBuilder builder = new LibraryElementBuilder(
6026 resolver.analysisContext, resolver.errorListener);
6027 Library library = resolver.createLibrary(librarySource);
6028 LibraryElement element = builder.buildLibrary(library);
6029 GatheringErrorListener listener = new GatheringErrorListener();
6030 listener.addAll2(resolver.errorListener);
6031 listener.assertErrorsWithCodes(expectedErrorCodes);
6032 return element;
6033 }
6034 }
6035
6036 @reflectiveTest
6037 class LibraryImportScopeTest extends ResolverTestCase {
6038 void test_conflictingImports() {
6039 AnalysisContext context = AnalysisContextFactory.contextWithCore();
6040 String typeNameA = "A";
6041 String typeNameB = "B";
6042 String typeNameC = "C";
6043 ClassElement typeA = ElementFactory.classElement2(typeNameA);
6044 ClassElement typeB1 = ElementFactory.classElement2(typeNameB);
6045 ClassElement typeB2 = ElementFactory.classElement2(typeNameB);
6046 ClassElement typeC = ElementFactory.classElement2(typeNameC);
6047 LibraryElement importedLibrary1 = createTestLibrary(context, "imported1");
6048 (importedLibrary1.definingCompilationUnit as CompilationUnitElementImpl)
6049 .types = <ClassElement>[typeA, typeB1];
6050 ImportElementImpl import1 =
6051 ElementFactory.importFor(importedLibrary1, null);
6052 LibraryElement importedLibrary2 = createTestLibrary(context, "imported2");
6053 (importedLibrary2.definingCompilationUnit as CompilationUnitElementImpl)
6054 .types = <ClassElement>[typeB2, typeC];
6055 ImportElementImpl import2 =
6056 ElementFactory.importFor(importedLibrary2, null);
6057 LibraryElementImpl importingLibrary =
6058 createTestLibrary(context, "importing");
6059 importingLibrary.imports = <ImportElement>[import1, import2];
6060 {
6061 GatheringErrorListener errorListener = new GatheringErrorListener();
6062 Scope scope = new LibraryImportScope(importingLibrary, errorListener);
6063 expect(scope.lookup(AstFactory.identifier3(typeNameA), importingLibrary),
6064 typeA);
6065 errorListener.assertNoErrors();
6066 expect(scope.lookup(AstFactory.identifier3(typeNameC), importingLibrary),
6067 typeC);
6068 errorListener.assertNoErrors();
6069 Element element =
6070 scope.lookup(AstFactory.identifier3(typeNameB), importingLibrary);
6071 errorListener.assertErrorsWithCodes([StaticWarningCode.AMBIGUOUS_IMPORT]);
6072 EngineTestCase.assertInstanceOf((obj) => obj is MultiplyDefinedElement,
6073 MultiplyDefinedElement, element);
6074 List<Element> conflictingElements =
6075 (element as MultiplyDefinedElement).conflictingElements;
6076 expect(conflictingElements, hasLength(2));
6077 if (identical(conflictingElements[0], typeB1)) {
6078 expect(conflictingElements[1], same(typeB2));
6079 } else if (identical(conflictingElements[0], typeB2)) {
6080 expect(conflictingElements[1], same(typeB1));
6081 } else {
6082 expect(conflictingElements[0], same(typeB1));
6083 }
6084 }
6085 {
6086 GatheringErrorListener errorListener = new GatheringErrorListener();
6087 Scope scope = new LibraryImportScope(importingLibrary, errorListener);
6088 Identifier identifier = AstFactory.identifier3(typeNameB);
6089 AstFactory.methodDeclaration(null, AstFactory.typeName3(identifier), null,
6090 null, AstFactory.identifier3("foo"), null);
6091 Element element = scope.lookup(identifier, importingLibrary);
6092 errorListener.assertErrorsWithCodes([StaticWarningCode.AMBIGUOUS_IMPORT]);
6093 EngineTestCase.assertInstanceOf((obj) => obj is MultiplyDefinedElement,
6094 MultiplyDefinedElement, element);
6095 }
6096 }
6097
6098 void test_creation_empty() {
6099 LibraryElement definingLibrary = createDefaultTestLibrary();
6100 GatheringErrorListener errorListener = new GatheringErrorListener();
6101 new LibraryImportScope(definingLibrary, errorListener);
6102 }
6103
6104 void test_creation_nonEmpty() {
6105 AnalysisContext context = AnalysisContextFactory.contextWithCore();
6106 String importedTypeName = "A";
6107 ClassElement importedType =
6108 new ClassElementImpl.forNode(AstFactory.identifier3(importedTypeName));
6109 LibraryElement importedLibrary = createTestLibrary(context, "imported");
6110 (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
6111 .types = <ClassElement>[importedType];
6112 LibraryElementImpl definingLibrary =
6113 createTestLibrary(context, "importing");
6114 ImportElementImpl importElement = new ImportElementImpl(0);
6115 importElement.importedLibrary = importedLibrary;
6116 definingLibrary.imports = <ImportElement>[importElement];
6117 GatheringErrorListener errorListener = new GatheringErrorListener();
6118 Scope scope = new LibraryImportScope(definingLibrary, errorListener);
6119 expect(
6120 scope.lookup(AstFactory.identifier3(importedTypeName), definingLibrary),
6121 importedType);
6122 }
6123
6124 void test_getErrorListener() {
6125 LibraryElement definingLibrary = createDefaultTestLibrary();
6126 GatheringErrorListener errorListener = new GatheringErrorListener();
6127 LibraryImportScope scope =
6128 new LibraryImportScope(definingLibrary, errorListener);
6129 expect(scope.errorListener, errorListener);
6130 }
6131
6132 void test_nonConflictingImports_fromSdk() {
6133 AnalysisContext context = AnalysisContextFactory.contextWithCore();
6134 String typeName = "List";
6135 ClassElement type = ElementFactory.classElement2(typeName);
6136 LibraryElement importedLibrary = createTestLibrary(context, "lib");
6137 (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
6138 .types = <ClassElement>[type];
6139 ImportElementImpl importCore = ElementFactory.importFor(
6140 context.getLibraryElement(context.sourceFactory.forUri("dart:core")),
6141 null);
6142 ImportElementImpl importLib =
6143 ElementFactory.importFor(importedLibrary, null);
6144 LibraryElementImpl importingLibrary =
6145 createTestLibrary(context, "importing");
6146 importingLibrary.imports = <ImportElement>[importCore, importLib];
6147 GatheringErrorListener errorListener = new GatheringErrorListener();
6148 Scope scope = new LibraryImportScope(importingLibrary, errorListener);
6149 expect(
6150 scope.lookup(AstFactory.identifier3(typeName), importingLibrary), type);
6151 errorListener
6152 .assertErrorsWithCodes([StaticWarningCode.CONFLICTING_DART_IMPORT]);
6153 }
6154
6155 void test_nonConflictingImports_sameElement() {
6156 AnalysisContext context = AnalysisContextFactory.contextWithCore();
6157 String typeNameA = "A";
6158 String typeNameB = "B";
6159 ClassElement typeA = ElementFactory.classElement2(typeNameA);
6160 ClassElement typeB = ElementFactory.classElement2(typeNameB);
6161 LibraryElement importedLibrary = createTestLibrary(context, "imported");
6162 (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
6163 .types = <ClassElement>[typeA, typeB];
6164 ImportElementImpl import1 = ElementFactory.importFor(importedLibrary, null);
6165 ImportElementImpl import2 = ElementFactory.importFor(importedLibrary, null);
6166 LibraryElementImpl importingLibrary =
6167 createTestLibrary(context, "importing");
6168 importingLibrary.imports = <ImportElement>[import1, import2];
6169 GatheringErrorListener errorListener = new GatheringErrorListener();
6170 Scope scope = new LibraryImportScope(importingLibrary, errorListener);
6171 expect(scope.lookup(AstFactory.identifier3(typeNameA), importingLibrary),
6172 typeA);
6173 errorListener.assertNoErrors();
6174 expect(scope.lookup(AstFactory.identifier3(typeNameB), importingLibrary),
6175 typeB);
6176 errorListener.assertNoErrors();
6177 }
6178
6179 void test_prefixedAndNonPrefixed() {
6180 AnalysisContext context = AnalysisContextFactory.contextWithCore();
6181 String typeName = "C";
6182 String prefixName = "p";
6183 ClassElement prefixedType = ElementFactory.classElement2(typeName);
6184 ClassElement nonPrefixedType = ElementFactory.classElement2(typeName);
6185 LibraryElement prefixedLibrary =
6186 createTestLibrary(context, "import.prefixed");
6187 (prefixedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
6188 .types = <ClassElement>[prefixedType];
6189 ImportElementImpl prefixedImport = ElementFactory.importFor(
6190 prefixedLibrary, ElementFactory.prefix(prefixName));
6191 LibraryElement nonPrefixedLibrary =
6192 createTestLibrary(context, "import.nonPrefixed");
6193 (nonPrefixedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
6194 .types = <ClassElement>[nonPrefixedType];
6195 ImportElementImpl nonPrefixedImport =
6196 ElementFactory.importFor(nonPrefixedLibrary, null);
6197 LibraryElementImpl importingLibrary =
6198 createTestLibrary(context, "importing");
6199 importingLibrary.imports = <ImportElement>[
6200 prefixedImport,
6201 nonPrefixedImport
6202 ];
6203 GatheringErrorListener errorListener = new GatheringErrorListener();
6204 Scope scope = new LibraryImportScope(importingLibrary, errorListener);
6205 Element prefixedElement = scope.lookup(
6206 AstFactory.identifier5(prefixName, typeName), importingLibrary);
6207 errorListener.assertNoErrors();
6208 expect(prefixedElement, same(prefixedType));
6209 Element nonPrefixedElement =
6210 scope.lookup(AstFactory.identifier3(typeName), importingLibrary);
6211 errorListener.assertNoErrors();
6212 expect(nonPrefixedElement, same(nonPrefixedType));
6213 }
6214 }
6215
6216 @reflectiveTest
6217 class LibraryResolver2Test extends ResolverTestCase {
6218 LibraryResolver2 _resolver;
6219
6220 Source _coreLibrarySource;
6221
6222 Source _asyncLibrarySource;
6223
6224 @override
6225 void setUp() {
6226 super.setUp();
6227 _resolver = new LibraryResolver2(analysisContext2);
6228 _coreLibrarySource =
6229 analysisContext2.sourceFactory.forUri(DartSdk.DART_CORE);
6230 _asyncLibrarySource =
6231 analysisContext2.sourceFactory.forUri(DartSdk.DART_ASYNC);
6232 }
6233
6234 void test_imports_relative() {
6235 Source sourceA = addSource(r'''
6236 library libA;
6237 import 'libB.dart';
6238 class A {}''');
6239 Source sourceB = addNamedSource(
6240 "/libB.dart",
6241 r'''
6242 library libB;
6243 import 'test.dart
6244 class B {}''');
6245 List<ResolvableLibrary> cycle = new List<ResolvableLibrary>();
6246 ResolvableLibrary coreLib = _createResolvableLibrary(_coreLibrarySource);
6247 coreLib.libraryElement = analysisContext2
6248 .computeLibraryElement(_coreLibrarySource) as LibraryElementImpl;
6249 ResolvableLibrary asyncLib = _createResolvableLibrary(_asyncLibrarySource);
6250 asyncLib.libraryElement = analysisContext2
6251 .computeLibraryElement(_asyncLibrarySource) as LibraryElementImpl;
6252 ResolvableLibrary libA = _createResolvableLibrary(sourceA);
6253 ResolvableLibrary libB = _createResolvableLibrary(sourceB);
6254 libA.importedLibraries = <ResolvableLibrary>[coreLib, asyncLib, libB];
6255 libB.importedLibraries = <ResolvableLibrary>[coreLib, asyncLib, libA];
6256 cycle.add(libA);
6257 cycle.add(libB);
6258 LibraryElement library = _resolver.resolveLibrary(sourceA, cycle);
6259 List<LibraryElement> importedLibraries = library.importedLibraries;
6260 assertNamedElements(importedLibraries, ["dart.core", "libB"]);
6261 }
6262
6263 ResolvableLibrary _createResolvableLibrary(Source source) {
6264 CompilationUnit unit = analysisContext2.parseCompilationUnit(source);
6265 ResolvableLibrary resolvableLibrary = new ResolvableLibrary(source);
6266 resolvableLibrary.resolvableCompilationUnits = <ResolvableCompilationUnit>[
6267 new ResolvableCompilationUnit(source, unit)
6268 ];
6269 return resolvableLibrary;
6270 }
6271 }
6272
6273 @reflectiveTest
6274 class LibraryResolverTest extends ResolverTestCase {
6275 LibraryResolver _resolver;
6276
6277 @override
6278 void setUp() {
6279 super.setUp();
6280 _resolver = new LibraryResolver(analysisContext2);
6281 }
6282
6283 void test_imports_dart_html() {
6284 Source source = addSource(r'''
6285 library libA;
6286 import 'dart:html';
6287 class A {}''');
6288 LibraryElement library = _resolver.resolveLibrary(source, true);
6289 List<LibraryElement> importedLibraries = library.importedLibraries;
6290 assertNamedElements(importedLibraries, ["dart.core", "dart.dom.html"]);
6291 }
6292
6293 void test_imports_none() {
6294 Source source = addSource(r'''
6295 library libA;
6296 class A {}''');
6297 LibraryElement library = _resolver.resolveLibrary(source, true);
6298 List<LibraryElement> importedLibraries = library.importedLibraries;
6299 assertNamedElements(importedLibraries, ["dart.core"]);
6300 }
6301
6302 void test_imports_relative() {
6303 addNamedSource("/libB.dart", "library libB;");
6304 Source source = addSource(r'''
6305 library libA;
6306 import 'libB.dart';
6307 class A {}''');
6308 LibraryElement library = _resolver.resolveLibrary(source, true);
6309 List<LibraryElement> importedLibraries = library.importedLibraries;
6310 assertNamedElements(importedLibraries, ["dart.core", "libB"]);
6311 }
6312 }
6313
6314 @reflectiveTest
6315 class LibraryScopeTest extends ResolverTestCase {
6316 void test_creation_empty() {
6317 LibraryElement definingLibrary = createDefaultTestLibrary();
6318 GatheringErrorListener errorListener = new GatheringErrorListener();
6319 new LibraryScope(definingLibrary, errorListener);
6320 }
6321
6322 void test_creation_nonEmpty() {
6323 AnalysisContext context = AnalysisContextFactory.contextWithCore();
6324 String importedTypeName = "A";
6325 ClassElement importedType =
6326 new ClassElementImpl.forNode(AstFactory.identifier3(importedTypeName));
6327 LibraryElement importedLibrary = createTestLibrary(context, "imported");
6328 (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
6329 .types = <ClassElement>[importedType];
6330 LibraryElementImpl definingLibrary =
6331 createTestLibrary(context, "importing");
6332 ImportElementImpl importElement = new ImportElementImpl(0);
6333 importElement.importedLibrary = importedLibrary;
6334 definingLibrary.imports = <ImportElement>[importElement];
6335 GatheringErrorListener errorListener = new GatheringErrorListener();
6336 Scope scope = new LibraryScope(definingLibrary, errorListener);
6337 expect(
6338 scope.lookup(AstFactory.identifier3(importedTypeName), definingLibrary),
6339 importedType);
6340 }
6341
6342 void test_getErrorListener() {
6343 LibraryElement definingLibrary = createDefaultTestLibrary();
6344 GatheringErrorListener errorListener = new GatheringErrorListener();
6345 LibraryScope scope = new LibraryScope(definingLibrary, errorListener);
6346 expect(scope.errorListener, errorListener);
6347 }
6348 }
6349
6350 @reflectiveTest
6351 class LibraryTest extends EngineTestCase {
6352 /**
6353 * The error listener to which all errors will be reported.
6354 */
6355 GatheringErrorListener _errorListener;
6356
6357 /**
6358 * The analysis context to pass in to all libraries created by the tests.
6359 */
6360 InternalAnalysisContext _analysisContext;
6361
6362 /**
6363 * The library used by the tests.
6364 */
6365 Library _library;
6366
6367 @override
6368 void setUp() {
6369 _analysisContext = AnalysisContextFactory.contextWithCore();
6370 _errorListener = new GatheringErrorListener();
6371 _library = _createLibrary("/lib.dart");
6372 }
6373
6374 @override
6375 void tearDown() {
6376 _errorListener = null;
6377 _analysisContext = null;
6378 _library = null;
6379 super.tearDown();
6380 }
6381
6382 void test_getExplicitlyImportsCore() {
6383 expect(_library.explicitlyImportsCore, isFalse);
6384 _errorListener.assertNoErrors();
6385 }
6386
6387 void test_getExports() {
6388 expect(_library.exports, hasLength(0));
6389 _errorListener.assertNoErrors();
6390 }
6391
6392 void test_getImports() {
6393 expect(_library.imports, hasLength(0));
6394 _errorListener.assertNoErrors();
6395 }
6396
6397 void test_getImportsAndExports() {
6398 _library.importedLibraries = <Library>[_createLibrary("/imported.dart")];
6399 _library.exportedLibraries = <Library>[_createLibrary("/exported.dart")];
6400 expect(_library.importsAndExports, hasLength(2));
6401 _errorListener.assertNoErrors();
6402 }
6403
6404 void test_getLibraryScope() {
6405 LibraryElementImpl element = new LibraryElementImpl.forNode(
6406 _analysisContext, AstFactory.libraryIdentifier2(["lib"]));
6407 element.definingCompilationUnit =
6408 new CompilationUnitElementImpl("lib.dart");
6409 _library.libraryElement = element;
6410 expect(_library.libraryScope, isNotNull);
6411 _errorListener.assertNoErrors();
6412 }
6413
6414 void test_getLibrarySource() {
6415 expect(_library.librarySource, isNotNull);
6416 }
6417
6418 void test_setExplicitlyImportsCore() {
6419 _library.explicitlyImportsCore = true;
6420 expect(_library.explicitlyImportsCore, isTrue);
6421 _errorListener.assertNoErrors();
6422 }
6423
6424 void test_setExportedLibraries() {
6425 Library exportLibrary = _createLibrary("/exported.dart");
6426 _library.exportedLibraries = <Library>[exportLibrary];
6427 List<Library> exports = _library.exports;
6428 expect(exports, hasLength(1));
6429 expect(exports[0], same(exportLibrary));
6430 _errorListener.assertNoErrors();
6431 }
6432
6433 void test_setImportedLibraries() {
6434 Library importLibrary = _createLibrary("/imported.dart");
6435 _library.importedLibraries = <Library>[importLibrary];
6436 List<Library> imports = _library.imports;
6437 expect(imports, hasLength(1));
6438 expect(imports[0], same(importLibrary));
6439 _errorListener.assertNoErrors();
6440 }
6441
6442 void test_setLibraryElement() {
6443 LibraryElementImpl element = new LibraryElementImpl.forNode(
6444 _analysisContext, AstFactory.libraryIdentifier2(["lib"]));
6445 _library.libraryElement = element;
6446 expect(_library.libraryElement, same(element));
6447 }
6448
6449 Library _createLibrary(String definingCompilationUnitPath) => new Library(
6450 _analysisContext,
6451 _errorListener,
6452 new FileBasedSource(
6453 FileUtilities2.createFile(definingCompilationUnitPath)));
6454 }
6455
6456 @reflectiveTest
6457 class MemberMapTest {
6458 /**
6459 * The null type.
6460 */
6461 InterfaceType _nullType;
6462
6463 void setUp() {
6464 _nullType = new TestTypeProvider().nullType;
6465 }
6466
6467 void test_MemberMap_copyConstructor() {
6468 MethodElement m1 = ElementFactory.methodElement("m1", _nullType);
6469 MethodElement m2 = ElementFactory.methodElement("m2", _nullType);
6470 MethodElement m3 = ElementFactory.methodElement("m3", _nullType);
6471 MemberMap map = new MemberMap();
6472 map.put(m1.name, m1);
6473 map.put(m2.name, m2);
6474 map.put(m3.name, m3);
6475 MemberMap copy = new MemberMap.from(map);
6476 expect(copy.size, map.size);
6477 expect(copy.get(m1.name), m1);
6478 expect(copy.get(m2.name), m2);
6479 expect(copy.get(m3.name), m3);
6480 }
6481
6482 void test_MemberMap_override() {
6483 MethodElement m1 = ElementFactory.methodElement("m", _nullType);
6484 MethodElement m2 = ElementFactory.methodElement("m", _nullType);
6485 MemberMap map = new MemberMap();
6486 map.put(m1.name, m1);
6487 map.put(m2.name, m2);
6488 expect(map.size, 1);
6489 expect(map.get("m"), m2);
6490 }
6491
6492 void test_MemberMap_put() {
6493 MethodElement m1 = ElementFactory.methodElement("m1", _nullType);
6494 MemberMap map = new MemberMap();
6495 expect(map.size, 0);
6496 map.put(m1.name, m1);
6497 expect(map.size, 1);
6498 expect(map.get("m1"), m1);
6499 }
6500 }
6501
6502 /**
6503 * An analysis context that has a fake SDK that is much smaller and faster for
6504 * testing purposes.
6505 */
6506 class NewAnalysisContextForTests extends newContext.AnalysisContextImpl {
6507 @override
6508 void set analysisOptions(AnalysisOptions options) {
6509 AnalysisOptions currentOptions = analysisOptions;
6510 bool needsRecompute = currentOptions.analyzeFunctionBodiesPredicate !=
6511 options.analyzeFunctionBodiesPredicate ||
6512 currentOptions.generateImplicitErrors !=
6513 options.generateImplicitErrors ||
6514 currentOptions.generateSdkErrors != options.generateSdkErrors ||
6515 currentOptions.dart2jsHint != options.dart2jsHint ||
6516 (currentOptions.hint && !options.hint) ||
6517 currentOptions.preserveComments != options.preserveComments ||
6518 currentOptions.enableStrictCallChecks != options.enableStrictCallChecks;
6519 if (needsRecompute) {
6520 fail(
6521 "Cannot set options that cause the sources to be reanalyzed in a test context");
6522 }
6523 super.analysisOptions = options;
6524 }
6525
6526 @override
6527 bool exists(Source source) =>
6528 super.exists(source) || sourceFactory.dartSdk.context.exists(source);
6529
6530 @override
6531 TimestampedData<String> getContents(Source source) {
6532 if (source.isInSystemLibrary) {
6533 return sourceFactory.dartSdk.context.getContents(source);
6534 }
6535 return super.getContents(source);
6536 }
6537
6538 @override
6539 int getModificationStamp(Source source) {
6540 if (source.isInSystemLibrary) {
6541 return sourceFactory.dartSdk.context.getModificationStamp(source);
6542 }
6543 return super.getModificationStamp(source);
6544 }
6545
6546 /**
6547 * Set the analysis options, even if they would force re-analysis. This method should only be
6548 * invoked before the fake SDK is initialized.
6549 *
6550 * @param options the analysis options to be set
6551 */
6552 void _internalSetAnalysisOptions(AnalysisOptions options) {
6553 super.analysisOptions = options;
6554 }
6555 }
6556
6557 @reflectiveTest
6558 class NonHintCodeTest extends ResolverTestCase {
6559 void test_deadCode_deadBlock_conditionalElse_debugConst() {
6560 Source source = addSource(r'''
6561 const bool DEBUG = true;
6562 f() {
6563 DEBUG ? 1 : 2;
6564 }''');
6565 computeLibrarySourceErrors(source);
6566 assertNoErrors(source);
6567 verify([source]);
6568 }
6569
6570 void test_deadCode_deadBlock_conditionalIf_debugConst() {
6571 Source source = addSource(r'''
6572 const bool DEBUG = false;
6573 f() {
6574 DEBUG ? 1 : 2;
6575 }''');
6576 computeLibrarySourceErrors(source);
6577 assertNoErrors(source);
6578 verify([source]);
6579 }
6580
6581 void test_deadCode_deadBlock_else() {
6582 Source source = addSource(r'''
6583 const bool DEBUG = true;
6584 f() {
6585 if(DEBUG) {} else {}
6586 }''');
6587 computeLibrarySourceErrors(source);
6588 assertNoErrors(source);
6589 verify([source]);
6590 }
6591
6592 void test_deadCode_deadBlock_if_debugConst_prefixedIdentifier() {
6593 Source source = addSource(r'''
6594 class A {
6595 static const bool DEBUG = false;
6596 }
6597 f() {
6598 if(A.DEBUG) {}
6599 }''');
6600 computeLibrarySourceErrors(source);
6601 assertNoErrors(source);
6602 verify([source]);
6603 }
6604
6605 void test_deadCode_deadBlock_if_debugConst_prefixedIdentifier2() {
6606 Source source = addSource(r'''
6607 library L;
6608 import 'lib2.dart';
6609 f() {
6610 if(A.DEBUG) {}
6611 }''');
6612 addNamedSource(
6613 "/lib2.dart",
6614 r'''
6615 library lib2;
6616 class A {
6617 static const bool DEBUG = false;
6618 }''');
6619 computeLibrarySourceErrors(source);
6620 assertNoErrors(source);
6621 verify([source]);
6622 }
6623
6624 void test_deadCode_deadBlock_if_debugConst_propertyAccessor() {
6625 Source source = addSource(r'''
6626 library L;
6627 import 'lib2.dart' as LIB;
6628 f() {
6629 if(LIB.A.DEBUG) {}
6630 }''');
6631 addNamedSource(
6632 "/lib2.dart",
6633 r'''
6634 library lib2;
6635 class A {
6636 static const bool DEBUG = false;
6637 }''');
6638 computeLibrarySourceErrors(source);
6639 assertNoErrors(source);
6640 verify([source]);
6641 }
6642
6643 void test_deadCode_deadBlock_if_debugConst_simpleIdentifier() {
6644 Source source = addSource(r'''
6645 const bool DEBUG = false;
6646 f() {
6647 if(DEBUG) {}
6648 }''');
6649 computeLibrarySourceErrors(source);
6650 assertNoErrors(source);
6651 verify([source]);
6652 }
6653
6654 void test_deadCode_deadBlock_while_debugConst() {
6655 Source source = addSource(r'''
6656 const bool DEBUG = false;
6657 f() {
6658 while(DEBUG) {}
6659 }''');
6660 computeLibrarySourceErrors(source);
6661 assertNoErrors(source);
6662 verify([source]);
6663 }
6664
6665 void test_deadCode_deadCatch_onCatchSubtype() {
6666 Source source = addSource(r'''
6667 class A {}
6668 class B extends A {}
6669 f() {
6670 try {} on B catch (e) {} on A catch (e) {} catch (e) {}
6671 }''');
6672 computeLibrarySourceErrors(source);
6673 assertNoErrors(source);
6674 verify([source]);
6675 }
6676
6677 void test_deadCode_deadOperandLHS_and_debugConst() {
6678 Source source = addSource(r'''
6679 const bool DEBUG = false;
6680 f() {
6681 bool b = DEBUG && false;
6682 }''');
6683 computeLibrarySourceErrors(source);
6684 assertNoErrors(source);
6685 verify([source]);
6686 }
6687
6688 void test_deadCode_deadOperandLHS_or_debugConst() {
6689 Source source = addSource(r'''
6690 const bool DEBUG = true;
6691 f() {
6692 bool b = DEBUG || true;
6693 }''');
6694 computeLibrarySourceErrors(source);
6695 assertNoErrors(source);
6696 verify([source]);
6697 }
6698
6699 void test_divisionOptimization() {
6700 Source source = addSource(r'''
6701 f(int x, int y) {
6702 var v = x / y.toInt();
6703 }''');
6704 computeLibrarySourceErrors(source);
6705 assertNoErrors(source);
6706 verify([source]);
6707 }
6708
6709 void test_divisionOptimization_supressIfDivisionNotDefinedInCore() {
6710 Source source = addSource(r'''
6711 f(x, y) {
6712 var v = (x / y).toInt();
6713 }''');
6714 computeLibrarySourceErrors(source);
6715 assertNoErrors(source);
6716 verify([source]);
6717 }
6718
6719 void test_divisionOptimization_supressIfDivisionOverridden() {
6720 Source source = addSource(r'''
6721 class A {
6722 num operator /(x) { return x; }
6723 }
6724 f(A x, A y) {
6725 var v = (x / y).toInt();
6726 }''');
6727 computeLibrarySourceErrors(source);
6728 assertNoErrors(source);
6729 verify([source]);
6730 }
6731
6732 void test_duplicateImport_as() {
6733 Source source = addSource(r'''
6734 library L;
6735 import 'lib1.dart';
6736 import 'lib1.dart' as one;
6737 A a;
6738 one.A a2;''');
6739 addNamedSource(
6740 "/lib1.dart",
6741 r'''
6742 library lib1;
6743 class A {}''');
6744 computeLibrarySourceErrors(source);
6745 assertNoErrors(source);
6746 verify([source]);
6747 }
6748
6749 void test_duplicateImport_hide() {
6750 Source source = addSource(r'''
6751 library L;
6752 import 'lib1.dart';
6753 import 'lib1.dart' hide A;
6754 A a;
6755 B b;''');
6756 addNamedSource(
6757 "/lib1.dart",
6758 r'''
6759 library lib1;
6760 class A {}
6761 class B {}''');
6762 computeLibrarySourceErrors(source);
6763 assertNoErrors(source);
6764 verify([source]);
6765 }
6766
6767 void test_duplicateImport_show() {
6768 Source source = addSource(r'''
6769 library L;
6770 import 'lib1.dart';
6771 import 'lib1.dart' show A;
6772 A a;
6773 B b;''');
6774 addNamedSource(
6775 "/lib1.dart",
6776 r'''
6777 library lib1;
6778 class A {}
6779 class B {}''');
6780 computeLibrarySourceErrors(source);
6781 assertNoErrors(source);
6782 verify([source]);
6783 }
6784
6785 void test_importDeferredLibraryWithLoadFunction() {
6786 resolveWithErrors(<String>[
6787 r'''
6788 library lib1;
6789 f() {}''',
6790 r'''
6791 library root;
6792 import 'lib1.dart' deferred as lib1;
6793 main() { lib1.f(); }'''
6794 ], ErrorCode.EMPTY_LIST);
6795 }
6796
6797 void test_issue20904BuggyTypePromotionAtIfJoin_1() {
6798 // https://code.google.com/p/dart/issues/detail?id=20904
6799 Source source = addSource(r'''
6800 f(var message, var dynamic_) {
6801 if (message is Function) {
6802 message = dynamic_;
6803 }
6804 int s = message;
6805 }''');
6806 computeLibrarySourceErrors(source);
6807 assertNoErrors(source);
6808 verify([source]);
6809 }
6810
6811 void test_issue20904BuggyTypePromotionAtIfJoin_3() {
6812 // https://code.google.com/p/dart/issues/detail?id=20904
6813 Source source = addSource(r'''
6814 f(var message) {
6815 var dynamic_;
6816 if (message is Function) {
6817 message = dynamic_;
6818 } else {
6819 return;
6820 }
6821 int s = message;
6822 }''');
6823 computeLibrarySourceErrors(source);
6824 assertNoErrors(source);
6825 verify([source]);
6826 }
6827
6828 void test_issue20904BuggyTypePromotionAtIfJoin_4() {
6829 // https://code.google.com/p/dart/issues/detail?id=20904
6830 Source source = addSource(r'''
6831 f(var message) {
6832 if (message is Function) {
6833 message = '';
6834 } else {
6835 return;
6836 }
6837 String s = message;
6838 }''');
6839 computeLibrarySourceErrors(source);
6840 assertNoErrors(source);
6841 verify([source]);
6842 }
6843
6844 void test_missingReturn_emptyFunctionBody() {
6845 Source source = addSource(r'''
6846 abstract class A {
6847 int m();
6848 }''');
6849 computeLibrarySourceErrors(source);
6850 assertNoErrors(source);
6851 verify([source]);
6852 }
6853
6854 void test_missingReturn_expressionFunctionBody() {
6855 Source source = addSource("int f() => 0;");
6856 computeLibrarySourceErrors(source);
6857 assertNoErrors(source);
6858 verify([source]);
6859 }
6860
6861 void test_missingReturn_noReturnType() {
6862 Source source = addSource("f() {}");
6863 computeLibrarySourceErrors(source);
6864 assertNoErrors(source);
6865 verify([source]);
6866 }
6867
6868 void test_missingReturn_voidReturnType() {
6869 Source source = addSource("void f() {}");
6870 computeLibrarySourceErrors(source);
6871 assertNoErrors(source);
6872 verify([source]);
6873 }
6874
6875 void test_overrideEqualsButNotHashCode() {
6876 Source source = addSource(r'''
6877 class A {
6878 bool operator ==(x) { return x; }
6879 get hashCode => 0;
6880 }''');
6881 computeLibrarySourceErrors(source);
6882 assertNoErrors(source);
6883 verify([source]);
6884 }
6885
6886 void test_overrideOnNonOverridingGetter_inInterface() {
6887 Source source = addSource(r'''
6888 library dart.core;
6889 const override = null;
6890 class A {
6891 int get m => 0;
6892 }
6893 class B implements A {
6894 @override
6895 int get m => 1;
6896 }''');
6897 computeLibrarySourceErrors(source);
6898 assertNoErrors(source);
6899 verify([source]);
6900 }
6901
6902 void test_overrideOnNonOverridingGetter_inSuperclass() {
6903 Source source = addSource(r'''
6904 library dart.core;
6905 const override = null;
6906 class A {
6907 int get m => 0;
6908 }
6909 class B extends A {
6910 @override
6911 int get m => 1;
6912 }''');
6913 computeLibrarySourceErrors(source);
6914 assertNoErrors(source);
6915 verify([source]);
6916 }
6917
6918 void test_overrideOnNonOverridingMethod_inInterface() {
6919 Source source = addSource(r'''
6920 library dart.core;
6921 const override = null;
6922 class A {
6923 int m() => 0;
6924 }
6925 class B implements A {
6926 @override
6927 int m() => 1;
6928 }''');
6929 computeLibrarySourceErrors(source);
6930 assertNoErrors(source);
6931 verify([source]);
6932 }
6933
6934 void test_overrideOnNonOverridingMethod_inSuperclass() {
6935 Source source = addSource(r'''
6936 library dart.core;
6937 const override = null;
6938 class A {
6939 int m() => 0;
6940 }
6941 class B extends A {
6942 @override
6943 int m() => 1;
6944 }''');
6945 computeLibrarySourceErrors(source);
6946 assertNoErrors(source);
6947 verify([source]);
6948 }
6949
6950 void test_overrideOnNonOverridingSetter_inInterface() {
6951 Source source = addSource(r'''
6952 library dart.core;
6953 const override = null;
6954 class A {
6955 set m(int x) {}
6956 }
6957 class B implements A {
6958 @override
6959 set m(int x) {}
6960 }''');
6961 computeLibrarySourceErrors(source);
6962 assertNoErrors(source);
6963 verify([source]);
6964 }
6965
6966 void test_overrideOnNonOverridingSetter_inSuperclass() {
6967 Source source = addSource(r'''
6968 library dart.core;
6969 const override = null;
6970 class A {
6971 set m(int x) {}
6972 }
6973 class B extends A {
6974 @override
6975 set m(int x) {}
6976 }''');
6977 computeLibrarySourceErrors(source);
6978 assertNoErrors(source);
6979 verify([source]);
6980 }
6981
6982 void test_propagatedFieldType() {
6983 Source source = addSource(r'''
6984 class A { }
6985 class X<T> {
6986 final x = new List<T>();
6987 }
6988 class Z {
6989 final X<A> y = new X<A>();
6990 foo() {
6991 y.x.add(new A());
6992 }
6993 }''');
6994 computeLibrarySourceErrors(source);
6995 assertNoErrors(source);
6996 verify([source]);
6997 }
6998
6999 void test_proxy_annotation_prefixed() {
7000 Source source = addSource(r'''
7001 library L;
7002 @proxy
7003 class A {}
7004 f(var a) {
7005 a = new A();
7006 a.m();
7007 var x = a.g;
7008 a.s = 1;
7009 var y = a + a;
7010 a++;
7011 ++a;
7012 }''');
7013 computeLibrarySourceErrors(source);
7014 assertNoErrors(source);
7015 }
7016
7017 void test_proxy_annotation_prefixed2() {
7018 Source source = addSource(r'''
7019 library L;
7020 @proxy
7021 class A {}
7022 class B {
7023 f(var a) {
7024 a = new A();
7025 a.m();
7026 var x = a.g;
7027 a.s = 1;
7028 var y = a + a;
7029 a++;
7030 ++a;
7031 }
7032 }''');
7033 computeLibrarySourceErrors(source);
7034 assertNoErrors(source);
7035 }
7036
7037 void test_proxy_annotation_prefixed3() {
7038 Source source = addSource(r'''
7039 library L;
7040 class B {
7041 f(var a) {
7042 a = new A();
7043 a.m();
7044 var x = a.g;
7045 a.s = 1;
7046 var y = a + a;
7047 a++;
7048 ++a;
7049 }
7050 }
7051 @proxy
7052 class A {}''');
7053 computeLibrarySourceErrors(source);
7054 assertNoErrors(source);
7055 }
7056
7057 void test_undefinedGetter_inSubtype() {
7058 Source source = addSource(r'''
7059 class A {}
7060 class B extends A {
7061 get b => 0;
7062 }
7063 f(var a) {
7064 if(a is A) {
7065 return a.b;
7066 }
7067 }''');
7068 computeLibrarySourceErrors(source);
7069 assertNoErrors(source);
7070 }
7071
7072 void test_undefinedMethod_assignmentExpression_inSubtype() {
7073 Source source = addSource(r'''
7074 class A {}
7075 class B extends A {
7076 operator +(B b) {return new B();}
7077 }
7078 f(var a, var a2) {
7079 a = new A();
7080 a2 = new A();
7081 a += a2;
7082 }''');
7083 computeLibrarySourceErrors(source);
7084 assertNoErrors(source);
7085 }
7086
7087 void test_undefinedMethod_dynamic() {
7088 Source source = addSource(r'''
7089 class D<T extends dynamic> {
7090 fieldAccess(T t) => t.abc;
7091 methodAccess(T t) => t.xyz(1, 2, 'three');
7092 }''');
7093 computeLibrarySourceErrors(source);
7094 assertNoErrors(source);
7095 }
7096
7097 void test_undefinedMethod_inSubtype() {
7098 Source source = addSource(r'''
7099 class A {}
7100 class B extends A {
7101 b() {}
7102 }
7103 f() {
7104 var a = new A();
7105 a.b();
7106 }''');
7107 computeLibrarySourceErrors(source);
7108 assertNoErrors(source);
7109 }
7110
7111 void test_undefinedMethod_unionType_all() {
7112 Source source = addSource(r'''
7113 class A {
7114 int m(int x) => 0;
7115 }
7116 class B {
7117 String m() => '0';
7118 }
7119 f(A a, B b) {
7120 var ab;
7121 if (0 < 1) {
7122 ab = a;
7123 } else {
7124 ab = b;
7125 }
7126 ab.m();
7127 }''');
7128 computeLibrarySourceErrors(source);
7129 assertNoErrors(source);
7130 }
7131
7132 void test_undefinedMethod_unionType_some() {
7133 Source source = addSource(r'''
7134 class A {
7135 int m(int x) => 0;
7136 }
7137 class B {}
7138 f(A a, B b) {
7139 var ab;
7140 if (0 < 1) {
7141 ab = a;
7142 } else {
7143 ab = b;
7144 }
7145 ab.m(0);
7146 }''');
7147 computeLibrarySourceErrors(source);
7148 assertNoErrors(source);
7149 }
7150
7151 void test_undefinedOperator_binaryExpression_inSubtype() {
7152 Source source = addSource(r'''
7153 class A {}
7154 class B extends A {
7155 operator +(B b) {}
7156 }
7157 f(var a) {
7158 if(a is A) {
7159 a + 1;
7160 }
7161 }''');
7162 computeLibrarySourceErrors(source);
7163 assertNoErrors(source);
7164 }
7165
7166 void test_undefinedOperator_indexBoth_inSubtype() {
7167 Source source = addSource(r'''
7168 class A {}
7169 class B extends A {
7170 operator [](int index) {}
7171 }
7172 f(var a) {
7173 if(a is A) {
7174 a[0]++;
7175 }
7176 }''');
7177 computeLibrarySourceErrors(source);
7178 assertNoErrors(source);
7179 }
7180
7181 void test_undefinedOperator_indexGetter_inSubtype() {
7182 Source source = addSource(r'''
7183 class A {}
7184 class B extends A {
7185 operator [](int index) {}
7186 }
7187 f(var a) {
7188 if(a is A) {
7189 a[0];
7190 }
7191 }''');
7192 computeLibrarySourceErrors(source);
7193 assertNoErrors(source);
7194 }
7195
7196 void test_undefinedOperator_indexSetter_inSubtype() {
7197 Source source = addSource(r'''
7198 class A {}
7199 class B extends A {
7200 operator []=(i, v) {}
7201 }
7202 f(var a) {
7203 if(a is A) {
7204 a[0] = 1;
7205 }
7206 }''');
7207 computeLibrarySourceErrors(source);
7208 assertNoErrors(source);
7209 }
7210
7211 void test_undefinedOperator_postfixExpression() {
7212 Source source = addSource(r'''
7213 class A {}
7214 class B extends A {
7215 operator +(B b) {return new B();}
7216 }
7217 f(var a) {
7218 if(a is A) {
7219 a++;
7220 }
7221 }''');
7222 computeLibrarySourceErrors(source);
7223 assertNoErrors(source);
7224 }
7225
7226 void test_undefinedOperator_prefixExpression() {
7227 Source source = addSource(r'''
7228 class A {}
7229 class B extends A {
7230 operator +(B b) {return new B();}
7231 }
7232 f(var a) {
7233 if(a is A) {
7234 ++a;
7235 }
7236 }''');
7237 computeLibrarySourceErrors(source);
7238 assertNoErrors(source);
7239 }
7240
7241 void test_undefinedSetter_inSubtype() {
7242 Source source = addSource(r'''
7243 class A {}
7244 class B extends A {
7245 set b(x) {}
7246 }
7247 f(var a) {
7248 if(a is A) {
7249 a.b = 0;
7250 }
7251 }''');
7252 computeLibrarySourceErrors(source);
7253 assertNoErrors(source);
7254 }
7255
7256 void test_unnecessaryCast_13855_parameter_A() {
7257 // dartbug.com/13855, dartbug.com/13732
7258 Source source = addSource(r'''
7259 class A{
7260 a() {}
7261 }
7262 class B<E> {
7263 E e;
7264 m() {
7265 (e as A).a();
7266 }
7267 }''');
7268 computeLibrarySourceErrors(source);
7269 assertNoErrors(source);
7270 verify([source]);
7271 }
7272
7273 void test_unnecessaryCast_conditionalExpression() {
7274 Source source = addSource(r'''
7275 abstract class I {}
7276 class A implements I {}
7277 class B implements I {}
7278 I m(A a, B b) {
7279 return a == null ? b as I : a as I;
7280 }''');
7281 computeLibrarySourceErrors(source);
7282 assertNoErrors(source);
7283 verify([source]);
7284 }
7285
7286 void test_unnecessaryCast_dynamic_type() {
7287 Source source = addSource(r'''
7288 m(v) {
7289 var b = v as Object;
7290 }''');
7291 computeLibrarySourceErrors(source);
7292 assertNoErrors(source);
7293 verify([source]);
7294 }
7295
7296 void test_unnecessaryCast_generics() {
7297 // dartbug.com/18953
7298 Source source = addSource(r'''
7299 import 'dart:async';
7300 Future<int> f() => new Future.value(0);
7301 void g(bool c) {
7302 (c ? f(): new Future.value(0) as Future<int>).then((int value) {});
7303 }''');
7304 computeLibrarySourceErrors(source);
7305 assertNoErrors(source);
7306 verify([source]);
7307 }
7308
7309 void test_unnecessaryCast_type_dynamic() {
7310 Source source = addSource(r'''
7311 m(v) {
7312 var b = Object as dynamic;
7313 }''');
7314 computeLibrarySourceErrors(source);
7315 assertNoErrors(source);
7316 verify([source]);
7317 }
7318
7319 void test_unusedImport_annotationOnDirective() {
7320 Source source = addSource(r'''
7321 library L;
7322 @A()
7323 import 'lib1.dart';''');
7324 Source source2 = addNamedSource(
7325 "/lib1.dart",
7326 r'''
7327 library lib1;
7328 class A {
7329 const A() {}
7330 }''');
7331 computeLibrarySourceErrors(source);
7332 assertErrors(source);
7333 verify([source, source2]);
7334 }
7335
7336 void test_unusedImport_as_equalPrefixes() {
7337 // 18818
7338 Source source = addSource(r'''
7339 library L;
7340 import 'lib1.dart' as one;
7341 import 'lib2.dart' as one;
7342 one.A a;
7343 one.B b;''');
7344 Source source2 = addNamedSource(
7345 "/lib1.dart",
7346 r'''
7347 library lib1;
7348 class A {}''');
7349 Source source3 = addNamedSource(
7350 "/lib2.dart",
7351 r'''
7352 library lib2;
7353 class B {}''');
7354 computeLibrarySourceErrors(source);
7355 assertErrors(source);
7356 assertNoErrors(source2);
7357 assertNoErrors(source3);
7358 verify([source, source2, source3]);
7359 }
7360
7361 void test_unusedImport_core_library() {
7362 Source source = addSource(r'''
7363 library L;
7364 import 'dart:core';''');
7365 computeLibrarySourceErrors(source);
7366 assertNoErrors(source);
7367 verify([source]);
7368 }
7369
7370 void test_unusedImport_export() {
7371 Source source = addSource(r'''
7372 library L;
7373 import 'lib1.dart';
7374 Two two;''');
7375 addNamedSource(
7376 "/lib1.dart",
7377 r'''
7378 library lib1;
7379 export 'lib2.dart';
7380 class One {}''');
7381 addNamedSource(
7382 "/lib2.dart",
7383 r'''
7384 library lib2;
7385 class Two {}''');
7386 computeLibrarySourceErrors(source);
7387 assertNoErrors(source);
7388 verify([source]);
7389 }
7390
7391 void test_unusedImport_export2() {
7392 Source source = addSource(r'''
7393 library L;
7394 import 'lib1.dart';
7395 Three three;''');
7396 addNamedSource(
7397 "/lib1.dart",
7398 r'''
7399 library lib1;
7400 export 'lib2.dart';
7401 class One {}''');
7402 addNamedSource(
7403 "/lib2.dart",
7404 r'''
7405 library lib2;
7406 export 'lib3.dart';
7407 class Two {}''');
7408 addNamedSource(
7409 "/lib3.dart",
7410 r'''
7411 library lib3;
7412 class Three {}''');
7413 computeLibrarySourceErrors(source);
7414 assertNoErrors(source);
7415 verify([source]);
7416 }
7417
7418 void test_unusedImport_export_infiniteLoop() {
7419 Source source = addSource(r'''
7420 library L;
7421 import 'lib1.dart';
7422 Two two;''');
7423 addNamedSource(
7424 "/lib1.dart",
7425 r'''
7426 library lib1;
7427 export 'lib2.dart';
7428 class One {}''');
7429 addNamedSource(
7430 "/lib2.dart",
7431 r'''
7432 library lib2;
7433 export 'lib3.dart';
7434 class Two {}''');
7435 addNamedSource(
7436 "/lib3.dart",
7437 r'''
7438 library lib3;
7439 export 'lib2.dart';
7440 class Three {}''');
7441 computeLibrarySourceErrors(source);
7442 assertNoErrors(source);
7443 verify([source]);
7444 }
7445
7446 void test_unusedImport_metadata() {
7447 Source source = addSource(r'''
7448 library L;
7449 @A(x)
7450 import 'lib1.dart';
7451 class A {
7452 final int value;
7453 const A(this.value);
7454 }''');
7455 addNamedSource(
7456 "/lib1.dart",
7457 r'''
7458 library lib1;
7459 const x = 0;''');
7460 computeLibrarySourceErrors(source);
7461 assertNoErrors(source);
7462 verify([source]);
7463 }
7464
7465 void test_unusedImport_prefix_topLevelFunction() {
7466 Source source = addSource(r'''
7467 library L;
7468 import 'lib1.dart' hide topLevelFunction;
7469 import 'lib1.dart' as one show topLevelFunction;
7470 class A {
7471 static void x() {
7472 One o;
7473 one.topLevelFunction();
7474 }
7475 }''');
7476 addNamedSource(
7477 "/lib1.dart",
7478 r'''
7479 library lib1;
7480 class One {}
7481 topLevelFunction() {}''');
7482 computeLibrarySourceErrors(source);
7483 assertNoErrors(source);
7484 verify([source]);
7485 }
7486
7487 void test_useOfVoidResult_implicitReturnValue() {
7488 Source source = addSource(r'''
7489 f() {}
7490 class A {
7491 n() {
7492 var a = f();
7493 }
7494 }''');
7495 computeLibrarySourceErrors(source);
7496 assertNoErrors(source);
7497 verify([source]);
7498 }
7499
7500 void test_useOfVoidResult_nonVoidReturnValue() {
7501 Source source = addSource(r'''
7502 int f() => 1;
7503 g() {
7504 var a = f();
7505 }''');
7506 computeLibrarySourceErrors(source);
7507 assertNoErrors(source);
7508 verify([source]);
7509 }
7510 }
7511
7512 class PubSuggestionCodeTest extends ResolverTestCase {
7513 void test_import_package() {
7514 Source source = addSource("import 'package:somepackage/other.dart';");
7515 computeLibrarySourceErrors(source);
7516 assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
7517 }
7518
7519 void test_import_packageWithDotDot() {
7520 Source source = addSource("import 'package:somepackage/../other.dart';");
7521 computeLibrarySourceErrors(source);
7522 assertErrors(source, [
7523 CompileTimeErrorCode.URI_DOES_NOT_EXIST,
7524 HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
7525 ]);
7526 }
7527
7528 void test_import_packageWithLeadingDotDot() {
7529 Source source = addSource("import 'package:../other.dart';");
7530 computeLibrarySourceErrors(source);
7531 assertErrors(source, [
7532 CompileTimeErrorCode.URI_DOES_NOT_EXIST,
7533 HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
7534 ]);
7535 }
7536
7537 void test_import_referenceIntoLibDirectory() {
7538 cacheSource("/myproj/pubspec.yaml", "");
7539 cacheSource("/myproj/lib/other.dart", "");
7540 Source source =
7541 addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
7542 computeLibrarySourceErrors(source);
7543 assertErrors(
7544 source, [HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE]);
7545 }
7546
7547 void test_import_referenceIntoLibDirectory_no_pubspec() {
7548 cacheSource("/myproj/lib/other.dart", "");
7549 Source source =
7550 addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
7551 computeLibrarySourceErrors(source);
7552 assertNoErrors(source);
7553 }
7554
7555 void test_import_referenceOutOfLibDirectory() {
7556 cacheSource("/myproj/pubspec.yaml", "");
7557 cacheSource("/myproj/web/other.dart", "");
7558 Source source =
7559 addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
7560 computeLibrarySourceErrors(source);
7561 assertErrors(
7562 source, [HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE]);
7563 }
7564
7565 void test_import_referenceOutOfLibDirectory_no_pubspec() {
7566 cacheSource("/myproj/web/other.dart", "");
7567 Source source =
7568 addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
7569 computeLibrarySourceErrors(source);
7570 assertNoErrors(source);
7571 }
7572
7573 void test_import_valid_inside_lib1() {
7574 cacheSource("/myproj/pubspec.yaml", "");
7575 cacheSource("/myproj/lib/other.dart", "");
7576 Source source =
7577 addNamedSource("/myproj/lib/test.dart", "import 'other.dart';");
7578 computeLibrarySourceErrors(source);
7579 assertNoErrors(source);
7580 }
7581
7582 void test_import_valid_inside_lib2() {
7583 cacheSource("/myproj/pubspec.yaml", "");
7584 cacheSource("/myproj/lib/bar/other.dart", "");
7585 Source source = addNamedSource(
7586 "/myproj/lib/foo/test.dart", "import '../bar/other.dart';");
7587 computeLibrarySourceErrors(source);
7588 assertNoErrors(source);
7589 }
7590
7591 void test_import_valid_outside_lib() {
7592 cacheSource("/myproj/pubspec.yaml", "");
7593 cacheSource("/myproj/web/other.dart", "");
7594 Source source =
7595 addNamedSource("/myproj/lib2/test.dart", "import '../web/other.dart';");
7596 computeLibrarySourceErrors(source);
7597 assertNoErrors(source);
7598 }
7599 }
7600
7601 /**
7602 * An AST visitor used to verify that all of the nodes in an AST structure that
7603 * should have been resolved were resolved.
7604 */
7605 class ResolutionVerifier extends RecursiveAstVisitor<Object> {
7606 /**
7607 * A set containing nodes that are known to not be resolvable and should
7608 * therefore not cause the test to fail.
7609 */
7610 final Set<AstNode> _knownExceptions;
7611
7612 /**
7613 * A list containing all of the AST nodes that were not resolved.
7614 */
7615 List<AstNode> _unresolvedNodes = new List<AstNode>();
7616
7617 /**
7618 * A list containing all of the AST nodes that were resolved to an element of
7619 * the wrong type.
7620 */
7621 List<AstNode> _wrongTypedNodes = new List<AstNode>();
7622
7623 /**
7624 * Initialize a newly created verifier to verify that all of the identifiers
7625 * in the visited AST structures that are expected to have been resolved have
7626 * an element associated with them. Nodes in the set of [_knownExceptions] are
7627 * not expected to have been resolved, even if they normally would have been
7628 * expected to have been resolved.
7629 */
7630 ResolutionVerifier([this._knownExceptions]);
7631
7632 /**
7633 * Assert that all of the visited identifiers were resolved.
7634 */
7635 void assertResolved() {
7636 if (!_unresolvedNodes.isEmpty || !_wrongTypedNodes.isEmpty) {
7637 StringBuffer buffer = new StringBuffer();
7638 if (!_unresolvedNodes.isEmpty) {
7639 buffer.write("Failed to resolve ");
7640 buffer.write(_unresolvedNodes.length);
7641 buffer.writeln(" nodes:");
7642 _printNodes(buffer, _unresolvedNodes);
7643 }
7644 if (!_wrongTypedNodes.isEmpty) {
7645 buffer.write("Resolved ");
7646 buffer.write(_wrongTypedNodes.length);
7647 buffer.writeln(" to the wrong type of element:");
7648 _printNodes(buffer, _wrongTypedNodes);
7649 }
7650 fail(buffer.toString());
7651 }
7652 }
7653
7654 @override
7655 Object visitAnnotation(Annotation node) {
7656 node.visitChildren(this);
7657 ElementAnnotation elementAnnotation = node.elementAnnotation;
7658 if (elementAnnotation == null) {
7659 if (_knownExceptions == null || !_knownExceptions.contains(node)) {
7660 _unresolvedNodes.add(node);
7661 }
7662 } else if (elementAnnotation is! ElementAnnotation) {
7663 _wrongTypedNodes.add(node);
7664 }
7665 return null;
7666 }
7667
7668 @override
7669 Object visitBinaryExpression(BinaryExpression node) {
7670 node.visitChildren(this);
7671 if (!node.operator.isUserDefinableOperator) {
7672 return null;
7673 }
7674 DartType operandType = node.leftOperand.staticType;
7675 if (operandType == null || operandType.isDynamic) {
7676 return null;
7677 }
7678 return _checkResolved(
7679 node, node.staticElement, (node) => node is MethodElement);
7680 }
7681
7682 @override
7683 Object visitCommentReference(CommentReference node) => null;
7684
7685 @override
7686 Object visitCompilationUnit(CompilationUnit node) {
7687 node.visitChildren(this);
7688 return _checkResolved(
7689 node, node.element, (node) => node is CompilationUnitElement);
7690 }
7691
7692 @override
7693 Object visitExportDirective(ExportDirective node) =>
7694 _checkResolved(node, node.element, (node) => node is ExportElement);
7695
7696 @override
7697 Object visitFunctionDeclaration(FunctionDeclaration node) {
7698 node.visitChildren(this);
7699 if (node.element is LibraryElement) {
7700 _wrongTypedNodes.add(node);
7701 }
7702 return null;
7703 }
7704
7705 @override
7706 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
7707 node.visitChildren(this);
7708 // TODO(brianwilkerson) If we start resolving function expressions, then
7709 // conditionally check to see whether the node was resolved correctly.
7710 return null;
7711 //checkResolved(node, node.getElement(), FunctionElement.class);
7712 }
7713
7714 @override
7715 Object visitImportDirective(ImportDirective node) {
7716 // Not sure how to test the combinators given that it isn't an error if the
7717 // names are not defined.
7718 _checkResolved(node, node.element, (node) => node is ImportElement);
7719 SimpleIdentifier prefix = node.prefix;
7720 if (prefix == null) {
7721 return null;
7722 }
7723 return _checkResolved(
7724 prefix, prefix.staticElement, (node) => node is PrefixElement);
7725 }
7726
7727 @override
7728 Object visitIndexExpression(IndexExpression node) {
7729 node.visitChildren(this);
7730 DartType targetType = node.realTarget.staticType;
7731 if (targetType == null || targetType.isDynamic) {
7732 return null;
7733 }
7734 return _checkResolved(
7735 node, node.staticElement, (node) => node is MethodElement);
7736 }
7737
7738 @override
7739 Object visitLibraryDirective(LibraryDirective node) =>
7740 _checkResolved(node, node.element, (node) => node is LibraryElement);
7741
7742 @override
7743 Object visitNamedExpression(NamedExpression node) =>
7744 node.expression.accept(this);
7745
7746 @override
7747 Object visitPartDirective(PartDirective node) => _checkResolved(
7748 node, node.element, (node) => node is CompilationUnitElement);
7749
7750 @override
7751 Object visitPartOfDirective(PartOfDirective node) =>
7752 _checkResolved(node, node.element, (node) => node is LibraryElement);
7753
7754 @override
7755 Object visitPostfixExpression(PostfixExpression node) {
7756 node.visitChildren(this);
7757 if (!node.operator.isUserDefinableOperator) {
7758 return null;
7759 }
7760 DartType operandType = node.operand.staticType;
7761 if (operandType == null || operandType.isDynamic) {
7762 return null;
7763 }
7764 return _checkResolved(
7765 node, node.staticElement, (node) => node is MethodElement);
7766 }
7767
7768 @override
7769 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
7770 SimpleIdentifier prefix = node.prefix;
7771 prefix.accept(this);
7772 DartType prefixType = prefix.staticType;
7773 if (prefixType == null || prefixType.isDynamic) {
7774 return null;
7775 }
7776 return _checkResolved(node, node.staticElement, null);
7777 }
7778
7779 @override
7780 Object visitPrefixExpression(PrefixExpression node) {
7781 node.visitChildren(this);
7782 if (!node.operator.isUserDefinableOperator) {
7783 return null;
7784 }
7785 DartType operandType = node.operand.staticType;
7786 if (operandType == null || operandType.isDynamic) {
7787 return null;
7788 }
7789 return _checkResolved(
7790 node, node.staticElement, (node) => node is MethodElement);
7791 }
7792
7793 @override
7794 Object visitPropertyAccess(PropertyAccess node) {
7795 Expression target = node.realTarget;
7796 target.accept(this);
7797 DartType targetType = target.staticType;
7798 if (targetType == null || targetType.isDynamic) {
7799 return null;
7800 }
7801 return node.propertyName.accept(this);
7802 }
7803
7804 @override
7805 Object visitSimpleIdentifier(SimpleIdentifier node) {
7806 if (node.name == "void") {
7807 return null;
7808 }
7809 AstNode parent = node.parent;
7810 if (parent is MethodInvocation) {
7811 MethodInvocation invocation = parent;
7812 if (identical(invocation.methodName, node)) {
7813 Expression target = invocation.realTarget;
7814 DartType targetType = target == null ? null : target.staticType;
7815 if (targetType == null || targetType.isDynamic) {
7816 return null;
7817 }
7818 }
7819 }
7820 return _checkResolved(node, node.staticElement, null);
7821 }
7822
7823 Object _checkResolved(
7824 AstNode node, Element element, Predicate<Element> predicate) {
7825 if (element == null) {
7826 if (_knownExceptions == null || !_knownExceptions.contains(node)) {
7827 _unresolvedNodes.add(node);
7828 }
7829 } else if (predicate != null) {
7830 if (!predicate(element)) {
7831 _wrongTypedNodes.add(node);
7832 }
7833 }
7834 return null;
7835 }
7836
7837 String _getFileName(AstNode node) {
7838 // TODO (jwren) there are two copies of this method, one here and one in
7839 // StaticTypeVerifier, they should be resolved into a single method
7840 if (node != null) {
7841 AstNode root = node.root;
7842 if (root is CompilationUnit) {
7843 CompilationUnit rootCU = root;
7844 if (rootCU.element != null) {
7845 return rootCU.element.source.fullName;
7846 } else {
7847 return "<unknown file- CompilationUnit.getElement() returned null>";
7848 }
7849 } else {
7850 return "<unknown file- CompilationUnit.getRoot() is not a CompilationUni t>";
7851 }
7852 }
7853 return "<unknown file- ASTNode is null>";
7854 }
7855
7856 void _printNodes(StringBuffer buffer, List<AstNode> nodes) {
7857 for (AstNode identifier in nodes) {
7858 buffer.write(" ");
7859 buffer.write(identifier.toString());
7860 buffer.write(" (");
7861 buffer.write(_getFileName(identifier));
7862 buffer.write(" : ");
7863 buffer.write(identifier.offset);
7864 buffer.writeln(")");
7865 }
7866 }
7867 }
7868
7869 class ResolverTestCase extends EngineTestCase {
7870 /**
7871 * The analysis context used to parse the compilation units being resolved.
7872 */
7873 InternalAnalysisContext analysisContext2;
7874
7875 /**
7876 * Specifies if [assertErrors] should check for [HintCode.UNUSED_ELEMENT] and
7877 * [HintCode.UNUSED_FIELD].
7878 */
7879 bool enableUnusedElement = false;
7880
7881 /**
7882 * Specifies if [assertErrors] should check for [HintCode.UNUSED_LOCAL_VARIABL E].
7883 */
7884 bool enableUnusedLocalVariable = false;
7885
7886 AnalysisContext get analysisContext => analysisContext2;
7887
7888 /**
7889 * Return a type provider that can be used to test the results of resolution.
7890 *
7891 * @return a type provider
7892 * @throws AnalysisException if dart:core cannot be resolved
7893 */
7894 TypeProvider get typeProvider => analysisContext2.typeProvider;
7895
7896 /**
7897 * Add a source file to the content provider. The file path should be absolute .
7898 *
7899 * @param filePath the path of the file being added
7900 * @param contents the contents to be returned by the content provider for the specified file
7901 * @return the source object representing the added file
7902 */
7903 Source addNamedSource(String filePath, String contents) {
7904 Source source = cacheSource(filePath, contents);
7905 ChangeSet changeSet = new ChangeSet();
7906 changeSet.addedSource(source);
7907 analysisContext2.applyChanges(changeSet);
7908 return source;
7909 }
7910
7911 /**
7912 * Add a source file to the content provider.
7913 *
7914 * @param contents the contents to be returned by the content provider for the specified file
7915 * @return the source object representing the added file
7916 */
7917 Source addSource(String contents) => addNamedSource("/test.dart", contents);
7918
7919 /**
7920 * Assert that the number of errors reported against the given source matches the number of errors
7921 * that are given and that they have the expected error codes. The order in wh ich the errors were
7922 * gathered is ignored.
7923 *
7924 * @param source the source against which the errors should have been reported
7925 * @param expectedErrorCodes the error codes of the errors that should have be en reported
7926 * @throws AnalysisException if the reported errors could not be computed
7927 * @throws AssertionFailedError if a different number of errors have been repo rted than were
7928 * expected
7929 */
7930 void assertErrors(Source source,
7931 [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
7932 GatheringErrorListener errorListener = new GatheringErrorListener();
7933 for (AnalysisError error in analysisContext2.computeErrors(source)) {
7934 ErrorCode errorCode = error.errorCode;
7935 if (!enableUnusedElement &&
7936 (errorCode == HintCode.UNUSED_ELEMENT ||
7937 errorCode == HintCode.UNUSED_FIELD)) {
7938 continue;
7939 }
7940 if (!enableUnusedLocalVariable &&
7941 (errorCode == HintCode.UNUSED_CATCH_CLAUSE ||
7942 errorCode == HintCode.UNUSED_CATCH_STACK ||
7943 errorCode == HintCode.UNUSED_LOCAL_VARIABLE)) {
7944 continue;
7945 }
7946 errorListener.onError(error);
7947 }
7948 errorListener.assertErrorsWithCodes(expectedErrorCodes);
7949 }
7950
7951 /**
7952 * Assert that no errors have been reported against the given source.
7953 *
7954 * @param source the source against which no errors should have been reported
7955 * @throws AnalysisException if the reported errors could not be computed
7956 * @throws AssertionFailedError if any errors have been reported
7957 */
7958 void assertNoErrors(Source source) {
7959 assertErrors(source);
7960 }
7961
7962 /**
7963 * Cache the source file content in the source factory but don't add the sourc e to the analysis
7964 * context. The file path should be absolute.
7965 *
7966 * @param filePath the path of the file being cached
7967 * @param contents the contents to be returned by the content provider for the specified file
7968 * @return the source object representing the cached file
7969 */
7970 Source cacheSource(String filePath, String contents) {
7971 Source source = new FileBasedSource(FileUtilities2.createFile(filePath));
7972 analysisContext2.setContents(source, contents);
7973 return source;
7974 }
7975
7976 /**
7977 * Computes errors for the given [librarySource].
7978 * This assumes that the given [librarySource] and its parts have already
7979 * been added to the content provider using the method [addNamedSource].
7980 */
7981 void computeLibrarySourceErrors(Source librarySource) {
7982 analysisContext.computeErrors(librarySource);
7983 }
7984
7985 /**
7986 * Create a library element that represents a library named `"test"` containin g a single
7987 * empty compilation unit.
7988 *
7989 * @return the library element that was created
7990 */
7991 LibraryElementImpl createDefaultTestLibrary() =>
7992 createTestLibrary(AnalysisContextFactory.contextWithCore(), "test");
7993
7994 /**
7995 * Create a library element that represents a library with the given name cont aining a single
7996 * empty compilation unit.
7997 *
7998 * @param libraryName the name of the library to be created
7999 * @return the library element that was created
8000 */
8001 LibraryElementImpl createTestLibrary(
8002 AnalysisContext context, String libraryName,
8003 [List<String> typeNames]) {
8004 String fileName = "$libraryName.dart";
8005 FileBasedSource definingCompilationUnitSource =
8006 _createNamedSource(fileName);
8007 List<CompilationUnitElement> sourcedCompilationUnits;
8008 if (typeNames == null) {
8009 sourcedCompilationUnits = CompilationUnitElement.EMPTY_LIST;
8010 } else {
8011 int count = typeNames.length;
8012 sourcedCompilationUnits = new List<CompilationUnitElement>(count);
8013 for (int i = 0; i < count; i++) {
8014 String typeName = typeNames[i];
8015 ClassElementImpl type =
8016 new ClassElementImpl.forNode(AstFactory.identifier3(typeName));
8017 String fileName = "$typeName.dart";
8018 CompilationUnitElementImpl compilationUnit =
8019 new CompilationUnitElementImpl(fileName);
8020 compilationUnit.source = _createNamedSource(fileName);
8021 compilationUnit.librarySource = definingCompilationUnitSource;
8022 compilationUnit.types = <ClassElement>[type];
8023 sourcedCompilationUnits[i] = compilationUnit;
8024 }
8025 }
8026 CompilationUnitElementImpl compilationUnit =
8027 new CompilationUnitElementImpl(fileName);
8028 compilationUnit.librarySource =
8029 compilationUnit.source = definingCompilationUnitSource;
8030 LibraryElementImpl library = new LibraryElementImpl.forNode(
8031 context, AstFactory.libraryIdentifier2([libraryName]));
8032 library.definingCompilationUnit = compilationUnit;
8033 library.parts = sourcedCompilationUnits;
8034 return library;
8035 }
8036
8037 Expression findTopLevelConstantExpression(
8038 CompilationUnit compilationUnit, String name) =>
8039 findTopLevelDeclaration(compilationUnit, name).initializer;
8040
8041 VariableDeclaration findTopLevelDeclaration(
8042 CompilationUnit compilationUnit, String name) {
8043 for (CompilationUnitMember member in compilationUnit.declarations) {
8044 if (member is TopLevelVariableDeclaration) {
8045 for (VariableDeclaration variable in member.variables.variables) {
8046 if (variable.name.name == name) {
8047 return variable;
8048 }
8049 }
8050 }
8051 }
8052 return null;
8053 // Not found
8054 }
8055
8056 /**
8057 * @param code the code that assigns the value to the variable "v", no matter how. We check that
8058 * "v" has expected static and propagated type.
8059 */
8060 void _assertPropagatedAssignedType(String code, DartType expectedStaticType,
8061 DartType expectedPropagatedType) {
8062 SimpleIdentifier identifier = _findMarkedIdentifier(code, "v = ");
8063 expect(identifier.staticType, same(expectedStaticType));
8064 expect(identifier.propagatedType, same(expectedPropagatedType));
8065 }
8066
8067 /**
8068 * Check the static and propagated types of the expression marked with "; // m arker" comment.
8069 *
8070 * @param code source code to analyze, with the expression to check marked wit h "// marker".
8071 * @param expectedStaticType if non-null, check actual static type is equal to this.
8072 * @param expectedPropagatedType if non-null, check actual static type is equa l to this.
8073 * @throws Exception
8074 */
8075 void _assertTypeOfMarkedExpression(String code, DartType expectedStaticType,
8076 DartType expectedPropagatedType) {
8077 SimpleIdentifier identifier = _findMarkedIdentifier(code, "; // marker");
8078 if (expectedStaticType != null) {
8079 expect(identifier.staticType, expectedStaticType);
8080 }
8081 expect(identifier.propagatedType, expectedPropagatedType);
8082 }
8083
8084 /**
8085 * Return the `SimpleIdentifier` marked by `marker`. The source code must have no
8086 * errors and be verifiable.
8087 *
8088 * @param code source code to analyze.
8089 * @param marker marker identifying sought after expression in source code.
8090 * @return expression marked by the marker.
8091 * @throws Exception
8092 */
8093 SimpleIdentifier _findMarkedIdentifier(String code, String marker) {
8094 try {
8095 Source source = addSource(code);
8096 LibraryElement library = resolve2(source);
8097 assertNoErrors(source);
8098 verify([source]);
8099 CompilationUnit unit = resolveCompilationUnit(source, library);
8100 // Could generalize this further by making [SimpleIdentifier.class] a
8101 // parameter.
8102 return EngineTestCase.findNode(
8103 unit, code, marker, (node) => node is SimpleIdentifier);
8104 } catch (exception) {
8105 // Is there a better exception to throw here? The point is that an
8106 // assertion failure here should be a failure, in both "test_*" and
8107 // "fail_*" tests. However, an assertion failure is success for the
8108 // purpose of "fail_*" tests, so without catching them here "fail_*" tests
8109 // can succeed by failing for the wrong reason.
8110 throw new JavaException("Unexexpected assertion failure: $exception");
8111 }
8112 }
8113
8114 /**
8115 * In the rare cases we want to group several tests into single "test_" method , so need a way to
8116 * reset test instance to reuse it.
8117 */
8118 void reset() {
8119 analysisContext2 = AnalysisContextFactory.contextWithCore();
8120 }
8121
8122 /**
8123 * Reset the analysis context to have the given options applied.
8124 *
8125 * @param options the analysis options to be applied to the context
8126 */
8127 void resetWithOptions(AnalysisOptions options) {
8128 analysisContext2 =
8129 AnalysisContextFactory.contextWithCoreAndOptions(options);
8130 }
8131
8132 /**
8133 * Given a library and all of its parts, resolve the contents of the library a nd the contents of
8134 * the parts. This assumes that the sources for the library and its parts have already been added
8135 * to the content provider using the method [addNamedSource].
8136 *
8137 * @param librarySource the source for the compilation unit that defines the l ibrary
8138 * @return the element representing the resolved library
8139 * @throws AnalysisException if the analysis could not be performed
8140 */
8141 LibraryElement resolve2(Source librarySource) =>
8142 analysisContext2.computeLibraryElement(librarySource);
8143
8144 /**
8145 * Return the resolved compilation unit corresponding to the given source in t he given library.
8146 *
8147 * @param source the source of the compilation unit to be returned
8148 * @param library the library in which the compilation unit is to be resolved
8149 * @return the resolved compilation unit
8150 * @throws Exception if the compilation unit could not be resolved
8151 */
8152 CompilationUnit resolveCompilationUnit(
8153 Source source, LibraryElement library) =>
8154 analysisContext2.resolveCompilationUnit(source, library);
8155
8156 CompilationUnit resolveSource(String sourceText) =>
8157 resolveSource2("/test.dart", sourceText);
8158
8159 CompilationUnit resolveSource2(String fileName, String sourceText) {
8160 Source source = addNamedSource(fileName, sourceText);
8161 LibraryElement library = analysisContext.computeLibraryElement(source);
8162 return analysisContext.resolveCompilationUnit(source, library);
8163 }
8164
8165 Source resolveSources(List<String> sourceTexts) {
8166 for (int i = 0; i < sourceTexts.length; i++) {
8167 CompilationUnit unit =
8168 resolveSource2("/lib${i + 1}.dart", sourceTexts[i]);
8169 // reference the source if this is the last source
8170 if (i + 1 == sourceTexts.length) {
8171 return unit.element.source;
8172 }
8173 }
8174 return null;
8175 }
8176
8177 void resolveWithAndWithoutExperimental(
8178 List<String> strSources,
8179 List<ErrorCode> codesWithoutExperimental,
8180 List<ErrorCode> codesWithExperimental) {
8181 // Setup analysis context as non-experimental
8182 AnalysisOptionsImpl options = new AnalysisOptionsImpl();
8183 // options.enableDeferredLoading = false;
8184 resetWithOptions(options);
8185 // Analysis and assertions
8186 Source source = resolveSources(strSources);
8187 assertErrors(source, codesWithoutExperimental);
8188 verify([source]);
8189 // Setup analysis context as experimental
8190 reset();
8191 // Analysis and assertions
8192 source = resolveSources(strSources);
8193 assertErrors(source, codesWithExperimental);
8194 verify([source]);
8195 }
8196
8197 void resolveWithErrors(List<String> strSources, List<ErrorCode> codes) {
8198 // Analysis and assertions
8199 Source source = resolveSources(strSources);
8200 assertErrors(source, codes);
8201 verify([source]);
8202 }
8203
8204 @override
8205 void setUp() {
8206 reset();
8207 }
8208
8209 @override
8210 void tearDown() {
8211 analysisContext2 = null;
8212 super.tearDown();
8213 }
8214
8215 /**
8216 * Verify that all of the identifiers in the compilation units associated with
8217 * the given [sources] have been resolved.
8218 */
8219 void verify(List<Source> sources) {
8220 ResolutionVerifier verifier = new ResolutionVerifier();
8221 for (Source source in sources) {
8222 List<Source> libraries = analysisContext2.getLibrariesContaining(source);
8223 for (Source library in libraries) {
8224 analysisContext2
8225 .resolveCompilationUnit2(source, library)
8226 .accept(verifier);
8227 }
8228 }
8229 verifier.assertResolved();
8230 }
8231
8232 /**
8233 * Create a source object representing a file with the given [fileName] and
8234 * give it an empty content. Return the source that was created.
8235 */
8236 FileBasedSource _createNamedSource(String fileName) {
8237 FileBasedSource source =
8238 new FileBasedSource(FileUtilities2.createFile(fileName));
8239 analysisContext2.setContents(source, "");
8240 return source;
8241 }
8242 }
8243
8244 class Scope_EnclosedScopeTest_test_define_duplicate extends Scope {
8245 GatheringErrorListener listener;
8246
8247 Scope_EnclosedScopeTest_test_define_duplicate(this.listener) : super();
8248
8249 @override
8250 AnalysisErrorListener get errorListener => listener;
8251
8252 @override
8253 Element internalLookup(Identifier identifier, String name,
8254 LibraryElement referencingLibrary) =>
8255 null;
8256 }
8257
8258 class Scope_EnclosedScopeTest_test_define_normal extends Scope {
8259 GatheringErrorListener listener;
8260
8261 Scope_EnclosedScopeTest_test_define_normal(this.listener) : super();
8262
8263 @override
8264 AnalysisErrorListener get errorListener => listener;
8265
8266 @override
8267 Element internalLookup(Identifier identifier, String name,
8268 LibraryElement referencingLibrary) =>
8269 null;
8270 }
8271
8272 @reflectiveTest
8273 class ScopeTest extends ResolverTestCase {
8274 void test_define_duplicate() {
8275 GatheringErrorListener errorListener = new GatheringErrorListener();
8276 ScopeTest_TestScope scope = new ScopeTest_TestScope(errorListener);
8277 VariableElement element1 =
8278 ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
8279 VariableElement element2 =
8280 ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
8281 scope.define(element1);
8282 scope.define(element2);
8283 errorListener.assertErrorsWithSeverities([ErrorSeverity.ERROR]);
8284 }
8285
8286 void test_define_normal() {
8287 GatheringErrorListener errorListener = new GatheringErrorListener();
8288 ScopeTest_TestScope scope = new ScopeTest_TestScope(errorListener);
8289 VariableElement element1 =
8290 ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
8291 VariableElement element2 =
8292 ElementFactory.localVariableElement(AstFactory.identifier3("v2"));
8293 scope.define(element1);
8294 scope.define(element2);
8295 errorListener.assertNoErrors();
8296 }
8297
8298 void test_getErrorListener() {
8299 GatheringErrorListener errorListener = new GatheringErrorListener();
8300 ScopeTest_TestScope scope = new ScopeTest_TestScope(errorListener);
8301 expect(scope.errorListener, errorListener);
8302 }
8303
8304 void test_isPrivateName_nonPrivate() {
8305 expect(Scope.isPrivateName("Public"), isFalse);
8306 }
8307
8308 void test_isPrivateName_private() {
8309 expect(Scope.isPrivateName("_Private"), isTrue);
8310 }
8311 }
8312
8313 /**
8314 * A non-abstract subclass that can be used for testing purposes.
8315 */
8316 class ScopeTest_TestScope extends Scope {
8317 /**
8318 * The listener that is to be informed when an error is encountered.
8319 */
8320 final AnalysisErrorListener errorListener;
8321
8322 ScopeTest_TestScope(this.errorListener);
8323
8324 @override
8325 Element internalLookup(Identifier identifier, String name,
8326 LibraryElement referencingLibrary) =>
8327 localLookup(name, referencingLibrary);
8328 }
8329
8330 @reflectiveTest
8331 class SimpleResolverTest extends ResolverTestCase {
8332 void fail_getter_and_setter_fromMixins_property_access() {
8333 // TODO(paulberry): it appears that auxiliaryElements isn't properly set on
8334 // a SimpleIdentifier that's inside a property access. This bug should be
8335 // fixed.
8336 Source source = addSource('''
8337 class B {}
8338 class M1 {
8339 get x => null;
8340 set x(value) {}
8341 }
8342 class M2 {
8343 get x => null;
8344 set x(value) {}
8345 }
8346 class C extends B with M1, M2 {}
8347 void main() {
8348 new C().x += 1;
8349 }
8350 ''');
8351 LibraryElement library = resolve2(source);
8352 assertNoErrors(source);
8353 verify([source]);
8354 // Verify that both the getter and setter for "x" in "new C().x" refer to
8355 // the accessors defined in M2.
8356 FunctionDeclaration main =
8357 library.definingCompilationUnit.functions[0].computeNode();
8358 BlockFunctionBody body = main.functionExpression.body;
8359 ExpressionStatement stmt = body.block.statements[0];
8360 AssignmentExpression assignment = stmt.expression;
8361 PropertyAccess propertyAccess = assignment.leftHandSide;
8362 expect(
8363 propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
8364 expect(
8365 propertyAccess
8366 .propertyName.auxiliaryElements.staticElement.enclosingElement.name,
8367 'M2');
8368 }
8369
8370 void fail_staticInvocation() {
8371 Source source = addSource(r'''
8372 class A {
8373 static int get g => (a,b) => 0;
8374 }
8375 class B {
8376 f() {
8377 A.g(1,0);
8378 }
8379 }''');
8380 computeLibrarySourceErrors(source);
8381 assertNoErrors(source);
8382 verify([source]);
8383 }
8384
8385 void test_argumentResolution_required_matching() {
8386 Source source = addSource(r'''
8387 class A {
8388 void f() {
8389 g(1, 2, 3);
8390 }
8391 void g(a, b, c) {}
8392 }''');
8393 _validateArgumentResolution(source, [0, 1, 2]);
8394 }
8395
8396 void test_argumentResolution_required_tooFew() {
8397 Source source = addSource(r'''
8398 class A {
8399 void f() {
8400 g(1, 2);
8401 }
8402 void g(a, b, c) {}
8403 }''');
8404 _validateArgumentResolution(source, [0, 1]);
8405 }
8406
8407 void test_argumentResolution_required_tooMany() {
8408 Source source = addSource(r'''
8409 class A {
8410 void f() {
8411 g(1, 2, 3);
8412 }
8413 void g(a, b) {}
8414 }''');
8415 _validateArgumentResolution(source, [0, 1, -1]);
8416 }
8417
8418 void test_argumentResolution_requiredAndNamed_extra() {
8419 Source source = addSource(r'''
8420 class A {
8421 void f() {
8422 g(1, 2, c: 3, d: 4);
8423 }
8424 void g(a, b, {c}) {}
8425 }''');
8426 _validateArgumentResolution(source, [0, 1, 2, -1]);
8427 }
8428
8429 void test_argumentResolution_requiredAndNamed_matching() {
8430 Source source = addSource(r'''
8431 class A {
8432 void f() {
8433 g(1, 2, c: 3);
8434 }
8435 void g(a, b, {c}) {}
8436 }''');
8437 _validateArgumentResolution(source, [0, 1, 2]);
8438 }
8439
8440 void test_argumentResolution_requiredAndNamed_missing() {
8441 Source source = addSource(r'''
8442 class A {
8443 void f() {
8444 g(1, 2, d: 3);
8445 }
8446 void g(a, b, {c, d}) {}
8447 }''');
8448 _validateArgumentResolution(source, [0, 1, 3]);
8449 }
8450
8451 void test_argumentResolution_requiredAndPositional_fewer() {
8452 Source source = addSource(r'''
8453 class A {
8454 void f() {
8455 g(1, 2, 3);
8456 }
8457 void g(a, b, [c, d]) {}
8458 }''');
8459 _validateArgumentResolution(source, [0, 1, 2]);
8460 }
8461
8462 void test_argumentResolution_requiredAndPositional_matching() {
8463 Source source = addSource(r'''
8464 class A {
8465 void f() {
8466 g(1, 2, 3, 4);
8467 }
8468 void g(a, b, [c, d]) {}
8469 }''');
8470 _validateArgumentResolution(source, [0, 1, 2, 3]);
8471 }
8472
8473 void test_argumentResolution_requiredAndPositional_more() {
8474 Source source = addSource(r'''
8475 class A {
8476 void f() {
8477 g(1, 2, 3, 4);
8478 }
8479 void g(a, b, [c]) {}
8480 }''');
8481 _validateArgumentResolution(source, [0, 1, 2, -1]);
8482 }
8483
8484 void test_argumentResolution_setter_propagated() {
8485 Source source = addSource(r'''
8486 main() {
8487 var a = new A();
8488 a.sss = 0;
8489 }
8490 class A {
8491 set sss(x) {}
8492 }''');
8493 LibraryElement library = resolve2(source);
8494 CompilationUnitElement unit = library.definingCompilationUnit;
8495 // find "a.sss = 0"
8496 AssignmentExpression assignment;
8497 {
8498 FunctionElement mainElement = unit.functions[0];
8499 FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
8500 Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
8501 ExpressionStatement expressionStatement =
8502 statement as ExpressionStatement;
8503 assignment = expressionStatement.expression as AssignmentExpression;
8504 }
8505 // get parameter
8506 Expression rhs = assignment.rightHandSide;
8507 expect(rhs.staticParameterElement, isNull);
8508 ParameterElement parameter = rhs.propagatedParameterElement;
8509 expect(parameter, isNotNull);
8510 expect(parameter.displayName, "x");
8511 // validate
8512 ClassElement classA = unit.types[0];
8513 PropertyAccessorElement setter = classA.accessors[0];
8514 expect(setter.parameters[0], same(parameter));
8515 }
8516
8517 void test_argumentResolution_setter_propagated_propertyAccess() {
8518 Source source = addSource(r'''
8519 main() {
8520 var a = new A();
8521 a.b.sss = 0;
8522 }
8523 class A {
8524 B b = new B();
8525 }
8526 class B {
8527 set sss(x) {}
8528 }''');
8529 LibraryElement library = resolve2(source);
8530 CompilationUnitElement unit = library.definingCompilationUnit;
8531 // find "a.b.sss = 0"
8532 AssignmentExpression assignment;
8533 {
8534 FunctionElement mainElement = unit.functions[0];
8535 FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
8536 Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
8537 ExpressionStatement expressionStatement =
8538 statement as ExpressionStatement;
8539 assignment = expressionStatement.expression as AssignmentExpression;
8540 }
8541 // get parameter
8542 Expression rhs = assignment.rightHandSide;
8543 expect(rhs.staticParameterElement, isNull);
8544 ParameterElement parameter = rhs.propagatedParameterElement;
8545 expect(parameter, isNotNull);
8546 expect(parameter.displayName, "x");
8547 // validate
8548 ClassElement classB = unit.types[1];
8549 PropertyAccessorElement setter = classB.accessors[0];
8550 expect(setter.parameters[0], same(parameter));
8551 }
8552
8553 void test_argumentResolution_setter_static() {
8554 Source source = addSource(r'''
8555 main() {
8556 A a = new A();
8557 a.sss = 0;
8558 }
8559 class A {
8560 set sss(x) {}
8561 }''');
8562 LibraryElement library = resolve2(source);
8563 CompilationUnitElement unit = library.definingCompilationUnit;
8564 // find "a.sss = 0"
8565 AssignmentExpression assignment;
8566 {
8567 FunctionElement mainElement = unit.functions[0];
8568 FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
8569 Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
8570 ExpressionStatement expressionStatement =
8571 statement as ExpressionStatement;
8572 assignment = expressionStatement.expression as AssignmentExpression;
8573 }
8574 // get parameter
8575 Expression rhs = assignment.rightHandSide;
8576 ParameterElement parameter = rhs.staticParameterElement;
8577 expect(parameter, isNotNull);
8578 expect(parameter.displayName, "x");
8579 // validate
8580 ClassElement classA = unit.types[0];
8581 PropertyAccessorElement setter = classA.accessors[0];
8582 expect(setter.parameters[0], same(parameter));
8583 }
8584
8585 void test_argumentResolution_setter_static_propertyAccess() {
8586 Source source = addSource(r'''
8587 main() {
8588 A a = new A();
8589 a.b.sss = 0;
8590 }
8591 class A {
8592 B b = new B();
8593 }
8594 class B {
8595 set sss(x) {}
8596 }''');
8597 LibraryElement library = resolve2(source);
8598 CompilationUnitElement unit = library.definingCompilationUnit;
8599 // find "a.b.sss = 0"
8600 AssignmentExpression assignment;
8601 {
8602 FunctionElement mainElement = unit.functions[0];
8603 FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
8604 Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
8605 ExpressionStatement expressionStatement =
8606 statement as ExpressionStatement;
8607 assignment = expressionStatement.expression as AssignmentExpression;
8608 }
8609 // get parameter
8610 Expression rhs = assignment.rightHandSide;
8611 ParameterElement parameter = rhs.staticParameterElement;
8612 expect(parameter, isNotNull);
8613 expect(parameter.displayName, "x");
8614 // validate
8615 ClassElement classB = unit.types[1];
8616 PropertyAccessorElement setter = classB.accessors[0];
8617 expect(setter.parameters[0], same(parameter));
8618 }
8619
8620 void test_breakTarget_labeled() {
8621 // Verify that the target of the label is correctly found and is recorded
8622 // as the unlabeled portion of the statement.
8623 String text = r'''
8624 void f() {
8625 loop1: while (true) {
8626 loop2: for (int i = 0; i < 10; i++) {
8627 break loop1;
8628 break loop2;
8629 }
8630 }
8631 }
8632 ''';
8633 CompilationUnit unit = resolveSource(text);
8634 WhileStatement whileStatement = EngineTestCase.findNode(
8635 unit, text, 'while (true)', (n) => n is WhileStatement);
8636 ForStatement forStatement =
8637 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
8638 BreakStatement break1 = EngineTestCase.findNode(
8639 unit, text, 'break loop1', (n) => n is BreakStatement);
8640 BreakStatement break2 = EngineTestCase.findNode(
8641 unit, text, 'break loop2', (n) => n is BreakStatement);
8642 expect(break1.target, same(whileStatement));
8643 expect(break2.target, same(forStatement));
8644 }
8645
8646 void test_breakTarget_unlabeledBreakFromDo() {
8647 String text = r'''
8648 void f() {
8649 do {
8650 break;
8651 } while (true);
8652 }
8653 ''';
8654 CompilationUnit unit = resolveSource(text);
8655 DoStatement doStatement =
8656 EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement);
8657 BreakStatement breakStatement = EngineTestCase.findNode(
8658 unit, text, 'break', (n) => n is BreakStatement);
8659 expect(breakStatement.target, same(doStatement));
8660 }
8661
8662 void test_breakTarget_unlabeledBreakFromFor() {
8663 String text = r'''
8664 void f() {
8665 for (int i = 0; i < 10; i++) {
8666 break;
8667 }
8668 }
8669 ''';
8670 CompilationUnit unit = resolveSource(text);
8671 ForStatement forStatement =
8672 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
8673 BreakStatement breakStatement = EngineTestCase.findNode(
8674 unit, text, 'break', (n) => n is BreakStatement);
8675 expect(breakStatement.target, same(forStatement));
8676 }
8677
8678 void test_breakTarget_unlabeledBreakFromForEach() {
8679 String text = r'''
8680 void f() {
8681 for (x in []) {
8682 break;
8683 }
8684 }
8685 ''';
8686 CompilationUnit unit = resolveSource(text);
8687 ForEachStatement forStatement = EngineTestCase.findNode(
8688 unit, text, 'for', (n) => n is ForEachStatement);
8689 BreakStatement breakStatement = EngineTestCase.findNode(
8690 unit, text, 'break', (n) => n is BreakStatement);
8691 expect(breakStatement.target, same(forStatement));
8692 }
8693
8694 void test_breakTarget_unlabeledBreakFromSwitch() {
8695 String text = r'''
8696 void f() {
8697 while (true) {
8698 switch (0) {
8699 case 0:
8700 break;
8701 }
8702 }
8703 }
8704 ''';
8705 CompilationUnit unit = resolveSource(text);
8706 SwitchStatement switchStatement = EngineTestCase.findNode(
8707 unit, text, 'switch', (n) => n is SwitchStatement);
8708 BreakStatement breakStatement = EngineTestCase.findNode(
8709 unit, text, 'break', (n) => n is BreakStatement);
8710 expect(breakStatement.target, same(switchStatement));
8711 }
8712
8713 void test_breakTarget_unlabeledBreakFromWhile() {
8714 String text = r'''
8715 void f() {
8716 while (true) {
8717 break;
8718 }
8719 }
8720 ''';
8721 CompilationUnit unit = resolveSource(text);
8722 WhileStatement whileStatement = EngineTestCase.findNode(
8723 unit, text, 'while', (n) => n is WhileStatement);
8724 BreakStatement breakStatement = EngineTestCase.findNode(
8725 unit, text, 'break', (n) => n is BreakStatement);
8726 expect(breakStatement.target, same(whileStatement));
8727 }
8728
8729 void test_breakTarget_unlabeledBreakToOuterFunction() {
8730 // Verify that unlabeled break statements can't resolve to loops in an
8731 // outer function.
8732 String text = r'''
8733 void f() {
8734 while (true) {
8735 void g() {
8736 break;
8737 }
8738 }
8739 }
8740 ''';
8741 CompilationUnit unit = resolveSource(text);
8742 BreakStatement breakStatement = EngineTestCase.findNode(
8743 unit, text, 'break', (n) => n is BreakStatement);
8744 expect(breakStatement.target, isNull);
8745 }
8746
8747 void test_class_definesCall() {
8748 Source source = addSource(r'''
8749 class A {
8750 int call(int x) { return x; }
8751 }
8752 int f(A a) {
8753 return a(0);
8754 }''');
8755 computeLibrarySourceErrors(source);
8756 assertNoErrors(source);
8757 verify([source]);
8758 }
8759
8760 void test_class_extends_implements() {
8761 Source source = addSource(r'''
8762 class A extends B implements C {}
8763 class B {}
8764 class C {}''');
8765 computeLibrarySourceErrors(source);
8766 assertNoErrors(source);
8767 verify([source]);
8768 }
8769
8770 void test_commentReference_class() {
8771 Source source = addSource(r'''
8772 f() {}
8773 /** [A] [new A] [A.n] [new A.n] [m] [f] */
8774 class A {
8775 A() {}
8776 A.n() {}
8777 m() {}
8778 }''');
8779 computeLibrarySourceErrors(source);
8780 assertNoErrors(source);
8781 verify([source]);
8782 }
8783
8784 void test_commentReference_parameter() {
8785 Source source = addSource(r'''
8786 class A {
8787 A() {}
8788 A.n() {}
8789 /** [e] [f] */
8790 m(e, f()) {}
8791 }''');
8792 computeLibrarySourceErrors(source);
8793 assertNoErrors(source);
8794 verify([source]);
8795 }
8796
8797 void test_commentReference_singleLine() {
8798 Source source = addSource(r'''
8799 /// [A]
8800 class A {}''');
8801 computeLibrarySourceErrors(source);
8802 assertNoErrors(source);
8803 verify([source]);
8804 }
8805
8806 void test_continueTarget_labeled() {
8807 // Verify that the target of the label is correctly found and is recorded
8808 // as the unlabeled portion of the statement.
8809 String text = r'''
8810 void f() {
8811 loop1: while (true) {
8812 loop2: for (int i = 0; i < 10; i++) {
8813 continue loop1;
8814 continue loop2;
8815 }
8816 }
8817 }
8818 ''';
8819 CompilationUnit unit = resolveSource(text);
8820 WhileStatement whileStatement = EngineTestCase.findNode(
8821 unit, text, 'while (true)', (n) => n is WhileStatement);
8822 ForStatement forStatement =
8823 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
8824 ContinueStatement continue1 = EngineTestCase.findNode(
8825 unit, text, 'continue loop1', (n) => n is ContinueStatement);
8826 ContinueStatement continue2 = EngineTestCase.findNode(
8827 unit, text, 'continue loop2', (n) => n is ContinueStatement);
8828 expect(continue1.target, same(whileStatement));
8829 expect(continue2.target, same(forStatement));
8830 }
8831
8832 void test_continueTarget_unlabeledContinueFromDo() {
8833 String text = r'''
8834 void f() {
8835 do {
8836 continue;
8837 } while (true);
8838 }
8839 ''';
8840 CompilationUnit unit = resolveSource(text);
8841 DoStatement doStatement =
8842 EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement);
8843 ContinueStatement continueStatement = EngineTestCase.findNode(
8844 unit, text, 'continue', (n) => n is ContinueStatement);
8845 expect(continueStatement.target, same(doStatement));
8846 }
8847
8848 void test_continueTarget_unlabeledContinueFromFor() {
8849 String text = r'''
8850 void f() {
8851 for (int i = 0; i < 10; i++) {
8852 continue;
8853 }
8854 }
8855 ''';
8856 CompilationUnit unit = resolveSource(text);
8857 ForStatement forStatement =
8858 EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
8859 ContinueStatement continueStatement = EngineTestCase.findNode(
8860 unit, text, 'continue', (n) => n is ContinueStatement);
8861 expect(continueStatement.target, same(forStatement));
8862 }
8863
8864 void test_continueTarget_unlabeledContinueFromForEach() {
8865 String text = r'''
8866 void f() {
8867 for (x in []) {
8868 continue;
8869 }
8870 }
8871 ''';
8872 CompilationUnit unit = resolveSource(text);
8873 ForEachStatement forStatement = EngineTestCase.findNode(
8874 unit, text, 'for', (n) => n is ForEachStatement);
8875 ContinueStatement continueStatement = EngineTestCase.findNode(
8876 unit, text, 'continue', (n) => n is ContinueStatement);
8877 expect(continueStatement.target, same(forStatement));
8878 }
8879
8880 void test_continueTarget_unlabeledContinueFromWhile() {
8881 String text = r'''
8882 void f() {
8883 while (true) {
8884 continue;
8885 }
8886 }
8887 ''';
8888 CompilationUnit unit = resolveSource(text);
8889 WhileStatement whileStatement = EngineTestCase.findNode(
8890 unit, text, 'while', (n) => n is WhileStatement);
8891 ContinueStatement continueStatement = EngineTestCase.findNode(
8892 unit, text, 'continue', (n) => n is ContinueStatement);
8893 expect(continueStatement.target, same(whileStatement));
8894 }
8895
8896 void test_continueTarget_unlabeledContinueSkipsSwitch() {
8897 String text = r'''
8898 void f() {
8899 while (true) {
8900 switch (0) {
8901 case 0:
8902 continue;
8903 }
8904 }
8905 }
8906 ''';
8907 CompilationUnit unit = resolveSource(text);
8908 WhileStatement whileStatement = EngineTestCase.findNode(
8909 unit, text, 'while', (n) => n is WhileStatement);
8910 ContinueStatement continueStatement = EngineTestCase.findNode(
8911 unit, text, 'continue', (n) => n is ContinueStatement);
8912 expect(continueStatement.target, same(whileStatement));
8913 }
8914
8915 void test_continueTarget_unlabeledContinueToOuterFunction() {
8916 // Verify that unlabeled continue statements can't resolve to loops in an
8917 // outer function.
8918 String text = r'''
8919 void f() {
8920 while (true) {
8921 void g() {
8922 continue;
8923 }
8924 }
8925 }
8926 ''';
8927 CompilationUnit unit = resolveSource(text);
8928 ContinueStatement continueStatement = EngineTestCase.findNode(
8929 unit, text, 'continue', (n) => n is ContinueStatement);
8930 expect(continueStatement.target, isNull);
8931 }
8932
8933 void test_empty() {
8934 Source source = addSource("");
8935 computeLibrarySourceErrors(source);
8936 assertNoErrors(source);
8937 verify([source]);
8938 }
8939
8940 void test_entryPoint_exported() {
8941 addNamedSource(
8942 "/two.dart",
8943 r'''
8944 library two;
8945 main() {}''');
8946 Source source = addNamedSource(
8947 "/one.dart",
8948 r'''
8949 library one;
8950 export 'two.dart';''');
8951 LibraryElement library = resolve2(source);
8952 expect(library, isNotNull);
8953 FunctionElement main = library.entryPoint;
8954 expect(main, isNotNull);
8955 expect(main.library, isNot(same(library)));
8956 assertNoErrors(source);
8957 verify([source]);
8958 }
8959
8960 void test_entryPoint_local() {
8961 Source source = addNamedSource(
8962 "/one.dart",
8963 r'''
8964 library one;
8965 main() {}''');
8966 LibraryElement library = resolve2(source);
8967 expect(library, isNotNull);
8968 FunctionElement main = library.entryPoint;
8969 expect(main, isNotNull);
8970 expect(main.library, same(library));
8971 assertNoErrors(source);
8972 verify([source]);
8973 }
8974
8975 void test_entryPoint_none() {
8976 Source source = addNamedSource("/one.dart", "library one;");
8977 LibraryElement library = resolve2(source);
8978 expect(library, isNotNull);
8979 expect(library.entryPoint, isNull);
8980 assertNoErrors(source);
8981 verify([source]);
8982 }
8983
8984 void test_enum_externalLibrary() {
8985 addNamedSource(
8986 "/my_lib.dart",
8987 r'''
8988 library my_lib;
8989 enum EEE {A, B, C}''');
8990 Source source = addSource(r'''
8991 import 'my_lib.dart';
8992 main() {
8993 EEE e = null;
8994 }''');
8995 computeLibrarySourceErrors(source);
8996 assertNoErrors(source);
8997 verify([source]);
8998 }
8999
9000 void test_extractedMethodAsConstant() {
9001 Source source = addSource(r'''
9002 abstract class Comparable<T> {
9003 int compareTo(T other);
9004 static int compare(Comparable a, Comparable b) => a.compareTo(b);
9005 }
9006 class A {
9007 void sort([compare = Comparable.compare]) {}
9008 }''');
9009 computeLibrarySourceErrors(source);
9010 assertNoErrors(source);
9011 verify([source]);
9012 }
9013
9014 void test_fieldFormalParameter() {
9015 Source source = addSource(r'''
9016 class A {
9017 int x;
9018 A(this.x) {}
9019 }''');
9020 computeLibrarySourceErrors(source);
9021 assertNoErrors(source);
9022 verify([source]);
9023 }
9024
9025 void test_forEachLoops_nonConflicting() {
9026 Source source = addSource(r'''
9027 f() {
9028 List list = [1,2,3];
9029 for (int x in list) {}
9030 for (int x in list) {}
9031 }''');
9032 computeLibrarySourceErrors(source);
9033 assertNoErrors(source);
9034 verify([source]);
9035 }
9036
9037 void test_forLoops_nonConflicting() {
9038 Source source = addSource(r'''
9039 f() {
9040 for (int i = 0; i < 3; i++) {
9041 }
9042 for (int i = 0; i < 3; i++) {
9043 }
9044 }''');
9045 computeLibrarySourceErrors(source);
9046 assertNoErrors(source);
9047 verify([source]);
9048 }
9049
9050 void test_functionTypeAlias() {
9051 Source source = addSource(r'''
9052 typedef bool P(e);
9053 class A {
9054 P p;
9055 m(e) {
9056 if (p(e)) {}
9057 }
9058 }''');
9059 computeLibrarySourceErrors(source);
9060 assertNoErrors(source);
9061 verify([source]);
9062 }
9063
9064 void test_getter_and_setter_fromMixins_bare_identifier() {
9065 Source source = addSource('''
9066 class B {}
9067 class M1 {
9068 get x => null;
9069 set x(value) {}
9070 }
9071 class M2 {
9072 get x => null;
9073 set x(value) {}
9074 }
9075 class C extends B with M1, M2 {
9076 void f() {
9077 x += 1;
9078 }
9079 }
9080 ''');
9081 LibraryElement library = resolve2(source);
9082 assertNoErrors(source);
9083 verify([source]);
9084 // Verify that both the getter and setter for "x" in C.f() refer to the
9085 // accessors defined in M2.
9086 ClassElement classC = library.definingCompilationUnit.types[3];
9087 MethodDeclaration f = classC.getMethod('f').computeNode();
9088 BlockFunctionBody body = f.body;
9089 ExpressionStatement stmt = body.block.statements[0];
9090 AssignmentExpression assignment = stmt.expression;
9091 SimpleIdentifier leftHandSide = assignment.leftHandSide;
9092 expect(leftHandSide.staticElement.enclosingElement.name, 'M2');
9093 expect(leftHandSide.auxiliaryElements.staticElement.enclosingElement.name,
9094 'M2');
9095 }
9096
9097 void test_getter_fromMixins_bare_identifier() {
9098 Source source = addSource('''
9099 class B {}
9100 class M1 {
9101 get x => null;
9102 }
9103 class M2 {
9104 get x => null;
9105 }
9106 class C extends B with M1, M2 {
9107 f() {
9108 return x;
9109 }
9110 }
9111 ''');
9112 LibraryElement library = resolve2(source);
9113 assertNoErrors(source);
9114 verify([source]);
9115 // Verify that the getter for "x" in C.f() refers to the getter defined in
9116 // M2.
9117 ClassElement classC = library.definingCompilationUnit.types[3];
9118 MethodDeclaration f = classC.getMethod('f').computeNode();
9119 BlockFunctionBody body = f.body;
9120 ReturnStatement stmt = body.block.statements[0];
9121 SimpleIdentifier x = stmt.expression;
9122 expect(x.staticElement.enclosingElement.name, 'M2');
9123 }
9124
9125 void test_getter_fromMixins_property_access() {
9126 Source source = addSource('''
9127 class B {}
9128 class M1 {
9129 get x => null;
9130 }
9131 class M2 {
9132 get x => null;
9133 }
9134 class C extends B with M1, M2 {}
9135 void main() {
9136 var y = new C().x;
9137 }
9138 ''');
9139 LibraryElement library = resolve2(source);
9140 assertNoErrors(source);
9141 verify([source]);
9142 // Verify that the getter for "x" in "new C().x" refers to the getter
9143 // defined in M2.
9144 FunctionDeclaration main =
9145 library.definingCompilationUnit.functions[0].computeNode();
9146 BlockFunctionBody body = main.functionExpression.body;
9147 VariableDeclarationStatement stmt = body.block.statements[0];
9148 PropertyAccess propertyAccess = stmt.variables.variables[0].initializer;
9149 expect(
9150 propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
9151 }
9152
9153 void test_getterAndSetterWithDifferentTypes() {
9154 Source source = addSource(r'''
9155 class A {
9156 int get f => 0;
9157 void set f(String s) {}
9158 }
9159 g (A a) {
9160 a.f = a.f.toString();
9161 }''');
9162 computeLibrarySourceErrors(source);
9163 assertErrors(
9164 source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
9165 verify([source]);
9166 }
9167
9168 void test_hasReferenceToSuper() {
9169 Source source = addSource(r'''
9170 class A {}
9171 class B {toString() => super.toString();}''');
9172 LibraryElement library = resolve2(source);
9173 expect(library, isNotNull);
9174 CompilationUnitElement unit = library.definingCompilationUnit;
9175 expect(unit, isNotNull);
9176 List<ClassElement> classes = unit.types;
9177 expect(classes, hasLength(2));
9178 expect(classes[0].hasReferenceToSuper, isFalse);
9179 expect(classes[1].hasReferenceToSuper, isTrue);
9180 assertNoErrors(source);
9181 verify([source]);
9182 }
9183
9184 void test_import_hide() {
9185 addNamedSource(
9186 "/lib1.dart",
9187 r'''
9188 library lib1;
9189 set foo(value) {}
9190 class A {}''');
9191 addNamedSource(
9192 "/lib2.dart",
9193 r'''
9194 library lib2;
9195 set foo(value) {}''');
9196 Source source = addNamedSource(
9197 "/lib3.dart",
9198 r'''
9199 import 'lib1.dart' hide foo;
9200 import 'lib2.dart';
9201
9202 main() {
9203 foo = 0;
9204 }
9205 A a;''');
9206 computeLibrarySourceErrors(source);
9207 assertNoErrors(source);
9208 verify([source]);
9209 }
9210
9211 void test_import_prefix() {
9212 addNamedSource(
9213 "/two.dart",
9214 r'''
9215 library two;
9216 f(int x) {
9217 return x * x;
9218 }''');
9219 Source source = addNamedSource(
9220 "/one.dart",
9221 r'''
9222 library one;
9223 import 'two.dart' as _two;
9224 main() {
9225 _two.f(0);
9226 }''');
9227 computeLibrarySourceErrors(source);
9228 assertNoErrors(source);
9229 verify([source]);
9230 }
9231
9232 void test_import_spaceInUri() {
9233 addNamedSource(
9234 "/sub folder/lib.dart",
9235 r'''
9236 library lib;
9237 foo() {}''');
9238 Source source = addNamedSource(
9239 "/app.dart",
9240 r'''
9241 import 'sub folder/lib.dart';
9242
9243 main() {
9244 foo();
9245 }''');
9246 computeLibrarySourceErrors(source);
9247 assertNoErrors(source);
9248 verify([source]);
9249 }
9250
9251 void test_indexExpression_typeParameters() {
9252 Source source = addSource(r'''
9253 f() {
9254 List<int> a;
9255 a[0];
9256 List<List<int>> b;
9257 b[0][0];
9258 List<List<List<int>>> c;
9259 c[0][0][0];
9260 }''');
9261 computeLibrarySourceErrors(source);
9262 assertNoErrors(source);
9263 verify([source]);
9264 }
9265
9266 void test_indexExpression_typeParameters_invalidAssignmentWarning() {
9267 Source source = addSource(r'''
9268 f() {
9269 List<List<int>> b;
9270 b[0][0] = 'hi';
9271 }''');
9272 computeLibrarySourceErrors(source);
9273 assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
9274 verify([source]);
9275 }
9276
9277 void test_indirectOperatorThroughCall() {
9278 Source source = addSource(r'''
9279 class A {
9280 B call() { return new B(); }
9281 }
9282
9283 class B {
9284 int operator [](int i) { return i; }
9285 }
9286
9287 A f = new A();
9288
9289 g(int x) {}
9290
9291 main() {
9292 g(f()[0]);
9293 }''');
9294 computeLibrarySourceErrors(source);
9295 assertNoErrors(source);
9296 verify([source]);
9297 }
9298
9299 void test_invoke_dynamicThroughGetter() {
9300 Source source = addSource(r'''
9301 class A {
9302 List get X => [() => 0];
9303 m(A a) {
9304 X.last;
9305 }
9306 }''');
9307 computeLibrarySourceErrors(source);
9308 assertNoErrors(source);
9309 verify([source]);
9310 }
9311
9312 void test_isValidMixin_badSuperclass() {
9313 Source source = addSource(r'''
9314 class A extends B {}
9315 class B {}''');
9316 LibraryElement library = resolve2(source);
9317 expect(library, isNotNull);
9318 CompilationUnitElement unit = library.definingCompilationUnit;
9319 expect(unit, isNotNull);
9320 List<ClassElement> classes = unit.types;
9321 expect(classes, hasLength(2));
9322 expect(classes[0].isValidMixin, isFalse);
9323 assertNoErrors(source);
9324 verify([source]);
9325 }
9326
9327 void test_isValidMixin_constructor() {
9328 Source source = addSource(r'''
9329 class A {
9330 A() {}
9331 }''');
9332 LibraryElement library = resolve2(source);
9333 expect(library, isNotNull);
9334 CompilationUnitElement unit = library.definingCompilationUnit;
9335 expect(unit, isNotNull);
9336 List<ClassElement> classes = unit.types;
9337 expect(classes, hasLength(1));
9338 expect(classes[0].isValidMixin, isFalse);
9339 assertNoErrors(source);
9340 verify([source]);
9341 }
9342
9343 void test_isValidMixin_super() {
9344 Source source = addSource(r'''
9345 class A {
9346 toString() {
9347 return super.toString();
9348 }
9349 }''');
9350 LibraryElement library = resolve2(source);
9351 expect(library, isNotNull);
9352 CompilationUnitElement unit = library.definingCompilationUnit;
9353 expect(unit, isNotNull);
9354 List<ClassElement> classes = unit.types;
9355 expect(classes, hasLength(1));
9356 expect(classes[0].isValidMixin, isFalse);
9357 assertNoErrors(source);
9358 verify([source]);
9359 }
9360
9361 void test_isValidMixin_valid() {
9362 Source source = addSource("class A {}");
9363 LibraryElement library = resolve2(source);
9364 expect(library, isNotNull);
9365 CompilationUnitElement unit = library.definingCompilationUnit;
9366 expect(unit, isNotNull);
9367 List<ClassElement> classes = unit.types;
9368 expect(classes, hasLength(1));
9369 expect(classes[0].isValidMixin, isTrue);
9370 assertNoErrors(source);
9371 verify([source]);
9372 }
9373
9374 void test_labels_switch() {
9375 Source source = addSource(r'''
9376 void doSwitch(int target) {
9377 switch (target) {
9378 l0: case 0:
9379 continue l1;
9380 l1: case 1:
9381 continue l0;
9382 default:
9383 continue l1;
9384 }
9385 }''');
9386 LibraryElement library = resolve2(source);
9387 expect(library, isNotNull);
9388 assertNoErrors(source);
9389 verify([source]);
9390 }
9391
9392 void test_localVariable_types_invoked() {
9393 Source source = addSource(r'''
9394 const A = null;
9395 main() {
9396 var myVar = (int p) => 'foo';
9397 myVar(42);
9398 }''');
9399 LibraryElement library = resolve2(source);
9400 expect(library, isNotNull);
9401 CompilationUnit unit =
9402 analysisContext.resolveCompilationUnit(source, library);
9403 expect(unit, isNotNull);
9404 List<bool> found = [false];
9405 List<CaughtException> thrownException = new List<CaughtException>(1);
9406 unit.accept(new _SimpleResolverTest_localVariable_types_invoked(
9407 this, found, thrownException));
9408 if (thrownException[0] != null) {
9409 throw new AnalysisException(
9410 "Exception", new CaughtException(thrownException[0], null));
9411 }
9412 expect(found[0], isTrue);
9413 }
9414
9415 void test_metadata_class() {
9416 Source source = addSource(r'''
9417 const A = null;
9418 @A class C<A> {}''');
9419 LibraryElement library = resolve2(source);
9420 expect(library, isNotNull);
9421 CompilationUnitElement unitElement = library.definingCompilationUnit;
9422 expect(unitElement, isNotNull);
9423 List<ClassElement> classes = unitElement.types;
9424 expect(classes, hasLength(1));
9425 List<ElementAnnotation> annotations = classes[0].metadata;
9426 expect(annotations, hasLength(1));
9427 assertNoErrors(source);
9428 verify([source]);
9429 CompilationUnit unit = resolveCompilationUnit(source, library);
9430 NodeList<CompilationUnitMember> declarations = unit.declarations;
9431 expect(declarations, hasLength(2));
9432 Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
9433 .variables
9434 .variables[0].name.staticElement;
9435 EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
9436 PropertyInducingElement, expectedElement);
9437 expectedElement = (expectedElement as PropertyInducingElement).getter;
9438 Element actualElement =
9439 (declarations[1] as ClassDeclaration).metadata[0].name.staticElement;
9440 expect(actualElement, same(expectedElement));
9441 }
9442
9443 void test_metadata_field() {
9444 Source source = addSource(r'''
9445 const A = null;
9446 class C {
9447 @A int f;
9448 }''');
9449 LibraryElement library = resolve2(source);
9450 expect(library, isNotNull);
9451 CompilationUnitElement unit = library.definingCompilationUnit;
9452 expect(unit, isNotNull);
9453 List<ClassElement> classes = unit.types;
9454 expect(classes, hasLength(1));
9455 FieldElement field = classes[0].fields[0];
9456 List<ElementAnnotation> annotations = field.metadata;
9457 expect(annotations, hasLength(1));
9458 assertNoErrors(source);
9459 verify([source]);
9460 }
9461
9462 void test_metadata_fieldFormalParameter() {
9463 Source source = addSource(r'''
9464 const A = null;
9465 class C {
9466 int f;
9467 C(@A this.f);
9468 }''');
9469 LibraryElement library = resolve2(source);
9470 expect(library, isNotNull);
9471 CompilationUnitElement unit = library.definingCompilationUnit;
9472 expect(unit, isNotNull);
9473 List<ClassElement> classes = unit.types;
9474 expect(classes, hasLength(1));
9475 List<ConstructorElement> constructors = classes[0].constructors;
9476 expect(constructors, hasLength(1));
9477 List<ParameterElement> parameters = constructors[0].parameters;
9478 expect(parameters, hasLength(1));
9479 List<ElementAnnotation> annotations = parameters[0].metadata;
9480 expect(annotations, hasLength(1));
9481 assertNoErrors(source);
9482 verify([source]);
9483 }
9484
9485 void test_metadata_function() {
9486 Source source = addSource(r'''
9487 const A = null;
9488 @A f() {}''');
9489 LibraryElement library = resolve2(source);
9490 expect(library, isNotNull);
9491 CompilationUnitElement unit = library.definingCompilationUnit;
9492 expect(unit, isNotNull);
9493 List<FunctionElement> functions = unit.functions;
9494 expect(functions, hasLength(1));
9495 List<ElementAnnotation> annotations = functions[0].metadata;
9496 expect(annotations, hasLength(1));
9497 assertNoErrors(source);
9498 verify([source]);
9499 }
9500
9501 void test_metadata_functionTypedParameter() {
9502 Source source = addSource(r'''
9503 const A = null;
9504 f(@A int p(int x)) {}''');
9505 LibraryElement library = resolve2(source);
9506 expect(library, isNotNull);
9507 CompilationUnitElement unit = library.definingCompilationUnit;
9508 expect(unit, isNotNull);
9509 List<FunctionElement> functions = unit.functions;
9510 expect(functions, hasLength(1));
9511 List<ParameterElement> parameters = functions[0].parameters;
9512 expect(parameters, hasLength(1));
9513 List<ElementAnnotation> annotations1 = parameters[0].metadata;
9514 expect(annotations1, hasLength(1));
9515 assertNoErrors(source);
9516 verify([source]);
9517 }
9518
9519 void test_metadata_libraryDirective() {
9520 Source source = addSource(r'''
9521 @A library lib;
9522 const A = null;''');
9523 LibraryElement library = resolve2(source);
9524 expect(library, isNotNull);
9525 List<ElementAnnotation> annotations = library.metadata;
9526 expect(annotations, hasLength(1));
9527 assertNoErrors(source);
9528 verify([source]);
9529 }
9530
9531 void test_metadata_method() {
9532 Source source = addSource(r'''
9533 const A = null;
9534 class C {
9535 @A void m() {}
9536 }''');
9537 LibraryElement library = resolve2(source);
9538 expect(library, isNotNull);
9539 CompilationUnitElement unit = library.definingCompilationUnit;
9540 expect(unit, isNotNull);
9541 List<ClassElement> classes = unit.types;
9542 expect(classes, hasLength(1));
9543 MethodElement method = classes[0].methods[0];
9544 List<ElementAnnotation> annotations = method.metadata;
9545 expect(annotations, hasLength(1));
9546 assertNoErrors(source);
9547 verify([source]);
9548 }
9549
9550 void test_metadata_namedParameter() {
9551 Source source = addSource(r'''
9552 const A = null;
9553 f({@A int p : 0}) {}''');
9554 LibraryElement library = resolve2(source);
9555 expect(library, isNotNull);
9556 CompilationUnitElement unit = library.definingCompilationUnit;
9557 expect(unit, isNotNull);
9558 List<FunctionElement> functions = unit.functions;
9559 expect(functions, hasLength(1));
9560 List<ParameterElement> parameters = functions[0].parameters;
9561 expect(parameters, hasLength(1));
9562 List<ElementAnnotation> annotations1 = parameters[0].metadata;
9563 expect(annotations1, hasLength(1));
9564 assertNoErrors(source);
9565 verify([source]);
9566 }
9567
9568 void test_metadata_positionalParameter() {
9569 Source source = addSource(r'''
9570 const A = null;
9571 f([@A int p = 0]) {}''');
9572 LibraryElement library = resolve2(source);
9573 expect(library, isNotNull);
9574 CompilationUnitElement unit = library.definingCompilationUnit;
9575 expect(unit, isNotNull);
9576 List<FunctionElement> functions = unit.functions;
9577 expect(functions, hasLength(1));
9578 List<ParameterElement> parameters = functions[0].parameters;
9579 expect(parameters, hasLength(1));
9580 List<ElementAnnotation> annotations1 = parameters[0].metadata;
9581 expect(annotations1, hasLength(1));
9582 assertNoErrors(source);
9583 verify([source]);
9584 }
9585
9586 void test_metadata_simpleParameter() {
9587 Source source = addSource(r'''
9588 const A = null;
9589 f(@A p1, @A int p2) {}''');
9590 LibraryElement library = resolve2(source);
9591 expect(library, isNotNull);
9592 CompilationUnitElement unit = library.definingCompilationUnit;
9593 expect(unit, isNotNull);
9594 List<FunctionElement> functions = unit.functions;
9595 expect(functions, hasLength(1));
9596 List<ParameterElement> parameters = functions[0].parameters;
9597 expect(parameters, hasLength(2));
9598 List<ElementAnnotation> annotations1 = parameters[0].metadata;
9599 expect(annotations1, hasLength(1));
9600 List<ElementAnnotation> annotations2 = parameters[1].metadata;
9601 expect(annotations2, hasLength(1));
9602 assertNoErrors(source);
9603 verify([source]);
9604 }
9605
9606 void test_metadata_typedef() {
9607 Source source = addSource(r'''
9608 const A = null;
9609 @A typedef F<A>();''');
9610 LibraryElement library = resolve2(source);
9611 expect(library, isNotNull);
9612 CompilationUnitElement unitElement = library.definingCompilationUnit;
9613 expect(unitElement, isNotNull);
9614 List<FunctionTypeAliasElement> aliases = unitElement.functionTypeAliases;
9615 expect(aliases, hasLength(1));
9616 List<ElementAnnotation> annotations = aliases[0].metadata;
9617 expect(annotations, hasLength(1));
9618 assertNoErrors(source);
9619 verify([source]);
9620 CompilationUnit unit = resolveCompilationUnit(source, library);
9621 NodeList<CompilationUnitMember> declarations = unit.declarations;
9622 expect(declarations, hasLength(2));
9623 Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
9624 .variables
9625 .variables[0].name.staticElement;
9626 EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
9627 PropertyInducingElement, expectedElement);
9628 expectedElement = (expectedElement as PropertyInducingElement).getter;
9629 Element actualElement =
9630 (declarations[1] as FunctionTypeAlias).metadata[0].name.staticElement;
9631 expect(actualElement, same(expectedElement));
9632 }
9633
9634 void test_method_fromMixin() {
9635 Source source = addSource(r'''
9636 class B {
9637 bar() => 1;
9638 }
9639 class A {
9640 foo() => 2;
9641 }
9642
9643 class C extends B with A {
9644 bar() => super.bar();
9645 foo() => super.foo();
9646 }''');
9647 computeLibrarySourceErrors(source);
9648 assertNoErrors(source);
9649 verify([source]);
9650 }
9651
9652 void test_method_fromMixins() {
9653 Source source = addSource('''
9654 class B {}
9655 class M1 {
9656 void f() {}
9657 }
9658 class M2 {
9659 void f() {}
9660 }
9661 class C extends B with M1, M2 {}
9662 void main() {
9663 new C().f();
9664 }
9665 ''');
9666 LibraryElement library = resolve2(source);
9667 assertNoErrors(source);
9668 verify([source]);
9669 // Verify that the "f" in "new C().f()" refers to the "f" defined in M2.
9670 FunctionDeclaration main =
9671 library.definingCompilationUnit.functions[0].computeNode();
9672 BlockFunctionBody body = main.functionExpression.body;
9673 ExpressionStatement stmt = body.block.statements[0];
9674 MethodInvocation expr = stmt.expression;
9675 expect(expr.methodName.staticElement.enclosingElement.name, 'M2');
9676 }
9677
9678 void test_method_fromMixins_bare_identifier() {
9679 Source source = addSource('''
9680 class B {}
9681 class M1 {
9682 void f() {}
9683 }
9684 class M2 {
9685 void f() {}
9686 }
9687 class C extends B with M1, M2 {
9688 void g() {
9689 f();
9690 }
9691 }
9692 ''');
9693 LibraryElement library = resolve2(source);
9694 assertNoErrors(source);
9695 verify([source]);
9696 // Verify that the call to f() in C.g() refers to the method defined in M2.
9697 ClassElement classC = library.definingCompilationUnit.types[3];
9698 MethodDeclaration g = classC.getMethod('g').computeNode();
9699 BlockFunctionBody body = g.body;
9700 ExpressionStatement stmt = body.block.statements[0];
9701 MethodInvocation invocation = stmt.expression;
9702 SimpleIdentifier methodName = invocation.methodName;
9703 expect(methodName.staticElement.enclosingElement.name, 'M2');
9704 }
9705
9706 void test_method_fromMixins_invked_from_outside_class() {
9707 Source source = addSource('''
9708 class B {}
9709 class M1 {
9710 void f() {}
9711 }
9712 class M2 {
9713 void f() {}
9714 }
9715 class C extends B with M1, M2 {}
9716 void main() {
9717 new C().f();
9718 }
9719 ''');
9720 LibraryElement library = resolve2(source);
9721 assertNoErrors(source);
9722 verify([source]);
9723 // Verify that the call to f() in "new C().f()" refers to the method
9724 // defined in M2.
9725 FunctionDeclaration main =
9726 library.definingCompilationUnit.functions[0].computeNode();
9727 BlockFunctionBody body = main.functionExpression.body;
9728 ExpressionStatement stmt = body.block.statements[0];
9729 MethodInvocation invocation = stmt.expression;
9730 expect(invocation.methodName.staticElement.enclosingElement.name, 'M2');
9731 }
9732
9733 void test_method_fromSuperclassMixin() {
9734 Source source = addSource(r'''
9735 class A {
9736 void m1() {}
9737 }
9738 class B extends Object with A {
9739 }
9740 class C extends B {
9741 }
9742 f(C c) {
9743 c.m1();
9744 }''');
9745 computeLibrarySourceErrors(source);
9746 assertNoErrors(source);
9747 verify([source]);
9748 }
9749
9750 void test_methodCascades() {
9751 Source source = addSource(r'''
9752 class A {
9753 void m1() {}
9754 void m2() {}
9755 void m() {
9756 A a = new A();
9757 a..m1()
9758 ..m2();
9759 }
9760 }''');
9761 computeLibrarySourceErrors(source);
9762 assertNoErrors(source);
9763 verify([source]);
9764 }
9765
9766 void test_methodCascades_withSetter() {
9767 Source source = addSource(r'''
9768 class A {
9769 String name;
9770 void m1() {}
9771 void m2() {}
9772 void m() {
9773 A a = new A();
9774 a..m1()
9775 ..name = 'name'
9776 ..m2();
9777 }
9778 }''');
9779 computeLibrarySourceErrors(source);
9780 // failing with error code: INVOCATION_OF_NON_FUNCTION
9781 assertNoErrors(source);
9782 verify([source]);
9783 }
9784
9785 void test_resolveAgainstNull() {
9786 Source source = addSource(r'''
9787 f(var p) {
9788 return null == p;
9789 }''');
9790 computeLibrarySourceErrors(source);
9791 assertNoErrors(source);
9792 }
9793
9794 void test_setter_fromMixins_bare_identifier() {
9795 Source source = addSource('''
9796 class B {}
9797 class M1 {
9798 set x(value) {}
9799 }
9800 class M2 {
9801 set x(value) {}
9802 }
9803 class C extends B with M1, M2 {
9804 void f() {
9805 x = 1;
9806 }
9807 }
9808 ''');
9809 LibraryElement library = resolve2(source);
9810 assertNoErrors(source);
9811 verify([source]);
9812 // Verify that the setter for "x" in C.f() refers to the setter defined in
9813 // M2.
9814 ClassElement classC = library.definingCompilationUnit.types[3];
9815 MethodDeclaration f = classC.getMethod('f').computeNode();
9816 BlockFunctionBody body = f.body;
9817 ExpressionStatement stmt = body.block.statements[0];
9818 AssignmentExpression assignment = stmt.expression;
9819 SimpleIdentifier leftHandSide = assignment.leftHandSide;
9820 expect(leftHandSide.staticElement.enclosingElement.name, 'M2');
9821 }
9822
9823 void test_setter_fromMixins_property_access() {
9824 Source source = addSource('''
9825 class B {}
9826 class M1 {
9827 set x(value) {}
9828 }
9829 class M2 {
9830 set x(value) {}
9831 }
9832 class C extends B with M1, M2 {}
9833 void main() {
9834 new C().x = 1;
9835 }
9836 ''');
9837 LibraryElement library = resolve2(source);
9838 assertNoErrors(source);
9839 verify([source]);
9840 // Verify that the setter for "x" in "new C().x" refers to the setter
9841 // defined in M2.
9842 FunctionDeclaration main =
9843 library.definingCompilationUnit.functions[0].computeNode();
9844 BlockFunctionBody body = main.functionExpression.body;
9845 ExpressionStatement stmt = body.block.statements[0];
9846 AssignmentExpression assignment = stmt.expression;
9847 PropertyAccess propertyAccess = assignment.leftHandSide;
9848 expect(
9849 propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
9850 }
9851
9852 void test_setter_inherited() {
9853 Source source = addSource(r'''
9854 class A {
9855 int get x => 0;
9856 set x(int p) {}
9857 }
9858 class B extends A {
9859 int get x => super.x == null ? 0 : super.x;
9860 int f() => x = 1;
9861 }''');
9862 computeLibrarySourceErrors(source);
9863 assertNoErrors(source);
9864 verify([source]);
9865 }
9866
9867 void test_setter_static() {
9868 Source source = addSource(r'''
9869 set s(x) {
9870 }
9871
9872 main() {
9873 s = 123;
9874 }''');
9875 computeLibrarySourceErrors(source);
9876 assertNoErrors(source);
9877 verify([source]);
9878 }
9879
9880 /**
9881 * Resolve the given source and verify that the arguments in a specific method invocation were
9882 * correctly resolved.
9883 *
9884 * The source is expected to be source for a compilation unit, the first decla ration is expected
9885 * to be a class, the first member of which is expected to be a method with a block body, and the
9886 * first statement in the body is expected to be an expression statement whose expression is a
9887 * method invocation. It is the arguments to that method invocation that are t ested. The method
9888 * invocation can contain errors.
9889 *
9890 * The arguments were resolved correctly if the number of expressions in the l ist matches the
9891 * length of the array of indices and if, for each index in the array of indic es, the parameter to
9892 * which the argument expression was resolved is the parameter in the invoked method's list of
9893 * parameters at that index. Arguments that should not be resolved to a parame ter because of an
9894 * error can be denoted by including a negative index in the array of indices.
9895 *
9896 * @param source the source to be resolved
9897 * @param indices the array of indices used to associate arguments with parame ters
9898 * @throws Exception if the source could not be resolved or if the structure o f the source is not
9899 * valid
9900 */
9901 void _validateArgumentResolution(Source source, List<int> indices) {
9902 LibraryElement library = resolve2(source);
9903 expect(library, isNotNull);
9904 ClassElement classElement = library.definingCompilationUnit.types[0];
9905 List<ParameterElement> parameters = classElement.methods[1].parameters;
9906 CompilationUnit unit = resolveCompilationUnit(source, library);
9907 expect(unit, isNotNull);
9908 ClassDeclaration classDeclaration =
9909 unit.declarations[0] as ClassDeclaration;
9910 MethodDeclaration methodDeclaration =
9911 classDeclaration.members[0] as MethodDeclaration;
9912 Block block = (methodDeclaration.body as BlockFunctionBody).block;
9913 ExpressionStatement statement = block.statements[0] as ExpressionStatement;
9914 MethodInvocation invocation = statement.expression as MethodInvocation;
9915 NodeList<Expression> arguments = invocation.argumentList.arguments;
9916 int argumentCount = arguments.length;
9917 expect(argumentCount, indices.length);
9918 for (int i = 0; i < argumentCount; i++) {
9919 Expression argument = arguments[i];
9920 ParameterElement element = argument.staticParameterElement;
9921 int index = indices[i];
9922 if (index < 0) {
9923 expect(element, isNull);
9924 } else {
9925 expect(element, same(parameters[index]));
9926 }
9927 }
9928 }
9929 }
9930
9931 class SourceContainer_ChangeSetTest_test_toString implements SourceContainer {
9932 @override
9933 bool contains(Source source) => false;
9934 }
9935
9936 /**
9937 * Like [StaticTypeAnalyzerTest], but as end-to-end tests.
9938 */
9939 @reflectiveTest
9940 class StaticTypeAnalyzer2Test extends ResolverTestCase {
9941 String testCode;
9942 Source testSource;
9943 CompilationUnit testUnit;
9944
9945 void test_FunctionExpressionInvocation_block() {
9946 String code = r'''
9947 main() {
9948 var foo = (() { return 1; })();
9949 }
9950 ''';
9951 _resolveTestUnit(code);
9952 SimpleIdentifier identifier = _findIdentifier('foo');
9953 VariableDeclaration declaration =
9954 identifier.getAncestor((node) => node is VariableDeclaration);
9955 expect(declaration.initializer.staticType.isDynamic, isTrue);
9956 expect(declaration.initializer.propagatedType, isNull);
9957 }
9958
9959 void test_FunctionExpressionInvocation_curried() {
9960 String code = r'''
9961 typedef int F();
9962 F f() => null;
9963 main() {
9964 var foo = f()();
9965 }
9966 ''';
9967 _resolveTestUnit(code);
9968 SimpleIdentifier identifier = _findIdentifier('foo');
9969 VariableDeclaration declaration =
9970 identifier.getAncestor((node) => node is VariableDeclaration);
9971 expect(declaration.initializer.staticType.name, 'int');
9972 expect(declaration.initializer.propagatedType, isNull);
9973 }
9974
9975 void test_FunctionExpressionInvocation_expression() {
9976 String code = r'''
9977 main() {
9978 var foo = (() => 1)();
9979 }
9980 ''';
9981 _resolveTestUnit(code);
9982 SimpleIdentifier identifier = _findIdentifier('foo');
9983 VariableDeclaration declaration =
9984 identifier.getAncestor((node) => node is VariableDeclaration);
9985 expect(declaration.initializer.staticType.name, 'int');
9986 expect(declaration.initializer.propagatedType, isNull);
9987 }
9988
9989 void test_MethodInvocation_nameType_localVariable() {
9990 String code = r"""
9991 typedef Foo();
9992 main() {
9993 Foo foo;
9994 foo();
9995 }
9996 """;
9997 _resolveTestUnit(code);
9998 // "foo" should be resolved to the "Foo" type
9999 SimpleIdentifier identifier = _findIdentifier("foo();");
10000 DartType type = identifier.staticType;
10001 expect(type, new isInstanceOf<FunctionType>());
10002 }
10003
10004 void test_MethodInvocation_nameType_parameter_FunctionTypeAlias() {
10005 String code = r"""
10006 typedef Foo();
10007 main(Foo foo) {
10008 foo();
10009 }
10010 """;
10011 _resolveTestUnit(code);
10012 // "foo" should be resolved to the "Foo" type
10013 SimpleIdentifier identifier = _findIdentifier("foo();");
10014 DartType type = identifier.staticType;
10015 expect(type, new isInstanceOf<FunctionType>());
10016 }
10017
10018 void test_MethodInvocation_nameType_parameter_propagatedType() {
10019 String code = r"""
10020 typedef Foo();
10021 main(p) {
10022 if (p is Foo) {
10023 p();
10024 }
10025 }
10026 """;
10027 _resolveTestUnit(code);
10028 SimpleIdentifier identifier = _findIdentifier("p()");
10029 expect(identifier.staticType, DynamicTypeImpl.instance);
10030 {
10031 FunctionType type = identifier.propagatedType;
10032 expect(type, isNotNull);
10033 expect(type.name, 'Foo');
10034 }
10035 }
10036
10037 SimpleIdentifier _findIdentifier(String search) {
10038 SimpleIdentifier identifier = EngineTestCase.findNode(
10039 testUnit, testCode, search, (node) => node is SimpleIdentifier);
10040 return identifier;
10041 }
10042
10043 void _resolveTestUnit(String code) {
10044 testCode = code;
10045 testSource = addSource(testCode);
10046 LibraryElement library = resolve2(testSource);
10047 assertNoErrors(testSource);
10048 verify([testSource]);
10049 testUnit = resolveCompilationUnit(testSource, library);
10050 }
10051 }
10052
10053 @reflectiveTest
10054 class StaticTypeAnalyzerTest extends EngineTestCase {
10055 /**
10056 * The error listener to which errors will be reported.
10057 */
10058 GatheringErrorListener _listener;
10059
10060 /**
10061 * The resolver visitor used to create the analyzer.
10062 */
10063 ResolverVisitor _visitor;
10064
10065 /**
10066 * The analyzer being used to analyze the test cases.
10067 */
10068 StaticTypeAnalyzer _analyzer;
10069
10070 /**
10071 * The type provider used to access the types.
10072 */
10073 TestTypeProvider _typeProvider;
10074
10075 void fail_visitFunctionExpressionInvocation() {
10076 fail("Not yet tested");
10077 _listener.assertNoErrors();
10078 }
10079
10080 void fail_visitMethodInvocation() {
10081 fail("Not yet tested");
10082 _listener.assertNoErrors();
10083 }
10084
10085 void fail_visitSimpleIdentifier() {
10086 fail("Not yet tested");
10087 _listener.assertNoErrors();
10088 }
10089
10090 @override
10091 void setUp() {
10092 _listener = new GatheringErrorListener();
10093 _typeProvider = new TestTypeProvider();
10094 _analyzer = _createAnalyzer();
10095 }
10096
10097 void test_flatten_derived() {
10098 // class Derived<T> extends Future<T> { ... }
10099 ClassElementImpl derivedClass =
10100 ElementFactory.classElement2('Derived', ['T']);
10101 derivedClass.supertype = _typeProvider.futureType
10102 .substitute4([derivedClass.typeParameters[0].type]);
10103 InterfaceType intType = _typeProvider.intType;
10104 DartType dynamicType = _typeProvider.dynamicType;
10105 InterfaceType derivedIntType = derivedClass.type.substitute4([intType]);
10106 // flatten(Derived) = dynamic
10107 InterfaceType derivedDynamicType =
10108 derivedClass.type.substitute4([dynamicType]);
10109 expect(_flatten(derivedDynamicType), dynamicType);
10110 // flatten(Derived<int>) = int
10111 expect(_flatten(derivedIntType), intType);
10112 // flatten(Derived<Derived>) = Derived
10113 expect(_flatten(derivedClass.type.substitute4([derivedDynamicType])),
10114 derivedDynamicType);
10115 // flatten(Derived<Derived<int>>) = Derived<int>
10116 expect(_flatten(derivedClass.type.substitute4([derivedIntType])),
10117 derivedIntType);
10118 }
10119
10120 void test_flatten_inhibit_recursion() {
10121 // class A extends B
10122 // class B extends A
10123 ClassElementImpl classA = ElementFactory.classElement2('A', []);
10124 ClassElementImpl classB = ElementFactory.classElement2('B', []);
10125 classA.supertype = classB.type;
10126 classB.supertype = classA.type;
10127 // flatten(A) = A and flatten(B) = B, since neither class contains Future
10128 // in its class hierarchy. Even though there is a loop in the class
10129 // hierarchy, flatten() should terminate.
10130 expect(_flatten(classA.type), classA.type);
10131 expect(_flatten(classB.type), classB.type);
10132 }
10133
10134 void test_flatten_related_derived_types() {
10135 InterfaceType intType = _typeProvider.intType;
10136 InterfaceType numType = _typeProvider.numType;
10137 // class Derived<T> extends Future<T>
10138 ClassElementImpl derivedClass =
10139 ElementFactory.classElement2('Derived', ['T']);
10140 derivedClass.supertype = _typeProvider.futureType
10141 .substitute4([derivedClass.typeParameters[0].type]);
10142 InterfaceType derivedType = derivedClass.type;
10143 // class A extends Derived<int> implements Derived<num> { ... }
10144 ClassElementImpl classA =
10145 ElementFactory.classElement('A', derivedType.substitute4([intType]));
10146 classA.interfaces = <InterfaceType>[
10147 derivedType.substitute4([numType])
10148 ];
10149 // class B extends Future<num> implements Future<int> { ... }
10150 ClassElementImpl classB =
10151 ElementFactory.classElement('B', derivedType.substitute4([numType]));
10152 classB.interfaces = <InterfaceType>[
10153 derivedType.substitute4([intType])
10154 ];
10155 // flatten(A) = flatten(B) = int, since int is more specific than num.
10156 // The code in flatten() that inhibits infinite recursion shouldn't be
10157 // fooled by the fact that Derived appears twice in the type hierarchy.
10158 expect(_flatten(classA.type), intType);
10159 expect(_flatten(classB.type), intType);
10160 }
10161
10162 void test_flatten_related_types() {
10163 InterfaceType futureType = _typeProvider.futureType;
10164 InterfaceType intType = _typeProvider.intType;
10165 InterfaceType numType = _typeProvider.numType;
10166 // class A extends Future<int> implements Future<num> { ... }
10167 ClassElementImpl classA =
10168 ElementFactory.classElement('A', futureType.substitute4([intType]));
10169 classA.interfaces = <InterfaceType>[
10170 futureType.substitute4([numType])
10171 ];
10172 // class B extends Future<num> implements Future<int> { ... }
10173 ClassElementImpl classB =
10174 ElementFactory.classElement('B', futureType.substitute4([numType]));
10175 classB.interfaces = <InterfaceType>[
10176 futureType.substitute4([intType])
10177 ];
10178 // flatten(A) = flatten(B) = int, since int is more specific than num.
10179 expect(_flatten(classA.type), intType);
10180 expect(_flatten(classB.type), intType);
10181 }
10182
10183 void test_flatten_simple() {
10184 InterfaceType intType = _typeProvider.intType;
10185 DartType dynamicType = _typeProvider.dynamicType;
10186 InterfaceType futureDynamicType = _typeProvider.futureDynamicType;
10187 InterfaceType futureIntType =
10188 _typeProvider.futureType.substitute4([intType]);
10189 InterfaceType futureFutureDynamicType =
10190 _typeProvider.futureType.substitute4([futureDynamicType]);
10191 InterfaceType futureFutureIntType =
10192 _typeProvider.futureType.substitute4([futureIntType]);
10193 // flatten(int) = int
10194 expect(_flatten(intType), intType);
10195 // flatten(dynamic) = dynamic
10196 expect(_flatten(dynamicType), dynamicType);
10197 // flatten(Future) = dynamic
10198 expect(_flatten(futureDynamicType), dynamicType);
10199 // flatten(Future<int>) = int
10200 expect(_flatten(futureIntType), intType);
10201 // flatten(Future<Future>) = dynamic
10202 expect(_flatten(futureFutureDynamicType), dynamicType);
10203 // flatten(Future<Future<int>>) = int
10204 expect(_flatten(futureFutureIntType), intType);
10205 }
10206
10207 void test_flatten_unrelated_types() {
10208 InterfaceType futureType = _typeProvider.futureType;
10209 InterfaceType intType = _typeProvider.intType;
10210 InterfaceType stringType = _typeProvider.stringType;
10211 // class A extends Future<int> implements Future<String> { ... }
10212 ClassElementImpl classA =
10213 ElementFactory.classElement('A', futureType.substitute4([intType]));
10214 classA.interfaces = <InterfaceType>[
10215 futureType.substitute4([stringType])
10216 ];
10217 // class B extends Future<String> implements Future<int> { ... }
10218 ClassElementImpl classB =
10219 ElementFactory.classElement('B', futureType.substitute4([stringType]));
10220 classB.interfaces = <InterfaceType>[
10221 futureType.substitute4([intType])
10222 ];
10223 // flatten(A) = A and flatten(B) = B, since neither string nor int is more
10224 // specific than the other.
10225 expect(_flatten(classA.type), classA.type);
10226 expect(_flatten(classB.type), classB.type);
10227 }
10228
10229 void test_visitAdjacentStrings() {
10230 // "a" "b"
10231 Expression node = AstFactory
10232 .adjacentStrings([_resolvedString("a"), _resolvedString("b")]);
10233 expect(_analyze(node), same(_typeProvider.stringType));
10234 _listener.assertNoErrors();
10235 }
10236
10237 void test_visitAsExpression() {
10238 // class A { ... this as B ... }
10239 // class B extends A {}
10240 ClassElement superclass = ElementFactory.classElement2("A");
10241 InterfaceType superclassType = superclass.type;
10242 ClassElement subclass = ElementFactory.classElement("B", superclassType);
10243 Expression node = AstFactory.asExpression(
10244 AstFactory.thisExpression(), AstFactory.typeName(subclass));
10245 expect(_analyze3(node, superclassType), same(subclass.type));
10246 _listener.assertNoErrors();
10247 }
10248
10249 void test_visitAssignmentExpression_compound() {
10250 // i += 1
10251 InterfaceType numType = _typeProvider.numType;
10252 SimpleIdentifier identifier = _resolvedVariable(_typeProvider.intType, "i");
10253 AssignmentExpression node = AstFactory.assignmentExpression(
10254 identifier, TokenType.PLUS_EQ, _resolvedInteger(1));
10255 MethodElement plusMethod = getMethod(numType, "+");
10256 node.staticElement = plusMethod;
10257 expect(_analyze(node), same(numType));
10258 _listener.assertNoErrors();
10259 }
10260
10261 void test_visitAssignmentExpression_compoundIfNull_differentTypes() {
10262 // double d; d ??= 0
10263 Expression node = AstFactory.assignmentExpression(
10264 _resolvedVariable(_typeProvider.doubleType, 'd'),
10265 TokenType.QUESTION_QUESTION_EQ,
10266 _resolvedInteger(0));
10267 expect(_analyze(node), same(_typeProvider.numType));
10268 _listener.assertNoErrors();
10269 }
10270
10271 void test_visitAssignmentExpression_compoundIfNull_sameTypes() {
10272 // int i; i ??= 0
10273 Expression node = AstFactory.assignmentExpression(
10274 _resolvedVariable(_typeProvider.intType, 'i'),
10275 TokenType.QUESTION_QUESTION_EQ,
10276 _resolvedInteger(0));
10277 expect(_analyze(node), same(_typeProvider.intType));
10278 _listener.assertNoErrors();
10279 }
10280
10281 void test_visitAssignmentExpression_simple() {
10282 // i = 0
10283 InterfaceType intType = _typeProvider.intType;
10284 Expression node = AstFactory.assignmentExpression(
10285 _resolvedVariable(intType, "i"), TokenType.EQ, _resolvedInteger(0));
10286 expect(_analyze(node), same(intType));
10287 _listener.assertNoErrors();
10288 }
10289
10290 void test_visitAwaitExpression_flattened() {
10291 // await e, where e has type Future<Future<int>>
10292 InterfaceType intType = _typeProvider.intType;
10293 InterfaceType futureIntType =
10294 _typeProvider.futureType.substitute4(<DartType>[intType]);
10295 InterfaceType futureFutureIntType =
10296 _typeProvider.futureType.substitute4(<DartType>[futureIntType]);
10297 Expression node =
10298 AstFactory.awaitExpression(_resolvedVariable(futureFutureIntType, 'e'));
10299 expect(_analyze(node), same(intType));
10300 _listener.assertNoErrors();
10301 }
10302
10303 void test_visitAwaitExpression_simple() {
10304 // await e, where e has type Future<int>
10305 InterfaceType intType = _typeProvider.intType;
10306 InterfaceType futureIntType =
10307 _typeProvider.futureType.substitute4(<DartType>[intType]);
10308 Expression node =
10309 AstFactory.awaitExpression(_resolvedVariable(futureIntType, 'e'));
10310 expect(_analyze(node), same(intType));
10311 _listener.assertNoErrors();
10312 }
10313
10314 void test_visitBinaryExpression_equals() {
10315 // 2 == 3
10316 Expression node = AstFactory.binaryExpression(
10317 _resolvedInteger(2), TokenType.EQ_EQ, _resolvedInteger(3));
10318 expect(_analyze(node), same(_typeProvider.boolType));
10319 _listener.assertNoErrors();
10320 }
10321
10322 void test_visitBinaryExpression_ifNull() {
10323 // 1 ?? 1.5
10324 Expression node = AstFactory.binaryExpression(
10325 _resolvedInteger(1), TokenType.QUESTION_QUESTION, _resolvedDouble(1.5));
10326 expect(_analyze(node), same(_typeProvider.numType));
10327 _listener.assertNoErrors();
10328 }
10329
10330 void test_visitBinaryExpression_logicalAnd() {
10331 // false && true
10332 Expression node = AstFactory.binaryExpression(
10333 AstFactory.booleanLiteral(false),
10334 TokenType.AMPERSAND_AMPERSAND,
10335 AstFactory.booleanLiteral(true));
10336 expect(_analyze(node), same(_typeProvider.boolType));
10337 _listener.assertNoErrors();
10338 }
10339
10340 void test_visitBinaryExpression_logicalOr() {
10341 // false || true
10342 Expression node = AstFactory.binaryExpression(
10343 AstFactory.booleanLiteral(false),
10344 TokenType.BAR_BAR,
10345 AstFactory.booleanLiteral(true));
10346 expect(_analyze(node), same(_typeProvider.boolType));
10347 _listener.assertNoErrors();
10348 }
10349
10350 void test_visitBinaryExpression_minusID_propagated() {
10351 // a - b
10352 BinaryExpression node = AstFactory.binaryExpression(
10353 _propagatedVariable(_typeProvider.intType, 'a'),
10354 TokenType.MINUS,
10355 _propagatedVariable(_typeProvider.doubleType, 'b'));
10356 node.propagatedElement = getMethod(_typeProvider.numType, "+");
10357 _analyze(node);
10358 expect(node.propagatedType, same(_typeProvider.doubleType));
10359 _listener.assertNoErrors();
10360 }
10361
10362 void test_visitBinaryExpression_notEquals() {
10363 // 2 != 3
10364 Expression node = AstFactory.binaryExpression(
10365 _resolvedInteger(2), TokenType.BANG_EQ, _resolvedInteger(3));
10366 expect(_analyze(node), same(_typeProvider.boolType));
10367 _listener.assertNoErrors();
10368 }
10369
10370 void test_visitBinaryExpression_plusID() {
10371 // 1 + 2.0
10372 BinaryExpression node = AstFactory.binaryExpression(
10373 _resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0));
10374 node.staticElement = getMethod(_typeProvider.numType, "+");
10375 expect(_analyze(node), same(_typeProvider.doubleType));
10376 _listener.assertNoErrors();
10377 }
10378
10379 void test_visitBinaryExpression_plusII() {
10380 // 1 + 2
10381 BinaryExpression node = AstFactory.binaryExpression(
10382 _resolvedInteger(1), TokenType.PLUS, _resolvedInteger(2));
10383 node.staticElement = getMethod(_typeProvider.numType, "+");
10384 expect(_analyze(node), same(_typeProvider.intType));
10385 _listener.assertNoErrors();
10386 }
10387
10388 void test_visitBinaryExpression_plusII_propagated() {
10389 // a + b
10390 BinaryExpression node = AstFactory.binaryExpression(
10391 _propagatedVariable(_typeProvider.intType, 'a'),
10392 TokenType.PLUS,
10393 _propagatedVariable(_typeProvider.intType, 'b'));
10394 node.propagatedElement = getMethod(_typeProvider.numType, "+");
10395 _analyze(node);
10396 expect(node.propagatedType, same(_typeProvider.intType));
10397 _listener.assertNoErrors();
10398 }
10399
10400 void test_visitBinaryExpression_slash() {
10401 // 2 / 2
10402 BinaryExpression node = AstFactory.binaryExpression(
10403 _resolvedInteger(2), TokenType.SLASH, _resolvedInteger(2));
10404 node.staticElement = getMethod(_typeProvider.numType, "/");
10405 expect(_analyze(node), same(_typeProvider.doubleType));
10406 _listener.assertNoErrors();
10407 }
10408
10409 void test_visitBinaryExpression_star_notSpecial() {
10410 // class A {
10411 // A operator *(double value);
10412 // }
10413 // (a as A) * 2.0
10414 ClassElementImpl classA = ElementFactory.classElement2("A");
10415 InterfaceType typeA = classA.type;
10416 MethodElement operator =
10417 ElementFactory.methodElement("*", typeA, [_typeProvider.doubleType]);
10418 classA.methods = <MethodElement>[operator];
10419 BinaryExpression node = AstFactory.binaryExpression(
10420 AstFactory.asExpression(
10421 AstFactory.identifier3("a"), AstFactory.typeName(classA)),
10422 TokenType.PLUS,
10423 _resolvedDouble(2.0));
10424 node.staticElement = operator;
10425 expect(_analyze(node), same(typeA));
10426 _listener.assertNoErrors();
10427 }
10428
10429 void test_visitBinaryExpression_starID() {
10430 // 1 * 2.0
10431 BinaryExpression node = AstFactory.binaryExpression(
10432 _resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0));
10433 node.staticElement = getMethod(_typeProvider.numType, "*");
10434 expect(_analyze(node), same(_typeProvider.doubleType));
10435 _listener.assertNoErrors();
10436 }
10437
10438 void test_visitBooleanLiteral_false() {
10439 // false
10440 Expression node = AstFactory.booleanLiteral(false);
10441 expect(_analyze(node), same(_typeProvider.boolType));
10442 _listener.assertNoErrors();
10443 }
10444
10445 void test_visitBooleanLiteral_true() {
10446 // true
10447 Expression node = AstFactory.booleanLiteral(true);
10448 expect(_analyze(node), same(_typeProvider.boolType));
10449 _listener.assertNoErrors();
10450 }
10451
10452 void test_visitCascadeExpression() {
10453 // a..length
10454 Expression node = AstFactory.cascadeExpression(
10455 _resolvedString("a"), [AstFactory.propertyAccess2(null, "length")]);
10456 expect(_analyze(node), same(_typeProvider.stringType));
10457 _listener.assertNoErrors();
10458 }
10459
10460 void test_visitConditionalExpression_differentTypes() {
10461 // true ? 1.0 : 0
10462 Expression node = AstFactory.conditionalExpression(
10463 AstFactory.booleanLiteral(true),
10464 _resolvedDouble(1.0),
10465 _resolvedInteger(0));
10466 expect(_analyze(node), same(_typeProvider.numType));
10467 _listener.assertNoErrors();
10468 }
10469
10470 void test_visitConditionalExpression_sameTypes() {
10471 // true ? 1 : 0
10472 Expression node = AstFactory.conditionalExpression(
10473 AstFactory.booleanLiteral(true),
10474 _resolvedInteger(1),
10475 _resolvedInteger(0));
10476 expect(_analyze(node), same(_typeProvider.intType));
10477 _listener.assertNoErrors();
10478 }
10479
10480 void test_visitDoubleLiteral() {
10481 // 4.33
10482 Expression node = AstFactory.doubleLiteral(4.33);
10483 expect(_analyze(node), same(_typeProvider.doubleType));
10484 _listener.assertNoErrors();
10485 }
10486
10487 void test_visitFunctionExpression_async_block() {
10488 // () async {}
10489 BlockFunctionBody body = AstFactory.blockFunctionBody2();
10490 body.keyword = TokenFactory.tokenFromString('async');
10491 FunctionExpression node =
10492 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
10493 DartType resultType = _analyze(node);
10494 _assertFunctionType(
10495 _typeProvider.futureDynamicType, null, null, null, resultType);
10496 _listener.assertNoErrors();
10497 }
10498
10499 void test_visitFunctionExpression_async_expression() {
10500 // () async => e, where e has type int
10501 InterfaceType intType = _typeProvider.intType;
10502 InterfaceType futureIntType =
10503 _typeProvider.futureType.substitute4(<DartType>[intType]);
10504 Expression expression = _resolvedVariable(intType, 'e');
10505 ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
10506 body.keyword = TokenFactory.tokenFromString('async');
10507 FunctionExpression node =
10508 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
10509 DartType resultType = _analyze(node);
10510 _assertFunctionType(futureIntType, null, null, null, resultType);
10511 _listener.assertNoErrors();
10512 }
10513
10514 void test_visitFunctionExpression_async_expression_flatten() {
10515 // () async => e, where e has type Future<int>
10516 InterfaceType intType = _typeProvider.intType;
10517 InterfaceType futureIntType =
10518 _typeProvider.futureType.substitute4(<DartType>[intType]);
10519 Expression expression = _resolvedVariable(futureIntType, 'e');
10520 ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
10521 body.keyword = TokenFactory.tokenFromString('async');
10522 FunctionExpression node =
10523 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
10524 DartType resultType = _analyze(node);
10525 _assertFunctionType(futureIntType, null, null, null, resultType);
10526 _listener.assertNoErrors();
10527 }
10528
10529 void test_visitFunctionExpression_async_expression_flatten_twice() {
10530 // () async => e, where e has type Future<Future<int>>
10531 InterfaceType intType = _typeProvider.intType;
10532 InterfaceType futureIntType =
10533 _typeProvider.futureType.substitute4(<DartType>[intType]);
10534 InterfaceType futureFutureIntType =
10535 _typeProvider.futureType.substitute4(<DartType>[futureIntType]);
10536 Expression expression = _resolvedVariable(futureFutureIntType, 'e');
10537 ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
10538 body.keyword = TokenFactory.tokenFromString('async');
10539 FunctionExpression node =
10540 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
10541 DartType resultType = _analyze(node);
10542 _assertFunctionType(futureIntType, null, null, null, resultType);
10543 _listener.assertNoErrors();
10544 }
10545
10546 void test_visitFunctionExpression_generator_async() {
10547 // () async* {}
10548 BlockFunctionBody body = AstFactory.blockFunctionBody2();
10549 body.keyword = TokenFactory.tokenFromString('async');
10550 body.star = TokenFactory.tokenFromType(TokenType.STAR);
10551 FunctionExpression node =
10552 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
10553 DartType resultType = _analyze(node);
10554 _assertFunctionType(
10555 _typeProvider.streamDynamicType, null, null, null, resultType);
10556 _listener.assertNoErrors();
10557 }
10558
10559 void test_visitFunctionExpression_generator_sync() {
10560 // () sync* {}
10561 BlockFunctionBody body = AstFactory.blockFunctionBody2();
10562 body.keyword = TokenFactory.tokenFromString('sync');
10563 body.star = TokenFactory.tokenFromType(TokenType.STAR);
10564 FunctionExpression node =
10565 _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
10566 DartType resultType = _analyze(node);
10567 _assertFunctionType(
10568 _typeProvider.iterableDynamicType, null, null, null, resultType);
10569 _listener.assertNoErrors();
10570 }
10571
10572 void test_visitFunctionExpression_named_block() {
10573 // ({p1 : 0, p2 : 0}) {}
10574 DartType dynamicType = _typeProvider.dynamicType;
10575 FormalParameter p1 = AstFactory.namedFormalParameter(
10576 AstFactory.simpleFormalParameter3("p1"), _resolvedInteger(0));
10577 _setType(p1, dynamicType);
10578 FormalParameter p2 = AstFactory.namedFormalParameter(
10579 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
10580 _setType(p2, dynamicType);
10581 FunctionExpression node = _resolvedFunctionExpression(
10582 AstFactory.formalParameterList([p1, p2]),
10583 AstFactory.blockFunctionBody2());
10584 _analyze5(p1);
10585 _analyze5(p2);
10586 DartType resultType = _analyze(node);
10587 Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
10588 expectedNamedTypes["p1"] = dynamicType;
10589 expectedNamedTypes["p2"] = dynamicType;
10590 _assertFunctionType(
10591 dynamicType, null, null, expectedNamedTypes, resultType);
10592 _listener.assertNoErrors();
10593 }
10594
10595 void test_visitFunctionExpression_named_expression() {
10596 // ({p : 0}) -> 0;
10597 DartType dynamicType = _typeProvider.dynamicType;
10598 FormalParameter p = AstFactory.namedFormalParameter(
10599 AstFactory.simpleFormalParameter3("p"), _resolvedInteger(0));
10600 _setType(p, dynamicType);
10601 FunctionExpression node = _resolvedFunctionExpression(
10602 AstFactory.formalParameterList([p]),
10603 AstFactory.expressionFunctionBody(_resolvedInteger(0)));
10604 _analyze5(p);
10605 DartType resultType = _analyze(node);
10606 Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
10607 expectedNamedTypes["p"] = dynamicType;
10608 _assertFunctionType(
10609 _typeProvider.intType, null, null, expectedNamedTypes, resultType);
10610 _listener.assertNoErrors();
10611 }
10612
10613 void test_visitFunctionExpression_normal_block() {
10614 // (p1, p2) {}
10615 DartType dynamicType = _typeProvider.dynamicType;
10616 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
10617 _setType(p1, dynamicType);
10618 FormalParameter p2 = AstFactory.simpleFormalParameter3("p2");
10619 _setType(p2, dynamicType);
10620 FunctionExpression node = _resolvedFunctionExpression(
10621 AstFactory.formalParameterList([p1, p2]),
10622 AstFactory.blockFunctionBody2());
10623 _analyze5(p1);
10624 _analyze5(p2);
10625 DartType resultType = _analyze(node);
10626 _assertFunctionType(dynamicType, <DartType>[dynamicType, dynamicType], null,
10627 null, resultType);
10628 _listener.assertNoErrors();
10629 }
10630
10631 void test_visitFunctionExpression_normal_expression() {
10632 // (p1, p2) -> 0
10633 DartType dynamicType = _typeProvider.dynamicType;
10634 FormalParameter p = AstFactory.simpleFormalParameter3("p");
10635 _setType(p, dynamicType);
10636 FunctionExpression node = _resolvedFunctionExpression(
10637 AstFactory.formalParameterList([p]),
10638 AstFactory.expressionFunctionBody(_resolvedInteger(0)));
10639 _analyze5(p);
10640 DartType resultType = _analyze(node);
10641 _assertFunctionType(
10642 _typeProvider.intType, <DartType>[dynamicType], null, null, resultType);
10643 _listener.assertNoErrors();
10644 }
10645
10646 void test_visitFunctionExpression_normalAndNamed_block() {
10647 // (p1, {p2 : 0}) {}
10648 DartType dynamicType = _typeProvider.dynamicType;
10649 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
10650 _setType(p1, dynamicType);
10651 FormalParameter p2 = AstFactory.namedFormalParameter(
10652 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
10653 _setType(p2, dynamicType);
10654 FunctionExpression node = _resolvedFunctionExpression(
10655 AstFactory.formalParameterList([p1, p2]),
10656 AstFactory.blockFunctionBody2());
10657 _analyze5(p2);
10658 DartType resultType = _analyze(node);
10659 Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
10660 expectedNamedTypes["p2"] = dynamicType;
10661 _assertFunctionType(dynamicType, <DartType>[dynamicType], null,
10662 expectedNamedTypes, resultType);
10663 _listener.assertNoErrors();
10664 }
10665
10666 void test_visitFunctionExpression_normalAndNamed_expression() {
10667 // (p1, {p2 : 0}) -> 0
10668 DartType dynamicType = _typeProvider.dynamicType;
10669 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
10670 _setType(p1, dynamicType);
10671 FormalParameter p2 = AstFactory.namedFormalParameter(
10672 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
10673 _setType(p2, dynamicType);
10674 FunctionExpression node = _resolvedFunctionExpression(
10675 AstFactory.formalParameterList([p1, p2]),
10676 AstFactory.expressionFunctionBody(_resolvedInteger(0)));
10677 _analyze5(p2);
10678 DartType resultType = _analyze(node);
10679 Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
10680 expectedNamedTypes["p2"] = dynamicType;
10681 _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType], null,
10682 expectedNamedTypes, resultType);
10683 _listener.assertNoErrors();
10684 }
10685
10686 void test_visitFunctionExpression_normalAndPositional_block() {
10687 // (p1, [p2 = 0]) {}
10688 DartType dynamicType = _typeProvider.dynamicType;
10689 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
10690 _setType(p1, dynamicType);
10691 FormalParameter p2 = AstFactory.positionalFormalParameter(
10692 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
10693 _setType(p2, dynamicType);
10694 FunctionExpression node = _resolvedFunctionExpression(
10695 AstFactory.formalParameterList([p1, p2]),
10696 AstFactory.blockFunctionBody2());
10697 _analyze5(p1);
10698 _analyze5(p2);
10699 DartType resultType = _analyze(node);
10700 _assertFunctionType(dynamicType, <DartType>[dynamicType],
10701 <DartType>[dynamicType], null, resultType);
10702 _listener.assertNoErrors();
10703 }
10704
10705 void test_visitFunctionExpression_normalAndPositional_expression() {
10706 // (p1, [p2 = 0]) -> 0
10707 DartType dynamicType = _typeProvider.dynamicType;
10708 FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
10709 _setType(p1, dynamicType);
10710 FormalParameter p2 = AstFactory.positionalFormalParameter(
10711 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
10712 _setType(p2, dynamicType);
10713 FunctionExpression node = _resolvedFunctionExpression(
10714 AstFactory.formalParameterList([p1, p2]),
10715 AstFactory.expressionFunctionBody(_resolvedInteger(0)));
10716 _analyze5(p1);
10717 _analyze5(p2);
10718 DartType resultType = _analyze(node);
10719 _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType],
10720 <DartType>[dynamicType], null, resultType);
10721 _listener.assertNoErrors();
10722 }
10723
10724 void test_visitFunctionExpression_positional_block() {
10725 // ([p1 = 0, p2 = 0]) {}
10726 DartType dynamicType = _typeProvider.dynamicType;
10727 FormalParameter p1 = AstFactory.positionalFormalParameter(
10728 AstFactory.simpleFormalParameter3("p1"), _resolvedInteger(0));
10729 _setType(p1, dynamicType);
10730 FormalParameter p2 = AstFactory.positionalFormalParameter(
10731 AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
10732 _setType(p2, dynamicType);
10733 FunctionExpression node = _resolvedFunctionExpression(
10734 AstFactory.formalParameterList([p1, p2]),
10735 AstFactory.blockFunctionBody2());
10736 _analyze5(p1);
10737 _analyze5(p2);
10738 DartType resultType = _analyze(node);
10739 _assertFunctionType(dynamicType, null, <DartType>[dynamicType, dynamicType],
10740 null, resultType);
10741 _listener.assertNoErrors();
10742 }
10743
10744 void test_visitFunctionExpression_positional_expression() {
10745 // ([p1 = 0, p2 = 0]) -> 0
10746 DartType dynamicType = _typeProvider.dynamicType;
10747 FormalParameter p = AstFactory.positionalFormalParameter(
10748 AstFactory.simpleFormalParameter3("p"), _resolvedInteger(0));
10749 _setType(p, dynamicType);
10750 FunctionExpression node = _resolvedFunctionExpression(
10751 AstFactory.formalParameterList([p]),
10752 AstFactory.expressionFunctionBody(_resolvedInteger(0)));
10753 _analyze5(p);
10754 DartType resultType = _analyze(node);
10755 _assertFunctionType(
10756 _typeProvider.intType, null, <DartType>[dynamicType], null, resultType);
10757 _listener.assertNoErrors();
10758 }
10759
10760 void test_visitIndexExpression_getter() {
10761 // List a;
10762 // a[2]
10763 InterfaceType listType = _typeProvider.listType;
10764 SimpleIdentifier identifier = _resolvedVariable(listType, "a");
10765 IndexExpression node =
10766 AstFactory.indexExpression(identifier, _resolvedInteger(2));
10767 MethodElement indexMethod = listType.element.methods[0];
10768 node.staticElement = indexMethod;
10769 expect(_analyze(node), same(listType.typeArguments[0]));
10770 _listener.assertNoErrors();
10771 }
10772
10773 void test_visitIndexExpression_setter() {
10774 // List a;
10775 // a[2] = 0
10776 InterfaceType listType = _typeProvider.listType;
10777 SimpleIdentifier identifier = _resolvedVariable(listType, "a");
10778 IndexExpression node =
10779 AstFactory.indexExpression(identifier, _resolvedInteger(2));
10780 MethodElement indexMethod = listType.element.methods[1];
10781 node.staticElement = indexMethod;
10782 AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0));
10783 expect(_analyze(node), same(listType.typeArguments[0]));
10784 _listener.assertNoErrors();
10785 }
10786
10787 void test_visitIndexExpression_typeParameters() {
10788 // List<int> list = ...
10789 // list[0]
10790 InterfaceType intType = _typeProvider.intType;
10791 InterfaceType listType = _typeProvider.listType;
10792 // (int) -> E
10793 MethodElement methodElement = getMethod(listType, "[]");
10794 // "list" has type List<int>
10795 SimpleIdentifier identifier = AstFactory.identifier3("list");
10796 InterfaceType listOfIntType = listType.substitute4(<DartType>[intType]);
10797 identifier.staticType = listOfIntType;
10798 // list[0] has MethodElement element (int) -> E
10799 IndexExpression indexExpression =
10800 AstFactory.indexExpression(identifier, AstFactory.integer(0));
10801 MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType);
10802 indexExpression.staticElement = indexMethod;
10803 // analyze and assert result of the index expression
10804 expect(_analyze(indexExpression), same(intType));
10805 _listener.assertNoErrors();
10806 }
10807
10808 void test_visitIndexExpression_typeParameters_inSetterContext() {
10809 // List<int> list = ...
10810 // list[0] = 0;
10811 InterfaceType intType = _typeProvider.intType;
10812 InterfaceType listType = _typeProvider.listType;
10813 // (int, E) -> void
10814 MethodElement methodElement = getMethod(listType, "[]=");
10815 // "list" has type List<int>
10816 SimpleIdentifier identifier = AstFactory.identifier3("list");
10817 InterfaceType listOfIntType = listType.substitute4(<DartType>[intType]);
10818 identifier.staticType = listOfIntType;
10819 // list[0] has MethodElement element (int) -> E
10820 IndexExpression indexExpression =
10821 AstFactory.indexExpression(identifier, AstFactory.integer(0));
10822 MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType);
10823 indexExpression.staticElement = indexMethod;
10824 // list[0] should be in a setter context
10825 AstFactory.assignmentExpression(
10826 indexExpression, TokenType.EQ, AstFactory.integer(0));
10827 // analyze and assert result of the index expression
10828 expect(_analyze(indexExpression), same(intType));
10829 _listener.assertNoErrors();
10830 }
10831
10832 void test_visitInstanceCreationExpression_named() {
10833 // new C.m()
10834 ClassElementImpl classElement = ElementFactory.classElement2("C");
10835 String constructorName = "m";
10836 ConstructorElementImpl constructor =
10837 ElementFactory.constructorElement2(classElement, constructorName);
10838 constructor.returnType = classElement.type;
10839 FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
10840 constructor.type = constructorType;
10841 classElement.constructors = <ConstructorElement>[constructor];
10842 InstanceCreationExpression node = AstFactory.instanceCreationExpression2(
10843 null,
10844 AstFactory.typeName(classElement),
10845 [AstFactory.identifier3(constructorName)]);
10846 node.staticElement = constructor;
10847 expect(_analyze(node), same(classElement.type));
10848 _listener.assertNoErrors();
10849 }
10850
10851 void test_visitInstanceCreationExpression_typeParameters() {
10852 // new C<I>()
10853 ClassElementImpl elementC = ElementFactory.classElement2("C", ["E"]);
10854 ClassElementImpl elementI = ElementFactory.classElement2("I");
10855 ConstructorElementImpl constructor =
10856 ElementFactory.constructorElement2(elementC, null);
10857 elementC.constructors = <ConstructorElement>[constructor];
10858 constructor.returnType = elementC.type;
10859 FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
10860 constructor.type = constructorType;
10861 TypeName typeName =
10862 AstFactory.typeName(elementC, [AstFactory.typeName(elementI)]);
10863 typeName.type = elementC.type.substitute4(<DartType>[elementI.type]);
10864 InstanceCreationExpression node =
10865 AstFactory.instanceCreationExpression2(null, typeName);
10866 node.staticElement = constructor;
10867 InterfaceType interfaceType = _analyze(node) as InterfaceType;
10868 List<DartType> typeArgs = interfaceType.typeArguments;
10869 expect(typeArgs.length, 1);
10870 expect(typeArgs[0], elementI.type);
10871 _listener.assertNoErrors();
10872 }
10873
10874 void test_visitInstanceCreationExpression_unnamed() {
10875 // new C()
10876 ClassElementImpl classElement = ElementFactory.classElement2("C");
10877 ConstructorElementImpl constructor =
10878 ElementFactory.constructorElement2(classElement, null);
10879 constructor.returnType = classElement.type;
10880 FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
10881 constructor.type = constructorType;
10882 classElement.constructors = <ConstructorElement>[constructor];
10883 InstanceCreationExpression node = AstFactory.instanceCreationExpression2(
10884 null, AstFactory.typeName(classElement));
10885 node.staticElement = constructor;
10886 expect(_analyze(node), same(classElement.type));
10887 _listener.assertNoErrors();
10888 }
10889
10890 void test_visitIntegerLiteral() {
10891 // 42
10892 Expression node = _resolvedInteger(42);
10893 expect(_analyze(node), same(_typeProvider.intType));
10894 _listener.assertNoErrors();
10895 }
10896
10897 void test_visitIsExpression_negated() {
10898 // a is! String
10899 Expression node = AstFactory.isExpression(
10900 _resolvedString("a"), true, AstFactory.typeName4("String"));
10901 expect(_analyze(node), same(_typeProvider.boolType));
10902 _listener.assertNoErrors();
10903 }
10904
10905 void test_visitIsExpression_notNegated() {
10906 // a is String
10907 Expression node = AstFactory.isExpression(
10908 _resolvedString("a"), false, AstFactory.typeName4("String"));
10909 expect(_analyze(node), same(_typeProvider.boolType));
10910 _listener.assertNoErrors();
10911 }
10912
10913 void test_visitListLiteral_empty() {
10914 // []
10915 Expression node = AstFactory.listLiteral();
10916 DartType resultType = _analyze(node);
10917 _assertType2(
10918 _typeProvider.listType
10919 .substitute4(<DartType>[_typeProvider.dynamicType]),
10920 resultType);
10921 _listener.assertNoErrors();
10922 }
10923
10924 void test_visitListLiteral_nonEmpty() {
10925 // [0]
10926 Expression node = AstFactory.listLiteral([_resolvedInteger(0)]);
10927 DartType resultType = _analyze(node);
10928 _assertType2(
10929 _typeProvider.listType
10930 .substitute4(<DartType>[_typeProvider.dynamicType]),
10931 resultType);
10932 _listener.assertNoErrors();
10933 }
10934
10935 void test_visitMapLiteral_empty() {
10936 // {}
10937 Expression node = AstFactory.mapLiteral2();
10938 DartType resultType = _analyze(node);
10939 _assertType2(
10940 _typeProvider.mapType.substitute4(
10941 <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]),
10942 resultType);
10943 _listener.assertNoErrors();
10944 }
10945
10946 void test_visitMapLiteral_nonEmpty() {
10947 // {"k" : 0}
10948 Expression node = AstFactory
10949 .mapLiteral2([AstFactory.mapLiteralEntry("k", _resolvedInteger(0))]);
10950 DartType resultType = _analyze(node);
10951 _assertType2(
10952 _typeProvider.mapType.substitute4(
10953 <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]),
10954 resultType);
10955 _listener.assertNoErrors();
10956 }
10957
10958 void test_visitMethodInvocation_then() {
10959 // then()
10960 Expression node = AstFactory.methodInvocation(null, "then");
10961 _analyze(node);
10962 _listener.assertNoErrors();
10963 }
10964
10965 void test_visitNamedExpression() {
10966 // n: a
10967 Expression node = AstFactory.namedExpression2("n", _resolvedString("a"));
10968 expect(_analyze(node), same(_typeProvider.stringType));
10969 _listener.assertNoErrors();
10970 }
10971
10972 void test_visitNullLiteral() {
10973 // null
10974 Expression node = AstFactory.nullLiteral();
10975 expect(_analyze(node), same(_typeProvider.bottomType));
10976 _listener.assertNoErrors();
10977 }
10978
10979 void test_visitParenthesizedExpression() {
10980 // (0)
10981 Expression node = AstFactory.parenthesizedExpression(_resolvedInteger(0));
10982 expect(_analyze(node), same(_typeProvider.intType));
10983 _listener.assertNoErrors();
10984 }
10985
10986 void test_visitPostfixExpression_minusMinus() {
10987 // 0--
10988 PostfixExpression node = AstFactory.postfixExpression(
10989 _resolvedInteger(0), TokenType.MINUS_MINUS);
10990 expect(_analyze(node), same(_typeProvider.intType));
10991 _listener.assertNoErrors();
10992 }
10993
10994 void test_visitPostfixExpression_plusPlus() {
10995 // 0++
10996 PostfixExpression node =
10997 AstFactory.postfixExpression(_resolvedInteger(0), TokenType.PLUS_PLUS);
10998 expect(_analyze(node), same(_typeProvider.intType));
10999 _listener.assertNoErrors();
11000 }
11001
11002 void test_visitPrefixedIdentifier_getter() {
11003 DartType boolType = _typeProvider.boolType;
11004 PropertyAccessorElementImpl getter =
11005 ElementFactory.getterElement("b", false, boolType);
11006 PrefixedIdentifier node = AstFactory.identifier5("a", "b");
11007 node.identifier.staticElement = getter;
11008 expect(_analyze(node), same(boolType));
11009 _listener.assertNoErrors();
11010 }
11011
11012 void test_visitPrefixedIdentifier_setter() {
11013 DartType boolType = _typeProvider.boolType;
11014 FieldElementImpl field =
11015 ElementFactory.fieldElement("b", false, false, false, boolType);
11016 PropertyAccessorElement setter = field.setter;
11017 PrefixedIdentifier node = AstFactory.identifier5("a", "b");
11018 node.identifier.staticElement = setter;
11019 expect(_analyze(node), same(boolType));
11020 _listener.assertNoErrors();
11021 }
11022
11023 void test_visitPrefixedIdentifier_variable() {
11024 VariableElementImpl variable = ElementFactory.localVariableElement2("b");
11025 variable.type = _typeProvider.boolType;
11026 PrefixedIdentifier node = AstFactory.identifier5("a", "b");
11027 node.identifier.staticElement = variable;
11028 expect(_analyze(node), same(_typeProvider.boolType));
11029 _listener.assertNoErrors();
11030 }
11031
11032 void test_visitPrefixExpression_bang() {
11033 // !0
11034 PrefixExpression node =
11035 AstFactory.prefixExpression(TokenType.BANG, _resolvedInteger(0));
11036 expect(_analyze(node), same(_typeProvider.boolType));
11037 _listener.assertNoErrors();
11038 }
11039
11040 void test_visitPrefixExpression_minus() {
11041 // -0
11042 PrefixExpression node =
11043 AstFactory.prefixExpression(TokenType.MINUS, _resolvedInteger(0));
11044 MethodElement minusMethod = getMethod(_typeProvider.numType, "-");
11045 node.staticElement = minusMethod;
11046 expect(_analyze(node), same(_typeProvider.numType));
11047 _listener.assertNoErrors();
11048 }
11049
11050 void test_visitPrefixExpression_minusMinus() {
11051 // --0
11052 PrefixExpression node =
11053 AstFactory.prefixExpression(TokenType.MINUS_MINUS, _resolvedInteger(0));
11054 MethodElement minusMethod = getMethod(_typeProvider.numType, "-");
11055 node.staticElement = minusMethod;
11056 expect(_analyze(node), same(_typeProvider.intType));
11057 _listener.assertNoErrors();
11058 }
11059
11060 void test_visitPrefixExpression_not() {
11061 // !true
11062 Expression node = AstFactory.prefixExpression(
11063 TokenType.BANG, AstFactory.booleanLiteral(true));
11064 expect(_analyze(node), same(_typeProvider.boolType));
11065 _listener.assertNoErrors();
11066 }
11067
11068 void test_visitPrefixExpression_plusPlus() {
11069 // ++0
11070 PrefixExpression node =
11071 AstFactory.prefixExpression(TokenType.PLUS_PLUS, _resolvedInteger(0));
11072 MethodElement plusMethod = getMethod(_typeProvider.numType, "+");
11073 node.staticElement = plusMethod;
11074 expect(_analyze(node), same(_typeProvider.intType));
11075 _listener.assertNoErrors();
11076 }
11077
11078 void test_visitPrefixExpression_tilde() {
11079 // ~0
11080 PrefixExpression node =
11081 AstFactory.prefixExpression(TokenType.TILDE, _resolvedInteger(0));
11082 MethodElement tildeMethod = getMethod(_typeProvider.intType, "~");
11083 node.staticElement = tildeMethod;
11084 expect(_analyze(node), same(_typeProvider.intType));
11085 _listener.assertNoErrors();
11086 }
11087
11088 void test_visitPropertyAccess_propagated_getter() {
11089 DartType boolType = _typeProvider.boolType;
11090 PropertyAccessorElementImpl getter =
11091 ElementFactory.getterElement("b", false, boolType);
11092 PropertyAccess node =
11093 AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
11094 node.propertyName.propagatedElement = getter;
11095 expect(_analyze2(node, false), same(boolType));
11096 _listener.assertNoErrors();
11097 }
11098
11099 void test_visitPropertyAccess_propagated_setter() {
11100 DartType boolType = _typeProvider.boolType;
11101 FieldElementImpl field =
11102 ElementFactory.fieldElement("b", false, false, false, boolType);
11103 PropertyAccessorElement setter = field.setter;
11104 PropertyAccess node =
11105 AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
11106 node.propertyName.propagatedElement = setter;
11107 expect(_analyze2(node, false), same(boolType));
11108 _listener.assertNoErrors();
11109 }
11110
11111 void test_visitPropertyAccess_static_getter() {
11112 DartType boolType = _typeProvider.boolType;
11113 PropertyAccessorElementImpl getter =
11114 ElementFactory.getterElement("b", false, boolType);
11115 PropertyAccess node =
11116 AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
11117 node.propertyName.staticElement = getter;
11118 expect(_analyze(node), same(boolType));
11119 _listener.assertNoErrors();
11120 }
11121
11122 void test_visitPropertyAccess_static_setter() {
11123 DartType boolType = _typeProvider.boolType;
11124 FieldElementImpl field =
11125 ElementFactory.fieldElement("b", false, false, false, boolType);
11126 PropertyAccessorElement setter = field.setter;
11127 PropertyAccess node =
11128 AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
11129 node.propertyName.staticElement = setter;
11130 expect(_analyze(node), same(boolType));
11131 _listener.assertNoErrors();
11132 }
11133
11134 void test_visitSimpleIdentifier_dynamic() {
11135 // "dynamic"
11136 SimpleIdentifier identifier = AstFactory.identifier3('dynamic');
11137 DynamicElementImpl element = DynamicElementImpl.instance;
11138 identifier.staticElement = element;
11139 identifier.staticType = _typeProvider.typeType;
11140 expect(_analyze(identifier), same(_typeProvider.typeType));
11141 _listener.assertNoErrors();
11142 }
11143
11144 void test_visitSimpleStringLiteral() {
11145 // "a"
11146 Expression node = _resolvedString("a");
11147 expect(_analyze(node), same(_typeProvider.stringType));
11148 _listener.assertNoErrors();
11149 }
11150
11151 void test_visitStringInterpolation() {
11152 // "a${'b'}c"
11153 Expression node = AstFactory.string([
11154 AstFactory.interpolationString("a", "a"),
11155 AstFactory.interpolationExpression(_resolvedString("b")),
11156 AstFactory.interpolationString("c", "c")
11157 ]);
11158 expect(_analyze(node), same(_typeProvider.stringType));
11159 _listener.assertNoErrors();
11160 }
11161
11162 void test_visitSuperExpression() {
11163 // super
11164 InterfaceType superType = ElementFactory.classElement2("A").type;
11165 InterfaceType thisType = ElementFactory.classElement("B", superType).type;
11166 Expression node = AstFactory.superExpression();
11167 expect(_analyze3(node, thisType), same(thisType));
11168 _listener.assertNoErrors();
11169 }
11170
11171 void test_visitSymbolLiteral() {
11172 expect(_analyze(AstFactory.symbolLiteral(["a"])),
11173 same(_typeProvider.symbolType));
11174 }
11175
11176 void test_visitThisExpression() {
11177 // this
11178 InterfaceType thisType = ElementFactory
11179 .classElement("B", ElementFactory.classElement2("A").type)
11180 .type;
11181 Expression node = AstFactory.thisExpression();
11182 expect(_analyze3(node, thisType), same(thisType));
11183 _listener.assertNoErrors();
11184 }
11185
11186 void test_visitThrowExpression_withoutValue() {
11187 // throw
11188 Expression node = AstFactory.throwExpression();
11189 expect(_analyze(node), same(_typeProvider.bottomType));
11190 _listener.assertNoErrors();
11191 }
11192
11193 void test_visitThrowExpression_withValue() {
11194 // throw 0
11195 Expression node = AstFactory.throwExpression2(_resolvedInteger(0));
11196 expect(_analyze(node), same(_typeProvider.bottomType));
11197 _listener.assertNoErrors();
11198 }
11199
11200 /**
11201 * Return the type associated with the given expression after the static type analyzer has
11202 * computed a type for it.
11203 *
11204 * @param node the expression with which the type is associated
11205 * @return the type associated with the expression
11206 */
11207 DartType _analyze(Expression node) => _analyze4(node, null, true);
11208
11209 /**
11210 * Return the type associated with the given expression after the static or pr opagated type
11211 * analyzer has computed a type for it.
11212 *
11213 * @param node the expression with which the type is associated
11214 * @param useStaticType `true` if the static type is being requested, and `fal se` if
11215 * the propagated type is being requested
11216 * @return the type associated with the expression
11217 */
11218 DartType _analyze2(Expression node, bool useStaticType) =>
11219 _analyze4(node, null, useStaticType);
11220
11221 /**
11222 * Return the type associated with the given expression after the static type analyzer has
11223 * computed a type for it.
11224 *
11225 * @param node the expression with which the type is associated
11226 * @param thisType the type of 'this'
11227 * @return the type associated with the expression
11228 */
11229 DartType _analyze3(Expression node, InterfaceType thisType) =>
11230 _analyze4(node, thisType, true);
11231
11232 /**
11233 * Return the type associated with the given expression after the static type analyzer has
11234 * computed a type for it.
11235 *
11236 * @param node the expression with which the type is associated
11237 * @param thisType the type of 'this'
11238 * @param useStaticType `true` if the static type is being requested, and `fal se` if
11239 * the propagated type is being requested
11240 * @return the type associated with the expression
11241 */
11242 DartType _analyze4(
11243 Expression node, InterfaceType thisType, bool useStaticType) {
11244 try {
11245 _analyzer.thisType = thisType;
11246 } catch (exception) {
11247 throw new IllegalArgumentException(
11248 "Could not set type of 'this'", exception);
11249 }
11250 node.accept(_analyzer);
11251 if (useStaticType) {
11252 return node.staticType;
11253 } else {
11254 return node.propagatedType;
11255 }
11256 }
11257
11258 /**
11259 * Return the type associated with the given parameter after the static type a nalyzer has computed
11260 * a type for it.
11261 *
11262 * @param node the parameter with which the type is associated
11263 * @return the type associated with the parameter
11264 */
11265 DartType _analyze5(FormalParameter node) {
11266 node.accept(_analyzer);
11267 return (node.identifier.staticElement as ParameterElement).type;
11268 }
11269
11270 /**
11271 * Assert that the actual type is a function type with the expected characteri stics.
11272 *
11273 * @param expectedReturnType the expected return type of the function
11274 * @param expectedNormalTypes the expected types of the normal parameters
11275 * @param expectedOptionalTypes the expected types of the optional parameters
11276 * @param expectedNamedTypes the expected types of the named parameters
11277 * @param actualType the type being tested
11278 */
11279 void _assertFunctionType(
11280 DartType expectedReturnType,
11281 List<DartType> expectedNormalTypes,
11282 List<DartType> expectedOptionalTypes,
11283 Map<String, DartType> expectedNamedTypes,
11284 DartType actualType) {
11285 EngineTestCase.assertInstanceOf(
11286 (obj) => obj is FunctionType, FunctionType, actualType);
11287 FunctionType functionType = actualType as FunctionType;
11288 List<DartType> normalTypes = functionType.normalParameterTypes;
11289 if (expectedNormalTypes == null) {
11290 expect(normalTypes, hasLength(0));
11291 } else {
11292 int expectedCount = expectedNormalTypes.length;
11293 expect(normalTypes, hasLength(expectedCount));
11294 for (int i = 0; i < expectedCount; i++) {
11295 expect(normalTypes[i], same(expectedNormalTypes[i]));
11296 }
11297 }
11298 List<DartType> optionalTypes = functionType.optionalParameterTypes;
11299 if (expectedOptionalTypes == null) {
11300 expect(optionalTypes, hasLength(0));
11301 } else {
11302 int expectedCount = expectedOptionalTypes.length;
11303 expect(optionalTypes, hasLength(expectedCount));
11304 for (int i = 0; i < expectedCount; i++) {
11305 expect(optionalTypes[i], same(expectedOptionalTypes[i]));
11306 }
11307 }
11308 Map<String, DartType> namedTypes = functionType.namedParameterTypes;
11309 if (expectedNamedTypes == null) {
11310 expect(namedTypes, hasLength(0));
11311 } else {
11312 expect(namedTypes, hasLength(expectedNamedTypes.length));
11313 expectedNamedTypes.forEach((String name, DartType type) {
11314 expect(namedTypes[name], same(type));
11315 });
11316 }
11317 expect(functionType.returnType, equals(expectedReturnType));
11318 }
11319
11320 void _assertType(
11321 InterfaceTypeImpl expectedType, InterfaceTypeImpl actualType) {
11322 expect(actualType.displayName, expectedType.displayName);
11323 expect(actualType.element, expectedType.element);
11324 List<DartType> expectedArguments = expectedType.typeArguments;
11325 int length = expectedArguments.length;
11326 List<DartType> actualArguments = actualType.typeArguments;
11327 expect(actualArguments, hasLength(length));
11328 for (int i = 0; i < length; i++) {
11329 _assertType2(expectedArguments[i], actualArguments[i]);
11330 }
11331 }
11332
11333 void _assertType2(DartType expectedType, DartType actualType) {
11334 if (expectedType is InterfaceTypeImpl) {
11335 EngineTestCase.assertInstanceOf(
11336 (obj) => obj is InterfaceTypeImpl, InterfaceTypeImpl, actualType);
11337 _assertType(expectedType, actualType as InterfaceTypeImpl);
11338 }
11339 // TODO(brianwilkerson) Compare other kinds of types then make this a shared
11340 // utility method.
11341 }
11342
11343 /**
11344 * Create the analyzer used by the tests.
11345 *
11346 * @return the analyzer to be used by the tests
11347 */
11348 StaticTypeAnalyzer _createAnalyzer() {
11349 InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
11350 FileBasedSource source =
11351 new FileBasedSource(FileUtilities2.createFile("/lib.dart"));
11352 CompilationUnitElementImpl definingCompilationUnit =
11353 new CompilationUnitElementImpl("lib.dart");
11354 definingCompilationUnit.librarySource =
11355 definingCompilationUnit.source = source;
11356 LibraryElementImpl definingLibrary =
11357 new LibraryElementImpl.forNode(context, null);
11358 definingLibrary.definingCompilationUnit = definingCompilationUnit;
11359 Library library = new Library(context, _listener, source);
11360 library.libraryElement = definingLibrary;
11361 _visitor = new ResolverVisitor(
11362 library.libraryElement, source, _typeProvider, library.errorListener,
11363 nameScope: library.libraryScope,
11364 inheritanceManager: library.inheritanceManager);
11365 _visitor.overrideManager.enterScope();
11366 try {
11367 return _visitor.typeAnalyzer;
11368 } catch (exception) {
11369 throw new IllegalArgumentException(
11370 "Could not create analyzer", exception);
11371 }
11372 }
11373
11374 DartType _flatten(DartType type) =>
11375 StaticTypeAnalyzer.flattenFutures(_typeProvider, type);
11376
11377 /**
11378 * Return a simple identifier that has been resolved to a variable element wit h the given type.
11379 *
11380 * @param type the type of the variable being represented
11381 * @param variableName the name of the variable
11382 * @return a simple identifier that has been resolved to a variable element wi th the given type
11383 */
11384 SimpleIdentifier _propagatedVariable(
11385 InterfaceType type, String variableName) {
11386 SimpleIdentifier identifier = AstFactory.identifier3(variableName);
11387 VariableElementImpl element =
11388 ElementFactory.localVariableElement(identifier);
11389 element.type = type;
11390 identifier.staticType = _typeProvider.dynamicType;
11391 identifier.propagatedElement = element;
11392 identifier.propagatedType = type;
11393 return identifier;
11394 }
11395
11396 /**
11397 * Return an integer literal that has been resolved to the correct type.
11398 *
11399 * @param value the value of the literal
11400 * @return an integer literal that has been resolved to the correct type
11401 */
11402 DoubleLiteral _resolvedDouble(double value) {
11403 DoubleLiteral literal = AstFactory.doubleLiteral(value);
11404 literal.staticType = _typeProvider.doubleType;
11405 return literal;
11406 }
11407
11408 /**
11409 * Create a function expression that has an element associated with it, where the element has an
11410 * incomplete type associated with it (just like the one
11411 * [ElementBuilder.visitFunctionExpression] would have built if we had
11412 * run it).
11413 *
11414 * @param parameters the parameters to the function
11415 * @param body the body of the function
11416 * @return a resolved function expression
11417 */
11418 FunctionExpression _resolvedFunctionExpression(
11419 FormalParameterList parameters, FunctionBody body) {
11420 List<ParameterElement> parameterElements = new List<ParameterElement>();
11421 for (FormalParameter parameter in parameters.parameters) {
11422 ParameterElementImpl element =
11423 new ParameterElementImpl.forNode(parameter.identifier);
11424 element.parameterKind = parameter.kind;
11425 element.type = _typeProvider.dynamicType;
11426 parameter.identifier.staticElement = element;
11427 parameterElements.add(element);
11428 }
11429 FunctionExpression node = AstFactory.functionExpression2(parameters, body);
11430 FunctionElementImpl element = new FunctionElementImpl.forNode(null);
11431 element.parameters = parameterElements;
11432 element.type = new FunctionTypeImpl(element);
11433 node.element = element;
11434 return node;
11435 }
11436
11437 /**
11438 * Return an integer literal that has been resolved to the correct type.
11439 *
11440 * @param value the value of the literal
11441 * @return an integer literal that has been resolved to the correct type
11442 */
11443 IntegerLiteral _resolvedInteger(int value) {
11444 IntegerLiteral literal = AstFactory.integer(value);
11445 literal.staticType = _typeProvider.intType;
11446 return literal;
11447 }
11448
11449 /**
11450 * Return a string literal that has been resolved to the correct type.
11451 *
11452 * @param value the value of the literal
11453 * @return a string literal that has been resolved to the correct type
11454 */
11455 SimpleStringLiteral _resolvedString(String value) {
11456 SimpleStringLiteral string = AstFactory.string2(value);
11457 string.staticType = _typeProvider.stringType;
11458 return string;
11459 }
11460
11461 /**
11462 * Return a simple identifier that has been resolved to a variable element wit h the given type.
11463 *
11464 * @param type the type of the variable being represented
11465 * @param variableName the name of the variable
11466 * @return a simple identifier that has been resolved to a variable element wi th the given type
11467 */
11468 SimpleIdentifier _resolvedVariable(InterfaceType type, String variableName) {
11469 SimpleIdentifier identifier = AstFactory.identifier3(variableName);
11470 VariableElementImpl element =
11471 ElementFactory.localVariableElement(identifier);
11472 element.type = type;
11473 identifier.staticElement = element;
11474 identifier.staticType = type;
11475 return identifier;
11476 }
11477
11478 /**
11479 * Set the type of the given parameter to the given type.
11480 *
11481 * @param parameter the parameter whose type is to be set
11482 * @param type the new type of the given parameter
11483 */
11484 void _setType(FormalParameter parameter, DartType type) {
11485 SimpleIdentifier identifier = parameter.identifier;
11486 Element element = identifier.staticElement;
11487 if (element is! ParameterElement) {
11488 element = new ParameterElementImpl.forNode(identifier);
11489 identifier.staticElement = element;
11490 }
11491 (element as ParameterElementImpl).type = type;
11492 }
11493 }
11494
11495 /**
11496 * Instances of the class `StaticTypeVerifier` verify that all of the nodes in a n AST
11497 * structure that should have a static type associated with them do have a stati c type.
11498 */
11499 class StaticTypeVerifier extends GeneralizingAstVisitor<Object> {
11500 /**
11501 * A list containing all of the AST Expression nodes that were not resolved.
11502 */
11503 List<Expression> _unresolvedExpressions = new List<Expression>();
11504
11505 /**
11506 * A list containing all of the AST Expression nodes for which a propagated ty pe was computed but
11507 * where that type was not more specific than the static type.
11508 */
11509 List<Expression> _invalidlyPropagatedExpressions = new List<Expression>();
11510
11511 /**
11512 * A list containing all of the AST TypeName nodes that were not resolved.
11513 */
11514 List<TypeName> _unresolvedTypes = new List<TypeName>();
11515
11516 /**
11517 * Counter for the number of Expression nodes visited that are resolved.
11518 */
11519 int _resolvedExpressionCount = 0;
11520
11521 /**
11522 * Counter for the number of Expression nodes visited that have propagated typ e information.
11523 */
11524 int _propagatedExpressionCount = 0;
11525
11526 /**
11527 * Counter for the number of TypeName nodes visited that are resolved.
11528 */
11529 int _resolvedTypeCount = 0;
11530
11531 /**
11532 * Assert that all of the visited nodes have a static type associated with the m.
11533 */
11534 void assertResolved() {
11535 if (!_unresolvedExpressions.isEmpty || !_unresolvedTypes.isEmpty) {
11536 StringBuffer buffer = new StringBuffer();
11537 int unresolvedTypeCount = _unresolvedTypes.length;
11538 if (unresolvedTypeCount > 0) {
11539 buffer.write("Failed to resolve ");
11540 buffer.write(unresolvedTypeCount);
11541 buffer.write(" of ");
11542 buffer.write(_resolvedTypeCount + unresolvedTypeCount);
11543 buffer.writeln(" type names:");
11544 for (TypeName identifier in _unresolvedTypes) {
11545 buffer.write(" ");
11546 buffer.write(identifier.toString());
11547 buffer.write(" (");
11548 buffer.write(_getFileName(identifier));
11549 buffer.write(" : ");
11550 buffer.write(identifier.offset);
11551 buffer.writeln(")");
11552 }
11553 }
11554 int unresolvedExpressionCount = _unresolvedExpressions.length;
11555 if (unresolvedExpressionCount > 0) {
11556 buffer.writeln("Failed to resolve ");
11557 buffer.write(unresolvedExpressionCount);
11558 buffer.write(" of ");
11559 buffer.write(_resolvedExpressionCount + unresolvedExpressionCount);
11560 buffer.writeln(" expressions:");
11561 for (Expression expression in _unresolvedExpressions) {
11562 buffer.write(" ");
11563 buffer.write(expression.toString());
11564 buffer.write(" (");
11565 buffer.write(_getFileName(expression));
11566 buffer.write(" : ");
11567 buffer.write(expression.offset);
11568 buffer.writeln(")");
11569 }
11570 }
11571 int invalidlyPropagatedExpressionCount =
11572 _invalidlyPropagatedExpressions.length;
11573 if (invalidlyPropagatedExpressionCount > 0) {
11574 buffer.writeln("Incorrectly propagated ");
11575 buffer.write(invalidlyPropagatedExpressionCount);
11576 buffer.write(" of ");
11577 buffer.write(_propagatedExpressionCount);
11578 buffer.writeln(" expressions:");
11579 for (Expression expression in _invalidlyPropagatedExpressions) {
11580 buffer.write(" ");
11581 buffer.write(expression.toString());
11582 buffer.write(" [");
11583 buffer.write(expression.staticType.displayName);
11584 buffer.write(", ");
11585 buffer.write(expression.propagatedType.displayName);
11586 buffer.writeln("]");
11587 buffer.write(" ");
11588 buffer.write(_getFileName(expression));
11589 buffer.write(" : ");
11590 buffer.write(expression.offset);
11591 buffer.writeln(")");
11592 }
11593 }
11594 fail(buffer.toString());
11595 }
11596 }
11597
11598 @override
11599 Object visitBreakStatement(BreakStatement node) => null;
11600
11601 @override
11602 Object visitCommentReference(CommentReference node) => null;
11603
11604 @override
11605 Object visitContinueStatement(ContinueStatement node) => null;
11606
11607 @override
11608 Object visitExportDirective(ExportDirective node) => null;
11609
11610 @override
11611 Object visitExpression(Expression node) {
11612 node.visitChildren(this);
11613 DartType staticType = node.staticType;
11614 if (staticType == null) {
11615 _unresolvedExpressions.add(node);
11616 } else {
11617 _resolvedExpressionCount++;
11618 DartType propagatedType = node.propagatedType;
11619 if (propagatedType != null) {
11620 _propagatedExpressionCount++;
11621 if (!propagatedType.isMoreSpecificThan(staticType)) {
11622 _invalidlyPropagatedExpressions.add(node);
11623 }
11624 }
11625 }
11626 return null;
11627 }
11628
11629 @override
11630 Object visitImportDirective(ImportDirective node) => null;
11631
11632 @override
11633 Object visitLabel(Label node) => null;
11634
11635 @override
11636 Object visitLibraryIdentifier(LibraryIdentifier node) => null;
11637
11638 @override
11639 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
11640 // In cases where we have a prefixed identifier where the prefix is dynamic,
11641 // we don't want to assert that the node will have a type.
11642 if (node.staticType == null && node.prefix.staticType.isDynamic) {
11643 return null;
11644 }
11645 return super.visitPrefixedIdentifier(node);
11646 }
11647
11648 @override
11649 Object visitSimpleIdentifier(SimpleIdentifier node) {
11650 // In cases where identifiers are being used for something other than an
11651 // expressions, then they can be ignored.
11652 AstNode parent = node.parent;
11653 if (parent is MethodInvocation && identical(node, parent.methodName)) {
11654 return null;
11655 } else if (parent is RedirectingConstructorInvocation &&
11656 identical(node, parent.constructorName)) {
11657 return null;
11658 } else if (parent is SuperConstructorInvocation &&
11659 identical(node, parent.constructorName)) {
11660 return null;
11661 } else if (parent is ConstructorName && identical(node, parent.name)) {
11662 return null;
11663 } else if (parent is ConstructorFieldInitializer &&
11664 identical(node, parent.fieldName)) {
11665 return null;
11666 } else if (node.staticElement is PrefixElement) {
11667 // Prefixes don't have a type.
11668 return null;
11669 }
11670 return super.visitSimpleIdentifier(node);
11671 }
11672
11673 @override
11674 Object visitTypeName(TypeName node) {
11675 // Note: do not visit children from this node, the child SimpleIdentifier in
11676 // TypeName (i.e. "String") does not have a static type defined.
11677 if (node.type == null) {
11678 _unresolvedTypes.add(node);
11679 } else {
11680 _resolvedTypeCount++;
11681 }
11682 return null;
11683 }
11684
11685 String _getFileName(AstNode node) {
11686 // TODO (jwren) there are two copies of this method, one here and one in
11687 // ResolutionVerifier, they should be resolved into a single method
11688 if (node != null) {
11689 AstNode root = node.root;
11690 if (root is CompilationUnit) {
11691 CompilationUnit rootCU = root;
11692 if (rootCU.element != null) {
11693 return rootCU.element.source.fullName;
11694 } else {
11695 return "<unknown file- CompilationUnit.getElement() returned null>";
11696 }
11697 } else {
11698 return "<unknown file- CompilationUnit.getRoot() is not a CompilationUni t>";
11699 }
11700 }
11701 return "<unknown file- ASTNode is null>";
11702 }
11703 }
11704
11705 /**
11706 * The class `StrictModeTest` contains tests to ensure that the correct errors a nd warnings
11707 * are reported when the analysis engine is run in strict mode.
11708 */
11709 @reflectiveTest
11710 class StrictModeTest extends ResolverTestCase {
11711 void fail_for() {
11712 Source source = addSource(r'''
11713 int f(List<int> list) {
11714 num sum = 0;
11715 for (num i = 0; i < list.length; i++) {
11716 sum += list[i];
11717 }
11718 }''');
11719 computeLibrarySourceErrors(source);
11720 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11721 }
11722
11723 @override
11724 void setUp() {
11725 AnalysisOptionsImpl options = new AnalysisOptionsImpl();
11726 options.hint = false;
11727 resetWithOptions(options);
11728 }
11729
11730 void test_assert_is() {
11731 Source source = addSource(r'''
11732 int f(num n) {
11733 assert (n is int);
11734 return n & 0x0F;
11735 }''');
11736 computeLibrarySourceErrors(source);
11737 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11738 }
11739
11740 void test_conditional_and_is() {
11741 Source source = addSource(r'''
11742 int f(num n) {
11743 return (n is int && n > 0) ? n & 0x0F : 0;
11744 }''');
11745 computeLibrarySourceErrors(source);
11746 assertNoErrors(source);
11747 }
11748
11749 void test_conditional_is() {
11750 Source source = addSource(r'''
11751 int f(num n) {
11752 return (n is int) ? n & 0x0F : 0;
11753 }''');
11754 computeLibrarySourceErrors(source);
11755 assertNoErrors(source);
11756 }
11757
11758 void test_conditional_isNot() {
11759 Source source = addSource(r'''
11760 int f(num n) {
11761 return (n is! int) ? 0 : n & 0x0F;
11762 }''');
11763 computeLibrarySourceErrors(source);
11764 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11765 }
11766
11767 void test_conditional_or_is() {
11768 Source source = addSource(r'''
11769 int f(num n) {
11770 return (n is! int || n < 0) ? 0 : n & 0x0F;
11771 }''');
11772 computeLibrarySourceErrors(source);
11773 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11774 }
11775
11776 void test_forEach() {
11777 Source source = addSource(r'''
11778 int f(List<int> list) {
11779 num sum = 0;
11780 for (num n in list) {
11781 sum += n & 0x0F;
11782 }
11783 }''');
11784 computeLibrarySourceErrors(source);
11785 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11786 }
11787
11788 void test_if_and_is() {
11789 Source source = addSource(r'''
11790 int f(num n) {
11791 if (n is int && n > 0) {
11792 return n & 0x0F;
11793 }
11794 return 0;
11795 }''');
11796 computeLibrarySourceErrors(source);
11797 assertNoErrors(source);
11798 }
11799
11800 void test_if_is() {
11801 Source source = addSource(r'''
11802 int f(num n) {
11803 if (n is int) {
11804 return n & 0x0F;
11805 }
11806 return 0;
11807 }''');
11808 computeLibrarySourceErrors(source);
11809 assertNoErrors(source);
11810 }
11811
11812 void test_if_isNot() {
11813 Source source = addSource(r'''
11814 int f(num n) {
11815 if (n is! int) {
11816 return 0;
11817 } else {
11818 return n & 0x0F;
11819 }
11820 }''');
11821 computeLibrarySourceErrors(source);
11822 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11823 }
11824
11825 void test_if_isNot_abrupt() {
11826 Source source = addSource(r'''
11827 int f(num n) {
11828 if (n is! int) {
11829 return 0;
11830 }
11831 return n & 0x0F;
11832 }''');
11833 computeLibrarySourceErrors(source);
11834 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11835 }
11836
11837 void test_if_or_is() {
11838 Source source = addSource(r'''
11839 int f(num n) {
11840 if (n is! int || n < 0) {
11841 return 0;
11842 } else {
11843 return n & 0x0F;
11844 }
11845 }''');
11846 computeLibrarySourceErrors(source);
11847 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11848 }
11849
11850 void test_localVar() {
11851 Source source = addSource(r'''
11852 int f() {
11853 num n = 1234;
11854 return n & 0x0F;
11855 }''');
11856 computeLibrarySourceErrors(source);
11857 assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
11858 }
11859 }
11860
11861 @reflectiveTest
11862 class SubtypeManagerTest extends EngineTestCase {
11863 /**
11864 * The inheritance manager being tested.
11865 */
11866 SubtypeManager _subtypeManager;
11867
11868 /**
11869 * The compilation unit element containing all of the types setup in each test .
11870 */
11871 CompilationUnitElementImpl _definingCompilationUnit;
11872
11873 @override
11874 void setUp() {
11875 super.setUp();
11876 AnalysisContext context = AnalysisContextFactory.contextWithCore();
11877 FileBasedSource source =
11878 new FileBasedSource(FileUtilities2.createFile("/test.dart"));
11879 _definingCompilationUnit = new CompilationUnitElementImpl("test.dart");
11880 _definingCompilationUnit.librarySource =
11881 _definingCompilationUnit.source = source;
11882 LibraryElementImpl definingLibrary =
11883 ElementFactory.library(context, "test");
11884 definingLibrary.definingCompilationUnit = _definingCompilationUnit;
11885 _subtypeManager = new SubtypeManager();
11886 }
11887
11888 void test_computeAllSubtypes_infiniteLoop() {
11889 //
11890 // class A extends B
11891 // class B extends A
11892 //
11893 ClassElementImpl classA = ElementFactory.classElement2("A");
11894 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
11895 classA.supertype = classB.type;
11896 _definingCompilationUnit.types = <ClassElement>[classA, classB];
11897 HashSet<ClassElement> subtypesOfA =
11898 _subtypeManager.computeAllSubtypes(classA);
11899 List<ClassElement> arraySubtypesOfA = new List.from(subtypesOfA);
11900 expect(subtypesOfA, hasLength(2));
11901 expect(arraySubtypesOfA, unorderedEquals([classA, classB]));
11902 }
11903
11904 void test_computeAllSubtypes_manyRecursiveSubtypes() {
11905 //
11906 // class A
11907 // class B extends A
11908 // class C extends B
11909 // class D extends B
11910 // class E extends B
11911 //
11912 ClassElementImpl classA = ElementFactory.classElement2("A");
11913 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
11914 ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
11915 ClassElementImpl classD = ElementFactory.classElement("D", classB.type);
11916 ClassElementImpl classE = ElementFactory.classElement("E", classB.type);
11917 _definingCompilationUnit.types = <ClassElement>[
11918 classA,
11919 classB,
11920 classC,
11921 classD,
11922 classE
11923 ];
11924 HashSet<ClassElement> subtypesOfA =
11925 _subtypeManager.computeAllSubtypes(classA);
11926 List<ClassElement> arraySubtypesOfA = new List.from(subtypesOfA);
11927 HashSet<ClassElement> subtypesOfB =
11928 _subtypeManager.computeAllSubtypes(classB);
11929 List<ClassElement> arraySubtypesOfB = new List.from(subtypesOfB);
11930 expect(subtypesOfA, hasLength(4));
11931 expect(arraySubtypesOfA, unorderedEquals([classB, classC, classD, classE]));
11932 expect(subtypesOfB, hasLength(3));
11933 expect(arraySubtypesOfB, unorderedEquals([classC, classD, classE]));
11934 }
11935
11936 void test_computeAllSubtypes_noSubtypes() {
11937 //
11938 // class A
11939 //
11940 ClassElementImpl classA = ElementFactory.classElement2("A");
11941 _definingCompilationUnit.types = <ClassElement>[classA];
11942 HashSet<ClassElement> subtypesOfA =
11943 _subtypeManager.computeAllSubtypes(classA);
11944 expect(subtypesOfA, hasLength(0));
11945 }
11946
11947 void test_computeAllSubtypes_oneSubtype() {
11948 //
11949 // class A
11950 // class B extends A
11951 //
11952 ClassElementImpl classA = ElementFactory.classElement2("A");
11953 ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
11954 _definingCompilationUnit.types = <ClassElement>[classA, classB];
11955 HashSet<ClassElement> subtypesOfA =
11956 _subtypeManager.computeAllSubtypes(classA);
11957 List<ClassElement> arraySubtypesOfA = new List.from(subtypesOfA);
11958 expect(subtypesOfA, hasLength(1));
11959 expect(arraySubtypesOfA, unorderedEquals([classB]));
11960 }
11961 }
11962
11963 @reflectiveTest
11964 class TypeOverrideManagerTest extends EngineTestCase {
11965 void test_exitScope_noScopes() {
11966 TypeOverrideManager manager = new TypeOverrideManager();
11967 try {
11968 manager.exitScope();
11969 fail("Expected IllegalStateException");
11970 } on IllegalStateException {
11971 // Expected
11972 }
11973 }
11974
11975 void test_exitScope_oneScope() {
11976 TypeOverrideManager manager = new TypeOverrideManager();
11977 manager.enterScope();
11978 manager.exitScope();
11979 try {
11980 manager.exitScope();
11981 fail("Expected IllegalStateException");
11982 } on IllegalStateException {
11983 // Expected
11984 }
11985 }
11986
11987 void test_exitScope_twoScopes() {
11988 TypeOverrideManager manager = new TypeOverrideManager();
11989 manager.enterScope();
11990 manager.exitScope();
11991 manager.enterScope();
11992 manager.exitScope();
11993 try {
11994 manager.exitScope();
11995 fail("Expected IllegalStateException");
11996 } on IllegalStateException {
11997 // Expected
11998 }
11999 }
12000
12001 void test_getType_enclosedOverride() {
12002 TypeOverrideManager manager = new TypeOverrideManager();
12003 LocalVariableElementImpl element =
12004 ElementFactory.localVariableElement2("v");
12005 InterfaceType type = ElementFactory.classElement2("C").type;
12006 manager.enterScope();
12007 manager.setType(element, type);
12008 manager.enterScope();
12009 expect(manager.getType(element), same(type));
12010 }
12011
12012 void test_getType_immediateOverride() {
12013 TypeOverrideManager manager = new TypeOverrideManager();
12014 LocalVariableElementImpl element =
12015 ElementFactory.localVariableElement2("v");
12016 InterfaceType type = ElementFactory.classElement2("C").type;
12017 manager.enterScope();
12018 manager.setType(element, type);
12019 expect(manager.getType(element), same(type));
12020 }
12021
12022 void test_getType_noOverride() {
12023 TypeOverrideManager manager = new TypeOverrideManager();
12024 manager.enterScope();
12025 expect(manager.getType(ElementFactory.localVariableElement2("v")), isNull);
12026 }
12027
12028 void test_getType_noScope() {
12029 TypeOverrideManager manager = new TypeOverrideManager();
12030 expect(manager.getType(ElementFactory.localVariableElement2("v")), isNull);
12031 }
12032 }
12033
12034 @reflectiveTest
12035 class TypePropagationTest extends ResolverTestCase {
12036 void fail_finalPropertyInducingVariable_classMember_instance() {
12037 addNamedSource(
12038 "/lib.dart",
12039 r'''
12040 class A {
12041 final v = 0;
12042 }''');
12043 String code = r'''
12044 import 'lib.dart';
12045 f(A a) {
12046 return a.v; // marker
12047 }''';
12048 _assertTypeOfMarkedExpression(
12049 code, typeProvider.dynamicType, typeProvider.intType);
12050 }
12051
12052 void fail_finalPropertyInducingVariable_classMember_instance_inherited() {
12053 addNamedSource(
12054 "/lib.dart",
12055 r'''
12056 class A {
12057 final v = 0;
12058 }''');
12059 String code = r'''
12060 import 'lib.dart';
12061 class B extends A {
12062 m() {
12063 return v; // marker
12064 }
12065 }''';
12066 _assertTypeOfMarkedExpression(
12067 code, typeProvider.dynamicType, typeProvider.intType);
12068 }
12069
12070 void fail_finalPropertyInducingVariable_classMember_instance_propagatedTarget( ) {
12071 addNamedSource(
12072 "/lib.dart",
12073 r'''
12074 class A {
12075 final v = 0;
12076 }''');
12077 String code = r'''
12078 import 'lib.dart';
12079 f(p) {
12080 if (p is A) {
12081 return p.v; // marker
12082 }
12083 }''';
12084 _assertTypeOfMarkedExpression(
12085 code, typeProvider.dynamicType, typeProvider.intType);
12086 }
12087
12088 void fail_finalPropertyInducingVariable_classMember_static() {
12089 addNamedSource(
12090 "/lib.dart",
12091 r'''
12092 class A {
12093 static final V = 0;
12094 }''');
12095 String code = r'''
12096 import 'lib.dart';
12097 f() {
12098 return A.V; // marker
12099 }''';
12100 _assertTypeOfMarkedExpression(
12101 code, typeProvider.dynamicType, typeProvider.intType);
12102 }
12103
12104 void fail_finalPropertyInducingVariable_topLevelVaraible_prefixed() {
12105 addNamedSource("/lib.dart", "final V = 0;");
12106 String code = r'''
12107 import 'lib.dart' as p;
12108 f() {
12109 var v2 = p.V; // marker prefixed
12110 }''';
12111 _assertTypeOfMarkedExpression(
12112 code, typeProvider.dynamicType, typeProvider.intType);
12113 }
12114
12115 void fail_finalPropertyInducingVariable_topLevelVaraible_simple() {
12116 addNamedSource("/lib.dart", "final V = 0;");
12117 String code = r'''
12118 import 'lib.dart';
12119 f() {
12120 return V; // marker simple
12121 }''';
12122 _assertTypeOfMarkedExpression(
12123 code, typeProvider.dynamicType, typeProvider.intType);
12124 }
12125
12126 void fail_mergePropagatedTypesAtJoinPoint_1() {
12127 // https://code.google.com/p/dart/issues/detail?id=19929
12128 _assertTypeOfMarkedExpression(
12129 r'''
12130 f1(x) {
12131 var y = [];
12132 if (x) {
12133 y = 0;
12134 } else {
12135 y = '';
12136 }
12137 // Propagated type is [List] here: incorrect.
12138 // Best we can do is [Object]?
12139 return y; // marker
12140 }''',
12141 null,
12142 typeProvider.dynamicType);
12143 }
12144
12145 void fail_mergePropagatedTypesAtJoinPoint_2() {
12146 // https://code.google.com/p/dart/issues/detail?id=19929
12147 _assertTypeOfMarkedExpression(
12148 r'''
12149 f2(x) {
12150 var y = [];
12151 if (x) {
12152 y = 0;
12153 } else {
12154 }
12155 // Propagated type is [List] here: incorrect.
12156 // Best we can do is [Object]?
12157 return y; // marker
12158 }''',
12159 null,
12160 typeProvider.dynamicType);
12161 }
12162
12163 void fail_mergePropagatedTypesAtJoinPoint_3() {
12164 // https://code.google.com/p/dart/issues/detail?id=19929
12165 _assertTypeOfMarkedExpression(
12166 r'''
12167 f4(x) {
12168 var y = [];
12169 if (x) {
12170 y = 0;
12171 } else {
12172 y = 1.5;
12173 }
12174 // Propagated type is [List] here: incorrect.
12175 // A correct answer is the least upper bound of [int] and [double],
12176 // i.e. [num].
12177 return y; // marker
12178 }''',
12179 null,
12180 typeProvider.numType);
12181 }
12182
12183 void fail_mergePropagatedTypesAtJoinPoint_5() {
12184 // https://code.google.com/p/dart/issues/detail?id=19929
12185 _assertTypeOfMarkedExpression(
12186 r'''
12187 f6(x,y) {
12188 var z = [];
12189 if (x || (z = y) < 0) {
12190 } else {
12191 z = 0;
12192 }
12193 // Propagated type is [List] here: incorrect.
12194 // Best we can do is [Object]?
12195 return z; // marker
12196 }''',
12197 null,
12198 typeProvider.dynamicType);
12199 }
12200
12201 void fail_mergePropagatedTypesAtJoinPoint_7() {
12202 // https://code.google.com/p/dart/issues/detail?id=19929
12203 //
12204 // In general [continue]s are unsafe for the purposes of
12205 // [isAbruptTerminationStatement].
12206 //
12207 // This is like example 6, but less tricky: the code in the branch that
12208 // [continue]s is in effect after the [if].
12209 String code = r'''
12210 f() {
12211 var x = 0;
12212 var c = false;
12213 var d = true;
12214 while (d) {
12215 if (c) {
12216 d = false;
12217 } else {
12218 x = '';
12219 c = true;
12220 continue;
12221 }
12222 x; // marker
12223 }
12224 }''';
12225 DartType t = _findMarkedIdentifier(code, "; // marker").propagatedType;
12226 expect(typeProvider.intType.isSubtypeOf(t), isTrue);
12227 expect(typeProvider.stringType.isSubtypeOf(t), isTrue);
12228 }
12229
12230 void fail_mergePropagatedTypesAtJoinPoint_8() {
12231 // https://code.google.com/p/dart/issues/detail?id=19929
12232 //
12233 // In nested loops [breaks]s are unsafe for the purposes of
12234 // [isAbruptTerminationStatement].
12235 //
12236 // This is a combination of 6 and 7: we use an unlabeled [break]
12237 // like a continue for the outer loop / like a labeled [break] to
12238 // jump just above the [if].
12239 String code = r'''
12240 f() {
12241 var x = 0;
12242 var c = false;
12243 var d = true;
12244 while (d) {
12245 while (d) {
12246 if (c) {
12247 d = false;
12248 } else {
12249 x = '';
12250 c = true;
12251 break;
12252 }
12253 x; // marker
12254 }
12255 }
12256 }''';
12257 DartType t = _findMarkedIdentifier(code, "; // marker").propagatedType;
12258 expect(typeProvider.intType.isSubtypeOf(t), isTrue);
12259 expect(typeProvider.stringType.isSubtypeOf(t), isTrue);
12260 }
12261
12262 void fail_propagatedReturnType_functionExpression() {
12263 // TODO(scheglov) disabled because we don't resolve function expression
12264 String code = r'''
12265 main() {
12266 var v = (() {return 42;})();
12267 }''';
12268 _assertPropagatedAssignedType(
12269 code, typeProvider.dynamicType, typeProvider.intType);
12270 }
12271
12272 void test_as() {
12273 Source source = addSource(r'''
12274 class A {
12275 bool get g => true;
12276 }
12277 A f(var p) {
12278 if ((p as A).g) {
12279 return p;
12280 } else {
12281 return null;
12282 }
12283 }''');
12284 LibraryElement library = resolve2(source);
12285 assertNoErrors(source);
12286 verify([source]);
12287 CompilationUnit unit = resolveCompilationUnit(source, library);
12288 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
12289 InterfaceType typeA = classA.element.type;
12290 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
12291 BlockFunctionBody body =
12292 function.functionExpression.body as BlockFunctionBody;
12293 IfStatement ifStatement = body.block.statements[0] as IfStatement;
12294 ReturnStatement statement =
12295 (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
12296 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
12297 expect(variableName.propagatedType, same(typeA));
12298 }
12299
12300 void test_assert() {
12301 Source source = addSource(r'''
12302 class A {}
12303 A f(var p) {
12304 assert (p is A);
12305 return p;
12306 }''');
12307 LibraryElement library = resolve2(source);
12308 assertNoErrors(source);
12309 verify([source]);
12310 CompilationUnit unit = resolveCompilationUnit(source, library);
12311 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
12312 InterfaceType typeA = classA.element.type;
12313 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
12314 BlockFunctionBody body =
12315 function.functionExpression.body as BlockFunctionBody;
12316 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
12317 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
12318 expect(variableName.propagatedType, same(typeA));
12319 }
12320
12321 void test_assignment() {
12322 Source source = addSource(r'''
12323 f() {
12324 var v;
12325 v = 0;
12326 return v;
12327 }''');
12328 LibraryElement library = resolve2(source);
12329 assertNoErrors(source);
12330 verify([source]);
12331 CompilationUnit unit = resolveCompilationUnit(source, library);
12332 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
12333 BlockFunctionBody body =
12334 function.functionExpression.body as BlockFunctionBody;
12335 ReturnStatement statement = body.block.statements[2] as ReturnStatement;
12336 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
12337 expect(variableName.propagatedType, same(typeProvider.intType));
12338 }
12339
12340 void test_assignment_afterInitializer() {
12341 Source source = addSource(r'''
12342 f() {
12343 var v = 0;
12344 v = 1.0;
12345 return v;
12346 }''');
12347 LibraryElement library = resolve2(source);
12348 assertNoErrors(source);
12349 verify([source]);
12350 CompilationUnit unit = resolveCompilationUnit(source, library);
12351 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
12352 BlockFunctionBody body =
12353 function.functionExpression.body as BlockFunctionBody;
12354 ReturnStatement statement = body.block.statements[2] as ReturnStatement;
12355 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
12356 expect(variableName.propagatedType, same(typeProvider.doubleType));
12357 }
12358
12359 void test_assignment_null() {
12360 String code = r'''
12361 main() {
12362 int v; // declare
12363 v = null;
12364 return v; // return
12365 }''';
12366 CompilationUnit unit;
12367 {
12368 Source source = addSource(code);
12369 LibraryElement library = resolve2(source);
12370 assertNoErrors(source);
12371 verify([source]);
12372 unit = resolveCompilationUnit(source, library);
12373 }
12374 {
12375 SimpleIdentifier identifier = EngineTestCase.findNode(
12376 unit, code, "v; // declare", (node) => node is SimpleIdentifier);
12377 expect(identifier.staticType, same(typeProvider.intType));
12378 expect(identifier.propagatedType, same(null));
12379 }
12380 {
12381 SimpleIdentifier identifier = EngineTestCase.findNode(
12382 unit, code, "v = null;", (node) => node is SimpleIdentifier);
12383 expect(identifier.staticType, same(typeProvider.intType));
12384 expect(identifier.propagatedType, same(null));
12385 }
12386 {
12387 SimpleIdentifier identifier = EngineTestCase.findNode(
12388 unit, code, "v; // return", (node) => node is SimpleIdentifier);
12389 expect(identifier.staticType, same(typeProvider.intType));
12390 expect(identifier.propagatedType, same(null));
12391 }
12392 }
12393
12394 void test_CanvasElement_getContext() {
12395 String code = r'''
12396 import 'dart:html';
12397 main(CanvasElement canvas) {
12398 var context = canvas.getContext('2d');
12399 }''';
12400 Source source = addSource(code);
12401 LibraryElement library = resolve2(source);
12402 assertNoErrors(source);
12403 verify([source]);
12404 CompilationUnit unit = resolveCompilationUnit(source, library);
12405 SimpleIdentifier identifier = EngineTestCase.findNode(
12406 unit, code, "context", (node) => node is SimpleIdentifier);
12407 expect(identifier.propagatedType.name, "CanvasRenderingContext2D");
12408 }
12409
12410 void test_forEach() {
12411 String code = r'''
12412 main() {
12413 var list = <String> [];
12414 for (var e in list) {
12415 e;
12416 }
12417 }''';
12418 Source source = addSource(code);
12419 LibraryElement library = resolve2(source);
12420 assertNoErrors(source);
12421 verify([source]);
12422 CompilationUnit unit = resolveCompilationUnit(source, library);
12423 InterfaceType stringType = typeProvider.stringType;
12424 // in the declaration
12425 {
12426 SimpleIdentifier identifier = EngineTestCase.findNode(
12427 unit, code, "e in", (node) => node is SimpleIdentifier);
12428 expect(identifier.propagatedType, same(stringType));
12429 }
12430 // in the loop body
12431 {
12432 SimpleIdentifier identifier = EngineTestCase.findNode(
12433 unit, code, "e;", (node) => node is SimpleIdentifier);
12434 expect(identifier.propagatedType, same(stringType));
12435 }
12436 }
12437
12438 void test_forEach_async() {
12439 String code = r'''
12440 import 'dart:async';
12441 f(Stream<String> stream) async {
12442 await for (var e in stream) {
12443 e;
12444 }
12445 }''';
12446 Source source = addSource(code);
12447 LibraryElement library = resolve2(source);
12448 assertNoErrors(source);
12449 verify([source]);
12450 CompilationUnit unit = resolveCompilationUnit(source, library);
12451 InterfaceType stringType = typeProvider.stringType;
12452 // in the declaration
12453 {
12454 SimpleIdentifier identifier = EngineTestCase.findNode(
12455 unit, code, "e in", (node) => node is SimpleIdentifier);
12456 expect(identifier.propagatedType, same(stringType));
12457 }
12458 // in the loop body
12459 {
12460 SimpleIdentifier identifier = EngineTestCase.findNode(
12461 unit, code, "e;", (node) => node is SimpleIdentifier);
12462 expect(identifier.propagatedType, same(stringType));
12463 }
12464 }
12465
12466 void test_functionExpression_asInvocationArgument() {
12467 String code = r'''
12468 class MyMap<K, V> {
12469 forEach(f(K key, V value)) {}
12470 }
12471 f(MyMap<int, String> m) {
12472 m.forEach((k, v) {
12473 k;
12474 v;
12475 });
12476 }''';
12477 Source source = addSource(code);
12478 LibraryElement library = resolve2(source);
12479 assertNoErrors(source);
12480 verify([source]);
12481 CompilationUnit unit = resolveCompilationUnit(source, library);
12482 // k
12483 DartType intType = typeProvider.intType;
12484 FormalParameter kParameter = EngineTestCase.findNode(
12485 unit, code, "k, ", (node) => node is SimpleFormalParameter);
12486 expect(kParameter.identifier.propagatedType, same(intType));
12487 SimpleIdentifier kIdentifier = EngineTestCase.findNode(
12488 unit, code, "k;", (node) => node is SimpleIdentifier);
12489 expect(kIdentifier.propagatedType, same(intType));
12490 expect(kIdentifier.staticType, same(typeProvider.dynamicType));
12491 // v
12492 DartType stringType = typeProvider.stringType;
12493 FormalParameter vParameter = EngineTestCase.findNode(
12494 unit, code, "v)", (node) => node is SimpleFormalParameter);
12495 expect(vParameter.identifier.propagatedType, same(stringType));
12496 SimpleIdentifier vIdentifier = EngineTestCase.findNode(
12497 unit, code, "v;", (node) => node is SimpleIdentifier);
12498 expect(vIdentifier.propagatedType, same(stringType));
12499 expect(vIdentifier.staticType, same(typeProvider.dynamicType));
12500 }
12501
12502 void test_functionExpression_asInvocationArgument_fromInferredInvocation() {
12503 String code = r'''
12504 class MyMap<K, V> {
12505 forEach(f(K key, V value)) {}
12506 }
12507 f(MyMap<int, String> m) {
12508 var m2 = m;
12509 m2.forEach((k, v) {});
12510 }''';
12511 Source source = addSource(code);
12512 LibraryElement library = resolve2(source);
12513 assertNoErrors(source);
12514 verify([source]);
12515 CompilationUnit unit = resolveCompilationUnit(source, library);
12516 // k
12517 DartType intType = typeProvider.intType;
12518 FormalParameter kParameter = EngineTestCase.findNode(
12519 unit, code, "k, ", (node) => node is SimpleFormalParameter);
12520 expect(kParameter.identifier.propagatedType, same(intType));
12521 // v
12522 DartType stringType = typeProvider.stringType;
12523 FormalParameter vParameter = EngineTestCase.findNode(
12524 unit, code, "v)", (node) => node is SimpleFormalParameter);
12525 expect(vParameter.identifier.propagatedType, same(stringType));
12526 }
12527
12528 void test_functionExpression_asInvocationArgument_functionExpressionInvocation () {
12529 String code = r'''
12530 main() {
12531 (f(String value)) {} ((v) {
12532 v;
12533 });
12534 }''';
12535 Source source = addSource(code);
12536 LibraryElement library = resolve2(source);
12537 assertNoErrors(source);
12538 verify([source]);
12539 CompilationUnit unit = resolveCompilationUnit(source, library);
12540 // v
12541 DartType dynamicType = typeProvider.dynamicType;
12542 DartType stringType = typeProvider.stringType;
12543 FormalParameter vParameter = EngineTestCase.findNode(
12544 unit, code, "v)", (node) => node is FormalParameter);
12545 expect(vParameter.identifier.propagatedType, same(stringType));
12546 expect(vParameter.identifier.staticType, same(dynamicType));
12547 SimpleIdentifier vIdentifier = EngineTestCase.findNode(
12548 unit, code, "v;", (node) => node is SimpleIdentifier);
12549 expect(vIdentifier.propagatedType, same(stringType));
12550 expect(vIdentifier.staticType, same(dynamicType));
12551 }
12552
12553 void test_functionExpression_asInvocationArgument_keepIfLessSpecific() {
12554 String code = r'''
12555 class MyList {
12556 forEach(f(Object value)) {}
12557 }
12558 f(MyList list) {
12559 list.forEach((int v) {
12560 v;
12561 });
12562 }''';
12563 Source source = addSource(code);
12564 LibraryElement library = resolve2(source);
12565 assertNoErrors(source);
12566 verify([source]);
12567 CompilationUnit unit = resolveCompilationUnit(source, library);
12568 // v
12569 DartType intType = typeProvider.intType;
12570 FormalParameter vParameter = EngineTestCase.findNode(
12571 unit, code, "v)", (node) => node is SimpleFormalParameter);
12572 expect(vParameter.identifier.propagatedType, same(null));
12573 expect(vParameter.identifier.staticType, same(intType));
12574 SimpleIdentifier vIdentifier = EngineTestCase.findNode(
12575 unit, code, "v;", (node) => node is SimpleIdentifier);
12576 expect(vIdentifier.staticType, same(intType));
12577 expect(vIdentifier.propagatedType, same(null));
12578 }
12579
12580 void test_functionExpression_asInvocationArgument_notSubtypeOfStaticType() {
12581 String code = r'''
12582 class A {
12583 m(void f(int i)) {}
12584 }
12585 x() {
12586 A a = new A();
12587 a.m(() => 0);
12588 }''';
12589 Source source = addSource(code);
12590 LibraryElement library = resolve2(source);
12591 assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
12592 verify([source]);
12593 CompilationUnit unit = resolveCompilationUnit(source, library);
12594 // () => 0
12595 FunctionExpression functionExpression = EngineTestCase.findNode(
12596 unit, code, "() => 0)", (node) => node is FunctionExpression);
12597 expect((functionExpression.staticType as FunctionType).parameters.length,
12598 same(0));
12599 expect(functionExpression.propagatedType, same(null));
12600 }
12601
12602 void test_functionExpression_asInvocationArgument_replaceIfMoreSpecific() {
12603 String code = r'''
12604 class MyList<E> {
12605 forEach(f(E value)) {}
12606 }
12607 f(MyList<String> list) {
12608 list.forEach((Object v) {
12609 v;
12610 });
12611 }''';
12612 Source source = addSource(code);
12613 LibraryElement library = resolve2(source);
12614 assertNoErrors(source);
12615 verify([source]);
12616 CompilationUnit unit = resolveCompilationUnit(source, library);
12617 // v
12618 DartType stringType = typeProvider.stringType;
12619 FormalParameter vParameter = EngineTestCase.findNode(
12620 unit, code, "v)", (node) => node is SimpleFormalParameter);
12621 expect(vParameter.identifier.propagatedType, same(stringType));
12622 expect(vParameter.identifier.staticType, same(typeProvider.objectType));
12623 SimpleIdentifier vIdentifier = EngineTestCase.findNode(
12624 unit, code, "v;", (node) => node is SimpleIdentifier);
12625 expect(vIdentifier.propagatedType, same(stringType));
12626 }
12627
12628 void test_Future_then() {
12629 String code = r'''
12630 import 'dart:async';
12631 main(Future<int> firstFuture) {
12632 firstFuture.then((p1) {
12633 return 1.0;
12634 }).then((p2) {
12635 return new Future<String>.value('str');
12636 }).then((p3) {
12637 });
12638 }''';
12639 Source source = addSource(code);
12640 LibraryElement library = resolve2(source);
12641 assertNoErrors(source);
12642 verify([source]);
12643 CompilationUnit unit = resolveCompilationUnit(source, library);
12644 // p1
12645 FormalParameter p1 = EngineTestCase.findNode(
12646 unit, code, "p1) {", (node) => node is SimpleFormalParameter);
12647 expect(p1.identifier.propagatedType, same(typeProvider.intType));
12648 // p2
12649 FormalParameter p2 = EngineTestCase.findNode(
12650 unit, code, "p2) {", (node) => node is SimpleFormalParameter);
12651 expect(p2.identifier.propagatedType, same(typeProvider.doubleType));
12652 // p3
12653 FormalParameter p3 = EngineTestCase.findNode(
12654 unit, code, "p3) {", (node) => node is SimpleFormalParameter);
12655 expect(p3.identifier.propagatedType, same(typeProvider.stringType));
12656 }
12657
12658 void test_initializer() {
12659 Source source = addSource(r'''
12660 f() {
12661 var v = 0;
12662 return v;
12663 }''');
12664 LibraryElement library = resolve2(source);
12665 assertNoErrors(source);
12666 verify([source]);
12667 CompilationUnit unit = resolveCompilationUnit(source, library);
12668 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
12669 BlockFunctionBody body =
12670 function.functionExpression.body as BlockFunctionBody;
12671 NodeList<Statement> statements = body.block.statements;
12672 // Type of 'v' in declaration.
12673 {
12674 VariableDeclarationStatement statement =
12675 statements[0] as VariableDeclarationStatement;
12676 SimpleIdentifier variableName = statement.variables.variables[0].name;
12677 expect(variableName.staticType, same(typeProvider.dynamicType));
12678 expect(variableName.propagatedType, same(typeProvider.intType));
12679 }
12680 // Type of 'v' in reference.
12681 {
12682 ReturnStatement statement = statements[1] as ReturnStatement;
12683 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
12684 expect(variableName.propagatedType, same(typeProvider.intType));
12685 }
12686 }
12687
12688 void test_initializer_dereference() {
12689 Source source = addSource(r'''
12690 f() {
12691 var v = 'String';
12692 v.
12693 }''');
12694 LibraryElement library = resolve2(source);
12695 CompilationUnit unit = resolveCompilationUnit(source, library);
12696 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
12697 BlockFunctionBody body =
12698 function.functionExpression.body as BlockFunctionBody;
12699 ExpressionStatement statement =
12700 body.block.statements[1] as ExpressionStatement;
12701 PrefixedIdentifier invocation = statement.expression as PrefixedIdentifier;
12702 SimpleIdentifier variableName = invocation.prefix;
12703 expect(variableName.propagatedType, same(typeProvider.stringType));
12704 }
12705
12706 void test_initializer_hasStaticType() {
12707 Source source = addSource(r'''
12708 f() {
12709 int v = 0;
12710 return v;
12711 }''');
12712 LibraryElement library = resolve2(source);
12713 assertNoErrors(source);
12714 verify([source]);
12715 CompilationUnit unit = resolveCompilationUnit(source, library);
12716 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
12717 BlockFunctionBody body =
12718 function.functionExpression.body as BlockFunctionBody;
12719 NodeList<Statement> statements = body.block.statements;
12720 // Type of 'v' in declaration.
12721 {
12722 VariableDeclarationStatement statement =
12723 statements[0] as VariableDeclarationStatement;
12724 SimpleIdentifier variableName = statement.variables.variables[0].name;
12725 expect(variableName.staticType, same(typeProvider.intType));
12726 expect(variableName.propagatedType, isNull);
12727 }
12728 // Type of 'v' in reference.
12729 {
12730 ReturnStatement statement = statements[1] as ReturnStatement;
12731 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
12732 expect(variableName.staticType, same(typeProvider.intType));
12733 expect(variableName.propagatedType, isNull);
12734 }
12735 }
12736
12737 void test_initializer_hasStaticType_parameterized() {
12738 Source source = addSource(r'''
12739 f() {
12740 List<int> v = <int>[];
12741 return v;
12742 }''');
12743 LibraryElement library = resolve2(source);
12744 assertNoErrors(source);
12745 verify([source]);
12746 CompilationUnit unit = resolveCompilationUnit(source, library);
12747 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
12748 BlockFunctionBody body =
12749 function.functionExpression.body as BlockFunctionBody;
12750 NodeList<Statement> statements = body.block.statements;
12751 // Type of 'v' in declaration.
12752 {
12753 VariableDeclarationStatement statement =
12754 statements[0] as VariableDeclarationStatement;
12755 SimpleIdentifier variableName = statement.variables.variables[0].name;
12756 expect(variableName.staticType, isNotNull);
12757 expect(variableName.propagatedType, isNull);
12758 }
12759 // Type of 'v' in reference.
12760 {
12761 ReturnStatement statement = statements[1] as ReturnStatement;
12762 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
12763 expect(variableName.staticType, isNotNull);
12764 expect(variableName.propagatedType, isNull);
12765 }
12766 }
12767
12768 void test_initializer_null() {
12769 String code = r'''
12770 main() {
12771 int v = null;
12772 return v; // marker
12773 }''';
12774 CompilationUnit unit;
12775 {
12776 Source source = addSource(code);
12777 LibraryElement library = resolve2(source);
12778 assertNoErrors(source);
12779 verify([source]);
12780 unit = resolveCompilationUnit(source, library);
12781 }
12782 {
12783 SimpleIdentifier identifier = EngineTestCase.findNode(
12784 unit, code, "v = null;", (node) => node is SimpleIdentifier);
12785 expect(identifier.staticType, same(typeProvider.intType));
12786 expect(identifier.propagatedType, same(null));
12787 }
12788 {
12789 SimpleIdentifier identifier = EngineTestCase.findNode(
12790 unit, code, "v; // marker", (node) => node is SimpleIdentifier);
12791 expect(identifier.staticType, same(typeProvider.intType));
12792 expect(identifier.propagatedType, same(null));
12793 }
12794 }
12795
12796 void test_is_conditional() {
12797 Source source = addSource(r'''
12798 class A {}
12799 A f(var p) {
12800 return (p is A) ? p : null;
12801 }''');
12802 LibraryElement library = resolve2(source);
12803 assertNoErrors(source);
12804 verify([source]);
12805 CompilationUnit unit = resolveCompilationUnit(source, library);
12806 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
12807 InterfaceType typeA = classA.element.type;
12808 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
12809 BlockFunctionBody body =
12810 function.functionExpression.body as BlockFunctionBody;
12811 ReturnStatement statement = body.block.statements[0] as ReturnStatement;
12812 ConditionalExpression conditional =
12813 statement.expression as ConditionalExpression;
12814 SimpleIdentifier variableName =
12815 conditional.thenExpression as SimpleIdentifier;
12816 expect(variableName.propagatedType, same(typeA));
12817 }
12818
12819 void test_is_if() {
12820 Source source = addSource(r'''
12821 class A {}
12822 A f(var p) {
12823 if (p is A) {
12824 return p;
12825 } else {
12826 return null;
12827 }
12828 }''');
12829 LibraryElement library = resolve2(source);
12830 assertNoErrors(source);
12831 verify([source]);
12832 CompilationUnit unit = resolveCompilationUnit(source, library);
12833 // prepare A
12834 InterfaceType typeA;
12835 {
12836 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
12837 typeA = classA.element.type;
12838 }
12839 // verify "f"
12840 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
12841 BlockFunctionBody body =
12842 function.functionExpression.body as BlockFunctionBody;
12843 IfStatement ifStatement = body.block.statements[0] as IfStatement;
12844 // "p is A"
12845 {
12846 IsExpression isExpression = ifStatement.condition;
12847 SimpleIdentifier variableName = isExpression.expression;
12848 expect(variableName.propagatedType, isNull);
12849 }
12850 // "return p;"
12851 {
12852 ReturnStatement statement =
12853 (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
12854 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
12855 expect(variableName.propagatedType, same(typeA));
12856 }
12857 }
12858
12859 void test_is_if_lessSpecific() {
12860 Source source = addSource(r'''
12861 class A {}
12862 A f(A p) {
12863 if (p is String) {
12864 return p;
12865 } else {
12866 return null;
12867 }
12868 }''');
12869 LibraryElement library = resolve2(source);
12870 assertNoErrors(source);
12871 verify([source]);
12872 CompilationUnit unit = resolveCompilationUnit(source, library);
12873 // ClassDeclaration classA = (ClassDeclaration) unit.getDeclarations().get(0) ;
12874 // InterfaceType typeA = classA.getElement().getType();
12875 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
12876 BlockFunctionBody body =
12877 function.functionExpression.body as BlockFunctionBody;
12878 IfStatement ifStatement = body.block.statements[0] as IfStatement;
12879 ReturnStatement statement =
12880 (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
12881 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
12882 expect(variableName.propagatedType, same(null));
12883 }
12884
12885 void test_is_if_logicalAnd() {
12886 Source source = addSource(r'''
12887 class A {}
12888 A f(var p) {
12889 if (p is A && p != null) {
12890 return p;
12891 } else {
12892 return null;
12893 }
12894 }''');
12895 LibraryElement library = resolve2(source);
12896 assertNoErrors(source);
12897 verify([source]);
12898 CompilationUnit unit = resolveCompilationUnit(source, library);
12899 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
12900 InterfaceType typeA = classA.element.type;
12901 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
12902 BlockFunctionBody body =
12903 function.functionExpression.body as BlockFunctionBody;
12904 IfStatement ifStatement = body.block.statements[0] as IfStatement;
12905 ReturnStatement statement =
12906 (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
12907 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
12908 expect(variableName.propagatedType, same(typeA));
12909 }
12910
12911 void test_is_postConditional() {
12912 Source source = addSource(r'''
12913 class A {}
12914 A f(var p) {
12915 A a = (p is A) ? p : throw null;
12916 return p;
12917 }''');
12918 LibraryElement library = resolve2(source);
12919 assertNoErrors(source);
12920 verify([source]);
12921 CompilationUnit unit = resolveCompilationUnit(source, library);
12922 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
12923 InterfaceType typeA = classA.element.type;
12924 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
12925 BlockFunctionBody body =
12926 function.functionExpression.body as BlockFunctionBody;
12927 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
12928 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
12929 expect(variableName.propagatedType, same(typeA));
12930 }
12931
12932 void test_is_postIf() {
12933 Source source = addSource(r'''
12934 class A {}
12935 A f(var p) {
12936 if (p is A) {
12937 A a = p;
12938 } else {
12939 return null;
12940 }
12941 return p;
12942 }''');
12943 LibraryElement library = resolve2(source);
12944 assertNoErrors(source);
12945 verify([source]);
12946 CompilationUnit unit = resolveCompilationUnit(source, library);
12947 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
12948 InterfaceType typeA = classA.element.type;
12949 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
12950 BlockFunctionBody body =
12951 function.functionExpression.body as BlockFunctionBody;
12952 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
12953 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
12954 expect(variableName.propagatedType, same(typeA));
12955 }
12956
12957 void test_is_subclass() {
12958 Source source = addSource(r'''
12959 class A {}
12960 class B extends A {
12961 B m() => this;
12962 }
12963 A f(A p) {
12964 if (p is B) {
12965 return p.m();
12966 }
12967 return p;
12968 }''');
12969 LibraryElement library = resolve2(source);
12970 assertNoErrors(source);
12971 CompilationUnit unit = resolveCompilationUnit(source, library);
12972 FunctionDeclaration function = unit.declarations[2] as FunctionDeclaration;
12973 BlockFunctionBody body =
12974 function.functionExpression.body as BlockFunctionBody;
12975 IfStatement ifStatement = body.block.statements[0] as IfStatement;
12976 ReturnStatement statement =
12977 (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
12978 MethodInvocation invocation = statement.expression as MethodInvocation;
12979 expect(invocation.methodName.staticElement, isNotNull);
12980 expect(invocation.methodName.propagatedElement, isNull);
12981 }
12982
12983 void test_is_while() {
12984 Source source = addSource(r'''
12985 class A {}
12986 A f(var p) {
12987 while (p is A) {
12988 return p;
12989 }
12990 return p;
12991 }''');
12992 LibraryElement library = resolve2(source);
12993 assertNoErrors(source);
12994 verify([source]);
12995 CompilationUnit unit = resolveCompilationUnit(source, library);
12996 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
12997 InterfaceType typeA = classA.element.type;
12998 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
12999 BlockFunctionBody body =
13000 function.functionExpression.body as BlockFunctionBody;
13001 WhileStatement whileStatement = body.block.statements[0] as WhileStatement;
13002 ReturnStatement statement =
13003 (whileStatement.body as Block).statements[0] as ReturnStatement;
13004 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13005 expect(variableName.propagatedType, same(typeA));
13006 }
13007
13008 void test_isNot_conditional() {
13009 Source source = addSource(r'''
13010 class A {}
13011 A f(var p) {
13012 return (p is! A) ? null : p;
13013 }''');
13014 LibraryElement library = resolve2(source);
13015 assertNoErrors(source);
13016 verify([source]);
13017 CompilationUnit unit = resolveCompilationUnit(source, library);
13018 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
13019 InterfaceType typeA = classA.element.type;
13020 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13021 BlockFunctionBody body =
13022 function.functionExpression.body as BlockFunctionBody;
13023 ReturnStatement statement = body.block.statements[0] as ReturnStatement;
13024 ConditionalExpression conditional =
13025 statement.expression as ConditionalExpression;
13026 SimpleIdentifier variableName =
13027 conditional.elseExpression as SimpleIdentifier;
13028 expect(variableName.propagatedType, same(typeA));
13029 }
13030
13031 void test_isNot_if() {
13032 Source source = addSource(r'''
13033 class A {}
13034 A f(var p) {
13035 if (p is! A) {
13036 return null;
13037 } else {
13038 return p;
13039 }
13040 }''');
13041 LibraryElement library = resolve2(source);
13042 assertNoErrors(source);
13043 verify([source]);
13044 CompilationUnit unit = resolveCompilationUnit(source, library);
13045 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
13046 InterfaceType typeA = classA.element.type;
13047 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13048 BlockFunctionBody body =
13049 function.functionExpression.body as BlockFunctionBody;
13050 IfStatement ifStatement = body.block.statements[0] as IfStatement;
13051 ReturnStatement statement =
13052 (ifStatement.elseStatement as Block).statements[0] as ReturnStatement;
13053 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13054 expect(variableName.propagatedType, same(typeA));
13055 }
13056
13057 void test_isNot_if_logicalOr() {
13058 Source source = addSource(r'''
13059 class A {}
13060 A f(var p) {
13061 if (p is! A || null == p) {
13062 return null;
13063 } else {
13064 return p;
13065 }
13066 }''');
13067 LibraryElement library = resolve2(source);
13068 assertNoErrors(source);
13069 CompilationUnit unit = resolveCompilationUnit(source, library);
13070 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
13071 InterfaceType typeA = classA.element.type;
13072 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13073 BlockFunctionBody body =
13074 function.functionExpression.body as BlockFunctionBody;
13075 IfStatement ifStatement = body.block.statements[0] as IfStatement;
13076 ReturnStatement statement =
13077 (ifStatement.elseStatement as Block).statements[0] as ReturnStatement;
13078 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13079 expect(variableName.propagatedType, same(typeA));
13080 }
13081
13082 void test_isNot_postConditional() {
13083 Source source = addSource(r'''
13084 class A {}
13085 A f(var p) {
13086 A a = (p is! A) ? throw null : p;
13087 return p;
13088 }''');
13089 LibraryElement library = resolve2(source);
13090 assertNoErrors(source);
13091 verify([source]);
13092 CompilationUnit unit = resolveCompilationUnit(source, library);
13093 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
13094 InterfaceType typeA = classA.element.type;
13095 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13096 BlockFunctionBody body =
13097 function.functionExpression.body as BlockFunctionBody;
13098 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
13099 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13100 expect(variableName.propagatedType, same(typeA));
13101 }
13102
13103 void test_isNot_postIf() {
13104 Source source = addSource(r'''
13105 class A {}
13106 A f(var p) {
13107 if (p is! A) {
13108 return null;
13109 }
13110 return p;
13111 }''');
13112 LibraryElement library = resolve2(source);
13113 assertNoErrors(source);
13114 verify([source]);
13115 CompilationUnit unit = resolveCompilationUnit(source, library);
13116 ClassDeclaration classA = unit.declarations[0] as ClassDeclaration;
13117 InterfaceType typeA = classA.element.type;
13118 FunctionDeclaration function = unit.declarations[1] as FunctionDeclaration;
13119 BlockFunctionBody body =
13120 function.functionExpression.body as BlockFunctionBody;
13121 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
13122 SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
13123 expect(variableName.propagatedType, same(typeA));
13124 }
13125
13126 void test_issue20904BuggyTypePromotionAtIfJoin_5() {
13127 // https://code.google.com/p/dart/issues/detail?id=20904
13128 //
13129 // This is not an example of the 20904 bug, but rather,
13130 // an example of something that one obvious fix changes inadvertently: we
13131 // want to avoid using type information from is-checks when it
13132 // loses precision. I can't see how to get a bad hint this way, since
13133 // it seems the propagated type is not used to generate hints when a
13134 // more precise type would cause no hint. For example, for code like the
13135 // following, when the propagated type of [x] is [A] -- as happens for the
13136 // fix these tests aim to warn against -- there is no warning for
13137
13138 // calling a method defined on [B] but not [A] (there aren't any, but
13139 // pretend), but there is for calling a method not defined on either.
13140 // By not overriding the propagated type via an is-check that loses
13141 // precision, we get more precise completion under an is-check. However,
13142 // I can only imagine strange code would make use of this feature.
13143 //
13144 // Here the is-check improves precision, so we use it.
13145 String code = r'''
13146 class A {}
13147 class B extends A {}
13148 f() {
13149 var a = new A();
13150 var b = new B();
13151 b; // B
13152 if (a is B) {
13153 return a; // marker
13154 }
13155 }''';
13156 DartType tB = _findMarkedIdentifier(code, "; // B").propagatedType;
13157 _assertTypeOfMarkedExpression(code, null, tB);
13158 }
13159
13160 void test_issue20904BuggyTypePromotionAtIfJoin_6() {
13161 // https://code.google.com/p/dart/issues/detail?id=20904
13162 //
13163 // The other half of the *_5() test.
13164 //
13165 // Here the is-check loses precision, so we don't use it.
13166 String code = r'''
13167 class A {}
13168 class B extends A {}
13169 f() {
13170 var b = new B();
13171 b; // B
13172 if (b is A) {
13173 return b; // marker
13174 }
13175 }''';
13176 DartType tB = _findMarkedIdentifier(code, "; // B").propagatedType;
13177 _assertTypeOfMarkedExpression(code, null, tB);
13178 }
13179
13180 void test_listLiteral_different() {
13181 Source source = addSource(r'''
13182 f() {
13183 var v = [0, '1', 2];
13184 return v[2];
13185 }''');
13186 LibraryElement library = resolve2(source);
13187 assertNoErrors(source);
13188 verify([source]);
13189 CompilationUnit unit = resolveCompilationUnit(source, library);
13190 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
13191 BlockFunctionBody body =
13192 function.functionExpression.body as BlockFunctionBody;
13193 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
13194 IndexExpression indexExpression = statement.expression as IndexExpression;
13195 expect(indexExpression.propagatedType, isNull);
13196 }
13197
13198 void test_listLiteral_same() {
13199 Source source = addSource(r'''
13200 f() {
13201 var v = [0, 1, 2];
13202 return v[2];
13203 }''');
13204 LibraryElement library = resolve2(source);
13205 assertNoErrors(source);
13206 verify([source]);
13207 CompilationUnit unit = resolveCompilationUnit(source, library);
13208 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
13209 BlockFunctionBody body =
13210 function.functionExpression.body as BlockFunctionBody;
13211 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
13212 IndexExpression indexExpression = statement.expression as IndexExpression;
13213 expect(indexExpression.propagatedType, isNull);
13214 Expression v = indexExpression.target;
13215 InterfaceType propagatedType = v.propagatedType as InterfaceType;
13216 expect(propagatedType.element, same(typeProvider.listType.element));
13217 List<DartType> typeArguments = propagatedType.typeArguments;
13218 expect(typeArguments, hasLength(1));
13219 expect(typeArguments[0], same(typeProvider.dynamicType));
13220 }
13221
13222 void test_mapLiteral_different() {
13223 Source source = addSource(r'''
13224 f() {
13225 var v = {'0' : 0, 1 : '1', '2' : 2};
13226 return v;
13227 }''');
13228 LibraryElement library = resolve2(source);
13229 assertNoErrors(source);
13230 verify([source]);
13231 CompilationUnit unit = resolveCompilationUnit(source, library);
13232 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
13233 BlockFunctionBody body =
13234 function.functionExpression.body as BlockFunctionBody;
13235 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
13236 SimpleIdentifier identifier = statement.expression as SimpleIdentifier;
13237 InterfaceType propagatedType = identifier.propagatedType as InterfaceType;
13238 expect(propagatedType.element, same(typeProvider.mapType.element));
13239 List<DartType> typeArguments = propagatedType.typeArguments;
13240 expect(typeArguments, hasLength(2));
13241 expect(typeArguments[0], same(typeProvider.dynamicType));
13242 expect(typeArguments[1], same(typeProvider.dynamicType));
13243 }
13244
13245 void test_mapLiteral_same() {
13246 Source source = addSource(r'''
13247 f() {
13248 var v = {'a' : 0, 'b' : 1, 'c' : 2};
13249 return v;
13250 }''');
13251 LibraryElement library = resolve2(source);
13252 assertNoErrors(source);
13253 verify([source]);
13254 CompilationUnit unit = resolveCompilationUnit(source, library);
13255 FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
13256 BlockFunctionBody body =
13257 function.functionExpression.body as BlockFunctionBody;
13258 ReturnStatement statement = body.block.statements[1] as ReturnStatement;
13259 SimpleIdentifier identifier = statement.expression as SimpleIdentifier;
13260 InterfaceType propagatedType = identifier.propagatedType as InterfaceType;
13261 expect(propagatedType.element, same(typeProvider.mapType.element));
13262 List<DartType> typeArguments = propagatedType.typeArguments;
13263 expect(typeArguments, hasLength(2));
13264 expect(typeArguments[0], same(typeProvider.dynamicType));
13265 expect(typeArguments[1], same(typeProvider.dynamicType));
13266 }
13267
13268 void test_mergePropagatedTypes_afterIfThen_different() {
13269 String code = r'''
13270 main() {
13271 var v = 0;
13272 if (v != null) {
13273 v = '';
13274 }
13275 return v;
13276 }''';
13277 {
13278 SimpleIdentifier identifier = _findMarkedIdentifier(code, "v;");
13279 expect(identifier.propagatedType, null);
13280 }
13281 {
13282 SimpleIdentifier identifier = _findMarkedIdentifier(code, "v = '';");
13283 expect(identifier.propagatedType, typeProvider.stringType);
13284 }
13285 }
13286
13287 void test_mergePropagatedTypes_afterIfThen_same() {
13288 _assertTypeOfMarkedExpression(
13289 r'''
13290 main() {
13291 var v = 1;
13292 if (v != null) {
13293 v = 2;
13294 }
13295 return v; // marker
13296 }''',
13297 null,
13298 typeProvider.intType);
13299 }
13300
13301 void test_mergePropagatedTypes_afterIfThenElse_different() {
13302 _assertTypeOfMarkedExpression(
13303 r'''
13304 main() {
13305 var v = 1;
13306 if (v != null) {
13307 v = 2;
13308 } else {
13309 v = '3';
13310 }
13311 return v; // marker
13312 }''',
13313 null,
13314 null);
13315 }
13316
13317 void test_mergePropagatedTypes_afterIfThenElse_same() {
13318 _assertTypeOfMarkedExpression(
13319 r'''
13320 main() {
13321 var v = 1;
13322 if (v != null) {
13323 v = 2;
13324 } else {
13325 v = 3;
13326 }
13327 return v; // marker
13328 }''',
13329 null,
13330 typeProvider.intType);
13331 }
13332
13333 void test_mergePropagatedTypesAtJoinPoint_4() {
13334 // https://code.google.com/p/dart/issues/detail?id=19929
13335 _assertTypeOfMarkedExpression(
13336 r'''
13337 f5(x) {
13338 var y = [];
13339 if (x) {
13340 y = 0;
13341 } else {
13342 return y;
13343 }
13344 // Propagated type is [int] here: correct.
13345 return y; // marker
13346 }''',
13347 null,
13348 typeProvider.intType);
13349 }
13350
13351 void test_mutatedOutsideScope() {
13352 // https://code.google.com/p/dart/issues/detail?id=22732
13353 Source source = addSource(r'''
13354 class Base {
13355 }
13356
13357 class Derived extends Base {
13358 get y => null;
13359 }
13360
13361 class C {
13362 void f() {
13363 Base x = null;
13364 if (x is Derived) {
13365 print(x.y); // BAD
13366 }
13367 x = null;
13368 }
13369 }
13370
13371 void g() {
13372 Base x = null;
13373 if (x is Derived) {
13374 print(x.y); // GOOD
13375 }
13376 x = null;
13377 }''');
13378 computeLibrarySourceErrors(source);
13379 assertNoErrors(source);
13380 }
13381
13382 void test_objectMethodOnDynamicExpression_doubleEquals() {
13383 // https://code.google.com/p/dart/issues/detail?id=20342
13384 //
13385 // This was not actually part of Issue 20342, since the spec specifies a
13386 // static type of [bool] for [==] comparison and the implementation
13387 // was already consistent with the spec there. But, it's another
13388 // [Object] method, so it's included here.
13389 _assertTypeOfMarkedExpression(
13390 r'''
13391 f1(x) {
13392 var v = (x == x);
13393 return v; // marker
13394 }''',
13395 null,
13396 typeProvider.boolType);
13397 }
13398
13399 void test_objectMethodOnDynamicExpression_hashCode() {
13400 // https://code.google.com/p/dart/issues/detail?id=20342
13401 _assertTypeOfMarkedExpression(
13402 r'''
13403 f1(x) {
13404 var v = x.hashCode;
13405 return v; // marker
13406 }''',
13407 null,
13408 typeProvider.intType);
13409 }
13410
13411 void test_objectMethodOnDynamicExpression_runtimeType() {
13412 // https://code.google.com/p/dart/issues/detail?id=20342
13413 _assertTypeOfMarkedExpression(
13414 r'''
13415 f1(x) {
13416 var v = x.runtimeType;
13417 return v; // marker
13418 }''',
13419 null,
13420 typeProvider.typeType);
13421 }
13422
13423 void test_objectMethodOnDynamicExpression_toString() {
13424 // https://code.google.com/p/dart/issues/detail?id=20342
13425 _assertTypeOfMarkedExpression(
13426 r'''
13427 f1(x) {
13428 var v = x.toString();
13429 return v; // marker
13430 }''',
13431 null,
13432 typeProvider.stringType);
13433 }
13434
13435 void test_propagatedReturnType_function_hasReturnType_returnsNull() {
13436 String code = r'''
13437 String f() => null;
13438 main() {
13439 var v = f();
13440 }''';
13441 _assertPropagatedAssignedType(
13442 code, typeProvider.dynamicType, typeProvider.stringType);
13443 }
13444
13445 void test_propagatedReturnType_function_lessSpecificStaticReturnType() {
13446 String code = r'''
13447 Object f() => 42;
13448 main() {
13449 var v = f();
13450 }''';
13451 _assertPropagatedAssignedType(
13452 code, typeProvider.dynamicType, typeProvider.intType);
13453 }
13454
13455 void test_propagatedReturnType_function_moreSpecificStaticReturnType() {
13456 String code = r'''
13457 int f(v) => (v as num);
13458 main() {
13459 var v = f(3);
13460 }''';
13461 _assertPropagatedAssignedType(
13462 code, typeProvider.dynamicType, typeProvider.intType);
13463 }
13464
13465 void test_propagatedReturnType_function_noReturnTypeName_blockBody_multipleRet urns() {
13466 String code = r'''
13467 f() {
13468 if (true) return 0;
13469 return 1.0;
13470 }
13471 main() {
13472 var v = f();
13473 }''';
13474 _assertPropagatedAssignedType(
13475 code, typeProvider.dynamicType, typeProvider.numType);
13476 }
13477
13478 void test_propagatedReturnType_function_noReturnTypeName_blockBody_oneReturn() {
13479 String code = r'''
13480 f() {
13481 var z = 42;
13482 return z;
13483 }
13484 main() {
13485 var v = f();
13486 }''';
13487 _assertPropagatedAssignedType(
13488 code, typeProvider.dynamicType, typeProvider.intType);
13489 }
13490
13491 void test_propagatedReturnType_function_noReturnTypeName_expressionBody() {
13492 String code = r'''
13493 f() => 42;
13494 main() {
13495 var v = f();
13496 }''';
13497 _assertPropagatedAssignedType(
13498 code, typeProvider.dynamicType, typeProvider.intType);
13499 }
13500
13501 void test_propagatedReturnType_localFunction() {
13502 String code = r'''
13503 main() {
13504 f() => 42;
13505 var v = f();
13506 }''';
13507 _assertPropagatedAssignedType(
13508 code, typeProvider.dynamicType, typeProvider.intType);
13509 }
13510
13511 void test_query() {
13512 Source source = addSource(r'''
13513 import 'dart:html';
13514
13515 main() {
13516 var v1 = query('a');
13517 var v2 = query('A');
13518 var v3 = query('body:active');
13519 var v4 = query('button[foo="bar"]');
13520 var v5 = query('div.class');
13521 var v6 = query('input#id');
13522 var v7 = query('select#id');
13523 // invocation of method
13524 var m1 = document.query('div');
13525 // unsupported currently
13526 var b1 = query('noSuchTag');
13527 var b2 = query('DART_EDITOR_NO_SUCH_TYPE');
13528 var b3 = query('body div');
13529 return [v1, v2, v3, v4, v5, v6, v7, m1, b1, b2, b3];
13530 }''');
13531 LibraryElement library = resolve2(source);
13532 assertNoErrors(source);
13533 verify([source]);
13534 CompilationUnit unit = resolveCompilationUnit(source, library);
13535 FunctionDeclaration main = unit.declarations[0] as FunctionDeclaration;
13536 BlockFunctionBody body = main.functionExpression.body as BlockFunctionBody;
13537 ReturnStatement statement = body.block.statements[11] as ReturnStatement;
13538 NodeList<Expression> elements =
13539 (statement.expression as ListLiteral).elements;
13540 expect(elements[0].propagatedType.name, "AnchorElement");
13541 expect(elements[1].propagatedType.name, "AnchorElement");
13542 expect(elements[2].propagatedType.name, "BodyElement");
13543 expect(elements[3].propagatedType.name, "ButtonElement");
13544 expect(elements[4].propagatedType.name, "DivElement");
13545 expect(elements[5].propagatedType.name, "InputElement");
13546 expect(elements[6].propagatedType.name, "SelectElement");
13547 expect(elements[7].propagatedType.name, "DivElement");
13548 expect(elements[8].propagatedType.name, "Element");
13549 expect(elements[9].propagatedType.name, "Element");
13550 expect(elements[10].propagatedType.name, "Element");
13551 }
13552 }
13553
13554 @reflectiveTest
13555 class StrongModeTypePropagationTest extends ResolverTestCase {
13556 @override
13557 void setUp() {
13558 AnalysisOptionsImpl options = new AnalysisOptionsImpl();
13559 options.strongMode = true;
13560 resetWithOptions(options);
13561 }
13562
13563 void test_localVariableInference_constant() {
13564 String code = r'''
13565 main() {
13566 var v = 3;
13567 return v; // marker
13568 }''';
13569 _assertPropagatedAssignedType(code, typeProvider.intType, null);
13570 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
13571 }
13572
13573 void test_localVariableInference_transitive_local() {
13574 String code = r'''
13575 main() {
13576 var x = 3;
13577 var v = x;
13578 return v; // marker
13579 }''';
13580 _assertPropagatedAssignedType(code, typeProvider.intType, null);
13581 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
13582 }
13583
13584 void test_localVariableInference_transitive_list_local() {
13585 String code = r'''
13586 main() {
13587 var x = <int>[3];
13588 var v = x[0];
13589 return v; // marker
13590 }''';
13591 _assertPropagatedAssignedType(code, typeProvider.intType, null);
13592 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
13593 }
13594
13595 void test_localVariableInference_transitive_toplevel_lexical() {
13596 String code = r'''
13597 int x = 3;
13598 main() {
13599 var v = x;
13600 return v; // marker
13601 }
13602 ''';
13603 _assertPropagatedAssignedType(code, typeProvider.intType, null);
13604 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
13605 }
13606
13607 void test_localVariableInference_transitive_toplevel_reversed() {
13608 String code = r'''
13609 main() {
13610 var v = x;
13611 return v; // marker
13612 }
13613 int x = 3;
13614 ''';
13615 _assertPropagatedAssignedType(code, typeProvider.intType, null);
13616 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
13617 }
13618
13619 void fail_localVariableInference_transitive_toplevel_inferred_lexical() {
13620 String code = r'''
13621 final x = 3;
13622 main() {
13623 var v = x;
13624 return v; // marker
13625 }
13626 ''';
13627 _assertPropagatedAssignedType(code, typeProvider.intType, null);
13628 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
13629 }
13630
13631 void fail_localVariableInference_transitive_toplevel_inferred_reversed() {
13632 String code = r'''
13633 main() {
13634 var v = x;
13635 return v; // marker
13636 }
13637 final x = 3;
13638 ''';
13639 _assertPropagatedAssignedType(code, typeProvider.intType, null);
13640 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
13641 }
13642
13643 void test_localVariableInference_transitive_field_lexical() {
13644 String code = r'''
13645 class A {
13646 int x = 3;
13647 f() {
13648 var v = x;
13649 return v; // marker
13650 }
13651 }
13652 main() {
13653 }
13654 ''';
13655 _assertPropagatedAssignedType(code, typeProvider.intType, null);
13656 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
13657 }
13658
13659 void test_localVariableInference_transitive_field_reversed() {
13660 String code = r'''
13661 class A {
13662 f() {
13663 var v = x;
13664 return v; // marker
13665 }
13666 int x = 3;
13667 }
13668 main() {
13669 }
13670 ''';
13671 _assertPropagatedAssignedType(code, typeProvider.intType, null);
13672 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
13673 }
13674
13675 void fail_localVariableInference_transitive_field_inferred_lexical() {
13676 String code = r'''
13677 class A {
13678 final x = 3;
13679 f() {
13680 var v = x;
13681 return v; // marker
13682 }
13683 }
13684 main() {
13685 }
13686 ''';
13687 _assertPropagatedAssignedType(code, typeProvider.intType, null);
13688 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
13689 }
13690
13691 void fail_localVariableInference_transitive_field_inferred_reversed() {
13692 String code = r'''
13693 class A {
13694 f() {
13695 var v = x;
13696 return v; // marker
13697 }
13698 final x = 3;
13699 }
13700 main() {
13701 }
13702 ''';
13703 _assertPropagatedAssignedType(code, typeProvider.intType, null);
13704 _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
13705 }
13706
13707 void test_localVariableInference_declaredType_disabled() {
13708 String code = r'''
13709 main() {
13710 dynamic v = 3;
13711 return v; // marker
13712 }''';
13713 _assertPropagatedAssignedType(
13714 code, typeProvider.dynamicType, typeProvider.intType);
13715 _assertTypeOfMarkedExpression(
13716 code, typeProvider.dynamicType, typeProvider.intType);
13717 }
13718
13719 void test_localVariableInference_bottom_disabled() {
13720 String code = r'''
13721 main() {
13722 var v = null;
13723 return v; // marker
13724 }''';
13725 _assertPropagatedAssignedType(code, typeProvider.dynamicType, null);
13726 _assertTypeOfMarkedExpression(code, typeProvider.dynamicType, null);
13727 }
13728
13729 void test_localVariableInference_noInitializer_disabled() {
13730 String code = r'''
13731 main() {
13732 var v;
13733 v = 3;
13734 return v; // marker
13735 }''';
13736 _assertPropagatedAssignedType(
13737 code, typeProvider.dynamicType, typeProvider.intType);
13738 _assertTypeOfMarkedExpression(
13739 code, typeProvider.dynamicType, typeProvider.intType);
13740 }
13741 }
13742
13743 @reflectiveTest
13744 class TypeProviderImplTest extends EngineTestCase {
13745 void test_creation() {
13746 //
13747 // Create a mock library element with the types expected to be in dart:core.
13748 // We cannot use either ElementFactory or TestTypeProvider (which uses
13749 // ElementFactory) because we side-effect the elements in ways that would
13750 // break other tests.
13751 //
13752 InterfaceType objectType = _classElement("Object", null).type;
13753 InterfaceType boolType = _classElement("bool", objectType).type;
13754 InterfaceType numType = _classElement("num", objectType).type;
13755 InterfaceType doubleType = _classElement("double", numType).type;
13756 InterfaceType functionType = _classElement("Function", objectType).type;
13757 InterfaceType futureType = _classElement("Future", objectType, ["T"]).type;
13758 InterfaceType intType = _classElement("int", numType).type;
13759 InterfaceType iterableType =
13760 _classElement("Iterable", objectType, ["T"]).type;
13761 InterfaceType listType = _classElement("List", objectType, ["E"]).type;
13762 InterfaceType mapType = _classElement("Map", objectType, ["K", "V"]).type;
13763 InterfaceType stackTraceType = _classElement("StackTrace", objectType).type;
13764 InterfaceType streamType = _classElement("Stream", objectType, ["T"]).type;
13765 InterfaceType stringType = _classElement("String", objectType).type;
13766 InterfaceType symbolType = _classElement("Symbol", objectType).type;
13767 InterfaceType typeType = _classElement("Type", objectType).type;
13768 CompilationUnitElementImpl coreUnit =
13769 new CompilationUnitElementImpl("core.dart");
13770 coreUnit.types = <ClassElement>[
13771 boolType.element,
13772 doubleType.element,
13773 functionType.element,
13774 intType.element,
13775 iterableType.element,
13776 listType.element,
13777 mapType.element,
13778 objectType.element,
13779 stackTraceType.element,
13780 stringType.element,
13781 symbolType.element,
13782 typeType.element
13783 ];
13784 CompilationUnitElementImpl asyncUnit =
13785 new CompilationUnitElementImpl("async.dart");
13786 asyncUnit.types = <ClassElement>[futureType.element, streamType.element];
13787 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
13788 LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
13789 context, AstFactory.libraryIdentifier2(["dart.core"]));
13790 coreLibrary.definingCompilationUnit = coreUnit;
13791 LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
13792 context, AstFactory.libraryIdentifier2(["dart.async"]));
13793 asyncLibrary.definingCompilationUnit = asyncUnit;
13794 //
13795 // Create a type provider and ensure that it can return the expected types.
13796 //
13797 TypeProviderImpl provider = new TypeProviderImpl(coreLibrary, asyncLibrary);
13798 expect(provider.boolType, same(boolType));
13799 expect(provider.bottomType, isNotNull);
13800 expect(provider.doubleType, same(doubleType));
13801 expect(provider.dynamicType, isNotNull);
13802 expect(provider.functionType, same(functionType));
13803 expect(provider.futureType, same(futureType));
13804 expect(provider.intType, same(intType));
13805 expect(provider.listType, same(listType));
13806 expect(provider.mapType, same(mapType));
13807 expect(provider.objectType, same(objectType));
13808 expect(provider.stackTraceType, same(stackTraceType));
13809 expect(provider.stringType, same(stringType));
13810 expect(provider.symbolType, same(symbolType));
13811 expect(provider.typeType, same(typeType));
13812 }
13813
13814 ClassElement _classElement(String typeName, InterfaceType superclassType,
13815 [List<String> parameterNames]) {
13816 ClassElementImpl element =
13817 new ClassElementImpl.forNode(AstFactory.identifier3(typeName));
13818 element.supertype = superclassType;
13819 InterfaceTypeImpl type = new InterfaceTypeImpl(element);
13820 element.type = type;
13821 if (parameterNames != null) {
13822 int count = parameterNames.length;
13823 if (count > 0) {
13824 List<TypeParameterElementImpl> typeParameters =
13825 new List<TypeParameterElementImpl>(count);
13826 List<TypeParameterTypeImpl> typeArguments =
13827 new List<TypeParameterTypeImpl>(count);
13828 for (int i = 0; i < count; i++) {
13829 TypeParameterElementImpl typeParameter =
13830 new TypeParameterElementImpl.forNode(
13831 AstFactory.identifier3(parameterNames[i]));
13832 typeParameters[i] = typeParameter;
13833 typeArguments[i] = new TypeParameterTypeImpl(typeParameter);
13834 typeParameter.type = typeArguments[i];
13835 }
13836 element.typeParameters = typeParameters;
13837 type.typeArguments = typeArguments;
13838 }
13839 }
13840 return element;
13841 }
13842 }
13843
13844 @reflectiveTest
13845 class TypeResolverVisitorTest extends EngineTestCase {
13846 /**
13847 * The error listener to which errors will be reported.
13848 */
13849 GatheringErrorListener _listener;
13850
13851 /**
13852 * The object representing the information about the library in which the type s are being
13853 * resolved.
13854 */
13855 Library _library;
13856
13857 /**
13858 * The type provider used to access the types.
13859 */
13860 TestTypeProvider _typeProvider;
13861
13862 /**
13863 * The visitor used to resolve types needed to form the type hierarchy.
13864 */
13865 TypeResolverVisitor _visitor;
13866
13867 void fail_visitConstructorDeclaration() {
13868 fail("Not yet tested");
13869 _listener.assertNoErrors();
13870 }
13871
13872 void fail_visitFunctionTypeAlias() {
13873 fail("Not yet tested");
13874 _listener.assertNoErrors();
13875 }
13876
13877 void fail_visitVariableDeclaration() {
13878 fail("Not yet tested");
13879 ClassElement type = ElementFactory.classElement2("A");
13880 VariableDeclaration node = AstFactory.variableDeclaration("a");
13881 AstFactory.variableDeclarationList(null, AstFactory.typeName(type), [node]);
13882 //resolve(node);
13883 expect(node.name.staticType, same(type.type));
13884 _listener.assertNoErrors();
13885 }
13886
13887 @override
13888 void setUp() {
13889 _listener = new GatheringErrorListener();
13890 InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
13891 Source librarySource =
13892 new FileBasedSource(FileUtilities2.createFile("/lib.dart"));
13893 _library = new Library(context, _listener, librarySource);
13894 LibraryElementImpl element = new LibraryElementImpl.forNode(
13895 context, AstFactory.libraryIdentifier2(["lib"]));
13896 element.definingCompilationUnit =
13897 new CompilationUnitElementImpl("lib.dart");
13898 _library.libraryElement = element;
13899 _typeProvider = new TestTypeProvider();
13900 _visitor = new TypeResolverVisitor(_library.libraryElement, librarySource,
13901 _typeProvider, _library.errorListener,
13902 nameScope: _library.libraryScope);
13903 }
13904
13905 void test_visitCatchClause_exception() {
13906 // catch (e)
13907 CatchClause clause = AstFactory.catchClause("e");
13908 SimpleIdentifier exceptionParameter = clause.exceptionParameter;
13909 exceptionParameter.staticElement =
13910 new LocalVariableElementImpl.forNode(exceptionParameter);
13911 _resolveCatchClause(clause, _typeProvider.dynamicType, null);
13912 _listener.assertNoErrors();
13913 }
13914
13915 void test_visitCatchClause_exception_stackTrace() {
13916 // catch (e, s)
13917 CatchClause clause = AstFactory.catchClause2("e", "s");
13918 SimpleIdentifier exceptionParameter = clause.exceptionParameter;
13919 exceptionParameter.staticElement =
13920 new LocalVariableElementImpl.forNode(exceptionParameter);
13921 SimpleIdentifier stackTraceParameter = clause.stackTraceParameter;
13922 stackTraceParameter.staticElement =
13923 new LocalVariableElementImpl.forNode(stackTraceParameter);
13924 _resolveCatchClause(
13925 clause, _typeProvider.dynamicType, _typeProvider.stackTraceType);
13926 _listener.assertNoErrors();
13927 }
13928
13929 void test_visitCatchClause_on_exception() {
13930 // on E catch (e)
13931 ClassElement exceptionElement = ElementFactory.classElement2("E");
13932 TypeName exceptionType = AstFactory.typeName(exceptionElement);
13933 CatchClause clause = AstFactory.catchClause4(exceptionType, "e");
13934 SimpleIdentifier exceptionParameter = clause.exceptionParameter;
13935 exceptionParameter.staticElement =
13936 new LocalVariableElementImpl.forNode(exceptionParameter);
13937 _resolveCatchClause(
13938 clause, exceptionElement.type, null, [exceptionElement]);
13939 _listener.assertNoErrors();
13940 }
13941
13942 void test_visitCatchClause_on_exception_stackTrace() {
13943 // on E catch (e, s)
13944 ClassElement exceptionElement = ElementFactory.classElement2("E");
13945 TypeName exceptionType = AstFactory.typeName(exceptionElement);
13946 (exceptionType.name as SimpleIdentifier).staticElement = exceptionElement;
13947 CatchClause clause = AstFactory.catchClause5(exceptionType, "e", "s");
13948 SimpleIdentifier exceptionParameter = clause.exceptionParameter;
13949 exceptionParameter.staticElement =
13950 new LocalVariableElementImpl.forNode(exceptionParameter);
13951 SimpleIdentifier stackTraceParameter = clause.stackTraceParameter;
13952 stackTraceParameter.staticElement =
13953 new LocalVariableElementImpl.forNode(stackTraceParameter);
13954 _resolveCatchClause(clause, exceptionElement.type,
13955 _typeProvider.stackTraceType, [exceptionElement]);
13956 _listener.assertNoErrors();
13957 }
13958
13959 void test_visitClassDeclaration() {
13960 // class A extends B with C implements D {}
13961 // class B {}
13962 // class C {}
13963 // class D {}
13964 ClassElement elementA = ElementFactory.classElement2("A");
13965 ClassElement elementB = ElementFactory.classElement2("B");
13966 ClassElement elementC = ElementFactory.classElement2("C");
13967 ClassElement elementD = ElementFactory.classElement2("D");
13968 ExtendsClause extendsClause =
13969 AstFactory.extendsClause(AstFactory.typeName(elementB));
13970 WithClause withClause =
13971 AstFactory.withClause([AstFactory.typeName(elementC)]);
13972 ImplementsClause implementsClause =
13973 AstFactory.implementsClause([AstFactory.typeName(elementD)]);
13974 ClassDeclaration declaration = AstFactory.classDeclaration(
13975 null, "A", null, extendsClause, withClause, implementsClause);
13976 declaration.name.staticElement = elementA;
13977 _resolveNode(declaration, [elementA, elementB, elementC, elementD]);
13978 expect(elementA.supertype, same(elementB.type));
13979 List<InterfaceType> mixins = elementA.mixins;
13980 expect(mixins, hasLength(1));
13981 expect(mixins[0], same(elementC.type));
13982 List<InterfaceType> interfaces = elementA.interfaces;
13983 expect(interfaces, hasLength(1));
13984 expect(interfaces[0], same(elementD.type));
13985 _listener.assertNoErrors();
13986 }
13987
13988 void test_visitClassDeclaration_instanceMemberCollidesWithClass() {
13989 // class A {}
13990 // class B extends A {
13991 // void A() {}
13992 // }
13993 ClassElementImpl elementA = ElementFactory.classElement2("A");
13994 ClassElementImpl elementB = ElementFactory.classElement2("B");
13995 elementB.methods = <MethodElement>[
13996 ElementFactory.methodElement("A", VoidTypeImpl.instance)
13997 ];
13998 ExtendsClause extendsClause =
13999 AstFactory.extendsClause(AstFactory.typeName(elementA));
14000 ClassDeclaration declaration =
14001 AstFactory.classDeclaration(null, "B", null, extendsClause, null, null);
14002 declaration.name.staticElement = elementB;
14003 _resolveNode(declaration, [elementA, elementB]);
14004 expect(elementB.supertype, same(elementA.type));
14005 _listener.assertNoErrors();
14006 }
14007
14008 void test_visitClassTypeAlias() {
14009 // class A = B with C implements D;
14010 ClassElement elementA = ElementFactory.classElement2("A");
14011 ClassElement elementB = ElementFactory.classElement2("B");
14012 ClassElement elementC = ElementFactory.classElement2("C");
14013 ClassElement elementD = ElementFactory.classElement2("D");
14014 WithClause withClause =
14015 AstFactory.withClause([AstFactory.typeName(elementC)]);
14016 ImplementsClause implementsClause =
14017 AstFactory.implementsClause([AstFactory.typeName(elementD)]);
14018 ClassTypeAlias alias = AstFactory.classTypeAlias("A", null, null,
14019 AstFactory.typeName(elementB), withClause, implementsClause);
14020 alias.name.staticElement = elementA;
14021 _resolveNode(alias, [elementA, elementB, elementC, elementD]);
14022 expect(elementA.supertype, same(elementB.type));
14023 List<InterfaceType> mixins = elementA.mixins;
14024 expect(mixins, hasLength(1));
14025 expect(mixins[0], same(elementC.type));
14026 List<InterfaceType> interfaces = elementA.interfaces;
14027 expect(interfaces, hasLength(1));
14028 expect(interfaces[0], same(elementD.type));
14029 _listener.assertNoErrors();
14030 }
14031
14032 void test_visitClassTypeAlias_constructorWithOptionalParams_ignored() {
14033 // class T {}
14034 // class B {
14035 // B.c1();
14036 // B.c2([T a0]);
14037 // B.c3({T a0});
14038 // }
14039 // class M {}
14040 // class C = B with M
14041 ClassElement classT = ElementFactory.classElement2('T', []);
14042 ClassElementImpl classB = ElementFactory.classElement2('B', []);
14043 ConstructorElementImpl constructorBc1 =
14044 ElementFactory.constructorElement2(classB, 'c1', []);
14045 ConstructorElementImpl constructorBc2 =
14046 ElementFactory.constructorElement2(classB, 'c2', [classT.type]);
14047 (constructorBc2.parameters[0] as ParameterElementImpl).parameterKind =
14048 ParameterKind.POSITIONAL;
14049 ConstructorElementImpl constructorBc3 =
14050 ElementFactory.constructorElement2(classB, 'c3', [classT.type]);
14051 (constructorBc3.parameters[0] as ParameterElementImpl).parameterKind =
14052 ParameterKind.NAMED;
14053 classB.constructors = [constructorBc1, constructorBc2, constructorBc3];
14054 ClassElement classM = ElementFactory.classElement2('M', []);
14055 WithClause withClause =
14056 AstFactory.withClause([AstFactory.typeName(classM, [])]);
14057 ClassElement classC = ElementFactory.classTypeAlias2('C', []);
14058 ClassTypeAlias alias = AstFactory.classTypeAlias(
14059 'C', null, null, AstFactory.typeName(classB, []), withClause, null);
14060 alias.name.staticElement = classC;
14061 _resolveNode(alias, [classT, classB, classM, classC]);
14062 expect(classC.constructors, hasLength(1));
14063 ConstructorElement constructor = classC.constructors[0];
14064 expect(constructor.isFactory, isFalse);
14065 expect(constructor.isSynthetic, isTrue);
14066 expect(constructor.name, 'c1');
14067 expect(constructor.functions, hasLength(0));
14068 expect(constructor.labels, hasLength(0));
14069 expect(constructor.localVariables, hasLength(0));
14070 expect(constructor.parameters, isEmpty);
14071 }
14072
14073 void test_visitClassTypeAlias_constructorWithParams() {
14074 // class T {}
14075 // class B {
14076 // B(T a0);
14077 // }
14078 // class M {}
14079 // class C = B with M
14080 ClassElement classT = ElementFactory.classElement2('T', []);
14081 ClassElementImpl classB = ElementFactory.classElement2('B', []);
14082 ConstructorElementImpl constructorB =
14083 ElementFactory.constructorElement2(classB, '', [classT.type]);
14084 classB.constructors = [constructorB];
14085 ClassElement classM = ElementFactory.classElement2('M', []);
14086 WithClause withClause =
14087 AstFactory.withClause([AstFactory.typeName(classM, [])]);
14088 ClassElement classC = ElementFactory.classTypeAlias2('C', []);
14089 ClassTypeAlias alias = AstFactory.classTypeAlias(
14090 'C', null, null, AstFactory.typeName(classB, []), withClause, null);
14091 alias.name.staticElement = classC;
14092 _resolveNode(alias, [classT, classB, classM, classC]);
14093 expect(classC.constructors, hasLength(1));
14094 ConstructorElement constructor = classC.constructors[0];
14095 expect(constructor.isFactory, isFalse);
14096 expect(constructor.isSynthetic, isTrue);
14097 expect(constructor.name, '');
14098 expect(constructor.functions, hasLength(0));
14099 expect(constructor.labels, hasLength(0));
14100 expect(constructor.localVariables, hasLength(0));
14101 expect(constructor.parameters, hasLength(1));
14102 expect(constructor.parameters[0].type, equals(classT.type));
14103 expect(constructor.parameters[0].name,
14104 equals(constructorB.parameters[0].name));
14105 }
14106
14107 void test_visitClassTypeAlias_defaultConstructor() {
14108 // class B {}
14109 // class M {}
14110 // class C = B with M
14111 ClassElementImpl classB = ElementFactory.classElement2('B', []);
14112 ConstructorElementImpl constructorB =
14113 ElementFactory.constructorElement2(classB, '', []);
14114 constructorB.setModifier(Modifier.SYNTHETIC, true);
14115 classB.constructors = [constructorB];
14116 ClassElement classM = ElementFactory.classElement2('M', []);
14117 WithClause withClause =
14118 AstFactory.withClause([AstFactory.typeName(classM, [])]);
14119 ClassElement classC = ElementFactory.classTypeAlias2('C', []);
14120 ClassTypeAlias alias = AstFactory.classTypeAlias(
14121 'C', null, null, AstFactory.typeName(classB, []), withClause, null);
14122 alias.name.staticElement = classC;
14123 _resolveNode(alias, [classB, classM, classC]);
14124 expect(classC.constructors, hasLength(1));
14125 ConstructorElement constructor = classC.constructors[0];
14126 expect(constructor.isFactory, isFalse);
14127 expect(constructor.isSynthetic, isTrue);
14128 expect(constructor.name, '');
14129 expect(constructor.functions, hasLength(0));
14130 expect(constructor.labels, hasLength(0));
14131 expect(constructor.localVariables, hasLength(0));
14132 expect(constructor.parameters, isEmpty);
14133 }
14134
14135 void test_visitFieldFormalParameter_functionType() {
14136 InterfaceType intType = _typeProvider.intType;
14137 TypeName intTypeName = AstFactory.typeName4("int");
14138 String innerParameterName = "a";
14139 SimpleFormalParameter parameter =
14140 AstFactory.simpleFormalParameter3(innerParameterName);
14141 parameter.identifier.staticElement =
14142 ElementFactory.requiredParameter(innerParameterName);
14143 String outerParameterName = "p";
14144 FormalParameter node = AstFactory.fieldFormalParameter(null, intTypeName,
14145 outerParameterName, AstFactory.formalParameterList([parameter]));
14146 node.identifier.staticElement =
14147 ElementFactory.requiredParameter(outerParameterName);
14148 DartType parameterType = _resolveFormalParameter(node, [intType.element]);
14149 EngineTestCase.assertInstanceOf(
14150 (obj) => obj is FunctionType, FunctionType, parameterType);
14151 FunctionType functionType = parameterType as FunctionType;
14152 expect(functionType.returnType, same(intType));
14153 expect(functionType.parameters, hasLength(1));
14154 _listener.assertNoErrors();
14155 }
14156
14157 void test_visitFieldFormalParameter_noType() {
14158 String parameterName = "p";
14159 FormalParameter node =
14160 AstFactory.fieldFormalParameter(Keyword.VAR, null, parameterName);
14161 node.identifier.staticElement =
14162 ElementFactory.requiredParameter(parameterName);
14163 expect(_resolveFormalParameter(node), same(_typeProvider.dynamicType));
14164 _listener.assertNoErrors();
14165 }
14166
14167 void test_visitFieldFormalParameter_type() {
14168 InterfaceType intType = _typeProvider.intType;
14169 TypeName intTypeName = AstFactory.typeName4("int");
14170 String parameterName = "p";
14171 FormalParameter node =
14172 AstFactory.fieldFormalParameter(null, intTypeName, parameterName);
14173 node.identifier.staticElement =
14174 ElementFactory.requiredParameter(parameterName);
14175 expect(_resolveFormalParameter(node, [intType.element]), same(intType));
14176 _listener.assertNoErrors();
14177 }
14178
14179 void test_visitFunctionDeclaration() {
14180 // R f(P p) {}
14181 // class R {}
14182 // class P {}
14183 ClassElement elementR = ElementFactory.classElement2('R');
14184 ClassElement elementP = ElementFactory.classElement2('P');
14185 FunctionElement elementF = ElementFactory.functionElement('f');
14186 FunctionDeclaration declaration = AstFactory.functionDeclaration(
14187 AstFactory.typeName4('R'),
14188 null,
14189 'f',
14190 AstFactory.functionExpression2(
14191 AstFactory.formalParameterList([
14192 AstFactory.simpleFormalParameter4(AstFactory.typeName4('P'), 'p')
14193 ]),
14194 null));
14195 declaration.name.staticElement = elementF;
14196 _resolveNode(declaration, [elementR, elementP]);
14197 expect(declaration.returnType.type, elementR.type);
14198 SimpleFormalParameter parameter =
14199 declaration.functionExpression.parameters.parameters[0];
14200 expect(parameter.type.type, elementP.type);
14201 _listener.assertNoErrors();
14202 }
14203
14204 void test_visitFunctionDeclaration_typeParameter() {
14205 // E f<E>(E e) {}
14206 TypeParameterElement elementE = ElementFactory.typeParameterElement('E');
14207 FunctionElementImpl elementF = ElementFactory.functionElement('f');
14208 elementF.typeParameters = <TypeParameterElement>[elementE];
14209 FunctionDeclaration declaration = AstFactory.functionDeclaration(
14210 AstFactory.typeName4('E'),
14211 null,
14212 'f',
14213 AstFactory.functionExpression2(
14214 AstFactory.formalParameterList([
14215 AstFactory.simpleFormalParameter4(AstFactory.typeName4('E'), 'e')
14216 ]),
14217 null));
14218 declaration.name.staticElement = elementF;
14219 _resolveNode(declaration, []);
14220 expect(declaration.returnType.type, elementE.type);
14221 SimpleFormalParameter parameter =
14222 declaration.functionExpression.parameters.parameters[0];
14223 expect(parameter.type.type, elementE.type);
14224 _listener.assertNoErrors();
14225 }
14226
14227 void test_visitFunctionTypedFormalParameter() {
14228 // R f(R g(P p)) {}
14229 // class R {}
14230 // class P {}
14231 ClassElement elementR = ElementFactory.classElement2('R');
14232 ClassElement elementP = ElementFactory.classElement2('P');
14233 FunctionElement elementF = ElementFactory.functionElement('f');
14234 ParameterElementImpl requiredParameter =
14235 ElementFactory.requiredParameter('p');
14236 FunctionTypedFormalParameter parameterDeclaration = AstFactory
14237 .functionTypedFormalParameter(AstFactory.typeName4('R'), 'g', [
14238 AstFactory.simpleFormalParameter4(AstFactory.typeName4('P'), 'p')
14239 ]);
14240 parameterDeclaration.identifier.staticElement = requiredParameter;
14241 FunctionDeclaration declaration = AstFactory.functionDeclaration(
14242 AstFactory.typeName4('R'),
14243 null,
14244 'f',
14245 AstFactory.functionExpression2(
14246 AstFactory.formalParameterList([parameterDeclaration]), null));
14247 declaration.name.staticElement = elementF;
14248 _resolveNode(declaration, [elementR, elementP]);
14249 expect(declaration.returnType.type, elementR.type);
14250 FunctionTypedFormalParameter parameter =
14251 declaration.functionExpression.parameters.parameters[0];
14252 expect(parameter.returnType.type, elementR.type);
14253 SimpleFormalParameter innerParameter = parameter.parameters.parameters[0];
14254 expect(innerParameter.type.type, elementP.type);
14255 _listener.assertNoErrors();
14256 }
14257
14258 void test_visitFunctionTypedFormalParameter_typeParameter() {
14259 // R f(R g<E>(E e)) {}
14260 // class R {}
14261 ClassElement elementR = ElementFactory.classElement2('R');
14262 TypeParameterElement elementE = ElementFactory.typeParameterElement('E');
14263 FunctionElement elementF = ElementFactory.functionElement('f');
14264 ParameterElementImpl requiredParameter =
14265 ElementFactory.requiredParameter('g');
14266 requiredParameter.typeParameters = <TypeParameterElement>[elementE];
14267 FunctionTypedFormalParameter parameterDeclaration = AstFactory
14268 .functionTypedFormalParameter(AstFactory.typeName4('R'), 'g', [
14269 AstFactory.simpleFormalParameter4(AstFactory.typeName4('E'), 'e')
14270 ]);
14271 parameterDeclaration.identifier.staticElement = requiredParameter;
14272 FunctionDeclaration declaration = AstFactory.functionDeclaration(
14273 AstFactory.typeName4('R'),
14274 null,
14275 'f',
14276 AstFactory.functionExpression2(
14277 AstFactory.formalParameterList([parameterDeclaration]), null));
14278 declaration.name.staticElement = elementF;
14279 _resolveNode(declaration, [elementR]);
14280 expect(declaration.returnType.type, elementR.type);
14281 FunctionTypedFormalParameter parameter =
14282 declaration.functionExpression.parameters.parameters[0];
14283 expect(parameter.returnType.type, elementR.type);
14284 SimpleFormalParameter innerParameter = parameter.parameters.parameters[0];
14285 expect(innerParameter.type.type, elementE.type);
14286 _listener.assertNoErrors();
14287 }
14288
14289 void test_visitMethodDeclaration() {
14290 // class A {
14291 // R m(P p) {}
14292 // }
14293 // class R {}
14294 // class P {}
14295 ClassElementImpl elementA = ElementFactory.classElement2('A');
14296 ClassElement elementR = ElementFactory.classElement2('R');
14297 ClassElement elementP = ElementFactory.classElement2('P');
14298 MethodElement elementM = ElementFactory.methodElement('m', null);
14299 elementA.methods = <MethodElement>[elementM];
14300 MethodDeclaration declaration = AstFactory.methodDeclaration(
14301 null,
14302 AstFactory.typeName4('R'),
14303 null,
14304 null,
14305 AstFactory.identifier3('m'),
14306 AstFactory.formalParameterList([
14307 AstFactory.simpleFormalParameter4(AstFactory.typeName4('P'), 'p')
14308 ]));
14309 declaration.name.staticElement = elementM;
14310 _resolveNode(declaration, [elementA, elementR, elementP]);
14311 expect(declaration.returnType.type, elementR.type);
14312 SimpleFormalParameter parameter = declaration.parameters.parameters[0];
14313 expect(parameter.type.type, elementP.type);
14314 _listener.assertNoErrors();
14315 }
14316
14317 void test_visitMethodDeclaration_typeParameter() {
14318 // class A {
14319 // E m<E>(E e) {}
14320 // }
14321 ClassElementImpl elementA = ElementFactory.classElement2('A');
14322 TypeParameterElement elementE = ElementFactory.typeParameterElement('E');
14323 MethodElementImpl elementM = ElementFactory.methodElement('m', null);
14324 elementM.typeParameters = <TypeParameterElement>[elementE];
14325 elementA.methods = <MethodElement>[elementM];
14326 MethodDeclaration declaration = AstFactory.methodDeclaration(
14327 null,
14328 AstFactory.typeName4('E'),
14329 null,
14330 null,
14331 AstFactory.identifier3('m'),
14332 AstFactory.formalParameterList([
14333 AstFactory.simpleFormalParameter4(AstFactory.typeName4('E'), 'e')
14334 ]));
14335 declaration.name.staticElement = elementM;
14336 _resolveNode(declaration, [elementA]);
14337 expect(declaration.returnType.type, elementE.type);
14338 SimpleFormalParameter parameter = declaration.parameters.parameters[0];
14339 expect(parameter.type.type, elementE.type);
14340 _listener.assertNoErrors();
14341 }
14342
14343 void test_visitSimpleFormalParameter_noType() {
14344 // p
14345 FormalParameter node = AstFactory.simpleFormalParameter3("p");
14346 node.identifier.staticElement =
14347 new ParameterElementImpl.forNode(AstFactory.identifier3("p"));
14348 expect(_resolveFormalParameter(node), same(_typeProvider.dynamicType));
14349 _listener.assertNoErrors();
14350 }
14351
14352 void test_visitSimpleFormalParameter_type() {
14353 // int p
14354 InterfaceType intType = _typeProvider.intType;
14355 ClassElement intElement = intType.element;
14356 FormalParameter node =
14357 AstFactory.simpleFormalParameter4(AstFactory.typeName(intElement), "p");
14358 SimpleIdentifier identifier = node.identifier;
14359 ParameterElementImpl element = new ParameterElementImpl.forNode(identifier);
14360 identifier.staticElement = element;
14361 expect(_resolveFormalParameter(node, [intElement]), same(intType));
14362 _listener.assertNoErrors();
14363 }
14364
14365 void test_visitTypeName_noParameters_noArguments() {
14366 ClassElement classA = ElementFactory.classElement2("A");
14367 TypeName typeName = AstFactory.typeName(classA);
14368 typeName.type = null;
14369 _resolveNode(typeName, [classA]);
14370 expect(typeName.type, same(classA.type));
14371 _listener.assertNoErrors();
14372 }
14373
14374 void test_visitTypeName_parameters_arguments() {
14375 ClassElement classA = ElementFactory.classElement2("A", ["E"]);
14376 ClassElement classB = ElementFactory.classElement2("B");
14377 TypeName typeName =
14378 AstFactory.typeName(classA, [AstFactory.typeName(classB)]);
14379 typeName.type = null;
14380 _resolveNode(typeName, [classA, classB]);
14381 InterfaceType resultType = typeName.type as InterfaceType;
14382 expect(resultType.element, same(classA));
14383 List<DartType> resultArguments = resultType.typeArguments;
14384 expect(resultArguments, hasLength(1));
14385 expect(resultArguments[0], same(classB.type));
14386 _listener.assertNoErrors();
14387 }
14388
14389 void test_visitTypeName_parameters_noArguments() {
14390 ClassElement classA = ElementFactory.classElement2("A", ["E"]);
14391 TypeName typeName = AstFactory.typeName(classA);
14392 typeName.type = null;
14393 _resolveNode(typeName, [classA]);
14394 InterfaceType resultType = typeName.type as InterfaceType;
14395 expect(resultType.element, same(classA));
14396 List<DartType> resultArguments = resultType.typeArguments;
14397 expect(resultArguments, hasLength(1));
14398 expect(resultArguments[0], same(DynamicTypeImpl.instance));
14399 _listener.assertNoErrors();
14400 }
14401
14402 void test_visitTypeName_void() {
14403 ClassElement classA = ElementFactory.classElement2("A");
14404 TypeName typeName = AstFactory.typeName4("void");
14405 _resolveNode(typeName, [classA]);
14406 expect(typeName.type, same(VoidTypeImpl.instance));
14407 _listener.assertNoErrors();
14408 }
14409
14410 /**
14411 * Analyze the given catch clause and assert that the types of the parameters have been set to the
14412 * given types. The types can be null if the catch clause does not have the co rresponding
14413 * parameter.
14414 *
14415 * @param node the catch clause to be analyzed
14416 * @param exceptionType the expected type of the exception parameter
14417 * @param stackTraceType the expected type of the stack trace parameter
14418 * @param definedElements the elements that are to be defined in the scope in which the element is
14419 * being resolved
14420 */
14421 void _resolveCatchClause(
14422 CatchClause node, DartType exceptionType, InterfaceType stackTraceType,
14423 [List<Element> definedElements]) {
14424 _resolveNode(node, definedElements);
14425 SimpleIdentifier exceptionParameter = node.exceptionParameter;
14426 if (exceptionParameter != null) {
14427 expect(exceptionParameter.staticType, same(exceptionType));
14428 }
14429 SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
14430 if (stackTraceParameter != null) {
14431 expect(stackTraceParameter.staticType, same(stackTraceType));
14432 }
14433 }
14434
14435 /**
14436 * Return the type associated with the given parameter after the static type a nalyzer has computed
14437 * a type for it.
14438 *
14439 * @param node the parameter with which the type is associated
14440 * @param definedElements the elements that are to be defined in the scope in which the element is
14441 * being resolved
14442 * @return the type associated with the parameter
14443 */
14444 DartType _resolveFormalParameter(FormalParameter node,
14445 [List<Element> definedElements]) {
14446 _resolveNode(node, definedElements);
14447 return (node.identifier.staticElement as ParameterElement).type;
14448 }
14449
14450 /**
14451 * Return the element associated with the given identifier after the resolver has resolved the
14452 * identifier.
14453 *
14454 * @param node the expression to be resolved
14455 * @param definedElements the elements that are to be defined in the scope in which the element is
14456 * being resolved
14457 * @return the element to which the expression was resolved
14458 */
14459 void _resolveNode(AstNode node, [List<Element> definedElements]) {
14460 if (definedElements != null) {
14461 for (Element element in definedElements) {
14462 _library.libraryScope.define(element);
14463 }
14464 }
14465 node.accept(_visitor);
14466 }
14467 }
14468
14469 class _AnalysisContextFactory_initContextWithCore
14470 extends DirectoryBasedDartSdk {
14471 _AnalysisContextFactory_initContextWithCore(JavaFile arg0) : super(arg0);
14472
14473 @override
14474 LibraryMap initialLibraryMap(bool useDart2jsPaths) {
14475 LibraryMap map = new LibraryMap();
14476 _addLibrary(map, DartSdk.DART_ASYNC, false, "async.dart");
14477 _addLibrary(map, DartSdk.DART_CORE, false, "core.dart");
14478 _addLibrary(map, DartSdk.DART_HTML, false, "html_dartium.dart");
14479 _addLibrary(map, AnalysisContextFactory._DART_MATH, false, "math.dart");
14480 _addLibrary(map, AnalysisContextFactory._DART_INTERCEPTORS, true,
14481 "_interceptors.dart");
14482 _addLibrary(
14483 map, AnalysisContextFactory._DART_JS_HELPER, true, "_js_helper.dart");
14484 return map;
14485 }
14486
14487 void _addLibrary(LibraryMap map, String uri, bool isInternal, String path) {
14488 SdkLibraryImpl library = new SdkLibraryImpl(uri);
14489 if (isInternal) {
14490 library.category = "Internal";
14491 }
14492 library.path = path;
14493 map.setLibrary(uri, library);
14494 }
14495 }
14496
14497 class _SimpleResolverTest_localVariable_types_invoked
14498 extends RecursiveAstVisitor<Object> {
14499 final SimpleResolverTest test;
14500
14501 List<bool> found;
14502
14503 List<CaughtException> thrownException;
14504
14505 _SimpleResolverTest_localVariable_types_invoked(
14506 this.test, this.found, this.thrownException)
14507 : super();
14508
14509 @override
14510 Object visitSimpleIdentifier(SimpleIdentifier node) {
14511 if (node.name == "myVar" && node.parent is MethodInvocation) {
14512 try {
14513 found[0] = true;
14514 // check static type
14515 DartType staticType = node.staticType;
14516 expect(staticType, same(test.typeProvider.dynamicType));
14517 // check propagated type
14518 FunctionType propagatedType = node.propagatedType as FunctionType;
14519 expect(propagatedType.returnType, test.typeProvider.stringType);
14520 } on AnalysisException catch (e, stackTrace) {
14521 thrownException[0] = new CaughtException(e, stackTrace);
14522 }
14523 }
14524 return null;
14525 }
14526 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698