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

Side by Side Diff: test/checker/inferred_type_test.dart

Issue 1028793002: Transitive inference using SCC (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: transitive inference on Created 5 years, 9 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) 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 /// Tests for type inference. 5 /// Tests for type inference.
6 library dev_compiler.test.inferred_type_test; 6 library dev_compiler.test.inferred_type_test;
7 7
8 import 'package:unittest/unittest.dart'; 8 import 'package:unittest/unittest.dart';
9 9
10 import 'package:dev_compiler/src/testing.dart'; 10 import 'package:dev_compiler/src/testing.dart';
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 y = /*severe:StaticTypeError*/"hi"; 155 y = /*severe:StaticTypeError*/"hi";
156 A.x = "hi"; 156 A.x = "hi";
157 A.y = /*severe:StaticTypeError*/"hi"; 157 A.y = /*severe:StaticTypeError*/"hi";
158 new A().x2 = "hi"; 158 new A().x2 = "hi";
159 new A().y2 = /*severe:StaticTypeError*/"hi"; 159 new A().y2 = /*severe:StaticTypeError*/"hi";
160 } 160 }
161 ''' 161 '''
162 }); 162 });
163 }); 163 });
164 164
165 test('do not infer from variables in same lib (order independence)', () { 165 test('do not infer from variables if flag is off', () {
166 testChecker({ 166 testChecker({
167 '/main.dart': ''' 167 '/main.dart': '''
168 var x = 2; 168 var x = 2;
169 var y = x; 169 var y = x;
170 170
171 test1() { 171 test1() {
172 x = /*severe:StaticTypeError*/"hi"; 172 x = /*severe:StaticTypeError*/"hi";
173 y = "hi"; 173 y = "hi";
174 } 174 }
175 ''' 175 '''
176 }); 176 }, inferTransitively: false);
177 177
178 testChecker({ 178 testChecker({
179 '/main.dart': ''' 179 '/main.dart': '''
180 class A { 180 class A {
181 static var x = 2; 181 static var x = 2;
182 static var y = A.x; 182 static var y = A.x;
183 } 183 }
184 184
185 test1() { 185 test1() {
186 A.x = /*severe:StaticTypeError*/"hi"; 186 A.x = /*severe:StaticTypeError*/"hi";
187 A.y = "hi"; 187 A.y = "hi";
188 } 188 }
189 ''' 189 '''
190 }); 190 }, inferTransitively: false);
191 }); 191 });
192 192
193 test('not ok to infer from variables in non-cycle libs', () { 193 test('do not infer from variables in non-cycle imports if flag is off', () {
194 testChecker({ 194 testChecker({
195 '/a.dart': ''' 195 '/a.dart': '''
196 var x = 2; 196 var x = 2;
197 ''', 197 ''',
198 '/main.dart': ''' 198 '/main.dart': '''
199 import 'a.dart'; 199 import 'a.dart';
200 var y = x; 200 var y = x;
201 201
202 test1() { 202 test1() {
203 x = /*severe:StaticTypeError*/"hi"; 203 x = /*severe:StaticTypeError*/"hi";
204 y = "hi"; 204 y = "hi";
205 } 205 }
206 ''' 206 '''
207 }); 207 }, inferTransitively: false);
208 208
209 testChecker({ 209 testChecker({
210 '/a.dart': ''' 210 '/a.dart': '''
211 class A { static var x = 2; } 211 class A { static var x = 2; }
212 ''', 212 ''',
213 '/main.dart': ''' 213 '/main.dart': '''
214 import 'a.dart'; 214 import 'a.dart';
215 class B { static var y = A.x; } 215 class B { static var y = A.x; }
216 216
217 test1() { 217 test1() {
218 A.x = /*severe:StaticTypeError*/"hi"; 218 A.x = /*severe:StaticTypeError*/"hi";
219 B.y = "hi"; 219 B.y = "hi";
220 } 220 }
221 ''' 221 '''
222 }); 222 }, inferTransitively: false);
223 }); 223 });
224 224
225 test('ok to infer from variables in non-cycle libs with flag', () { 225 test('infer from variables in non-cycle imports with flag', () {
226 testChecker({ 226 testChecker({
227 '/a.dart': ''' 227 '/a.dart': '''
228 var x = 2; 228 var x = 2;
229 ''', 229 ''',
230 '/main.dart': ''' 230 '/main.dart': '''
231 import 'a.dart'; 231 import 'a.dart';
232 var y = x; 232 var y = x;
233 233
234 test1() { 234 test1() {
235 x = /*severe:StaticTypeError*/"hi"; 235 x = /*severe:StaticTypeError*/"hi";
(...skipping 11 matching lines...) Expand all
247 class B { static var y = A.x; } 247 class B { static var y = A.x; }
248 248
249 test1() { 249 test1() {
250 A.x = /*severe:StaticTypeError*/"hi"; 250 A.x = /*severe:StaticTypeError*/"hi";
251 B.y = /*severe:StaticTypeError*/"hi"; 251 B.y = /*severe:StaticTypeError*/"hi";
252 } 252 }
253 ''' 253 '''
254 }, inferTransitively: true); 254 }, inferTransitively: true);
255 }); 255 });
256 256
257 test('do not infer from variables in cycle libs', () { 257 test('do not infer from variables in cycle libs when flag is off', () {
258 testChecker({ 258 testChecker({
259 '/a.dart': ''' 259 '/a.dart': '''
260 import 'main.dart'; 260 import 'main.dart';
261 var x = 2; // ok to infer 261 var x = 2; // ok to infer
262 ''', 262 ''',
263 '/main.dart': ''' 263 '/main.dart': '''
264 import 'a.dart'; 264 import 'a.dart';
265 var y = x; // not ok to infer yet 265 var y = x; // not ok to infer yet
266 266
267 test1() { 267 test1() {
268 int t = 3; 268 int t = 3;
269 t = x; 269 t = x;
270 t = /*info:DownCast*/y; 270 t = /*info:DownCast*/y;
271 } 271 }
272 ''' 272 '''
273 }, inferTransitively: false);
274
275 testChecker({
276 '/a.dart': '''
277 import 'main.dart';
278 class A { static var x = 2; }
279 ''',
280 '/main.dart': '''
281 import 'a.dart';
282 class B { static var y = A.x; }
283
284 test1() {
285 int t = 3;
286 t = A.x;
287 t = /*info:DownCast*/B.y;
288 }
289 '''
290 }, inferTransitively: false);
291 });
292
293 test('infer from variables in cycle libs when flag is on', () {
294 testChecker({
295 '/a.dart': '''
296 import 'main.dart';
297 var x = 2; // ok to infer
298 ''',
299 '/main.dart': '''
300 import 'a.dart';
301 var y = x; // now ok :)
302
303 test1() {
304 int t = 3;
305 t = x;
306 t = y;
307 }
308 '''
273 }, inferTransitively: true); 309 }, inferTransitively: true);
274 310
275 testChecker({ 311 testChecker({
276 '/a.dart': ''' 312 '/a.dart': '''
277 import 'main.dart'; 313 import 'main.dart';
278 class A { static var x = 2; } 314 class A { static var x = 2; }
279 ''', 315 ''',
280 '/main.dart': ''' 316 '/main.dart': '''
281 import 'a.dart'; 317 import 'a.dart';
282 class B { static var y = A.x; } 318 class B { static var y = A.x; }
283 319
284 test1() { 320 test1() {
285 int t = 3; 321 int t = 3;
286 t = A.x; 322 t = A.x;
287 t = /*info:DownCast*/A.y; 323 t = B.y;
288 } 324 }
289 ''' 325 '''
290 }, inferTransitively: true); 326 }, inferTransitively: true);
291 }); 327 });
292 328
293 test('do not infer from static and instance fields', () { 329 test('do not infer from static and instance fields when flag is off', () {
294 testChecker({ 330 testChecker({
295 '/a.dart': ''' 331 '/a.dart': '''
296 import 'b.dart'; 332 import 'b.dart';
297 class A { 333 class A {
298 static final a1 = B.b1; 334 static final a1 = B.b1;
299 final a2 = new B().b2; 335 final a2 = new B().b2;
300 } 336 }
301 ''', 337 ''',
302 '/b.dart': ''' 338 '/b.dart': '''
303 class B { 339 class B {
304 static final b1 = 1; 340 static final b1 = 1;
305 final b2 = 1; 341 final b2 = 1;
306 } 342 }
307 ''', 343 ''',
308 '/main.dart': ''' 344 '/main.dart': '''
309 import "a.dart"; 345 import "a.dart";
310 346
311 test1() { 347 test1() {
312 int x = 0; 348 int x = 0;
313 // inference in A disabled (flag is off) 349 // inference in A disabled (flag is off)
314 x = /*info:DownCast*/A.a1; 350 x = /*info:DownCast*/A.a1;
315 x = /*info:DownCast*/new A().a2; 351 x = /*info:DownCast*/new A().a2;
316 } 352 }
317 ''' 353 '''
318 }); 354 }, inferTransitively: false);
319 }); 355 });
320 356
321 test('can infer also from static and instance fields (flag on)', () { 357 test('can infer also from static and instance fields (flag on)', () {
322 testChecker({ 358 testChecker({
323 '/a.dart': ''' 359 '/a.dart': '''
324 import 'b.dart'; 360 import 'b.dart';
325 class A { 361 class A {
326 static final a1 = B.b1; 362 static final a1 = B.b1;
327 final a2 = new B().b2; 363 final a2 = new B().b2;
328 } 364 }
(...skipping 10 matching lines...) Expand all
339 test1() { 375 test1() {
340 int x = 0; 376 int x = 0;
341 // inference in A now works. 377 // inference in A now works.
342 x = A.a1; 378 x = A.a1;
343 x = new A().a2; 379 x = new A().a2;
344 } 380 }
345 ''' 381 '''
346 }, inferTransitively: true); 382 }, inferTransitively: true);
347 }); 383 });
348 384
349 test('inference uses declared types', () {
350 testChecker({
351 '/main.dart': '''
352 int w = 0;
353 var x = 0;
354
355 var y = w; // y can be inferred because w is typed int.
356 var z = x; // z cannot, because x would be inferred.
357
358 test1() {
359 int a;
360 a = w;
361 a = x;
362 a = y;
363 a = /*info:DownCast*/z;
364 }
365 '''
366 }, inferTransitively: true);
367 });
368
369 test('inference in cycles is deterministic', () { 385 test('inference in cycles is deterministic', () {
370 testChecker({ 386 testChecker({
371 '/a.dart': ''' 387 '/a.dart': '''
372 import 'b.dart'; 388 import 'b.dart';
373 class A { 389 class A {
374 static final a1 = B.b1; 390 static final a1 = B.b1;
375 final a2 = new B().b2; 391 final a2 = new B().b2;
376 } 392 }
377 ''', 393 ''',
378 '/b.dart': ''' 394 '/b.dart': '''
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 test1() { 442 test1() {
427 int x = 0; 443 int x = 0;
428 // inference in A works, it's not in a cycle 444 // inference in A works, it's not in a cycle
429 x = A.a1; 445 x = A.a1;
430 x = new A().a2; 446 x = new A().a2;
431 447
432 // Within a cycle we allow inference when the RHS is well known, but 448 // Within a cycle we allow inference when the RHS is well known, but
433 // not when it depends on other fields within the cycle 449 // not when it depends on other fields within the cycle
434 x = C.c1; 450 x = C.c1;
435 x = D.d1; 451 x = D.d1;
436 x = /*info:DownCast*/D.d2; 452 x = D.d2;
437 x = new C().c2; 453 x = new C().c2;
438 x = new D().d3; 454 x = new D().d3;
439 x = /*info:DownCast*/new D().d4; 455 x = /*info:DownCast*/new D().d4;
440 456
441 457
442 // Similarly if the library contains parts. 458 // Similarly if the library contains parts.
443 x = E.e1; 459 x = E.e1;
444 x = /*info:DownCast*/E.e2; 460 x = E.e2;
445 x = E.e3; 461 x = E.e3;
446 x = new E().e4; 462 x = new E().e4;
447 x = /*info:DownCast*/new E().e5; 463 x = /*info:DownCast*/new E().e5;
448 x = new E().e6; 464 x = new E().e6;
449 x = F.f1; 465 x = F.f1;
450 x = new F().f2; 466 x = new F().f2;
451 } 467 }
452 ''' 468 '''
453 }, inferTransitively: true); 469 }, inferTransitively: true);
454 }); 470 });
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 int i = 0; 538 int i = 0;
523 A a; 539 A a;
524 B b; 540 B b;
525 a = t1; 541 a = t1;
526 i = /*info:DownCast*/t2; 542 i = /*info:DownCast*/t2;
527 b = t3; 543 b = t3;
528 i = /*info:DownCast*/t4; 544 i = /*info:DownCast*/t4;
529 i = new B().y; // B.y was inferred though 545 i = new B().y; // B.y was inferred though
530 } 546 }
531 ''' 547 '''
532 }); 548 }, inferTransitively: false);
533 549
534 // but flags can enable this behavior. 550 // but flags can enable this behavior.
535 testChecker({ 551 testChecker({
536 '/a.dart': ''' 552 '/a.dart': '''
537 class A { 553 class A {
538 var x = 3; 554 var x = 3;
539 } 555 }
540 ''', 556 ''',
541 '/main.dart': ''' 557 '/main.dart': '''
542 import 'a.dart'; 558 import 'a.dart';
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 s = /*severe:StaticTypeError*/new B().w; 1061 s = /*severe:StaticTypeError*/new B().w;
1046 1062
1047 i = /*info:DownCast*/new B().x; 1063 i = /*info:DownCast*/new B().x;
1048 i = new B().y; 1064 i = new B().y;
1049 i = /*severe:StaticTypeError*/new B().z; 1065 i = /*severe:StaticTypeError*/new B().z;
1050 i = new B().w; 1066 i = new B().w;
1051 } 1067 }
1052 ''' 1068 '''
1053 }, inferFromOverrides: true); 1069 }, inferFromOverrides: true);
1054 }); 1070 });
1071
1072 test('infer consts transitively', () {
1073 testChecker({
1074 '/b.dart': '''
1075 const b1 = 2;
1076 ''',
1077 '/a.dart': '''
1078 import 'main.dart';
1079 import 'b.dart';
1080 const a1 = m2;
1081 const a2 = b1;
1082 ''',
1083 '/main.dart': '''
1084 import 'a.dart';
1085 const m1 = a1;
1086 const m2 = a2;
1087
1088 foo() {
1089 int i;
1090 i = m1;
1091 }
1092 '''
1093 }, inferFromOverrides: true, inferTransitively: true);
1094 });
1095
1096 test('infer statics transitively', () {
1097 testChecker({
1098 '/b.dart': '''
1099 final b1 = 2;
1100 ''',
1101 '/a.dart': '''
1102 import 'main.dart';
1103 import 'b.dart';
1104 final a1 = m2;
1105 class A {
1106 static final a2 = b1;
1107 }
1108 ''',
1109 '/main.dart': '''
1110 import 'a.dart';
1111 final m1 = a1;
1112 final m2 = A.a2;
1113
1114 foo() {
1115 int i;
1116 i = m1;
1117 }
1118 '''
1119 }, inferFromOverrides: true, inferTransitively: true);
1120
1121 testChecker({
1122 '/main.dart': '''
1123 const x1 = 1;
1124 final x2 = 1;
1125 final y1 = x1;
1126 final y2 = x2;
1127
1128 foo() {
1129 int i;
1130 i = y1;
1131 i = y2;
1132 }
1133 '''
1134 }, inferFromOverrides: true, inferTransitively: true);
1135
1136 testChecker({
1137 '/a.dart': '''
1138 const a1 = 3;
1139 const a2 = 4;
1140 class A {
1141 a3;
1142 }
1143 ''',
1144 '/main.dart': '''
1145 import 'a.dart' show a1, A;
1146 import 'a.dart' as p show a2, A;
1147 const t1 = 1;
1148 const t2 = t1;
1149 const t3 = a1;
1150 const t4 = p.a2;
1151 const t5 = A.a3;
1152 const t6 = p.A.a3;
1153
1154 foo() {
1155 int i;
1156 i = t1;
1157 i = t2;
1158 i = t3;
1159 i = t4;
1160 }
1161 '''
1162 }, inferFromOverrides: true, inferTransitively: true);
1163 });
1164
1165 test('infer statics with method invocations', () {
1166 testChecker({
1167 '/a.dart': '''
1168 m3(String a, String b, [a1,a2]) {}
1169 ''',
1170 '/main.dart': '''
1171 import 'a.dart';
1172 class T {
1173 static final T foo = m1(m2(m3('', '')));
1174 static T m1(String m) { return null; }
1175 static String m2(e) { return ''; }
1176 }
1177
1178
1179 '''
1180 }, inferFromOverrides: true, inferTransitively: true);
1181 });
1055 } 1182 }
OLDNEW
« pubspec.yaml ('K') | « pubspec.yaml ('k') | test/codegen/expect/sunflower/sunflower.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698