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

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

Issue 2298913003: Pull in test_reflective_loader 0.0.4 and switch analyzer to it. (Closed)
Patch Set: Fixes for review comments. Created 4 years, 3 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
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 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 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 // These tests are for an experimental feature that treats Dart primitive types 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 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 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. 8 // NNBD, for that matter) so don't get too crazy about it.
9 9
10 library analyzer.test.src.task.non_null_primitives.checker_test; 10 library analyzer.test.src.task.non_null_primitives.checker_test;
11 11
12 import '../../../reflective_tests.dart'; 12 import 'package:test_reflective_loader/test_reflective_loader.dart';
13
13 import '../strong/strong_test_helper.dart'; 14 import '../strong/strong_test_helper.dart';
14 15
15 void main() { 16 void main() {
16 initStrongModeTests(); 17 initStrongModeTests();
17 runReflectiveTests(NonNullCheckerTest); 18 defineReflectiveTests(NonNullCheckerTest);
19 }
20
21 String _withError(String file, String error) {
22 return ("" + file).replaceFirst("boom", error);
18 } 23 }
19 24
20 @reflectiveTest 25 @reflectiveTest
21 class NonNullCheckerTest { 26 class NonNullCheckerTest {
22 // Tests simple usage of ints as iterators for a loop. Not directly related to 27 // Tests simple usage of ints as iterators for a loop. Not directly related to
23 // non-nullability, but if it is implemented this should be more efficient, 28 // non-nullability, but if it is implemented this should be more efficient,
24 // since languages.length will not be null-checked on every iteration. 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
25 void test_forLoop() { 88 void test_forLoop() {
26 checkFile(''' 89 checkFile('''
27 class MyList { 90 class MyList {
28 int length; 91 int length;
29 MyList() { 92 MyList() {
30 length = 6; 93 length = 6;
31 } 94 }
32 String operator [](int i) { 95 String operator [](int i) {
33 return <String>["Dart", "Java", "JS", "C", "C++", "C#"][i]; 96 return <String>["Dart", "Java", "JS", "C", "C++", "C#"][i];
34 } 97 }
35 } 98 }
36 99
37 main() { 100 main() {
38 var languages = new MyList(); 101 var languages = new MyList();
39 for (int i = 0; i < languages.length; ++i) { 102 for (int i = 0; i < languages.length; ++i) {
40 print(languages[i]); 103 print(languages[i]);
41 } 104 }
42 } 105 }
43 '''); 106 ''');
44 } 107 }
45 108
46 void test_nullableTypes() {
47 // By default x can be set to null.
48 checkFile('int x = null;');
49 }
50
51 void test_initialize_nonnullable_with_null() { 109 void test_initialize_nonnullable_with_null() {
52 addFile('int x = /*error:INVALID_ASSIGNMENT*/null;'); 110 addFile('int x = /*error:INVALID_ASSIGNMENT*/null;');
53 check(nonnullableTypes: <String>['dart:core,int']); 111 check(nonnullableTypes: <String>['dart:core,int']);
54 } 112 }
55 113
56 void test_initialize_nonnullable_with_valid_value() { 114 void test_initialize_nonnullable_with_valid_value() {
57 addFile('int x = 0;'); 115 addFile('int x = 0;');
58 check(nonnullableTypes: <String>['dart:core,int']); 116 check(nonnullableTypes: <String>['dart:core,int']);
59 } 117 }
60 118
61 void test_assign_null_to_nonnullable() { 119 void test_nonnullable_fields() {
62 addFile(''' 120 addFile(defaultNnbdExample);
63 int x = 0; 121 // `null` can be passed as an argument to `Point` in default mode.
64 122 addFile(_withError(defaultNnbdExampleMod1, "error:INVALID_ASSIGNMENT"));
65 main() { 123 // A nullable expression can be passed as an argument to `Point` in default
66 x = 1; 124 // mode.
67 x = /*error:INVALID_ASSIGNMENT*/null; 125 addFile(_withError(defaultNnbdExampleMod2, "error:INVALID_ASSIGNMENT"));
68 }
69 ''');
70 check(nonnullableTypes: <String>['dart:core,int']); 126 check(nonnullableTypes: <String>['dart:core,int']);
71 } 127 }
72 128
73 void test_uninitialized_nonnullable_local_variable() { 129 void test_nullable_fields() {
74 // Ideally, we will do flow analysis and throw an error only if a variable 130 addFile(defaultNnbdExample);
75 // is used before it has been initialized. 131 // `null` can be passed as an argument to `Point` in default mode.
76 addFile('main() { int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x; }'); 132 addFile(defaultNnbdExampleMod1);
77 check(nonnullableTypes: <String>['dart:core,int']); 133 // A nullable expression can be passed as an argument to `Point` in default
134 // mode.
135 addFile(defaultNnbdExampleMod2);
136 check();
78 } 137 }
79 138
80 void test_uninitialized_nonnullable_top_level_variable_declaration() { 139 // Default example from NNBD document.
81 // If `int`s are non-nullable, then this code should throw an error. 140 void test_nullableTypes() {
82 addFile('int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x;'); 141 // By default x can be set to null.
142 checkFile('int x = null;');
143 }
144
145 void test_prefer_final_to_non_nullable_error() {
146 addFile('main() { final int /*error:FINAL_NOT_INITIALIZED*/x; }');
147 addFile('final int /*error:FINAL_NOT_INITIALIZED*/x;');
148 addFile('''
149 void foo() {}
150
151 class A {
152 final int x;
153
154 /*warning:FINAL_NOT_INITIALIZED_CONSTRUCTOR_1*/A();
155 }
156 ''');
83 check(nonnullableTypes: <String>['dart:core,int']); 157 check(nonnullableTypes: <String>['dart:core,int']);
84 } 158 }
85 159
86 void test_uninitialized_nonnullable_field_declaration() { 160 void test_uninitialized_nonnullable_field_declaration() {
87 addFile(''' 161 addFile('''
88 void foo() {} 162 void foo() {}
89 163
90 class A { 164 class A {
91 // Ideally, we should allow x to be init in the constructor, but that requires 165 // Ideally, we should allow x to be init in the constructor, but that requires
92 // too much complication in the checker, so for now we throw a static error at 166 // too much complication in the checker, so for now we throw a static error at
93 // the declaration site. 167 // the declaration site.
94 int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x; 168 int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x;
95 169
96 A(); 170 A();
97 } 171 }
98 '''); 172 ''');
99 check(nonnullableTypes: <String>['dart:core,int']); 173 check(nonnullableTypes: <String>['dart:core,int']);
100 } 174 }
101 175
102 void test_prefer_final_to_non_nullable_error() { 176 void test_uninitialized_nonnullable_local_variable() {
103 addFile('main() { final int /*error:FINAL_NOT_INITIALIZED*/x; }'); 177 // Ideally, we will do flow analysis and throw an error only if a variable
104 addFile('final int /*error:FINAL_NOT_INITIALIZED*/x;'); 178 // is used before it has been initialized.
105 addFile(''' 179 addFile('main() { int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x; }');
106 void foo() {}
107
108 class A {
109 final int x;
110
111 /*warning:FINAL_NOT_INITIALIZED_CONSTRUCTOR_1*/A();
112 }
113 ''');
114 check(nonnullableTypes: <String>['dart:core,int']); 180 check(nonnullableTypes: <String>['dart:core,int']);
115 } 181 }
116 182
117 // Default example from NNBD document. 183 void test_uninitialized_nonnullable_top_level_variable_declaration() {
118 final String defaultNnbdExample = ''' 184 // If `int`s are non-nullable, then this code should throw an error.
119 class Point { 185 addFile('int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x;');
120 final int x, y;
121 Point(this.x, this.y);
122 Point operator +(Point other) => new Point(x + other.x, y + other.y);
123 String toString() => "x: \$x, y: \$y";
124 }
125
126 void main() {
127 Point p1 = new Point(0, 0);
128 Point p2 = new Point(10, 10);
129 print("p1 + p2 = \${p1 + p2}");
130 }
131 ''';
132
133 final String defaultNnbdExampleMod1 = '''
134 class Point {
135 final int x, y;
136 Point(this.x, this.y);
137 Point operator +(Point other) => new Point(x + other.x, y + other.y);
138 String toString() => "x: \$x, y: \$y";
139 }
140
141 void main() {
142 Point p1 = new Point(0, 0);
143 Point p2 = new Point(10, /*boom*/null); // Change here.
144 print("p1 + p2 = \${p1 + p2}");
145 }
146 ''';
147
148 final String defaultNnbdExampleMod2 = '''
149 class Point {
150 final int x, y;
151 Point(this.x, this.y);
152 Point operator +(Point other) => new Point(x + other.x, y + other.y);
153 String toString() => "x: \$x, y: \$y";
154 }
155
156 void main() {
157 bool f = false; // Necessary, because dead code is otherwise detected.
158 Point p1 = new Point(0, 0);
159 Point p2 = new Point(10, /*boom*/f ? 10 : null); // Change here.
160 print("p1 + p2 = \${p1 + p2}");
161 }
162 ''';
163
164 void test_nullable_fields() {
165 addFile(defaultNnbdExample);
166 // `null` can be passed as an argument to `Point` in default mode.
167 addFile(defaultNnbdExampleMod1);
168 // A nullable expression can be passed as an argument to `Point` in default
169 // mode.
170 addFile(defaultNnbdExampleMod2);
171 check();
172 }
173
174 void test_nonnullable_fields() {
175 addFile(defaultNnbdExample);
176 // `null` can be passed as an argument to `Point` in default mode.
177 addFile(_withError(defaultNnbdExampleMod1, "error:INVALID_ASSIGNMENT"));
178 // A nullable expression can be passed as an argument to `Point` in default
179 // mode.
180 addFile(_withError(defaultNnbdExampleMod2, "error:INVALID_ASSIGNMENT"));
181 check(nonnullableTypes: <String>['dart:core,int']); 186 check(nonnullableTypes: <String>['dart:core,int']);
182 } 187 }
183 } 188 }
184
185 String _withError(String file, String error) {
186 return ("" + file).replaceFirst("boom", error);
187 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698