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 // TODO(jmesserly): this file needs to be refactored, it's a port from | 5 // TODO(jmesserly): this file needs to be refactored, it's a port from |
6 // package:dev_compiler's tests | 6 // package:dev_compiler's tests |
7 /// Tests for type inference. | 7 /// Tests for type inference. |
8 library analyzer.test.src.task.strong.inferred_type_test; | 8 library analyzer.test.src.task.strong.inferred_type_test; |
9 | 9 |
10 import 'package:analyzer/dart/element/element.dart'; | 10 import 'package:analyzer/dart/element/element.dart'; |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 String s = /*info:DYNAMIC_CAST*/await f(); | 242 String s = /*info:DYNAMIC_CAST*/await f(); |
243 } | 243 } |
244 '''); | 244 '''); |
245 var f = mainUnit.functions[0].localVariables[0]; | 245 var f = mainUnit.functions[0].localVariables[0]; |
246 expect(f.type.toString(), '() → Future<dynamic>'); | 246 expect(f.type.toString(), '() → Future<dynamic>'); |
247 } | 247 } |
248 | 248 |
249 void test_blockBodiedLambdas_doesNotInferBottom_async_topLevel() { | 249 void test_blockBodiedLambdas_doesNotInferBottom_async_topLevel() { |
250 var mainUnit = checkFile(r''' | 250 var mainUnit = checkFile(r''' |
251 import 'dart:async'; | 251 import 'dart:async'; |
252 var f = /*warning:UNSAFE_BLOCK_CLOSURE_INFERENCE*/() async { return null; }; | 252 var f = /*warning:UNSAFE_BLOCK_CLOSURE_INFERENCE,info:INFERRED_TYPE_CLOSURE*/()
async { return null; }; |
253 '''); | 253 '''); |
254 var f = mainUnit.topLevelVariables[0]; | 254 var f = mainUnit.topLevelVariables[0]; |
255 expect(f.type.toString(), '() → Future<dynamic>'); | 255 expect(f.type.toString(), '() → Future<dynamic>'); |
256 } | 256 } |
257 | 257 |
258 void test_blockBodiedLambdas_doesNotInferBottom_asyncStar() { | 258 void test_blockBodiedLambdas_doesNotInferBottom_asyncStar() { |
259 if (!mayCheckTypesOfLocals) { | 259 if (!mayCheckTypesOfLocals) { |
260 return; | 260 return; |
261 } | 261 } |
262 var mainUnit = checkFile(r''' | 262 var mainUnit = checkFile(r''' |
(...skipping 1402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1665 expect(x.type.toString(), 'int'); | 1665 expect(x.type.toString(), 'int'); |
1666 } | 1666 } |
1667 | 1667 |
1668 void test_futureThen() { | 1668 void test_futureThen() { |
1669 String build({String declared, String downwards, String upwards}) => ''' | 1669 String build({String declared, String downwards, String upwards}) => ''' |
1670 import 'dart:async'; | 1670 import 'dart:async'; |
1671 class MyFuture<T> implements Future<T> { | 1671 class MyFuture<T> implements Future<T> { |
1672 MyFuture() {} | 1672 MyFuture() {} |
1673 MyFuture.value(T x) {} | 1673 MyFuture.value(T x) {} |
1674 dynamic noSuchMethod(invocation); | 1674 dynamic noSuchMethod(invocation); |
1675 MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null; | 1675 MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null; |
1676 } | 1676 } |
1677 | 1677 |
1678 void main() { | 1678 void main() { |
1679 $declared f; | 1679 $declared f; |
1680 $downwards<int> t1 = f.then((_) async => await new $upwards<int>.value(3)); | 1680 $downwards<int> t1 = f.then((_) async => await new $upwards<int>.value(3)); |
1681 $downwards<int> t2 = f.then(/*info:INFERRED_TYPE_CLOSURE*/(_) async { | 1681 $downwards<int> t2 = f.then(/*info:INFERRED_TYPE_CLOSURE*/(_) async { |
1682 return await new $upwards<int>.value(3);}); | 1682 return await new $upwards<int>.value(3);}); |
1683 $downwards<int> t3 = f.then((_) async => 3); | 1683 $downwards<int> t3 = f.then((_) async => 3); |
1684 $downwards<int> t4 = f.then(/*info:INFERRED_TYPE_CLOSURE*/(_) async { | 1684 $downwards<int> t4 = f.then(/*info:INFERRED_TYPE_CLOSURE*/(_) async { |
1685 return 3;}); | 1685 return 3;}); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1745 build(declared: "Future", downwards: "Future", upwards: "Future")); | 1745 build(declared: "Future", downwards: "Future", upwards: "Future")); |
1746 } | 1746 } |
1747 | 1747 |
1748 void test_futureThen_conditional() { | 1748 void test_futureThen_conditional() { |
1749 String build({String declared, String downwards, String upwards}) => ''' | 1749 String build({String declared, String downwards, String upwards}) => ''' |
1750 import 'dart:async'; | 1750 import 'dart:async'; |
1751 class MyFuture<T> implements Future<T> { | 1751 class MyFuture<T> implements Future<T> { |
1752 MyFuture() {} | 1752 MyFuture() {} |
1753 MyFuture.value(T x) {} | 1753 MyFuture.value(T x) {} |
1754 dynamic noSuchMethod(invocation); | 1754 dynamic noSuchMethod(invocation); |
1755 MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null; | 1755 MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null; |
1756 } | 1756 } |
1757 | 1757 |
1758 void main() { | 1758 void main() { |
1759 $declared<bool> f; | 1759 $declared<bool> f; |
1760 $downwards<int> t1 = f.then(/*info:INFERRED_TYPE_CLOSURE*/ | 1760 $downwards<int> t1 = f.then(/*info:INFERRED_TYPE_CLOSURE*/ |
1761 (x) async => x ? 2 : await new $upwards<int>.value(3)); | 1761 (x) async => x ? 2 : await new $upwards<int>.value(3)); |
1762 $downwards<int> t2 = f.then(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CL
OSURE*/(x) async { // TODO(leafp): Why the duplicate here? | 1762 $downwards<int> t2 = f.then(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CL
OSURE*/(x) async { // TODO(leafp): Why the duplicate here? |
1763 return await x ? 2 : new $upwards<int>.value(3);}); | 1763 return await x ? 2 : new $upwards<int>.value(3);}); |
1764 $downwards<int> t5 = f.then(/*info:INFERRED_TYPE_CLOSURE*/ | 1764 $downwards<int> t5 = f.then(/*info:INFERRED_TYPE_CLOSURE,error:INVALID_CAST_FU
NCTION_EXPR*/ |
1765 (x) => x ? 2 : new $upwards<int>.value(3)); | 1765 (x) => x ? 2 : new $upwards<int>.value(3)); |
1766 $downwards<int> t6 = f.then(/*info:INFERRED_TYPE_CLOSURE*/ | 1766 $downwards<int> t6 = f.then(/*info:INFERRED_TYPE_CLOSURE*/ |
1767 (x) {return x ? 2 : new $upwards<int>.value(3);}); | 1767 (x) {return /*warning:DOWN_CAST_COMPOSITE*/x ? 2 : new $upwards<int>.value
(3);}); |
1768 } | 1768 } |
1769 '''; | 1769 '''; |
1770 checkFile( | 1770 checkFile( |
1771 build(declared: "MyFuture", downwards: "Future", upwards: "Future")); | |
1772 checkFile( | |
1773 build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture")); | |
1774 checkFile( | |
1775 build(declared: "MyFuture", downwards: "MyFuture", upwards: "Future")); | |
1776 checkFile(build( | |
1777 declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture")); | |
1778 checkFile( | |
1779 build(declared: "Future", downwards: "Future", upwards: "MyFuture")); | |
1780 checkFile( | |
1781 build(declared: "Future", downwards: "Future", upwards: "Future")); | |
1782 } | |
1783 | |
1784 void test_futureThen_conditional_comment() { | |
1785 String build({String declared, String downwards, String upwards}) => ''' | |
1786 import 'dart:async'; | |
1787 class MyFuture<T> implements Future<T> { | |
1788 MyFuture() {} | |
1789 MyFuture.value(T x) {} | |
1790 dynamic noSuchMethod(invocation); | |
1791 MyFuture/*<S>*/ then/*<S>*/(dynamic f(T x), {Function onError}) => null; | |
1792 } | |
1793 | |
1794 void main() { | |
1795 $declared<bool> f; | |
1796 $downwards<int> t1 = f.then(/*info:INFERRED_TYPE_CLOSURE*/ | |
1797 (x) async => x ? 2 : await new $upwards<int>.value(3)); | |
1798 $downwards<int> t2 = f.then(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CL
OSURE*/(x) async { // TODO(leafp): Why the duplicate here? | |
1799 return await x ? 2 : new $upwards<int>.value(3);}); | |
1800 $downwards<int> t5 = f.then(/*info:INFERRED_TYPE_CLOSURE*/ | |
1801 (x) => x ? 2 : new $upwards<int>.value(3)); | |
1802 $downwards<int> t6 = f.then(/*info:INFERRED_TYPE_CLOSURE*/ | |
1803 (x) {return x ? 2 : new $upwards<int>.value(3);}); | |
1804 } | |
1805 '''; | |
1806 checkFile( | |
1807 build(declared: "MyFuture", downwards: "Future", upwards: "Future")); | 1771 build(declared: "MyFuture", downwards: "Future", upwards: "Future")); |
1808 checkFile( | 1772 checkFile( |
1809 build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture")); | 1773 build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture")); |
1810 checkFile( | 1774 checkFile( |
1811 build(declared: "MyFuture", downwards: "MyFuture", upwards: "Future")); | 1775 build(declared: "MyFuture", downwards: "MyFuture", upwards: "Future")); |
1812 checkFile(build( | 1776 checkFile(build( |
1813 declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture")); | 1777 declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture")); |
1814 checkFile( | 1778 checkFile( |
1815 build(declared: "Future", downwards: "Future", upwards: "MyFuture")); | 1779 build(declared: "Future", downwards: "Future", upwards: "MyFuture")); |
1816 checkFile( | 1780 checkFile( |
(...skipping 10 matching lines...) Expand all Loading... |
1827 .then(/*info:INFERRED_TYPE_CLOSURE*/(x) => []) | 1791 .then(/*info:INFERRED_TYPE_CLOSURE*/(x) => []) |
1828 .whenComplete(/*pass should be info:INFERRED_TYPE_LITERAL*/() {}); | 1792 .whenComplete(/*pass should be info:INFERRED_TYPE_LITERAL*/() {}); |
1829 b = f.then(/*info:INFERRED_TYPE_CLOSURE*/(x) => /*info:INFERRED_TYPE_LITERAL*/
[]); | 1793 b = f.then(/*info:INFERRED_TYPE_CLOSURE*/(x) => /*info:INFERRED_TYPE_LITERAL*/
[]); |
1830 } | 1794 } |
1831 '''); | 1795 '''); |
1832 } | 1796 } |
1833 | 1797 |
1834 void test_futureThen_explicitFuture() { | 1798 void test_futureThen_explicitFuture() { |
1835 checkFile(r''' | 1799 checkFile(r''' |
1836 import "dart:async"; | 1800 import "dart:async"; |
1837 main() { | 1801 m1() { |
1838 Future<int> f; | 1802 Future<int> f; |
1839 var x = f.then<Future<List<int>>>(/*info:INFERRED_TYPE_CLOSURE*/(x) => /*info:
INFERRED_TYPE_LITERAL*/[]); | 1803 var x = f.then<Future<List<int>>>(/*info:INFERRED_TYPE_CLOSURE,error:ARGUMENT_
TYPE_NOT_ASSIGNABLE*/(x) => []); |
| 1804 Future<List<int>> y = x; |
| 1805 } |
| 1806 m2() { |
| 1807 Future<int> f; |
| 1808 var x = f.then<List<int>>(/*info:INFERRED_TYPE_CLOSURE*/(x) => /*info:INFERRED
_TYPE_LITERAL*/[]); |
1840 Future<List<int>> y = x; | 1809 Future<List<int>> y = x; |
1841 } | 1810 } |
1842 '''); | 1811 '''); |
1843 } | |
1844 | |
1845 void test_futureThen_explicitFuture_comment() { | |
1846 checkFile(r''' | |
1847 import "dart:async"; | |
1848 main() { | |
1849 Future<int> f; | |
1850 var x = f.then/*<Future<List<int>>>*/(/*info:INFERRED_TYPE_CLOSURE*/(x) => /*i
nfo:INFERRED_TYPE_LITERAL*/[]); | |
1851 Future<List<int>> y = x; | |
1852 } | |
1853 '''); | |
1854 } | 1812 } |
1855 | 1813 |
1856 void test_futureThen_upwards() { | 1814 void test_futureThen_upwards() { |
1857 // Regression test for https://github.com/dart-lang/sdk/issues/27088. | 1815 // Regression test for https://github.com/dart-lang/sdk/issues/27088. |
1858 String build({String declared, String downwards, String upwards}) => ''' | 1816 String build({String declared, String downwards, String upwards}) => ''' |
1859 import 'dart:async'; | 1817 import 'dart:async'; |
1860 class MyFuture<T> implements Future<T> { | 1818 class MyFuture<T> implements Future<T> { |
1861 MyFuture() {} | 1819 MyFuture() {} |
1862 MyFuture.value(T x) {} | 1820 MyFuture.value(T x) {} |
1863 dynamic noSuchMethod(invocation); | 1821 dynamic noSuchMethod(invocation); |
1864 MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null; | 1822 MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null; |
1865 } | 1823 } |
1866 | 1824 |
1867 void main() { | 1825 void main() { |
1868 var f = foo().then((_) => 2.3); | |
1869 $downwards<int> f2 = /*error:INVALID_ASSIGNMENT*/f; | |
1870 | |
1871 // The unnecessary cast is to illustrate that we inferred <double> for | |
1872 // the generic type args, even though we had a return type context. | |
1873 $downwards<num> f3 = /*info:UNNECESSARY_CAST*/foo().then( | |
1874 (_) => 2.3) as $upwards<double>; | |
1875 } | |
1876 $declared foo() => new $declared<int>.value(1); | |
1877 '''; | |
1878 checkFile( | |
1879 build(declared: "MyFuture", downwards: "Future", upwards: "Future")); | |
1880 checkFile(build( | |
1881 declared: "MyFuture", downwards: "MyFuture", upwards: "MyFuture")); | |
1882 checkFile( | |
1883 build(declared: "Future", downwards: "Future", upwards: "Future")); | |
1884 } | |
1885 | |
1886 void test_futureThen_upwards_comment() { | |
1887 // Regression test for https://github.com/dart-lang/sdk/issues/27088. | |
1888 String build({String declared, String downwards, String upwards}) => ''' | |
1889 import 'dart:async'; | |
1890 class MyFuture<T> implements Future<T> { | |
1891 MyFuture() {} | |
1892 MyFuture.value(T x) {} | |
1893 dynamic noSuchMethod(invocation); | |
1894 MyFuture/*<S>*/ then/*<S>*/(dynamic f(T x), {Function onError}) => null; | |
1895 } | |
1896 | |
1897 void main() { | |
1898 var f = foo().then((_) => 2.3); | 1826 var f = foo().then((_) => 2.3); |
1899 $downwards<int> f2 = /*error:INVALID_ASSIGNMENT*/f; | 1827 $downwards<int> f2 = /*error:INVALID_ASSIGNMENT*/f; |
1900 | 1828 |
1901 // The unnecessary cast is to illustrate that we inferred <double> for | 1829 // The unnecessary cast is to illustrate that we inferred <double> for |
1902 // the generic type args, even though we had a return type context. | 1830 // the generic type args, even though we had a return type context. |
1903 $downwards<num> f3 = /*info:UNNECESSARY_CAST*/foo().then( | 1831 $downwards<num> f3 = /*info:UNNECESSARY_CAST*/foo().then( |
1904 (_) => 2.3) as $upwards<double>; | 1832 (_) => 2.3) as $upwards<double>; |
1905 } | 1833 } |
1906 $declared foo() => new $declared<int>.value(1); | 1834 $declared foo() => new $declared<int>.value(1); |
1907 '''; | 1835 '''; |
(...skipping 12 matching lines...) Expand all Loading... |
1920 main() { | 1848 main() { |
1921 Future<int> base; | 1849 Future<int> base; |
1922 var f = base.then(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CLOSURE*/(x)
{ return x == 0; }); | 1850 var f = base.then(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CLOSURE*/(x)
{ return x == 0; }); |
1923 var g = base.then(/*info:INFERRED_TYPE_CLOSURE*/(x) => x == 0); | 1851 var g = base.then(/*info:INFERRED_TYPE_CLOSURE*/(x) => x == 0); |
1924 Future<bool> b = f; | 1852 Future<bool> b = f; |
1925 b = g; | 1853 b = g; |
1926 } | 1854 } |
1927 '''); | 1855 '''); |
1928 } | 1856 } |
1929 | 1857 |
| 1858 void test_futureOr_subtyping() { |
| 1859 checkFile(r''' |
| 1860 import 'dart:async'; |
| 1861 void add(int x) {} |
| 1862 add2(int y) {} |
| 1863 main() { |
| 1864 Future<int> f; |
| 1865 var a = f.then(add); |
| 1866 var b = f.then(add2); |
| 1867 } |
| 1868 '''); |
| 1869 } |
| 1870 |
1930 void test_futureUnion_asyncConditional() { | 1871 void test_futureUnion_asyncConditional() { |
1931 String build({String declared, String downwards, String upwards}) => ''' | 1872 String build({String declared, String downwards, String upwards}) => ''' |
1932 import 'dart:async'; | 1873 import 'dart:async'; |
1933 class MyFuture<T> implements Future<T> { | 1874 class MyFuture<T> implements Future<T> { |
1934 MyFuture() {} | 1875 MyFuture() {} |
1935 MyFuture.value(x) {} | 1876 MyFuture.value(x) {} |
1936 dynamic noSuchMethod(invocation); | 1877 dynamic noSuchMethod(invocation); |
1937 MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null; | 1878 MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null; |
1938 } | 1879 } |
1939 | 1880 |
1940 $downwards<int> g1(bool x) async { | 1881 $downwards<int> g1(bool x) async { |
1941 return x ? 42 : /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value(42); } | 1882 return x ? 42 : /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value(42); } |
1942 $downwards<int> g2(bool x) async => | 1883 $downwards<int> g2(bool x) async => |
1943 x ? 42 : /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value(42); | 1884 x ? 42 : /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value(42); |
1944 $downwards<int> g3(bool x) async { | 1885 $downwards<int> g3(bool x) async { |
1945 var y = x ? 42 : new $upwards.value(42); | 1886 var y = x ? 42 : new $upwards.value(42); |
1946 return y; | 1887 return y; |
1947 } | 1888 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1979 // in the resolver visitor isn't powerful enough to catch this for the | 1920 // in the resolver visitor isn't powerful enough to catch this for the |
1980 // subclass. See the TODO there. | 1921 // subclass. See the TODO there. |
1981 var allocInfo = | 1922 var allocInfo = |
1982 (upwards == "Future") ? "/*info:INFERRED_TYPE_ALLOCATION*/" : ""; | 1923 (upwards == "Future") ? "/*info:INFERRED_TYPE_ALLOCATION*/" : ""; |
1983 return ''' | 1924 return ''' |
1984 import 'dart:async'; | 1925 import 'dart:async'; |
1985 class MyFuture<T> implements Future<T> { | 1926 class MyFuture<T> implements Future<T> { |
1986 MyFuture() {} | 1927 MyFuture() {} |
1987 MyFuture.value([x]) {} | 1928 MyFuture.value([x]) {} |
1988 dynamic noSuchMethod(invocation); | 1929 dynamic noSuchMethod(invocation); |
1989 MyFuture<S> then<S>(dynamic f(T x), {Function onError}) => null; | 1930 MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null; |
1990 } | 1931 } |
1991 | 1932 |
1992 $declared f; | 1933 $declared f; |
1993 // Instantiates Future<int> | |
1994 $downwards<int> t1 = f.then((_) => | |
1995 ${allocInfo}new $upwards.value('hi')); | |
1996 | |
1997 // Instantiates List<int> | |
1998 $downwards<List<int>> t2 = f.then((_) => /*info:INFERRED_TYPE_LITERAL*/[3]); | |
1999 $downwards<List<int>> g2() async { return /*info:INFERRED_TYPE_LITERAL*/[3]; } | |
2000 $downwards<List<int>> g3() async { | |
2001 return /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value( | |
2002 /*info:INFERRED_TYPE_LITERAL*/[3]); } | |
2003 '''; | |
2004 } | |
2005 | |
2006 ; | |
2007 checkFile( | |
2008 build(declared: "MyFuture", downwards: "Future", upwards: "Future")); | |
2009 checkFile( | |
2010 build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture")); | |
2011 checkFile( | |
2012 build(declared: "Future", downwards: "Future", upwards: "Future")); | |
2013 checkFile( | |
2014 build(declared: "Future", downwards: "Future", upwards: "MyFuture")); | |
2015 } | |
2016 | |
2017 void test_futureUnion_downwards_comment() { | |
2018 String build({String declared, String downwards, String upwards}) { | |
2019 // TODO(leafp): The use of matchTypes in visitInstanceCreationExpression | |
2020 // in the resolver visitor isn't powerful enough to catch this for the | |
2021 // subclass. See the TODO there. | |
2022 var allocInfo = | |
2023 (upwards == "Future") ? "/*info:INFERRED_TYPE_ALLOCATION*/" : ""; | |
2024 return ''' | |
2025 import 'dart:async'; | |
2026 class MyFuture<T> implements Future<T> { | |
2027 MyFuture() {} | |
2028 MyFuture.value([x]) {} | |
2029 dynamic noSuchMethod(invocation); | |
2030 MyFuture/*<S>*/ then/*<S>*/(dynamic f(T x), {Function onError}) => null; | |
2031 } | |
2032 | |
2033 $declared f; | |
2034 // Instantiates Future<int> | 1934 // Instantiates Future<int> |
2035 $downwards<int> t1 = f.then((_) => | 1935 $downwards<int> t1 = f.then((_) => |
2036 ${allocInfo}new $upwards.value('hi')); | 1936 ${allocInfo}new $upwards.value('hi')); |
2037 | 1937 |
2038 // Instantiates List<int> | 1938 // Instantiates List<int> |
2039 $downwards<List<int>> t2 = f.then((_) => /*info:INFERRED_TYPE_LITERAL*/[3]); | 1939 $downwards<List<int>> t2 = f.then((_) => /*info:INFERRED_TYPE_LITERAL*/[3]); |
2040 $downwards<List<int>> g2() async { return /*info:INFERRED_TYPE_LITERAL*/[3]; } | 1940 $downwards<List<int>> g2() async { return /*info:INFERRED_TYPE_LITERAL*/[3]; } |
2041 $downwards<List<int>> g3() async { | 1941 $downwards<List<int>> g3() async { |
2042 return /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value( | 1942 return /*info:INFERRED_TYPE_ALLOCATION*/new $upwards.value( |
2043 /*info:INFERRED_TYPE_LITERAL*/[3]); } | 1943 /*info:INFERRED_TYPE_LITERAL*/[3]); } |
2044 '''; | 1944 '''; |
2045 } | 1945 } |
2046 | 1946 |
2047 ; | |
2048 checkFile( | 1947 checkFile( |
2049 build(declared: "MyFuture", downwards: "Future", upwards: "Future")); | 1948 build(declared: "MyFuture", downwards: "Future", upwards: "Future")); |
2050 checkFile( | 1949 checkFile( |
2051 build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture")); | 1950 build(declared: "MyFuture", downwards: "Future", upwards: "MyFuture")); |
2052 checkFile( | 1951 checkFile( |
2053 build(declared: "Future", downwards: "Future", upwards: "Future")); | 1952 build(declared: "Future", downwards: "Future", upwards: "Future")); |
2054 checkFile( | 1953 checkFile( |
2055 build(declared: "Future", downwards: "Future", upwards: "MyFuture")); | 1954 build(declared: "Future", downwards: "Future", upwards: "MyFuture")); |
2056 } | 1955 } |
2057 | 1956 |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2659 void test_genericMethods_IterableAndFuture() { | 2558 void test_genericMethods_IterableAndFuture() { |
2660 checkFile(''' | 2559 checkFile(''' |
2661 import 'dart:async'; | 2560 import 'dart:async'; |
2662 | 2561 |
2663 Future<int> make(int x) => (/*info:INFERRED_TYPE_ALLOCATION*/new Future(() => x)
); | 2562 Future<int> make(int x) => (/*info:INFERRED_TYPE_ALLOCATION*/new Future(() => x)
); |
2664 | 2563 |
2665 main() { | 2564 main() { |
2666 Iterable<Future<int>> list = <int>[1, 2, 3].map(make); | 2565 Iterable<Future<int>> list = <int>[1, 2, 3].map(make); |
2667 Future<List<int>> results = Future.wait(list); | 2566 Future<List<int>> results = Future.wait(list); |
2668 Future<String> results2 = results.then((List<int> list) | 2567 Future<String> results2 = results.then((List<int> list) |
2669 => list.fold('', /*info:INFERRED_TYPE_CLOSURE*/(x, y) => x + y.toString())); | 2568 => list.fold('', /*info:INFERRED_TYPE_CLOSURE*/(x, y) => /*info:DYNAMIC_CAST
,info:DYNAMIC_INVOKE*/x /*error:UNDEFINED_OPERATOR*/+ y.toString())); |
| 2569 |
| 2570 Future<String> results3 = results.then((List<int> list) |
| 2571 => list.fold('', /*info:INFERRED_TYPE_CLOSURE*/(String x, y) => x + y.toStri
ng())); |
2670 } | 2572 } |
2671 '''); | 2573 '''); |
2672 } | 2574 } |
2673 | 2575 |
2674 void test_genericMethods_usesGreatestLowerBound() { | 2576 void test_genericMethods_usesGreatestLowerBound() { |
2675 var mainUnit = checkFile(r''' | 2577 var mainUnit = checkFile(r''' |
2676 typedef Iterable<num> F(int x); | 2578 typedef Iterable<num> F(int x); |
2677 typedef List<int> G(double x); | 2579 typedef List<int> G(double x); |
2678 | 2580 |
2679 T generic<T>(a(T _), b(T _)) => null; | 2581 T generic<T>(a(T _), b(T _)) => null; |
(...skipping 2734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5414 T run<T>(T f()) { | 5316 T run<T>(T f()) { |
5415 print("running"); | 5317 print("running"); |
5416 var t = f(); | 5318 var t = f(); |
5417 print("done running"); | 5319 print("done running"); |
5418 return t; | 5320 return t; |
5419 } | 5321 } |
5420 | 5322 |
5421 | 5323 |
5422 void printRunning() { print("running"); } | 5324 void printRunning() { print("running"); } |
5423 var x = run<dynamic>(printRunning); | 5325 var x = run<dynamic>(printRunning); |
5424 var y = run(printRunning); | 5326 var y = /*info:USE_OF_VOID_RESULT*/run(printRunning); |
5425 | 5327 |
5426 main() { | 5328 main() { |
5427 void printRunning() { print("running"); } | 5329 void printRunning() { print("running"); } |
5428 var x = run<dynamic>(printRunning); | 5330 var x = run<dynamic>(printRunning); |
5429 var y = run(printRunning); | 5331 var y = /*info:USE_OF_VOID_RESULT*/run(printRunning); |
5430 x = 123; | 5332 x = 123; |
5431 x = 'hi'; | 5333 x = 'hi'; |
5432 y = 123; | 5334 y = /*error:INVALID_ASSIGNMENT*/123; |
5433 y = 'hi'; | 5335 y = /*error:INVALID_ASSIGNMENT*/'hi'; |
5434 } | 5336 } |
5435 '''); | 5337 '''); |
5436 | 5338 |
5437 var x = unit.topLevelVariables[0]; | 5339 var x = unit.topLevelVariables[0]; |
5438 var y = unit.topLevelVariables[1]; | 5340 var y = unit.topLevelVariables[1]; |
5439 expect(x.type.toString(), 'dynamic'); | 5341 expect(x.type.toString(), 'dynamic'); |
5440 expect(y.type.toString(), 'dynamic'); | 5342 expect(y.type.toString(), 'void'); |
5441 } | |
5442 | |
5443 void test_voidReturnTypeSubtypesDynamic_comment() { | |
5444 var unit = checkFile(r''' | |
5445 /*=T*/ run/*<T>*/(/*=T*/ f()) { | |
5446 print("running"); | |
5447 var t = f(); | |
5448 print("done running"); | |
5449 return t; | |
5450 } | |
5451 | |
5452 | |
5453 void printRunning() { print("running"); } | |
5454 var x = run/*<dynamic>*/(printRunning); | |
5455 var y = run(printRunning); | |
5456 | |
5457 main() { | |
5458 void printRunning() { print("running"); } | |
5459 var x = run/*<dynamic>*/(printRunning); | |
5460 var y = run(printRunning); | |
5461 x = 123; | |
5462 x = 'hi'; | |
5463 y = 123; | |
5464 y = 'hi'; | |
5465 } | |
5466 '''); | |
5467 | |
5468 var x = unit.topLevelVariables[0]; | |
5469 var y = unit.topLevelVariables[1]; | |
5470 expect(x.type.toString(), 'dynamic'); | |
5471 expect(y.type.toString(), 'dynamic'); | |
5472 } | 5343 } |
5473 } | 5344 } |
5474 | 5345 |
5475 @reflectiveTest | 5346 @reflectiveTest |
5476 class InferredTypeTest extends InferredTypeMixin { | 5347 class InferredTypeTest extends InferredTypeMixin { |
5477 @override | 5348 @override |
5478 bool get mayCheckTypesOfLocals => true; | 5349 bool get mayCheckTypesOfLocals => true; |
5479 | 5350 |
5480 /// Adds a file to check. The file should contain: | 5351 /// Adds a file to check. The file should contain: |
5481 /// | 5352 /// |
(...skipping 27 matching lines...) Expand all Loading... |
5509 } | 5380 } |
5510 | 5381 |
5511 void setUp() { | 5382 void setUp() { |
5512 helper.doSetUp(); | 5383 helper.doSetUp(); |
5513 } | 5384 } |
5514 | 5385 |
5515 void tearDown() { | 5386 void tearDown() { |
5516 helper.doTearDown(); | 5387 helper.doTearDown(); |
5517 } | 5388 } |
5518 } | 5389 } |
OLD | NEW |