OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 analyzer.test.src.task.strong.inferred_type_test; | 5 library analyzer.test.src.task.strong.inferred_type_test; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 | 8 |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/element/element.dart'; | 10 import 'package:analyzer/dart/element/element.dart'; |
(...skipping 1659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1670 await checkFileElement( | 1670 await checkFileElement( |
1671 build(declared: "MyFuture", downwards: "MyFuture", upwards: "Future")); | 1671 build(declared: "MyFuture", downwards: "MyFuture", upwards: "Future")); |
1672 await checkFileElement(build( | 1672 await checkFileElement(build( |
1673 declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture")); | 1673 declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture")); |
1674 await checkFileElement( | 1674 await checkFileElement( |
1675 build(declared: "Future", downwards: "Future", upwards: "MyFuture")); | 1675 build(declared: "Future", downwards: "Future", upwards: "MyFuture")); |
1676 await checkFileElement( | 1676 await checkFileElement( |
1677 build(declared: "Future", downwards: "Future", upwards: "Future")); | 1677 build(declared: "Future", downwards: "Future", upwards: "Future")); |
1678 } | 1678 } |
1679 | 1679 |
1680 test_futureThen_conditional_deprecated() async { | |
1681 // Tests the deprecated ad hoc future inference for classes which implement | |
1682 // Future but haven't been updated to use FutureOr | |
1683 String build({String declared, String downwards, String upwards}) => ''' | |
1684 import 'dart:async'; | |
1685 class MyFuture<T> implements Future<T> { | |
1686 MyFuture() {} | |
1687 MyFuture.value(T x) {} | |
1688 dynamic noSuchMethod(invocation); | |
1689 MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null; | |
1690 } | |
1691 | |
1692 void main() { | |
1693 $declared<bool> f; | |
1694 $downwards<int> t1 = f.then(/*info:INFERRED_TYPE_CLOSURE*/ | |
1695 (x) async => x ? 2 : await new $upwards<int>.value(3)); | |
1696 $downwards<int> t2 = f.then(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CL
OSURE*/(x) async { // TODO(leafp): Why the duplicate here? | |
1697 return /*info:DOWN_CAST_COMPOSITE*/await x ? 2 : new $upwards<int>.value(3);
}); | |
1698 $downwards<int> t5 = f.then(/*info:INFERRED_TYPE_CLOSURE*/ | |
1699 (x) => x ? 2 : new $upwards<int>.value(3)); | |
1700 $downwards<int> t6 = f.then(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CL
OSURE*/ | |
1701 (x) {return /*info:DOWN_CAST_COMPOSITE*/x ? 2 : new $upwards<int>.value(3)
;}); | |
1702 } | |
1703 '''; | |
1704 await checkFileElement( | |
1705 build(declared: "MyFuture", downwards: "Future", upwards: "Future")); | |
1706 await checkFileElement( | |
1707 build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture")); | |
1708 await checkFileElement( | |
1709 build(declared: "MyFuture", downwards: "MyFuture", upwards: "Future")); | |
1710 await checkFileElement(build( | |
1711 declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture")); | |
1712 } | |
1713 | |
1714 test_futureThen_deprecated() async { | |
1715 // Tests the deprecated ad hoc future inference for classes which implement | |
1716 // Future but haven't been updated to use FutureOr | |
1717 String build({String declared, String downwards, String upwards}) => ''' | |
1718 import 'dart:async'; | |
1719 class MyFuture<T> implements Future<T> { | |
1720 MyFuture() {} | |
1721 MyFuture.value(T x) {} | |
1722 dynamic noSuchMethod(invocation); | |
1723 MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null; | |
1724 } | |
1725 | |
1726 void main() { | |
1727 $declared f; | |
1728 $downwards<int> t1 = f.then((_) async => await new $upwards<int>.value(3)); | |
1729 $downwards<int> t2 = f.then(/*info:INFERRED_TYPE_CLOSURE*/(_) async { | |
1730 return await new $upwards<int>.value(3);}); | |
1731 $downwards<int> t3 = f.then((_) async => 3); | |
1732 $downwards<int> t4 = f.then(/*info:INFERRED_TYPE_CLOSURE*/(_) async { | |
1733 return 3;}); | |
1734 $downwards<int> t5 = f.then((_) => new $upwards<int>.value(3)); | |
1735 $downwards<int> t6 = f.then(/*info:INFERRED_TYPE_CLOSURE*/(_) {return new $upw
ards<int>.value(3);}); | |
1736 $downwards<int> t7 = f.then((_) async => new $upwards<int>.value(3)); | |
1737 $downwards<int> t8 = f.then(/*info:INFERRED_TYPE_CLOSURE*/(_) async { | |
1738 return new $upwards<int>.value(3);}); | |
1739 } | |
1740 '''; | |
1741 | |
1742 await checkFileElement( | |
1743 build(declared: "MyFuture", downwards: "Future", upwards: "Future")); | |
1744 await checkFileElement( | |
1745 build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture")); | |
1746 await checkFileElement( | |
1747 build(declared: "MyFuture", downwards: "MyFuture", upwards: "Future")); | |
1748 await checkFileElement(build( | |
1749 declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture")); | |
1750 await checkFileElement( | |
1751 build(declared: "Future", downwards: "Future", upwards: "MyFuture")); | |
1752 await checkFileElement( | |
1753 build(declared: "Future", downwards: "Future", upwards: "Future")); | |
1754 } | |
1755 | |
1756 test_futureThen_downwardsMethodTarget() async { | 1680 test_futureThen_downwardsMethodTarget() async { |
1757 // Not working yet, see: https://github.com/dart-lang/sdk/issues/27114 | 1681 // Not working yet, see: https://github.com/dart-lang/sdk/issues/27114 |
1758 await checkFileElement(r''' | 1682 await checkFileElement(r''' |
1759 import 'dart:async'; | 1683 import 'dart:async'; |
1760 main() { | 1684 main() { |
1761 Future<int> f; | 1685 Future<int> f; |
1762 Future<List<int>> b = /*info:ASSIGNMENT_CAST should be pass*/f | 1686 Future<List<int>> b = /*info:ASSIGNMENT_CAST should be pass*/f |
1763 .then(/*info:INFERRED_TYPE_CLOSURE*/(x) => []) | 1687 .then(/*info:INFERRED_TYPE_CLOSURE*/(x) => []) |
1764 .whenComplete(/*info:INFERRED_TYPE_CLOSURE*/() {}); | 1688 .whenComplete(/*info:INFERRED_TYPE_CLOSURE*/() {}); |
1765 b = f.then(/*info:INFERRED_TYPE_CLOSURE*/(x) => /*info:INFERRED_TYPE_LITERAL*/
[]); | 1689 b = f.then(/*info:INFERRED_TYPE_CLOSURE*/(x) => /*info:INFERRED_TYPE_LITERAL*/
[]); |
1766 } | 1690 } |
1767 '''); | 1691 '''); |
1768 } | 1692 } |
1769 | 1693 |
1770 test_futureThen_explicitFuture() async { | 1694 test_futureThen_explicitFuture() async { |
1771 await checkFileElement(r''' | 1695 await checkFileElement(r''' |
1772 import "dart:async"; | 1696 import "dart:async"; |
1773 m1() { | 1697 m1() { |
1774 Future<int> f; | 1698 Future<int> f; |
1775 var x = f.then<Future<List<int>>>(/*info:INFERRED_TYPE_CLOSURE, | 1699 var x = f.then<Future<List<int>>>(/*info:INFERRED_TYPE_CLOSURE, |
1776 error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ | 1700 error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ |
1777 (x) => /*info:INFERRED_TYPE_LITERAL*/[]); | 1701 (x) => []); |
1778 Future<List<int>> y = x; | 1702 Future<List<int>> y = x; |
1779 } | 1703 } |
1780 m2() { | 1704 m2() { |
1781 Future<int> f; | 1705 Future<int> f; |
1782 var x = f.then<List<int>>(/*info:INFERRED_TYPE_CLOSURE*/(x) => /*info:INFERRED
_TYPE_LITERAL*/[]); | 1706 var x = f.then<List<int>>(/*info:INFERRED_TYPE_CLOSURE*/(x) => /*info:INFERRED
_TYPE_LITERAL*/[]); |
1783 Future<List<int>> y = x; | 1707 Future<List<int>> y = x; |
1784 } | 1708 } |
1785 '''); | 1709 '''); |
1786 } | 1710 } |
1787 | 1711 |
(...skipping 20 matching lines...) Expand all Loading... |
1808 $declared foo() => new $declared<int>.value(1); | 1732 $declared foo() => new $declared<int>.value(1); |
1809 '''; | 1733 '''; |
1810 await checkFileElement( | 1734 await checkFileElement( |
1811 build(declared: "MyFuture", downwards: "Future", upwards: "Future")); | 1735 build(declared: "MyFuture", downwards: "Future", upwards: "Future")); |
1812 await checkFileElement(build( | 1736 await checkFileElement(build( |
1813 declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture")); | 1737 declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture")); |
1814 await checkFileElement( | 1738 await checkFileElement( |
1815 build(declared: "Future", downwards: "Future", upwards: "Future")); | 1739 build(declared: "Future", downwards: "Future", upwards: "Future")); |
1816 } | 1740 } |
1817 | 1741 |
1818 test_futureThen_upwards_deprecated() async { | |
1819 // Tests the deprecated ad hoc future inference for classes which implement | |
1820 // Future but haven't been updated to use FutureOr | |
1821 // Regression test for https://github.com/dart-lang/sdk/issues/27088. | |
1822 String build({String declared, String downwards, String upwards}) => ''' | |
1823 import 'dart:async'; | |
1824 class MyFuture<T> implements Future<T> { | |
1825 MyFuture() {} | |
1826 MyFuture.value(T x) {} | |
1827 dynamic noSuchMethod(invocation); | |
1828 MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null; | |
1829 } | |
1830 | |
1831 void main() { | |
1832 var f = foo().then((_) => 2.3); | |
1833 $downwards<int> f2 = /*error:INVALID_ASSIGNMENT*/f; | |
1834 | |
1835 // The unnecessary cast is to illustrate that we inferred <double> for | |
1836 // the generic type args, even though we had a return type context. | |
1837 $downwards<num> f3 = /*info:UNNECESSARY_CAST*/foo().then( | |
1838 (_) => 2.3) as $upwards<double>; | |
1839 } | |
1840 $declared foo() => new $declared<int>.value(1); | |
1841 '''; | |
1842 await checkFileElement( | |
1843 build(declared: "MyFuture", downwards: "Future", upwards: "Future")); | |
1844 await checkFileElement(build( | |
1845 declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture")); | |
1846 await checkFileElement( | |
1847 build(declared: "Future", downwards: "Future", upwards: "Future")); | |
1848 } | |
1849 | |
1850 test_futureThen_upwardsFromBlock() async { | 1742 test_futureThen_upwardsFromBlock() async { |
1851 // Regression test for https://github.com/dart-lang/sdk/issues/27113. | 1743 // Regression test for https://github.com/dart-lang/sdk/issues/27113. |
1852 await checkFileElement(r''' | 1744 await checkFileElement(r''' |
1853 import 'dart:async'; | 1745 import 'dart:async'; |
1854 main() { | 1746 main() { |
1855 Future<int> base; | 1747 Future<int> base; |
1856 var f = base.then(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CLOSURE*/(x)
{ return x == 0; }); | 1748 var f = base.then(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CLOSURE*/(x)
{ return x == 0; }); |
1857 var g = base.then(/*info:INFERRED_TYPE_CLOSURE*/(x) => x == 0); | 1749 var g = base.then(/*info:INFERRED_TYPE_CLOSURE*/(x) => x == 0); |
1858 Future<bool> b = f; | 1750 Future<bool> b = f; |
1859 b = g; | 1751 b = g; |
(...skipping 17 matching lines...) Expand all Loading... |
1877 /*info:DOWN_CAST_COMPOSITE*/x ? 42 : /*info:INFERRED_TYPE_ALLOCATION*/new $upw
ards.value(42); | 1769 /*info:DOWN_CAST_COMPOSITE*/x ? 42 : /*info:INFERRED_TYPE_ALLOCATION*/new $upw
ards.value(42); |
1878 $downwards<int> g3(bool x) async { | 1770 $downwards<int> g3(bool x) async { |
1879 var y = x ? 42 : new $upwards.value(42); | 1771 var y = x ? 42 : new $upwards.value(42); |
1880 return /*info:DOWN_CAST_COMPOSITE*/y; | 1772 return /*info:DOWN_CAST_COMPOSITE*/y; |
1881 } | 1773 } |
1882 '''; | 1774 '''; |
1883 await checkFileElement(build(downwards: "Future", upwards: "Future")); | 1775 await checkFileElement(build(downwards: "Future", upwards: "Future")); |
1884 await checkFileElement(build(downwards: "Future", upwards: "MyFuture")); | 1776 await checkFileElement(build(downwards: "Future", upwards: "MyFuture")); |
1885 } | 1777 } |
1886 | 1778 |
1887 test_futureUnion_asyncConditional_deprecated() async { | |
1888 // Tests the deprecated ad hoc future inference for classes which implement | |
1889 // Future but haven't been updated to use FutureOr | |
1890 String build({String declared, String downwards, String upwards}) => ''' | |
1891 import 'dart:async'; | |
1892 class MyFuture<T> implements Future<T> { | |
1893 MyFuture() {} | |
1894 MyFuture.value(x) {} | |
1895 dynamic noSuchMethod(invocation); | |
1896 MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null; | |
1897 } | |
1898 | |
1899 $downwards<int> g1(bool x) async { | |
1900 return /*info:DOWN_CAST_COMPOSITE*/x ? 42 : /*info:INFERRED_TYPE_ALLOCATION*/n
ew $upwards.value(42); } | |
1901 $downwards<int> g2(bool x) async => | |
1902 /*info:DOWN_CAST_COMPOSITE*/x ? 42 : /*info:INFERRED_TYPE_ALLOCATION*/new $upw
ards.value(42); | |
1903 $downwards<int> g3(bool x) async { | |
1904 var y = x ? 42 : new $upwards.value(42); | |
1905 return /*info:DOWN_CAST_COMPOSITE*/y; | |
1906 } | |
1907 '''; | |
1908 await checkFileElement(build(downwards: "Future", upwards: "Future")); | |
1909 await checkFileElement(build(downwards: "Future", upwards: "MyFuture")); | |
1910 } | |
1911 | |
1912 test_futureUnion_downwards() async { | 1779 test_futureUnion_downwards() async { |
1913 String build({String declared, String downwards, String upwards}) { | 1780 String build({String declared, String downwards, String upwards}) { |
1914 return ''' | 1781 return ''' |
1915 import 'dart:async'; | 1782 import 'dart:async'; |
1916 class MyFuture<T> implements Future<T> { | 1783 class MyFuture<T> implements Future<T> { |
1917 MyFuture() {} | 1784 MyFuture() {} |
1918 MyFuture.value([x]) {} | 1785 MyFuture.value([x]) {} |
1919 dynamic noSuchMethod(invocation); | 1786 dynamic noSuchMethod(invocation); |
1920 MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null; | 1787 MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null; |
1921 } | 1788 } |
(...skipping 15 matching lines...) Expand all Loading... |
1937 await checkFileElement( | 1804 await checkFileElement( |
1938 build(declared: "MyFuture", downwards: "Future", upwards: "Future")); | 1805 build(declared: "MyFuture", downwards: "Future", upwards: "Future")); |
1939 await checkFileElement( | 1806 await checkFileElement( |
1940 build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture")); | 1807 build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture")); |
1941 await checkFileElement( | 1808 await checkFileElement( |
1942 build(declared: "Future", downwards: "Future", upwards: "Future")); | 1809 build(declared: "Future", downwards: "Future", upwards: "Future")); |
1943 await checkFileElement( | 1810 await checkFileElement( |
1944 build(declared: "Future", downwards: "Future", upwards: "MyFuture")); | 1811 build(declared: "Future", downwards: "Future", upwards: "MyFuture")); |
1945 } | 1812 } |
1946 | 1813 |
1947 test_futureUnion_downwards_deprecated() async { | |
1948 // Tests the deprecated ad hoc future inference for classes which implement | |
1949 // Future but haven't been updated to use FutureOr | |
1950 String build({String declared, String downwards, String upwards}) { | |
1951 return ''' | |
1952 import 'dart:async'; | |
1953 class MyFuture<T> implements Future<T> { | |
1954 MyFuture() {} | |
1955 MyFuture.value([x]) {} | |
1956 dynamic noSuchMethod(invocation); | |
1957 MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null; | |
1958 } | |
1959 | |
1960 $declared f; | |
1961 // Instantiates Future<int> | |
1962 $downwards<int> t1 = f.then((_) => | |
1963 /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value('hi')); | |
1964 | |
1965 // Instantiates List<int> | |
1966 $downwards<List<int>> t2 = f.then((_) => /*info:INFERRED_TYPE_LITERAL*/[3]); | |
1967 $downwards<List<int>> g2() async { return /*info:INFERRED_TYPE_LITERAL*/[3]; } | |
1968 $downwards<List<int>> g3() async { | |
1969 return /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value( | |
1970 /*info:INFERRED_TYPE_LITERAL*/[3]); } | |
1971 '''; | |
1972 } | |
1973 | |
1974 await checkFileElement( | |
1975 build(declared: "MyFuture", downwards: "Future", upwards: "Future")); | |
1976 await checkFileElement( | |
1977 build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture")); | |
1978 await checkFileElement( | |
1979 build(declared: "Future", downwards: "Future", upwards: "Future")); | |
1980 await checkFileElement( | |
1981 build(declared: "Future", downwards: "Future", upwards: "MyFuture")); | |
1982 } | |
1983 | |
1984 test_futureUnion_downwardsGenericMethodWithFutureReturn() async { | 1814 test_futureUnion_downwardsGenericMethodWithFutureReturn() async { |
1985 // Regression test for https://github.com/dart-lang/sdk/issues/27134 | 1815 // Regression test for https://github.com/dart-lang/sdk/issues/27134 |
1986 // | 1816 // |
1987 // We need to take a future union into account for both directions of | 1817 // We need to take a future union into account for both directions of |
1988 // generic method inference. | 1818 // generic method inference. |
1989 await checkFileElement(r''' | 1819 await checkFileElement(r''' |
1990 import 'dart:async'; | 1820 import 'dart:async'; |
1991 | 1821 |
1992 foo() async { | 1822 foo() async { |
1993 Future<List<A>> f1 = null; | 1823 Future<List<A>> f1 = null; |
(...skipping 3017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5011 .test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr
2(); | 4841 .test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr
2(); |
5012 } | 4842 } |
5013 | 4843 |
5014 @failingTest | 4844 @failingTest |
5015 @override | 4845 @override |
5016 test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr2_comme
nt() async { | 4846 test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr2_comme
nt() async { |
5017 await super | 4847 await super |
5018 .test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr
2_comment(); | 4848 .test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr
2_comment(); |
5019 } | 4849 } |
5020 } | 4850 } |
OLD | NEW |