OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library test.src.task.dart_test; |
| 6 |
| 7 import 'package:analyzer/src/context/cache.dart'; |
| 8 import 'package:analyzer/src/generated/ast.dart'; |
| 9 import 'package:analyzer/src/generated/constant.dart'; |
| 10 import 'package:analyzer/src/generated/element.dart'; |
| 11 import 'package:analyzer/src/generated/engine.dart' |
| 12 show AnalysisOptionsImpl, CacheState; |
| 13 import 'package:analyzer/src/generated/error.dart'; |
| 14 import 'package:analyzer/src/generated/resolver.dart'; |
| 15 import 'package:analyzer/src/generated/scanner.dart'; |
| 16 import 'package:analyzer/src/generated/sdk.dart'; |
| 17 import 'package:analyzer/src/generated/source.dart'; |
| 18 import 'package:analyzer/src/services/lint.dart'; |
| 19 import 'package:analyzer/src/task/dart.dart'; |
| 20 import 'package:analyzer/src/task/html.dart'; |
| 21 import 'package:analyzer/task/dart.dart'; |
| 22 import 'package:analyzer/task/general.dart'; |
| 23 import 'package:analyzer/task/model.dart'; |
| 24 import 'package:unittest/unittest.dart'; |
| 25 |
| 26 import '../../generated/resolver_test.dart'; |
| 27 import '../../generated/test_support.dart'; |
| 28 import '../../reflective_tests.dart'; |
| 29 import '../../utils.dart'; |
| 30 import '../context/abstract_context.dart'; |
| 31 |
| 32 main() { |
| 33 initializeTestEnvironment(); |
| 34 runReflectiveTests(BuildCompilationUnitElementTaskTest); |
| 35 runReflectiveTests(BuildDirectiveElementsTaskTest); |
| 36 runReflectiveTests(BuildEnumMemberElementsTaskTest); |
| 37 runReflectiveTests(BuildExportNamespaceTaskTest); |
| 38 runReflectiveTests(BuildLibraryElementTaskTest); |
| 39 runReflectiveTests(BuildPublicNamespaceTaskTest); |
| 40 runReflectiveTests(BuildSourceExportClosureTaskTest); |
| 41 runReflectiveTests(BuildSourceImportExportClosureTaskTest); |
| 42 runReflectiveTests(BuildTypeProviderTaskTest); |
| 43 runReflectiveTests(ComputeConstantDependenciesTaskTest); |
| 44 runReflectiveTests(ComputeConstantValueTaskTest); |
| 45 runReflectiveTests(ComputeInferableStaticVariableDependenciesTaskTest); |
| 46 runReflectiveTests(ComputeLibraryCycleTaskTest); |
| 47 runReflectiveTests(ContainingLibrariesTaskTest); |
| 48 runReflectiveTests(DartErrorsTaskTest); |
| 49 runReflectiveTests(EvaluateUnitConstantsTaskTest); |
| 50 runReflectiveTests(GatherUsedImportedElementsTaskTest); |
| 51 runReflectiveTests(GatherUsedLocalElementsTaskTest); |
| 52 runReflectiveTests(GenerateHintsTaskTest); |
| 53 runReflectiveTests(GenerateLintsTaskTest); |
| 54 runReflectiveTests(InferInstanceMembersInUnitTaskTest); |
| 55 runReflectiveTests(InferStaticVariableTypesInUnitTaskTest); |
| 56 runReflectiveTests(InferStaticVariableTypeTaskTest); |
| 57 runReflectiveTests(LibraryErrorsReadyTaskTest); |
| 58 runReflectiveTests(LibraryUnitErrorsTaskTest); |
| 59 runReflectiveTests(ParseDartTaskTest); |
| 60 runReflectiveTests(PartiallyResolveUnitReferencesTaskTest); |
| 61 runReflectiveTests(ResolveInstanceFieldsInUnitTaskTest); |
| 62 runReflectiveTests(ResolveLibraryTypeNamesTaskTest); |
| 63 runReflectiveTests(ResolveUnitTaskTest); |
| 64 runReflectiveTests(ResolveUnitTypeNamesTaskTest); |
| 65 runReflectiveTests(ResolveVariableReferencesTaskTest); |
| 66 runReflectiveTests(ScanDartTaskTest); |
| 67 runReflectiveTests(StrongModeInferenceTest); |
| 68 runReflectiveTests(VerifyUnitTaskTest); |
| 69 } |
| 70 |
| 71 isInstanceOf isBuildCompilationUnitElementTask = |
| 72 new isInstanceOf<BuildCompilationUnitElementTask>(); |
| 73 isInstanceOf isBuildDirectiveElementsTask = |
| 74 new isInstanceOf<BuildDirectiveElementsTask>(); |
| 75 isInstanceOf isBuildEnumMemberElementsTask = |
| 76 new isInstanceOf<BuildEnumMemberElementsTask>(); |
| 77 isInstanceOf isBuildExportNamespaceTask = |
| 78 new isInstanceOf<BuildExportNamespaceTask>(); |
| 79 isInstanceOf isBuildLibraryElementTask = |
| 80 new isInstanceOf<BuildLibraryElementTask>(); |
| 81 isInstanceOf isBuildPublicNamespaceTask = |
| 82 new isInstanceOf<BuildPublicNamespaceTask>(); |
| 83 isInstanceOf isBuildSourceExportClosureTask = |
| 84 new isInstanceOf<BuildSourceExportClosureTask>(); |
| 85 isInstanceOf isBuildSourceImportExportClosureTask = |
| 86 new isInstanceOf<BuildSourceImportExportClosureTask>(); |
| 87 isInstanceOf isBuildTypeProviderTask = |
| 88 new isInstanceOf<BuildTypeProviderTask>(); |
| 89 isInstanceOf isComputeConstantDependenciesTask = |
| 90 new isInstanceOf<ComputeConstantDependenciesTask>(); |
| 91 isInstanceOf isComputeConstantValueTask = |
| 92 new isInstanceOf<ComputeConstantValueTask>(); |
| 93 isInstanceOf isComputeInferableStaticVariableDependenciesTask = |
| 94 new isInstanceOf<ComputeInferableStaticVariableDependenciesTask>(); |
| 95 isInstanceOf isContainingLibrariesTask = |
| 96 new isInstanceOf<ContainingLibrariesTask>(); |
| 97 isInstanceOf isDartErrorsTask = new isInstanceOf<DartErrorsTask>(); |
| 98 isInstanceOf isEvaluateUnitConstantsTask = |
| 99 new isInstanceOf<EvaluateUnitConstantsTask>(); |
| 100 isInstanceOf isGatherUsedImportedElementsTask = |
| 101 new isInstanceOf<GatherUsedImportedElementsTask>(); |
| 102 isInstanceOf isGatherUsedLocalElementsTask = |
| 103 new isInstanceOf<GatherUsedLocalElementsTask>(); |
| 104 isInstanceOf isGenerateHintsTask = new isInstanceOf<GenerateHintsTask>(); |
| 105 isInstanceOf isGenerateLintsTask = new isInstanceOf<GenerateLintsTask>(); |
| 106 isInstanceOf isInferInstanceMembersInUnitTask = |
| 107 new isInstanceOf<InferInstanceMembersInUnitTask>(); |
| 108 isInstanceOf isInferStaticVariableTypesInUnitTask = |
| 109 new isInstanceOf<InferStaticVariableTypesInUnitTask>(); |
| 110 isInstanceOf isInferStaticVariableTypeTask = |
| 111 new isInstanceOf<InferStaticVariableTypeTask>(); |
| 112 isInstanceOf isLibraryErrorsReadyTask = |
| 113 new isInstanceOf<LibraryErrorsReadyTask>(); |
| 114 isInstanceOf isLibraryUnitErrorsTask = |
| 115 new isInstanceOf<LibraryUnitErrorsTask>(); |
| 116 isInstanceOf isParseDartTask = new isInstanceOf<ParseDartTask>(); |
| 117 isInstanceOf isPartiallyResolveUnitReferencesTask = |
| 118 new isInstanceOf<PartiallyResolveUnitReferencesTask>(); |
| 119 isInstanceOf isResolveLibraryTypeNamesTask = |
| 120 new isInstanceOf<ResolveLibraryTypeNamesTask>(); |
| 121 isInstanceOf isResolveUnitTask = new isInstanceOf<ResolveUnitTask>(); |
| 122 isInstanceOf isResolveUnitTypeNamesTask = |
| 123 new isInstanceOf<ResolveUnitTypeNamesTask>(); |
| 124 isInstanceOf isResolveVariableReferencesTask = |
| 125 new isInstanceOf<ResolveVariableReferencesTask>(); |
| 126 isInstanceOf isScanDartTask = new isInstanceOf<ScanDartTask>(); |
| 127 isInstanceOf isVerifyUnitTask = new isInstanceOf<VerifyUnitTask>(); |
| 128 |
| 129 final LintCode _testLintCode = new LintCode('test lint', 'test lint code'); |
| 130 |
| 131 @reflectiveTest |
| 132 class BuildCompilationUnitElementTaskTest extends _AbstractDartTaskTest { |
| 133 Source source; |
| 134 LibrarySpecificUnit target; |
| 135 |
| 136 test_perform_find_constants() { |
| 137 _performBuildTask(''' |
| 138 const x = 1; |
| 139 class C { |
| 140 static const y = 1; |
| 141 const C([p = 1]); |
| 142 } |
| 143 @x |
| 144 f() { |
| 145 const z = 1; |
| 146 } |
| 147 '''); |
| 148 CompilationUnit unit = outputs[RESOLVED_UNIT1]; |
| 149 CompilationUnitElement unitElement = outputs[COMPILATION_UNIT_ELEMENT]; |
| 150 Annotation annotation = unit.declarations |
| 151 .firstWhere((m) => m is FunctionDeclaration) |
| 152 .metadata[0]; |
| 153 List<ConstantEvaluationTarget> expectedConstants = [ |
| 154 unitElement.accessors.firstWhere((e) => e.isGetter).variable, |
| 155 unitElement.types[0].fields[0], |
| 156 unitElement.functions[0].localVariables[0], |
| 157 unitElement.types[0].constructors[0], |
| 158 new ConstantEvaluationTarget_Annotation( |
| 159 context, source, source, annotation), |
| 160 unitElement.types[0].constructors[0].parameters[0] |
| 161 ]; |
| 162 expect( |
| 163 outputs[COMPILATION_UNIT_CONSTANTS].toSet(), expectedConstants.toSet()); |
| 164 } |
| 165 |
| 166 test_perform_library() { |
| 167 _performBuildTask(r''' |
| 168 library lib; |
| 169 import 'lib2.dart'; |
| 170 export 'lib3.dart'; |
| 171 part 'part.dart'; |
| 172 final x = ''; |
| 173 class A { |
| 174 static final y = 0; |
| 175 } |
| 176 class B = Object with A; |
| 177 '''); |
| 178 expect(outputs, hasLength(3)); |
| 179 expect(outputs[COMPILATION_UNIT_CONSTANTS], isNotNull); |
| 180 expect(outputs[COMPILATION_UNIT_ELEMENT], isNotNull); |
| 181 expect(outputs[RESOLVED_UNIT1], isNotNull); |
| 182 } |
| 183 |
| 184 test_perform_reuseElement() { |
| 185 _performBuildTask(r''' |
| 186 library lib; |
| 187 class A {} |
| 188 class B = Object with A; |
| 189 '''); |
| 190 CompilationUnit unit = outputs[RESOLVED_UNIT1]; |
| 191 CompilationUnitElement unitElement = outputs[COMPILATION_UNIT_ELEMENT]; |
| 192 expect(unit, isNotNull); |
| 193 expect(unitElement, isNotNull); |
| 194 // invalidate RESOLVED_UNIT1 |
| 195 CacheEntry cacheEntry = analysisCache.get(target); |
| 196 cacheEntry.setState(RESOLVED_UNIT1, CacheState.INVALID); |
| 197 // compute again |
| 198 computeResult(target, RESOLVED_UNIT1, |
| 199 matcher: isBuildCompilationUnitElementTask); |
| 200 expect(outputs[COMPILATION_UNIT_ELEMENT], same(unitElement)); |
| 201 expect(outputs[RESOLVED_UNIT1], isNot(same(unit))); |
| 202 } |
| 203 |
| 204 void _performBuildTask(String content) { |
| 205 source = newSource('/test.dart', content); |
| 206 target = new LibrarySpecificUnit(source, source); |
| 207 computeResult(target, RESOLVED_UNIT1, |
| 208 matcher: isBuildCompilationUnitElementTask); |
| 209 } |
| 210 } |
| 211 |
| 212 @reflectiveTest |
| 213 class BuildDirectiveElementsTaskTest extends _AbstractDartTaskTest { |
| 214 test_perform() { |
| 215 List<Source> sources = newSources({ |
| 216 '/libA.dart': ''' |
| 217 library libA; |
| 218 import 'libB.dart'; |
| 219 export 'libC.dart'; |
| 220 ''', |
| 221 '/libB.dart': ''' |
| 222 library libB; |
| 223 ''', |
| 224 '/libC.dart': ''' |
| 225 library libC; |
| 226 ''' |
| 227 }); |
| 228 Source sourceA = sources[0]; |
| 229 Source sourceB = sources[1]; |
| 230 Source sourceC = sources[2]; |
| 231 // perform task |
| 232 computeResult(sourceA, LIBRARY_ELEMENT2, |
| 233 matcher: isBuildDirectiveElementsTask); |
| 234 // prepare outputs |
| 235 LibraryElement libraryElementA = outputs[LIBRARY_ELEMENT2]; |
| 236 LibraryElement libraryElementB = _getImportLibraryInput(sourceB); |
| 237 LibraryElement libraryElementC = _getExportLibraryInput(sourceC); |
| 238 // no errors |
| 239 _assertErrorsWithCodes([]); |
| 240 // validate directives |
| 241 CompilationUnit libraryUnitA = context |
| 242 .getCacheEntry(new LibrarySpecificUnit(sourceA, sourceA)) |
| 243 .getValue(RESOLVED_UNIT1); |
| 244 { |
| 245 ImportDirective importNode = libraryUnitA.directives[1]; |
| 246 ImportElement importElement = importNode.element; |
| 247 expect(importElement, isNotNull); |
| 248 expect(importElement.importedLibrary, libraryElementB); |
| 249 expect(importElement.prefix, isNull); |
| 250 expect(importElement.nameOffset, 14); |
| 251 expect(importElement.uriOffset, 21); |
| 252 expect(importElement.uriEnd, 32); |
| 253 } |
| 254 { |
| 255 ExportDirective exportNode = libraryUnitA.directives[2]; |
| 256 ExportElement exportElement = exportNode.element; |
| 257 expect(exportElement, isNotNull); |
| 258 expect(exportElement.exportedLibrary, libraryElementC); |
| 259 expect(exportElement.nameOffset, 34); |
| 260 expect(exportElement.uriOffset, 41); |
| 261 expect(exportElement.uriEnd, 52); |
| 262 } |
| 263 // validate LibraryElement |
| 264 expect(libraryElementA.hasExtUri, isFalse); |
| 265 // has an artificial "dart:core" import |
| 266 { |
| 267 List<ImportElement> imports = libraryElementA.imports; |
| 268 expect(imports, hasLength(2)); |
| 269 expect(imports[1].importedLibrary.isDartCore, isTrue); |
| 270 expect(imports[1].isSynthetic, isTrue); |
| 271 } |
| 272 } |
| 273 |
| 274 test_perform_combinators() { |
| 275 List<Source> sources = newSources({ |
| 276 '/libA.dart': ''' |
| 277 library libA; |
| 278 import 'libB.dart' show A, B hide C, D; |
| 279 ''', |
| 280 '/libB.dart': ''' |
| 281 library libB; |
| 282 ''' |
| 283 }); |
| 284 Source sourceA = sources[0]; |
| 285 // perform task |
| 286 computeResult(sourceA, LIBRARY_ELEMENT2, |
| 287 matcher: isBuildDirectiveElementsTask); |
| 288 // prepare outputs |
| 289 CompilationUnit libraryUnitA = context |
| 290 .getCacheEntry(new LibrarySpecificUnit(sourceA, sourceA)) |
| 291 .getValue(RESOLVED_UNIT1); |
| 292 // no errors |
| 293 _assertErrorsWithCodes([]); |
| 294 // validate directives |
| 295 ImportDirective importNode = libraryUnitA.directives[1]; |
| 296 ImportElement importElement = importNode.element; |
| 297 List<NamespaceCombinator> combinators = importElement.combinators; |
| 298 expect(combinators, hasLength(2)); |
| 299 { |
| 300 ShowElementCombinator combinator = combinators[0]; |
| 301 expect(combinator.offset, 33); |
| 302 expect(combinator.end, 42); |
| 303 expect(combinator.shownNames, ['A', 'B']); |
| 304 } |
| 305 { |
| 306 HideElementCombinator combinator = combinators[1]; |
| 307 expect(combinator.hiddenNames, ['C', 'D']); |
| 308 } |
| 309 } |
| 310 |
| 311 test_perform_dartCoreContext() { |
| 312 List<Source> sources = newSources({'/libA.dart': ''}); |
| 313 Source source = sources[0]; |
| 314 // perform task |
| 315 computeResult(source, LIBRARY_ELEMENT2, |
| 316 matcher: isBuildDirectiveElementsTask); |
| 317 // prepare outputs |
| 318 LibraryElement libraryElement = outputs[LIBRARY_ELEMENT2]; |
| 319 // verify that dart:core has SDK context |
| 320 { |
| 321 LibraryElement coreLibrary = libraryElement.importedLibraries[0]; |
| 322 DartSdk dartSdk = context.sourceFactory.dartSdk; |
| 323 expect(coreLibrary.context, same(dartSdk.context)); |
| 324 } |
| 325 } |
| 326 |
| 327 test_perform_error_exportOfNonLibrary() { |
| 328 List<Source> sources = newSources({ |
| 329 '/libA.dart': ''' |
| 330 library libA; |
| 331 export 'part.dart'; |
| 332 ''', |
| 333 '/part.dart': ''' |
| 334 part of notLib; |
| 335 ''' |
| 336 }); |
| 337 Source sourceA = sources[0]; |
| 338 // perform task |
| 339 computeResult(sourceA, LIBRARY_ELEMENT2, |
| 340 matcher: isBuildDirectiveElementsTask); |
| 341 // validate errors |
| 342 _assertErrorsWithCodes([CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY]); |
| 343 } |
| 344 |
| 345 test_perform_error_importOfNonLibrary() { |
| 346 List<Source> sources = newSources({ |
| 347 '/libA.dart': ''' |
| 348 library libA; |
| 349 import 'part.dart'; |
| 350 ''', |
| 351 '/part.dart': ''' |
| 352 part of notLib; |
| 353 ''' |
| 354 }); |
| 355 Source sourceA = sources[0]; |
| 356 // perform task |
| 357 computeResult(sourceA, LIBRARY_ELEMENT2, |
| 358 matcher: isBuildDirectiveElementsTask); |
| 359 // validate errors |
| 360 _assertErrorsWithCodes([CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY]); |
| 361 } |
| 362 |
| 363 test_perform_explicitDartCoreImport() { |
| 364 List<Source> sources = newSources({ |
| 365 '/lib.dart': ''' |
| 366 library lib; |
| 367 import 'dart:core' show List; |
| 368 ''' |
| 369 }); |
| 370 Source source = sources[0]; |
| 371 // perform task |
| 372 computeResult(source, LIBRARY_ELEMENT2, |
| 373 matcher: isBuildDirectiveElementsTask); |
| 374 // prepare outputs |
| 375 LibraryElement libraryElement = outputs[LIBRARY_ELEMENT2]; |
| 376 // has an explicit "dart:core" import |
| 377 { |
| 378 List<ImportElement> imports = libraryElement.imports; |
| 379 expect(imports, hasLength(1)); |
| 380 expect(imports[0].importedLibrary.isDartCore, isTrue); |
| 381 expect(imports[0].isSynthetic, isFalse); |
| 382 } |
| 383 } |
| 384 |
| 385 test_perform_hasExtUri() { |
| 386 List<Source> sources = newSources({ |
| 387 '/lib.dart': ''' |
| 388 import 'dart-ext:doesNotExist.dart'; |
| 389 ''' |
| 390 }); |
| 391 Source source = sources[0]; |
| 392 // perform task |
| 393 computeResult(source, LIBRARY_ELEMENT2, |
| 394 matcher: isBuildDirectiveElementsTask); |
| 395 // prepare outputs |
| 396 LibraryElement libraryElement = outputs[LIBRARY_ELEMENT2]; |
| 397 expect(libraryElement.hasExtUri, isTrue); |
| 398 } |
| 399 |
| 400 test_perform_importPrefix() { |
| 401 List<Source> sources = newSources({ |
| 402 '/libA.dart': ''' |
| 403 library libA; |
| 404 import 'libB.dart' as pref; |
| 405 import 'libC.dart' as pref; |
| 406 ''', |
| 407 '/libB.dart': ''' |
| 408 library libB; |
| 409 ''', |
| 410 '/libC.dart': ''' |
| 411 library libC; |
| 412 ''' |
| 413 }); |
| 414 Source sourceA = sources[0]; |
| 415 Source sourceB = sources[1]; |
| 416 // perform task |
| 417 computeResult(sourceA, LIBRARY_ELEMENT2, |
| 418 matcher: isBuildDirectiveElementsTask); |
| 419 // prepare outputs |
| 420 CompilationUnit libraryUnitA = context |
| 421 .getCacheEntry(new LibrarySpecificUnit(sourceA, sourceA)) |
| 422 .getValue(RESOLVED_UNIT1); |
| 423 // validate directives |
| 424 ImportDirective importNodeB = libraryUnitA.directives[1]; |
| 425 SimpleIdentifier prefixNodeB = importNodeB.prefix; |
| 426 ImportElement importElementB = importNodeB.element; |
| 427 PrefixElement prefixElement = importElementB.prefix; |
| 428 expect(importElementB, isNotNull); |
| 429 expect(importElementB.importedLibrary, _getImportLibraryInput(sourceB)); |
| 430 expect(prefixElement, isNotNull); |
| 431 expect(importElementB.prefixOffset, prefixElement.nameOffset); |
| 432 expect(prefixNodeB.staticElement, prefixElement); |
| 433 // PrefixElement "pref" is shared |
| 434 ImportDirective importNodeC = libraryUnitA.directives[2]; |
| 435 SimpleIdentifier prefixNodeC = importNodeC.prefix; |
| 436 ImportElement importElementC = importNodeC.element; |
| 437 expect(prefixNodeC.staticElement, prefixElement); |
| 438 expect(importElementC.prefix, prefixElement); |
| 439 } |
| 440 |
| 441 void _assertErrorsWithCodes(List<ErrorCode> expectedErrorCodes) { |
| 442 _fillErrorListener(BUILD_DIRECTIVES_ERRORS); |
| 443 errorListener.assertErrorsWithCodes(expectedErrorCodes); |
| 444 } |
| 445 |
| 446 _getExportLibraryInput(Source source) { |
| 447 var key = BuildDirectiveElementsTask.EXPORTS_LIBRARY_ELEMENT_INPUT_NAME; |
| 448 return task.inputs[key][source]; |
| 449 } |
| 450 |
| 451 _getImportLibraryInput(Source source) { |
| 452 var key = BuildDirectiveElementsTask.IMPORTS_LIBRARY_ELEMENT_INPUT_NAME; |
| 453 return task.inputs[key][source]; |
| 454 } |
| 455 } |
| 456 |
| 457 @reflectiveTest |
| 458 class BuildEnumMemberElementsTaskTest extends _AbstractDartTaskTest { |
| 459 test_perform() { |
| 460 Source source = newSource( |
| 461 '/test.dart', |
| 462 ''' |
| 463 enum MyEnum { |
| 464 A, B |
| 465 } |
| 466 '''); |
| 467 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT2, |
| 468 matcher: isBuildEnumMemberElementsTask); |
| 469 CompilationUnit unit = outputs[RESOLVED_UNIT2]; |
| 470 // validate Element |
| 471 ClassElement enumElement = unit.element.getEnum('MyEnum'); |
| 472 List<FieldElement> fields = enumElement.fields; |
| 473 expect(fields, hasLength(4)); |
| 474 { |
| 475 FieldElementImpl index = fields[0]; |
| 476 expect(index, isNotNull); |
| 477 expect(index.name, 'index'); |
| 478 expect(index.isStatic, isFalse); |
| 479 expect(index.evaluationResult, isNull); |
| 480 _assertGetter(index); |
| 481 } |
| 482 { |
| 483 ConstFieldElementImpl values = fields[1]; |
| 484 expect(values, isNotNull); |
| 485 expect(values.name, 'values'); |
| 486 expect(values.isStatic, isTrue); |
| 487 expect(values.evaluationResult, isNotNull); |
| 488 _assertGetter(values); |
| 489 } |
| 490 { |
| 491 ConstFieldElementImpl constant = fields[2]; |
| 492 expect(constant, isNotNull); |
| 493 expect(constant.name, 'A'); |
| 494 expect(constant.isStatic, isTrue); |
| 495 expect(constant.evaluationResult, isNotNull); |
| 496 _assertGetter(constant); |
| 497 } |
| 498 { |
| 499 ConstFieldElementImpl constant = fields[3]; |
| 500 expect(constant, isNotNull); |
| 501 expect(constant.name, 'B'); |
| 502 expect(constant.isStatic, isTrue); |
| 503 expect(constant.evaluationResult, isNotNull); |
| 504 _assertGetter(constant); |
| 505 } |
| 506 // validate nodes |
| 507 EnumDeclaration enumNode = unit.declarations[0]; |
| 508 expect(enumNode.name.staticElement, same(enumElement)); |
| 509 expect(enumNode.constants[0].element, same(enumElement.getField('A'))); |
| 510 expect(enumNode.constants[1].element, same(enumElement.getField('B'))); |
| 511 } |
| 512 |
| 513 static void _assertGetter(FieldElement field) { |
| 514 PropertyAccessorElement getter = field.getter; |
| 515 expect(getter, isNotNull); |
| 516 expect(getter.variable, same(field)); |
| 517 expect(getter.type, isNotNull); |
| 518 } |
| 519 } |
| 520 |
| 521 @reflectiveTest |
| 522 class BuildExportNamespaceTaskTest extends _AbstractDartTaskTest { |
| 523 test_perform_entryPoint() { |
| 524 Source sourceA = newSource( |
| 525 '/a.dart', |
| 526 ''' |
| 527 library lib_a; |
| 528 export 'b.dart'; |
| 529 '''); |
| 530 Source sourceB = newSource( |
| 531 '/b.dart', |
| 532 ''' |
| 533 library lib_b; |
| 534 main() {} |
| 535 '''); |
| 536 computeResult(sourceA, LIBRARY_ELEMENT4, |
| 537 matcher: isBuildExportNamespaceTask); |
| 538 // validate |
| 539 LibraryElement library = outputs[LIBRARY_ELEMENT4]; |
| 540 FunctionElement entryPoint = library.entryPoint; |
| 541 expect(entryPoint, isNotNull); |
| 542 expect(entryPoint.source, sourceB); |
| 543 } |
| 544 |
| 545 test_perform_hideCombinator() { |
| 546 Source sourceA = newSource( |
| 547 '/a.dart', |
| 548 ''' |
| 549 library lib_a; |
| 550 export 'b.dart' hide B1; |
| 551 class A1 {} |
| 552 class A2 {} |
| 553 class _A3 {} |
| 554 '''); |
| 555 newSource( |
| 556 '/b.dart', |
| 557 ''' |
| 558 library lib_b; |
| 559 class B1 {} |
| 560 class B2 {} |
| 561 class B3 {} |
| 562 class _B4 {} |
| 563 '''); |
| 564 newSource( |
| 565 '/c.dart', |
| 566 ''' |
| 567 library lib_c; |
| 568 class C1 {} |
| 569 class C2 {} |
| 570 class C3 {} |
| 571 '''); |
| 572 computeResult(sourceA, LIBRARY_ELEMENT4, |
| 573 matcher: isBuildExportNamespaceTask); |
| 574 // validate |
| 575 LibraryElement library = outputs[LIBRARY_ELEMENT4]; |
| 576 Namespace namespace = library.exportNamespace; |
| 577 Iterable<String> definedKeys = namespace.definedNames.keys; |
| 578 expect(definedKeys, unorderedEquals(['A1', 'A2', 'B2', 'B3'])); |
| 579 } |
| 580 |
| 581 test_perform_showCombinator() { |
| 582 Source sourceA = newSource( |
| 583 '/a.dart', |
| 584 ''' |
| 585 library lib_a; |
| 586 export 'b.dart' show B1; |
| 587 class A1 {} |
| 588 class A2 {} |
| 589 class _A3 {} |
| 590 '''); |
| 591 newSource( |
| 592 '/b.dart', |
| 593 ''' |
| 594 library lib_b; |
| 595 class B1 {} |
| 596 class B2 {} |
| 597 class _B3 {} |
| 598 '''); |
| 599 computeResult(sourceA, LIBRARY_ELEMENT4, |
| 600 matcher: isBuildExportNamespaceTask); |
| 601 // validate |
| 602 LibraryElement library = outputs[LIBRARY_ELEMENT4]; |
| 603 Namespace namespace = library.exportNamespace; |
| 604 Iterable<String> definedKeys = namespace.definedNames.keys; |
| 605 expect(definedKeys, unorderedEquals(['A1', 'A2', 'B1'])); |
| 606 } |
| 607 |
| 608 test_perform_showCombinator_setter() { |
| 609 Source sourceA = newSource( |
| 610 '/a.dart', |
| 611 ''' |
| 612 library lib_a; |
| 613 export 'b.dart' show topLevelB; |
| 614 class A {} |
| 615 '''); |
| 616 newSource( |
| 617 '/b.dart', |
| 618 ''' |
| 619 library lib_b; |
| 620 int topLevelB; |
| 621 '''); |
| 622 computeResult(sourceA, LIBRARY_ELEMENT4, |
| 623 matcher: isBuildExportNamespaceTask); |
| 624 // validate |
| 625 LibraryElement library = outputs[LIBRARY_ELEMENT4]; |
| 626 Namespace namespace = library.exportNamespace; |
| 627 Iterable<String> definedKeys = namespace.definedNames.keys; |
| 628 expect(definedKeys, unorderedEquals(['A', 'topLevelB', 'topLevelB='])); |
| 629 } |
| 630 } |
| 631 |
| 632 @reflectiveTest |
| 633 class BuildLibraryElementTaskTest extends _AbstractDartTaskTest { |
| 634 Source librarySource; |
| 635 CompilationUnit libraryUnit; |
| 636 CompilationUnitElement libraryUnitElement; |
| 637 List<CompilationUnit> partUnits; |
| 638 |
| 639 LibraryElement libraryElement; |
| 640 |
| 641 test_perform() { |
| 642 _performBuildTask({ |
| 643 '/lib.dart': ''' |
| 644 library lib; |
| 645 part 'part1.dart'; |
| 646 part 'part2.dart'; |
| 647 ''', |
| 648 '/part1.dart': ''' |
| 649 part of lib; |
| 650 ''', |
| 651 '/part2.dart': ''' |
| 652 part of lib; |
| 653 ''' |
| 654 }); |
| 655 expect(outputs, hasLength(3)); |
| 656 // simple outputs |
| 657 expect(outputs[BUILD_LIBRARY_ERRORS], isEmpty); |
| 658 expect(outputs[IS_LAUNCHABLE], isFalse); |
| 659 // LibraryElement output |
| 660 expect(libraryElement, isNotNull); |
| 661 expect(libraryElement.entryPoint, isNull); |
| 662 expect(libraryElement.source, same(librarySource)); |
| 663 expect(libraryElement.definingCompilationUnit, libraryUnitElement); |
| 664 expect(libraryElement.parts, |
| 665 unorderedEquals([partUnits[0].element, partUnits[1].element])); |
| 666 // LibraryElement references |
| 667 expect((libraryUnit.directives[0] as LibraryDirective).element, |
| 668 same(libraryElement)); |
| 669 expect((partUnits[0].directives[0] as PartOfDirective).element, |
| 670 same(libraryElement)); |
| 671 expect((partUnits[1].directives[0] as PartOfDirective).element, |
| 672 same(libraryElement)); |
| 673 // CompilationUnitElement(s) |
| 674 CompilationUnitElement firstPart; |
| 675 CompilationUnitElement secondPart; |
| 676 if (partUnits[0].element.uri == 'part1.dart') { |
| 677 firstPart = partUnits[0].element; |
| 678 secondPart = partUnits[1].element; |
| 679 } else { |
| 680 firstPart = partUnits[1].element; |
| 681 secondPart = partUnits[0].element; |
| 682 } |
| 683 expect(firstPart.uri, 'part1.dart'); |
| 684 expect(firstPart.uriOffset, 18); |
| 685 expect(firstPart.uriEnd, 30); |
| 686 expect( |
| 687 (libraryUnit.directives[1] as PartDirective).element, same(firstPart)); |
| 688 |
| 689 expect(secondPart.uri, 'part2.dart'); |
| 690 expect(secondPart.uriOffset, 37); |
| 691 expect(secondPart.uriEnd, 49); |
| 692 expect( |
| 693 (libraryUnit.directives[2] as PartDirective).element, same(secondPart)); |
| 694 } |
| 695 |
| 696 test_perform_error_missingLibraryDirectiveWithPart_hasCommon() { |
| 697 _performBuildTask({ |
| 698 '/lib.dart': ''' |
| 699 part 'partA.dart'; |
| 700 part 'partB.dart'; |
| 701 ''', |
| 702 '/partA.dart': ''' |
| 703 part of my_lib; |
| 704 ''', |
| 705 '/partB.dart': ''' |
| 706 part of my_lib; |
| 707 ''' |
| 708 }); |
| 709 _assertErrorsWithCodes( |
| 710 [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]); |
| 711 AnalysisError error = errorListener.errors[0]; |
| 712 expect(error.getProperty(ErrorProperty.PARTS_LIBRARY_NAME), 'my_lib'); |
| 713 } |
| 714 |
| 715 test_perform_error_missingLibraryDirectiveWithPart_noCommon() { |
| 716 _performBuildTask({ |
| 717 '/lib.dart': ''' |
| 718 part 'partA.dart'; |
| 719 part 'partB.dart'; |
| 720 ''', |
| 721 '/partA.dart': ''' |
| 722 part of libA; |
| 723 ''', |
| 724 '/partB.dart': ''' |
| 725 part of libB; |
| 726 ''' |
| 727 }); |
| 728 _assertErrorsWithCodes( |
| 729 [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]); |
| 730 AnalysisError error = errorListener.errors[0]; |
| 731 expect(error.getProperty(ErrorProperty.PARTS_LIBRARY_NAME), isNull); |
| 732 } |
| 733 |
| 734 test_perform_error_partDoesNotExist() { |
| 735 _performBuildTask({ |
| 736 '/lib.dart': ''' |
| 737 library lib; |
| 738 part 'part.dart'; |
| 739 ''' |
| 740 }); |
| 741 // we already report URI_DOES_NOT_EXIST, no need to report other errors |
| 742 _assertErrorsWithCodes([]); |
| 743 } |
| 744 |
| 745 test_perform_error_partOfDifferentLibrary() { |
| 746 _performBuildTask({ |
| 747 '/lib.dart': ''' |
| 748 library lib; |
| 749 part 'part.dart'; |
| 750 ''', |
| 751 '/part.dart': ''' |
| 752 part of someOtherLib; |
| 753 ''' |
| 754 }); |
| 755 _assertErrorsWithCodes([StaticWarningCode.PART_OF_DIFFERENT_LIBRARY]); |
| 756 } |
| 757 |
| 758 test_perform_error_partOfNonPart() { |
| 759 _performBuildTask({ |
| 760 '/lib.dart': ''' |
| 761 library lib; |
| 762 part 'part.dart'; |
| 763 ''', |
| 764 '/part.dart': ''' |
| 765 // no part of |
| 766 ''' |
| 767 }); |
| 768 _assertErrorsWithCodes([CompileTimeErrorCode.PART_OF_NON_PART]); |
| 769 } |
| 770 |
| 771 test_perform_invalidUri_part() { |
| 772 _performBuildTask({ |
| 773 '/lib.dart': ''' |
| 774 library lib; |
| 775 part '//////////'; |
| 776 ''' |
| 777 }); |
| 778 expect(libraryElement.parts, isEmpty); |
| 779 } |
| 780 |
| 781 test_perform_isLaunchable_inDefiningUnit() { |
| 782 _performBuildTask({ |
| 783 '/lib.dart': ''' |
| 784 library lib; |
| 785 main() { |
| 786 } |
| 787 ''' |
| 788 }); |
| 789 expect(outputs[IS_LAUNCHABLE], isTrue); |
| 790 expect(libraryElement.entryPoint, isNotNull); |
| 791 } |
| 792 |
| 793 test_perform_isLaunchable_inPartUnit() { |
| 794 _performBuildTask({ |
| 795 '/lib.dart': ''' |
| 796 library lib; |
| 797 part 'part.dart'; |
| 798 ''', |
| 799 '/part.dart': ''' |
| 800 part of lib; |
| 801 main() { |
| 802 } |
| 803 ''' |
| 804 }); |
| 805 expect(outputs[IS_LAUNCHABLE], isTrue); |
| 806 expect(libraryElement.entryPoint, isNotNull); |
| 807 } |
| 808 |
| 809 test_perform_noSuchFilePart() { |
| 810 _performBuildTask({ |
| 811 '/lib.dart': ''' |
| 812 library lib; |
| 813 part 'no-such-file.dart'; |
| 814 ''' |
| 815 }); |
| 816 expect(libraryElement.parts, hasLength(1)); |
| 817 CompilationUnitElement part = libraryElement.parts[0]; |
| 818 expect(part, isNotNull); |
| 819 expect(part.source, isNotNull); |
| 820 expect(part.library, same(libraryElement)); |
| 821 expect(context.exists(part.source), isFalse); |
| 822 } |
| 823 |
| 824 test_perform_patchTopLevelAccessors() { |
| 825 _performBuildTask({ |
| 826 '/lib.dart': ''' |
| 827 library lib; |
| 828 part 'part1.dart'; |
| 829 part 'part2.dart'; |
| 830 ''', |
| 831 '/part1.dart': ''' |
| 832 part of lib; |
| 833 int get test => 0; |
| 834 ''', |
| 835 '/part2.dart': ''' |
| 836 part of lib; |
| 837 void set test(_) {} |
| 838 ''' |
| 839 }); |
| 840 CompilationUnitElement unitElement1 = partUnits[0].element; |
| 841 CompilationUnitElement unitElement2 = partUnits[1].element; |
| 842 PropertyAccessorElement getter = unitElement1.accessors[0]; |
| 843 PropertyAccessorElement setter = unitElement2.accessors[0]; |
| 844 PropertyInducingElement variable = getter.variable; |
| 845 expect(getter.isGetter, isTrue); |
| 846 expect(setter.isSetter, isTrue); |
| 847 expect(variable, isNotNull); |
| 848 expect(setter.variable, same(variable)); |
| 849 expect(unitElement1.topLevelVariables, [variable]); |
| 850 expect(unitElement2.topLevelVariables, [variable]); |
| 851 } |
| 852 |
| 853 void _assertErrorsWithCodes(List<ErrorCode> expectedErrorCodes) { |
| 854 _fillErrorListener(BUILD_LIBRARY_ERRORS); |
| 855 errorListener.assertErrorsWithCodes(expectedErrorCodes); |
| 856 } |
| 857 |
| 858 void _performBuildTask(Map<String, String> sourceMap) { |
| 859 List<Source> sources = newSources(sourceMap); |
| 860 Source libSource = sources.first; |
| 861 computeResult(libSource, LIBRARY_ELEMENT1, |
| 862 matcher: isBuildLibraryElementTask); |
| 863 libraryUnit = context |
| 864 .getCacheEntry(new LibrarySpecificUnit(libSource, libSource)) |
| 865 .getValue(RESOLVED_UNIT1); |
| 866 libraryUnitElement = libraryUnit.element; |
| 867 librarySource = libraryUnitElement.source; |
| 868 libraryElement = outputs[LIBRARY_ELEMENT1]; |
| 869 partUnits = task.inputs[BuildLibraryElementTask.PARTS_UNIT_INPUT]; |
| 870 } |
| 871 } |
| 872 |
| 873 @reflectiveTest |
| 874 class BuildPublicNamespaceTaskTest extends _AbstractDartTaskTest { |
| 875 test_perform() { |
| 876 List<Source> sources = newSources({ |
| 877 '/lib.dart': ''' |
| 878 library lib; |
| 879 part 'part.dart'; |
| 880 a() {} |
| 881 _b() {} |
| 882 ''', |
| 883 '/part.dart': ''' |
| 884 part of lib; |
| 885 _c() {} |
| 886 d() {} |
| 887 ''' |
| 888 }); |
| 889 computeResult(sources.first, LIBRARY_ELEMENT3, |
| 890 matcher: isBuildPublicNamespaceTask); |
| 891 // validate |
| 892 LibraryElement library = outputs[LIBRARY_ELEMENT3]; |
| 893 Namespace namespace = library.publicNamespace; |
| 894 expect(namespace.definedNames.keys, unorderedEquals(['a', 'd'])); |
| 895 } |
| 896 } |
| 897 |
| 898 @reflectiveTest |
| 899 class BuildSourceExportClosureTaskTest extends _AbstractDartTaskTest { |
| 900 test_perform_exportClosure() { |
| 901 Source sourceA = newSource( |
| 902 '/a.dart', |
| 903 ''' |
| 904 library lib_a; |
| 905 export 'b.dart'; |
| 906 '''); |
| 907 Source sourceB = newSource( |
| 908 '/b.dart', |
| 909 ''' |
| 910 library lib_b; |
| 911 export 'c.dart'; |
| 912 '''); |
| 913 Source sourceC = newSource( |
| 914 '/c.dart', |
| 915 ''' |
| 916 library lib_c; |
| 917 export 'a.dart'; |
| 918 '''); |
| 919 Source sourceD = newSource( |
| 920 '/d.dart', |
| 921 ''' |
| 922 library lib_d; |
| 923 '''); |
| 924 // a.dart |
| 925 { |
| 926 computeResult(sourceA, EXPORT_SOURCE_CLOSURE, |
| 927 matcher: isBuildSourceExportClosureTask); |
| 928 List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE]; |
| 929 expect(closure, unorderedEquals([sourceA, sourceB, sourceC])); |
| 930 } |
| 931 // c.dart |
| 932 { |
| 933 computeResult(sourceC, EXPORT_SOURCE_CLOSURE, |
| 934 matcher: isBuildSourceExportClosureTask); |
| 935 List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE]; |
| 936 expect(closure, unorderedEquals([sourceA, sourceB, sourceC])); |
| 937 } |
| 938 // d.dart |
| 939 { |
| 940 computeResult(sourceD, EXPORT_SOURCE_CLOSURE, |
| 941 matcher: isBuildSourceExportClosureTask); |
| 942 List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE]; |
| 943 expect(closure, unorderedEquals([sourceD])); |
| 944 } |
| 945 } |
| 946 } |
| 947 |
| 948 @reflectiveTest |
| 949 class BuildSourceImportExportClosureTaskTest extends _AbstractDartTaskTest { |
| 950 test_perform_importExportClosure() { |
| 951 Source sourceA = newSource( |
| 952 '/a.dart', |
| 953 ''' |
| 954 library lib_a; |
| 955 '''); |
| 956 Source sourceB = newSource( |
| 957 '/b.dart', |
| 958 ''' |
| 959 library lib_b; |
| 960 export 'a.dart'; |
| 961 '''); |
| 962 Source sourceC = newSource( |
| 963 '/c.dart', |
| 964 ''' |
| 965 library lib_c; |
| 966 import 'b.dart'; |
| 967 '''); |
| 968 Source coreSource = context.sourceFactory.resolveUri(null, 'dart:core'); |
| 969 // c.dart |
| 970 { |
| 971 computeResult(sourceC, IMPORT_EXPORT_SOURCE_CLOSURE, |
| 972 matcher: isBuildSourceImportExportClosureTask); |
| 973 List<Source> closure = outputs[IMPORT_EXPORT_SOURCE_CLOSURE]; |
| 974 expect(closure, contains(sourceA)); |
| 975 expect(closure, contains(sourceB)); |
| 976 expect(closure, contains(sourceC)); |
| 977 expect(closure, contains(coreSource)); |
| 978 } |
| 979 // b.dart |
| 980 { |
| 981 computeResult(sourceB, IMPORT_EXPORT_SOURCE_CLOSURE, |
| 982 matcher: isBuildSourceImportExportClosureTask); |
| 983 List<Source> closure = outputs[IMPORT_EXPORT_SOURCE_CLOSURE]; |
| 984 expect(closure, contains(sourceA)); |
| 985 expect(closure, contains(sourceB)); |
| 986 expect(closure, contains(coreSource)); |
| 987 } |
| 988 } |
| 989 |
| 990 test_perform_isClient_false() { |
| 991 Source sourceA = newSource( |
| 992 '/a.dart', |
| 993 ''' |
| 994 library lib_a; |
| 995 import 'b.dart'; |
| 996 '''); |
| 997 newSource( |
| 998 '/b.dart', |
| 999 ''' |
| 1000 library lib_b; |
| 1001 '''); |
| 1002 computeResult(sourceA, IS_CLIENT, |
| 1003 matcher: isBuildSourceImportExportClosureTask); |
| 1004 expect(outputs[IS_CLIENT], isFalse); |
| 1005 } |
| 1006 |
| 1007 test_perform_isClient_true_export_indirect() { |
| 1008 newSource( |
| 1009 '/exports_html.dart', |
| 1010 ''' |
| 1011 library lib_exports_html; |
| 1012 export 'dart:html'; |
| 1013 '''); |
| 1014 Source source = newSource( |
| 1015 '/test.dart', |
| 1016 ''' |
| 1017 import 'exports_html.dart'; |
| 1018 '''); |
| 1019 computeResult(source, IS_CLIENT, |
| 1020 matcher: isBuildSourceImportExportClosureTask); |
| 1021 expect(outputs[IS_CLIENT], isTrue); |
| 1022 } |
| 1023 |
| 1024 test_perform_isClient_true_import_direct() { |
| 1025 Source sourceA = newSource( |
| 1026 '/a.dart', |
| 1027 ''' |
| 1028 library lib_a; |
| 1029 import 'dart:html'; |
| 1030 '''); |
| 1031 computeResult(sourceA, IS_CLIENT, |
| 1032 matcher: isBuildSourceImportExportClosureTask); |
| 1033 expect(outputs[IS_CLIENT], isTrue); |
| 1034 } |
| 1035 |
| 1036 test_perform_isClient_true_import_indirect() { |
| 1037 Source sourceA = newSource( |
| 1038 '/a.dart', |
| 1039 ''' |
| 1040 library lib_a; |
| 1041 import 'b.dart'; |
| 1042 '''); |
| 1043 newSource( |
| 1044 '/b.dart', |
| 1045 ''' |
| 1046 library lib_b; |
| 1047 import 'dart:html'; |
| 1048 '''); |
| 1049 computeResult(sourceA, IS_CLIENT, |
| 1050 matcher: isBuildSourceImportExportClosureTask); |
| 1051 expect(outputs[IS_CLIENT], isTrue); |
| 1052 } |
| 1053 } |
| 1054 |
| 1055 @reflectiveTest |
| 1056 class BuildTypeProviderTaskTest extends _AbstractDartTaskTest { |
| 1057 test_perform() { |
| 1058 computeResult(AnalysisContextTarget.request, TYPE_PROVIDER, |
| 1059 matcher: isBuildTypeProviderTask); |
| 1060 // validate |
| 1061 TypeProvider typeProvider = outputs[TYPE_PROVIDER]; |
| 1062 expect(typeProvider, isNotNull); |
| 1063 expect(typeProvider.boolType, isNotNull); |
| 1064 expect(typeProvider.intType, isNotNull); |
| 1065 expect(typeProvider.futureType, isNotNull); |
| 1066 } |
| 1067 } |
| 1068 |
| 1069 @reflectiveTest |
| 1070 class ComputeConstantDependenciesTaskTest extends _AbstractDartTaskTest { |
| 1071 Annotation findClassAnnotation(CompilationUnit unit, String className) { |
| 1072 for (CompilationUnitMember member in unit.declarations) { |
| 1073 if (member is ClassDeclaration && member.name.name == className) { |
| 1074 expect(member.metadata, hasLength(1)); |
| 1075 return member.metadata[0]; |
| 1076 } |
| 1077 } |
| 1078 fail('Annotation not found'); |
| 1079 return null; |
| 1080 } |
| 1081 |
| 1082 test_annotation_with_args() { |
| 1083 Source source = newSource( |
| 1084 '/test.dart', |
| 1085 ''' |
| 1086 const x = 1; |
| 1087 @D(x) class C {} |
| 1088 class D { const D(value); } |
| 1089 '''); |
| 1090 // First compute the resolved unit for the source. |
| 1091 LibrarySpecificUnit librarySpecificUnit = |
| 1092 new LibrarySpecificUnit(source, source); |
| 1093 computeResult(librarySpecificUnit, RESOLVED_UNIT1); |
| 1094 CompilationUnit unit = outputs[RESOLVED_UNIT1]; |
| 1095 // Find the elements for x and D's constructor, and the annotation on C. |
| 1096 List<PropertyAccessorElement> accessors = unit.element.accessors; |
| 1097 Element x = accessors |
| 1098 .firstWhere((PropertyAccessorElement accessor) => |
| 1099 accessor.isGetter && accessor.name == 'x') |
| 1100 .variable; |
| 1101 List<ClassElement> types = unit.element.types; |
| 1102 Element constructorForD = |
| 1103 types.firstWhere((ClassElement cls) => cls.name == 'D').constructors[0]; |
| 1104 Annotation annotation = findClassAnnotation(unit, 'C'); |
| 1105 // Now compute the dependencies for the annotation, and check that it is |
| 1106 // the set [x, constructorForD]. |
| 1107 // TODO(paulberry): test librarySource != source |
| 1108 computeResult( |
| 1109 new ConstantEvaluationTarget_Annotation( |
| 1110 context, source, source, annotation), |
| 1111 CONSTANT_DEPENDENCIES, |
| 1112 matcher: isComputeConstantDependenciesTask); |
| 1113 expect( |
| 1114 outputs[CONSTANT_DEPENDENCIES].toSet(), [x, constructorForD].toSet()); |
| 1115 } |
| 1116 |
| 1117 test_annotation_without_args() { |
| 1118 Source source = newSource( |
| 1119 '/test.dart', |
| 1120 ''' |
| 1121 const x = 1; |
| 1122 @x class C {} |
| 1123 '''); |
| 1124 // First compute the resolved unit for the source. |
| 1125 LibrarySpecificUnit librarySpecificUnit = |
| 1126 new LibrarySpecificUnit(source, source); |
| 1127 computeResult(librarySpecificUnit, RESOLVED_UNIT1); |
| 1128 CompilationUnit unit = outputs[RESOLVED_UNIT1]; |
| 1129 // Find the element for x and the annotation on C. |
| 1130 List<PropertyAccessorElement> accessors = unit.element.accessors; |
| 1131 Element x = accessors |
| 1132 .firstWhere((PropertyAccessorElement accessor) => |
| 1133 accessor.isGetter && accessor.name == 'x') |
| 1134 .variable; |
| 1135 Annotation annotation = findClassAnnotation(unit, 'C'); |
| 1136 // Now compute the dependencies for the annotation, and check that it is |
| 1137 // the list [x]. |
| 1138 computeResult( |
| 1139 new ConstantEvaluationTarget_Annotation( |
| 1140 context, source, source, annotation), |
| 1141 CONSTANT_DEPENDENCIES, |
| 1142 matcher: isComputeConstantDependenciesTask); |
| 1143 expect(outputs[CONSTANT_DEPENDENCIES], [x]); |
| 1144 } |
| 1145 |
| 1146 test_enumConstant() { |
| 1147 Source source = newSource( |
| 1148 '/test.dart', |
| 1149 ''' |
| 1150 enum E {A, B, C} |
| 1151 '''); |
| 1152 // First compute the resolved unit for the source. |
| 1153 LibrarySpecificUnit librarySpecificUnit = |
| 1154 new LibrarySpecificUnit(source, source); |
| 1155 computeResult(librarySpecificUnit, RESOLVED_UNIT2); |
| 1156 CompilationUnit unit = outputs[RESOLVED_UNIT2]; |
| 1157 // Find the element for 'A' |
| 1158 EnumDeclaration enumDeclaration = unit.declarations[0]; |
| 1159 EnumConstantDeclaration constantDeclaration = enumDeclaration.constants[0]; |
| 1160 FieldElement constantElement = constantDeclaration.element; |
| 1161 // Now compute the dependencies for the constant and check that there are |
| 1162 // none. |
| 1163 computeResult(constantElement, CONSTANT_DEPENDENCIES, |
| 1164 matcher: isComputeConstantDependenciesTask); |
| 1165 expect(outputs[CONSTANT_DEPENDENCIES], isEmpty); |
| 1166 } |
| 1167 |
| 1168 test_perform() { |
| 1169 Source source = newSource( |
| 1170 '/test.dart', |
| 1171 ''' |
| 1172 const x = y; |
| 1173 const y = 1; |
| 1174 '''); |
| 1175 // First compute the resolved unit for the source. |
| 1176 LibrarySpecificUnit librarySpecificUnit = |
| 1177 new LibrarySpecificUnit(source, source); |
| 1178 computeResult(librarySpecificUnit, RESOLVED_UNIT1); |
| 1179 CompilationUnit unit = outputs[RESOLVED_UNIT1]; |
| 1180 // Find the elements for the constants x and y. |
| 1181 List<PropertyAccessorElement> accessors = unit.element.accessors; |
| 1182 Element x = accessors |
| 1183 .firstWhere((PropertyAccessorElement accessor) => |
| 1184 accessor.isGetter && accessor.name == 'x') |
| 1185 .variable; |
| 1186 Element y = accessors |
| 1187 .firstWhere((PropertyAccessorElement accessor) => |
| 1188 accessor.isGetter && accessor.name == 'y') |
| 1189 .variable; |
| 1190 // Now compute the dependencies for x, and check that it is the list [y]. |
| 1191 computeResult(x, CONSTANT_DEPENDENCIES, |
| 1192 matcher: isComputeConstantDependenciesTask); |
| 1193 expect(outputs[CONSTANT_DEPENDENCIES], [y]); |
| 1194 } |
| 1195 } |
| 1196 |
| 1197 @reflectiveTest |
| 1198 class ComputeConstantValueTaskTest extends _AbstractDartTaskTest { |
| 1199 EvaluationResultImpl computeClassAnnotation( |
| 1200 Source source, CompilationUnit unit, String className) { |
| 1201 for (CompilationUnitMember member in unit.declarations) { |
| 1202 if (member is ClassDeclaration && member.name.name == className) { |
| 1203 expect(member.metadata, hasLength(1)); |
| 1204 Annotation annotation = member.metadata[0]; |
| 1205 ConstantEvaluationTarget_Annotation target = |
| 1206 new ConstantEvaluationTarget_Annotation( |
| 1207 context, source, source, annotation); |
| 1208 computeResult(target, CONSTANT_VALUE, |
| 1209 matcher: isComputeConstantValueTask); |
| 1210 expect(outputs[CONSTANT_VALUE], same(target)); |
| 1211 EvaluationResultImpl evaluationResult = (annotation.elementAnnotation |
| 1212 as ElementAnnotationImpl).evaluationResult; |
| 1213 return evaluationResult; |
| 1214 } |
| 1215 } |
| 1216 fail('Annotation not found'); |
| 1217 return null; |
| 1218 } |
| 1219 |
| 1220 test_annotation_non_const_constructor() { |
| 1221 // Calling a non-const constructor from an annotation that is illegal, but |
| 1222 // shouldn't crash analysis. |
| 1223 Source source = newSource( |
| 1224 '/test.dart', |
| 1225 ''' |
| 1226 class A { |
| 1227 final int i; |
| 1228 A(this.i); |
| 1229 } |
| 1230 |
| 1231 @A(5) |
| 1232 class C {} |
| 1233 '''); |
| 1234 // First compute the resolved unit for the source. |
| 1235 CompilationUnit unit = _resolveSource(source); |
| 1236 // Compute the constant value of the annotation on C. |
| 1237 EvaluationResultImpl evaluationResult = |
| 1238 computeClassAnnotation(source, unit, 'C'); |
| 1239 // And check that it has no value stored in it. |
| 1240 expect(evaluationResult, isNotNull); |
| 1241 expect(evaluationResult.value, isNull); |
| 1242 } |
| 1243 |
| 1244 test_annotation_with_args() { |
| 1245 Source source = newSource( |
| 1246 '/test.dart', |
| 1247 ''' |
| 1248 const x = 1; |
| 1249 @D(x) class C {} |
| 1250 class D { |
| 1251 const D(this.value); |
| 1252 final value; |
| 1253 } |
| 1254 '''); |
| 1255 // First compute the resolved unit for the source. |
| 1256 CompilationUnit unit = _resolveSource(source); |
| 1257 // Compute the constant value of the annotation on C. |
| 1258 EvaluationResultImpl evaluationResult = |
| 1259 computeClassAnnotation(source, unit, 'C'); |
| 1260 // And check that it has the expected value. |
| 1261 expect(evaluationResult, isNotNull); |
| 1262 expect(evaluationResult.value, isNotNull); |
| 1263 expect(evaluationResult.value.type, isNotNull); |
| 1264 expect(evaluationResult.value.type.name, 'D'); |
| 1265 expect(evaluationResult.value.fields, contains('value')); |
| 1266 expect(evaluationResult.value.fields['value'].intValue, 1); |
| 1267 } |
| 1268 |
| 1269 test_annotation_without_args() { |
| 1270 Source source = newSource( |
| 1271 '/test.dart', |
| 1272 ''' |
| 1273 const x = 1; |
| 1274 @x class C {} |
| 1275 '''); |
| 1276 // First compute the resolved unit for the source. |
| 1277 CompilationUnit unit = _resolveSource(source); |
| 1278 // Compute the constant value of the annotation on C. |
| 1279 EvaluationResultImpl evaluationResult = |
| 1280 computeClassAnnotation(source, unit, 'C'); |
| 1281 // And check that it has the expected value. |
| 1282 expect(evaluationResult, isNotNull); |
| 1283 expect(evaluationResult.value, isNotNull); |
| 1284 expect(evaluationResult.value.intValue, 1); |
| 1285 } |
| 1286 |
| 1287 test_circular_reference() { |
| 1288 _checkCircularities( |
| 1289 'x', |
| 1290 ['y'], |
| 1291 ''' |
| 1292 const x = y + 1; |
| 1293 const y = x + 1; |
| 1294 '''); |
| 1295 } |
| 1296 |
| 1297 test_circular_reference_one_element() { |
| 1298 // See dartbug.com/23490. |
| 1299 _checkCircularities('x', [], 'const x = x;'); |
| 1300 } |
| 1301 |
| 1302 test_circular_reference_strongly_connected_component() { |
| 1303 // When there is a circularity, all elements in the strongly connected |
| 1304 // component should be marked as having an error. |
| 1305 _checkCircularities( |
| 1306 'a', |
| 1307 ['b', 'c', 'd'], |
| 1308 ''' |
| 1309 const a = b; |
| 1310 const b = c + d; |
| 1311 const c = a; |
| 1312 const d = a; |
| 1313 '''); |
| 1314 } |
| 1315 |
| 1316 test_const_constructor_calls_implicit_super_constructor_implicitly() { |
| 1317 // Note: the situation below is a compile-time error (since the synthetic |
| 1318 // constructor for Base is non-const), but we need to handle it without |
| 1319 // throwing an exception. |
| 1320 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue( |
| 1321 'x', |
| 1322 ''' |
| 1323 class Base {} |
| 1324 class Derived extends Base { |
| 1325 const Derived(); |
| 1326 } |
| 1327 const x = const Derived(); |
| 1328 '''); |
| 1329 expect(evaluationResult, isNotNull); |
| 1330 } |
| 1331 |
| 1332 test_dependency() { |
| 1333 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue( |
| 1334 'x', |
| 1335 ''' |
| 1336 const x = y + 1; |
| 1337 const y = 1; |
| 1338 '''); |
| 1339 expect(evaluationResult, isNotNull); |
| 1340 expect(evaluationResult.value, isNotNull); |
| 1341 expect(evaluationResult.value.intValue, 2); |
| 1342 } |
| 1343 |
| 1344 test_external_const_factory() { |
| 1345 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue( |
| 1346 'x', |
| 1347 ''' |
| 1348 const x = const C.foo(); |
| 1349 |
| 1350 class C extends B { |
| 1351 external const factory C.foo(); |
| 1352 } |
| 1353 |
| 1354 class B {} |
| 1355 '''); |
| 1356 expect(evaluationResult, isNotNull); |
| 1357 } |
| 1358 |
| 1359 test_simple_constant() { |
| 1360 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue( |
| 1361 'x', |
| 1362 ''' |
| 1363 const x = 1; |
| 1364 '''); |
| 1365 expect(evaluationResult, isNotNull); |
| 1366 expect(evaluationResult.value, isNotNull); |
| 1367 expect(evaluationResult.value.intValue, 1); |
| 1368 } |
| 1369 |
| 1370 void _checkCircularities( |
| 1371 String variableName, List<String> otherVariables, String content) { |
| 1372 // Evaluating the first constant should produce an error. |
| 1373 CompilationUnit unit = _resolveUnit(content); |
| 1374 _expectCircularityError(_evaluateConstant(unit, variableName)); |
| 1375 // And all the other constants involved in the strongly connected component |
| 1376 // should be set to the same error state. |
| 1377 for (String otherVariableName in otherVariables) { |
| 1378 PropertyInducingElement otherVariableElement = |
| 1379 _findVariable(unit, otherVariableName); |
| 1380 _expectCircularityError((otherVariableElement |
| 1381 as TopLevelVariableElementImpl).evaluationResult); |
| 1382 } |
| 1383 } |
| 1384 |
| 1385 EvaluationResultImpl _computeTopLevelVariableConstValue( |
| 1386 String variableName, String content) { |
| 1387 return _evaluateConstant(_resolveUnit(content), variableName); |
| 1388 } |
| 1389 |
| 1390 EvaluationResultImpl _evaluateConstant( |
| 1391 CompilationUnit unit, String variableName) { |
| 1392 // Find the element for the given constant. |
| 1393 PropertyInducingElement variableElement = _findVariable(unit, variableName); |
| 1394 // Now compute the value of the constant. |
| 1395 computeResult(variableElement, CONSTANT_VALUE, |
| 1396 matcher: isComputeConstantValueTask); |
| 1397 expect(outputs[CONSTANT_VALUE], same(variableElement)); |
| 1398 EvaluationResultImpl evaluationResult = |
| 1399 (variableElement as TopLevelVariableElementImpl).evaluationResult; |
| 1400 return evaluationResult; |
| 1401 } |
| 1402 |
| 1403 void _expectCircularityError(EvaluationResultImpl evaluationResult) { |
| 1404 expect(evaluationResult, isNotNull); |
| 1405 expect(evaluationResult.value, isNull); |
| 1406 expect(evaluationResult.errors, hasLength(1)); |
| 1407 expect(evaluationResult.errors[0].errorCode, |
| 1408 CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT); |
| 1409 } |
| 1410 |
| 1411 PropertyInducingElement _findVariable( |
| 1412 CompilationUnit unit, String variableName) { |
| 1413 // Find the element for the given constant. |
| 1414 return unit.element.topLevelVariables.firstWhere( |
| 1415 (TopLevelVariableElement variable) => variable.name == variableName); |
| 1416 } |
| 1417 |
| 1418 CompilationUnit _resolveSource(Source source) { |
| 1419 LibrarySpecificUnit librarySpecificUnit = |
| 1420 new LibrarySpecificUnit(source, source); |
| 1421 computeResult(librarySpecificUnit, RESOLVED_UNIT1); |
| 1422 CompilationUnit unit = outputs[RESOLVED_UNIT1]; |
| 1423 return unit; |
| 1424 } |
| 1425 |
| 1426 CompilationUnit _resolveUnit(String content) => |
| 1427 _resolveSource(newSource('/test.dart', content)); |
| 1428 } |
| 1429 |
| 1430 @reflectiveTest |
| 1431 class ComputeInferableStaticVariableDependenciesTaskTest |
| 1432 extends _AbstractDartTaskTest { |
| 1433 @override |
| 1434 void setUp() { |
| 1435 super.setUp(); |
| 1436 // Variable dependencies are only available in strong mode. |
| 1437 enableStrongMode(); |
| 1438 } |
| 1439 |
| 1440 test_perform() { |
| 1441 AnalysisTarget source = newSource( |
| 1442 '/test.dart', |
| 1443 ''' |
| 1444 const a = b; |
| 1445 const b = 0; |
| 1446 '''); |
| 1447 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1448 computeResult(target, RESOLVED_UNIT5); |
| 1449 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 1450 TopLevelVariableElement elementA = unit.element.topLevelVariables[0]; |
| 1451 TopLevelVariableElement elementB = unit.element.topLevelVariables[1]; |
| 1452 |
| 1453 computeResult(elementA, INFERABLE_STATIC_VARIABLE_DEPENDENCIES, |
| 1454 matcher: isComputeInferableStaticVariableDependenciesTask); |
| 1455 expect(outputs, hasLength(1)); |
| 1456 List<VariableElement> dependencies = |
| 1457 outputs[INFERABLE_STATIC_VARIABLE_DEPENDENCIES]; |
| 1458 expect(dependencies, unorderedEquals([elementB])); |
| 1459 } |
| 1460 } |
| 1461 |
| 1462 @reflectiveTest |
| 1463 class ComputeLibraryCycleTaskTest extends _AbstractDartTaskTest { |
| 1464 @override |
| 1465 void setUp() { |
| 1466 super.setUp(); |
| 1467 enableStrongMode(); |
| 1468 } |
| 1469 |
| 1470 void test_library_cycle_linear() { |
| 1471 List<Source> sources = newSources({ |
| 1472 '/a.dart': ''' |
| 1473 ''', |
| 1474 '/b.dart': ''' |
| 1475 import 'a.dart'; |
| 1476 ''' |
| 1477 }); |
| 1478 List<Map<ResultDescriptor, dynamic>> results = |
| 1479 computeLibraryResultsMap(sources, LIBRARY_CYCLE); |
| 1480 List<LibraryElement> component0 = results[0][LIBRARY_CYCLE]; |
| 1481 List<LibraryElement> component1 = results[1][LIBRARY_CYCLE]; |
| 1482 expect(component0, hasLength(1)); |
| 1483 expect(component1, hasLength(1)); |
| 1484 |
| 1485 List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS]; |
| 1486 List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS]; |
| 1487 expect(units0, hasLength(1)); |
| 1488 expect(units1, hasLength(1)); |
| 1489 |
| 1490 List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES]; |
| 1491 List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES]; |
| 1492 expect(dep0, hasLength(1)); // dart:core |
| 1493 expect(dep1, hasLength(2)); // dart:core, a.dart |
| 1494 } |
| 1495 |
| 1496 void test_library_cycle_loop() { |
| 1497 List<Source> sources = newSources({ |
| 1498 '/a.dart': ''' |
| 1499 import 'c.dart'; |
| 1500 ''', |
| 1501 '/b.dart': ''' |
| 1502 import 'a.dart'; |
| 1503 ''', |
| 1504 '/c.dart': ''' |
| 1505 import 'b.dart'; |
| 1506 ''' |
| 1507 }); |
| 1508 List<Map<ResultDescriptor, dynamic>> results = |
| 1509 computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList(); |
| 1510 List<LibraryElement> component0 = results[0][LIBRARY_CYCLE]; |
| 1511 List<LibraryElement> component1 = results[1][LIBRARY_CYCLE]; |
| 1512 List<LibraryElement> component2 = results[2][LIBRARY_CYCLE]; |
| 1513 |
| 1514 expect(component0, hasLength(3)); |
| 1515 expect(component1, hasLength(3)); |
| 1516 expect(component2, hasLength(3)); |
| 1517 |
| 1518 List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS]; |
| 1519 List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS]; |
| 1520 List<CompilationUnitElement> units2 = results[2][LIBRARY_CYCLE_UNITS]; |
| 1521 expect(units0, hasLength(3)); |
| 1522 expect(units1, hasLength(3)); |
| 1523 expect(units2, hasLength(3)); |
| 1524 |
| 1525 List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES]; |
| 1526 List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES]; |
| 1527 List<CompilationUnitElement> dep2 = results[2][LIBRARY_CYCLE_DEPENDENCIES]; |
| 1528 expect(dep0, hasLength(1)); // dart:core |
| 1529 expect(dep1, hasLength(1)); // dart:core |
| 1530 expect(dep2, hasLength(1)); // dart:core |
| 1531 } |
| 1532 |
| 1533 void test_library_cycle_self_loop() { |
| 1534 List<Source> sources = newSources({ |
| 1535 '/a.dart': ''' |
| 1536 import 'a.dart'; |
| 1537 ''' |
| 1538 }); |
| 1539 List<Map<ResultDescriptor, dynamic>> results = |
| 1540 computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList(); |
| 1541 List<LibraryElement> component0 = results[0][LIBRARY_CYCLE]; |
| 1542 expect(component0, hasLength(1)); |
| 1543 |
| 1544 List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS]; |
| 1545 expect(units0, hasLength(1)); |
| 1546 |
| 1547 List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES]; |
| 1548 expect(dep0, hasLength(1)); // dart:core |
| 1549 } |
| 1550 |
| 1551 void test_library_cycle_singleton() { |
| 1552 Source source = newSource( |
| 1553 '/test.dart', |
| 1554 ''' |
| 1555 import 'dart:core'; |
| 1556 '''); |
| 1557 computeResult(new LibrarySpecificUnit(source, source), LIBRARY_CYCLE); |
| 1558 List<LibraryElement> component = outputs[LIBRARY_CYCLE]; |
| 1559 List<CompilationUnitElement> units = outputs[LIBRARY_CYCLE_UNITS]; |
| 1560 List<CompilationUnitElement> deps = outputs[LIBRARY_CYCLE_DEPENDENCIES]; |
| 1561 expect(component, hasLength(1)); |
| 1562 expect(units, hasLength(1)); |
| 1563 expect(deps, hasLength(1)); |
| 1564 } |
| 1565 |
| 1566 void test_library_cycle_tree() { |
| 1567 List<Source> sources = newSources({ |
| 1568 '/a.dart': ''' |
| 1569 ''', |
| 1570 '/b.dart': ''' |
| 1571 ''', |
| 1572 '/c.dart': ''' |
| 1573 import 'a.dart'; |
| 1574 import 'b.dart'; |
| 1575 ''' |
| 1576 }); |
| 1577 List<Map<ResultDescriptor, dynamic>> results = |
| 1578 computeLibraryResultsMap(sources, LIBRARY_CYCLE); |
| 1579 List<LibraryElement> component0 = results[0][LIBRARY_CYCLE]; |
| 1580 List<LibraryElement> component1 = results[1][LIBRARY_CYCLE]; |
| 1581 List<LibraryElement> component2 = results[2][LIBRARY_CYCLE]; |
| 1582 expect(component0, hasLength(1)); |
| 1583 expect(component1, hasLength(1)); |
| 1584 expect(component2, hasLength(1)); |
| 1585 |
| 1586 List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS]; |
| 1587 List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS]; |
| 1588 List<CompilationUnitElement> units2 = results[2][LIBRARY_CYCLE_UNITS]; |
| 1589 expect(units0, hasLength(1)); |
| 1590 expect(units1, hasLength(1)); |
| 1591 expect(units2, hasLength(1)); |
| 1592 |
| 1593 List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES]; |
| 1594 List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES]; |
| 1595 List<CompilationUnitElement> dep2 = results[2][LIBRARY_CYCLE_DEPENDENCIES]; |
| 1596 expect(dep0, hasLength(1)); // dart:core |
| 1597 expect(dep1, hasLength(1)); // dart:core, |
| 1598 expect(dep2, hasLength(3)); // dart:core, a.dart, b.dart |
| 1599 } |
| 1600 |
| 1601 void test_library_double_loop() { |
| 1602 List<Source> sources = newSources({ |
| 1603 '/a.dart': ''' |
| 1604 import 'b.dart'; |
| 1605 ''', |
| 1606 '/b.dart': ''' |
| 1607 import 'a.dart'; |
| 1608 ''', |
| 1609 '/c.dart': ''' |
| 1610 import 'd.dart' as foo; |
| 1611 import 'a.dart' as bar; |
| 1612 export 'b.dart'; |
| 1613 ''', |
| 1614 '/d.dart': ''' |
| 1615 import 'c.dart' as foo; |
| 1616 import 'b.dart' as bar; |
| 1617 export 'a.dart'; |
| 1618 ''' |
| 1619 }); |
| 1620 List<Map<ResultDescriptor, dynamic>> results = |
| 1621 computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList(); |
| 1622 List<LibraryElement> component0 = results[0][LIBRARY_CYCLE]; |
| 1623 List<LibraryElement> component1 = results[1][LIBRARY_CYCLE]; |
| 1624 List<LibraryElement> component2 = results[2][LIBRARY_CYCLE]; |
| 1625 List<LibraryElement> component3 = results[3][LIBRARY_CYCLE]; |
| 1626 |
| 1627 expect(component0, hasLength(2)); |
| 1628 expect(component1, hasLength(2)); |
| 1629 expect(component2, hasLength(2)); |
| 1630 expect(component3, hasLength(2)); |
| 1631 |
| 1632 List<CompilationUnitElement> units0 = results[0][LIBRARY_CYCLE_UNITS]; |
| 1633 List<CompilationUnitElement> units1 = results[1][LIBRARY_CYCLE_UNITS]; |
| 1634 List<CompilationUnitElement> units2 = results[2][LIBRARY_CYCLE_UNITS]; |
| 1635 List<CompilationUnitElement> units3 = results[3][LIBRARY_CYCLE_UNITS]; |
| 1636 expect(units0, hasLength(2)); |
| 1637 expect(units1, hasLength(2)); |
| 1638 expect(units2, hasLength(2)); |
| 1639 expect(units3, hasLength(2)); |
| 1640 |
| 1641 List<CompilationUnitElement> dep0 = results[0][LIBRARY_CYCLE_DEPENDENCIES]; |
| 1642 List<CompilationUnitElement> dep1 = results[1][LIBRARY_CYCLE_DEPENDENCIES]; |
| 1643 List<CompilationUnitElement> dep2 = results[2][LIBRARY_CYCLE_DEPENDENCIES]; |
| 1644 List<CompilationUnitElement> dep3 = results[3][LIBRARY_CYCLE_DEPENDENCIES]; |
| 1645 expect(dep0, hasLength(1)); // dart:core |
| 1646 expect(dep1, hasLength(1)); // dart:core |
| 1647 expect(dep3, hasLength(3)); // dart:core, a.dart, b.dart |
| 1648 expect(dep3, hasLength(3)); // dart:core, a.dart, b.dart |
| 1649 } |
| 1650 |
| 1651 void test_library_double_loop_parts() { |
| 1652 List<Source> sources = newSources({ |
| 1653 '/a.dart': ''' |
| 1654 import 'b.dart'; |
| 1655 part 'aa.dart'; |
| 1656 part 'ab.dart'; |
| 1657 ''', |
| 1658 '/b.dart': ''' |
| 1659 import 'a.dart'; |
| 1660 ''', |
| 1661 '/aa.dart': ''' |
| 1662 ''', |
| 1663 '/ab.dart': ''' |
| 1664 ''', |
| 1665 '/c.dart': ''' |
| 1666 import 'd.dart' as foo; |
| 1667 import 'a.dart' as bar; |
| 1668 export 'b.dart'; |
| 1669 ''', |
| 1670 '/d.dart': ''' |
| 1671 import 'c.dart' as foo; |
| 1672 import 'b.dart' as bar; |
| 1673 export 'a.dart'; |
| 1674 part 'da.dart'; |
| 1675 part 'db.dart'; |
| 1676 ''', |
| 1677 '/da.dart': ''' |
| 1678 ''', |
| 1679 '/db.dart': ''' |
| 1680 ''' |
| 1681 }); |
| 1682 computeResult( |
| 1683 new LibrarySpecificUnit(sources[0], sources[0]), LIBRARY_CYCLE); |
| 1684 Map<ResultDescriptor, dynamic> results0 = outputs; |
| 1685 computeResult( |
| 1686 new LibrarySpecificUnit(sources[1], sources[1]), LIBRARY_CYCLE); |
| 1687 Map<ResultDescriptor, dynamic> results1 = outputs; |
| 1688 computeResult( |
| 1689 new LibrarySpecificUnit(sources[0], sources[2]), LIBRARY_CYCLE); |
| 1690 Map<ResultDescriptor, dynamic> results2 = outputs; |
| 1691 computeResult( |
| 1692 new LibrarySpecificUnit(sources[0], sources[3]), LIBRARY_CYCLE); |
| 1693 Map<ResultDescriptor, dynamic> results3 = outputs; |
| 1694 computeResult( |
| 1695 new LibrarySpecificUnit(sources[4], sources[4]), LIBRARY_CYCLE); |
| 1696 Map<ResultDescriptor, dynamic> results4 = outputs; |
| 1697 computeResult( |
| 1698 new LibrarySpecificUnit(sources[5], sources[5]), LIBRARY_CYCLE); |
| 1699 Map<ResultDescriptor, dynamic> results5 = outputs; |
| 1700 computeResult( |
| 1701 new LibrarySpecificUnit(sources[5], sources[6]), LIBRARY_CYCLE); |
| 1702 Map<ResultDescriptor, dynamic> results6 = outputs; |
| 1703 computeResult( |
| 1704 new LibrarySpecificUnit(sources[5], sources[7]), LIBRARY_CYCLE); |
| 1705 Map<ResultDescriptor, dynamic> results7 = outputs; |
| 1706 |
| 1707 List<LibraryElement> component0 = results0[LIBRARY_CYCLE]; |
| 1708 List<LibraryElement> component1 = results1[LIBRARY_CYCLE]; |
| 1709 List<LibraryElement> component2 = results2[LIBRARY_CYCLE]; |
| 1710 List<LibraryElement> component3 = results3[LIBRARY_CYCLE]; |
| 1711 List<LibraryElement> component4 = results4[LIBRARY_CYCLE]; |
| 1712 List<LibraryElement> component5 = results5[LIBRARY_CYCLE]; |
| 1713 List<LibraryElement> component6 = results6[LIBRARY_CYCLE]; |
| 1714 List<LibraryElement> component7 = results7[LIBRARY_CYCLE]; |
| 1715 |
| 1716 expect(component0, hasLength(2)); |
| 1717 expect(component1, hasLength(2)); |
| 1718 expect(component2, hasLength(2)); |
| 1719 expect(component3, hasLength(2)); |
| 1720 expect(component4, hasLength(2)); |
| 1721 expect(component5, hasLength(2)); |
| 1722 expect(component6, hasLength(2)); |
| 1723 expect(component7, hasLength(2)); |
| 1724 |
| 1725 List<CompilationUnitElement> units0 = results0[LIBRARY_CYCLE_UNITS]; |
| 1726 List<CompilationUnitElement> units1 = results1[LIBRARY_CYCLE_UNITS]; |
| 1727 List<CompilationUnitElement> units2 = results2[LIBRARY_CYCLE_UNITS]; |
| 1728 List<CompilationUnitElement> units3 = results3[LIBRARY_CYCLE_UNITS]; |
| 1729 List<CompilationUnitElement> units4 = results4[LIBRARY_CYCLE_UNITS]; |
| 1730 List<CompilationUnitElement> units5 = results5[LIBRARY_CYCLE_UNITS]; |
| 1731 List<CompilationUnitElement> units6 = results6[LIBRARY_CYCLE_UNITS]; |
| 1732 List<CompilationUnitElement> units7 = results7[LIBRARY_CYCLE_UNITS]; |
| 1733 expect(units0, hasLength(4)); |
| 1734 expect(units1, hasLength(4)); |
| 1735 expect(units2, hasLength(4)); |
| 1736 expect(units3, hasLength(4)); |
| 1737 expect(units4, hasLength(4)); |
| 1738 expect(units5, hasLength(4)); |
| 1739 expect(units6, hasLength(4)); |
| 1740 expect(units7, hasLength(4)); |
| 1741 |
| 1742 List<CompilationUnitElement> dep0 = results0[LIBRARY_CYCLE_DEPENDENCIES]; |
| 1743 List<CompilationUnitElement> dep1 = results1[LIBRARY_CYCLE_DEPENDENCIES]; |
| 1744 List<CompilationUnitElement> dep2 = results2[LIBRARY_CYCLE_DEPENDENCIES]; |
| 1745 List<CompilationUnitElement> dep3 = results3[LIBRARY_CYCLE_DEPENDENCIES]; |
| 1746 List<CompilationUnitElement> dep4 = results4[LIBRARY_CYCLE_DEPENDENCIES]; |
| 1747 List<CompilationUnitElement> dep5 = results5[LIBRARY_CYCLE_DEPENDENCIES]; |
| 1748 List<CompilationUnitElement> dep6 = results6[LIBRARY_CYCLE_DEPENDENCIES]; |
| 1749 List<CompilationUnitElement> dep7 = results7[LIBRARY_CYCLE_DEPENDENCIES]; |
| 1750 expect(dep0, hasLength(1)); // dart:core |
| 1751 expect(dep1, hasLength(1)); // dart:core |
| 1752 expect(dep2, hasLength(1)); // dart:core |
| 1753 expect(dep3, hasLength(1)); // dart:core |
| 1754 expect(dep4, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart |
| 1755 expect(dep5, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart |
| 1756 expect(dep6, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart |
| 1757 expect(dep7, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart |
| 1758 } |
| 1759 } |
| 1760 |
| 1761 @reflectiveTest |
| 1762 class ContainingLibrariesTaskTest extends _AbstractDartTaskTest { |
| 1763 test_perform_definingCompilationUnit() { |
| 1764 AnalysisTarget library = newSource('/test.dart', 'library test;'); |
| 1765 computeResult(library, INCLUDED_PARTS); |
| 1766 computeResult(library, CONTAINING_LIBRARIES, |
| 1767 matcher: isContainingLibrariesTask); |
| 1768 expect(outputs, hasLength(1)); |
| 1769 List<Source> containingLibraries = outputs[CONTAINING_LIBRARIES]; |
| 1770 expect(containingLibraries, unorderedEquals([library])); |
| 1771 } |
| 1772 |
| 1773 test_perform_partInMultipleLibraries() { |
| 1774 AnalysisTarget library1 = |
| 1775 newSource('/lib1.dart', 'library test; part "part.dart";'); |
| 1776 AnalysisTarget library2 = |
| 1777 newSource('/lib2.dart', 'library test; part "part.dart";'); |
| 1778 AnalysisTarget part = newSource('/part.dart', 'part of test;'); |
| 1779 computeResult(library1, INCLUDED_PARTS); |
| 1780 computeResult(library2, INCLUDED_PARTS); |
| 1781 computeResult(part, SOURCE_KIND); |
| 1782 computeResult(part, CONTAINING_LIBRARIES, |
| 1783 matcher: isContainingLibrariesTask); |
| 1784 expect(outputs, hasLength(1)); |
| 1785 List<Source> containingLibraries = outputs[CONTAINING_LIBRARIES]; |
| 1786 expect(containingLibraries, unorderedEquals([library1, library2])); |
| 1787 } |
| 1788 |
| 1789 test_perform_partInSingleLibrary() { |
| 1790 AnalysisTarget library = |
| 1791 newSource('/lib.dart', 'library test; part "part.dart";'); |
| 1792 AnalysisTarget part = newSource('/part.dart', 'part of test;'); |
| 1793 computeResult(library, INCLUDED_PARTS); |
| 1794 computeResult(part, SOURCE_KIND); |
| 1795 computeResult(part, CONTAINING_LIBRARIES, |
| 1796 matcher: isContainingLibrariesTask); |
| 1797 expect(outputs, hasLength(1)); |
| 1798 List<Source> containingLibraries = outputs[CONTAINING_LIBRARIES]; |
| 1799 expect(containingLibraries, unorderedEquals([library])); |
| 1800 } |
| 1801 } |
| 1802 |
| 1803 @reflectiveTest |
| 1804 class DartErrorsTaskTest extends _AbstractDartTaskTest { |
| 1805 test_perform_definingCompilationUnit() { |
| 1806 AnalysisTarget library = |
| 1807 newSource('/test.dart', 'library test; import "dart:math";'); |
| 1808 computeResult(library, INCLUDED_PARTS); |
| 1809 computeResult(library, DART_ERRORS, matcher: isDartErrorsTask); |
| 1810 expect(outputs, hasLength(1)); |
| 1811 List<AnalysisError> errors = outputs[DART_ERRORS]; |
| 1812 expect(errors, hasLength(1)); |
| 1813 } |
| 1814 |
| 1815 test_perform_partInSingleLibrary() { |
| 1816 AnalysisTarget library = newSource( |
| 1817 '/lib.dart', 'library test; import "dart:math"; part "part.dart";'); |
| 1818 AnalysisTarget part = |
| 1819 newSource('/part.dart', 'part of test; class A extends A {}'); |
| 1820 computeResult(library, INCLUDED_PARTS); |
| 1821 computeResult(library, DART_ERRORS); |
| 1822 computeResult(part, DART_ERRORS, matcher: isDartErrorsTask); |
| 1823 expect(outputs, hasLength(1)); |
| 1824 List<AnalysisError> errors = outputs[DART_ERRORS]; |
| 1825 // This should contain only the errors in the part file, not the ones in the |
| 1826 // library. |
| 1827 expect(errors, hasLength(1)); |
| 1828 } |
| 1829 } |
| 1830 |
| 1831 @reflectiveTest |
| 1832 class EvaluateUnitConstantsTaskTest extends _AbstractDartTaskTest { |
| 1833 test_perform() { |
| 1834 Source source = newSource( |
| 1835 '/test.dart', |
| 1836 ''' |
| 1837 class C { |
| 1838 const C(); |
| 1839 } |
| 1840 |
| 1841 @x |
| 1842 f() {} |
| 1843 |
| 1844 const x = const C(); |
| 1845 '''); |
| 1846 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1847 computeResult(target, RESOLVED_UNIT, matcher: isEvaluateUnitConstantsTask); |
| 1848 CompilationUnit unit = outputs[RESOLVED_UNIT]; |
| 1849 CompilationUnitElement unitElement = unit.element; |
| 1850 expect( |
| 1851 (unitElement.types[0].constructors[0] as ConstructorElementImpl) |
| 1852 .isCycleFree, |
| 1853 isTrue); |
| 1854 expect( |
| 1855 (unitElement.functions[0].metadata[0] as ElementAnnotationImpl) |
| 1856 .evaluationResult, |
| 1857 isNotNull); |
| 1858 expect( |
| 1859 (unitElement.topLevelVariables[0] as TopLevelVariableElementImpl) |
| 1860 .evaluationResult, |
| 1861 isNotNull); |
| 1862 } |
| 1863 } |
| 1864 |
| 1865 @reflectiveTest |
| 1866 class GatherUsedImportedElementsTaskTest extends _AbstractDartTaskTest { |
| 1867 UsedImportedElements usedElements; |
| 1868 Set<String> usedElementNames; |
| 1869 |
| 1870 test_perform() { |
| 1871 newSource( |
| 1872 '/a.dart', |
| 1873 r''' |
| 1874 library lib_a; |
| 1875 class A {} |
| 1876 '''); |
| 1877 newSource( |
| 1878 '/b.dart', |
| 1879 r''' |
| 1880 library lib_b; |
| 1881 class B {} |
| 1882 '''); |
| 1883 Source source = newSource( |
| 1884 '/test.dart', |
| 1885 r''' |
| 1886 import 'a.dart'; |
| 1887 import 'b.dart'; |
| 1888 main() { |
| 1889 new A(); |
| 1890 }'''); |
| 1891 _computeUsedElements(source); |
| 1892 // validate |
| 1893 expect(usedElementNames, unorderedEquals(['A'])); |
| 1894 } |
| 1895 |
| 1896 void _computeUsedElements(Source source) { |
| 1897 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1898 computeResult(target, USED_IMPORTED_ELEMENTS, |
| 1899 matcher: isGatherUsedImportedElementsTask); |
| 1900 usedElements = outputs[USED_IMPORTED_ELEMENTS]; |
| 1901 usedElementNames = usedElements.elements.map((e) => e.name).toSet(); |
| 1902 } |
| 1903 } |
| 1904 |
| 1905 @reflectiveTest |
| 1906 class GatherUsedLocalElementsTaskTest extends _AbstractDartTaskTest { |
| 1907 UsedLocalElements usedElements; |
| 1908 Set<String> usedElementNames; |
| 1909 |
| 1910 fail_perform_forPart_afterLibraryUpdate() { |
| 1911 Source libSource = newSource( |
| 1912 '/my_lib.dart', |
| 1913 ''' |
| 1914 library my_lib; |
| 1915 part 'my_part.dart'; |
| 1916 foo() => null; |
| 1917 class _LocalClass {} |
| 1918 '''); |
| 1919 Source partSource = newSource( |
| 1920 '/my_part.dart', |
| 1921 ''' |
| 1922 part of my_lib; |
| 1923 bar() { |
| 1924 print(_LocalClass); |
| 1925 } |
| 1926 '''); |
| 1927 AnalysisTarget libTarget = new LibrarySpecificUnit(libSource, libSource); |
| 1928 AnalysisTarget partTarget = new LibrarySpecificUnit(libSource, partSource); |
| 1929 computeResult(libTarget, USED_LOCAL_ELEMENTS); |
| 1930 computeResult(partTarget, USED_LOCAL_ELEMENTS); |
| 1931 // _LocalClass is used in my_part.dart |
| 1932 { |
| 1933 UsedLocalElements usedElements = |
| 1934 analysisCache.getValue(partTarget, USED_LOCAL_ELEMENTS); |
| 1935 expect(usedElements.elements, contains(predicate((Element e) { |
| 1936 return e.displayName == '_LocalClass'; |
| 1937 }))); |
| 1938 } |
| 1939 // change my_lib.dart and recompute |
| 1940 context.setContents( |
| 1941 libSource, |
| 1942 ''' |
| 1943 library my_lib; |
| 1944 part 'my_part.dart'; |
| 1945 String foo() => null; |
| 1946 class _LocalClass {} |
| 1947 '''); |
| 1948 computeResult(libTarget, USED_LOCAL_ELEMENTS); |
| 1949 computeResult(partTarget, USED_LOCAL_ELEMENTS); |
| 1950 // _LocalClass should still be used in my_part.dart |
| 1951 { |
| 1952 UsedLocalElements usedElements = |
| 1953 analysisCache.getValue(partTarget, USED_LOCAL_ELEMENTS); |
| 1954 expect(usedElements.elements, contains(predicate((Element e) { |
| 1955 return e.displayName == '_LocalClass'; |
| 1956 }))); |
| 1957 } |
| 1958 } |
| 1959 |
| 1960 test_perform_localVariable() { |
| 1961 Source source = newSource( |
| 1962 '/test.dart', |
| 1963 r''' |
| 1964 main() { |
| 1965 var v1 = 1; |
| 1966 var v2 = 2; |
| 1967 print(v2); |
| 1968 }'''); |
| 1969 _computeUsedElements(source); |
| 1970 // validate |
| 1971 expect(usedElementNames, unorderedEquals(['v2'])); |
| 1972 } |
| 1973 |
| 1974 test_perform_method() { |
| 1975 Source source = newSource( |
| 1976 '/test.dart', |
| 1977 r''' |
| 1978 class A { |
| 1979 _m1() {} |
| 1980 _m2() {} |
| 1981 } |
| 1982 |
| 1983 main(A a, p) { |
| 1984 a._m2(); |
| 1985 p._m3(); |
| 1986 } |
| 1987 '''); |
| 1988 _computeUsedElements(source); |
| 1989 // validate |
| 1990 expect(usedElementNames, unorderedEquals(['A', 'a', 'p', '_m2'])); |
| 1991 expect(usedElements.members, unorderedEquals(['_m2', '_m3'])); |
| 1992 } |
| 1993 |
| 1994 void _computeUsedElements(Source source) { |
| 1995 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1996 computeResult(target, USED_LOCAL_ELEMENTS, |
| 1997 matcher: isGatherUsedLocalElementsTask); |
| 1998 usedElements = outputs[USED_LOCAL_ELEMENTS]; |
| 1999 usedElementNames = usedElements.elements.map((e) => e.name).toSet(); |
| 2000 } |
| 2001 } |
| 2002 |
| 2003 @reflectiveTest |
| 2004 class GenerateHintsTaskTest extends _AbstractDartTaskTest { |
| 2005 test_perform_bestPractices_missingReturn() { |
| 2006 Source source = newSource( |
| 2007 '/test.dart', |
| 2008 ''' |
| 2009 int main() { |
| 2010 } |
| 2011 '''); |
| 2012 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2013 computeResult(target, HINTS, matcher: isGenerateHintsTask); |
| 2014 // validate |
| 2015 _fillErrorListener(HINTS); |
| 2016 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.MISSING_RETURN]); |
| 2017 } |
| 2018 |
| 2019 test_perform_dart2js() { |
| 2020 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); |
| 2021 options.dart2jsHint = true; |
| 2022 prepareAnalysisContext(options); |
| 2023 Source source = newSource( |
| 2024 '/test.dart', |
| 2025 ''' |
| 2026 main(p) { |
| 2027 if (p is double) { |
| 2028 print('double'); |
| 2029 } |
| 2030 } |
| 2031 '''); |
| 2032 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2033 computeResult(target, HINTS, matcher: isGenerateHintsTask); |
| 2034 // validate |
| 2035 _fillErrorListener(HINTS); |
| 2036 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.IS_DOUBLE]); |
| 2037 } |
| 2038 |
| 2039 test_perform_deadCode() { |
| 2040 Source source = newSource( |
| 2041 '/test.dart', |
| 2042 ''' |
| 2043 main() { |
| 2044 if (false) { |
| 2045 print('how?'); |
| 2046 } |
| 2047 } |
| 2048 '''); |
| 2049 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2050 computeResult(target, HINTS, matcher: isGenerateHintsTask); |
| 2051 // validate |
| 2052 _fillErrorListener(HINTS); |
| 2053 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.DEAD_CODE]); |
| 2054 } |
| 2055 |
| 2056 test_perform_disabled() { |
| 2057 context.analysisOptions = |
| 2058 new AnalysisOptionsImpl.from(context.analysisOptions)..hint = false; |
| 2059 Source source = newSource( |
| 2060 '/test.dart', |
| 2061 ''' |
| 2062 int main() { |
| 2063 } |
| 2064 '''); |
| 2065 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2066 computeResult(target, HINTS, matcher: isGenerateHintsTask); |
| 2067 // validate |
| 2068 _fillErrorListener(HINTS); |
| 2069 errorListener.assertNoErrors(); |
| 2070 } |
| 2071 |
| 2072 test_perform_imports_duplicateImport() { |
| 2073 newSource( |
| 2074 '/a.dart', |
| 2075 r''' |
| 2076 library lib_a; |
| 2077 class A {} |
| 2078 '''); |
| 2079 Source source = newSource( |
| 2080 '/test.dart', |
| 2081 r''' |
| 2082 import 'a.dart'; |
| 2083 import 'a.dart'; |
| 2084 main() { |
| 2085 new A(); |
| 2086 } |
| 2087 '''); |
| 2088 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2089 computeResult(target, HINTS, matcher: isGenerateHintsTask); |
| 2090 // validate |
| 2091 _fillErrorListener(HINTS); |
| 2092 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.DUPLICATE_IMPORT]); |
| 2093 } |
| 2094 |
| 2095 test_perform_imports_unusedImport_one() { |
| 2096 newSource( |
| 2097 '/a.dart', |
| 2098 r''' |
| 2099 library lib_a; |
| 2100 class A {} |
| 2101 '''); |
| 2102 newSource( |
| 2103 '/b.dart', |
| 2104 r''' |
| 2105 library lib_b; |
| 2106 class B {} |
| 2107 '''); |
| 2108 Source source = newSource( |
| 2109 '/test.dart', |
| 2110 r''' |
| 2111 import 'a.dart'; |
| 2112 import 'b.dart'; |
| 2113 main() { |
| 2114 new A(); |
| 2115 }'''); |
| 2116 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2117 computeResult(target, HINTS, matcher: isGenerateHintsTask); |
| 2118 // validate |
| 2119 _fillErrorListener(HINTS); |
| 2120 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.UNUSED_IMPORT]); |
| 2121 } |
| 2122 |
| 2123 test_perform_imports_unusedImport_zero() { |
| 2124 newSource( |
| 2125 '/a.dart', |
| 2126 r''' |
| 2127 library lib_a; |
| 2128 class A {} |
| 2129 '''); |
| 2130 Source source = newSource( |
| 2131 '/test.dart', |
| 2132 r''' |
| 2133 import 'a.dart'; |
| 2134 main() { |
| 2135 new A(); |
| 2136 }'''); |
| 2137 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2138 computeResult(target, HINTS, matcher: isGenerateHintsTask); |
| 2139 // validate |
| 2140 _fillErrorListener(HINTS); |
| 2141 errorListener.assertNoErrors(); |
| 2142 } |
| 2143 |
| 2144 test_perform_overrideVerifier() { |
| 2145 Source source = newSource( |
| 2146 '/test.dart', |
| 2147 ''' |
| 2148 class A {} |
| 2149 class B { |
| 2150 @override |
| 2151 m() {} |
| 2152 } |
| 2153 '''); |
| 2154 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2155 computeResult(target, HINTS, matcher: isGenerateHintsTask); |
| 2156 // validate |
| 2157 _fillErrorListener(HINTS); |
| 2158 errorListener.assertErrorsWithCodes( |
| 2159 <ErrorCode>[HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]); |
| 2160 } |
| 2161 |
| 2162 test_perform_todo() { |
| 2163 Source source = newSource( |
| 2164 '/test.dart', |
| 2165 ''' |
| 2166 main() { |
| 2167 // TODO(developer) foo bar |
| 2168 } |
| 2169 '''); |
| 2170 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2171 computeResult(target, HINTS, matcher: isGenerateHintsTask); |
| 2172 // validate |
| 2173 _fillErrorListener(HINTS); |
| 2174 errorListener.assertErrorsWithCodes(<ErrorCode>[TodoCode.TODO]); |
| 2175 } |
| 2176 |
| 2177 test_perform_unusedLocalElements_class() { |
| 2178 Source source = newSource( |
| 2179 '/test.dart', |
| 2180 ''' |
| 2181 class _A {} |
| 2182 class _B {} |
| 2183 main() { |
| 2184 new _A(); |
| 2185 } |
| 2186 '''); |
| 2187 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2188 computeResult(target, HINTS, matcher: isGenerateHintsTask); |
| 2189 // validate |
| 2190 _fillErrorListener(HINTS); |
| 2191 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.UNUSED_ELEMENT]); |
| 2192 } |
| 2193 |
| 2194 test_perform_unusedLocalElements_localVariable() { |
| 2195 Source source = newSource( |
| 2196 '/test.dart', |
| 2197 ''' |
| 2198 main() { |
| 2199 var v = 42; |
| 2200 } |
| 2201 '''); |
| 2202 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2203 computeResult(target, HINTS, matcher: isGenerateHintsTask); |
| 2204 // validate |
| 2205 _fillErrorListener(HINTS); |
| 2206 errorListener |
| 2207 .assertErrorsWithCodes(<ErrorCode>[HintCode.UNUSED_LOCAL_VARIABLE]); |
| 2208 } |
| 2209 |
| 2210 test_perform_unusedLocalElements_method() { |
| 2211 Source source = newSource( |
| 2212 '/my_lib.dart', |
| 2213 ''' |
| 2214 library my_lib; |
| 2215 part 'my_part.dart'; |
| 2216 class A { |
| 2217 _ma() {} |
| 2218 _mb() {} |
| 2219 _mc() {} |
| 2220 } |
| 2221 '''); |
| 2222 newSource( |
| 2223 '/my_part.dart', |
| 2224 ''' |
| 2225 part of my_lib; |
| 2226 |
| 2227 f(A a) { |
| 2228 a._mb(); |
| 2229 } |
| 2230 '''); |
| 2231 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2232 computeResult(target, HINTS, matcher: isGenerateHintsTask); |
| 2233 // validate |
| 2234 _fillErrorListener(HINTS); |
| 2235 errorListener.assertErrorsWithCodes( |
| 2236 <ErrorCode>[HintCode.UNUSED_ELEMENT, HintCode.UNUSED_ELEMENT]); |
| 2237 } |
| 2238 } |
| 2239 |
| 2240 @reflectiveTest |
| 2241 class GenerateLintsTaskTest extends _AbstractDartTaskTest { |
| 2242 void enableLints() { |
| 2243 AnalysisOptionsImpl options = context.analysisOptions; |
| 2244 options.lint = true; |
| 2245 context.analysisOptions = options; |
| 2246 } |
| 2247 |
| 2248 @override |
| 2249 void setUp() { |
| 2250 super.setUp(); |
| 2251 enableLints(); |
| 2252 } |
| 2253 |
| 2254 @override |
| 2255 void tearDown() { |
| 2256 LintGenerator.LINTERS.clear(); |
| 2257 super.tearDown(); |
| 2258 } |
| 2259 |
| 2260 test_camel_case_types() { |
| 2261 Source source = newSource( |
| 2262 '/test.dart', |
| 2263 ''' |
| 2264 class a { } |
| 2265 '''); |
| 2266 |
| 2267 LintGenerator.LINTERS.clear(); |
| 2268 LintGenerator.LINTERS.add(new GenerateLintsTaskTest_TestLinter()); |
| 2269 |
| 2270 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2271 computeResult(target, LINTS, matcher: isGenerateLintsTask); |
| 2272 // validate |
| 2273 _fillErrorListener(LINTS); |
| 2274 errorListener.assertErrorsWithCodes(<ErrorCode>[_testLintCode]); |
| 2275 } |
| 2276 } |
| 2277 |
| 2278 class GenerateLintsTaskTest_AstVisitor extends SimpleAstVisitor { |
| 2279 Linter linter; |
| 2280 GenerateLintsTaskTest_AstVisitor(this.linter); |
| 2281 |
| 2282 @override |
| 2283 visitClassDeclaration(ClassDeclaration node) { |
| 2284 if (!new RegExp(r'^([_]*)([A-Z]+[a-z0-9]*)+$') |
| 2285 .hasMatch(node.name.toString())) { |
| 2286 linter.reporter.reportErrorForNode(_testLintCode, node, []); |
| 2287 } |
| 2288 } |
| 2289 } |
| 2290 |
| 2291 class GenerateLintsTaskTest_TestLinter extends Linter { |
| 2292 @override |
| 2293 AstVisitor getVisitor() => new GenerateLintsTaskTest_AstVisitor(this); |
| 2294 } |
| 2295 |
| 2296 @reflectiveTest |
| 2297 class InferInstanceMembersInUnitTaskTest extends _AbstractDartTaskTest { |
| 2298 void test_perform() { |
| 2299 enableStrongMode(); |
| 2300 AnalysisTarget source = newSource( |
| 2301 '/test.dart', |
| 2302 ''' |
| 2303 class A { |
| 2304 X f; |
| 2305 Y m(Z x) {} |
| 2306 } |
| 2307 class B extends A { |
| 2308 var f; |
| 2309 m(x) {} |
| 2310 } |
| 2311 class X {} |
| 2312 class Y {} |
| 2313 class Z {} |
| 2314 '''); |
| 2315 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8, |
| 2316 matcher: isInferInstanceMembersInUnitTask); |
| 2317 CompilationUnit unit = outputs[RESOLVED_UNIT8]; |
| 2318 VariableDeclaration field = getFieldInClass(unit, 'B', 'f'); |
| 2319 MethodDeclaration method = getMethodInClass(unit, 'B', 'm'); |
| 2320 DartType typeX = getClass(unit, 'X').element.type; |
| 2321 DartType typeY = getClass(unit, 'Y').element.type; |
| 2322 DartType typeZ = getClass(unit, 'Z').element.type; |
| 2323 |
| 2324 expect(field.element.type, typeX); |
| 2325 expect(method.element.returnType, typeY); |
| 2326 expect(method.element.parameters[0].type, typeZ); |
| 2327 } |
| 2328 |
| 2329 void test_perform_cross_library_const() { |
| 2330 enableStrongMode(); |
| 2331 AnalysisTarget firstSource = newSource( |
| 2332 '/first.dart', |
| 2333 ''' |
| 2334 library first; |
| 2335 |
| 2336 const a = 'hello'; |
| 2337 '''); |
| 2338 AnalysisTarget secondSource = newSource( |
| 2339 '/second.dart', |
| 2340 ''' |
| 2341 import 'first.dart'; |
| 2342 |
| 2343 const b = a; |
| 2344 class M { |
| 2345 String c = a; |
| 2346 } |
| 2347 '''); |
| 2348 computeResult( |
| 2349 new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT8, |
| 2350 matcher: isInferInstanceMembersInUnitTask); |
| 2351 CompilationUnit firstUnit = outputs[RESOLVED_UNIT8]; |
| 2352 computeResult( |
| 2353 new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT8); |
| 2354 CompilationUnit secondUnit = outputs[RESOLVED_UNIT8]; |
| 2355 |
| 2356 VariableDeclaration variableA = getTopLevelVariable(firstUnit, 'a'); |
| 2357 VariableDeclaration variableB = getTopLevelVariable(secondUnit, 'b'); |
| 2358 VariableDeclaration variableC = getFieldInClass(secondUnit, 'M', 'c'); |
| 2359 InterfaceType stringType = context.typeProvider.stringType; |
| 2360 |
| 2361 expect(variableA.element.type, stringType); |
| 2362 expect(variableB.element.type, stringType); |
| 2363 expect(variableB.initializer.staticType, stringType); |
| 2364 expect(variableC.element.type, stringType); |
| 2365 expect(variableC.initializer.staticType, stringType); |
| 2366 } |
| 2367 |
| 2368 void test_perform_reresolution() { |
| 2369 enableStrongMode(); |
| 2370 AnalysisTarget source = newSource( |
| 2371 '/test.dart', |
| 2372 ''' |
| 2373 const topLevel = ''; |
| 2374 class C { |
| 2375 String field = topLevel; |
| 2376 } |
| 2377 '''); |
| 2378 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8); |
| 2379 CompilationUnit unit = outputs[RESOLVED_UNIT8]; |
| 2380 VariableDeclaration topLevelDecl = getTopLevelVariable(unit, 'topLevel'); |
| 2381 VariableDeclaration fieldDecl = getFieldInClass(unit, 'C', 'field'); |
| 2382 VariableElement topLevel = topLevelDecl.name.staticElement; |
| 2383 VariableElement field = fieldDecl.name.staticElement; |
| 2384 |
| 2385 InterfaceType stringType = context.typeProvider.stringType; |
| 2386 expect(topLevel.type, stringType); |
| 2387 expect(field.type, stringType); |
| 2388 expect(fieldDecl.initializer.staticType, stringType); |
| 2389 } |
| 2390 } |
| 2391 |
| 2392 @reflectiveTest |
| 2393 class InferStaticVariableTypesInUnitTaskTest extends _AbstractDartTaskTest { |
| 2394 void test_perform_const_field() { |
| 2395 enableStrongMode(); |
| 2396 AnalysisTarget source = newSource( |
| 2397 '/test.dart', |
| 2398 ''' |
| 2399 class M { |
| 2400 static const X = ""; |
| 2401 } |
| 2402 '''); |
| 2403 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6, |
| 2404 matcher: isInferStaticVariableTypesInUnitTask); |
| 2405 CompilationUnit unit = outputs[RESOLVED_UNIT6]; |
| 2406 VariableDeclaration declaration = getFieldInClass(unit, 'M', 'X'); |
| 2407 InterfaceType stringType = context.typeProvider.stringType; |
| 2408 expect(declaration.element.type, stringType); |
| 2409 } |
| 2410 |
| 2411 void test_perform_nestedDeclarations() { |
| 2412 enableStrongMode(); |
| 2413 AnalysisTarget source = newSource( |
| 2414 '/test.dart', |
| 2415 ''' |
| 2416 var f = (int x) { |
| 2417 int squared(int value) => value * value; |
| 2418 var xSquared = squared(x); |
| 2419 return xSquared; |
| 2420 }; |
| 2421 '''); |
| 2422 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6, |
| 2423 matcher: isInferStaticVariableTypesInUnitTask); |
| 2424 } |
| 2425 |
| 2426 void test_perform_recursive() { |
| 2427 enableStrongMode(); |
| 2428 AnalysisTarget firstSource = newSource( |
| 2429 '/first.dart', |
| 2430 ''' |
| 2431 import 'second.dart'; |
| 2432 |
| 2433 var a = new M(); |
| 2434 var c = b; |
| 2435 '''); |
| 2436 AnalysisTarget secondSource = newSource( |
| 2437 '/second.dart', |
| 2438 ''' |
| 2439 import 'first.dart'; |
| 2440 |
| 2441 var b = a; |
| 2442 class M {} |
| 2443 '''); |
| 2444 computeResult( |
| 2445 new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT6, |
| 2446 matcher: isInferStaticVariableTypesInUnitTask); |
| 2447 CompilationUnit firstUnit = outputs[RESOLVED_UNIT6]; |
| 2448 computeResult( |
| 2449 new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT6); |
| 2450 CompilationUnit secondUnit = outputs[RESOLVED_UNIT6]; |
| 2451 |
| 2452 VariableDeclaration variableA = getTopLevelVariable(firstUnit, 'a'); |
| 2453 VariableDeclaration variableB = getTopLevelVariable(secondUnit, 'b'); |
| 2454 VariableDeclaration variableC = getTopLevelVariable(firstUnit, 'c'); |
| 2455 ClassDeclaration classM = getClass(secondUnit, 'M'); |
| 2456 DartType typeM = classM.element.type; |
| 2457 |
| 2458 expect(variableA.element.type, typeM); |
| 2459 expect(variableB.element.type, typeM); |
| 2460 expect(variableB.initializer.staticType, typeM); |
| 2461 expect(variableC.element.type, typeM); |
| 2462 expect(variableC.initializer.staticType, typeM); |
| 2463 } |
| 2464 |
| 2465 void test_perform_simple() { |
| 2466 enableStrongMode(); |
| 2467 AnalysisTarget source = newSource( |
| 2468 '/test.dart', |
| 2469 ''' |
| 2470 var X = 1; |
| 2471 |
| 2472 var Y = () { |
| 2473 return 1 + X; |
| 2474 }; |
| 2475 '''); |
| 2476 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6, |
| 2477 matcher: isInferStaticVariableTypesInUnitTask); |
| 2478 CompilationUnit unit = outputs[RESOLVED_UNIT6]; |
| 2479 TopLevelVariableDeclaration declaration = unit.declarations[1]; |
| 2480 FunctionExpression function = |
| 2481 declaration.variables.variables[0].initializer; |
| 2482 BlockFunctionBody body = function.body; |
| 2483 ReturnStatement statement = body.block.statements[0]; |
| 2484 Expression expression = statement.expression; |
| 2485 InterfaceType intType = context.typeProvider.intType; |
| 2486 expect(expression.staticType, intType); |
| 2487 } |
| 2488 } |
| 2489 |
| 2490 @reflectiveTest |
| 2491 class InferStaticVariableTypeTaskTest extends _AbstractDartTaskTest { |
| 2492 void test_getDeclaration_staticField() { |
| 2493 AnalysisTarget source = newSource( |
| 2494 '/test.dart', |
| 2495 ''' |
| 2496 class C { |
| 2497 var field = ''; |
| 2498 } |
| 2499 '''); |
| 2500 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5); |
| 2501 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 2502 VariableDeclaration declaration = getFieldInClass(unit, 'C', 'field'); |
| 2503 VariableElement variable = declaration.name.staticElement; |
| 2504 InferStaticVariableTypeTask inferTask = |
| 2505 new InferStaticVariableTypeTask(task.context, variable); |
| 2506 expect(inferTask.getDeclaration(unit), declaration); |
| 2507 } |
| 2508 |
| 2509 void test_getDeclaration_topLevel() { |
| 2510 AnalysisTarget source = newSource( |
| 2511 '/test.dart', |
| 2512 ''' |
| 2513 var topLevel = ''; |
| 2514 '''); |
| 2515 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5); |
| 2516 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 2517 VariableDeclaration declaration = getTopLevelVariable(unit, 'topLevel'); |
| 2518 VariableElement variable = declaration.name.staticElement; |
| 2519 InferStaticVariableTypeTask inferTask = |
| 2520 new InferStaticVariableTypeTask(task.context, variable); |
| 2521 expect(inferTask.getDeclaration(unit), declaration); |
| 2522 } |
| 2523 |
| 2524 void test_perform() { |
| 2525 enableStrongMode(); |
| 2526 AnalysisTarget source = newSource( |
| 2527 '/test3.dart', |
| 2528 ''' |
| 2529 var topLevel3 = ''; |
| 2530 class C { |
| 2531 var field3 = topLevel3; |
| 2532 } |
| 2533 '''); |
| 2534 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5); |
| 2535 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 2536 VariableDeclaration topLevelDecl = getTopLevelVariable(unit, 'topLevel3'); |
| 2537 VariableDeclaration fieldDecl = getFieldInClass(unit, 'C', 'field3'); |
| 2538 VariableElement topLevel = topLevelDecl.name.staticElement; |
| 2539 VariableElement field = fieldDecl.name.staticElement; |
| 2540 |
| 2541 computeResult(field, INFERRED_STATIC_VARIABLE, |
| 2542 matcher: isInferStaticVariableTypeTask); |
| 2543 InterfaceType stringType = context.typeProvider.stringType; |
| 2544 expect(topLevel.type, stringType); |
| 2545 expect(field.type, stringType); |
| 2546 expect(fieldDecl.initializer.staticType, stringType); |
| 2547 } |
| 2548 |
| 2549 void test_perform_const() { |
| 2550 enableStrongMode(); |
| 2551 AnalysisTarget source = newSource( |
| 2552 '/test.dart', |
| 2553 ''' |
| 2554 const topLevel = "hello"; |
| 2555 class C { |
| 2556 var field = topLevel; |
| 2557 } |
| 2558 '''); |
| 2559 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5); |
| 2560 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 2561 VariableElement topLevel = |
| 2562 getTopLevelVariable(unit, 'topLevel').name.staticElement; |
| 2563 VariableElement field = |
| 2564 getFieldInClass(unit, 'C', 'field').name.staticElement; |
| 2565 |
| 2566 computeResult(field, INFERRED_STATIC_VARIABLE, |
| 2567 matcher: isInferStaticVariableTypeTask); |
| 2568 InterfaceType stringType = context.typeProvider.stringType; |
| 2569 expect(topLevel.type, stringType); |
| 2570 expect(field.type, stringType); |
| 2571 } |
| 2572 |
| 2573 void test_perform_cycle() { |
| 2574 enableStrongMode(); |
| 2575 AnalysisTarget source = newSource( |
| 2576 '/test.dart', |
| 2577 ''' |
| 2578 var piFirst = true; |
| 2579 var pi = piFirst ? 3.14 : tau / 2; |
| 2580 var tau = piFirst ? pi * 2 : 6.28; |
| 2581 '''); |
| 2582 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5); |
| 2583 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 2584 VariableElement piFirst = |
| 2585 getTopLevelVariable(unit, 'piFirst').name.staticElement; |
| 2586 VariableElement pi = getTopLevelVariable(unit, 'pi').name.staticElement; |
| 2587 VariableElement tau = getTopLevelVariable(unit, 'tau').name.staticElement; |
| 2588 |
| 2589 computeResult(piFirst, INFERRED_STATIC_VARIABLE, |
| 2590 matcher: isInferStaticVariableTypeTask); |
| 2591 expect(piFirst.type, context.typeProvider.boolType); |
| 2592 expect(pi.type.isDynamic, isTrue); |
| 2593 expect(tau.type.isDynamic, isTrue); |
| 2594 } |
| 2595 |
| 2596 void test_perform_error() { |
| 2597 enableStrongMode(); |
| 2598 AnalysisTarget source = newSource( |
| 2599 '/test.dart', |
| 2600 ''' |
| 2601 var a = '' / null; |
| 2602 '''); |
| 2603 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5); |
| 2604 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 2605 VariableElement a = getTopLevelVariable(unit, 'a').name.staticElement; |
| 2606 |
| 2607 computeResult(a, INFERRED_STATIC_VARIABLE, |
| 2608 matcher: isInferStaticVariableTypeTask); |
| 2609 expect(a.type.isDynamic, isTrue); |
| 2610 } |
| 2611 |
| 2612 void test_perform_null() { |
| 2613 enableStrongMode(); |
| 2614 AnalysisTarget source = newSource( |
| 2615 '/test.dart', |
| 2616 ''' |
| 2617 var a = null; |
| 2618 '''); |
| 2619 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5); |
| 2620 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 2621 VariableElement a = getTopLevelVariable(unit, 'a').name.staticElement; |
| 2622 |
| 2623 computeResult(a, INFERRED_STATIC_VARIABLE, |
| 2624 matcher: isInferStaticVariableTypeTask); |
| 2625 expect(a.type.isDynamic, isTrue); |
| 2626 } |
| 2627 } |
| 2628 |
| 2629 @reflectiveTest |
| 2630 class LibraryErrorsReadyTaskTest extends _AbstractDartTaskTest { |
| 2631 test_perform() { |
| 2632 Source library = newSource( |
| 2633 '/lib.dart', |
| 2634 r''' |
| 2635 library lib; |
| 2636 part 'part1.dart'; |
| 2637 part 'part2.dart'; |
| 2638 X v1; |
| 2639 '''); |
| 2640 Source part1 = newSource( |
| 2641 '/part1.dart', |
| 2642 r''' |
| 2643 part of lib; |
| 2644 X v2; |
| 2645 '''); |
| 2646 Source part2 = newSource( |
| 2647 '/part2.dart', |
| 2648 r''' |
| 2649 part of lib; |
| 2650 X v3; |
| 2651 '''); |
| 2652 computeResult(library, LIBRARY_ERRORS_READY, |
| 2653 matcher: isLibraryErrorsReadyTask); |
| 2654 expect(outputs, hasLength(1)); |
| 2655 bool ready = outputs[LIBRARY_ERRORS_READY]; |
| 2656 expect(ready, isTrue); |
| 2657 expect(context.getErrors(library).errors, hasLength(1)); |
| 2658 expect(context.getErrors(part1).errors, hasLength(1)); |
| 2659 expect(context.getErrors(part2).errors, hasLength(1)); |
| 2660 } |
| 2661 } |
| 2662 |
| 2663 @reflectiveTest |
| 2664 class LibraryUnitErrorsTaskTest extends _AbstractDartTaskTest { |
| 2665 test_perform_definingCompilationUnit() { |
| 2666 AnalysisTarget library = |
| 2667 newSource('/test.dart', 'library test; import "dart:math";'); |
| 2668 computeResult( |
| 2669 new LibrarySpecificUnit(library, library), LIBRARY_UNIT_ERRORS, |
| 2670 matcher: isLibraryUnitErrorsTask); |
| 2671 expect(outputs, hasLength(1)); |
| 2672 List<AnalysisError> errors = outputs[LIBRARY_UNIT_ERRORS]; |
| 2673 expect(errors, hasLength(1)); |
| 2674 } |
| 2675 |
| 2676 test_perform_partInSingleLibrary() { |
| 2677 AnalysisTarget library = |
| 2678 newSource('/lib.dart', 'library test; part "part.dart";'); |
| 2679 AnalysisTarget part = newSource('/part.dart', 'part of test;'); |
| 2680 computeResult(new LibrarySpecificUnit(library, part), LIBRARY_UNIT_ERRORS, |
| 2681 matcher: isLibraryUnitErrorsTask); |
| 2682 expect(outputs, hasLength(1)); |
| 2683 List<AnalysisError> errors = outputs[LIBRARY_UNIT_ERRORS]; |
| 2684 expect(errors, hasLength(0)); |
| 2685 } |
| 2686 } |
| 2687 |
| 2688 @reflectiveTest |
| 2689 class ParseDartTaskTest extends _AbstractDartTaskTest { |
| 2690 Source source; |
| 2691 |
| 2692 test_perform() { |
| 2693 _performParseTask(r''' |
| 2694 part of lib; |
| 2695 class B {}'''); |
| 2696 expect(outputs, hasLength(8)); |
| 2697 expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0)); |
| 2698 expect(outputs[EXPORTED_LIBRARIES], hasLength(0)); |
| 2699 _assertHasCore(outputs[IMPORTED_LIBRARIES], 1); |
| 2700 expect(outputs[INCLUDED_PARTS], hasLength(0)); |
| 2701 expect(outputs[PARSE_ERRORS], hasLength(0)); |
| 2702 expect(outputs[PARSED_UNIT], isNotNull); |
| 2703 expect(outputs[SOURCE_KIND], SourceKind.PART); |
| 2704 expect(outputs[UNITS], hasLength(1)); |
| 2705 } |
| 2706 |
| 2707 test_perform_computeSourceKind_noDirectives_hasContainingLibrary() { |
| 2708 // Parse "lib.dart" to let the context know that "test.dart" is included. |
| 2709 computeResult( |
| 2710 newSource( |
| 2711 '/lib.dart', |
| 2712 r''' |
| 2713 library lib; |
| 2714 part 'test.dart'; |
| 2715 '''), |
| 2716 PARSED_UNIT); |
| 2717 // If there are no the "part of" directive, then it is not a part. |
| 2718 _performParseTask(''); |
| 2719 expect(outputs[SOURCE_KIND], SourceKind.LIBRARY); |
| 2720 } |
| 2721 |
| 2722 test_perform_computeSourceKind_noDirectives_noContainingLibrary() { |
| 2723 _performParseTask(''); |
| 2724 expect(outputs[SOURCE_KIND], SourceKind.LIBRARY); |
| 2725 } |
| 2726 |
| 2727 test_perform_doesNotExist() { |
| 2728 _performParseTask(null); |
| 2729 expect(outputs, hasLength(8)); |
| 2730 expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0)); |
| 2731 expect(outputs[EXPORTED_LIBRARIES], hasLength(0)); |
| 2732 _assertHasCore(outputs[IMPORTED_LIBRARIES], 1); |
| 2733 expect(outputs[INCLUDED_PARTS], hasLength(0)); |
| 2734 expect(outputs[PARSE_ERRORS], hasLength(0)); |
| 2735 expect(outputs[PARSED_UNIT], isNotNull); |
| 2736 expect(outputs[SOURCE_KIND], SourceKind.UNKNOWN); |
| 2737 expect(outputs[UNITS], hasLength(1)); |
| 2738 } |
| 2739 |
| 2740 test_perform_invalidDirectives() { |
| 2741 _performParseTask(r''' |
| 2742 library lib; |
| 2743 import '/does/not/exist.dart'; |
| 2744 import '://invaliduri.dart'; |
| 2745 export '${a}lib3.dart'; |
| 2746 part 'part.dart'; |
| 2747 class A {}'''); |
| 2748 expect(outputs, hasLength(8)); |
| 2749 expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1)); |
| 2750 expect(outputs[EXPORTED_LIBRARIES], hasLength(0)); |
| 2751 _assertHasCore(outputs[IMPORTED_LIBRARIES], 2); |
| 2752 expect(outputs[INCLUDED_PARTS], hasLength(1)); |
| 2753 expect(outputs[PARSE_ERRORS], hasLength(2)); |
| 2754 expect(outputs[PARSED_UNIT], isNotNull); |
| 2755 expect(outputs[SOURCE_KIND], SourceKind.LIBRARY); |
| 2756 expect(outputs[UNITS], hasLength(2)); |
| 2757 } |
| 2758 |
| 2759 test_perform_library() { |
| 2760 _performParseTask(r''' |
| 2761 library lib; |
| 2762 import 'lib2.dart'; |
| 2763 export 'lib3.dart'; |
| 2764 part 'part.dart'; |
| 2765 class A {'''); |
| 2766 expect(outputs, hasLength(8)); |
| 2767 expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1)); |
| 2768 expect(outputs[EXPORTED_LIBRARIES], hasLength(1)); |
| 2769 _assertHasCore(outputs[IMPORTED_LIBRARIES], 2); |
| 2770 expect(outputs[INCLUDED_PARTS], hasLength(1)); |
| 2771 expect(outputs[PARSE_ERRORS], hasLength(1)); |
| 2772 expect(outputs[PARSED_UNIT], isNotNull); |
| 2773 expect(outputs[SOURCE_KIND], SourceKind.LIBRARY); |
| 2774 expect(outputs[UNITS], hasLength(2)); |
| 2775 } |
| 2776 |
| 2777 test_perform_library_selfReferenceAsPart() { |
| 2778 _performParseTask(r''' |
| 2779 library lib; |
| 2780 part 'test.dart'; |
| 2781 '''); |
| 2782 expect(outputs[INCLUDED_PARTS], unorderedEquals(<Source>[source])); |
| 2783 } |
| 2784 |
| 2785 test_perform_part() { |
| 2786 _performParseTask(r''' |
| 2787 part of lib; |
| 2788 class B {}'''); |
| 2789 expect(outputs, hasLength(8)); |
| 2790 expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0)); |
| 2791 expect(outputs[EXPORTED_LIBRARIES], hasLength(0)); |
| 2792 _assertHasCore(outputs[IMPORTED_LIBRARIES], 1); |
| 2793 expect(outputs[INCLUDED_PARTS], hasLength(0)); |
| 2794 expect(outputs[PARSE_ERRORS], hasLength(0)); |
| 2795 expect(outputs[PARSED_UNIT], isNotNull); |
| 2796 expect(outputs[SOURCE_KIND], SourceKind.PART); |
| 2797 expect(outputs[UNITS], hasLength(1)); |
| 2798 } |
| 2799 |
| 2800 void _performParseTask(String content) { |
| 2801 source = newSource('/test.dart', content); |
| 2802 computeResult(source, PARSED_UNIT, matcher: isParseDartTask); |
| 2803 } |
| 2804 |
| 2805 static void _assertHasCore(List<Source> sources, int lenght) { |
| 2806 expect(sources, hasLength(lenght)); |
| 2807 expect(sources, contains(predicate((Source s) { |
| 2808 return s.fullName.endsWith('core.dart'); |
| 2809 }))); |
| 2810 } |
| 2811 } |
| 2812 |
| 2813 @reflectiveTest |
| 2814 class PartiallyResolveUnitReferencesTaskTest extends _AbstractDartTaskTest { |
| 2815 test_perform() { |
| 2816 enableStrongMode(); |
| 2817 Source source = newSource( |
| 2818 '/test.dart', |
| 2819 ''' |
| 2820 int a = b; |
| 2821 int b = c; |
| 2822 var d = 0; |
| 2823 class A {} |
| 2824 class C { |
| 2825 static final f = ''; |
| 2826 var g = 0; |
| 2827 } |
| 2828 '''); |
| 2829 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2830 computeResult(target, RESOLVED_UNIT5, |
| 2831 matcher: isPartiallyResolveUnitReferencesTask); |
| 2832 // Test the outputs |
| 2833 expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(4)); |
| 2834 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 2835 expect(unit, same(outputs[RESOLVED_UNIT5])); |
| 2836 // Test the state of the AST |
| 2837 TopLevelVariableDeclaration a = unit.declarations[0]; |
| 2838 VariableDeclaration variableA = a.variables.variables[0]; |
| 2839 SimpleIdentifier initializer = variableA.initializer; |
| 2840 expect(initializer.staticElement, isNotNull); |
| 2841 } |
| 2842 |
| 2843 test_perform_importExport() { |
| 2844 newSource( |
| 2845 '/a.dart', |
| 2846 ''' |
| 2847 library a; |
| 2848 class A<T> { |
| 2849 T m() {} |
| 2850 } |
| 2851 '''); |
| 2852 newSource( |
| 2853 '/b.dart', |
| 2854 ''' |
| 2855 library b; |
| 2856 export 'a.dart'; |
| 2857 '''); |
| 2858 Source sourceC = newSource( |
| 2859 '/c.dart', |
| 2860 ''' |
| 2861 library c; |
| 2862 import 'b.dart'; |
| 2863 main() { |
| 2864 new A<int>().m(); |
| 2865 } |
| 2866 '''); |
| 2867 computeResult(new LibrarySpecificUnit(sourceC, sourceC), RESOLVED_UNIT5, |
| 2868 matcher: isPartiallyResolveUnitReferencesTask); |
| 2869 // validate |
| 2870 expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(0)); |
| 2871 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 2872 expect(unit, isNotNull); |
| 2873 |
| 2874 FunctionDeclaration mainFunction = unit.declarations[0]; |
| 2875 expect(mainFunction.element, isNotNull); |
| 2876 BlockFunctionBody body = mainFunction.functionExpression.body; |
| 2877 List<Statement> statements = body.block.statements; |
| 2878 ExpressionStatement statement = statements[0]; |
| 2879 MethodInvocation invocation = statement.expression; |
| 2880 MethodElement methodElement = invocation.methodName.staticElement; |
| 2881 expect(methodElement, isNull); |
| 2882 } |
| 2883 |
| 2884 test_perform_notResolved() { |
| 2885 enableStrongMode(); |
| 2886 Source source = newSource( |
| 2887 '/test.dart', |
| 2888 ''' |
| 2889 int A; |
| 2890 f1() { |
| 2891 A; |
| 2892 } |
| 2893 var f2 = () { |
| 2894 A; |
| 2895 void f3() { |
| 2896 A; |
| 2897 } |
| 2898 } |
| 2899 class C { |
| 2900 C() { |
| 2901 A; |
| 2902 } |
| 2903 m() { |
| 2904 A; |
| 2905 } |
| 2906 } |
| 2907 '''); |
| 2908 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2909 computeResult(target, RESOLVED_UNIT5, |
| 2910 matcher: isPartiallyResolveUnitReferencesTask); |
| 2911 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 2912 NodeList<CompilationUnitMember> declarations = unit.declarations; |
| 2913 |
| 2914 void expectReference(BlockFunctionBody body, bool isResolved) { |
| 2915 ExpressionStatement statement = body.block.statements[0]; |
| 2916 SimpleIdentifier reference = statement.expression; |
| 2917 expect(reference.staticElement, isResolved ? isNotNull : isNull); |
| 2918 } |
| 2919 // |
| 2920 // The reference to 'A' in 'f1' should not be resolved. |
| 2921 // |
| 2922 FunctionDeclaration f1 = declarations[1]; |
| 2923 expectReference(f1.functionExpression.body, false); |
| 2924 // |
| 2925 // The references to 'A' in 'f2' should be resolved. |
| 2926 // |
| 2927 TopLevelVariableDeclaration f2 = declarations[2]; |
| 2928 FunctionExpression expression2 = f2.variables.variables[0].initializer; |
| 2929 BlockFunctionBody body2 = expression2.body; |
| 2930 expectReference(body2, true); |
| 2931 |
| 2932 FunctionDeclarationStatement statement2 = body2.block.statements[1]; |
| 2933 BlockFunctionBody innerBody = |
| 2934 statement2.functionDeclaration.functionExpression.body; |
| 2935 expectReference(innerBody, true); |
| 2936 // |
| 2937 // The references to 'A' in 'C' should not be resolved. |
| 2938 // |
| 2939 ClassDeclaration c = declarations[3]; |
| 2940 NodeList<ClassMember> members = c.members; |
| 2941 |
| 2942 ConstructorDeclaration constructor = members[0]; |
| 2943 expectReference(constructor.body, false); |
| 2944 |
| 2945 MethodDeclaration method = members[1]; |
| 2946 expectReference(method.body, false); |
| 2947 } |
| 2948 } |
| 2949 |
| 2950 @reflectiveTest |
| 2951 class ResolveInstanceFieldsInUnitTaskTest extends _AbstractDartTaskTest { |
| 2952 @override |
| 2953 void setUp() { |
| 2954 super.setUp(); |
| 2955 enableStrongMode(); |
| 2956 } |
| 2957 |
| 2958 // Test inference of instance fields across units |
| 2959 void test_perform_inference_cross_unit_instance() { |
| 2960 List<Source> sources = newSources({ |
| 2961 '/a.dart': ''' |
| 2962 import 'b.dart'; |
| 2963 class A { |
| 2964 final a2 = new B().b2; |
| 2965 } |
| 2966 ''', |
| 2967 '/b.dart': ''' |
| 2968 class B { |
| 2969 final b2 = 1; |
| 2970 } |
| 2971 ''', |
| 2972 '/main.dart': ''' |
| 2973 import "a.dart"; |
| 2974 |
| 2975 test1() { |
| 2976 int x = 0; |
| 2977 x = new A().a2; |
| 2978 } |
| 2979 ''' |
| 2980 }); |
| 2981 InterfaceType intType = context.typeProvider.intType; |
| 2982 DartType dynamicType = context.typeProvider.dynamicType; |
| 2983 |
| 2984 computeResult( |
| 2985 new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT7); |
| 2986 CompilationUnit unit1 = outputs[RESOLVED_UNIT7]; |
| 2987 |
| 2988 // B.b2 shoud be resolved on the rhs, but not yet inferred. |
| 2989 assertVariableDeclarationTypes( |
| 2990 getFieldInClass(unit1, "B", "b2"), dynamicType, intType); |
| 2991 |
| 2992 computeResult( |
| 2993 new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7); |
| 2994 CompilationUnit unit0 = outputs[RESOLVED_UNIT7]; |
| 2995 |
| 2996 // B.b2 should now be fully resolved and inferred. |
| 2997 assertVariableDeclarationTypes( |
| 2998 getFieldInClass(unit1, "B", "b2"), intType, intType); |
| 2999 |
| 3000 // A.a2 should now be resolved on the rhs, but not yet inferred. |
| 3001 assertVariableDeclarationTypes( |
| 3002 getFieldInClass(unit0, "A", "a2"), dynamicType, intType); |
| 3003 |
| 3004 computeResult( |
| 3005 new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7); |
| 3006 CompilationUnit unit2 = outputs[RESOLVED_UNIT7]; |
| 3007 |
| 3008 // A.a2 should now be fully resolved and inferred. |
| 3009 assertVariableDeclarationTypes( |
| 3010 getFieldInClass(unit0, "A", "a2"), intType, intType); |
| 3011 |
| 3012 assertVariableDeclarationTypes( |
| 3013 getFieldInClass(unit1, "B", "b2"), intType, intType); |
| 3014 } |
| 3015 |
| 3016 // Test inference of instance fields across units |
| 3017 void test_perform_inference_cross_unit_instance_cyclic() { |
| 3018 List<Source> sources = newSources({ |
| 3019 '/a.dart': ''' |
| 3020 import 'b.dart'; |
| 3021 class A { |
| 3022 final a2 = new B().b2; |
| 3023 } |
| 3024 ''', |
| 3025 '/b.dart': ''' |
| 3026 import 'a.dart'; |
| 3027 class B { |
| 3028 final b2 = 1; |
| 3029 } |
| 3030 ''', |
| 3031 '/main.dart': ''' |
| 3032 import "a.dart"; |
| 3033 |
| 3034 test1() { |
| 3035 int x = 0; |
| 3036 x = new A().a2; |
| 3037 } |
| 3038 ''' |
| 3039 }); |
| 3040 InterfaceType intType = context.typeProvider.intType; |
| 3041 DartType dynamicType = context.typeProvider.dynamicType; |
| 3042 |
| 3043 computeResult( |
| 3044 new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7); |
| 3045 CompilationUnit unit0 = outputs[RESOLVED_UNIT7]; |
| 3046 |
| 3047 // A.a2 should now be resolved on the rhs, but not yet inferred. |
| 3048 assertVariableDeclarationTypes( |
| 3049 getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType); |
| 3050 |
| 3051 computeResult( |
| 3052 new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7); |
| 3053 CompilationUnit unit2 = outputs[RESOLVED_UNIT7]; |
| 3054 |
| 3055 // A.a2 should now be fully resolved and inferred. |
| 3056 assertVariableDeclarationTypes( |
| 3057 getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType); |
| 3058 } |
| 3059 |
| 3060 // Test inference of instance fields across units with cycles |
| 3061 void test_perform_inference_cross_unit_static_instance() { |
| 3062 List<Source> sources = newSources({ |
| 3063 '/a.dart': ''' |
| 3064 import 'b.dart'; |
| 3065 class A { |
| 3066 static final a1 = B.b1; |
| 3067 final a2 = new B().b2; |
| 3068 } |
| 3069 ''', |
| 3070 '/b.dart': ''' |
| 3071 class B { |
| 3072 static final b1 = 1; |
| 3073 final b2 = 1; |
| 3074 } |
| 3075 ''', |
| 3076 '/main.dart': ''' |
| 3077 import "a.dart"; |
| 3078 |
| 3079 test1() { |
| 3080 int x = 0; |
| 3081 // inference in A now works. |
| 3082 x = A.a1; |
| 3083 x = new A().a2; |
| 3084 } |
| 3085 ''' |
| 3086 }); |
| 3087 InterfaceType intType = context.typeProvider.intType; |
| 3088 DartType dynamicType = context.typeProvider.dynamicType; |
| 3089 |
| 3090 computeResult( |
| 3091 new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT7); |
| 3092 CompilationUnit unit1 = outputs[RESOLVED_UNIT7]; |
| 3093 |
| 3094 assertVariableDeclarationTypes( |
| 3095 getFieldInClass(unit1, "B", "b1"), intType, intType); |
| 3096 assertVariableDeclarationTypes( |
| 3097 getFieldInClass(unit1, "B", "b2"), dynamicType, intType); |
| 3098 |
| 3099 computeResult( |
| 3100 new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7); |
| 3101 CompilationUnit unit0 = outputs[RESOLVED_UNIT7]; |
| 3102 |
| 3103 assertVariableDeclarationTypes( |
| 3104 getFieldInClass(unit0, "A", "a1"), intType, intType); |
| 3105 assertVariableDeclarationTypes( |
| 3106 getFieldInClass(unit0, "A", "a2"), dynamicType, intType); |
| 3107 |
| 3108 assertVariableDeclarationTypes( |
| 3109 getFieldInClass(unit1, "B", "b1"), intType, intType); |
| 3110 assertVariableDeclarationTypes( |
| 3111 getFieldInClass(unit1, "B", "b2"), intType, intType); |
| 3112 |
| 3113 computeResult( |
| 3114 new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT7); |
| 3115 CompilationUnit unit2 = outputs[RESOLVED_UNIT7]; |
| 3116 |
| 3117 assertVariableDeclarationTypes( |
| 3118 getFieldInClass(unit0, "A", "a1"), intType, intType); |
| 3119 assertVariableDeclarationTypes( |
| 3120 getFieldInClass(unit0, "A", "a2"), intType, intType); |
| 3121 |
| 3122 assertVariableDeclarationTypes( |
| 3123 getFieldInClass(unit1, "B", "b1"), intType, intType); |
| 3124 assertVariableDeclarationTypes( |
| 3125 getFieldInClass(unit1, "B", "b2"), intType, intType); |
| 3126 } |
| 3127 |
| 3128 // Test inference between static and instance fields |
| 3129 void test_perform_inference_instance() { |
| 3130 List<Source> sources = newSources({ |
| 3131 '/a.dart': ''' |
| 3132 import 'b.dart'; |
| 3133 class A { |
| 3134 final a2 = new B().b2; |
| 3135 } |
| 3136 |
| 3137 class B { |
| 3138 final b2 = 1; |
| 3139 } |
| 3140 ''', |
| 3141 '/main.dart': ''' |
| 3142 import "a.dart"; |
| 3143 |
| 3144 test1() { |
| 3145 int x = 0; |
| 3146 x = new A().a2; |
| 3147 } |
| 3148 ''' |
| 3149 }); |
| 3150 InterfaceType intType = context.typeProvider.intType; |
| 3151 DartType dynamicType = context.typeProvider.dynamicType; |
| 3152 |
| 3153 computeResult( |
| 3154 new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT7); |
| 3155 CompilationUnit unit0 = outputs[RESOLVED_UNIT7]; |
| 3156 |
| 3157 // A.a2 should now be resolved on the rhs, but not yet inferred. |
| 3158 assertVariableDeclarationTypes( |
| 3159 getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType); |
| 3160 |
| 3161 // B.b2 shoud be resolved on the rhs, but not yet inferred. |
| 3162 assertVariableDeclarationTypes( |
| 3163 getFieldInClass(unit0, "B", "b2"), dynamicType, intType); |
| 3164 |
| 3165 computeResult( |
| 3166 new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT7); |
| 3167 CompilationUnit unit1 = outputs[RESOLVED_UNIT7]; |
| 3168 |
| 3169 // A.a2 should now be fully resolved and inferred. |
| 3170 assertVariableDeclarationTypes( |
| 3171 getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType); |
| 3172 |
| 3173 // B.b2 should now be fully resolved and inferred. |
| 3174 assertVariableDeclarationTypes( |
| 3175 getFieldInClass(unit0, "B", "b2"), intType, intType); |
| 3176 } |
| 3177 } |
| 3178 |
| 3179 @reflectiveTest |
| 3180 class ResolveLibraryTypeNamesTaskTest extends _AbstractDartTaskTest { |
| 3181 test_perform() { |
| 3182 Source sourceLib = newSource( |
| 3183 '/my_lib.dart', |
| 3184 ''' |
| 3185 library my_lib; |
| 3186 part 'my_part.dart'; |
| 3187 class A {} |
| 3188 class B extends A {} |
| 3189 '''); |
| 3190 newSource( |
| 3191 '/my_part.dart', |
| 3192 ''' |
| 3193 part of my_lib; |
| 3194 class C extends A {} |
| 3195 '''); |
| 3196 computeResult(sourceLib, LIBRARY_ELEMENT5, |
| 3197 matcher: isResolveLibraryTypeNamesTask); |
| 3198 // validate |
| 3199 LibraryElement library = outputs[LIBRARY_ELEMENT5]; |
| 3200 { |
| 3201 ClassElement classB = library.getType('B'); |
| 3202 expect(classB.supertype.displayName, 'A'); |
| 3203 } |
| 3204 { |
| 3205 ClassElement classC = library.getType('C'); |
| 3206 expect(classC.supertype.displayName, 'A'); |
| 3207 } |
| 3208 } |
| 3209 |
| 3210 test_perform_external() { |
| 3211 Source sourceA = newSource( |
| 3212 '/a.dart', |
| 3213 ''' |
| 3214 library a; |
| 3215 import 'b.dart'; |
| 3216 class A extends B {} |
| 3217 '''); |
| 3218 newSource( |
| 3219 '/b.dart', |
| 3220 ''' |
| 3221 library b; |
| 3222 class B {} |
| 3223 '''); |
| 3224 // The reference A to B should be resolved, but there's no requirement that |
| 3225 // the full class hierarchy be resolved. |
| 3226 computeResult(sourceA, LIBRARY_ELEMENT5, |
| 3227 matcher: isResolveLibraryTypeNamesTask); |
| 3228 // validate |
| 3229 LibraryElement library = outputs[LIBRARY_ELEMENT5]; |
| 3230 { |
| 3231 ClassElement clazz = library.getType('A'); |
| 3232 expect(clazz.displayName, 'A'); |
| 3233 clazz = clazz.supertype.element; |
| 3234 expect(clazz.displayName, 'B'); |
| 3235 } |
| 3236 } |
| 3237 } |
| 3238 |
| 3239 @reflectiveTest |
| 3240 class ResolveUnitTaskTest extends _AbstractDartTaskTest { |
| 3241 void test_perform() { |
| 3242 AnalysisTarget source = newSource( |
| 3243 '/test.dart', |
| 3244 ''' |
| 3245 void f() { |
| 3246 var c = new C(); |
| 3247 c.m(); |
| 3248 } |
| 3249 class C { |
| 3250 void m() { |
| 3251 f(); |
| 3252 } |
| 3253 } |
| 3254 '''); |
| 3255 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9, |
| 3256 matcher: isResolveUnitTask); |
| 3257 CompilationUnit unit = outputs[RESOLVED_UNIT9]; |
| 3258 |
| 3259 FunctionDeclaration f = unit.declarations[0]; |
| 3260 _assertResolved(f.functionExpression.body); |
| 3261 |
| 3262 MethodDeclaration m = (unit.declarations[1] as ClassDeclaration).members[0]; |
| 3263 _assertResolved(m.body); |
| 3264 |
| 3265 expect(outputs[RESOLVE_UNIT_ERRORS], hasLength(0)); |
| 3266 } |
| 3267 |
| 3268 void _assertResolved(FunctionBody body) { |
| 3269 ResolutionVerifier verifier = new ResolutionVerifier(); |
| 3270 body.accept(verifier); |
| 3271 verifier.assertResolved(); |
| 3272 } |
| 3273 } |
| 3274 |
| 3275 @reflectiveTest |
| 3276 class ResolveUnitTypeNamesTaskTest extends _AbstractDartTaskTest { |
| 3277 test_perform() { |
| 3278 Source source = newSource( |
| 3279 '/test.dart', |
| 3280 ''' |
| 3281 class A {} |
| 3282 class B extends A {} |
| 3283 int f(String p) => p.length; |
| 3284 '''); |
| 3285 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 3286 computeResult(target, RESOLVED_UNIT3, matcher: isResolveUnitTypeNamesTask); |
| 3287 // validate |
| 3288 CompilationUnit unit = outputs[RESOLVED_UNIT3]; |
| 3289 { |
| 3290 ClassDeclaration nodeA = unit.declarations[0]; |
| 3291 ClassDeclaration nodeB = unit.declarations[1]; |
| 3292 DartType extendsType = nodeB.extendsClause.superclass.type; |
| 3293 expect(extendsType, nodeA.element.type); |
| 3294 } |
| 3295 { |
| 3296 FunctionDeclaration functionNode = unit.declarations[2]; |
| 3297 DartType returnType = functionNode.returnType.type; |
| 3298 List<FormalParameter> parameters = |
| 3299 functionNode.functionExpression.parameters.parameters; |
| 3300 expect(returnType.displayName, 'int'); |
| 3301 expect(parameters[0].element.type.displayName, 'String'); |
| 3302 } |
| 3303 } |
| 3304 |
| 3305 test_perform_errors() { |
| 3306 Source source = newSource( |
| 3307 '/test.dart', |
| 3308 ''' |
| 3309 NoSuchClass f() => null; |
| 3310 '''); |
| 3311 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 3312 computeResult(target, RESOLVE_TYPE_NAMES_ERRORS, |
| 3313 matcher: isResolveUnitTypeNamesTask); |
| 3314 // validate |
| 3315 _fillErrorListener(RESOLVE_TYPE_NAMES_ERRORS); |
| 3316 errorListener |
| 3317 .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]); |
| 3318 } |
| 3319 |
| 3320 test_perform_typedef() { |
| 3321 Source source = newSource( |
| 3322 '/test.dart', |
| 3323 ''' |
| 3324 typedef int F(G g); |
| 3325 typedef String G(int p); |
| 3326 '''); |
| 3327 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 3328 computeResult(target, RESOLVED_UNIT3, matcher: isResolveUnitTypeNamesTask); |
| 3329 // validate |
| 3330 CompilationUnit unit = outputs[RESOLVED_UNIT3]; |
| 3331 FunctionTypeAlias nodeF = unit.declarations[0]; |
| 3332 FunctionTypeAlias nodeG = unit.declarations[1]; |
| 3333 { |
| 3334 FormalParameter parameter = nodeF.parameters.parameters[0]; |
| 3335 DartType parameterType = parameter.element.type; |
| 3336 Element returnTypeElement = nodeF.returnType.type.element; |
| 3337 expect(returnTypeElement.displayName, 'int'); |
| 3338 expect(parameterType.element, nodeG.element); |
| 3339 } |
| 3340 { |
| 3341 FormalParameter parameter = nodeG.parameters.parameters[0]; |
| 3342 DartType parameterType = parameter.element.type; |
| 3343 expect(nodeG.returnType.type.element.displayName, 'String'); |
| 3344 expect(parameterType.element.displayName, 'int'); |
| 3345 } |
| 3346 } |
| 3347 |
| 3348 test_perform_typedef_errors() { |
| 3349 Source source = newSource( |
| 3350 '/test.dart', |
| 3351 ''' |
| 3352 typedef int F(NoSuchType p); |
| 3353 '''); |
| 3354 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 3355 computeResult(target, RESOLVE_TYPE_NAMES_ERRORS, |
| 3356 matcher: isResolveUnitTypeNamesTask); |
| 3357 // validate |
| 3358 _fillErrorListener(RESOLVE_TYPE_NAMES_ERRORS); |
| 3359 errorListener |
| 3360 .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]); |
| 3361 } |
| 3362 } |
| 3363 |
| 3364 @reflectiveTest |
| 3365 class ResolveVariableReferencesTaskTest extends _AbstractDartTaskTest { |
| 3366 /** |
| 3367 * Verify that the mutated states of the given [variable] correspond to the |
| 3368 * [mutatedInClosure] and [mutatedInScope] matchers. |
| 3369 */ |
| 3370 void expectMutated(VariableElement variable, Matcher mutatedInClosure, |
| 3371 Matcher mutatedInScope) { |
| 3372 expect(variable.isPotentiallyMutatedInClosure, mutatedInClosure); |
| 3373 expect(variable.isPotentiallyMutatedInScope, mutatedInScope); |
| 3374 } |
| 3375 |
| 3376 test_perform_buildClosureLibraryElements() { |
| 3377 Source source = newSource( |
| 3378 '/test.dart', |
| 3379 ''' |
| 3380 main() { |
| 3381 } |
| 3382 '''); |
| 3383 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 3384 computeResult(target, RESOLVED_UNIT4, |
| 3385 matcher: isResolveVariableReferencesTask); |
| 3386 } |
| 3387 |
| 3388 test_perform_local() { |
| 3389 Source source = newSource( |
| 3390 '/test.dart', |
| 3391 ''' |
| 3392 main() { |
| 3393 var v1 = 1; |
| 3394 var v2 = 1; |
| 3395 var v3 = 1; |
| 3396 var v4 = 1; |
| 3397 v2 = 2; |
| 3398 v4 = 2; |
| 3399 localFunction() { |
| 3400 v3 = 3; |
| 3401 v4 = 3; |
| 3402 } |
| 3403 } |
| 3404 '''); |
| 3405 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 3406 computeResult(target, RESOLVED_UNIT4, |
| 3407 matcher: isResolveVariableReferencesTask); |
| 3408 // validate |
| 3409 CompilationUnit unit = outputs[RESOLVED_UNIT4]; |
| 3410 FunctionElement main = unit.element.functions[0]; |
| 3411 expectMutated(main.localVariables[0], isFalse, isFalse); |
| 3412 expectMutated(main.localVariables[1], isFalse, isTrue); |
| 3413 expectMutated(main.localVariables[2], isTrue, isTrue); |
| 3414 expectMutated(main.localVariables[3], isTrue, isTrue); |
| 3415 } |
| 3416 |
| 3417 test_perform_parameter() { |
| 3418 Source source = newSource( |
| 3419 '/test.dart', |
| 3420 ''' |
| 3421 main(p1, p2, p3, p4) { |
| 3422 p2 = 2; |
| 3423 p4 = 2; |
| 3424 localFunction() { |
| 3425 p3 = 3; |
| 3426 p4 = 3; |
| 3427 } |
| 3428 } |
| 3429 '''); |
| 3430 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 3431 computeResult(target, RESOLVED_UNIT4, |
| 3432 matcher: isResolveVariableReferencesTask); |
| 3433 // validate |
| 3434 CompilationUnit unit = outputs[RESOLVED_UNIT4]; |
| 3435 FunctionElement main = unit.element.functions[0]; |
| 3436 expectMutated(main.parameters[0], isFalse, isFalse); |
| 3437 expectMutated(main.parameters[1], isFalse, isTrue); |
| 3438 expectMutated(main.parameters[2], isTrue, isTrue); |
| 3439 expectMutated(main.parameters[3], isTrue, isTrue); |
| 3440 } |
| 3441 } |
| 3442 |
| 3443 @reflectiveTest |
| 3444 class ScanDartTaskTest extends _AbstractDartTaskTest { |
| 3445 test_perform_errors() { |
| 3446 _performScanTask('import "'); |
| 3447 expect(outputs, hasLength(3)); |
| 3448 expect(outputs[LINE_INFO], isNotNull); |
| 3449 expect(outputs[SCAN_ERRORS], hasLength(1)); |
| 3450 expect(outputs[TOKEN_STREAM], isNotNull); |
| 3451 } |
| 3452 |
| 3453 test_perform_noErrors() { |
| 3454 _performScanTask('class A {}'); |
| 3455 expect(outputs, hasLength(3)); |
| 3456 expect(outputs[LINE_INFO], isNotNull); |
| 3457 expect(outputs[SCAN_ERRORS], hasLength(0)); |
| 3458 expect(outputs[TOKEN_STREAM], isNotNull); |
| 3459 } |
| 3460 |
| 3461 test_perform_script() { |
| 3462 String scriptContent = ''' |
| 3463 void buttonPressed() { |
| 3464 '''; |
| 3465 String htmlContent = ''' |
| 3466 <!DOCTYPE html> |
| 3467 <html> |
| 3468 <head> |
| 3469 <title>test page</title> |
| 3470 <script type='application/dart'>$scriptContent</script> |
| 3471 </head> |
| 3472 <body>Test</body> |
| 3473 </html> |
| 3474 '''; |
| 3475 Source source = newSource('/test.html', htmlContent); |
| 3476 DartScript script = |
| 3477 new DartScript(source, [new ScriptFragment(97, 5, 36, scriptContent)]); |
| 3478 |
| 3479 computeResult(script, TOKEN_STREAM, matcher: isScanDartTask); |
| 3480 expect(outputs[LINE_INFO], isNotNull); |
| 3481 expect(outputs[SCAN_ERRORS], isEmpty); |
| 3482 Token tokenStream = outputs[TOKEN_STREAM]; |
| 3483 expect(tokenStream, isNotNull); |
| 3484 expect(tokenStream.lexeme, 'void'); |
| 3485 } |
| 3486 |
| 3487 void _performScanTask(String content) { |
| 3488 AnalysisTarget target = newSource('/test.dart', content); |
| 3489 computeResult(target, TOKEN_STREAM, matcher: isScanDartTask); |
| 3490 } |
| 3491 } |
| 3492 |
| 3493 @reflectiveTest |
| 3494 class StrongModeInferenceTest extends _AbstractDartTaskTest { |
| 3495 @override |
| 3496 void setUp() { |
| 3497 super.setUp(); |
| 3498 enableStrongMode(); |
| 3499 } |
| 3500 |
| 3501 // Check that even within a static variable cycle, inferred |
| 3502 // types get propagated to the members of the cycle. |
| 3503 void test_perform_cycle() { |
| 3504 AnalysisTarget source = newSource( |
| 3505 '/test.dart', |
| 3506 ''' |
| 3507 var piFirst = true; |
| 3508 var pi = piFirst ? 3.14 : tau / 2; |
| 3509 var tau = piFirst ? pi * 2 : 6.28; |
| 3510 '''); |
| 3511 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9); |
| 3512 CompilationUnit unit = outputs[RESOLVED_UNIT9]; |
| 3513 VariableElement piFirst = |
| 3514 getTopLevelVariable(unit, 'piFirst').name.staticElement; |
| 3515 VariableElement pi = getTopLevelVariable(unit, 'pi').name.staticElement; |
| 3516 VariableElement tau = getTopLevelVariable(unit, 'tau').name.staticElement; |
| 3517 Expression piFirstUse = (getTopLevelVariable(unit, 'tau').initializer |
| 3518 as ConditionalExpression).condition; |
| 3519 |
| 3520 expect(piFirstUse.staticType, context.typeProvider.boolType); |
| 3521 expect(piFirst.type, context.typeProvider.boolType); |
| 3522 expect(pi.type.isDynamic, isTrue); |
| 3523 expect(tau.type.isDynamic, isTrue); |
| 3524 } |
| 3525 |
| 3526 void test_perform_inference_cross_unit_cyclic() { |
| 3527 AnalysisTarget firstSource = newSource( |
| 3528 '/a.dart', |
| 3529 ''' |
| 3530 import 'test.dart'; |
| 3531 var x = 2; |
| 3532 class A { static var x = 2; } |
| 3533 '''); |
| 3534 AnalysisTarget secondSource = newSource( |
| 3535 '/test.dart', |
| 3536 ''' |
| 3537 import 'a.dart'; |
| 3538 var y = x; |
| 3539 class B { static var y = A.x; } |
| 3540 |
| 3541 test1() { |
| 3542 int t = 3; |
| 3543 t = x; |
| 3544 t = y; |
| 3545 t = A.x; |
| 3546 t = B.y; |
| 3547 } |
| 3548 '''); |
| 3549 computeResult( |
| 3550 new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT9); |
| 3551 CompilationUnit unit1 = outputs[RESOLVED_UNIT9]; |
| 3552 computeResult( |
| 3553 new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT9); |
| 3554 CompilationUnit unit2 = outputs[RESOLVED_UNIT9]; |
| 3555 |
| 3556 InterfaceType intType = context.typeProvider.intType; |
| 3557 |
| 3558 assertVariableDeclarationTypes( |
| 3559 getTopLevelVariable(unit1, "x"), intType, intType); |
| 3560 assertVariableDeclarationTypes( |
| 3561 getFieldInClass(unit1, "A", "x"), intType, intType); |
| 3562 |
| 3563 assertVariableDeclarationTypes( |
| 3564 getTopLevelVariable(unit2, "y"), intType, intType); |
| 3565 assertVariableDeclarationTypes( |
| 3566 getFieldInClass(unit2, "B", "y"), intType, intType); |
| 3567 |
| 3568 List<Statement> statements = |
| 3569 getStatementsInTopLevelFunction(unit2, "test1"); |
| 3570 |
| 3571 assertAssignmentStatementTypes(statements[1], intType, intType); |
| 3572 assertAssignmentStatementTypes(statements[2], intType, intType); |
| 3573 assertAssignmentStatementTypes(statements[3], intType, intType); |
| 3574 assertAssignmentStatementTypes(statements[4], intType, intType); |
| 3575 } |
| 3576 |
| 3577 // Test that local variables in method bodies are inferred appropriately |
| 3578 void test_perform_inference_cross_unit_instance() { |
| 3579 List<Source> sources = newSources({ |
| 3580 '/a.dart': ''' |
| 3581 import 'b.dart'; |
| 3582 class A { |
| 3583 final a2 = new B().b2; |
| 3584 } |
| 3585 ''', |
| 3586 '/b.dart': ''' |
| 3587 class B { |
| 3588 final b2 = 1; |
| 3589 } |
| 3590 ''', |
| 3591 '/main.dart': ''' |
| 3592 import "a.dart"; |
| 3593 |
| 3594 test1() { |
| 3595 int x = 0; |
| 3596 x = new A().a2; |
| 3597 } |
| 3598 ''' |
| 3599 }); |
| 3600 List<dynamic> units = |
| 3601 computeLibraryResults(sources, RESOLVED_UNIT9).toList(); |
| 3602 CompilationUnit unit0 = units[0]; |
| 3603 CompilationUnit unit1 = units[1]; |
| 3604 CompilationUnit unit2 = units[2]; |
| 3605 |
| 3606 InterfaceType intType = context.typeProvider.intType; |
| 3607 |
| 3608 assertVariableDeclarationTypes( |
| 3609 getFieldInClass(unit0, "A", "a2"), intType, intType); |
| 3610 |
| 3611 assertVariableDeclarationTypes( |
| 3612 getFieldInClass(unit1, "B", "b2"), intType, intType); |
| 3613 |
| 3614 List<Statement> statements = |
| 3615 getStatementsInTopLevelFunction(unit2, "test1"); |
| 3616 |
| 3617 assertAssignmentStatementTypes(statements[1], intType, intType); |
| 3618 } |
| 3619 |
| 3620 // Test inference interactions between local variables and fields |
| 3621 void test_perform_inference_cross_unit_instance_member() { |
| 3622 List<Source> sources = newSources({ |
| 3623 '/a.dart': ''' |
| 3624 import 'b.dart'; |
| 3625 var bar = new B(); |
| 3626 void foo() { |
| 3627 String x = bar.f.z; |
| 3628 } |
| 3629 ''', |
| 3630 '/b.dart': ''' |
| 3631 class C { |
| 3632 var z = 3; |
| 3633 } |
| 3634 |
| 3635 class B { |
| 3636 var f = new C(); |
| 3637 } |
| 3638 ''', |
| 3639 '/c.dart': ''' |
| 3640 import 'b.dart'; |
| 3641 var bar = new B(); |
| 3642 void foo() { |
| 3643 String x = bar.f.z; |
| 3644 } |
| 3645 ''' |
| 3646 }); |
| 3647 List<dynamic> units = |
| 3648 computeLibraryResults(sources, RESOLVED_UNIT9).toList(); |
| 3649 CompilationUnit unit0 = units[0]; |
| 3650 CompilationUnit unit1 = units[1]; |
| 3651 CompilationUnit unit2 = units[2]; |
| 3652 |
| 3653 InterfaceType intType = context.typeProvider.intType; |
| 3654 InterfaceType stringType = context.typeProvider.stringType; |
| 3655 |
| 3656 assertVariableDeclarationStatementTypes( |
| 3657 getStatementsInTopLevelFunction(unit0, "foo")[0], stringType, intType); |
| 3658 assertVariableDeclarationStatementTypes( |
| 3659 getStatementsInTopLevelFunction(unit2, "foo")[0], stringType, intType); |
| 3660 } |
| 3661 |
| 3662 // Test inference interactions between local variables and top level |
| 3663 // variables |
| 3664 void test_perform_inference_cross_unit_non_cyclic() { |
| 3665 AnalysisTarget firstSource = newSource( |
| 3666 '/a.dart', |
| 3667 ''' |
| 3668 var x = 2; |
| 3669 class A { static var x = 2; } |
| 3670 '''); |
| 3671 AnalysisTarget secondSource = newSource( |
| 3672 '/test.dart', |
| 3673 ''' |
| 3674 import 'a.dart'; |
| 3675 var y = x; |
| 3676 class B { static var y = A.x; } |
| 3677 |
| 3678 test1() { |
| 3679 x = /*severe:StaticTypeError*/"hi"; |
| 3680 y = /*severe:StaticTypeError*/"hi"; |
| 3681 A.x = /*severe:StaticTypeError*/"hi"; |
| 3682 B.y = /*severe:StaticTypeError*/"hi"; |
| 3683 } |
| 3684 '''); |
| 3685 computeResult( |
| 3686 new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT9); |
| 3687 CompilationUnit unit1 = outputs[RESOLVED_UNIT9]; |
| 3688 computeResult( |
| 3689 new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT9); |
| 3690 CompilationUnit unit2 = outputs[RESOLVED_UNIT9]; |
| 3691 |
| 3692 InterfaceType intType = context.typeProvider.intType; |
| 3693 InterfaceType stringType = context.typeProvider.stringType; |
| 3694 |
| 3695 assertVariableDeclarationTypes( |
| 3696 getTopLevelVariable(unit1, "x"), intType, intType); |
| 3697 assertVariableDeclarationTypes( |
| 3698 getFieldInClass(unit1, "A", "x"), intType, intType); |
| 3699 |
| 3700 assertVariableDeclarationTypes( |
| 3701 getTopLevelVariable(unit2, "y"), intType, intType); |
| 3702 assertVariableDeclarationTypes( |
| 3703 getFieldInClass(unit2, "B", "y"), intType, intType); |
| 3704 |
| 3705 List<Statement> statements = |
| 3706 getStatementsInTopLevelFunction(unit2, "test1"); |
| 3707 |
| 3708 assertAssignmentStatementTypes(statements[0], intType, stringType); |
| 3709 assertAssignmentStatementTypes(statements[1], intType, stringType); |
| 3710 } |
| 3711 |
| 3712 // Test that inference does not propagate from null |
| 3713 void test_perform_inference_cross_unit_static_instance() { |
| 3714 List<Source> sources = newSources({ |
| 3715 '/a.dart': ''' |
| 3716 import 'b.dart'; |
| 3717 class A { |
| 3718 static final a1 = B.b1; |
| 3719 final a2 = new B().b2; |
| 3720 } |
| 3721 ''', |
| 3722 '/b.dart': ''' |
| 3723 class B { |
| 3724 static final b1 = 1; |
| 3725 final b2 = 1; |
| 3726 } |
| 3727 ''', |
| 3728 '/main.dart': ''' |
| 3729 import "a.dart"; |
| 3730 |
| 3731 test1() { |
| 3732 int x = 0; |
| 3733 // inference in A now works. |
| 3734 x = A.a1; |
| 3735 x = new A().a2; |
| 3736 } |
| 3737 ''' |
| 3738 }); |
| 3739 List<dynamic> units = |
| 3740 computeLibraryResults(sources, RESOLVED_UNIT9).toList(); |
| 3741 CompilationUnit unit0 = units[0]; |
| 3742 CompilationUnit unit1 = units[1]; |
| 3743 CompilationUnit unit2 = units[2]; |
| 3744 |
| 3745 InterfaceType intType = context.typeProvider.intType; |
| 3746 |
| 3747 assertVariableDeclarationTypes( |
| 3748 getFieldInClass(unit0, "A", "a1"), intType, intType); |
| 3749 assertVariableDeclarationTypes( |
| 3750 getFieldInClass(unit0, "A", "a2"), intType, intType); |
| 3751 |
| 3752 assertVariableDeclarationTypes( |
| 3753 getFieldInClass(unit1, "B", "b1"), intType, intType); |
| 3754 assertVariableDeclarationTypes( |
| 3755 getFieldInClass(unit1, "B", "b2"), intType, intType); |
| 3756 |
| 3757 List<Statement> statements = |
| 3758 getStatementsInTopLevelFunction(unit2, "test1"); |
| 3759 |
| 3760 assertAssignmentStatementTypes(statements[1], intType, intType); |
| 3761 assertAssignmentStatementTypes(statements[2], intType, intType); |
| 3762 } |
| 3763 |
| 3764 // Test inference across units (non-cyclic) |
| 3765 void test_perform_inference_local_variables() { |
| 3766 AnalysisTarget source = newSource( |
| 3767 '/test.dart', |
| 3768 ''' |
| 3769 test() { |
| 3770 int x = 3; |
| 3771 x = "hi"; |
| 3772 var y = 3; |
| 3773 y = "hi"; |
| 3774 } |
| 3775 '''); |
| 3776 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9); |
| 3777 CompilationUnit unit = outputs[RESOLVED_UNIT9]; |
| 3778 |
| 3779 InterfaceType intType = context.typeProvider.intType; |
| 3780 InterfaceType stringType = context.typeProvider.stringType; |
| 3781 |
| 3782 List<Statement> statements = getStatementsInTopLevelFunction(unit, "test"); |
| 3783 |
| 3784 assertVariableDeclarationStatementTypes(statements[0], intType, intType); |
| 3785 assertAssignmentStatementTypes(statements[1], intType, stringType); |
| 3786 assertVariableDeclarationStatementTypes(statements[2], intType, intType); |
| 3787 assertAssignmentStatementTypes(statements[3], intType, stringType); |
| 3788 } |
| 3789 |
| 3790 // Test inference across units (cyclic) |
| 3791 void test_perform_inference_local_variables_fields() { |
| 3792 AnalysisTarget source = newSource( |
| 3793 '/test.dart', |
| 3794 ''' |
| 3795 class A { |
| 3796 int x = 0; |
| 3797 |
| 3798 test1() { |
| 3799 var a = x; |
| 3800 a = "hi"; |
| 3801 a = 3; |
| 3802 var b = y; |
| 3803 b = "hi"; |
| 3804 b = 4; |
| 3805 var c = z; |
| 3806 c = "hi"; |
| 3807 c = 4; |
| 3808 } |
| 3809 |
| 3810 int y; // field def after use |
| 3811 final z = 42; // should infer `int` |
| 3812 } |
| 3813 '''); |
| 3814 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9); |
| 3815 CompilationUnit unit = outputs[RESOLVED_UNIT9]; |
| 3816 |
| 3817 InterfaceType intType = context.typeProvider.intType; |
| 3818 InterfaceType stringType = context.typeProvider.stringType; |
| 3819 |
| 3820 List<Statement> statements = getStatementsInMethod(unit, "A", "test1"); |
| 3821 |
| 3822 assertVariableDeclarationStatementTypes(statements[0], intType, intType); |
| 3823 assertAssignmentStatementTypes(statements[1], intType, stringType); |
| 3824 assertAssignmentStatementTypes(statements[2], intType, intType); |
| 3825 |
| 3826 assertVariableDeclarationStatementTypes(statements[3], intType, intType); |
| 3827 assertAssignmentStatementTypes(statements[4], intType, stringType); |
| 3828 assertAssignmentStatementTypes(statements[5], intType, intType); |
| 3829 |
| 3830 assertVariableDeclarationStatementTypes(statements[6], intType, intType); |
| 3831 assertAssignmentStatementTypes(statements[7], intType, stringType); |
| 3832 assertAssignmentStatementTypes(statements[8], intType, intType); |
| 3833 |
| 3834 assertVariableDeclarationTypes( |
| 3835 getFieldInClass(unit, "A", "x"), intType, intType); |
| 3836 assertVariableDeclarationTypes( |
| 3837 getFieldInClass(unit, "A", "z"), intType, intType); |
| 3838 } |
| 3839 |
| 3840 // Test inference of instance fields across units |
| 3841 void test_perform_inference_local_variables_topLevel() { |
| 3842 AnalysisTarget source = newSource( |
| 3843 '/test.dart', |
| 3844 ''' |
| 3845 int x = 0; |
| 3846 |
| 3847 test1() { |
| 3848 var a = x; |
| 3849 a = /*severe:StaticTypeError*/"hi"; |
| 3850 a = 3; |
| 3851 var b = y; |
| 3852 b = /*severe:StaticTypeError*/"hi"; |
| 3853 b = 4; |
| 3854 var c = z; |
| 3855 c = /*severe:StaticTypeError*/"hi"; |
| 3856 c = 4; |
| 3857 } |
| 3858 |
| 3859 int y = 0; // field def after use |
| 3860 final z = 42; // should infer `int` |
| 3861 '''); |
| 3862 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9); |
| 3863 CompilationUnit unit = outputs[RESOLVED_UNIT9]; |
| 3864 |
| 3865 InterfaceType intType = context.typeProvider.intType; |
| 3866 InterfaceType stringType = context.typeProvider.stringType; |
| 3867 |
| 3868 List<Statement> statements = getStatementsInTopLevelFunction(unit, "test1"); |
| 3869 |
| 3870 assertVariableDeclarationStatementTypes(statements[0], intType, intType); |
| 3871 assertAssignmentStatementTypes(statements[1], intType, stringType); |
| 3872 assertAssignmentStatementTypes(statements[2], intType, intType); |
| 3873 |
| 3874 assertVariableDeclarationStatementTypes(statements[3], intType, intType); |
| 3875 assertAssignmentStatementTypes(statements[4], intType, stringType); |
| 3876 assertAssignmentStatementTypes(statements[5], intType, intType); |
| 3877 |
| 3878 assertVariableDeclarationStatementTypes(statements[6], intType, intType); |
| 3879 assertAssignmentStatementTypes(statements[7], intType, stringType); |
| 3880 assertAssignmentStatementTypes(statements[8], intType, intType); |
| 3881 |
| 3882 assertVariableDeclarationTypes( |
| 3883 getTopLevelVariable(unit, "x"), intType, intType); |
| 3884 assertVariableDeclarationTypes( |
| 3885 getTopLevelVariable(unit, "y"), intType, intType); |
| 3886 assertVariableDeclarationTypes( |
| 3887 getTopLevelVariable(unit, "z"), intType, intType); |
| 3888 } |
| 3889 |
| 3890 // Test inference between static and instance fields |
| 3891 void test_perform_inference_null() { |
| 3892 AnalysisTarget source = newSource( |
| 3893 '/test.dart', |
| 3894 ''' |
| 3895 var x = null; |
| 3896 var y = 3; |
| 3897 class A { |
| 3898 static var x = null; |
| 3899 static var y = 3; |
| 3900 |
| 3901 var x2 = null; |
| 3902 var y2 = 3; |
| 3903 } |
| 3904 |
| 3905 test() { |
| 3906 x = "hi"; |
| 3907 y = /*severe:StaticTypeError*/"hi"; |
| 3908 A.x = "hi"; |
| 3909 A.y = /*severe:StaticTypeError*/"hi"; |
| 3910 new A().x2 = "hi"; |
| 3911 new A().y2 = /*severe:StaticTypeError*/"hi"; |
| 3912 } |
| 3913 '''); |
| 3914 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9); |
| 3915 CompilationUnit unit = outputs[RESOLVED_UNIT9]; |
| 3916 |
| 3917 InterfaceType intType = context.typeProvider.intType; |
| 3918 InterfaceType stringType = context.typeProvider.stringType; |
| 3919 DartType bottomType = context.typeProvider.bottomType; |
| 3920 DartType dynamicType = context.typeProvider.dynamicType; |
| 3921 |
| 3922 assertVariableDeclarationTypes( |
| 3923 getTopLevelVariable(unit, "x"), dynamicType, bottomType); |
| 3924 assertVariableDeclarationTypes( |
| 3925 getTopLevelVariable(unit, "y"), intType, intType); |
| 3926 assertVariableDeclarationTypes( |
| 3927 getFieldInClass(unit, "A", "x"), dynamicType, bottomType); |
| 3928 assertVariableDeclarationTypes( |
| 3929 getFieldInClass(unit, "A", "y"), intType, intType); |
| 3930 assertVariableDeclarationTypes( |
| 3931 getFieldInClass(unit, "A", "x2"), dynamicType, bottomType); |
| 3932 assertVariableDeclarationTypes( |
| 3933 getFieldInClass(unit, "A", "y2"), intType, intType); |
| 3934 |
| 3935 List<Statement> statements = getStatementsInTopLevelFunction(unit, "test"); |
| 3936 |
| 3937 assertAssignmentStatementTypes(statements[0], dynamicType, stringType); |
| 3938 assertAssignmentStatementTypes(statements[1], intType, stringType); |
| 3939 assertAssignmentStatementTypes(statements[2], dynamicType, stringType); |
| 3940 assertAssignmentStatementTypes(statements[3], intType, stringType); |
| 3941 assertAssignmentStatementTypes(statements[4], dynamicType, stringType); |
| 3942 assertAssignmentStatementTypes(statements[5], intType, stringType); |
| 3943 } |
| 3944 |
| 3945 // Test inference between fields and method bodies |
| 3946 void test_perform_local_explicit_disabled() { |
| 3947 AnalysisTarget source = newSource( |
| 3948 '/test.dart', |
| 3949 ''' |
| 3950 test() { |
| 3951 int x = 3; |
| 3952 x = "hi"; |
| 3953 } |
| 3954 '''); |
| 3955 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9); |
| 3956 CompilationUnit unit = outputs[RESOLVED_UNIT9]; |
| 3957 |
| 3958 InterfaceType intType = context.typeProvider.intType; |
| 3959 InterfaceType stringType = context.typeProvider.stringType; |
| 3960 |
| 3961 List<Statement> statements = getStatementsInTopLevelFunction(unit, "test"); |
| 3962 VariableDeclaration decl = |
| 3963 (statements[0] as VariableDeclarationStatement).variables.variables[0]; |
| 3964 expect(decl.element.type, intType); |
| 3965 expect(decl.initializer.staticType, intType); |
| 3966 |
| 3967 ExpressionStatement statement = statements[1]; |
| 3968 AssignmentExpression assgn = statement.expression; |
| 3969 expect(assgn.leftHandSide.staticType, intType); |
| 3970 expect(assgn.rightHandSide.staticType, stringType); |
| 3971 } |
| 3972 } |
| 3973 |
| 3974 @reflectiveTest |
| 3975 class VerifyUnitTaskTest extends _AbstractDartTaskTest { |
| 3976 test_perform_constantError() { |
| 3977 Source source = newSource( |
| 3978 '/test.dart', |
| 3979 ''' |
| 3980 main(int p) { |
| 3981 const v = p; |
| 3982 } |
| 3983 '''); |
| 3984 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 3985 computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask); |
| 3986 // validate |
| 3987 _fillErrorListener(VERIFY_ERRORS); |
| 3988 errorListener.assertErrorsWithCodes(<ErrorCode>[ |
| 3989 CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE |
| 3990 ]); |
| 3991 } |
| 3992 |
| 3993 test_perform_directiveError() { |
| 3994 Source source = newSource( |
| 3995 '/test.dart', |
| 3996 ''' |
| 3997 import 'no-such-file.dart'; |
| 3998 '''); |
| 3999 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 4000 computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask); |
| 4001 // validate |
| 4002 _fillErrorListener(VERIFY_ERRORS); |
| 4003 errorListener.assertErrorsWithCodes( |
| 4004 <ErrorCode>[CompileTimeErrorCode.URI_DOES_NOT_EXIST]); |
| 4005 } |
| 4006 |
| 4007 void test_perform_reresolution() { |
| 4008 enableStrongMode(); |
| 4009 AnalysisTarget source = newSource( |
| 4010 '/test.dart', |
| 4011 ''' |
| 4012 const topLevel = 3; |
| 4013 class C { |
| 4014 String field = topLevel; |
| 4015 } |
| 4016 '''); |
| 4017 computeResult(new LibrarySpecificUnit(source, source), VERIFY_ERRORS); |
| 4018 // validate |
| 4019 _fillErrorListener(VERIFY_ERRORS); |
| 4020 errorListener.assertErrorsWithCodes( |
| 4021 <ErrorCode>[StaticTypeWarningCode.INVALID_ASSIGNMENT]); |
| 4022 } |
| 4023 |
| 4024 test_perform_verifyError() { |
| 4025 Source source = newSource( |
| 4026 '/test.dart', |
| 4027 ''' |
| 4028 main() { |
| 4029 if (42) { |
| 4030 print('Not bool!'); |
| 4031 } |
| 4032 } |
| 4033 '''); |
| 4034 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 4035 computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask); |
| 4036 // validate |
| 4037 _fillErrorListener(VERIFY_ERRORS); |
| 4038 errorListener.assertErrorsWithCodes( |
| 4039 <ErrorCode>[StaticTypeWarningCode.NON_BOOL_CONDITION]); |
| 4040 } |
| 4041 } |
| 4042 |
| 4043 class _AbstractDartTaskTest extends AbstractContextTest { |
| 4044 Source emptySource; |
| 4045 |
| 4046 GatheringErrorListener errorListener = new GatheringErrorListener(); |
| 4047 |
| 4048 void assertAssignmentStatementTypes( |
| 4049 Statement stmt, DartType leftType, DartType rightType) { |
| 4050 AssignmentExpression assgn = (stmt as ExpressionStatement).expression; |
| 4051 expect(assgn.leftHandSide.staticType, leftType); |
| 4052 expect(assgn.rightHandSide.staticType, rightType); |
| 4053 } |
| 4054 |
| 4055 void assertIsInvalid(AnalysisTarget target, ResultDescriptor descriptor) { |
| 4056 CacheEntry entry = context.getCacheEntry(target); |
| 4057 expect(entry.isInvalid(descriptor), isTrue); |
| 4058 } |
| 4059 |
| 4060 void assertIsValid(AnalysisTarget target, ResultDescriptor descriptor) { |
| 4061 CacheEntry entry = context.getCacheEntry(target); |
| 4062 expect(entry.isValid(descriptor), isTrue); |
| 4063 } |
| 4064 |
| 4065 void assertSameResults(List<ResultDescriptor> descriptors) { |
| 4066 descriptors.forEach((descriptor) { |
| 4067 var oldResult = oldOutputs[descriptor]; |
| 4068 var newResult = outputs[descriptor]; |
| 4069 expect(newResult, same(oldResult), reason: descriptor.name); |
| 4070 }); |
| 4071 } |
| 4072 |
| 4073 void assertVariableDeclarationStatementTypes( |
| 4074 Statement stmt, DartType varType, DartType initializerType) { |
| 4075 VariableDeclaration decl = |
| 4076 (stmt as VariableDeclarationStatement).variables.variables[0]; |
| 4077 assertVariableDeclarationTypes(decl, varType, initializerType); |
| 4078 } |
| 4079 |
| 4080 void assertVariableDeclarationTypes( |
| 4081 VariableDeclaration decl, DartType varType, DartType initializerType) { |
| 4082 expect(decl.element.type, varType); |
| 4083 expect(decl.initializer.staticType, initializerType); |
| 4084 } |
| 4085 |
| 4086 List<dynamic> computeLibraryResults( |
| 4087 List<Source> sources, ResultDescriptor result, |
| 4088 {isInstanceOf matcher: null}) { |
| 4089 dynamic compute(Source source) { |
| 4090 computeResult(new LibrarySpecificUnit(source, source), result, |
| 4091 matcher: matcher); |
| 4092 return outputs[result]; |
| 4093 } |
| 4094 return sources.map(compute).toList(); |
| 4095 } |
| 4096 |
| 4097 List<Map<ResultDescriptor, dynamic>> computeLibraryResultsMap( |
| 4098 List<Source> sources, ResultDescriptor result, |
| 4099 {isInstanceOf matcher: null}) { |
| 4100 Map<ResultDescriptor, dynamic> compute(Source source) { |
| 4101 computeResult(new LibrarySpecificUnit(source, source), result, |
| 4102 matcher: matcher); |
| 4103 return outputs; |
| 4104 } |
| 4105 return sources.map(compute).toList(); |
| 4106 } |
| 4107 |
| 4108 /** |
| 4109 * Create a script object with a single fragment containing the given |
| 4110 * [scriptContent]. |
| 4111 */ |
| 4112 DartScript createScript(String scriptContent) { |
| 4113 String htmlContent = ''' |
| 4114 <!DOCTYPE html> |
| 4115 <html> |
| 4116 <head> |
| 4117 <title>test page</title> |
| 4118 <script type='application/dart'>$scriptContent</script> |
| 4119 </head> |
| 4120 <body>Test</body> |
| 4121 </html> |
| 4122 '''; |
| 4123 Source source = newSource('/test.html', htmlContent); |
| 4124 return new DartScript( |
| 4125 source, [new ScriptFragment(97, 5, 36, scriptContent)]); |
| 4126 } |
| 4127 |
| 4128 /** |
| 4129 * Enable strong mode in the current analysis context. |
| 4130 */ |
| 4131 void enableStrongMode() { |
| 4132 AnalysisOptionsImpl options = context.analysisOptions; |
| 4133 options.strongMode = true; |
| 4134 context.analysisOptions = options; |
| 4135 } |
| 4136 |
| 4137 /** |
| 4138 * Return the declaration of the class with the given [className] in the given |
| 4139 * compilation [unit]. |
| 4140 */ |
| 4141 ClassDeclaration getClass(CompilationUnit unit, String className) { |
| 4142 NodeList<CompilationUnitMember> unitMembers = unit.declarations; |
| 4143 for (CompilationUnitMember unitMember in unitMembers) { |
| 4144 if (unitMember is ClassDeclaration && unitMember.name.name == className) { |
| 4145 return unitMember; |
| 4146 } |
| 4147 } |
| 4148 fail('No class named $className in ${unit.element.source}'); |
| 4149 return null; |
| 4150 } |
| 4151 |
| 4152 /** |
| 4153 * Return the declaration of the field with the given [fieldName] in the class |
| 4154 * with the given [className] in the given compilation [unit]. |
| 4155 */ |
| 4156 VariableDeclaration getFieldInClass( |
| 4157 CompilationUnit unit, String className, String fieldName) { |
| 4158 ClassDeclaration unitMember = getClass(unit, className); |
| 4159 NodeList<ClassMember> classMembers = unitMember.members; |
| 4160 for (ClassMember classMember in classMembers) { |
| 4161 if (classMember is FieldDeclaration) { |
| 4162 NodeList<VariableDeclaration> fields = classMember.fields.variables; |
| 4163 for (VariableDeclaration field in fields) { |
| 4164 if (field.name.name == fieldName) { |
| 4165 return field; |
| 4166 } |
| 4167 } |
| 4168 } |
| 4169 } |
| 4170 fail('No field named $fieldName in $className'); |
| 4171 return null; |
| 4172 } |
| 4173 |
| 4174 /** |
| 4175 * Return the declaration of the method with the given [methodName] in the |
| 4176 * class with the given [className] in the given compilation [unit]. |
| 4177 */ |
| 4178 MethodDeclaration getMethodInClass( |
| 4179 CompilationUnit unit, String className, String methodName) { |
| 4180 ClassDeclaration unitMember = getClass(unit, className); |
| 4181 NodeList<ClassMember> classMembers = unitMember.members; |
| 4182 for (ClassMember classMember in classMembers) { |
| 4183 if (classMember is MethodDeclaration) { |
| 4184 if (classMember.name.name == methodName) { |
| 4185 return classMember; |
| 4186 } |
| 4187 } |
| 4188 } |
| 4189 fail('No method named $methodName in $className'); |
| 4190 return null; |
| 4191 } |
| 4192 |
| 4193 List<Statement> getStatementsInMethod( |
| 4194 CompilationUnit unit, String className, String methodName) { |
| 4195 MethodDeclaration method = getMethodInClass(unit, className, methodName); |
| 4196 BlockFunctionBody body = method.body; |
| 4197 return body.block.statements; |
| 4198 } |
| 4199 |
| 4200 List<Statement> getStatementsInTopLevelFunction( |
| 4201 CompilationUnit unit, String functionName) { |
| 4202 FunctionDeclaration function = getTopLevelFunction(unit, functionName); |
| 4203 BlockFunctionBody body = function.functionExpression.body; |
| 4204 return body.block.statements; |
| 4205 } |
| 4206 |
| 4207 /** |
| 4208 * Return the declaration of the top-level function with the given |
| 4209 * [functionName] in the given compilation [unit]. |
| 4210 */ |
| 4211 FunctionDeclaration getTopLevelFunction( |
| 4212 CompilationUnit unit, String functionName) { |
| 4213 NodeList<CompilationUnitMember> unitMembers = unit.declarations; |
| 4214 for (CompilationUnitMember unitMember in unitMembers) { |
| 4215 if (unitMember is FunctionDeclaration) { |
| 4216 if (unitMember.name.name == functionName) { |
| 4217 return unitMember; |
| 4218 } |
| 4219 } |
| 4220 } |
| 4221 return null; |
| 4222 } |
| 4223 |
| 4224 /** |
| 4225 * Return the declaration of the top-level variable with the given |
| 4226 * [variableName] in the given compilation [unit]. |
| 4227 */ |
| 4228 VariableDeclaration getTopLevelVariable( |
| 4229 CompilationUnit unit, String variableName) { |
| 4230 NodeList<CompilationUnitMember> unitMembers = unit.declarations; |
| 4231 for (CompilationUnitMember unitMember in unitMembers) { |
| 4232 if (unitMember is TopLevelVariableDeclaration) { |
| 4233 NodeList<VariableDeclaration> variables = |
| 4234 unitMember.variables.variables; |
| 4235 for (VariableDeclaration variable in variables) { |
| 4236 if (variable.name.name == variableName) { |
| 4237 return variable; |
| 4238 } |
| 4239 } |
| 4240 } |
| 4241 } |
| 4242 return null; |
| 4243 } |
| 4244 |
| 4245 void setUp() { |
| 4246 super.setUp(); |
| 4247 emptySource = newSource('/test.dart'); |
| 4248 } |
| 4249 |
| 4250 /** |
| 4251 * Fill [errorListener] with [result] errors in the current [task]. |
| 4252 */ |
| 4253 void _fillErrorListener(ResultDescriptor<List<AnalysisError>> result) { |
| 4254 List<AnalysisError> errors = task.outputs[result]; |
| 4255 expect(errors, isNotNull, reason: result.name); |
| 4256 errorListener = new GatheringErrorListener(); |
| 4257 errorListener.addAll(errors); |
| 4258 } |
| 4259 } |
OLD | NEW |