Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: packages/analyzer/test/src/task/strong/non_null_checker_test.dart

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
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.
4
5 // These tests are for an experimental feature that treats Dart primitive types
6 // (int, bool, double, etc.) as non-nullable. This file is not evidence for an
7 // intention to officially support non-nullable primitives in Dart (or general
8 // NNBD, for that matter) so don't get too crazy about it.
9
10 library analyzer.test.src.task.non_null_primitives.checker_test;
11
12 import 'package:test_reflective_loader/test_reflective_loader.dart';
13
14 import '../strong/strong_test_helper.dart';
15
16 void main() {
17 initStrongModeTests();
18 defineReflectiveTests(NonNullCheckerTest);
19 }
20
21 String _withError(String file, String error) {
22 return ("" + file).replaceFirst("boom", error);
23 }
24
25 @reflectiveTest
26 class NonNullCheckerTest {
27 // Tests simple usage of ints as iterators for a loop. Not directly related to
28 // non-nullability, but if it is implemented this should be more efficient,
29 // since languages.length will not be null-checked on every iteration.
30 final String defaultNnbdExample = '''
31 class Point {
32 final int x, y;
33 Point(this.x, this.y);
34 Point operator +(Point other) => new Point(x + other.x, y + other.y);
35 String toString() => "x: \$x, y: \$y";
36 }
37
38 void main() {
39 Point p1 = new Point(0, 0);
40 Point p2 = new Point(10, 10);
41 print("p1 + p2 = \${p1 + p2}");
42 }
43 ''';
44
45 final String defaultNnbdExampleMod1 = '''
46 class Point {
47 final int x, y;
48 Point(this.x, this.y);
49 Point operator +(Point other) => new Point(x + other.x, y + other.y);
50 String toString() => "x: \$x, y: \$y";
51 }
52
53 void main() {
54 Point p1 = new Point(0, 0);
55 Point p2 = new Point(10, /*boom*/null); // Change here.
56 print("p1 + p2 = \${p1 + p2}");
57 }
58 ''';
59
60 final String defaultNnbdExampleMod2 = '''
61 class Point {
62 final int x, y;
63 Point(this.x, this.y);
64 Point operator +(Point other) => new Point(x + other.x, y + other.y);
65 String toString() => "x: \$x, y: \$y";
66 }
67
68 void main() {
69 bool f = false; // Necessary, because dead code is otherwise detected.
70 Point p1 = new Point(0, 0);
71 Point p2 = new Point(10, /*boom*/f ? 10 : null); // Change here.
72 print("p1 + p2 = \${p1 + p2}");
73 }
74 ''';
75
76 void test_assign_null_to_nonnullable() {
77 addFile('''
78 int x = 0;
79
80 main() {
81 x = 1;
82 x = /*error:INVALID_ASSIGNMENT*/null;
83 }
84 ''');
85 check(nonnullableTypes: <String>['dart:core,int']);
86 }
87
88 void test_forLoop() {
89 checkFile('''
90 class MyList {
91 int length;
92 MyList() {
93 length = 6;
94 }
95 String operator [](int i) {
96 return <String>["Dart", "Java", "JS", "C", "C++", "C#"][i];
97 }
98 }
99
100 main() {
101 var languages = new MyList();
102 for (int i = 0; i < languages.length; ++i) {
103 print(languages[i]);
104 }
105 }
106 ''');
107 }
108
109 void test_compoundAssignment() {
110 addFile('''
111 void main() {
112 int i = 1;
113 i += 2;
114 /*error:INVALID_ASSIGNMENT*/i += null;
115 print(i);
116 }
117 ''');
118 check(nonnullableTypes: <String>['dart:core,int']);
119 }
120
121 void test_forEach() {
122 addFile('''
123 void main() {
124 var ints = <num>[1, 2, 3, null];
125 for (int /*error:INVALID_ASSIGNMENT*/i in ints) {
126 print(i);
127 }
128 }
129 ''');
130 check(nonnullableTypes: <String>['dart:core,int']);
131 }
132
133 void test_initialize_nonnullable_with_null() {
134 addFile('int x = /*error:INVALID_ASSIGNMENT*/null;');
135 check(nonnullableTypes: <String>['dart:core,int']);
136 }
137
138 void test_initialize_nonnullable_with_valid_value() {
139 addFile('int x = 0;');
140 check(nonnullableTypes: <String>['dart:core,int']);
141 }
142
143 void test_nonnullable_fields() {
144 addFile(defaultNnbdExample);
145 // `null` can be passed as an argument to `Point` in default mode.
146 addFile(_withError(defaultNnbdExampleMod1, "error:INVALID_ASSIGNMENT"));
147 // A nullable expression can be passed as an argument to `Point` in default
148 // mode.
149 addFile(_withError(defaultNnbdExampleMod2, "error:INVALID_ASSIGNMENT"));
150 check(nonnullableTypes: <String>['dart:core,int']);
151 }
152
153 void test_nullable_fields() {
154 addFile(defaultNnbdExample);
155 // `null` can be passed as an argument to `Point` in default mode.
156 addFile(defaultNnbdExampleMod1);
157 // A nullable expression can be passed as an argument to `Point` in default
158 // mode.
159 addFile(defaultNnbdExampleMod2);
160 check();
161 }
162
163 // Default example from NNBD document.
164 void test_nullableTypes() {
165 // By default x can be set to null.
166 checkFile('int x = null;');
167 }
168
169 void test_prefer_final_to_non_nullable_error() {
170 addFile('main() { final int /*error:FINAL_NOT_INITIALIZED*/x; }');
171 addFile('final int /*error:FINAL_NOT_INITIALIZED*/x;');
172 addFile('''
173 void foo() {}
174
175 class A {
176 final int x;
177
178 /*warning:FINAL_NOT_INITIALIZED_CONSTRUCTOR_1*/A();
179 }
180 ''');
181 check(nonnullableTypes: <String>['dart:core,int']);
182 }
183
184 void test_uninitialized_nonnullable_field_declaration() {
185 addFile('''
186 void foo() {}
187
188 class A {
189 // Ideally, we should allow x to be init in the constructor, but that requires
190 // too much complication in the checker, so for now we throw a static error at
191 // the declaration site.
192 int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x;
193
194 A();
195 }
196 ''');
197 check(nonnullableTypes: <String>['dart:core,int']);
198 }
199
200 void test_uninitialized_nonnullable_local_variable() {
201 // Ideally, we will do flow analysis and throw an error only if a variable
202 // is used before it has been initialized.
203 addFile('main() { int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x; }');
204 check(nonnullableTypes: <String>['dart:core,int']);
205 }
206
207 void test_uninitialized_nonnullable_top_level_variable_declaration() {
208 // If `int`s are non-nullable, then this code should throw an error.
209 addFile('int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x;');
210 check(nonnullableTypes: <String>['dart:core,int']);
211 }
212
213 void test_method_call() {
214 addFile('''
215 int s(int x) {
216 return x + 1;
217 }
218
219 void main() {
220 s(10);
221 s(/*error:INVALID_ASSIGNMENT*/null);
222 }
223 ''');
224 check(nonnullableTypes: <String>['dart:core,int']);
225 }
226
227 void test_generics() {
228 addFile('''
229 class Foo<T> {
230 T x;
231
232 Foo(this.x);
233 }
234
235 void main() {
236 var f = new Foo<String>("hello");
237 var g = new Foo<int>(10);
238 var h = new Foo<String>(null);
239 var i = new Foo<int>(/*error:INVALID_ASSIGNMENT*/null);
240
241 print(f.x);
242 print(g.x);
243 print(h.x);
244 print(i.x);
245 }
246 ''');
247 addFile('''
248 class Foo<T> {
249 T x; // Should be annotated for a runtime check: x = (null as T)
250
251 Foo();
252 }
253
254 void main() {
255 var f = new Foo<String>();
256 var g = new Foo<int>(); // Should fail at runtime.
257 }
258 ''');
259 check(nonnullableTypes: <String>['dart:core,int']);
260 }
261
262 void test_map() {
263 addFile('''
264 class Pair<K, V> {
265 K first;
266 V second;
267
268 Pair(this.first, this.second);
269 }
270
271 class SlowMap<K, V> {
272 List<Pair<K, V>> array;
273 int arrayLength = 0;
274
275 SlowMap() : array = <Pair<K, V>>[];
276
277 void insert(K key, V value) {
278 array.add(new Pair<K, V>(key, value));
279 ++arrayLength;
280 }
281
282 bool has(K key) {
283 for (int i = 0; i < arrayLength; ++i) {
284 if (array[i].first == key) {
285 return true;
286 }
287 }
288 return false;
289 }
290
291 V get(K key) {
292 for (int i = 0; i < arrayLength; ++i) {
293 if (array[i].first == key) {
294 return array[i].second;
295 }
296 }
297 return null;
298 // TODO(stanm): generate explicit cast to V which will produce a runtime
299 // error if V is non-nullable. Optionally, generate a static warning too.
300 }
301 }
302
303 void main() {
304 var legs = new SlowMap<String, int>();
305 legs.insert("spider", 8);
306 legs.insert("goat", 4);
307 legs.insert("chicken", 2);
308
309 int x = legs.get("goat"); // This should not produce an error.
310 int y = legs.get("sheep"); // TODO(stanm): Runtime error here.
311 }
312 ''');
313 check(nonnullableTypes: <String>['dart:core,int']);
314 }
315 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698