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

Unified Diff: pkg/analyzer/test/generated/resolver_test.dart

Issue 1782463002: Split resolver_test.dart into smaller files. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer/test/generated/resolver_test.dart
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index b51be7fd29ec97c53abb3da25a75eb60c498236f..4fe65162bea5621db6e60252c6751af51a5c7c73 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -13,56 +13,38 @@ import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/generated/element_resolver.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/java_core.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/java_engine_io.dart';
-import 'package:analyzer/src/generated/java_io.dart';
import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/static_type_analyzer.dart';
import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
-import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/string_source.dart';
import 'package:unittest/unittest.dart';
import '../reflective_tests.dart';
import '../utils.dart';
+import 'analysis_context_factory.dart';
+import 'resolver_test_case.dart';
import 'test_support.dart';
main() {
initializeTestEnvironment();
runReflectiveTests(AnalysisDeltaTest);
runReflectiveTests(ChangeSetTest);
- runReflectiveTests(CheckedModeCompileTimeErrorCodeTest);
runReflectiveTests(DisableAsyncTestCase);
- runReflectiveTests(ElementResolverTest);
runReflectiveTests(EnclosedScopeTest);
runReflectiveTests(ErrorResolverTest);
- runReflectiveTests(HintCodeTest);
- runReflectiveTests(InheritanceManagerTest);
runReflectiveTests(LibraryImportScopeTest);
runReflectiveTests(LibraryScopeTest);
runReflectiveTests(MemberMapTest);
- runReflectiveTests(NonHintCodeTest);
runReflectiveTests(ScopeTest);
- runReflectiveTests(SimpleResolverTest);
- runReflectiveTests(StaticTypeAnalyzerTest);
- runReflectiveTests(StaticTypeAnalyzer2Test);
runReflectiveTests(StrictModeTest);
- runReflectiveTests(StrongModeDownwardsInferenceTest);
- runReflectiveTests(StrongModeStaticTypeAnalyzer2Test);
- runReflectiveTests(StrongModeTypePropagationTest);
runReflectiveTests(SubtypeManagerTest);
runReflectiveTests(TypeOverrideManagerTest);
runReflectiveTests(TypePropagationTest);
@@ -70,490 +52,6 @@ main() {
runReflectiveTests(TypeResolverVisitorTest);
}
-/**
- * The class `AnalysisContextFactory` defines utility methods used to create analysis contexts
- * for testing purposes.
- */
-class AnalysisContextFactory {
- static String _DART_MATH = "dart:math";
-
- static String _DART_INTERCEPTORS = "dart:_interceptors";
-
- static String _DART_JS_HELPER = "dart:_js_helper";
-
- /**
- * Create an analysis context that has a fake core library already resolved.
- * Return the context that was created.
- */
- static InternalAnalysisContext contextWithCore() {
- AnalysisContextForTests context = new AnalysisContextForTests();
- return initContextWithCore(context);
- }
-
- /**
- * Create an analysis context that uses the given [options] and has a fake
- * core library already resolved. Return the context that was created.
- */
- static InternalAnalysisContext contextWithCoreAndOptions(
- AnalysisOptions options) {
- AnalysisContextForTests context = new AnalysisContextForTests();
- context._internalSetAnalysisOptions(options);
- return initContextWithCore(context);
- }
-
- static InternalAnalysisContext contextWithCoreAndPackages(
- Map<String, String> packages) {
- AnalysisContextForTests context = new AnalysisContextForTests();
- return initContextWithCore(context, new TestPackageUriResolver(packages));
- }
-
- /**
- * Initialize the given analysis context with a fake core library already resolved.
- *
- * @param context the context to be initialized (not `null`)
- * @return the analysis context that was created
- */
- static InternalAnalysisContext initContextWithCore(
- InternalAnalysisContext context,
- [UriResolver contributedResolver]) {
- DirectoryBasedDartSdk sdk = new _AnalysisContextFactory_initContextWithCore(
- new JavaFile("/fake/sdk"),
- enableAsync: context.analysisOptions.enableAsync);
- List<UriResolver> resolvers = <UriResolver>[
- new DartUriResolver(sdk),
- new FileUriResolver()
- ];
- if (contributedResolver != null) {
- resolvers.add(contributedResolver);
- }
- SourceFactory sourceFactory = new SourceFactory(resolvers);
- context.sourceFactory = sourceFactory;
- AnalysisContext coreContext = sdk.context;
- (coreContext.analysisOptions as AnalysisOptionsImpl).strongMode =
- context.analysisOptions.strongMode;
- //
- // dart:core
- //
- TestTypeProvider provider = new TestTypeProvider();
- CompilationUnitElementImpl coreUnit =
- new CompilationUnitElementImpl("core.dart");
- Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE);
- coreContext.setContents(coreSource, "");
- coreUnit.librarySource = coreUnit.source = coreSource;
- ClassElementImpl proxyClassElement = ElementFactory.classElement2("_Proxy");
- proxyClassElement.constructors = <ConstructorElement>[
- ElementFactory.constructorElement(proxyClassElement, '', true)
- ..isCycleFree = true
- ..constantInitializers = <ConstructorInitializer>[]
- ];
- ClassElement objectClassElement = provider.objectType.element;
- coreUnit.types = <ClassElement>[
- provider.boolType.element,
- provider.deprecatedType.element,
- provider.doubleType.element,
- provider.functionType.element,
- provider.intType.element,
- provider.iterableType.element,
- provider.iteratorType.element,
- provider.listType.element,
- provider.mapType.element,
- provider.nullType.element,
- provider.numType.element,
- objectClassElement,
- proxyClassElement,
- provider.stackTraceType.element,
- provider.stringType.element,
- provider.symbolType.element,
- provider.typeType.element
- ];
- coreUnit.functions = <FunctionElement>[
- ElementFactory.functionElement3("identical", provider.boolType.element,
- <ClassElement>[objectClassElement, objectClassElement], null),
- ElementFactory.functionElement3("print", VoidTypeImpl.instance.element,
- <ClassElement>[objectClassElement], null)
- ];
- TopLevelVariableElement proxyTopLevelVariableElt = ElementFactory
- .topLevelVariableElement3("proxy", true, false, proxyClassElement.type);
- ConstTopLevelVariableElementImpl deprecatedTopLevelVariableElt =
- ElementFactory.topLevelVariableElement3(
- "deprecated", true, false, provider.deprecatedType);
- {
- ClassElement deprecatedElement = provider.deprecatedType.element;
- InstanceCreationExpression initializer = AstFactory
- .instanceCreationExpression2(
- Keyword.CONST,
- AstFactory.typeName(deprecatedElement),
- [AstFactory.string2('next release')]);
- ConstructorElement constructor = deprecatedElement.constructors.single;
- initializer.staticElement = constructor;
- initializer.constructorName.staticElement = constructor;
- deprecatedTopLevelVariableElt.constantInitializer = initializer;
- }
- coreUnit.accessors = <PropertyAccessorElement>[
- proxyTopLevelVariableElt.getter,
- deprecatedTopLevelVariableElt.getter
- ];
- coreUnit.topLevelVariables = <TopLevelVariableElement>[
- proxyTopLevelVariableElt,
- deprecatedTopLevelVariableElt
- ];
- LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
- coreContext, AstFactory.libraryIdentifier2(["dart", "core"]));
- coreLibrary.definingCompilationUnit = coreUnit;
- //
- // dart:async
- //
- Source asyncSource;
- LibraryElementImpl asyncLibrary;
- if (context.analysisOptions.enableAsync) {
- asyncLibrary = new LibraryElementImpl.forNode(
- coreContext, AstFactory.libraryIdentifier2(["dart", "async"]));
- CompilationUnitElementImpl asyncUnit =
- new CompilationUnitElementImpl("async.dart");
- asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
- coreContext.setContents(asyncSource, "");
- asyncUnit.librarySource = asyncUnit.source = asyncSource;
- asyncLibrary.definingCompilationUnit = asyncUnit;
- // Future
- ClassElementImpl futureElement =
- ElementFactory.classElement2("Future", ["T"]);
- futureElement.enclosingElement = asyncUnit;
- // factory Future.value([value])
- ConstructorElementImpl futureConstructor =
- ElementFactory.constructorElement2(futureElement, "value");
- futureConstructor.parameters = <ParameterElement>[
- ElementFactory.positionalParameter2("value", provider.dynamicType)
- ];
- futureConstructor.factory = true;
- futureElement.constructors = <ConstructorElement>[futureConstructor];
- // Future then(onValue(T value), { Function onError });
- TypeDefiningElement futureThenR = DynamicElementImpl.instance;
- if (context.analysisOptions.strongMode) {
- futureThenR = ElementFactory.typeParameterWithType('R');
- }
- FunctionElementImpl thenOnValue = ElementFactory.functionElement3(
- 'onValue', futureThenR, [futureElement.typeParameters[0]], null);
- thenOnValue.synthetic = true;
-
- DartType futureRType = futureElement.type.instantiate([futureThenR.type]);
- MethodElementImpl thenMethod = ElementFactory
- .methodElementWithParameters(futureElement, "then", futureRType, [
- ElementFactory.requiredParameter2("onValue", thenOnValue.type),
- ElementFactory.namedParameter2("onError", provider.functionType)
- ]);
- if (!futureThenR.type.isDynamic) {
- thenMethod.typeParameters = [futureThenR];
- }
- thenOnValue.enclosingElement = thenMethod;
- thenOnValue.type = new FunctionTypeImpl(thenOnValue);
- (thenMethod.parameters[0] as ParameterElementImpl).type =
- thenOnValue.type;
- thenMethod.type = new FunctionTypeImpl(thenMethod);
-
- futureElement.methods = <MethodElement>[thenMethod];
- // Completer
- ClassElementImpl completerElement =
- ElementFactory.classElement2("Completer", ["T"]);
- ConstructorElementImpl completerConstructor =
- ElementFactory.constructorElement2(completerElement, null);
- completerElement.constructors = <ConstructorElement>[
- completerConstructor
- ];
- // StreamSubscription
- ClassElementImpl streamSubscriptionElement =
- ElementFactory.classElement2("StreamSubscription", ["T"]);
- // Stream
- ClassElementImpl streamElement =
- ElementFactory.classElement2("Stream", ["T"]);
- streamElement.constructors = <ConstructorElement>[
- ElementFactory.constructorElement2(streamElement, null)
- ];
- DartType returnType = streamSubscriptionElement.type
- .instantiate(streamElement.type.typeArguments);
- FunctionElementImpl listenOnData = ElementFactory.functionElement3(
- 'onData',
- VoidTypeImpl.instance.element,
- <TypeDefiningElement>[streamElement.typeParameters[0]],
- null);
- listenOnData.synthetic = true;
- List<DartType> parameterTypes = <DartType>[listenOnData.type,];
- // TODO(brianwilkerson) This is missing the optional parameters.
- MethodElementImpl listenMethod =
- ElementFactory.methodElement('listen', returnType, parameterTypes);
- streamElement.methods = <MethodElement>[listenMethod];
- listenMethod.type = new FunctionTypeImpl(listenMethod);
-
- FunctionElementImpl listenParamFunction = parameterTypes[0].element;
- listenParamFunction.enclosingElement = listenMethod;
- listenParamFunction.type = new FunctionTypeImpl(listenParamFunction);
- ParameterElementImpl listenParam = listenMethod.parameters[0];
- listenParam.type = listenParamFunction.type;
-
- asyncUnit.types = <ClassElement>[
- completerElement,
- futureElement,
- streamElement,
- streamSubscriptionElement
- ];
- }
- //
- // dart:html
- //
- CompilationUnitElementImpl htmlUnit =
- new CompilationUnitElementImpl("html_dartium.dart");
- Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
- coreContext.setContents(htmlSource, "");
- htmlUnit.librarySource = htmlUnit.source = htmlSource;
- ClassElementImpl elementElement = ElementFactory.classElement2("Element");
- InterfaceType elementType = elementElement.type;
- ClassElementImpl canvasElement =
- ElementFactory.classElement("CanvasElement", elementType);
- ClassElementImpl contextElement =
- ElementFactory.classElement2("CanvasRenderingContext");
- InterfaceType contextElementType = contextElement.type;
- ClassElementImpl context2dElement = ElementFactory.classElement(
- "CanvasRenderingContext2D", contextElementType);
- canvasElement.methods = <MethodElement>[
- ElementFactory.methodElement(
- "getContext", contextElementType, [provider.stringType])
- ];
- canvasElement.accessors = <PropertyAccessorElement>[
- ElementFactory.getterElement("context2D", false, context2dElement.type)
- ];
- canvasElement.fields = canvasElement.accessors
- .map((PropertyAccessorElement accessor) => accessor.variable)
- .toList();
- ClassElementImpl documentElement =
- ElementFactory.classElement("Document", elementType);
- ClassElementImpl htmlDocumentElement =
- ElementFactory.classElement("HtmlDocument", documentElement.type);
- htmlDocumentElement.methods = <MethodElement>[
- ElementFactory
- .methodElement("query", elementType, <DartType>[provider.stringType])
- ];
- htmlUnit.types = <ClassElement>[
- ElementFactory.classElement("AnchorElement", elementType),
- ElementFactory.classElement("BodyElement", elementType),
- ElementFactory.classElement("ButtonElement", elementType),
- canvasElement,
- contextElement,
- context2dElement,
- ElementFactory.classElement("DivElement", elementType),
- documentElement,
- elementElement,
- htmlDocumentElement,
- ElementFactory.classElement("InputElement", elementType),
- ElementFactory.classElement("SelectElement", elementType)
- ];
- htmlUnit.functions = <FunctionElement>[
- ElementFactory.functionElement3("query", elementElement,
- <ClassElement>[provider.stringType.element], ClassElement.EMPTY_LIST)
- ];
- TopLevelVariableElementImpl document =
- ElementFactory.topLevelVariableElement3(
- "document", false, true, htmlDocumentElement.type);
- htmlUnit.topLevelVariables = <TopLevelVariableElement>[document];
- htmlUnit.accessors = <PropertyAccessorElement>[document.getter];
- LibraryElementImpl htmlLibrary = new LibraryElementImpl.forNode(
- coreContext, AstFactory.libraryIdentifier2(["dart", "dom", "html"]));
- htmlLibrary.definingCompilationUnit = htmlUnit;
- //
- // dart:math
- //
- CompilationUnitElementImpl mathUnit =
- new CompilationUnitElementImpl("math.dart");
- Source mathSource = sourceFactory.forUri(_DART_MATH);
- coreContext.setContents(mathSource, "");
- mathUnit.librarySource = mathUnit.source = mathSource;
- FunctionElement cosElement = ElementFactory.functionElement3(
- "cos",
- provider.doubleType.element,
- <ClassElement>[provider.numType.element],
- ClassElement.EMPTY_LIST);
- TopLevelVariableElement ln10Element = ElementFactory
- .topLevelVariableElement3("LN10", true, false, provider.doubleType);
- TypeParameterElement maxT =
- ElementFactory.typeParameterWithType('T', provider.numType);
- FunctionElementImpl maxElement = ElementFactory.functionElement3(
- "max", maxT, [maxT, maxT], ClassElement.EMPTY_LIST);
- maxElement.typeParameters = [maxT];
- maxElement.type = new FunctionTypeImpl(maxElement);
- TopLevelVariableElement piElement = ElementFactory.topLevelVariableElement3(
- "PI", true, false, provider.doubleType);
- ClassElementImpl randomElement = ElementFactory.classElement2("Random");
- randomElement.abstract = true;
- ConstructorElementImpl randomConstructor =
- ElementFactory.constructorElement2(randomElement, null);
- randomConstructor.factory = true;
- ParameterElementImpl seedParam = new ParameterElementImpl("seed", 0);
- seedParam.parameterKind = ParameterKind.POSITIONAL;
- seedParam.type = provider.intType;
- randomConstructor.parameters = <ParameterElement>[seedParam];
- randomElement.constructors = <ConstructorElement>[randomConstructor];
- FunctionElement sinElement = ElementFactory.functionElement3(
- "sin",
- provider.doubleType.element,
- <ClassElement>[provider.numType.element],
- ClassElement.EMPTY_LIST);
- FunctionElement sqrtElement = ElementFactory.functionElement3(
- "sqrt",
- provider.doubleType.element,
- <ClassElement>[provider.numType.element],
- ClassElement.EMPTY_LIST);
- mathUnit.accessors = <PropertyAccessorElement>[
- ln10Element.getter,
- piElement.getter
- ];
- mathUnit.functions = <FunctionElement>[
- cosElement,
- maxElement,
- sinElement,
- sqrtElement
- ];
- mathUnit.topLevelVariables = <TopLevelVariableElement>[
- ln10Element,
- piElement
- ];
- mathUnit.types = <ClassElement>[randomElement];
- LibraryElementImpl mathLibrary = new LibraryElementImpl.forNode(
- coreContext, AstFactory.libraryIdentifier2(["dart", "math"]));
- mathLibrary.definingCompilationUnit = mathUnit;
- //
- // Set empty sources for the rest of the libraries.
- //
- Source source = sourceFactory.forUri(_DART_INTERCEPTORS);
- coreContext.setContents(source, "");
- source = sourceFactory.forUri(_DART_JS_HELPER);
- coreContext.setContents(source, "");
- //
- // Record the elements.
- //
- HashMap<Source, LibraryElement> elementMap =
- new HashMap<Source, LibraryElement>();
- elementMap[coreSource] = coreLibrary;
- if (asyncSource != null) {
- elementMap[asyncSource] = asyncLibrary;
- }
- elementMap[htmlSource] = htmlLibrary;
- elementMap[mathSource] = mathLibrary;
- //
- // Set the public and export namespaces. We don't use exports in the fake
- // core library so public and export namespaces are the same.
- //
- for (LibraryElementImpl library in elementMap.values) {
- Namespace namespace =
- new NamespaceBuilder().createPublicNamespaceForLibrary(library);
- library.exportNamespace = namespace;
- library.publicNamespace = namespace;
- }
- context.recordLibraryElements(elementMap);
- // Create the synthetic element for `loadLibrary`.
- for (LibraryElementImpl library in elementMap.values) {
- library.createLoadLibraryFunction(context.typeProvider);
- }
- return context;
- }
-}
-
-/**
- * An analysis context that has a fake SDK that is much smaller and faster for
- * testing purposes.
- */
-class AnalysisContextForTests extends AnalysisContextImpl {
- @override
- void set analysisOptions(AnalysisOptions options) {
- AnalysisOptions currentOptions = analysisOptions;
- bool needsRecompute = currentOptions.analyzeFunctionBodiesPredicate !=
- options.analyzeFunctionBodiesPredicate ||
- currentOptions.generateImplicitErrors !=
- options.generateImplicitErrors ||
- currentOptions.generateSdkErrors != options.generateSdkErrors ||
- currentOptions.dart2jsHint != options.dart2jsHint ||
- (currentOptions.hint && !options.hint) ||
- currentOptions.preserveComments != options.preserveComments ||
- currentOptions.enableStrictCallChecks != options.enableStrictCallChecks;
- if (needsRecompute) {
- fail(
- "Cannot set options that cause the sources to be reanalyzed in a test context");
- }
- super.analysisOptions = options;
- }
-
- @override
- bool exists(Source source) =>
- super.exists(source) || sourceFactory.dartSdk.context.exists(source);
-
- @override
- TimestampedData<String> getContents(Source source) {
- if (source.isInSystemLibrary) {
- return sourceFactory.dartSdk.context.getContents(source);
- }
- return super.getContents(source);
- }
-
- @override
- int getModificationStamp(Source source) {
- if (source.isInSystemLibrary) {
- return sourceFactory.dartSdk.context.getModificationStamp(source);
- }
- return super.getModificationStamp(source);
- }
-
- /**
- * Set the analysis options, even if they would force re-analysis. This method should only be
- * invoked before the fake SDK is initialized.
- *
- * @param options the analysis options to be set
- */
- void _internalSetAnalysisOptions(AnalysisOptions options) {
- super.analysisOptions = options;
- }
-}
-
-/**
- * Helper for creating and managing single [AnalysisContext].
- */
-class AnalysisContextHelper {
- AnalysisContext context;
-
- /**
- * Creates new [AnalysisContext] using [AnalysisContextFactory].
- */
- AnalysisContextHelper([AnalysisOptionsImpl options]) {
- if (options == null) {
- options = new AnalysisOptionsImpl();
- }
- options.cacheSize = 256;
- context = AnalysisContextFactory.contextWithCoreAndOptions(options);
- }
-
- Source addSource(String path, String code) {
- Source source = new FileBasedSource(FileUtilities2.createFile(path));
- if (path.endsWith(".dart") || path.endsWith(".html")) {
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source);
- context.applyChanges(changeSet);
- }
- context.setContents(source, code);
- return source;
- }
-
- CompilationUnitElement getDefiningUnitElement(Source source) =>
- context.getCompilationUnitElement(source, source);
-
- CompilationUnit resolveDefiningUnit(Source source) {
- LibraryElement libraryElement = context.computeLibraryElement(source);
- return context.resolveCompilationUnit(source, libraryElement);
- }
-
- void runTasks() {
- AnalysisResult result = context.performAnalysisTask();
- while (result.changeNotices != null) {
- result = context.performAnalysisTask();
- }
- }
-}
-
@reflectiveTest
class AnalysisDeltaTest extends EngineTestCase {
TestSource source1 = new TestSource('/1.dart');
@@ -648,14075 +146,896 @@ class ChangeSetTest extends EngineTestCase {
}
@reflectiveTest
-class CheckedModeCompileTimeErrorCodeTest extends ResolverTestCase {
- void test_fieldFormalParameterAssignableToField_extends() {
- // According to checked-mode type checking rules, a value of type B is
- // assignable to a field of type A, because B extends A (and hence is a
- // subtype of A).
- Source source = addSource(r'''
-class A {
- const A();
-}
-class B extends A {
- const B();
-}
-class C {
- final A a;
- const C(this.a);
-}
-var v = const C(const B());''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
+class DisableAsyncTestCase extends ResolverTestCase {
+ @override
+ void setUp() {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableAsync = false;
+ resetWithOptions(options);
}
- void test_fieldFormalParameterAssignableToField_fieldType_unresolved_null() {
- // Null always passes runtime type checks, even when the type is
- // unresolved.
+ void test_resolve() {
Source source = addSource(r'''
-class A {
- final Unresolved x;
- const A(String this.x);
-}
-var v = const A(null);''');
+class C {
+ foo() {
+ bar();
+ }
+ bar() {
+ //
+ }
+}''');
computeLibrarySourceErrors(source);
- assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
- verify([source]);
+ assertErrors(source, []);
}
- void test_fieldFormalParameterAssignableToField_implements() {
- // According to checked-mode type checking rules, a value of type B is
- // assignable to a field of type A, because B implements A (and hence is a
- // subtype of A).
+ void test_resolve_async() {
Source source = addSource(r'''
-class A {}
-class B implements A {
- const B();
-}
class C {
- final A a;
- const C(this.a);
-}
-var v = const C(const B());''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
+ Future foo() async {
+ await bar();
+ return null;
}
-
- void test_fieldFormalParameterAssignableToField_list_dynamic() {
- // [1, 2, 3] has type List<dynamic>, which is a subtype of List<int>.
- Source source = addSource(r'''
-class A {
- const A(List<int> x);
-}
-var x = const A(const [1, 2, 3]);''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
+ Future bar() {
+ return new Future.delayed(new Duration(milliseconds: 10));
}
-
- void test_fieldFormalParameterAssignableToField_list_nonDynamic() {
- // <int>[1, 2, 3] has type List<int>, which is a subtype of List<num>.
- Source source = addSource(r'''
-class A {
- const A(List<num> x);
-}
-var x = const A(const <int>[1, 2, 3]);''');
+}''');
computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
+ assertErrors(source, [
+ StaticWarningCode.UNDEFINED_CLASS,
+ StaticWarningCode.UNDEFINED_CLASS,
+ StaticWarningCode.UNDEFINED_CLASS,
+ StaticWarningCode.UNDEFINED_CLASS,
+ ParserErrorCode.ASYNC_NOT_SUPPORTED
+ ]);
}
-
- void test_fieldFormalParameterAssignableToField_map_dynamic() {
- // {1: 2} has type Map<dynamic, dynamic>, which is a subtype of
- // Map<int, int>.
- Source source = addSource(r'''
-class A {
- const A(Map<int, int> x);
}
-var x = const A(const {1: 2});''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
- void test_fieldFormalParameterAssignableToField_map_keyDifferent() {
- // <int, int>{1: 2} has type Map<int, int>, which is a subtype of
- // Map<num, int>.
- Source source = addSource(r'''
-class A {
- const A(Map<num, int> x);
-}
-var x = const A(const <int, int>{1: 2});''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
+@reflectiveTest
+class EnclosedScopeTest extends ResolverTestCase {
+ void test_define_duplicate() {
+ GatheringErrorListener listener = new GatheringErrorListener();
+ Scope rootScope =
+ new Scope_EnclosedScopeTest_test_define_duplicate(listener);
+ EnclosedScope scope = new EnclosedScope(rootScope);
+ VariableElement element1 =
+ ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
+ VariableElement element2 =
+ ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
+ scope.define(element1);
+ scope.define(element2);
+ listener.assertErrorsWithSeverities([ErrorSeverity.ERROR]);
}
- void test_fieldFormalParameterAssignableToField_map_valueDifferent() {
- // <int, int>{1: 2} has type Map<int, int>, which is a subtype of
- // Map<int, num>.
- Source source = addSource(r'''
-class A {
- const A(Map<int, num> x);
-}
-var x = const A(const <int, int>{1: 2});''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
+ void test_define_normal() {
+ GatheringErrorListener listener = new GatheringErrorListener();
+ Scope rootScope = new Scope_EnclosedScopeTest_test_define_normal(listener);
+ EnclosedScope outerScope = new EnclosedScope(rootScope);
+ EnclosedScope innerScope = new EnclosedScope(outerScope);
+ VariableElement element1 =
+ ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
+ VariableElement element2 =
+ ElementFactory.localVariableElement(AstFactory.identifier3("v2"));
+ outerScope.define(element1);
+ innerScope.define(element2);
+ listener.assertNoErrors();
}
-
- void test_fieldFormalParameterAssignableToField_notype() {
- // If a field is declared without a type, then any value may be assigned to
- // it.
- Source source = addSource(r'''
-class A {
- final x;
- const A(this.x);
}
-var v = const A(5);''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
- void test_fieldFormalParameterAssignableToField_null() {
- // Null is assignable to anything.
+@reflectiveTest
+class ErrorResolverTest extends ResolverTestCase {
+ void test_breakLabelOnSwitchMember() {
Source source = addSource(r'''
class A {
- final int x;
- const A(this.x);
-}
-var v = const A(null);''');
+ void m(int i) {
+ switch (i) {
+ l: case 0:
+ break;
+ case 1:
+ break l;
+ }
+ }
+}''');
computeLibrarySourceErrors(source);
- assertNoErrors(source);
+ assertErrors(source, [ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER]);
verify([source]);
}
- void test_fieldFormalParameterAssignableToField_typedef() {
- // foo has the runtime type dynamic -> dynamic, so it should be assignable
- // to A.f.
+ void test_continueLabelOnSwitch() {
Source source = addSource(r'''
-typedef String Int2String(int x);
class A {
- final Int2String f;
- const A(this.f);
-}
-foo(x) => 1;
-var v = const A(foo);''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
+ void m(int i) {
+ l: switch (i) {
+ case 0:
+ continue l;
+ }
}
-
- void test_fieldFormalParameterAssignableToField_typeSubstitution() {
- // foo has the runtime type dynamic -> dynamic, so it should be assignable
- // to A.f.
- Source source = addSource(r'''
-class A<T> {
- final T x;
- const A(this.x);
-}
-var v = const A<int>(3);''');
+}''');
computeLibrarySourceErrors(source);
- assertNoErrors(source);
+ assertErrors(source, [ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH]);
verify([source]);
}
- void test_fieldFormalParameterNotAssignableToField() {
+ void test_enclosingElement_invalidLocalFunction() {
Source source = addSource(r'''
-class A {
- final int x;
- const A(this.x);
-}
-var v = const A('foo');''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_extends() {
- // According to checked-mode type checking rules, a value of type A is not
- // assignable to a field of type B, because B extends A (the subtyping
- // relationship is in the wrong direction).
- Source source = addSource(r'''
-class A {
- const A();
-}
-class B extends A {
- const B();
-}
-class C {
- final B b;
- const C(this.b);
-}
-var v = const C(const A());''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_fieldType() {
- Source source = addSource(r'''
-class A {
- final int x;
- const A(String this.x);
-}
-var v = const A('foo');''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_fieldType_unresolved() {
- Source source = addSource(r'''
-class A {
- final Unresolved x;
- const A(String this.x);
-}
-var v = const A('foo');''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- StaticWarningCode.UNDEFINED_CLASS
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_implements() {
- // According to checked-mode type checking rules, a value of type A is not
- // assignable to a field of type B, because B implements A (the subtyping
- // relationship is in the wrong direction).
- Source source = addSource(r'''
-class A {
- const A();
-}
-class B implements A {}
-class C {
- final B b;
- const C(this.b);
-}
-var v = const C(const A());''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_list() {
- // <num>[1, 2, 3] has type List<num>, which is not a subtype of List<int>.
- Source source = addSource(r'''
-class A {
- const A(List<int> x);
-}
-var x = const A(const <num>[1, 2, 3]);''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_map_keyMismatch() {
- // <num, int>{1: 2} has type Map<num, int>, which is not a subtype of
- // Map<int, int>.
- Source source = addSource(r'''
-class A {
- const A(Map<int, int> x);
-}
-var x = const A(const <num, int>{1: 2});''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_map_valueMismatch() {
- // <int, num>{1: 2} has type Map<int, num>, which is not a subtype of
- // Map<int, int>.
- Source source = addSource(r'''
-class A {
- const A(Map<int, int> x);
-}
-var x = const A(const <int, num>{1: 2});''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_optional() {
- Source source = addSource(r'''
-class A {
- final int x;
- const A([this.x = 'foo']);
-}
-var v = const A();''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- StaticTypeWarningCode.INVALID_ASSIGNMENT
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_typedef() {
- // foo has the runtime type String -> int, so it should not be assignable
- // to A.f (A.f requires it to be int -> String).
- Source source = addSource(r'''
-typedef String Int2String(int x);
-class A {
- final Int2String f;
- const A(this.f);
-}
-int foo(String x) => 1;
-var v = const A(foo);''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_fieldInitializerNotAssignable() {
- Source source = addSource(r'''
-class A {
- final int x;
- const A() : x = '';
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
- StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_fieldTypeMismatch() {
- Source source = addSource(r'''
-class A {
- const A(x) : y = x;
- final int y;
-}
-var v = const A('foo');''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
- ]);
- verify([source]);
- }
-
- void test_fieldTypeMismatch_generic() {
- Source source = addSource(r'''
-class C<T> {
- final T x = y;
- const C();
-}
-const int y = 1;
-var v = const C<String>();
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
- StaticTypeWarningCode.INVALID_ASSIGNMENT
- ]);
- verify([source]);
- }
-
- void test_fieldTypeMismatch_unresolved() {
- Source source = addSource(r'''
-class A {
- const A(x) : y = x;
- final Unresolved y;
-}
-var v = const A('foo');''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
- StaticWarningCode.UNDEFINED_CLASS
- ]);
- verify([source]);
- }
-
- void test_fieldTypeOk_generic() {
- Source source = addSource(r'''
-class C<T> {
- final T x = y;
- const C();
-}
-const int y = 1;
-var v = const C<int>();
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
- verify([source]);
- }
-
- void test_fieldTypeOk_null() {
- Source source = addSource(r'''
-class A {
- const A(x) : y = x;
- final int y;
-}
-var v = const A(null);''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_fieldTypeOk_unresolved_null() {
- // Null always passes runtime type checks, even when the type is
- // unresolved.
- Source source = addSource(r'''
-class A {
- const A(x) : y = x;
- final Unresolved y;
-}
-var v = const A(null);''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
- verify([source]);
- }
-
- void test_listElementTypeNotAssignable() {
- Source source = addSource("var v = const <String> [42];");
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
- StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_mapKeyTypeNotAssignable() {
- Source source = addSource("var v = const <String, int > {1 : 2};");
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
- StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_mapValueTypeNotAssignable() {
- Source source = addSource("var v = const <String, String> {'a' : 2};");
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
- StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_parameterAssignable_null() {
- // Null is assignable to anything.
- Source source = addSource(r'''
-class A {
- const A(int x);
-}
-var v = const A(null);''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_parameterAssignable_typeSubstitution() {
- Source source = addSource(r'''
-class A<T> {
- const A(T x);
-}
-var v = const A<int>(3);''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_parameterAssignable_undefined_null() {
- // Null always passes runtime type checks, even when the type is
- // unresolved.
- Source source = addSource(r'''
-class A {
- const A(Unresolved x);
-}
-var v = const A(null);''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
- verify([source]);
- }
-
- void test_parameterNotAssignable() {
- Source source = addSource(r'''
-class A {
- const A(int x);
-}
-var v = const A('foo');''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_parameterNotAssignable_typeSubstitution() {
- Source source = addSource(r'''
-class A<T> {
- const A(T x);
-}
-var v = const A<int>('foo');''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_parameterNotAssignable_undefined() {
- Source source = addSource(r'''
-class A {
- const A(Unresolved x);
-}
-var v = const A('foo');''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- StaticWarningCode.UNDEFINED_CLASS
- ]);
- verify([source]);
- }
-
- void test_redirectingConstructor_paramTypeMismatch() {
- Source source = addSource(r'''
-class A {
- const A.a1(x) : this.a2(x);
- const A.a2(String x);
-}
-var v = const A.a1(0);''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
- ]);
- verify([source]);
- }
-
- void test_topLevelVarAssignable_null() {
- Source source = addSource("const int x = null;");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_topLevelVarAssignable_undefined_null() {
- // Null always passes runtime type checks, even when the type is
- // unresolved.
- Source source = addSource("const Unresolved x = null;");
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
- verify([source]);
- }
-
- void test_topLevelVarNotAssignable() {
- Source source = addSource("const int x = 'foo';");
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
- StaticTypeWarningCode.INVALID_ASSIGNMENT
- ]);
- verify([source]);
- }
-
- void test_topLevelVarNotAssignable_undefined() {
- Source source = addSource("const Unresolved x = 'foo';");
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
- StaticWarningCode.UNDEFINED_CLASS
- ]);
- verify([source]);
- }
-}
-
-@reflectiveTest
-class DisableAsyncTestCase extends ResolverTestCase {
- @override
- void setUp() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.enableAsync = false;
- resetWithOptions(options);
- }
-
- void test_resolve() {
- Source source = addSource(r'''
-class C {
- foo() {
- bar();
- }
- bar() {
- //
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- }
-
- void test_resolve_async() {
- Source source = addSource(r'''
-class C {
- Future foo() async {
- await bar();
- return null;
- }
- Future bar() {
- return new Future.delayed(new Duration(milliseconds: 10));
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- StaticWarningCode.UNDEFINED_CLASS,
- StaticWarningCode.UNDEFINED_CLASS,
- StaticWarningCode.UNDEFINED_CLASS,
- StaticWarningCode.UNDEFINED_CLASS,
- ParserErrorCode.ASYNC_NOT_SUPPORTED
- ]);
- }
-}
-
-@reflectiveTest
-class ElementResolverTest extends EngineTestCase {
- /**
- * The error listener to which errors will be reported.
- */
- GatheringErrorListener _listener;
-
- /**
- * The type provider used to access the types.
- */
- TestTypeProvider _typeProvider;
-
- /**
- * The library containing the code being resolved.
- */
- LibraryElementImpl _definingLibrary;
-
- /**
- * The resolver visitor that maintains the state for the resolver.
- */
- ResolverVisitor _visitor;
-
- /**
- * The resolver being used to resolve the test cases.
- */
- ElementResolver _resolver;
-
- void fail_visitExportDirective_combinators() {
- fail("Not yet tested");
- // Need to set up the exported library so that the identifier can be
- // resolved.
- ExportDirective directive = AstFactory.exportDirective2(null, [
- AstFactory.hideCombinator2(["A"])
- ]);
- _resolveNode(directive);
- _listener.assertNoErrors();
- }
-
- void fail_visitFunctionExpressionInvocation() {
- fail("Not yet tested");
- _listener.assertNoErrors();
- }
-
- void fail_visitImportDirective_combinators_noPrefix() {
- fail("Not yet tested");
- // Need to set up the imported library so that the identifier can be
- // resolved.
- ImportDirective directive = AstFactory.importDirective3(null, null, [
- AstFactory.showCombinator2(["A"])
- ]);
- _resolveNode(directive);
- _listener.assertNoErrors();
- }
-
- void fail_visitImportDirective_combinators_prefix() {
- fail("Not yet tested");
- // Need to set up the imported library so that the identifiers can be
- // resolved.
- String prefixName = "p";
- _definingLibrary.imports = <ImportElement>[
- ElementFactory.importFor(null, ElementFactory.prefix(prefixName))
- ];
- ImportDirective directive = AstFactory.importDirective3(null, prefixName, [
- AstFactory.showCombinator2(["A"]),
- AstFactory.hideCombinator2(["B"])
- ]);
- _resolveNode(directive);
- _listener.assertNoErrors();
- }
-
- void fail_visitRedirectingConstructorInvocation() {
- fail("Not yet tested");
- _listener.assertNoErrors();
- }
-
- @override
- void setUp() {
- super.setUp();
- _listener = new GatheringErrorListener();
- _typeProvider = new TestTypeProvider();
- _resolver = _createResolver();
- }
-
- void test_lookUpMethodInInterfaces() {
- InterfaceType intType = _typeProvider.intType;
- //
- // abstract class A { int operator[](int index); }
- //
- ClassElementImpl classA = ElementFactory.classElement2("A");
- MethodElement operator =
- ElementFactory.methodElement("[]", intType, [intType]);
- classA.methods = <MethodElement>[operator];
- //
- // class B implements A {}
- //
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- //
- // class C extends Object with B {}
- //
- ClassElementImpl classC = ElementFactory.classElement2("C");
- classC.mixins = <InterfaceType>[classB.type];
- //
- // class D extends C {}
- //
- ClassElementImpl classD = ElementFactory.classElement("D", classC.type);
- //
- // D a;
- // a[i];
- //
- SimpleIdentifier array = AstFactory.identifier3("a");
- array.staticType = classD.type;
- IndexExpression expression =
- AstFactory.indexExpression(array, AstFactory.identifier3("i"));
- expect(_resolveIndexExpression(expression), same(operator));
- _listener.assertNoErrors();
- }
-
- void test_visitAssignmentExpression_compound() {
- InterfaceType intType = _typeProvider.intType;
- SimpleIdentifier leftHandSide = AstFactory.identifier3("a");
- leftHandSide.staticType = intType;
- AssignmentExpression assignment = AstFactory.assignmentExpression(
- leftHandSide, TokenType.PLUS_EQ, AstFactory.integer(1));
- _resolveNode(assignment);
- expect(
- assignment.staticElement, same(getMethod(_typeProvider.numType, "+")));
- _listener.assertNoErrors();
- }
-
- void test_visitAssignmentExpression_simple() {
- AssignmentExpression expression = AstFactory.assignmentExpression(
- AstFactory.identifier3("x"), TokenType.EQ, AstFactory.integer(0));
- _resolveNode(expression);
- expect(expression.staticElement, isNull);
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_bangEq() {
- // String i;
- // var j;
- // i == j
- InterfaceType stringType = _typeProvider.stringType;
- SimpleIdentifier left = AstFactory.identifier3("i");
- left.staticType = stringType;
- BinaryExpression expression = AstFactory.binaryExpression(
- left, TokenType.BANG_EQ, AstFactory.identifier3("j"));
- _resolveNode(expression);
- var stringElement = stringType.element;
- expect(expression.staticElement, isNotNull);
- expect(
- expression.staticElement,
- stringElement.lookUpMethod(
- TokenType.EQ_EQ.lexeme, stringElement.library));
- expect(expression.propagatedElement, isNull);
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_eq() {
- // String i;
- // var j;
- // i == j
- InterfaceType stringType = _typeProvider.stringType;
- SimpleIdentifier left = AstFactory.identifier3("i");
- left.staticType = stringType;
- BinaryExpression expression = AstFactory.binaryExpression(
- left, TokenType.EQ_EQ, AstFactory.identifier3("j"));
- _resolveNode(expression);
- var stringElement = stringType.element;
- expect(
- expression.staticElement,
- stringElement.lookUpMethod(
- TokenType.EQ_EQ.lexeme, stringElement.library));
- expect(expression.propagatedElement, isNull);
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_plus() {
- // num i;
- // var j;
- // i + j
- InterfaceType numType = _typeProvider.numType;
- SimpleIdentifier left = AstFactory.identifier3("i");
- left.staticType = numType;
- BinaryExpression expression = AstFactory.binaryExpression(
- left, TokenType.PLUS, AstFactory.identifier3("j"));
- _resolveNode(expression);
- expect(expression.staticElement, getMethod(numType, "+"));
- expect(expression.propagatedElement, isNull);
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_plus_propagatedElement() {
- // var i = 1;
- // var j;
- // i + j
- InterfaceType numType = _typeProvider.numType;
- SimpleIdentifier left = AstFactory.identifier3("i");
- left.propagatedType = numType;
- BinaryExpression expression = AstFactory.binaryExpression(
- left, TokenType.PLUS, AstFactory.identifier3("j"));
- _resolveNode(expression);
- expect(expression.staticElement, isNull);
- expect(expression.propagatedElement, getMethod(numType, "+"));
- _listener.assertNoErrors();
- }
-
- void test_visitBreakStatement_withLabel() {
- // loop: while (true) {
- // break loop;
- // }
- String label = "loop";
- LabelElementImpl labelElement = new LabelElementImpl.forNode(
- AstFactory.identifier3(label), false, false);
- BreakStatement breakStatement = AstFactory.breakStatement2(label);
- Expression condition = AstFactory.booleanLiteral(true);
- WhileStatement whileStatement =
- AstFactory.whileStatement(condition, breakStatement);
- expect(_resolveBreak(breakStatement, labelElement, whileStatement),
- same(labelElement));
- expect(breakStatement.target, same(whileStatement));
- _listener.assertNoErrors();
- }
-
- void test_visitBreakStatement_withoutLabel() {
- BreakStatement statement = AstFactory.breakStatement();
- _resolveStatement(statement, null, null);
- _listener.assertNoErrors();
- }
-
- void test_visitCommentReference_prefixedIdentifier_class_getter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- // set accessors
- String propName = "p";
- PropertyAccessorElement getter =
- ElementFactory.getterElement(propName, false, _typeProvider.intType);
- PropertyAccessorElement setter =
- ElementFactory.setterElement(propName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getter, setter];
- // set name scope
- _visitor.nameScope = new EnclosedScope(null)
- ..defineNameWithoutChecking('A', classA);
- // prepare "A.p"
- PrefixedIdentifier prefixed = AstFactory.identifier5('A', 'p');
- CommentReference commentReference = new CommentReference(null, prefixed);
- // resolve
- _resolveNode(commentReference);
- expect(prefixed.prefix.staticElement, classA);
- expect(prefixed.identifier.staticElement, getter);
- _listener.assertNoErrors();
- }
-
- void test_visitCommentReference_prefixedIdentifier_class_method() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- // set method
- MethodElement method =
- ElementFactory.methodElement("m", _typeProvider.intType);
- classA.methods = <MethodElement>[method];
- // set name scope
- _visitor.nameScope = new EnclosedScope(null)
- ..defineNameWithoutChecking('A', classA);
- // prepare "A.m"
- PrefixedIdentifier prefixed = AstFactory.identifier5('A', 'm');
- CommentReference commentReference = new CommentReference(null, prefixed);
- // resolve
- _resolveNode(commentReference);
- expect(prefixed.prefix.staticElement, classA);
- expect(prefixed.identifier.staticElement, method);
- _listener.assertNoErrors();
- }
-
- void test_visitConstructorName_named() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String constructorName = "a";
- ConstructorElement constructor =
- ElementFactory.constructorElement2(classA, constructorName);
- classA.constructors = <ConstructorElement>[constructor];
- ConstructorName name = AstFactory.constructorName(
- AstFactory.typeName(classA), constructorName);
- _resolveNode(name);
- expect(name.staticElement, same(constructor));
- _listener.assertNoErrors();
- }
-
- void test_visitConstructorName_unnamed() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String constructorName = null;
- ConstructorElement constructor =
- ElementFactory.constructorElement2(classA, constructorName);
- classA.constructors = <ConstructorElement>[constructor];
- ConstructorName name = AstFactory.constructorName(
- AstFactory.typeName(classA), constructorName);
- _resolveNode(name);
- expect(name.staticElement, same(constructor));
- _listener.assertNoErrors();
- }
-
- void test_visitContinueStatement_withLabel() {
- // loop: while (true) {
- // continue loop;
- // }
- String label = "loop";
- LabelElementImpl labelElement = new LabelElementImpl.forNode(
- AstFactory.identifier3(label), false, false);
- ContinueStatement continueStatement = AstFactory.continueStatement(label);
- Expression condition = AstFactory.booleanLiteral(true);
- WhileStatement whileStatement =
- AstFactory.whileStatement(condition, continueStatement);
- expect(_resolveContinue(continueStatement, labelElement, whileStatement),
- same(labelElement));
- expect(continueStatement.target, same(whileStatement));
- _listener.assertNoErrors();
- }
-
- void test_visitContinueStatement_withoutLabel() {
- ContinueStatement statement = AstFactory.continueStatement();
- _resolveStatement(statement, null, null);
- _listener.assertNoErrors();
- }
-
- void test_visitEnumDeclaration() {
- CompilationUnitElementImpl compilationUnitElement =
- ElementFactory.compilationUnit('foo.dart');
- ClassElementImpl enumElement =
- ElementFactory.enumElement(_typeProvider, ('E'));
- compilationUnitElement.enums = <ClassElement>[enumElement];
- EnumDeclaration enumNode = AstFactory.enumDeclaration2('E', []);
- Annotation annotationNode =
- AstFactory.annotation(AstFactory.identifier3('a'));
- annotationNode.element = ElementFactory.classElement2('A');
- annotationNode.elementAnnotation =
- new ElementAnnotationImpl(compilationUnitElement);
- enumNode.metadata.add(annotationNode);
- enumNode.name.staticElement = enumElement;
- List<ElementAnnotation> metadata = <ElementAnnotation>[
- annotationNode.elementAnnotation
- ];
- _resolveNode(enumNode);
- expect(metadata[0].element, annotationNode.element);
- }
-
- void test_visitExportDirective_noCombinators() {
- ExportDirective directive = AstFactory.exportDirective2(null);
- directive.element = ElementFactory
- .exportFor(ElementFactory.library(_definingLibrary.context, "lib"));
- _resolveNode(directive);
- _listener.assertNoErrors();
- }
-
- void test_visitFieldFormalParameter() {
- String fieldName = "f";
- InterfaceType intType = _typeProvider.intType;
- FieldElementImpl fieldElement =
- ElementFactory.fieldElement(fieldName, false, false, false, intType);
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.fields = <FieldElement>[fieldElement];
- FieldFormalParameter parameter =
- AstFactory.fieldFormalParameter2(fieldName);
- FieldFormalParameterElementImpl parameterElement =
- ElementFactory.fieldFormalParameter(parameter.identifier);
- parameterElement.field = fieldElement;
- parameterElement.type = intType;
- parameter.identifier.staticElement = parameterElement;
- _resolveInClass(parameter, classA);
- expect(parameter.element.type, same(intType));
- }
-
- void test_visitImportDirective_noCombinators_noPrefix() {
- ImportDirective directive = AstFactory.importDirective3(null, null);
- directive.element = ElementFactory.importFor(
- ElementFactory.library(_definingLibrary.context, "lib"), null);
- _resolveNode(directive);
- _listener.assertNoErrors();
- }
-
- void test_visitImportDirective_noCombinators_prefix() {
- String prefixName = "p";
- ImportElement importElement = ElementFactory.importFor(
- ElementFactory.library(_definingLibrary.context, "lib"),
- ElementFactory.prefix(prefixName));
- _definingLibrary.imports = <ImportElement>[importElement];
- ImportDirective directive = AstFactory.importDirective3(null, prefixName);
- directive.element = importElement;
- _resolveNode(directive);
- _listener.assertNoErrors();
- }
-
- void test_visitImportDirective_withCombinators() {
- ShowCombinator combinator = AstFactory.showCombinator2(["A", "B", "C"]);
- ImportDirective directive =
- AstFactory.importDirective3(null, null, [combinator]);
- LibraryElementImpl library =
- ElementFactory.library(_definingLibrary.context, "lib");
- TopLevelVariableElementImpl varA =
- ElementFactory.topLevelVariableElement2("A");
- TopLevelVariableElementImpl varB =
- ElementFactory.topLevelVariableElement2("B");
- TopLevelVariableElementImpl varC =
- ElementFactory.topLevelVariableElement2("C");
- CompilationUnitElementImpl unit =
- library.definingCompilationUnit as CompilationUnitElementImpl;
- unit.accessors = <PropertyAccessorElement>[
- varA.getter,
- varA.setter,
- varB.getter,
- varC.setter
- ];
- unit.topLevelVariables = <TopLevelVariableElement>[varA, varB, varC];
- directive.element = ElementFactory.importFor(library, null);
- _resolveNode(directive);
- expect(combinator.shownNames[0].staticElement, same(varA));
- expect(combinator.shownNames[1].staticElement, same(varB));
- expect(combinator.shownNames[2].staticElement, same(varC));
- _listener.assertNoErrors();
- }
-
- void test_visitIndexExpression_get() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType intType = _typeProvider.intType;
- MethodElement getter =
- ElementFactory.methodElement("[]", intType, [intType]);
- classA.methods = <MethodElement>[getter];
- SimpleIdentifier array = AstFactory.identifier3("a");
- array.staticType = classA.type;
- IndexExpression expression =
- AstFactory.indexExpression(array, AstFactory.identifier3("i"));
- expect(_resolveIndexExpression(expression), same(getter));
- _listener.assertNoErrors();
- }
-
- void test_visitIndexExpression_set() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType intType = _typeProvider.intType;
- MethodElement setter =
- ElementFactory.methodElement("[]=", intType, [intType]);
- classA.methods = <MethodElement>[setter];
- SimpleIdentifier array = AstFactory.identifier3("a");
- array.staticType = classA.type;
- IndexExpression expression =
- AstFactory.indexExpression(array, AstFactory.identifier3("i"));
- AstFactory.assignmentExpression(
- expression, TokenType.EQ, AstFactory.integer(0));
- expect(_resolveIndexExpression(expression), same(setter));
- _listener.assertNoErrors();
- }
-
- void test_visitInstanceCreationExpression_named() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String constructorName = "a";
- ConstructorElement constructor =
- ElementFactory.constructorElement2(classA, constructorName);
- classA.constructors = <ConstructorElement>[constructor];
- ConstructorName name = AstFactory.constructorName(
- AstFactory.typeName(classA), constructorName);
- name.staticElement = constructor;
- InstanceCreationExpression creation =
- AstFactory.instanceCreationExpression(Keyword.NEW, name);
- _resolveNode(creation);
- expect(creation.staticElement, same(constructor));
- _listener.assertNoErrors();
- }
-
- void test_visitInstanceCreationExpression_unnamed() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String constructorName = null;
- ConstructorElement constructor =
- ElementFactory.constructorElement2(classA, constructorName);
- classA.constructors = <ConstructorElement>[constructor];
- ConstructorName name = AstFactory.constructorName(
- AstFactory.typeName(classA), constructorName);
- name.staticElement = constructor;
- InstanceCreationExpression creation =
- AstFactory.instanceCreationExpression(Keyword.NEW, name);
- _resolveNode(creation);
- expect(creation.staticElement, same(constructor));
- _listener.assertNoErrors();
- }
-
- void test_visitInstanceCreationExpression_unnamed_namedParameter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String constructorName = null;
- ConstructorElementImpl constructor =
- ElementFactory.constructorElement2(classA, constructorName);
- String parameterName = "a";
- ParameterElement parameter = ElementFactory.namedParameter(parameterName);
- constructor.parameters = <ParameterElement>[parameter];
- classA.constructors = <ConstructorElement>[constructor];
- ConstructorName name = AstFactory.constructorName(
- AstFactory.typeName(classA), constructorName);
- name.staticElement = constructor;
- InstanceCreationExpression creation = AstFactory.instanceCreationExpression(
- Keyword.NEW,
- name,
- [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]);
- _resolveNode(creation);
- expect(creation.staticElement, same(constructor));
- expect(
- (creation.argumentList.arguments[0] as NamedExpression)
- .name
- .label
- .staticElement,
- same(parameter));
- _listener.assertNoErrors();
- }
-
- void test_visitMethodInvocation() {
- InterfaceType numType = _typeProvider.numType;
- SimpleIdentifier left = AstFactory.identifier3("i");
- left.staticType = numType;
- String methodName = "abs";
- MethodInvocation invocation = AstFactory.methodInvocation(left, methodName);
- _resolveNode(invocation);
- expect(invocation.methodName.staticElement,
- same(getMethod(numType, methodName)));
- _listener.assertNoErrors();
- }
-
- void test_visitMethodInvocation_namedParameter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- String parameterName = "p";
- MethodElementImpl method = ElementFactory.methodElement(methodName, null);
- ParameterElement parameter = ElementFactory.namedParameter(parameterName);
- method.parameters = <ParameterElement>[parameter];
- classA.methods = <MethodElement>[method];
- SimpleIdentifier left = AstFactory.identifier3("i");
- left.staticType = classA.type;
- MethodInvocation invocation = AstFactory.methodInvocation(left, methodName,
- [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]);
- _resolveNode(invocation);
- expect(invocation.methodName.staticElement, same(method));
- expect(
- (invocation.argumentList.arguments[0] as NamedExpression)
- .name
- .label
- .staticElement,
- same(parameter));
- _listener.assertNoErrors();
- }
-
- void test_visitPostfixExpression() {
- InterfaceType numType = _typeProvider.numType;
- SimpleIdentifier operand = AstFactory.identifier3("i");
- operand.staticType = numType;
- PostfixExpression expression =
- AstFactory.postfixExpression(operand, TokenType.PLUS_PLUS);
- _resolveNode(expression);
- expect(expression.staticElement, getMethod(numType, "+"));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_dynamic() {
- DartType dynamicType = _typeProvider.dynamicType;
- SimpleIdentifier target = AstFactory.identifier3("a");
- VariableElementImpl variable = ElementFactory.localVariableElement(target);
- variable.type = dynamicType;
- target.staticElement = variable;
- target.staticType = dynamicType;
- PrefixedIdentifier identifier =
- AstFactory.identifier(target, AstFactory.identifier3("b"));
- _resolveNode(identifier);
- expect(identifier.staticElement, isNull);
- expect(identifier.identifier.staticElement, isNull);
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_nonDynamic() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "b";
- PropertyAccessorElement getter =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getter];
- SimpleIdentifier target = AstFactory.identifier3("a");
- VariableElementImpl variable = ElementFactory.localVariableElement(target);
- variable.type = classA.type;
- target.staticElement = variable;
- target.staticType = classA.type;
- PrefixedIdentifier identifier =
- AstFactory.identifier(target, AstFactory.identifier3(getterName));
- _resolveNode(identifier);
- expect(identifier.staticElement, same(getter));
- expect(identifier.identifier.staticElement, same(getter));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_staticClassMember_getter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- // set accessors
- String propName = "b";
- PropertyAccessorElement getter =
- ElementFactory.getterElement(propName, false, _typeProvider.intType);
- PropertyAccessorElement setter =
- ElementFactory.setterElement(propName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getter, setter];
- // prepare "A.m"
- SimpleIdentifier target = AstFactory.identifier3("A");
- target.staticElement = classA;
- target.staticType = classA.type;
- PrefixedIdentifier identifier =
- AstFactory.identifier(target, AstFactory.identifier3(propName));
- // resolve
- _resolveNode(identifier);
- expect(identifier.staticElement, same(getter));
- expect(identifier.identifier.staticElement, same(getter));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_staticClassMember_method() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- // set methods
- String propName = "m";
- MethodElement method =
- ElementFactory.methodElement("m", _typeProvider.intType);
- classA.methods = <MethodElement>[method];
- // prepare "A.m"
- SimpleIdentifier target = AstFactory.identifier3("A");
- target.staticElement = classA;
- target.staticType = classA.type;
- PrefixedIdentifier identifier =
- AstFactory.identifier(target, AstFactory.identifier3(propName));
- AstFactory.assignmentExpression(
- identifier, TokenType.EQ, AstFactory.nullLiteral());
- // resolve
- _resolveNode(identifier);
- expect(identifier.staticElement, same(method));
- expect(identifier.identifier.staticElement, same(method));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_staticClassMember_setter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- // set accessors
- String propName = "b";
- PropertyAccessorElement getter =
- ElementFactory.getterElement(propName, false, _typeProvider.intType);
- PropertyAccessorElement setter =
- ElementFactory.setterElement(propName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getter, setter];
- // prepare "A.b = null"
- SimpleIdentifier target = AstFactory.identifier3("A");
- target.staticElement = classA;
- target.staticType = classA.type;
- PrefixedIdentifier identifier =
- AstFactory.identifier(target, AstFactory.identifier3(propName));
- AstFactory.assignmentExpression(
- identifier, TokenType.EQ, AstFactory.nullLiteral());
- // resolve
- _resolveNode(identifier);
- expect(identifier.staticElement, same(setter));
- expect(identifier.identifier.staticElement, same(setter));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixExpression() {
- InterfaceType numType = _typeProvider.numType;
- SimpleIdentifier operand = AstFactory.identifier3("i");
- operand.staticType = numType;
- PrefixExpression expression =
- AstFactory.prefixExpression(TokenType.PLUS_PLUS, operand);
- _resolveNode(expression);
- expect(expression.staticElement, getMethod(numType, "+"));
- _listener.assertNoErrors();
- }
-
- void test_visitPropertyAccess_getter_identifier() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "b";
- PropertyAccessorElement getter =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getter];
- SimpleIdentifier target = AstFactory.identifier3("a");
- target.staticType = classA.type;
- PropertyAccess access = AstFactory.propertyAccess2(target, getterName);
- _resolveNode(access);
- expect(access.propertyName.staticElement, same(getter));
- _listener.assertNoErrors();
- }
-
- void test_visitPropertyAccess_getter_super() {
- //
- // class A {
- // int get b;
- // }
- // class B {
- // ... super.m ...
- // }
- //
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "b";
- PropertyAccessorElement getter =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getter];
- SuperExpression target = AstFactory.superExpression();
- target.staticType = ElementFactory.classElement("B", classA.type).type;
- PropertyAccess access = AstFactory.propertyAccess2(target, getterName);
- AstFactory.methodDeclaration2(
- null,
- null,
- null,
- null,
- AstFactory.identifier3("m"),
- AstFactory.formalParameterList(),
- AstFactory.expressionFunctionBody(access));
- _resolveNode(access);
- expect(access.propertyName.staticElement, same(getter));
- _listener.assertNoErrors();
- }
-
- void test_visitPropertyAccess_setter_this() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String setterName = "b";
- PropertyAccessorElement setter =
- ElementFactory.setterElement(setterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[setter];
- ThisExpression target = AstFactory.thisExpression();
- target.staticType = classA.type;
- PropertyAccess access = AstFactory.propertyAccess2(target, setterName);
- AstFactory.assignmentExpression(
- access, TokenType.EQ, AstFactory.integer(0));
- _resolveNode(access);
- expect(access.propertyName.staticElement, same(setter));
- _listener.assertNoErrors();
- }
-
- void test_visitSimpleIdentifier_classScope() {
- InterfaceType doubleType = _typeProvider.doubleType;
- String fieldName = "NAN";
- SimpleIdentifier node = AstFactory.identifier3(fieldName);
- _resolveInClass(node, doubleType.element);
- expect(node.staticElement, getGetter(doubleType, fieldName));
- _listener.assertNoErrors();
- }
-
- void test_visitSimpleIdentifier_dynamic() {
- SimpleIdentifier node = AstFactory.identifier3("dynamic");
- _resolveIdentifier(node);
- expect(node.staticElement, same(_typeProvider.dynamicType.element));
- expect(node.staticType, same(_typeProvider.typeType));
- _listener.assertNoErrors();
- }
-
- void test_visitSimpleIdentifier_lexicalScope() {
- SimpleIdentifier node = AstFactory.identifier3("i");
- VariableElementImpl element = ElementFactory.localVariableElement(node);
- expect(_resolveIdentifier(node, [element]), same(element));
- _listener.assertNoErrors();
- }
-
- void test_visitSimpleIdentifier_lexicalScope_field_setter() {
- InterfaceType intType = _typeProvider.intType;
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String fieldName = "a";
- FieldElement field =
- ElementFactory.fieldElement(fieldName, false, false, false, intType);
- classA.fields = <FieldElement>[field];
- classA.accessors = <PropertyAccessorElement>[field.getter, field.setter];
- SimpleIdentifier node = AstFactory.identifier3(fieldName);
- AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0));
- _resolveInClass(node, classA);
- Element element = node.staticElement;
- EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccessorElement,
- PropertyAccessorElement, element);
- expect((element as PropertyAccessorElement).isSetter, isTrue);
- _listener.assertNoErrors();
- }
-
- void test_visitSuperConstructorInvocation() {
- ClassElementImpl superclass = ElementFactory.classElement2("A");
- ConstructorElementImpl superConstructor =
- ElementFactory.constructorElement2(superclass, null);
- superclass.constructors = <ConstructorElement>[superConstructor];
- ClassElementImpl subclass =
- ElementFactory.classElement("B", superclass.type);
- ConstructorElementImpl subConstructor =
- ElementFactory.constructorElement2(subclass, null);
- subclass.constructors = <ConstructorElement>[subConstructor];
- SuperConstructorInvocation invocation =
- AstFactory.superConstructorInvocation();
- _resolveInClass(invocation, subclass);
- expect(invocation.staticElement, superConstructor);
- _listener.assertNoErrors();
- }
-
- void test_visitSuperConstructorInvocation_namedParameter() {
- ClassElementImpl superclass = ElementFactory.classElement2("A");
- ConstructorElementImpl superConstructor =
- ElementFactory.constructorElement2(superclass, null);
- String parameterName = "p";
- ParameterElement parameter = ElementFactory.namedParameter(parameterName);
- superConstructor.parameters = <ParameterElement>[parameter];
- superclass.constructors = <ConstructorElement>[superConstructor];
- ClassElementImpl subclass =
- ElementFactory.classElement("B", superclass.type);
- ConstructorElementImpl subConstructor =
- ElementFactory.constructorElement2(subclass, null);
- subclass.constructors = <ConstructorElement>[subConstructor];
- SuperConstructorInvocation invocation = AstFactory
- .superConstructorInvocation([
- AstFactory.namedExpression2(parameterName, AstFactory.integer(0))
- ]);
- _resolveInClass(invocation, subclass);
- expect(invocation.staticElement, superConstructor);
- expect(
- (invocation.argumentList.arguments[0] as NamedExpression)
- .name
- .label
- .staticElement,
- same(parameter));
- _listener.assertNoErrors();
- }
-
- /**
- * Create the resolver used by the tests.
- *
- * @return the resolver that was created
- */
- ElementResolver _createResolver() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- FileBasedSource source =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- CompilationUnitElementImpl definingCompilationUnit =
- new CompilationUnitElementImpl("test.dart");
- definingCompilationUnit.librarySource =
- definingCompilationUnit.source = source;
- _definingLibrary = ElementFactory.library(context, "test");
- _definingLibrary.definingCompilationUnit = definingCompilationUnit;
- _visitor = new ResolverVisitor(
- _definingLibrary, source, _typeProvider, _listener,
- nameScope: new LibraryScope(_definingLibrary, _listener));
- try {
- return _visitor.elementResolver;
- } catch (exception) {
- throw new IllegalArgumentException(
- "Could not create resolver", exception);
- }
- }
-
- /**
- * Return the element associated with the label of [statement] after the
- * resolver has resolved it. [labelElement] is the label element to be
- * defined in the statement's label scope, and [labelTarget] is the statement
- * the label resolves to.
- */
- Element _resolveBreak(BreakStatement statement, LabelElementImpl labelElement,
- Statement labelTarget) {
- _resolveStatement(statement, labelElement, labelTarget);
- return statement.label.staticElement;
- }
-
- /**
- * Return the element associated with the label [statement] after the
- * resolver has resolved it. [labelElement] is the label element to be
- * defined in the statement's label scope, and [labelTarget] is the AST node
- * the label resolves to.
- *
- * @param statement the statement to be resolved
- * @param labelElement the label element to be defined in the statement's label scope
- * @return the element to which the statement's label was resolved
- */
- Element _resolveContinue(ContinueStatement statement,
- LabelElementImpl labelElement, AstNode labelTarget) {
- _resolveStatement(statement, labelElement, labelTarget);
- return statement.label.staticElement;
- }
-
- /**
- * Return the element associated with the given identifier after the resolver has resolved the
- * identifier.
- *
- * @param node the expression to be resolved
- * @param definedElements the elements that are to be defined in the scope in which the element is
- * being resolved
- * @return the element to which the expression was resolved
- */
- Element _resolveIdentifier(Identifier node, [List<Element> definedElements]) {
- _resolveNode(node, definedElements);
- return node.staticElement;
- }
-
- /**
- * Return the element associated with the given identifier after the resolver has resolved the
- * identifier.
- *
- * @param node the expression to be resolved
- * @param enclosingClass the element representing the class enclosing the identifier
- * @return the element to which the expression was resolved
- */
- void _resolveInClass(AstNode node, ClassElement enclosingClass) {
- try {
- Scope outerScope = _visitor.nameScope;
- try {
- _visitor.enclosingClass = enclosingClass;
- EnclosedScope innerScope = new ClassScope(
- new TypeParameterScope(outerScope, enclosingClass), enclosingClass);
- _visitor.nameScope = innerScope;
- node.accept(_resolver);
- } finally {
- _visitor.enclosingClass = null;
- _visitor.nameScope = outerScope;
- }
- } catch (exception) {
- throw new IllegalArgumentException("Could not resolve node", exception);
- }
- }
-
- /**
- * Return the element associated with the given expression after the resolver has resolved the
- * expression.
- *
- * @param node the expression to be resolved
- * @param definedElements the elements that are to be defined in the scope in which the element is
- * being resolved
- * @return the element to which the expression was resolved
- */
- Element _resolveIndexExpression(IndexExpression node,
- [List<Element> definedElements]) {
- _resolveNode(node, definedElements);
- return node.staticElement;
- }
-
- /**
- * Return the element associated with the given identifier after the resolver has resolved the
- * identifier.
- *
- * @param node the expression to be resolved
- * @param definedElements the elements that are to be defined in the scope in which the element is
- * being resolved
- * @return the element to which the expression was resolved
- */
- void _resolveNode(AstNode node, [List<Element> definedElements]) {
- try {
- Scope outerScope = _visitor.nameScope;
- try {
- EnclosedScope innerScope = new EnclosedScope(outerScope);
- if (definedElements != null) {
- for (Element element in definedElements) {
- innerScope.define(element);
- }
- }
- _visitor.nameScope = innerScope;
- node.accept(_resolver);
- } finally {
- _visitor.nameScope = outerScope;
- }
- } catch (exception) {
- throw new IllegalArgumentException("Could not resolve node", exception);
- }
- }
-
- /**
- * Return the element associated with the label of the given statement after the resolver has
- * resolved the statement.
- *
- * @param statement the statement to be resolved
- * @param labelElement the label element to be defined in the statement's label scope
- * @return the element to which the statement's label was resolved
- */
- void _resolveStatement(
- Statement statement, LabelElementImpl labelElement, AstNode labelTarget) {
- try {
- LabelScope outerScope = _visitor.labelScope;
- try {
- LabelScope innerScope;
- if (labelElement == null) {
- innerScope = outerScope;
- } else {
- innerScope = new LabelScope(
- outerScope, labelElement.name, labelTarget, labelElement);
- }
- _visitor.labelScope = innerScope;
- statement.accept(_resolver);
- } finally {
- _visitor.labelScope = outerScope;
- }
- } catch (exception) {
- throw new IllegalArgumentException("Could not resolve node", exception);
- }
- }
-}
-
-@reflectiveTest
-class EnclosedScopeTest extends ResolverTestCase {
- void test_define_duplicate() {
- GatheringErrorListener listener = new GatheringErrorListener();
- Scope rootScope =
- new Scope_EnclosedScopeTest_test_define_duplicate(listener);
- EnclosedScope scope = new EnclosedScope(rootScope);
- VariableElement element1 =
- ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
- VariableElement element2 =
- ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
- scope.define(element1);
- scope.define(element2);
- listener.assertErrorsWithSeverities([ErrorSeverity.ERROR]);
- }
-
- void test_define_normal() {
- GatheringErrorListener listener = new GatheringErrorListener();
- Scope rootScope = new Scope_EnclosedScopeTest_test_define_normal(listener);
- EnclosedScope outerScope = new EnclosedScope(rootScope);
- EnclosedScope innerScope = new EnclosedScope(outerScope);
- VariableElement element1 =
- ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
- VariableElement element2 =
- ElementFactory.localVariableElement(AstFactory.identifier3("v2"));
- outerScope.define(element1);
- innerScope.define(element2);
- listener.assertNoErrors();
- }
-}
-
-@reflectiveTest
-class ErrorResolverTest extends ResolverTestCase {
- void test_breakLabelOnSwitchMember() {
- Source source = addSource(r'''
-class A {
- void m(int i) {
- switch (i) {
- l: case 0:
- break;
- case 1:
- break l;
- }
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER]);
- verify([source]);
- }
-
- void test_continueLabelOnSwitch() {
- Source source = addSource(r'''
-class A {
- void m(int i) {
- l: switch (i) {
- case 0:
- continue l;
- }
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH]);
- verify([source]);
- }
-
- void test_enclosingElement_invalidLocalFunction() {
- Source source = addSource(r'''
-class C {
- C() {
- int get x => 0;
- }
-}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- var unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- var types = unit.types;
- expect(types, isNotNull);
- expect(types, hasLength(1));
- var type = types[0];
- expect(type, isNotNull);
- var constructors = type.constructors;
- expect(constructors, isNotNull);
- expect(constructors, hasLength(1));
- ConstructorElement constructor = constructors[0];
- expect(constructor, isNotNull);
- List<FunctionElement> functions = constructor.functions;
- expect(functions, isNotNull);
- expect(functions, hasLength(1));
- expect(functions[0].enclosingElement, constructor);
- assertErrors(source, [ParserErrorCode.GETTER_IN_FUNCTION]);
- }
-}
-
-/**
- * Tests for generic method and function resolution that do not use strong mode.
- */
-@reflectiveTest
-class GenericMethodResolverTest extends _StaticTypeAnalyzer2TestShared {
- void setUp() {
- super.setUp();
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.enableGenericMethods = true;
- resetWithOptions(options);
- }
-
- void test_genericMethod_propagatedType_promotion() {
- // Regression test for:
- // https://github.com/dart-lang/sdk/issues/25340
- //
- // Note, after https://github.com/dart-lang/sdk/issues/25486 the original
- // strong mode example won't work, as we now compute a static type and
- // therefore discard the propagated type.
- //
- // So this test does not use strong mode.
- _resolveTestUnit(r'''
-abstract class Iter {
- List<S> map<S>(S f(x));
-}
-class C {}
-C toSpan(dynamic element) {
- if (element is Iter) {
- var y = element.map(toSpan);
- }
- return null;
-}''');
- _expectIdentifierType('y = ', 'dynamic', 'List<dynamic>');
- }
-}
-
-@reflectiveTest
-class HintCodeTest extends ResolverTestCase {
- void fail_deadCode_statementAfterRehrow() {
- Source source = addSource(r'''
-f() {
- try {
- var one = 1;
- } catch (e) {
- rethrow;
- var two = 2;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void fail_deadCode_statementAfterThrow() {
- Source source = addSource(r'''
-f() {
- var one = 1;
- throw 'Stop here';
- var two = 2;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void fail_isInt() {
- Source source = addSource("var v = 1 is int;");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.IS_INT]);
- verify([source]);
- }
-
- void fail_isNotInt() {
- Source source = addSource("var v = 1 is! int;");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.IS_NOT_INT]);
- verify([source]);
- }
-
- void fail_overrideEqualsButNotHashCode() {
- Source source = addSource(r'''
-class A {
- bool operator ==(x) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]);
- verify([source]);
- }
-
- void fail_unusedImport_as_equalPrefixes() {
- // See todo at ImportsVerifier.prefixElementMap.
- Source source = addSource(r'''
-library L;
-import 'lib1.dart' as one;
-import 'lib2.dart' as one;
-one.A a;''');
- Source source2 = addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}''');
- Source source3 = addNamedSource(
- "/lib2.dart",
- r'''
-library lib2;
-class B {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_IMPORT]);
- assertNoErrors(source2);
- assertNoErrors(source3);
- verify([source, source2, source3]);
- }
-
- @override
- void reset() {
- analysisContext2 = AnalysisContextFactory.contextWithCoreAndPackages({
- 'package:meta/meta.dart': r'''
-library meta;
-
-const _Factory factory = const _Factory();
-const _Literal literal = const _Literal();
-const _MustCallSuper mustCallSuper = const _MustCallSuper();
-const _Override override = const _Override();
-const _Protected protected = const _Protected();
-const _Required required = const _Required();
-
-class _Factory {
- const _Factory();
-}
-class _Literal {
- const _Literal();
-}
-class _MustCallSuper {
- const _MustCallSuper();
-}
-class _Override {
- const _Override();
-}
-class _Protected {
- const _Protected();
-}
-class _Required {
- final String reason;
- const _Required([this.reason]));
-}
-'''
- });
- }
-
- void test_argumentTypeNotAssignable_functionType() {
- Source source = addSource(r'''
-m() {
- var a = new A();
- a.n(() => 0);
-}
-class A {
- n(void f(int i)) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
- verify([source]);
- }
-
- void test_argumentTypeNotAssignable_message() {
- // The implementation of HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE assumes that
- // StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE has the same message.
- expect(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE.message,
- HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE.message);
- }
-
- void test_argumentTypeNotAssignable_type() {
- Source source = addSource(r'''
-m() {
- var i = '';
- n(i);
-}
-n(int i) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
- verify([source]);
- }
-
- void test_canBeNullAfterNullAware_false_methodInvocation() {
- Source source = addSource(r'''
-m(x) {
- x?.a()?.b();
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_canBeNullAfterNullAware_false_propertyAccess() {
- Source source = addSource(r'''
-m(x) {
- x?.a?.b;
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_canBeNullAfterNullAware_methodInvocation() {
- Source source = addSource(r'''
-m(x) {
- x?.a.b();
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
- verify([source]);
- }
-
- void test_canBeNullAfterNullAware_parenthesized() {
- Source source = addSource(r'''
-m(x) {
- (x?.a).b;
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
- verify([source]);
- }
-
- void test_canBeNullAfterNullAware_propertyAccess() {
- Source source = addSource(r'''
-m(x) {
- x?.a.b;
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_conditionalElse() {
- Source source = addSource(r'''
-f() {
- true ? 1 : 2;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_conditionalElse_nested() {
- // test that a dead else-statement can't generate additional violations
- Source source = addSource(r'''
-f() {
- true ? true : false && false;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_conditionalIf() {
- Source source = addSource(r'''
-f() {
- false ? 1 : 2;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_conditionalIf_nested() {
- // test that a dead then-statement can't generate additional violations
- Source source = addSource(r'''
-f() {
- false ? false && false : true;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_else() {
- Source source = addSource(r'''
-f() {
- if(true) {} else {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_else_nested() {
- // test that a dead else-statement can't generate additional violations
- Source source = addSource(r'''
-f() {
- if(true) {} else {if (false) {}}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_if() {
- Source source = addSource(r'''
-f() {
- if(false) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_if_nested() {
- // test that a dead then-statement can't generate additional violations
- Source source = addSource(r'''
-f() {
- if(false) {if(false) {}}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_while() {
- Source source = addSource(r'''
-f() {
- while(false) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_while_nested() {
- // test that a dead while body can't generate additional violations
- Source source = addSource(r'''
-f() {
- while(false) {if(false) {}}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadCatch_catchFollowingCatch() {
- Source source = addSource(r'''
-class A {}
-f() {
- try {} catch (e) {} catch (e) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
- verify([source]);
- }
-
- void test_deadCode_deadCatch_catchFollowingCatch_nested() {
- // test that a dead catch clause can't generate additional violations
- Source source = addSource(r'''
-class A {}
-f() {
- try {} catch (e) {} catch (e) {if(false) {}}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
- verify([source]);
- }
-
- void test_deadCode_deadCatch_catchFollowingCatch_object() {
- Source source = addSource(r'''
-f() {
- try {} on Object catch (e) {} catch (e) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
- verify([source]);
- }
-
- void test_deadCode_deadCatch_catchFollowingCatch_object_nested() {
- // test that a dead catch clause can't generate additional violations
- Source source = addSource(r'''
-f() {
- try {} on Object catch (e) {} catch (e) {if(false) {}}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
- verify([source]);
- }
-
- void test_deadCode_deadCatch_onCatchSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {}
-f() {
- try {} on A catch (e) {} on B catch (e) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]);
- verify([source]);
- }
-
- void test_deadCode_deadCatch_onCatchSubtype_nested() {
- // test that a dead catch clause can't generate additional violations
- Source source = addSource(r'''
-class A {}
-class B extends A {}
-f() {
- try {} on A catch (e) {} on B catch (e) {if(false) {}}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]);
- verify([source]);
- }
-
- void test_deadCode_deadOperandLHS_and() {
- Source source = addSource(r'''
-f() {
- bool b = false && false;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadOperandLHS_and_nested() {
- Source source = addSource(r'''
-f() {
- bool b = false && (false && false);
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadOperandLHS_or() {
- Source source = addSource(r'''
-f() {
- bool b = true || true;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadOperandLHS_or_nested() {
- Source source = addSource(r'''
-f() {
- bool b = true || (false && false);
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterBreak_inDefaultCase() {
- Source source = addSource(r'''
-f(v) {
- switch(v) {
- case 1:
- default:
- break;
- var a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterBreak_inForEachStatement() {
- Source source = addSource(r'''
-f() {
- var list;
- for(var l in list) {
- break;
- var a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterBreak_inForStatement() {
- Source source = addSource(r'''
-f() {
- for(;;) {
- break;
- var a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterBreak_inSwitchCase() {
- Source source = addSource(r'''
-f(v) {
- switch(v) {
- case 1:
- break;
- var a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterBreak_inWhileStatement() {
- Source source = addSource(r'''
-f(v) {
- while(v) {
- break;
- var a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterContinue_inForEachStatement() {
- Source source = addSource(r'''
-f() {
- var list;
- for(var l in list) {
- continue;
- var a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterContinue_inForStatement() {
- Source source = addSource(r'''
-f() {
- for(;;) {
- continue;
- var a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterContinue_inWhileStatement() {
- Source source = addSource(r'''
-f(v) {
- while(v) {
- continue;
- var a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterReturn_function() {
- Source source = addSource(r'''
-f() {
- var one = 1;
- return;
- var two = 2;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterReturn_ifStatement() {
- Source source = addSource(r'''
-f(bool b) {
- if(b) {
- var one = 1;
- return;
- var two = 2;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterReturn_method() {
- Source source = addSource(r'''
-class A {
- m() {
- var one = 1;
- return;
- var two = 2;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterReturn_nested() {
- Source source = addSource(r'''
-f() {
- var one = 1;
- return;
- if(false) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterReturn_twoReturns() {
- Source source = addSource(r'''
-f() {
- var one = 1;
- return;
- var two = 2;
- return;
- var three = 3;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_assignment() {
- Source source = addSource(r'''
-class A {
- @deprecated
- A operator+(A a) { return a; }
-}
-f(A a) {
- A b;
- a += b;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_Deprecated() {
- Source source = addSource(r'''
-class A {
- @Deprecated('0.9')
- m() {}
- n() {m();}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_deprecated() {
- Source source = addSource(r'''
-class A {
- @deprecated
- m() {}
- n() {m();}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_export() {
- Source source = addSource("export 'deprecated_library.dart';");
- addNamedSource(
- "/deprecated_library.dart",
- r'''
-@deprecated
-library deprecated_library;
-class A {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_getter() {
- Source source = addSource(r'''
-class A {
- @deprecated
- get m => 1;
-}
-f(A a) {
- return a.m;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_import() {
- Source source = addSource(r'''
-import 'deprecated_library.dart';
-f(A a) {}''');
- addNamedSource(
- "/deprecated_library.dart",
- r'''
-@deprecated
-library deprecated_library;
-class A {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_indexExpression() {
- Source source = addSource(r'''
-class A {
- @deprecated
- operator[](int i) {}
-}
-f(A a) {
- return a[1];
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_instanceCreation() {
- Source source = addSource(r'''
-class A {
- @deprecated
- A(int i) {}
-}
-f() {
- A a = new A(1);
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_instanceCreation_namedConstructor() {
- Source source = addSource(r'''
-class A {
- @deprecated
- A.named(int i) {}
-}
-f() {
- A a = new A.named(1);
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_operator() {
- Source source = addSource(r'''
-class A {
- @deprecated
- operator+(A a) {}
-}
-f(A a) {
- A b;
- return a + b;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_setter() {
- Source source = addSource(r'''
-class A {
- @deprecated
- set s(v) {}
-}
-f(A a) {
- return a.s = 1;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_superConstructor() {
- Source source = addSource(r'''
-class A {
- @deprecated
- A() {}
-}
-class B extends A {
- B() : super() {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_superConstructor_namedConstructor() {
- Source source = addSource(r'''
-class A {
- @deprecated
- A.named() {}
-}
-class B extends A {
- B() : super.named() {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_divisionOptimization_double() {
- Source source = addSource(r'''
-f(double x, double y) {
- var v = (x / y).toInt();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
- verify([source]);
- }
-
- void test_divisionOptimization_int() {
- Source source = addSource(r'''
-f(int x, int y) {
- var v = (x / y).toInt();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
- verify([source]);
- }
-
- void test_divisionOptimization_propagatedType() {
- // Tests the propagated type information of the '/' method
- Source source = addSource(r'''
-f(x, y) {
- x = 1;
- y = 1;
- var v = (x / y).toInt();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
- verify([source]);
- }
-
- void test_divisionOptimization_wrappedBinaryExpression() {
- Source source = addSource(r'''
-f(int x, int y) {
- var v = (((x / y))).toInt();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
- verify([source]);
- }
-
- void test_duplicateImport() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart';
-A a;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DUPLICATE_IMPORT]);
- verify([source]);
- }
-
- void test_duplicateImport2() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart';
-import 'lib1.dart';
-A a;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}''');
- computeLibrarySourceErrors(source);
- assertErrors(
- source, [HintCode.DUPLICATE_IMPORT, HintCode.DUPLICATE_IMPORT]);
- verify([source]);
- }
-
- void test_duplicateImport3() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart' as M show A hide B;
-import 'lib1.dart' as M show A hide B;
-M.A a;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}
-class B {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DUPLICATE_IMPORT]);
- verify([source]);
- }
-
- void test_importDeferredLibraryWithLoadFunction() {
- resolveWithErrors(<String>[
- r'''
-library lib1;
-loadLibrary() {}
-f() {}''',
- r'''
-library root;
-import 'lib1.dart' deferred as lib1;
-main() { lib1.f(); }'''
- ], <ErrorCode>[
- HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION
- ]);
- }
-
- void test_invalidAssignment_instanceVariable() {
- Source source = addSource(r'''
-class A {
- int x;
-}
-f(var y) {
- A a;
- if(y is String) {
- a.x = y;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
- verify([source]);
- }
-
- void test_invalidAssignment_localVariable() {
- Source source = addSource(r'''
-f(var y) {
- if(y is String) {
- int x = y;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
- verify([source]);
- }
-
- void test_invalidAssignment_message() {
- // The implementation of HintCode.INVALID_ASSIGNMENT assumes that
- // StaticTypeWarningCode.INVALID_ASSIGNMENT has the same message.
- expect(StaticTypeWarningCode.INVALID_ASSIGNMENT.message,
- HintCode.INVALID_ASSIGNMENT.message);
- }
-
- void test_invalidAssignment_staticVariable() {
- Source source = addSource(r'''
-class A {
- static int x;
-}
-f(var y) {
- if(y is String) {
- A.x = y;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
- verify([source]);
- }
-
- void test_invalidAssignment_variableDeclaration() {
- // 17971
- Source source = addSource(r'''
-class Point {
- final num x, y;
- Point(this.x, this.y);
- Point operator +(Point other) {
- return new Point(x+other.x, y+other.y);
- }
-}
-main() {
- var p1 = new Point(0, 0);
- var p2 = new Point(10, 10);
- int n = p1 + p2;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_field() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- int a;
-}
-abstract class B implements A {
- int b() => a;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_function() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void a(){ }
-}
-main() {
- new A().a();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_getter() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- int get a => 42;
-}
-abstract class B implements A {
- int b() => a;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_message() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void a(){ }
-}
-class B {
- void b() => new A().a();
-}''');
- List<AnalysisError> errors = analysisContext2.computeErrors(source);
- expect(errors, hasLength(1));
- expect(errors[0].message,
- "The member 'a' can only be used within instance members of subclasses of 'A'");
- }
-
- void test_invalidUseOfProtectedMember_method_1() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void a(){ }
-}
-class B {
- void b() => new A().a();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_method_2() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void a(){ }
-}
-abstract class B implements A {
- void b() => a();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_OK_1() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void a(){ }
-}
-class B extends A {
- void b() => a();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_OK_2() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void a(){ }
-}
-class B extends Object with A {
- void b() => a();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_OK_3() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected m1() {}
-}
-class B extends A {
- static m2(A a) => a.m1();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_OK_4() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void a(){ }
-}
-class B extends A {
- void a() => a();
-}
-main() {
- new B().a();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_OK_field() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- int a = 42;
-}
-class B extends A {
- int b() => a;
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_OK_getter() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- int get a => 42;
-}
-class B extends A {
- int b() => a;
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_OK_setter() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void set a(int i) { }
-}
-class B extends A {
- void b(int i) {
- a = i;
- }
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_setter() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void set a(int i) { }
-}
-abstract class B implements A {
- b(int i) {
- a = i;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_topLevelVariable() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-@protected
-int x = 0;
-main() {
- print(x);
-}''');
- computeLibrarySourceErrors(source);
- // TODO(brianwilkerson) This should produce a hint because the annotation is
- // being applied to the wrong kind of declaration.
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_isDouble() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.dart2jsHint = true;
- resetWithOptions(options);
- Source source = addSource("var v = 1 is double;");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.IS_DOUBLE]);
- verify([source]);
- }
-
- void test_isNotDouble() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.dart2jsHint = true;
- resetWithOptions(options);
- Source source = addSource("var v = 1 is! double;");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.IS_NOT_DOUBLE]);
- verify([source]);
- }
-
- void test_missingReturn_async() {
- Source source = addSource('''
-import 'dart:async';
-Future<int> f() async {}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.MISSING_RETURN]);
- verify([source]);
- }
-
- void test_missingReturn_function() {
- Source source = addSource("int f() {}");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.MISSING_RETURN]);
- verify([source]);
- }
-
- void test_missingReturn_method() {
- Source source = addSource(r'''
-class A {
- int m() {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.MISSING_RETURN]);
- verify([source]);
- }
-
- void test_mustCallSuper() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @mustCallSuper
- void a() {}
-}
-class B extends A {
- @override
- void a()
- {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.MUST_CALL_SUPER]);
- verify([source]);
- }
-
- void test_mustCallSuper_indirect() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @mustCallSuper
- void a() {}
-}
-class C extends A {
- @override
- void a() {
- super.a();
- }
-}
-class D extends C {
- @override
- void a() {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.MUST_CALL_SUPER]);
- verify([source]);
- }
-
- void test_mustCallSuper_OK() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @mustCallSuper
- void a() {}
-}
-class C extends A {
- @override
- void a() {
- super.a(); //OK
- }
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- verify([source]);
- }
-
- @override
- void test_nullAwareInCondition_assert() {
- Source source = addSource(r'''
-m(x) {
- assert (x?.a);
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_conditionalExpression() {
- Source source = addSource(r'''
-m(x) {
- return x?.a ? 0 : 1;
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_do() {
- Source source = addSource(r'''
-m(x) {
- do {} while (x?.a);
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_for() {
- Source source = addSource(r'''
-m(x) {
- for (var v = x; v?.a; v = v.next) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if() {
- Source source = addSource(r'''
-m(x) {
- if (x?.a) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_conditionalAnd_first() {
- Source source = addSource(r'''
-m(x) {
- if (x?.a && x.b) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_conditionalAnd_second() {
- Source source = addSource(r'''
-m(x) {
- if (x.a && x?.b) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_conditionalAnd_third() {
- Source source = addSource(r'''
-m(x) {
- if (x.a && x.b && x?.c) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_conditionalOr_first() {
- Source source = addSource(r'''
-m(x) {
- if (x?.a || x.b) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_conditionalOr_second() {
- Source source = addSource(r'''
-m(x) {
- if (x.a || x?.b) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_conditionalOr_third() {
- Source source = addSource(r'''
-m(x) {
- if (x.a || x.b || x?.c) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_not() {
- Source source = addSource(r'''
-m(x) {
- if (!x?.a) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_parenthesized() {
- Source source = addSource(r'''
-m(x) {
- if ((x?.a)) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_while() {
- Source source = addSource(r'''
-m(x) {
- while (x?.a) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingGetter_invalid() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
-}
-class B extends A {
- @override
- int get m => 1;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER]);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingMethod_invalid() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
-}
-class B extends A {
- @override
- int m() => 1;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingSetter_invalid() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
-}
-class B extends A {
- @override
- set m(int x) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER]);
- verify([source]);
- }
-
- void test_typeCheck_type_is_Null() {
- Source source = addSource(r'''
-m(i) {
- bool b = i is Null;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.TYPE_CHECK_IS_NULL]);
- verify([source]);
- }
-
- void test_typeCheck_type_not_Null() {
- Source source = addSource(r'''
-m(i) {
- bool b = i is! Null;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.TYPE_CHECK_IS_NOT_NULL]);
- verify([source]);
- }
-
- void test_undefinedGetter() {
- Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- return a.m;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_GETTER]);
- }
-
- void test_undefinedGetter_message() {
- // The implementation of HintCode.UNDEFINED_SETTER assumes that
- // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the
- // same, this verifies that assumption.
- expect(StaticWarningCode.UNDEFINED_GETTER.message,
- StaticTypeWarningCode.UNDEFINED_GETTER.message);
- }
-
- void test_undefinedMethod() {
- Source source = addSource(r'''
-f() {
- var a = 'str';
- a.notAMethodOnString();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_METHOD]);
- }
-
- void test_undefinedMethod_assignmentExpression() {
- Source source = addSource(r'''
-class A {}
-class B {
- f(var a, var a2) {
- a = new A();
- a2 = new A();
- a += a2;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_METHOD]);
- }
-
- void test_undefinedOperator_binaryExpression() {
- Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- a + 1;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
-
- void test_undefinedOperator_indexBoth() {
- Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- a[0]++;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
-
- void test_undefinedOperator_indexGetter() {
- Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- a[0];
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
-
- void test_undefinedOperator_indexSetter() {
- Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- a[0] = 1;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
-
- void test_undefinedOperator_postfixExpression() {
- Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- a++;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
-
- void test_undefinedOperator_prefixExpression() {
- Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- ++a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
-
- void test_undefinedSetter() {
- Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- a.m = 0;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_SETTER]);
- }
-
- void test_undefinedSetter_message() {
- // The implementation of HintCode.UNDEFINED_SETTER assumes that
- // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the
- // same, this verifies that assumption.
- expect(StaticWarningCode.UNDEFINED_SETTER.message,
- StaticTypeWarningCode.UNDEFINED_SETTER.message);
- }
-
- void test_unnecessaryCast_type_supertype() {
- Source source = addSource(r'''
-m(int i) {
- var b = i as Object;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_CAST]);
- verify([source]);
- }
-
- void test_unnecessaryCast_type_type() {
- Source source = addSource(r'''
-m(num i) {
- var b = i as num;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_CAST]);
- verify([source]);
- }
-
- void test_unnecessaryNoSuchMethod_blockBody() {
- Source source = addSource(r'''
-class A {
- noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
- mmm();
- noSuchMethod(y) {
- return super.noSuchMethod(y);
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_NO_SUCH_METHOD]);
- verify([source]);
- }
-
- void test_unnecessaryNoSuchMethod_expressionBody() {
- Source source = addSource(r'''
-class A {
- noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
- mmm();
- noSuchMethod(y) => super.noSuchMethod(y);
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_NO_SUCH_METHOD]);
- verify([source]);
- }
-
- void test_unnecessaryTypeCheck_null_is_Null() {
- Source source = addSource("bool b = null is Null;");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
- verify([source]);
- }
-
- void test_unnecessaryTypeCheck_null_not_Null() {
- Source source = addSource("bool b = null is! Null;");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
- verify([source]);
- }
-
- void test_unnecessaryTypeCheck_type_is_dynamic() {
- Source source = addSource(r'''
-m(i) {
- bool b = i is dynamic;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
- verify([source]);
- }
-
- void test_unnecessaryTypeCheck_type_is_object() {
- Source source = addSource(r'''
-m(i) {
- bool b = i is Object;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
- verify([source]);
- }
-
- void test_unnecessaryTypeCheck_type_not_dynamic() {
- Source source = addSource(r'''
-m(i) {
- bool b = i is! dynamic;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
- verify([source]);
- }
-
- void test_unnecessaryTypeCheck_type_not_object() {
- Source source = addSource(r'''
-m(i) {
- bool b = i is! Object;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
- verify([source]);
- }
-
- void test_unusedElement_class_isUsed_extends() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {}
-class B extends _A {}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_class_isUsed_fieldDeclaration() {
- enableUnusedElement = true;
- var src = r'''
-class Foo {
- _Bar x;
-}
-
-class _Bar {
-}
-''';
- Source source = addSource(src);
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_class_isUsed_implements() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {}
-class B implements _A {}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_class_isUsed_instanceCreation() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {}
-main() {
- new _A();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_class_isUsed_staticFieldAccess() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {
- static const F = 42;
-}
-main() {
- _A.F;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_class_isUsed_staticMethodInvocation() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {
- static m() {}
-}
-main() {
- _A.m();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_class_isUsed_typeArgument() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {}
-main() {
- var v = new List<_A>();
- print(v);
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_class_notUsed_inClassMember() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {
- static staticMethod() {
- new _A();
- }
- instanceMethod() {
- new _A();
- }
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_class_notUsed_inConstructorName() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {
- _A() {}
- _A.named() {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_class_notUsed_isExpression() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {}
-main(p) {
- if (p is _A) {
- }
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_class_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {}
-main() {
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_class_notUsed_variableDeclaration() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {}
-main() {
- _A v;
- print(v);
-}
-print(x) {}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_enum_isUsed_fieldReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-enum _MyEnum {A, B, C}
-main() {
- print(_MyEnum.B);
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_enum_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-enum _MyEnum {A, B, C}
-main() {
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_functionLocal_isUsed_closure() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-main() {
- print(() {});
-}
-print(x) {}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionLocal_isUsed_invocation() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-main() {
- f() {}
- f();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionLocal_isUsed_reference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-main() {
- f() {}
- print(f);
-}
-print(x) {}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionLocal_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-main() {
- f() {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_functionLocal_notUsed_referenceFromItself() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-main() {
- _f(int p) {
- _f(p - 1);
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_functionTop_isUsed_invocation() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-_f() {}
-main() {
- _f();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionTop_isUsed_reference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-_f() {}
-main() {
- print(_f);
-}
-print(x) {}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionTop_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-_f() {}
-main() {
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_functionTop_notUsed_referenceFromItself() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-_f(int p) {
- _f(p - 1);
-}
-main() {
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_functionTypeAlias_isUsed_isExpression() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-typedef _F(a, b);
-main(f) {
- if (f is _F) {
- print('F');
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionTypeAlias_isUsed_reference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-typedef _F(a, b);
-main(_F f) {
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionTypeAlias_isUsed_typeArgument() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-typedef _F(a, b);
-main() {
- var v = new List<_F>();
- print(v);
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionTypeAlias_isUsed_variableDeclaration() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-typedef _F(a, b);
-class A {
- _F f;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionTypeAlias_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-typedef _F(a, b);
-main() {
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_getter_isUsed_invocation_implicitThis() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- get _g => null;
- useGetter() {
- var v = _g;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_getter_isUsed_invocation_PrefixedIdentifier() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- get _g => null;
-}
-main(A a) {
- var v = a._g;
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_getter_isUsed_invocation_PropertyAccess() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- get _g => null;
-}
-main() {
- var v = new A()._g;
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_getter_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- get _g => null;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_getter_notUsed_referenceFromItself() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- get _g {
- return _g;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_hasReference_implicitThis() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
- useMethod() {
- print(_m);
- }
-}
-print(x) {}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_hasReference_implicitThis_subclass() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
- useMethod() {
- print(_m);
- }
-}
-class B extends A {
- _m() {}
-}
-print(x) {}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_hasReference_PrefixedIdentifier() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
-}
-main(A a) {
- a._m;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_hasReference_PropertyAccess() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
-}
-main() {
- new A()._m;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_invocation_implicitThis() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
- useMethod() {
- _m();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_invocation_implicitThis_subclass() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
- useMethod() {
- _m();
- }
-}
-class B extends A {
- _m() {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_invocation_MemberElement() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A<T> {
- _m(T t) {}
-}
-main(A<int> a) {
- a._m(0);
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_invocation_propagated() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
-}
-main() {
- var a = new A();
- a._m();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_invocation_static() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
-}
-main() {
- A a = new A();
- a._m();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_invocation_subclass() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
-}
-class B extends A {
- _m() {}
-}
-main(A a) {
- a._m();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_notPrivate() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- m() {}
-}
-main() {
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_staticInvocation() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- static _m() {}
-}
-main() {
- A._m();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- static _m() {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_method_notUsed_referenceFromItself() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- static _m(int p) {
- _m(p - 1);
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_setter_isUsed_invocation_implicitThis() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- set _s(x) {}
- useSetter() {
- _s = 42;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_setter_isUsed_invocation_PrefixedIdentifier() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- set _s(x) {}
-}
-main(A a) {
- a._s = 42;
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_setter_isUsed_invocation_PropertyAccess() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- set _s(x) {}
-}
-main() {
- new A()._s = 42;
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_setter_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- set _s(x) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_setter_notUsed_referenceFromItself() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- set _s(int x) {
- if (x > 5) {
- _s = x - 1;
- }
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedField_isUsed_argument() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f = 0;
- main() {
- print(++_f);
- }
-}
-print(x) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedField_isUsed_reference_implicitThis() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
- main() {
- print(_f);
- }
-}
-print(x) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedField_isUsed_reference_implicitThis_expressionFunctionBody() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
- m() => _f;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedField_isUsed_reference_implicitThis_subclass() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
- main() {
- print(_f);
- }
-}
-class B extends A {
- int _f;
-}
-print(x) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedField_isUsed_reference_qualified_propagatedElement() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
-}
-main() {
- var a = new A();
- print(a._f);
-}
-print(x) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedField_isUsed_reference_qualified_staticElement() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
-}
-main() {
- A a = new A();
- print(a._f);
-}
-print(x) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedField_isUsed_reference_qualified_unresolved() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
-}
-main(a) {
- print(a._f);
-}
-print(x) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedField_notUsed_compoundAssign() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
- main() {
- _f += 2;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_FIELD]);
- verify([source]);
- }
-
- void test_unusedField_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_FIELD]);
- verify([source]);
- }
-
- void test_unusedField_notUsed_postfixExpr() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f = 0;
- main() {
- _f++;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_FIELD]);
- verify([source]);
- }
-
- void test_unusedField_notUsed_prefixExpr() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f = 0;
- main() {
- ++_f;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_FIELD]);
- verify([source]);
- }
-
- void test_unusedField_notUsed_simpleAssignment() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
- m() {
- _f = 1;
- }
-}
-main(A a) {
- a._f = 2;
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_FIELD]);
- verify([source]);
- }
-
- void test_unusedImport() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';''');
- Source source2 = addNamedSource("/lib1.dart", "library lib1;");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_IMPORT]);
- assertNoErrors(source2);
- verify([source, source2]);
- }
-
- void test_unusedImport_as() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart' as one;
-one.A a;''');
- Source source2 = addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_IMPORT]);
- assertNoErrors(source2);
- verify([source, source2]);
- }
-
- void test_unusedImport_hide() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart' hide A;
-A a;''');
- Source source2 = addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_IMPORT]);
- assertNoErrors(source2);
- verify([source, source2]);
- }
-
- void test_unusedImport_show() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart' show A;
-import 'lib1.dart' show B;
-A a;''');
- Source source2 = addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}
-class B {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_IMPORT]);
- assertNoErrors(source2);
- verify([source, source2]);
- }
-
- void test_unusedLocalVariable_inCatch_exception() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- try {
- } on String catch (exception) {
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_CATCH_CLAUSE]);
- verify([source]);
- }
-
- void test_unusedLocalVariable_inCatch_exception_hasStack() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- try {
- } catch (exception, stack) {
- print(stack);
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedLocalVariable_inCatch_exception_noOnClause() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- try {
- } catch (exception) {
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedLocalVariable_inCatch_stackTrace() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- try {
- } catch (exception, stackTrace) {
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_CATCH_STACK]);
- verify([source]);
- }
-
- void test_unusedLocalVariable_inCatch_stackTrace_used() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- try {
- } catch (exception, stackTrace) {
- print('exception at $stackTrace');
- }
-}
-print(x) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedLocalVariable_inFor_underscore_ignored() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- for (var _ in [1,2,3]) {
- for (var __ in [4,5,6]) {
- // do something
- }
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedLocalVariable_inFunction() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- var v = 1;
- v = 2;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
- verify([source]);
- }
-
- void test_unusedLocalVariable_inMethod() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-class A {
- foo() {
- var v = 1;
- v = 2;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
- verify([source]);
- }
-
- void test_unusedLocalVariable_isInvoked() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-typedef Foo();
-main() {
- Foo foo;
- foo();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedLocalVariable_isRead_notUsed_compoundAssign() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- var v = 1;
- v += 2;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
- verify([source]);
- }
-
- void test_unusedLocalVariable_isRead_notUsed_postfixExpr() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- var v = 1;
- v++;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
- verify([source]);
- }
-
- void test_unusedLocalVariable_isRead_notUsed_prefixExpr() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- var v = 1;
- ++v;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
- verify([source]);
- }
-
- void test_unusedLocalVariable_isRead_usedArgument() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- var v = 1;
- print(++v);
-}
-print(x) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedLocalVariable_isRead_usedInvocationTarget() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-class A {
- foo() {}
-}
-main() {
- var a = new A();
- a.foo();
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_useOfVoidResult_assignmentExpression_function() {
- Source source = addSource(r'''
-void f() {}
-class A {
- n() {
- var a;
- a = f();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
- verify([source]);
- }
-
- void test_useOfVoidResult_assignmentExpression_method() {
- Source source = addSource(r'''
-class A {
- void m() {}
- n() {
- var a;
- a = m();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
- verify([source]);
- }
-
- void test_useOfVoidResult_inForLoop() {
- Source source = addSource(r'''
-class A {
- void m() {}
- n() {
- for(var a = m();;) {}
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
- verify([source]);
- }
-
- void test_useOfVoidResult_variableDeclaration_function() {
- Source source = addSource(r'''
-void f() {}
-class A {
- n() {
- var a = f();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
- verify([source]);
- }
-
- void test_useOfVoidResult_variableDeclaration_method() {
- Source source = addSource(r'''
-class A {
- void m() {}
- n() {
- var a = m();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
- verify([source]);
- }
-
- void test_useOfVoidResult_variableDeclaration_method2() {
- Source source = addSource(r'''
-class A {
- void m() {}
- n() {
- var a = m(), b = m();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(
- source, [HintCode.USE_OF_VOID_RESULT, HintCode.USE_OF_VOID_RESULT]);
- verify([source]);
- }
-}
-
-@reflectiveTest
-class InheritanceManagerTest {
- /**
- * The type provider used to access the types.
- */
- TestTypeProvider _typeProvider;
-
- /**
- * The library containing the code being resolved.
- */
- LibraryElementImpl _definingLibrary;
-
- /**
- * The inheritance manager being tested.
- */
- InheritanceManager _inheritanceManager;
-
- /**
- * The number of members that Object implements (as determined by [TestTypeProvider]).
- */
- int _numOfMembersInObject = 0;
-
- void setUp() {
- _typeProvider = new TestTypeProvider();
- _inheritanceManager = _createInheritanceManager();
- InterfaceType objectType = _typeProvider.objectType;
- _numOfMembersInObject =
- objectType.methods.length + objectType.accessors.length;
- }
-
- void test_getMapOfMembersInheritedFromClasses_accessor_extends() {
- // class A { int get g; }
- // class B extends A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(getterName), same(getterG));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromClasses_accessor_implements() {
- // class A { int get g; }
- // class B implements A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject);
- expect(mapB.get(getterName), isNull);
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromClasses_accessor_with() {
- // class A { int get g; }
- // class B extends Object with A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(getterName), same(getterG));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromClasses_implicitExtends() {
- // class A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
- expect(mapA.size, _numOfMembersInObject);
- _assertNoErrors(classA);
- }
-
- void test_getMapOfMembersInheritedFromClasses_method_extends() {
- // class A { int g(); }
- // class B extends A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.supertype = classA.type;
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(methodName), same(methodM));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromClasses_method_implements() {
- // class A { int g(); }
- // class B implements A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject);
- expect(mapB.get(methodName), isNull);
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromClasses_method_with() {
- // class A { int g(); }
- // class B extends Object with A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(methodName), same(methodM));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromClasses_method_with_two_mixins() {
- // class A1 { int m(); }
- // class A2 { int m(); }
- // class B extends Object with A1, A2 {}
- ClassElementImpl classA1 = ElementFactory.classElement2("A1");
- String methodName = "m";
- MethodElement methodA1M =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA1.methods = <MethodElement>[methodA1M];
- ClassElementImpl classA2 = ElementFactory.classElement2("A2");
- MethodElement methodA2M =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA2.methods = <MethodElement>[methodA2M];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA1.type, classA2.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
- expect(mapB.get(methodName), same(methodA2M));
- _assertNoErrors(classA1);
- _assertNoErrors(classA2);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromInterfaces_accessor_extends() {
- // class A { int get g; }
- // class B extends A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(getterName), same(getterG));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromInterfaces_accessor_implements() {
- // class A { int get g; }
- // class B implements A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(getterName), same(getterG));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromInterfaces_accessor_with() {
- // class A { int get g; }
- // class B extends Object with A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(getterName), same(getterG));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromInterfaces_implicitExtends() {
- // class A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- _assertNoErrors(classA);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_getter_method() {
- // class I1 { int m(); }
- // class I2 { int get m; }
- // class A implements I2, I1 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classI1.methods = <MethodElement>[methodM];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- PropertyAccessorElement getter =
- ElementFactory.getterElement(methodName, false, _typeProvider.intType);
- classI2.accessors = <PropertyAccessorElement>[getter];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI2.type, classI1.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapA.get(methodName), isNull);
- _assertErrors(classA,
- [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_int_str() {
- // class I1 { int m(); }
- // class I2 { String m(); }
- // class A implements I1, I2 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElement methodM1 =
- ElementFactory.methodElement(methodName, null, [_typeProvider.intType]);
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElement methodM2 = ElementFactory
- .methodElement(methodName, null, [_typeProvider.stringType]);
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapA.get(methodName), isNull);
- _assertErrors(
- classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_method_getter() {
- // class I1 { int m(); }
- // class I2 { int get m; }
- // class A implements I1, I2 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classI1.methods = <MethodElement>[methodM];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- PropertyAccessorElement getter =
- ElementFactory.getterElement(methodName, false, _typeProvider.intType);
- classI2.accessors = <PropertyAccessorElement>[getter];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapA.get(methodName), isNull);
- _assertErrors(classA,
- [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_numOfRequiredParams() {
- // class I1 { dynamic m(int, [int]); }
- // class I2 { dynamic m(int, int, int); }
- // class A implements I1, I2 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElementImpl methodM1 =
- ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
- ParameterElementImpl parameter1 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
- parameter1.type = _typeProvider.intType;
- parameter1.parameterKind = ParameterKind.REQUIRED;
- ParameterElementImpl parameter2 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
- parameter2.type = _typeProvider.intType;
- parameter2.parameterKind = ParameterKind.POSITIONAL;
- methodM1.parameters = <ParameterElement>[parameter1, parameter2];
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElementImpl methodM2 =
- ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
- ParameterElementImpl parameter3 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
- parameter3.type = _typeProvider.intType;
- parameter3.parameterKind = ParameterKind.REQUIRED;
- ParameterElementImpl parameter4 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a4"));
- parameter4.type = _typeProvider.intType;
- parameter4.parameterKind = ParameterKind.REQUIRED;
- ParameterElementImpl parameter5 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a5"));
- parameter5.type = _typeProvider.intType;
- parameter5.parameterKind = ParameterKind.REQUIRED;
- methodM2.parameters = <ParameterElement>[
- parameter3,
- parameter4,
- parameter5
- ];
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapA.get(methodName), isNull);
- _assertErrors(
- classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_str_int() {
- // class I1 { int m(); }
- // class I2 { String m(); }
- // class A implements I2, I1 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElement methodM1 = ElementFactory
- .methodElement(methodName, null, [_typeProvider.stringType]);
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElement methodM2 =
- ElementFactory.methodElement(methodName, null, [_typeProvider.intType]);
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI2.type, classI1.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapA.get(methodName), isNull);
- _assertErrors(
- classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
- }
-
- void test_getMapOfMembersInheritedFromInterfaces_method_extends() {
- // class A { int g(); }
- // class B extends A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(methodName), same(methodM));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromInterfaces_method_implements() {
- // class A { int g(); }
- // class B implements A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(methodName), same(methodM));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromInterfaces_method_with() {
- // class A { int g(); }
- // class B extends Object with A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(methodName), same(methodM));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromInterfaces_union_differentNames() {
- // class I1 { int m1(); }
- // class I2 { int m2(); }
- // class A implements I1, I2 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName1 = "m1";
- MethodElement methodM1 =
- ElementFactory.methodElement(methodName1, _typeProvider.intType);
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- String methodName2 = "m2";
- MethodElement methodM2 =
- ElementFactory.methodElement(methodName2, _typeProvider.intType);
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject + 2);
- expect(mapA.get(methodName1), same(methodM1));
- expect(mapA.get(methodName2), same(methodM2));
- _assertNoErrors(classA);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_getters() {
- // class I1 { int get g; }
- // class I2 { num get g; }
- // class A implements I1, I2 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String accessorName = "g";
- PropertyAccessorElement getter1 = ElementFactory.getterElement(
- accessorName, false, _typeProvider.intType);
- classI1.accessors = <PropertyAccessorElement>[getter1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- PropertyAccessorElement getter2 = ElementFactory.getterElement(
- accessorName, false, _typeProvider.numType);
- classI2.accessors = <PropertyAccessorElement>[getter2];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject + 1);
- PropertyAccessorElement syntheticAccessor = ElementFactory.getterElement(
- accessorName, false, _typeProvider.dynamicType);
- expect(mapA.get(accessorName).type, syntheticAccessor.type);
- _assertNoErrors(classA);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_methods() {
- // class I1 { dynamic m(int); }
- // class I2 { dynamic m(num); }
- // class A implements I1, I2 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElementImpl methodM1 =
- ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
- ParameterElementImpl parameter1 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
- parameter1.type = _typeProvider.intType;
- parameter1.parameterKind = ParameterKind.REQUIRED;
- methodM1.parameters = <ParameterElement>[parameter1];
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElementImpl methodM2 =
- ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
- ParameterElementImpl parameter2 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
- parameter2.type = _typeProvider.numType;
- parameter2.parameterKind = ParameterKind.REQUIRED;
- methodM2.parameters = <ParameterElement>[parameter2];
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject + 1);
- MethodElement syntheticMethod = ElementFactory.methodElement(
- methodName, _typeProvider.dynamicType, [_typeProvider.dynamicType]);
- expect(mapA.get(methodName).type, syntheticMethod.type);
- _assertNoErrors(classA);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_setters() {
- // class I1 { set s(int); }
- // class I2 { set s(num); }
- // class A implements I1, I2 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String accessorName = "s";
- PropertyAccessorElement setter1 = ElementFactory.setterElement(
- accessorName, false, _typeProvider.intType);
- classI1.accessors = <PropertyAccessorElement>[setter1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- PropertyAccessorElement setter2 = ElementFactory.setterElement(
- accessorName, false, _typeProvider.numType);
- classI2.accessors = <PropertyAccessorElement>[setter2];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject + 1);
- PropertyAccessorElementImpl syntheticAccessor = ElementFactory
- .setterElement(accessorName, false, _typeProvider.dynamicType);
- syntheticAccessor.returnType = _typeProvider.dynamicType;
- expect(mapA.get("$accessorName=").type, syntheticAccessor.type);
- _assertNoErrors(classA);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_getters() {
- // class A {}
- // class B extends A {}
- // class C extends B {}
- // class I1 { A get g; }
- // class I2 { B get g; }
- // class I3 { C get g; }
- // class D implements I1, I2, I3 {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String accessorName = "g";
- PropertyAccessorElement getter1 =
- ElementFactory.getterElement(accessorName, false, classA.type);
- classI1.accessors = <PropertyAccessorElement>[getter1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- PropertyAccessorElement getter2 =
- ElementFactory.getterElement(accessorName, false, classB.type);
- classI2.accessors = <PropertyAccessorElement>[getter2];
- ClassElementImpl classI3 = ElementFactory.classElement2("I3");
- PropertyAccessorElement getter3 =
- ElementFactory.getterElement(accessorName, false, classC.type);
- classI3.accessors = <PropertyAccessorElement>[getter3];
- ClassElementImpl classD = ElementFactory.classElement2("D");
- classD.interfaces = <InterfaceType>[
- classI1.type,
- classI2.type,
- classI3.type
- ];
- MemberMap mapD =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD);
- expect(mapD.size, _numOfMembersInObject + 1);
- PropertyAccessorElement syntheticAccessor = ElementFactory.getterElement(
- accessorName, false, _typeProvider.dynamicType);
- expect(mapD.get(accessorName).type, syntheticAccessor.type);
- _assertNoErrors(classD);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_methods() {
- // class A {}
- // class B extends A {}
- // class C extends B {}
- // class I1 { dynamic m(A a); }
- // class I2 { dynamic m(B b); }
- // class I3 { dynamic m(C c); }
- // class D implements I1, I2, I3 {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElementImpl methodM1 =
- ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
- ParameterElementImpl parameter1 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
- parameter1.type = classA.type;
- parameter1.parameterKind = ParameterKind.REQUIRED;
- methodM1.parameters = <ParameterElement>[parameter1];
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElementImpl methodM2 =
- ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
- ParameterElementImpl parameter2 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
- parameter2.type = classB.type;
- parameter2.parameterKind = ParameterKind.REQUIRED;
- methodM2.parameters = <ParameterElement>[parameter2];
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classI3 = ElementFactory.classElement2("I3");
- MethodElementImpl methodM3 =
- ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
- ParameterElementImpl parameter3 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
- parameter3.type = classC.type;
- parameter3.parameterKind = ParameterKind.REQUIRED;
- methodM3.parameters = <ParameterElement>[parameter3];
- classI3.methods = <MethodElement>[methodM3];
- ClassElementImpl classD = ElementFactory.classElement2("D");
- classD.interfaces = <InterfaceType>[
- classI1.type,
- classI2.type,
- classI3.type
- ];
- MemberMap mapD =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD);
- expect(mapD.size, _numOfMembersInObject + 1);
- MethodElement syntheticMethod = ElementFactory.methodElement(
- methodName, _typeProvider.dynamicType, [_typeProvider.dynamicType]);
- expect(mapD.get(methodName).type, syntheticMethod.type);
- _assertNoErrors(classD);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_setters() {
- // class A {}
- // class B extends A {}
- // class C extends B {}
- // class I1 { set s(A); }
- // class I2 { set s(B); }
- // class I3 { set s(C); }
- // class D implements I1, I2, I3 {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String accessorName = "s";
- PropertyAccessorElement setter1 =
- ElementFactory.setterElement(accessorName, false, classA.type);
- classI1.accessors = <PropertyAccessorElement>[setter1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- PropertyAccessorElement setter2 =
- ElementFactory.setterElement(accessorName, false, classB.type);
- classI2.accessors = <PropertyAccessorElement>[setter2];
- ClassElementImpl classI3 = ElementFactory.classElement2("I3");
- PropertyAccessorElement setter3 =
- ElementFactory.setterElement(accessorName, false, classC.type);
- classI3.accessors = <PropertyAccessorElement>[setter3];
- ClassElementImpl classD = ElementFactory.classElement2("D");
- classD.interfaces = <InterfaceType>[
- classI1.type,
- classI2.type,
- classI3.type
- ];
- MemberMap mapD =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD);
- expect(mapD.size, _numOfMembersInObject + 1);
- PropertyAccessorElementImpl syntheticAccessor = ElementFactory
- .setterElement(accessorName, false, _typeProvider.dynamicType);
- syntheticAccessor.returnType = _typeProvider.dynamicType;
- expect(mapD.get("$accessorName=").type, syntheticAccessor.type);
- _assertNoErrors(classD);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods() {
- // class I1 { int m(); }
- // class I2 { int m([int]); }
- // class A implements I1, I2 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElement methodM1 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElementImpl methodM2 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- ParameterElementImpl parameter1 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
- parameter1.type = _typeProvider.intType;
- parameter1.parameterKind = ParameterKind.POSITIONAL;
- methodM2.parameters = <ParameterElement>[parameter1];
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject + 1);
- expect(mapA.get(methodName), same(methodM2));
- _assertNoErrors(classA);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods() {
- // class I1 { int m(); }
- // class I2 { int m([int]); }
- // class I3 { int m([int, int]); }
- // class A implements I1, I2, I3 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElementImpl methodM1 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElementImpl methodM2 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- ParameterElementImpl parameter1 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
- parameter1.type = _typeProvider.intType;
- parameter1.parameterKind = ParameterKind.POSITIONAL;
- methodM1.parameters = <ParameterElement>[parameter1];
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classI3 = ElementFactory.classElement2("I3");
- MethodElementImpl methodM3 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- ParameterElementImpl parameter2 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
- parameter2.type = _typeProvider.intType;
- parameter2.parameterKind = ParameterKind.POSITIONAL;
- ParameterElementImpl parameter3 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
- parameter3.type = _typeProvider.intType;
- parameter3.parameterKind = ParameterKind.POSITIONAL;
- methodM3.parameters = <ParameterElement>[parameter2, parameter3];
- classI3.methods = <MethodElement>[methodM3];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[
- classI1.type,
- classI2.type,
- classI3.type
- ];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject + 1);
- expect(mapA.get(methodName), same(methodM3));
- _assertNoErrors(classA);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods() {
- // class I1 { int m(); }
- // class I2 { int m(); }
- // class I3 { int m([int]); }
- // class I4 { int m([int, int]); }
- // class A implements I1, I2, I3, I4 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElement methodM1 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElement methodM2 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classI3 = ElementFactory.classElement2("I3");
- MethodElementImpl methodM3 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- ParameterElementImpl parameter1 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
- parameter1.type = _typeProvider.intType;
- parameter1.parameterKind = ParameterKind.POSITIONAL;
- methodM3.parameters = <ParameterElement>[parameter1];
- classI3.methods = <MethodElement>[methodM3];
- ClassElementImpl classI4 = ElementFactory.classElement2("I4");
- MethodElementImpl methodM4 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- ParameterElementImpl parameter2 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
- parameter2.type = _typeProvider.intType;
- parameter2.parameterKind = ParameterKind.POSITIONAL;
- ParameterElementImpl parameter3 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
- parameter3.type = _typeProvider.intType;
- parameter3.parameterKind = ParameterKind.POSITIONAL;
- methodM4.parameters = <ParameterElement>[parameter2, parameter3];
- classI4.methods = <MethodElement>[methodM4];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[
- classI1.type,
- classI2.type,
- classI3.type,
- classI4.type
- ];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject + 1);
- expect(mapA.get(methodName), same(methodM4));
- _assertNoErrors(classA);
- }
-
- void test_lookupInheritance_interface_getter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classB, getterName),
- same(getterG));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_interface_method() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classB, methodName),
- same(methodM));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_interface_setter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String setterName = "s";
- PropertyAccessorElement setterS =
- ElementFactory.setterElement(setterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[setterS];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
- same(setterS));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_interface_staticMember() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- (methodM as MethodElementImpl).static = true;
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_interfaces_infiniteLoop() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
- _assertNoErrors(classA);
- }
-
- void test_lookupInheritance_interfaces_infiniteLoop2() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classA.interfaces = <InterfaceType>[classB.type];
- classB.interfaces = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_interfaces_union2() {
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName1 = "m1";
- MethodElement methodM1 =
- ElementFactory.methodElement(methodName1, _typeProvider.intType);
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- String methodName2 = "m2";
- MethodElement methodM2 =
- ElementFactory.methodElement(methodName2, _typeProvider.intType);
- classI2.methods = <MethodElement>[methodM2];
- classI2.interfaces = <InterfaceType>[classI1.type];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI2.type];
- expect(_inheritanceManager.lookupInheritance(classA, methodName1),
- same(methodM1));
- expect(_inheritanceManager.lookupInheritance(classA, methodName2),
- same(methodM2));
- _assertNoErrors(classI1);
- _assertNoErrors(classI2);
- _assertNoErrors(classA);
- }
-
- void test_lookupInheritance_mixin_getter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classB, getterName),
- same(getterG));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_mixin_method() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classB, methodName),
- same(methodM));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_mixin_setter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String setterName = "s";
- PropertyAccessorElement setterS =
- ElementFactory.setterElement(setterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[setterS];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
- same(setterS));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_mixin_staticMember() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- (methodM as MethodElementImpl).static = true;
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_noMember() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- expect(_inheritanceManager.lookupInheritance(classA, "a"), isNull);
- _assertNoErrors(classA);
- }
-
- void test_lookupInheritance_superclass_getter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- expect(_inheritanceManager.lookupInheritance(classB, getterName),
- same(getterG));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_superclass_infiniteLoop() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.supertype = classA.type;
- expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
- _assertNoErrors(classA);
- }
-
- void test_lookupInheritance_superclass_infiniteLoop2() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classA.supertype = classB.type;
- classB.supertype = classA.type;
- expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_superclass_method() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- expect(_inheritanceManager.lookupInheritance(classB, methodName),
- same(methodM));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_superclass_setter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String setterName = "s";
- PropertyAccessorElement setterS =
- ElementFactory.setterElement(setterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[setterS];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
- same(setterS));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_superclass_staticMember() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- (methodM as MethodElementImpl).static = true;
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupMember_getter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- expect(_inheritanceManager.lookupMember(classA, getterName), same(getterG));
- _assertNoErrors(classA);
- }
-
- void test_lookupMember_getter_static() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, true, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- expect(_inheritanceManager.lookupMember(classA, getterName), isNull);
- _assertNoErrors(classA);
- }
-
- void test_lookupMember_method() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- expect(_inheritanceManager.lookupMember(classA, methodName), same(methodM));
- _assertNoErrors(classA);
- }
-
- void test_lookupMember_method_static() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- (methodM as MethodElementImpl).static = true;
- classA.methods = <MethodElement>[methodM];
- expect(_inheritanceManager.lookupMember(classA, methodName), isNull);
- _assertNoErrors(classA);
- }
-
- void test_lookupMember_noMember() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- expect(_inheritanceManager.lookupMember(classA, "a"), isNull);
- _assertNoErrors(classA);
- }
-
- void test_lookupMember_setter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String setterName = "s";
- PropertyAccessorElement setterS =
- ElementFactory.setterElement(setterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[setterS];
- expect(_inheritanceManager.lookupMember(classA, "$setterName="),
- same(setterS));
- _assertNoErrors(classA);
- }
-
- void test_lookupMember_setter_static() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String setterName = "s";
- PropertyAccessorElement setterS =
- ElementFactory.setterElement(setterName, true, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[setterS];
- expect(_inheritanceManager.lookupMember(classA, setterName), isNull);
- _assertNoErrors(classA);
- }
-
- void test_lookupOverrides_noParentClasses() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElementImpl methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- expect(
- _inheritanceManager.lookupOverrides(classA, methodName), hasLength(0));
- _assertNoErrors(classA);
- }
-
- void test_lookupOverrides_overrideBaseClass() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElementImpl methodMinA =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodMinA];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- MethodElementImpl methodMinB =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classB.methods = <MethodElement>[methodMinB];
- List<ExecutableElement> overrides =
- _inheritanceManager.lookupOverrides(classB, methodName);
- expect(overrides, unorderedEquals([methodMinA]));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupOverrides_overrideInterface() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElementImpl methodMinA =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodMinA];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- MethodElementImpl methodMinB =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classB.methods = <MethodElement>[methodMinB];
- List<ExecutableElement> overrides =
- _inheritanceManager.lookupOverrides(classB, methodName);
- expect(overrides, unorderedEquals([methodMinA]));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupOverrides_overrideTwoInterfaces() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElementImpl methodMinA =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodMinA];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- MethodElementImpl methodMinB =
- ElementFactory.methodElement(methodName, _typeProvider.doubleType);
- classB.methods = <MethodElement>[methodMinB];
- ClassElementImpl classC = ElementFactory.classElement2("C");
- classC.interfaces = <InterfaceType>[classA.type, classB.type];
- MethodElementImpl methodMinC =
- ElementFactory.methodElement(methodName, _typeProvider.numType);
- classC.methods = <MethodElement>[methodMinC];
- List<ExecutableElement> overrides =
- _inheritanceManager.lookupOverrides(classC, methodName);
- expect(overrides, unorderedEquals([methodMinA, methodMinB]));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- _assertNoErrors(classC);
- }
-
- void _assertErrors(ClassElement classElt,
- [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
- GatheringErrorListener errorListener = new GatheringErrorListener();
- HashSet<AnalysisError> actualErrors =
- _inheritanceManager.getErrors(classElt);
- if (actualErrors != null) {
- for (AnalysisError error in actualErrors) {
- errorListener.onError(error);
- }
- }
- errorListener.assertErrorsWithCodes(expectedErrorCodes);
- }
-
- void _assertNoErrors(ClassElement classElt) {
- _assertErrors(classElt);
- }
-
- /**
- * Create the inheritance manager used by the tests.
- *
- * @return the inheritance manager that was created
- */
- InheritanceManager _createInheritanceManager() {
- AnalysisContext context = AnalysisContextFactory.contextWithCore();
- FileBasedSource source =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- CompilationUnitElementImpl definingCompilationUnit =
- new CompilationUnitElementImpl("test.dart");
- definingCompilationUnit.librarySource =
- definingCompilationUnit.source = source;
- _definingLibrary = ElementFactory.library(context, "test");
- _definingLibrary.definingCompilationUnit = definingCompilationUnit;
- return new InheritanceManager(_definingLibrary);
- }
-}
-
-@reflectiveTest
-class LibraryImportScopeTest extends ResolverTestCase {
- void test_conflictingImports() {
- AnalysisContext context = AnalysisContextFactory.contextWithCore();
- String typeNameA = "A";
- String typeNameB = "B";
- String typeNameC = "C";
- ClassElement typeA = ElementFactory.classElement2(typeNameA);
- ClassElement typeB1 = ElementFactory.classElement2(typeNameB);
- ClassElement typeB2 = ElementFactory.classElement2(typeNameB);
- ClassElement typeC = ElementFactory.classElement2(typeNameC);
- LibraryElement importedLibrary1 = createTestLibrary(context, "imported1");
- (importedLibrary1.definingCompilationUnit as CompilationUnitElementImpl)
- .types = <ClassElement>[typeA, typeB1];
- ImportElementImpl import1 =
- ElementFactory.importFor(importedLibrary1, null);
- LibraryElement importedLibrary2 = createTestLibrary(context, "imported2");
- (importedLibrary2.definingCompilationUnit as CompilationUnitElementImpl)
- .types = <ClassElement>[typeB2, typeC];
- ImportElementImpl import2 =
- ElementFactory.importFor(importedLibrary2, null);
- LibraryElementImpl importingLibrary =
- createTestLibrary(context, "importing");
- importingLibrary.imports = <ImportElement>[import1, import2];
- {
- GatheringErrorListener errorListener = new GatheringErrorListener();
- Scope scope = new LibraryImportScope(importingLibrary, errorListener);
- expect(scope.lookup(AstFactory.identifier3(typeNameA), importingLibrary),
- typeA);
- errorListener.assertNoErrors();
- expect(scope.lookup(AstFactory.identifier3(typeNameC), importingLibrary),
- typeC);
- errorListener.assertNoErrors();
- Element element =
- scope.lookup(AstFactory.identifier3(typeNameB), importingLibrary);
- errorListener.assertErrorsWithCodes([StaticWarningCode.AMBIGUOUS_IMPORT]);
- EngineTestCase.assertInstanceOf((obj) => obj is MultiplyDefinedElement,
- MultiplyDefinedElement, element);
- List<Element> conflictingElements =
- (element as MultiplyDefinedElement).conflictingElements;
- expect(conflictingElements, hasLength(2));
- if (identical(conflictingElements[0], typeB1)) {
- expect(conflictingElements[1], same(typeB2));
- } else if (identical(conflictingElements[0], typeB2)) {
- expect(conflictingElements[1], same(typeB1));
- } else {
- expect(conflictingElements[0], same(typeB1));
- }
- }
- {
- GatheringErrorListener errorListener = new GatheringErrorListener();
- Scope scope = new LibraryImportScope(importingLibrary, errorListener);
- Identifier identifier = AstFactory.identifier3(typeNameB);
- AstFactory.methodDeclaration(null, AstFactory.typeName3(identifier), null,
- null, AstFactory.identifier3("foo"), null);
- Element element = scope.lookup(identifier, importingLibrary);
- errorListener.assertErrorsWithCodes([StaticWarningCode.AMBIGUOUS_IMPORT]);
- EngineTestCase.assertInstanceOf((obj) => obj is MultiplyDefinedElement,
- MultiplyDefinedElement, element);
- }
- }
-
- void test_creation_empty() {
- LibraryElement definingLibrary = createDefaultTestLibrary();
- GatheringErrorListener errorListener = new GatheringErrorListener();
- new LibraryImportScope(definingLibrary, errorListener);
- }
-
- void test_creation_nonEmpty() {
- AnalysisContext context = AnalysisContextFactory.contextWithCore();
- String importedTypeName = "A";
- ClassElement importedType =
- new ClassElementImpl.forNode(AstFactory.identifier3(importedTypeName));
- LibraryElement importedLibrary = createTestLibrary(context, "imported");
- (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
- .types = <ClassElement>[importedType];
- LibraryElementImpl definingLibrary =
- createTestLibrary(context, "importing");
- ImportElementImpl importElement = new ImportElementImpl(0);
- importElement.importedLibrary = importedLibrary;
- definingLibrary.imports = <ImportElement>[importElement];
- GatheringErrorListener errorListener = new GatheringErrorListener();
- Scope scope = new LibraryImportScope(definingLibrary, errorListener);
- expect(
- scope.lookup(AstFactory.identifier3(importedTypeName), definingLibrary),
- importedType);
- }
-
- void test_getErrorListener() {
- LibraryElement definingLibrary = createDefaultTestLibrary();
- GatheringErrorListener errorListener = new GatheringErrorListener();
- LibraryImportScope scope =
- new LibraryImportScope(definingLibrary, errorListener);
- expect(scope.errorListener, errorListener);
- }
-
- void test_nonConflictingImports_fromSdk() {
- AnalysisContext context = AnalysisContextFactory.contextWithCore();
- String typeName = "List";
- ClassElement type = ElementFactory.classElement2(typeName);
- LibraryElement importedLibrary = createTestLibrary(context, "lib");
- (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
- .types = <ClassElement>[type];
- ImportElementImpl importCore = ElementFactory.importFor(
- context.getLibraryElement(context.sourceFactory.forUri("dart:core")),
- null);
- ImportElementImpl importLib =
- ElementFactory.importFor(importedLibrary, null);
- LibraryElementImpl importingLibrary =
- createTestLibrary(context, "importing");
- importingLibrary.imports = <ImportElement>[importCore, importLib];
- GatheringErrorListener errorListener = new GatheringErrorListener();
- Scope scope = new LibraryImportScope(importingLibrary, errorListener);
- expect(
- scope.lookup(AstFactory.identifier3(typeName), importingLibrary), type);
- errorListener
- .assertErrorsWithCodes([StaticWarningCode.CONFLICTING_DART_IMPORT]);
- }
-
- void test_nonConflictingImports_sameElement() {
- AnalysisContext context = AnalysisContextFactory.contextWithCore();
- String typeNameA = "A";
- String typeNameB = "B";
- ClassElement typeA = ElementFactory.classElement2(typeNameA);
- ClassElement typeB = ElementFactory.classElement2(typeNameB);
- LibraryElement importedLibrary = createTestLibrary(context, "imported");
- (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
- .types = <ClassElement>[typeA, typeB];
- ImportElementImpl import1 = ElementFactory.importFor(importedLibrary, null);
- ImportElementImpl import2 = ElementFactory.importFor(importedLibrary, null);
- LibraryElementImpl importingLibrary =
- createTestLibrary(context, "importing");
- importingLibrary.imports = <ImportElement>[import1, import2];
- GatheringErrorListener errorListener = new GatheringErrorListener();
- Scope scope = new LibraryImportScope(importingLibrary, errorListener);
- expect(scope.lookup(AstFactory.identifier3(typeNameA), importingLibrary),
- typeA);
- errorListener.assertNoErrors();
- expect(scope.lookup(AstFactory.identifier3(typeNameB), importingLibrary),
- typeB);
- errorListener.assertNoErrors();
- }
-
- void test_prefixedAndNonPrefixed() {
- AnalysisContext context = AnalysisContextFactory.contextWithCore();
- String typeName = "C";
- String prefixName = "p";
- ClassElement prefixedType = ElementFactory.classElement2(typeName);
- ClassElement nonPrefixedType = ElementFactory.classElement2(typeName);
- LibraryElement prefixedLibrary =
- createTestLibrary(context, "import.prefixed");
- (prefixedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
- .types = <ClassElement>[prefixedType];
- ImportElementImpl prefixedImport = ElementFactory.importFor(
- prefixedLibrary, ElementFactory.prefix(prefixName));
- LibraryElement nonPrefixedLibrary =
- createTestLibrary(context, "import.nonPrefixed");
- (nonPrefixedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
- .types = <ClassElement>[nonPrefixedType];
- ImportElementImpl nonPrefixedImport =
- ElementFactory.importFor(nonPrefixedLibrary, null);
- LibraryElementImpl importingLibrary =
- createTestLibrary(context, "importing");
- importingLibrary.imports = <ImportElement>[
- prefixedImport,
- nonPrefixedImport
- ];
- GatheringErrorListener errorListener = new GatheringErrorListener();
- Scope scope = new LibraryImportScope(importingLibrary, errorListener);
- Element prefixedElement = scope.lookup(
- AstFactory.identifier5(prefixName, typeName), importingLibrary);
- errorListener.assertNoErrors();
- expect(prefixedElement, same(prefixedType));
- Element nonPrefixedElement =
- scope.lookup(AstFactory.identifier3(typeName), importingLibrary);
- errorListener.assertNoErrors();
- expect(nonPrefixedElement, same(nonPrefixedType));
- }
-}
-
-@reflectiveTest
-class LibraryScopeTest extends ResolverTestCase {
- void test_creation_empty() {
- LibraryElement definingLibrary = createDefaultTestLibrary();
- GatheringErrorListener errorListener = new GatheringErrorListener();
- new LibraryScope(definingLibrary, errorListener);
- }
-
- void test_creation_nonEmpty() {
- AnalysisContext context = AnalysisContextFactory.contextWithCore();
- String importedTypeName = "A";
- ClassElement importedType =
- new ClassElementImpl.forNode(AstFactory.identifier3(importedTypeName));
- LibraryElement importedLibrary = createTestLibrary(context, "imported");
- (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
- .types = <ClassElement>[importedType];
- LibraryElementImpl definingLibrary =
- createTestLibrary(context, "importing");
- ImportElementImpl importElement = new ImportElementImpl(0);
- importElement.importedLibrary = importedLibrary;
- definingLibrary.imports = <ImportElement>[importElement];
- GatheringErrorListener errorListener = new GatheringErrorListener();
- Scope scope = new LibraryScope(definingLibrary, errorListener);
- expect(
- scope.lookup(AstFactory.identifier3(importedTypeName), definingLibrary),
- importedType);
- }
-
- void test_getErrorListener() {
- LibraryElement definingLibrary = createDefaultTestLibrary();
- GatheringErrorListener errorListener = new GatheringErrorListener();
- LibraryScope scope = new LibraryScope(definingLibrary, errorListener);
- expect(scope.errorListener, errorListener);
- }
-}
-
-@reflectiveTest
-class MemberMapTest {
- /**
- * The null type.
- */
- InterfaceType _nullType;
-
- void setUp() {
- _nullType = new TestTypeProvider().nullType;
- }
-
- void test_MemberMap_copyConstructor() {
- MethodElement m1 = ElementFactory.methodElement("m1", _nullType);
- MethodElement m2 = ElementFactory.methodElement("m2", _nullType);
- MethodElement m3 = ElementFactory.methodElement("m3", _nullType);
- MemberMap map = new MemberMap();
- map.put(m1.name, m1);
- map.put(m2.name, m2);
- map.put(m3.name, m3);
- MemberMap copy = new MemberMap.from(map);
- expect(copy.size, map.size);
- expect(copy.get(m1.name), m1);
- expect(copy.get(m2.name), m2);
- expect(copy.get(m3.name), m3);
- }
-
- void test_MemberMap_override() {
- MethodElement m1 = ElementFactory.methodElement("m", _nullType);
- MethodElement m2 = ElementFactory.methodElement("m", _nullType);
- MemberMap map = new MemberMap();
- map.put(m1.name, m1);
- map.put(m2.name, m2);
- expect(map.size, 1);
- expect(map.get("m"), m2);
- }
-
- void test_MemberMap_put() {
- MethodElement m1 = ElementFactory.methodElement("m1", _nullType);
- MemberMap map = new MemberMap();
- expect(map.size, 0);
- map.put(m1.name, m1);
- expect(map.size, 1);
- expect(map.get("m1"), m1);
- }
-}
-
-@reflectiveTest
-class NonHintCodeTest extends ResolverTestCase {
- void test_deadCode_deadBlock_conditionalElse_debugConst() {
- Source source = addSource(r'''
-const bool DEBUG = true;
-f() {
- DEBUG ? 1 : 2;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_conditionalIf_debugConst() {
- Source source = addSource(r'''
-const bool DEBUG = false;
-f() {
- DEBUG ? 1 : 2;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_else() {
- Source source = addSource(r'''
-const bool DEBUG = true;
-f() {
- if(DEBUG) {} else {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_if_debugConst_prefixedIdentifier() {
- Source source = addSource(r'''
-class A {
- static const bool DEBUG = false;
-}
-f() {
- if(A.DEBUG) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_if_debugConst_prefixedIdentifier2() {
- Source source = addSource(r'''
-library L;
-import 'lib2.dart';
-f() {
- if(A.DEBUG) {}
-}''');
- addNamedSource(
- "/lib2.dart",
- r'''
-library lib2;
-class A {
- static const bool DEBUG = false;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_if_debugConst_propertyAccessor() {
- Source source = addSource(r'''
-library L;
-import 'lib2.dart' as LIB;
-f() {
- if(LIB.A.DEBUG) {}
-}''');
- addNamedSource(
- "/lib2.dart",
- r'''
-library lib2;
-class A {
- static const bool DEBUG = false;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_if_debugConst_simpleIdentifier() {
- Source source = addSource(r'''
-const bool DEBUG = false;
-f() {
- if(DEBUG) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_while_debugConst() {
- Source source = addSource(r'''
-const bool DEBUG = false;
-f() {
- while(DEBUG) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadCatch_onCatchSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {}
-f() {
- try {} on B catch (e) {} on A catch (e) {} catch (e) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadOperandLHS_and_debugConst() {
- Source source = addSource(r'''
-const bool DEBUG = false;
-f() {
- bool b = DEBUG && false;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadOperandLHS_or_debugConst() {
- Source source = addSource(r'''
-const bool DEBUG = true;
-f() {
- bool b = DEBUG || true;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_classWithConstructor() {
- Source source = addSource(r'''
-@deprecated
-class C {
- C();
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_divisionOptimization() {
- Source source = addSource(r'''
-f(int x, int y) {
- var v = x / y.toInt();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_divisionOptimization_supressIfDivisionNotDefinedInCore() {
- Source source = addSource(r'''
-f(x, y) {
- var v = (x / y).toInt();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_divisionOptimization_supressIfDivisionOverridden() {
- Source source = addSource(r'''
-class A {
- num operator /(x) { return x; }
-}
-f(A x, A y) {
- var v = (x / y).toInt();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_duplicateImport_as() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart' as one;
-A a;
-one.A a2;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_duplicateImport_hide() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart' hide A;
-A a;
-B b;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}
-class B {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_duplicateImport_show() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart' show A;
-A a;
-B b;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}
-class B {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_importDeferredLibraryWithLoadFunction() {
- resolveWithErrors(<String>[
- r'''
-library lib1;
-f() {}''',
- r'''
-library root;
-import 'lib1.dart' deferred as lib1;
-main() { lib1.f(); }'''
- ], ErrorCode.EMPTY_LIST);
- }
-
- void test_issue20904BuggyTypePromotionAtIfJoin_1() {
- // https://code.google.com/p/dart/issues/detail?id=20904
- Source source = addSource(r'''
-f(var message, var dynamic_) {
- if (message is Function) {
- message = dynamic_;
- }
- int s = message;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_issue20904BuggyTypePromotionAtIfJoin_3() {
- // https://code.google.com/p/dart/issues/detail?id=20904
- Source source = addSource(r'''
-f(var message) {
- var dynamic_;
- if (message is Function) {
- message = dynamic_;
- } else {
- return;
- }
- int s = message;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_issue20904BuggyTypePromotionAtIfJoin_4() {
- // https://code.google.com/p/dart/issues/detail?id=20904
- Source source = addSource(r'''
-f(var message) {
- if (message is Function) {
- message = '';
- } else {
- return;
- }
- String s = message;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_missingReturn_emptyFunctionBody() {
- Source source = addSource(r'''
-abstract class A {
- int m();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_missingReturn_expressionFunctionBody() {
- Source source = addSource("int f() => 0;");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_missingReturn_noReturnType() {
- Source source = addSource("f() {}");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_missingReturn_voidReturnType() {
- Source source = addSource("void f() {}");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_nullAwareInCondition_for_noCondition() {
- Source source = addSource(r'''
-m(x) {
- for (var v = x; ; v++) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_notTopLevel() {
- Source source = addSource(r'''
-m(x) {
- if (x?.y == null) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_overrideEqualsButNotHashCode() {
- Source source = addSource(r'''
-class A {
- bool operator ==(x) { return x; }
- get hashCode => 0;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingGetter_inInterface() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
- int get m => 0;
-}
-class B implements A {
- @override
- int get m => 1;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingGetter_inSuperclass() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
- int get m => 0;
-}
-class B extends A {
- @override
- int get m => 1;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingMethod_inInterface() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
- int m() => 0;
-}
-class B implements A {
- @override
- int m() => 1;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingMethod_inSuperclass() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
- int m() => 0;
-}
-class B extends A {
- @override
- int m() => 1;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingSetter_inInterface() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
- set m(int x) {}
-}
-class B implements A {
- @override
- set m(int x) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingSetter_inSuperclass() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
- set m(int x) {}
-}
-class B extends A {
- @override
- set m(int x) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_propagatedFieldType() {
- Source source = addSource(r'''
-class A { }
-class X<T> {
- final x = new List<T>();
-}
-class Z {
- final X<A> y = new X<A>();
- foo() {
- y.x.add(new A());
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_proxy_annotation_prefixed() {
- Source source = addSource(r'''
-library L;
-@proxy
-class A {}
-f(var a) {
- a = new A();
- a.m();
- var x = a.g;
- a.s = 1;
- var y = a + a;
- a++;
- ++a;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_proxy_annotation_prefixed2() {
- Source source = addSource(r'''
-library L;
-@proxy
-class A {}
-class B {
- f(var a) {
- a = new A();
- a.m();
- var x = a.g;
- a.s = 1;
- var y = a + a;
- a++;
- ++a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_proxy_annotation_prefixed3() {
- Source source = addSource(r'''
-library L;
-class B {
- f(var a) {
- a = new A();
- a.m();
- var x = a.g;
- a.s = 1;
- var y = a + a;
- a++;
- ++a;
- }
-}
-@proxy
-class A {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedGetter_inSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- get b => 0;
-}
-f(var a) {
- if(a is A) {
- return a.b;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedMethod_assignmentExpression_inSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- operator +(B b) {return new B();}
-}
-f(var a, var a2) {
- a = new A();
- a2 = new A();
- a += a2;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedMethod_dynamic() {
- Source source = addSource(r'''
-class D<T extends dynamic> {
- fieldAccess(T t) => t.abc;
- methodAccess(T t) => t.xyz(1, 2, 'three');
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedMethod_inSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- b() {}
-}
-f() {
- var a = new A();
- a.b();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedMethod_unionType_all() {
- Source source = addSource(r'''
-class A {
- int m(int x) => 0;
-}
-class B {
- String m() => '0';
-}
-f(A a, B b) {
- var ab;
- if (0 < 1) {
- ab = a;
- } else {
- ab = b;
- }
- ab.m();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedMethod_unionType_some() {
- Source source = addSource(r'''
-class A {
- int m(int x) => 0;
-}
-class B {}
-f(A a, B b) {
- var ab;
- if (0 < 1) {
- ab = a;
- } else {
- ab = b;
- }
- ab.m(0);
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedOperator_binaryExpression_inSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- operator +(B b) {}
-}
-f(var a) {
- if(a is A) {
- a + 1;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedOperator_indexBoth_inSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- operator [](int index) {}
-}
-f(var a) {
- if(a is A) {
- a[0]++;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedOperator_indexGetter_inSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- operator [](int index) {}
-}
-f(var a) {
- if(a is A) {
- a[0];
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedOperator_indexSetter_inSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- operator []=(i, v) {}
-}
-f(var a) {
- if(a is A) {
- a[0] = 1;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedOperator_postfixExpression() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- operator +(B b) {return new B();}
-}
-f(var a) {
- if(a is A) {
- a++;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedOperator_prefixExpression() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- operator +(B b) {return new B();}
-}
-f(var a) {
- if(a is A) {
- ++a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedSetter_inSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- set b(x) {}
-}
-f(var a) {
- if(a is A) {
- a.b = 0;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_unnecessaryCast_13855_parameter_A() {
- // dartbug.com/13855, dartbug.com/13732
- Source source = addSource(r'''
-class A{
- a() {}
-}
-class B<E> {
- E e;
- m() {
- (e as A).a();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unnecessaryCast_conditionalExpression() {
- Source source = addSource(r'''
-abstract class I {}
-class A implements I {}
-class B implements I {}
-I m(A a, B b) {
- return a == null ? b as I : a as I;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unnecessaryCast_dynamic_type() {
- Source source = addSource(r'''
-m(v) {
- var b = v as Object;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unnecessaryCast_generics() {
- // dartbug.com/18953
- Source source = addSource(r'''
-import 'dart:async';
-Future<int> f() => new Future.value(0);
-void g(bool c) {
- (c ? f(): new Future.value(0) as Future<int>).then((int value) {});
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unnecessaryCast_type_dynamic() {
- Source source = addSource(r'''
-m(v) {
- var b = Object as dynamic;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unnecessaryNoSuchMethod_blockBody_notReturnStatement() {
- Source source = addSource(r'''
-class A {
- noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
- mmm();
- noSuchMethod(y) {
- print(y);
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unnecessaryNoSuchMethod_blockBody_notSingleStatement() {
- Source source = addSource(r'''
-class A {
- noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
- mmm();
- noSuchMethod(y) {
- print(y);
- return super.noSuchMethod(y);
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unnecessaryNoSuchMethod_expressionBody_notNoSuchMethod() {
- Source source = addSource(r'''
-class A {
- noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
- mmm();
- noSuchMethod(y) => super.hashCode;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unnecessaryNoSuchMethod_expressionBody_notSuper() {
- Source source = addSource(r'''
-class A {
- noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
- mmm();
- noSuchMethod(y) => 42;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedImport_annotationOnDirective() {
- Source source = addSource(r'''
-library L;
-@A()
-import 'lib1.dart';''');
- Source source2 = addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {
- const A() {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source, source2]);
- }
-
- void test_unusedImport_as_equalPrefixes() {
- // 18818
- Source source = addSource(r'''
-library L;
-import 'lib1.dart' as one;
-import 'lib2.dart' as one;
-one.A a;
-one.B b;''');
- Source source2 = addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}''');
- Source source3 = addNamedSource(
- "/lib2.dart",
- r'''
-library lib2;
-class B {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- assertNoErrors(source2);
- assertNoErrors(source3);
- verify([source, source2, source3]);
- }
-
- void test_unusedImport_core_library() {
- Source source = addSource(r'''
-library L;
-import 'dart:core';''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedImport_export() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-Two two;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-export 'lib2.dart';
-class One {}''');
- addNamedSource(
- "/lib2.dart",
- r'''
-library lib2;
-class Two {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedImport_export2() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-Three three;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-export 'lib2.dart';
-class One {}''');
- addNamedSource(
- "/lib2.dart",
- r'''
-library lib2;
-export 'lib3.dart';
-class Two {}''');
- addNamedSource(
- "/lib3.dart",
- r'''
-library lib3;
-class Three {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedImport_export_infiniteLoop() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-Two two;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-export 'lib2.dart';
-class One {}''');
- addNamedSource(
- "/lib2.dart",
- r'''
-library lib2;
-export 'lib3.dart';
-class Two {}''');
- addNamedSource(
- "/lib3.dart",
- r'''
-library lib3;
-export 'lib2.dart';
-class Three {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedImport_metadata() {
- Source source = addSource(r'''
-library L;
-@A(x)
-import 'lib1.dart';
-class A {
- final int value;
- const A(this.value);
-}''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-const x = 0;''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedImport_prefix_topLevelFunction() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart' hide topLevelFunction;
-import 'lib1.dart' as one show topLevelFunction;
-class A {
- static void x() {
- One o;
- one.topLevelFunction();
- }
-}''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class One {}
-topLevelFunction() {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_useOfVoidResult_implicitReturnValue() {
- Source source = addSource(r'''
-f() {}
-class A {
- n() {
- var a = f();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_useOfVoidResult_nonVoidReturnValue() {
- Source source = addSource(r'''
-int f() => 1;
-g() {
- var a = f();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-}
-
-class PubSuggestionCodeTest extends ResolverTestCase {
- void test_import_package() {
- Source source = addSource("import 'package:somepackage/other.dart';");
- computeLibrarySourceErrors(source);
- assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
- }
-
- void test_import_packageWithDotDot() {
- Source source = addSource("import 'package:somepackage/../other.dart';");
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CompileTimeErrorCode.URI_DOES_NOT_EXIST,
- HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
- ]);
- }
-
- void test_import_packageWithLeadingDotDot() {
- Source source = addSource("import 'package:../other.dart';");
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CompileTimeErrorCode.URI_DOES_NOT_EXIST,
- HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
- ]);
- }
-
- void test_import_referenceIntoLibDirectory() {
- cacheSource("/myproj/pubspec.yaml", "");
- cacheSource("/myproj/lib/other.dart", "");
- Source source =
- addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
- computeLibrarySourceErrors(source);
- assertErrors(
- source, [HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE]);
- }
-
- void test_import_referenceIntoLibDirectory_no_pubspec() {
- cacheSource("/myproj/lib/other.dart", "");
- Source source =
- addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_import_referenceOutOfLibDirectory() {
- cacheSource("/myproj/pubspec.yaml", "");
- cacheSource("/myproj/web/other.dart", "");
- Source source =
- addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
- computeLibrarySourceErrors(source);
- assertErrors(
- source, [HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE]);
- }
-
- void test_import_referenceOutOfLibDirectory_no_pubspec() {
- cacheSource("/myproj/web/other.dart", "");
- Source source =
- addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_import_valid_inside_lib1() {
- cacheSource("/myproj/pubspec.yaml", "");
- cacheSource("/myproj/lib/other.dart", "");
- Source source =
- addNamedSource("/myproj/lib/test.dart", "import 'other.dart';");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_import_valid_inside_lib2() {
- cacheSource("/myproj/pubspec.yaml", "");
- cacheSource("/myproj/lib/bar/other.dart", "");
- Source source = addNamedSource(
- "/myproj/lib/foo/test.dart", "import '../bar/other.dart';");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_import_valid_outside_lib() {
- cacheSource("/myproj/pubspec.yaml", "");
- cacheSource("/myproj/web/other.dart", "");
- Source source =
- addNamedSource("/myproj/lib2/test.dart", "import '../web/other.dart';");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-}
-
-/**
- * An AST visitor used to verify that all of the nodes in an AST structure that
- * should have been resolved were resolved.
- */
-class ResolutionVerifier extends RecursiveAstVisitor<Object> {
- /**
- * A set containing nodes that are known to not be resolvable and should
- * therefore not cause the test to fail.
- */
- final Set<AstNode> _knownExceptions;
-
- /**
- * A list containing all of the AST nodes that were not resolved.
- */
- List<AstNode> _unresolvedNodes = new List<AstNode>();
-
- /**
- * A list containing all of the AST nodes that were resolved to an element of
- * the wrong type.
- */
- List<AstNode> _wrongTypedNodes = new List<AstNode>();
-
- /**
- * Initialize a newly created verifier to verify that all of the identifiers
- * in the visited AST structures that are expected to have been resolved have
- * an element associated with them. Nodes in the set of [_knownExceptions] are
- * not expected to have been resolved, even if they normally would have been
- * expected to have been resolved.
- */
- ResolutionVerifier([this._knownExceptions]);
-
- /**
- * Assert that all of the visited identifiers were resolved.
- */
- void assertResolved() {
- if (!_unresolvedNodes.isEmpty || !_wrongTypedNodes.isEmpty) {
- StringBuffer buffer = new StringBuffer();
- if (!_unresolvedNodes.isEmpty) {
- buffer.write("Failed to resolve ");
- buffer.write(_unresolvedNodes.length);
- buffer.writeln(" nodes:");
- _printNodes(buffer, _unresolvedNodes);
- }
- if (!_wrongTypedNodes.isEmpty) {
- buffer.write("Resolved ");
- buffer.write(_wrongTypedNodes.length);
- buffer.writeln(" to the wrong type of element:");
- _printNodes(buffer, _wrongTypedNodes);
- }
- fail(buffer.toString());
- }
- }
-
- @override
- Object visitAnnotation(Annotation node) {
- node.visitChildren(this);
- ElementAnnotation elementAnnotation = node.elementAnnotation;
- if (elementAnnotation == null) {
- if (_knownExceptions == null || !_knownExceptions.contains(node)) {
- _unresolvedNodes.add(node);
- }
- } else if (elementAnnotation is! ElementAnnotation) {
- _wrongTypedNodes.add(node);
- }
- return null;
- }
-
- @override
- Object visitBinaryExpression(BinaryExpression node) {
- node.visitChildren(this);
- if (!node.operator.isUserDefinableOperator) {
- return null;
- }
- DartType operandType = node.leftOperand.staticType;
- if (operandType == null || operandType.isDynamic) {
- return null;
- }
- return _checkResolved(
- node, node.staticElement, (node) => node is MethodElement);
- }
-
- @override
- Object visitCommentReference(CommentReference node) => null;
-
- @override
- Object visitCompilationUnit(CompilationUnit node) {
- node.visitChildren(this);
- return _checkResolved(
- node, node.element, (node) => node is CompilationUnitElement);
- }
-
- @override
- Object visitExportDirective(ExportDirective node) =>
- _checkResolved(node, node.element, (node) => node is ExportElement);
-
- @override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
- node.visitChildren(this);
- if (node.element is LibraryElement) {
- _wrongTypedNodes.add(node);
- }
- return null;
- }
-
- @override
- Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
- node.visitChildren(this);
- // TODO(brianwilkerson) If we start resolving function expressions, then
- // conditionally check to see whether the node was resolved correctly.
- return null;
- //checkResolved(node, node.getElement(), FunctionElement.class);
- }
-
- @override
- Object visitImportDirective(ImportDirective node) {
- // Not sure how to test the combinators given that it isn't an error if the
- // names are not defined.
- _checkResolved(node, node.element, (node) => node is ImportElement);
- SimpleIdentifier prefix = node.prefix;
- if (prefix == null) {
- return null;
- }
- return _checkResolved(
- prefix, prefix.staticElement, (node) => node is PrefixElement);
- }
-
- @override
- Object visitIndexExpression(IndexExpression node) {
- node.visitChildren(this);
- DartType targetType = node.realTarget.staticType;
- if (targetType == null || targetType.isDynamic) {
- return null;
- }
- return _checkResolved(
- node, node.staticElement, (node) => node is MethodElement);
- }
-
- @override
- Object visitLibraryDirective(LibraryDirective node) =>
- _checkResolved(node, node.element, (node) => node is LibraryElement);
-
- @override
- Object visitNamedExpression(NamedExpression node) =>
- node.expression.accept(this);
-
- @override
- Object visitPartDirective(PartDirective node) => _checkResolved(
- node, node.element, (node) => node is CompilationUnitElement);
-
- @override
- Object visitPartOfDirective(PartOfDirective node) =>
- _checkResolved(node, node.element, (node) => node is LibraryElement);
-
- @override
- Object visitPostfixExpression(PostfixExpression node) {
- node.visitChildren(this);
- if (!node.operator.isUserDefinableOperator) {
- return null;
- }
- DartType operandType = node.operand.staticType;
- if (operandType == null || operandType.isDynamic) {
- return null;
- }
- return _checkResolved(
- node, node.staticElement, (node) => node is MethodElement);
- }
-
- @override
- Object visitPrefixedIdentifier(PrefixedIdentifier node) {
- SimpleIdentifier prefix = node.prefix;
- prefix.accept(this);
- DartType prefixType = prefix.staticType;
- if (prefixType == null || prefixType.isDynamic) {
- return null;
- }
- return _checkResolved(node, node.staticElement, null);
- }
-
- @override
- Object visitPrefixExpression(PrefixExpression node) {
- node.visitChildren(this);
- if (!node.operator.isUserDefinableOperator) {
- return null;
- }
- DartType operandType = node.operand.staticType;
- if (operandType == null || operandType.isDynamic) {
- return null;
- }
- return _checkResolved(
- node, node.staticElement, (node) => node is MethodElement);
- }
-
- @override
- Object visitPropertyAccess(PropertyAccess node) {
- Expression target = node.realTarget;
- target.accept(this);
- DartType targetType = target.staticType;
- if (targetType == null || targetType.isDynamic) {
- return null;
- }
- return node.propertyName.accept(this);
- }
-
- @override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
- if (node.name == "void") {
- return null;
- }
- if (node.staticType != null &&
- node.staticType.isDynamic &&
- node.staticElement == null) {
- return null;
- }
- AstNode parent = node.parent;
- if (parent is MethodInvocation) {
- MethodInvocation invocation = parent;
- if (identical(invocation.methodName, node)) {
- Expression target = invocation.realTarget;
- DartType targetType = target == null ? null : target.staticType;
- if (targetType == null || targetType.isDynamic) {
- return null;
- }
- }
- }
- return _checkResolved(node, node.staticElement, null);
- }
-
- Object _checkResolved(
- AstNode node, Element element, Predicate<Element> predicate) {
- if (element == null) {
- if (_knownExceptions == null || !_knownExceptions.contains(node)) {
- _unresolvedNodes.add(node);
- }
- } else if (predicate != null) {
- if (!predicate(element)) {
- _wrongTypedNodes.add(node);
- }
- }
- return null;
- }
-
- String _getFileName(AstNode node) {
- // TODO (jwren) there are two copies of this method, one here and one in
- // StaticTypeVerifier, they should be resolved into a single method
- if (node != null) {
- AstNode root = node.root;
- if (root is CompilationUnit) {
- CompilationUnit rootCU = root;
- if (rootCU.element != null) {
- return rootCU.element.source.fullName;
- } else {
- return "<unknown file- CompilationUnit.getElement() returned null>";
- }
- } else {
- return "<unknown file- CompilationUnit.getRoot() is not a CompilationUnit>";
- }
- }
- return "<unknown file- ASTNode is null>";
- }
-
- void _printNodes(StringBuffer buffer, List<AstNode> nodes) {
- for (AstNode identifier in nodes) {
- buffer.write(" ");
- buffer.write(identifier.toString());
- buffer.write(" (");
- buffer.write(_getFileName(identifier));
- buffer.write(" : ");
- buffer.write(identifier.offset);
- buffer.writeln(")");
- }
- }
-}
-
-class ResolverTestCase extends EngineTestCase {
- /**
- * The analysis context used to parse the compilation units being resolved.
- */
- InternalAnalysisContext analysisContext2;
-
- /**
- * Specifies if [assertErrors] should check for [HintCode.UNUSED_ELEMENT] and
- * [HintCode.UNUSED_FIELD].
- */
- bool enableUnusedElement = false;
-
- /**
- * Specifies if [assertErrors] should check for [HintCode.UNUSED_LOCAL_VARIABLE].
- */
- bool enableUnusedLocalVariable = false;
-
- AnalysisContext get analysisContext => analysisContext2;
-
- /**
- * Return a type provider that can be used to test the results of resolution.
- *
- * @return a type provider
- * @throws AnalysisException if dart:core cannot be resolved
- */
- TypeProvider get typeProvider => analysisContext2.typeProvider;
-
- /**
- * Return a type system that can be used to test the results of resolution.
- *
- * @return a type system
- */
- TypeSystem get typeSystem => analysisContext2.typeSystem;
-
- /**
- * Add a source file to the content provider. The file path should be absolute.
- *
- * @param filePath the path of the file being added
- * @param contents the contents to be returned by the content provider for the specified file
- * @return the source object representing the added file
- */
- Source addNamedSource(String filePath, String contents) {
- Source source = cacheSource(filePath, contents);
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source);
- analysisContext2.applyChanges(changeSet);
- return source;
- }
-
- /**
- * Add a source file to the content provider.
- *
- * @param contents the contents to be returned by the content provider for the specified file
- * @return the source object representing the added file
- */
- Source addSource(String contents) => addNamedSource("/test.dart", contents);
-
- /**
- * Assert that the number of errors reported against the given source matches the number of errors
- * that are given and that they have the expected error codes. The order in which the errors were
- * gathered is ignored.
- *
- * @param source the source against which the errors should have been reported
- * @param expectedErrorCodes the error codes of the errors that should have been reported
- * @throws AnalysisException if the reported errors could not be computed
- * @throws AssertionFailedError if a different number of errors have been reported than were
- * expected
- */
- void assertErrors(Source source,
- [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
- GatheringErrorListener errorListener = new GatheringErrorListener();
- for (AnalysisError error in analysisContext2.computeErrors(source)) {
- expect(error.source, source);
- ErrorCode errorCode = error.errorCode;
- if (!enableUnusedElement &&
- (errorCode == HintCode.UNUSED_ELEMENT ||
- errorCode == HintCode.UNUSED_FIELD)) {
- continue;
- }
- if (!enableUnusedLocalVariable &&
- (errorCode == HintCode.UNUSED_CATCH_CLAUSE ||
- errorCode == HintCode.UNUSED_CATCH_STACK ||
- errorCode == HintCode.UNUSED_LOCAL_VARIABLE)) {
- continue;
- }
- errorListener.onError(error);
- }
- errorListener.assertErrorsWithCodes(expectedErrorCodes);
- }
-
- /**
- * Asserts that [code] verifies, but has errors with the given error codes.
- *
- * Like [assertErrors], but takes a string of source code.
- */
- // TODO(rnystrom): Use this in more tests that have the same structure.
- void assertErrorsInCode(String code, List<ErrorCode> errors) {
- Source source = addSource(code);
- computeLibrarySourceErrors(source);
- assertErrors(source, errors);
- verify([source]);
- }
-
- /**
- * Asserts that [code] has errors with the given error codes.
- *
- * Like [assertErrors], but takes a string of source code.
- */
- void assertErrorsInUnverifiedCode(String code, List<ErrorCode> errors) {
- Source source = addSource(code);
- computeLibrarySourceErrors(source);
- assertErrors(source, errors);
- }
-
- /**
- * Assert that no errors have been reported against the given source.
- *
- * @param source the source against which no errors should have been reported
- * @throws AnalysisException if the reported errors could not be computed
- * @throws AssertionFailedError if any errors have been reported
- */
- void assertNoErrors(Source source) {
- assertErrors(source);
- }
-
- /**
- * Asserts that [code] has no errors or warnings.
- */
- // TODO(rnystrom): Use this in more tests that have the same structure.
- void assertNoErrorsInCode(String code) {
- Source source = addSource(code);
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- /**
- * Cache the source file content in the source factory but don't add the source to the analysis
- * context. The file path should be absolute.
- *
- * @param filePath the path of the file being cached
- * @param contents the contents to be returned by the content provider for the specified file
- * @return the source object representing the cached file
- */
- Source cacheSource(String filePath, String contents) {
- Source source = new FileBasedSource(FileUtilities2.createFile(filePath));
- analysisContext2.setContents(source, contents);
- return source;
- }
-
- /**
- * Change the contents of the given [source] to the given [contents].
- */
- void changeSource(Source source, String contents) {
- analysisContext2.setContents(source, contents);
- ChangeSet changeSet = new ChangeSet();
- changeSet.changedSource(source);
- analysisContext2.applyChanges(changeSet);
- }
-
- /**
- * Computes errors for the given [librarySource].
- * This assumes that the given [librarySource] and its parts have already
- * been added to the content provider using the method [addNamedSource].
- */
- void computeLibrarySourceErrors(Source librarySource) {
- analysisContext.computeErrors(librarySource);
- }
-
- /**
- * Create a library element that represents a library named `"test"` containing a single
- * empty compilation unit.
- *
- * @return the library element that was created
- */
- LibraryElementImpl createDefaultTestLibrary() =>
- createTestLibrary(AnalysisContextFactory.contextWithCore(), "test");
-
- /**
- * Create a library element that represents a library with the given name containing a single
- * empty compilation unit.
- *
- * @param libraryName the name of the library to be created
- * @return the library element that was created
- */
- LibraryElementImpl createTestLibrary(
- AnalysisContext context, String libraryName,
- [List<String> typeNames]) {
- String fileName = "$libraryName.dart";
- FileBasedSource definingCompilationUnitSource =
- _createNamedSource(fileName);
- List<CompilationUnitElement> sourcedCompilationUnits;
- if (typeNames == null) {
- sourcedCompilationUnits = CompilationUnitElement.EMPTY_LIST;
- } else {
- int count = typeNames.length;
- sourcedCompilationUnits = new List<CompilationUnitElement>(count);
- for (int i = 0; i < count; i++) {
- String typeName = typeNames[i];
- ClassElementImpl type =
- new ClassElementImpl.forNode(AstFactory.identifier3(typeName));
- String fileName = "$typeName.dart";
- CompilationUnitElementImpl compilationUnit =
- new CompilationUnitElementImpl(fileName);
- compilationUnit.source = _createNamedSource(fileName);
- compilationUnit.librarySource = definingCompilationUnitSource;
- compilationUnit.types = <ClassElement>[type];
- sourcedCompilationUnits[i] = compilationUnit;
- }
- }
- CompilationUnitElementImpl compilationUnit =
- new CompilationUnitElementImpl(fileName);
- compilationUnit.librarySource =
- compilationUnit.source = definingCompilationUnitSource;
- LibraryElementImpl library = new LibraryElementImpl.forNode(
- context, AstFactory.libraryIdentifier2([libraryName]));
- library.definingCompilationUnit = compilationUnit;
- library.parts = sourcedCompilationUnits;
- return library;
- }
-
- Expression findTopLevelConstantExpression(
- CompilationUnit compilationUnit, String name) =>
- findTopLevelDeclaration(compilationUnit, name).initializer;
-
- VariableDeclaration findTopLevelDeclaration(
- CompilationUnit compilationUnit, String name) {
- for (CompilationUnitMember member in compilationUnit.declarations) {
- if (member is TopLevelVariableDeclaration) {
- for (VariableDeclaration variable in member.variables.variables) {
- if (variable.name.name == name) {
- return variable;
- }
- }
- }
- }
- return null;
- // Not found
- }
-
- /**
- * In the rare cases we want to group several tests into single "test_" method, so need a way to
- * reset test instance to reuse it.
- */
- void reset() {
- analysisContext2 = AnalysisContextFactory.contextWithCore();
- }
-
- /**
- * Reset the analysis context to have the given options applied.
- *
- * @param options the analysis options to be applied to the context
- */
- void resetWithOptions(AnalysisOptions options) {
- analysisContext2 =
- AnalysisContextFactory.contextWithCoreAndOptions(options);
- }
-
- /**
- * Given a library and all of its parts, resolve the contents of the library and the contents of
- * the parts. This assumes that the sources for the library and its parts have already been added
- * to the content provider using the method [addNamedSource].
- *
- * @param librarySource the source for the compilation unit that defines the library
- * @return the element representing the resolved library
- * @throws AnalysisException if the analysis could not be performed
- */
- LibraryElement resolve2(Source librarySource) =>
- analysisContext2.computeLibraryElement(librarySource);
-
- /**
- * Return the resolved compilation unit corresponding to the given source in the given library.
- *
- * @param source the source of the compilation unit to be returned
- * @param library the library in which the compilation unit is to be resolved
- * @return the resolved compilation unit
- * @throws Exception if the compilation unit could not be resolved
- */
- CompilationUnit resolveCompilationUnit(
- Source source, LibraryElement library) =>
- analysisContext2.resolveCompilationUnit(source, library);
-
- CompilationUnit resolveSource(String sourceText) =>
- resolveSource2("/test.dart", sourceText);
-
- CompilationUnit resolveSource2(String fileName, String sourceText) {
- Source source = addNamedSource(fileName, sourceText);
- LibraryElement library = analysisContext.computeLibraryElement(source);
- return analysisContext.resolveCompilationUnit(source, library);
- }
-
- Source resolveSources(List<String> sourceTexts) {
- for (int i = 0; i < sourceTexts.length; i++) {
- CompilationUnit unit =
- resolveSource2("/lib${i + 1}.dart", sourceTexts[i]);
- // reference the source if this is the last source
- if (i + 1 == sourceTexts.length) {
- return unit.element.source;
- }
- }
- return null;
- }
-
- void resolveWithAndWithoutExperimental(
- List<String> strSources,
- List<ErrorCode> codesWithoutExperimental,
- List<ErrorCode> codesWithExperimental) {
- // Setup analysis context as non-experimental
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-// options.enableDeferredLoading = false;
- resetWithOptions(options);
- // Analysis and assertions
- Source source = resolveSources(strSources);
- assertErrors(source, codesWithoutExperimental);
- verify([source]);
- // Setup analysis context as experimental
- reset();
- // Analysis and assertions
- source = resolveSources(strSources);
- assertErrors(source, codesWithExperimental);
- verify([source]);
- }
-
- void resolveWithErrors(List<String> strSources, List<ErrorCode> codes) {
- // Analysis and assertions
- Source source = resolveSources(strSources);
- assertErrors(source, codes);
- verify([source]);
- }
-
- @override
- void setUp() {
- ElementFactory.flushStaticState();
- super.setUp();
- reset();
- }
-
- @override
- void tearDown() {
- analysisContext2 = null;
- super.tearDown();
- }
-
- /**
- * Verify that all of the identifiers in the compilation units associated with
- * the given [sources] have been resolved.
- */
- void verify(List<Source> sources) {
- ResolutionVerifier verifier = new ResolutionVerifier();
- for (Source source in sources) {
- List<Source> libraries = analysisContext2.getLibrariesContaining(source);
- for (Source library in libraries) {
- analysisContext2
- .resolveCompilationUnit2(source, library)
- .accept(verifier);
- }
- }
- verifier.assertResolved();
- }
-
- /**
- * @param code the code that assigns the value to the variable "v", no matter how. We check that
- * "v" has expected static and propagated type.
- */
- void _assertPropagatedAssignedType(String code, DartType expectedStaticType,
- DartType expectedPropagatedType) {
- SimpleIdentifier identifier = _findMarkedIdentifier(code, "v = ");
- expect(identifier.staticType, same(expectedStaticType));
- expect(identifier.propagatedType, same(expectedPropagatedType));
- }
-
- /**
- * @param code the code that iterates using variable "v". We check that
- * "v" has expected static and propagated type.
- */
- void _assertPropagatedIterationType(String code, DartType expectedStaticType,
- DartType expectedPropagatedType) {
- SimpleIdentifier identifier = _findMarkedIdentifier(code, "v in ");
- expect(identifier.staticType, same(expectedStaticType));
- expect(identifier.propagatedType, same(expectedPropagatedType));
- }
-
- /**
- * Check the static and propagated types of the expression marked with "; // marker" comment.
- *
- * @param code source code to analyze, with the expression to check marked with "// marker".
- * @param expectedStaticType if non-null, check actual static type is equal to this.
- * @param expectedPropagatedType if non-null, check actual static type is equal to this.
- * @throws Exception
- */
- void _assertTypeOfMarkedExpression(String code, DartType expectedStaticType,
- DartType expectedPropagatedType) {
- SimpleIdentifier identifier = _findMarkedIdentifier(code, "; // marker");
- if (expectedStaticType != null) {
- expect(identifier.staticType, expectedStaticType);
- }
- expect(identifier.propagatedType, expectedPropagatedType);
- }
-
- /**
- * Create a source object representing a file with the given [fileName] and
- * give it an empty content. Return the source that was created.
- */
- FileBasedSource _createNamedSource(String fileName) {
- FileBasedSource source =
- new FileBasedSource(FileUtilities2.createFile(fileName));
- analysisContext2.setContents(source, "");
- return source;
- }
-
- /**
- * Return the `SimpleIdentifier` marked by `marker`. The source code must have no
- * errors and be verifiable.
- *
- * @param code source code to analyze.
- * @param marker marker identifying sought after expression in source code.
- * @return expression marked by the marker.
- * @throws Exception
- */
- SimpleIdentifier _findMarkedIdentifier(String code, String marker) {
- try {
- Source source = addSource(code);
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = resolveCompilationUnit(source, library);
- // Could generalize this further by making [SimpleIdentifier.class] a
- // parameter.
- return EngineTestCase.findNode(
- unit, code, marker, (node) => node is SimpleIdentifier);
- } catch (exception) {
- // Is there a better exception to throw here? The point is that an
- // assertion failure here should be a failure, in both "test_*" and
- // "fail_*" tests. However, an assertion failure is success for the
- // purpose of "fail_*" tests, so without catching them here "fail_*" tests
- // can succeed by failing for the wrong reason.
- throw new JavaException("Unexexpected assertion failure: $exception");
- }
- }
-}
-
-class Scope_EnclosedScopeTest_test_define_duplicate extends Scope {
- GatheringErrorListener listener;
-
- Scope_EnclosedScopeTest_test_define_duplicate(this.listener) : super();
-
- @override
- AnalysisErrorListener get errorListener => listener;
-
- @override
- Element internalLookup(Identifier identifier, String name,
- LibraryElement referencingLibrary) =>
- null;
-}
-
-class Scope_EnclosedScopeTest_test_define_normal extends Scope {
- GatheringErrorListener listener;
-
- Scope_EnclosedScopeTest_test_define_normal(this.listener) : super();
-
- @override
- AnalysisErrorListener get errorListener => listener;
-
- @override
- Element internalLookup(Identifier identifier, String name,
- LibraryElement referencingLibrary) =>
- null;
-}
-
-@reflectiveTest
-class ScopeTest extends ResolverTestCase {
- void test_define_duplicate() {
- GatheringErrorListener errorListener = new GatheringErrorListener();
- ScopeTest_TestScope scope = new ScopeTest_TestScope(errorListener);
- VariableElement element1 =
- ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
- VariableElement element2 =
- ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
- scope.define(element1);
- scope.define(element2);
- errorListener.assertErrorsWithSeverities([ErrorSeverity.ERROR]);
- }
-
- void test_define_normal() {
- GatheringErrorListener errorListener = new GatheringErrorListener();
- ScopeTest_TestScope scope = new ScopeTest_TestScope(errorListener);
- VariableElement element1 =
- ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
- VariableElement element2 =
- ElementFactory.localVariableElement(AstFactory.identifier3("v2"));
- scope.define(element1);
- scope.define(element2);
- errorListener.assertNoErrors();
- }
-
- void test_getErrorListener() {
- GatheringErrorListener errorListener = new GatheringErrorListener();
- ScopeTest_TestScope scope = new ScopeTest_TestScope(errorListener);
- expect(scope.errorListener, errorListener);
- }
-
- void test_isPrivateName_nonPrivate() {
- expect(Scope.isPrivateName("Public"), isFalse);
- }
-
- void test_isPrivateName_private() {
- expect(Scope.isPrivateName("_Private"), isTrue);
- }
-}
-
-/**
- * A non-abstract subclass that can be used for testing purposes.
- */
-class ScopeTest_TestScope extends Scope {
- /**
- * The listener that is to be informed when an error is encountered.
- */
- final AnalysisErrorListener errorListener;
-
- ScopeTest_TestScope(this.errorListener);
-
- @override
- Element internalLookup(Identifier identifier, String name,
- LibraryElement referencingLibrary) =>
- localLookup(name, referencingLibrary);
-}
-
-@reflectiveTest
-class SimpleResolverTest extends ResolverTestCase {
- void fail_getter_and_setter_fromMixins_property_access() {
- // TODO(paulberry): it appears that auxiliaryElements isn't properly set on
- // a SimpleIdentifier that's inside a property access. This bug should be
- // fixed.
- Source source = addSource('''
-class B {}
-class M1 {
- get x => null;
- set x(value) {}
-}
-class M2 {
- get x => null;
- set x(value) {}
-}
-class C extends B with M1, M2 {}
-void main() {
- new C().x += 1;
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that both the getter and setter for "x" in "new C().x" refer to
- // the accessors defined in M2.
- FunctionDeclaration main =
- library.definingCompilationUnit.functions[0].computeNode();
- BlockFunctionBody body = main.functionExpression.body;
- ExpressionStatement stmt = body.block.statements[0];
- AssignmentExpression assignment = stmt.expression;
- PropertyAccess propertyAccess = assignment.leftHandSide;
- expect(
- propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
- expect(
- propertyAccess
- .propertyName.auxiliaryElements.staticElement.enclosingElement.name,
- 'M2');
- }
-
- void fail_staticInvocation() {
- Source source = addSource(r'''
-class A {
- static int get g => (a,b) => 0;
-}
-class B {
- f() {
- A.g(1,0);
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_argumentResolution_required_matching() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, 3);
- }
- void g(a, b, c) {}
-}''');
- _validateArgumentResolution(source, [0, 1, 2]);
- }
-
- void test_argumentResolution_required_tooFew() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2);
- }
- void g(a, b, c) {}
-}''');
- _validateArgumentResolution(source, [0, 1]);
- }
-
- void test_argumentResolution_required_tooMany() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, 3);
- }
- void g(a, b) {}
-}''');
- _validateArgumentResolution(source, [0, 1, -1]);
- }
-
- void test_argumentResolution_requiredAndNamed_extra() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, c: 3, d: 4);
- }
- void g(a, b, {c}) {}
-}''');
- _validateArgumentResolution(source, [0, 1, 2, -1]);
- }
-
- void test_argumentResolution_requiredAndNamed_matching() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, c: 3);
- }
- void g(a, b, {c}) {}
-}''');
- _validateArgumentResolution(source, [0, 1, 2]);
- }
-
- void test_argumentResolution_requiredAndNamed_missing() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, d: 3);
- }
- void g(a, b, {c, d}) {}
-}''');
- _validateArgumentResolution(source, [0, 1, 3]);
- }
-
- void test_argumentResolution_requiredAndPositional_fewer() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, 3);
- }
- void g(a, b, [c, d]) {}
-}''');
- _validateArgumentResolution(source, [0, 1, 2]);
- }
-
- void test_argumentResolution_requiredAndPositional_matching() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, 3, 4);
- }
- void g(a, b, [c, d]) {}
-}''');
- _validateArgumentResolution(source, [0, 1, 2, 3]);
- }
-
- void test_argumentResolution_requiredAndPositional_more() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, 3, 4);
- }
- void g(a, b, [c]) {}
-}''');
- _validateArgumentResolution(source, [0, 1, 2, -1]);
- }
-
- void test_argumentResolution_setter_propagated() {
- Source source = addSource(r'''
-main() {
- var a = new A();
- a.sss = 0;
-}
-class A {
- set sss(x) {}
-}''');
- LibraryElement library = resolve2(source);
- CompilationUnitElement unit = library.definingCompilationUnit;
- // find "a.sss = 0"
- AssignmentExpression assignment;
- {
- FunctionElement mainElement = unit.functions[0];
- FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
- Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
- ExpressionStatement expressionStatement =
- statement as ExpressionStatement;
- assignment = expressionStatement.expression as AssignmentExpression;
- }
- // get parameter
- Expression rhs = assignment.rightHandSide;
- expect(rhs.staticParameterElement, isNull);
- ParameterElement parameter = rhs.propagatedParameterElement;
- expect(parameter, isNotNull);
- expect(parameter.displayName, "x");
- // validate
- ClassElement classA = unit.types[0];
- PropertyAccessorElement setter = classA.accessors[0];
- expect(setter.parameters[0], same(parameter));
- }
-
- void test_argumentResolution_setter_propagated_propertyAccess() {
- Source source = addSource(r'''
-main() {
- var a = new A();
- a.b.sss = 0;
-}
-class A {
- B b = new B();
-}
-class B {
- set sss(x) {}
-}''');
- LibraryElement library = resolve2(source);
- CompilationUnitElement unit = library.definingCompilationUnit;
- // find "a.b.sss = 0"
- AssignmentExpression assignment;
- {
- FunctionElement mainElement = unit.functions[0];
- FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
- Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
- ExpressionStatement expressionStatement =
- statement as ExpressionStatement;
- assignment = expressionStatement.expression as AssignmentExpression;
- }
- // get parameter
- Expression rhs = assignment.rightHandSide;
- expect(rhs.staticParameterElement, isNull);
- ParameterElement parameter = rhs.propagatedParameterElement;
- expect(parameter, isNotNull);
- expect(parameter.displayName, "x");
- // validate
- ClassElement classB = unit.types[1];
- PropertyAccessorElement setter = classB.accessors[0];
- expect(setter.parameters[0], same(parameter));
- }
-
- void test_argumentResolution_setter_static() {
- Source source = addSource(r'''
-main() {
- A a = new A();
- a.sss = 0;
-}
-class A {
- set sss(x) {}
-}''');
- LibraryElement library = resolve2(source);
- CompilationUnitElement unit = library.definingCompilationUnit;
- // find "a.sss = 0"
- AssignmentExpression assignment;
- {
- FunctionElement mainElement = unit.functions[0];
- FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
- Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
- ExpressionStatement expressionStatement =
- statement as ExpressionStatement;
- assignment = expressionStatement.expression as AssignmentExpression;
- }
- // get parameter
- Expression rhs = assignment.rightHandSide;
- ParameterElement parameter = rhs.staticParameterElement;
- expect(parameter, isNotNull);
- expect(parameter.displayName, "x");
- // validate
- ClassElement classA = unit.types[0];
- PropertyAccessorElement setter = classA.accessors[0];
- expect(setter.parameters[0], same(parameter));
- }
-
- void test_argumentResolution_setter_static_propertyAccess() {
- Source source = addSource(r'''
-main() {
- A a = new A();
- a.b.sss = 0;
-}
-class A {
- B b = new B();
-}
-class B {
- set sss(x) {}
-}''');
- LibraryElement library = resolve2(source);
- CompilationUnitElement unit = library.definingCompilationUnit;
- // find "a.b.sss = 0"
- AssignmentExpression assignment;
- {
- FunctionElement mainElement = unit.functions[0];
- FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
- Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
- ExpressionStatement expressionStatement =
- statement as ExpressionStatement;
- assignment = expressionStatement.expression as AssignmentExpression;
- }
- // get parameter
- Expression rhs = assignment.rightHandSide;
- ParameterElement parameter = rhs.staticParameterElement;
- expect(parameter, isNotNull);
- expect(parameter.displayName, "x");
- // validate
- ClassElement classB = unit.types[1];
- PropertyAccessorElement setter = classB.accessors[0];
- expect(setter.parameters[0], same(parameter));
- }
-
- void test_breakTarget_labeled() {
- // Verify that the target of the label is correctly found and is recorded
- // as the unlabeled portion of the statement.
- String text = r'''
-void f() {
- loop1: while (true) {
- loop2: for (int i = 0; i < 10; i++) {
- break loop1;
- break loop2;
- }
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- WhileStatement whileStatement = EngineTestCase.findNode(
- unit, text, 'while (true)', (n) => n is WhileStatement);
- ForStatement forStatement =
- EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
- BreakStatement break1 = EngineTestCase.findNode(
- unit, text, 'break loop1', (n) => n is BreakStatement);
- BreakStatement break2 = EngineTestCase.findNode(
- unit, text, 'break loop2', (n) => n is BreakStatement);
- expect(break1.target, same(whileStatement));
- expect(break2.target, same(forStatement));
- }
-
- void test_breakTarget_unlabeledBreakFromDo() {
- String text = r'''
-void f() {
- do {
- break;
- } while (true);
-}
-''';
- CompilationUnit unit = resolveSource(text);
- DoStatement doStatement =
- EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement);
- BreakStatement breakStatement = EngineTestCase.findNode(
- unit, text, 'break', (n) => n is BreakStatement);
- expect(breakStatement.target, same(doStatement));
- }
-
- void test_breakTarget_unlabeledBreakFromFor() {
- String text = r'''
-void f() {
- for (int i = 0; i < 10; i++) {
- break;
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- ForStatement forStatement =
- EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
- BreakStatement breakStatement = EngineTestCase.findNode(
- unit, text, 'break', (n) => n is BreakStatement);
- expect(breakStatement.target, same(forStatement));
- }
-
- void test_breakTarget_unlabeledBreakFromForEach() {
- String text = r'''
-void f() {
- for (x in []) {
- break;
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- ForEachStatement forStatement = EngineTestCase.findNode(
- unit, text, 'for', (n) => n is ForEachStatement);
- BreakStatement breakStatement = EngineTestCase.findNode(
- unit, text, 'break', (n) => n is BreakStatement);
- expect(breakStatement.target, same(forStatement));
- }
-
- void test_breakTarget_unlabeledBreakFromSwitch() {
- String text = r'''
-void f() {
- while (true) {
- switch (0) {
- case 0:
- break;
- }
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- SwitchStatement switchStatement = EngineTestCase.findNode(
- unit, text, 'switch', (n) => n is SwitchStatement);
- BreakStatement breakStatement = EngineTestCase.findNode(
- unit, text, 'break', (n) => n is BreakStatement);
- expect(breakStatement.target, same(switchStatement));
- }
-
- void test_breakTarget_unlabeledBreakFromWhile() {
- String text = r'''
-void f() {
- while (true) {
- break;
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- WhileStatement whileStatement = EngineTestCase.findNode(
- unit, text, 'while', (n) => n is WhileStatement);
- BreakStatement breakStatement = EngineTestCase.findNode(
- unit, text, 'break', (n) => n is BreakStatement);
- expect(breakStatement.target, same(whileStatement));
- }
-
- void test_breakTarget_unlabeledBreakToOuterFunction() {
- // Verify that unlabeled break statements can't resolve to loops in an
- // outer function.
- String text = r'''
-void f() {
- while (true) {
- void g() {
- break;
- }
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- BreakStatement breakStatement = EngineTestCase.findNode(
- unit, text, 'break', (n) => n is BreakStatement);
- expect(breakStatement.target, isNull);
- }
-
- void test_class_definesCall() {
- Source source = addSource(r'''
-class A {
- int call(int x) { return x; }
-}
-int f(A a) {
- return a(0);
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_class_extends_implements() {
- Source source = addSource(r'''
-class A extends B implements C {}
-class B {}
-class C {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_commentReference_class() {
- Source source = addSource(r'''
-f() {}
-/** [A] [new A] [A.n] [new A.n] [m] [f] */
-class A {
- A() {}
- A.n() {}
- m() {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_commentReference_parameter() {
- Source source = addSource(r'''
-class A {
- A() {}
- A.n() {}
- /** [e] [f] */
- m(e, f()) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_commentReference_singleLine() {
- Source source = addSource(r'''
-/// [A]
-class A {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_continueTarget_labeled() {
- // Verify that the target of the label is correctly found and is recorded
- // as the unlabeled portion of the statement.
- String text = r'''
-void f() {
- loop1: while (true) {
- loop2: for (int i = 0; i < 10; i++) {
- continue loop1;
- continue loop2;
- }
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- WhileStatement whileStatement = EngineTestCase.findNode(
- unit, text, 'while (true)', (n) => n is WhileStatement);
- ForStatement forStatement =
- EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
- ContinueStatement continue1 = EngineTestCase.findNode(
- unit, text, 'continue loop1', (n) => n is ContinueStatement);
- ContinueStatement continue2 = EngineTestCase.findNode(
- unit, text, 'continue loop2', (n) => n is ContinueStatement);
- expect(continue1.target, same(whileStatement));
- expect(continue2.target, same(forStatement));
- }
-
- void test_continueTarget_unlabeledContinueFromDo() {
- String text = r'''
-void f() {
- do {
- continue;
- } while (true);
-}
-''';
- CompilationUnit unit = resolveSource(text);
- DoStatement doStatement =
- EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement);
- ContinueStatement continueStatement = EngineTestCase.findNode(
- unit, text, 'continue', (n) => n is ContinueStatement);
- expect(continueStatement.target, same(doStatement));
- }
-
- void test_continueTarget_unlabeledContinueFromFor() {
- String text = r'''
-void f() {
- for (int i = 0; i < 10; i++) {
- continue;
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- ForStatement forStatement =
- EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
- ContinueStatement continueStatement = EngineTestCase.findNode(
- unit, text, 'continue', (n) => n is ContinueStatement);
- expect(continueStatement.target, same(forStatement));
- }
-
- void test_continueTarget_unlabeledContinueFromForEach() {
- String text = r'''
-void f() {
- for (x in []) {
- continue;
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- ForEachStatement forStatement = EngineTestCase.findNode(
- unit, text, 'for', (n) => n is ForEachStatement);
- ContinueStatement continueStatement = EngineTestCase.findNode(
- unit, text, 'continue', (n) => n is ContinueStatement);
- expect(continueStatement.target, same(forStatement));
- }
-
- void test_continueTarget_unlabeledContinueFromWhile() {
- String text = r'''
-void f() {
- while (true) {
- continue;
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- WhileStatement whileStatement = EngineTestCase.findNode(
- unit, text, 'while', (n) => n is WhileStatement);
- ContinueStatement continueStatement = EngineTestCase.findNode(
- unit, text, 'continue', (n) => n is ContinueStatement);
- expect(continueStatement.target, same(whileStatement));
- }
-
- void test_continueTarget_unlabeledContinueSkipsSwitch() {
- String text = r'''
-void f() {
- while (true) {
- switch (0) {
- case 0:
- continue;
- }
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- WhileStatement whileStatement = EngineTestCase.findNode(
- unit, text, 'while', (n) => n is WhileStatement);
- ContinueStatement continueStatement = EngineTestCase.findNode(
- unit, text, 'continue', (n) => n is ContinueStatement);
- expect(continueStatement.target, same(whileStatement));
- }
-
- void test_continueTarget_unlabeledContinueToOuterFunction() {
- // Verify that unlabeled continue statements can't resolve to loops in an
- // outer function.
- String text = r'''
-void f() {
- while (true) {
- void g() {
- continue;
- }
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- ContinueStatement continueStatement = EngineTestCase.findNode(
- unit, text, 'continue', (n) => n is ContinueStatement);
- expect(continueStatement.target, isNull);
- }
-
- void test_empty() {
- Source source = addSource("");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_entryPoint_exported() {
- addNamedSource(
- "/two.dart",
- r'''
-library two;
-main() {}''');
- Source source = addNamedSource(
- "/one.dart",
- r'''
-library one;
-export 'two.dart';''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- FunctionElement main = library.entryPoint;
- expect(main, isNotNull);
- expect(main.library, isNot(same(library)));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_entryPoint_local() {
- Source source = addNamedSource(
- "/one.dart",
- r'''
-library one;
-main() {}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- FunctionElement main = library.entryPoint;
- expect(main, isNotNull);
- expect(main.library, same(library));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_entryPoint_none() {
- Source source = addNamedSource("/one.dart", "library one;");
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- expect(library.entryPoint, isNull);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_enum_externalLibrary() {
- addNamedSource(
- "/my_lib.dart",
- r'''
-library my_lib;
-enum EEE {A, B, C}''');
- Source source = addSource(r'''
-import 'my_lib.dart';
-main() {
- EEE e = null;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_extractedMethodAsConstant() {
- Source source = addSource(r'''
-abstract class Comparable<T> {
- int compareTo(T other);
- static int compare(Comparable a, Comparable b) => a.compareTo(b);
-}
-class A {
- void sort([compare = Comparable.compare]) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_fieldFormalParameter() {
- Source source = addSource(r'''
-class A {
- int x;
- A(this.x) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_forEachLoops_nonConflicting() {
- Source source = addSource(r'''
-f() {
- List list = [1,2,3];
- for (int x in list) {}
- for (int x in list) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_forLoops_nonConflicting() {
- Source source = addSource(r'''
-f() {
- for (int i = 0; i < 3; i++) {
- }
- for (int i = 0; i < 3; i++) {
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_functionTypeAlias() {
- Source source = addSource(r'''
-typedef bool P(e);
-class A {
- P p;
- m(e) {
- if (p(e)) {}
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_getter_and_setter_fromMixins_bare_identifier() {
- Source source = addSource('''
-class B {}
-class M1 {
- get x => null;
- set x(value) {}
-}
-class M2 {
- get x => null;
- set x(value) {}
-}
-class C extends B with M1, M2 {
- void f() {
- x += 1;
- }
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that both the getter and setter for "x" in C.f() refer to the
- // accessors defined in M2.
- ClassElement classC = library.definingCompilationUnit.types[3];
- MethodDeclaration f = classC.getMethod('f').computeNode();
- BlockFunctionBody body = f.body;
- ExpressionStatement stmt = body.block.statements[0];
- AssignmentExpression assignment = stmt.expression;
- SimpleIdentifier leftHandSide = assignment.leftHandSide;
- expect(leftHandSide.staticElement.enclosingElement.name, 'M2');
- expect(leftHandSide.auxiliaryElements.staticElement.enclosingElement.name,
- 'M2');
- }
-
- void test_getter_fromMixins_bare_identifier() {
- Source source = addSource('''
-class B {}
-class M1 {
- get x => null;
-}
-class M2 {
- get x => null;
-}
-class C extends B with M1, M2 {
- f() {
- return x;
- }
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that the getter for "x" in C.f() refers to the getter defined in
- // M2.
- ClassElement classC = library.definingCompilationUnit.types[3];
- MethodDeclaration f = classC.getMethod('f').computeNode();
- BlockFunctionBody body = f.body;
- ReturnStatement stmt = body.block.statements[0];
- SimpleIdentifier x = stmt.expression;
- expect(x.staticElement.enclosingElement.name, 'M2');
- }
-
- void test_getter_fromMixins_property_access() {
- Source source = addSource('''
-class B {}
-class M1 {
- get x => null;
-}
-class M2 {
- get x => null;
-}
-class C extends B with M1, M2 {}
-void main() {
- var y = new C().x;
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that the getter for "x" in "new C().x" refers to the getter
- // defined in M2.
- FunctionDeclaration main =
- library.definingCompilationUnit.functions[0].computeNode();
- BlockFunctionBody body = main.functionExpression.body;
- VariableDeclarationStatement stmt = body.block.statements[0];
- PropertyAccess propertyAccess = stmt.variables.variables[0].initializer;
- expect(
- propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
- }
-
- void test_getterAndSetterWithDifferentTypes() {
- Source source = addSource(r'''
-class A {
- int get f => 0;
- void set f(String s) {}
-}
-g (A a) {
- a.f = a.f.toString();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(
- source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
- verify([source]);
- }
-
- void test_hasReferenceToSuper() {
- Source source = addSource(r'''
-class A {}
-class B {toString() => super.toString();}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<ClassElement> classes = unit.types;
- expect(classes, hasLength(2));
- expect(classes[0].hasReferenceToSuper, isFalse);
- expect(classes[1].hasReferenceToSuper, isTrue);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_import_hide() {
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-set foo(value) {}
-class A {}''');
- addNamedSource(
- "/lib2.dart",
- r'''
-library lib2;
-set foo(value) {}''');
- Source source = addNamedSource(
- "/lib3.dart",
- r'''
-import 'lib1.dart' hide foo;
-import 'lib2.dart';
-
-main() {
- foo = 0;
-}
-A a;''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_import_prefix() {
- addNamedSource(
- "/two.dart",
- r'''
-library two;
-f(int x) {
- return x * x;
-}''');
- Source source = addNamedSource(
- "/one.dart",
- r'''
-library one;
-import 'two.dart' as _two;
-main() {
- _two.f(0);
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_import_spaceInUri() {
- addNamedSource(
- "/sub folder/lib.dart",
- r'''
-library lib;
-foo() {}''');
- Source source = addNamedSource(
- "/app.dart",
- r'''
-import 'sub folder/lib.dart';
-
-main() {
- foo();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_indexExpression_typeParameters() {
- Source source = addSource(r'''
-f() {
- List<int> a;
- a[0];
- List<List<int>> b;
- b[0][0];
- List<List<List<int>>> c;
- c[0][0][0];
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_indexExpression_typeParameters_invalidAssignmentWarning() {
- Source source = addSource(r'''
-f() {
- List<List<int>> b;
- b[0][0] = 'hi';
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
- verify([source]);
- }
-
- void test_indirectOperatorThroughCall() {
- Source source = addSource(r'''
-class A {
- B call() { return new B(); }
-}
-
-class B {
- int operator [](int i) { return i; }
-}
-
-A f = new A();
-
-g(int x) {}
-
-main() {
- g(f()[0]);
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_invoke_dynamicThroughGetter() {
- Source source = addSource(r'''
-class A {
- List get X => [() => 0];
- m(A a) {
- X.last;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_isValidMixin_badSuperclass() {
- Source source = addSource(r'''
-class A extends B {}
-class B {}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isFalse);
- assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
- verify([source]);
- }
-
- void test_isValidMixin_badSuperclass_withSuperMixins() {
- resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
- Source source = addSource(r'''
-class A extends B {}
-class B {}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isTrue);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_isValidMixin_constructor() {
- Source source = addSource(r'''
-class A {
- A() {}
-}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isFalse);
- assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
- verify([source]);
- }
-
- void test_isValidMixin_constructor_withSuperMixins() {
- resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
- Source source = addSource(r'''
-class A {
- A() {}
-}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isFalse);
- assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
- verify([source]);
- }
-
- void test_isValidMixin_factoryConstructor() {
- Source source = addSource(r'''
-class A {
- factory A() => null;
-}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isTrue);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_isValidMixin_factoryConstructor_withSuperMixins() {
- resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
- Source source = addSource(r'''
-class A {
- factory A() => null;
-}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isTrue);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_isValidMixin_super() {
- Source source = addSource(r'''
-class A {
- toString() {
- return super.toString();
- }
-}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isFalse);
- assertErrors(source, [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]);
- verify([source]);
- }
-
- void test_isValidMixin_super_withSuperMixins() {
- resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
- Source source = addSource(r'''
-class A {
- toString() {
- return super.toString();
- }
-}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isTrue);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_isValidMixin_valid() {
- Source source = addSource('''
-class A {}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isTrue);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_isValidMixin_valid_withSuperMixins() {
- resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
- Source source = addSource('''
-class A {}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isTrue);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_labels_switch() {
- Source source = addSource(r'''
-void doSwitch(int target) {
- switch (target) {
- l0: case 0:
- continue l1;
- l1: case 1:
- continue l0;
- default:
- continue l1;
- }
-}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_localVariable_types_invoked() {
- Source source = addSource(r'''
-const A = null;
-main() {
- var myVar = (int p) => 'foo';
- myVar(42);
-}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnit unit =
- analysisContext.resolveCompilationUnit(source, library);
- expect(unit, isNotNull);
- List<bool> found = [false];
- List<CaughtException> thrownException = new List<CaughtException>(1);
- unit.accept(new _SimpleResolverTest_localVariable_types_invoked(
- this, found, thrownException));
- if (thrownException[0] != null) {
- throw new AnalysisException(
- "Exception", new CaughtException(thrownException[0], null));
- }
- expect(found[0], isTrue);
- }
-
- void test_metadata_class() {
- Source source = addSource(r'''
-const A = null;
-@A class C<A> {}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unitElement = library.definingCompilationUnit;
- expect(unitElement, isNotNull);
- List<ClassElement> classes = unitElement.types;
- expect(classes, hasLength(1));
- List<ElementAnnotation> annotations = classes[0].metadata;
- expect(annotations, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = resolveCompilationUnit(source, library);
- NodeList<CompilationUnitMember> declarations = unit.declarations;
- expect(declarations, hasLength(2));
- Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
- .variables
- .variables[0]
- .name
- .staticElement;
- EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
- PropertyInducingElement, expectedElement);
- expectedElement = (expectedElement as PropertyInducingElement).getter;
- Element actualElement =
- (declarations[1] as ClassDeclaration).metadata[0].name.staticElement;
- expect(actualElement, same(expectedElement));
- }
-
- void test_metadata_field() {
- Source source = addSource(r'''
-const A = null;
-class C {
- @A int f;
-}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<ClassElement> classes = unit.types;
- expect(classes, hasLength(1));
- FieldElement field = classes[0].fields[0];
- List<ElementAnnotation> annotations = field.metadata;
- expect(annotations, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_fieldFormalParameter() {
- Source source = addSource(r'''
-const A = null;
-class C {
- int f;
- C(@A this.f);
-}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<ClassElement> classes = unit.types;
- expect(classes, hasLength(1));
- List<ConstructorElement> constructors = classes[0].constructors;
- expect(constructors, hasLength(1));
- List<ParameterElement> parameters = constructors[0].parameters;
- expect(parameters, hasLength(1));
- List<ElementAnnotation> annotations = parameters[0].metadata;
- expect(annotations, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_function() {
- Source source = addSource(r'''
-const A = null;
-@A f() {}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<FunctionElement> functions = unit.functions;
- expect(functions, hasLength(1));
- List<ElementAnnotation> annotations = functions[0].metadata;
- expect(annotations, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_functionTypedParameter() {
- Source source = addSource(r'''
-const A = null;
-f(@A int p(int x)) {}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<FunctionElement> functions = unit.functions;
- expect(functions, hasLength(1));
- List<ParameterElement> parameters = functions[0].parameters;
- expect(parameters, hasLength(1));
- List<ElementAnnotation> annotations1 = parameters[0].metadata;
- expect(annotations1, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_libraryDirective() {
- Source source = addSource(r'''
-@A library lib;
-const A = null;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- List<ElementAnnotation> annotations = library.metadata;
- expect(annotations, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_method() {
- Source source = addSource(r'''
-const A = null;
-class C {
- @A void m() {}
-}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<ClassElement> classes = unit.types;
- expect(classes, hasLength(1));
- MethodElement method = classes[0].methods[0];
- List<ElementAnnotation> annotations = method.metadata;
- expect(annotations, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_namedParameter() {
- Source source = addSource(r'''
-const A = null;
-f({@A int p : 0}) {}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<FunctionElement> functions = unit.functions;
- expect(functions, hasLength(1));
- List<ParameterElement> parameters = functions[0].parameters;
- expect(parameters, hasLength(1));
- List<ElementAnnotation> annotations1 = parameters[0].metadata;
- expect(annotations1, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_positionalParameter() {
- Source source = addSource(r'''
-const A = null;
-f([@A int p = 0]) {}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<FunctionElement> functions = unit.functions;
- expect(functions, hasLength(1));
- List<ParameterElement> parameters = functions[0].parameters;
- expect(parameters, hasLength(1));
- List<ElementAnnotation> annotations1 = parameters[0].metadata;
- expect(annotations1, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_simpleParameter() {
- Source source = addSource(r'''
-const A = null;
-f(@A p1, @A int p2) {}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<FunctionElement> functions = unit.functions;
- expect(functions, hasLength(1));
- List<ParameterElement> parameters = functions[0].parameters;
- expect(parameters, hasLength(2));
- List<ElementAnnotation> annotations1 = parameters[0].metadata;
- expect(annotations1, hasLength(1));
- List<ElementAnnotation> annotations2 = parameters[1].metadata;
- expect(annotations2, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_typedef() {
- Source source = addSource(r'''
-const A = null;
-@A typedef F<A>();''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unitElement = library.definingCompilationUnit;
- expect(unitElement, isNotNull);
- List<FunctionTypeAliasElement> aliases = unitElement.functionTypeAliases;
- expect(aliases, hasLength(1));
- List<ElementAnnotation> annotations = aliases[0].metadata;
- expect(annotations, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = resolveCompilationUnit(source, library);
- NodeList<CompilationUnitMember> declarations = unit.declarations;
- expect(declarations, hasLength(2));
- Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
- .variables
- .variables[0]
- .name
- .staticElement;
- EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
- PropertyInducingElement, expectedElement);
- expectedElement = (expectedElement as PropertyInducingElement).getter;
- Element actualElement =
- (declarations[1] as FunctionTypeAlias).metadata[0].name.staticElement;
- expect(actualElement, same(expectedElement));
- }
-
- void test_method_fromMixin() {
- Source source = addSource(r'''
-class B {
- bar() => 1;
-}
-class A {
- foo() => 2;
-}
-
-class C extends B with A {
- bar() => super.bar();
- foo() => super.foo();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_method_fromMixins() {
- Source source = addSource('''
-class B {}
-class M1 {
- void f() {}
-}
-class M2 {
- void f() {}
-}
-class C extends B with M1, M2 {}
-void main() {
- new C().f();
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that the "f" in "new C().f()" refers to the "f" defined in M2.
- FunctionDeclaration main =
- library.definingCompilationUnit.functions[0].computeNode();
- BlockFunctionBody body = main.functionExpression.body;
- ExpressionStatement stmt = body.block.statements[0];
- MethodInvocation expr = stmt.expression;
- expect(expr.methodName.staticElement.enclosingElement.name, 'M2');
- }
-
- void test_method_fromMixins_bare_identifier() {
- Source source = addSource('''
-class B {}
-class M1 {
- void f() {}
-}
-class M2 {
- void f() {}
-}
-class C extends B with M1, M2 {
- void g() {
- f();
- }
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that the call to f() in C.g() refers to the method defined in M2.
- ClassElement classC = library.definingCompilationUnit.types[3];
- MethodDeclaration g = classC.getMethod('g').computeNode();
- BlockFunctionBody body = g.body;
- ExpressionStatement stmt = body.block.statements[0];
- MethodInvocation invocation = stmt.expression;
- SimpleIdentifier methodName = invocation.methodName;
- expect(methodName.staticElement.enclosingElement.name, 'M2');
- }
-
- void test_method_fromMixins_invked_from_outside_class() {
- Source source = addSource('''
-class B {}
-class M1 {
- void f() {}
-}
-class M2 {
- void f() {}
-}
-class C extends B with M1, M2 {}
-void main() {
- new C().f();
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that the call to f() in "new C().f()" refers to the method
- // defined in M2.
- FunctionDeclaration main =
- library.definingCompilationUnit.functions[0].computeNode();
- BlockFunctionBody body = main.functionExpression.body;
- ExpressionStatement stmt = body.block.statements[0];
- MethodInvocation invocation = stmt.expression;
- expect(invocation.methodName.staticElement.enclosingElement.name, 'M2');
- }
-
- void test_method_fromSuperclassMixin() {
- Source source = addSource(r'''
-class A {
- void m1() {}
-}
-class B extends Object with A {
-}
-class C extends B {
-}
-f(C c) {
- c.m1();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_methodCascades() {
- Source source = addSource(r'''
-class A {
- void m1() {}
- void m2() {}
- void m() {
- A a = new A();
- a..m1()
- ..m2();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_methodCascades_withSetter() {
- Source source = addSource(r'''
-class A {
- String name;
- void m1() {}
- void m2() {}
- void m() {
- A a = new A();
- a..m1()
- ..name = 'name'
- ..m2();
- }
-}''');
- computeLibrarySourceErrors(source);
- // failing with error code: INVOCATION_OF_NON_FUNCTION
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_resolveAgainstNull() {
- Source source = addSource(r'''
-f(var p) {
- return null == p;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_setter_fromMixins_bare_identifier() {
- Source source = addSource('''
-class B {}
-class M1 {
- set x(value) {}
-}
-class M2 {
- set x(value) {}
-}
-class C extends B with M1, M2 {
- void f() {
- x = 1;
- }
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that the setter for "x" in C.f() refers to the setter defined in
- // M2.
- ClassElement classC = library.definingCompilationUnit.types[3];
- MethodDeclaration f = classC.getMethod('f').computeNode();
- BlockFunctionBody body = f.body;
- ExpressionStatement stmt = body.block.statements[0];
- AssignmentExpression assignment = stmt.expression;
- SimpleIdentifier leftHandSide = assignment.leftHandSide;
- expect(leftHandSide.staticElement.enclosingElement.name, 'M2');
- }
-
- void test_setter_fromMixins_property_access() {
- Source source = addSource('''
-class B {}
-class M1 {
- set x(value) {}
-}
-class M2 {
- set x(value) {}
-}
-class C extends B with M1, M2 {}
-void main() {
- new C().x = 1;
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that the setter for "x" in "new C().x" refers to the setter
- // defined in M2.
- FunctionDeclaration main =
- library.definingCompilationUnit.functions[0].computeNode();
- BlockFunctionBody body = main.functionExpression.body;
- ExpressionStatement stmt = body.block.statements[0];
- AssignmentExpression assignment = stmt.expression;
- PropertyAccess propertyAccess = assignment.leftHandSide;
- expect(
- propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
- }
-
- void test_setter_inherited() {
- Source source = addSource(r'''
-class A {
- int get x => 0;
- set x(int p) {}
-}
-class B extends A {
- int get x => super.x == null ? 0 : super.x;
- int f() => x = 1;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_setter_static() {
- Source source = addSource(r'''
-set s(x) {
-}
-
-main() {
- s = 123;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- /**
- * Resolve the given source and verify that the arguments in a specific method invocation were
- * correctly resolved.
- *
- * The source is expected to be source for a compilation unit, the first declaration is expected
- * to be a class, the first member of which is expected to be a method with a block body, and the
- * first statement in the body is expected to be an expression statement whose expression is a
- * method invocation. It is the arguments to that method invocation that are tested. The method
- * invocation can contain errors.
- *
- * The arguments were resolved correctly if the number of expressions in the list matches the
- * length of the array of indices and if, for each index in the array of indices, the parameter to
- * which the argument expression was resolved is the parameter in the invoked method's list of
- * parameters at that index. Arguments that should not be resolved to a parameter because of an
- * error can be denoted by including a negative index in the array of indices.
- *
- * @param source the source to be resolved
- * @param indices the array of indices used to associate arguments with parameters
- * @throws Exception if the source could not be resolved or if the structure of the source is not
- * valid
- */
- void _validateArgumentResolution(Source source, List<int> indices) {
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- ClassElement classElement = library.definingCompilationUnit.types[0];
- List<ParameterElement> parameters = classElement.methods[1].parameters;
- CompilationUnit unit = resolveCompilationUnit(source, library);
- expect(unit, isNotNull);
- ClassDeclaration classDeclaration =
- unit.declarations[0] as ClassDeclaration;
- MethodDeclaration methodDeclaration =
- classDeclaration.members[0] as MethodDeclaration;
- Block block = (methodDeclaration.body as BlockFunctionBody).block;
- ExpressionStatement statement = block.statements[0] as ExpressionStatement;
- MethodInvocation invocation = statement.expression as MethodInvocation;
- NodeList<Expression> arguments = invocation.argumentList.arguments;
- int argumentCount = arguments.length;
- expect(argumentCount, indices.length);
- for (int i = 0; i < argumentCount; i++) {
- Expression argument = arguments[i];
- ParameterElement element = argument.staticParameterElement;
- int index = indices[i];
- if (index < 0) {
- expect(element, isNull);
- } else {
- expect(element, same(parameters[index]));
- }
- }
- }
-}
-
-class SourceContainer_ChangeSetTest_test_toString implements SourceContainer {
- @override
- bool contains(Source source) => false;
-}
-
-/**
- * Like [StaticTypeAnalyzerTest], but as end-to-end tests.
- */
-@reflectiveTest
-class StaticTypeAnalyzer2Test extends _StaticTypeAnalyzer2TestShared {
- void test_FunctionExpressionInvocation_block() {
- String code = r'''
-main() {
- var foo = (() { return 1; })();
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'dynamic', isNull);
- }
-
- void test_FunctionExpressionInvocation_curried() {
- String code = r'''
-typedef int F();
-F f() => null;
-main() {
- var foo = f()();
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'int', isNull);
- }
-
- void test_FunctionExpressionInvocation_expression() {
- String code = r'''
-main() {
- var foo = (() => 1)();
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'int', isNull);
- }
-
- void test_MethodInvocation_nameType_localVariable() {
- String code = r"""
-typedef Foo();
-main() {
- Foo foo;
- foo();
-}
-""";
- _resolveTestUnit(code);
- // "foo" should be resolved to the "Foo" type
- _expectIdentifierType("foo();", new isInstanceOf<FunctionType>());
- }
-
- void test_MethodInvocation_nameType_parameter_FunctionTypeAlias() {
- String code = r"""
-typedef Foo();
-main(Foo foo) {
- foo();
-}
-""";
- _resolveTestUnit(code);
- // "foo" should be resolved to the "Foo" type
- _expectIdentifierType("foo();", new isInstanceOf<FunctionType>());
- }
-
- void test_MethodInvocation_nameType_parameter_propagatedType() {
- String code = r"""
-typedef Foo();
-main(p) {
- if (p is Foo) {
- p();
- }
-}
-""";
- _resolveTestUnit(code);
- _expectIdentifierType("p()", DynamicTypeImpl.instance,
- predicate((type) => type.name == 'Foo'));
- }
-
- void test_staticMethods_classTypeParameters() {
- String code = r'''
-class C<T> {
- static void m() => null;
-}
-main() {
- print(C.m);
-}
-''';
- _resolveTestUnit(code);
- _expectFunctionType('m);', '() → void');
- }
-
- void test_staticMethods_classTypeParameters_genericMethod() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.enableGenericMethods = true;
- resetWithOptions(options);
- String code = r'''
-class C<T> {
- static void m<S>(S s) {
- void f<U>(S s, U u) {}
- print(f);
- }
-}
-main() {
- print(C.m);
-}
-''';
- _resolveTestUnit(code);
- // C - m
- TypeParameterType typeS;
- {
- _expectFunctionType('m);', '<S>(S) → void',
- elementTypeParams: '[S]', typeFormals: '[S]');
-
- FunctionTypeImpl type = _findIdentifier('m);').staticType;
- typeS = type.typeFormals[0].type;
- type = type.instantiate([DynamicTypeImpl.instance]);
- expect(type.toString(), '(dynamic) → void');
- expect(type.typeParameters.toString(), '[S]');
- expect(type.typeArguments, [DynamicTypeImpl.instance]);
- expect(type.typeFormals, isEmpty);
- }
- // C - m - f
- {
- _expectFunctionType('f);', '<U>(S, U) → void',
- elementTypeParams: '[U]',
- typeParams: '[S]',
- typeArgs: '[S]',
- typeFormals: '[U]');
-
- FunctionTypeImpl type = _findIdentifier('f);').staticType;
- type = type.instantiate([DynamicTypeImpl.instance]);
- expect(type.toString(), '(S, dynamic) → void');
- expect(type.typeParameters.toString(), '[S, U]');
- expect(type.typeArguments, [typeS, DynamicTypeImpl.instance]);
- expect(type.typeFormals, isEmpty);
- }
- }
-}
-
-@reflectiveTest
-class StaticTypeAnalyzerTest extends EngineTestCase {
- /**
- * The error listener to which errors will be reported.
- */
- GatheringErrorListener _listener;
-
- /**
- * The resolver visitor used to create the analyzer.
- */
- ResolverVisitor _visitor;
-
- /**
- * The analyzer being used to analyze the test cases.
- */
- StaticTypeAnalyzer _analyzer;
-
- /**
- * The type provider used to access the types.
- */
- TestTypeProvider _typeProvider;
-
- /**
- * The type system used to analyze the test cases.
- */
- TypeSystem get _typeSystem => _visitor.typeSystem;
-
- void fail_visitFunctionExpressionInvocation() {
- fail("Not yet tested");
- _listener.assertNoErrors();
- }
-
- void fail_visitMethodInvocation() {
- fail("Not yet tested");
- _listener.assertNoErrors();
- }
-
- void fail_visitSimpleIdentifier() {
- fail("Not yet tested");
- _listener.assertNoErrors();
- }
-
- @override
- void setUp() {
- super.setUp();
- _listener = new GatheringErrorListener();
- _analyzer = _createAnalyzer();
- }
-
- void test_flatten_derived() {
- // class Derived<T> extends Future<T> { ... }
- ClassElementImpl derivedClass =
- ElementFactory.classElement2('Derived', ['T']);
- derivedClass.supertype = _typeProvider.futureType
- .instantiate([derivedClass.typeParameters[0].type]);
- InterfaceType intType = _typeProvider.intType;
- DartType dynamicType = _typeProvider.dynamicType;
- InterfaceType derivedIntType = derivedClass.type.instantiate([intType]);
- // flatten(Derived) = dynamic
- InterfaceType derivedDynamicType =
- derivedClass.type.instantiate([dynamicType]);
- expect(_flatten(derivedDynamicType), dynamicType);
- // flatten(Derived<int>) = int
- expect(_flatten(derivedIntType), intType);
- // flatten(Derived<Derived>) = Derived
- expect(_flatten(derivedClass.type.instantiate([derivedDynamicType])),
- derivedDynamicType);
- // flatten(Derived<Derived<int>>) = Derived<int>
- expect(_flatten(derivedClass.type.instantiate([derivedIntType])),
- derivedIntType);
- }
-
- void test_flatten_inhibit_recursion() {
- // class A extends B
- // class B extends A
- ClassElementImpl classA = ElementFactory.classElement2('A', []);
- ClassElementImpl classB = ElementFactory.classElement2('B', []);
- classA.supertype = classB.type;
- classB.supertype = classA.type;
- // flatten(A) = A and flatten(B) = B, since neither class contains Future
- // in its class hierarchy. Even though there is a loop in the class
- // hierarchy, flatten() should terminate.
- expect(_flatten(classA.type), classA.type);
- expect(_flatten(classB.type), classB.type);
- }
-
- void test_flatten_related_derived_types() {
- InterfaceType intType = _typeProvider.intType;
- InterfaceType numType = _typeProvider.numType;
- // class Derived<T> extends Future<T>
- ClassElementImpl derivedClass =
- ElementFactory.classElement2('Derived', ['T']);
- derivedClass.supertype = _typeProvider.futureType
- .instantiate([derivedClass.typeParameters[0].type]);
- InterfaceType derivedType = derivedClass.type;
- // class A extends Derived<int> implements Derived<num> { ... }
- ClassElementImpl classA =
- ElementFactory.classElement('A', derivedType.instantiate([intType]));
- classA.interfaces = <InterfaceType>[
- derivedType.instantiate([numType])
- ];
- // class B extends Future<num> implements Future<int> { ... }
- ClassElementImpl classB =
- ElementFactory.classElement('B', derivedType.instantiate([numType]));
- classB.interfaces = <InterfaceType>[
- derivedType.instantiate([intType])
- ];
- // flatten(A) = flatten(B) = int, since int is more specific than num.
- // The code in flatten() that inhibits infinite recursion shouldn't be
- // fooled by the fact that Derived appears twice in the type hierarchy.
- expect(_flatten(classA.type), intType);
- expect(_flatten(classB.type), intType);
- }
-
- void test_flatten_related_types() {
- InterfaceType futureType = _typeProvider.futureType;
- InterfaceType intType = _typeProvider.intType;
- InterfaceType numType = _typeProvider.numType;
- // class A extends Future<int> implements Future<num> { ... }
- ClassElementImpl classA =
- ElementFactory.classElement('A', futureType.instantiate([intType]));
- classA.interfaces = <InterfaceType>[
- futureType.instantiate([numType])
- ];
- // class B extends Future<num> implements Future<int> { ... }
- ClassElementImpl classB =
- ElementFactory.classElement('B', futureType.instantiate([numType]));
- classB.interfaces = <InterfaceType>[
- futureType.instantiate([intType])
- ];
- // flatten(A) = flatten(B) = int, since int is more specific than num.
- expect(_flatten(classA.type), intType);
- expect(_flatten(classB.type), intType);
- }
-
- void test_flatten_simple() {
- InterfaceType intType = _typeProvider.intType;
- DartType dynamicType = _typeProvider.dynamicType;
- InterfaceType futureDynamicType = _typeProvider.futureDynamicType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate([intType]);
- InterfaceType futureFutureDynamicType =
- _typeProvider.futureType.instantiate([futureDynamicType]);
- InterfaceType futureFutureIntType =
- _typeProvider.futureType.instantiate([futureIntType]);
- // flatten(int) = int
- expect(_flatten(intType), intType);
- // flatten(dynamic) = dynamic
- expect(_flatten(dynamicType), dynamicType);
- // flatten(Future) = dynamic
- expect(_flatten(futureDynamicType), dynamicType);
- // flatten(Future<int>) = int
- expect(_flatten(futureIntType), intType);
- // flatten(Future<Future>) = dynamic
- expect(_flatten(futureFutureDynamicType), dynamicType);
- // flatten(Future<Future<int>>) = int
- expect(_flatten(futureFutureIntType), intType);
- }
-
- void test_flatten_unrelated_types() {
- InterfaceType futureType = _typeProvider.futureType;
- InterfaceType intType = _typeProvider.intType;
- InterfaceType stringType = _typeProvider.stringType;
- // class A extends Future<int> implements Future<String> { ... }
- ClassElementImpl classA =
- ElementFactory.classElement('A', futureType.instantiate([intType]));
- classA.interfaces = <InterfaceType>[
- futureType.instantiate([stringType])
- ];
- // class B extends Future<String> implements Future<int> { ... }
- ClassElementImpl classB =
- ElementFactory.classElement('B', futureType.instantiate([stringType]));
- classB.interfaces = <InterfaceType>[
- futureType.instantiate([intType])
- ];
- // flatten(A) = A and flatten(B) = B, since neither string nor int is more
- // specific than the other.
- expect(_flatten(classA.type), classA.type);
- expect(_flatten(classB.type), classB.type);
- }
-
- void test_visitAdjacentStrings() {
- // "a" "b"
- Expression node = AstFactory
- .adjacentStrings([_resolvedString("a"), _resolvedString("b")]);
- expect(_analyze(node), same(_typeProvider.stringType));
- _listener.assertNoErrors();
- }
-
- void test_visitAsExpression() {
- // class A { ... this as B ... }
- // class B extends A {}
- ClassElement superclass = ElementFactory.classElement2("A");
- InterfaceType superclassType = superclass.type;
- ClassElement subclass = ElementFactory.classElement("B", superclassType);
- Expression node = AstFactory.asExpression(
- AstFactory.thisExpression(), AstFactory.typeName(subclass));
- expect(_analyze3(node, superclassType), same(subclass.type));
- _listener.assertNoErrors();
- }
-
- void test_visitAssignmentExpression_compound() {
- // i += 1
- InterfaceType numType = _typeProvider.numType;
- SimpleIdentifier identifier = _resolvedVariable(_typeProvider.intType, "i");
- AssignmentExpression node = AstFactory.assignmentExpression(
- identifier, TokenType.PLUS_EQ, _resolvedInteger(1));
- MethodElement plusMethod = getMethod(numType, "+");
- node.staticElement = plusMethod;
- expect(_analyze(node), same(numType));
- _listener.assertNoErrors();
- }
-
- void test_visitAssignmentExpression_compoundIfNull_differentTypes() {
- // double d; d ??= 0
- Expression node = AstFactory.assignmentExpression(
- _resolvedVariable(_typeProvider.doubleType, 'd'),
- TokenType.QUESTION_QUESTION_EQ,
- _resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.numType));
- _listener.assertNoErrors();
- }
-
- void test_visitAssignmentExpression_compoundIfNull_sameTypes() {
- // int i; i ??= 0
- Expression node = AstFactory.assignmentExpression(
- _resolvedVariable(_typeProvider.intType, 'i'),
- TokenType.QUESTION_QUESTION_EQ,
- _resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitAssignmentExpression_simple() {
- // i = 0
- InterfaceType intType = _typeProvider.intType;
- Expression node = AstFactory.assignmentExpression(
- _resolvedVariable(intType, "i"), TokenType.EQ, _resolvedInteger(0));
- expect(_analyze(node), same(intType));
- _listener.assertNoErrors();
- }
-
- void test_visitAwaitExpression_flattened() {
- // await e, where e has type Future<Future<int>>
- InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate(<DartType>[intType]);
- InterfaceType futureFutureIntType =
- _typeProvider.futureType.instantiate(<DartType>[futureIntType]);
- Expression node =
- AstFactory.awaitExpression(_resolvedVariable(futureFutureIntType, 'e'));
- expect(_analyze(node), same(intType));
- _listener.assertNoErrors();
- }
-
- void test_visitAwaitExpression_simple() {
- // await e, where e has type Future<int>
- InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate(<DartType>[intType]);
- Expression node =
- AstFactory.awaitExpression(_resolvedVariable(futureIntType, 'e'));
- expect(_analyze(node), same(intType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_equals() {
- // 2 == 3
- Expression node = AstFactory.binaryExpression(
- _resolvedInteger(2), TokenType.EQ_EQ, _resolvedInteger(3));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_ifNull() {
- // 1 ?? 1.5
- Expression node = AstFactory.binaryExpression(
- _resolvedInteger(1), TokenType.QUESTION_QUESTION, _resolvedDouble(1.5));
- expect(_analyze(node), same(_typeProvider.numType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_logicalAnd() {
- // false && true
- Expression node = AstFactory.binaryExpression(
- AstFactory.booleanLiteral(false),
- TokenType.AMPERSAND_AMPERSAND,
- AstFactory.booleanLiteral(true));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_logicalOr() {
- // false || true
- Expression node = AstFactory.binaryExpression(
- AstFactory.booleanLiteral(false),
- TokenType.BAR_BAR,
- AstFactory.booleanLiteral(true));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_minusID_propagated() {
- // a - b
- BinaryExpression node = AstFactory.binaryExpression(
- _propagatedVariable(_typeProvider.intType, 'a'),
- TokenType.MINUS,
- _propagatedVariable(_typeProvider.doubleType, 'b'));
- node.propagatedElement = getMethod(_typeProvider.numType, "+");
- _analyze(node);
- expect(node.propagatedType, same(_typeProvider.doubleType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_notEquals() {
- // 2 != 3
- Expression node = AstFactory.binaryExpression(
- _resolvedInteger(2), TokenType.BANG_EQ, _resolvedInteger(3));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_plusID() {
- // 1 + 2.0
- BinaryExpression node = AstFactory.binaryExpression(
- _resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0));
- node.staticElement = getMethod(_typeProvider.numType, "+");
- expect(_analyze(node), same(_typeProvider.doubleType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_plusII() {
- // 1 + 2
- BinaryExpression node = AstFactory.binaryExpression(
- _resolvedInteger(1), TokenType.PLUS, _resolvedInteger(2));
- node.staticElement = getMethod(_typeProvider.numType, "+");
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_plusII_propagated() {
- // a + b
- BinaryExpression node = AstFactory.binaryExpression(
- _propagatedVariable(_typeProvider.intType, 'a'),
- TokenType.PLUS,
- _propagatedVariable(_typeProvider.intType, 'b'));
- node.propagatedElement = getMethod(_typeProvider.numType, "+");
- _analyze(node);
- expect(node.propagatedType, same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_slash() {
- // 2 / 2
- BinaryExpression node = AstFactory.binaryExpression(
- _resolvedInteger(2), TokenType.SLASH, _resolvedInteger(2));
- node.staticElement = getMethod(_typeProvider.numType, "/");
- expect(_analyze(node), same(_typeProvider.doubleType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_star_notSpecial() {
- // class A {
- // A operator *(double value);
- // }
- // (a as A) * 2.0
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
- MethodElement operator =
- ElementFactory.methodElement("*", typeA, [_typeProvider.doubleType]);
- classA.methods = <MethodElement>[operator];
- BinaryExpression node = AstFactory.binaryExpression(
- AstFactory.asExpression(
- AstFactory.identifier3("a"), AstFactory.typeName(classA)),
- TokenType.PLUS,
- _resolvedDouble(2.0));
- node.staticElement = operator;
- expect(_analyze(node), same(typeA));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_starID() {
- // 1 * 2.0
- BinaryExpression node = AstFactory.binaryExpression(
- _resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0));
- node.staticElement = getMethod(_typeProvider.numType, "*");
- expect(_analyze(node), same(_typeProvider.doubleType));
- _listener.assertNoErrors();
- }
-
- void test_visitBooleanLiteral_false() {
- // false
- Expression node = AstFactory.booleanLiteral(false);
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitBooleanLiteral_true() {
- // true
- Expression node = AstFactory.booleanLiteral(true);
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitCascadeExpression() {
- // a..length
- Expression node = AstFactory.cascadeExpression(
- _resolvedString("a"), [AstFactory.propertyAccess2(null, "length")]);
- expect(_analyze(node), same(_typeProvider.stringType));
- _listener.assertNoErrors();
- }
-
- void test_visitConditionalExpression_differentTypes() {
- // true ? 1.0 : 0
- Expression node = AstFactory.conditionalExpression(
- AstFactory.booleanLiteral(true),
- _resolvedDouble(1.0),
- _resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.numType));
- _listener.assertNoErrors();
- }
-
- void test_visitConditionalExpression_sameTypes() {
- // true ? 1 : 0
- Expression node = AstFactory.conditionalExpression(
- AstFactory.booleanLiteral(true),
- _resolvedInteger(1),
- _resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitDoubleLiteral() {
- // 4.33
- Expression node = AstFactory.doubleLiteral(4.33);
- expect(_analyze(node), same(_typeProvider.doubleType));
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_async_block() {
- // () async {}
- BlockFunctionBody body = AstFactory.blockFunctionBody2();
- body.keyword = TokenFactory.tokenFromString('async');
- FunctionExpression node =
- _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
- DartType resultType = _analyze(node);
- _assertFunctionType(
- _typeProvider.futureDynamicType, null, null, null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_async_expression() {
- // () async => e, where e has type int
- InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate(<DartType>[intType]);
- Expression expression = _resolvedVariable(intType, 'e');
- ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
- body.keyword = TokenFactory.tokenFromString('async');
- FunctionExpression node =
- _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
- DartType resultType = _analyze(node);
- _assertFunctionType(futureIntType, null, null, null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_async_expression_flatten() {
- // () async => e, where e has type Future<int>
- InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate(<DartType>[intType]);
- Expression expression = _resolvedVariable(futureIntType, 'e');
- ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
- body.keyword = TokenFactory.tokenFromString('async');
- FunctionExpression node =
- _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
- DartType resultType = _analyze(node);
- _assertFunctionType(futureIntType, null, null, null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_async_expression_flatten_twice() {
- // () async => e, where e has type Future<Future<int>>
- InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate(<DartType>[intType]);
- InterfaceType futureFutureIntType =
- _typeProvider.futureType.instantiate(<DartType>[futureIntType]);
- Expression expression = _resolvedVariable(futureFutureIntType, 'e');
- ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
- body.keyword = TokenFactory.tokenFromString('async');
- FunctionExpression node =
- _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
- DartType resultType = _analyze(node);
- _assertFunctionType(futureIntType, null, null, null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_generator_async() {
- // () async* {}
- BlockFunctionBody body = AstFactory.blockFunctionBody2();
- body.keyword = TokenFactory.tokenFromString('async');
- body.star = TokenFactory.tokenFromType(TokenType.STAR);
- FunctionExpression node =
- _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
- DartType resultType = _analyze(node);
- _assertFunctionType(
- _typeProvider.streamDynamicType, null, null, null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_generator_sync() {
- // () sync* {}
- BlockFunctionBody body = AstFactory.blockFunctionBody2();
- body.keyword = TokenFactory.tokenFromString('sync');
- body.star = TokenFactory.tokenFromType(TokenType.STAR);
- FunctionExpression node =
- _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
- DartType resultType = _analyze(node);
- _assertFunctionType(
- _typeProvider.iterableDynamicType, null, null, null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_named_block() {
- // ({p1 : 0, p2 : 0}) {}
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p1 = AstFactory.namedFormalParameter(
- AstFactory.simpleFormalParameter3("p1"), _resolvedInteger(0));
- _setType(p1, dynamicType);
- FormalParameter p2 = AstFactory.namedFormalParameter(
- AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
- _setType(p2, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p1, p2]),
- AstFactory.blockFunctionBody2());
- _analyze5(p1);
- _analyze5(p2);
- DartType resultType = _analyze(node);
- Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
- expectedNamedTypes["p1"] = dynamicType;
- expectedNamedTypes["p2"] = dynamicType;
- _assertFunctionType(
- dynamicType, null, null, expectedNamedTypes, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_named_expression() {
- // ({p : 0}) -> 0;
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p = AstFactory.namedFormalParameter(
- AstFactory.simpleFormalParameter3("p"), _resolvedInteger(0));
- _setType(p, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p]),
- AstFactory.expressionFunctionBody(_resolvedInteger(0)));
- _analyze5(p);
- DartType resultType = _analyze(node);
- Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
- expectedNamedTypes["p"] = dynamicType;
- _assertFunctionType(
- _typeProvider.intType, null, null, expectedNamedTypes, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_normal_block() {
- // (p1, p2) {}
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
- _setType(p1, dynamicType);
- FormalParameter p2 = AstFactory.simpleFormalParameter3("p2");
- _setType(p2, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p1, p2]),
- AstFactory.blockFunctionBody2());
- _analyze5(p1);
- _analyze5(p2);
- DartType resultType = _analyze(node);
- _assertFunctionType(dynamicType, <DartType>[dynamicType, dynamicType], null,
- null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_normal_expression() {
- // (p1, p2) -> 0
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p = AstFactory.simpleFormalParameter3("p");
- _setType(p, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p]),
- AstFactory.expressionFunctionBody(_resolvedInteger(0)));
- _analyze5(p);
- DartType resultType = _analyze(node);
- _assertFunctionType(
- _typeProvider.intType, <DartType>[dynamicType], null, null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_normalAndNamed_block() {
- // (p1, {p2 : 0}) {}
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
- _setType(p1, dynamicType);
- FormalParameter p2 = AstFactory.namedFormalParameter(
- AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
- _setType(p2, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p1, p2]),
- AstFactory.blockFunctionBody2());
- _analyze5(p2);
- DartType resultType = _analyze(node);
- Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
- expectedNamedTypes["p2"] = dynamicType;
- _assertFunctionType(dynamicType, <DartType>[dynamicType], null,
- expectedNamedTypes, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_normalAndNamed_expression() {
- // (p1, {p2 : 0}) -> 0
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
- _setType(p1, dynamicType);
- FormalParameter p2 = AstFactory.namedFormalParameter(
- AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
- _setType(p2, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p1, p2]),
- AstFactory.expressionFunctionBody(_resolvedInteger(0)));
- _analyze5(p2);
- DartType resultType = _analyze(node);
- Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
- expectedNamedTypes["p2"] = dynamicType;
- _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType], null,
- expectedNamedTypes, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_normalAndPositional_block() {
- // (p1, [p2 = 0]) {}
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
- _setType(p1, dynamicType);
- FormalParameter p2 = AstFactory.positionalFormalParameter(
- AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
- _setType(p2, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p1, p2]),
- AstFactory.blockFunctionBody2());
- _analyze5(p1);
- _analyze5(p2);
- DartType resultType = _analyze(node);
- _assertFunctionType(dynamicType, <DartType>[dynamicType],
- <DartType>[dynamicType], null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_normalAndPositional_expression() {
- // (p1, [p2 = 0]) -> 0
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
- _setType(p1, dynamicType);
- FormalParameter p2 = AstFactory.positionalFormalParameter(
- AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
- _setType(p2, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p1, p2]),
- AstFactory.expressionFunctionBody(_resolvedInteger(0)));
- _analyze5(p1);
- _analyze5(p2);
- DartType resultType = _analyze(node);
- _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType],
- <DartType>[dynamicType], null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_positional_block() {
- // ([p1 = 0, p2 = 0]) {}
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p1 = AstFactory.positionalFormalParameter(
- AstFactory.simpleFormalParameter3("p1"), _resolvedInteger(0));
- _setType(p1, dynamicType);
- FormalParameter p2 = AstFactory.positionalFormalParameter(
- AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
- _setType(p2, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p1, p2]),
- AstFactory.blockFunctionBody2());
- _analyze5(p1);
- _analyze5(p2);
- DartType resultType = _analyze(node);
- _assertFunctionType(dynamicType, null, <DartType>[dynamicType, dynamicType],
- null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_positional_expression() {
- // ([p1 = 0, p2 = 0]) -> 0
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p = AstFactory.positionalFormalParameter(
- AstFactory.simpleFormalParameter3("p"), _resolvedInteger(0));
- _setType(p, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p]),
- AstFactory.expressionFunctionBody(_resolvedInteger(0)));
- _analyze5(p);
- DartType resultType = _analyze(node);
- _assertFunctionType(
- _typeProvider.intType, null, <DartType>[dynamicType], null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitIndexExpression_getter() {
- // List a;
- // a[2]
- InterfaceType listType = _typeProvider.listType;
- SimpleIdentifier identifier = _resolvedVariable(listType, "a");
- IndexExpression node =
- AstFactory.indexExpression(identifier, _resolvedInteger(2));
- MethodElement indexMethod = listType.element.methods[0];
- node.staticElement = indexMethod;
- expect(_analyze(node), same(listType.typeArguments[0]));
- _listener.assertNoErrors();
- }
-
- void test_visitIndexExpression_setter() {
- // List a;
- // a[2] = 0
- InterfaceType listType = _typeProvider.listType;
- SimpleIdentifier identifier = _resolvedVariable(listType, "a");
- IndexExpression node =
- AstFactory.indexExpression(identifier, _resolvedInteger(2));
- MethodElement indexMethod = listType.element.methods[1];
- node.staticElement = indexMethod;
- AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0));
- expect(_analyze(node), same(listType.typeArguments[0]));
- _listener.assertNoErrors();
- }
-
- void test_visitIndexExpression_typeParameters() {
- // List<int> list = ...
- // list[0]
- InterfaceType intType = _typeProvider.intType;
- InterfaceType listType = _typeProvider.listType;
- // (int) -> E
- MethodElement methodElement = getMethod(listType, "[]");
- // "list" has type List<int>
- SimpleIdentifier identifier = AstFactory.identifier3("list");
- InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
- identifier.staticType = listOfIntType;
- // list[0] has MethodElement element (int) -> E
- IndexExpression indexExpression =
- AstFactory.indexExpression(identifier, AstFactory.integer(0));
- MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType);
- indexExpression.staticElement = indexMethod;
- // analyze and assert result of the index expression
- expect(_analyze(indexExpression), same(intType));
- _listener.assertNoErrors();
- }
-
- void test_visitIndexExpression_typeParameters_inSetterContext() {
- // List<int> list = ...
- // list[0] = 0;
- InterfaceType intType = _typeProvider.intType;
- InterfaceType listType = _typeProvider.listType;
- // (int, E) -> void
- MethodElement methodElement = getMethod(listType, "[]=");
- // "list" has type List<int>
- SimpleIdentifier identifier = AstFactory.identifier3("list");
- InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
- identifier.staticType = listOfIntType;
- // list[0] has MethodElement element (int) -> E
- IndexExpression indexExpression =
- AstFactory.indexExpression(identifier, AstFactory.integer(0));
- MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType);
- indexExpression.staticElement = indexMethod;
- // list[0] should be in a setter context
- AstFactory.assignmentExpression(
- indexExpression, TokenType.EQ, AstFactory.integer(0));
- // analyze and assert result of the index expression
- expect(_analyze(indexExpression), same(intType));
- _listener.assertNoErrors();
- }
-
- void test_visitInstanceCreationExpression_named() {
- // new C.m()
- ClassElementImpl classElement = ElementFactory.classElement2("C");
- String constructorName = "m";
- ConstructorElementImpl constructor =
- ElementFactory.constructorElement2(classElement, constructorName);
- constructor.returnType = classElement.type;
- FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
- constructor.type = constructorType;
- classElement.constructors = <ConstructorElement>[constructor];
- InstanceCreationExpression node = AstFactory.instanceCreationExpression2(
- null,
- AstFactory.typeName(classElement),
- [AstFactory.identifier3(constructorName)]);
- node.staticElement = constructor;
- expect(_analyze(node), same(classElement.type));
- _listener.assertNoErrors();
- }
-
- void test_visitInstanceCreationExpression_typeParameters() {
- // new C<I>()
- ClassElementImpl elementC = ElementFactory.classElement2("C", ["E"]);
- ClassElementImpl elementI = ElementFactory.classElement2("I");
- ConstructorElementImpl constructor =
- ElementFactory.constructorElement2(elementC, null);
- elementC.constructors = <ConstructorElement>[constructor];
- constructor.returnType = elementC.type;
- FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
- constructor.type = constructorType;
- TypeName typeName =
- AstFactory.typeName(elementC, [AstFactory.typeName(elementI)]);
- typeName.type = elementC.type.instantiate(<DartType>[elementI.type]);
- InstanceCreationExpression node =
- AstFactory.instanceCreationExpression2(null, typeName);
- node.staticElement = constructor;
- InterfaceType interfaceType = _analyze(node) as InterfaceType;
- List<DartType> typeArgs = interfaceType.typeArguments;
- expect(typeArgs.length, 1);
- expect(typeArgs[0], elementI.type);
- _listener.assertNoErrors();
- }
-
- void test_visitInstanceCreationExpression_unnamed() {
- // new C()
- ClassElementImpl classElement = ElementFactory.classElement2("C");
- ConstructorElementImpl constructor =
- ElementFactory.constructorElement2(classElement, null);
- constructor.returnType = classElement.type;
- FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
- constructor.type = constructorType;
- classElement.constructors = <ConstructorElement>[constructor];
- InstanceCreationExpression node = AstFactory.instanceCreationExpression2(
- null, AstFactory.typeName(classElement));
- node.staticElement = constructor;
- expect(_analyze(node), same(classElement.type));
- _listener.assertNoErrors();
- }
-
- void test_visitIntegerLiteral() {
- // 42
- Expression node = _resolvedInteger(42);
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitIsExpression_negated() {
- // a is! String
- Expression node = AstFactory.isExpression(
- _resolvedString("a"), true, AstFactory.typeName4("String"));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitIsExpression_notNegated() {
- // a is String
- Expression node = AstFactory.isExpression(
- _resolvedString("a"), false, AstFactory.typeName4("String"));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitListLiteral_empty() {
- // []
- Expression node = AstFactory.listLiteral();
- DartType resultType = _analyze(node);
- _assertType2(
- _typeProvider.listType
- .instantiate(<DartType>[_typeProvider.dynamicType]),
- resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitListLiteral_nonEmpty() {
- // [0]
- Expression node = AstFactory.listLiteral([_resolvedInteger(0)]);
- DartType resultType = _analyze(node);
- _assertType2(
- _typeProvider.listType
- .instantiate(<DartType>[_typeProvider.dynamicType]),
- resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitMapLiteral_empty() {
- // {}
- Expression node = AstFactory.mapLiteral2();
- DartType resultType = _analyze(node);
- _assertType2(
- _typeProvider.mapType.instantiate(
- <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]),
- resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitMapLiteral_nonEmpty() {
- // {"k" : 0}
- Expression node = AstFactory
- .mapLiteral2([AstFactory.mapLiteralEntry("k", _resolvedInteger(0))]);
- DartType resultType = _analyze(node);
- _assertType2(
- _typeProvider.mapType.instantiate(
- <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]),
- resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitMethodInvocation_then() {
- // then()
- Expression node = AstFactory.methodInvocation(null, "then");
- _analyze(node);
- _listener.assertNoErrors();
- }
-
- void test_visitNamedExpression() {
- // n: a
- Expression node = AstFactory.namedExpression2("n", _resolvedString("a"));
- expect(_analyze(node), same(_typeProvider.stringType));
- _listener.assertNoErrors();
- }
-
- void test_visitNullLiteral() {
- // null
- Expression node = AstFactory.nullLiteral();
- expect(_analyze(node), same(_typeProvider.bottomType));
- _listener.assertNoErrors();
- }
-
- void test_visitParenthesizedExpression() {
- // (0)
- Expression node = AstFactory.parenthesizedExpression(_resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitPostfixExpression_minusMinus() {
- // 0--
- PostfixExpression node = AstFactory.postfixExpression(
- _resolvedInteger(0), TokenType.MINUS_MINUS);
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitPostfixExpression_plusPlus() {
- // 0++
- PostfixExpression node =
- AstFactory.postfixExpression(_resolvedInteger(0), TokenType.PLUS_PLUS);
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_getter() {
- DartType boolType = _typeProvider.boolType;
- PropertyAccessorElementImpl getter =
- ElementFactory.getterElement("b", false, boolType);
- PrefixedIdentifier node = AstFactory.identifier5("a", "b");
- node.identifier.staticElement = getter;
- expect(_analyze(node), same(boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_setter() {
- DartType boolType = _typeProvider.boolType;
- FieldElementImpl field =
- ElementFactory.fieldElement("b", false, false, false, boolType);
- PropertyAccessorElement setter = field.setter;
- PrefixedIdentifier node = AstFactory.identifier5("a", "b");
- node.identifier.staticElement = setter;
- expect(_analyze(node), same(boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_variable() {
- VariableElementImpl variable = ElementFactory.localVariableElement2("b");
- variable.type = _typeProvider.boolType;
- PrefixedIdentifier node = AstFactory.identifier5("a", "b");
- node.identifier.staticElement = variable;
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixExpression_bang() {
- // !0
- PrefixExpression node =
- AstFactory.prefixExpression(TokenType.BANG, _resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixExpression_minus() {
- // -0
- PrefixExpression node =
- AstFactory.prefixExpression(TokenType.MINUS, _resolvedInteger(0));
- MethodElement minusMethod = getMethod(_typeProvider.numType, "-");
- node.staticElement = minusMethod;
- expect(_analyze(node), same(_typeProvider.numType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixExpression_minusMinus() {
- // --0
- PrefixExpression node =
- AstFactory.prefixExpression(TokenType.MINUS_MINUS, _resolvedInteger(0));
- MethodElement minusMethod = getMethod(_typeProvider.numType, "-");
- node.staticElement = minusMethod;
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixExpression_not() {
- // !true
- Expression node = AstFactory.prefixExpression(
- TokenType.BANG, AstFactory.booleanLiteral(true));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixExpression_plusPlus() {
- // ++0
- PrefixExpression node =
- AstFactory.prefixExpression(TokenType.PLUS_PLUS, _resolvedInteger(0));
- MethodElement plusMethod = getMethod(_typeProvider.numType, "+");
- node.staticElement = plusMethod;
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixExpression_tilde() {
- // ~0
- PrefixExpression node =
- AstFactory.prefixExpression(TokenType.TILDE, _resolvedInteger(0));
- MethodElement tildeMethod = getMethod(_typeProvider.intType, "~");
- node.staticElement = tildeMethod;
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitPropertyAccess_propagated_getter() {
- DartType boolType = _typeProvider.boolType;
- PropertyAccessorElementImpl getter =
- ElementFactory.getterElement("b", false, boolType);
- PropertyAccess node =
- AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
- node.propertyName.propagatedElement = getter;
- expect(_analyze2(node, false), same(boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPropertyAccess_propagated_setter() {
- DartType boolType = _typeProvider.boolType;
- FieldElementImpl field =
- ElementFactory.fieldElement("b", false, false, false, boolType);
- PropertyAccessorElement setter = field.setter;
- PropertyAccess node =
- AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
- node.propertyName.propagatedElement = setter;
- expect(_analyze2(node, false), same(boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPropertyAccess_static_getter() {
- DartType boolType = _typeProvider.boolType;
- PropertyAccessorElementImpl getter =
- ElementFactory.getterElement("b", false, boolType);
- PropertyAccess node =
- AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
- node.propertyName.staticElement = getter;
- expect(_analyze(node), same(boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPropertyAccess_static_setter() {
- DartType boolType = _typeProvider.boolType;
- FieldElementImpl field =
- ElementFactory.fieldElement("b", false, false, false, boolType);
- PropertyAccessorElement setter = field.setter;
- PropertyAccess node =
- AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
- node.propertyName.staticElement = setter;
- expect(_analyze(node), same(boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitSimpleIdentifier_dynamic() {
- // "dynamic"
- SimpleIdentifier identifier = AstFactory.identifier3('dynamic');
- DynamicElementImpl element = DynamicElementImpl.instance;
- identifier.staticElement = element;
- identifier.staticType = _typeProvider.typeType;
- expect(_analyze(identifier), same(_typeProvider.typeType));
- _listener.assertNoErrors();
- }
-
- void test_visitSimpleStringLiteral() {
- // "a"
- Expression node = _resolvedString("a");
- expect(_analyze(node), same(_typeProvider.stringType));
- _listener.assertNoErrors();
- }
-
- void test_visitStringInterpolation() {
- // "a${'b'}c"
- Expression node = AstFactory.string([
- AstFactory.interpolationString("a", "a"),
- AstFactory.interpolationExpression(_resolvedString("b")),
- AstFactory.interpolationString("c", "c")
- ]);
- expect(_analyze(node), same(_typeProvider.stringType));
- _listener.assertNoErrors();
- }
-
- void test_visitSuperExpression() {
- // super
- InterfaceType superType = ElementFactory.classElement2("A").type;
- InterfaceType thisType = ElementFactory.classElement("B", superType).type;
- Expression node = AstFactory.superExpression();
- expect(_analyze3(node, thisType), same(thisType));
- _listener.assertNoErrors();
- }
-
- void test_visitSymbolLiteral() {
- expect(_analyze(AstFactory.symbolLiteral(["a"])),
- same(_typeProvider.symbolType));
- }
-
- void test_visitThisExpression() {
- // this
- InterfaceType thisType = ElementFactory
- .classElement("B", ElementFactory.classElement2("A").type)
- .type;
- Expression node = AstFactory.thisExpression();
- expect(_analyze3(node, thisType), same(thisType));
- _listener.assertNoErrors();
- }
-
- void test_visitThrowExpression_withoutValue() {
- // throw
- Expression node = AstFactory.throwExpression();
- expect(_analyze(node), same(_typeProvider.bottomType));
- _listener.assertNoErrors();
- }
-
- void test_visitThrowExpression_withValue() {
- // throw 0
- Expression node = AstFactory.throwExpression2(_resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.bottomType));
- _listener.assertNoErrors();
- }
-
- /**
- * Return the type associated with the given expression after the static type analyzer has
- * computed a type for it.
- *
- * @param node the expression with which the type is associated
- * @return the type associated with the expression
- */
- DartType _analyze(Expression node) => _analyze4(node, null, true);
-
- /**
- * Return the type associated with the given expression after the static or propagated type
- * analyzer has computed a type for it.
- *
- * @param node the expression with which the type is associated
- * @param useStaticType `true` if the static type is being requested, and `false` if
- * the propagated type is being requested
- * @return the type associated with the expression
- */
- DartType _analyze2(Expression node, bool useStaticType) =>
- _analyze4(node, null, useStaticType);
-
- /**
- * Return the type associated with the given expression after the static type analyzer has
- * computed a type for it.
- *
- * @param node the expression with which the type is associated
- * @param thisType the type of 'this'
- * @return the type associated with the expression
- */
- DartType _analyze3(Expression node, InterfaceType thisType) =>
- _analyze4(node, thisType, true);
-
- /**
- * Return the type associated with the given expression after the static type analyzer has
- * computed a type for it.
- *
- * @param node the expression with which the type is associated
- * @param thisType the type of 'this'
- * @param useStaticType `true` if the static type is being requested, and `false` if
- * the propagated type is being requested
- * @return the type associated with the expression
- */
- DartType _analyze4(
- Expression node, InterfaceType thisType, bool useStaticType) {
- try {
- _analyzer.thisType = thisType;
- } catch (exception) {
- throw new IllegalArgumentException(
- "Could not set type of 'this'", exception);
- }
- node.accept(_analyzer);
- if (useStaticType) {
- return node.staticType;
- } else {
- return node.propagatedType;
- }
- }
-
- /**
- * Return the type associated with the given parameter after the static type analyzer has computed
- * a type for it.
- *
- * @param node the parameter with which the type is associated
- * @return the type associated with the parameter
- */
- DartType _analyze5(FormalParameter node) {
- node.accept(_analyzer);
- return (node.identifier.staticElement as ParameterElement).type;
- }
-
- /**
- * Assert that the actual type is a function type with the expected characteristics.
- *
- * @param expectedReturnType the expected return type of the function
- * @param expectedNormalTypes the expected types of the normal parameters
- * @param expectedOptionalTypes the expected types of the optional parameters
- * @param expectedNamedTypes the expected types of the named parameters
- * @param actualType the type being tested
- */
- void _assertFunctionType(
- DartType expectedReturnType,
- List<DartType> expectedNormalTypes,
- List<DartType> expectedOptionalTypes,
- Map<String, DartType> expectedNamedTypes,
- DartType actualType) {
- EngineTestCase.assertInstanceOf(
- (obj) => obj is FunctionType, FunctionType, actualType);
- FunctionType functionType = actualType as FunctionType;
- List<DartType> normalTypes = functionType.normalParameterTypes;
- if (expectedNormalTypes == null) {
- expect(normalTypes, hasLength(0));
- } else {
- int expectedCount = expectedNormalTypes.length;
- expect(normalTypes, hasLength(expectedCount));
- for (int i = 0; i < expectedCount; i++) {
- expect(normalTypes[i], same(expectedNormalTypes[i]));
- }
- }
- List<DartType> optionalTypes = functionType.optionalParameterTypes;
- if (expectedOptionalTypes == null) {
- expect(optionalTypes, hasLength(0));
- } else {
- int expectedCount = expectedOptionalTypes.length;
- expect(optionalTypes, hasLength(expectedCount));
- for (int i = 0; i < expectedCount; i++) {
- expect(optionalTypes[i], same(expectedOptionalTypes[i]));
- }
- }
- Map<String, DartType> namedTypes = functionType.namedParameterTypes;
- if (expectedNamedTypes == null) {
- expect(namedTypes, hasLength(0));
- } else {
- expect(namedTypes, hasLength(expectedNamedTypes.length));
- expectedNamedTypes.forEach((String name, DartType type) {
- expect(namedTypes[name], same(type));
- });
- }
- expect(functionType.returnType, equals(expectedReturnType));
- }
-
- void _assertType(
- InterfaceTypeImpl expectedType, InterfaceTypeImpl actualType) {
- expect(actualType.displayName, expectedType.displayName);
- expect(actualType.element, expectedType.element);
- List<DartType> expectedArguments = expectedType.typeArguments;
- int length = expectedArguments.length;
- List<DartType> actualArguments = actualType.typeArguments;
- expect(actualArguments, hasLength(length));
- for (int i = 0; i < length; i++) {
- _assertType2(expectedArguments[i], actualArguments[i]);
- }
- }
-
- void _assertType2(DartType expectedType, DartType actualType) {
- if (expectedType is InterfaceTypeImpl) {
- EngineTestCase.assertInstanceOf(
- (obj) => obj is InterfaceTypeImpl, InterfaceTypeImpl, actualType);
- _assertType(expectedType, actualType as InterfaceTypeImpl);
- }
- // TODO(brianwilkerson) Compare other kinds of types then make this a shared
- // utility method.
- }
-
- /**
- * Create the analyzer used by the tests.
- *
- * @return the analyzer to be used by the tests
- */
- StaticTypeAnalyzer _createAnalyzer() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- FileBasedSource source =
- new FileBasedSource(FileUtilities2.createFile("/lib.dart"));
- CompilationUnitElementImpl definingCompilationUnit =
- new CompilationUnitElementImpl("lib.dart");
- definingCompilationUnit.librarySource =
- definingCompilationUnit.source = source;
- LibraryElementImpl definingLibrary =
- new LibraryElementImpl.forNode(context, null);
- definingLibrary.definingCompilationUnit = definingCompilationUnit;
- _typeProvider = new TestTypeProvider(context);
- _visitor = new ResolverVisitor(
- definingLibrary, source, _typeProvider, _listener,
- nameScope: new LibraryScope(definingLibrary, _listener));
- _visitor.overrideManager.enterScope();
- try {
- return _visitor.typeAnalyzer;
- } catch (exception) {
- throw new IllegalArgumentException(
- "Could not create analyzer", exception);
- }
- }
-
- DartType _flatten(DartType type) => type.flattenFutures(_typeSystem);
-
- /**
- * Return a simple identifier that has been resolved to a variable element with the given type.
- *
- * @param type the type of the variable being represented
- * @param variableName the name of the variable
- * @return a simple identifier that has been resolved to a variable element with the given type
- */
- SimpleIdentifier _propagatedVariable(
- InterfaceType type, String variableName) {
- SimpleIdentifier identifier = AstFactory.identifier3(variableName);
- VariableElementImpl element =
- ElementFactory.localVariableElement(identifier);
- element.type = type;
- identifier.staticType = _typeProvider.dynamicType;
- identifier.propagatedElement = element;
- identifier.propagatedType = type;
- return identifier;
- }
-
- /**
- * Return an integer literal that has been resolved to the correct type.
- *
- * @param value the value of the literal
- * @return an integer literal that has been resolved to the correct type
- */
- DoubleLiteral _resolvedDouble(double value) {
- DoubleLiteral literal = AstFactory.doubleLiteral(value);
- literal.staticType = _typeProvider.doubleType;
- return literal;
- }
-
- /**
- * Create a function expression that has an element associated with it, where the element has an
- * incomplete type associated with it (just like the one
- * [ElementBuilder.visitFunctionExpression] would have built if we had
- * run it).
- *
- * @param parameters the parameters to the function
- * @param body the body of the function
- * @return a resolved function expression
- */
- FunctionExpression _resolvedFunctionExpression(
- FormalParameterList parameters, FunctionBody body) {
- List<ParameterElement> parameterElements = new List<ParameterElement>();
- for (FormalParameter parameter in parameters.parameters) {
- ParameterElementImpl element =
- new ParameterElementImpl.forNode(parameter.identifier);
- element.parameterKind = parameter.kind;
- element.type = _typeProvider.dynamicType;
- parameter.identifier.staticElement = element;
- parameterElements.add(element);
- }
- FunctionExpression node = AstFactory.functionExpression2(parameters, body);
- FunctionElementImpl element = new FunctionElementImpl.forNode(null);
- element.parameters = parameterElements;
- element.type = new FunctionTypeImpl(element);
- node.element = element;
- return node;
- }
-
- /**
- * Return an integer literal that has been resolved to the correct type.
- *
- * @param value the value of the literal
- * @return an integer literal that has been resolved to the correct type
- */
- IntegerLiteral _resolvedInteger(int value) {
- IntegerLiteral literal = AstFactory.integer(value);
- literal.staticType = _typeProvider.intType;
- return literal;
- }
-
- /**
- * Return a string literal that has been resolved to the correct type.
- *
- * @param value the value of the literal
- * @return a string literal that has been resolved to the correct type
- */
- SimpleStringLiteral _resolvedString(String value) {
- SimpleStringLiteral string = AstFactory.string2(value);
- string.staticType = _typeProvider.stringType;
- return string;
- }
-
- /**
- * Return a simple identifier that has been resolved to a variable element with the given type.
- *
- * @param type the type of the variable being represented
- * @param variableName the name of the variable
- * @return a simple identifier that has been resolved to a variable element with the given type
- */
- SimpleIdentifier _resolvedVariable(InterfaceType type, String variableName) {
- SimpleIdentifier identifier = AstFactory.identifier3(variableName);
- VariableElementImpl element =
- ElementFactory.localVariableElement(identifier);
- element.type = type;
- identifier.staticElement = element;
- identifier.staticType = type;
- return identifier;
- }
-
- /**
- * Set the type of the given parameter to the given type.
- *
- * @param parameter the parameter whose type is to be set
- * @param type the new type of the given parameter
- */
- void _setType(FormalParameter parameter, DartType type) {
- SimpleIdentifier identifier = parameter.identifier;
- Element element = identifier.staticElement;
- if (element is! ParameterElement) {
- element = new ParameterElementImpl.forNode(identifier);
- identifier.staticElement = element;
- }
- (element as ParameterElementImpl).type = type;
- }
-}
-
-/**
- * Instances of the class `StaticTypeVerifier` verify that all of the nodes in an AST
- * structure that should have a static type associated with them do have a static type.
- */
-class StaticTypeVerifier extends GeneralizingAstVisitor<Object> {
- /**
- * A list containing all of the AST Expression nodes that were not resolved.
- */
- List<Expression> _unresolvedExpressions = new List<Expression>();
-
- /**
- * A list containing all of the AST Expression nodes for which a propagated type was computed but
- * where that type was not more specific than the static type.
- */
- List<Expression> _invalidlyPropagatedExpressions = new List<Expression>();
-
- /**
- * A list containing all of the AST TypeName nodes that were not resolved.
- */
- List<TypeName> _unresolvedTypes = new List<TypeName>();
-
- /**
- * Counter for the number of Expression nodes visited that are resolved.
- */
- int _resolvedExpressionCount = 0;
-
- /**
- * Counter for the number of Expression nodes visited that have propagated type information.
- */
- int _propagatedExpressionCount = 0;
-
- /**
- * Counter for the number of TypeName nodes visited that are resolved.
- */
- int _resolvedTypeCount = 0;
-
- /**
- * Assert that all of the visited nodes have a static type associated with them.
- */
- void assertResolved() {
- if (!_unresolvedExpressions.isEmpty || !_unresolvedTypes.isEmpty) {
- StringBuffer buffer = new StringBuffer();
- int unresolvedTypeCount = _unresolvedTypes.length;
- if (unresolvedTypeCount > 0) {
- buffer.write("Failed to resolve ");
- buffer.write(unresolvedTypeCount);
- buffer.write(" of ");
- buffer.write(_resolvedTypeCount + unresolvedTypeCount);
- buffer.writeln(" type names:");
- for (TypeName identifier in _unresolvedTypes) {
- buffer.write(" ");
- buffer.write(identifier.toString());
- buffer.write(" (");
- buffer.write(_getFileName(identifier));
- buffer.write(" : ");
- buffer.write(identifier.offset);
- buffer.writeln(")");
- }
- }
- int unresolvedExpressionCount = _unresolvedExpressions.length;
- if (unresolvedExpressionCount > 0) {
- buffer.writeln("Failed to resolve ");
- buffer.write(unresolvedExpressionCount);
- buffer.write(" of ");
- buffer.write(_resolvedExpressionCount + unresolvedExpressionCount);
- buffer.writeln(" expressions:");
- for (Expression expression in _unresolvedExpressions) {
- buffer.write(" ");
- buffer.write(expression.toString());
- buffer.write(" (");
- buffer.write(_getFileName(expression));
- buffer.write(" : ");
- buffer.write(expression.offset);
- buffer.writeln(")");
- }
- }
- int invalidlyPropagatedExpressionCount =
- _invalidlyPropagatedExpressions.length;
- if (invalidlyPropagatedExpressionCount > 0) {
- buffer.writeln("Incorrectly propagated ");
- buffer.write(invalidlyPropagatedExpressionCount);
- buffer.write(" of ");
- buffer.write(_propagatedExpressionCount);
- buffer.writeln(" expressions:");
- for (Expression expression in _invalidlyPropagatedExpressions) {
- buffer.write(" ");
- buffer.write(expression.toString());
- buffer.write(" [");
- buffer.write(expression.staticType.displayName);
- buffer.write(", ");
- buffer.write(expression.propagatedType.displayName);
- buffer.writeln("]");
- buffer.write(" ");
- buffer.write(_getFileName(expression));
- buffer.write(" : ");
- buffer.write(expression.offset);
- buffer.writeln(")");
- }
- }
- fail(buffer.toString());
- }
- }
-
- @override
- Object visitBreakStatement(BreakStatement node) => null;
-
- @override
- Object visitCommentReference(CommentReference node) => null;
-
- @override
- Object visitContinueStatement(ContinueStatement node) => null;
-
- @override
- Object visitExportDirective(ExportDirective node) => null;
-
- @override
- Object visitExpression(Expression node) {
- node.visitChildren(this);
- DartType staticType = node.staticType;
- if (staticType == null) {
- _unresolvedExpressions.add(node);
- } else {
- _resolvedExpressionCount++;
- DartType propagatedType = node.propagatedType;
- if (propagatedType != null) {
- _propagatedExpressionCount++;
- if (!propagatedType.isMoreSpecificThan(staticType)) {
- _invalidlyPropagatedExpressions.add(node);
- }
- }
- }
- return null;
- }
-
- @override
- Object visitImportDirective(ImportDirective node) => null;
-
- @override
- Object visitLabel(Label node) => null;
-
- @override
- Object visitLibraryIdentifier(LibraryIdentifier node) => null;
-
- @override
- Object visitPrefixedIdentifier(PrefixedIdentifier node) {
- // In cases where we have a prefixed identifier where the prefix is dynamic,
- // we don't want to assert that the node will have a type.
- if (node.staticType == null && node.prefix.staticType.isDynamic) {
- return null;
- }
- return super.visitPrefixedIdentifier(node);
- }
-
- @override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
- // In cases where identifiers are being used for something other than an
- // expressions, then they can be ignored.
- AstNode parent = node.parent;
- if (parent is MethodInvocation && identical(node, parent.methodName)) {
- return null;
- } else if (parent is RedirectingConstructorInvocation &&
- identical(node, parent.constructorName)) {
- return null;
- } else if (parent is SuperConstructorInvocation &&
- identical(node, parent.constructorName)) {
- return null;
- } else if (parent is ConstructorName && identical(node, parent.name)) {
- return null;
- } else if (parent is ConstructorFieldInitializer &&
- identical(node, parent.fieldName)) {
- return null;
- } else if (node.staticElement is PrefixElement) {
- // Prefixes don't have a type.
- return null;
- }
- return super.visitSimpleIdentifier(node);
- }
-
- @override
- Object visitTypeName(TypeName node) {
- // Note: do not visit children from this node, the child SimpleIdentifier in
- // TypeName (i.e. "String") does not have a static type defined.
- if (node.type == null) {
- _unresolvedTypes.add(node);
- } else {
- _resolvedTypeCount++;
- }
- return null;
- }
-
- String _getFileName(AstNode node) {
- // TODO (jwren) there are two copies of this method, one here and one in
- // ResolutionVerifier, they should be resolved into a single method
- if (node != null) {
- AstNode root = node.root;
- if (root is CompilationUnit) {
- CompilationUnit rootCU = root;
- if (rootCU.element != null) {
- return rootCU.element.source.fullName;
- } else {
- return "<unknown file- CompilationUnit.getElement() returned null>";
- }
- } else {
- return "<unknown file- CompilationUnit.getRoot() is not a CompilationUnit>";
- }
- }
- return "<unknown file- ASTNode is null>";
- }
-}
-
-/**
- * The class `StrictModeTest` contains tests to ensure that the correct errors and warnings
- * are reported when the analysis engine is run in strict mode.
- */
-@reflectiveTest
-class StrictModeTest extends ResolverTestCase {
- void fail_for() {
- Source source = addSource(r'''
-int f(List<int> list) {
- num sum = 0;
- for (num i = 0; i < list.length; i++) {
- sum += list[i];
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- }
-
- @override
- void setUp() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.hint = false;
- resetWithOptions(options);
- }
-
- void test_assert_is() {
- Source source = addSource(r'''
-int f(num n) {
- assert (n is int);
- return n & 0x0F;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- }
-
- void test_conditional_and_is() {
- Source source = addSource(r'''
-int f(num n) {
- return (n is int && n > 0) ? n & 0x0F : 0;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_conditional_is() {
- Source source = addSource(r'''
-int f(num n) {
- return (n is int) ? n & 0x0F : 0;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_conditional_isNot() {
- Source source = addSource(r'''
-int f(num n) {
- return (n is! int) ? 0 : n & 0x0F;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- }
-
- void test_conditional_or_is() {
- Source source = addSource(r'''
-int f(num n) {
- return (n is! int || n < 0) ? 0 : n & 0x0F;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- }
-
- void test_forEach() {
- Source source = addSource(r'''
-int f(List<int> list) {
- num sum = 0;
- for (num n in list) {
- sum += n & 0x0F;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- }
-
- void test_if_and_is() {
- Source source = addSource(r'''
-int f(num n) {
- if (n is int && n > 0) {
- return n & 0x0F;
- }
- return 0;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_if_is() {
- Source source = addSource(r'''
-int f(num n) {
- if (n is int) {
- return n & 0x0F;
- }
- return 0;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_if_isNot() {
- Source source = addSource(r'''
-int f(num n) {
- if (n is! int) {
- return 0;
- } else {
- return n & 0x0F;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- }
-
- void test_if_isNot_abrupt() {
- Source source = addSource(r'''
-int f(num n) {
- if (n is! int) {
- return 0;
- }
- return n & 0x0F;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- }
-
- void test_if_or_is() {
- Source source = addSource(r'''
-int f(num n) {
- if (n is! int || n < 0) {
- return 0;
- } else {
- return n & 0x0F;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- }
-
- void test_localVar() {
- Source source = addSource(r'''
-int f() {
- num n = 1234;
- return n & 0x0F;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- }
-}
-
-/**
- * Strong mode static analyzer downwards inference tests
- */
-@reflectiveTest
-class StrongModeDownwardsInferenceTest extends ResolverTestCase {
- TypeAssertions _assertions;
-
- Asserter<DartType> _isDynamic;
- Asserter<InterfaceType> _isFutureOfDynamic;
- Asserter<InterfaceType> _isFutureOfInt;
- Asserter<DartType> _isInt;
- Asserter<DartType> _isNum;
- Asserter<DartType> _isString;
-
- AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, DartType>
- _isFunction2Of;
- AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isFutureOf;
- AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>, DartType>
- _isInstantiationOf;
- AsserterBuilder<Asserter<DartType>, InterfaceType> _isListOf;
- AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, InterfaceType>
- _isMapOf;
- AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isStreamOf;
- AsserterBuilder<DartType, DartType> _isType;
-
- AsserterBuilder<Element, DartType> _hasElement;
- AsserterBuilder<DartType, DartType> _sameElement;
-
- @override
- void setUp() {
- super.setUp();
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.strongMode = true;
- resetWithOptions(options);
- _assertions = new TypeAssertions(typeProvider);
- _isType = _assertions.isType;
- _hasElement = _assertions.hasElement;
- _isInstantiationOf = _assertions.isInstantiationOf;
- _isInt = _assertions.isInt;
- _isNum = _assertions.isNum;
- _isString = _assertions.isString;
- _isDynamic = _assertions.isDynamic;
- _isListOf = _assertions.isListOf;
- _isMapOf = _assertions.isMapOf;
- _isFunction2Of = _assertions.isFunction2Of;
- _sameElement = _assertions.sameElement;
- _isFutureOf = _isInstantiationOf(_sameElement(typeProvider.futureType));
- _isFutureOfDynamic = _isFutureOf([_isDynamic]);
- _isFutureOfInt = _isFutureOf([_isInt]);
- _isStreamOf = _isInstantiationOf(_sameElement(typeProvider.streamType));
- }
-
- void test_async_method_propagation() {
- String code = r'''
- import "dart:async";
- class A {
- Future f0() => new Future.value(3);
- Future f1() async => new Future.value(3);
- Future f2() async => await new Future.value(3);
-
- Future<int> f3() => new Future.value(3);
- Future<int> f4() async => new Future.value(3);
- Future<int> f5() async => await new Future.value(3);
-
- Future g0() { return new Future.value(3); }
- Future g1() async { return new Future.value(3); }
- Future g2() async { return await new Future.value(3); }
-
- Future<int> g3() { return new Future.value(3); }
- Future<int> g4() async { return new Future.value(3); }
- Future<int> g5() async { return await new Future.value(3); }
- }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- void check(String name, Asserter<InterfaceType> typeTest) {
- MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
- FunctionBody body = test.body;
- Expression returnExp;
- if (body is ExpressionFunctionBody) {
- returnExp = body.expression;
- } else {
- ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0];
- returnExp = stmt.expression;
- }
- DartType type = returnExp.staticType;
- if (returnExp is AwaitExpression) {
- type = returnExp.expression.staticType;
- }
- typeTest(type);
- }
-
- check("f0", _isFutureOfDynamic);
- check("f1", _isFutureOfDynamic);
- check("f2", _isFutureOfDynamic);
-
- check("f3", _isFutureOfInt);
- // This should be int when we handle the implicit Future<T> | T union
- // https://github.com/dart-lang/sdk/issues/25322
- check("f4", _isFutureOfDynamic);
- check("f5", _isFutureOfInt);
-
- check("g0", _isFutureOfDynamic);
- check("g1", _isFutureOfDynamic);
- check("g2", _isFutureOfDynamic);
-
- check("g3", _isFutureOfInt);
- // This should be int when we handle the implicit Future<T> | T union
- // https://github.com/dart-lang/sdk/issues/25322
- check("g4", _isFutureOfDynamic);
- check("g5", _isFutureOfInt);
- }
-
- void test_async_propagation() {
- String code = r'''
- import "dart:async";
-
- Future f0() => new Future.value(3);
- Future f1() async => new Future.value(3);
- Future f2() async => await new Future.value(3);
-
- Future<int> f3() => new Future.value(3);
- Future<int> f4() async => new Future.value(3);
- Future<int> f5() async => await new Future.value(3);
-
- Future g0() { return new Future.value(3); }
- Future g1() async { return new Future.value(3); }
- Future g2() async { return await new Future.value(3); }
-
- Future<int> g3() { return new Future.value(3); }
- Future<int> g4() async { return new Future.value(3); }
- Future<int> g5() async { return await new Future.value(3); }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- void check(String name, Asserter<InterfaceType> typeTest) {
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
- FunctionBody body = test.functionExpression.body;
- Expression returnExp;
- if (body is ExpressionFunctionBody) {
- returnExp = body.expression;
- } else {
- ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0];
- returnExp = stmt.expression;
- }
- DartType type = returnExp.staticType;
- if (returnExp is AwaitExpression) {
- type = returnExp.expression.staticType;
- }
- typeTest(type);
- }
-
- check("f0", _isFutureOfDynamic);
- check("f1", _isFutureOfDynamic);
- check("f2", _isFutureOfDynamic);
-
- check("f3", _isFutureOfInt);
- // This should be int when we handle the implicit Future<T> | T union
- // https://github.com/dart-lang/sdk/issues/25322
- check("f4", _isFutureOfDynamic);
- check("f5", _isFutureOfInt);
-
- check("g0", _isFutureOfDynamic);
- check("g1", _isFutureOfDynamic);
- check("g2", _isFutureOfDynamic);
-
- check("g3", _isFutureOfInt);
- // This should be int when we handle the implicit Future<T> | T union
- // https://github.com/dart-lang/sdk/issues/25322
- check("g4", _isFutureOfDynamic);
- check("g5", _isFutureOfInt);
- }
-
- void test_async_star_method_propagation() {
- String code = r'''
- import "dart:async";
- class A {
- Stream g0() async* { yield []; }
- Stream g1() async* { yield* new Stream(); }
-
- Stream<List<int>> g2() async* { yield []; }
- Stream<List<int>> g3() async* { yield* new Stream(); }
- }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- void check(String name, Asserter<InterfaceType> typeTest) {
- MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
- BlockFunctionBody body = test.body;
- YieldStatement stmt = body.block.statements[0];
- Expression exp = stmt.expression;
- typeTest(exp.staticType);
- }
-
- check("g0", _isListOf(_isDynamic));
- check("g1", _isStreamOf([_isDynamic]));
-
- check("g2", _isListOf(_isInt));
- check("g3", _isStreamOf([_isListOf(_isInt)]));
- }
-
- void test_async_star_propagation() {
- String code = r'''
- import "dart:async";
-
- Stream g0() async* { yield []; }
- Stream g1() async* { yield* new Stream(); }
-
- Stream<List<int>> g2() async* { yield []; }
- Stream<List<int>> g3() async* { yield* new Stream(); }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- void check(String name, Asserter<InterfaceType> typeTest) {
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
- BlockFunctionBody body = test.functionExpression.body;
- YieldStatement stmt = body.block.statements[0];
- Expression exp = stmt.expression;
- typeTest(exp.staticType);
- }
-
- check("g0", _isListOf(_isDynamic));
- check("g1", _isStreamOf([_isDynamic]));
-
- check("g2", _isListOf(_isInt));
- check("g3", _isStreamOf([_isListOf(_isInt)]));
- }
-
- void test_cascadeExpression() {
- String code = r'''
- class A<T> {
- List<T> map(T a, List<T> mapper(T x)) => mapper(a);
- }
-
- void main () {
- A<int> a = new A()..map(0, (x) => [x]);
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- CascadeExpression fetch(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- CascadeExpression exp = decl.initializer;
- return exp;
- }
- Element elementA = AstFinder.getClass(unit, "A").element;
-
- CascadeExpression cascade = fetch(0);
- _isInstantiationOf(_hasElement(elementA))([_isInt])(cascade.staticType);
- MethodInvocation invoke = cascade.cascadeSections[0];
- FunctionExpression function = invoke.argumentList.arguments[1];
- ExecutableElement f0 = function.element;
- _isListOf(_isInt)(f0.type.returnType);
- expect(f0.type.normalParameterTypes[0], typeProvider.intType);
- }
-
- void test_constructorInitializer_propagation() {
- String code = r'''
- class A {
- List<String> x;
- A() : this.x = [];
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- ConstructorDeclaration constructor =
- AstFinder.getConstructorInClass(unit, "A", null);
- ConstructorFieldInitializer assignment = constructor.initializers[0];
- Expression exp = assignment.expression;
- _isListOf(_isString)(exp.staticType);
- }
-
- void test_factoryConstructor_propagation() {
- String code = r'''
- class A<T> {
- factory A() { return new B(); }
- }
- class B<S> extends A<S> {}
- ''';
- CompilationUnit unit = resolveSource(code);
-
- ConstructorDeclaration constructor =
- AstFinder.getConstructorInClass(unit, "A", null);
- BlockFunctionBody body = constructor.body;
- ReturnStatement stmt = body.block.statements[0];
- InstanceCreationExpression exp = stmt.expression;
- ClassElement elementB = AstFinder.getClass(unit, "B").element;
- ClassElement elementA = AstFinder.getClass(unit, "A").element;
- expect(exp.constructorName.type.type.element, elementB);
- _isInstantiationOf(_hasElement(elementB))(
- [_isType(elementA.typeParameters[0].type)])(exp.staticType);
- }
-
- void test_fieldDeclaration_propagation() {
- String code = r'''
- class A {
- List<String> f0 = ["hello"];
- }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- VariableDeclaration field = AstFinder.getFieldInClass(unit, "A", "f0");
-
- _isListOf(_isString)(field.initializer.staticType);
- }
-
- void test_functionDeclaration_body_propagation() {
- String code = r'''
- typedef T Function2<S, T>(S x);
-
- List<int> test1() => [];
-
- Function2<int, int> test2 (int x) {
- Function2<String, int> inner() {
- return (x) => x.length;
- }
- return (x) => x;
- }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
-
- FunctionDeclaration test1 = AstFinder.getTopLevelFunction(unit, "test1");
- ExpressionFunctionBody body = test1.functionExpression.body;
- assertListOfInt(body.expression.staticType);
-
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test2");
-
- FunctionDeclaration inner =
- (statements[0] as FunctionDeclarationStatement).functionDeclaration;
- BlockFunctionBody body0 = inner.functionExpression.body;
- ReturnStatement return0 = body0.block.statements[0];
- Expression anon0 = return0.expression;
- FunctionType type0 = anon0.staticType;
- expect(type0.returnType, typeProvider.intType);
- expect(type0.normalParameterTypes[0], typeProvider.stringType);
-
- FunctionExpression anon1 = (statements[1] as ReturnStatement).expression;
- FunctionType type1 = anon1.element.type;
- expect(type1.returnType, typeProvider.intType);
- expect(type1.normalParameterTypes[0], typeProvider.intType);
- }
-
- void test_functionLiteral_assignment_typedArguments() {
- String code = r'''
- typedef T Function2<S, T>(S x);
-
- void main () {
- Function2<int, String> l0 = (int x) => null;
- Function2<int, String> l1 = (int x) => "hello";
- Function2<int, String> l2 = (String x) => "hello";
- Function2<int, String> l3 = (int x) => 3;
- Function2<int, String> l4 = (int x) {return 3;};
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- FunctionExpression exp = decl.initializer;
- return exp.element.type;
- }
- _isFunction2Of(_isInt, _isString)(literal(0));
- _isFunction2Of(_isInt, _isString)(literal(1));
- _isFunction2Of(_isString, _isString)(literal(2));
- _isFunction2Of(_isInt, _isInt)(literal(3));
- _isFunction2Of(_isInt, _isString)(literal(4));
- }
-
- void test_functionLiteral_assignment_unTypedArguments() {
- String code = r'''
- typedef T Function2<S, T>(S x);
-
- void main () {
- Function2<int, String> l0 = (x) => null;
- Function2<int, String> l1 = (x) => "hello";
- Function2<int, String> l2 = (x) => "hello";
- Function2<int, String> l3 = (x) => 3;
- Function2<int, String> l4 = (x) {return 3;};
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- FunctionExpression exp = decl.initializer;
- return exp.element.type;
- }
- _isFunction2Of(_isInt, _isString)(literal(0));
- _isFunction2Of(_isInt, _isString)(literal(1));
- _isFunction2Of(_isInt, _isString)(literal(2));
- _isFunction2Of(_isInt, _isInt)(literal(3));
- _isFunction2Of(_isInt, _isString)(literal(4));
- }
-
- void test_functionLiteral_body_propagation() {
- String code = r'''
- typedef T Function2<S, T>(S x);
-
- void main () {
- Function2<int, List<String>> l0 = (int x) => ["hello"];
- Function2<int, List<String>> l1 = (String x) => ["hello"];
- Function2<int, List<String>> l2 = (int x) => [3];
- Function2<int, List<String>> l3 = (int x) {return [3];};
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- Expression functionReturnValue(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- FunctionExpression exp = decl.initializer;
- FunctionBody body = exp.body;
- if (body is ExpressionFunctionBody) {
- return body.expression;
- } else {
- Statement stmt = (body as BlockFunctionBody).block.statements[0];
- return (stmt as ReturnStatement).expression;
- }
- }
- Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
- assertListOfString(functionReturnValue(0).staticType);
- assertListOfString(functionReturnValue(1).staticType);
- assertListOfString(functionReturnValue(2).staticType);
- assertListOfString(functionReturnValue(3).staticType);
- }
-
- void test_functionLiteral_functionExpressionInvocation_typedArguments() {
- String code = r'''
- class Mapper<F, T> {
- T map(T mapper(F x)) => mapper(null);
- }
-
- void main () {
- (new Mapper<int, String>().map)((int x) => null);
- (new Mapper<int, String>().map)((int x) => "hello");
- (new Mapper<int, String>().map)((String x) => "hello");
- (new Mapper<int, String>().map)((int x) => 3);
- (new Mapper<int, String>().map)((int x) {return 3;});
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- ExpressionStatement stmt = statements[i];
- FunctionExpressionInvocation invk = stmt.expression;
- FunctionExpression exp = invk.argumentList.arguments[0];
- return exp.element.type;
- }
- _isFunction2Of(_isInt, _isString)(literal(0));
- _isFunction2Of(_isInt, _isString)(literal(1));
- _isFunction2Of(_isString, _isString)(literal(2));
- _isFunction2Of(_isInt, _isInt)(literal(3));
- _isFunction2Of(_isInt, _isString)(literal(4));
- }
-
- void test_functionLiteral_functionExpressionInvocation_unTypedArguments() {
- String code = r'''
- class Mapper<F, T> {
- T map(T mapper(F x)) => mapper(null);
- }
-
- void main () {
- (new Mapper<int, String>().map)((x) => null);
- (new Mapper<int, String>().map)((x) => "hello");
- (new Mapper<int, String>().map)((x) => "hello");
- (new Mapper<int, String>().map)((x) => 3);
- (new Mapper<int, String>().map)((x) {return 3;});
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- ExpressionStatement stmt = statements[i];
- FunctionExpressionInvocation invk = stmt.expression;
- FunctionExpression exp = invk.argumentList.arguments[0];
- return exp.element.type;
- }
- _isFunction2Of(_isInt, _isString)(literal(0));
- _isFunction2Of(_isInt, _isString)(literal(1));
- _isFunction2Of(_isInt, _isString)(literal(2));
- _isFunction2Of(_isInt, _isInt)(literal(3));
- _isFunction2Of(_isInt, _isString)(literal(4));
- }
-
- void test_functionLiteral_functionInvocation_typedArguments() {
- String code = r'''
- String map(String mapper(int x)) => mapper(null);
-
- void main () {
- map((int x) => null);
- map((int x) => "hello");
- map((String x) => "hello");
- map((int x) => 3);
- map((int x) {return 3;});
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- ExpressionStatement stmt = statements[i];
- MethodInvocation invk = stmt.expression;
- FunctionExpression exp = invk.argumentList.arguments[0];
- return exp.element.type;
- }
- _isFunction2Of(_isInt, _isString)(literal(0));
- _isFunction2Of(_isInt, _isString)(literal(1));
- _isFunction2Of(_isString, _isString)(literal(2));
- _isFunction2Of(_isInt, _isInt)(literal(3));
- _isFunction2Of(_isInt, _isString)(literal(4));
- }
-
- void test_functionLiteral_functionInvocation_unTypedArguments() {
- String code = r'''
- String map(String mapper(int x)) => mapper(null);
-
- void main () {
- map((x) => null);
- map((x) => "hello");
- map((x) => "hello");
- map((x) => 3);
- map((x) {return 3;});
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- ExpressionStatement stmt = statements[i];
- MethodInvocation invk = stmt.expression;
- FunctionExpression exp = invk.argumentList.arguments[0];
- return exp.element.type;
- }
- _isFunction2Of(_isInt, _isString)(literal(0));
- _isFunction2Of(_isInt, _isString)(literal(1));
- _isFunction2Of(_isInt, _isString)(literal(2));
- _isFunction2Of(_isInt, _isInt)(literal(3));
- _isFunction2Of(_isInt, _isString)(literal(4));
- }
-
- void test_functionLiteral_methodInvocation_typedArguments() {
- String code = r'''
- class Mapper<F, T> {
- T map(T mapper(F x)) => mapper(null);
- }
-
- void main () {
- new Mapper<int, String>().map((int x) => null);
- new Mapper<int, String>().map((int x) => "hello");
- new Mapper<int, String>().map((String x) => "hello");
- new Mapper<int, String>().map((int x) => 3);
- new Mapper<int, String>().map((int x) {return 3;});
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- ExpressionStatement stmt = statements[i];
- MethodInvocation invk = stmt.expression;
- FunctionExpression exp = invk.argumentList.arguments[0];
- return exp.element.type;
- }
- _isFunction2Of(_isInt, _isString)(literal(0));
- _isFunction2Of(_isInt, _isString)(literal(1));
- _isFunction2Of(_isString, _isString)(literal(2));
- _isFunction2Of(_isInt, _isInt)(literal(3));
- _isFunction2Of(_isInt, _isString)(literal(4));
- }
-
- void test_functionLiteral_methodInvocation_unTypedArguments() {
- String code = r'''
- class Mapper<F, T> {
- T map(T mapper(F x)) => mapper(null);
- }
-
- void main () {
- new Mapper<int, String>().map((x) => null);
- new Mapper<int, String>().map((x) => "hello");
- new Mapper<int, String>().map((x) => "hello");
- new Mapper<int, String>().map((x) => 3);
- new Mapper<int, String>().map((x) {return 3;});
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- ExpressionStatement stmt = statements[i];
- MethodInvocation invk = stmt.expression;
- FunctionExpression exp = invk.argumentList.arguments[0];
- return exp.element.type;
- }
- _isFunction2Of(_isInt, _isString)(literal(0));
- _isFunction2Of(_isInt, _isString)(literal(1));
- _isFunction2Of(_isInt, _isString)(literal(2));
- _isFunction2Of(_isInt, _isInt)(literal(3));
- _isFunction2Of(_isInt, _isString)(literal(4));
- }
-
- void test_functionLiteral_unTypedArgument_propagation() {
- String code = r'''
- typedef T Function2<S, T>(S x);
-
- void main () {
- Function2<int, int> l0 = (x) => x;
- Function2<int, int> l1 = (x) => x+1;
- Function2<int, String> l2 = (x) => x;
- Function2<int, String> l3 = (x) => x.toLowerCase();
- Function2<String, String> l4 = (x) => x.toLowerCase();
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- Expression functionReturnValue(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- FunctionExpression exp = decl.initializer;
- FunctionBody body = exp.body;
- if (body is ExpressionFunctionBody) {
- return body.expression;
- } else {
- Statement stmt = (body as BlockFunctionBody).block.statements[0];
- return (stmt as ReturnStatement).expression;
- }
- }
- expect(functionReturnValue(0).staticType, typeProvider.intType);
- expect(functionReturnValue(1).staticType, typeProvider.intType);
- expect(functionReturnValue(2).staticType, typeProvider.intType);
- expect(functionReturnValue(3).staticType, typeProvider.dynamicType);
- expect(functionReturnValue(4).staticType, typeProvider.stringType);
- }
-
- void test_inference_hints() {
- Source source = addSource(r'''
- void main () {
- var x = 3;
- List<int> l0 = [];
- }
- ''');
- resolve2(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_instanceCreation() {
- String code = r'''
- class A<S, T> {
- S x;
- T y;
- A(this.x, this.y);
- A.named(this.x, this.y);
- }
-
- class B<S, T> extends A<T, S> {
- B(S y, T x) : super(x, y);
- B.named(S y, T x) : super.named(x, y);
- }
-
- class C<S> extends B<S, S> {
- C(S a) : super(a, a);
- C.named(S a) : super.named(a, a);
- }
-
- class D<S, T> extends B<T, int> {
- D(T a) : super(a, 3);
- D.named(T a) : super.named(a, 3);
- }
-
- class E<S, T> extends A<C<S>, T> {
- E(T a) : super(null, a);
- }
-
- class F<S, T> extends A<S, T> {
- F(S x, T y, {List<S> a, List<T> b}) : super(x, y);
- F.named(S x, T y, [S a, T b]) : super(a, b);
- }
-
- void test0() {
- A<int, String> a0 = new A(3, "hello");
- A<int, String> a1 = new A.named(3, "hello");
- A<int, String> a2 = new A<int, String>(3, "hello");
- A<int, String> a3 = new A<int, String>.named(3, "hello");
- A<int, String> a4 = new A<int, dynamic>(3, "hello");
- A<int, String> a5 = new A<dynamic, dynamic>.named(3, "hello");
- }
- void test1() {
- A<int, String> a0 = new A("hello", 3);
- A<int, String> a1 = new A.named("hello", 3);
- }
- void test2() {
- A<int, String> a0 = new B("hello", 3);
- A<int, String> a1 = new B.named("hello", 3);
- A<int, String> a2 = new B<String, int>("hello", 3);
- A<int, String> a3 = new B<String, int>.named("hello", 3);
- A<int, String> a4 = new B<String, dynamic>("hello", 3);
- A<int, String> a5 = new B<dynamic, dynamic>.named("hello", 3);
- }
- void test3() {
- A<int, String> a0 = new B(3, "hello");
- A<int, String> a1 = new B.named(3, "hello");
- }
- void test4() {
- A<int, int> a0 = new C(3);
- A<int, int> a1 = new C.named(3);
- A<int, int> a2 = new C<int>(3);
- A<int, int> a3 = new C<int>.named(3);
- A<int, int> a4 = new C<dynamic>(3);
- A<int, int> a5 = new C<dynamic>.named(3);
- }
- void test5() {
- A<int, int> a0 = new C("hello");
- A<int, int> a1 = new C.named("hello");
- }
- void test6() {
- A<int, String> a0 = new D("hello");
- A<int, String> a1 = new D.named("hello");
- A<int, String> a2 = new D<int, String>("hello");
- A<int, String> a3 = new D<String, String>.named("hello");
- A<int, String> a4 = new D<num, dynamic>("hello");
- A<int, String> a5 = new D<dynamic, dynamic>.named("hello");
- }
- void test7() {
- A<int, String> a0 = new D(3);
- A<int, String> a1 = new D.named(3);
- }
- void test8() {
- // Currently we only allow variable constraints. Test that we reject.
- A<C<int>, String> a0 = new E("hello");
- }
- void test9() { // Check named and optional arguments
- A<int, String> a0 = new F(3, "hello", a: [3], b: ["hello"]);
- A<int, String> a1 = new F(3, "hello", a: ["hello"], b:[3]);
- A<int, String> a2 = new F.named(3, "hello", 3, "hello");
- A<int, String> a3 = new F.named(3, "hello");
- A<int, String> a4 = new F.named(3, "hello", "hello", 3);
- A<int, String> a5 = new F.named(3, "hello", "hello");
- }
- }''';
- CompilationUnit unit = resolveSource(code);
-
- Expression rhs(VariableDeclarationStatement stmt) {
- VariableDeclaration decl = stmt.variables.variables[0];
- Expression exp = decl.initializer;
- return exp;
- }
-
- void hasType(Asserter<DartType> assertion, Expression exp) =>
- assertion(exp.staticType);
-
- Element elementA = AstFinder.getClass(unit, "A").element;
- Element elementB = AstFinder.getClass(unit, "B").element;
- Element elementC = AstFinder.getClass(unit, "C").element;
- Element elementD = AstFinder.getClass(unit, "D").element;
- Element elementE = AstFinder.getClass(unit, "E").element;
- Element elementF = AstFinder.getClass(unit, "F").element;
-
- AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf =
- _isInstantiationOf(_hasElement(elementA));
- AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf =
- _isInstantiationOf(_hasElement(elementB));
- AsserterBuilder<List<Asserter<DartType>>, DartType> assertCOf =
- _isInstantiationOf(_hasElement(elementC));
- AsserterBuilder<List<Asserter<DartType>>, DartType> assertDOf =
- _isInstantiationOf(_hasElement(elementD));
- AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf =
- _isInstantiationOf(_hasElement(elementE));
- AsserterBuilder<List<Asserter<DartType>>, DartType> assertFOf =
- _isInstantiationOf(_hasElement(elementF));
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test0");
-
- hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
- hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
- hasType(assertAOf([_isInt, _isString]), rhs(statements[1]));
- hasType(assertAOf([_isInt, _isString]), rhs(statements[2]));
- hasType(assertAOf([_isInt, _isString]), rhs(statements[3]));
- hasType(assertAOf([_isInt, _isDynamic]), rhs(statements[4]));
- hasType(assertAOf([_isDynamic, _isDynamic]), rhs(statements[5]));
- }
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test1");
- hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
- hasType(assertAOf([_isInt, _isString]), rhs(statements[1]));
- }
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test2");
- hasType(assertBOf([_isString, _isInt]), rhs(statements[0]));
- hasType(assertBOf([_isString, _isInt]), rhs(statements[1]));
- hasType(assertBOf([_isString, _isInt]), rhs(statements[2]));
- hasType(assertBOf([_isString, _isInt]), rhs(statements[3]));
- hasType(assertBOf([_isString, _isDynamic]), rhs(statements[4]));
- hasType(assertBOf([_isDynamic, _isDynamic]), rhs(statements[5]));
- }
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test3");
- hasType(assertBOf([_isString, _isInt]), rhs(statements[0]));
- hasType(assertBOf([_isString, _isInt]), rhs(statements[1]));
- }
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test4");
- hasType(assertCOf([_isInt]), rhs(statements[0]));
- hasType(assertCOf([_isInt]), rhs(statements[1]));
- hasType(assertCOf([_isInt]), rhs(statements[2]));
- hasType(assertCOf([_isInt]), rhs(statements[3]));
- hasType(assertCOf([_isDynamic]), rhs(statements[4]));
- hasType(assertCOf([_isDynamic]), rhs(statements[5]));
- }
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test5");
- hasType(assertCOf([_isInt]), rhs(statements[0]));
- hasType(assertCOf([_isInt]), rhs(statements[1]));
- }
-
- {
- // The first type parameter is not constrained by the
- // context. We could choose a tighter type, but currently
- // we just use dynamic.
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test6");
- hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0]));
- hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1]));
- hasType(assertDOf([_isInt, _isString]), rhs(statements[2]));
- hasType(assertDOf([_isString, _isString]), rhs(statements[3]));
- hasType(assertDOf([_isNum, _isDynamic]), rhs(statements[4]));
- hasType(assertDOf([_isDynamic, _isDynamic]), rhs(statements[5]));
- }
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test7");
- hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0]));
- hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1]));
- }
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test8");
- hasType(assertEOf([_isDynamic, _isDynamic]), rhs(statements[0]));
- }
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test9");
- hasType(assertFOf([_isInt, _isString]), rhs(statements[0]));
- hasType(assertFOf([_isInt, _isString]), rhs(statements[1]));
- hasType(assertFOf([_isInt, _isString]), rhs(statements[2]));
- hasType(assertFOf([_isInt, _isString]), rhs(statements[3]));
- hasType(assertFOf([_isInt, _isString]), rhs(statements[4]));
- hasType(assertFOf([_isInt, _isString]), rhs(statements[5]));
- }
- }
-
- void test_listLiteral_nested() {
- String code = r'''
- void main () {
- List<List<int>> l0 = [[]];
- Iterable<List<int>> l1 = [[3]];
- Iterable<List<int>> l2 = [[3], [4]];
- List<List<int>> l3 = [["hello", 3], []];
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- ListLiteral literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- ListLiteral exp = decl.initializer;
- return exp;
- }
-
- Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
- Asserter<InterfaceType> assertListOfListOfInt = _isListOf(assertListOfInt);
-
- assertListOfListOfInt(literal(0).staticType);
- assertListOfListOfInt(literal(1).staticType);
- assertListOfListOfInt(literal(2).staticType);
- assertListOfListOfInt(literal(3).staticType);
-
- assertListOfInt(literal(1).elements[0].staticType);
- assertListOfInt(literal(2).elements[0].staticType);
- assertListOfInt(literal(3).elements[0].staticType);
- }
-
- void test_listLiteral_simple() {
- String code = r'''
- void main () {
- List<int> l0 = [];
- List<int> l1 = [3];
- List<int> l2 = ["hello"];
- List<int> l3 = ["hello", 3];
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- ListLiteral exp = decl.initializer;
- return exp.staticType;
- }
-
- Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
-
- assertListOfInt(literal(0));
- assertListOfInt(literal(1));
- assertListOfInt(literal(2));
- assertListOfInt(literal(3));
- }
-
- void test_listLiteral_simple_const() {
- String code = r'''
- void main () {
- const List<int> c0 = const [];
- const List<int> c1 = const [3];
- const List<int> c2 = const ["hello"];
- const List<int> c3 = const ["hello", 3];
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- ListLiteral exp = decl.initializer;
- return exp.staticType;
- }
-
- Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
-
- assertListOfInt(literal(0));
- assertListOfInt(literal(1));
- assertListOfInt(literal(2));
- assertListOfInt(literal(3));
- }
-
- void test_listLiteral_simple_disabled() {
- String code = r'''
- void main () {
- List<int> l0 = <num>[];
- List<int> l1 = <num>[3];
- List<int> l2 = <String>["hello"];
- List<int> l3 = <dynamic>["hello", 3];
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- ListLiteral exp = decl.initializer;
- return exp.staticType;
- }
-
- _isListOf(_isNum)(literal(0));
- _isListOf(_isNum)(literal(1));
- _isListOf(_isString)(literal(2));
- _isListOf(_isDynamic)(literal(3));
- }
-
- void test_listLiteral_simple_subtype() {
- String code = r'''
- void main () {
- Iterable<int> l0 = [];
- Iterable<int> l1 = [3];
- Iterable<int> l2 = ["hello"];
- Iterable<int> l3 = ["hello", 3];
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- ListLiteral exp = decl.initializer;
- return exp.staticType;
- }
-
- Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
-
- assertListOfInt(literal(0));
- assertListOfInt(literal(1));
- assertListOfInt(literal(2));
- assertListOfInt(literal(3));
- }
-
- void test_mapLiteral_nested() {
- String code = r'''
- void main () {
- Map<int, List<String>> l0 = {};
- Map<int, List<String>> l1 = {3: ["hello"]};
- Map<int, List<String>> l2 = {"hello": ["hello"]};
- Map<int, List<String>> l3 = {3: [3]};
- Map<int, List<String>> l4 = {3:["hello"], "hello": [3]};
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- MapLiteral literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- MapLiteral exp = decl.initializer;
- return exp;
- }
-
- Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
- Asserter<InterfaceType> assertMapOfIntToListOfString =
- _isMapOf(_isInt, assertListOfString);
-
- assertMapOfIntToListOfString(literal(0).staticType);
- assertMapOfIntToListOfString(literal(1).staticType);
- assertMapOfIntToListOfString(literal(2).staticType);
- assertMapOfIntToListOfString(literal(3).staticType);
- assertMapOfIntToListOfString(literal(4).staticType);
-
- assertListOfString(literal(1).entries[0].value.staticType);
- assertListOfString(literal(2).entries[0].value.staticType);
- assertListOfString(literal(3).entries[0].value.staticType);
- assertListOfString(literal(4).entries[0].value.staticType);
- }
-
- void test_mapLiteral_simple() {
- String code = r'''
- void main () {
- Map<int, String> l0 = {};
- Map<int, String> l1 = {3: "hello"};
- Map<int, String> l2 = {"hello": "hello"};
- Map<int, String> l3 = {3: 3};
- Map<int, String> l4 = {3:"hello", "hello": 3};
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- MapLiteral exp = decl.initializer;
- return exp.staticType;
- }
-
- Asserter<InterfaceType> assertMapOfIntToString =
- _isMapOf(_isInt, _isString);
-
- assertMapOfIntToString(literal(0));
- assertMapOfIntToString(literal(1));
- assertMapOfIntToString(literal(2));
- assertMapOfIntToString(literal(3));
- }
-
- void test_mapLiteral_simple_disabled() {
- String code = r'''
- void main () {
- Map<int, String> l0 = <int, dynamic>{};
- Map<int, String> l1 = <int, dynamic>{3: "hello"};
- Map<int, String> l2 = <int, dynamic>{"hello": "hello"};
- Map<int, String> l3 = <int, dynamic>{3: 3};
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- MapLiteral exp = decl.initializer;
- return exp.staticType;
- }
-
- Asserter<InterfaceType> assertMapOfIntToDynamic =
- _isMapOf(_isInt, _isDynamic);
-
- assertMapOfIntToDynamic(literal(0));
- assertMapOfIntToDynamic(literal(1));
- assertMapOfIntToDynamic(literal(2));
- assertMapOfIntToDynamic(literal(3));
- }
-
- void test_methodDeclaration_body_propagation() {
- String code = r'''
- class A {
- List<String> m0(int x) => ["hello"];
- List<String> m1(int x) {return [3];};
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- Expression methodReturnValue(String methodName) {
- MethodDeclaration method =
- AstFinder.getMethodInClass(unit, "A", methodName);
- FunctionBody body = method.body;
- if (body is ExpressionFunctionBody) {
- return body.expression;
- } else {
- Statement stmt = (body as BlockFunctionBody).block.statements[0];
- return (stmt as ReturnStatement).expression;
- }
- }
- Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
- assertListOfString(methodReturnValue("m0").staticType);
- assertListOfString(methodReturnValue("m1").staticType);
- }
-
- void test_redirectingConstructor_propagation() {
- String code = r'''
- class A {
- A() : this.named([]);
- A.named(List<String> x);
- }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- ConstructorDeclaration constructor =
- AstFinder.getConstructorInClass(unit, "A", null);
- RedirectingConstructorInvocation invocation = constructor.initializers[0];
- Expression exp = invocation.argumentList.arguments[0];
- _isListOf(_isString)(exp.staticType);
- }
-
- void test_superConstructorInvocation_propagation() {
- String code = r'''
- class B {
- B(List<String>);
- }
- class A extends B {
- A() : super([]);
- }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- ConstructorDeclaration constructor =
- AstFinder.getConstructorInClass(unit, "A", null);
- SuperConstructorInvocation invocation = constructor.initializers[0];
- Expression exp = invocation.argumentList.arguments[0];
- _isListOf(_isString)(exp.staticType);
- }
-
- void test_sync_star_method_propagation() {
- String code = r'''
- import "dart:async";
- class A {
- Iterable f0() sync* { yield []; }
- Iterable f1() sync* { yield* new List(); }
-
- Iterable<List<int>> f2() sync* { yield []; }
- Iterable<List<int>> f3() sync* { yield* new List(); }
- }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- void check(String name, Asserter<InterfaceType> typeTest) {
- MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
- BlockFunctionBody body = test.body;
- YieldStatement stmt = body.block.statements[0];
- Expression exp = stmt.expression;
- typeTest(exp.staticType);
- }
-
- check("f0", _isListOf(_isDynamic));
- check("f1", _isListOf(_isDynamic));
-
- check("f2", _isListOf(_isInt));
- check("f3", _isListOf(_isListOf(_isInt)));
+class C {
+ C() {
+ int get x => 0;
}
-
- void test_sync_star_propagation() {
- String code = r'''
- import "dart:async";
-
- Iterable f0() sync* { yield []; }
- Iterable f1() sync* { yield* new List(); }
-
- Iterable<List<int>> f2() sync* { yield []; }
- Iterable<List<int>> f3() sync* { yield* new List(); }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- void check(String name, Asserter<InterfaceType> typeTest) {
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
- BlockFunctionBody body = test.functionExpression.body;
- YieldStatement stmt = body.block.statements[0];
- Expression exp = stmt.expression;
- typeTest(exp.staticType);
- }
-
- check("f0", _isListOf(_isDynamic));
- check("f1", _isListOf(_isDynamic));
-
- check("f2", _isListOf(_isInt));
- check("f3", _isListOf(_isListOf(_isInt)));
+}''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ var unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ var types = unit.types;
+ expect(types, isNotNull);
+ expect(types, hasLength(1));
+ var type = types[0];
+ expect(type, isNotNull);
+ var constructors = type.constructors;
+ expect(constructors, isNotNull);
+ expect(constructors, hasLength(1));
+ ConstructorElement constructor = constructors[0];
+ expect(constructor, isNotNull);
+ List<FunctionElement> functions = constructor.functions;
+ expect(functions, isNotNull);
+ expect(functions, hasLength(1));
+ expect(functions[0].enclosingElement, constructor);
+ assertErrors(source, [ParserErrorCode.GETTER_IN_FUNCTION]);
}
}
/**
- * Strong mode static analyzer end to end tests
+ * Tests for generic method and function resolution that do not use strong mode.
*/
@reflectiveTest
-class StrongModeStaticTypeAnalyzer2Test extends _StaticTypeAnalyzer2TestShared {
- void fail_genericMethod_tearoff_instantiated() {
- _resolveTestUnit(r'''
-class C<E> {
- /*=T*/ f/*<T>*/(E e) => null;
- static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
- static final h = g;
-}
-
-/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
-var topG = topF;
-void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
- var c = new C<int>();
- /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
- var methodTearOffInst = c.f/*<int>*/;
- var staticTearOffInst = C.g/*<int>*/;
- var staticFieldTearOffInst = C.h/*<int>*/;
- var topFunTearOffInst = topF/*<int>*/;
- var topFieldTearOffInst = topG/*<int>*/;
- var localTearOffInst = lf/*<int>*/;
- var paramTearOffInst = pf/*<int>*/;
-}
-''');
- _expectIdentifierType('methodTearOffInst', "(int) → int");
- _expectIdentifierType('staticTearOffInst', "(int) → int");
- _expectIdentifierType('staticFieldTearOffInst', "(int) → int");
- _expectIdentifierType('topFunTearOffInst', "(int) → int");
- _expectIdentifierType('topFieldTearOffInst', "(int) → int");
- _expectIdentifierType('localTearOffInst', "(int) → int");
- _expectIdentifierType('paramTearOffInst', "(int) → int");
- }
-
+class GenericMethodResolverTest extends StaticTypeAnalyzer2TestShared {
void setUp() {
super.setUp();
AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.strongMode = true;
+ options.enableGenericMethods = true;
resetWithOptions(options);
}
- void test_dynamicObjectGetter_hashCode() {
- String code = r'''
-main() {
- dynamic a = null;
- var foo = a.hashCode;
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'int', isNull);
- }
-
- void test_dynamicObjectMethod_toString() {
- String code = r'''
-main() {
- dynamic a = null;
- var foo = a.toString();
+ void test_genericMethod_propagatedType_promotion() {
+ // Regression test for:
+ // https://github.com/dart-lang/sdk/issues/25340
+ //
+ // Note, after https://github.com/dart-lang/sdk/issues/25486 the original
+ // strong mode example won't work, as we now compute a static type and
+ // therefore discard the propagated type.
+ //
+ // So this test does not use strong mode.
+ resolveTestUnit(r'''
+abstract class Iter {
+ List<S> map<S>(S f(x));
}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'String', isNull);
- }
-
- void test_genericFunction() {
- _resolveTestUnit(r'/*=T*/ f/*<T>*/(/*=T*/ x) => null;');
- _expectFunctionType('f', '<T>(T) → T',
- elementTypeParams: '[T]', typeFormals: '[T]');
- SimpleIdentifier f = _findIdentifier('f');
- FunctionElementImpl e = f.staticElement;
- FunctionType ft = e.type.instantiate([typeProvider.stringType]);
- expect(ft.toString(), '(String) → String');
+class C {}
+C toSpan(dynamic element) {
+ if (element is Iter) {
+ var y = element.map(toSpan);
}
-
- void test_genericFunction_bounds() {
- _resolveTestUnit(r'/*=T*/ f/*<T extends num>*/(/*=T*/ x) => null;');
- _expectFunctionType('f', '<T extends num>(T) → T',
- elementTypeParams: '[T extends num]', typeFormals: '[T extends num]');
+ return null;
+}''');
+ expectIdentifierType('y = ', 'dynamic', 'List<dynamic>');
}
+}
- void test_genericFunction_parameter() {
- _resolveTestUnit(r'''
-void g(/*=T*/ f/*<T>*/(/*=T*/ x)) {}
-''');
- _expectFunctionType('f', '<T>(T) → T',
- elementTypeParams: '[T]', typeFormals: '[T]');
- SimpleIdentifier f = _findIdentifier('f');
- ParameterElementImpl e = f.staticElement;
- FunctionType type = e.type;
- FunctionType ft = type.instantiate([typeProvider.stringType]);
- expect(ft.toString(), '(String) → String');
+@reflectiveTest
+class LibraryImportScopeTest extends ResolverTestCase {
+ void test_conflictingImports() {
+ AnalysisContext context = AnalysisContextFactory.contextWithCore();
+ String typeNameA = "A";
+ String typeNameB = "B";
+ String typeNameC = "C";
+ ClassElement typeA = ElementFactory.classElement2(typeNameA);
+ ClassElement typeB1 = ElementFactory.classElement2(typeNameB);
+ ClassElement typeB2 = ElementFactory.classElement2(typeNameB);
+ ClassElement typeC = ElementFactory.classElement2(typeNameC);
+ LibraryElement importedLibrary1 = createTestLibrary(context, "imported1");
+ (importedLibrary1.definingCompilationUnit as CompilationUnitElementImpl)
+ .types = <ClassElement>[typeA, typeB1];
+ ImportElementImpl import1 =
+ ElementFactory.importFor(importedLibrary1, null);
+ LibraryElement importedLibrary2 = createTestLibrary(context, "imported2");
+ (importedLibrary2.definingCompilationUnit as CompilationUnitElementImpl)
+ .types = <ClassElement>[typeB2, typeC];
+ ImportElementImpl import2 =
+ ElementFactory.importFor(importedLibrary2, null);
+ LibraryElementImpl importingLibrary =
+ createTestLibrary(context, "importing");
+ importingLibrary.imports = <ImportElement>[import1, import2];
+ {
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ Scope scope = new LibraryImportScope(importingLibrary, errorListener);
+ expect(scope.lookup(AstFactory.identifier3(typeNameA), importingLibrary),
+ typeA);
+ errorListener.assertNoErrors();
+ expect(scope.lookup(AstFactory.identifier3(typeNameC), importingLibrary),
+ typeC);
+ errorListener.assertNoErrors();
+ Element element =
+ scope.lookup(AstFactory.identifier3(typeNameB), importingLibrary);
+ errorListener.assertErrorsWithCodes([StaticWarningCode.AMBIGUOUS_IMPORT]);
+ EngineTestCase.assertInstanceOf((obj) => obj is MultiplyDefinedElement,
+ MultiplyDefinedElement, element);
+ List<Element> conflictingElements =
+ (element as MultiplyDefinedElement).conflictingElements;
+ expect(conflictingElements, hasLength(2));
+ if (identical(conflictingElements[0], typeB1)) {
+ expect(conflictingElements[1], same(typeB2));
+ } else if (identical(conflictingElements[0], typeB2)) {
+ expect(conflictingElements[1], same(typeB1));
+ } else {
+ expect(conflictingElements[0], same(typeB1));
+ }
+ }
+ {
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ Scope scope = new LibraryImportScope(importingLibrary, errorListener);
+ Identifier identifier = AstFactory.identifier3(typeNameB);
+ AstFactory.methodDeclaration(null, AstFactory.typeName3(identifier), null,
+ null, AstFactory.identifier3("foo"), null);
+ Element element = scope.lookup(identifier, importingLibrary);
+ errorListener.assertErrorsWithCodes([StaticWarningCode.AMBIGUOUS_IMPORT]);
+ EngineTestCase.assertInstanceOf((obj) => obj is MultiplyDefinedElement,
+ MultiplyDefinedElement, element);
+ }
}
- void test_genericFunction_static() {
- _resolveTestUnit(r'''
-class C<E> {
- static /*=T*/ f/*<T>*/(/*=T*/ x) => null;
-}
-''');
- _expectFunctionType('f', '<T>(T) → T',
- elementTypeParams: '[T]', typeFormals: '[T]');
- SimpleIdentifier f = _findIdentifier('f');
- MethodElementImpl e = f.staticElement;
- FunctionType ft = e.type.instantiate([typeProvider.stringType]);
- expect(ft.toString(), '(String) → String');
+ void test_creation_empty() {
+ LibraryElement definingLibrary = createDefaultTestLibrary();
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ new LibraryImportScope(definingLibrary, errorListener);
}
- void test_genericFunction_typedef() {
- String code = r'''
-typedef T F<T>(T x);
-F f0;
-
-class C {
- static F f1;
- F f2;
- void g(F f3) {
- F f4;
- f0(3);
- f1(3);
- f2(3);
- f3(3);
- f4(3);
+ void test_creation_nonEmpty() {
+ AnalysisContext context = AnalysisContextFactory.contextWithCore();
+ String importedTypeName = "A";
+ ClassElement importedType =
+ new ClassElementImpl.forNode(AstFactory.identifier3(importedTypeName));
+ LibraryElement importedLibrary = createTestLibrary(context, "imported");
+ (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
+ .types = <ClassElement>[importedType];
+ LibraryElementImpl definingLibrary =
+ createTestLibrary(context, "importing");
+ ImportElementImpl importElement = new ImportElementImpl(0);
+ importElement.importedLibrary = importedLibrary;
+ definingLibrary.imports = <ImportElement>[importElement];
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ Scope scope = new LibraryImportScope(definingLibrary, errorListener);
+ expect(
+ scope.lookup(AstFactory.identifier3(importedTypeName), definingLibrary),
+ importedType);
}
-}
-class D<S> {
- static F f1;
- F f2;
- void g(F f3) {
- F f4;
- f0(3);
- f1(3);
- f2(3);
- f3(3);
- f4(3);
+ void test_getErrorListener() {
+ LibraryElement definingLibrary = createDefaultTestLibrary();
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ LibraryImportScope scope =
+ new LibraryImportScope(definingLibrary, errorListener);
+ expect(scope.errorListener, errorListener);
}
-}
-''';
- _resolveTestUnit(code);
-
- checkBody(String className) {
- List<Statement> statements =
- AstFinder.getStatementsInMethod(testUnit, className, "g");
-
- for (int i = 1; i <= 5; i++) {
- Expression exp = (statements[i] as ExpressionStatement).expression;
- expect(exp.staticType, typeProvider.dynamicType);
- }
- }
- checkBody("C");
- checkBody("D");
+ void test_nonConflictingImports_fromSdk() {
+ AnalysisContext context = AnalysisContextFactory.contextWithCore();
+ String typeName = "List";
+ ClassElement type = ElementFactory.classElement2(typeName);
+ LibraryElement importedLibrary = createTestLibrary(context, "lib");
+ (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
+ .types = <ClassElement>[type];
+ ImportElementImpl importCore = ElementFactory.importFor(
+ context.getLibraryElement(context.sourceFactory.forUri("dart:core")),
+ null);
+ ImportElementImpl importLib =
+ ElementFactory.importFor(importedLibrary, null);
+ LibraryElementImpl importingLibrary =
+ createTestLibrary(context, "importing");
+ importingLibrary.imports = <ImportElement>[importCore, importLib];
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ Scope scope = new LibraryImportScope(importingLibrary, errorListener);
+ expect(
+ scope.lookup(AstFactory.identifier3(typeName), importingLibrary), type);
+ errorListener
+ .assertErrorsWithCodes([StaticWarningCode.CONFLICTING_DART_IMPORT]);
}
- void test_genericMethod() {
- _resolveTestUnit(r'''
-class C<E> {
- List/*<T>*/ f/*<T>*/(E e) => null;
-}
-main() {
- C<String> cOfString;
-}
-''');
- _expectFunctionType('f', '<T>(E) → List<T>',
- elementTypeParams: '[T]',
- typeParams: '[E]',
- typeArgs: '[E]',
- typeFormals: '[T]');
- SimpleIdentifier c = _findIdentifier('cOfString');
- FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
- expect(ft.toString(), '<T>(String) → List<T>');
- ft = ft.instantiate([typeProvider.intType]);
- expect(ft.toString(), '(String) → List<int>');
- expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
+ void test_nonConflictingImports_sameElement() {
+ AnalysisContext context = AnalysisContextFactory.contextWithCore();
+ String typeNameA = "A";
+ String typeNameB = "B";
+ ClassElement typeA = ElementFactory.classElement2(typeNameA);
+ ClassElement typeB = ElementFactory.classElement2(typeNameB);
+ LibraryElement importedLibrary = createTestLibrary(context, "imported");
+ (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
+ .types = <ClassElement>[typeA, typeB];
+ ImportElementImpl import1 = ElementFactory.importFor(importedLibrary, null);
+ ImportElementImpl import2 = ElementFactory.importFor(importedLibrary, null);
+ LibraryElementImpl importingLibrary =
+ createTestLibrary(context, "importing");
+ importingLibrary.imports = <ImportElement>[import1, import2];
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ Scope scope = new LibraryImportScope(importingLibrary, errorListener);
+ expect(scope.lookup(AstFactory.identifier3(typeNameA), importingLibrary),
+ typeA);
+ errorListener.assertNoErrors();
+ expect(scope.lookup(AstFactory.identifier3(typeNameB), importingLibrary),
+ typeB);
+ errorListener.assertNoErrors();
}
- void test_genericMethod_explicitTypeParams() {
- _resolveTestUnit(r'''
-class C<E> {
- List/*<T>*/ f/*<T>*/(E e) => null;
-}
-main() {
- C<String> cOfString;
- var x = cOfString.f/*<int>*/('hi');
-}
-''');
- MethodInvocation f = _findIdentifier('f/*<int>*/').parent;
- FunctionType ft = f.staticInvokeType;
- expect(ft.toString(), '(String) → List<int>');
- expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
-
- SimpleIdentifier x = _findIdentifier('x');
- expect(x.staticType,
- typeProvider.listType.instantiate([typeProvider.intType]));
+ void test_prefixedAndNonPrefixed() {
+ AnalysisContext context = AnalysisContextFactory.contextWithCore();
+ String typeName = "C";
+ String prefixName = "p";
+ ClassElement prefixedType = ElementFactory.classElement2(typeName);
+ ClassElement nonPrefixedType = ElementFactory.classElement2(typeName);
+ LibraryElement prefixedLibrary =
+ createTestLibrary(context, "import.prefixed");
+ (prefixedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
+ .types = <ClassElement>[prefixedType];
+ ImportElementImpl prefixedImport = ElementFactory.importFor(
+ prefixedLibrary, ElementFactory.prefix(prefixName));
+ LibraryElement nonPrefixedLibrary =
+ createTestLibrary(context, "import.nonPrefixed");
+ (nonPrefixedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
+ .types = <ClassElement>[nonPrefixedType];
+ ImportElementImpl nonPrefixedImport =
+ ElementFactory.importFor(nonPrefixedLibrary, null);
+ LibraryElementImpl importingLibrary =
+ createTestLibrary(context, "importing");
+ importingLibrary.imports = <ImportElement>[
+ prefixedImport,
+ nonPrefixedImport
+ ];
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ Scope scope = new LibraryImportScope(importingLibrary, errorListener);
+ Element prefixedElement = scope.lookup(
+ AstFactory.identifier5(prefixName, typeName), importingLibrary);
+ errorListener.assertNoErrors();
+ expect(prefixedElement, same(prefixedType));
+ Element nonPrefixedElement =
+ scope.lookup(AstFactory.identifier3(typeName), importingLibrary);
+ errorListener.assertNoErrors();
+ expect(nonPrefixedElement, same(nonPrefixedType));
}
-
- void test_genericMethod_functionExpressionInvocation_explicit() {
- _resolveTestUnit(r'''
-class C<E> {
- /*=T*/ f/*<T>*/(/*=T*/ e) => null;
- static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
- static final h = g;
}
-/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
-var topG = topF;
-void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
- var c = new C<int>();
- /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+@reflectiveTest
+class LibraryScopeTest extends ResolverTestCase {
+ void test_creation_empty() {
+ LibraryElement definingLibrary = createDefaultTestLibrary();
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ new LibraryScope(definingLibrary, errorListener);
+ }
- var lambdaCall = (/*<E>*/(/*=E*/ e) => e)/*<int>*/(3);
- var methodCall = (c.f)/*<int>*/(3);
- var staticCall = (C.g)/*<int>*/(3);
- var staticFieldCall = (C.h)/*<int>*/(3);
- var topFunCall = (topF)/*<int>*/(3);
- var topFieldCall = (topG)/*<int>*/(3);
- var localCall = (lf)/*<int>*/(3);
- var paramCall = (pf)/*<int>*/(3);
-}
-''');
- _expectIdentifierType('methodCall', "int");
- _expectIdentifierType('staticCall', "int");
- _expectIdentifierType('staticFieldCall', "int");
- _expectIdentifierType('topFunCall', "int");
- _expectIdentifierType('topFieldCall', "int");
- _expectIdentifierType('localCall', "int");
- _expectIdentifierType('paramCall', "int");
- _expectIdentifierType('lambdaCall', "int");
+ void test_creation_nonEmpty() {
+ AnalysisContext context = AnalysisContextFactory.contextWithCore();
+ String importedTypeName = "A";
+ ClassElement importedType =
+ new ClassElementImpl.forNode(AstFactory.identifier3(importedTypeName));
+ LibraryElement importedLibrary = createTestLibrary(context, "imported");
+ (importedLibrary.definingCompilationUnit as CompilationUnitElementImpl)
+ .types = <ClassElement>[importedType];
+ LibraryElementImpl definingLibrary =
+ createTestLibrary(context, "importing");
+ ImportElementImpl importElement = new ImportElementImpl(0);
+ importElement.importedLibrary = importedLibrary;
+ definingLibrary.imports = <ImportElement>[importElement];
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ Scope scope = new LibraryScope(definingLibrary, errorListener);
+ expect(
+ scope.lookup(AstFactory.identifier3(importedTypeName), definingLibrary),
+ importedType);
}
- void test_genericMethod_functionExpressionInvocation_inferred() {
- _resolveTestUnit(r'''
-class C<E> {
- /*=T*/ f/*<T>*/(/*=T*/ e) => null;
- static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
- static final h = g;
+ void test_getErrorListener() {
+ LibraryElement definingLibrary = createDefaultTestLibrary();
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ LibraryScope scope = new LibraryScope(definingLibrary, errorListener);
+ expect(scope.errorListener, errorListener);
+ }
}
-/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
-var topG = topF;
-void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
- var c = new C<int>();
- /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+@reflectiveTest
+class MemberMapTest {
+ /**
+ * The null type.
+ */
+ InterfaceType _nullType;
- var lambdaCall = (/*<E>*/(/*=E*/ e) => e)(3);
- var methodCall = (c.f)(3);
- var staticCall = (C.g)(3);
- var staticFieldCall = (C.h)(3);
- var topFunCall = (topF)(3);
- var topFieldCall = (topG)(3);
- var localCall = (lf)(3);
- var paramCall = (pf)(3);
-}
-''');
- _expectIdentifierType('methodCall', "int");
- _expectIdentifierType('staticCall', "int");
- _expectIdentifierType('staticFieldCall', "int");
- _expectIdentifierType('topFunCall', "int");
- _expectIdentifierType('topFieldCall', "int");
- _expectIdentifierType('localCall', "int");
- _expectIdentifierType('paramCall', "int");
- _expectIdentifierType('lambdaCall', "int");
+ void setUp() {
+ _nullType = new TestTypeProvider().nullType;
}
- void test_genericMethod_functionInvocation_explicit() {
- _resolveTestUnit(r'''
-class C<E> {
- /*=T*/ f/*<T>*/(/*=T*/ e) => null;
- static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
- static final h = g;
-}
-
-/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
-var topG = topF;
-void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
- var c = new C<int>();
- /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
- var methodCall = c.f/*<int>*/(3);
- var staticCall = C.g/*<int>*/(3);
- var staticFieldCall = C.h/*<int>*/(3);
- var topFunCall = topF/*<int>*/(3);
- var topFieldCall = topG/*<int>*/(3);
- var localCall = lf/*<int>*/(3);
- var paramCall = pf/*<int>*/(3);
-}
-''');
- _expectIdentifierType('methodCall', "int");
- _expectIdentifierType('staticCall', "int");
- _expectIdentifierType('staticFieldCall', "int");
- _expectIdentifierType('topFunCall', "int");
- _expectIdentifierType('topFieldCall', "int");
- _expectIdentifierType('localCall', "int");
- _expectIdentifierType('paramCall', "int");
+ void test_MemberMap_copyConstructor() {
+ MethodElement m1 = ElementFactory.methodElement("m1", _nullType);
+ MethodElement m2 = ElementFactory.methodElement("m2", _nullType);
+ MethodElement m3 = ElementFactory.methodElement("m3", _nullType);
+ MemberMap map = new MemberMap();
+ map.put(m1.name, m1);
+ map.put(m2.name, m2);
+ map.put(m3.name, m3);
+ MemberMap copy = new MemberMap.from(map);
+ expect(copy.size, map.size);
+ expect(copy.get(m1.name), m1);
+ expect(copy.get(m2.name), m2);
+ expect(copy.get(m3.name), m3);
}
- void test_genericMethod_functionInvocation_inferred() {
- _resolveTestUnit(r'''
-class C<E> {
- /*=T*/ f/*<T>*/(/*=T*/ e) => null;
- static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
- static final h = g;
-}
-
-/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
-var topG = topF;
-void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
- var c = new C<int>();
- /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
- var methodCall = c.f(3);
- var staticCall = C.g(3);
- var staticFieldCall = C.h(3);
- var topFunCall = topF(3);
- var topFieldCall = topG(3);
- var localCall = lf(3);
- var paramCall = pf(3);
-}
-''');
- _expectIdentifierType('methodCall', "int");
- _expectIdentifierType('staticCall', "int");
- _expectIdentifierType('staticFieldCall', "int");
- _expectIdentifierType('topFunCall', "int");
- _expectIdentifierType('topFieldCall', "int");
- _expectIdentifierType('localCall', "int");
- _expectIdentifierType('paramCall', "int");
+ void test_MemberMap_override() {
+ MethodElement m1 = ElementFactory.methodElement("m", _nullType);
+ MethodElement m2 = ElementFactory.methodElement("m", _nullType);
+ MemberMap map = new MemberMap();
+ map.put(m1.name, m1);
+ map.put(m2.name, m2);
+ expect(map.size, 1);
+ expect(map.get("m"), m2);
}
- void test_genericMethod_functionTypedParameter() {
- _resolveTestUnit(r'''
-class C<E> {
- List/*<T>*/ f/*<T>*/(/*=T*/ f(E e)) => null;
-}
-main() {
- C<String> cOfString;
-}
-''');
- _expectFunctionType('f', '<T>((E) → T) → List<T>',
- elementTypeParams: '[T]',
- typeParams: '[E]',
- typeArgs: '[E]',
- typeFormals: '[T]');
-
- SimpleIdentifier c = _findIdentifier('cOfString');
- FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
- expect(ft.toString(), '<T>((String) → T) → List<T>');
- ft = ft.instantiate([typeProvider.intType]);
- expect(ft.toString(), '((String) → int) → List<int>');
+ void test_MemberMap_put() {
+ MethodElement m1 = ElementFactory.methodElement("m1", _nullType);
+ MemberMap map = new MemberMap();
+ expect(map.size, 0);
+ map.put(m1.name, m1);
+ expect(map.size, 1);
+ expect(map.get("m1"), m1);
}
-
- void test_genericMethod_implicitDynamic() {
- // Regression test for:
- // https://github.com/dart-lang/sdk/issues/25100#issuecomment-162047588
- // These should not cause any hints or warnings.
- _resolveTestUnit(r'''
-class List<E> {
- /*=T*/ map/*<T>*/(/*=T*/ f(E e)) => null;
}
-void foo() {
- List list = null;
- list.map((e) => e);
- list.map((e) => 3);
-}''');
- _expectIdentifierType('map((e) => e);', '<T>((dynamic) → T) → T', isNull);
- _expectIdentifierType('map((e) => 3);', '<T>((dynamic) → T) → T', isNull);
- MethodInvocation m1 = _findIdentifier('map((e) => e);').parent;
- expect(m1.staticInvokeType.toString(), '((dynamic) → dynamic) → dynamic');
- MethodInvocation m2 = _findIdentifier('map((e) => 3);').parent;
- expect(m2.staticInvokeType.toString(), '((dynamic) → int) → int');
- }
+class Scope_EnclosedScopeTest_test_define_duplicate extends Scope {
+ GatheringErrorListener listener;
- void test_genericMethod_max_doubleDouble() {
- String code = r'''
-import 'dart:math';
-main() {
- var foo = max(1.0, 2.0);
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'double', isNull);
- }
+ Scope_EnclosedScopeTest_test_define_duplicate(this.listener) : super();
- void test_genericMethod_max_doubleDouble_prefixed() {
- String code = r'''
-import 'dart:math' as math;
-main() {
- var foo = math.max(1.0, 2.0);
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'double', isNull);
- }
+ @override
+ AnalysisErrorListener get errorListener => listener;
- void test_genericMethod_max_doubleInt() {
- String code = r'''
-import 'dart:math';
-main() {
- var foo = max(1.0, 2);
+ @override
+ Element internalLookup(Identifier identifier, String name,
+ LibraryElement referencingLibrary) =>
+ null;
}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'num', isNull);
- }
- void test_genericMethod_max_intDouble() {
- String code = r'''
-import 'dart:math';
-main() {
- var foo = max(1, 2.0);
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'num', isNull);
- }
+class Scope_EnclosedScopeTest_test_define_normal extends Scope {
+ GatheringErrorListener listener;
- void test_genericMethod_max_intInt() {
- String code = r'''
-import 'dart:math';
-main() {
- var foo = max(1, 2);
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'int', isNull);
- }
+ Scope_EnclosedScopeTest_test_define_normal(this.listener) : super();
- void test_genericMethod_nestedBound() {
- String code = r'''
-class Foo<T extends num> {
- void method/*<U extends T>*/(dynamic/*=U*/ u) {
- u.abs();
- }
-}
-''';
- // Just validate that there is no warning on the call to `.abs()`.
- _resolveTestUnit(code);
- }
+ @override
+ AnalysisErrorListener get errorListener => listener;
- void test_genericMethod_nestedCapture() {
- _resolveTestUnit(r'''
-class C<T> {
- /*=T*/ f/*<S>*/(/*=S*/ x) {
- new C<S>().f/*<int>*/(3);
- new C<S>().f; // tear-off
- return null;
- }
+ @override
+ Element internalLookup(Identifier identifier, String name,
+ LibraryElement referencingLibrary) =>
+ null;
}
-''');
- MethodInvocation f = _findIdentifier('f/*<int>*/(3);').parent;
- expect(f.staticInvokeType.toString(), '(int) → S');
- FunctionType ft = f.staticInvokeType;
- expect('${ft.typeArguments}/${ft.typeParameters}', '[S, int]/[T, S]');
- _expectIdentifierType('f;', '<S₀>(S₀) → S');
- }
-
- void test_genericMethod_nestedFunctions() {
- _resolveTestUnit(r'''
-/*=S*/ f/*<S>*/(/*=S*/ x) {
- g/*<S>*/(/*=S*/ x) => f;
- return null;
-}
-''');
- _expectIdentifierType('f', '<S>(S) → S');
- _expectIdentifierType('g', '<S>(S) → dynamic');
+@reflectiveTest
+class ScopeTest extends ResolverTestCase {
+ void test_define_duplicate() {
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ ScopeTest_TestScope scope = new ScopeTest_TestScope(errorListener);
+ VariableElement element1 =
+ ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
+ VariableElement element2 =
+ ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
+ scope.define(element1);
+ scope.define(element2);
+ errorListener.assertErrorsWithSeverities([ErrorSeverity.ERROR]);
}
- void test_genericMethod_override() {
- _resolveTestUnit(r'''
-class C {
- /*=T*/ f/*<T>*/(/*=T*/ x) => null;
-}
-class D extends C {
- /*=T*/ f/*<T>*/(/*=T*/ x) => null; // from D
-}
-''');
- _expectFunctionType('f/*<T>*/(/*=T*/ x) => null; // from D', '<T>(T) → T',
- elementTypeParams: '[T]', typeFormals: '[T]');
- SimpleIdentifier f =
- _findIdentifier('f/*<T>*/(/*=T*/ x) => null; // from D');
- MethodElementImpl e = f.staticElement;
- FunctionType ft = e.type.instantiate([typeProvider.stringType]);
- expect(ft.toString(), '(String) → String');
+ void test_define_normal() {
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ ScopeTest_TestScope scope = new ScopeTest_TestScope(errorListener);
+ VariableElement element1 =
+ ElementFactory.localVariableElement(AstFactory.identifier3("v1"));
+ VariableElement element2 =
+ ElementFactory.localVariableElement(AstFactory.identifier3("v2"));
+ scope.define(element1);
+ scope.define(element2);
+ errorListener.assertNoErrors();
}
- void test_genericMethod_override_bounds() {
- _resolveTestUnit(r'''
-class A {}
-class B extends A {}
-class C {
- /*=T*/ f/*<T extends B>*/(/*=T*/ x) => null;
-}
-class D extends C {
- /*=T*/ f/*<T extends A>*/(/*=T*/ x) => null;
-}
-''');
+ void test_getErrorListener() {
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ ScopeTest_TestScope scope = new ScopeTest_TestScope(errorListener);
+ expect(scope.errorListener, errorListener);
}
- void test_genericMethod_override_invalidReturnType() {
- Source source = addSource(r'''
-class C {
- Iterable/*<T>*/ f/*<T>*/(/*=T*/ x) => null;
-}
-class D extends C {
- String f/*<S>*/(/*=S*/ x) => null;
-}''');
- // TODO(jmesserly): we can't use assertErrors because STRONG_MODE_* errors
- // from CodeChecker don't have working equality.
- List<AnalysisError> errors = analysisContext2.computeErrors(source);
-
- // Sort errors by name.
- errors.sort((AnalysisError e1, AnalysisError e2) =>
- e1.errorCode.name.compareTo(e2.errorCode.name));
-
- expect(errors.map((e) => e.errorCode.name), [
- 'INVALID_METHOD_OVERRIDE_RETURN_TYPE',
- 'STRONG_MODE_INVALID_METHOD_OVERRIDE'
- ]);
- expect(errors[0].message, contains('Iterable<S>'),
- reason: 'errors should be in terms of the type parameters '
- 'at the error location');
- verify([source]);
+ void test_isPrivateName_nonPrivate() {
+ expect(Scope.isPrivateName("Public"), isFalse);
}
- void test_genericMethod_override_invalidTypeParamBounds() {
- Source source = addSource(r'''
-class A {}
-class B extends A {}
-class C {
- /*=T*/ f/*<T extends A>*/(/*=T*/ x) => null;
-}
-class D extends C {
- /*=T*/ f/*<T extends B>*/(/*=T*/ x) => null;
-}''');
- // TODO(jmesserly): this is modified code from assertErrors, which we can't
- // use directly because STRONG_MODE_* errors don't have working equality.
- List<AnalysisError> errors = analysisContext2.computeErrors(source);
- List errorNames = errors.map((e) => e.errorCode.name).toList();
- expect(errorNames, hasLength(2));
- expect(errorNames, contains('STRONG_MODE_INVALID_METHOD_OVERRIDE'));
- expect(
- errorNames, contains('INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND'));
- verify([source]);
+ void test_isPrivateName_private() {
+ expect(Scope.isPrivateName("_Private"), isTrue);
}
-
- void test_genericMethod_override_invalidTypeParamCount() {
- Source source = addSource(r'''
-class C {
- /*=T*/ f/*<T>*/(/*=T*/ x) => null;
}
-class D extends C {
- /*=S*/ f/*<T, S>*/(/*=T*/ x) => null;
-}''');
- // TODO(jmesserly): we can't use assertErrors because STRONG_MODE_* errors
- // from CodeChecker don't have working equality.
- List<AnalysisError> errors = analysisContext2.computeErrors(source);
- expect(errors.map((e) => e.errorCode.name), [
- 'STRONG_MODE_INVALID_METHOD_OVERRIDE',
- 'INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS'
- ]);
- verify([source]);
- }
- void test_genericMethod_propagatedType_promotion() {
- // Regression test for:
- // https://github.com/dart-lang/sdk/issues/25340
+/**
+ * A non-abstract subclass that can be used for testing purposes.
+ */
+class ScopeTest_TestScope extends Scope {
+ /**
+ * The listener that is to be informed when an error is encountered.
+ */
+ final AnalysisErrorListener errorListener;
- // Note, after https://github.com/dart-lang/sdk/issues/25486 the original
- // example won't work, as we now compute a static type and therefore discard
- // the propagated type. So a new test was created that doesn't run under
- // strong mode.
- _resolveTestUnit(r'''
-abstract class Iter {
- List/*<S>*/ map/*<S>*/(/*=S*/ f(x));
-}
-class C {}
-C toSpan(dynamic element) {
- if (element is Iter) {
- var y = element.map(toSpan);
- }
- return null;
-}''');
- _expectIdentifierType('y = ', 'List<C>', isNull);
- }
+ ScopeTest_TestScope(this.errorListener);
- void test_genericMethod_tearoff() {
- _resolveTestUnit(r'''
-class C<E> {
- /*=T*/ f/*<T>*/(E e) => null;
- static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
- static final h = g;
+ @override
+ Element internalLookup(Identifier identifier, String name,
+ LibraryElement referencingLibrary) =>
+ localLookup(name, referencingLibrary);
}
-/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
-var topG = topF;
-void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
- var c = new C<int>();
- /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
- var methodTearOff = c.f;
- var staticTearOff = C.g;
- var staticFieldTearOff = C.h;
- var topFunTearOff = topF;
- var topFieldTearOff = topG;
- var localTearOff = lf;
- var paramTearOff = pf;
+class SourceContainer_ChangeSetTest_test_toString implements SourceContainer {
+ @override
+ bool contains(Source source) => false;
}
-''');
- _expectIdentifierType('methodTearOff', "<T>(int) → T");
- _expectIdentifierType('staticTearOff', "<T>(T) → T");
- _expectIdentifierType('staticFieldTearOff', "<T>(T) → T");
- _expectIdentifierType('topFunTearOff', "<T>(T) → T");
- _expectIdentifierType('topFieldTearOff', "<T>(T) → T");
- _expectIdentifierType('localTearOff', "<T>(T) → T");
- _expectIdentifierType('paramTearOff', "<T>(T) → T");
- }
- void test_genericMethod_then() {
- String code = r'''
-import 'dart:async';
-String toString(int x) => x.toString();
-main() {
- Future<int> bar = null;
- var foo = bar.then(toString);
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'Future<String>', isNull);
- }
+/**
+ * Instances of the class `StaticTypeVerifier` verify that all of the nodes in an AST
+ * structure that should have a static type associated with them do have a static type.
+ */
+class StaticTypeVerifier extends GeneralizingAstVisitor<Object> {
+ /**
+ * A list containing all of the AST Expression nodes that were not resolved.
+ */
+ List<Expression> _unresolvedExpressions = new List<Expression>();
- void test_genericMethod_then_prefixed() {
- String code = r'''
-import 'dart:async' as async;
-String toString(int x) => x.toString();
-main() {
- async.Future<int> bar = null;
- var foo = bar.then(toString);
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'Future<String>', isNull);
- }
+ /**
+ * A list containing all of the AST Expression nodes for which a propagated type was computed but
+ * where that type was not more specific than the static type.
+ */
+ List<Expression> _invalidlyPropagatedExpressions = new List<Expression>();
- void test_genericMethod_then_propagatedType() {
- // Regression test for https://github.com/dart-lang/sdk/issues/25482.
- String code = r'''
-import 'dart:async';
-void main() {
- Future<String> p;
- var foo = p.then((r) => new Future<String>.value(3));
-}
-''';
- // This should produce no hints or warnings.
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'Future<String>', isNull);
- }
+ /**
+ * A list containing all of the AST TypeName nodes that were not resolved.
+ */
+ List<TypeName> _unresolvedTypes = new List<TypeName>();
- void test_implicitBounds() {
- String code = r'''
-class A<T> {}
+ /**
+ * Counter for the number of Expression nodes visited that are resolved.
+ */
+ int _resolvedExpressionCount = 0;
-class B<T extends num> {}
+ /**
+ * Counter for the number of Expression nodes visited that have propagated type information.
+ */
+ int _propagatedExpressionCount = 0;
-class C<S extends int, T extends B<S>, U extends B> {}
+ /**
+ * Counter for the number of TypeName nodes visited that are resolved.
+ */
+ int _resolvedTypeCount = 0;
-void test() {
-//
- A ai;
- B bi;
- C ci;
- var aa = new A();
- var bb = new B();
- var cc = new C();
-}
-''';
- _resolveTestUnit(code);
- _expectIdentifierType('ai', "A<dynamic>");
- _expectIdentifierType('bi', "B<num>");
- _expectIdentifierType('ci', "C<int, B<int>, B<num>>");
- _expectIdentifierType('aa', "A<dynamic>");
- _expectIdentifierType('bb', "B<num>");
- _expectIdentifierType('cc', "C<int, B<int>, B<num>>");
+ /**
+ * Assert that all of the visited nodes have a static type associated with them.
+ */
+ void assertResolved() {
+ if (!_unresolvedExpressions.isEmpty || !_unresolvedTypes.isEmpty) {
+ StringBuffer buffer = new StringBuffer();
+ int unresolvedTypeCount = _unresolvedTypes.length;
+ if (unresolvedTypeCount > 0) {
+ buffer.write("Failed to resolve ");
+ buffer.write(unresolvedTypeCount);
+ buffer.write(" of ");
+ buffer.write(_resolvedTypeCount + unresolvedTypeCount);
+ buffer.writeln(" type names:");
+ for (TypeName identifier in _unresolvedTypes) {
+ buffer.write(" ");
+ buffer.write(identifier.toString());
+ buffer.write(" (");
+ buffer.write(_getFileName(identifier));
+ buffer.write(" : ");
+ buffer.write(identifier.offset);
+ buffer.writeln(")");
+ }
+ }
+ int unresolvedExpressionCount = _unresolvedExpressions.length;
+ if (unresolvedExpressionCount > 0) {
+ buffer.writeln("Failed to resolve ");
+ buffer.write(unresolvedExpressionCount);
+ buffer.write(" of ");
+ buffer.write(_resolvedExpressionCount + unresolvedExpressionCount);
+ buffer.writeln(" expressions:");
+ for (Expression expression in _unresolvedExpressions) {
+ buffer.write(" ");
+ buffer.write(expression.toString());
+ buffer.write(" (");
+ buffer.write(_getFileName(expression));
+ buffer.write(" : ");
+ buffer.write(expression.offset);
+ buffer.writeln(")");
+ }
+ }
+ int invalidlyPropagatedExpressionCount =
+ _invalidlyPropagatedExpressions.length;
+ if (invalidlyPropagatedExpressionCount > 0) {
+ buffer.writeln("Incorrectly propagated ");
+ buffer.write(invalidlyPropagatedExpressionCount);
+ buffer.write(" of ");
+ buffer.write(_propagatedExpressionCount);
+ buffer.writeln(" expressions:");
+ for (Expression expression in _invalidlyPropagatedExpressions) {
+ buffer.write(" ");
+ buffer.write(expression.toString());
+ buffer.write(" [");
+ buffer.write(expression.staticType.displayName);
+ buffer.write(", ");
+ buffer.write(expression.propagatedType.displayName);
+ buffer.writeln("]");
+ buffer.write(" ");
+ buffer.write(_getFileName(expression));
+ buffer.write(" : ");
+ buffer.write(expression.offset);
+ buffer.writeln(")");
+ }
+ }
+ fail(buffer.toString());
+ }
}
- void test_setterWithDynamicTypeIsError() {
- Source source = addSource(r'''
-class A {
- dynamic set f(String s) => null;
-}
-dynamic set g(int x) => null;
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
- StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
- ]);
- verify([source]);
- }
+ @override
+ Object visitBreakStatement(BreakStatement node) => null;
- void test_setterWithExplicitVoidType_returningVoid() {
- Source source = addSource(r'''
-void returnsVoid() {}
-class A {
- void set f(String s) => returnsVoid();
-}
-void set g(int x) => returnsVoid();
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
+ @override
+ Object visitCommentReference(CommentReference node) => null;
- void test_setterWithNoVoidType() {
- Source source = addSource(r'''
-class A {
- set f(String s) {
- return '42';
- }
-}
-set g(int x) => 42;
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
- StaticTypeWarningCode.RETURN_OF_INVALID_TYPE
- ]);
- verify([source]);
- }
+ @override
+ Object visitContinueStatement(ContinueStatement node) => null;
- void test_setterWithNoVoidType_returningVoid() {
- Source source = addSource(r'''
-void returnsVoid() {}
-class A {
- set f(String s) => returnsVoid();
-}
-set g(int x) => returnsVoid();
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
+ @override
+ Object visitExportDirective(ExportDirective node) => null;
- void test_setterWithOtherTypeIsError() {
- Source source = addSource(r'''
-class A {
- String set f(String s) => null;
-}
-Object set g(x) => null;
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
- StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
- ]);
- verify([source]);
+ @override
+ Object visitExpression(Expression node) {
+ node.visitChildren(this);
+ DartType staticType = node.staticType;
+ if (staticType == null) {
+ _unresolvedExpressions.add(node);
+ } else {
+ _resolvedExpressionCount++;
+ DartType propagatedType = node.propagatedType;
+ if (propagatedType != null) {
+ _propagatedExpressionCount++;
+ if (!propagatedType.isMoreSpecificThan(staticType)) {
+ _invalidlyPropagatedExpressions.add(node);
+ }
+ }
+ }
+ return null;
}
- void test_ternaryOperator_null_left() {
- String code = r'''
-main() {
- var foo = (true) ? null : 3;
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'int', isNull);
- }
+ @override
+ Object visitImportDirective(ImportDirective node) => null;
- void test_ternaryOperator_null_right() {
- String code = r'''
-main() {
- var foo = (true) ? 3 : null;
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'int', isNull);
- }
-}
+ @override
+ Object visitLabel(Label node) => null;
-@reflectiveTest
-class StrongModeTypePropagationTest extends ResolverTestCase {
@override
- void setUp() {
- super.setUp();
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.strongMode = true;
- resetWithOptions(options);
- }
+ Object visitLibraryIdentifier(LibraryIdentifier node) => null;
- void test_foreachInference_dynamic_disabled() {
- String code = r'''
-main() {
- var list = <int>[];
- for (dynamic v in list) {
- v; // marker
- }
-}''';
- _assertPropagatedIterationType(
- code, typeProvider.dynamicType, typeProvider.intType);
- _assertTypeOfMarkedExpression(
- code, typeProvider.dynamicType, typeProvider.intType);
+ @override
+ Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+ // In cases where we have a prefixed identifier where the prefix is dynamic,
+ // we don't want to assert that the node will have a type.
+ if (node.staticType == null && node.prefix.staticType.isDynamic) {
+ return null;
+ }
+ return super.visitPrefixedIdentifier(node);
}
- void test_foreachInference_reusedVar_disabled() {
- String code = r'''
-main() {
- var list = <int>[];
- var v;
- for (v in list) {
- v; // marker
- }
-}''';
- _assertPropagatedIterationType(
- code, typeProvider.dynamicType, typeProvider.intType);
- _assertTypeOfMarkedExpression(
- code, typeProvider.dynamicType, typeProvider.intType);
+ @override
+ Object visitSimpleIdentifier(SimpleIdentifier node) {
+ // In cases where identifiers are being used for something other than an
+ // expressions, then they can be ignored.
+ AstNode parent = node.parent;
+ if (parent is MethodInvocation && identical(node, parent.methodName)) {
+ return null;
+ } else if (parent is RedirectingConstructorInvocation &&
+ identical(node, parent.constructorName)) {
+ return null;
+ } else if (parent is SuperConstructorInvocation &&
+ identical(node, parent.constructorName)) {
+ return null;
+ } else if (parent is ConstructorName && identical(node, parent.name)) {
+ return null;
+ } else if (parent is ConstructorFieldInitializer &&
+ identical(node, parent.fieldName)) {
+ return null;
+ } else if (node.staticElement is PrefixElement) {
+ // Prefixes don't have a type.
+ return null;
+ }
+ return super.visitSimpleIdentifier(node);
}
- void test_foreachInference_var() {
- String code = r'''
-main() {
- var list = <int>[];
- for (var v in list) {
- v; // marker
+ @override
+ Object visitTypeName(TypeName node) {
+ // Note: do not visit children from this node, the child SimpleIdentifier in
+ // TypeName (i.e. "String") does not have a static type defined.
+ if (node.type == null) {
+ _unresolvedTypes.add(node);
+ } else {
+ _resolvedTypeCount++;
+ }
+ return null;
}
-}''';
- _assertPropagatedIterationType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+
+ String _getFileName(AstNode node) {
+ // TODO (jwren) there are two copies of this method, one here and one in
+ // ResolutionVerifier, they should be resolved into a single method
+ if (node != null) {
+ AstNode root = node.root;
+ if (root is CompilationUnit) {
+ CompilationUnit rootCU = root;
+ if (rootCU.element != null) {
+ return rootCU.element.source.fullName;
+ } else {
+ return "<unknown file- CompilationUnit.getElement() returned null>";
+ }
+ } else {
+ return "<unknown file- CompilationUnit.getRoot() is not a CompilationUnit>";
+ }
+ }
+ return "<unknown file- ASTNode is null>";
}
+}
- void test_foreachInference_var_iterable() {
- String code = r'''
-main() {
- Iterable<int> list = <int>[];
- for (var v in list) {
- v; // marker
+/**
+ * The class `StrictModeTest` contains tests to ensure that the correct errors and warnings
+ * are reported when the analysis engine is run in strict mode.
+ */
+@reflectiveTest
+class StrictModeTest extends ResolverTestCase {
+ void fail_for() {
+ Source source = addSource(r'''
+int f(List<int> list) {
+ num sum = 0;
+ for (num i = 0; i < list.length; i++) {
+ sum += list[i];
}
-}''';
- _assertPropagatedIterationType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
- void test_foreachInference_var_stream() {
- String code = r'''
-import 'dart:async';
-main() async {
- Stream<int> stream = null;
- await for (var v in stream) {
- v; // marker
- }
-}''';
- _assertPropagatedIterationType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ @override
+ void setUp() {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.hint = false;
+ resetWithOptions(options);
}
- void test_localVariableInference_bottom_disabled() {
- String code = r'''
-main() {
- var v = null;
- v; // marker
-}''';
- _assertPropagatedAssignedType(code, typeProvider.dynamicType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.dynamicType, null);
+ void test_assert_is() {
+ Source source = addSource(r'''
+int f(num n) {
+ assert (n is int);
+ return n & 0x0F;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
- void test_localVariableInference_constant() {
- String code = r'''
-main() {
- var v = 3;
- v; // marker
-}''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ void test_conditional_and_is() {
+ Source source = addSource(r'''
+int f(num n) {
+ return (n is int && n > 0) ? n & 0x0F : 0;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
}
- void test_localVariableInference_declaredType_disabled() {
- String code = r'''
-main() {
- dynamic v = 3;
- v; // marker
-}''';
- _assertPropagatedAssignedType(
- code, typeProvider.dynamicType, typeProvider.intType);
- _assertTypeOfMarkedExpression(
- code, typeProvider.dynamicType, typeProvider.intType);
+ void test_conditional_is() {
+ Source source = addSource(r'''
+int f(num n) {
+ return (n is int) ? n & 0x0F : 0;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
}
- void test_localVariableInference_noInitializer_disabled() {
- String code = r'''
-main() {
- var v;
- v = 3;
- v; // marker
-}''';
- _assertPropagatedAssignedType(
- code, typeProvider.dynamicType, typeProvider.intType);
- _assertTypeOfMarkedExpression(
- code, typeProvider.dynamicType, typeProvider.intType);
+ void test_conditional_isNot() {
+ Source source = addSource(r'''
+int f(num n) {
+ return (n is! int) ? 0 : n & 0x0F;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
- void test_localVariableInference_transitive_field_inferred_lexical() {
- String code = r'''
-class A {
- final x = 3;
- f() {
- var v = x;
- return v; // marker
- }
-}
-main() {
-}
-''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ void test_conditional_or_is() {
+ Source source = addSource(r'''
+int f(num n) {
+ return (n is! int || n < 0) ? 0 : n & 0x0F;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
- void test_localVariableInference_transitive_field_inferred_reversed() {
- String code = r'''
-class A {
- f() {
- var v = x;
- return v; // marker
+ void test_forEach() {
+ Source source = addSource(r'''
+int f(List<int> list) {
+ num sum = 0;
+ for (num n in list) {
+ sum += n & 0x0F;
}
- final x = 3;
-}
-main() {
-}
-''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
- void test_localVariableInference_transitive_field_lexical() {
- String code = r'''
-class A {
- int x = 3;
- f() {
- var v = x;
- return v; // marker
+ void test_if_and_is() {
+ Source source = addSource(r'''
+int f(num n) {
+ if (n is int && n > 0) {
+ return n & 0x0F;
}
-}
-main() {
-}
-''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ return 0;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
}
- void test_localVariableInference_transitive_field_reversed() {
- String code = r'''
-class A {
- f() {
- var v = x;
- return v; // marker
+ void test_if_is() {
+ Source source = addSource(r'''
+int f(num n) {
+ if (n is int) {
+ return n & 0x0F;
}
- int x = 3;
-}
-main() {
-}
-''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ return 0;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
}
- void test_localVariableInference_transitive_list_local() {
- String code = r'''
-main() {
- var x = <int>[3];
- var v = x[0];
- v; // marker
-}''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ void test_if_isNot() {
+ Source source = addSource(r'''
+int f(num n) {
+ if (n is! int) {
+ return 0;
+ } else {
+ return n & 0x0F;
}
-
- void test_localVariableInference_transitive_local() {
- String code = r'''
-main() {
- var x = 3;
- var v = x;
- v; // marker
-}''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
- void test_localVariableInference_transitive_toplevel_inferred_lexical() {
- String code = r'''
-final x = 3;
-main() {
- var v = x;
- v; // marker
-}
-''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ void test_if_isNot_abrupt() {
+ Source source = addSource(r'''
+int f(num n) {
+ if (n is! int) {
+ return 0;
}
-
- void test_localVariableInference_transitive_toplevel_inferred_reversed() {
- String code = r'''
-main() {
- var v = x;
- v; // marker
-}
-final x = 3;
-''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ return n & 0x0F;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
- void test_localVariableInference_transitive_toplevel_lexical() {
- String code = r'''
-int x = 3;
-main() {
- var v = x;
- v; // marker
-}
-''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ void test_if_or_is() {
+ Source source = addSource(r'''
+int f(num n) {
+ if (n is! int || n < 0) {
+ return 0;
+ } else {
+ return n & 0x0F;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
- void test_localVariableInference_transitive_toplevel_reversed() {
- String code = r'''
-main() {
- var v = x;
- v; // marker
-}
-int x = 3;
-''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ void test_localVar() {
+ Source source = addSource(r'''
+int f() {
+ num n = 1234;
+ return n & 0x0F;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
}
@@ -14820,23 +1139,6 @@ class SubtypeManagerTest {
}
}
-class TestPackageUriResolver extends UriResolver {
- Map<Uri, Source> sourceMap = new HashMap<Uri, Source>();
-
- TestPackageUriResolver(Map<String, String> map) {
- map.forEach((String uri, String contents) {
- sourceMap[Uri.parse(uri)] =
- new StringSource(contents, '/test_pkg_source.dart');
- });
- }
-
- @override
- Source resolveAbsolute(Uri uri, [Uri actualUri]) => sourceMap[uri];
-
- @override
- Uri restoreAbsolute(Source source) => throw new UnimplementedError();
-}
-
@reflectiveTest
class TypeOverrideManagerTest extends EngineTestCase {
void test_exitScope_noScopes() {
@@ -14912,7 +1214,7 @@ class TypeOverrideManagerTest extends EngineTestCase {
class TypePropagationTest extends ResolverTestCase {
void fail_mergePropagatedTypesAtJoinPoint_1() {
// https://code.google.com/p/dart/issues/detail?id=19929
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f1(x) {
var y = [];
@@ -14931,7 +1233,7 @@ f1(x) {
void fail_mergePropagatedTypesAtJoinPoint_2() {
// https://code.google.com/p/dart/issues/detail?id=19929
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f2(x) {
var y = [];
@@ -14949,7 +1251,7 @@ f2(x) {
void fail_mergePropagatedTypesAtJoinPoint_3() {
// https://code.google.com/p/dart/issues/detail?id=19929
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f4(x) {
var y = [];
@@ -14969,7 +1271,7 @@ f4(x) {
void fail_mergePropagatedTypesAtJoinPoint_5() {
// https://code.google.com/p/dart/issues/detail?id=19929
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f6(x,y) {
var z = [];
@@ -15009,7 +1311,7 @@ f() {
x; // marker
}
}''';
- DartType t = _findMarkedIdentifier(code, "; // marker").propagatedType;
+ DartType t = findMarkedIdentifier(code, "; // marker").propagatedType;
expect(typeProvider.intType.isSubtypeOf(t), isTrue);
expect(typeProvider.stringType.isSubtypeOf(t), isTrue);
}
@@ -15041,7 +1343,7 @@ f() {
}
}
}''';
- DartType t = _findMarkedIdentifier(code, "; // marker").propagatedType;
+ DartType t = findMarkedIdentifier(code, "; // marker").propagatedType;
expect(typeProvider.intType.isSubtypeOf(t), isTrue);
expect(typeProvider.stringType.isSubtypeOf(t), isTrue);
}
@@ -15052,7 +1354,7 @@ f() {
main() {
var v = (() {return 42;})();
}''';
- _assertPropagatedAssignedType(
+ assertPropagatedAssignedType(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -15206,7 +1508,7 @@ import 'lib.dart';
f(A a) {
return a.v; // marker
}''';
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -15224,7 +1526,7 @@ class B extends A {
return v; // marker
}
}''';
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -15243,7 +1545,7 @@ f(p) {
return p.v; // marker
}
}''';
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -15255,7 +1557,7 @@ class A {
v; // marker
}
}''';
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -15271,7 +1573,7 @@ import 'lib.dart';
f() {
return A.V; // marker
}''';
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -15282,7 +1584,7 @@ import 'lib.dart' as p;
f() {
var v2 = p.V; // marker prefixed
}''';
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -15293,7 +1595,7 @@ import 'lib.dart';
f() {
return V; // marker simple
}''';
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -15730,7 +2032,7 @@ main() {
helper.max(10, 10); // marker
}''';
SimpleIdentifier methodName =
- _findMarkedIdentifier(code, "(10, 10); // marker");
+ findMarkedIdentifier(code, "(10, 10); // marker");
MethodInvocation methodInvoke = methodName.parent;
expect(methodInvoke.methodName.staticElement, isNotNull);
expect(methodInvoke.methodName.propagatedElement, isNull);
@@ -16096,8 +2398,8 @@ f() {
return a; // marker
}
}''';
- DartType tB = _findMarkedIdentifier(code, "; // B").propagatedType;
- _assertTypeOfMarkedExpression(code, null, tB);
+ DartType tB = findMarkedIdentifier(code, "; // B").propagatedType;
+ assertTypeOfMarkedExpression(code, null, tB);
}
void test_issue20904BuggyTypePromotionAtIfJoin_6() {
@@ -16116,8 +2418,8 @@ f() {
return b; // marker
}
}''';
- DartType tB = _findMarkedIdentifier(code, "; // B").propagatedType;
- _assertTypeOfMarkedExpression(code, null, tB);
+ DartType tB = findMarkedIdentifier(code, "; // B").propagatedType;
+ assertTypeOfMarkedExpression(code, null, tB);
}
void test_listLiteral_different() {
@@ -16218,17 +2520,17 @@ main() {
return v;
}''';
{
- SimpleIdentifier identifier = _findMarkedIdentifier(code, "v;");
+ SimpleIdentifier identifier = findMarkedIdentifier(code, "v;");
expect(identifier.propagatedType, null);
}
{
- SimpleIdentifier identifier = _findMarkedIdentifier(code, "v = '';");
+ SimpleIdentifier identifier = findMarkedIdentifier(code, "v = '';");
expect(identifier.propagatedType, typeProvider.stringType);
}
}
void test_mergePropagatedTypes_afterIfThen_same() {
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
main() {
var v = 1;
@@ -16242,7 +2544,7 @@ main() {
}
void test_mergePropagatedTypes_afterIfThenElse_different() {
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
main() {
var v = 1;
@@ -16258,7 +2560,7 @@ main() {
}
void test_mergePropagatedTypes_afterIfThenElse_same() {
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
main() {
var v = 1;
@@ -16275,7 +2577,7 @@ main() {
void test_mergePropagatedTypesAtJoinPoint_4() {
// https://code.google.com/p/dart/issues/detail?id=19929
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f5(x) {
var y = [];
@@ -16336,7 +2638,7 @@ main() {
helper.$name; // marker
}''';
- SimpleIdentifier id = _findMarkedIdentifier(code, "; // marker");
+ SimpleIdentifier id = findMarkedIdentifier(code, "; // marker");
PrefixedIdentifier prefixedId = id.parent;
expect(id.staticType, typeProvider.dynamicType);
expect(prefixedId.staticType, typeProvider.dynamicType);
@@ -16350,7 +2652,7 @@ main() {
$name; // marker
}''';
- SimpleIdentifier getter = _findMarkedIdentifier(code, "; // marker");
+ SimpleIdentifier getter = findMarkedIdentifier(code, "; // marker");
expect(getter.staticType, typeProvider.dynamicType);
}
@@ -16361,7 +2663,7 @@ main() {
dynamic obj;
obj..$name..$name; // marker
}''';
- PropertyAccess access = _findMarkedIdentifier(code, "; // marker").parent;
+ PropertyAccess access = findMarkedIdentifier(code, "; // marker").parent;
expect(access.staticType, typeProvider.dynamicType);
expect(access.realTarget.staticType, typeProvider.dynamicType);
}
@@ -16379,7 +2681,7 @@ import 'helper.dart' as helper;
main() {
helper.$name(); // marker
}''';
- SimpleIdentifier methodName = _findMarkedIdentifier(code, "(); // marker");
+ SimpleIdentifier methodName = findMarkedIdentifier(code, "(); // marker");
MethodInvocation methodInvoke = methodName.parent;
expect(methodName.staticType, typeProvider.dynamicType);
expect(methodInvoke.staticType, typeProvider.dynamicType);
@@ -16392,10 +2694,10 @@ main() {
dynamic $name = () => null;
$name(); // marker
}''';
- SimpleIdentifier identifier = _findMarkedIdentifier(code, "$name = ");
+ SimpleIdentifier identifier = findMarkedIdentifier(code, "$name = ");
expect(identifier.staticType, typeProvider.dynamicType);
- SimpleIdentifier methodName = _findMarkedIdentifier(code, "(); // marker");
+ SimpleIdentifier methodName = findMarkedIdentifier(code, "(); // marker");
MethodInvocation methodInvoke = methodName.parent;
expect(methodName.staticType, typeProvider.dynamicType);
expect(methodInvoke.staticType, typeProvider.dynamicType);
@@ -16408,7 +2710,7 @@ main() {
dynamic obj;
obj..$name()..$name(); // marker
}''';
- SimpleIdentifier methodName = _findMarkedIdentifier(code, "(); // marker");
+ SimpleIdentifier methodName = findMarkedIdentifier(code, "(); // marker");
MethodInvocation methodInvoke = methodName.parent;
expect(methodInvoke.staticType, typeProvider.dynamicType);
@@ -16422,7 +2724,7 @@ main() {
// static type of [bool] for [==] comparison and the implementation
// was already consistent with the spec there. But, it's another
// [Object] method, so it's included here.
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f1(x) {
var v = (x == x);
@@ -16434,7 +2736,7 @@ f1(x) {
void test_objectMethodOnDynamicExpression_hashCode() {
// https://code.google.com/p/dart/issues/detail?id=20342
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f1(x) {
var v = x.hashCode;
@@ -16446,7 +2748,7 @@ f1(x) {
void test_objectMethodOnDynamicExpression_runtimeType() {
// https://code.google.com/p/dart/issues/detail?id=20342
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f1(x) {
var v = x.runtimeType;
@@ -16458,7 +2760,7 @@ f1(x) {
void test_objectMethodOnDynamicExpression_toString() {
// https://code.google.com/p/dart/issues/detail?id=20342
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f1(x) {
var v = x.toString();
@@ -16474,7 +2776,7 @@ main() {
f() => 42;
var v = f();
}''';
- _assertPropagatedAssignedType(
+ assertPropagatedAssignedType(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -17338,70 +3640,6 @@ class TypeResolverVisitorTest {
}
}
-class _AnalysisContextFactory_initContextWithCore
- extends DirectoryBasedDartSdk {
- final bool enableAsync;
- _AnalysisContextFactory_initContextWithCore(JavaFile arg0,
- {this.enableAsync: true})
- : super(arg0);
-
- @override
- LibraryMap initialLibraryMap(bool useDart2jsPaths) {
- LibraryMap map = new LibraryMap();
- if (enableAsync) {
- _addLibrary(map, DartSdk.DART_ASYNC, false, "async.dart");
- }
- _addLibrary(map, DartSdk.DART_CORE, false, "core.dart");
- _addLibrary(map, DartSdk.DART_HTML, false, "html_dartium.dart");
- _addLibrary(map, AnalysisContextFactory._DART_MATH, false, "math.dart");
- _addLibrary(map, AnalysisContextFactory._DART_INTERCEPTORS, true,
- "_interceptors.dart");
- _addLibrary(
- map, AnalysisContextFactory._DART_JS_HELPER, true, "_js_helper.dart");
- return map;
- }
-
- void _addLibrary(LibraryMap map, String uri, bool isInternal, String path) {
- SdkLibraryImpl library = new SdkLibraryImpl(uri);
- if (isInternal) {
- library.category = "Internal";
- }
- library.path = path;
- map.setLibrary(uri, library);
- }
-}
-
-class _SimpleResolverTest_localVariable_types_invoked
- extends RecursiveAstVisitor<Object> {
- final SimpleResolverTest test;
-
- List<bool> found;
-
- List<CaughtException> thrownException;
-
- _SimpleResolverTest_localVariable_types_invoked(
- this.test, this.found, this.thrownException)
- : super();
-
- @override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
- if (node.name == "myVar" && node.parent is MethodInvocation) {
- try {
- found[0] = true;
- // check static type
- DartType staticType = node.staticType;
- expect(staticType, same(test.typeProvider.dynamicType));
- // check propagated type
- FunctionType propagatedType = node.propagatedType as FunctionType;
- expect(propagatedType.returnType, test.typeProvider.stringType);
- } on AnalysisException catch (e, stackTrace) {
- thrownException[0] = new CaughtException(e, stackTrace);
- }
- }
- return null;
- }
-}
-
/**
* Represents an element left over from a previous resolver run.
*
@@ -17416,103 +3654,3 @@ class _StaleElement extends ElementImpl {
@override
accept(_) => throw "_StaleElement shouldn't be visited";
}
-
-/**
- * Shared infrastructure for [StaticTypeAnalyzer2Test] and
- * [StrongModeStaticTypeAnalyzer2Test].
- */
-class _StaticTypeAnalyzer2TestShared extends ResolverTestCase {
- String testCode;
- Source testSource;
- CompilationUnit testUnit;
-
- /**
- * Looks up the identifier with [name] and validates that its type type
- * stringifies to [type] and that its generics match the given stringified
- * output.
- */
- _expectFunctionType(String name, String type,
- {String elementTypeParams: '[]',
- String typeParams: '[]',
- String typeArgs: '[]',
- String typeFormals: '[]'}) {
- SimpleIdentifier identifier = _findIdentifier(name);
- // Element is either ExecutableElement or ParameterElement.
- var element = identifier.staticElement;
- FunctionTypeImpl functionType = identifier.staticType;
- expect(functionType.toString(), type);
- expect(element.typeParameters.toString(), elementTypeParams);
- expect(functionType.typeParameters.toString(), typeParams);
- expect(functionType.typeArguments.toString(), typeArgs);
- expect(functionType.typeFormals.toString(), typeFormals);
- }
-
- /**
- * Looks up the identifier with [name] and validates its static [type].
- *
- * If [type] is a string, validates that the identifier's static type
- * stringifies to that text. Otherwise, [type] is used directly a [Matcher]
- * to match the type.
- *
- * If [propagatedType] is given, also validate's the identifier's propagated
- * type.
- */
- void _expectIdentifierType(String name, type, [propagatedType]) {
- SimpleIdentifier identifier = _findIdentifier(name);
- _expectType(identifier.staticType, type);
- if (propagatedType != null) {
- _expectType(identifier.propagatedType, propagatedType);
- }
- }
-
- /**
- * Looks up the initializer for the declaration containing [identifier] and
- * validates its static [type].
- *
- * If [type] is a string, validates that the identifier's static type
- * stringifies to that text. Otherwise, [type] is used directly a [Matcher]
- * to match the type.
- *
- * If [propagatedType] is given, also validate's the identifier's propagated
- * type.
- */
- void _expectInitializerType(String name, type, [propagatedType]) {
- SimpleIdentifier identifier = _findIdentifier(name);
- VariableDeclaration declaration =
- identifier.getAncestor((node) => node is VariableDeclaration);
- Expression initializer = declaration.initializer;
- _expectType(initializer.staticType, type);
- if (propagatedType != null) {
- _expectType(initializer.propagatedType, propagatedType);
- }
- }
-
- /**
- * Validates that [type] matches [expected].
- *
- * If [expected] is a string, validates that the type stringifies to that
- * text. Otherwise, [expected] is used directly a [Matcher] to match the type.
- */
- _expectType(DartType type, expected) {
- if (expected is String) {
- expect(type.toString(), expected);
- } else {
- expect(type, expected);
- }
- }
-
- SimpleIdentifier _findIdentifier(String search) {
- SimpleIdentifier identifier = EngineTestCase.findNode(
- testUnit, testCode, search, (node) => node is SimpleIdentifier);
- return identifier;
- }
-
- void _resolveTestUnit(String code) {
- testCode = code;
- testSource = addSource(testCode);
- LibraryElement library = resolve2(testSource);
- assertNoErrors(testSource);
- verify([testSource]);
- testUnit = resolveCompilationUnit(testSource, library);
- }
-}

Powered by Google App Engine
This is Rietveld 408576698