OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library analyzer.test.generated.element_test; | |
6 | |
7 import 'package:analyzer/dart/element/element.dart'; | |
8 import 'package:analyzer/dart/element/type.dart'; | |
9 import 'package:analyzer/src/dart/element/element.dart'; | |
10 import 'package:analyzer/src/dart/element/type.dart'; | |
11 import 'package:analyzer/src/generated/ast.dart'; | |
12 import 'package:analyzer/src/generated/engine.dart' | |
13 show AnalysisContext, AnalysisOptionsImpl; | |
14 import 'package:analyzer/src/generated/java_core.dart'; | |
15 import 'package:analyzer/src/generated/source_io.dart'; | |
16 import 'package:analyzer/src/generated/testing/ast_factory.dart'; | |
17 import 'package:analyzer/src/generated/testing/element_factory.dart'; | |
18 import 'package:analyzer/src/generated/testing/test_type_provider.dart'; | |
19 import 'package:unittest/unittest.dart'; | |
20 | |
21 import '../reflective_tests.dart'; | |
22 import '../utils.dart'; | |
23 import 'resolver_test.dart' show TestTypeProvider, AnalysisContextHelper; | |
24 import 'test_support.dart'; | |
25 | |
26 main() { | |
27 initializeTestEnvironment(); | |
28 runReflectiveTests(ElementKindTest); | |
29 runReflectiveTests(FieldElementImplTest); | |
30 runReflectiveTests(FunctionTypeImplTest); | |
31 runReflectiveTests(InterfaceTypeImplTest); | |
32 runReflectiveTests(TypeParameterTypeImplTest); | |
33 runReflectiveTests(VoidTypeImplTest); | |
34 runReflectiveTests(ClassElementImplTest); | |
35 runReflectiveTests(CompilationUnitElementImplTest); | |
36 runReflectiveTests(ElementLocationImplTest); | |
37 runReflectiveTests(ElementImplTest); | |
38 runReflectiveTests(LibraryElementImplTest); | |
39 runReflectiveTests(MethodElementImplTest); | |
40 runReflectiveTests(MultiplyDefinedElementImplTest); | |
41 runReflectiveTests(ParameterElementImplTest); | |
42 } | |
43 | |
44 @reflectiveTest | |
45 class ClassElementImplTest extends EngineTestCase { | |
46 void test_computeNode_ClassDeclaration() { | |
47 AnalysisContextHelper contextHelper = new AnalysisContextHelper(); | |
48 AnalysisContext context = contextHelper.context; | |
49 Source source = contextHelper.addSource( | |
50 "/test.dart", | |
51 r''' | |
52 class A {} | |
53 @deprecated class B {} | |
54 enum C {C1, C2, C3} | |
55 @deprecated enum D {D1, D2, D3}'''); | |
56 // prepare CompilationUnitElement | |
57 LibraryElement libraryElement = context.computeLibraryElement(source); | |
58 CompilationUnitElement unitElement = libraryElement.definingCompilationUnit; | |
59 // A | |
60 { | |
61 ClassElement elementA = unitElement.getType("A"); | |
62 expect(elementA.isDeprecated, isFalse); | |
63 expect(elementA.isEnum, isFalse); | |
64 ClassDeclaration nodeA = elementA.computeNode(); | |
65 expect(nodeA, isNotNull); | |
66 expect(nodeA.name.name, "A"); | |
67 expect(nodeA.element, same(elementA)); | |
68 } | |
69 // B | |
70 { | |
71 ClassElement elementB = unitElement.getType("B"); | |
72 expect(elementB.isDeprecated, isTrue); | |
73 expect(elementB.isEnum, isFalse); | |
74 ClassDeclaration nodeB = elementB.computeNode(); | |
75 expect(nodeB, isNotNull); | |
76 expect(nodeB.name.name, "B"); | |
77 expect(nodeB.element, same(elementB)); | |
78 } | |
79 // C | |
80 { | |
81 ClassElement elementC = unitElement.getEnum("C"); | |
82 expect(elementC.isDeprecated, isFalse); | |
83 expect(elementC.isEnum, isTrue); | |
84 EnumDeclaration nodeC = elementC.computeNode(); | |
85 expect(nodeC, isNotNull); | |
86 expect(nodeC.name.name, "C"); | |
87 expect(nodeC.element, same(elementC)); | |
88 } | |
89 // D | |
90 { | |
91 ClassElement elementD = unitElement.getEnum("D"); | |
92 expect(elementD.isDeprecated, isTrue); | |
93 expect(elementD.isEnum, isTrue); | |
94 EnumDeclaration nodeC = elementD.computeNode(); | |
95 expect(nodeC, isNotNull); | |
96 expect(nodeC.name.name, "D"); | |
97 expect(nodeC.element, same(elementD)); | |
98 } | |
99 } | |
100 | |
101 void test_computeNode_ClassTypeAlias() { | |
102 AnalysisContextHelper contextHelper = new AnalysisContextHelper(); | |
103 AnalysisContext context = contextHelper.context; | |
104 Source source = contextHelper.addSource( | |
105 "/test.dart", | |
106 r''' | |
107 abstract class A<K, V> = Object with MapMixin<K, V>; | |
108 '''); | |
109 // prepare CompilationUnitElement | |
110 LibraryElement libraryElement = context.computeLibraryElement(source); | |
111 CompilationUnitElement unitElement = libraryElement.definingCompilationUnit; | |
112 // A | |
113 { | |
114 ClassElement elementA = unitElement.getType("A"); | |
115 ClassTypeAlias nodeA = elementA.computeNode(); | |
116 expect(nodeA, isNotNull); | |
117 expect(nodeA.name.name, "A"); | |
118 expect(nodeA.element, same(elementA)); | |
119 } | |
120 } | |
121 | |
122 void test_getAllSupertypes_interface() { | |
123 ClassElement classA = ElementFactory.classElement2("A"); | |
124 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
125 ClassElementImpl elementC = ElementFactory.classElement2("C"); | |
126 InterfaceType typeObject = classA.supertype; | |
127 InterfaceType typeA = classA.type; | |
128 InterfaceType typeB = classB.type; | |
129 InterfaceType typeC = elementC.type; | |
130 elementC.interfaces = <InterfaceType>[typeB]; | |
131 List<InterfaceType> supers = elementC.allSupertypes; | |
132 List<InterfaceType> types = new List<InterfaceType>(); | |
133 types.addAll(supers); | |
134 expect(types.contains(typeA), isTrue); | |
135 expect(types.contains(typeB), isTrue); | |
136 expect(types.contains(typeObject), isTrue); | |
137 expect(types.contains(typeC), isFalse); | |
138 } | |
139 | |
140 void test_getAllSupertypes_mixins() { | |
141 ClassElement classA = ElementFactory.classElement2("A"); | |
142 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
143 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
144 InterfaceType typeObject = classA.supertype; | |
145 InterfaceType typeA = classA.type; | |
146 InterfaceType typeB = classB.type; | |
147 InterfaceType typeC = classC.type; | |
148 classC.mixins = <InterfaceType>[typeB]; | |
149 List<InterfaceType> supers = classC.allSupertypes; | |
150 List<InterfaceType> types = new List<InterfaceType>(); | |
151 types.addAll(supers); | |
152 expect(types.contains(typeA), isFalse); | |
153 expect(types.contains(typeB), isTrue); | |
154 expect(types.contains(typeObject), isTrue); | |
155 expect(types.contains(typeC), isFalse); | |
156 } | |
157 | |
158 void test_getAllSupertypes_recursive() { | |
159 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
160 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
161 classA.supertype = classB.type; | |
162 List<InterfaceType> supers = classB.allSupertypes; | |
163 expect(supers, hasLength(1)); | |
164 } | |
165 | |
166 void test_getField() { | |
167 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
168 String fieldName = "f"; | |
169 FieldElementImpl field = | |
170 ElementFactory.fieldElement(fieldName, false, false, false, null); | |
171 classA.fields = <FieldElement>[field]; | |
172 expect(classA.getField(fieldName), same(field)); | |
173 expect(field.isEnumConstant, false); | |
174 // no such field | |
175 expect(classA.getField("noSuchField"), same(null)); | |
176 } | |
177 | |
178 void test_getMethod_declared() { | |
179 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
180 String methodName = "m"; | |
181 MethodElement method = ElementFactory.methodElement(methodName, null); | |
182 classA.methods = <MethodElement>[method]; | |
183 expect(classA.getMethod(methodName), same(method)); | |
184 } | |
185 | |
186 void test_getMethod_undeclared() { | |
187 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
188 String methodName = "m"; | |
189 MethodElement method = ElementFactory.methodElement(methodName, null); | |
190 classA.methods = <MethodElement>[method]; | |
191 expect(classA.getMethod("${methodName}x"), isNull); | |
192 } | |
193 | |
194 void test_hasNonFinalField_false_const() { | |
195 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
196 classA.fields = <FieldElement>[ | |
197 ElementFactory.fieldElement("f", false, false, true, classA.type) | |
198 ]; | |
199 expect(classA.hasNonFinalField, isFalse); | |
200 } | |
201 | |
202 void test_hasNonFinalField_false_final() { | |
203 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
204 classA.fields = <FieldElement>[ | |
205 ElementFactory.fieldElement("f", false, true, false, classA.type) | |
206 ]; | |
207 expect(classA.hasNonFinalField, isFalse); | |
208 } | |
209 | |
210 void test_hasNonFinalField_false_recursive() { | |
211 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
212 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
213 classA.supertype = classB.type; | |
214 expect(classA.hasNonFinalField, isFalse); | |
215 } | |
216 | |
217 void test_hasNonFinalField_true_immediate() { | |
218 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
219 classA.fields = <FieldElement>[ | |
220 ElementFactory.fieldElement("f", false, false, false, classA.type) | |
221 ]; | |
222 expect(classA.hasNonFinalField, isTrue); | |
223 } | |
224 | |
225 void test_hasNonFinalField_true_inherited() { | |
226 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
227 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
228 classA.fields = <FieldElement>[ | |
229 ElementFactory.fieldElement("f", false, false, false, classA.type) | |
230 ]; | |
231 expect(classB.hasNonFinalField, isTrue); | |
232 } | |
233 | |
234 void test_hasStaticMember_false_empty() { | |
235 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
236 // no members | |
237 expect(classA.hasStaticMember, isFalse); | |
238 } | |
239 | |
240 void test_hasStaticMember_false_instanceMethod() { | |
241 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
242 MethodElement method = ElementFactory.methodElement("foo", null); | |
243 classA.methods = <MethodElement>[method]; | |
244 expect(classA.hasStaticMember, isFalse); | |
245 } | |
246 | |
247 void test_hasStaticMember_instanceGetter() { | |
248 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
249 PropertyAccessorElement getter = | |
250 ElementFactory.getterElement("foo", false, null); | |
251 classA.accessors = <PropertyAccessorElement>[getter]; | |
252 expect(classA.hasStaticMember, isFalse); | |
253 } | |
254 | |
255 void test_hasStaticMember_true_getter() { | |
256 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
257 PropertyAccessorElementImpl getter = | |
258 ElementFactory.getterElement("foo", false, null); | |
259 classA.accessors = <PropertyAccessorElement>[getter]; | |
260 // "foo" is static | |
261 getter.static = true; | |
262 expect(classA.hasStaticMember, isTrue); | |
263 } | |
264 | |
265 void test_hasStaticMember_true_method() { | |
266 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
267 MethodElementImpl method = ElementFactory.methodElement("foo", null); | |
268 classA.methods = <MethodElement>[method]; | |
269 // "foo" is static | |
270 method.static = true; | |
271 expect(classA.hasStaticMember, isTrue); | |
272 } | |
273 | |
274 void test_hasStaticMember_true_setter() { | |
275 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
276 PropertyAccessorElementImpl setter = | |
277 ElementFactory.setterElement("foo", false, null); | |
278 classA.accessors = <PropertyAccessorElement>[setter]; | |
279 // "foo" is static | |
280 setter.static = true; | |
281 expect(classA.hasStaticMember, isTrue); | |
282 } | |
283 | |
284 void test_isEnum() { | |
285 String firstConst = "A"; | |
286 String secondConst = "B"; | |
287 ClassElementImpl enumE = ElementFactory | |
288 .enumElement(new TestTypeProvider(), "E", [firstConst, secondConst]); | |
289 | |
290 // E is an enum | |
291 expect(enumE.isEnum, true); | |
292 | |
293 // A and B are static members | |
294 expect(enumE.getField(firstConst).isEnumConstant, true); | |
295 expect(enumE.getField(secondConst).isEnumConstant, true); | |
296 } | |
297 | |
298 void test_lookUpConcreteMethod_declared() { | |
299 // class A { | |
300 // m() {} | |
301 // } | |
302 LibraryElementImpl library = | |
303 ElementFactory.library(createAnalysisContext(), "lib"); | |
304 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
305 String methodName = "m"; | |
306 MethodElement method = ElementFactory.methodElement(methodName, null); | |
307 classA.methods = <MethodElement>[method]; | |
308 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
309 <ClassElement>[classA]; | |
310 expect(classA.lookUpConcreteMethod(methodName, library), same(method)); | |
311 } | |
312 | |
313 void test_lookUpConcreteMethod_declaredAbstract() { | |
314 // class A { | |
315 // m(); | |
316 // } | |
317 LibraryElementImpl library = | |
318 ElementFactory.library(createAnalysisContext(), "lib"); | |
319 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
320 String methodName = "m"; | |
321 MethodElementImpl method = ElementFactory.methodElement(methodName, null); | |
322 method.abstract = true; | |
323 classA.methods = <MethodElement>[method]; | |
324 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
325 <ClassElement>[classA]; | |
326 expect(classA.lookUpConcreteMethod(methodName, library), isNull); | |
327 } | |
328 | |
329 void test_lookUpConcreteMethod_declaredAbstractAndInherited() { | |
330 // class A { | |
331 // m() {} | |
332 // } | |
333 // class B extends A { | |
334 // m(); | |
335 // } | |
336 LibraryElementImpl library = | |
337 ElementFactory.library(createAnalysisContext(), "lib"); | |
338 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
339 String methodName = "m"; | |
340 MethodElement inheritedMethod = | |
341 ElementFactory.methodElement(methodName, null); | |
342 classA.methods = <MethodElement>[inheritedMethod]; | |
343 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
344 MethodElementImpl method = ElementFactory.methodElement(methodName, null); | |
345 method.abstract = true; | |
346 classB.methods = <MethodElement>[method]; | |
347 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
348 <ClassElement>[classA, classB]; | |
349 expect(classB.lookUpConcreteMethod(methodName, library), | |
350 same(inheritedMethod)); | |
351 } | |
352 | |
353 void test_lookUpConcreteMethod_declaredAndInherited() { | |
354 // class A { | |
355 // m() {} | |
356 // } | |
357 // class B extends A { | |
358 // m() {} | |
359 // } | |
360 LibraryElementImpl library = | |
361 ElementFactory.library(createAnalysisContext(), "lib"); | |
362 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
363 String methodName = "m"; | |
364 MethodElement inheritedMethod = | |
365 ElementFactory.methodElement(methodName, null); | |
366 classA.methods = <MethodElement>[inheritedMethod]; | |
367 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
368 MethodElement method = ElementFactory.methodElement(methodName, null); | |
369 classB.methods = <MethodElement>[method]; | |
370 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
371 <ClassElement>[classA, classB]; | |
372 expect(classB.lookUpConcreteMethod(methodName, library), same(method)); | |
373 } | |
374 | |
375 void test_lookUpConcreteMethod_declaredAndInheritedAbstract() { | |
376 // abstract class A { | |
377 // m(); | |
378 // } | |
379 // class B extends A { | |
380 // m() {} | |
381 // } | |
382 LibraryElementImpl library = | |
383 ElementFactory.library(createAnalysisContext(), "lib"); | |
384 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
385 classA.abstract = true; | |
386 String methodName = "m"; | |
387 MethodElementImpl inheritedMethod = | |
388 ElementFactory.methodElement(methodName, null); | |
389 inheritedMethod.abstract = true; | |
390 classA.methods = <MethodElement>[inheritedMethod]; | |
391 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
392 MethodElement method = ElementFactory.methodElement(methodName, null); | |
393 classB.methods = <MethodElement>[method]; | |
394 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
395 <ClassElement>[classA, classB]; | |
396 expect(classB.lookUpConcreteMethod(methodName, library), same(method)); | |
397 } | |
398 | |
399 void test_lookUpConcreteMethod_inherited() { | |
400 // class A { | |
401 // m() {} | |
402 // } | |
403 // class B extends A { | |
404 // } | |
405 LibraryElementImpl library = | |
406 ElementFactory.library(createAnalysisContext(), "lib"); | |
407 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
408 String methodName = "m"; | |
409 MethodElement inheritedMethod = | |
410 ElementFactory.methodElement(methodName, null); | |
411 classA.methods = <MethodElement>[inheritedMethod]; | |
412 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
413 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
414 <ClassElement>[classA, classB]; | |
415 expect(classB.lookUpConcreteMethod(methodName, library), | |
416 same(inheritedMethod)); | |
417 } | |
418 | |
419 void test_lookUpConcreteMethod_undeclared() { | |
420 // class A { | |
421 // } | |
422 LibraryElementImpl library = | |
423 ElementFactory.library(createAnalysisContext(), "lib"); | |
424 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
425 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
426 <ClassElement>[classA]; | |
427 expect(classA.lookUpConcreteMethod("m", library), isNull); | |
428 } | |
429 | |
430 void test_lookUpGetter_declared() { | |
431 // class A { | |
432 // get g {} | |
433 // } | |
434 LibraryElementImpl library = | |
435 ElementFactory.library(createAnalysisContext(), "lib"); | |
436 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
437 String getterName = "g"; | |
438 PropertyAccessorElement getter = | |
439 ElementFactory.getterElement(getterName, false, null); | |
440 classA.accessors = <PropertyAccessorElement>[getter]; | |
441 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
442 <ClassElement>[classA]; | |
443 expect(classA.lookUpGetter(getterName, library), same(getter)); | |
444 } | |
445 | |
446 void test_lookUpGetter_inherited() { | |
447 // class A { | |
448 // get g {} | |
449 // } | |
450 // class B extends A { | |
451 // } | |
452 LibraryElementImpl library = | |
453 ElementFactory.library(createAnalysisContext(), "lib"); | |
454 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
455 String getterName = "g"; | |
456 PropertyAccessorElement getter = | |
457 ElementFactory.getterElement(getterName, false, null); | |
458 classA.accessors = <PropertyAccessorElement>[getter]; | |
459 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
460 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
461 <ClassElement>[classA, classB]; | |
462 expect(classB.lookUpGetter(getterName, library), same(getter)); | |
463 } | |
464 | |
465 void test_lookUpGetter_undeclared() { | |
466 // class A { | |
467 // } | |
468 LibraryElementImpl library = | |
469 ElementFactory.library(createAnalysisContext(), "lib"); | |
470 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
471 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
472 <ClassElement>[classA]; | |
473 expect(classA.lookUpGetter("g", library), isNull); | |
474 } | |
475 | |
476 void test_lookUpGetter_undeclared_recursive() { | |
477 // class A extends B { | |
478 // } | |
479 // class B extends A { | |
480 // } | |
481 LibraryElementImpl library = | |
482 ElementFactory.library(createAnalysisContext(), "lib"); | |
483 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
484 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
485 classA.supertype = classB.type; | |
486 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
487 <ClassElement>[classA, classB]; | |
488 expect(classA.lookUpGetter("g", library), isNull); | |
489 } | |
490 | |
491 void test_lookUpInheritedConcreteGetter_declared() { | |
492 // class A { | |
493 // get g {} | |
494 // } | |
495 LibraryElementImpl library = | |
496 ElementFactory.library(createAnalysisContext(), "lib"); | |
497 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
498 String getterName = "g"; | |
499 PropertyAccessorElement getter = | |
500 ElementFactory.getterElement(getterName, false, null); | |
501 classA.accessors = <PropertyAccessorElement>[getter]; | |
502 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
503 <ClassElement>[classA]; | |
504 expect(classA.lookUpInheritedConcreteGetter(getterName, library), isNull); | |
505 } | |
506 | |
507 void test_lookUpInheritedConcreteGetter_inherited() { | |
508 // class A { | |
509 // get g {} | |
510 // } | |
511 // class B extends A { | |
512 // } | |
513 LibraryElementImpl library = | |
514 ElementFactory.library(createAnalysisContext(), "lib"); | |
515 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
516 String getterName = "g"; | |
517 PropertyAccessorElement inheritedGetter = | |
518 ElementFactory.getterElement(getterName, false, null); | |
519 classA.accessors = <PropertyAccessorElement>[inheritedGetter]; | |
520 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
521 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
522 <ClassElement>[classA, classB]; | |
523 expect(classB.lookUpInheritedConcreteGetter(getterName, library), | |
524 same(inheritedGetter)); | |
525 } | |
526 | |
527 void test_lookUpInheritedConcreteGetter_undeclared() { | |
528 // class A { | |
529 // } | |
530 LibraryElementImpl library = | |
531 ElementFactory.library(createAnalysisContext(), "lib"); | |
532 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
533 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
534 <ClassElement>[classA]; | |
535 expect(classA.lookUpInheritedConcreteGetter("g", library), isNull); | |
536 } | |
537 | |
538 void test_lookUpInheritedConcreteGetter_undeclared_recursive() { | |
539 // class A extends B { | |
540 // } | |
541 // class B extends A { | |
542 // } | |
543 LibraryElementImpl library = | |
544 ElementFactory.library(createAnalysisContext(), "lib"); | |
545 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
546 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
547 classA.supertype = classB.type; | |
548 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
549 <ClassElement>[classA, classB]; | |
550 expect(classA.lookUpInheritedConcreteGetter("g", library), isNull); | |
551 } | |
552 | |
553 void test_lookUpInheritedConcreteMethod_declared() { | |
554 // class A { | |
555 // m() {} | |
556 // } | |
557 LibraryElementImpl library = | |
558 ElementFactory.library(createAnalysisContext(), "lib"); | |
559 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
560 String methodName = "m"; | |
561 MethodElement method = ElementFactory.methodElement(methodName, null); | |
562 classA.methods = <MethodElement>[method]; | |
563 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
564 <ClassElement>[classA]; | |
565 expect(classA.lookUpInheritedConcreteMethod(methodName, library), isNull); | |
566 } | |
567 | |
568 void test_lookUpInheritedConcreteMethod_declaredAbstractAndInherited() { | |
569 // class A { | |
570 // m() {} | |
571 // } | |
572 // class B extends A { | |
573 // m(); | |
574 // } | |
575 LibraryElementImpl library = | |
576 ElementFactory.library(createAnalysisContext(), "lib"); | |
577 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
578 String methodName = "m"; | |
579 MethodElement inheritedMethod = | |
580 ElementFactory.methodElement(methodName, null); | |
581 classA.methods = <MethodElement>[inheritedMethod]; | |
582 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
583 MethodElementImpl method = ElementFactory.methodElement(methodName, null); | |
584 method.abstract = true; | |
585 classB.methods = <MethodElement>[method]; | |
586 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
587 <ClassElement>[classA, classB]; | |
588 expect(classB.lookUpInheritedConcreteMethod(methodName, library), | |
589 same(inheritedMethod)); | |
590 } | |
591 | |
592 void test_lookUpInheritedConcreteMethod_declaredAndInherited() { | |
593 // class A { | |
594 // m() {} | |
595 // } | |
596 // class B extends A { | |
597 // m() {} | |
598 // } | |
599 LibraryElementImpl library = | |
600 ElementFactory.library(createAnalysisContext(), "lib"); | |
601 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
602 String methodName = "m"; | |
603 MethodElement inheritedMethod = | |
604 ElementFactory.methodElement(methodName, null); | |
605 classA.methods = <MethodElement>[inheritedMethod]; | |
606 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
607 MethodElement method = ElementFactory.methodElement(methodName, null); | |
608 classB.methods = <MethodElement>[method]; | |
609 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
610 <ClassElement>[classA, classB]; | |
611 expect(classB.lookUpInheritedConcreteMethod(methodName, library), | |
612 same(inheritedMethod)); | |
613 } | |
614 | |
615 void test_lookUpInheritedConcreteMethod_declaredAndInheritedAbstract() { | |
616 // abstract class A { | |
617 // m(); | |
618 // } | |
619 // class B extends A { | |
620 // m() {} | |
621 // } | |
622 LibraryElementImpl library = | |
623 ElementFactory.library(createAnalysisContext(), "lib"); | |
624 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
625 classA.abstract = true; | |
626 String methodName = "m"; | |
627 MethodElementImpl inheritedMethod = | |
628 ElementFactory.methodElement(methodName, null); | |
629 inheritedMethod.abstract = true; | |
630 classA.methods = <MethodElement>[inheritedMethod]; | |
631 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
632 MethodElement method = ElementFactory.methodElement(methodName, null); | |
633 classB.methods = <MethodElement>[method]; | |
634 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
635 <ClassElement>[classA, classB]; | |
636 expect(classB.lookUpInheritedConcreteMethod(methodName, library), isNull); | |
637 } | |
638 | |
639 void | |
640 test_lookUpInheritedConcreteMethod_declaredAndInheritedWithAbstractBetween
() { | |
641 // class A { | |
642 // m() {} | |
643 // } | |
644 // class B extends A { | |
645 // m(); | |
646 // } | |
647 // class C extends B { | |
648 // m() {} | |
649 // } | |
650 LibraryElementImpl library = | |
651 ElementFactory.library(createAnalysisContext(), "lib"); | |
652 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
653 String methodName = "m"; | |
654 MethodElement inheritedMethod = | |
655 ElementFactory.methodElement(methodName, null); | |
656 classA.methods = <MethodElement>[inheritedMethod]; | |
657 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
658 MethodElementImpl abstractMethod = | |
659 ElementFactory.methodElement(methodName, null); | |
660 abstractMethod.abstract = true; | |
661 classB.methods = <MethodElement>[abstractMethod]; | |
662 ClassElementImpl classC = ElementFactory.classElement("C", classB.type); | |
663 MethodElementImpl method = ElementFactory.methodElement(methodName, null); | |
664 classC.methods = <MethodElement>[method]; | |
665 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
666 <ClassElement>[classA, classB, classC]; | |
667 expect(classC.lookUpInheritedConcreteMethod(methodName, library), | |
668 same(inheritedMethod)); | |
669 } | |
670 | |
671 void test_lookUpInheritedConcreteMethod_inherited() { | |
672 // class A { | |
673 // m() {} | |
674 // } | |
675 // class B extends A { | |
676 // } | |
677 LibraryElementImpl library = | |
678 ElementFactory.library(createAnalysisContext(), "lib"); | |
679 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
680 String methodName = "m"; | |
681 MethodElement inheritedMethod = | |
682 ElementFactory.methodElement(methodName, null); | |
683 classA.methods = <MethodElement>[inheritedMethod]; | |
684 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
685 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
686 <ClassElement>[classA, classB]; | |
687 expect(classB.lookUpInheritedConcreteMethod(methodName, library), | |
688 same(inheritedMethod)); | |
689 } | |
690 | |
691 void test_lookUpInheritedConcreteMethod_undeclared() { | |
692 // class A { | |
693 // } | |
694 LibraryElementImpl library = | |
695 ElementFactory.library(createAnalysisContext(), "lib"); | |
696 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
697 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
698 <ClassElement>[classA]; | |
699 expect(classA.lookUpInheritedConcreteMethod("m", library), isNull); | |
700 } | |
701 | |
702 void test_lookUpInheritedConcreteSetter_declared() { | |
703 // class A { | |
704 // set g(x) {} | |
705 // } | |
706 LibraryElementImpl library = | |
707 ElementFactory.library(createAnalysisContext(), "lib"); | |
708 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
709 String setterName = "s"; | |
710 PropertyAccessorElement setter = | |
711 ElementFactory.setterElement(setterName, false, null); | |
712 classA.accessors = <PropertyAccessorElement>[setter]; | |
713 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
714 <ClassElement>[classA]; | |
715 expect(classA.lookUpInheritedConcreteSetter(setterName, library), isNull); | |
716 } | |
717 | |
718 void test_lookUpInheritedConcreteSetter_inherited() { | |
719 // class A { | |
720 // set g(x) {} | |
721 // } | |
722 // class B extends A { | |
723 // } | |
724 LibraryElementImpl library = | |
725 ElementFactory.library(createAnalysisContext(), "lib"); | |
726 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
727 String setterName = "s"; | |
728 PropertyAccessorElement setter = | |
729 ElementFactory.setterElement(setterName, false, null); | |
730 classA.accessors = <PropertyAccessorElement>[setter]; | |
731 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
732 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
733 <ClassElement>[classA, classB]; | |
734 expect(classB.lookUpInheritedConcreteSetter(setterName, library), | |
735 same(setter)); | |
736 } | |
737 | |
738 void test_lookUpInheritedConcreteSetter_undeclared() { | |
739 // class A { | |
740 // } | |
741 LibraryElementImpl library = | |
742 ElementFactory.library(createAnalysisContext(), "lib"); | |
743 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
744 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
745 <ClassElement>[classA]; | |
746 expect(classA.lookUpInheritedConcreteSetter("s", library), isNull); | |
747 } | |
748 | |
749 void test_lookUpInheritedConcreteSetter_undeclared_recursive() { | |
750 // class A extends B { | |
751 // } | |
752 // class B extends A { | |
753 // } | |
754 LibraryElementImpl library = | |
755 ElementFactory.library(createAnalysisContext(), "lib"); | |
756 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
757 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
758 classA.supertype = classB.type; | |
759 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
760 <ClassElement>[classA, classB]; | |
761 expect(classA.lookUpInheritedConcreteSetter("s", library), isNull); | |
762 } | |
763 | |
764 void test_lookUpInheritedMethod_declared() { | |
765 // class A { | |
766 // m() {} | |
767 // } | |
768 LibraryElementImpl library = | |
769 ElementFactory.library(createAnalysisContext(), "lib"); | |
770 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
771 String methodName = "m"; | |
772 MethodElement method = ElementFactory.methodElement(methodName, null); | |
773 classA.methods = <MethodElement>[method]; | |
774 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
775 <ClassElement>[classA]; | |
776 expect(classA.lookUpInheritedMethod(methodName, library), isNull); | |
777 } | |
778 | |
779 void test_lookUpInheritedMethod_declaredAndInherited() { | |
780 // class A { | |
781 // m() {} | |
782 // } | |
783 // class B extends A { | |
784 // m() {} | |
785 // } | |
786 LibraryElementImpl library = | |
787 ElementFactory.library(createAnalysisContext(), "lib"); | |
788 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
789 String methodName = "m"; | |
790 MethodElement inheritedMethod = | |
791 ElementFactory.methodElement(methodName, null); | |
792 classA.methods = <MethodElement>[inheritedMethod]; | |
793 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
794 MethodElement method = ElementFactory.methodElement(methodName, null); | |
795 classB.methods = <MethodElement>[method]; | |
796 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
797 <ClassElement>[classA, classB]; | |
798 expect(classB.lookUpInheritedMethod(methodName, library), | |
799 same(inheritedMethod)); | |
800 } | |
801 | |
802 void test_lookUpInheritedMethod_inherited() { | |
803 // class A { | |
804 // m() {} | |
805 // } | |
806 // class B extends A { | |
807 // } | |
808 LibraryElementImpl library = | |
809 ElementFactory.library(createAnalysisContext(), "lib"); | |
810 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
811 String methodName = "m"; | |
812 MethodElement inheritedMethod = | |
813 ElementFactory.methodElement(methodName, null); | |
814 classA.methods = <MethodElement>[inheritedMethod]; | |
815 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
816 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
817 <ClassElement>[classA, classB]; | |
818 expect(classB.lookUpInheritedMethod(methodName, library), | |
819 same(inheritedMethod)); | |
820 } | |
821 | |
822 void test_lookUpInheritedMethod_undeclared() { | |
823 // class A { | |
824 // } | |
825 LibraryElementImpl library = | |
826 ElementFactory.library(createAnalysisContext(), "lib"); | |
827 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
828 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
829 <ClassElement>[classA]; | |
830 expect(classA.lookUpInheritedMethod("m", library), isNull); | |
831 } | |
832 | |
833 void test_lookUpMethod_declared() { | |
834 LibraryElementImpl library = | |
835 ElementFactory.library(createAnalysisContext(), "lib"); | |
836 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
837 String methodName = "m"; | |
838 MethodElement method = ElementFactory.methodElement(methodName, null); | |
839 classA.methods = <MethodElement>[method]; | |
840 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
841 <ClassElement>[classA]; | |
842 expect(classA.lookUpMethod(methodName, library), same(method)); | |
843 } | |
844 | |
845 void test_lookUpMethod_inherited() { | |
846 LibraryElementImpl library = | |
847 ElementFactory.library(createAnalysisContext(), "lib"); | |
848 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
849 String methodName = "m"; | |
850 MethodElement method = ElementFactory.methodElement(methodName, null); | |
851 classA.methods = <MethodElement>[method]; | |
852 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
853 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
854 <ClassElement>[classA, classB]; | |
855 expect(classB.lookUpMethod(methodName, library), same(method)); | |
856 } | |
857 | |
858 void test_lookUpMethod_undeclared() { | |
859 LibraryElementImpl library = | |
860 ElementFactory.library(createAnalysisContext(), "lib"); | |
861 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
862 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
863 <ClassElement>[classA]; | |
864 expect(classA.lookUpMethod("m", library), isNull); | |
865 } | |
866 | |
867 void test_lookUpMethod_undeclared_recursive() { | |
868 LibraryElementImpl library = | |
869 ElementFactory.library(createAnalysisContext(), "lib"); | |
870 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
871 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
872 classA.supertype = classB.type; | |
873 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
874 <ClassElement>[classA, classB]; | |
875 expect(classA.lookUpMethod("m", library), isNull); | |
876 } | |
877 | |
878 void test_lookUpSetter_declared() { | |
879 // class A { | |
880 // set g(x) {} | |
881 // } | |
882 LibraryElementImpl library = | |
883 ElementFactory.library(createAnalysisContext(), "lib"); | |
884 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
885 String setterName = "s"; | |
886 PropertyAccessorElement setter = | |
887 ElementFactory.setterElement(setterName, false, null); | |
888 classA.accessors = <PropertyAccessorElement>[setter]; | |
889 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
890 <ClassElement>[classA]; | |
891 expect(classA.lookUpSetter(setterName, library), same(setter)); | |
892 } | |
893 | |
894 void test_lookUpSetter_inherited() { | |
895 // class A { | |
896 // set g(x) {} | |
897 // } | |
898 // class B extends A { | |
899 // } | |
900 LibraryElementImpl library = | |
901 ElementFactory.library(createAnalysisContext(), "lib"); | |
902 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
903 String setterName = "s"; | |
904 PropertyAccessorElement setter = | |
905 ElementFactory.setterElement(setterName, false, null); | |
906 classA.accessors = <PropertyAccessorElement>[setter]; | |
907 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
908 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
909 <ClassElement>[classA, classB]; | |
910 expect(classB.lookUpSetter(setterName, library), same(setter)); | |
911 } | |
912 | |
913 void test_lookUpSetter_undeclared() { | |
914 // class A { | |
915 // } | |
916 LibraryElementImpl library = | |
917 ElementFactory.library(createAnalysisContext(), "lib"); | |
918 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
919 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
920 <ClassElement>[classA]; | |
921 expect(classA.lookUpSetter("s", library), isNull); | |
922 } | |
923 | |
924 void test_lookUpSetter_undeclared_recursive() { | |
925 // class A extends B { | |
926 // } | |
927 // class B extends A { | |
928 // } | |
929 LibraryElementImpl library = | |
930 ElementFactory.library(createAnalysisContext(), "lib"); | |
931 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
932 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
933 classA.supertype = classB.type; | |
934 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
935 <ClassElement>[classA, classB]; | |
936 expect(classA.lookUpSetter("s", library), isNull); | |
937 } | |
938 } | |
939 | |
940 @reflectiveTest | |
941 class CompilationUnitElementImplTest extends EngineTestCase { | |
942 void test_getElementAt() { | |
943 AnalysisContextHelper contextHelper = new AnalysisContextHelper(); | |
944 AnalysisContext context = contextHelper.context; | |
945 String code = r''' | |
946 class A { | |
947 int field; | |
948 } | |
949 main() { | |
950 int localVar = 42; | |
951 } | |
952 '''; | |
953 Source libSource = contextHelper.addSource("/my_lib.dart", code); | |
954 // prepare library/unit elements | |
955 LibraryElement libraryElement = context.computeLibraryElement(libSource); | |
956 CompilationUnitElement unitElement = libraryElement.definingCompilationUnit; | |
957 // A | |
958 ClassElement elementA; | |
959 { | |
960 int offset = code.indexOf('A {'); | |
961 elementA = unitElement.getElementAt(offset); | |
962 expect(elementA, isNotNull); | |
963 expect(elementA.enclosingElement, unitElement); | |
964 expect(elementA.name, 'A'); | |
965 } | |
966 // A.field | |
967 { | |
968 int offset = code.indexOf('field;'); | |
969 FieldElement element = unitElement.getElementAt(offset); | |
970 expect(element, isNotNull); | |
971 expect(element.enclosingElement, elementA); | |
972 expect(element.name, 'field'); | |
973 } | |
974 // main | |
975 FunctionElement mainElement; | |
976 { | |
977 int offset = code.indexOf('main() {'); | |
978 mainElement = unitElement.getElementAt(offset); | |
979 expect(mainElement, isNotNull); | |
980 expect(mainElement.enclosingElement, unitElement); | |
981 expect(mainElement.name, 'main'); | |
982 } | |
983 // main.localVar | |
984 { | |
985 int offset = code.indexOf('localVar'); | |
986 LocalVariableElement element = unitElement.getElementAt(offset); | |
987 expect(element, isNotNull); | |
988 expect(element.enclosingElement, mainElement); | |
989 expect(element.name, 'localVar'); | |
990 } | |
991 // null | |
992 expect(unitElement.getElementAt(1000), isNull); | |
993 } | |
994 | |
995 void test_getElementAt_multipleUnitsInLibrary() { | |
996 AnalysisContextHelper contextHelper = new AnalysisContextHelper(); | |
997 AnalysisContext context = contextHelper.context; | |
998 Source libSource = contextHelper.addSource( | |
999 "/my_lib.dart", | |
1000 r''' | |
1001 library my_lib; | |
1002 part 'unit_a.dart'; | |
1003 part 'unit_b.dart'; | |
1004 '''); | |
1005 Source unitSourceA = | |
1006 contextHelper.addSource("/unit_a.dart", 'part of my_lib;class A {}'); | |
1007 Source unitSourceB = | |
1008 contextHelper.addSource("/unit_b.dart", 'part of my_lib;class B {}'); | |
1009 int offset = 'part of my_lib;class A {}'.indexOf('A {}'); | |
1010 // prepare library/unit elements | |
1011 context.computeLibraryElement(libSource); | |
1012 CompilationUnitElement unitElementA = | |
1013 context.getCompilationUnitElement(unitSourceA, libSource); | |
1014 CompilationUnitElement unitElementB = | |
1015 context.getCompilationUnitElement(unitSourceB, libSource); | |
1016 // A | |
1017 { | |
1018 ClassElement element = unitElementA.getElementAt(offset); | |
1019 expect(element, isNotNull); | |
1020 expect(element.enclosingElement, unitElementA); | |
1021 expect(element.name, 'A'); | |
1022 } | |
1023 // B | |
1024 { | |
1025 ClassElement element = unitElementB.getElementAt(offset); | |
1026 expect(element, isNotNull); | |
1027 expect(element.enclosingElement, unitElementB); | |
1028 expect(element.name, 'B'); | |
1029 } | |
1030 } | |
1031 | |
1032 void test_getEnum_declared() { | |
1033 TestTypeProvider typeProvider = new TestTypeProvider(); | |
1034 CompilationUnitElementImpl unit = | |
1035 ElementFactory.compilationUnit("/lib.dart"); | |
1036 String enumName = "E"; | |
1037 ClassElement enumElement = | |
1038 ElementFactory.enumElement(typeProvider, enumName); | |
1039 unit.enums = <ClassElement>[enumElement]; | |
1040 expect(unit.getEnum(enumName), same(enumElement)); | |
1041 } | |
1042 | |
1043 void test_getEnum_undeclared() { | |
1044 TestTypeProvider typeProvider = new TestTypeProvider(); | |
1045 CompilationUnitElementImpl unit = | |
1046 ElementFactory.compilationUnit("/lib.dart"); | |
1047 String enumName = "E"; | |
1048 ClassElement enumElement = | |
1049 ElementFactory.enumElement(typeProvider, enumName); | |
1050 unit.enums = <ClassElement>[enumElement]; | |
1051 expect(unit.getEnum("${enumName}x"), isNull); | |
1052 } | |
1053 | |
1054 void test_getType_declared() { | |
1055 CompilationUnitElementImpl unit = | |
1056 ElementFactory.compilationUnit("/lib.dart"); | |
1057 String className = "C"; | |
1058 ClassElement classElement = ElementFactory.classElement2(className); | |
1059 unit.types = <ClassElement>[classElement]; | |
1060 expect(unit.getType(className), same(classElement)); | |
1061 } | |
1062 | |
1063 void test_getType_undeclared() { | |
1064 CompilationUnitElementImpl unit = | |
1065 ElementFactory.compilationUnit("/lib.dart"); | |
1066 String className = "C"; | |
1067 ClassElement classElement = ElementFactory.classElement2(className); | |
1068 unit.types = <ClassElement>[classElement]; | |
1069 expect(unit.getType("${className}x"), isNull); | |
1070 } | |
1071 } | |
1072 | |
1073 @reflectiveTest | |
1074 class ElementImplTest extends EngineTestCase { | |
1075 void test_equals() { | |
1076 LibraryElementImpl library = | |
1077 ElementFactory.library(createAnalysisContext(), "lib"); | |
1078 ClassElementImpl classElement = ElementFactory.classElement2("C"); | |
1079 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
1080 <ClassElement>[classElement]; | |
1081 FieldElement field = ElementFactory.fieldElement( | |
1082 "next", false, false, false, classElement.type); | |
1083 classElement.fields = <FieldElement>[field]; | |
1084 expect(field == field, isTrue); | |
1085 expect(field == field.getter, isFalse); | |
1086 expect(field == field.setter, isFalse); | |
1087 expect(field.getter == field.setter, isFalse); | |
1088 } | |
1089 | |
1090 void test_isAccessibleIn_private_differentLibrary() { | |
1091 AnalysisContext context = createAnalysisContext(); | |
1092 LibraryElementImpl library1 = ElementFactory.library(context, "lib1"); | |
1093 ClassElement classElement = ElementFactory.classElement2("_C"); | |
1094 (library1.definingCompilationUnit as CompilationUnitElementImpl).types = | |
1095 <ClassElement>[classElement]; | |
1096 LibraryElementImpl library2 = ElementFactory.library(context, "lib2"); | |
1097 expect(classElement.isAccessibleIn(library2), isFalse); | |
1098 } | |
1099 | |
1100 void test_isAccessibleIn_private_sameLibrary() { | |
1101 LibraryElementImpl library = | |
1102 ElementFactory.library(createAnalysisContext(), "lib"); | |
1103 ClassElement classElement = ElementFactory.classElement2("_C"); | |
1104 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
1105 <ClassElement>[classElement]; | |
1106 expect(classElement.isAccessibleIn(library), isTrue); | |
1107 } | |
1108 | |
1109 void test_isAccessibleIn_public_differentLibrary() { | |
1110 AnalysisContext context = createAnalysisContext(); | |
1111 LibraryElementImpl library1 = ElementFactory.library(context, "lib1"); | |
1112 ClassElement classElement = ElementFactory.classElement2("C"); | |
1113 (library1.definingCompilationUnit as CompilationUnitElementImpl).types = | |
1114 <ClassElement>[classElement]; | |
1115 LibraryElementImpl library2 = ElementFactory.library(context, "lib2"); | |
1116 expect(classElement.isAccessibleIn(library2), isTrue); | |
1117 } | |
1118 | |
1119 void test_isAccessibleIn_public_sameLibrary() { | |
1120 LibraryElementImpl library = | |
1121 ElementFactory.library(createAnalysisContext(), "lib"); | |
1122 ClassElement classElement = ElementFactory.classElement2("C"); | |
1123 (library.definingCompilationUnit as CompilationUnitElementImpl).types = | |
1124 <ClassElement>[classElement]; | |
1125 expect(classElement.isAccessibleIn(library), isTrue); | |
1126 } | |
1127 | |
1128 void test_isPrivate_false() { | |
1129 Element element = ElementFactory.classElement2("C"); | |
1130 expect(element.isPrivate, isFalse); | |
1131 } | |
1132 | |
1133 void test_isPrivate_null() { | |
1134 Element element = ElementFactory.classElement2(null); | |
1135 expect(element.isPrivate, isTrue); | |
1136 } | |
1137 | |
1138 void test_isPrivate_true() { | |
1139 Element element = ElementFactory.classElement2("_C"); | |
1140 expect(element.isPrivate, isTrue); | |
1141 } | |
1142 | |
1143 void test_isPublic_false() { | |
1144 Element element = ElementFactory.classElement2("_C"); | |
1145 expect(element.isPublic, isFalse); | |
1146 } | |
1147 | |
1148 void test_isPublic_null() { | |
1149 Element element = ElementFactory.classElement2(null); | |
1150 expect(element.isPublic, isFalse); | |
1151 } | |
1152 | |
1153 void test_isPublic_true() { | |
1154 Element element = ElementFactory.classElement2("C"); | |
1155 expect(element.isPublic, isTrue); | |
1156 } | |
1157 | |
1158 void test_SORT_BY_OFFSET() { | |
1159 ClassElementImpl classElementA = ElementFactory.classElement2("A"); | |
1160 classElementA.nameOffset = 1; | |
1161 ClassElementImpl classElementB = ElementFactory.classElement2("B"); | |
1162 classElementB.nameOffset = 2; | |
1163 expect(Element.SORT_BY_OFFSET(classElementA, classElementA), 0); | |
1164 expect(Element.SORT_BY_OFFSET(classElementA, classElementB) < 0, isTrue); | |
1165 expect(Element.SORT_BY_OFFSET(classElementB, classElementA) > 0, isTrue); | |
1166 } | |
1167 } | |
1168 | |
1169 @reflectiveTest | |
1170 class ElementKindTest extends EngineTestCase { | |
1171 void test_of_nonNull() { | |
1172 expect(ElementKind.of(ElementFactory.classElement2("A")), | |
1173 same(ElementKind.CLASS)); | |
1174 } | |
1175 | |
1176 void test_of_null() { | |
1177 expect(ElementKind.of(null), same(ElementKind.ERROR)); | |
1178 } | |
1179 } | |
1180 | |
1181 @reflectiveTest | |
1182 class ElementLocationImplTest extends EngineTestCase { | |
1183 void test_create_encoding() { | |
1184 String encoding = "a;b;c"; | |
1185 ElementLocationImpl location = new ElementLocationImpl.con2(encoding); | |
1186 expect(location.encoding, encoding); | |
1187 } | |
1188 | |
1189 /** | |
1190 * For example unnamed constructor. | |
1191 */ | |
1192 void test_create_encoding_emptyLast() { | |
1193 String encoding = "a;b;c;"; | |
1194 ElementLocationImpl location = new ElementLocationImpl.con2(encoding); | |
1195 expect(location.encoding, encoding); | |
1196 } | |
1197 | |
1198 void test_equals_equal() { | |
1199 String encoding = "a;b;c"; | |
1200 ElementLocationImpl first = new ElementLocationImpl.con2(encoding); | |
1201 ElementLocationImpl second = new ElementLocationImpl.con2(encoding); | |
1202 expect(first == second, isTrue); | |
1203 } | |
1204 | |
1205 void test_equals_notEqual_differentLengths() { | |
1206 ElementLocationImpl first = new ElementLocationImpl.con2("a;b;c"); | |
1207 ElementLocationImpl second = new ElementLocationImpl.con2("a;b;c;d"); | |
1208 expect(first == second, isFalse); | |
1209 } | |
1210 | |
1211 void test_equals_notEqual_notLocation() { | |
1212 ElementLocationImpl first = new ElementLocationImpl.con2("a;b;c"); | |
1213 expect(first == "a;b;d", isFalse); | |
1214 } | |
1215 | |
1216 void test_equals_notEqual_sameLengths() { | |
1217 ElementLocationImpl first = new ElementLocationImpl.con2("a;b;c"); | |
1218 ElementLocationImpl second = new ElementLocationImpl.con2("a;b;d"); | |
1219 expect(first == second, isFalse); | |
1220 } | |
1221 | |
1222 void test_getComponents() { | |
1223 String encoding = "a;b;c"; | |
1224 ElementLocationImpl location = new ElementLocationImpl.con2(encoding); | |
1225 List<String> components = location.components; | |
1226 expect(components, hasLength(3)); | |
1227 expect(components[0], "a"); | |
1228 expect(components[1], "b"); | |
1229 expect(components[2], "c"); | |
1230 } | |
1231 | |
1232 void test_getEncoding() { | |
1233 String encoding = "a;b;c;;d"; | |
1234 ElementLocationImpl location = new ElementLocationImpl.con2(encoding); | |
1235 expect(location.encoding, encoding); | |
1236 } | |
1237 | |
1238 void test_hashCode_equal() { | |
1239 String encoding = "a;b;c"; | |
1240 ElementLocationImpl first = new ElementLocationImpl.con2(encoding); | |
1241 ElementLocationImpl second = new ElementLocationImpl.con2(encoding); | |
1242 expect(first.hashCode == second.hashCode, isTrue); | |
1243 } | |
1244 } | |
1245 | |
1246 @reflectiveTest | |
1247 class FieldElementImplTest extends EngineTestCase { | |
1248 void test_computeNode() { | |
1249 AnalysisContextHelper contextHelper = new AnalysisContextHelper(); | |
1250 AnalysisContext context = contextHelper.context; | |
1251 Source source = contextHelper.addSource( | |
1252 "/test.dart", | |
1253 r''' | |
1254 class A { | |
1255 int a; | |
1256 } | |
1257 enum B {B1, B2, B3}'''); | |
1258 // prepare CompilationUnitElement | |
1259 LibraryElement libraryElement = context.computeLibraryElement(source); | |
1260 CompilationUnitElement unitElement = libraryElement.definingCompilationUnit; | |
1261 // A | |
1262 { | |
1263 FieldElement elementA = unitElement.getType("A").getField('a'); | |
1264 VariableDeclaration nodeA = elementA.computeNode(); | |
1265 expect(nodeA, isNotNull); | |
1266 expect(nodeA.name.name, "a"); | |
1267 expect(nodeA.element, same(elementA)); | |
1268 } | |
1269 // B | |
1270 { | |
1271 FieldElement elementB = unitElement.getEnum("B").getField('B2'); | |
1272 EnumConstantDeclaration nodeB = elementB.computeNode(); | |
1273 expect(nodeB, isNotNull); | |
1274 expect(nodeB.name.name, "B2"); | |
1275 expect(nodeB.element, same(elementB)); | |
1276 } | |
1277 } | |
1278 } | |
1279 | |
1280 @reflectiveTest | |
1281 class FunctionTypeImplTest extends EngineTestCase { | |
1282 void test_creation() { | |
1283 expect( | |
1284 new FunctionTypeImpl( | |
1285 new FunctionElementImpl.forNode(AstFactory.identifier3("f"))), | |
1286 isNotNull); | |
1287 } | |
1288 | |
1289 void test_equality_recursive() { | |
1290 FunctionTypeAliasElementImpl s = | |
1291 ElementFactory.functionTypeAliasElement('s'); | |
1292 FunctionTypeAliasElementImpl t = | |
1293 ElementFactory.functionTypeAliasElement('t'); | |
1294 FunctionTypeAliasElementImpl u = | |
1295 ElementFactory.functionTypeAliasElement('u'); | |
1296 FunctionTypeAliasElementImpl v = | |
1297 ElementFactory.functionTypeAliasElement('v'); | |
1298 s.returnType = t.type; | |
1299 t.returnType = s.type; | |
1300 u.returnType = v.type; | |
1301 v.returnType = u.type; | |
1302 // We don't care whether the types compare equal or not. We just need the | |
1303 // computation to terminate. | |
1304 expect(s.type == u.type, new isInstanceOf<bool>()); | |
1305 } | |
1306 | |
1307 void test_getElement() { | |
1308 FunctionElementImpl typeElement = | |
1309 new FunctionElementImpl.forNode(AstFactory.identifier3("f")); | |
1310 FunctionTypeImpl type = new FunctionTypeImpl(typeElement); | |
1311 expect(type.element, typeElement); | |
1312 } | |
1313 | |
1314 void test_getNamedParameterTypes() { | |
1315 FunctionTypeImpl type = new FunctionTypeImpl( | |
1316 new FunctionElementImpl.forNode(AstFactory.identifier3("f"))); | |
1317 Map<String, DartType> types = type.namedParameterTypes; | |
1318 expect(types, hasLength(0)); | |
1319 } | |
1320 | |
1321 void test_getNormalParameterTypes() { | |
1322 FunctionTypeImpl type = new FunctionTypeImpl( | |
1323 new FunctionElementImpl.forNode(AstFactory.identifier3("f"))); | |
1324 List<DartType> types = type.normalParameterTypes; | |
1325 expect(types, hasLength(0)); | |
1326 } | |
1327 | |
1328 void test_getReturnType() { | |
1329 DartType expectedReturnType = VoidTypeImpl.instance; | |
1330 FunctionElementImpl functionElement = | |
1331 new FunctionElementImpl.forNode(AstFactory.identifier3("f")); | |
1332 functionElement.returnType = expectedReturnType; | |
1333 FunctionTypeImpl type = new FunctionTypeImpl(functionElement); | |
1334 DartType returnType = type.returnType; | |
1335 expect(returnType, expectedReturnType); | |
1336 } | |
1337 | |
1338 void test_getTypeArguments() { | |
1339 FunctionTypeImpl type = new FunctionTypeImpl( | |
1340 new FunctionElementImpl.forNode(AstFactory.identifier3("f"))); | |
1341 List<DartType> types = type.typeArguments; | |
1342 expect(types, hasLength(0)); | |
1343 } | |
1344 | |
1345 void test_hashCode_element() { | |
1346 FunctionTypeImpl type = new FunctionTypeImpl( | |
1347 new FunctionElementImpl.forNode(AstFactory.identifier3("f"))); | |
1348 type.hashCode; | |
1349 } | |
1350 | |
1351 void test_hashCode_noElement() { | |
1352 FunctionTypeImpl type = new FunctionTypeImpl(null); | |
1353 type.hashCode; | |
1354 } | |
1355 | |
1356 void test_hashCode_recursive() { | |
1357 FunctionTypeAliasElementImpl s = | |
1358 ElementFactory.functionTypeAliasElement('s'); | |
1359 FunctionTypeAliasElementImpl t = | |
1360 ElementFactory.functionTypeAliasElement('t'); | |
1361 s.returnType = t.type; | |
1362 t.returnType = s.type; | |
1363 // We don't care what the hash code is. We just need its computation to | |
1364 // terminate. | |
1365 expect(t.type.hashCode, new isInstanceOf<int>()); | |
1366 } | |
1367 | |
1368 void test_isAssignableTo_normalAndPositionalArgs() { | |
1369 // ([a]) -> void <: (a) -> void | |
1370 ClassElement a = ElementFactory.classElement2("A"); | |
1371 FunctionType t = | |
1372 ElementFactory.functionElement6("t", null, <ClassElement>[a]).type; | |
1373 FunctionType s = | |
1374 ElementFactory.functionElement5("s", <ClassElement>[a]).type; | |
1375 expect(t.isSubtypeOf(s), isTrue); | |
1376 expect(s.isSubtypeOf(t), isFalse); | |
1377 // assignable iff subtype | |
1378 expect(t.isAssignableTo(s), isTrue); | |
1379 expect(s.isAssignableTo(t), isFalse); | |
1380 } | |
1381 | |
1382 void test_isSubtypeOf_baseCase_classFunction() { | |
1383 // () -> void <: Function | |
1384 ClassElementImpl functionElement = ElementFactory.classElement2("Function"); | |
1385 InterfaceTypeImpl functionType = | |
1386 new _FunctionTypeImplTest_isSubtypeOf_baseCase_classFunction( | |
1387 functionElement); | |
1388 FunctionType f = ElementFactory.functionElement("f").type; | |
1389 expect(f.isSubtypeOf(functionType), isTrue); | |
1390 } | |
1391 | |
1392 void test_isSubtypeOf_baseCase_notFunctionType() { | |
1393 // class C | |
1394 // ! () -> void <: C | |
1395 FunctionType f = ElementFactory.functionElement("f").type; | |
1396 InterfaceType t = ElementFactory.classElement2("C").type; | |
1397 expect(f.isSubtypeOf(t), isFalse); | |
1398 } | |
1399 | |
1400 void test_isSubtypeOf_baseCase_null() { | |
1401 // ! () -> void <: null | |
1402 FunctionType f = ElementFactory.functionElement("f").type; | |
1403 expect(f.isSubtypeOf(null), isFalse); | |
1404 } | |
1405 | |
1406 void test_isSubtypeOf_baseCase_self() { | |
1407 // () -> void <: () -> void | |
1408 FunctionType f = ElementFactory.functionElement("f").type; | |
1409 expect(f.isSubtypeOf(f), isTrue); | |
1410 } | |
1411 | |
1412 void test_isSubtypeOf_namedParameters_isAssignable() { | |
1413 // B extends A | |
1414 // ({name: A}) -> void <: ({name: B}) -> void | |
1415 // ({name: B}) -> void <: ({name: A}) -> void | |
1416 ClassElement a = ElementFactory.classElement2("A"); | |
1417 ClassElement b = ElementFactory.classElement("B", a.type); | |
1418 FunctionType t = ElementFactory.functionElement4( | |
1419 "t", null, null, <String>["name"], <ClassElement>[a]).type; | |
1420 FunctionType s = ElementFactory.functionElement4( | |
1421 "s", null, null, <String>["name"], <ClassElement>[b]).type; | |
1422 expect(t.isSubtypeOf(s), isTrue); | |
1423 expect(s.isSubtypeOf(t), isTrue); | |
1424 } | |
1425 | |
1426 void test_isSubtypeOf_namedParameters_isNotAssignable() { | |
1427 // ! ({name: A}) -> void <: ({name: B}) -> void | |
1428 FunctionType t = ElementFactory.functionElement4( | |
1429 "t", | |
1430 null, | |
1431 null, | |
1432 <String>["name"], | |
1433 <ClassElement>[ElementFactory.classElement2("A")]).type; | |
1434 FunctionType s = ElementFactory.functionElement4( | |
1435 "s", | |
1436 null, | |
1437 null, | |
1438 <String>["name"], | |
1439 <ClassElement>[ElementFactory.classElement2("B")]).type; | |
1440 expect(t.isSubtypeOf(s), isFalse); | |
1441 } | |
1442 | |
1443 void test_isSubtypeOf_namedParameters_namesDifferent() { | |
1444 // B extends A | |
1445 // void t({A name}) {} | |
1446 // void s({A diff}) {} | |
1447 // ! t <: s | |
1448 // ! s <: t | |
1449 ClassElement a = ElementFactory.classElement2("A"); | |
1450 ClassElement b = ElementFactory.classElement("B", a.type); | |
1451 FunctionType t = ElementFactory.functionElement4( | |
1452 "t", null, null, <String>["name"], <ClassElement>[a]).type; | |
1453 FunctionType s = ElementFactory.functionElement4( | |
1454 "s", null, null, <String>["diff"], <ClassElement>[b]).type; | |
1455 expect(t.isSubtypeOf(s), isFalse); | |
1456 expect(s.isSubtypeOf(t), isFalse); | |
1457 } | |
1458 | |
1459 void test_isSubtypeOf_namedParameters_orderOfParams() { | |
1460 // B extends A | |
1461 // ({A: A, B: B}) -> void <: ({B: B, A: A}) -> void | |
1462 ClassElement a = ElementFactory.classElement2("A"); | |
1463 ClassElement b = ElementFactory.classElement("B", a.type); | |
1464 FunctionType t = ElementFactory.functionElement4( | |
1465 "t", null, null, <String>["A", "B"], <ClassElement>[a, b]).type; | |
1466 FunctionType s = ElementFactory.functionElement4( | |
1467 "s", null, null, <String>["B", "A"], <ClassElement>[b, a]).type; | |
1468 expect(t.isSubtypeOf(s), isTrue); | |
1469 } | |
1470 | |
1471 void test_isSubtypeOf_namedParameters_orderOfParams2() { | |
1472 // B extends A | |
1473 // ! ({B: B}) -> void <: ({B: B, A: A}) -> void | |
1474 ClassElement a = ElementFactory.classElement2("A"); | |
1475 ClassElement b = ElementFactory.classElement("B", a.type); | |
1476 FunctionType t = ElementFactory.functionElement4( | |
1477 "t", null, null, <String>["B"], <ClassElement>[b]).type; | |
1478 FunctionType s = ElementFactory.functionElement4( | |
1479 "s", null, null, <String>["B", "A"], <ClassElement>[b, a]).type; | |
1480 expect(t.isSubtypeOf(s), isFalse); | |
1481 } | |
1482 | |
1483 void test_isSubtypeOf_namedParameters_orderOfParams3() { | |
1484 // B extends A | |
1485 // ({A: A, B: B}) -> void <: ({A: A}) -> void | |
1486 ClassElement a = ElementFactory.classElement2("A"); | |
1487 ClassElement b = ElementFactory.classElement("B", a.type); | |
1488 FunctionType t = ElementFactory.functionElement4( | |
1489 "t", null, null, <String>["A", "B"], <ClassElement>[a, b]).type; | |
1490 FunctionType s = ElementFactory.functionElement4( | |
1491 "s", null, null, <String>["B"], <ClassElement>[b]).type; | |
1492 expect(t.isSubtypeOf(s), isTrue); | |
1493 } | |
1494 | |
1495 void test_isSubtypeOf_namedParameters_sHasMoreParams() { | |
1496 // B extends A | |
1497 // ! ({name: A}) -> void <: ({name: B, name2: B}) -> void | |
1498 ClassElement a = ElementFactory.classElement2("A"); | |
1499 ClassElement b = ElementFactory.classElement("B", a.type); | |
1500 FunctionType t = ElementFactory.functionElement4( | |
1501 "t", null, null, <String>["name"], <ClassElement>[a]).type; | |
1502 FunctionType s = ElementFactory.functionElement4( | |
1503 "s", null, null, <String>["name", "name2"], <ClassElement>[b, b]).type; | |
1504 expect(t.isSubtypeOf(s), isFalse); | |
1505 } | |
1506 | |
1507 void test_isSubtypeOf_namedParameters_tHasMoreParams() { | |
1508 // B extends A | |
1509 // ({name: A, name2: A}) -> void <: ({name: B}) -> void | |
1510 ClassElement a = ElementFactory.classElement2("A"); | |
1511 ClassElement b = ElementFactory.classElement("B", a.type); | |
1512 FunctionType t = ElementFactory.functionElement4( | |
1513 "t", null, null, <String>["name", "name2"], <ClassElement>[a, a]).type; | |
1514 FunctionType s = ElementFactory.functionElement4( | |
1515 "s", null, null, <String>["name"], <ClassElement>[b]).type; | |
1516 expect(t.isSubtypeOf(s), isTrue); | |
1517 } | |
1518 | |
1519 void test_isSubtypeOf_normalAndPositionalArgs_1() { | |
1520 // ([a]) -> void <: (a) -> void | |
1521 ClassElement a = ElementFactory.classElement2("A"); | |
1522 FunctionType t = | |
1523 ElementFactory.functionElement6("t", null, <ClassElement>[a]).type; | |
1524 FunctionType s = | |
1525 ElementFactory.functionElement5("s", <ClassElement>[a]).type; | |
1526 expect(t.isSubtypeOf(s), isTrue); | |
1527 expect(s.isSubtypeOf(t), isFalse); | |
1528 } | |
1529 | |
1530 void test_isSubtypeOf_normalAndPositionalArgs_2() { | |
1531 // (a, [a]) -> void <: (a) -> void | |
1532 ClassElement a = ElementFactory.classElement2("A"); | |
1533 FunctionType t = ElementFactory | |
1534 .functionElement6("t", <ClassElement>[a], <ClassElement>[a]).type; | |
1535 FunctionType s = | |
1536 ElementFactory.functionElement5("s", <ClassElement>[a]).type; | |
1537 expect(t.isSubtypeOf(s), isTrue); | |
1538 expect(s.isSubtypeOf(t), isFalse); | |
1539 } | |
1540 | |
1541 void test_isSubtypeOf_normalAndPositionalArgs_3() { | |
1542 // ([a]) -> void <: () -> void | |
1543 ClassElement a = ElementFactory.classElement2("A"); | |
1544 FunctionType t = | |
1545 ElementFactory.functionElement6("t", null, <ClassElement>[a]).type; | |
1546 FunctionType s = ElementFactory.functionElement("s").type; | |
1547 expect(t.isSubtypeOf(s), isTrue); | |
1548 expect(s.isSubtypeOf(t), isFalse); | |
1549 } | |
1550 | |
1551 void test_isSubtypeOf_normalAndPositionalArgs_4() { | |
1552 // (a, b, [c, d, e]) -> void <: (a, b, c, [d]) -> void | |
1553 ClassElement a = ElementFactory.classElement2("A"); | |
1554 ClassElement b = ElementFactory.classElement2("B"); | |
1555 ClassElement c = ElementFactory.classElement2("C"); | |
1556 ClassElement d = ElementFactory.classElement2("D"); | |
1557 ClassElement e = ElementFactory.classElement2("E"); | |
1558 FunctionType t = ElementFactory.functionElement6( | |
1559 "t", <ClassElement>[a, b], <ClassElement>[c, d, e]).type; | |
1560 FunctionType s = ElementFactory | |
1561 .functionElement6("s", <ClassElement>[a, b, c], <ClassElement>[d]).type; | |
1562 expect(t.isSubtypeOf(s), isTrue); | |
1563 expect(s.isSubtypeOf(t), isFalse); | |
1564 } | |
1565 | |
1566 void test_isSubtypeOf_normalParameters_isAssignable() { | |
1567 // B extends A | |
1568 // (a) -> void <: (b) -> void | |
1569 // (b) -> void <: (a) -> void | |
1570 ClassElement a = ElementFactory.classElement2("A"); | |
1571 ClassElement b = ElementFactory.classElement("B", a.type); | |
1572 FunctionType t = | |
1573 ElementFactory.functionElement5("t", <ClassElement>[a]).type; | |
1574 FunctionType s = | |
1575 ElementFactory.functionElement5("s", <ClassElement>[b]).type; | |
1576 expect(t.isSubtypeOf(s), isTrue); | |
1577 expect(s.isSubtypeOf(t), isTrue); | |
1578 } | |
1579 | |
1580 void test_isSubtypeOf_normalParameters_isNotAssignable() { | |
1581 // ! (a) -> void <: (b) -> void | |
1582 FunctionType t = ElementFactory.functionElement5( | |
1583 "t", <ClassElement>[ElementFactory.classElement2("A")]).type; | |
1584 FunctionType s = ElementFactory.functionElement5( | |
1585 "s", <ClassElement>[ElementFactory.classElement2("B")]).type; | |
1586 expect(t.isSubtypeOf(s), isFalse); | |
1587 } | |
1588 | |
1589 void test_isSubtypeOf_normalParameters_sHasMoreParams() { | |
1590 // B extends A | |
1591 // ! (a) -> void <: (b, b) -> void | |
1592 ClassElement a = ElementFactory.classElement2("A"); | |
1593 ClassElement b = ElementFactory.classElement("B", a.type); | |
1594 FunctionType t = | |
1595 ElementFactory.functionElement5("t", <ClassElement>[a]).type; | |
1596 FunctionType s = | |
1597 ElementFactory.functionElement5("s", <ClassElement>[b, b]).type; | |
1598 expect(t.isSubtypeOf(s), isFalse); | |
1599 } | |
1600 | |
1601 void test_isSubtypeOf_normalParameters_tHasMoreParams() { | |
1602 // B extends A | |
1603 // ! (a, a) -> void <: (a) -> void | |
1604 ClassElement a = ElementFactory.classElement2("A"); | |
1605 ClassElement b = ElementFactory.classElement("B", a.type); | |
1606 FunctionType t = | |
1607 ElementFactory.functionElement5("t", <ClassElement>[a, a]).type; | |
1608 FunctionType s = | |
1609 ElementFactory.functionElement5("s", <ClassElement>[b]).type; | |
1610 // note, this is a different assertion from the other "tHasMoreParams" | |
1611 // tests, this is intentional as it is a difference of the "normal | |
1612 // parameters" | |
1613 expect(t.isSubtypeOf(s), isFalse); | |
1614 } | |
1615 | |
1616 void test_isSubtypeOf_Object() { | |
1617 // () -> void <: Object | |
1618 FunctionType f = ElementFactory.functionElement("f").type; | |
1619 InterfaceType t = ElementFactory.object.type; | |
1620 expect(f.isSubtypeOf(t), isTrue); | |
1621 } | |
1622 | |
1623 void test_isSubtypeOf_positionalParameters_isAssignable() { | |
1624 // B extends A | |
1625 // ([a]) -> void <: ([b]) -> void | |
1626 // ([b]) -> void <: ([a]) -> void | |
1627 ClassElement a = ElementFactory.classElement2("A"); | |
1628 ClassElement b = ElementFactory.classElement("B", a.type); | |
1629 FunctionType t = | |
1630 ElementFactory.functionElement6("t", null, <ClassElement>[a]).type; | |
1631 FunctionType s = | |
1632 ElementFactory.functionElement6("s", null, <ClassElement>[b]).type; | |
1633 expect(t.isSubtypeOf(s), isTrue); | |
1634 expect(s.isSubtypeOf(t), isTrue); | |
1635 } | |
1636 | |
1637 void test_isSubtypeOf_positionalParameters_isNotAssignable() { | |
1638 // ! ([a]) -> void <: ([b]) -> void | |
1639 FunctionType t = ElementFactory.functionElement6( | |
1640 "t", null, <ClassElement>[ElementFactory.classElement2("A")]).type; | |
1641 FunctionType s = ElementFactory.functionElement6( | |
1642 "s", null, <ClassElement>[ElementFactory.classElement2("B")]).type; | |
1643 expect(t.isSubtypeOf(s), isFalse); | |
1644 } | |
1645 | |
1646 void test_isSubtypeOf_positionalParameters_sHasMoreParams() { | |
1647 // B extends A | |
1648 // ! ([a]) -> void <: ([b, b]) -> void | |
1649 ClassElement a = ElementFactory.classElement2("A"); | |
1650 ClassElement b = ElementFactory.classElement("B", a.type); | |
1651 FunctionType t = | |
1652 ElementFactory.functionElement6("t", null, <ClassElement>[a]).type; | |
1653 FunctionType s = | |
1654 ElementFactory.functionElement6("s", null, <ClassElement>[b, b]).type; | |
1655 expect(t.isSubtypeOf(s), isFalse); | |
1656 } | |
1657 | |
1658 void test_isSubtypeOf_positionalParameters_tHasMoreParams() { | |
1659 // B extends A | |
1660 // ([a, a]) -> void <: ([b]) -> void | |
1661 ClassElement a = ElementFactory.classElement2("A"); | |
1662 ClassElement b = ElementFactory.classElement("B", a.type); | |
1663 FunctionType t = | |
1664 ElementFactory.functionElement6("t", null, <ClassElement>[a, a]).type; | |
1665 FunctionType s = | |
1666 ElementFactory.functionElement6("s", null, <ClassElement>[b]).type; | |
1667 expect(t.isSubtypeOf(s), isTrue); | |
1668 } | |
1669 | |
1670 void test_isSubtypeOf_returnType_sIsVoid() { | |
1671 // () -> void <: void | |
1672 FunctionType t = ElementFactory.functionElement("t").type; | |
1673 FunctionType s = ElementFactory.functionElement("s").type; | |
1674 // function s has the implicit return type of void, we assert it here | |
1675 expect(VoidTypeImpl.instance == s.returnType, isTrue); | |
1676 expect(t.isSubtypeOf(s), isTrue); | |
1677 } | |
1678 | |
1679 void test_isSubtypeOf_returnType_tAssignableToS() { | |
1680 // B extends A | |
1681 // () -> A <: () -> B | |
1682 // () -> B <: () -> A | |
1683 ClassElement a = ElementFactory.classElement2("A"); | |
1684 ClassElement b = ElementFactory.classElement("B", a.type); | |
1685 FunctionType t = ElementFactory.functionElement2("t", a).type; | |
1686 FunctionType s = ElementFactory.functionElement2("s", b).type; | |
1687 expect(t.isSubtypeOf(s), isTrue); | |
1688 expect(s.isSubtypeOf(t), isTrue); | |
1689 } | |
1690 | |
1691 void test_isSubtypeOf_returnType_tNotAssignableToS() { | |
1692 // ! () -> A <: () -> B | |
1693 FunctionType t = ElementFactory | |
1694 .functionElement2("t", ElementFactory.classElement2("A")) | |
1695 .type; | |
1696 FunctionType s = ElementFactory | |
1697 .functionElement2("s", ElementFactory.classElement2("B")) | |
1698 .type; | |
1699 expect(t.isSubtypeOf(s), isFalse); | |
1700 } | |
1701 | |
1702 void test_isSubtypeOf_typeParameters_matchesBounds() { | |
1703 TestTypeProvider provider = new TestTypeProvider(); | |
1704 InterfaceType boolType = provider.boolType; | |
1705 InterfaceType stringType = provider.stringType; | |
1706 TypeParameterElementImpl parameterB = | |
1707 new TypeParameterElementImpl.forNode(AstFactory.identifier3("B")); | |
1708 parameterB.bound = boolType; | |
1709 TypeParameterTypeImpl typeB = new TypeParameterTypeImpl(parameterB); | |
1710 TypeParameterElementImpl parameterS = | |
1711 new TypeParameterElementImpl.forNode(AstFactory.identifier3("S")); | |
1712 parameterS.bound = stringType; | |
1713 TypeParameterTypeImpl typeS = new TypeParameterTypeImpl(parameterS); | |
1714 FunctionElementImpl functionAliasElement = | |
1715 new FunctionElementImpl.forNode(AstFactory.identifier3("func")); | |
1716 functionAliasElement.parameters = <ParameterElement>[ | |
1717 ElementFactory.requiredParameter2("a", typeB), | |
1718 ElementFactory.positionalParameter2("b", typeS) | |
1719 ]; | |
1720 functionAliasElement.returnType = stringType; | |
1721 FunctionTypeImpl functionAliasType = | |
1722 new FunctionTypeImpl(functionAliasElement); | |
1723 functionAliasElement.type = functionAliasType; | |
1724 FunctionElementImpl functionElement = | |
1725 new FunctionElementImpl.forNode(AstFactory.identifier3("f")); | |
1726 functionElement.parameters = <ParameterElement>[ | |
1727 ElementFactory.requiredParameter2("c", boolType), | |
1728 ElementFactory.positionalParameter2("d", stringType) | |
1729 ]; | |
1730 functionElement.returnType = provider.dynamicType; | |
1731 FunctionTypeImpl functionType = new FunctionTypeImpl(functionElement); | |
1732 functionElement.type = functionType; | |
1733 expect(functionType.isAssignableTo(functionAliasType), isTrue); | |
1734 } | |
1735 | |
1736 void test_isSubtypeOf_wrongFunctionType_normal_named() { | |
1737 // ! (a) -> void <: ({name: A}) -> void | |
1738 // ! ({name: A}) -> void <: (a) -> void | |
1739 ClassElement a = ElementFactory.classElement2("A"); | |
1740 FunctionType t = | |
1741 ElementFactory.functionElement5("t", <ClassElement>[a]).type; | |
1742 FunctionType s = ElementFactory | |
1743 .functionElement7("s", null, <String>["name"], <ClassElement>[a]).type; | |
1744 expect(t.isSubtypeOf(s), isFalse); | |
1745 expect(s.isSubtypeOf(t), isFalse); | |
1746 } | |
1747 | |
1748 void test_isSubtypeOf_wrongFunctionType_optional_named() { | |
1749 // ! ([a]) -> void <: ({name: A}) -> void | |
1750 // ! ({name: A}) -> void <: ([a]) -> void | |
1751 ClassElement a = ElementFactory.classElement2("A"); | |
1752 FunctionType t = | |
1753 ElementFactory.functionElement6("t", null, <ClassElement>[a]).type; | |
1754 FunctionType s = ElementFactory | |
1755 .functionElement7("s", null, <String>["name"], <ClassElement>[a]).type; | |
1756 expect(t.isSubtypeOf(s), isFalse); | |
1757 expect(s.isSubtypeOf(t), isFalse); | |
1758 } | |
1759 | |
1760 void test_namedParameterTypes_pruned_no_type_arguments() { | |
1761 FunctionTypeAliasElementImpl f = | |
1762 ElementFactory.functionTypeAliasElement('f'); | |
1763 FunctionTypeAliasElementImpl g = | |
1764 ElementFactory.functionTypeAliasElement('g'); | |
1765 f.parameters = [ElementFactory.namedParameter2('x', g.type)]; | |
1766 FunctionTypeImpl paramType = f.type.namedParameterTypes['x']; | |
1767 expect(paramType.prunedTypedefs, hasLength(1)); | |
1768 expect(paramType.prunedTypedefs[0], same(f)); | |
1769 } | |
1770 | |
1771 void test_namedParameterTypes_pruned_with_type_arguments() { | |
1772 FunctionTypeAliasElementImpl f = | |
1773 ElementFactory.functionTypeAliasElement('f'); | |
1774 FunctionTypeAliasElementImpl g = | |
1775 ElementFactory.functionTypeAliasElement('g'); | |
1776 f.typeParameters = [ElementFactory.typeParameterElement('T')]; | |
1777 f.parameters = [ElementFactory.namedParameter2('x', g.type)]; | |
1778 FunctionTypeImpl paramType = f.type.namedParameterTypes['x']; | |
1779 expect(paramType.prunedTypedefs, hasLength(1)); | |
1780 expect(paramType.prunedTypedefs[0], same(f)); | |
1781 } | |
1782 | |
1783 void test_newPrune_no_previous_prune() { | |
1784 FunctionTypeAliasElementImpl f = | |
1785 ElementFactory.functionTypeAliasElement('f'); | |
1786 FunctionTypeImpl type = f.type; | |
1787 List<FunctionTypeAliasElement> pruneList = type.newPrune; | |
1788 expect(pruneList, hasLength(1)); | |
1789 expect(pruneList[0], same(f)); | |
1790 } | |
1791 | |
1792 void test_newPrune_non_typedef() { | |
1793 // No pruning needs to be done for function types that aren't associated | |
1794 // with typedefs because those types can't be directly referred to by the | |
1795 // user (and hence can't participate in circularities). | |
1796 FunctionElementImpl f = ElementFactory.functionElement('f'); | |
1797 FunctionTypeImpl type = f.type; | |
1798 expect(type.newPrune, isNull); | |
1799 } | |
1800 | |
1801 void test_newPrune_synthetic_typedef() { | |
1802 // No pruning needs to be done for function types that are associated with | |
1803 // synthetic typedefs because those types are only created for | |
1804 // function-typed formal parameters, which can't be directly referred to by | |
1805 // the user (and hence can't participate in circularities). | |
1806 FunctionTypeAliasElementImpl f = | |
1807 ElementFactory.functionTypeAliasElement('f'); | |
1808 f.synthetic = true; | |
1809 FunctionTypeImpl type = f.type; | |
1810 expect(type.newPrune, isNull); | |
1811 } | |
1812 | |
1813 void test_newPrune_with_previous_prune() { | |
1814 FunctionTypeAliasElementImpl f = | |
1815 ElementFactory.functionTypeAliasElement('f'); | |
1816 FunctionTypeAliasElementImpl g = | |
1817 ElementFactory.functionTypeAliasElement('g'); | |
1818 FunctionTypeImpl type = f.type; | |
1819 FunctionTypeImpl prunedType = type.pruned([g]); | |
1820 List<FunctionTypeAliasElement> pruneList = prunedType.newPrune; | |
1821 expect(pruneList, hasLength(2)); | |
1822 expect(pruneList, contains(f)); | |
1823 expect(pruneList, contains(g)); | |
1824 } | |
1825 | |
1826 void test_normalParameterTypes_pruned_no_type_arguments() { | |
1827 FunctionTypeAliasElementImpl f = | |
1828 ElementFactory.functionTypeAliasElement('f'); | |
1829 FunctionTypeAliasElementImpl g = | |
1830 ElementFactory.functionTypeAliasElement('g'); | |
1831 f.parameters = [ElementFactory.requiredParameter2('x', g.type)]; | |
1832 FunctionTypeImpl paramType = f.type.normalParameterTypes[0]; | |
1833 expect(paramType.prunedTypedefs, hasLength(1)); | |
1834 expect(paramType.prunedTypedefs[0], same(f)); | |
1835 } | |
1836 | |
1837 void test_normalParameterTypes_pruned_with_type_arguments() { | |
1838 FunctionTypeAliasElementImpl f = | |
1839 ElementFactory.functionTypeAliasElement('f'); | |
1840 FunctionTypeAliasElementImpl g = | |
1841 ElementFactory.functionTypeAliasElement('g'); | |
1842 f.typeParameters = [ElementFactory.typeParameterElement('T')]; | |
1843 f.parameters = [ElementFactory.requiredParameter2('x', g.type)]; | |
1844 FunctionTypeImpl paramType = f.type.normalParameterTypes[0]; | |
1845 expect(paramType.prunedTypedefs, hasLength(1)); | |
1846 expect(paramType.prunedTypedefs[0], same(f)); | |
1847 } | |
1848 | |
1849 void test_optionalParameterTypes_pruned_no_type_arguments() { | |
1850 FunctionTypeAliasElementImpl f = | |
1851 ElementFactory.functionTypeAliasElement('f'); | |
1852 FunctionTypeAliasElementImpl g = | |
1853 ElementFactory.functionTypeAliasElement('g'); | |
1854 f.parameters = [ElementFactory.positionalParameter2('x', g.type)]; | |
1855 FunctionTypeImpl paramType = f.type.optionalParameterTypes[0]; | |
1856 expect(paramType.prunedTypedefs, hasLength(1)); | |
1857 expect(paramType.prunedTypedefs[0], same(f)); | |
1858 } | |
1859 | |
1860 void test_optionalParameterTypes_pruned_with_type_arguments() { | |
1861 FunctionTypeAliasElementImpl f = | |
1862 ElementFactory.functionTypeAliasElement('f'); | |
1863 FunctionTypeAliasElementImpl g = | |
1864 ElementFactory.functionTypeAliasElement('g'); | |
1865 f.typeParameters = [ElementFactory.typeParameterElement('T')]; | |
1866 f.parameters = [ElementFactory.positionalParameter2('x', g.type)]; | |
1867 FunctionTypeImpl paramType = f.type.optionalParameterTypes[0]; | |
1868 expect(paramType.prunedTypedefs, hasLength(1)); | |
1869 expect(paramType.prunedTypedefs[0], same(f)); | |
1870 } | |
1871 | |
1872 void test_returnType_pruned_no_type_arguments() { | |
1873 FunctionTypeAliasElementImpl f = | |
1874 ElementFactory.functionTypeAliasElement('f'); | |
1875 FunctionTypeAliasElementImpl g = | |
1876 ElementFactory.functionTypeAliasElement('g'); | |
1877 f.returnType = g.type; | |
1878 FunctionTypeImpl paramType = f.type.returnType; | |
1879 expect(paramType.prunedTypedefs, hasLength(1)); | |
1880 expect(paramType.prunedTypedefs[0], same(f)); | |
1881 } | |
1882 | |
1883 void test_returnType_pruned_with_type_arguments() { | |
1884 FunctionTypeAliasElementImpl f = | |
1885 ElementFactory.functionTypeAliasElement('f'); | |
1886 FunctionTypeAliasElementImpl g = | |
1887 ElementFactory.functionTypeAliasElement('g'); | |
1888 f.typeParameters = [ElementFactory.typeParameterElement('T')]; | |
1889 f.returnType = g.type; | |
1890 FunctionTypeImpl paramType = f.type.returnType; | |
1891 expect(paramType.prunedTypedefs, hasLength(1)); | |
1892 expect(paramType.prunedTypedefs[0], same(f)); | |
1893 } | |
1894 | |
1895 void test_substitute2_equal() { | |
1896 ClassElementImpl definingClass = ElementFactory.classElement2("C", ["E"]); | |
1897 TypeParameterType parameterType = definingClass.typeParameters[0].type; | |
1898 MethodElementImpl functionElement = | |
1899 new MethodElementImpl.forNode(AstFactory.identifier3("m")); | |
1900 String namedParameterName = "c"; | |
1901 functionElement.parameters = <ParameterElement>[ | |
1902 ElementFactory.requiredParameter2("a", parameterType), | |
1903 ElementFactory.positionalParameter2("b", parameterType), | |
1904 ElementFactory.namedParameter2(namedParameterName, parameterType) | |
1905 ]; | |
1906 functionElement.returnType = parameterType; | |
1907 definingClass.methods = <MethodElement>[functionElement]; | |
1908 FunctionTypeImpl functionType = new FunctionTypeImpl(functionElement); | |
1909 InterfaceTypeImpl argumentType = new InterfaceTypeImpl( | |
1910 new ClassElementImpl.forNode(AstFactory.identifier3("D"))); | |
1911 FunctionType result = functionType | |
1912 .substitute2(<DartType>[argumentType], <DartType>[parameterType]); | |
1913 expect(result.returnType, argumentType); | |
1914 List<DartType> normalParameters = result.normalParameterTypes; | |
1915 expect(normalParameters, hasLength(1)); | |
1916 expect(normalParameters[0], argumentType); | |
1917 List<DartType> optionalParameters = result.optionalParameterTypes; | |
1918 expect(optionalParameters, hasLength(1)); | |
1919 expect(optionalParameters[0], argumentType); | |
1920 Map<String, DartType> namedParameters = result.namedParameterTypes; | |
1921 expect(namedParameters, hasLength(1)); | |
1922 expect(namedParameters[namedParameterName], argumentType); | |
1923 } | |
1924 | |
1925 void test_substitute2_notEqual() { | |
1926 DartType returnType = new InterfaceTypeImpl( | |
1927 new ClassElementImpl.forNode(AstFactory.identifier3("R"))); | |
1928 DartType normalParameterType = new InterfaceTypeImpl( | |
1929 new ClassElementImpl.forNode(AstFactory.identifier3("A"))); | |
1930 DartType optionalParameterType = new InterfaceTypeImpl( | |
1931 new ClassElementImpl.forNode(AstFactory.identifier3("B"))); | |
1932 DartType namedParameterType = new InterfaceTypeImpl( | |
1933 new ClassElementImpl.forNode(AstFactory.identifier3("C"))); | |
1934 FunctionElementImpl functionElement = | |
1935 new FunctionElementImpl.forNode(AstFactory.identifier3("f")); | |
1936 String namedParameterName = "c"; | |
1937 functionElement.parameters = <ParameterElement>[ | |
1938 ElementFactory.requiredParameter2("a", normalParameterType), | |
1939 ElementFactory.positionalParameter2("b", optionalParameterType), | |
1940 ElementFactory.namedParameter2(namedParameterName, namedParameterType) | |
1941 ]; | |
1942 functionElement.returnType = returnType; | |
1943 FunctionTypeImpl functionType = new FunctionTypeImpl(functionElement); | |
1944 InterfaceTypeImpl argumentType = new InterfaceTypeImpl( | |
1945 new ClassElementImpl.forNode(AstFactory.identifier3("D"))); | |
1946 TypeParameterTypeImpl parameterType = new TypeParameterTypeImpl( | |
1947 new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"))); | |
1948 FunctionType result = functionType | |
1949 .substitute2(<DartType>[argumentType], <DartType>[parameterType]); | |
1950 expect(result.returnType, returnType); | |
1951 List<DartType> normalParameters = result.normalParameterTypes; | |
1952 expect(normalParameters, hasLength(1)); | |
1953 expect(normalParameters[0], normalParameterType); | |
1954 List<DartType> optionalParameters = result.optionalParameterTypes; | |
1955 expect(optionalParameters, hasLength(1)); | |
1956 expect(optionalParameters[0], optionalParameterType); | |
1957 Map<String, DartType> namedParameters = result.namedParameterTypes; | |
1958 expect(namedParameters, hasLength(1)); | |
1959 expect(namedParameters[namedParameterName], namedParameterType); | |
1960 } | |
1961 | |
1962 void test_toString_recursive() { | |
1963 FunctionTypeAliasElementImpl t = | |
1964 ElementFactory.functionTypeAliasElement("t"); | |
1965 FunctionTypeAliasElementImpl s = | |
1966 ElementFactory.functionTypeAliasElement("s"); | |
1967 t.returnType = s.type; | |
1968 s.returnType = t.type; | |
1969 expect(t.type.toString(), '() \u2192 () \u2192 ...'); | |
1970 } | |
1971 | |
1972 void test_toString_recursive_via_interface_type() { | |
1973 FunctionTypeAliasElementImpl f = | |
1974 ElementFactory.functionTypeAliasElement('f'); | |
1975 ClassElementImpl c = ElementFactory.classElement2('C', ['T']); | |
1976 f.returnType = c.type.substitute4([f.type]); | |
1977 expect(f.type.toString(), '() \u2192 C<...>'); | |
1978 } | |
1979 | |
1980 void test_withTypeArguments() { | |
1981 ClassElementImpl enclosingClass = ElementFactory.classElement2("C", ["E"]); | |
1982 MethodElementImpl methodElement = | |
1983 new MethodElementImpl.forNode(AstFactory.identifier3("m")); | |
1984 enclosingClass.methods = <MethodElement>[methodElement]; | |
1985 FunctionTypeImpl type = new FunctionTypeImpl(methodElement); | |
1986 DartType expectedType = enclosingClass.typeParameters[0].type; | |
1987 List<DartType> arguments = type.typeArguments; | |
1988 expect(arguments, hasLength(1)); | |
1989 expect(arguments[0], expectedType); | |
1990 } | |
1991 } | |
1992 | |
1993 @reflectiveTest | |
1994 class InterfaceTypeImplTest extends EngineTestCase { | |
1995 /** | |
1996 * The type provider used to access the types. | |
1997 */ | |
1998 TestTypeProvider _typeProvider; | |
1999 | |
2000 @override | |
2001 void setUp() { | |
2002 super.setUp(); | |
2003 _typeProvider = new TestTypeProvider(); | |
2004 } | |
2005 | |
2006 void test_computeLongestInheritancePathToObject_multipleInterfacePaths() { | |
2007 // | |
2008 // Object | |
2009 // | | |
2010 // A | |
2011 // / \ | |
2012 // B C | |
2013 // | | | |
2014 // | D | |
2015 // \ / | |
2016 // E | |
2017 // | |
2018 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2019 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
2020 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
2021 ClassElementImpl classD = ElementFactory.classElement2("D"); | |
2022 ClassElementImpl classE = ElementFactory.classElement2("E"); | |
2023 classB.interfaces = <InterfaceType>[classA.type]; | |
2024 classC.interfaces = <InterfaceType>[classA.type]; | |
2025 classD.interfaces = <InterfaceType>[classC.type]; | |
2026 classE.interfaces = <InterfaceType>[classB.type, classD.type]; | |
2027 // assertion: even though the longest path to Object for typeB is 2, and | |
2028 // typeE implements typeB, the longest path for typeE is 4 since it also | |
2029 // implements typeD | |
2030 expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type), | |
2031 2); | |
2032 expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classE.type), | |
2033 4); | |
2034 } | |
2035 | |
2036 void test_computeLongestInheritancePathToObject_multipleSuperclassPaths() { | |
2037 // | |
2038 // Object | |
2039 // | | |
2040 // A | |
2041 // / \ | |
2042 // B C | |
2043 // | | | |
2044 // | D | |
2045 // \ / | |
2046 // E | |
2047 // | |
2048 ClassElement classA = ElementFactory.classElement2("A"); | |
2049 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
2050 ClassElement classC = ElementFactory.classElement("C", classA.type); | |
2051 ClassElement classD = ElementFactory.classElement("D", classC.type); | |
2052 ClassElementImpl classE = ElementFactory.classElement("E", classB.type); | |
2053 classE.interfaces = <InterfaceType>[classD.type]; | |
2054 // assertion: even though the longest path to Object for typeB is 2, and | |
2055 // typeE extends typeB, the longest path for typeE is 4 since it also | |
2056 // implements typeD | |
2057 expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type), | |
2058 2); | |
2059 expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classE.type), | |
2060 4); | |
2061 } | |
2062 | |
2063 void test_computeLongestInheritancePathToObject_object() { | |
2064 // | |
2065 // Object | |
2066 // | | |
2067 // A | |
2068 // | |
2069 ClassElement classA = ElementFactory.classElement2("A"); | |
2070 InterfaceType object = classA.supertype; | |
2071 expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(object), 0); | |
2072 } | |
2073 | |
2074 void test_computeLongestInheritancePathToObject_recursion() { | |
2075 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2076 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
2077 classA.supertype = classB.type; | |
2078 expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classA.type), | |
2079 2); | |
2080 } | |
2081 | |
2082 void test_computeLongestInheritancePathToObject_singleInterfacePath() { | |
2083 // | |
2084 // Object | |
2085 // | | |
2086 // A | |
2087 // | | |
2088 // B | |
2089 // | | |
2090 // C | |
2091 // | |
2092 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2093 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
2094 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
2095 classB.interfaces = <InterfaceType>[classA.type]; | |
2096 classC.interfaces = <InterfaceType>[classB.type]; | |
2097 expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classA.type), | |
2098 1); | |
2099 expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type), | |
2100 2); | |
2101 expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classC.type), | |
2102 3); | |
2103 } | |
2104 | |
2105 void test_computeLongestInheritancePathToObject_singleSuperclassPath() { | |
2106 // | |
2107 // Object | |
2108 // | | |
2109 // A | |
2110 // | | |
2111 // B | |
2112 // | | |
2113 // C | |
2114 // | |
2115 ClassElement classA = ElementFactory.classElement2("A"); | |
2116 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
2117 ClassElement classC = ElementFactory.classElement("C", classB.type); | |
2118 expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classA.type), | |
2119 1); | |
2120 expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classB.type), | |
2121 2); | |
2122 expect(InterfaceTypeImpl.computeLongestInheritancePathToObject(classC.type), | |
2123 3); | |
2124 } | |
2125 | |
2126 void test_computeSuperinterfaceSet_genericInterfacePath() { | |
2127 // | |
2128 // A | |
2129 // | implements | |
2130 // B<T> | |
2131 // | implements | |
2132 // C<T> | |
2133 // | |
2134 // D | |
2135 // | |
2136 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2137 ClassElementImpl classB = ElementFactory.classElement2("B", ["T"]); | |
2138 ClassElementImpl classC = ElementFactory.classElement2("C", ["T"]); | |
2139 ClassElement classD = ElementFactory.classElement2("D"); | |
2140 InterfaceType typeA = classA.type; | |
2141 classB.interfaces = <InterfaceType>[typeA]; | |
2142 InterfaceTypeImpl typeBT = new InterfaceTypeImpl(classB); | |
2143 DartType typeT = classC.type.typeArguments[0]; | |
2144 typeBT.typeArguments = <DartType>[typeT]; | |
2145 classC.interfaces = <InterfaceType>[typeBT]; | |
2146 // A | |
2147 Set<InterfaceType> superinterfacesOfA = | |
2148 InterfaceTypeImpl.computeSuperinterfaceSet(typeA); | |
2149 expect(superinterfacesOfA, hasLength(1)); | |
2150 InterfaceType typeObject = ElementFactory.object.type; | |
2151 expect(superinterfacesOfA.contains(typeObject), isTrue); | |
2152 // B<D> | |
2153 InterfaceTypeImpl typeBD = new InterfaceTypeImpl(classB); | |
2154 typeBD.typeArguments = <DartType>[classD.type]; | |
2155 Set<InterfaceType> superinterfacesOfBD = | |
2156 InterfaceTypeImpl.computeSuperinterfaceSet(typeBD); | |
2157 expect(superinterfacesOfBD, hasLength(2)); | |
2158 expect(superinterfacesOfBD.contains(typeObject), isTrue); | |
2159 expect(superinterfacesOfBD.contains(typeA), isTrue); | |
2160 // C<D> | |
2161 InterfaceTypeImpl typeCD = new InterfaceTypeImpl(classC); | |
2162 typeCD.typeArguments = <DartType>[classD.type]; | |
2163 Set<InterfaceType> superinterfacesOfCD = | |
2164 InterfaceTypeImpl.computeSuperinterfaceSet(typeCD); | |
2165 expect(superinterfacesOfCD, hasLength(3)); | |
2166 expect(superinterfacesOfCD.contains(typeObject), isTrue); | |
2167 expect(superinterfacesOfCD.contains(typeA), isTrue); | |
2168 expect(superinterfacesOfCD.contains(typeBD), isTrue); | |
2169 } | |
2170 | |
2171 void test_computeSuperinterfaceSet_genericSuperclassPath() { | |
2172 // | |
2173 // A | |
2174 // | | |
2175 // B<T> | |
2176 // | | |
2177 // C<T> | |
2178 // | |
2179 // D | |
2180 // | |
2181 ClassElement classA = ElementFactory.classElement2("A"); | |
2182 InterfaceType typeA = classA.type; | |
2183 ClassElement classB = ElementFactory.classElement("B", typeA, ["T"]); | |
2184 ClassElementImpl classC = ElementFactory.classElement2("C", ["T"]); | |
2185 InterfaceTypeImpl typeBT = new InterfaceTypeImpl(classB); | |
2186 DartType typeT = classC.type.typeArguments[0]; | |
2187 typeBT.typeArguments = <DartType>[typeT]; | |
2188 classC.supertype = typeBT; | |
2189 ClassElement classD = ElementFactory.classElement2("D"); | |
2190 // A | |
2191 Set<InterfaceType> superinterfacesOfA = | |
2192 InterfaceTypeImpl.computeSuperinterfaceSet(typeA); | |
2193 expect(superinterfacesOfA, hasLength(1)); | |
2194 InterfaceType typeObject = ElementFactory.object.type; | |
2195 expect(superinterfacesOfA.contains(typeObject), isTrue); | |
2196 // B<D> | |
2197 InterfaceTypeImpl typeBD = new InterfaceTypeImpl(classB); | |
2198 typeBD.typeArguments = <DartType>[classD.type]; | |
2199 Set<InterfaceType> superinterfacesOfBD = | |
2200 InterfaceTypeImpl.computeSuperinterfaceSet(typeBD); | |
2201 expect(superinterfacesOfBD, hasLength(2)); | |
2202 expect(superinterfacesOfBD.contains(typeObject), isTrue); | |
2203 expect(superinterfacesOfBD.contains(typeA), isTrue); | |
2204 // C<D> | |
2205 InterfaceTypeImpl typeCD = new InterfaceTypeImpl(classC); | |
2206 typeCD.typeArguments = <DartType>[classD.type]; | |
2207 Set<InterfaceType> superinterfacesOfCD = | |
2208 InterfaceTypeImpl.computeSuperinterfaceSet(typeCD); | |
2209 expect(superinterfacesOfCD, hasLength(3)); | |
2210 expect(superinterfacesOfCD.contains(typeObject), isTrue); | |
2211 expect(superinterfacesOfCD.contains(typeA), isTrue); | |
2212 expect(superinterfacesOfCD.contains(typeBD), isTrue); | |
2213 } | |
2214 | |
2215 void test_computeSuperinterfaceSet_multipleInterfacePaths() { | |
2216 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2217 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
2218 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
2219 ClassElementImpl classD = ElementFactory.classElement2("D"); | |
2220 ClassElementImpl classE = ElementFactory.classElement2("E"); | |
2221 classB.interfaces = <InterfaceType>[classA.type]; | |
2222 classC.interfaces = <InterfaceType>[classA.type]; | |
2223 classD.interfaces = <InterfaceType>[classC.type]; | |
2224 classE.interfaces = <InterfaceType>[classB.type, classD.type]; | |
2225 // D | |
2226 Set<InterfaceType> superinterfacesOfD = | |
2227 InterfaceTypeImpl.computeSuperinterfaceSet(classD.type); | |
2228 expect(superinterfacesOfD, hasLength(3)); | |
2229 expect(superinterfacesOfD.contains(ElementFactory.object.type), isTrue); | |
2230 expect(superinterfacesOfD.contains(classA.type), isTrue); | |
2231 expect(superinterfacesOfD.contains(classC.type), isTrue); | |
2232 // E | |
2233 Set<InterfaceType> superinterfacesOfE = | |
2234 InterfaceTypeImpl.computeSuperinterfaceSet(classE.type); | |
2235 expect(superinterfacesOfE, hasLength(5)); | |
2236 expect(superinterfacesOfE.contains(ElementFactory.object.type), isTrue); | |
2237 expect(superinterfacesOfE.contains(classA.type), isTrue); | |
2238 expect(superinterfacesOfE.contains(classB.type), isTrue); | |
2239 expect(superinterfacesOfE.contains(classC.type), isTrue); | |
2240 expect(superinterfacesOfE.contains(classD.type), isTrue); | |
2241 } | |
2242 | |
2243 void test_computeSuperinterfaceSet_multipleSuperclassPaths() { | |
2244 ClassElement classA = ElementFactory.classElement2("A"); | |
2245 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
2246 ClassElement classC = ElementFactory.classElement("C", classA.type); | |
2247 ClassElement classD = ElementFactory.classElement("D", classC.type); | |
2248 ClassElementImpl classE = ElementFactory.classElement("E", classB.type); | |
2249 classE.interfaces = <InterfaceType>[classD.type]; | |
2250 // D | |
2251 Set<InterfaceType> superinterfacesOfD = | |
2252 InterfaceTypeImpl.computeSuperinterfaceSet(classD.type); | |
2253 expect(superinterfacesOfD, hasLength(3)); | |
2254 expect(superinterfacesOfD.contains(ElementFactory.object.type), isTrue); | |
2255 expect(superinterfacesOfD.contains(classA.type), isTrue); | |
2256 expect(superinterfacesOfD.contains(classC.type), isTrue); | |
2257 // E | |
2258 Set<InterfaceType> superinterfacesOfE = | |
2259 InterfaceTypeImpl.computeSuperinterfaceSet(classE.type); | |
2260 expect(superinterfacesOfE, hasLength(5)); | |
2261 expect(superinterfacesOfE.contains(ElementFactory.object.type), isTrue); | |
2262 expect(superinterfacesOfE.contains(classA.type), isTrue); | |
2263 expect(superinterfacesOfE.contains(classB.type), isTrue); | |
2264 expect(superinterfacesOfE.contains(classC.type), isTrue); | |
2265 expect(superinterfacesOfE.contains(classD.type), isTrue); | |
2266 } | |
2267 | |
2268 void test_computeSuperinterfaceSet_recursion() { | |
2269 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2270 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
2271 classA.supertype = classB.type; | |
2272 Set<InterfaceType> superinterfacesOfB = | |
2273 InterfaceTypeImpl.computeSuperinterfaceSet(classB.type); | |
2274 expect(superinterfacesOfB, hasLength(2)); | |
2275 } | |
2276 | |
2277 void test_computeSuperinterfaceSet_singleInterfacePath() { | |
2278 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2279 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
2280 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
2281 classB.interfaces = <InterfaceType>[classA.type]; | |
2282 classC.interfaces = <InterfaceType>[classB.type]; | |
2283 // A | |
2284 Set<InterfaceType> superinterfacesOfA = | |
2285 InterfaceTypeImpl.computeSuperinterfaceSet(classA.type); | |
2286 expect(superinterfacesOfA, hasLength(1)); | |
2287 expect(superinterfacesOfA.contains(ElementFactory.object.type), isTrue); | |
2288 // B | |
2289 Set<InterfaceType> superinterfacesOfB = | |
2290 InterfaceTypeImpl.computeSuperinterfaceSet(classB.type); | |
2291 expect(superinterfacesOfB, hasLength(2)); | |
2292 expect(superinterfacesOfB.contains(ElementFactory.object.type), isTrue); | |
2293 expect(superinterfacesOfB.contains(classA.type), isTrue); | |
2294 // C | |
2295 Set<InterfaceType> superinterfacesOfC = | |
2296 InterfaceTypeImpl.computeSuperinterfaceSet(classC.type); | |
2297 expect(superinterfacesOfC, hasLength(3)); | |
2298 expect(superinterfacesOfC.contains(ElementFactory.object.type), isTrue); | |
2299 expect(superinterfacesOfC.contains(classA.type), isTrue); | |
2300 expect(superinterfacesOfC.contains(classB.type), isTrue); | |
2301 } | |
2302 | |
2303 void test_computeSuperinterfaceSet_singleSuperclassPath() { | |
2304 // | |
2305 // A | |
2306 // | | |
2307 // B | |
2308 // | | |
2309 // C | |
2310 // | |
2311 ClassElement classA = ElementFactory.classElement2("A"); | |
2312 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
2313 ClassElement classC = ElementFactory.classElement("C", classB.type); | |
2314 // A | |
2315 Set<InterfaceType> superinterfacesOfA = | |
2316 InterfaceTypeImpl.computeSuperinterfaceSet(classA.type); | |
2317 expect(superinterfacesOfA, hasLength(1)); | |
2318 expect(superinterfacesOfA.contains(ElementFactory.object.type), isTrue); | |
2319 // B | |
2320 Set<InterfaceType> superinterfacesOfB = | |
2321 InterfaceTypeImpl.computeSuperinterfaceSet(classB.type); | |
2322 expect(superinterfacesOfB, hasLength(2)); | |
2323 expect(superinterfacesOfB.contains(ElementFactory.object.type), isTrue); | |
2324 expect(superinterfacesOfB.contains(classA.type), isTrue); | |
2325 // C | |
2326 Set<InterfaceType> superinterfacesOfC = | |
2327 InterfaceTypeImpl.computeSuperinterfaceSet(classC.type); | |
2328 expect(superinterfacesOfC, hasLength(3)); | |
2329 expect(superinterfacesOfC.contains(ElementFactory.object.type), isTrue); | |
2330 expect(superinterfacesOfC.contains(classA.type), isTrue); | |
2331 expect(superinterfacesOfC.contains(classB.type), isTrue); | |
2332 } | |
2333 | |
2334 void test_creation() { | |
2335 expect(new InterfaceTypeImpl(ElementFactory.classElement2("A")), isNotNull); | |
2336 } | |
2337 | |
2338 void test_getAccessors() { | |
2339 ClassElementImpl typeElement = ElementFactory.classElement2("A"); | |
2340 PropertyAccessorElement getterG = | |
2341 ElementFactory.getterElement("g", false, null); | |
2342 PropertyAccessorElement getterH = | |
2343 ElementFactory.getterElement("h", false, null); | |
2344 typeElement.accessors = <PropertyAccessorElement>[getterG, getterH]; | |
2345 InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement); | |
2346 expect(type.accessors.length, 2); | |
2347 } | |
2348 | |
2349 void test_getAccessors_empty() { | |
2350 ClassElementImpl typeElement = ElementFactory.classElement2("A"); | |
2351 InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement); | |
2352 expect(type.accessors.length, 0); | |
2353 } | |
2354 | |
2355 void test_getConstructors() { | |
2356 ClassElementImpl typeElement = ElementFactory.classElement2("A"); | |
2357 ConstructorElementImpl constructorOne = | |
2358 ElementFactory.constructorElement(typeElement, 'one', false); | |
2359 ConstructorElementImpl constructorTwo = | |
2360 ElementFactory.constructorElement(typeElement, 'two', false); | |
2361 typeElement.constructors = <ConstructorElement>[ | |
2362 constructorOne, | |
2363 constructorTwo | |
2364 ]; | |
2365 InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement); | |
2366 expect(type.constructors, hasLength(2)); | |
2367 } | |
2368 | |
2369 void test_getConstructors_empty() { | |
2370 ClassElementImpl typeElement = ElementFactory.classElement2("A"); | |
2371 typeElement.constructors = ConstructorElement.EMPTY_LIST; | |
2372 InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement); | |
2373 expect(type.constructors, isEmpty); | |
2374 } | |
2375 | |
2376 void test_getElement() { | |
2377 ClassElementImpl typeElement = ElementFactory.classElement2("A"); | |
2378 InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement); | |
2379 expect(type.element, typeElement); | |
2380 } | |
2381 | |
2382 void test_getGetter_implemented() { | |
2383 // | |
2384 // class A { g {} } | |
2385 // | |
2386 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2387 String getterName = "g"; | |
2388 PropertyAccessorElement getterG = | |
2389 ElementFactory.getterElement(getterName, false, null); | |
2390 classA.accessors = <PropertyAccessorElement>[getterG]; | |
2391 InterfaceType typeA = classA.type; | |
2392 expect(typeA.getGetter(getterName), same(getterG)); | |
2393 } | |
2394 | |
2395 void test_getGetter_parameterized() { | |
2396 // | |
2397 // class A<E> { E get g {} } | |
2398 // | |
2399 ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]); | |
2400 DartType typeE = classA.type.typeArguments[0]; | |
2401 String getterName = "g"; | |
2402 PropertyAccessorElementImpl getterG = | |
2403 ElementFactory.getterElement(getterName, false, typeE); | |
2404 classA.accessors = <PropertyAccessorElement>[getterG]; | |
2405 getterG.type = new FunctionTypeImpl(getterG); | |
2406 // | |
2407 // A<I> | |
2408 // | |
2409 InterfaceType typeI = ElementFactory.classElement2("I").type; | |
2410 InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA); | |
2411 typeAI.typeArguments = <DartType>[typeI]; | |
2412 PropertyAccessorElement getter = typeAI.getGetter(getterName); | |
2413 expect(getter, isNotNull); | |
2414 FunctionType getterType = getter.type; | |
2415 expect(getterType.returnType, same(typeI)); | |
2416 } | |
2417 | |
2418 void test_getGetter_unimplemented() { | |
2419 // | |
2420 // class A {} | |
2421 // | |
2422 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2423 InterfaceType typeA = classA.type; | |
2424 expect(typeA.getGetter("g"), isNull); | |
2425 } | |
2426 | |
2427 void test_getInterfaces_nonParameterized() { | |
2428 // | |
2429 // class C implements A, B | |
2430 // | |
2431 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2432 InterfaceType typeA = classA.type; | |
2433 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
2434 InterfaceType typeB = classB.type; | |
2435 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
2436 classC.interfaces = <InterfaceType>[typeA, typeB]; | |
2437 List<InterfaceType> interfaces = classC.type.interfaces; | |
2438 expect(interfaces, hasLength(2)); | |
2439 if (identical(interfaces[0], typeA)) { | |
2440 expect(interfaces[1], same(typeB)); | |
2441 } else { | |
2442 expect(interfaces[0], same(typeB)); | |
2443 expect(interfaces[1], same(typeA)); | |
2444 } | |
2445 } | |
2446 | |
2447 void test_getInterfaces_parameterized() { | |
2448 // | |
2449 // class A<E> | |
2450 // class B<F> implements A<F> | |
2451 // | |
2452 ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]); | |
2453 ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]); | |
2454 InterfaceType typeB = classB.type; | |
2455 InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA); | |
2456 typeAF.typeArguments = <DartType>[typeB.typeArguments[0]]; | |
2457 classB.interfaces = <InterfaceType>[typeAF]; | |
2458 // | |
2459 // B<I> | |
2460 // | |
2461 InterfaceType typeI = ElementFactory.classElement2("I").type; | |
2462 InterfaceTypeImpl typeBI = new InterfaceTypeImpl(classB); | |
2463 typeBI.typeArguments = <DartType>[typeI]; | |
2464 List<InterfaceType> interfaces = typeBI.interfaces; | |
2465 expect(interfaces, hasLength(1)); | |
2466 InterfaceType result = interfaces[0]; | |
2467 expect(result.element, same(classA)); | |
2468 expect(result.typeArguments[0], same(typeI)); | |
2469 } | |
2470 | |
2471 void test_getMethod_implemented() { | |
2472 // | |
2473 // class A { m() {} } | |
2474 // | |
2475 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2476 String methodName = "m"; | |
2477 MethodElementImpl methodM = ElementFactory.methodElement(methodName, null); | |
2478 classA.methods = <MethodElement>[methodM]; | |
2479 InterfaceType typeA = classA.type; | |
2480 expect(typeA.getMethod(methodName), same(methodM)); | |
2481 } | |
2482 | |
2483 void test_getMethod_parameterized() { | |
2484 // | |
2485 // class A<E> { E m(E p) {} } | |
2486 // | |
2487 ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]); | |
2488 DartType typeE = classA.type.typeArguments[0]; | |
2489 String methodName = "m"; | |
2490 MethodElementImpl methodM = | |
2491 ElementFactory.methodElement(methodName, typeE, [typeE]); | |
2492 classA.methods = <MethodElement>[methodM]; | |
2493 methodM.type = new FunctionTypeImpl(methodM); | |
2494 // | |
2495 // A<I> | |
2496 // | |
2497 InterfaceType typeI = ElementFactory.classElement2("I").type; | |
2498 InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA); | |
2499 typeAI.typeArguments = <DartType>[typeI]; | |
2500 MethodElement method = typeAI.getMethod(methodName); | |
2501 expect(method, isNotNull); | |
2502 FunctionType methodType = method.type; | |
2503 expect(methodType.returnType, same(typeI)); | |
2504 List<DartType> parameterTypes = methodType.normalParameterTypes; | |
2505 expect(parameterTypes, hasLength(1)); | |
2506 expect(parameterTypes[0], same(typeI)); | |
2507 } | |
2508 | |
2509 void test_getMethod_unimplemented() { | |
2510 // | |
2511 // class A {} | |
2512 // | |
2513 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2514 InterfaceType typeA = classA.type; | |
2515 expect(typeA.getMethod("m"), isNull); | |
2516 } | |
2517 | |
2518 void test_getMethods() { | |
2519 ClassElementImpl typeElement = ElementFactory.classElement2("A"); | |
2520 MethodElementImpl methodOne = ElementFactory.methodElement("one", null); | |
2521 MethodElementImpl methodTwo = ElementFactory.methodElement("two", null); | |
2522 typeElement.methods = <MethodElement>[methodOne, methodTwo]; | |
2523 InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement); | |
2524 expect(type.methods.length, 2); | |
2525 } | |
2526 | |
2527 void test_getMethods_empty() { | |
2528 ClassElementImpl typeElement = ElementFactory.classElement2("A"); | |
2529 InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement); | |
2530 expect(type.methods.length, 0); | |
2531 } | |
2532 | |
2533 void test_getMixins_nonParameterized() { | |
2534 // | |
2535 // class C extends Object with A, B | |
2536 // | |
2537 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2538 InterfaceType typeA = classA.type; | |
2539 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
2540 InterfaceType typeB = classB.type; | |
2541 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
2542 classC.mixins = <InterfaceType>[typeA, typeB]; | |
2543 List<InterfaceType> interfaces = classC.type.mixins; | |
2544 expect(interfaces, hasLength(2)); | |
2545 if (identical(interfaces[0], typeA)) { | |
2546 expect(interfaces[1], same(typeB)); | |
2547 } else { | |
2548 expect(interfaces[0], same(typeB)); | |
2549 expect(interfaces[1], same(typeA)); | |
2550 } | |
2551 } | |
2552 | |
2553 void test_getMixins_parameterized() { | |
2554 // | |
2555 // class A<E> | |
2556 // class B<F> extends Object with A<F> | |
2557 // | |
2558 ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]); | |
2559 ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]); | |
2560 InterfaceType typeB = classB.type; | |
2561 InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA); | |
2562 typeAF.typeArguments = <DartType>[typeB.typeArguments[0]]; | |
2563 classB.mixins = <InterfaceType>[typeAF]; | |
2564 // | |
2565 // B<I> | |
2566 // | |
2567 InterfaceType typeI = ElementFactory.classElement2("I").type; | |
2568 InterfaceTypeImpl typeBI = new InterfaceTypeImpl(classB); | |
2569 typeBI.typeArguments = <DartType>[typeI]; | |
2570 List<InterfaceType> interfaces = typeBI.mixins; | |
2571 expect(interfaces, hasLength(1)); | |
2572 InterfaceType result = interfaces[0]; | |
2573 expect(result.element, same(classA)); | |
2574 expect(result.typeArguments[0], same(typeI)); | |
2575 } | |
2576 | |
2577 void test_getSetter_implemented() { | |
2578 // | |
2579 // class A { s() {} } | |
2580 // | |
2581 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2582 String setterName = "s"; | |
2583 PropertyAccessorElement setterS = | |
2584 ElementFactory.setterElement(setterName, false, null); | |
2585 classA.accessors = <PropertyAccessorElement>[setterS]; | |
2586 InterfaceType typeA = classA.type; | |
2587 expect(typeA.getSetter(setterName), same(setterS)); | |
2588 } | |
2589 | |
2590 void test_getSetter_parameterized() { | |
2591 // | |
2592 // class A<E> { set s(E p) {} } | |
2593 // | |
2594 ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]); | |
2595 DartType typeE = classA.type.typeArguments[0]; | |
2596 String setterName = "s"; | |
2597 PropertyAccessorElementImpl setterS = | |
2598 ElementFactory.setterElement(setterName, false, typeE); | |
2599 classA.accessors = <PropertyAccessorElement>[setterS]; | |
2600 setterS.type = new FunctionTypeImpl(setterS); | |
2601 // | |
2602 // A<I> | |
2603 // | |
2604 InterfaceType typeI = ElementFactory.classElement2("I").type; | |
2605 InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA); | |
2606 typeAI.typeArguments = <DartType>[typeI]; | |
2607 PropertyAccessorElement setter = typeAI.getSetter(setterName); | |
2608 expect(setter, isNotNull); | |
2609 FunctionType setterType = setter.type; | |
2610 List<DartType> parameterTypes = setterType.normalParameterTypes; | |
2611 expect(parameterTypes, hasLength(1)); | |
2612 expect(parameterTypes[0], same(typeI)); | |
2613 } | |
2614 | |
2615 void test_getSetter_unimplemented() { | |
2616 // | |
2617 // class A {} | |
2618 // | |
2619 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2620 InterfaceType typeA = classA.type; | |
2621 expect(typeA.getSetter("s"), isNull); | |
2622 } | |
2623 | |
2624 void test_getSuperclass_nonParameterized() { | |
2625 // | |
2626 // class B extends A | |
2627 // | |
2628 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2629 InterfaceType typeA = classA.type; | |
2630 ClassElementImpl classB = ElementFactory.classElement("B", typeA); | |
2631 InterfaceType typeB = classB.type; | |
2632 expect(typeB.superclass, same(typeA)); | |
2633 } | |
2634 | |
2635 void test_getSuperclass_parameterized() { | |
2636 // | |
2637 // class A<E> | |
2638 // class B<F> extends A<F> | |
2639 // | |
2640 ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]); | |
2641 ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]); | |
2642 InterfaceType typeB = classB.type; | |
2643 InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA); | |
2644 typeAF.typeArguments = <DartType>[typeB.typeArguments[0]]; | |
2645 classB.supertype = typeAF; | |
2646 // | |
2647 // B<I> | |
2648 // | |
2649 InterfaceType typeI = ElementFactory.classElement2("I").type; | |
2650 InterfaceTypeImpl typeBI = new InterfaceTypeImpl(classB); | |
2651 typeBI.typeArguments = <DartType>[typeI]; | |
2652 InterfaceType superclass = typeBI.superclass; | |
2653 expect(superclass.element, same(classA)); | |
2654 expect(superclass.typeArguments[0], same(typeI)); | |
2655 } | |
2656 | |
2657 void test_getTypeArguments_empty() { | |
2658 InterfaceType type = ElementFactory.classElement2("A").type; | |
2659 expect(type.typeArguments, hasLength(0)); | |
2660 } | |
2661 | |
2662 void test_hashCode() { | |
2663 ClassElement classA = ElementFactory.classElement2("A"); | |
2664 InterfaceType typeA = classA.type; | |
2665 expect(0 == typeA.hashCode, isFalse); | |
2666 } | |
2667 | |
2668 void test_isAssignableTo_typeVariables() { | |
2669 // | |
2670 // class A<E> {} | |
2671 // class B<F, G> { | |
2672 // A<F> af; | |
2673 // f (A<G> ag) { | |
2674 // af = ag; | |
2675 // } | |
2676 // } | |
2677 // | |
2678 ClassElement classA = ElementFactory.classElement2("A", ["E"]); | |
2679 ClassElement classB = ElementFactory.classElement2("B", ["F", "G"]); | |
2680 InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA); | |
2681 typeAF.typeArguments = <DartType>[classB.typeParameters[0].type]; | |
2682 InterfaceTypeImpl typeAG = new InterfaceTypeImpl(classA); | |
2683 typeAG.typeArguments = <DartType>[classB.typeParameters[1].type]; | |
2684 expect(typeAG.isAssignableTo(typeAF), isFalse); | |
2685 } | |
2686 | |
2687 void test_isAssignableTo_void() { | |
2688 InterfaceTypeImpl intType = _typeProvider.intType; | |
2689 expect(VoidTypeImpl.instance.isAssignableTo(intType), isFalse); | |
2690 } | |
2691 | |
2692 void test_isDirectSupertypeOf_extends() { | |
2693 ClassElement classA = ElementFactory.classElement2("A"); | |
2694 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
2695 InterfaceType typeA = classA.type; | |
2696 InterfaceType typeB = classB.type; | |
2697 expect(typeA.isDirectSupertypeOf(typeB), isTrue); | |
2698 } | |
2699 | |
2700 void test_isDirectSupertypeOf_false() { | |
2701 ClassElement classA = ElementFactory.classElement2("A"); | |
2702 ClassElement classB = ElementFactory.classElement2("B"); | |
2703 ClassElement classC = ElementFactory.classElement("C", classB.type); | |
2704 InterfaceType typeA = classA.type; | |
2705 InterfaceType typeC = classC.type; | |
2706 expect(typeA.isDirectSupertypeOf(typeC), isFalse); | |
2707 } | |
2708 | |
2709 void test_isDirectSupertypeOf_implements() { | |
2710 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2711 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
2712 InterfaceType typeA = classA.type; | |
2713 InterfaceType typeB = classB.type; | |
2714 classB.interfaces = <InterfaceType>[typeA]; | |
2715 expect(typeA.isDirectSupertypeOf(typeB), isTrue); | |
2716 } | |
2717 | |
2718 void test_isDirectSupertypeOf_with() { | |
2719 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2720 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
2721 InterfaceType typeA = classA.type; | |
2722 InterfaceType typeB = classB.type; | |
2723 classB.mixins = <InterfaceType>[typeA]; | |
2724 expect(typeA.isDirectSupertypeOf(typeB), isTrue); | |
2725 } | |
2726 | |
2727 void test_isMoreSpecificThan_bottom() { | |
2728 DartType type = ElementFactory.classElement2("A").type; | |
2729 expect(BottomTypeImpl.instance.isMoreSpecificThan(type), isTrue); | |
2730 } | |
2731 | |
2732 void test_isMoreSpecificThan_covariance() { | |
2733 ClassElement classA = ElementFactory.classElement2("A", ["E"]); | |
2734 ClassElement classI = ElementFactory.classElement2("I"); | |
2735 ClassElement classJ = ElementFactory.classElement("J", classI.type); | |
2736 InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA); | |
2737 InterfaceTypeImpl typeAJ = new InterfaceTypeImpl(classA); | |
2738 typeAI.typeArguments = <DartType>[classI.type]; | |
2739 typeAJ.typeArguments = <DartType>[classJ.type]; | |
2740 expect(typeAJ.isMoreSpecificThan(typeAI), isTrue); | |
2741 expect(typeAI.isMoreSpecificThan(typeAJ), isFalse); | |
2742 } | |
2743 | |
2744 void test_isMoreSpecificThan_directSupertype() { | |
2745 ClassElement classA = ElementFactory.classElement2("A"); | |
2746 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
2747 InterfaceType typeA = classA.type; | |
2748 InterfaceType typeB = classB.type; | |
2749 expect(typeB.isMoreSpecificThan(typeA), isTrue); | |
2750 // the opposite test tests a different branch in isMoreSpecificThan() | |
2751 expect(typeA.isMoreSpecificThan(typeB), isFalse); | |
2752 } | |
2753 | |
2754 void test_isMoreSpecificThan_dynamic() { | |
2755 InterfaceType type = ElementFactory.classElement2("A").type; | |
2756 expect(type.isMoreSpecificThan(DynamicTypeImpl.instance), isTrue); | |
2757 } | |
2758 | |
2759 void test_isMoreSpecificThan_generic() { | |
2760 ClassElement classA = ElementFactory.classElement2("A", ["E"]); | |
2761 ClassElement classB = ElementFactory.classElement2("B"); | |
2762 DartType dynamicType = DynamicTypeImpl.instance; | |
2763 InterfaceType typeAOfDynamic = | |
2764 classA.type.substitute4(<DartType>[dynamicType]); | |
2765 InterfaceType typeAOfB = classA.type.substitute4(<DartType>[classB.type]); | |
2766 expect(typeAOfDynamic.isMoreSpecificThan(typeAOfB), isFalse); | |
2767 expect(typeAOfB.isMoreSpecificThan(typeAOfDynamic), isTrue); | |
2768 } | |
2769 | |
2770 void test_isMoreSpecificThan_self() { | |
2771 InterfaceType type = ElementFactory.classElement2("A").type; | |
2772 expect(type.isMoreSpecificThan(type), isTrue); | |
2773 } | |
2774 | |
2775 void test_isMoreSpecificThan_transitive_interface() { | |
2776 // | |
2777 // class A {} | |
2778 // class B extends A {} | |
2779 // class C implements B {} | |
2780 // | |
2781 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2782 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
2783 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
2784 classC.interfaces = <InterfaceType>[classB.type]; | |
2785 InterfaceType typeA = classA.type; | |
2786 InterfaceType typeC = classC.type; | |
2787 expect(typeC.isMoreSpecificThan(typeA), isTrue); | |
2788 } | |
2789 | |
2790 void test_isMoreSpecificThan_transitive_mixin() { | |
2791 // | |
2792 // class A {} | |
2793 // class B extends A {} | |
2794 // class C with B {} | |
2795 // | |
2796 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2797 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
2798 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
2799 classC.mixins = <InterfaceType>[classB.type]; | |
2800 InterfaceType typeA = classA.type; | |
2801 InterfaceType typeC = classC.type; | |
2802 expect(typeC.isMoreSpecificThan(typeA), isTrue); | |
2803 } | |
2804 | |
2805 void test_isMoreSpecificThan_transitive_recursive() { | |
2806 // | |
2807 // class A extends B {} | |
2808 // class B extends A {} | |
2809 // class C {} | |
2810 // | |
2811 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2812 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
2813 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
2814 InterfaceType typeA = classA.type; | |
2815 InterfaceType typeC = classC.type; | |
2816 classA.supertype = classB.type; | |
2817 expect(typeA.isMoreSpecificThan(typeC), isFalse); | |
2818 } | |
2819 | |
2820 void test_isMoreSpecificThan_transitive_superclass() { | |
2821 // | |
2822 // class A {} | |
2823 // class B extends A {} | |
2824 // class C extends B {} | |
2825 // | |
2826 ClassElement classA = ElementFactory.classElement2("A"); | |
2827 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
2828 ClassElement classC = ElementFactory.classElement("C", classB.type); | |
2829 InterfaceType typeA = classA.type; | |
2830 InterfaceType typeC = classC.type; | |
2831 expect(typeC.isMoreSpecificThan(typeA), isTrue); | |
2832 } | |
2833 | |
2834 void test_isMoreSpecificThan_typeParameterType() { | |
2835 // | |
2836 // class A<E> {} | |
2837 // | |
2838 ClassElement classA = ElementFactory.classElement2("A", ["E"]); | |
2839 InterfaceType typeA = classA.type; | |
2840 TypeParameterType parameterType = classA.typeParameters[0].type; | |
2841 DartType objectType = _typeProvider.objectType; | |
2842 expect(parameterType.isMoreSpecificThan(objectType), isTrue); | |
2843 expect(parameterType.isMoreSpecificThan(typeA), isFalse); | |
2844 } | |
2845 | |
2846 void test_isMoreSpecificThan_typeParameterType_withBound() { | |
2847 // | |
2848 // class A {} | |
2849 // class B<E extends A> {} | |
2850 // | |
2851 ClassElement classA = ElementFactory.classElement2("A"); | |
2852 InterfaceType typeA = classA.type; | |
2853 ClassElementImpl classB = ElementFactory.classElement2("B"); | |
2854 TypeParameterElementImpl parameterEA = | |
2855 new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")); | |
2856 TypeParameterType parameterAEType = new TypeParameterTypeImpl(parameterEA); | |
2857 parameterEA.bound = typeA; | |
2858 parameterEA.type = parameterAEType; | |
2859 classB.typeParameters = <TypeParameterElementImpl>[parameterEA]; | |
2860 expect(parameterAEType.isMoreSpecificThan(typeA), isTrue); | |
2861 } | |
2862 | |
2863 void test_isSubtypeOf_directSubtype() { | |
2864 ClassElement classA = ElementFactory.classElement2("A"); | |
2865 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
2866 InterfaceType typeA = classA.type; | |
2867 InterfaceType typeB = classB.type; | |
2868 expect(typeB.isSubtypeOf(typeA), isTrue); | |
2869 expect(typeA.isSubtypeOf(typeB), isFalse); | |
2870 } | |
2871 | |
2872 void test_isSubtypeOf_dynamic() { | |
2873 ClassElement classA = ElementFactory.classElement2("A"); | |
2874 InterfaceType typeA = classA.type; | |
2875 DartType dynamicType = DynamicTypeImpl.instance; | |
2876 expect(dynamicType.isSubtypeOf(typeA), isTrue); | |
2877 expect(typeA.isSubtypeOf(dynamicType), isTrue); | |
2878 } | |
2879 | |
2880 void test_isSubtypeOf_function() { | |
2881 // | |
2882 // void f(String s) {} | |
2883 // class A { | |
2884 // void call(String s) {} | |
2885 // } | |
2886 // | |
2887 InterfaceType stringType = _typeProvider.stringType; | |
2888 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2889 classA.methods = <MethodElement>[ | |
2890 ElementFactory.methodElement("call", VoidTypeImpl.instance, [stringType]) | |
2891 ]; | |
2892 FunctionType functionType = ElementFactory | |
2893 .functionElement5("f", <ClassElement>[stringType.element]).type; | |
2894 expect(classA.type.isSubtypeOf(functionType), isTrue); | |
2895 } | |
2896 | |
2897 void test_isSubtypeOf_generic() { | |
2898 ClassElement classA = ElementFactory.classElement2("A", ["E"]); | |
2899 ClassElement classB = ElementFactory.classElement2("B"); | |
2900 DartType dynamicType = DynamicTypeImpl.instance; | |
2901 InterfaceType typeAOfDynamic = | |
2902 classA.type.substitute4(<DartType>[dynamicType]); | |
2903 InterfaceType typeAOfB = classA.type.substitute4(<DartType>[classB.type]); | |
2904 expect(typeAOfDynamic.isSubtypeOf(typeAOfB), isTrue); | |
2905 expect(typeAOfB.isSubtypeOf(typeAOfDynamic), isTrue); | |
2906 } | |
2907 | |
2908 void test_isSubtypeOf_interface() { | |
2909 ClassElement classA = ElementFactory.classElement2("A"); | |
2910 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
2911 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
2912 InterfaceType typeObject = classA.supertype; | |
2913 InterfaceType typeA = classA.type; | |
2914 InterfaceType typeB = classB.type; | |
2915 InterfaceType typeC = classC.type; | |
2916 classC.interfaces = <InterfaceType>[typeB]; | |
2917 expect(typeC.isSubtypeOf(typeB), isTrue); | |
2918 expect(typeC.isSubtypeOf(typeObject), isTrue); | |
2919 expect(typeC.isSubtypeOf(typeA), isTrue); | |
2920 expect(typeA.isSubtypeOf(typeC), isFalse); | |
2921 } | |
2922 | |
2923 void test_isSubtypeOf_mixins() { | |
2924 // | |
2925 // class A {} | |
2926 // class B extends A {} | |
2927 // class C with B {} | |
2928 // | |
2929 ClassElement classA = ElementFactory.classElement2("A"); | |
2930 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
2931 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
2932 InterfaceType typeObject = classA.supertype; | |
2933 InterfaceType typeA = classA.type; | |
2934 InterfaceType typeB = classB.type; | |
2935 InterfaceType typeC = classC.type; | |
2936 classC.mixins = <InterfaceType>[typeB]; | |
2937 expect(typeC.isSubtypeOf(typeB), isTrue); | |
2938 expect(typeC.isSubtypeOf(typeObject), isTrue); | |
2939 expect(typeC.isSubtypeOf(typeA), isTrue); | |
2940 expect(typeA.isSubtypeOf(typeC), isFalse); | |
2941 } | |
2942 | |
2943 void test_isSubtypeOf_object() { | |
2944 ClassElement classA = ElementFactory.classElement2("A"); | |
2945 InterfaceType typeA = classA.type; | |
2946 InterfaceType typeObject = classA.supertype; | |
2947 expect(typeA.isSubtypeOf(typeObject), isTrue); | |
2948 expect(typeObject.isSubtypeOf(typeA), isFalse); | |
2949 } | |
2950 | |
2951 void test_isSubtypeOf_self() { | |
2952 ClassElement classA = ElementFactory.classElement2("A"); | |
2953 InterfaceType typeA = classA.type; | |
2954 expect(typeA.isSubtypeOf(typeA), isTrue); | |
2955 } | |
2956 | |
2957 void test_isSubtypeOf_transitive_recursive() { | |
2958 // | |
2959 // class A extends B {} | |
2960 // class B extends A {} | |
2961 // class C {} | |
2962 // | |
2963 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
2964 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
2965 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
2966 InterfaceType typeA = classA.type; | |
2967 InterfaceType typeC = classC.type; | |
2968 classA.supertype = classB.type; | |
2969 expect(typeA.isSubtypeOf(typeC), isFalse); | |
2970 } | |
2971 | |
2972 void test_isSubtypeOf_transitive_superclass() { | |
2973 ClassElement classA = ElementFactory.classElement2("A"); | |
2974 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
2975 ClassElement classC = ElementFactory.classElement("C", classB.type); | |
2976 InterfaceType typeA = classA.type; | |
2977 InterfaceType typeC = classC.type; | |
2978 expect(typeC.isSubtypeOf(typeA), isTrue); | |
2979 expect(typeA.isSubtypeOf(typeC), isFalse); | |
2980 } | |
2981 | |
2982 void test_isSubtypeOf_typeArguments() { | |
2983 DartType dynamicType = DynamicTypeImpl.instance; | |
2984 ClassElement classA = ElementFactory.classElement2("A", ["E"]); | |
2985 ClassElement classI = ElementFactory.classElement2("I"); | |
2986 ClassElement classJ = ElementFactory.classElement("J", classI.type); | |
2987 ClassElement classK = ElementFactory.classElement2("K"); | |
2988 InterfaceType typeA = classA.type; | |
2989 InterfaceType typeA_dynamic = typeA.substitute4(<DartType>[dynamicType]); | |
2990 InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA); | |
2991 InterfaceTypeImpl typeAJ = new InterfaceTypeImpl(classA); | |
2992 InterfaceTypeImpl typeAK = new InterfaceTypeImpl(classA); | |
2993 typeAI.typeArguments = <DartType>[classI.type]; | |
2994 typeAJ.typeArguments = <DartType>[classJ.type]; | |
2995 typeAK.typeArguments = <DartType>[classK.type]; | |
2996 // A<J> <: A<I> since J <: I | |
2997 expect(typeAJ.isSubtypeOf(typeAI), isTrue); | |
2998 expect(typeAI.isSubtypeOf(typeAJ), isFalse); | |
2999 // A<I> <: A<I> since I <: I | |
3000 expect(typeAI.isSubtypeOf(typeAI), isTrue); | |
3001 // A <: A<I> and A <: A<J> | |
3002 expect(typeA_dynamic.isSubtypeOf(typeAI), isTrue); | |
3003 expect(typeA_dynamic.isSubtypeOf(typeAJ), isTrue); | |
3004 // A<I> <: A and A<J> <: A | |
3005 expect(typeAI.isSubtypeOf(typeA_dynamic), isTrue); | |
3006 expect(typeAJ.isSubtypeOf(typeA_dynamic), isTrue); | |
3007 // A<I> !<: A<K> and A<K> !<: A<I> | |
3008 expect(typeAI.isSubtypeOf(typeAK), isFalse); | |
3009 expect(typeAK.isSubtypeOf(typeAI), isFalse); | |
3010 } | |
3011 | |
3012 void test_isSubtypeOf_typeParameter() { | |
3013 // | |
3014 // class A<E> {} | |
3015 // | |
3016 ClassElement classA = ElementFactory.classElement2("A", ["E"]); | |
3017 InterfaceType typeA = classA.type; | |
3018 TypeParameterType parameterType = classA.typeParameters[0].type; | |
3019 expect(typeA.isSubtypeOf(parameterType), isFalse); | |
3020 } | |
3021 | |
3022 void test_isSupertypeOf_directSupertype() { | |
3023 ClassElement classA = ElementFactory.classElement2("A"); | |
3024 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
3025 InterfaceType typeA = classA.type; | |
3026 InterfaceType typeB = classB.type; | |
3027 expect(typeB.isSupertypeOf(typeA), isFalse); | |
3028 expect(typeA.isSupertypeOf(typeB), isTrue); | |
3029 } | |
3030 | |
3031 void test_isSupertypeOf_dynamic() { | |
3032 ClassElement classA = ElementFactory.classElement2("A"); | |
3033 InterfaceType typeA = classA.type; | |
3034 DartType dynamicType = DynamicTypeImpl.instance; | |
3035 expect(dynamicType.isSupertypeOf(typeA), isTrue); | |
3036 expect(typeA.isSupertypeOf(dynamicType), isTrue); | |
3037 } | |
3038 | |
3039 void test_isSupertypeOf_indirectSupertype() { | |
3040 ClassElement classA = ElementFactory.classElement2("A"); | |
3041 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
3042 ClassElement classC = ElementFactory.classElement("C", classB.type); | |
3043 InterfaceType typeA = classA.type; | |
3044 InterfaceType typeC = classC.type; | |
3045 expect(typeC.isSupertypeOf(typeA), isFalse); | |
3046 expect(typeA.isSupertypeOf(typeC), isTrue); | |
3047 } | |
3048 | |
3049 void test_isSupertypeOf_interface() { | |
3050 ClassElement classA = ElementFactory.classElement2("A"); | |
3051 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
3052 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
3053 InterfaceType typeObject = classA.supertype; | |
3054 InterfaceType typeA = classA.type; | |
3055 InterfaceType typeB = classB.type; | |
3056 InterfaceType typeC = classC.type; | |
3057 classC.interfaces = <InterfaceType>[typeB]; | |
3058 expect(typeB.isSupertypeOf(typeC), isTrue); | |
3059 expect(typeObject.isSupertypeOf(typeC), isTrue); | |
3060 expect(typeA.isSupertypeOf(typeC), isTrue); | |
3061 expect(typeC.isSupertypeOf(typeA), isFalse); | |
3062 } | |
3063 | |
3064 void test_isSupertypeOf_mixins() { | |
3065 // | |
3066 // class A {} | |
3067 // class B extends A {} | |
3068 // class C with B {} | |
3069 // | |
3070 ClassElement classA = ElementFactory.classElement2("A"); | |
3071 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
3072 ClassElementImpl classC = ElementFactory.classElement2("C"); | |
3073 InterfaceType typeObject = classA.supertype; | |
3074 InterfaceType typeA = classA.type; | |
3075 InterfaceType typeB = classB.type; | |
3076 InterfaceType typeC = classC.type; | |
3077 classC.mixins = <InterfaceType>[typeB]; | |
3078 expect(typeB.isSupertypeOf(typeC), isTrue); | |
3079 expect(typeObject.isSupertypeOf(typeC), isTrue); | |
3080 expect(typeA.isSupertypeOf(typeC), isTrue); | |
3081 expect(typeC.isSupertypeOf(typeA), isFalse); | |
3082 } | |
3083 | |
3084 void test_isSupertypeOf_object() { | |
3085 ClassElement classA = ElementFactory.classElement2("A"); | |
3086 InterfaceType typeA = classA.type; | |
3087 InterfaceType typeObject = classA.supertype; | |
3088 expect(typeA.isSupertypeOf(typeObject), isFalse); | |
3089 expect(typeObject.isSupertypeOf(typeA), isTrue); | |
3090 } | |
3091 | |
3092 void test_isSupertypeOf_self() { | |
3093 ClassElement classA = ElementFactory.classElement2("A"); | |
3094 InterfaceType typeA = classA.type; | |
3095 expect(typeA.isSupertypeOf(typeA), isTrue); | |
3096 } | |
3097 | |
3098 void test_lookUpGetter_implemented() { | |
3099 // | |
3100 // class A { g {} } | |
3101 // | |
3102 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
3103 String getterName = "g"; | |
3104 PropertyAccessorElement getterG = | |
3105 ElementFactory.getterElement(getterName, false, null); | |
3106 classA.accessors = <PropertyAccessorElement>[getterG]; | |
3107 InterfaceType typeA = classA.type; | |
3108 LibraryElementImpl library = | |
3109 ElementFactory.library(createAnalysisContext(), "lib"); | |
3110 CompilationUnitElement unit = library.definingCompilationUnit; | |
3111 (unit as CompilationUnitElementImpl).types = <ClassElement>[classA]; | |
3112 expect(typeA.lookUpGetter(getterName, library), same(getterG)); | |
3113 } | |
3114 | |
3115 void test_lookUpGetter_inherited() { | |
3116 // | |
3117 // class A { g {} } | |
3118 // class B extends A {} | |
3119 // | |
3120 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
3121 String getterName = "g"; | |
3122 PropertyAccessorElement getterG = | |
3123 ElementFactory.getterElement(getterName, false, null); | |
3124 classA.accessors = <PropertyAccessorElement>[getterG]; | |
3125 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
3126 InterfaceType typeB = classB.type; | |
3127 LibraryElementImpl library = | |
3128 ElementFactory.library(createAnalysisContext(), "lib"); | |
3129 CompilationUnitElement unit = library.definingCompilationUnit; | |
3130 (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB]; | |
3131 expect(typeB.lookUpGetter(getterName, library), same(getterG)); | |
3132 } | |
3133 | |
3134 void test_lookUpGetter_mixin_shadowing() { | |
3135 // | |
3136 // class B {} | |
3137 // class M1 { get g {} } | |
3138 // class M2 { get g {} } | |
3139 // class C extends B with M1, M2 {} | |
3140 // | |
3141 TestTypeProvider typeProvider = new TestTypeProvider(); | |
3142 String getterName = 'g'; | |
3143 ClassElementImpl classB = ElementFactory.classElement2('B'); | |
3144 ClassElementImpl classM1 = ElementFactory.classElement2('M1'); | |
3145 PropertyAccessorElementImpl getterM1g = ElementFactory.getterElement( | |
3146 getterName, false, typeProvider.dynamicType); | |
3147 classM1.accessors = <PropertyAccessorElement>[getterM1g]; | |
3148 ClassElementImpl classM2 = ElementFactory.classElement2('M2'); | |
3149 PropertyAccessorElementImpl getterM2g = ElementFactory.getterElement( | |
3150 getterName, false, typeProvider.dynamicType); | |
3151 classM2.accessors = <PropertyAccessorElement>[getterM2g]; | |
3152 ClassElementImpl classC = ElementFactory.classElement('C', classB.type); | |
3153 classC.mixins = <InterfaceType>[classM1.type, classM2.type]; | |
3154 LibraryElementImpl library = | |
3155 ElementFactory.library(createAnalysisContext(), "lib"); | |
3156 CompilationUnitElementImpl unit = library.definingCompilationUnit; | |
3157 unit.types = <ClassElement>[classB, classM1, classM2, classC]; | |
3158 expect(classC.type.lookUpGetter(getterName, library), getterM2g); | |
3159 } | |
3160 | |
3161 void test_lookUpGetter_recursive() { | |
3162 // | |
3163 // class A extends B {} | |
3164 // class B extends A {} | |
3165 // | |
3166 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
3167 InterfaceType typeA = classA.type; | |
3168 ClassElementImpl classB = ElementFactory.classElement("B", typeA); | |
3169 classA.supertype = classB.type; | |
3170 LibraryElementImpl library = | |
3171 ElementFactory.library(createAnalysisContext(), "lib"); | |
3172 CompilationUnitElement unit = library.definingCompilationUnit; | |
3173 (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB]; | |
3174 expect(typeA.lookUpGetter("g", library), isNull); | |
3175 } | |
3176 | |
3177 void test_lookUpGetter_unimplemented() { | |
3178 // | |
3179 // class A {} | |
3180 // | |
3181 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
3182 InterfaceType typeA = classA.type; | |
3183 LibraryElementImpl library = | |
3184 ElementFactory.library(createAnalysisContext(), "lib"); | |
3185 CompilationUnitElement unit = library.definingCompilationUnit; | |
3186 (unit as CompilationUnitElementImpl).types = <ClassElement>[classA]; | |
3187 expect(typeA.lookUpGetter("g", library), isNull); | |
3188 } | |
3189 | |
3190 void test_lookUpMethod_implemented() { | |
3191 // | |
3192 // class A { m() {} } | |
3193 // | |
3194 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
3195 String methodName = "m"; | |
3196 MethodElementImpl methodM = ElementFactory.methodElement(methodName, null); | |
3197 classA.methods = <MethodElement>[methodM]; | |
3198 InterfaceType typeA = classA.type; | |
3199 LibraryElementImpl library = | |
3200 ElementFactory.library(createAnalysisContext(), "lib"); | |
3201 CompilationUnitElement unit = library.definingCompilationUnit; | |
3202 (unit as CompilationUnitElementImpl).types = <ClassElement>[classA]; | |
3203 expect(typeA.lookUpMethod(methodName, library), same(methodM)); | |
3204 } | |
3205 | |
3206 void test_lookUpMethod_inherited() { | |
3207 // | |
3208 // class A { m() {} } | |
3209 // class B extends A {} | |
3210 // | |
3211 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
3212 String methodName = "m"; | |
3213 MethodElementImpl methodM = ElementFactory.methodElement(methodName, null); | |
3214 classA.methods = <MethodElement>[methodM]; | |
3215 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
3216 InterfaceType typeB = classB.type; | |
3217 LibraryElementImpl library = | |
3218 ElementFactory.library(createAnalysisContext(), "lib"); | |
3219 CompilationUnitElement unit = library.definingCompilationUnit; | |
3220 (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB]; | |
3221 expect(typeB.lookUpMethod(methodName, library), same(methodM)); | |
3222 } | |
3223 | |
3224 void test_lookUpMethod_mixin_shadowing() { | |
3225 // | |
3226 // class B {} | |
3227 // class M1 { m() {} } | |
3228 // class M2 { m() {} } | |
3229 // class C extends B with M1, M2 {} | |
3230 // | |
3231 String methodName = 'm'; | |
3232 ClassElementImpl classB = ElementFactory.classElement2('B'); | |
3233 ClassElementImpl classM1 = ElementFactory.classElement2('M1'); | |
3234 MethodElementImpl methodM1m = | |
3235 ElementFactory.methodElement(methodName, null); | |
3236 classM1.methods = <MethodElement>[methodM1m]; | |
3237 ClassElementImpl classM2 = ElementFactory.classElement2('M2'); | |
3238 MethodElementImpl methodM2m = | |
3239 ElementFactory.methodElement(methodName, null); | |
3240 classM2.methods = <MethodElement>[methodM2m]; | |
3241 ClassElementImpl classC = ElementFactory.classElement('C', classB.type); | |
3242 classC.mixins = <InterfaceType>[classM1.type, classM2.type]; | |
3243 LibraryElementImpl library = | |
3244 ElementFactory.library(createAnalysisContext(), "lib"); | |
3245 CompilationUnitElementImpl unit = library.definingCompilationUnit; | |
3246 unit.types = <ClassElement>[classB, classM1, classM2, classC]; | |
3247 expect(classC.type.lookUpMethod(methodName, library), methodM2m); | |
3248 } | |
3249 | |
3250 void test_lookUpMethod_parameterized() { | |
3251 // | |
3252 // class A<E> { E m(E p) {} } | |
3253 // class B<F> extends A<F> {} | |
3254 // | |
3255 ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]); | |
3256 DartType typeE = classA.type.typeArguments[0]; | |
3257 String methodName = "m"; | |
3258 MethodElementImpl methodM = | |
3259 ElementFactory.methodElement(methodName, typeE, [typeE]); | |
3260 classA.methods = <MethodElement>[methodM]; | |
3261 methodM.type = new FunctionTypeImpl(methodM); | |
3262 ClassElementImpl classB = ElementFactory.classElement2("B", ["F"]); | |
3263 InterfaceType typeB = classB.type; | |
3264 InterfaceTypeImpl typeAF = new InterfaceTypeImpl(classA); | |
3265 typeAF.typeArguments = <DartType>[typeB.typeArguments[0]]; | |
3266 classB.supertype = typeAF; | |
3267 LibraryElementImpl library = | |
3268 ElementFactory.library(createAnalysisContext(), "lib"); | |
3269 CompilationUnitElement unit = library.definingCompilationUnit; | |
3270 (unit as CompilationUnitElementImpl).types = <ClassElement>[classA]; | |
3271 // | |
3272 // B<I> | |
3273 // | |
3274 InterfaceType typeI = ElementFactory.classElement2("I").type; | |
3275 InterfaceTypeImpl typeBI = new InterfaceTypeImpl(classB); | |
3276 typeBI.typeArguments = <DartType>[typeI]; | |
3277 MethodElement method = typeBI.lookUpMethod(methodName, library); | |
3278 expect(method, isNotNull); | |
3279 FunctionType methodType = method.type; | |
3280 expect(methodType.returnType, same(typeI)); | |
3281 List<DartType> parameterTypes = methodType.normalParameterTypes; | |
3282 expect(parameterTypes, hasLength(1)); | |
3283 expect(parameterTypes[0], same(typeI)); | |
3284 } | |
3285 | |
3286 void test_lookUpMethod_recursive() { | |
3287 // | |
3288 // class A extends B {} | |
3289 // class B extends A {} | |
3290 // | |
3291 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
3292 InterfaceType typeA = classA.type; | |
3293 ClassElementImpl classB = ElementFactory.classElement("B", typeA); | |
3294 classA.supertype = classB.type; | |
3295 LibraryElementImpl library = | |
3296 ElementFactory.library(createAnalysisContext(), "lib"); | |
3297 CompilationUnitElement unit = library.definingCompilationUnit; | |
3298 (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB]; | |
3299 expect(typeA.lookUpMethod("m", library), isNull); | |
3300 } | |
3301 | |
3302 void test_lookUpMethod_unimplemented() { | |
3303 // | |
3304 // class A {} | |
3305 // | |
3306 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
3307 InterfaceType typeA = classA.type; | |
3308 LibraryElementImpl library = | |
3309 ElementFactory.library(createAnalysisContext(), "lib"); | |
3310 CompilationUnitElement unit = library.definingCompilationUnit; | |
3311 (unit as CompilationUnitElementImpl).types = <ClassElement>[classA]; | |
3312 expect(typeA.lookUpMethod("m", library), isNull); | |
3313 } | |
3314 | |
3315 void test_lookUpSetter_implemented() { | |
3316 // | |
3317 // class A { s(x) {} } | |
3318 // | |
3319 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
3320 String setterName = "s"; | |
3321 PropertyAccessorElement setterS = | |
3322 ElementFactory.setterElement(setterName, false, null); | |
3323 classA.accessors = <PropertyAccessorElement>[setterS]; | |
3324 InterfaceType typeA = classA.type; | |
3325 LibraryElementImpl library = | |
3326 ElementFactory.library(createAnalysisContext(), "lib"); | |
3327 CompilationUnitElement unit = library.definingCompilationUnit; | |
3328 (unit as CompilationUnitElementImpl).types = <ClassElement>[classA]; | |
3329 expect(typeA.lookUpSetter(setterName, library), same(setterS)); | |
3330 } | |
3331 | |
3332 void test_lookUpSetter_inherited() { | |
3333 // | |
3334 // class A { s(x) {} } | |
3335 // class B extends A {} | |
3336 // | |
3337 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
3338 String setterName = "g"; | |
3339 PropertyAccessorElement setterS = | |
3340 ElementFactory.setterElement(setterName, false, null); | |
3341 classA.accessors = <PropertyAccessorElement>[setterS]; | |
3342 ClassElementImpl classB = ElementFactory.classElement("B", classA.type); | |
3343 InterfaceType typeB = classB.type; | |
3344 LibraryElementImpl library = | |
3345 ElementFactory.library(createAnalysisContext(), "lib"); | |
3346 CompilationUnitElement unit = library.definingCompilationUnit; | |
3347 (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB]; | |
3348 expect(typeB.lookUpSetter(setterName, library), same(setterS)); | |
3349 } | |
3350 | |
3351 void test_lookUpSetter_mixin_shadowing() { | |
3352 // | |
3353 // class B {} | |
3354 // class M1 { set s() {} } | |
3355 // class M2 { set s() {} } | |
3356 // class C extends B with M1, M2 {} | |
3357 // | |
3358 TestTypeProvider typeProvider = new TestTypeProvider(); | |
3359 String setterName = 's'; | |
3360 ClassElementImpl classB = ElementFactory.classElement2('B'); | |
3361 ClassElementImpl classM1 = ElementFactory.classElement2('M1'); | |
3362 PropertyAccessorElementImpl setterM1g = ElementFactory.setterElement( | |
3363 setterName, false, typeProvider.dynamicType); | |
3364 classM1.accessors = <PropertyAccessorElement>[setterM1g]; | |
3365 ClassElementImpl classM2 = ElementFactory.classElement2('M2'); | |
3366 PropertyAccessorElementImpl setterM2g = ElementFactory.getterElement( | |
3367 setterName, false, typeProvider.dynamicType); | |
3368 classM2.accessors = <PropertyAccessorElement>[setterM2g]; | |
3369 ClassElementImpl classC = ElementFactory.classElement('C', classB.type); | |
3370 classC.mixins = <InterfaceType>[classM1.type, classM2.type]; | |
3371 LibraryElementImpl library = | |
3372 ElementFactory.library(createAnalysisContext(), "lib"); | |
3373 CompilationUnitElementImpl unit = library.definingCompilationUnit; | |
3374 unit.types = <ClassElement>[classB, classM1, classM2, classC]; | |
3375 expect(classC.type.lookUpGetter(setterName, library), setterM2g); | |
3376 } | |
3377 | |
3378 void test_lookUpSetter_recursive() { | |
3379 // | |
3380 // class A extends B {} | |
3381 // class B extends A {} | |
3382 // | |
3383 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
3384 InterfaceType typeA = classA.type; | |
3385 ClassElementImpl classB = ElementFactory.classElement("B", typeA); | |
3386 classA.supertype = classB.type; | |
3387 LibraryElementImpl library = | |
3388 ElementFactory.library(createAnalysisContext(), "lib"); | |
3389 CompilationUnitElement unit = library.definingCompilationUnit; | |
3390 (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB]; | |
3391 expect(typeA.lookUpSetter("s", library), isNull); | |
3392 } | |
3393 | |
3394 void test_lookUpSetter_unimplemented() { | |
3395 // | |
3396 // class A {} | |
3397 // | |
3398 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
3399 InterfaceType typeA = classA.type; | |
3400 LibraryElementImpl library = | |
3401 ElementFactory.library(createAnalysisContext(), "lib"); | |
3402 CompilationUnitElement unit = library.definingCompilationUnit; | |
3403 (unit as CompilationUnitElementImpl).types = <ClassElement>[classA]; | |
3404 expect(typeA.lookUpSetter("s", library), isNull); | |
3405 } | |
3406 | |
3407 void test_setTypeArguments() { | |
3408 InterfaceTypeImpl type = | |
3409 ElementFactory.classElement2("A").type as InterfaceTypeImpl; | |
3410 List<DartType> typeArguments = <DartType>[ | |
3411 ElementFactory.classElement2("B").type, | |
3412 ElementFactory.classElement2("C").type | |
3413 ]; | |
3414 type.typeArguments = typeArguments; | |
3415 expect(type.typeArguments, typeArguments); | |
3416 } | |
3417 | |
3418 void test_substitute_equal() { | |
3419 ClassElement classAE = ElementFactory.classElement2("A", ["E"]); | |
3420 InterfaceType typeAE = classAE.type; | |
3421 InterfaceType argumentType = ElementFactory.classElement2("B").type; | |
3422 List<DartType> args = [argumentType]; | |
3423 List<DartType> params = [classAE.typeParameters[0].type]; | |
3424 InterfaceType typeAESubbed = typeAE.substitute2(args, params); | |
3425 expect(typeAESubbed.element, classAE); | |
3426 List<DartType> resultArguments = typeAESubbed.typeArguments; | |
3427 expect(resultArguments, hasLength(1)); | |
3428 expect(resultArguments[0], argumentType); | |
3429 } | |
3430 | |
3431 void test_substitute_exception() { | |
3432 try { | |
3433 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
3434 InterfaceTypeImpl type = new InterfaceTypeImpl(classA); | |
3435 InterfaceType argumentType = ElementFactory.classElement2("B").type; | |
3436 type.substitute2(<DartType>[argumentType], <DartType>[]); | |
3437 fail( | |
3438 "Expected to encounter exception, argument and parameter type array le
ngths not equal."); | |
3439 } catch (e) { | |
3440 // Expected result | |
3441 } | |
3442 } | |
3443 | |
3444 void test_substitute_notEqual() { | |
3445 // The [test_substitute_equals] above has a slightly higher level | |
3446 // implementation. | |
3447 ClassElementImpl classA = ElementFactory.classElement2("A"); | |
3448 TypeParameterElementImpl parameterElement = | |
3449 new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")); | |
3450 InterfaceTypeImpl type = new InterfaceTypeImpl(classA); | |
3451 TypeParameterTypeImpl parameter = | |
3452 new TypeParameterTypeImpl(parameterElement); | |
3453 type.typeArguments = <DartType>[parameter]; | |
3454 InterfaceType argumentType = ElementFactory.classElement2("B").type; | |
3455 TypeParameterTypeImpl parameterType = new TypeParameterTypeImpl( | |
3456 new TypeParameterElementImpl.forNode(AstFactory.identifier3("F"))); | |
3457 InterfaceType result = | |
3458 type.substitute2(<DartType>[argumentType], <DartType>[parameterType]); | |
3459 expect(result.element, classA); | |
3460 List<DartType> resultArguments = result.typeArguments; | |
3461 expect(resultArguments, hasLength(1)); | |
3462 expect(resultArguments[0], parameter); | |
3463 } | |
3464 } | |
3465 | |
3466 @reflectiveTest | |
3467 class LibraryElementImplTest extends EngineTestCase { | |
3468 void test_creation() { | |
3469 expect( | |
3470 new LibraryElementImpl.forNode( | |
3471 createAnalysisContext(), AstFactory.libraryIdentifier2(["l"])), | |
3472 isNotNull); | |
3473 } | |
3474 | |
3475 void test_getImportedLibraries() { | |
3476 AnalysisContext context = createAnalysisContext(); | |
3477 LibraryElementImpl library1 = ElementFactory.library(context, "l1"); | |
3478 LibraryElementImpl library2 = ElementFactory.library(context, "l2"); | |
3479 LibraryElementImpl library3 = ElementFactory.library(context, "l3"); | |
3480 LibraryElementImpl library4 = ElementFactory.library(context, "l4"); | |
3481 PrefixElement prefixA = | |
3482 new PrefixElementImpl.forNode(AstFactory.identifier3("a")); | |
3483 PrefixElement prefixB = | |
3484 new PrefixElementImpl.forNode(AstFactory.identifier3("b")); | |
3485 List<ImportElementImpl> imports = [ | |
3486 ElementFactory.importFor(library2, null), | |
3487 ElementFactory.importFor(library2, prefixB), | |
3488 ElementFactory.importFor(library3, null), | |
3489 ElementFactory.importFor(library3, prefixA), | |
3490 ElementFactory.importFor(library3, prefixB), | |
3491 ElementFactory.importFor(library4, prefixA) | |
3492 ]; | |
3493 library1.imports = imports; | |
3494 List<LibraryElement> libraries = library1.importedLibraries; | |
3495 expect(libraries, | |
3496 unorderedEquals(<LibraryElement>[library2, library3, library4])); | |
3497 } | |
3498 | |
3499 void test_getPrefixes() { | |
3500 AnalysisContext context = createAnalysisContext(); | |
3501 LibraryElementImpl library = ElementFactory.library(context, "l1"); | |
3502 PrefixElement prefixA = | |
3503 new PrefixElementImpl.forNode(AstFactory.identifier3("a")); | |
3504 PrefixElement prefixB = | |
3505 new PrefixElementImpl.forNode(AstFactory.identifier3("b")); | |
3506 List<ImportElementImpl> imports = [ | |
3507 ElementFactory.importFor(ElementFactory.library(context, "l2"), null), | |
3508 ElementFactory.importFor(ElementFactory.library(context, "l3"), null), | |
3509 ElementFactory.importFor(ElementFactory.library(context, "l4"), prefixA), | |
3510 ElementFactory.importFor(ElementFactory.library(context, "l5"), prefixA), | |
3511 ElementFactory.importFor(ElementFactory.library(context, "l6"), prefixB) | |
3512 ]; | |
3513 library.imports = imports; | |
3514 List<PrefixElement> prefixes = library.prefixes; | |
3515 expect(prefixes, hasLength(2)); | |
3516 if (identical(prefixA, prefixes[0])) { | |
3517 expect(prefixes[1], same(prefixB)); | |
3518 } else { | |
3519 expect(prefixes[0], same(prefixB)); | |
3520 expect(prefixes[1], same(prefixA)); | |
3521 } | |
3522 } | |
3523 | |
3524 void test_getUnits() { | |
3525 AnalysisContext context = createAnalysisContext(); | |
3526 LibraryElementImpl library = ElementFactory.library(context, "test"); | |
3527 CompilationUnitElement unitLib = library.definingCompilationUnit; | |
3528 CompilationUnitElementImpl unitA = | |
3529 ElementFactory.compilationUnit("unit_a.dart", unitLib.source); | |
3530 CompilationUnitElementImpl unitB = | |
3531 ElementFactory.compilationUnit("unit_b.dart", unitLib.source); | |
3532 library.parts = <CompilationUnitElement>[unitA, unitB]; | |
3533 expect(library.units, | |
3534 unorderedEquals(<CompilationUnitElement>[unitLib, unitA, unitB])); | |
3535 } | |
3536 | |
3537 void test_getVisibleLibraries_cycle() { | |
3538 AnalysisContext context = createAnalysisContext(); | |
3539 LibraryElementImpl library = ElementFactory.library(context, "app"); | |
3540 LibraryElementImpl libraryA = ElementFactory.library(context, "A"); | |
3541 libraryA.imports = <ImportElementImpl>[ | |
3542 ElementFactory.importFor(library, null) | |
3543 ]; | |
3544 library.imports = <ImportElementImpl>[ | |
3545 ElementFactory.importFor(libraryA, null) | |
3546 ]; | |
3547 List<LibraryElement> libraries = library.visibleLibraries; | |
3548 expect(libraries, unorderedEquals(<LibraryElement>[library, libraryA])); | |
3549 } | |
3550 | |
3551 void test_getVisibleLibraries_directExports() { | |
3552 AnalysisContext context = createAnalysisContext(); | |
3553 LibraryElementImpl library = ElementFactory.library(context, "app"); | |
3554 LibraryElementImpl libraryA = ElementFactory.library(context, "A"); | |
3555 library.exports = <ExportElementImpl>[ElementFactory.exportFor(libraryA)]; | |
3556 List<LibraryElement> libraries = library.visibleLibraries; | |
3557 expect(libraries, unorderedEquals(<LibraryElement>[library])); | |
3558 } | |
3559 | |
3560 void test_getVisibleLibraries_directImports() { | |
3561 AnalysisContext context = createAnalysisContext(); | |
3562 LibraryElementImpl library = ElementFactory.library(context, "app"); | |
3563 LibraryElementImpl libraryA = ElementFactory.library(context, "A"); | |
3564 library.imports = <ImportElementImpl>[ | |
3565 ElementFactory.importFor(libraryA, null) | |
3566 ]; | |
3567 List<LibraryElement> libraries = library.visibleLibraries; | |
3568 expect(libraries, unorderedEquals(<LibraryElement>[library, libraryA])); | |
3569 } | |
3570 | |
3571 void test_getVisibleLibraries_indirectExports() { | |
3572 AnalysisContext context = createAnalysisContext(); | |
3573 LibraryElementImpl library = ElementFactory.library(context, "app"); | |
3574 LibraryElementImpl libraryA = ElementFactory.library(context, "A"); | |
3575 LibraryElementImpl libraryAA = ElementFactory.library(context, "AA"); | |
3576 libraryA.exports = <ExportElementImpl>[ElementFactory.exportFor(libraryAA)]; | |
3577 library.imports = <ImportElementImpl>[ | |
3578 ElementFactory.importFor(libraryA, null) | |
3579 ]; | |
3580 List<LibraryElement> libraries = library.visibleLibraries; | |
3581 expect(libraries, | |
3582 unorderedEquals(<LibraryElement>[library, libraryA, libraryAA])); | |
3583 } | |
3584 | |
3585 void test_getVisibleLibraries_indirectImports() { | |
3586 AnalysisContext context = createAnalysisContext(); | |
3587 LibraryElementImpl library = ElementFactory.library(context, "app"); | |
3588 LibraryElementImpl libraryA = ElementFactory.library(context, "A"); | |
3589 LibraryElementImpl libraryAA = ElementFactory.library(context, "AA"); | |
3590 LibraryElementImpl libraryB = ElementFactory.library(context, "B"); | |
3591 libraryA.imports = <ImportElementImpl>[ | |
3592 ElementFactory.importFor(libraryAA, null) | |
3593 ]; | |
3594 library.imports = <ImportElementImpl>[ | |
3595 ElementFactory.importFor(libraryA, null), | |
3596 ElementFactory.importFor(libraryB, null) | |
3597 ]; | |
3598 List<LibraryElement> libraries = library.visibleLibraries; | |
3599 expect( | |
3600 libraries, | |
3601 unorderedEquals( | |
3602 <LibraryElement>[library, libraryA, libraryAA, libraryB])); | |
3603 } | |
3604 | |
3605 void test_getVisibleLibraries_noImports() { | |
3606 AnalysisContext context = createAnalysisContext(); | |
3607 LibraryElementImpl library = ElementFactory.library(context, "app"); | |
3608 expect( | |
3609 library.visibleLibraries, unorderedEquals(<LibraryElement>[library])); | |
3610 } | |
3611 | |
3612 void test_isUpToDate() { | |
3613 AnalysisContext context = createAnalysisContext(); | |
3614 context.sourceFactory = new SourceFactory([]); | |
3615 LibraryElement library = ElementFactory.library(context, "foo"); | |
3616 context.setContents(library.definingCompilationUnit.source, "sdfsdff"); | |
3617 // Assert that we are not up to date if the target has an old time stamp. | |
3618 expect(library.isUpToDate(0), isFalse); | |
3619 // Assert that we are up to date with a target modification time in the | |
3620 // future. | |
3621 expect(library.isUpToDate(JavaSystem.currentTimeMillis() + 1000), isTrue); | |
3622 } | |
3623 | |
3624 void test_setImports() { | |
3625 AnalysisContext context = createAnalysisContext(); | |
3626 LibraryElementImpl library = new LibraryElementImpl.forNode( | |
3627 context, AstFactory.libraryIdentifier2(["l1"])); | |
3628 List<ImportElementImpl> expectedImports = [ | |
3629 ElementFactory.importFor(ElementFactory.library(context, "l2"), null), | |
3630 ElementFactory.importFor(ElementFactory.library(context, "l3"), null) | |
3631 ]; | |
3632 library.imports = expectedImports; | |
3633 List<ImportElement> actualImports = library.imports; | |
3634 expect(actualImports, hasLength(expectedImports.length)); | |
3635 for (int i = 0; i < actualImports.length; i++) { | |
3636 expect(actualImports[i], same(expectedImports[i])); | |
3637 } | |
3638 } | |
3639 } | |
3640 | |
3641 @reflectiveTest | |
3642 class MethodElementImplTest extends EngineTestCase { | |
3643 void test_computeNode() { | |
3644 AnalysisContextHelper contextHelper = new AnalysisContextHelper(); | |
3645 AnalysisContext context = contextHelper.context; | |
3646 Source source = contextHelper.addSource( | |
3647 "/test.dart", | |
3648 r''' | |
3649 abstract class A { | |
3650 String m1() => null; | |
3651 m2(); | |
3652 } | |
3653 '''); | |
3654 // prepare CompilationUnitElement | |
3655 LibraryElement libraryElement = context.computeLibraryElement(source); | |
3656 CompilationUnitElement unitElement = libraryElement.definingCompilationUnit; | |
3657 // m1 | |
3658 { | |
3659 MethodElement m1Element = unitElement.getType("A").getMethod('m1'); | |
3660 MethodDeclaration m1Node = m1Element.computeNode(); | |
3661 expect(m1Node, isNotNull); | |
3662 expect(m1Node.name.name, "m1"); | |
3663 expect(m1Node.element, same(m1Element)); | |
3664 } | |
3665 // m2 | |
3666 { | |
3667 MethodElement m2Element = unitElement.getType("A").getMethod('m2'); | |
3668 MethodDeclaration m2Node = m2Element.computeNode(); | |
3669 expect(m2Node, isNotNull); | |
3670 expect(m2Node.name.name, "m2"); | |
3671 expect(m2Node.element, same(m2Element)); | |
3672 } | |
3673 } | |
3674 | |
3675 void test_computeNode_withoutFunctionBody() { | |
3676 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | |
3677 options.analyzeFunctionBodies = false; | |
3678 AnalysisContextHelper contextHelper = new AnalysisContextHelper(options); | |
3679 AnalysisContext context = contextHelper.context; | |
3680 Source source = contextHelper.addSource( | |
3681 "/test.dart", | |
3682 r''' | |
3683 abstract class A { | |
3684 String m1() => null; | |
3685 m2(); | |
3686 } | |
3687 '''); | |
3688 // prepare CompilationUnitElement | |
3689 LibraryElement libraryElement = context.computeLibraryElement(source); | |
3690 CompilationUnitElement unitElement = libraryElement.definingCompilationUnit; | |
3691 // m1 | |
3692 { | |
3693 MethodElement m1Element = unitElement.getType("A").getMethod('m1'); | |
3694 MethodDeclaration m1Node = m1Element.computeNode(); | |
3695 expect(m1Node, isNotNull); | |
3696 expect(m1Node.name.name, "m1"); | |
3697 expect(m1Node.element, same(m1Element)); | |
3698 } | |
3699 // m2 | |
3700 { | |
3701 MethodElement m2Element = unitElement.getType("A").getMethod('m2'); | |
3702 MethodDeclaration m2Node = m2Element.computeNode(); | |
3703 expect(m2Node, isNotNull); | |
3704 expect(m2Node.name.name, "m2"); | |
3705 expect(m2Node.element, same(m2Element)); | |
3706 } | |
3707 } | |
3708 } | |
3709 | |
3710 @reflectiveTest | |
3711 class MultiplyDefinedElementImplTest extends EngineTestCase { | |
3712 void test_fromElements_conflicting() { | |
3713 Element firstElement = ElementFactory.localVariableElement2("xx"); | |
3714 Element secondElement = ElementFactory.localVariableElement2("yy"); | |
3715 Element result = MultiplyDefinedElementImpl.fromElements( | |
3716 null, firstElement, secondElement); | |
3717 EngineTestCase.assertInstanceOf( | |
3718 (obj) => obj is MultiplyDefinedElement, MultiplyDefinedElement, result); | |
3719 List<Element> elements = | |
3720 (result as MultiplyDefinedElement).conflictingElements; | |
3721 expect(elements, hasLength(2)); | |
3722 for (int i = 0; i < elements.length; i++) { | |
3723 EngineTestCase.assertInstanceOf((obj) => obj is LocalVariableElement, | |
3724 LocalVariableElement, elements[i]); | |
3725 } | |
3726 } | |
3727 | |
3728 void test_fromElements_multiple() { | |
3729 Element firstElement = ElementFactory.localVariableElement2("xx"); | |
3730 Element secondElement = ElementFactory.localVariableElement2("yy"); | |
3731 Element thirdElement = ElementFactory.localVariableElement2("zz"); | |
3732 Element result = MultiplyDefinedElementImpl.fromElements( | |
3733 null, | |
3734 MultiplyDefinedElementImpl.fromElements( | |
3735 null, firstElement, secondElement), | |
3736 thirdElement); | |
3737 EngineTestCase.assertInstanceOf( | |
3738 (obj) => obj is MultiplyDefinedElement, MultiplyDefinedElement, result); | |
3739 List<Element> elements = | |
3740 (result as MultiplyDefinedElement).conflictingElements; | |
3741 expect(elements, hasLength(3)); | |
3742 for (int i = 0; i < elements.length; i++) { | |
3743 EngineTestCase.assertInstanceOf((obj) => obj is LocalVariableElement, | |
3744 LocalVariableElement, elements[i]); | |
3745 } | |
3746 } | |
3747 | |
3748 void test_fromElements_nonConflicting() { | |
3749 Element element = ElementFactory.localVariableElement2("xx"); | |
3750 expect(MultiplyDefinedElementImpl.fromElements(null, element, element), | |
3751 same(element)); | |
3752 } | |
3753 } | |
3754 | |
3755 @reflectiveTest | |
3756 class ParameterElementImplTest extends EngineTestCase { | |
3757 void test_computeNode_DefaultFormalParameter() { | |
3758 AnalysisContextHelper contextHelper = new AnalysisContextHelper(); | |
3759 AnalysisContext context = contextHelper.context; | |
3760 Source source = contextHelper.addSource( | |
3761 "/test.dart", | |
3762 r''' | |
3763 main([int p = 42]) { | |
3764 }'''); | |
3765 // prepare CompilationUnitElement | |
3766 LibraryElement libraryElement = context.computeLibraryElement(source); | |
3767 CompilationUnitElement unitElement = libraryElement.definingCompilationUnit; | |
3768 // p | |
3769 { | |
3770 ParameterElement element = unitElement.functions[0].parameters[0]; | |
3771 DefaultFormalParameter node = element.computeNode(); | |
3772 expect(node, isNotNull); | |
3773 expect(node.identifier.name, 'p'); | |
3774 expect(node.element, same(element)); | |
3775 } | |
3776 } | |
3777 | |
3778 void test_computeNode_FieldFormalParameter() { | |
3779 AnalysisContextHelper contextHelper = new AnalysisContextHelper(); | |
3780 AnalysisContext context = contextHelper.context; | |
3781 Source source = contextHelper.addSource( | |
3782 "/test.dart", | |
3783 r''' | |
3784 class A { | |
3785 int p; | |
3786 A(this.p) { | |
3787 } | |
3788 }'''); | |
3789 // prepare CompilationUnitElement | |
3790 LibraryElement libraryElement = context.computeLibraryElement(source); | |
3791 CompilationUnitElement unitElement = libraryElement.definingCompilationUnit; | |
3792 // p | |
3793 { | |
3794 ClassElement classA = unitElement.types[0]; | |
3795 ConstructorElement constructorA = classA.constructors[0]; | |
3796 FieldFormalParameterElement element = constructorA.parameters[0]; | |
3797 FieldFormalParameter node = element.computeNode(); | |
3798 expect(node, isNotNull); | |
3799 expect(node.identifier.name, 'p'); | |
3800 expect(node.element, same(element)); | |
3801 } | |
3802 } | |
3803 | |
3804 void test_computeNode_FunctionTypedFormalParameter() { | |
3805 AnalysisContextHelper contextHelper = new AnalysisContextHelper(); | |
3806 AnalysisContext context = contextHelper.context; | |
3807 Source source = contextHelper.addSource( | |
3808 "/test.dart", | |
3809 r''' | |
3810 main(p(int a, int b)) { | |
3811 }'''); | |
3812 // prepare CompilationUnitElement | |
3813 LibraryElement libraryElement = context.computeLibraryElement(source); | |
3814 CompilationUnitElement unitElement = libraryElement.definingCompilationUnit; | |
3815 // p | |
3816 { | |
3817 ParameterElement element = unitElement.functions[0].parameters[0]; | |
3818 FunctionTypedFormalParameter node = element.computeNode(); | |
3819 expect(node, isNotNull); | |
3820 expect(node.identifier.name, 'p'); | |
3821 expect(node.element, same(element)); | |
3822 } | |
3823 } | |
3824 | |
3825 void test_computeNode_SimpleFormalParameter() { | |
3826 AnalysisContextHelper contextHelper = new AnalysisContextHelper(); | |
3827 AnalysisContext context = contextHelper.context; | |
3828 Source source = contextHelper.addSource( | |
3829 "/test.dart", | |
3830 r''' | |
3831 main(int p) { | |
3832 }'''); | |
3833 // prepare CompilationUnitElement | |
3834 LibraryElement libraryElement = context.computeLibraryElement(source); | |
3835 CompilationUnitElement unitElement = libraryElement.definingCompilationUnit; | |
3836 // p | |
3837 { | |
3838 ParameterElement element = unitElement.functions[0].parameters[0]; | |
3839 SimpleFormalParameter node = element.computeNode(); | |
3840 expect(node, isNotNull); | |
3841 expect(node.identifier.name, 'p'); | |
3842 expect(node.element, same(element)); | |
3843 } | |
3844 } | |
3845 } | |
3846 | |
3847 @reflectiveTest | |
3848 class TypeParameterTypeImplTest extends EngineTestCase { | |
3849 void test_creation() { | |
3850 expect( | |
3851 new TypeParameterTypeImpl( | |
3852 new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"))), | |
3853 isNotNull); | |
3854 } | |
3855 | |
3856 void test_getElement() { | |
3857 TypeParameterElementImpl element = | |
3858 new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")); | |
3859 TypeParameterTypeImpl type = new TypeParameterTypeImpl(element); | |
3860 expect(type.element, element); | |
3861 } | |
3862 | |
3863 void test_isMoreSpecificThan_typeArguments_dynamic() { | |
3864 TypeParameterElementImpl element = | |
3865 new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")); | |
3866 TypeParameterTypeImpl type = new TypeParameterTypeImpl(element); | |
3867 // E << dynamic | |
3868 expect(type.isMoreSpecificThan(DynamicTypeImpl.instance), isTrue); | |
3869 } | |
3870 | |
3871 void test_isMoreSpecificThan_typeArguments_object() { | |
3872 TypeParameterElementImpl element = | |
3873 new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")); | |
3874 TypeParameterTypeImpl type = new TypeParameterTypeImpl(element); | |
3875 // E << Object | |
3876 expect(type.isMoreSpecificThan(ElementFactory.object.type), isTrue); | |
3877 } | |
3878 | |
3879 void test_isMoreSpecificThan_typeArguments_resursive() { | |
3880 ClassElementImpl classS = ElementFactory.classElement2("A"); | |
3881 TypeParameterElementImpl typeParameterU = | |
3882 new TypeParameterElementImpl.forNode(AstFactory.identifier3("U")); | |
3883 TypeParameterTypeImpl typeParameterTypeU = | |
3884 new TypeParameterTypeImpl(typeParameterU); | |
3885 TypeParameterElementImpl typeParameterT = | |
3886 new TypeParameterElementImpl.forNode(AstFactory.identifier3("T")); | |
3887 TypeParameterTypeImpl typeParameterTypeT = | |
3888 new TypeParameterTypeImpl(typeParameterT); | |
3889 typeParameterT.bound = typeParameterTypeU; | |
3890 typeParameterU.bound = typeParameterTypeU; | |
3891 // <T extends U> and <U extends T> | |
3892 // T << S | |
3893 expect(typeParameterTypeT.isMoreSpecificThan(classS.type), isFalse); | |
3894 } | |
3895 | |
3896 void test_isMoreSpecificThan_typeArguments_self() { | |
3897 TypeParameterElementImpl element = | |
3898 new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")); | |
3899 TypeParameterTypeImpl type = new TypeParameterTypeImpl(element); | |
3900 // E << E | |
3901 expect(type.isMoreSpecificThan(type), isTrue); | |
3902 } | |
3903 | |
3904 void test_isMoreSpecificThan_typeArguments_transitivity_interfaceTypes() { | |
3905 // class A {} | |
3906 // class B extends A {} | |
3907 // | |
3908 ClassElement classA = ElementFactory.classElement2("A"); | |
3909 ClassElement classB = ElementFactory.classElement("B", classA.type); | |
3910 InterfaceType typeA = classA.type; | |
3911 InterfaceType typeB = classB.type; | |
3912 TypeParameterElementImpl typeParameterT = | |
3913 new TypeParameterElementImpl.forNode(AstFactory.identifier3("T")); | |
3914 typeParameterT.bound = typeB; | |
3915 TypeParameterTypeImpl typeParameterTypeT = | |
3916 new TypeParameterTypeImpl(typeParameterT); | |
3917 // <T extends B> | |
3918 // T << A | |
3919 expect(typeParameterTypeT.isMoreSpecificThan(typeA), isTrue); | |
3920 } | |
3921 | |
3922 void test_isMoreSpecificThan_typeArguments_transitivity_typeParameters() { | |
3923 ClassElementImpl classS = ElementFactory.classElement2("A"); | |
3924 TypeParameterElementImpl typeParameterU = | |
3925 new TypeParameterElementImpl.forNode(AstFactory.identifier3("U")); | |
3926 typeParameterU.bound = classS.type; | |
3927 TypeParameterTypeImpl typeParameterTypeU = | |
3928 new TypeParameterTypeImpl(typeParameterU); | |
3929 TypeParameterElementImpl typeParameterT = | |
3930 new TypeParameterElementImpl.forNode(AstFactory.identifier3("T")); | |
3931 typeParameterT.bound = typeParameterTypeU; | |
3932 TypeParameterTypeImpl typeParameterTypeT = | |
3933 new TypeParameterTypeImpl(typeParameterT); | |
3934 // <T extends U> and <U extends S> | |
3935 // T << S | |
3936 expect(typeParameterTypeT.isMoreSpecificThan(classS.type), isTrue); | |
3937 } | |
3938 | |
3939 void test_isMoreSpecificThan_typeArguments_upperBound() { | |
3940 ClassElementImpl classS = ElementFactory.classElement2("A"); | |
3941 TypeParameterElementImpl typeParameterT = | |
3942 new TypeParameterElementImpl.forNode(AstFactory.identifier3("T")); | |
3943 typeParameterT.bound = classS.type; | |
3944 TypeParameterTypeImpl typeParameterTypeT = | |
3945 new TypeParameterTypeImpl(typeParameterT); | |
3946 // <T extends S> | |
3947 // T << S | |
3948 expect(typeParameterTypeT.isMoreSpecificThan(classS.type), isTrue); | |
3949 } | |
3950 | |
3951 void test_substitute_equal() { | |
3952 TypeParameterElementImpl element = | |
3953 new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")); | |
3954 TypeParameterTypeImpl type = new TypeParameterTypeImpl(element); | |
3955 InterfaceTypeImpl argument = new InterfaceTypeImpl( | |
3956 new ClassElementImpl.forNode(AstFactory.identifier3("A"))); | |
3957 TypeParameterTypeImpl parameter = new TypeParameterTypeImpl(element); | |
3958 expect(type.substitute2(<DartType>[argument], <DartType>[parameter]), | |
3959 same(argument)); | |
3960 } | |
3961 | |
3962 void test_substitute_notEqual() { | |
3963 TypeParameterTypeImpl type = new TypeParameterTypeImpl( | |
3964 new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"))); | |
3965 InterfaceTypeImpl argument = new InterfaceTypeImpl( | |
3966 new ClassElementImpl.forNode(AstFactory.identifier3("A"))); | |
3967 TypeParameterTypeImpl parameter = new TypeParameterTypeImpl( | |
3968 new TypeParameterElementImpl.forNode(AstFactory.identifier3("F"))); | |
3969 expect(type.substitute2(<DartType>[argument], <DartType>[parameter]), | |
3970 same(type)); | |
3971 } | |
3972 } | |
3973 | |
3974 @reflectiveTest | |
3975 class VoidTypeImplTest extends EngineTestCase { | |
3976 /** | |
3977 * Reference {code VoidTypeImpl.getInstance()}. | |
3978 */ | |
3979 DartType _voidType = VoidTypeImpl.instance; | |
3980 | |
3981 void test_isMoreSpecificThan_void_A() { | |
3982 ClassElement classA = ElementFactory.classElement2("A"); | |
3983 expect(_voidType.isMoreSpecificThan(classA.type), isFalse); | |
3984 } | |
3985 | |
3986 void test_isMoreSpecificThan_void_dynamic() { | |
3987 expect(_voidType.isMoreSpecificThan(DynamicTypeImpl.instance), isTrue); | |
3988 } | |
3989 | |
3990 void test_isMoreSpecificThan_void_void() { | |
3991 expect(_voidType.isMoreSpecificThan(_voidType), isTrue); | |
3992 } | |
3993 | |
3994 void test_isSubtypeOf_void_A() { | |
3995 ClassElement classA = ElementFactory.classElement2("A"); | |
3996 expect(_voidType.isSubtypeOf(classA.type), isFalse); | |
3997 } | |
3998 | |
3999 void test_isSubtypeOf_void_dynamic() { | |
4000 expect(_voidType.isSubtypeOf(DynamicTypeImpl.instance), isTrue); | |
4001 } | |
4002 | |
4003 void test_isSubtypeOf_void_void() { | |
4004 expect(_voidType.isSubtypeOf(_voidType), isTrue); | |
4005 } | |
4006 | |
4007 void test_isVoid() { | |
4008 expect(_voidType.isVoid, isTrue); | |
4009 } | |
4010 } | |
4011 | |
4012 class _FunctionTypeImplTest_isSubtypeOf_baseCase_classFunction | |
4013 extends InterfaceTypeImpl { | |
4014 _FunctionTypeImplTest_isSubtypeOf_baseCase_classFunction(ClassElement arg0) | |
4015 : super(arg0); | |
4016 | |
4017 @override | |
4018 bool get isDartCoreFunction => true; | |
4019 } | |
OLD | NEW |