| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library engine.declaration_resolver_test; | 5 library engine.declaration_resolver_test; |
| 6 | 6 |
| 7 import 'dart:async'; |
| 8 |
| 7 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 8 import 'package:analyzer/dart/element/element.dart'; | 10 import 'package:analyzer/dart/element/element.dart'; |
| 9 import 'package:analyzer/src/dart/ast/ast.dart'; | 11 import 'package:analyzer/src/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/src/dart/ast/utilities.dart'; | 12 import 'package:analyzer/src/dart/ast/utilities.dart'; |
| 11 import 'package:analyzer/src/dart/element/element.dart'; | 13 import 'package:analyzer/src/dart/element/element.dart'; |
| 12 import 'package:analyzer/src/generated/declaration_resolver.dart'; | 14 import 'package:analyzer/src/generated/declaration_resolver.dart'; |
| 13 import 'package:analyzer/src/generated/engine.dart'; | 15 import 'package:analyzer/src/generated/engine.dart'; |
| 14 import 'package:analyzer/src/generated/source.dart'; | 16 import 'package:analyzer/src/generated/source.dart'; |
| 15 import 'package:analyzer/src/task/dart.dart'; | 17 import 'package:analyzer/src/task/dart.dart'; |
| 16 import 'package:analyzer/task/dart.dart'; | 18 import 'package:analyzer/task/dart.dart'; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 expect(metadata, isNotEmpty); | 54 expect(metadata, isNotEmpty); |
| 53 for (int i = 0; i < metadata.length; i++) { | 55 for (int i = 0; i < metadata.length; i++) { |
| 54 Matcher expectation = same(metadata[i].elementAnnotation); | 56 Matcher expectation = same(metadata[i].elementAnnotation); |
| 55 if (expectDifferent) { | 57 if (expectDifferent) { |
| 56 expectation = isNot(expectation); | 58 expectation = isNot(expectation); |
| 57 } | 59 } |
| 58 expect(metadata2[i].elementAnnotation, expectation); | 60 expect(metadata2[i].elementAnnotation, expectation); |
| 59 } | 61 } |
| 60 } | 62 } |
| 61 | 63 |
| 62 void setupCode(String code) { | 64 Future<Null> setupCode(String code) async { |
| 63 this.code = code; | 65 this.code = code; |
| 64 unit = resolveSource(code + ' const a = null;'); | 66 unit = await resolveSource(code + ' const a = null;'); |
| 65 unit2 = _cloneResolveUnit(unit); | 67 unit2 = _cloneResolveUnit(unit); |
| 66 } | 68 } |
| 67 | 69 |
| 68 void test_metadata_classDeclaration() { | 70 test_metadata_classDeclaration() async { |
| 69 setupCode('@a class C {}'); | 71 await setupCode('@a class C {}'); |
| 70 checkMetadata('C'); | 72 checkMetadata('C'); |
| 71 } | 73 } |
| 72 | 74 |
| 73 void test_metadata_classTypeAlias() { | 75 test_metadata_classTypeAlias() async { |
| 74 setupCode('@a class C = D with E; class D {} class E {}'); | 76 await setupCode('@a class C = D with E; class D {} class E {}'); |
| 75 checkMetadata('C'); | 77 checkMetadata('C'); |
| 76 } | 78 } |
| 77 | 79 |
| 78 void test_metadata_constructorDeclaration_named() { | 80 test_metadata_constructorDeclaration_named() async { |
| 79 setupCode('class C { @a C.x(); }'); | 81 await setupCode('class C { @a C.x(); }'); |
| 80 checkMetadata('x'); | 82 checkMetadata('x'); |
| 81 } | 83 } |
| 82 | 84 |
| 83 void test_metadata_constructorDeclaration_unnamed() { | 85 test_metadata_constructorDeclaration_unnamed() async { |
| 84 setupCode('class C { @a C(); }'); | 86 await setupCode('class C { @a C(); }'); |
| 85 checkMetadata('C()'); | 87 checkMetadata('C()'); |
| 86 } | 88 } |
| 87 | 89 |
| 88 void test_metadata_declaredIdentifier() { | 90 test_metadata_declaredIdentifier() async { |
| 89 setupCode('f(x, y) { for (@a var x in y) {} }'); | 91 await setupCode('f(x, y) { for (@a var x in y) {} }'); |
| 90 checkMetadata('var', expectDifferent: true); | 92 checkMetadata('var', expectDifferent: true); |
| 91 } | 93 } |
| 92 | 94 |
| 93 void test_metadata_enumDeclaration() { | 95 test_metadata_enumDeclaration() async { |
| 94 setupCode('@a enum E { v }'); | 96 await setupCode('@a enum E { v }'); |
| 95 checkMetadata('E'); | 97 checkMetadata('E'); |
| 96 } | 98 } |
| 97 | 99 |
| 98 void test_metadata_exportDirective() { | 100 test_metadata_exportDirective() async { |
| 99 addNamedSource('/foo.dart', 'class C {}'); | 101 addNamedSource('/foo.dart', 'class C {}'); |
| 100 setupCode('@a export "foo.dart";'); | 102 await setupCode('@a export "foo.dart";'); |
| 101 checkMetadata('export'); | 103 checkMetadata('export'); |
| 102 } | 104 } |
| 103 | 105 |
| 104 void test_metadata_exportDirective_resynthesized() { | 106 test_metadata_exportDirective_resynthesized() async { |
| 105 CompilationUnit unit = resolveSource(r''' | 107 CompilationUnit unit = await resolveSource(r''' |
| 106 @a | 108 @a |
| 107 export "dart:async"; | 109 export "dart:async"; |
| 108 | 110 |
| 109 @b | 111 @b |
| 110 export "dart:math"; | 112 export "dart:math"; |
| 111 | 113 |
| 112 const a = null; | 114 const a = null; |
| 113 const b = null; | 115 const b = null; |
| 114 '''); | 116 '''); |
| 115 expect(unit.directives[0].metadata.single.name.name, 'a'); | 117 expect(unit.directives[0].metadata.single.name.name, 'a'); |
| 116 expect(unit.directives[1].metadata.single.name.name, 'b'); | 118 expect(unit.directives[1].metadata.single.name.name, 'b'); |
| 117 var unitElement = unit.element as CompilationUnitElementImpl; | 119 var unitElement = unit.element as CompilationUnitElementImpl; |
| 118 // Damage the unit element - as if "setAnnotations" were not called. | 120 // Damage the unit element - as if "setAnnotations" were not called. |
| 119 // The ExportElement(s) still have the metadata, we should use it. | 121 // The ExportElement(s) still have the metadata, we should use it. |
| 120 unitElement.setAnnotations(unit.directives[0].offset, []); | 122 unitElement.setAnnotations(unit.directives[0].offset, []); |
| 121 unitElement.setAnnotations(unit.directives[1].offset, []); | 123 unitElement.setAnnotations(unit.directives[1].offset, []); |
| 122 expect(unitElement.library.exports[0].metadata, hasLength(1)); | 124 expect(unitElement.library.exports[0].metadata, hasLength(1)); |
| 123 expect(unitElement.library.exports[1].metadata, hasLength(1)); | 125 expect(unitElement.library.exports[1].metadata, hasLength(1)); |
| 124 // DeclarationResolver on the clone should succeed. | 126 // DeclarationResolver on the clone should succeed. |
| 125 CompilationUnit clonedUnit = AstCloner.clone(unit); | 127 CompilationUnit clonedUnit = AstCloner.clone(unit); |
| 126 new DeclarationResolver().resolve(clonedUnit, unit.element); | 128 new DeclarationResolver().resolve(clonedUnit, unit.element); |
| 127 expect(unit.directives[0].metadata.single.name.name, 'a'); | 129 expect(unit.directives[0].metadata.single.name.name, 'a'); |
| 128 expect(unit.directives[1].metadata.single.name.name, 'b'); | 130 expect(unit.directives[1].metadata.single.name.name, 'b'); |
| 129 } | 131 } |
| 130 | 132 |
| 131 void test_metadata_fieldDeclaration() { | 133 test_metadata_fieldDeclaration() async { |
| 132 setupCode('class C { @a int x; }'); | 134 await setupCode('class C { @a int x; }'); |
| 133 checkMetadata('x'); | 135 checkMetadata('x'); |
| 134 } | 136 } |
| 135 | 137 |
| 136 void test_metadata_fieldFormalParameter() { | 138 test_metadata_fieldFormalParameter() async { |
| 137 setupCode('class C { var x; C(@a this.x); }'); | 139 await setupCode('class C { var x; C(@a this.x); }'); |
| 138 checkMetadata('this'); | 140 checkMetadata('this'); |
| 139 } | 141 } |
| 140 | 142 |
| 141 void test_metadata_fieldFormalParameter_withDefault() { | 143 test_metadata_fieldFormalParameter_withDefault() async { |
| 142 setupCode('class C { var x; C([@a this.x = null]); }'); | 144 await setupCode('class C { var x; C([@a this.x = null]); }'); |
| 143 checkMetadata('this'); | 145 checkMetadata('this'); |
| 144 } | 146 } |
| 145 | 147 |
| 146 void test_metadata_functionDeclaration_function() { | 148 test_metadata_functionDeclaration_function() async { |
| 147 setupCode('@a f() {}'); | 149 await setupCode('@a f() {}'); |
| 148 checkMetadata('f'); | 150 checkMetadata('f'); |
| 149 } | 151 } |
| 150 | 152 |
| 151 void test_metadata_functionDeclaration_getter() { | 153 test_metadata_functionDeclaration_getter() async { |
| 152 setupCode('@a get f() => null;'); | 154 await setupCode('@a get f() => null;'); |
| 153 checkMetadata('f'); | 155 checkMetadata('f'); |
| 154 } | 156 } |
| 155 | 157 |
| 156 void test_metadata_functionDeclaration_setter() { | 158 test_metadata_functionDeclaration_setter() async { |
| 157 setupCode('@a set f(value) {}'); | 159 await setupCode('@a set f(value) {}'); |
| 158 checkMetadata('f'); | 160 checkMetadata('f'); |
| 159 } | 161 } |
| 160 | 162 |
| 161 void test_metadata_functionTypeAlias() { | 163 test_metadata_functionTypeAlias() async { |
| 162 setupCode('@a typedef F();'); | 164 await setupCode('@a typedef F();'); |
| 163 checkMetadata('F'); | 165 checkMetadata('F'); |
| 164 } | 166 } |
| 165 | 167 |
| 166 void test_metadata_functionTypedFormalParameter() { | 168 test_metadata_functionTypedFormalParameter() async { |
| 167 setupCode('f(@a g()) {}'); | 169 await setupCode('f(@a g()) {}'); |
| 168 checkMetadata('g'); | 170 checkMetadata('g'); |
| 169 } | 171 } |
| 170 | 172 |
| 171 void test_metadata_functionTypedFormalParameter_withDefault() { | 173 test_metadata_functionTypedFormalParameter_withDefault() async { |
| 172 setupCode('f([@a g() = null]) {}'); | 174 await setupCode('f([@a g() = null]) {}'); |
| 173 checkMetadata('g'); | 175 checkMetadata('g'); |
| 174 } | 176 } |
| 175 | 177 |
| 176 void test_metadata_importDirective() { | 178 test_metadata_importDirective() async { |
| 177 addNamedSource('/foo.dart', 'class C {}'); | 179 addNamedSource('/foo.dart', 'class C {}'); |
| 178 setupCode('@a import "foo.dart";'); | 180 await setupCode('@a import "foo.dart";'); |
| 179 checkMetadata('import'); | 181 checkMetadata('import'); |
| 180 } | 182 } |
| 181 | 183 |
| 182 void test_metadata_importDirective_partiallyResolved() { | 184 test_metadata_importDirective_partiallyResolved() async { |
| 183 addNamedSource('/foo.dart', 'class C {}'); | 185 addNamedSource('/foo.dart', 'class C {}'); |
| 184 this.code = 'const a = null; @a import "foo.dart";'; | 186 this.code = 'const a = null; @a import "foo.dart";'; |
| 185 Source source = addNamedSource('/test.dart', code); | 187 Source source = addNamedSource('/test.dart', code); |
| 186 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); | 188 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 187 analysisContext.computeResult(source, LIBRARY_ELEMENT1); | 189 analysisContext.computeResult(source, LIBRARY_ELEMENT1); |
| 188 unit = analysisContext.computeResult(target, RESOLVED_UNIT1); | 190 unit = analysisContext.computeResult(target, RESOLVED_UNIT1); |
| 189 unit2 = _cloneResolveUnit(unit); | 191 unit2 = _cloneResolveUnit(unit); |
| 190 checkMetadata('import'); | 192 checkMetadata('import'); |
| 191 } | 193 } |
| 192 | 194 |
| 193 void test_metadata_importDirective_resynthesized() { | 195 test_metadata_importDirective_resynthesized() async { |
| 194 CompilationUnit unit = resolveSource(r''' | 196 CompilationUnit unit = await resolveSource(r''' |
| 195 @a | 197 @a |
| 196 import "dart:async"; | 198 import "dart:async"; |
| 197 | 199 |
| 198 @b | 200 @b |
| 199 import "dart:math"; | 201 import "dart:math"; |
| 200 | 202 |
| 201 const a = null; | 203 const a = null; |
| 202 const b = null; | 204 const b = null; |
| 203 '''); | 205 '''); |
| 204 expect(unit.directives[0].metadata.single.name.name, 'a'); | 206 expect(unit.directives[0].metadata.single.name.name, 'a'); |
| 205 expect(unit.directives[1].metadata.single.name.name, 'b'); | 207 expect(unit.directives[1].metadata.single.name.name, 'b'); |
| 206 var unitElement = unit.element as CompilationUnitElementImpl; | 208 var unitElement = unit.element as CompilationUnitElementImpl; |
| 207 // Damage the unit element - as if "setAnnotations" were not called. | 209 // Damage the unit element - as if "setAnnotations" were not called. |
| 208 // The ImportElement(s) still have the metadata, we should use it. | 210 // The ImportElement(s) still have the metadata, we should use it. |
| 209 unitElement.setAnnotations(unit.directives[0].offset, []); | 211 unitElement.setAnnotations(unit.directives[0].offset, []); |
| 210 unitElement.setAnnotations(unit.directives[1].offset, []); | 212 unitElement.setAnnotations(unit.directives[1].offset, []); |
| 211 expect(unitElement.library.imports[0].metadata, hasLength(1)); | 213 expect(unitElement.library.imports[0].metadata, hasLength(1)); |
| 212 expect(unitElement.library.imports[1].metadata, hasLength(1)); | 214 expect(unitElement.library.imports[1].metadata, hasLength(1)); |
| 213 // DeclarationResolver on the clone should succeed. | 215 // DeclarationResolver on the clone should succeed. |
| 214 CompilationUnit clonedUnit = AstCloner.clone(unit); | 216 CompilationUnit clonedUnit = AstCloner.clone(unit); |
| 215 new DeclarationResolver().resolve(clonedUnit, unit.element); | 217 new DeclarationResolver().resolve(clonedUnit, unit.element); |
| 216 expect(unit.directives[0].metadata.single.name.name, 'a'); | 218 expect(unit.directives[0].metadata.single.name.name, 'a'); |
| 217 expect(unit.directives[1].metadata.single.name.name, 'b'); | 219 expect(unit.directives[1].metadata.single.name.name, 'b'); |
| 218 } | 220 } |
| 219 | 221 |
| 220 void test_metadata_libraryDirective() { | 222 test_metadata_libraryDirective() async { |
| 221 setupCode('@a library L;'); | 223 await setupCode('@a library L;'); |
| 222 checkMetadata('L'); | 224 checkMetadata('L'); |
| 223 } | 225 } |
| 224 | 226 |
| 225 void test_metadata_libraryDirective_resynthesized() { | 227 test_metadata_libraryDirective_resynthesized() async { |
| 226 CompilationUnit unit = resolveSource('@a library L; const a = null;'); | 228 CompilationUnit unit = |
| 229 await resolveSource('@a library L; const a = null;'); |
| 227 expect(unit.directives.single.metadata.single.name.name, 'a'); | 230 expect(unit.directives.single.metadata.single.name.name, 'a'); |
| 228 var unitElement = unit.element as CompilationUnitElementImpl; | 231 var unitElement = unit.element as CompilationUnitElementImpl; |
| 229 // Damage the unit element - as if "setAnnotations" were not called. | 232 // Damage the unit element - as if "setAnnotations" were not called. |
| 230 // The LibraryElement still has the metadata, we should use it. | 233 // The LibraryElement still has the metadata, we should use it. |
| 231 unitElement.setAnnotations(unit.directives.single.offset, []); | 234 unitElement.setAnnotations(unit.directives.single.offset, []); |
| 232 expect(unitElement.library.metadata, hasLength(1)); | 235 expect(unitElement.library.metadata, hasLength(1)); |
| 233 // DeclarationResolver on the clone should succeed. | 236 // DeclarationResolver on the clone should succeed. |
| 234 CompilationUnit clonedUnit = AstCloner.clone(unit); | 237 CompilationUnit clonedUnit = AstCloner.clone(unit); |
| 235 new DeclarationResolver().resolve(clonedUnit, unit.element); | 238 new DeclarationResolver().resolve(clonedUnit, unit.element); |
| 236 expect(clonedUnit.directives.single.metadata.single.name.name, 'a'); | 239 expect(clonedUnit.directives.single.metadata.single.name.name, 'a'); |
| 237 } | 240 } |
| 238 | 241 |
| 239 void test_metadata_localFunctionDeclaration() { | 242 test_metadata_localFunctionDeclaration() async { |
| 240 setupCode('f() { @a g() {} }'); | 243 await setupCode('f() { @a g() {} }'); |
| 241 // Note: metadata on local function declarations is ignored by the | 244 // Note: metadata on local function declarations is ignored by the |
| 242 // analyzer. TODO(paulberry): is this a bug? | 245 // analyzer. TODO(paulberry): is this a bug? |
| 243 FunctionDeclaration node = EngineTestCase.findNode( | 246 FunctionDeclaration node = EngineTestCase.findNode( |
| 244 unit, code, 'g', (AstNode n) => n is FunctionDeclaration); | 247 unit, code, 'g', (AstNode n) => n is FunctionDeclaration); |
| 245 expect((node as FunctionDeclarationImpl).metadata, isEmpty); | 248 expect((node as FunctionDeclarationImpl).metadata, isEmpty); |
| 246 } | 249 } |
| 247 | 250 |
| 248 void test_metadata_localVariableDeclaration() { | 251 test_metadata_localVariableDeclaration() async { |
| 249 setupCode('f() { @a int x; }'); | 252 await setupCode('f() { @a int x; }'); |
| 250 checkMetadata('x', expectDifferent: true); | 253 checkMetadata('x', expectDifferent: true); |
| 251 } | 254 } |
| 252 | 255 |
| 253 void test_metadata_methodDeclaration_getter() { | 256 test_metadata_methodDeclaration_getter() async { |
| 254 setupCode('class C { @a get m => null; }'); | 257 await setupCode('class C { @a get m => null; }'); |
| 255 checkMetadata('m'); | 258 checkMetadata('m'); |
| 256 } | 259 } |
| 257 | 260 |
| 258 void test_metadata_methodDeclaration_method() { | 261 test_metadata_methodDeclaration_method() async { |
| 259 setupCode('class C { @a m() {} }'); | 262 await setupCode('class C { @a m() {} }'); |
| 260 checkMetadata('m'); | 263 checkMetadata('m'); |
| 261 } | 264 } |
| 262 | 265 |
| 263 void test_metadata_methodDeclaration_setter() { | 266 test_metadata_methodDeclaration_setter() async { |
| 264 setupCode('class C { @a set m(value) {} }'); | 267 await setupCode('class C { @a set m(value) {} }'); |
| 265 checkMetadata('m'); | 268 checkMetadata('m'); |
| 266 } | 269 } |
| 267 | 270 |
| 268 void test_metadata_partDirective() { | 271 test_metadata_partDirective() async { |
| 269 addNamedSource('/foo.dart', 'part of L;'); | 272 addNamedSource('/foo.dart', 'part of L;'); |
| 270 setupCode('library L; @a part "foo.dart";'); | 273 await setupCode('library L; @a part "foo.dart";'); |
| 271 checkMetadata('part'); | 274 checkMetadata('part'); |
| 272 } | 275 } |
| 273 | 276 |
| 274 void test_metadata_simpleFormalParameter() { | 277 test_metadata_simpleFormalParameter() async { |
| 275 setupCode('f(@a x) {}) {}'); | 278 await setupCode('f(@a x) {}) {}'); |
| 276 checkMetadata('x'); | 279 checkMetadata('x'); |
| 277 } | 280 } |
| 278 | 281 |
| 279 void test_metadata_simpleFormalParameter_withDefault() { | 282 test_metadata_simpleFormalParameter_withDefault() async { |
| 280 setupCode('f([@a x = null]) {}'); | 283 await setupCode('f([@a x = null]) {}'); |
| 281 checkMetadata('x'); | 284 checkMetadata('x'); |
| 282 } | 285 } |
| 283 | 286 |
| 284 void test_metadata_topLevelVariableDeclaration() { | 287 test_metadata_topLevelVariableDeclaration() async { |
| 285 setupCode('@a int x;'); | 288 await setupCode('@a int x;'); |
| 286 checkMetadata('x'); | 289 checkMetadata('x'); |
| 287 } | 290 } |
| 288 | 291 |
| 289 void test_metadata_typeParameter_ofClass() { | 292 test_metadata_typeParameter_ofClass() async { |
| 290 setupCode('class C<@a T> {}'); | 293 await setupCode('class C<@a T> {}'); |
| 291 checkMetadata('T'); | 294 checkMetadata('T'); |
| 292 } | 295 } |
| 293 | 296 |
| 294 void test_metadata_typeParameter_ofClassTypeAlias() { | 297 test_metadata_typeParameter_ofClassTypeAlias() async { |
| 295 setupCode('class C<@a T> = D with E; class D {} class E {}'); | 298 await setupCode('class C<@a T> = D with E; class D {} class E {}'); |
| 296 checkMetadata('T'); | 299 checkMetadata('T'); |
| 297 } | 300 } |
| 298 | 301 |
| 299 void test_metadata_typeParameter_ofFunction() { | 302 test_metadata_typeParameter_ofFunction() async { |
| 300 setupCode('f<@a T>() {}'); | 303 await setupCode('f<@a T>() {}'); |
| 301 checkMetadata('T'); | 304 checkMetadata('T'); |
| 302 } | 305 } |
| 303 | 306 |
| 304 void test_metadata_typeParameter_ofTypedef() { | 307 test_metadata_typeParameter_ofTypedef() async { |
| 305 setupCode('typedef F<@a T>();'); | 308 await setupCode('typedef F<@a T>();'); |
| 306 checkMetadata('T'); | 309 checkMetadata('T'); |
| 307 } | 310 } |
| 308 | 311 |
| 309 NodeList<Annotation> _findMetadata(CompilationUnit unit, String search) { | 312 NodeList<Annotation> _findMetadata(CompilationUnit unit, String search) { |
| 310 AstNode node = | 313 AstNode node = |
| 311 EngineTestCase.findNode(unit, code, search, (AstNode _) => true); | 314 EngineTestCase.findNode(unit, code, search, (AstNode _) => true); |
| 312 while (node != null) { | 315 while (node != null) { |
| 313 if (node is AnnotatedNode && node.metadata.isNotEmpty) { | 316 if (node is AnnotatedNode && node.metadata.isNotEmpty) { |
| 314 return node.metadata; | 317 return node.metadata; |
| 315 } | 318 } |
| 316 if (node is NormalFormalParameter && node.metadata.isNotEmpty) { | 319 if (node is NormalFormalParameter && node.metadata.isNotEmpty) { |
| 317 return node.metadata; | 320 return node.metadata; |
| 318 } | 321 } |
| 319 node = node.parent; | 322 node = node.parent; |
| 320 } | 323 } |
| 321 fail('Node not found'); | 324 fail('Node not found'); |
| 322 return null; | 325 return null; |
| 323 } | 326 } |
| 324 } | 327 } |
| 325 | 328 |
| 326 @reflectiveTest | 329 @reflectiveTest |
| 327 class DeclarationResolverTest extends ResolverTestCase { | 330 class DeclarationResolverTest extends ResolverTestCase { |
| 328 @override | 331 @override |
| 329 void setUp() { | 332 void setUp() { |
| 330 super.setUp(); | 333 super.setUp(); |
| 331 } | 334 } |
| 332 | 335 |
| 333 void test_closure_inside_catch_block() { | 336 test_closure_inside_catch_block() async { |
| 334 String code = ''' | 337 String code = ''' |
| 335 f() { | 338 f() { |
| 336 try { | 339 try { |
| 337 } catch (e) { | 340 } catch (e) { |
| 338 return () => null; | 341 return () => null; |
| 339 } | 342 } |
| 340 } | 343 } |
| 341 '''; | 344 '''; |
| 342 CompilationUnit unit = resolveSource(code); | 345 CompilationUnit unit = await resolveSource(code); |
| 343 // re-resolve | 346 // re-resolve |
| 344 _cloneResolveUnit(unit); | 347 _cloneResolveUnit(unit); |
| 345 // no other validations than built into DeclarationResolver | 348 // no other validations than built into DeclarationResolver |
| 346 } | 349 } |
| 347 | 350 |
| 348 void test_closure_inside_labeled_statement() { | 351 test_closure_inside_labeled_statement() async { |
| 349 String code = ''' | 352 String code = ''' |
| 350 f(b) { | 353 f(b) { |
| 351 foo: while (true) { | 354 foo: while (true) { |
| 352 if (b) { | 355 if (b) { |
| 353 break foo; | 356 break foo; |
| 354 } | 357 } |
| 355 return () => null; | 358 return () => null; |
| 356 } | 359 } |
| 357 } | 360 } |
| 358 '''; | 361 '''; |
| 359 CompilationUnit unit = resolveSource(code); | 362 CompilationUnit unit = await resolveSource(code); |
| 360 // re-resolve | 363 // re-resolve |
| 361 _cloneResolveUnit(unit); | 364 _cloneResolveUnit(unit); |
| 362 // no other validations than built into DeclarationResolver | 365 // no other validations than built into DeclarationResolver |
| 363 } | 366 } |
| 364 | 367 |
| 365 void test_closure_inside_switch_case() { | 368 test_closure_inside_switch_case() async { |
| 366 String code = ''' | 369 String code = ''' |
| 367 void f(k, m) { | 370 void f(k, m) { |
| 368 switch (k) { | 371 switch (k) { |
| 369 case 0: | 372 case 0: |
| 370 m.forEach((key, value) {}); | 373 m.forEach((key, value) {}); |
| 371 break; | 374 break; |
| 372 } | 375 } |
| 373 } | 376 } |
| 374 '''; | 377 '''; |
| 375 CompilationUnit unit = resolveSource(code); | 378 CompilationUnit unit = await resolveSource(code); |
| 376 // re-resolve | 379 // re-resolve |
| 377 _cloneResolveUnit(unit); | 380 _cloneResolveUnit(unit); |
| 378 // no other validations than built into DeclarationResolver | 381 // no other validations than built into DeclarationResolver |
| 379 } | 382 } |
| 380 | 383 |
| 381 void test_closure_inside_switch_default() { | 384 test_closure_inside_switch_default() async { |
| 382 String code = ''' | 385 String code = ''' |
| 383 void f(k, m) { | 386 void f(k, m) { |
| 384 switch (k) { | 387 switch (k) { |
| 385 default: | 388 default: |
| 386 m.forEach((key, value) {}); | 389 m.forEach((key, value) {}); |
| 387 break; | 390 break; |
| 388 } | 391 } |
| 389 } | 392 } |
| 390 '''; | 393 '''; |
| 391 CompilationUnit unit = resolveSource(code); | 394 CompilationUnit unit = await resolveSource(code); |
| 392 // re-resolve | 395 // re-resolve |
| 393 _cloneResolveUnit(unit); | 396 _cloneResolveUnit(unit); |
| 394 // no other validations than built into DeclarationResolver | 397 // no other validations than built into DeclarationResolver |
| 395 } | 398 } |
| 396 | 399 |
| 397 void test_enumConstant_partiallyResolved() { | 400 test_enumConstant_partiallyResolved() async { |
| 398 String code = r''' | 401 String code = r''' |
| 399 enum Fruit {apple, pear} | 402 enum Fruit {apple, pear} |
| 400 '''; | 403 '''; |
| 401 Source source = addNamedSource('/test.dart', code); | 404 Source source = addNamedSource('/test.dart', code); |
| 402 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); | 405 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 403 analysisContext.computeResult(source, LIBRARY_ELEMENT1); | 406 analysisContext.computeResult(source, LIBRARY_ELEMENT1); |
| 404 CompilationUnit unit = | 407 CompilationUnit unit = |
| 405 analysisContext.computeResult(target, RESOLVED_UNIT1); | 408 analysisContext.computeResult(target, RESOLVED_UNIT1); |
| 406 _cloneResolveUnit(unit); | 409 _cloneResolveUnit(unit); |
| 407 } | 410 } |
| 408 | 411 |
| 409 void test_functionDeclaration_getter() { | 412 test_functionDeclaration_getter() async { |
| 410 String code = r''' | 413 String code = r''' |
| 411 int get zzz => 42; | 414 int get zzz => 42; |
| 412 '''; | 415 '''; |
| 413 CompilationUnit unit = resolveSource(code); | 416 CompilationUnit unit = await resolveSource(code); |
| 414 PropertyAccessorElement getterElement = | 417 PropertyAccessorElement getterElement = |
| 415 _findSimpleIdentifier(unit, code, 'zzz =>').staticElement; | 418 _findSimpleIdentifier(unit, code, 'zzz =>').staticElement; |
| 416 expect(getterElement.isGetter, isTrue); | 419 expect(getterElement.isGetter, isTrue); |
| 417 // re-resolve | 420 // re-resolve |
| 418 CompilationUnit unit2 = _cloneResolveUnit(unit); | 421 CompilationUnit unit2 = _cloneResolveUnit(unit); |
| 419 SimpleIdentifier getterName = _findSimpleIdentifier(unit2, code, 'zzz =>'); | 422 SimpleIdentifier getterName = _findSimpleIdentifier(unit2, code, 'zzz =>'); |
| 420 expect(getterName.staticElement, same(getterElement)); | 423 expect(getterName.staticElement, same(getterElement)); |
| 421 } | 424 } |
| 422 | 425 |
| 423 void test_functionDeclaration_setter() { | 426 test_functionDeclaration_setter() async { |
| 424 String code = r''' | 427 String code = r''' |
| 425 void set zzz(_) {} | 428 void set zzz(_) {} |
| 426 '''; | 429 '''; |
| 427 CompilationUnit unit = resolveSource(code); | 430 CompilationUnit unit = await resolveSource(code); |
| 428 PropertyAccessorElement setterElement = | 431 PropertyAccessorElement setterElement = |
| 429 _findSimpleIdentifier(unit, code, 'zzz(_)').staticElement; | 432 _findSimpleIdentifier(unit, code, 'zzz(_)').staticElement; |
| 430 expect(setterElement.isSetter, isTrue); | 433 expect(setterElement.isSetter, isTrue); |
| 431 // re-resolve | 434 // re-resolve |
| 432 CompilationUnit unit2 = _cloneResolveUnit(unit); | 435 CompilationUnit unit2 = _cloneResolveUnit(unit); |
| 433 SimpleIdentifier getterName = _findSimpleIdentifier(unit2, code, 'zzz(_)'); | 436 SimpleIdentifier getterName = _findSimpleIdentifier(unit2, code, 'zzz(_)'); |
| 434 expect(getterName.staticElement, same(setterElement)); | 437 expect(getterName.staticElement, same(setterElement)); |
| 435 } | 438 } |
| 436 | 439 |
| 437 void test_invalid_functionDeclaration_getter_inFunction() { | 440 test_invalid_functionDeclaration_getter_inFunction() async { |
| 438 String code = r''' | 441 String code = r''' |
| 439 var v = (() { | 442 var v = (() { |
| 440 main() { | 443 main() { |
| 441 int get zzz => 42; | 444 int get zzz => 42; |
| 442 } | 445 } |
| 443 }); | 446 }); |
| 444 '''; | 447 '''; |
| 445 CompilationUnit unit = resolveSource(code); | 448 CompilationUnit unit = await resolveSource(code); |
| 446 FunctionElement getterElement = | 449 FunctionElement getterElement = |
| 447 _findSimpleIdentifier(unit, code, 'zzz =>').staticElement; | 450 _findSimpleIdentifier(unit, code, 'zzz =>').staticElement; |
| 448 // re-resolve | 451 // re-resolve |
| 449 CompilationUnit unit2 = _cloneResolveUnit(unit); | 452 CompilationUnit unit2 = _cloneResolveUnit(unit); |
| 450 SimpleIdentifier getterName = _findSimpleIdentifier(unit2, code, 'zzz =>'); | 453 SimpleIdentifier getterName = _findSimpleIdentifier(unit2, code, 'zzz =>'); |
| 451 expect(getterName.staticElement, same(getterElement)); | 454 expect(getterName.staticElement, same(getterElement)); |
| 452 } | 455 } |
| 453 | 456 |
| 454 void test_invalid_functionDeclaration_setter_inFunction() { | 457 test_invalid_functionDeclaration_setter_inFunction() async { |
| 455 String code = r''' | 458 String code = r''' |
| 456 var v = (() { | 459 var v = (() { |
| 457 main() { | 460 main() { |
| 458 set zzz(x) {} | 461 set zzz(x) {} |
| 459 } | 462 } |
| 460 }); | 463 }); |
| 461 '''; | 464 '''; |
| 462 CompilationUnit unit = resolveSource(code); | 465 CompilationUnit unit = await resolveSource(code); |
| 463 FunctionElement setterElement = | 466 FunctionElement setterElement = |
| 464 _findSimpleIdentifier(unit, code, 'zzz(x)').staticElement; | 467 _findSimpleIdentifier(unit, code, 'zzz(x)').staticElement; |
| 465 // re-resolve | 468 // re-resolve |
| 466 CompilationUnit unit2 = _cloneResolveUnit(unit); | 469 CompilationUnit unit2 = _cloneResolveUnit(unit); |
| 467 SimpleIdentifier setterName = _findSimpleIdentifier(unit2, code, 'zzz(x)'); | 470 SimpleIdentifier setterName = _findSimpleIdentifier(unit2, code, 'zzz(x)'); |
| 468 expect(setterName.staticElement, same(setterElement)); | 471 expect(setterName.staticElement, same(setterElement)); |
| 469 } | 472 } |
| 470 | 473 |
| 471 void test_visitExportDirective_notExistingSource() { | 474 test_visitExportDirective_notExistingSource() async { |
| 472 String code = r''' | 475 String code = r''' |
| 473 export 'foo.dart'; | 476 export 'foo.dart'; |
| 474 '''; | 477 '''; |
| 475 CompilationUnit unit = resolveSource(code); | 478 CompilationUnit unit = await resolveSource(code); |
| 476 // re-resolve | 479 // re-resolve |
| 477 _cloneResolveUnit(unit); | 480 _cloneResolveUnit(unit); |
| 478 // no other validations than built into DeclarationResolver | 481 // no other validations than built into DeclarationResolver |
| 479 } | 482 } |
| 480 | 483 |
| 481 void test_visitExportDirective_unresolvedUri() { | 484 test_visitExportDirective_unresolvedUri() async { |
| 482 String code = r''' | 485 String code = r''' |
| 483 export 'package:foo/bar.dart'; | 486 export 'package:foo/bar.dart'; |
| 484 '''; | 487 '''; |
| 485 CompilationUnit unit = resolveSource(code); | 488 CompilationUnit unit = await resolveSource(code); |
| 486 // re-resolve | 489 // re-resolve |
| 487 _cloneResolveUnit(unit); | 490 _cloneResolveUnit(unit); |
| 488 // no other validations than built into DeclarationResolver | 491 // no other validations than built into DeclarationResolver |
| 489 } | 492 } |
| 490 | 493 |
| 491 void test_visitFunctionExpression() { | 494 test_visitFunctionExpression() async { |
| 492 String code = r''' | 495 String code = r''' |
| 493 main(List<String> items) { | 496 main(List<String> items) { |
| 494 items.forEach((item) {}); | 497 items.forEach((item) {}); |
| 495 } | 498 } |
| 496 '''; | 499 '''; |
| 497 CompilationUnit unit = resolveSource(code); | 500 CompilationUnit unit = await resolveSource(code); |
| 498 // re-resolve | 501 // re-resolve |
| 499 _cloneResolveUnit(unit); | 502 _cloneResolveUnit(unit); |
| 500 // no other validations than built into DeclarationResolver | 503 // no other validations than built into DeclarationResolver |
| 501 } | 504 } |
| 502 | 505 |
| 503 void test_visitImportDirective_notExistingSource() { | 506 test_visitImportDirective_notExistingSource() async { |
| 504 String code = r''' | 507 String code = r''' |
| 505 import 'foo.dart'; | 508 import 'foo.dart'; |
| 506 '''; | 509 '''; |
| 507 CompilationUnit unit = resolveSource(code); | 510 CompilationUnit unit = await resolveSource(code); |
| 508 // re-resolve | 511 // re-resolve |
| 509 _cloneResolveUnit(unit); | 512 _cloneResolveUnit(unit); |
| 510 // no other validations than built into DeclarationResolver | 513 // no other validations than built into DeclarationResolver |
| 511 } | 514 } |
| 512 | 515 |
| 513 void test_visitImportDirective_unresolvedUri() { | 516 test_visitImportDirective_unresolvedUri() async { |
| 514 String code = r''' | 517 String code = r''' |
| 515 import 'package:foo/bar.dart'; | 518 import 'package:foo/bar.dart'; |
| 516 '''; | 519 '''; |
| 517 CompilationUnit unit = resolveSource(code); | 520 CompilationUnit unit = await resolveSource(code); |
| 518 // re-resolve | 521 // re-resolve |
| 519 _cloneResolveUnit(unit); | 522 _cloneResolveUnit(unit); |
| 520 // no other validations than built into DeclarationResolver | 523 // no other validations than built into DeclarationResolver |
| 521 } | 524 } |
| 522 | 525 |
| 523 void test_visitMethodDeclaration_getter_duplicate() { | 526 test_visitMethodDeclaration_getter_duplicate() async { |
| 524 String code = r''' | 527 String code = r''' |
| 525 class C { | 528 class C { |
| 526 int get zzz => 1; | 529 int get zzz => 1; |
| 527 String get zzz => null; | 530 String get zzz => null; |
| 528 } | 531 } |
| 529 '''; | 532 '''; |
| 530 CompilationUnit unit = resolveSource(code); | 533 CompilationUnit unit = await resolveSource(code); |
| 531 PropertyAccessorElement firstElement = | 534 PropertyAccessorElement firstElement = |
| 532 _findSimpleIdentifier(unit, code, 'zzz => 1').staticElement; | 535 _findSimpleIdentifier(unit, code, 'zzz => 1').staticElement; |
| 533 PropertyAccessorElement secondElement = | 536 PropertyAccessorElement secondElement = |
| 534 _findSimpleIdentifier(unit, code, 'zzz => null').staticElement; | 537 _findSimpleIdentifier(unit, code, 'zzz => null').staticElement; |
| 535 // re-resolve | 538 // re-resolve |
| 536 CompilationUnit unit2 = _cloneResolveUnit(unit); | 539 CompilationUnit unit2 = _cloneResolveUnit(unit); |
| 537 SimpleIdentifier firstName = _findSimpleIdentifier(unit2, code, 'zzz => 1'); | 540 SimpleIdentifier firstName = _findSimpleIdentifier(unit2, code, 'zzz => 1'); |
| 538 SimpleIdentifier secondName = | 541 SimpleIdentifier secondName = |
| 539 _findSimpleIdentifier(unit2, code, 'zzz => null'); | 542 _findSimpleIdentifier(unit2, code, 'zzz => null'); |
| 540 expect(firstName.staticElement, same(firstElement)); | 543 expect(firstName.staticElement, same(firstElement)); |
| 541 expect(secondName.staticElement, same(secondElement)); | 544 expect(secondName.staticElement, same(secondElement)); |
| 542 } | 545 } |
| 543 | 546 |
| 544 void test_visitMethodDeclaration_getterSetter() { | 547 test_visitMethodDeclaration_getterSetter() async { |
| 545 String code = r''' | 548 String code = r''' |
| 546 class C { | 549 class C { |
| 547 int _field = 0; | 550 int _field = 0; |
| 548 int get field => _field; | 551 int get field => _field; |
| 549 void set field(value) {_field = value;} | 552 void set field(value) {_field = value;} |
| 550 } | 553 } |
| 551 '''; | 554 '''; |
| 552 CompilationUnit unit = resolveSource(code); | 555 CompilationUnit unit = await resolveSource(code); |
| 553 FieldElement getterElement = | 556 FieldElement getterElement = |
| 554 _findSimpleIdentifier(unit, code, 'field =').staticElement; | 557 _findSimpleIdentifier(unit, code, 'field =').staticElement; |
| 555 PropertyAccessorElement setterElement = | 558 PropertyAccessorElement setterElement = |
| 556 _findSimpleIdentifier(unit, code, 'field(').staticElement; | 559 _findSimpleIdentifier(unit, code, 'field(').staticElement; |
| 557 // re-resolve | 560 // re-resolve |
| 558 CompilationUnit unit2 = _cloneResolveUnit(unit); | 561 CompilationUnit unit2 = _cloneResolveUnit(unit); |
| 559 SimpleIdentifier getterName = _findSimpleIdentifier(unit2, code, 'field ='); | 562 SimpleIdentifier getterName = _findSimpleIdentifier(unit2, code, 'field ='); |
| 560 SimpleIdentifier setterName = _findSimpleIdentifier(unit2, code, 'field('); | 563 SimpleIdentifier setterName = _findSimpleIdentifier(unit2, code, 'field('); |
| 561 expect(getterName.staticElement, same(getterElement)); | 564 expect(getterName.staticElement, same(getterElement)); |
| 562 expect(setterName.staticElement, same(setterElement)); | 565 expect(setterName.staticElement, same(setterElement)); |
| 563 } | 566 } |
| 564 | 567 |
| 565 void test_visitMethodDeclaration_method_duplicate() { | 568 test_visitMethodDeclaration_method_duplicate() async { |
| 566 String code = r''' | 569 String code = r''' |
| 567 class C { | 570 class C { |
| 568 void zzz(x) {} | 571 void zzz(x) {} |
| 569 void zzz(y) {} | 572 void zzz(y) {} |
| 570 } | 573 } |
| 571 '''; | 574 '''; |
| 572 CompilationUnit unit = resolveSource(code); | 575 CompilationUnit unit = await resolveSource(code); |
| 573 MethodElement firstElement = | 576 MethodElement firstElement = |
| 574 _findSimpleIdentifier(unit, code, 'zzz(x)').staticElement; | 577 _findSimpleIdentifier(unit, code, 'zzz(x)').staticElement; |
| 575 MethodElement secondElement = | 578 MethodElement secondElement = |
| 576 _findSimpleIdentifier(unit, code, 'zzz(y)').staticElement; | 579 _findSimpleIdentifier(unit, code, 'zzz(y)').staticElement; |
| 577 // re-resolve | 580 // re-resolve |
| 578 CompilationUnit unit2 = _cloneResolveUnit(unit); | 581 CompilationUnit unit2 = _cloneResolveUnit(unit); |
| 579 SimpleIdentifier firstName = _findSimpleIdentifier(unit2, code, 'zzz(x)'); | 582 SimpleIdentifier firstName = _findSimpleIdentifier(unit2, code, 'zzz(x)'); |
| 580 SimpleIdentifier secondName = _findSimpleIdentifier(unit2, code, 'zzz(y)'); | 583 SimpleIdentifier secondName = _findSimpleIdentifier(unit2, code, 'zzz(y)'); |
| 581 expect(firstName.staticElement, same(firstElement)); | 584 expect(firstName.staticElement, same(firstElement)); |
| 582 expect(secondName.staticElement, same(secondElement)); | 585 expect(secondName.staticElement, same(secondElement)); |
| 583 } | 586 } |
| 584 | 587 |
| 585 void test_visitMethodDeclaration_setter_duplicate() { | 588 test_visitMethodDeclaration_setter_duplicate() async { |
| 586 // https://github.com/dart-lang/sdk/issues/25601 | 589 // https://github.com/dart-lang/sdk/issues/25601 |
| 587 String code = r''' | 590 String code = r''' |
| 588 class C { | 591 class C { |
| 589 set zzz(x) {} | 592 set zzz(x) {} |
| 590 set zzz(y) {} | 593 set zzz(y) {} |
| 591 } | 594 } |
| 592 '''; | 595 '''; |
| 593 CompilationUnit unit = resolveSource(code); | 596 CompilationUnit unit = await resolveSource(code); |
| 594 PropertyAccessorElement firstElement = | 597 PropertyAccessorElement firstElement = |
| 595 _findSimpleIdentifier(unit, code, 'zzz(x)').staticElement; | 598 _findSimpleIdentifier(unit, code, 'zzz(x)').staticElement; |
| 596 PropertyAccessorElement secondElement = | 599 PropertyAccessorElement secondElement = |
| 597 _findSimpleIdentifier(unit, code, 'zzz(y)').staticElement; | 600 _findSimpleIdentifier(unit, code, 'zzz(y)').staticElement; |
| 598 // re-resolve | 601 // re-resolve |
| 599 CompilationUnit unit2 = _cloneResolveUnit(unit); | 602 CompilationUnit unit2 = _cloneResolveUnit(unit); |
| 600 SimpleIdentifier firstName = _findSimpleIdentifier(unit2, code, 'zzz(x)'); | 603 SimpleIdentifier firstName = _findSimpleIdentifier(unit2, code, 'zzz(x)'); |
| 601 SimpleIdentifier secondName = _findSimpleIdentifier(unit2, code, 'zzz(y)'); | 604 SimpleIdentifier secondName = _findSimpleIdentifier(unit2, code, 'zzz(y)'); |
| 602 expect(firstName.staticElement, same(firstElement)); | 605 expect(firstName.staticElement, same(firstElement)); |
| 603 expect(secondName.staticElement, same(secondElement)); | 606 expect(secondName.staticElement, same(secondElement)); |
| 604 } | 607 } |
| 605 | 608 |
| 606 void test_visitMethodDeclaration_unaryMinus() { | 609 test_visitMethodDeclaration_unaryMinus() async { |
| 607 String code = r''' | 610 String code = r''' |
| 608 class C { | 611 class C { |
| 609 C operator -() => null; | 612 C operator -() => null; |
| 610 C operator -(C other) => null; | 613 C operator -(C other) => null; |
| 611 } | 614 } |
| 612 '''; | 615 '''; |
| 613 CompilationUnit unit = resolveSource(code); | 616 CompilationUnit unit = await resolveSource(code); |
| 614 // re-resolve | 617 // re-resolve |
| 615 _cloneResolveUnit(unit); | 618 _cloneResolveUnit(unit); |
| 616 // no other validations than built into DeclarationResolver | 619 // no other validations than built into DeclarationResolver |
| 617 } | 620 } |
| 618 | 621 |
| 619 void test_visitPartDirective_notExistingSource() { | 622 test_visitPartDirective_notExistingSource() async { |
| 620 String code = r''' | 623 String code = r''' |
| 621 part 'foo.bar'; | 624 part 'foo.bar'; |
| 622 '''; | 625 '''; |
| 623 CompilationUnit unit = resolveSource(code); | 626 CompilationUnit unit = await resolveSource(code); |
| 624 // re-resolve | 627 // re-resolve |
| 625 _cloneResolveUnit(unit); | 628 _cloneResolveUnit(unit); |
| 626 // no other validations than built into DeclarationResolver | 629 // no other validations than built into DeclarationResolver |
| 627 } | 630 } |
| 628 } | 631 } |
| 629 | 632 |
| 630 /** | 633 /** |
| 631 * Strong mode DeclarationResolver tests | 634 * Strong mode DeclarationResolver tests |
| 632 */ | 635 */ |
| 633 @reflectiveTest | 636 @reflectiveTest |
| 634 class StrongModeDeclarationResolverTest extends ResolverTestCase { | 637 class StrongModeDeclarationResolverTest extends ResolverTestCase { |
| 635 @override | 638 @override |
| 636 void setUp() { | 639 void setUp() { |
| 637 resetWith(options: new AnalysisOptionsImpl()..strongMode = true); | 640 resetWith(options: new AnalysisOptionsImpl()..strongMode = true); |
| 638 } | 641 } |
| 639 | 642 |
| 640 void test_genericFunction_typeParameter() { | 643 test_genericFunction_typeParameter() async { |
| 641 String code = r''' | 644 String code = r''' |
| 642 /*=T*/ max/*<T>*/(/*=T*/ x, /*=T*/ y) => null; | 645 /*=T*/ max/*<T>*/(/*=T*/ x, /*=T*/ y) => null; |
| 643 '''; | 646 '''; |
| 644 CompilationUnit unit = resolveSource(code); | 647 CompilationUnit unit = await resolveSource(code); |
| 645 FunctionDeclaration node = _findSimpleIdentifier(unit, code, 'max').parent; | 648 FunctionDeclaration node = _findSimpleIdentifier(unit, code, 'max').parent; |
| 646 TypeParameter t = node.functionExpression.typeParameters.typeParameters[0]; | 649 TypeParameter t = node.functionExpression.typeParameters.typeParameters[0]; |
| 647 | 650 |
| 648 FunctionElement element = node.name.staticElement; | 651 FunctionElement element = node.name.staticElement; |
| 649 TypeParameterElement tElement = element.typeParameters[0]; | 652 TypeParameterElement tElement = element.typeParameters[0]; |
| 650 expect(tElement, isNotNull); | 653 expect(tElement, isNotNull); |
| 651 expect(element.typeParameters.toString(), "[T]"); | 654 expect(element.typeParameters.toString(), "[T]"); |
| 652 expect(element.type.toString(), "<T>(T, T) → T"); | 655 expect(element.type.toString(), "<T>(T, T) → T"); |
| 653 expect(t.element, same(tElement)); | 656 expect(t.element, same(tElement)); |
| 654 | 657 |
| 655 // re-resolve | 658 // re-resolve |
| 656 CompilationUnit unit2 = _cloneResolveUnit(unit); | 659 CompilationUnit unit2 = _cloneResolveUnit(unit); |
| 657 node = _findSimpleIdentifier(unit2, code, 'max').parent; | 660 node = _findSimpleIdentifier(unit2, code, 'max').parent; |
| 658 t = node.functionExpression.typeParameters.typeParameters[0]; | 661 t = node.functionExpression.typeParameters.typeParameters[0]; |
| 659 expect(t.element, same(tElement)); | 662 expect(t.element, same(tElement)); |
| 660 } | 663 } |
| 661 | 664 |
| 662 void test_genericMethod_typeParameter() { | 665 test_genericMethod_typeParameter() async { |
| 663 String code = r''' | 666 String code = r''' |
| 664 class C { | 667 class C { |
| 665 /*=T*/ max/*<T>*/(/*=T*/ x, /*=T*/ y) => null; | 668 /*=T*/ max/*<T>*/(/*=T*/ x, /*=T*/ y) => null; |
| 666 } | 669 } |
| 667 '''; | 670 '''; |
| 668 CompilationUnit unit = resolveSource(code); | 671 CompilationUnit unit = await resolveSource(code); |
| 669 MethodDeclaration node = _findSimpleIdentifier(unit, code, 'max').parent; | 672 MethodDeclaration node = _findSimpleIdentifier(unit, code, 'max').parent; |
| 670 TypeParameter t = node.typeParameters.typeParameters[0]; | 673 TypeParameter t = node.typeParameters.typeParameters[0]; |
| 671 | 674 |
| 672 MethodElement element = node.name.staticElement; | 675 MethodElement element = node.name.staticElement; |
| 673 TypeParameterElement tElement = element.typeParameters[0]; | 676 TypeParameterElement tElement = element.typeParameters[0]; |
| 674 expect(tElement, isNotNull); | 677 expect(tElement, isNotNull); |
| 675 expect(element.typeParameters.toString(), "[T]"); | 678 expect(element.typeParameters.toString(), "[T]"); |
| 676 expect(element.type.toString(), "<T>(T, T) → T"); | 679 expect(element.type.toString(), "<T>(T, T) → T"); |
| 677 expect(t.element, same(tElement)); | 680 expect(t.element, same(tElement)); |
| 678 | 681 |
| 679 // re-resolve | 682 // re-resolve |
| 680 CompilationUnit unit2 = _cloneResolveUnit(unit); | 683 CompilationUnit unit2 = _cloneResolveUnit(unit); |
| 681 node = _findSimpleIdentifier(unit2, code, 'max').parent; | 684 node = _findSimpleIdentifier(unit2, code, 'max').parent; |
| 682 t = node.typeParameters.typeParameters[0]; | 685 t = node.typeParameters.typeParameters[0]; |
| 683 expect(t.element, same(tElement)); | 686 expect(t.element, same(tElement)); |
| 684 } | 687 } |
| 685 } | 688 } |
| OLD | NEW |