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

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

Issue 2761633002: Infer fields/getters/setters types according to the new top-level inference rules. (Closed)
Patch Set: Created 3 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 library analyzer.test.src.task.strong_mode_test; 5 library analyzer.test.src.task.strong_mode_test;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'package:analyzer/dart/element/element.dart'; 9 import 'package:analyzer/dart/element/element.dart';
10 import 'package:analyzer/dart/element/type.dart'; 10 import 'package:analyzer/dart/element/type.dart';
(...skipping 30 matching lines...) Expand all
41 Future<CompilationUnitElement> resolve(String content) async { 41 Future<CompilationUnitElement> resolve(String content) async {
42 Source source = addNamedSource('/test.dart', content); 42 Source source = addNamedSource('/test.dart', content);
43 if (enableNewAnalysisDriver) { 43 if (enableNewAnalysisDriver) {
44 var analysisResult = await computeAnalysisResult(source); 44 var analysisResult = await computeAnalysisResult(source);
45 return analysisResult.unit.element; 45 return analysisResult.unit.element;
46 } else { 46 } else {
47 return analysisContext.resolveCompilationUnit2(source, source).element; 47 return analysisContext.resolveCompilationUnit2(source, source).element;
48 } 48 }
49 } 49 }
50 50
51 test_inferCompilationUnit_field_multiple_different() async {
52 String fieldName = 'f';
53 CompilationUnitElement unit = await resolve('''
54 class A {
55 int $fieldName;
56 }
57 class B {
58 double $fieldName;
59 }
60 class C implements A, B {
61 var $fieldName;
62 }
63 ''');
64 ClassElement classC = unit.getType('C');
65 FieldElement fieldC = classC.getField(fieldName);
66 PropertyAccessorElement getterC = classC.getGetter(fieldName);
67 expect(fieldC.type.isDynamic, isTrue);
68 expect(getterC.returnType.isDynamic, isTrue);
69
70 _runInferrer(unit);
71
72 expect(fieldC.type.isDynamic, isTrue);
73 expect(getterC.returnType.isDynamic, isTrue);
74 }
75
76 test_inferCompilationUnit_field_multiple_different_generic() async {
77 String fieldName = 'f';
78 CompilationUnitElement unit = await resolve('''
79 class A<E> {
80 E $fieldName;
81 }
82 class B<E> {
83 E $fieldName;
84 }
85 class C implements A<int>, B<double> {
86 var $fieldName;
87 }
88 ''');
89 ClassElement classC = unit.getType('C');
90 FieldElement fieldC = classC.getField(fieldName);
91 PropertyAccessorElement getterC = classC.getGetter(fieldName);
92 expect(fieldC.type.isDynamic, isTrue);
93 expect(getterC.returnType.isDynamic, isTrue);
94
95 _runInferrer(unit);
96
97 expect(fieldC.type.isDynamic, isTrue);
98 expect(getterC.returnType.isDynamic, isTrue);
99 }
100
101 test_inferCompilationUnit_field_multiple_dynamic() async {
102 String fieldName = 'f';
103 CompilationUnitElement unit = await resolve('''
104 class A {
105 int $fieldName;
106 }
107 class B {
108 var $fieldName;
109 }
110 class C implements A, B {
111 var $fieldName;
112 }
113 ''');
114 ClassElement classC = unit.getType('C');
115 FieldElement fieldC = classC.getField(fieldName);
116 PropertyAccessorElement getterC = classC.getGetter(fieldName);
117 expect(fieldC.type.isDynamic, isTrue);
118 expect(getterC.returnType.isDynamic, isTrue);
119
120 _runInferrer(unit);
121
122 expect(fieldC.type.isDynamic, isTrue);
123 expect(getterC.returnType.isDynamic, isTrue);
124 }
125
126 test_inferCompilationUnit_field_multiple_same() async {
127 String fieldName = 'f';
128 CompilationUnitElement unit = await resolve('''
129 class A {
130 int $fieldName;
131 }
132 class B {
133 int $fieldName;
134 }
135 class C implements A, B {
136 var $fieldName;
137 }
138 ''');
139 ClassElement classA = unit.getType('A');
140 FieldElement fieldA = classA.getField(fieldName);
141 DartType expectedType = fieldA.type;
142 ClassElement classC = unit.getType('C');
143 FieldElement fieldC = classC.getField(fieldName);
144 PropertyAccessorElement getterC = classC.getGetter(fieldName);
145 expect(fieldC.type.isDynamic, isTrue);
146 expect(getterC.returnType.isDynamic, isTrue);
147
148 _runInferrer(unit);
149
150 expect(fieldC.type, expectedType);
151 expect(getterC.returnType, expectedType);
152 }
153
154 test_inferCompilationUnit_field_noOverride() async {
155 String fieldName = 'f';
156 CompilationUnitElement unit = await resolve('''
157 class A {
158 final $fieldName = 0;
159 }
160 ''');
161 ClassElement classA = unit.getType('A');
162 FieldElement fieldA = classA.getField(fieldName);
163 PropertyAccessorElement getterA = classA.getGetter(fieldName);
164 expect(fieldA.type.isDynamic, isTrue);
165 expect(getterA.returnType.isDynamic, isTrue);
166
167 InstanceMemberInferrer inferrer = _runInferrer(unit);
168
169 DartType intType = inferrer.typeProvider.intType;
170 expect(fieldA.type, intType);
171 expect(getterA.returnType, intType);
172 }
173
174 test_inferCompilationUnit_field_noOverride_bottom() async {
175 String fieldName = 'f';
176 CompilationUnitElement unit = await resolve('''
177 class A {
178 var $fieldName = null;
179 }
180 ''');
181 ClassElement classA = unit.getType('A');
182 FieldElement fieldA = classA.getField(fieldName);
183 PropertyAccessorElement getterA = classA.getGetter(fieldName);
184 expect(fieldA.type.isDynamic, isTrue);
185 expect(getterA.returnType.isDynamic, isTrue);
186
187 _runInferrer(unit);
188
189 expect(fieldA.type.isDynamic, isTrue);
190 expect(getterA.returnType.isDynamic, isTrue);
191 }
192
193 test_inferCompilationUnit_field_single_explicitlyDynamic() async {
194 String fieldName = 'f';
195 CompilationUnitElement unit = await resolve('''
196 class A {
197 dynamic $fieldName;
198 }
199 class B extends A {
200 var $fieldName = 0;
201 }
202 ''');
203 ClassElement classA = unit.getType('A');
204 FieldElement fieldA = classA.getField(fieldName);
205 PropertyAccessorElement getterA = classA.getGetter(fieldName);
206 ClassElement classB = unit.getType('B');
207 FieldElement fieldB = classB.getField(fieldName);
208 PropertyAccessorElement getterB = classB.getGetter(fieldName);
209 expect(fieldB.type.isDynamic, isTrue);
210 expect(getterB.returnType.isDynamic, isTrue);
211
212 _runInferrer(unit);
213
214 expect(fieldB.type, fieldA.type);
215 expect(getterB.returnType, getterA.returnType);
216 }
217
218 test_inferCompilationUnit_field_single_final() async {
219 String fieldName = 'f';
220 CompilationUnitElement unit = await resolve('''
221 class A {
222 final int $fieldName;
223 }
224 class B extends A {
225 final $fieldName;
226 }
227 ''');
228 ClassElement classA = unit.getType('A');
229 FieldElement fieldA = classA.getField(fieldName);
230 PropertyAccessorElement getterA = classA.getGetter(fieldName);
231 ClassElement classB = unit.getType('B');
232 FieldElement fieldB = classB.getField(fieldName);
233 PropertyAccessorElement getterB = classB.getGetter(fieldName);
234 expect(fieldB.type.isDynamic, isTrue);
235 expect(getterB.returnType.isDynamic, isTrue);
236
237 _runInferrer(unit);
238
239 expect(fieldB.type, fieldA.type);
240 expect(getterB.returnType, getterA.returnType);
241 }
242
243 test_inferCompilationUnit_field_single_final_narrowType() async {
244 String fieldName = 'f';
245 CompilationUnitElement unit = await resolve('''
246 class A {
247 final $fieldName;
248 }
249 class B extends A {
250 final $fieldName = 0;
251 }
252 ''');
253 ClassElement classB = unit.getType('B');
254 FieldElement fieldB = classB.getField(fieldName);
255 PropertyAccessorElement getterB = classB.getGetter(fieldName);
256 expect(fieldB.type.isDynamic, isTrue);
257 expect(getterB.returnType.isDynamic, isTrue);
258
259 InstanceMemberInferrer inferrer = _runInferrer(unit);
260
261 expect(fieldB.type, inferrer.typeProvider.intType);
262 expect(getterB.returnType, fieldB.type);
263 }
264
265 test_inferCompilationUnit_field_single_generic() async {
266 String fieldName = 'f';
267 CompilationUnitElement unit = await resolve('''
268 class A<E> {
269 E $fieldName;
270 }
271 class B<E> extends A<E> {
272 var $fieldName;
273 }
274 ''');
275 ClassElement classB = unit.getType('B');
276 DartType typeBE = classB.typeParameters[0].type;
277 FieldElement fieldB = classB.getField(fieldName);
278 PropertyAccessorElement getterB = classB.getGetter(fieldName);
279 expect(fieldB.type.isDynamic, isTrue);
280 expect(getterB.returnType.isDynamic, isTrue);
281
282 _runInferrer(unit);
283
284 expect(fieldB.type, typeBE);
285 expect(getterB.returnType, typeBE);
286 }
287
288 test_inferCompilationUnit_field_single_inconsistentAccessors() async {
289 String fieldName = 'f';
290 CompilationUnitElement unit = await resolve('''
291 class A {
292 int get $fieldName => 0;
293 set $fieldName(String value) {}
294 }
295 class B extends A {
296 var $fieldName;
297 }
298 ''');
299 ClassElement classB = unit.getType('B');
300 FieldElement fieldB = classB.getField(fieldName);
301 PropertyAccessorElement getterB = classB.getGetter(fieldName);
302 expect(fieldB.type.isDynamic, isTrue);
303 expect(getterB.returnType.isDynamic, isTrue);
304
305 _runInferrer(unit);
306
307 expect(fieldB.type.isDynamic, isTrue);
308 expect(getterB.returnType.isDynamic, isTrue);
309 }
310
311 test_inferCompilationUnit_field_single_noModifiers() async {
312 String fieldName = 'f';
313 CompilationUnitElement unit = await resolve('''
314 class A {
315 int $fieldName;
316 }
317 class B extends A {
318 var $fieldName;
319 }
320 ''');
321 ClassElement classA = unit.getType('A');
322 FieldElement fieldA = classA.getField(fieldName);
323 PropertyAccessorElement getterA = classA.getGetter(fieldName);
324 ClassElement classB = unit.getType('B');
325 FieldElement fieldB = classB.getField(fieldName);
326 PropertyAccessorElement getterB = classB.getGetter(fieldName);
327 expect(fieldB.type.isDynamic, isTrue);
328 expect(getterB.returnType.isDynamic, isTrue);
329
330 _runInferrer(unit);
331
332 expect(fieldB.type, fieldA.type);
333 expect(getterB.returnType, getterA.returnType);
334 }
335
336 test_inferCompilationUnit_fieldFormal() async {
337 String fieldName = 'f';
338 CompilationUnitElement unit = await resolve('''
339 class A {
340 final $fieldName = 0;
341 A([this.$fieldName = 'hello']);
342 }
343 ''');
344 ClassElement classA = unit.getType('A');
345 FieldElement fieldA = classA.getField(fieldName);
346 FieldFormalParameterElement paramA =
347 classA.unnamedConstructor.parameters[0];
348 expect(fieldA.type.isDynamic, isTrue);
349 expect(paramA.type.isDynamic, isTrue);
350
351 InstanceMemberInferrer inferrer = _runInferrer(unit);
352
353 DartType intType = inferrer.typeProvider.intType;
354 expect(fieldA.type, intType);
355 expect(paramA.type, intType);
356 }
357
358 test_inferCompilationUnit_getter_multiple_different() async {
359 String getterName = 'g';
360 CompilationUnitElement unit = await resolve('''
361 class A {
362 int get $getterName => 0;
363 }
364 class B {
365 double get $getterName => 0.0;
366 }
367 class C implements A, B {
368 get $getterName => 0;
369 }
370 ''');
371 ClassElement classC = unit.getType('C');
372 FieldElement fieldC = classC.getField(getterName);
373 PropertyAccessorElement getterC = classC.getGetter(getterName);
374 expect(fieldC.type.isDynamic, isTrue);
375 expect(getterC.returnType.isDynamic, isTrue);
376
377 _runInferrer(unit);
378
379 expect(fieldC.type.isDynamic, isTrue);
380 expect(getterC.returnType.isDynamic, isTrue);
381 }
382
383 test_inferCompilationUnit_getter_multiple_dynamic() async {
384 String getterName = 'g';
385 CompilationUnitElement unit = await resolve('''
386 class A {
387 int get $getterName => 0;
388 }
389 class B {
390 get $getterName => 0;
391 }
392 class C implements A, B {
393 get $getterName => 0;
394 }
395 ''');
396 ClassElement classC = unit.getType('C');
397 FieldElement fieldC = classC.getField(getterName);
398 PropertyAccessorElement getterC = classC.getGetter(getterName);
399 expect(fieldC.type.isDynamic, isTrue);
400 expect(getterC.returnType.isDynamic, isTrue);
401
402 _runInferrer(unit);
403
404 expect(fieldC.type.isDynamic, isTrue);
405 expect(getterC.returnType.isDynamic, isTrue);
406 }
407
408 test_inferCompilationUnit_getter_multiple_same() async {
409 String getterName = 'g';
410 CompilationUnitElement unit = await resolve('''
411 class A {
412 String get $getterName => '';
413 }
414 class B {
415 String get $getterName => '';
416 }
417 class C implements A, B {
418 get $getterName => '';
419 }
420 ''');
421 ClassElement classA = unit.getType('A');
422 PropertyAccessorElement getterA = classA.getGetter(getterName);
423 DartType expectedType = getterA.returnType;
424 ClassElement classC = unit.getType('C');
425 FieldElement fieldC = classC.getField(getterName);
426 PropertyAccessorElement getterC = classC.getGetter(getterName);
427 expect(fieldC.type.isDynamic, isTrue);
428 expect(getterC.returnType.isDynamic, isTrue);
429
430 _runInferrer(unit);
431
432 expect(fieldC.type, expectedType);
433 expect(getterC.returnType, expectedType);
434 }
435
436 test_inferCompilationUnit_getter_single() async {
437 String getterName = 'g';
438 CompilationUnitElement unit = await resolve('''
439 class A {
440 int get $getterName => 0;
441 }
442 class B extends A {
443 get $getterName => 0;
444 }
445 ''');
446 ClassElement classA = unit.getType('A');
447 FieldElement fieldA = classA.getField(getterName);
448 PropertyAccessorElement getterA = classA.getGetter(getterName);
449 ClassElement classB = unit.getType('B');
450 FieldElement fieldB = classB.getField(getterName);
451 PropertyAccessorElement getterB = classB.getGetter(getterName);
452 expect(fieldB.type.isDynamic, isTrue);
453 expect(getterB.returnType.isDynamic, isTrue);
454
455 _runInferrer(unit);
456
457 expect(fieldB.type, fieldA.type);
458 expect(getterB.returnType, getterA.returnType);
459 }
460
461 test_inferCompilationUnit_getter_single_generic() async {
462 String getterName = 'g';
463 CompilationUnitElement unit = await resolve('''
464 class A<E> {
465 E get $getterName => 0;
466 }
467 class B<E> extends A<E> {
468 get $getterName => 0;
469 }
470 ''');
471 ClassElement classB = unit.getType('B');
472 DartType typeBE = classB.typeParameters[0].type;
473 FieldElement fieldB = classB.getField(getterName);
474 PropertyAccessorElement getterB = classB.getGetter(getterName);
475 expect(fieldB.type.isDynamic, isTrue);
476 expect(getterB.returnType.isDynamic, isTrue);
477
478 _runInferrer(unit);
479
480 expect(fieldB.type, typeBE);
481 expect(getterB.returnType, typeBE);
482 }
483
484 test_inferCompilationUnit_getter_single_inconsistentAccessors() async {
485 String getterName = 'g';
486 CompilationUnitElement unit = await resolve('''
487 class A {
488 int get $getterName => 0;
489 set $getterName(String value) {}
490 }
491 class B extends A {
492 var get $getterName => 1;
493 }
494 ''');
495 ClassElement classA = unit.getType('A');
496 FieldElement fieldA = classA.getField(getterName);
497 PropertyAccessorElement getterA = classA.getGetter(getterName);
498 ClassElement classB = unit.getType('B');
499 FieldElement fieldB = classB.getField(getterName);
500 PropertyAccessorElement getterB = classB.getGetter(getterName);
501 expect(fieldB.type.isDynamic, isTrue);
502 expect(getterB.returnType.isDynamic, isTrue);
503
504 _runInferrer(unit);
505
506 // Expected behavior is that the getter is inferred: getters and setters
507 // are treated as independent methods.
508 expect(fieldB.type, fieldA.type);
509 expect(getterB.returnType, getterA.returnType);
510 }
511
512 test_inferCompilationUnit_invalid_inheritanceCycle() async { 51 test_inferCompilationUnit_invalid_inheritanceCycle() async {
513 CompilationUnitElement unit = await resolve(''' 52 CompilationUnitElement unit = await resolve('''
514 class A extends C {} 53 class A extends C {}
515 class B extends A {} 54 class B extends A {}
516 class C extends B {} 55 class C extends B {}
517 '''); 56 ''');
518 _runInferrer(unit); 57 _runInferrer(unit);
519 } 58 }
520 59
521 test_inferCompilationUnit_method_parameter_multiple_different() async { 60 test_inferCompilationUnit_method_parameter_multiple_different() async {
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 expect(methodB.returnType.isDynamic, isTrue); 401 expect(methodB.returnType.isDynamic, isTrue);
863 expect(methodB.type.typeArguments, [typeBE]); 402 expect(methodB.type.typeArguments, [typeBE]);
864 403
865 _runInferrer(unit); 404 _runInferrer(unit);
866 405
867 expect(methodB.returnType, classB.typeParameters[0].type); 406 expect(methodB.returnType, classB.typeParameters[0].type);
868 expect(methodB.type.typeArguments, [typeBE], 407 expect(methodB.type.typeArguments, [typeBE],
869 reason: 'function type should still have type arguments'); 408 reason: 'function type should still have type arguments');
870 } 409 }
871 410
872 test_inferCompilationUnit_setter_single() async {
873 String setterName = 'g';
874 CompilationUnitElement unit = await resolve('''
875 class A {
876 set $setterName(int x) {}
877 }
878 class B extends A {
879 set $setterName(x) {}
880 }
881 ''');
882 ClassElement classA = unit.getType('A');
883 FieldElement fieldA = classA.getField(setterName);
884 PropertyAccessorElement setterA = classA.getSetter(setterName);
885 ClassElement classB = unit.getType('B');
886 FieldElement fieldB = classB.getField(setterName);
887 PropertyAccessorElement setterB = classB.getSetter(setterName);
888 expect(fieldB.type.isDynamic, isTrue);
889 expect(setterB.parameters[0].type.isDynamic, isTrue);
890
891 _runInferrer(unit);
892
893 expect(fieldB.type, fieldA.type);
894 expect(setterB.parameters[0].type, setterA.parameters[0].type);
895 }
896
897 test_inferCompilationUnit_setter_single_generic() async {
898 String setterName = 'g';
899 CompilationUnitElement unit = await resolve('''
900 class A<E> {
901 set $setterName(E x) {}
902 }
903 class B<E> extends A<E> {
904 set $setterName(x) {}
905 }
906 ''');
907 ClassElement classB = unit.getType('B');
908 DartType typeBE = classB.typeParameters[0].type;
909 FieldElement fieldB = classB.getField(setterName);
910 PropertyAccessorElement setterB = classB.getSetter(setterName);
911 expect(fieldB.type.isDynamic, isTrue);
912 expect(setterB.parameters[0].type.isDynamic, isTrue);
913
914 _runInferrer(unit);
915
916 expect(fieldB.type, typeBE);
917 expect(setterB.parameters[0].type, typeBE);
918 }
919
920 test_inferCompilationUnit_setter_single_inconsistentAccessors() async {
921 String getterName = 'g';
922 CompilationUnitElement unit = await resolve('''
923 class A {
924 int get $getterName => 0;
925 set $getterName(String value) {}
926 }
927 class B extends A {
928 set $getterName(x) {}
929 }
930 ''');
931 ClassElement classA = unit.getType('A');
932 PropertyAccessorElement setterA = classA.getSetter(getterName);
933 ClassElement classB = unit.getType('B');
934 FieldElement fieldB = classB.getField(getterName);
935 PropertyAccessorElement setterB = classB.getSetter(getterName);
936 expect(fieldB.type.isDynamic, isTrue);
937 expect(setterB.parameters[0].type.isDynamic, isTrue);
938
939 _runInferrer(unit);
940
941 // Expected behavior is that the getter is inferred: getters and setters
942 // are treated as independent methods.
943 expect(setterB.parameters[0].type, setterA.parameters[0].type);
944
945 // Note that B's synthetic field type will be String. This matches what
946 // resolver would do if we explicitly typed the parameter as 'String'
947 expect(fieldB.type, setterB.parameters[0].type);
948 }
949
950 InstanceMemberInferrer _runInferrer(CompilationUnitElement unit) { 411 InstanceMemberInferrer _runInferrer(CompilationUnitElement unit) {
951 InstanceMemberInferrer inferrer = createInferrer(unit.library); 412 InstanceMemberInferrer inferrer = createInferrer(unit.library);
952 inferrer.inferCompilationUnit(unit); 413 inferrer.inferCompilationUnit(unit);
953 return inferrer; 414 return inferrer;
954 } 415 }
955 } 416 }
956 417
957 @reflectiveTest 418 @reflectiveTest
958 class SetFieldTypeTest extends ResolverTestCase { 419 class SetFieldTypeTest extends ResolverTestCase {
959 test_setter_withoutParameter() async { 420 test_setter_withoutParameter() async {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1031 } 492 }
1032 } 493 }
1033 } 494 }
1034 '''); 495 ''');
1035 var analysisResult = await computeAnalysisResult(source); 496 var analysisResult = await computeAnalysisResult(source);
1036 VariableGatherer gatherer = new VariableGatherer(filter); 497 VariableGatherer gatherer = new VariableGatherer(filter);
1037 analysisResult.unit.accept(gatherer); 498 analysisResult.unit.accept(gatherer);
1038 return gatherer.results; 499 return gatherer.results;
1039 } 500 }
1040 } 501 }
OLDNEW
« no previous file with comments | « pkg/analyzer/test/src/task/strong/inferred_type_test.dart ('k') | pkg/dev_compiler/test/not_yet_strong_tests.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698