| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library engine.resolver_test; | 5 library engine.resolver_test; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/src/generated/ast.dart'; | 9 import 'package:analyzer/src/generated/ast.dart'; |
| 10 import 'package:analyzer/src/generated/element.dart'; | 10 import 'package:analyzer/src/generated/element.dart'; |
| (...skipping 9524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9535 | 9535 |
| 9536 /** | 9536 /** |
| 9537 * Like [StaticTypeAnalyzerTest], but as end-to-end tests. | 9537 * Like [StaticTypeAnalyzerTest], but as end-to-end tests. |
| 9538 */ | 9538 */ |
| 9539 @reflectiveTest | 9539 @reflectiveTest |
| 9540 class StaticTypeAnalyzer2Test extends ResolverTestCase { | 9540 class StaticTypeAnalyzer2Test extends ResolverTestCase { |
| 9541 String testCode; | 9541 String testCode; |
| 9542 Source testSource; | 9542 Source testSource; |
| 9543 CompilationUnit testUnit; | 9543 CompilationUnit testUnit; |
| 9544 | 9544 |
| 9545 void test_MethodInvocation_nameType_localVariable() { | |
| 9546 String code = r""" | |
| 9547 typedef Foo(); | |
| 9548 main() { | |
| 9549 Foo foo; | |
| 9550 foo(); | |
| 9551 } | |
| 9552 """; | |
| 9553 _resolveTestUnit(code); | |
| 9554 // "foo" should be resolved to the "Foo" type | |
| 9555 SimpleIdentifier identifier = _findIdentifier("foo();"); | |
| 9556 DartType type = identifier.staticType; | |
| 9557 expect(type, new isInstanceOf<FunctionType>()); | |
| 9558 } | |
| 9559 | |
| 9560 void test_FunctionExpressionInvocation_block() { | 9545 void test_FunctionExpressionInvocation_block() { |
| 9561 String code = r''' | 9546 String code = r''' |
| 9562 main() { | 9547 main() { |
| 9563 var foo = (() { return 1; })(); | 9548 var foo = (() { return 1; })(); |
| 9564 } | 9549 } |
| 9565 '''; | 9550 '''; |
| 9566 _resolveTestUnit(code); | 9551 _resolveTestUnit(code); |
| 9567 SimpleIdentifier identifier = _findIdentifier('foo'); | 9552 SimpleIdentifier identifier = _findIdentifier('foo'); |
| 9568 VariableDeclaration declaration = | 9553 VariableDeclaration declaration = |
| 9569 identifier.getAncestor((node) => node is VariableDeclaration); | 9554 identifier.getAncestor((node) => node is VariableDeclaration); |
| 9570 expect(declaration.initializer.staticType.isDynamic, isTrue); | 9555 expect(declaration.initializer.staticType.isDynamic, isTrue); |
| 9571 expect(declaration.initializer.propagatedType, isNull); | 9556 expect(declaration.initializer.propagatedType, isNull); |
| 9572 } | 9557 } |
| 9573 | 9558 |
| 9574 void test_FunctionExpressionInvocation_expression() { | 9559 void test_FunctionExpressionInvocation_curried() { |
| 9575 String code = r''' | 9560 String code = r''' |
| 9561 typedef int F(); |
| 9562 F f() => null; |
| 9576 main() { | 9563 main() { |
| 9577 var foo = (() => 1)(); | 9564 var foo = f()(); |
| 9578 } | 9565 } |
| 9579 '''; | 9566 '''; |
| 9580 _resolveTestUnit(code); | 9567 _resolveTestUnit(code); |
| 9581 SimpleIdentifier identifier = _findIdentifier('foo'); | 9568 SimpleIdentifier identifier = _findIdentifier('foo'); |
| 9582 VariableDeclaration declaration = | 9569 VariableDeclaration declaration = |
| 9583 identifier.getAncestor((node) => node is VariableDeclaration); | 9570 identifier.getAncestor((node) => node is VariableDeclaration); |
| 9584 expect(declaration.initializer.staticType.name, 'int'); | 9571 expect(declaration.initializer.staticType.name, 'int'); |
| 9585 expect(declaration.initializer.propagatedType, isNull); | 9572 expect(declaration.initializer.propagatedType, isNull); |
| 9586 } | 9573 } |
| 9587 | 9574 |
| 9588 void test_FunctionExpressionInvocation_curried() { | 9575 void test_FunctionExpressionInvocation_expression() { |
| 9589 String code = r''' | 9576 String code = r''' |
| 9590 typedef int F(); | |
| 9591 F f() => null; | |
| 9592 main() { | 9577 main() { |
| 9593 var foo = f()(); | 9578 var foo = (() => 1)(); |
| 9594 } | 9579 } |
| 9595 '''; | 9580 '''; |
| 9596 _resolveTestUnit(code); | 9581 _resolveTestUnit(code); |
| 9597 SimpleIdentifier identifier = _findIdentifier('foo'); | 9582 SimpleIdentifier identifier = _findIdentifier('foo'); |
| 9598 VariableDeclaration declaration = | 9583 VariableDeclaration declaration = |
| 9599 identifier.getAncestor((node) => node is VariableDeclaration); | 9584 identifier.getAncestor((node) => node is VariableDeclaration); |
| 9600 expect(declaration.initializer.staticType.name, 'int'); | 9585 expect(declaration.initializer.staticType.name, 'int'); |
| 9601 expect(declaration.initializer.propagatedType, isNull); | 9586 expect(declaration.initializer.propagatedType, isNull); |
| 9602 } | 9587 } |
| 9603 | 9588 |
| 9589 void test_MethodInvocation_nameType_localVariable() { |
| 9590 String code = r""" |
| 9591 typedef Foo(); |
| 9592 main() { |
| 9593 Foo foo; |
| 9594 foo(); |
| 9595 } |
| 9596 """; |
| 9597 _resolveTestUnit(code); |
| 9598 // "foo" should be resolved to the "Foo" type |
| 9599 SimpleIdentifier identifier = _findIdentifier("foo();"); |
| 9600 DartType type = identifier.staticType; |
| 9601 expect(type, new isInstanceOf<FunctionType>()); |
| 9602 } |
| 9603 |
| 9604 void test_MethodInvocation_nameType_parameter_FunctionTypeAlias() { | 9604 void test_MethodInvocation_nameType_parameter_FunctionTypeAlias() { |
| 9605 String code = r""" | 9605 String code = r""" |
| 9606 typedef Foo(); | 9606 typedef Foo(); |
| 9607 main(Foo foo) { | 9607 main(Foo foo) { |
| 9608 foo(); | 9608 foo(); |
| 9609 } | 9609 } |
| 9610 """; | 9610 """; |
| 9611 _resolveTestUnit(code); | 9611 _resolveTestUnit(code); |
| 9612 // "foo" should be resolved to the "Foo" type | 9612 // "foo" should be resolved to the "Foo" type |
| 9613 SimpleIdentifier identifier = _findIdentifier("foo();"); | 9613 SimpleIdentifier identifier = _findIdentifier("foo();"); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9687 _listener.assertNoErrors(); | 9687 _listener.assertNoErrors(); |
| 9688 } | 9688 } |
| 9689 | 9689 |
| 9690 @override | 9690 @override |
| 9691 void setUp() { | 9691 void setUp() { |
| 9692 _listener = new GatheringErrorListener(); | 9692 _listener = new GatheringErrorListener(); |
| 9693 _typeProvider = new TestTypeProvider(); | 9693 _typeProvider = new TestTypeProvider(); |
| 9694 _analyzer = _createAnalyzer(); | 9694 _analyzer = _createAnalyzer(); |
| 9695 } | 9695 } |
| 9696 | 9696 |
| 9697 void test_flatten_derived() { |
| 9698 // class Derived<T> extends Future<T> { ... } |
| 9699 ClassElementImpl derivedClass = |
| 9700 ElementFactory.classElement2('Derived', ['T']); |
| 9701 derivedClass.supertype = _typeProvider.futureType |
| 9702 .substitute4([derivedClass.typeParameters[0].type]); |
| 9703 InterfaceType intType = _typeProvider.intType; |
| 9704 DartType dynamicType = _typeProvider.dynamicType; |
| 9705 InterfaceType derivedIntType = derivedClass.type.substitute4([intType]); |
| 9706 // flatten(Derived) = dynamic |
| 9707 InterfaceType derivedDynamicType = |
| 9708 derivedClass.type.substitute4([dynamicType]); |
| 9709 expect(_flatten(derivedDynamicType), dynamicType); |
| 9710 // flatten(Derived<int>) = int |
| 9711 expect(_flatten(derivedIntType), intType); |
| 9712 // flatten(Derived<Derived>) = Derived |
| 9713 expect(_flatten(derivedClass.type.substitute4([derivedDynamicType])), |
| 9714 derivedDynamicType); |
| 9715 // flatten(Derived<Derived<int>>) = Derived<int> |
| 9716 expect(_flatten(derivedClass.type.substitute4([derivedIntType])), |
| 9717 derivedIntType); |
| 9718 } |
| 9719 |
| 9720 void test_flatten_inhibit_recursion() { |
| 9721 // class A extends B |
| 9722 // class B extends A |
| 9723 ClassElementImpl classA = ElementFactory.classElement2('A', []); |
| 9724 ClassElementImpl classB = ElementFactory.classElement2('B', []); |
| 9725 classA.supertype = classB.type; |
| 9726 classB.supertype = classA.type; |
| 9727 // flatten(A) = A and flatten(B) = B, since neither class contains Future |
| 9728 // in its class hierarchy. Even though there is a loop in the class |
| 9729 // hierarchy, flatten() should terminate. |
| 9730 expect(_flatten(classA.type), classA.type); |
| 9731 expect(_flatten(classB.type), classB.type); |
| 9732 } |
| 9733 |
| 9734 void test_flatten_related_derived_types() { |
| 9735 InterfaceType intType = _typeProvider.intType; |
| 9736 InterfaceType numType = _typeProvider.numType; |
| 9737 // class Derived<T> extends Future<T> |
| 9738 ClassElementImpl derivedClass = |
| 9739 ElementFactory.classElement2('Derived', ['T']); |
| 9740 derivedClass.supertype = _typeProvider.futureType |
| 9741 .substitute4([derivedClass.typeParameters[0].type]); |
| 9742 InterfaceType derivedType = derivedClass.type; |
| 9743 // class A extends Derived<int> implements Derived<num> { ... } |
| 9744 ClassElementImpl classA = |
| 9745 ElementFactory.classElement('A', derivedType.substitute4([intType])); |
| 9746 classA.interfaces = <InterfaceType>[derivedType.substitute4([numType])]; |
| 9747 // class B extends Future<num> implements Future<int> { ... } |
| 9748 ClassElementImpl classB = |
| 9749 ElementFactory.classElement('B', derivedType.substitute4([numType])); |
| 9750 classB.interfaces = <InterfaceType>[derivedType.substitute4([intType])]; |
| 9751 // flatten(A) = flatten(B) = int, since int is more specific than num. |
| 9752 // The code in flatten() that inhibits infinite recursion shouldn't be |
| 9753 // fooled by the fact that Derived appears twice in the type hierarchy. |
| 9754 expect(_flatten(classA.type), intType); |
| 9755 expect(_flatten(classB.type), intType); |
| 9756 } |
| 9757 |
| 9758 void test_flatten_related_types() { |
| 9759 InterfaceType futureType = _typeProvider.futureType; |
| 9760 InterfaceType intType = _typeProvider.intType; |
| 9761 InterfaceType numType = _typeProvider.numType; |
| 9762 // class A extends Future<int> implements Future<num> { ... } |
| 9763 ClassElementImpl classA = |
| 9764 ElementFactory.classElement('A', futureType.substitute4([intType])); |
| 9765 classA.interfaces = <InterfaceType>[futureType.substitute4([numType])]; |
| 9766 // class B extends Future<num> implements Future<int> { ... } |
| 9767 ClassElementImpl classB = |
| 9768 ElementFactory.classElement('B', futureType.substitute4([numType])); |
| 9769 classB.interfaces = <InterfaceType>[futureType.substitute4([intType])]; |
| 9770 // flatten(A) = flatten(B) = int, since int is more specific than num. |
| 9771 expect(_flatten(classA.type), intType); |
| 9772 expect(_flatten(classB.type), intType); |
| 9773 } |
| 9774 |
| 9775 void test_flatten_simple() { |
| 9776 InterfaceType intType = _typeProvider.intType; |
| 9777 DartType dynamicType = _typeProvider.dynamicType; |
| 9778 InterfaceType futureDynamicType = _typeProvider.futureDynamicType; |
| 9779 InterfaceType futureIntType = |
| 9780 _typeProvider.futureType.substitute4([intType]); |
| 9781 InterfaceType futureFutureDynamicType = |
| 9782 _typeProvider.futureType.substitute4([futureDynamicType]); |
| 9783 InterfaceType futureFutureIntType = |
| 9784 _typeProvider.futureType.substitute4([futureIntType]); |
| 9785 // flatten(int) = int |
| 9786 expect(_flatten(intType), intType); |
| 9787 // flatten(dynamic) = dynamic |
| 9788 expect(_flatten(dynamicType), dynamicType); |
| 9789 // flatten(Future) = dynamic |
| 9790 expect(_flatten(futureDynamicType), dynamicType); |
| 9791 // flatten(Future<int>) = int |
| 9792 expect(_flatten(futureIntType), intType); |
| 9793 // flatten(Future<Future>) = dynamic |
| 9794 expect(_flatten(futureFutureDynamicType), dynamicType); |
| 9795 // flatten(Future<Future<int>>) = int |
| 9796 expect(_flatten(futureFutureIntType), intType); |
| 9797 } |
| 9798 |
| 9799 void test_flatten_unrelated_types() { |
| 9800 InterfaceType futureType = _typeProvider.futureType; |
| 9801 InterfaceType intType = _typeProvider.intType; |
| 9802 InterfaceType stringType = _typeProvider.stringType; |
| 9803 // class A extends Future<int> implements Future<String> { ... } |
| 9804 ClassElementImpl classA = |
| 9805 ElementFactory.classElement('A', futureType.substitute4([intType])); |
| 9806 classA.interfaces = <InterfaceType>[futureType.substitute4([stringType])]; |
| 9807 // class B extends Future<String> implements Future<int> { ... } |
| 9808 ClassElementImpl classB = |
| 9809 ElementFactory.classElement('B', futureType.substitute4([stringType])); |
| 9810 classB.interfaces = <InterfaceType>[futureType.substitute4([intType])]; |
| 9811 // flatten(A) = A and flatten(B) = B, since neither string nor int is more |
| 9812 // specific than the other. |
| 9813 expect(_flatten(classA.type), classA.type); |
| 9814 expect(_flatten(classB.type), classB.type); |
| 9815 } |
| 9816 |
| 9697 void test_visitAdjacentStrings() { | 9817 void test_visitAdjacentStrings() { |
| 9698 // "a" "b" | 9818 // "a" "b" |
| 9699 Expression node = AstFactory | 9819 Expression node = AstFactory |
| 9700 .adjacentStrings([_resolvedString("a"), _resolvedString("b")]); | 9820 .adjacentStrings([_resolvedString("a"), _resolvedString("b")]); |
| 9701 expect(_analyze(node), same(_typeProvider.stringType)); | 9821 expect(_analyze(node), same(_typeProvider.stringType)); |
| 9702 _listener.assertNoErrors(); | 9822 _listener.assertNoErrors(); |
| 9703 } | 9823 } |
| 9704 | 9824 |
| 9705 void test_visitAsExpression() { | 9825 void test_visitAsExpression() { |
| 9706 // class A { ... this as B ... } | 9826 // class A { ... this as B ... } |
| (...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10766 _visitor = new ResolverVisitor.con1(library, source, _typeProvider); | 10886 _visitor = new ResolverVisitor.con1(library, source, _typeProvider); |
| 10767 _visitor.overrideManager.enterScope(); | 10887 _visitor.overrideManager.enterScope(); |
| 10768 try { | 10888 try { |
| 10769 return _visitor.typeAnalyzer_J2DAccessor as StaticTypeAnalyzer; | 10889 return _visitor.typeAnalyzer_J2DAccessor as StaticTypeAnalyzer; |
| 10770 } catch (exception) { | 10890 } catch (exception) { |
| 10771 throw new IllegalArgumentException( | 10891 throw new IllegalArgumentException( |
| 10772 "Could not create analyzer", exception); | 10892 "Could not create analyzer", exception); |
| 10773 } | 10893 } |
| 10774 } | 10894 } |
| 10775 | 10895 |
| 10896 DartType _flatten(DartType type) => |
| 10897 StaticTypeAnalyzer.flattenFutures(_typeProvider, type); |
| 10898 |
| 10776 /** | 10899 /** |
| 10777 * Return an integer literal that has been resolved to the correct type. | 10900 * Return an integer literal that has been resolved to the correct type. |
| 10778 * | 10901 * |
| 10779 * @param value the value of the literal | 10902 * @param value the value of the literal |
| 10780 * @return an integer literal that has been resolved to the correct type | 10903 * @return an integer literal that has been resolved to the correct type |
| 10781 */ | 10904 */ |
| 10782 DoubleLiteral _resolvedDouble(double value) { | 10905 DoubleLiteral _resolvedDouble(double value) { |
| 10783 DoubleLiteral literal = AstFactory.doubleLiteral(value); | 10906 DoubleLiteral literal = AstFactory.doubleLiteral(value); |
| 10784 literal.staticType = _typeProvider.doubleType; | 10907 literal.staticType = _typeProvider.doubleType; |
| 10785 return literal; | 10908 return literal; |
| (...skipping 2750 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13536 // check propagated type | 13659 // check propagated type |
| 13537 FunctionType propagatedType = node.propagatedType as FunctionType; | 13660 FunctionType propagatedType = node.propagatedType as FunctionType; |
| 13538 expect(propagatedType.returnType, test.typeProvider.stringType); | 13661 expect(propagatedType.returnType, test.typeProvider.stringType); |
| 13539 } on AnalysisException catch (e, stackTrace) { | 13662 } on AnalysisException catch (e, stackTrace) { |
| 13540 thrownException[0] = new CaughtException(e, stackTrace); | 13663 thrownException[0] = new CaughtException(e, stackTrace); |
| 13541 } | 13664 } |
| 13542 } | 13665 } |
| 13543 return null; | 13666 return null; |
| 13544 } | 13667 } |
| 13545 } | 13668 } |
| OLD | NEW |