OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library analyzer.test.generated.element_resolver_test; | 5 library analyzer.test.generated.element_resolver_test; |
6 | 6 |
7 import 'package:analyzer/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
8 import 'package:analyzer/dart/ast/token.dart'; | 8 import 'package:analyzer/dart/ast/token.dart'; |
9 import 'package:analyzer/dart/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
10 import 'package:analyzer/dart/element/type.dart'; | 10 import 'package:analyzer/dart/element/type.dart'; |
11 import 'package:analyzer/file_system/memory_file_system.dart'; | 11 import 'package:analyzer/file_system/memory_file_system.dart'; |
12 import 'package:analyzer/src/dart/element/element.dart'; | 12 import 'package:analyzer/src/dart/element/element.dart'; |
13 import 'package:analyzer/src/generated/element_resolver.dart'; | 13 import 'package:analyzer/src/generated/element_resolver.dart'; |
14 import 'package:analyzer/src/generated/engine.dart'; | 14 import 'package:analyzer/src/generated/engine.dart'; |
15 import 'package:analyzer/src/generated/resolver.dart'; | 15 import 'package:analyzer/src/generated/resolver.dart'; |
16 import 'package:analyzer/src/generated/source.dart'; | 16 import 'package:analyzer/src/generated/source.dart'; |
17 import 'package:analyzer/src/generated/testing/ast_factory.dart'; | 17 import 'package:analyzer/src/generated/testing/ast_factory.dart'; |
18 import 'package:analyzer/src/generated/testing/element_factory.dart'; | 18 import 'package:analyzer/src/generated/testing/element_factory.dart'; |
19 import 'package:analyzer/src/generated/testing/test_type_provider.dart'; | 19 import 'package:analyzer/src/generated/testing/test_type_provider.dart'; |
20 import 'package:analyzer/src/source/source_resource.dart'; | 20 import 'package:analyzer/src/source/source_resource.dart'; |
21 import 'package:test_reflective_loader/test_reflective_loader.dart'; | 21 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
22 import 'package:unittest/unittest.dart'; | 22 import 'package:unittest/unittest.dart'; |
23 | 23 |
24 import '../utils.dart'; | 24 import '../utils.dart'; |
25 import 'analysis_context_factory.dart'; | 25 import 'analysis_context_factory.dart'; |
| 26 import 'resolver_test_case.dart'; |
26 import 'test_support.dart'; | 27 import 'test_support.dart'; |
27 | 28 |
28 main() { | 29 main() { |
29 initializeTestEnvironment(); | 30 initializeTestEnvironment(); |
| 31 defineReflectiveTests(ElementResolverCodeTest); |
30 defineReflectiveTests(ElementResolverTest); | 32 defineReflectiveTests(ElementResolverTest); |
31 } | 33 } |
32 | 34 |
33 @reflectiveTest | 35 @reflectiveTest |
| 36 class ElementResolverCodeTest extends ResolverTestCase { |
| 37 void test_annotation_class_namedConstructor() { |
| 38 addNamedSource( |
| 39 '/a.dart', |
| 40 r''' |
| 41 class A { |
| 42 const A.named(); |
| 43 } |
| 44 '''); |
| 45 _validateAnnotation('', '@A.named()', (SimpleIdentifier name1, |
| 46 SimpleIdentifier name2, |
| 47 SimpleIdentifier name3, |
| 48 Element annotationElement) { |
| 49 expect(name1, isNotNull); |
| 50 expect(name1.staticElement, new isInstanceOf<ClassElement>()); |
| 51 expect(name1.staticElement.displayName, 'A'); |
| 52 expect(name2, isNotNull); |
| 53 expect(name2.staticElement, new isInstanceOf<ConstructorElement>()); |
| 54 expect(name2.staticElement.displayName, 'named'); |
| 55 expect(name3, isNull); |
| 56 if (annotationElement is ConstructorElement) { |
| 57 expect(annotationElement, same(name2.staticElement)); |
| 58 expect(annotationElement.enclosingElement, name1.staticElement); |
| 59 expect(annotationElement.displayName, 'named'); |
| 60 expect(annotationElement.parameters, isEmpty); |
| 61 } else { |
| 62 fail('Expected "annotationElement" is ConstructorElement, ' |
| 63 'but (${annotationElement?.runtimeType}) $annotationElement found.')
; |
| 64 } |
| 65 }); |
| 66 } |
| 67 |
| 68 void test_annotation_class_prefixed_namedConstructor() { |
| 69 addNamedSource( |
| 70 '/a.dart', |
| 71 r''' |
| 72 class A { |
| 73 const A.named(); |
| 74 } |
| 75 '''); |
| 76 _validateAnnotation('as p', '@p.A.named()', (SimpleIdentifier name1, |
| 77 SimpleIdentifier name2, |
| 78 SimpleIdentifier name3, |
| 79 Element annotationElement) { |
| 80 expect(name1, isNotNull); |
| 81 expect(name1.staticElement, new isInstanceOf<PrefixElement>()); |
| 82 expect(name1.staticElement.displayName, 'p'); |
| 83 expect(name2, isNotNull); |
| 84 expect(name2.staticElement, new isInstanceOf<ClassElement>()); |
| 85 expect(name2.staticElement.displayName, 'A'); |
| 86 expect(name3, isNotNull); |
| 87 expect(name3.staticElement, new isInstanceOf<ConstructorElement>()); |
| 88 expect(name3.staticElement.displayName, 'named'); |
| 89 if (annotationElement is ConstructorElement) { |
| 90 expect(annotationElement, same(name3.staticElement)); |
| 91 expect(annotationElement.enclosingElement, name2.staticElement); |
| 92 expect(annotationElement.displayName, 'named'); |
| 93 expect(annotationElement.parameters, isEmpty); |
| 94 } else { |
| 95 fail('Expected "annotationElement" is ConstructorElement, ' |
| 96 'but (${annotationElement?.runtimeType}) $annotationElement found.')
; |
| 97 } |
| 98 }); |
| 99 } |
| 100 |
| 101 void test_annotation_class_prefixed_staticConstField() { |
| 102 addNamedSource( |
| 103 '/a.dart', |
| 104 r''' |
| 105 class A { |
| 106 static const V = 0; |
| 107 } |
| 108 '''); |
| 109 _validateAnnotation('as p', '@p.A.V', (SimpleIdentifier name1, |
| 110 SimpleIdentifier name2, |
| 111 SimpleIdentifier name3, |
| 112 Element annotationElement) { |
| 113 expect(name1, isNotNull); |
| 114 expect(name1.staticElement, new isInstanceOf<PrefixElement>()); |
| 115 expect(name1.staticElement.displayName, 'p'); |
| 116 expect(name2, isNotNull); |
| 117 expect(name2.staticElement, new isInstanceOf<ClassElement>()); |
| 118 expect(name2.staticElement.displayName, 'A'); |
| 119 expect(name3, isNotNull); |
| 120 expect(name3.staticElement, new isInstanceOf<PropertyAccessorElement>()); |
| 121 expect(name3.staticElement.displayName, 'V'); |
| 122 if (annotationElement is PropertyAccessorElement) { |
| 123 expect(annotationElement, same(name3.staticElement)); |
| 124 expect(annotationElement.enclosingElement, name2.staticElement); |
| 125 expect(annotationElement.displayName, 'V'); |
| 126 } else { |
| 127 fail('Expected "annotationElement" is PropertyAccessorElement, ' |
| 128 'but (${annotationElement?.runtimeType}) $annotationElement found.')
; |
| 129 } |
| 130 }); |
| 131 } |
| 132 |
| 133 void test_annotation_class_prefixed_unnamedConstructor() { |
| 134 addNamedSource( |
| 135 '/a.dart', |
| 136 r''' |
| 137 class A { |
| 138 const A(); |
| 139 } |
| 140 '''); |
| 141 _validateAnnotation('as p', '@p.A', (SimpleIdentifier name1, |
| 142 SimpleIdentifier name2, |
| 143 SimpleIdentifier name3, |
| 144 Element annotationElement) { |
| 145 expect(name1, isNotNull); |
| 146 expect(name1.staticElement, new isInstanceOf<PrefixElement>()); |
| 147 expect(name1.staticElement.displayName, 'p'); |
| 148 expect(name2, isNotNull); |
| 149 expect(name2.staticElement, new isInstanceOf<ClassElement>()); |
| 150 expect(name2.staticElement.displayName, 'A'); |
| 151 expect(name3, isNull); |
| 152 if (annotationElement is ConstructorElement) { |
| 153 expect(annotationElement.enclosingElement, name2.staticElement); |
| 154 expect(annotationElement.displayName, ''); |
| 155 expect(annotationElement.parameters, isEmpty); |
| 156 } else { |
| 157 fail('Expected "annotationElement" is ConstructorElement, ' |
| 158 'but (${annotationElement?.runtimeType}) $annotationElement found.')
; |
| 159 } |
| 160 }); |
| 161 } |
| 162 |
| 163 void test_annotation_class_staticConstField() { |
| 164 addNamedSource( |
| 165 '/a.dart', |
| 166 r''' |
| 167 class A { |
| 168 static const V = 0; |
| 169 } |
| 170 '''); |
| 171 _validateAnnotation('', '@A.V', (SimpleIdentifier name1, |
| 172 SimpleIdentifier name2, |
| 173 SimpleIdentifier name3, |
| 174 Element annotationElement) { |
| 175 expect(name1, isNotNull); |
| 176 expect(name1.staticElement, new isInstanceOf<ClassElement>()); |
| 177 expect(name1.staticElement.displayName, 'A'); |
| 178 expect(name2, isNotNull); |
| 179 expect(name2.staticElement, new isInstanceOf<PropertyAccessorElement>()); |
| 180 expect(name2.staticElement.displayName, 'V'); |
| 181 expect(name3, isNull); |
| 182 if (annotationElement is PropertyAccessorElement) { |
| 183 expect(annotationElement, same(name2.staticElement)); |
| 184 expect(annotationElement.enclosingElement, name1.staticElement); |
| 185 expect(annotationElement.displayName, 'V'); |
| 186 } else { |
| 187 fail('Expected "annotationElement" is PropertyAccessorElement, ' |
| 188 'but (${annotationElement?.runtimeType}) $annotationElement found.')
; |
| 189 } |
| 190 }); |
| 191 } |
| 192 |
| 193 void test_annotation_class_unnamedConstructor() { |
| 194 addNamedSource( |
| 195 '/a.dart', |
| 196 r''' |
| 197 class A { |
| 198 const A(); |
| 199 } |
| 200 '''); |
| 201 _validateAnnotation('', '@A', (SimpleIdentifier name1, |
| 202 SimpleIdentifier name2, |
| 203 SimpleIdentifier name3, |
| 204 Element annotationElement) { |
| 205 expect(name1, isNotNull); |
| 206 expect(name1.staticElement, new isInstanceOf<ClassElement>()); |
| 207 expect(name1.staticElement.displayName, 'A'); |
| 208 expect(name2, isNull); |
| 209 expect(name3, isNull); |
| 210 if (annotationElement is ConstructorElement) { |
| 211 expect(annotationElement.enclosingElement, name1.staticElement); |
| 212 expect(annotationElement.displayName, ''); |
| 213 expect(annotationElement.parameters, isEmpty); |
| 214 } else { |
| 215 fail('Expected "annotationElement" is ConstructorElement, ' |
| 216 'but (${annotationElement?.runtimeType}) $annotationElement found.')
; |
| 217 } |
| 218 }); |
| 219 } |
| 220 |
| 221 void test_annotation_topLevelVariable() { |
| 222 addNamedSource( |
| 223 '/a.dart', |
| 224 r''' |
| 225 const V = 0; |
| 226 '''); |
| 227 _validateAnnotation('', '@V', (SimpleIdentifier name1, |
| 228 SimpleIdentifier name2, |
| 229 SimpleIdentifier name3, |
| 230 Element annotationElement) { |
| 231 expect(name1, isNotNull); |
| 232 expect(name1.staticElement, new isInstanceOf<PropertyAccessorElement>()); |
| 233 expect(name1.staticElement.displayName, 'V'); |
| 234 expect(name2, isNull); |
| 235 expect(name3, isNull); |
| 236 if (annotationElement is PropertyAccessorElement) { |
| 237 expect(annotationElement, same(name1.staticElement)); |
| 238 expect(annotationElement.enclosingElement, |
| 239 new isInstanceOf<CompilationUnitElement>()); |
| 240 expect(annotationElement.displayName, 'V'); |
| 241 } else { |
| 242 fail('Expected "annotationElement" is PropertyAccessorElement, ' |
| 243 'but (${annotationElement?.runtimeType}) $annotationElement found.')
; |
| 244 } |
| 245 }); |
| 246 } |
| 247 |
| 248 void test_annotation_topLevelVariable_prefixed() { |
| 249 addNamedSource( |
| 250 '/a.dart', |
| 251 r''' |
| 252 const V = 0; |
| 253 '''); |
| 254 _validateAnnotation('as p', '@p.V', (SimpleIdentifier name1, |
| 255 SimpleIdentifier name2, |
| 256 SimpleIdentifier name3, |
| 257 Element annotationElement) { |
| 258 expect(name1, isNotNull); |
| 259 expect(name1.staticElement, new isInstanceOf<PrefixElement>()); |
| 260 expect(name1.staticElement.displayName, 'p'); |
| 261 expect(name2, isNotNull); |
| 262 expect(name2.staticElement, new isInstanceOf<PropertyAccessorElement>()); |
| 263 expect(name2.staticElement.displayName, 'V'); |
| 264 expect(name3, isNull); |
| 265 if (annotationElement is PropertyAccessorElement) { |
| 266 expect(annotationElement, same(name2.staticElement)); |
| 267 expect(annotationElement.enclosingElement, |
| 268 new isInstanceOf<CompilationUnitElement>()); |
| 269 expect(annotationElement.displayName, 'V'); |
| 270 } else { |
| 271 fail('Expected "annotationElement" is PropertyAccessorElement, ' |
| 272 'but (${annotationElement?.runtimeType}) $annotationElement found.')
; |
| 273 } |
| 274 }); |
| 275 } |
| 276 |
| 277 void _validateAnnotation( |
| 278 String annotationPrefix, |
| 279 String annotationText, |
| 280 validator(SimpleIdentifier name1, SimpleIdentifier name2, |
| 281 SimpleIdentifier name3, Element annotationElement)) { |
| 282 CompilationUnit unit = resolveSource(''' |
| 283 import 'a.dart' $annotationPrefix; |
| 284 $annotationText |
| 285 class C {} |
| 286 '''); |
| 287 var clazz = unit.declarations.single as ClassDeclaration; |
| 288 Annotation annotation = clazz.metadata.single; |
| 289 Identifier name = annotation.name; |
| 290 Element annotationElement = annotation.element; |
| 291 if (name is SimpleIdentifier) { |
| 292 validator(name, null, annotation.constructorName, annotationElement); |
| 293 } else if (name is PrefixedIdentifier) { |
| 294 validator(name.prefix, name.identifier, annotation.constructorName, |
| 295 annotationElement); |
| 296 } else { |
| 297 fail('Uknown "name": ${name?.runtimeType} $name'); |
| 298 } |
| 299 } |
| 300 } |
| 301 |
| 302 @reflectiveTest |
34 class ElementResolverTest extends EngineTestCase { | 303 class ElementResolverTest extends EngineTestCase { |
35 /** | 304 /** |
36 * The error listener to which errors will be reported. | 305 * The error listener to which errors will be reported. |
37 */ | 306 */ |
38 GatheringErrorListener _listener; | 307 GatheringErrorListener _listener; |
39 | 308 |
40 /** | 309 /** |
41 * The type provider used to access the types. | 310 * The type provider used to access the types. |
42 */ | 311 */ |
43 TestTypeProvider _typeProvider; | 312 TestTypeProvider _typeProvider; |
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1008 innerScope = new LabelScope( | 1277 innerScope = new LabelScope( |
1009 outerScope, labelElement.name, labelTarget, labelElement); | 1278 outerScope, labelElement.name, labelTarget, labelElement); |
1010 } | 1279 } |
1011 _visitor.labelScope = innerScope; | 1280 _visitor.labelScope = innerScope; |
1012 statement.accept(_resolver); | 1281 statement.accept(_resolver); |
1013 } finally { | 1282 } finally { |
1014 _visitor.labelScope = outerScope; | 1283 _visitor.labelScope = outerScope; |
1015 } | 1284 } |
1016 } | 1285 } |
1017 } | 1286 } |
OLD | NEW |