| 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 |