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_mode_test; | 5 library analyzer.test.src.task.strong_mode_test; |
6 | 6 |
7 import 'package:analyzer/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
8 import 'package:analyzer/dart/element/element.dart'; | 8 import 'package:analyzer/dart/element/element.dart'; |
9 import 'package:analyzer/dart/element/type.dart'; | 9 import 'package:analyzer/dart/element/type.dart'; |
| 10 import 'package:analyzer/src/generated/resolver.dart'; |
10 import 'package:analyzer/src/generated/source.dart'; | 11 import 'package:analyzer/src/generated/source.dart'; |
11 import 'package:analyzer/src/task/strong_mode.dart'; | 12 import 'package:analyzer/src/task/strong_mode.dart'; |
12 import 'package:unittest/unittest.dart'; | 13 import 'package:unittest/unittest.dart'; |
13 | 14 |
14 import '../../reflective_tests.dart'; | 15 import '../../reflective_tests.dart'; |
15 import '../../utils.dart'; | 16 import '../../utils.dart'; |
16 import '../context/abstract_context.dart'; | 17 import '../context/abstract_context.dart'; |
17 | 18 |
18 main() { | 19 main() { |
19 initializeTestEnvironment(); | 20 initializeTestEnvironment(); |
20 runReflectiveTests(InstanceMemberInferrerTest); | 21 runReflectiveTests(InstanceMemberInferrerTest); |
21 runReflectiveTests(SetFieldTypeTest); | 22 runReflectiveTests(SetFieldTypeTest); |
22 runReflectiveTests(VariableGathererTest); | 23 runReflectiveTests(VariableGathererTest); |
23 } | 24 } |
24 | 25 |
25 @reflectiveTest | 26 @reflectiveTest |
26 class InstanceMemberInferrerTest extends AbstractContextTest { | 27 class InstanceMemberInferrerTest extends AbstractContextTest { |
27 InstanceMemberInferrer get createInferrer => | 28 InstanceMemberInferrer createInferrer(LibraryElement library) { |
28 new InstanceMemberInferrer(context.typeProvider, | 29 return new InstanceMemberInferrer( |
29 typeSystem: context.typeSystem); | 30 context.typeProvider, new InheritanceManager(library), |
| 31 typeSystem: context.typeSystem); |
| 32 } |
30 | 33 |
31 /** | 34 /** |
32 * Add a source with the given [content] and return the result of resolving | 35 * Add a source with the given [content] and return the result of resolving |
33 * the source. | 36 * the source. |
34 */ | 37 */ |
35 CompilationUnitElement resolve(String content) { | 38 CompilationUnitElement resolve(String content) { |
36 Source source = addSource('/test.dart', content); | 39 Source source = addSource('/test.dart', content); |
37 return context.resolveCompilationUnit2(source, source).element; | 40 return context.resolveCompilationUnit2(source, source).element; |
38 } | 41 } |
39 | 42 |
40 void test_creation() { | 43 void test_creation() { |
41 InstanceMemberInferrer inferrer = createInferrer; | 44 InstanceMemberInferrer inferrer = createInferrer(null); |
42 expect(inferrer, isNotNull); | 45 expect(inferrer, isNotNull); |
43 expect(inferrer.typeSystem, isNotNull); | 46 expect(inferrer.typeSystem, isNotNull); |
44 } | 47 } |
45 | 48 |
46 void test_inferCompilationUnit_field_multiple_different() { | 49 void test_inferCompilationUnit_field_multiple_different() { |
47 InstanceMemberInferrer inferrer = createInferrer; | |
48 String fieldName = 'f'; | 50 String fieldName = 'f'; |
49 CompilationUnitElement unit = resolve(''' | 51 CompilationUnitElement unit = resolve(''' |
50 class A { | 52 class A { |
51 int $fieldName; | 53 int $fieldName; |
52 } | 54 } |
53 class B { | 55 class B { |
54 double $fieldName; | 56 double $fieldName; |
55 } | 57 } |
56 class C implements A, B { | 58 class C implements A, B { |
57 var $fieldName; | 59 var $fieldName; |
58 } | 60 } |
59 '''); | 61 '''); |
60 ClassElement classC = unit.getType('C'); | 62 ClassElement classC = unit.getType('C'); |
61 FieldElement fieldC = classC.getField(fieldName); | 63 FieldElement fieldC = classC.getField(fieldName); |
62 PropertyAccessorElement getterC = classC.getGetter(fieldName); | 64 PropertyAccessorElement getterC = classC.getGetter(fieldName); |
63 expect(fieldC.type.isDynamic, isTrue); | 65 expect(fieldC.type.isDynamic, isTrue); |
64 expect(getterC.returnType.isDynamic, isTrue); | 66 expect(getterC.returnType.isDynamic, isTrue); |
65 | 67 |
66 inferrer.inferCompilationUnit(unit); | 68 _runInferrer(unit); |
67 | 69 |
68 expect(fieldC.type.isDynamic, isTrue); | 70 expect(fieldC.type.isDynamic, isTrue); |
69 expect(getterC.returnType.isDynamic, isTrue); | 71 expect(getterC.returnType.isDynamic, isTrue); |
70 } | 72 } |
71 | 73 |
72 void test_inferCompilationUnit_field_multiple_different_generic() { | 74 void test_inferCompilationUnit_field_multiple_different_generic() { |
73 InstanceMemberInferrer inferrer = createInferrer; | |
74 String fieldName = 'f'; | 75 String fieldName = 'f'; |
75 CompilationUnitElement unit = resolve(''' | 76 CompilationUnitElement unit = resolve(''' |
76 class A<E> { | 77 class A<E> { |
77 E $fieldName; | 78 E $fieldName; |
78 } | 79 } |
79 class B<E> { | 80 class B<E> { |
80 E $fieldName; | 81 E $fieldName; |
81 } | 82 } |
82 class C implements A<int>, B<double> { | 83 class C implements A<int>, B<double> { |
83 var $fieldName; | 84 var $fieldName; |
84 } | 85 } |
85 '''); | 86 '''); |
86 ClassElement classC = unit.getType('C'); | 87 ClassElement classC = unit.getType('C'); |
87 FieldElement fieldC = classC.getField(fieldName); | 88 FieldElement fieldC = classC.getField(fieldName); |
88 PropertyAccessorElement getterC = classC.getGetter(fieldName); | 89 PropertyAccessorElement getterC = classC.getGetter(fieldName); |
89 expect(fieldC.type.isDynamic, isTrue); | 90 expect(fieldC.type.isDynamic, isTrue); |
90 expect(getterC.returnType.isDynamic, isTrue); | 91 expect(getterC.returnType.isDynamic, isTrue); |
91 | 92 |
92 inferrer.inferCompilationUnit(unit); | 93 _runInferrer(unit); |
93 | 94 |
94 expect(fieldC.type.isDynamic, isTrue); | 95 expect(fieldC.type.isDynamic, isTrue); |
95 expect(getterC.returnType.isDynamic, isTrue); | 96 expect(getterC.returnType.isDynamic, isTrue); |
96 } | 97 } |
97 | 98 |
98 void test_inferCompilationUnit_field_multiple_dynamic() { | 99 void test_inferCompilationUnit_field_multiple_dynamic() { |
99 InstanceMemberInferrer inferrer = createInferrer; | |
100 String fieldName = 'f'; | 100 String fieldName = 'f'; |
101 CompilationUnitElement unit = resolve(''' | 101 CompilationUnitElement unit = resolve(''' |
102 class A { | 102 class A { |
103 int $fieldName; | 103 int $fieldName; |
104 } | 104 } |
105 class B { | 105 class B { |
106 var $fieldName; | 106 var $fieldName; |
107 } | 107 } |
108 class C implements A, B { | 108 class C implements A, B { |
109 var $fieldName; | 109 var $fieldName; |
110 } | 110 } |
111 '''); | 111 '''); |
112 ClassElement classC = unit.getType('C'); | 112 ClassElement classC = unit.getType('C'); |
113 FieldElement fieldC = classC.getField(fieldName); | 113 FieldElement fieldC = classC.getField(fieldName); |
114 PropertyAccessorElement getterC = classC.getGetter(fieldName); | 114 PropertyAccessorElement getterC = classC.getGetter(fieldName); |
115 expect(fieldC.type.isDynamic, isTrue); | 115 expect(fieldC.type.isDynamic, isTrue); |
116 expect(getterC.returnType.isDynamic, isTrue); | 116 expect(getterC.returnType.isDynamic, isTrue); |
117 | 117 |
118 inferrer.inferCompilationUnit(unit); | 118 _runInferrer(unit); |
119 | 119 |
120 expect(fieldC.type.isDynamic, isTrue); | 120 expect(fieldC.type.isDynamic, isTrue); |
121 expect(getterC.returnType.isDynamic, isTrue); | 121 expect(getterC.returnType.isDynamic, isTrue); |
122 } | 122 } |
123 | 123 |
124 void test_inferCompilationUnit_field_multiple_same() { | 124 void test_inferCompilationUnit_field_multiple_same() { |
125 InstanceMemberInferrer inferrer = createInferrer; | |
126 String fieldName = 'f'; | 125 String fieldName = 'f'; |
127 CompilationUnitElement unit = resolve(''' | 126 CompilationUnitElement unit = resolve(''' |
128 class A { | 127 class A { |
129 int $fieldName; | 128 int $fieldName; |
130 } | 129 } |
131 class B { | 130 class B { |
132 int $fieldName; | 131 int $fieldName; |
133 } | 132 } |
134 class C implements A, B { | 133 class C implements A, B { |
135 var $fieldName; | 134 var $fieldName; |
136 } | 135 } |
137 '''); | 136 '''); |
138 ClassElement classA = unit.getType('A'); | 137 ClassElement classA = unit.getType('A'); |
139 FieldElement fieldA = classA.getField(fieldName); | 138 FieldElement fieldA = classA.getField(fieldName); |
140 DartType expectedType = fieldA.type; | 139 DartType expectedType = fieldA.type; |
141 ClassElement classC = unit.getType('C'); | 140 ClassElement classC = unit.getType('C'); |
142 FieldElement fieldC = classC.getField(fieldName); | 141 FieldElement fieldC = classC.getField(fieldName); |
143 PropertyAccessorElement getterC = classC.getGetter(fieldName); | 142 PropertyAccessorElement getterC = classC.getGetter(fieldName); |
144 expect(fieldC.type.isDynamic, isTrue); | 143 expect(fieldC.type.isDynamic, isTrue); |
145 expect(getterC.returnType.isDynamic, isTrue); | 144 expect(getterC.returnType.isDynamic, isTrue); |
146 | 145 |
147 inferrer.inferCompilationUnit(unit); | 146 _runInferrer(unit); |
148 | 147 |
149 expect(fieldC.type, expectedType); | 148 expect(fieldC.type, expectedType); |
150 expect(getterC.returnType, expectedType); | 149 expect(getterC.returnType, expectedType); |
151 } | 150 } |
152 | 151 |
153 void test_inferCompilationUnit_field_noOverride() { | 152 void test_inferCompilationUnit_field_noOverride() { |
154 InstanceMemberInferrer inferrer = createInferrer; | |
155 String fieldName = 'f'; | 153 String fieldName = 'f'; |
156 CompilationUnitElement unit = resolve(''' | 154 CompilationUnitElement unit = resolve(''' |
157 class A { | 155 class A { |
158 final $fieldName = 0; | 156 final $fieldName = 0; |
159 } | 157 } |
160 '''); | 158 '''); |
161 ClassElement classA = unit.getType('A'); | 159 ClassElement classA = unit.getType('A'); |
162 FieldElement fieldA = classA.getField(fieldName); | 160 FieldElement fieldA = classA.getField(fieldName); |
163 PropertyAccessorElement getterA = classA.getGetter(fieldName); | 161 PropertyAccessorElement getterA = classA.getGetter(fieldName); |
164 expect(fieldA.type.isDynamic, isTrue); | 162 expect(fieldA.type.isDynamic, isTrue); |
165 expect(getterA.returnType.isDynamic, isTrue); | 163 expect(getterA.returnType.isDynamic, isTrue); |
166 | 164 |
167 inferrer.inferCompilationUnit(unit); | 165 InstanceMemberInferrer inferrer = _runInferrer(unit); |
168 | 166 |
169 DartType intType = inferrer.typeProvider.intType; | 167 DartType intType = inferrer.typeProvider.intType; |
170 expect(fieldA.type, intType); | 168 expect(fieldA.type, intType); |
171 expect(getterA.returnType, intType); | 169 expect(getterA.returnType, intType); |
172 } | 170 } |
173 | 171 |
174 void test_inferCompilationUnit_field_noOverride_bottom() { | 172 void test_inferCompilationUnit_field_noOverride_bottom() { |
175 InstanceMemberInferrer inferrer = createInferrer; | |
176 String fieldName = 'f'; | 173 String fieldName = 'f'; |
177 CompilationUnitElement unit = resolve(''' | 174 CompilationUnitElement unit = resolve(''' |
178 class A { | 175 class A { |
179 var $fieldName = null; | 176 var $fieldName = null; |
180 } | 177 } |
181 '''); | 178 '''); |
182 ClassElement classA = unit.getType('A'); | 179 ClassElement classA = unit.getType('A'); |
183 FieldElement fieldA = classA.getField(fieldName); | 180 FieldElement fieldA = classA.getField(fieldName); |
184 PropertyAccessorElement getterA = classA.getGetter(fieldName); | 181 PropertyAccessorElement getterA = classA.getGetter(fieldName); |
185 expect(fieldA.type.isDynamic, isTrue); | 182 expect(fieldA.type.isDynamic, isTrue); |
186 expect(getterA.returnType.isDynamic, isTrue); | 183 expect(getterA.returnType.isDynamic, isTrue); |
187 | 184 |
188 inferrer.inferCompilationUnit(unit); | 185 _runInferrer(unit); |
189 | 186 |
190 expect(fieldA.type.isDynamic, isTrue); | 187 expect(fieldA.type.isDynamic, isTrue); |
191 expect(getterA.returnType.isDynamic, isTrue); | 188 expect(getterA.returnType.isDynamic, isTrue); |
192 } | 189 } |
193 | 190 |
194 void test_inferCompilationUnit_field_single_explicitlyDynamic() { | 191 void test_inferCompilationUnit_field_single_explicitlyDynamic() { |
195 InstanceMemberInferrer inferrer = createInferrer; | |
196 String fieldName = 'f'; | 192 String fieldName = 'f'; |
197 CompilationUnitElement unit = resolve(''' | 193 CompilationUnitElement unit = resolve(''' |
198 class A { | 194 class A { |
199 dynamic $fieldName; | 195 dynamic $fieldName; |
200 } | 196 } |
201 class B extends A { | 197 class B extends A { |
202 var $fieldName = 0; | 198 var $fieldName = 0; |
203 } | 199 } |
204 '''); | 200 '''); |
205 ClassElement classA = unit.getType('A'); | 201 ClassElement classA = unit.getType('A'); |
206 FieldElement fieldA = classA.getField(fieldName); | 202 FieldElement fieldA = classA.getField(fieldName); |
207 PropertyAccessorElement getterA = classA.getGetter(fieldName); | 203 PropertyAccessorElement getterA = classA.getGetter(fieldName); |
208 ClassElement classB = unit.getType('B'); | 204 ClassElement classB = unit.getType('B'); |
209 FieldElement fieldB = classB.getField(fieldName); | 205 FieldElement fieldB = classB.getField(fieldName); |
210 PropertyAccessorElement getterB = classB.getGetter(fieldName); | 206 PropertyAccessorElement getterB = classB.getGetter(fieldName); |
211 expect(fieldB.type.isDynamic, isTrue); | 207 expect(fieldB.type.isDynamic, isTrue); |
212 expect(getterB.returnType.isDynamic, isTrue); | 208 expect(getterB.returnType.isDynamic, isTrue); |
213 | 209 |
214 inferrer.inferCompilationUnit(unit); | 210 _runInferrer(unit); |
215 | 211 |
216 expect(fieldB.type, fieldA.type); | 212 expect(fieldB.type, fieldA.type); |
217 expect(getterB.returnType, getterA.returnType); | 213 expect(getterB.returnType, getterA.returnType); |
218 } | 214 } |
219 | 215 |
220 void test_inferCompilationUnit_field_single_final() { | 216 void test_inferCompilationUnit_field_single_final() { |
221 InstanceMemberInferrer inferrer = createInferrer; | |
222 String fieldName = 'f'; | 217 String fieldName = 'f'; |
223 CompilationUnitElement unit = resolve(''' | 218 CompilationUnitElement unit = resolve(''' |
224 class A { | 219 class A { |
225 final int $fieldName; | 220 final int $fieldName; |
226 } | 221 } |
227 class B extends A { | 222 class B extends A { |
228 final $fieldName; | 223 final $fieldName; |
229 } | 224 } |
230 '''); | 225 '''); |
231 ClassElement classA = unit.getType('A'); | 226 ClassElement classA = unit.getType('A'); |
232 FieldElement fieldA = classA.getField(fieldName); | 227 FieldElement fieldA = classA.getField(fieldName); |
233 PropertyAccessorElement getterA = classA.getGetter(fieldName); | 228 PropertyAccessorElement getterA = classA.getGetter(fieldName); |
234 ClassElement classB = unit.getType('B'); | 229 ClassElement classB = unit.getType('B'); |
235 FieldElement fieldB = classB.getField(fieldName); | 230 FieldElement fieldB = classB.getField(fieldName); |
236 PropertyAccessorElement getterB = classB.getGetter(fieldName); | 231 PropertyAccessorElement getterB = classB.getGetter(fieldName); |
237 expect(fieldB.type.isDynamic, isTrue); | 232 expect(fieldB.type.isDynamic, isTrue); |
238 expect(getterB.returnType.isDynamic, isTrue); | 233 expect(getterB.returnType.isDynamic, isTrue); |
239 | 234 |
240 inferrer.inferCompilationUnit(unit); | 235 _runInferrer(unit); |
241 | 236 |
242 expect(fieldB.type, fieldA.type); | 237 expect(fieldB.type, fieldA.type); |
243 expect(getterB.returnType, getterA.returnType); | 238 expect(getterB.returnType, getterA.returnType); |
244 } | 239 } |
245 | 240 |
246 void test_inferCompilationUnit_field_single_final_narrowType() { | 241 void test_inferCompilationUnit_field_single_final_narrowType() { |
247 InstanceMemberInferrer inferrer = createInferrer; | |
248 String fieldName = 'f'; | 242 String fieldName = 'f'; |
249 CompilationUnitElement unit = resolve(''' | 243 CompilationUnitElement unit = resolve(''' |
250 class A { | 244 class A { |
251 final $fieldName; | 245 final $fieldName; |
252 } | 246 } |
253 class B extends A { | 247 class B extends A { |
254 final $fieldName = 0; | 248 final $fieldName = 0; |
255 } | 249 } |
256 '''); | 250 '''); |
257 ClassElement classB = unit.getType('B'); | 251 ClassElement classB = unit.getType('B'); |
258 FieldElement fieldB = classB.getField(fieldName); | 252 FieldElement fieldB = classB.getField(fieldName); |
259 PropertyAccessorElement getterB = classB.getGetter(fieldName); | 253 PropertyAccessorElement getterB = classB.getGetter(fieldName); |
260 expect(fieldB.type.isDynamic, isTrue); | 254 expect(fieldB.type.isDynamic, isTrue); |
261 expect(getterB.returnType.isDynamic, isTrue); | 255 expect(getterB.returnType.isDynamic, isTrue); |
262 | 256 |
263 inferrer.inferCompilationUnit(unit); | 257 InstanceMemberInferrer inferrer = _runInferrer(unit); |
264 | 258 |
265 expect(fieldB.type, inferrer.typeProvider.intType); | 259 expect(fieldB.type, inferrer.typeProvider.intType); |
266 expect(getterB.returnType, fieldB.type); | 260 expect(getterB.returnType, fieldB.type); |
267 } | 261 } |
268 | 262 |
269 void test_inferCompilationUnit_field_single_generic() { | 263 void test_inferCompilationUnit_field_single_generic() { |
270 InstanceMemberInferrer inferrer = createInferrer; | |
271 String fieldName = 'f'; | 264 String fieldName = 'f'; |
272 CompilationUnitElement unit = resolve(''' | 265 CompilationUnitElement unit = resolve(''' |
273 class A<E> { | 266 class A<E> { |
274 E $fieldName; | 267 E $fieldName; |
275 } | 268 } |
276 class B<E> extends A<E> { | 269 class B<E> extends A<E> { |
277 var $fieldName; | 270 var $fieldName; |
278 } | 271 } |
279 '''); | 272 '''); |
280 ClassElement classB = unit.getType('B'); | 273 ClassElement classB = unit.getType('B'); |
281 DartType typeBE = classB.typeParameters[0].type; | 274 DartType typeBE = classB.typeParameters[0].type; |
282 FieldElement fieldB = classB.getField(fieldName); | 275 FieldElement fieldB = classB.getField(fieldName); |
283 PropertyAccessorElement getterB = classB.getGetter(fieldName); | 276 PropertyAccessorElement getterB = classB.getGetter(fieldName); |
284 expect(fieldB.type.isDynamic, isTrue); | 277 expect(fieldB.type.isDynamic, isTrue); |
285 expect(getterB.returnType.isDynamic, isTrue); | 278 expect(getterB.returnType.isDynamic, isTrue); |
286 | 279 |
287 inferrer.inferCompilationUnit(unit); | 280 _runInferrer(unit); |
288 | 281 |
289 expect(fieldB.type, typeBE); | 282 expect(fieldB.type, typeBE); |
290 expect(getterB.returnType, typeBE); | 283 expect(getterB.returnType, typeBE); |
291 } | 284 } |
292 | 285 |
293 void test_inferCompilationUnit_field_single_inconsistentAccessors() { | 286 void test_inferCompilationUnit_field_single_inconsistentAccessors() { |
294 InstanceMemberInferrer inferrer = createInferrer; | |
295 String fieldName = 'f'; | 287 String fieldName = 'f'; |
296 CompilationUnitElement unit = resolve(''' | 288 CompilationUnitElement unit = resolve(''' |
297 class A { | 289 class A { |
298 int get $fieldName => 0; | 290 int get $fieldName => 0; |
299 set $fieldName(String value) {} | 291 set $fieldName(String value) {} |
300 } | 292 } |
301 class B extends A { | 293 class B extends A { |
302 var $fieldName; | 294 var $fieldName; |
303 } | 295 } |
304 '''); | 296 '''); |
305 ClassElement classB = unit.getType('B'); | 297 ClassElement classB = unit.getType('B'); |
306 FieldElement fieldB = classB.getField(fieldName); | 298 FieldElement fieldB = classB.getField(fieldName); |
307 PropertyAccessorElement getterB = classB.getGetter(fieldName); | 299 PropertyAccessorElement getterB = classB.getGetter(fieldName); |
308 expect(fieldB.type.isDynamic, isTrue); | 300 expect(fieldB.type.isDynamic, isTrue); |
309 expect(getterB.returnType.isDynamic, isTrue); | 301 expect(getterB.returnType.isDynamic, isTrue); |
310 | 302 |
311 inferrer.inferCompilationUnit(unit); | 303 _runInferrer(unit); |
312 | 304 |
313 expect(fieldB.type.isDynamic, isTrue); | 305 expect(fieldB.type.isDynamic, isTrue); |
314 expect(getterB.returnType.isDynamic, isTrue); | 306 expect(getterB.returnType.isDynamic, isTrue); |
315 } | 307 } |
316 | 308 |
317 void test_inferCompilationUnit_field_single_noModifiers() { | 309 void test_inferCompilationUnit_field_single_noModifiers() { |
318 InstanceMemberInferrer inferrer = createInferrer; | |
319 String fieldName = 'f'; | 310 String fieldName = 'f'; |
320 CompilationUnitElement unit = resolve(''' | 311 CompilationUnitElement unit = resolve(''' |
321 class A { | 312 class A { |
322 int $fieldName; | 313 int $fieldName; |
323 } | 314 } |
324 class B extends A { | 315 class B extends A { |
325 var $fieldName; | 316 var $fieldName; |
326 } | 317 } |
327 '''); | 318 '''); |
328 ClassElement classA = unit.getType('A'); | 319 ClassElement classA = unit.getType('A'); |
329 FieldElement fieldA = classA.getField(fieldName); | 320 FieldElement fieldA = classA.getField(fieldName); |
330 PropertyAccessorElement getterA = classA.getGetter(fieldName); | 321 PropertyAccessorElement getterA = classA.getGetter(fieldName); |
331 ClassElement classB = unit.getType('B'); | 322 ClassElement classB = unit.getType('B'); |
332 FieldElement fieldB = classB.getField(fieldName); | 323 FieldElement fieldB = classB.getField(fieldName); |
333 PropertyAccessorElement getterB = classB.getGetter(fieldName); | 324 PropertyAccessorElement getterB = classB.getGetter(fieldName); |
334 expect(fieldB.type.isDynamic, isTrue); | 325 expect(fieldB.type.isDynamic, isTrue); |
335 expect(getterB.returnType.isDynamic, isTrue); | 326 expect(getterB.returnType.isDynamic, isTrue); |
336 | 327 |
337 inferrer.inferCompilationUnit(unit); | 328 _runInferrer(unit); |
338 | 329 |
339 expect(fieldB.type, fieldA.type); | 330 expect(fieldB.type, fieldA.type); |
340 expect(getterB.returnType, getterA.returnType); | 331 expect(getterB.returnType, getterA.returnType); |
341 } | 332 } |
342 | 333 |
343 void test_inferCompilationUnit_fieldFormal() { | 334 void test_inferCompilationUnit_fieldFormal() { |
344 InstanceMemberInferrer inferrer = createInferrer; | |
345 String fieldName = 'f'; | 335 String fieldName = 'f'; |
346 CompilationUnitElement unit = resolve(''' | 336 CompilationUnitElement unit = resolve(''' |
347 class A { | 337 class A { |
348 final $fieldName = 0; | 338 final $fieldName = 0; |
349 A([this.$fieldName = 'hello']); | 339 A([this.$fieldName = 'hello']); |
350 } | 340 } |
351 '''); | 341 '''); |
352 ClassElement classA = unit.getType('A'); | 342 ClassElement classA = unit.getType('A'); |
353 FieldElement fieldA = classA.getField(fieldName); | 343 FieldElement fieldA = classA.getField(fieldName); |
354 FieldFormalParameterElement paramA = | 344 FieldFormalParameterElement paramA = |
355 classA.unnamedConstructor.parameters[0]; | 345 classA.unnamedConstructor.parameters[0]; |
356 expect(fieldA.type.isDynamic, isTrue); | 346 expect(fieldA.type.isDynamic, isTrue); |
357 expect(paramA.type.isDynamic, isTrue); | 347 expect(paramA.type.isDynamic, isTrue); |
358 | 348 |
359 inferrer.inferCompilationUnit(unit); | 349 InstanceMemberInferrer inferrer = _runInferrer(unit); |
360 | 350 |
361 DartType intType = inferrer.typeProvider.intType; | 351 DartType intType = inferrer.typeProvider.intType; |
362 expect(fieldA.type, intType); | 352 expect(fieldA.type, intType); |
363 expect(paramA.type, intType); | 353 expect(paramA.type, intType); |
364 } | 354 } |
365 | 355 |
366 void test_inferCompilationUnit_getter_multiple_different() { | 356 void test_inferCompilationUnit_getter_multiple_different() { |
367 InstanceMemberInferrer inferrer = createInferrer; | |
368 String getterName = 'g'; | 357 String getterName = 'g'; |
369 CompilationUnitElement unit = resolve(''' | 358 CompilationUnitElement unit = resolve(''' |
370 class A { | 359 class A { |
371 int get $getterName => 0; | 360 int get $getterName => 0; |
372 } | 361 } |
373 class B { | 362 class B { |
374 double get $getterName => 0.0; | 363 double get $getterName => 0.0; |
375 } | 364 } |
376 class C implements A, B { | 365 class C implements A, B { |
377 get $getterName => 0; | 366 get $getterName => 0; |
378 } | 367 } |
379 '''); | 368 '''); |
380 ClassElement classC = unit.getType('C'); | 369 ClassElement classC = unit.getType('C'); |
381 FieldElement fieldC = classC.getField(getterName); | 370 FieldElement fieldC = classC.getField(getterName); |
382 PropertyAccessorElement getterC = classC.getGetter(getterName); | 371 PropertyAccessorElement getterC = classC.getGetter(getterName); |
383 expect(fieldC.type.isDynamic, isTrue); | 372 expect(fieldC.type.isDynamic, isTrue); |
384 expect(getterC.returnType.isDynamic, isTrue); | 373 expect(getterC.returnType.isDynamic, isTrue); |
385 | 374 |
386 inferrer.inferCompilationUnit(unit); | 375 _runInferrer(unit); |
387 | 376 |
388 expect(fieldC.type.isDynamic, isTrue); | 377 expect(fieldC.type.isDynamic, isTrue); |
389 expect(getterC.returnType.isDynamic, isTrue); | 378 expect(getterC.returnType.isDynamic, isTrue); |
390 } | 379 } |
391 | 380 |
392 void test_inferCompilationUnit_getter_multiple_dynamic() { | 381 void test_inferCompilationUnit_getter_multiple_dynamic() { |
393 InstanceMemberInferrer inferrer = createInferrer; | |
394 String getterName = 'g'; | 382 String getterName = 'g'; |
395 CompilationUnitElement unit = resolve(''' | 383 CompilationUnitElement unit = resolve(''' |
396 class A { | 384 class A { |
397 int get $getterName => 0; | 385 int get $getterName => 0; |
398 } | 386 } |
399 class B { | 387 class B { |
400 get $getterName => 0; | 388 get $getterName => 0; |
401 } | 389 } |
402 class C implements A, B { | 390 class C implements A, B { |
403 get $getterName => 0; | 391 get $getterName => 0; |
404 } | 392 } |
405 '''); | 393 '''); |
406 ClassElement classC = unit.getType('C'); | 394 ClassElement classC = unit.getType('C'); |
407 FieldElement fieldC = classC.getField(getterName); | 395 FieldElement fieldC = classC.getField(getterName); |
408 PropertyAccessorElement getterC = classC.getGetter(getterName); | 396 PropertyAccessorElement getterC = classC.getGetter(getterName); |
409 expect(fieldC.type.isDynamic, isTrue); | 397 expect(fieldC.type.isDynamic, isTrue); |
410 expect(getterC.returnType.isDynamic, isTrue); | 398 expect(getterC.returnType.isDynamic, isTrue); |
411 | 399 |
412 inferrer.inferCompilationUnit(unit); | 400 _runInferrer(unit); |
413 | 401 |
414 expect(fieldC.type.isDynamic, isTrue); | 402 expect(fieldC.type.isDynamic, isTrue); |
415 expect(getterC.returnType.isDynamic, isTrue); | 403 expect(getterC.returnType.isDynamic, isTrue); |
416 } | 404 } |
417 | 405 |
418 void test_inferCompilationUnit_getter_multiple_same() { | 406 void test_inferCompilationUnit_getter_multiple_same() { |
419 InstanceMemberInferrer inferrer = createInferrer; | |
420 String getterName = 'g'; | 407 String getterName = 'g'; |
421 CompilationUnitElement unit = resolve(''' | 408 CompilationUnitElement unit = resolve(''' |
422 class A { | 409 class A { |
423 String get $getterName => ''; | 410 String get $getterName => ''; |
424 } | 411 } |
425 class B { | 412 class B { |
426 String get $getterName => ''; | 413 String get $getterName => ''; |
427 } | 414 } |
428 class C implements A, B { | 415 class C implements A, B { |
429 get $getterName => ''; | 416 get $getterName => ''; |
430 } | 417 } |
431 '''); | 418 '''); |
432 ClassElement classA = unit.getType('A'); | 419 ClassElement classA = unit.getType('A'); |
433 PropertyAccessorElement getterA = classA.getGetter(getterName); | 420 PropertyAccessorElement getterA = classA.getGetter(getterName); |
434 DartType expectedType = getterA.returnType; | 421 DartType expectedType = getterA.returnType; |
435 ClassElement classC = unit.getType('C'); | 422 ClassElement classC = unit.getType('C'); |
436 FieldElement fieldC = classC.getField(getterName); | 423 FieldElement fieldC = classC.getField(getterName); |
437 PropertyAccessorElement getterC = classC.getGetter(getterName); | 424 PropertyAccessorElement getterC = classC.getGetter(getterName); |
438 expect(fieldC.type.isDynamic, isTrue); | 425 expect(fieldC.type.isDynamic, isTrue); |
439 expect(getterC.returnType.isDynamic, isTrue); | 426 expect(getterC.returnType.isDynamic, isTrue); |
440 | 427 |
441 inferrer.inferCompilationUnit(unit); | 428 _runInferrer(unit); |
442 | 429 |
443 expect(fieldC.type, expectedType); | 430 expect(fieldC.type, expectedType); |
444 expect(getterC.returnType, expectedType); | 431 expect(getterC.returnType, expectedType); |
445 } | 432 } |
446 | 433 |
447 void test_inferCompilationUnit_getter_single() { | 434 void test_inferCompilationUnit_getter_single() { |
448 InstanceMemberInferrer inferrer = createInferrer; | |
449 String getterName = 'g'; | 435 String getterName = 'g'; |
450 CompilationUnitElement unit = resolve(''' | 436 CompilationUnitElement unit = resolve(''' |
451 class A { | 437 class A { |
452 int get $getterName => 0; | 438 int get $getterName => 0; |
453 } | 439 } |
454 class B extends A { | 440 class B extends A { |
455 get $getterName => 0; | 441 get $getterName => 0; |
456 } | 442 } |
457 '''); | 443 '''); |
458 ClassElement classA = unit.getType('A'); | 444 ClassElement classA = unit.getType('A'); |
459 FieldElement fieldA = classA.getField(getterName); | 445 FieldElement fieldA = classA.getField(getterName); |
460 PropertyAccessorElement getterA = classA.getGetter(getterName); | 446 PropertyAccessorElement getterA = classA.getGetter(getterName); |
461 ClassElement classB = unit.getType('B'); | 447 ClassElement classB = unit.getType('B'); |
462 FieldElement fieldB = classB.getField(getterName); | 448 FieldElement fieldB = classB.getField(getterName); |
463 PropertyAccessorElement getterB = classB.getGetter(getterName); | 449 PropertyAccessorElement getterB = classB.getGetter(getterName); |
464 expect(fieldB.type.isDynamic, isTrue); | 450 expect(fieldB.type.isDynamic, isTrue); |
465 expect(getterB.returnType.isDynamic, isTrue); | 451 expect(getterB.returnType.isDynamic, isTrue); |
466 | 452 |
467 inferrer.inferCompilationUnit(unit); | 453 _runInferrer(unit); |
468 | 454 |
469 expect(fieldB.type, fieldA.type); | 455 expect(fieldB.type, fieldA.type); |
470 expect(getterB.returnType, getterA.returnType); | 456 expect(getterB.returnType, getterA.returnType); |
471 } | 457 } |
472 | 458 |
473 void test_inferCompilationUnit_getter_single_generic() { | 459 void test_inferCompilationUnit_getter_single_generic() { |
474 InstanceMemberInferrer inferrer = createInferrer; | |
475 String getterName = 'g'; | 460 String getterName = 'g'; |
476 CompilationUnitElement unit = resolve(''' | 461 CompilationUnitElement unit = resolve(''' |
477 class A<E> { | 462 class A<E> { |
478 E get $getterName => 0; | 463 E get $getterName => 0; |
479 } | 464 } |
480 class B<E> extends A<E> { | 465 class B<E> extends A<E> { |
481 get $getterName => 0; | 466 get $getterName => 0; |
482 } | 467 } |
483 '''); | 468 '''); |
484 ClassElement classB = unit.getType('B'); | 469 ClassElement classB = unit.getType('B'); |
485 DartType typeBE = classB.typeParameters[0].type; | 470 DartType typeBE = classB.typeParameters[0].type; |
486 FieldElement fieldB = classB.getField(getterName); | 471 FieldElement fieldB = classB.getField(getterName); |
487 PropertyAccessorElement getterB = classB.getGetter(getterName); | 472 PropertyAccessorElement getterB = classB.getGetter(getterName); |
488 expect(fieldB.type.isDynamic, isTrue); | 473 expect(fieldB.type.isDynamic, isTrue); |
489 expect(getterB.returnType.isDynamic, isTrue); | 474 expect(getterB.returnType.isDynamic, isTrue); |
490 | 475 |
491 inferrer.inferCompilationUnit(unit); | 476 _runInferrer(unit); |
492 | 477 |
493 expect(fieldB.type, typeBE); | 478 expect(fieldB.type, typeBE); |
494 expect(getterB.returnType, typeBE); | 479 expect(getterB.returnType, typeBE); |
495 } | 480 } |
496 | 481 |
497 void test_inferCompilationUnit_getter_single_inconsistentAccessors() { | 482 void test_inferCompilationUnit_getter_single_inconsistentAccessors() { |
498 InstanceMemberInferrer inferrer = createInferrer; | |
499 String getterName = 'g'; | 483 String getterName = 'g'; |
500 CompilationUnitElement unit = resolve(''' | 484 CompilationUnitElement unit = resolve(''' |
501 class A { | 485 class A { |
502 int get $getterName => 0; | 486 int get $getterName => 0; |
503 set $getterName(String value) {} | 487 set $getterName(String value) {} |
504 } | 488 } |
505 class B extends A { | 489 class B extends A { |
506 var get $getterName => 1; | 490 var get $getterName => 1; |
507 } | 491 } |
508 '''); | 492 '''); |
509 ClassElement classA = unit.getType('A'); | 493 ClassElement classA = unit.getType('A'); |
510 FieldElement fieldA = classA.getField(getterName); | 494 FieldElement fieldA = classA.getField(getterName); |
511 PropertyAccessorElement getterA = classA.getGetter(getterName); | 495 PropertyAccessorElement getterA = classA.getGetter(getterName); |
512 ClassElement classB = unit.getType('B'); | 496 ClassElement classB = unit.getType('B'); |
513 FieldElement fieldB = classB.getField(getterName); | 497 FieldElement fieldB = classB.getField(getterName); |
514 PropertyAccessorElement getterB = classB.getGetter(getterName); | 498 PropertyAccessorElement getterB = classB.getGetter(getterName); |
515 expect(fieldB.type.isDynamic, isTrue); | 499 expect(fieldB.type.isDynamic, isTrue); |
516 expect(getterB.returnType.isDynamic, isTrue); | 500 expect(getterB.returnType.isDynamic, isTrue); |
517 | 501 |
518 inferrer.inferCompilationUnit(unit); | 502 _runInferrer(unit); |
519 | 503 |
520 // Expected behavior is that the getter is inferred: getters and setters | 504 // Expected behavior is that the getter is inferred: getters and setters |
521 // are treated as independent methods. | 505 // are treated as independent methods. |
522 expect(fieldB.type, fieldA.type); | 506 expect(fieldB.type, fieldA.type); |
523 expect(getterB.returnType, getterA.returnType); | 507 expect(getterB.returnType, getterA.returnType); |
524 } | 508 } |
525 | 509 |
526 void test_inferCompilationUnit_invalid_inheritanceCycle() { | 510 void test_inferCompilationUnit_invalid_inheritanceCycle() { |
527 InstanceMemberInferrer inferrer = createInferrer; | |
528 CompilationUnitElement unit = resolve(''' | 511 CompilationUnitElement unit = resolve(''' |
529 class A extends C {} | 512 class A extends C {} |
530 class B extends A {} | 513 class B extends A {} |
531 class C extends B {} | 514 class C extends B {} |
532 '''); | 515 '''); |
533 inferrer.inferCompilationUnit(unit); | 516 _runInferrer(unit); |
534 } | 517 } |
535 | 518 |
536 void test_inferCompilationUnit_method_parameter_multiple_different() { | 519 void test_inferCompilationUnit_method_parameter_multiple_different() { |
537 InstanceMemberInferrer inferrer = createInferrer; | |
538 String methodName = 'm'; | 520 String methodName = 'm'; |
539 CompilationUnitElement unit = resolve(''' | 521 CompilationUnitElement unit = resolve(''' |
540 class A { | 522 class A { |
541 $methodName(int p) => 0; | 523 $methodName(int p) => 0; |
542 } | 524 } |
543 class B { | 525 class B { |
544 $methodName(double p) => 0; | 526 $methodName(double p) => 0; |
545 } | 527 } |
546 class C implements A, B { | 528 class C implements A, B { |
547 $methodName(p) => 0; | 529 $methodName(p) => 0; |
548 } | 530 } |
549 '''); | 531 '''); |
550 ClassElement classC = unit.getType('C'); | 532 ClassElement classC = unit.getType('C'); |
551 MethodElement methodC = classC.getMethod(methodName); | 533 MethodElement methodC = classC.getMethod(methodName); |
552 ParameterElement parameterC = methodC.parameters[0]; | 534 ParameterElement parameterC = methodC.parameters[0]; |
553 expect(parameterC.type.isDynamic, isTrue); | 535 expect(parameterC.type.isDynamic, isTrue); |
554 | 536 |
555 inferrer.inferCompilationUnit(unit); | 537 _runInferrer(unit); |
556 | 538 |
557 expect(parameterC.type.isDynamic, isTrue); | 539 expect(parameterC.type.isDynamic, isTrue); |
558 } | 540 } |
559 | 541 |
560 void test_inferCompilationUnit_method_parameter_multiple_named_different() { | 542 void test_inferCompilationUnit_method_parameter_multiple_named_different() { |
561 InstanceMemberInferrer inferrer = createInferrer; | |
562 String methodName = 'm'; | 543 String methodName = 'm'; |
563 CompilationUnitElement unit = resolve(''' | 544 CompilationUnitElement unit = resolve(''' |
564 class A { | 545 class A { |
565 $methodName({int p}) => 0; | 546 $methodName({int p}) => 0; |
566 } | 547 } |
567 class B { | 548 class B { |
568 $methodName({int q}) => 0; | 549 $methodName({int q}) => 0; |
569 } | 550 } |
570 class C implements A, B { | 551 class C implements A, B { |
571 $methodName({p}) => 0; | 552 $methodName({p}) => 0; |
572 } | 553 } |
573 '''); | 554 '''); |
574 ClassElement classC = unit.getType('C'); | 555 ClassElement classC = unit.getType('C'); |
575 MethodElement methodC = classC.getMethod(methodName); | 556 MethodElement methodC = classC.getMethod(methodName); |
576 ParameterElement parameterC = methodC.parameters[0]; | 557 ParameterElement parameterC = methodC.parameters[0]; |
577 expect(parameterC.type.isDynamic, isTrue); | 558 expect(parameterC.type.isDynamic, isTrue); |
578 | 559 |
579 inferrer.inferCompilationUnit(unit); | 560 _runInferrer(unit); |
580 | 561 |
581 expect(parameterC.type.isDynamic, isTrue); | 562 expect(parameterC.type.isDynamic, isTrue); |
582 } | 563 } |
583 | 564 |
584 void test_inferCompilationUnit_method_parameter_multiple_named_same() { | 565 void test_inferCompilationUnit_method_parameter_multiple_named_same() { |
585 InstanceMemberInferrer inferrer = createInferrer; | |
586 String methodName = 'm'; | 566 String methodName = 'm'; |
587 CompilationUnitElement unit = resolve(''' | 567 CompilationUnitElement unit = resolve(''' |
588 class A { | 568 class A { |
589 $methodName({int p}) => 0; | 569 $methodName({int p}) => 0; |
590 } | 570 } |
591 class B { | 571 class B { |
592 $methodName({int p}) => 0; | 572 $methodName({int p}) => 0; |
593 } | 573 } |
594 class C implements A, B { | 574 class C implements A, B { |
595 $methodName({p}) => 0; | 575 $methodName({p}) => 0; |
596 } | 576 } |
597 '''); | 577 '''); |
598 ClassElement classA = unit.getType('A'); | 578 ClassElement classA = unit.getType('A'); |
599 MethodElement methodA = classA.getMethod(methodName); | 579 MethodElement methodA = classA.getMethod(methodName); |
600 ParameterElement parameterA = methodA.parameters[0]; | 580 ParameterElement parameterA = methodA.parameters[0]; |
601 DartType expectedType = parameterA.type; | 581 DartType expectedType = parameterA.type; |
602 ClassElement classC = unit.getType('C'); | 582 ClassElement classC = unit.getType('C'); |
603 MethodElement methodC = classC.getMethod(methodName); | 583 MethodElement methodC = classC.getMethod(methodName); |
604 ParameterElement parameterC = methodC.parameters[0]; | 584 ParameterElement parameterC = methodC.parameters[0]; |
605 expect(parameterC.type.isDynamic, isTrue); | 585 expect(parameterC.type.isDynamic, isTrue); |
606 | 586 |
607 inferrer.inferCompilationUnit(unit); | 587 _runInferrer(unit); |
608 | 588 |
609 expect(parameterC.type, expectedType); | 589 expect(parameterC.type, expectedType); |
610 } | 590 } |
611 | 591 |
612 void test_inferCompilationUnit_method_parameter_multiple_namedAndRequired() { | 592 void test_inferCompilationUnit_method_parameter_multiple_namedAndRequired() { |
613 InstanceMemberInferrer inferrer = createInferrer; | |
614 String methodName = 'm'; | 593 String methodName = 'm'; |
615 CompilationUnitElement unit = resolve(''' | 594 CompilationUnitElement unit = resolve(''' |
616 class A { | 595 class A { |
617 $methodName({int p}) => 0; | 596 $methodName({int p}) => 0; |
618 } | 597 } |
619 class B { | 598 class B { |
620 $methodName(int p) => 0; | 599 $methodName(int p) => 0; |
621 } | 600 } |
622 class C implements A, B { | 601 class C implements A, B { |
623 $methodName(p) => 0; | 602 $methodName(p) => 0; |
624 } | 603 } |
625 '''); | 604 '''); |
626 ClassElement classC = unit.getType('C'); | 605 ClassElement classC = unit.getType('C'); |
627 MethodElement methodC = classC.getMethod(methodName); | 606 MethodElement methodC = classC.getMethod(methodName); |
628 ParameterElement parameterC = methodC.parameters[0]; | 607 ParameterElement parameterC = methodC.parameters[0]; |
629 expect(parameterC.type.isDynamic, isTrue); | 608 expect(parameterC.type.isDynamic, isTrue); |
630 | 609 |
631 inferrer.inferCompilationUnit(unit); | 610 _runInferrer(unit); |
632 | 611 |
633 expect(parameterC.type.isDynamic, isTrue); | 612 expect(parameterC.type.isDynamic, isTrue); |
634 } | 613 } |
635 | 614 |
636 void | 615 void |
637 test_inferCompilationUnit_method_parameter_multiple_optionalAndRequired()
{ | 616 test_inferCompilationUnit_method_parameter_multiple_optionalAndRequired()
{ |
638 InstanceMemberInferrer inferrer = createInferrer; | |
639 String methodName = 'm'; | 617 String methodName = 'm'; |
640 CompilationUnitElement unit = resolve(''' | 618 CompilationUnitElement unit = resolve(''' |
641 class A { | 619 class A { |
642 $methodName(int p) => 0; | 620 $methodName(int p) => 0; |
643 } | 621 } |
644 class B { | 622 class B { |
645 $methodName([int p]) => 0; | 623 $methodName([int p]) => 0; |
646 } | 624 } |
647 class C implements A, B { | 625 class C implements A, B { |
648 $methodName(p) => 0; | 626 $methodName(p) => 0; |
649 } | 627 } |
650 '''); | 628 '''); |
651 ClassElement classA = unit.getType('A'); | 629 ClassElement classA = unit.getType('A'); |
652 MethodElement methodA = classA.getMethod(methodName); | 630 MethodElement methodA = classA.getMethod(methodName); |
653 ParameterElement parameterA = methodA.parameters[0]; | 631 ParameterElement parameterA = methodA.parameters[0]; |
654 DartType expectedType = parameterA.type; | 632 DartType expectedType = parameterA.type; |
655 ClassElement classC = unit.getType('C'); | 633 ClassElement classC = unit.getType('C'); |
656 MethodElement methodC = classC.getMethod(methodName); | 634 MethodElement methodC = classC.getMethod(methodName); |
657 ParameterElement parameterC = methodC.parameters[0]; | 635 ParameterElement parameterC = methodC.parameters[0]; |
658 expect(parameterC.type.isDynamic, isTrue); | 636 expect(parameterC.type.isDynamic, isTrue); |
659 | 637 |
660 inferrer.inferCompilationUnit(unit); | 638 _runInferrer(unit); |
661 | 639 |
662 expect(parameterC.type, expectedType); | 640 expect(parameterC.type, expectedType); |
663 } | 641 } |
664 | 642 |
665 void test_inferCompilationUnit_method_parameter_single_generic() { | 643 void test_inferCompilationUnit_method_parameter_single_generic() { |
666 InstanceMemberInferrer inferrer = createInferrer; | |
667 String methodName = 'm'; | 644 String methodName = 'm'; |
668 CompilationUnitElement unit = resolve(''' | 645 CompilationUnitElement unit = resolve(''' |
669 class A<E> { | 646 class A<E> { |
670 $methodName(E p) => 0; | 647 $methodName(E p) => 0; |
671 } | 648 } |
672 class C<E> implements A<E> { | 649 class C<E> implements A<E> { |
673 $methodName(p) => 0; | 650 $methodName(p) => 0; |
674 } | 651 } |
675 '''); | 652 '''); |
676 ClassElement classC = unit.getType('C'); | 653 ClassElement classC = unit.getType('C'); |
677 DartType typeCE = classC.typeParameters[0].type; | 654 DartType typeCE = classC.typeParameters[0].type; |
678 MethodElement methodC = classC.getMethod(methodName); | 655 MethodElement methodC = classC.getMethod(methodName); |
679 ParameterElement parameterC = methodC.parameters[0]; | 656 ParameterElement parameterC = methodC.parameters[0]; |
680 expect(parameterC.type.isDynamic, isTrue); | 657 expect(parameterC.type.isDynamic, isTrue); |
681 expect(methodC.type.typeArguments, [typeCE]); | 658 expect(methodC.type.typeArguments, [typeCE]); |
682 | 659 |
683 inferrer.inferCompilationUnit(unit); | 660 _runInferrer(unit); |
684 | 661 |
685 expect(parameterC.type, classC.typeParameters[0].type); | 662 expect(parameterC.type, classC.typeParameters[0].type); |
686 expect(methodC.type.typeArguments, [typeCE], | 663 expect(methodC.type.typeArguments, [typeCE], |
687 reason: 'function type should still have type arguments'); | 664 reason: 'function type should still have type arguments'); |
688 } | 665 } |
689 | 666 |
690 void test_inferCompilationUnit_method_return_multiple_different() { | 667 void test_inferCompilationUnit_method_return_multiple_different() { |
691 InstanceMemberInferrer inferrer = createInferrer; | |
692 String methodName = 'm'; | 668 String methodName = 'm'; |
693 CompilationUnitElement unit = resolve(''' | 669 CompilationUnitElement unit = resolve(''' |
694 class A { | 670 class A { |
695 int $methodName() => 0; | 671 int $methodName() => 0; |
696 } | 672 } |
697 class B { | 673 class B { |
698 double $methodName() => 0.0; | 674 double $methodName() => 0.0; |
699 } | 675 } |
700 class C implements A, B { | 676 class C implements A, B { |
701 $methodName() => 0; | 677 $methodName() => 0; |
702 } | 678 } |
703 '''); | 679 '''); |
704 ClassElement classC = unit.getType('C'); | 680 ClassElement classC = unit.getType('C'); |
705 MethodElement methodC = classC.getMethod(methodName); | 681 MethodElement methodC = classC.getMethod(methodName); |
706 expect(methodC.returnType.isDynamic, isTrue); | 682 expect(methodC.returnType.isDynamic, isTrue); |
707 | 683 |
708 inferrer.inferCompilationUnit(unit); | 684 _runInferrer(unit); |
709 | 685 |
710 expect(methodC.returnType.isDynamic, isTrue); | 686 expect(methodC.returnType.isDynamic, isTrue); |
711 } | 687 } |
712 | 688 |
713 void test_inferCompilationUnit_method_return_multiple_different_generic() { | 689 void test_inferCompilationUnit_method_return_multiple_different_generic() { |
714 InstanceMemberInferrer inferrer = createInferrer; | |
715 String methodName = 'm'; | 690 String methodName = 'm'; |
716 CompilationUnitElement unit = resolve(''' | 691 CompilationUnitElement unit = resolve(''' |
717 class A<E> { | 692 class A<E> { |
718 E $methodName() => null; | 693 E $methodName() => null; |
719 } | 694 } |
720 class B<E> { | 695 class B<E> { |
721 E $methodName() => null; | 696 E $methodName() => null; |
722 } | 697 } |
723 class C implements A<int>, B<double> { | 698 class C implements A<int>, B<double> { |
724 $methodName() => null; | 699 $methodName() => null; |
725 } | 700 } |
726 '''); | 701 '''); |
727 ClassElement classC = unit.getType('C'); | 702 ClassElement classC = unit.getType('C'); |
728 MethodElement methodC = classC.getMethod(methodName); | 703 MethodElement methodC = classC.getMethod(methodName); |
729 expect(methodC.returnType.isDynamic, isTrue); | 704 expect(methodC.returnType.isDynamic, isTrue); |
730 | 705 |
731 inferrer.inferCompilationUnit(unit); | 706 _runInferrer(unit); |
732 | 707 |
733 expect(methodC.returnType.isDynamic, isTrue); | 708 expect(methodC.returnType.isDynamic, isTrue); |
734 } | 709 } |
735 | 710 |
736 void test_inferCompilationUnit_method_return_multiple_dynamic() { | 711 void test_inferCompilationUnit_method_return_multiple_dynamic() { |
737 InstanceMemberInferrer inferrer = createInferrer; | |
738 String methodName = 'm'; | 712 String methodName = 'm'; |
739 CompilationUnitElement unit = resolve(''' | 713 CompilationUnitElement unit = resolve(''' |
740 class A { | 714 class A { |
741 int $methodName() => 0; | 715 int $methodName() => 0; |
742 } | 716 } |
743 class B { | 717 class B { |
744 $methodName() => 0; | 718 $methodName() => 0; |
745 } | 719 } |
746 class C implements A, B { | 720 class C implements A, B { |
747 $methodName() => 0; | 721 $methodName() => 0; |
748 } | 722 } |
749 '''); | 723 '''); |
750 ClassElement classC = unit.getType('C'); | 724 ClassElement classC = unit.getType('C'); |
751 MethodElement methodC = classC.getMethod(methodName); | 725 MethodElement methodC = classC.getMethod(methodName); |
752 expect(methodC.returnType.isDynamic, isTrue); | 726 expect(methodC.returnType.isDynamic, isTrue); |
753 | 727 |
754 inferrer.inferCompilationUnit(unit); | 728 _runInferrer(unit); |
755 | 729 |
756 expect(methodC.returnType.isDynamic, isTrue); | 730 expect(methodC.returnType.isDynamic, isTrue); |
757 } | 731 } |
758 | 732 |
759 void test_inferCompilationUnit_method_return_multiple_same_generic() { | 733 void test_inferCompilationUnit_method_return_multiple_same_generic() { |
760 InstanceMemberInferrer inferrer = createInferrer; | |
761 String methodName = 'm'; | 734 String methodName = 'm'; |
762 CompilationUnitElement unit = resolve(''' | 735 CompilationUnitElement unit = resolve(''' |
763 class A<E> { | 736 class A<E> { |
764 E $methodName() => 0; | 737 E $methodName() => 0; |
765 } | 738 } |
766 class B<E> { | 739 class B<E> { |
767 E $methodName() => 0; | 740 E $methodName() => 0; |
768 } | 741 } |
769 class C<E> implements A<E>, B<E> { | 742 class C<E> implements A<E>, B<E> { |
770 $methodName() => 0; | 743 $methodName() => 0; |
771 } | 744 } |
772 '''); | 745 '''); |
773 ClassElement classC = unit.getType('C'); | 746 ClassElement classC = unit.getType('C'); |
774 MethodElement methodC = classC.getMethod(methodName); | 747 MethodElement methodC = classC.getMethod(methodName); |
775 expect(methodC.returnType.isDynamic, isTrue); | 748 expect(methodC.returnType.isDynamic, isTrue); |
776 | 749 |
777 inferrer.inferCompilationUnit(unit); | 750 _runInferrer(unit); |
778 | 751 |
779 expect(methodC.returnType, classC.typeParameters[0].type); | 752 expect(methodC.returnType, classC.typeParameters[0].type); |
780 } | 753 } |
781 | 754 |
782 void test_inferCompilationUnit_method_return_multiple_same_nonVoid() { | 755 void test_inferCompilationUnit_method_return_multiple_same_nonVoid() { |
783 InstanceMemberInferrer inferrer = createInferrer; | |
784 String methodName = 'm'; | 756 String methodName = 'm'; |
785 CompilationUnitElement unit = resolve(''' | 757 CompilationUnitElement unit = resolve(''' |
786 class A { | 758 class A { |
787 int $methodName() => 0; | 759 int $methodName() => 0; |
788 } | 760 } |
789 class B { | 761 class B { |
790 int $methodName() => 0; | 762 int $methodName() => 0; |
791 } | 763 } |
792 class C implements A, B { | 764 class C implements A, B { |
793 $methodName() => 0; | 765 $methodName() => 0; |
794 } | 766 } |
795 '''); | 767 '''); |
796 ClassElement classA = unit.getType('A'); | 768 ClassElement classA = unit.getType('A'); |
797 MethodElement methodA = classA.getMethod(methodName); | 769 MethodElement methodA = classA.getMethod(methodName); |
798 DartType expectedType = methodA.returnType; | 770 DartType expectedType = methodA.returnType; |
799 ClassElement classC = unit.getType('C'); | 771 ClassElement classC = unit.getType('C'); |
800 MethodElement methodC = classC.getMethod(methodName); | 772 MethodElement methodC = classC.getMethod(methodName); |
801 expect(methodC.returnType.isDynamic, isTrue); | 773 expect(methodC.returnType.isDynamic, isTrue); |
802 | 774 |
803 inferrer.inferCompilationUnit(unit); | 775 _runInferrer(unit); |
804 | 776 |
805 expect(methodC.returnType, expectedType); | 777 expect(methodC.returnType, expectedType); |
806 } | 778 } |
807 | 779 |
808 void test_inferCompilationUnit_method_return_multiple_same_void() { | 780 void test_inferCompilationUnit_method_return_multiple_same_void() { |
809 InstanceMemberInferrer inferrer = createInferrer; | |
810 String methodName = 'm'; | 781 String methodName = 'm'; |
811 CompilationUnitElement unit = resolve(''' | 782 CompilationUnitElement unit = resolve(''' |
812 class A { | 783 class A { |
813 void $methodName() {}; | 784 void $methodName() {}; |
814 } | 785 } |
815 class B { | 786 class B { |
816 void $methodName() {}; | 787 void $methodName() {}; |
817 } | 788 } |
818 class C implements A, B { | 789 class C implements A, B { |
819 $methodName() {}; | 790 $methodName() {}; |
820 } | 791 } |
821 '''); | 792 '''); |
822 ClassElement classA = unit.getType('A'); | 793 ClassElement classA = unit.getType('A'); |
823 MethodElement methodA = classA.getMethod(methodName); | 794 MethodElement methodA = classA.getMethod(methodName); |
824 DartType expectedType = methodA.returnType; | 795 DartType expectedType = methodA.returnType; |
825 ClassElement classC = unit.getType('C'); | 796 ClassElement classC = unit.getType('C'); |
826 MethodElement methodC = classC.getMethod(methodName); | 797 MethodElement methodC = classC.getMethod(methodName); |
827 expect(methodC.returnType.isDynamic, isTrue); | 798 expect(methodC.returnType.isDynamic, isTrue); |
828 | 799 |
829 inferrer.inferCompilationUnit(unit); | 800 _runInferrer(unit); |
830 | 801 |
831 expect(methodC.returnType, expectedType); | 802 expect(methodC.returnType, expectedType); |
832 } | 803 } |
833 | 804 |
834 void test_inferCompilationUnit_method_return_multiple_void() { | 805 void test_inferCompilationUnit_method_return_multiple_void() { |
835 InstanceMemberInferrer inferrer = createInferrer; | |
836 String methodName = 'm'; | 806 String methodName = 'm'; |
837 CompilationUnitElement unit = resolve(''' | 807 CompilationUnitElement unit = resolve(''' |
838 class A { | 808 class A { |
839 int $methodName() => 0; | 809 int $methodName() => 0; |
840 } | 810 } |
841 class B { | 811 class B { |
842 void $methodName() => 0; | 812 void $methodName() => 0; |
843 } | 813 } |
844 class C implements A, B { | 814 class C implements A, B { |
845 $methodName() => 0; | 815 $methodName() => 0; |
846 } | 816 } |
847 '''); | 817 '''); |
848 ClassElement classC = unit.getType('C'); | 818 ClassElement classC = unit.getType('C'); |
849 MethodElement methodC = classC.getMethod(methodName); | 819 MethodElement methodC = classC.getMethod(methodName); |
850 expect(methodC.returnType.isDynamic, isTrue); | 820 expect(methodC.returnType.isDynamic, isTrue); |
851 | 821 |
852 inferrer.inferCompilationUnit(unit); | 822 _runInferrer(unit); |
853 | 823 |
854 expect(methodC.returnType.isDynamic, isTrue); | 824 expect(methodC.returnType.isDynamic, isTrue); |
855 } | 825 } |
856 | 826 |
857 void test_inferCompilationUnit_method_return_single() { | 827 void test_inferCompilationUnit_method_return_single() { |
858 InstanceMemberInferrer inferrer = createInferrer; | |
859 String methodName = 'm'; | 828 String methodName = 'm'; |
860 CompilationUnitElement unit = resolve(''' | 829 CompilationUnitElement unit = resolve(''' |
861 class A { | 830 class A { |
862 int $methodName() => 0; | 831 int $methodName() => 0; |
863 } | 832 } |
864 class B extends A { | 833 class B extends A { |
865 $methodName() => 0; | 834 $methodName() => 0; |
866 } | 835 } |
867 '''); | 836 '''); |
868 ClassElement classA = unit.getType('A'); | 837 ClassElement classA = unit.getType('A'); |
869 MethodElement methodA = classA.getMethod(methodName); | 838 MethodElement methodA = classA.getMethod(methodName); |
870 ClassElement classB = unit.getType('B'); | 839 ClassElement classB = unit.getType('B'); |
871 MethodElement methodB = classB.getMethod(methodName); | 840 MethodElement methodB = classB.getMethod(methodName); |
872 expect(methodB.returnType.isDynamic, isTrue); | 841 expect(methodB.returnType.isDynamic, isTrue); |
873 | 842 |
874 inferrer.inferCompilationUnit(unit); | 843 _runInferrer(unit); |
875 | 844 |
876 expect(methodB.returnType, methodA.returnType); | 845 expect(methodB.returnType, methodA.returnType); |
877 } | 846 } |
878 | 847 |
879 void test_inferCompilationUnit_method_return_single_generic() { | 848 void test_inferCompilationUnit_method_return_single_generic() { |
880 InstanceMemberInferrer inferrer = createInferrer; | |
881 String methodName = 'm'; | 849 String methodName = 'm'; |
882 CompilationUnitElement unit = resolve(''' | 850 CompilationUnitElement unit = resolve(''' |
883 class A<E> { | 851 class A<E> { |
884 E $methodName() => 0; | 852 E $methodName() => 0; |
885 } | 853 } |
886 class B<E> extends A<E> { | 854 class B<E> extends A<E> { |
887 $methodName() => 0; | 855 $methodName() => 0; |
888 } | 856 } |
889 '''); | 857 '''); |
890 ClassElement classB = unit.getType('B'); | 858 ClassElement classB = unit.getType('B'); |
891 DartType typeBE = classB.typeParameters[0].type; | 859 DartType typeBE = classB.typeParameters[0].type; |
892 MethodElement methodB = classB.getMethod(methodName); | 860 MethodElement methodB = classB.getMethod(methodName); |
893 expect(methodB.returnType.isDynamic, isTrue); | 861 expect(methodB.returnType.isDynamic, isTrue); |
894 expect(methodB.type.typeArguments, [typeBE]); | 862 expect(methodB.type.typeArguments, [typeBE]); |
895 | 863 |
896 inferrer.inferCompilationUnit(unit); | 864 _runInferrer(unit); |
897 | 865 |
898 expect(methodB.returnType, classB.typeParameters[0].type); | 866 expect(methodB.returnType, classB.typeParameters[0].type); |
899 expect(methodB.type.typeArguments, [typeBE], | 867 expect(methodB.type.typeArguments, [typeBE], |
900 reason: 'function type should still have type arguments'); | 868 reason: 'function type should still have type arguments'); |
901 } | 869 } |
902 | 870 |
903 void test_inferCompilationUnit_setter_single() { | 871 void test_inferCompilationUnit_setter_single() { |
904 InstanceMemberInferrer inferrer = createInferrer; | |
905 String setterName = 'g'; | 872 String setterName = 'g'; |
906 CompilationUnitElement unit = resolve(''' | 873 CompilationUnitElement unit = resolve(''' |
907 class A { | 874 class A { |
908 set $setterName(int x) {} | 875 set $setterName(int x) {} |
909 } | 876 } |
910 class B extends A { | 877 class B extends A { |
911 set $setterName(x) {} | 878 set $setterName(x) {} |
912 } | 879 } |
913 '''); | 880 '''); |
914 ClassElement classA = unit.getType('A'); | 881 ClassElement classA = unit.getType('A'); |
915 FieldElement fieldA = classA.getField(setterName); | 882 FieldElement fieldA = classA.getField(setterName); |
916 PropertyAccessorElement setterA = classA.getSetter(setterName); | 883 PropertyAccessorElement setterA = classA.getSetter(setterName); |
917 ClassElement classB = unit.getType('B'); | 884 ClassElement classB = unit.getType('B'); |
918 FieldElement fieldB = classB.getField(setterName); | 885 FieldElement fieldB = classB.getField(setterName); |
919 PropertyAccessorElement setterB = classB.getSetter(setterName); | 886 PropertyAccessorElement setterB = classB.getSetter(setterName); |
920 expect(fieldB.type.isDynamic, isTrue); | 887 expect(fieldB.type.isDynamic, isTrue); |
921 expect(setterB.parameters[0].type.isDynamic, isTrue); | 888 expect(setterB.parameters[0].type.isDynamic, isTrue); |
922 | 889 |
923 inferrer.inferCompilationUnit(unit); | 890 _runInferrer(unit); |
924 | 891 |
925 expect(fieldB.type, fieldA.type); | 892 expect(fieldB.type, fieldA.type); |
926 expect(setterB.parameters[0].type, setterA.parameters[0].type); | 893 expect(setterB.parameters[0].type, setterA.parameters[0].type); |
927 } | 894 } |
928 | 895 |
929 void test_inferCompilationUnit_setter_single_generic() { | 896 void test_inferCompilationUnit_setter_single_generic() { |
930 InstanceMemberInferrer inferrer = createInferrer; | |
931 String setterName = 'g'; | 897 String setterName = 'g'; |
932 CompilationUnitElement unit = resolve(''' | 898 CompilationUnitElement unit = resolve(''' |
933 class A<E> { | 899 class A<E> { |
934 set $setterName(E x) {} | 900 set $setterName(E x) {} |
935 } | 901 } |
936 class B<E> extends A<E> { | 902 class B<E> extends A<E> { |
937 set $setterName(x) {} | 903 set $setterName(x) {} |
938 } | 904 } |
939 '''); | 905 '''); |
940 ClassElement classB = unit.getType('B'); | 906 ClassElement classB = unit.getType('B'); |
941 DartType typeBE = classB.typeParameters[0].type; | 907 DartType typeBE = classB.typeParameters[0].type; |
942 FieldElement fieldB = classB.getField(setterName); | 908 FieldElement fieldB = classB.getField(setterName); |
943 PropertyAccessorElement setterB = classB.getSetter(setterName); | 909 PropertyAccessorElement setterB = classB.getSetter(setterName); |
944 expect(fieldB.type.isDynamic, isTrue); | 910 expect(fieldB.type.isDynamic, isTrue); |
945 expect(setterB.parameters[0].type.isDynamic, isTrue); | 911 expect(setterB.parameters[0].type.isDynamic, isTrue); |
946 | 912 |
947 inferrer.inferCompilationUnit(unit); | 913 _runInferrer(unit); |
948 | 914 |
949 expect(fieldB.type, typeBE); | 915 expect(fieldB.type, typeBE); |
950 expect(setterB.parameters[0].type, typeBE); | 916 expect(setterB.parameters[0].type, typeBE); |
951 } | 917 } |
952 | 918 |
953 void test_inferCompilationUnit_setter_single_inconsistentAccessors() { | 919 void test_inferCompilationUnit_setter_single_inconsistentAccessors() { |
954 InstanceMemberInferrer inferrer = createInferrer; | |
955 String getterName = 'g'; | 920 String getterName = 'g'; |
956 CompilationUnitElement unit = resolve(''' | 921 CompilationUnitElement unit = resolve(''' |
957 class A { | 922 class A { |
958 int get $getterName => 0; | 923 int get $getterName => 0; |
959 set $getterName(String value) {} | 924 set $getterName(String value) {} |
960 } | 925 } |
961 class B extends A { | 926 class B extends A { |
962 set $getterName(x) {} | 927 set $getterName(x) {} |
963 } | 928 } |
964 '''); | 929 '''); |
965 ClassElement classA = unit.getType('A'); | 930 ClassElement classA = unit.getType('A'); |
966 PropertyAccessorElement setterA = classA.getSetter(getterName); | 931 PropertyAccessorElement setterA = classA.getSetter(getterName); |
967 ClassElement classB = unit.getType('B'); | 932 ClassElement classB = unit.getType('B'); |
968 FieldElement fieldB = classB.getField(getterName); | 933 FieldElement fieldB = classB.getField(getterName); |
969 PropertyAccessorElement setterB = classB.getSetter(getterName); | 934 PropertyAccessorElement setterB = classB.getSetter(getterName); |
970 expect(fieldB.type.isDynamic, isTrue); | 935 expect(fieldB.type.isDynamic, isTrue); |
971 expect(setterB.parameters[0].type.isDynamic, isTrue); | 936 expect(setterB.parameters[0].type.isDynamic, isTrue); |
972 | 937 |
973 inferrer.inferCompilationUnit(unit); | 938 _runInferrer(unit); |
974 | 939 |
975 // Expected behavior is that the getter is inferred: getters and setters | 940 // Expected behavior is that the getter is inferred: getters and setters |
976 // are treated as independent methods. | 941 // are treated as independent methods. |
977 expect(setterB.parameters[0].type, setterA.parameters[0].type); | 942 expect(setterB.parameters[0].type, setterA.parameters[0].type); |
978 | 943 |
979 // Note that B's synthetic field type will be String. This matches what | 944 // Note that B's synthetic field type will be String. This matches what |
980 // resolver would do if we explicitly typed the parameter as 'String' | 945 // resolver would do if we explicitly typed the parameter as 'String' |
981 expect(fieldB.type, setterB.parameters[0].type); | 946 expect(fieldB.type, setterB.parameters[0].type); |
982 } | 947 } |
| 948 |
| 949 InstanceMemberInferrer _runInferrer(CompilationUnitElement unit) { |
| 950 InstanceMemberInferrer inferrer = createInferrer(unit.library); |
| 951 inferrer.inferCompilationUnit(unit); |
| 952 return inferrer; |
| 953 } |
983 } | 954 } |
984 | 955 |
985 @reflectiveTest | 956 @reflectiveTest |
986 class SetFieldTypeTest extends AbstractContextTest { | 957 class SetFieldTypeTest extends AbstractContextTest { |
987 void test_setter_withoutParameter() { | 958 void test_setter_withoutParameter() { |
988 CompilationUnitElement unit = _resolve(''' | 959 CompilationUnitElement unit = _resolve(''' |
989 var x = 0; | 960 var x = 0; |
990 set x() {} | 961 set x() {} |
991 '''); | 962 '''); |
992 TopLevelVariableElement variable = unit.topLevelVariables.single; | 963 TopLevelVariableElement variable = unit.topLevelVariables.single; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1060 } | 1031 } |
1061 } | 1032 } |
1062 } | 1033 } |
1063 '''); | 1034 '''); |
1064 CompilationUnit unit = context.resolveCompilationUnit2(source, source); | 1035 CompilationUnit unit = context.resolveCompilationUnit2(source, source); |
1065 VariableGatherer gatherer = new VariableGatherer(filter); | 1036 VariableGatherer gatherer = new VariableGatherer(filter); |
1066 unit.accept(gatherer); | 1037 unit.accept(gatherer); |
1067 return gatherer.results; | 1038 return gatherer.results; |
1068 } | 1039 } |
1069 } | 1040 } |
OLD | NEW |