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.checker_test; | 5 library analyzer.test.src.task.strong.checker_test; |
6 | 6 |
7 import '../../../reflective_tests.dart'; | 7 import '../../../reflective_tests.dart'; |
8 import 'strong_test_helper.dart'; | 8 import 'strong_test_helper.dart'; |
9 | 9 |
10 void main() { | 10 void main() { |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
308 a[b] += d; | 308 a[b] += d; |
309 a[/*info:DYNAMIC_CAST*/c] += d; | 309 a[/*info:DYNAMIC_CAST*/c] += d; |
310 a[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z] += d; | 310 a[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z] += d; |
311 a[b] += /*info:DYNAMIC_CAST*/c; | 311 a[b] += /*info:DYNAMIC_CAST*/c; |
312 a[b] += /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z; | 312 a[b] += /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z; |
313 /*info:DYNAMIC_INVOKE,info:DYNAMIC_INVOKE*/c[b] += d; | 313 /*info:DYNAMIC_INVOKE,info:DYNAMIC_INVOKE*/c[b] += d; |
314 } | 314 } |
315 '''); | 315 '''); |
316 } | 316 } |
317 | 317 |
318 void test_constructorInvalid() { | |
319 // Regression test for https://github.com/dart-lang/sdk/issues/26695 | |
320 checkFile(''' | |
321 class A { | |
322 B({ /*error:FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR*/this.test: 1.0 }) {} | |
323 final double test = 0.0; | |
324 } | |
325 '''); | |
326 } | |
327 | |
318 void test_constructors() { | 328 void test_constructors() { |
319 checkFile(''' | 329 checkFile(''' |
320 const num z = 25; | 330 const num z = 25; |
321 Object obj = "world"; | 331 Object obj = "world"; |
322 | 332 |
323 class A { | 333 class A { |
324 int x; | 334 int x; |
325 String y; | 335 String y; |
326 | 336 |
327 A(this.x) : this.y = /*warning:FIELD_INITIALIZER_NOT_ASSIGNABLE*/42; | 337 A(this.x) : this.y = /*warning:FIELD_INITIALIZER_NOT_ASSIGNABLE*/42; |
(...skipping 14 matching lines...) Expand all Loading... | |
342 B.c3(num x, Object y) : super.c3(x, /*info:DOWN_CAST_IMPLICIT*/y); | 352 B.c3(num x, Object y) : super.c3(x, /*info:DOWN_CAST_IMPLICIT*/y); |
343 } | 353 } |
344 | 354 |
345 void main() { | 355 void main() { |
346 A a = new A.c2(/*info:DOWN_CAST_IMPLICIT*/z, /*warning:ARGUMENT_TYPE_NOT_ASSI GNABLE*/z); | 356 A a = new A.c2(/*info:DOWN_CAST_IMPLICIT*/z, /*warning:ARGUMENT_TYPE_NOT_ASSI GNABLE*/z); |
347 var b = new B.c2(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello", /*info:DOWN _CAST_IMPLICIT*/obj); | 357 var b = new B.c2(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello", /*info:DOWN _CAST_IMPLICIT*/obj); |
348 } | 358 } |
349 '''); | 359 '''); |
350 } | 360 } |
351 | 361 |
352 void test_constructorInvalid() { | |
353 // Regression test for https://github.com/dart-lang/sdk/issues/26695 | |
354 checkFile(''' | |
355 class A { | |
356 B({ /*error:FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR*/this.test: 1.0 }) {} | |
357 final double test = 0.0; | |
358 } | |
359 '''); | |
360 } | |
361 | |
362 void test_conversionAndDynamicInvoke() { | 362 void test_conversionAndDynamicInvoke() { |
363 addFile( | 363 addFile( |
364 ''' | 364 ''' |
365 dynamic toString = (int x) => x + 42; | 365 dynamic toString = (int x) => x + 42; |
366 dynamic hashCode = "hello"; | 366 dynamic hashCode = "hello"; |
367 ''', | 367 ''', |
368 name: '/helper.dart'); | 368 name: '/helper.dart'); |
369 checkFile(''' | 369 checkFile(''' |
370 import 'helper.dart' as helper; | 370 import 'helper.dart' as helper; |
371 | 371 |
(...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1904 for (;/*info:DOWN_CAST_IMPLICIT*/obj;) {} | 1904 for (;/*info:DOWN_CAST_IMPLICIT*/obj;) {} |
1905 for (;/*error:NON_BOOL_CONDITION*/i;) {} | 1905 for (;/*error:NON_BOOL_CONDITION*/i;) {} |
1906 } | 1906 } |
1907 '''); | 1907 '''); |
1908 } | 1908 } |
1909 | 1909 |
1910 void test_implicitCasts() { | 1910 void test_implicitCasts() { |
1911 addFile('num n; int i = /*info:ASSIGNMENT_CAST*/n;'); | 1911 addFile('num n; int i = /*info:ASSIGNMENT_CAST*/n;'); |
1912 check(); | 1912 check(); |
1913 // TODO(jmesserly): should not be emitting the hint as well as the error. | 1913 // TODO(jmesserly): should not be emitting the hint as well as the error. |
1914 // It is a "strong mode hint" however, so it will not be user visible. | |
1914 addFile( | 1915 addFile( |
1915 'num n; int i = /*info:ASSIGNMENT_CAST,error:INVALID_ASSIGNMENT*/n;'); | 1916 'num n; int i = /*info:ASSIGNMENT_CAST,error:INVALID_ASSIGNMENT*/n;'); |
1916 check(implicitCasts: false); | 1917 check(implicitCasts: false); |
1917 } | 1918 } |
1918 | 1919 |
1920 void test_implicitDynamic_field() { | |
1921 addFile(r''' | |
1922 class C { | |
1923 var /*error:IMPLICIT_DYNAMIC_FIELD*/x0; | |
1924 var /*error:IMPLICIT_DYNAMIC_FIELD*/x1 = (<dynamic>[])[0]; | |
Bob Nystrom
2016/06/23 23:25:52
This one is a little surprising to me. My intuitio
Jennifer Messerly
2016/06/24 01:15:56
Yeah, I added it for illustration. The current tec
| |
1925 var /*error:IMPLICIT_DYNAMIC_FIELD*/x2, | |
1926 x3 = 42, | |
1927 /*error:IMPLICIT_DYNAMIC_FIELD*/x4; | |
1928 dynamic y0; | |
1929 dynamic y1 = (<dynamic>[])[0]; | |
1930 } | |
1931 '''); | |
1932 check(implicitDynamic: false); | |
1933 } | |
1934 | |
1935 void test_implicitDynamic_function() { | |
1936 addFile(r''' | |
1937 /*=T*/ a/*<T>*/(/*=T*/ t) => t; | |
1938 /*=T*/ b/*<T>*/() => null; | |
1939 | |
1940 void main/*<S>*/() { | |
1941 dynamic d; | |
1942 int i; | |
1943 /*error:IMPLICIT_DYNAMIC_FUNCTION*/a(d); | |
1944 a(42); | |
1945 /*error:IMPLICIT_DYNAMIC_FUNCTION*/b(); | |
1946 d = /*error:IMPLICIT_DYNAMIC_FUNCTION*/b(); | |
1947 i = b(); | |
1948 | |
1949 void f/*<T>*/(/*=T*/ t) {}; | |
1950 /*=T*/ g/*<T>*/() => null; | |
1951 | |
1952 /*error:IMPLICIT_DYNAMIC_FUNCTION*/f(d); | |
1953 f(42); | |
1954 /*error:IMPLICIT_DYNAMIC_FUNCTION*/g(); | |
1955 d = /*error:IMPLICIT_DYNAMIC_FUNCTION*/g(); | |
1956 i = g(); | |
1957 | |
1958 /*error:IMPLICIT_DYNAMIC_INVOKE*/(/*<T>*/(/*=T*/ t) => t)(d); | |
1959 (/*<T>*/(/*=T*/ t) => t)(42); | |
1960 (/*<T>*/() => null as dynamic/*=T*/)/*<int>*/(); | |
1961 } | |
Bob Nystrom
2016/06/23 23:25:52
These test cases are fantastic. So thorough!
Jennifer Messerly
2016/06/24 01:15:56
Thanks. Wanted to illustrate what it does, especia
Leaf
2016/06/24 21:40:26
+1!
| |
1962 '''); | |
1963 check(implicitDynamic: false); | |
1964 } | |
1965 void test_implicitDynamic_listLiteral() { | |
1966 addFile(r''' | |
1967 | |
1968 var l0 = /*error:IMPLICIT_DYNAMIC_LIST_LITERAL*/[]; | |
1969 List l1 = /*error:IMPLICIT_DYNAMIC_LIST_LITERAL*/[]; | |
1970 List<dynamic> l2 = /*error:IMPLICIT_DYNAMIC_LIST_LITERAL*/[]; | |
Bob Nystrom
2016/06/23 23:25:52
This case is interesting too. This might be one to
Jennifer Messerly
2016/06/24 01:15:55
Yeah this dovetails into my other comment. We woul
| |
1971 dynamic d = 42; | |
1972 var l3 = /*error:IMPLICIT_DYNAMIC_LIST_LITERAL*/[d, d]; | |
Bob Nystrom
2016/06/23 23:25:52
I *think* I would consider this to be explicit. On
Jennifer Messerly
2016/06/24 01:15:55
That is an error in the current impl. makePair is
| |
1973 | |
1974 var l4 = <dynamic>[]; | |
1975 var l5 = <int>[]; | |
1976 List<int> l6 = /*info:INFERRED_TYPE_LITERAL*/[]; | |
1977 var l7 = /*info:INFERRED_TYPE_LITERAL*/[42]; | |
1978 '''); | |
1979 check(implicitDynamic: false); | |
1980 } | |
1981 | |
1982 void test_implicitDynamic_mapLiteral() { | |
1983 addFile(r''' | |
1984 var m0 = /*error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{}; | |
1985 Map m1 = /*error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{}; | |
1986 Map<dynamic, dynamic> m2 = /*error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{}; | |
1987 dynamic d = 42; | |
1988 var m3 = /*error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{d: d}; | |
1989 var m4 = /*info:INFERRED_TYPE_LITERAL,error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{'x': d, 'y': d}; | |
1990 var m5 = /*info:INFERRED_TYPE_LITERAL,error:IMPLICIT_DYNAMIC_MAP_LITERAL*/{d: 'x '}; | |
1991 | |
1992 var m6 = <dynamic, dynamic>{}; | |
1993 var m7 = <String, String>{}; | |
1994 Map<String, String> m8 = /*info:INFERRED_TYPE_LITERAL*/{}; | |
1995 var m9 = /*info:INFERRED_TYPE_LITERAL*/{'hi': 'there'}; | |
1996 '''); | |
1997 check(implicitDynamic: false); | |
1998 } | |
1999 | |
2000 void test_implicitDynamic_method() { | |
2001 addFile(r''' | |
2002 class C { | |
2003 /*=T*/ m/*<T>*/(/*=T*/ s) => s; | |
2004 /*=T*/ n/*<T>*/() => null; | |
2005 } | |
2006 class D<E> { | |
2007 /*=T*/ m/*<T>*/(/*=T*/ s) => s; | |
2008 /*=T*/ n/*<T>*/() => null; | |
2009 } | |
2010 void f() { | |
2011 dynamic d; | |
2012 int i; | |
2013 new C()./*error:IMPLICIT_DYNAMIC_METHOD*/m(d); | |
2014 new C().m(42); | |
2015 new C()./*error:IMPLICIT_DYNAMIC_METHOD*/n(); | |
2016 d = new C()./*error:IMPLICIT_DYNAMIC_METHOD*/n(); | |
2017 i = new C().n(); | |
2018 | |
2019 new D<int>()./*error:IMPLICIT_DYNAMIC_METHOD*/m(d); | |
Bob Nystrom
2016/06/23 23:25:52
This feels like an explicit use of dynamic to me s
Jennifer Messerly
2016/06/24 01:15:56
yes, same as your other examples. They will either
| |
2020 new D<int>().m(42); | |
2021 new D<int>()./*error:IMPLICIT_DYNAMIC_METHOD*/n(); | |
2022 d = new D<int>()./*error:IMPLICIT_DYNAMIC_METHOD*/n(); | |
2023 i = new D<int>().n(); | |
2024 } | |
2025 '''); | |
2026 check(implicitDynamic: false); | |
2027 } | |
2028 | |
2029 void test_implicitDynamic_parameter() { | |
2030 addFile(r''' | |
2031 const dynamic DYNAMIC_VALUE = 42; | |
2032 | |
2033 // simple formal | |
2034 void f0(/*error:IMPLICIT_DYNAMIC_PARAMETER*/x) {} | |
2035 void f1(dynamic x) {} | |
2036 | |
2037 // default formal | |
2038 void df0([/*error:IMPLICIT_DYNAMIC_PARAMETER*/x = DYNAMIC_VALUE]) {} | |
2039 void df1([dynamic x = DYNAMIC_VALUE]) {} | |
2040 | |
2041 // BUG: this should work, see https://github.com/dart-lang/sdk/issues/25794 | |
2042 void df2([/*error:IMPLICIT_DYNAMIC_PARAMETER*/x = 42]) {} | |
2043 | |
2044 // default formal (named) | |
2045 void nf0({/*error:IMPLICIT_DYNAMIC_PARAMETER*/x: DYNAMIC_VALUE}) {} | |
2046 void nf1({dynamic x: DYNAMIC_VALUE}) {} | |
2047 | |
2048 // BUG: this should work, see https://github.com/dart-lang/sdk/issues/25794 | |
2049 void nf2({/*error:IMPLICIT_DYNAMIC_PARAMETER*/x: 42}) {} | |
2050 | |
2051 // field formal | |
2052 class C { | |
2053 var /*error:IMPLICIT_DYNAMIC_FIELD*/x; | |
2054 C(this.x); | |
2055 } | |
2056 | |
2057 // function typed formal | |
2058 void ftf0(void x(/*error:IMPLICIT_DYNAMIC_PARAMETER*/y)) {} | |
2059 void ftf1(void x(int y)) {} | |
2060 '''); | |
2061 check(implicitDynamic: false); | |
2062 } | |
2063 | |
2064 void test_implicitDynamic_return() { | |
2065 addFile(r''' | |
2066 // function | |
2067 /*error:IMPLICIT_DYNAMIC_RETURN*/f0() {} | |
2068 dynamic f1() { return 42; } | |
2069 | |
2070 // nested function | |
2071 void main() { | |
2072 /*error:IMPLICIT_DYNAMIC_RETURN*/g0() {} | |
2073 dynamic g1() { return 42; } | |
2074 } | |
2075 | |
2076 // methods | |
2077 class B { | |
2078 int m1() => 42; | |
2079 } | |
2080 class C extends B { | |
2081 /*error:IMPLICIT_DYNAMIC_RETURN*/m0() => 123; | |
2082 m1() => 123; | |
2083 dynamic m2() => 'hi'; | |
2084 } | |
2085 | |
2086 // accessors | |
2087 set x(int value) {} | |
2088 /*error:IMPLICIT_DYNAMIC_RETURN*/get y0 => 42; | |
2089 dynamic get y1 => 42; | |
2090 | |
2091 // function typed formals | |
2092 void ftf0(/*error:IMPLICIT_DYNAMIC_RETURN*/f(int x)) {} | |
2093 void ftf1(dynamic f(int x)) {} | |
2094 | |
2095 // function expressions | |
2096 var fe0 = /*error:IMPLICIT_DYNAMIC_RETURN*/(int x) => x as dynamic; | |
2097 var fe1 = (int x) => x; | |
2098 '''); | |
2099 check(implicitDynamic: false); | |
2100 } | |
2101 | |
2102 void test_implicitDynamic_type() { | |
2103 addFile(r''' | |
2104 class C<T> {} | |
2105 class M1<T extends /*error:IMPLICIT_DYNAMIC_TYPE*/List> {} | |
2106 class M2<T> {} | |
2107 class I<T> {} | |
2108 class D<T, S> extends /*error:IMPLICIT_DYNAMIC_TYPE*/C | |
2109 with M1, /*error:IMPLICIT_DYNAMIC_TYPE*/M2 | |
2110 implements /*error:IMPLICIT_DYNAMIC_TYPE*/I {} | |
2111 | |
2112 C f(D d) { | |
2113 D x = new /*error:IMPLICIT_DYNAMIC_TYPE*/D(); | |
2114 D<int, dynamic> y = /*info:INFERRED_TYPE_ALLOCATION*/new /*error:IMPLICIT_DYNA MIC_TYPE*/D(); | |
2115 D<dynamic, int> z = /*info:INFERRED_TYPE_ALLOCATION*/new /*error:IMPLICIT_DYNA MIC_TYPE*/D(); | |
2116 return new /*error:IMPLICIT_DYNAMIC_TYPE*/C(); | |
2117 } | |
2118 | |
2119 class A<T extends num> {} | |
2120 class N1<T extends List<int>> {} | |
2121 class N2<T extends Object> {} | |
2122 class J<T extends Object> {} | |
2123 class B<T extends Object> extends A with N1, N2 implements J {} | |
2124 A g(B b) { | |
2125 B y = /*info:INFERRED_TYPE_ALLOCATION*/new B(); | |
2126 return /*info:INFERRED_TYPE_ALLOCATION*/new A(); | |
2127 } | |
2128 '''); | |
2129 check(implicitDynamic: false); | |
2130 } | |
2131 | |
2132 void test_implicitDynamic_variable() { | |
2133 addFile(r''' | |
2134 var /*error:IMPLICIT_DYNAMIC_VARIABLE*/x0; | |
2135 var /*error:IMPLICIT_DYNAMIC_VARIABLE*/x1 = (<dynamic>[])[0]; | |
2136 var /*error:IMPLICIT_DYNAMIC_VARIABLE*/x2, | |
2137 x3 = 42, | |
2138 /*error:IMPLICIT_DYNAMIC_VARIABLE*/x4; | |
2139 dynamic y0; | |
2140 dynamic y1 = (<dynamic>[])[0]; | |
2141 '''); | |
2142 check(implicitDynamic: false); | |
2143 } | |
2144 | |
1919 void test_invalidOverrides_baseClassOverrideToChildInterface() { | 2145 void test_invalidOverrides_baseClassOverrideToChildInterface() { |
1920 checkFile(''' | 2146 checkFile(''' |
1921 class A {} | 2147 class A {} |
1922 class B {} | 2148 class B {} |
1923 | 2149 |
1924 abstract class I { | 2150 abstract class I { |
1925 m(A a); | 2151 m(A a); |
1926 } | 2152 } |
1927 | 2153 |
1928 class Base { | 2154 class Base { |
(...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3309 // Regression test for https://github.com/dart-lang/sdk/issues/25069 | 3535 // Regression test for https://github.com/dart-lang/sdk/issues/25069 |
3310 checkFile(''' | 3536 checkFile(''' |
3311 typedef int Foo(); | 3537 typedef int Foo(); |
3312 void foo() {} | 3538 void foo() {} |
3313 void main () { | 3539 void main () { |
3314 Foo x = /*error:INVALID_ASSIGNMENT,info:USE_OF_VOID_RESULT*/foo(); | 3540 Foo x = /*error:INVALID_ASSIGNMENT,info:USE_OF_VOID_RESULT*/foo(); |
3315 } | 3541 } |
3316 '''); | 3542 '''); |
3317 } | 3543 } |
3318 } | 3544 } |
OLD | NEW |