| 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 62034f06a01c1f53328c1e2fa75f8b389aec0c0d..906bdd86dcdfd966142983b331b2407addf1974e 100644
|
| --- a/pkg/analyzer/test/generated/resolver_test.dart
|
| +++ b/pkg/analyzer/test/generated/resolver_test.dart
|
| @@ -9542,21 +9542,6 @@ class StaticTypeAnalyzer2Test extends ResolverTestCase {
|
| Source testSource;
|
| CompilationUnit testUnit;
|
|
|
| - void test_MethodInvocation_nameType_localVariable() {
|
| - String code = r"""
|
| -typedef Foo();
|
| -main() {
|
| - Foo foo;
|
| - foo();
|
| -}
|
| -""";
|
| - _resolveTestUnit(code);
|
| - // "foo" should be resolved to the "Foo" type
|
| - SimpleIdentifier identifier = _findIdentifier("foo();");
|
| - DartType type = identifier.staticType;
|
| - expect(type, new isInstanceOf<FunctionType>());
|
| - }
|
| -
|
| void test_FunctionExpressionInvocation_block() {
|
| String code = r'''
|
| main() {
|
| @@ -9571,10 +9556,12 @@ main() {
|
| expect(declaration.initializer.propagatedType, isNull);
|
| }
|
|
|
| - void test_FunctionExpressionInvocation_expression() {
|
| + void test_FunctionExpressionInvocation_curried() {
|
| String code = r'''
|
| +typedef int F();
|
| +F f() => null;
|
| main() {
|
| - var foo = (() => 1)();
|
| + var foo = f()();
|
| }
|
| ''';
|
| _resolveTestUnit(code);
|
| @@ -9585,12 +9572,10 @@ main() {
|
| expect(declaration.initializer.propagatedType, isNull);
|
| }
|
|
|
| - void test_FunctionExpressionInvocation_curried() {
|
| + void test_FunctionExpressionInvocation_expression() {
|
| String code = r'''
|
| -typedef int F();
|
| -F f() => null;
|
| main() {
|
| - var foo = f()();
|
| + var foo = (() => 1)();
|
| }
|
| ''';
|
| _resolveTestUnit(code);
|
| @@ -9601,6 +9586,21 @@ main() {
|
| expect(declaration.initializer.propagatedType, 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
|
| + SimpleIdentifier identifier = _findIdentifier("foo();");
|
| + DartType type = identifier.staticType;
|
| + expect(type, new isInstanceOf<FunctionType>());
|
| + }
|
| +
|
| void test_MethodInvocation_nameType_parameter_FunctionTypeAlias() {
|
| String code = r"""
|
| typedef Foo();
|
| @@ -9694,6 +9694,126 @@ class StaticTypeAnalyzerTest extends EngineTestCase {
|
| _analyzer = _createAnalyzer();
|
| }
|
|
|
| + void test_flatten_derived() {
|
| + // class Derived<T> extends Future<T> { ... }
|
| + ClassElementImpl derivedClass =
|
| + ElementFactory.classElement2('Derived', ['T']);
|
| + derivedClass.supertype = _typeProvider.futureType
|
| + .substitute4([derivedClass.typeParameters[0].type]);
|
| + InterfaceType intType = _typeProvider.intType;
|
| + DartType dynamicType = _typeProvider.dynamicType;
|
| + InterfaceType derivedIntType = derivedClass.type.substitute4([intType]);
|
| + // flatten(Derived) = dynamic
|
| + InterfaceType derivedDynamicType =
|
| + derivedClass.type.substitute4([dynamicType]);
|
| + expect(_flatten(derivedDynamicType), dynamicType);
|
| + // flatten(Derived<int>) = int
|
| + expect(_flatten(derivedIntType), intType);
|
| + // flatten(Derived<Derived>) = Derived
|
| + expect(_flatten(derivedClass.type.substitute4([derivedDynamicType])),
|
| + derivedDynamicType);
|
| + // flatten(Derived<Derived<int>>) = Derived<int>
|
| + expect(_flatten(derivedClass.type.substitute4([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
|
| + .substitute4([derivedClass.typeParameters[0].type]);
|
| + InterfaceType derivedType = derivedClass.type;
|
| + // class A extends Derived<int> implements Derived<num> { ... }
|
| + ClassElementImpl classA =
|
| + ElementFactory.classElement('A', derivedType.substitute4([intType]));
|
| + classA.interfaces = <InterfaceType>[derivedType.substitute4([numType])];
|
| + // class B extends Future<num> implements Future<int> { ... }
|
| + ClassElementImpl classB =
|
| + ElementFactory.classElement('B', derivedType.substitute4([numType]));
|
| + classB.interfaces = <InterfaceType>[derivedType.substitute4([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.substitute4([intType]));
|
| + classA.interfaces = <InterfaceType>[futureType.substitute4([numType])];
|
| + // class B extends Future<num> implements Future<int> { ... }
|
| + ClassElementImpl classB =
|
| + ElementFactory.classElement('B', futureType.substitute4([numType]));
|
| + classB.interfaces = <InterfaceType>[futureType.substitute4([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.substitute4([intType]);
|
| + InterfaceType futureFutureDynamicType =
|
| + _typeProvider.futureType.substitute4([futureDynamicType]);
|
| + InterfaceType futureFutureIntType =
|
| + _typeProvider.futureType.substitute4([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.substitute4([intType]));
|
| + classA.interfaces = <InterfaceType>[futureType.substitute4([stringType])];
|
| + // class B extends Future<String> implements Future<int> { ... }
|
| + ClassElementImpl classB =
|
| + ElementFactory.classElement('B', futureType.substitute4([stringType]));
|
| + classB.interfaces = <InterfaceType>[futureType.substitute4([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
|
| @@ -10773,6 +10893,9 @@ class StaticTypeAnalyzerTest extends EngineTestCase {
|
| }
|
| }
|
|
|
| + DartType _flatten(DartType type) =>
|
| + StaticTypeAnalyzer.flattenFutures(_typeProvider, type);
|
| +
|
| /**
|
| * Return an integer literal that has been resolved to the correct type.
|
| *
|
|
|