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/task/dart.dart'; |
| 19 import 'package:analyzer/src/task/html.dart'; |
| 20 import 'package:analyzer/task/dart.dart'; |
| 21 import 'package:analyzer/task/general.dart'; |
| 22 import 'package:analyzer/task/model.dart'; |
| 23 import 'package:unittest/unittest.dart'; |
| 24 |
| 25 import '../../generated/test_support.dart'; |
| 26 import '../../reflective_tests.dart'; |
| 27 import '../../utils.dart'; |
| 28 import '../context/abstract_context.dart'; |
| 29 |
| 30 main() { |
| 31 initializeTestEnvironment(); |
| 32 runReflectiveTests(BuildCompilationUnitElementTaskTest); |
| 33 runReflectiveTests(BuildDirectiveElementsTaskTest); |
| 34 runReflectiveTests(BuildEnumMemberElementsTaskTest); |
| 35 runReflectiveTests(BuildSourceExportClosureTaskTest); |
| 36 runReflectiveTests(BuildSourceImportExportClosureTaskTest); |
| 37 runReflectiveTests(BuildExportNamespaceTaskTest); |
| 38 runReflectiveTests(BuildLibraryElementTaskTest); |
| 39 runReflectiveTests(BuildPublicNamespaceTaskTest); |
| 40 runReflectiveTests(BuildTypeProviderTaskTest); |
| 41 runReflectiveTests(ComputeConstantDependenciesTaskTest); |
| 42 runReflectiveTests(ComputeConstantValueTaskTest); |
| 43 runReflectiveTests(ComputeInferableStaticVariableDependenciesTaskTest); |
| 44 runReflectiveTests(ContainingLibrariesTaskTest); |
| 45 runReflectiveTests(DartErrorsTaskTest); |
| 46 runReflectiveTests(EvaluateUnitConstantsTaskTest); |
| 47 runReflectiveTests(GatherUsedImportedElementsTaskTest); |
| 48 runReflectiveTests(GatherUsedLocalElementsTaskTest); |
| 49 runReflectiveTests(GenerateHintsTaskTest); |
| 50 runReflectiveTests(InferStaticVariableTypesInUnitTaskTest); |
| 51 runReflectiveTests(InferStaticVariableTypeTaskTest); |
| 52 runReflectiveTests(LibraryErrorsReadyTaskTest); |
| 53 runReflectiveTests(LibraryUnitErrorsTaskTest); |
| 54 runReflectiveTests(ParseDartTaskTest); |
| 55 runReflectiveTests(PartiallyResolveReferencesTaskTest); |
| 56 runReflectiveTests(ResolveUnitTypeNamesTaskTest); |
| 57 runReflectiveTests(ResolveLibraryTypeNamesTaskTest); |
| 58 runReflectiveTests(ResolveReferencesTaskTest); |
| 59 runReflectiveTests(ResolveVariableReferencesTaskTest); |
| 60 runReflectiveTests(ScanDartTaskTest); |
| 61 runReflectiveTests(VerifyUnitTaskTest); |
| 62 } |
| 63 |
| 64 @reflectiveTest |
| 65 class BuildCompilationUnitElementTaskTest extends _AbstractDartTaskTest { |
| 66 Source source; |
| 67 LibrarySpecificUnit target; |
| 68 |
| 69 test_buildInputs() { |
| 70 LibrarySpecificUnit target = |
| 71 new LibrarySpecificUnit(emptySource, emptySource); |
| 72 Map<String, TaskInput> inputs = |
| 73 BuildCompilationUnitElementTask.buildInputs(target); |
| 74 expect(inputs, isNotNull); |
| 75 expect( |
| 76 inputs.keys, |
| 77 unorderedEquals( |
| 78 [BuildCompilationUnitElementTask.PARSED_UNIT_INPUT_NAME])); |
| 79 } |
| 80 |
| 81 test_constructor() { |
| 82 BuildCompilationUnitElementTask task = |
| 83 new BuildCompilationUnitElementTask(context, emptySource); |
| 84 expect(task, isNotNull); |
| 85 expect(task.context, context); |
| 86 expect(task.target, emptySource); |
| 87 } |
| 88 |
| 89 test_createTask() { |
| 90 BuildCompilationUnitElementTask task = |
| 91 BuildCompilationUnitElementTask.createTask(context, emptySource); |
| 92 expect(task, isNotNull); |
| 93 expect(task.context, context); |
| 94 expect(task.target, emptySource); |
| 95 } |
| 96 |
| 97 test_description() { |
| 98 BuildCompilationUnitElementTask task = |
| 99 new BuildCompilationUnitElementTask(null, emptySource); |
| 100 expect(task.description, isNotNull); |
| 101 } |
| 102 |
| 103 test_descriptor() { |
| 104 TaskDescriptor descriptor = BuildCompilationUnitElementTask.DESCRIPTOR; |
| 105 expect(descriptor, isNotNull); |
| 106 } |
| 107 |
| 108 test_perform_find_constants() { |
| 109 _performBuildTask(''' |
| 110 const x = 1; |
| 111 class C { |
| 112 static const y = 1; |
| 113 const C([p = 1]); |
| 114 } |
| 115 @x |
| 116 f() { |
| 117 const z = 1; |
| 118 } |
| 119 '''); |
| 120 CompilationUnit unit = outputs[RESOLVED_UNIT1]; |
| 121 CompilationUnitElement unitElement = outputs[COMPILATION_UNIT_ELEMENT]; |
| 122 Annotation annotation = unit.declarations |
| 123 .firstWhere((m) => m is FunctionDeclaration) |
| 124 .metadata[0]; |
| 125 List<ConstantEvaluationTarget> expectedConstants = [ |
| 126 unitElement.accessors.firstWhere((e) => e.isGetter).variable, |
| 127 unitElement.types[0].fields[0], |
| 128 unitElement.functions[0].localVariables[0], |
| 129 unitElement.types[0].constructors[0], |
| 130 new ConstantEvaluationTarget_Annotation( |
| 131 context, source, source, annotation), |
| 132 unitElement.types[0].constructors[0].parameters[0] |
| 133 ]; |
| 134 expect( |
| 135 outputs[COMPILATION_UNIT_CONSTANTS].toSet(), expectedConstants.toSet()); |
| 136 } |
| 137 |
| 138 test_perform_library() { |
| 139 _performBuildTask(r''' |
| 140 library lib; |
| 141 import 'lib2.dart'; |
| 142 export 'lib3.dart'; |
| 143 part 'part.dart'; |
| 144 final x = ''; |
| 145 class A { |
| 146 static final y = 0; |
| 147 } |
| 148 class B = Object with A; |
| 149 '''); |
| 150 expect(outputs, hasLength(3)); |
| 151 expect(outputs[COMPILATION_UNIT_CONSTANTS], isNotNull); |
| 152 expect(outputs[COMPILATION_UNIT_ELEMENT], isNotNull); |
| 153 expect(outputs[RESOLVED_UNIT1], isNotNull); |
| 154 } |
| 155 |
| 156 test_perform_reuseElement() { |
| 157 _performBuildTask(r''' |
| 158 library lib; |
| 159 class A {} |
| 160 class B = Object with A; |
| 161 '''); |
| 162 CompilationUnit unit = outputs[RESOLVED_UNIT1]; |
| 163 CompilationUnitElement unitElement = outputs[COMPILATION_UNIT_ELEMENT]; |
| 164 expect(unit, isNotNull); |
| 165 expect(unitElement, isNotNull); |
| 166 // invalidate RESOLVED_UNIT1 |
| 167 CacheEntry cacheEntry = analysisCache.get(target); |
| 168 cacheEntry.setState(RESOLVED_UNIT1, CacheState.INVALID); |
| 169 // compute again |
| 170 computeResult(target, RESOLVED_UNIT1); |
| 171 expect(outputs[COMPILATION_UNIT_ELEMENT], same(unitElement)); |
| 172 expect(outputs[RESOLVED_UNIT1], isNot(same(unit))); |
| 173 } |
| 174 |
| 175 void _performBuildTask(String content) { |
| 176 source = newSource('/test.dart', content); |
| 177 target = new LibrarySpecificUnit(source, source); |
| 178 computeResult(target, RESOLVED_UNIT1); |
| 179 expect(task, new isInstanceOf<BuildCompilationUnitElementTask>()); |
| 180 } |
| 181 } |
| 182 |
| 183 @reflectiveTest |
| 184 class BuildDirectiveElementsTaskTest extends _AbstractDartTaskTest { |
| 185 test_constructor() { |
| 186 BuildDirectiveElementsTask task = |
| 187 new BuildDirectiveElementsTask(context, emptySource); |
| 188 expect(task, isNotNull); |
| 189 expect(task.context, context); |
| 190 expect(task.target, emptySource); |
| 191 } |
| 192 |
| 193 test_createTask() { |
| 194 BuildDirectiveElementsTask task = |
| 195 BuildDirectiveElementsTask.createTask(context, emptySource); |
| 196 expect(task, isNotNull); |
| 197 expect(task.context, context); |
| 198 expect(task.target, emptySource); |
| 199 } |
| 200 |
| 201 test_description() { |
| 202 BuildDirectiveElementsTask task = |
| 203 new BuildDirectiveElementsTask(null, emptySource); |
| 204 expect(task.description, isNotNull); |
| 205 } |
| 206 |
| 207 test_descriptor() { |
| 208 TaskDescriptor descriptor = BuildDirectiveElementsTask.DESCRIPTOR; |
| 209 expect(descriptor, isNotNull); |
| 210 } |
| 211 |
| 212 test_perform() { |
| 213 List<Source> sources = newSources({ |
| 214 '/libA.dart': ''' |
| 215 library libA; |
| 216 import 'libB.dart'; |
| 217 export 'libC.dart'; |
| 218 ''', |
| 219 '/libB.dart': ''' |
| 220 library libB; |
| 221 ''', |
| 222 '/libC.dart': ''' |
| 223 library libC; |
| 224 ''' |
| 225 }); |
| 226 Source sourceA = sources[0]; |
| 227 Source sourceB = sources[1]; |
| 228 Source sourceC = sources[2]; |
| 229 // perform task |
| 230 computeResult(sourceA, LIBRARY_ELEMENT2); |
| 231 expect(task, new isInstanceOf<BuildDirectiveElementsTask>()); |
| 232 // prepare outputs |
| 233 LibraryElement libraryElementA = outputs[LIBRARY_ELEMENT2]; |
| 234 LibraryElement libraryElementB = _getImportLibraryInput(sourceB); |
| 235 LibraryElement libraryElementC = _getExportLibraryInput(sourceC); |
| 236 // no errors |
| 237 _assertErrorsWithCodes([]); |
| 238 // validate directives |
| 239 CompilationUnit libraryUnitA = context |
| 240 .getCacheEntry(new LibrarySpecificUnit(sourceA, sourceA)) |
| 241 .getValue(RESOLVED_UNIT1); |
| 242 { |
| 243 ImportDirective importNode = libraryUnitA.directives[1]; |
| 244 ImportElement importElement = importNode.element; |
| 245 expect(importElement, isNotNull); |
| 246 expect(importElement.importedLibrary, libraryElementB); |
| 247 expect(importElement.prefix, isNull); |
| 248 expect(importElement.nameOffset, 14); |
| 249 expect(importElement.uriOffset, 21); |
| 250 expect(importElement.uriEnd, 32); |
| 251 } |
| 252 { |
| 253 ExportDirective exportNode = libraryUnitA.directives[2]; |
| 254 ExportElement exportElement = exportNode.element; |
| 255 expect(exportElement, isNotNull); |
| 256 expect(exportElement.exportedLibrary, libraryElementC); |
| 257 expect(exportElement.nameOffset, 34); |
| 258 expect(exportElement.uriOffset, 41); |
| 259 expect(exportElement.uriEnd, 52); |
| 260 } |
| 261 // validate LibraryElement |
| 262 expect(libraryElementA.hasExtUri, isFalse); |
| 263 // has an artificial "dart:core" import |
| 264 { |
| 265 List<ImportElement> imports = libraryElementA.imports; |
| 266 expect(imports, hasLength(2)); |
| 267 expect(imports[1].importedLibrary.isDartCore, isTrue); |
| 268 expect(imports[1].isSynthetic, isTrue); |
| 269 } |
| 270 } |
| 271 |
| 272 test_perform_combinators() { |
| 273 List<Source> sources = newSources({ |
| 274 '/libA.dart': ''' |
| 275 library libA; |
| 276 import 'libB.dart' show A, B hide C, D; |
| 277 ''', |
| 278 '/libB.dart': ''' |
| 279 library libB; |
| 280 ''' |
| 281 }); |
| 282 Source sourceA = sources[0]; |
| 283 // perform task |
| 284 computeResult(sourceA, LIBRARY_ELEMENT2); |
| 285 expect(task, new isInstanceOf<BuildDirectiveElementsTask>()); |
| 286 // prepare outputs |
| 287 CompilationUnit libraryUnitA = context |
| 288 .getCacheEntry(new LibrarySpecificUnit(sourceA, sourceA)) |
| 289 .getValue(RESOLVED_UNIT1); |
| 290 // no errors |
| 291 _assertErrorsWithCodes([]); |
| 292 // validate directives |
| 293 ImportDirective importNode = libraryUnitA.directives[1]; |
| 294 ImportElement importElement = importNode.element; |
| 295 List<NamespaceCombinator> combinators = importElement.combinators; |
| 296 expect(combinators, hasLength(2)); |
| 297 { |
| 298 ShowElementCombinator combinator = combinators[0]; |
| 299 expect(combinator.offset, 33); |
| 300 expect(combinator.end, 42); |
| 301 expect(combinator.shownNames, ['A', 'B']); |
| 302 } |
| 303 { |
| 304 HideElementCombinator combinator = combinators[1]; |
| 305 expect(combinator.hiddenNames, ['C', 'D']); |
| 306 } |
| 307 } |
| 308 |
| 309 test_perform_dartCoreContext() { |
| 310 List<Source> sources = newSources({'/libA.dart': ''}); |
| 311 Source source = sources[0]; |
| 312 // perform task |
| 313 computeResult(source, LIBRARY_ELEMENT2); |
| 314 expect(task, new isInstanceOf<BuildDirectiveElementsTask>()); |
| 315 // prepare outputs |
| 316 LibraryElement libraryElement = outputs[LIBRARY_ELEMENT2]; |
| 317 // verify that dart:core has SDK context |
| 318 { |
| 319 LibraryElement coreLibrary = libraryElement.importedLibraries[0]; |
| 320 DartSdk dartSdk = context.sourceFactory.dartSdk; |
| 321 expect(coreLibrary.context, same(dartSdk.context)); |
| 322 } |
| 323 } |
| 324 |
| 325 test_perform_error_exportOfNonLibrary() { |
| 326 List<Source> sources = newSources({ |
| 327 '/libA.dart': ''' |
| 328 library libA; |
| 329 export 'part.dart'; |
| 330 ''', |
| 331 '/part.dart': ''' |
| 332 part of notLib; |
| 333 ''' |
| 334 }); |
| 335 Source sourceA = sources[0]; |
| 336 // perform task |
| 337 computeResult(sourceA, LIBRARY_ELEMENT2); |
| 338 expect(task, new isInstanceOf<BuildDirectiveElementsTask>()); |
| 339 // validate errors |
| 340 _assertErrorsWithCodes([CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY]); |
| 341 } |
| 342 |
| 343 test_perform_error_importOfNonLibrary() { |
| 344 List<Source> sources = newSources({ |
| 345 '/libA.dart': ''' |
| 346 library libA; |
| 347 import 'part.dart'; |
| 348 ''', |
| 349 '/part.dart': ''' |
| 350 part of notLib; |
| 351 ''' |
| 352 }); |
| 353 Source sourceA = sources[0]; |
| 354 // perform task |
| 355 computeResult(sourceA, LIBRARY_ELEMENT2); |
| 356 expect(task, new isInstanceOf<BuildDirectiveElementsTask>()); |
| 357 // validate errors |
| 358 _assertErrorsWithCodes([CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY]); |
| 359 } |
| 360 |
| 361 test_perform_explicitDartCoreImport() { |
| 362 List<Source> sources = newSources({ |
| 363 '/lib.dart': ''' |
| 364 library lib; |
| 365 import 'dart:core' show List; |
| 366 ''' |
| 367 }); |
| 368 Source source = sources[0]; |
| 369 // perform task |
| 370 computeResult(source, LIBRARY_ELEMENT2); |
| 371 expect(task, new isInstanceOf<BuildDirectiveElementsTask>()); |
| 372 // prepare outputs |
| 373 LibraryElement libraryElement = outputs[LIBRARY_ELEMENT2]; |
| 374 // has an explicit "dart:core" import |
| 375 { |
| 376 List<ImportElement> imports = libraryElement.imports; |
| 377 expect(imports, hasLength(1)); |
| 378 expect(imports[0].importedLibrary.isDartCore, isTrue); |
| 379 expect(imports[0].isSynthetic, isFalse); |
| 380 } |
| 381 } |
| 382 |
| 383 test_perform_hasExtUri() { |
| 384 List<Source> sources = newSources({ |
| 385 '/lib.dart': ''' |
| 386 import 'dart-ext:doesNotExist.dart'; |
| 387 ''' |
| 388 }); |
| 389 Source source = sources[0]; |
| 390 // perform task |
| 391 computeResult(source, LIBRARY_ELEMENT2); |
| 392 expect(task, new isInstanceOf<BuildDirectiveElementsTask>()); |
| 393 // prepare outputs |
| 394 LibraryElement libraryElement = outputs[LIBRARY_ELEMENT2]; |
| 395 expect(libraryElement.hasExtUri, isTrue); |
| 396 } |
| 397 |
| 398 test_perform_importPrefix() { |
| 399 List<Source> sources = newSources({ |
| 400 '/libA.dart': ''' |
| 401 library libA; |
| 402 import 'libB.dart' as pref; |
| 403 import 'libC.dart' as pref; |
| 404 ''', |
| 405 '/libB.dart': ''' |
| 406 library libB; |
| 407 ''', |
| 408 '/libC.dart': ''' |
| 409 library libC; |
| 410 ''' |
| 411 }); |
| 412 Source sourceA = sources[0]; |
| 413 Source sourceB = sources[1]; |
| 414 // perform task |
| 415 computeResult(sourceA, LIBRARY_ELEMENT2); |
| 416 expect(task, new isInstanceOf<BuildDirectiveElementsTask>()); |
| 417 // prepare outputs |
| 418 CompilationUnit libraryUnitA = context |
| 419 .getCacheEntry(new LibrarySpecificUnit(sourceA, sourceA)) |
| 420 .getValue(RESOLVED_UNIT1); |
| 421 // validate directives |
| 422 { |
| 423 ImportDirective importNodeB = libraryUnitA.directives[1]; |
| 424 SimpleIdentifier prefixNodeB = importNodeB.prefix; |
| 425 ImportElement importElementB = importNodeB.element; |
| 426 PrefixElement prefixElement = importElementB.prefix; |
| 427 expect(importElementB, isNotNull); |
| 428 expect(importElementB.importedLibrary, _getImportLibraryInput(sourceB)); |
| 429 expect(prefixElement, isNotNull); |
| 430 expect(importElementB.prefixOffset, prefixElement.nameOffset); |
| 431 expect(prefixNodeB.staticElement, prefixElement); |
| 432 // PrefixElement "pref" is shared |
| 433 ImportDirective importNodeC = libraryUnitA.directives[2]; |
| 434 SimpleIdentifier prefixNodeC = importNodeC.prefix; |
| 435 ImportElement importElementC = importNodeC.element; |
| 436 expect(prefixNodeC.staticElement, prefixElement); |
| 437 expect(importElementC.prefix, prefixElement); |
| 438 } |
| 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 expect(task, new isInstanceOf<BuildEnumMemberElementsTask>()); |
| 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 expect(task, new isInstanceOf<BuildExportNamespaceTask>()); |
| 538 // validate |
| 539 { |
| 540 LibraryElement library = outputs[LIBRARY_ELEMENT4]; |
| 541 FunctionElement entryPoint = library.entryPoint; |
| 542 expect(entryPoint, isNotNull); |
| 543 expect(entryPoint.source, sourceB); |
| 544 } |
| 545 } |
| 546 |
| 547 test_perform_hideCombinator() { |
| 548 Source sourceA = newSource( |
| 549 '/a.dart', |
| 550 ''' |
| 551 library lib_a; |
| 552 export 'b.dart' hide B1; |
| 553 class A1 {} |
| 554 class A2 {} |
| 555 class _A3 {} |
| 556 '''); |
| 557 newSource( |
| 558 '/b.dart', |
| 559 ''' |
| 560 library lib_b; |
| 561 class B1 {} |
| 562 class B2 {} |
| 563 class B3 {} |
| 564 class _B4 {} |
| 565 '''); |
| 566 newSource( |
| 567 '/c.dart', |
| 568 ''' |
| 569 library lib_c; |
| 570 class C1 {} |
| 571 class C2 {} |
| 572 class C3 {} |
| 573 '''); |
| 574 computeResult(sourceA, LIBRARY_ELEMENT4); |
| 575 expect(task, new isInstanceOf<BuildExportNamespaceTask>()); |
| 576 // validate |
| 577 { |
| 578 LibraryElement library = outputs[LIBRARY_ELEMENT4]; |
| 579 Namespace namespace = library.exportNamespace; |
| 580 Iterable<String> definedKeys = namespace.definedNames.keys; |
| 581 expect(definedKeys, unorderedEquals(['A1', 'A2', 'B2', 'B3'])); |
| 582 } |
| 583 } |
| 584 |
| 585 test_perform_showCombinator() { |
| 586 Source sourceA = newSource( |
| 587 '/a.dart', |
| 588 ''' |
| 589 library lib_a; |
| 590 export 'b.dart' show B1; |
| 591 class A1 {} |
| 592 class A2 {} |
| 593 class _A3 {} |
| 594 '''); |
| 595 newSource( |
| 596 '/b.dart', |
| 597 ''' |
| 598 library lib_b; |
| 599 class B1 {} |
| 600 class B2 {} |
| 601 class _B3 {} |
| 602 '''); |
| 603 computeResult(sourceA, LIBRARY_ELEMENT4); |
| 604 expect(task, new isInstanceOf<BuildExportNamespaceTask>()); |
| 605 // validate |
| 606 { |
| 607 LibraryElement library = outputs[LIBRARY_ELEMENT4]; |
| 608 Namespace namespace = library.exportNamespace; |
| 609 Iterable<String> definedKeys = namespace.definedNames.keys; |
| 610 expect(definedKeys, unorderedEquals(['A1', 'A2', 'B1'])); |
| 611 } |
| 612 } |
| 613 |
| 614 test_perform_showCombinator_setter() { |
| 615 Source sourceA = newSource( |
| 616 '/a.dart', |
| 617 ''' |
| 618 library lib_a; |
| 619 export 'b.dart' show topLevelB; |
| 620 class A {} |
| 621 '''); |
| 622 newSource( |
| 623 '/b.dart', |
| 624 ''' |
| 625 library lib_b; |
| 626 int topLevelB; |
| 627 '''); |
| 628 computeResult(sourceA, LIBRARY_ELEMENT4); |
| 629 expect(task, new isInstanceOf<BuildExportNamespaceTask>()); |
| 630 // validate |
| 631 { |
| 632 LibraryElement library = outputs[LIBRARY_ELEMENT4]; |
| 633 Namespace namespace = library.exportNamespace; |
| 634 Iterable<String> definedKeys = namespace.definedNames.keys; |
| 635 expect(definedKeys, unorderedEquals(['A', 'topLevelB', 'topLevelB='])); |
| 636 } |
| 637 } |
| 638 } |
| 639 |
| 640 @reflectiveTest |
| 641 class BuildLibraryElementTaskTest extends _AbstractDartTaskTest { |
| 642 Source librarySource; |
| 643 CompilationUnit libraryUnit; |
| 644 CompilationUnitElement libraryUnitElement; |
| 645 List<CompilationUnit> partUnits; |
| 646 |
| 647 LibraryElement libraryElement; |
| 648 |
| 649 test_constructor() { |
| 650 BuildLibraryElementTask task = |
| 651 new BuildLibraryElementTask(context, emptySource); |
| 652 expect(task, isNotNull); |
| 653 expect(task.context, context); |
| 654 expect(task.target, emptySource); |
| 655 } |
| 656 |
| 657 test_createTask() { |
| 658 BuildLibraryElementTask task = |
| 659 BuildLibraryElementTask.createTask(context, emptySource); |
| 660 expect(task, isNotNull); |
| 661 expect(task.context, context); |
| 662 expect(task.target, emptySource); |
| 663 } |
| 664 |
| 665 test_description() { |
| 666 BuildLibraryElementTask task = |
| 667 new BuildLibraryElementTask(null, emptySource); |
| 668 expect(task.description, isNotNull); |
| 669 } |
| 670 |
| 671 test_descriptor() { |
| 672 TaskDescriptor descriptor = BuildLibraryElementTask.DESCRIPTOR; |
| 673 expect(descriptor, isNotNull); |
| 674 } |
| 675 |
| 676 test_perform() { |
| 677 _performBuildTask({ |
| 678 '/lib.dart': ''' |
| 679 library lib; |
| 680 part 'part1.dart'; |
| 681 part 'part2.dart'; |
| 682 ''', |
| 683 '/part1.dart': ''' |
| 684 part of lib; |
| 685 ''', |
| 686 '/part2.dart': ''' |
| 687 part of lib; |
| 688 ''' |
| 689 }); |
| 690 expect(outputs, hasLength(3)); |
| 691 // simple outputs |
| 692 expect(outputs[BUILD_LIBRARY_ERRORS], isEmpty); |
| 693 expect(outputs[IS_LAUNCHABLE], isFalse); |
| 694 // LibraryElement output |
| 695 expect(libraryElement, isNotNull); |
| 696 expect(libraryElement.entryPoint, isNull); |
| 697 expect(libraryElement.source, same(librarySource)); |
| 698 expect(libraryElement.definingCompilationUnit, libraryUnitElement); |
| 699 expect(libraryElement.parts, |
| 700 unorderedEquals([partUnits[0].element, partUnits[1].element])); |
| 701 // LibraryElement references |
| 702 expect((libraryUnit.directives[0] as LibraryDirective).element, |
| 703 same(libraryElement)); |
| 704 expect((partUnits[0].directives[0] as PartOfDirective).element, |
| 705 same(libraryElement)); |
| 706 expect((partUnits[1].directives[0] as PartOfDirective).element, |
| 707 same(libraryElement)); |
| 708 // CompilationUnitElement(s) |
| 709 CompilationUnitElement firstPart; |
| 710 CompilationUnitElement secondPart; |
| 711 if (partUnits[0].element.uri == 'part1.dart') { |
| 712 firstPart = partUnits[0].element; |
| 713 secondPart = partUnits[1].element; |
| 714 } else { |
| 715 firstPart = partUnits[1].element; |
| 716 secondPart = partUnits[0].element; |
| 717 } |
| 718 expect(firstPart.uri, 'part1.dart'); |
| 719 expect(firstPart.uriOffset, 18); |
| 720 expect(firstPart.uriEnd, 30); |
| 721 expect( |
| 722 (libraryUnit.directives[1] as PartDirective).element, same(firstPart)); |
| 723 |
| 724 expect(secondPart.uri, 'part2.dart'); |
| 725 expect(secondPart.uriOffset, 37); |
| 726 expect(secondPart.uriEnd, 49); |
| 727 expect( |
| 728 (libraryUnit.directives[2] as PartDirective).element, same(secondPart)); |
| 729 } |
| 730 |
| 731 test_perform_error_missingLibraryDirectiveWithPart_hasCommon() { |
| 732 _performBuildTask({ |
| 733 '/lib.dart': ''' |
| 734 part 'partA.dart'; |
| 735 part 'partB.dart'; |
| 736 ''', |
| 737 '/partA.dart': ''' |
| 738 part of my_lib; |
| 739 ''', |
| 740 '/partB.dart': ''' |
| 741 part of my_lib; |
| 742 ''' |
| 743 }); |
| 744 _assertErrorsWithCodes( |
| 745 [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]); |
| 746 AnalysisError error = errorListener.errors[0]; |
| 747 expect(error.getProperty(ErrorProperty.PARTS_LIBRARY_NAME), 'my_lib'); |
| 748 } |
| 749 |
| 750 test_perform_error_missingLibraryDirectiveWithPart_noCommon() { |
| 751 _performBuildTask({ |
| 752 '/lib.dart': ''' |
| 753 part 'partA.dart'; |
| 754 part 'partB.dart'; |
| 755 ''', |
| 756 '/partA.dart': ''' |
| 757 part of libA; |
| 758 ''', |
| 759 '/partB.dart': ''' |
| 760 part of libB; |
| 761 ''' |
| 762 }); |
| 763 _assertErrorsWithCodes( |
| 764 [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]); |
| 765 AnalysisError error = errorListener.errors[0]; |
| 766 expect(error.getProperty(ErrorProperty.PARTS_LIBRARY_NAME), isNull); |
| 767 } |
| 768 |
| 769 test_perform_error_partDoesNotExist() { |
| 770 _performBuildTask({ |
| 771 '/lib.dart': ''' |
| 772 library lib; |
| 773 part 'part.dart'; |
| 774 ''' |
| 775 }); |
| 776 // we already report URI_DOES_NOT_EXIST, no need to report other errors |
| 777 _assertErrorsWithCodes([]); |
| 778 } |
| 779 |
| 780 test_perform_error_partOfDifferentLibrary() { |
| 781 _performBuildTask({ |
| 782 '/lib.dart': ''' |
| 783 library lib; |
| 784 part 'part.dart'; |
| 785 ''', |
| 786 '/part.dart': ''' |
| 787 part of someOtherLib; |
| 788 ''' |
| 789 }); |
| 790 _assertErrorsWithCodes([StaticWarningCode.PART_OF_DIFFERENT_LIBRARY]); |
| 791 } |
| 792 |
| 793 test_perform_error_partOfNonPart() { |
| 794 _performBuildTask({ |
| 795 '/lib.dart': ''' |
| 796 library lib; |
| 797 part 'part.dart'; |
| 798 ''', |
| 799 '/part.dart': ''' |
| 800 // no part of |
| 801 ''' |
| 802 }); |
| 803 _assertErrorsWithCodes([CompileTimeErrorCode.PART_OF_NON_PART]); |
| 804 } |
| 805 |
| 806 test_perform_invalidUri_part() { |
| 807 _performBuildTask({ |
| 808 '/lib.dart': ''' |
| 809 library lib; |
| 810 part '//////////'; |
| 811 ''' |
| 812 }); |
| 813 expect(libraryElement.parts, isEmpty); |
| 814 } |
| 815 |
| 816 test_perform_isLaunchable_inDefiningUnit() { |
| 817 _performBuildTask({ |
| 818 '/lib.dart': ''' |
| 819 library lib; |
| 820 main() { |
| 821 } |
| 822 ''' |
| 823 }); |
| 824 expect(outputs[IS_LAUNCHABLE], isTrue); |
| 825 expect(libraryElement.entryPoint, isNotNull); |
| 826 } |
| 827 |
| 828 test_perform_isLaunchable_inPartUnit() { |
| 829 _performBuildTask({ |
| 830 '/lib.dart': ''' |
| 831 library lib; |
| 832 part 'part.dart'; |
| 833 ''', |
| 834 '/part.dart': ''' |
| 835 part of lib; |
| 836 main() { |
| 837 } |
| 838 ''' |
| 839 }); |
| 840 expect(outputs[IS_LAUNCHABLE], isTrue); |
| 841 expect(libraryElement.entryPoint, isNotNull); |
| 842 } |
| 843 |
| 844 test_perform_noSuchFilePart() { |
| 845 _performBuildTask({ |
| 846 '/lib.dart': ''' |
| 847 library lib; |
| 848 part 'no-such-file.dart'; |
| 849 ''' |
| 850 }); |
| 851 expect(libraryElement.parts, hasLength(1)); |
| 852 CompilationUnitElement part = libraryElement.parts[0]; |
| 853 expect(part, isNotNull); |
| 854 expect(part.source, isNotNull); |
| 855 expect(part.library, same(libraryElement)); |
| 856 expect(context.exists(part.source), isFalse); |
| 857 } |
| 858 |
| 859 test_perform_patchTopLevelAccessors() { |
| 860 _performBuildTask({ |
| 861 '/lib.dart': ''' |
| 862 library lib; |
| 863 part 'part1.dart'; |
| 864 part 'part2.dart'; |
| 865 ''', |
| 866 '/part1.dart': ''' |
| 867 part of lib; |
| 868 int get test => 0; |
| 869 ''', |
| 870 '/part2.dart': ''' |
| 871 part of lib; |
| 872 void set test(_) {} |
| 873 ''' |
| 874 }); |
| 875 CompilationUnitElement unitElement1 = partUnits[0].element; |
| 876 CompilationUnitElement unitElement2 = partUnits[1].element; |
| 877 PropertyAccessorElement getter = unitElement1.accessors[0]; |
| 878 PropertyAccessorElement setter = unitElement2.accessors[0]; |
| 879 PropertyInducingElement variable = getter.variable; |
| 880 expect(getter.isGetter, isTrue); |
| 881 expect(setter.isSetter, isTrue); |
| 882 expect(variable, isNotNull); |
| 883 expect(setter.variable, same(variable)); |
| 884 expect(unitElement1.topLevelVariables, [variable]); |
| 885 expect(unitElement2.topLevelVariables, [variable]); |
| 886 } |
| 887 |
| 888 void _assertErrorsWithCodes(List<ErrorCode> expectedErrorCodes) { |
| 889 _fillErrorListener(BUILD_LIBRARY_ERRORS); |
| 890 errorListener.assertErrorsWithCodes(expectedErrorCodes); |
| 891 } |
| 892 |
| 893 void _performBuildTask(Map<String, String> sourceMap) { |
| 894 List<Source> sources = newSources(sourceMap); |
| 895 Source libSource = sources.first; |
| 896 computeResult(libSource, LIBRARY_ELEMENT1); |
| 897 expect(task, new isInstanceOf<BuildLibraryElementTask>()); |
| 898 libraryUnit = context |
| 899 .getCacheEntry(new LibrarySpecificUnit(libSource, libSource)) |
| 900 .getValue(RESOLVED_UNIT1); |
| 901 libraryUnitElement = libraryUnit.element; |
| 902 librarySource = libraryUnitElement.source; |
| 903 libraryElement = outputs[LIBRARY_ELEMENT1]; |
| 904 partUnits = task.inputs[BuildLibraryElementTask.PARTS_UNIT_INPUT]; |
| 905 } |
| 906 } |
| 907 |
| 908 @reflectiveTest |
| 909 class BuildPublicNamespaceTaskTest extends _AbstractDartTaskTest { |
| 910 test_buildInputs() { |
| 911 Map<String, TaskInput> inputs = |
| 912 BuildPublicNamespaceTask.buildInputs(emptySource); |
| 913 expect(inputs, isNotNull); |
| 914 expect( |
| 915 inputs.keys, unorderedEquals([BuildPublicNamespaceTask.LIBRARY_INPUT])); |
| 916 } |
| 917 |
| 918 test_constructor() { |
| 919 BuildPublicNamespaceTask task = |
| 920 new BuildPublicNamespaceTask(context, emptySource); |
| 921 expect(task, isNotNull); |
| 922 expect(task.context, context); |
| 923 expect(task.target, emptySource); |
| 924 } |
| 925 |
| 926 test_createTask() { |
| 927 BuildPublicNamespaceTask task = |
| 928 BuildPublicNamespaceTask.createTask(context, emptySource); |
| 929 expect(task, isNotNull); |
| 930 expect(task.context, context); |
| 931 expect(task.target, emptySource); |
| 932 } |
| 933 |
| 934 test_description() { |
| 935 BuildPublicNamespaceTask task = |
| 936 new BuildPublicNamespaceTask(null, emptySource); |
| 937 expect(task.description, isNotNull); |
| 938 } |
| 939 |
| 940 test_descriptor() { |
| 941 TaskDescriptor descriptor = BuildPublicNamespaceTask.DESCRIPTOR; |
| 942 expect(descriptor, isNotNull); |
| 943 } |
| 944 |
| 945 test_perform() { |
| 946 List<Source> sources = newSources({ |
| 947 '/lib.dart': ''' |
| 948 library lib; |
| 949 part 'part.dart'; |
| 950 a() {} |
| 951 _b() {} |
| 952 ''', |
| 953 '/part.dart': ''' |
| 954 part of lib; |
| 955 _c() {} |
| 956 d() {} |
| 957 ''' |
| 958 }); |
| 959 computeResult(sources.first, LIBRARY_ELEMENT3); |
| 960 expect(task, new isInstanceOf<BuildPublicNamespaceTask>()); |
| 961 // validate |
| 962 LibraryElement library = outputs[LIBRARY_ELEMENT3]; |
| 963 Namespace namespace = library.publicNamespace; |
| 964 expect(namespace.definedNames.keys, unorderedEquals(['a', 'd'])); |
| 965 } |
| 966 } |
| 967 |
| 968 @reflectiveTest |
| 969 class BuildSourceExportClosureTaskTest extends _AbstractDartTaskTest { |
| 970 test_perform_exportClosure() { |
| 971 Source sourceA = newSource( |
| 972 '/a.dart', |
| 973 ''' |
| 974 library lib_a; |
| 975 export 'b.dart'; |
| 976 '''); |
| 977 Source sourceB = newSource( |
| 978 '/b.dart', |
| 979 ''' |
| 980 library lib_b; |
| 981 export 'c.dart'; |
| 982 '''); |
| 983 Source sourceC = newSource( |
| 984 '/c.dart', |
| 985 ''' |
| 986 library lib_c; |
| 987 export 'a.dart'; |
| 988 '''); |
| 989 Source sourceD = newSource( |
| 990 '/d.dart', |
| 991 ''' |
| 992 library lib_d; |
| 993 '''); |
| 994 // a.dart |
| 995 { |
| 996 computeResult(sourceA, EXPORT_SOURCE_CLOSURE); |
| 997 expect(task, new isInstanceOf<BuildSourceExportClosureTask>()); |
| 998 List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE]; |
| 999 expect(closure, unorderedEquals([sourceA, sourceB, sourceC])); |
| 1000 } |
| 1001 // c.dart |
| 1002 { |
| 1003 computeResult(sourceC, EXPORT_SOURCE_CLOSURE); |
| 1004 expect(task, new isInstanceOf<BuildSourceExportClosureTask>()); |
| 1005 List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE]; |
| 1006 expect(closure, unorderedEquals([sourceA, sourceB, sourceC])); |
| 1007 } |
| 1008 // d.dart |
| 1009 { |
| 1010 computeResult(sourceD, EXPORT_SOURCE_CLOSURE); |
| 1011 expect(task, new isInstanceOf<BuildSourceExportClosureTask>()); |
| 1012 List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE]; |
| 1013 expect(closure, unorderedEquals([sourceD])); |
| 1014 } |
| 1015 } |
| 1016 } |
| 1017 |
| 1018 @reflectiveTest |
| 1019 class BuildSourceImportExportClosureTaskTest extends _AbstractDartTaskTest { |
| 1020 test_perform_importExportClosure() { |
| 1021 Source sourceA = newSource( |
| 1022 '/a.dart', |
| 1023 ''' |
| 1024 library lib_a; |
| 1025 '''); |
| 1026 Source sourceB = newSource( |
| 1027 '/b.dart', |
| 1028 ''' |
| 1029 library lib_b; |
| 1030 export 'a.dart'; |
| 1031 '''); |
| 1032 Source sourceC = newSource( |
| 1033 '/c.dart', |
| 1034 ''' |
| 1035 library lib_c; |
| 1036 import 'b.dart'; |
| 1037 '''); |
| 1038 Source coreSource = context.sourceFactory.resolveUri(null, 'dart:core'); |
| 1039 // c.dart |
| 1040 { |
| 1041 computeResult(sourceC, IMPORT_EXPORT_SOURCE_CLOSURE); |
| 1042 expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>()); |
| 1043 List<Source> closure = outputs[IMPORT_EXPORT_SOURCE_CLOSURE]; |
| 1044 expect(closure, contains(sourceA)); |
| 1045 expect(closure, contains(sourceB)); |
| 1046 expect(closure, contains(sourceC)); |
| 1047 expect(closure, contains(coreSource)); |
| 1048 } |
| 1049 // b.dart |
| 1050 { |
| 1051 computeResult(sourceB, IMPORT_EXPORT_SOURCE_CLOSURE); |
| 1052 expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>()); |
| 1053 List<Source> closure = outputs[IMPORT_EXPORT_SOURCE_CLOSURE]; |
| 1054 expect(closure, contains(sourceA)); |
| 1055 expect(closure, contains(sourceB)); |
| 1056 expect(closure, contains(coreSource)); |
| 1057 } |
| 1058 } |
| 1059 |
| 1060 test_perform_isClient_false() { |
| 1061 Source sourceA = newSource( |
| 1062 '/a.dart', |
| 1063 ''' |
| 1064 library lib_a; |
| 1065 import 'b.dart'; |
| 1066 '''); |
| 1067 newSource( |
| 1068 '/b.dart', |
| 1069 ''' |
| 1070 library lib_b; |
| 1071 '''); |
| 1072 computeResult(sourceA, IS_CLIENT); |
| 1073 expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>()); |
| 1074 expect(outputs[IS_CLIENT], isFalse); |
| 1075 } |
| 1076 |
| 1077 test_perform_isClient_true_export_indirect() { |
| 1078 newSource( |
| 1079 '/exports_html.dart', |
| 1080 ''' |
| 1081 library lib_exports_html; |
| 1082 export 'dart:html'; |
| 1083 '''); |
| 1084 Source source = newSource( |
| 1085 '/test.dart', |
| 1086 ''' |
| 1087 import 'exports_html.dart'; |
| 1088 '''); |
| 1089 computeResult(source, IS_CLIENT); |
| 1090 expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>()); |
| 1091 expect(outputs[IS_CLIENT], isTrue); |
| 1092 } |
| 1093 |
| 1094 test_perform_isClient_true_import_direct() { |
| 1095 Source sourceA = newSource( |
| 1096 '/a.dart', |
| 1097 ''' |
| 1098 library lib_a; |
| 1099 import 'dart:html'; |
| 1100 '''); |
| 1101 computeResult(sourceA, IS_CLIENT); |
| 1102 expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>()); |
| 1103 expect(outputs[IS_CLIENT], isTrue); |
| 1104 } |
| 1105 |
| 1106 test_perform_isClient_true_import_indirect() { |
| 1107 Source sourceA = newSource( |
| 1108 '/a.dart', |
| 1109 ''' |
| 1110 library lib_a; |
| 1111 import 'b.dart'; |
| 1112 '''); |
| 1113 newSource( |
| 1114 '/b.dart', |
| 1115 ''' |
| 1116 library lib_b; |
| 1117 import 'dart:html'; |
| 1118 '''); |
| 1119 computeResult(sourceA, IS_CLIENT); |
| 1120 expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>()); |
| 1121 expect(outputs[IS_CLIENT], isTrue); |
| 1122 } |
| 1123 } |
| 1124 |
| 1125 @reflectiveTest |
| 1126 class BuildTypeProviderTaskTest extends _AbstractDartTaskTest { |
| 1127 test_perform() { |
| 1128 computeResult(AnalysisContextTarget.request, TYPE_PROVIDER); |
| 1129 expect(task, new isInstanceOf<BuildTypeProviderTask>()); |
| 1130 // validate |
| 1131 TypeProvider typeProvider = outputs[TYPE_PROVIDER]; |
| 1132 expect(typeProvider, isNotNull); |
| 1133 expect(typeProvider.boolType, isNotNull); |
| 1134 expect(typeProvider.intType, isNotNull); |
| 1135 expect(typeProvider.futureType, isNotNull); |
| 1136 } |
| 1137 } |
| 1138 |
| 1139 @reflectiveTest |
| 1140 class ComputeConstantDependenciesTaskTest extends _AbstractDartTaskTest { |
| 1141 Annotation findClassAnnotation(CompilationUnit unit, String className) { |
| 1142 for (CompilationUnitMember member in unit.declarations) { |
| 1143 if (member is ClassDeclaration && member.name.name == className) { |
| 1144 expect(member.metadata, hasLength(1)); |
| 1145 return member.metadata[0]; |
| 1146 } |
| 1147 } |
| 1148 fail('Annotation not found'); |
| 1149 return null; |
| 1150 } |
| 1151 |
| 1152 test_annotation_with_args() { |
| 1153 Source source = newSource( |
| 1154 '/test.dart', |
| 1155 ''' |
| 1156 const x = 1; |
| 1157 @D(x) class C {} |
| 1158 class D { const D(value); } |
| 1159 '''); |
| 1160 // First compute the resolved unit for the source. |
| 1161 LibrarySpecificUnit librarySpecificUnit = |
| 1162 new LibrarySpecificUnit(source, source); |
| 1163 computeResult(librarySpecificUnit, RESOLVED_UNIT1); |
| 1164 CompilationUnit unit = outputs[RESOLVED_UNIT1]; |
| 1165 // Find the elements for x and D's constructor, and the annotation on C. |
| 1166 List<PropertyAccessorElement> accessors = unit.element.accessors; |
| 1167 Element x = accessors |
| 1168 .firstWhere((PropertyAccessorElement accessor) => |
| 1169 accessor.isGetter && accessor.name == 'x') |
| 1170 .variable; |
| 1171 List<ClassElement> types = unit.element.types; |
| 1172 Element constructorForD = |
| 1173 types.firstWhere((ClassElement cls) => cls.name == 'D').constructors[0]; |
| 1174 Annotation annotation = findClassAnnotation(unit, 'C'); |
| 1175 // Now compute the dependencies for the annotation, and check that it is |
| 1176 // the set [x, constructorForD]. |
| 1177 // TODO(paulberry): test librarySource != source |
| 1178 computeResult( |
| 1179 new ConstantEvaluationTarget_Annotation( |
| 1180 context, source, source, annotation), |
| 1181 CONSTANT_DEPENDENCIES); |
| 1182 expect( |
| 1183 outputs[CONSTANT_DEPENDENCIES].toSet(), [x, constructorForD].toSet()); |
| 1184 } |
| 1185 |
| 1186 test_annotation_without_args() { |
| 1187 Source source = newSource( |
| 1188 '/test.dart', |
| 1189 ''' |
| 1190 const x = 1; |
| 1191 @x class C {} |
| 1192 '''); |
| 1193 // First compute the resolved unit for the source. |
| 1194 LibrarySpecificUnit librarySpecificUnit = |
| 1195 new LibrarySpecificUnit(source, source); |
| 1196 computeResult(librarySpecificUnit, RESOLVED_UNIT1); |
| 1197 CompilationUnit unit = outputs[RESOLVED_UNIT1]; |
| 1198 // Find the element for x and the annotation on C. |
| 1199 List<PropertyAccessorElement> accessors = unit.element.accessors; |
| 1200 Element x = accessors |
| 1201 .firstWhere((PropertyAccessorElement accessor) => |
| 1202 accessor.isGetter && accessor.name == 'x') |
| 1203 .variable; |
| 1204 Annotation annotation = findClassAnnotation(unit, 'C'); |
| 1205 // Now compute the dependencies for the annotation, and check that it is |
| 1206 // the list [x]. |
| 1207 computeResult( |
| 1208 new ConstantEvaluationTarget_Annotation( |
| 1209 context, source, source, annotation), |
| 1210 CONSTANT_DEPENDENCIES); |
| 1211 expect(outputs[CONSTANT_DEPENDENCIES], [x]); |
| 1212 } |
| 1213 |
| 1214 test_enumConstant() { |
| 1215 Source source = newSource( |
| 1216 '/test.dart', |
| 1217 ''' |
| 1218 enum E {A, B, C} |
| 1219 '''); |
| 1220 // First compute the resolved unit for the source. |
| 1221 LibrarySpecificUnit librarySpecificUnit = |
| 1222 new LibrarySpecificUnit(source, source); |
| 1223 computeResult(librarySpecificUnit, RESOLVED_UNIT2); |
| 1224 CompilationUnit unit = outputs[RESOLVED_UNIT2]; |
| 1225 // Find the element for 'A' |
| 1226 EnumDeclaration enumDeclaration = unit.declarations[0]; |
| 1227 EnumConstantDeclaration constantDeclaration = enumDeclaration.constants[0]; |
| 1228 FieldElement constantElement = constantDeclaration.element; |
| 1229 // Now compute the dependencies for the constant and check that there are |
| 1230 // none. |
| 1231 computeResult(constantElement, CONSTANT_DEPENDENCIES); |
| 1232 expect(outputs[CONSTANT_DEPENDENCIES], isEmpty); |
| 1233 } |
| 1234 |
| 1235 test_perform() { |
| 1236 Source source = newSource( |
| 1237 '/test.dart', |
| 1238 ''' |
| 1239 const x = y; |
| 1240 const y = 1; |
| 1241 '''); |
| 1242 // First compute the resolved unit for the source. |
| 1243 LibrarySpecificUnit librarySpecificUnit = |
| 1244 new LibrarySpecificUnit(source, source); |
| 1245 computeResult(librarySpecificUnit, RESOLVED_UNIT1); |
| 1246 CompilationUnit unit = outputs[RESOLVED_UNIT1]; |
| 1247 // Find the elements for the constants x and y. |
| 1248 List<PropertyAccessorElement> accessors = unit.element.accessors; |
| 1249 Element x = accessors |
| 1250 .firstWhere((PropertyAccessorElement accessor) => |
| 1251 accessor.isGetter && accessor.name == 'x') |
| 1252 .variable; |
| 1253 Element y = accessors |
| 1254 .firstWhere((PropertyAccessorElement accessor) => |
| 1255 accessor.isGetter && accessor.name == 'y') |
| 1256 .variable; |
| 1257 // Now compute the dependencies for x, and check that it is the list [y]. |
| 1258 computeResult(x, CONSTANT_DEPENDENCIES); |
| 1259 expect(outputs[CONSTANT_DEPENDENCIES], [y]); |
| 1260 } |
| 1261 } |
| 1262 |
| 1263 @reflectiveTest |
| 1264 class ComputeConstantValueTaskTest extends _AbstractDartTaskTest { |
| 1265 EvaluationResultImpl computeClassAnnotation( |
| 1266 Source source, CompilationUnit unit, String className) { |
| 1267 for (CompilationUnitMember member in unit.declarations) { |
| 1268 if (member is ClassDeclaration && member.name.name == className) { |
| 1269 expect(member.metadata, hasLength(1)); |
| 1270 Annotation annotation = member.metadata[0]; |
| 1271 ConstantEvaluationTarget_Annotation target = |
| 1272 new ConstantEvaluationTarget_Annotation( |
| 1273 context, source, source, annotation); |
| 1274 computeResult(target, CONSTANT_VALUE); |
| 1275 expect(outputs[CONSTANT_VALUE], same(target)); |
| 1276 EvaluationResultImpl evaluationResult = (annotation.elementAnnotation |
| 1277 as ElementAnnotationImpl).evaluationResult; |
| 1278 return evaluationResult; |
| 1279 } |
| 1280 } |
| 1281 fail('Annotation not found'); |
| 1282 return null; |
| 1283 } |
| 1284 |
| 1285 test_annotation_non_const_constructor() { |
| 1286 // Calling a non-const constructor from an annotation that is illegal, but |
| 1287 // shouldn't crash analysis. |
| 1288 Source source = newSource( |
| 1289 '/test.dart', |
| 1290 ''' |
| 1291 class A { |
| 1292 final int i; |
| 1293 A(this.i); |
| 1294 } |
| 1295 |
| 1296 @A(5) |
| 1297 class C {} |
| 1298 '''); |
| 1299 // First compute the resolved unit for the source. |
| 1300 CompilationUnit unit = _resolveSource(source); |
| 1301 // Compute the constant value of the annotation on C. |
| 1302 EvaluationResultImpl evaluationResult = |
| 1303 computeClassAnnotation(source, unit, 'C'); |
| 1304 // And check that it has no value stored in it. |
| 1305 expect(evaluationResult, isNotNull); |
| 1306 expect(evaluationResult.value, isNull); |
| 1307 } |
| 1308 |
| 1309 test_annotation_with_args() { |
| 1310 Source source = newSource( |
| 1311 '/test.dart', |
| 1312 ''' |
| 1313 const x = 1; |
| 1314 @D(x) class C {} |
| 1315 class D { |
| 1316 const D(this.value); |
| 1317 final value; |
| 1318 } |
| 1319 '''); |
| 1320 // First compute the resolved unit for the source. |
| 1321 CompilationUnit unit = _resolveSource(source); |
| 1322 // Compute the constant value of the annotation on C. |
| 1323 EvaluationResultImpl evaluationResult = |
| 1324 computeClassAnnotation(source, unit, 'C'); |
| 1325 // And check that it has the expected value. |
| 1326 expect(evaluationResult, isNotNull); |
| 1327 expect(evaluationResult.value, isNotNull); |
| 1328 expect(evaluationResult.value.type, isNotNull); |
| 1329 expect(evaluationResult.value.type.name, 'D'); |
| 1330 expect(evaluationResult.value.fields, contains('value')); |
| 1331 expect(evaluationResult.value.fields['value'].intValue, 1); |
| 1332 } |
| 1333 |
| 1334 test_annotation_without_args() { |
| 1335 Source source = newSource( |
| 1336 '/test.dart', |
| 1337 ''' |
| 1338 const x = 1; |
| 1339 @x class C {} |
| 1340 '''); |
| 1341 // First compute the resolved unit for the source. |
| 1342 CompilationUnit unit = _resolveSource(source); |
| 1343 // Compute the constant value of the annotation on C. |
| 1344 EvaluationResultImpl evaluationResult = |
| 1345 computeClassAnnotation(source, unit, 'C'); |
| 1346 // And check that it has the expected value. |
| 1347 expect(evaluationResult, isNotNull); |
| 1348 expect(evaluationResult.value, isNotNull); |
| 1349 expect(evaluationResult.value.intValue, 1); |
| 1350 } |
| 1351 |
| 1352 test_circular_reference() { |
| 1353 _checkCircularities( |
| 1354 'x', |
| 1355 ['y'], |
| 1356 ''' |
| 1357 const x = y + 1; |
| 1358 const y = x + 1; |
| 1359 '''); |
| 1360 } |
| 1361 |
| 1362 test_circular_reference_one_element() { |
| 1363 // See dartbug.com/23490. |
| 1364 _checkCircularities('x', [], 'const x = x;'); |
| 1365 } |
| 1366 |
| 1367 test_circular_reference_strongly_connected_component() { |
| 1368 // When there is a circularity, all elements in the strongly connected |
| 1369 // component should be marked as having an error. |
| 1370 _checkCircularities( |
| 1371 'a', |
| 1372 ['b', 'c', 'd'], |
| 1373 ''' |
| 1374 const a = b; |
| 1375 const b = c + d; |
| 1376 const c = a; |
| 1377 const d = a; |
| 1378 '''); |
| 1379 } |
| 1380 |
| 1381 test_const_constructor_calls_implicit_super_constructor_implicitly() { |
| 1382 // Note: the situation below is a compile-time error (since the synthetic |
| 1383 // constructor for Base is non-const), but we need to handle it without |
| 1384 // throwing an exception. |
| 1385 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue( |
| 1386 'x', |
| 1387 ''' |
| 1388 class Base {} |
| 1389 class Derived extends Base { |
| 1390 const Derived(); |
| 1391 } |
| 1392 const x = const Derived(); |
| 1393 '''); |
| 1394 expect(evaluationResult, isNotNull); |
| 1395 } |
| 1396 |
| 1397 test_dependency() { |
| 1398 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue( |
| 1399 'x', |
| 1400 ''' |
| 1401 const x = y + 1; |
| 1402 const y = 1; |
| 1403 '''); |
| 1404 expect(evaluationResult, isNotNull); |
| 1405 expect(evaluationResult.value, isNotNull); |
| 1406 expect(evaluationResult.value.intValue, 2); |
| 1407 } |
| 1408 |
| 1409 test_external_const_factory() { |
| 1410 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue( |
| 1411 'x', |
| 1412 ''' |
| 1413 const x = const C.foo(); |
| 1414 |
| 1415 class C extends B { |
| 1416 external const factory C.foo(); |
| 1417 } |
| 1418 |
| 1419 class B {} |
| 1420 '''); |
| 1421 expect(evaluationResult, isNotNull); |
| 1422 } |
| 1423 |
| 1424 test_simple_constant() { |
| 1425 EvaluationResultImpl evaluationResult = _computeTopLevelVariableConstValue( |
| 1426 'x', |
| 1427 ''' |
| 1428 const x = 1; |
| 1429 '''); |
| 1430 expect(evaluationResult, isNotNull); |
| 1431 expect(evaluationResult.value, isNotNull); |
| 1432 expect(evaluationResult.value.intValue, 1); |
| 1433 } |
| 1434 |
| 1435 void _checkCircularities( |
| 1436 String variableName, List<String> otherVariables, String content) { |
| 1437 // Evaluating the first constant should produce an error. |
| 1438 CompilationUnit unit = _resolveUnit(content); |
| 1439 _expectCircularityError(_evaluateConstant(unit, variableName)); |
| 1440 // And all the other constants involved in the strongly connected component |
| 1441 // should be set to the same error state. |
| 1442 for (String otherVariableName in otherVariables) { |
| 1443 PropertyInducingElement otherVariableElement = |
| 1444 _findVariable(unit, otherVariableName); |
| 1445 _expectCircularityError((otherVariableElement |
| 1446 as TopLevelVariableElementImpl).evaluationResult); |
| 1447 } |
| 1448 } |
| 1449 |
| 1450 EvaluationResultImpl _computeTopLevelVariableConstValue( |
| 1451 String variableName, String content) { |
| 1452 return _evaluateConstant(_resolveUnit(content), variableName); |
| 1453 } |
| 1454 |
| 1455 EvaluationResultImpl _evaluateConstant( |
| 1456 CompilationUnit unit, String variableName) { |
| 1457 // Find the element for the given constant. |
| 1458 PropertyInducingElement variableElement = _findVariable(unit, variableName); |
| 1459 // Now compute the value of the constant. |
| 1460 computeResult(variableElement, CONSTANT_VALUE); |
| 1461 expect(outputs[CONSTANT_VALUE], same(variableElement)); |
| 1462 EvaluationResultImpl evaluationResult = |
| 1463 (variableElement as TopLevelVariableElementImpl).evaluationResult; |
| 1464 return evaluationResult; |
| 1465 } |
| 1466 |
| 1467 void _expectCircularityError(EvaluationResultImpl evaluationResult) { |
| 1468 expect(evaluationResult, isNotNull); |
| 1469 expect(evaluationResult.value, isNull); |
| 1470 expect(evaluationResult.errors, hasLength(1)); |
| 1471 expect(evaluationResult.errors[0].errorCode, |
| 1472 CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT); |
| 1473 } |
| 1474 |
| 1475 PropertyInducingElement _findVariable( |
| 1476 CompilationUnit unit, String variableName) { |
| 1477 // Find the element for the given constant. |
| 1478 return unit.element.topLevelVariables.firstWhere( |
| 1479 (TopLevelVariableElement variable) => variable.name == variableName); |
| 1480 } |
| 1481 |
| 1482 CompilationUnit _resolveSource(Source source) { |
| 1483 LibrarySpecificUnit librarySpecificUnit = |
| 1484 new LibrarySpecificUnit(source, source); |
| 1485 computeResult(librarySpecificUnit, RESOLVED_UNIT1); |
| 1486 CompilationUnit unit = outputs[RESOLVED_UNIT1]; |
| 1487 return unit; |
| 1488 } |
| 1489 |
| 1490 CompilationUnit _resolveUnit(String content) => |
| 1491 _resolveSource(newSource('/test.dart', content)); |
| 1492 } |
| 1493 |
| 1494 @reflectiveTest |
| 1495 class ComputeInferableStaticVariableDependenciesTaskTest |
| 1496 extends _AbstractDartTaskTest { |
| 1497 test_perform() { |
| 1498 AnalysisTarget source = newSource( |
| 1499 '/test.dart', |
| 1500 ''' |
| 1501 const a = b; |
| 1502 const b = 0; |
| 1503 '''); |
| 1504 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1505 computeResult(target, RESOLVED_UNIT5); |
| 1506 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 1507 TopLevelVariableElement elementA = unit.element.topLevelVariables[0]; |
| 1508 TopLevelVariableElement elementB = unit.element.topLevelVariables[1]; |
| 1509 |
| 1510 computeResult(elementA, INFERABLE_STATIC_VARIABLE_DEPENDENCIES); |
| 1511 expect(task, |
| 1512 new isInstanceOf<ComputeInferableStaticVariableDependenciesTask>()); |
| 1513 expect(outputs, hasLength(1)); |
| 1514 List<VariableElement> dependencies = |
| 1515 outputs[INFERABLE_STATIC_VARIABLE_DEPENDENCIES]; |
| 1516 expect(dependencies, unorderedEquals([elementB])); |
| 1517 } |
| 1518 } |
| 1519 |
| 1520 @reflectiveTest |
| 1521 class ContainingLibrariesTaskTest extends _AbstractDartTaskTest { |
| 1522 test_buildInputs() { |
| 1523 Map<String, TaskInput> inputs = |
| 1524 ContainingLibrariesTask.buildInputs(emptySource); |
| 1525 expect(inputs, isNotNull); |
| 1526 expect(inputs, isEmpty); |
| 1527 } |
| 1528 |
| 1529 test_constructor() { |
| 1530 ContainingLibrariesTask task = |
| 1531 new ContainingLibrariesTask(context, emptySource); |
| 1532 expect(task, isNotNull); |
| 1533 expect(task.context, context); |
| 1534 expect(task.target, emptySource); |
| 1535 } |
| 1536 |
| 1537 test_createTask() { |
| 1538 ContainingLibrariesTask task = |
| 1539 ContainingLibrariesTask.createTask(context, emptySource); |
| 1540 expect(task, isNotNull); |
| 1541 expect(task.context, context); |
| 1542 expect(task.target, emptySource); |
| 1543 } |
| 1544 |
| 1545 test_description() { |
| 1546 ContainingLibrariesTask task = |
| 1547 new ContainingLibrariesTask(null, emptySource); |
| 1548 expect(task.description, isNotNull); |
| 1549 } |
| 1550 |
| 1551 test_descriptor() { |
| 1552 TaskDescriptor descriptor = ContainingLibrariesTask.DESCRIPTOR; |
| 1553 expect(descriptor, isNotNull); |
| 1554 } |
| 1555 |
| 1556 test_perform_definingCompilationUnit() { |
| 1557 AnalysisTarget library = newSource('/test.dart', 'library test;'); |
| 1558 computeResult(library, INCLUDED_PARTS); |
| 1559 computeResult(library, CONTAINING_LIBRARIES); |
| 1560 expect(task, new isInstanceOf<ContainingLibrariesTask>()); |
| 1561 expect(outputs, hasLength(1)); |
| 1562 List<Source> containingLibraries = outputs[CONTAINING_LIBRARIES]; |
| 1563 expect(containingLibraries, unorderedEquals([library])); |
| 1564 } |
| 1565 |
| 1566 test_perform_partInMultipleLibraries() { |
| 1567 AnalysisTarget library1 = |
| 1568 newSource('/lib1.dart', 'library test; part "part.dart";'); |
| 1569 AnalysisTarget library2 = |
| 1570 newSource('/lib2.dart', 'library test; part "part.dart";'); |
| 1571 AnalysisTarget part = newSource('/part.dart', 'part of test;'); |
| 1572 computeResult(library1, INCLUDED_PARTS); |
| 1573 computeResult(library2, INCLUDED_PARTS); |
| 1574 computeResult(part, SOURCE_KIND); |
| 1575 computeResult(part, CONTAINING_LIBRARIES); |
| 1576 expect(task, new isInstanceOf<ContainingLibrariesTask>()); |
| 1577 expect(outputs, hasLength(1)); |
| 1578 List<Source> containingLibraries = outputs[CONTAINING_LIBRARIES]; |
| 1579 expect(containingLibraries, unorderedEquals([library1, library2])); |
| 1580 } |
| 1581 |
| 1582 test_perform_partInSingleLibrary() { |
| 1583 AnalysisTarget library = |
| 1584 newSource('/lib.dart', 'library test; part "part.dart";'); |
| 1585 AnalysisTarget part = newSource('/part.dart', 'part of test;'); |
| 1586 computeResult(library, INCLUDED_PARTS); |
| 1587 computeResult(part, SOURCE_KIND); |
| 1588 computeResult(part, CONTAINING_LIBRARIES); |
| 1589 expect(task, new isInstanceOf<ContainingLibrariesTask>()); |
| 1590 expect(outputs, hasLength(1)); |
| 1591 List<Source> containingLibraries = outputs[CONTAINING_LIBRARIES]; |
| 1592 expect(containingLibraries, unorderedEquals([library])); |
| 1593 } |
| 1594 } |
| 1595 |
| 1596 @reflectiveTest |
| 1597 class DartErrorsTaskTest extends _AbstractDartTaskTest { |
| 1598 test_buildInputs() { |
| 1599 Map<String, TaskInput> inputs = DartErrorsTask.buildInputs(emptySource); |
| 1600 expect(inputs, isNotNull); |
| 1601 expect( |
| 1602 inputs.keys, |
| 1603 unorderedEquals([ |
| 1604 DartErrorsTask.BUILD_DIRECTIVES_ERRORS_INPUT, |
| 1605 DartErrorsTask.BUILD_LIBRARY_ERRORS_INPUT, |
| 1606 DartErrorsTask.PARSE_ERRORS_INPUT, |
| 1607 DartErrorsTask.SCAN_ERRORS_INPUT, |
| 1608 DartErrorsTask.LIBRARY_UNIT_ERRORS_INPUT |
| 1609 ])); |
| 1610 } |
| 1611 |
| 1612 test_constructor() { |
| 1613 DartErrorsTask task = new DartErrorsTask(context, emptySource); |
| 1614 expect(task, isNotNull); |
| 1615 expect(task.context, context); |
| 1616 expect(task.target, emptySource); |
| 1617 } |
| 1618 |
| 1619 test_createTask() { |
| 1620 DartErrorsTask task = DartErrorsTask.createTask(context, emptySource); |
| 1621 expect(task, isNotNull); |
| 1622 expect(task.context, context); |
| 1623 expect(task.target, emptySource); |
| 1624 } |
| 1625 |
| 1626 test_description() { |
| 1627 DartErrorsTask task = new DartErrorsTask(null, emptySource); |
| 1628 expect(task.description, isNotNull); |
| 1629 } |
| 1630 |
| 1631 test_descriptor() { |
| 1632 TaskDescriptor descriptor = DartErrorsTask.DESCRIPTOR; |
| 1633 expect(descriptor, isNotNull); |
| 1634 } |
| 1635 |
| 1636 test_perform_definingCompilationUnit() { |
| 1637 AnalysisTarget library = |
| 1638 newSource('/test.dart', 'library test; import "dart:math";'); |
| 1639 computeResult(library, INCLUDED_PARTS); |
| 1640 computeResult(library, DART_ERRORS); |
| 1641 expect(task, new isInstanceOf<DartErrorsTask>()); |
| 1642 expect(outputs, hasLength(1)); |
| 1643 List<AnalysisError> errors = outputs[DART_ERRORS]; |
| 1644 expect(errors, hasLength(1)); |
| 1645 } |
| 1646 |
| 1647 test_perform_partInSingleLibrary() { |
| 1648 AnalysisTarget library = newSource( |
| 1649 '/lib.dart', 'library test; import "dart:math"; part "part.dart";'); |
| 1650 AnalysisTarget part = |
| 1651 newSource('/part.dart', 'part of test; class A extends A {}'); |
| 1652 computeResult(library, INCLUDED_PARTS); |
| 1653 computeResult(library, DART_ERRORS); |
| 1654 computeResult(part, DART_ERRORS); |
| 1655 expect(task, new isInstanceOf<DartErrorsTask>()); |
| 1656 expect(outputs, hasLength(1)); |
| 1657 List<AnalysisError> errors = outputs[DART_ERRORS]; |
| 1658 // This should contain only the errors in the part file, not the ones in the |
| 1659 // library. |
| 1660 expect(errors, hasLength(1)); |
| 1661 } |
| 1662 } |
| 1663 |
| 1664 @reflectiveTest |
| 1665 class EvaluateUnitConstantsTaskTest extends _AbstractDartTaskTest { |
| 1666 test_perform() { |
| 1667 Source source = newSource( |
| 1668 '/test.dart', |
| 1669 ''' |
| 1670 class C { |
| 1671 const C(); |
| 1672 } |
| 1673 |
| 1674 @x |
| 1675 f() {} |
| 1676 |
| 1677 const x = const C(); |
| 1678 '''); |
| 1679 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1680 computeResult(target, RESOLVED_UNIT); |
| 1681 expect(task, new isInstanceOf<EvaluateUnitConstantsTask>()); |
| 1682 CompilationUnit unit = outputs[RESOLVED_UNIT]; |
| 1683 CompilationUnitElement unitElement = unit.element; |
| 1684 expect( |
| 1685 (unitElement.types[0].constructors[0] as ConstructorElementImpl) |
| 1686 .isCycleFree, |
| 1687 isTrue); |
| 1688 expect( |
| 1689 (unitElement.functions[0].metadata[0] as ElementAnnotationImpl) |
| 1690 .evaluationResult, |
| 1691 isNotNull); |
| 1692 expect( |
| 1693 (unitElement.topLevelVariables[0] as TopLevelVariableElementImpl) |
| 1694 .evaluationResult, |
| 1695 isNotNull); |
| 1696 } |
| 1697 } |
| 1698 |
| 1699 @reflectiveTest |
| 1700 class GatherUsedImportedElementsTaskTest extends _AbstractDartTaskTest { |
| 1701 UsedImportedElements usedElements; |
| 1702 Set<String> usedElementNames; |
| 1703 |
| 1704 test_perform() { |
| 1705 newSource( |
| 1706 '/a.dart', |
| 1707 r''' |
| 1708 library lib_a; |
| 1709 class A {} |
| 1710 '''); |
| 1711 newSource( |
| 1712 '/b.dart', |
| 1713 r''' |
| 1714 library lib_b; |
| 1715 class B {} |
| 1716 '''); |
| 1717 Source source = newSource( |
| 1718 '/test.dart', |
| 1719 r''' |
| 1720 import 'a.dart'; |
| 1721 import 'b.dart'; |
| 1722 main() { |
| 1723 new A(); |
| 1724 }'''); |
| 1725 _computeUsedElements(source); |
| 1726 // validate |
| 1727 expect(usedElementNames, unorderedEquals(['A'])); |
| 1728 } |
| 1729 |
| 1730 void _computeUsedElements(Source source) { |
| 1731 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1732 computeResult(target, USED_IMPORTED_ELEMENTS); |
| 1733 expect(task, new isInstanceOf<GatherUsedImportedElementsTask>()); |
| 1734 usedElements = outputs[USED_IMPORTED_ELEMENTS]; |
| 1735 usedElementNames = usedElements.elements.map((e) => e.name).toSet(); |
| 1736 } |
| 1737 } |
| 1738 |
| 1739 @reflectiveTest |
| 1740 class GatherUsedLocalElementsTaskTest extends _AbstractDartTaskTest { |
| 1741 UsedLocalElements usedElements; |
| 1742 Set<String> usedElementNames; |
| 1743 |
| 1744 test_perform_localVariable() { |
| 1745 Source source = newSource( |
| 1746 '/test.dart', |
| 1747 r''' |
| 1748 main() { |
| 1749 var v1 = 1; |
| 1750 var v2 = 2; |
| 1751 print(v2); |
| 1752 }'''); |
| 1753 _computeUsedElements(source); |
| 1754 // validate |
| 1755 expect(usedElementNames, unorderedEquals(['v2'])); |
| 1756 } |
| 1757 |
| 1758 test_perform_method() { |
| 1759 Source source = newSource( |
| 1760 '/test.dart', |
| 1761 r''' |
| 1762 class A { |
| 1763 _m1() {} |
| 1764 _m2() {} |
| 1765 } |
| 1766 |
| 1767 main(A a, p) { |
| 1768 a._m2(); |
| 1769 p._m3(); |
| 1770 } |
| 1771 '''); |
| 1772 _computeUsedElements(source); |
| 1773 // validate |
| 1774 expect(usedElementNames, unorderedEquals(['A', 'a', 'p', '_m2'])); |
| 1775 expect(usedElements.members, unorderedEquals(['_m2', '_m3'])); |
| 1776 } |
| 1777 |
| 1778 void _computeUsedElements(Source source) { |
| 1779 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1780 computeResult(target, USED_LOCAL_ELEMENTS); |
| 1781 expect(task, new isInstanceOf<GatherUsedLocalElementsTask>()); |
| 1782 usedElements = outputs[USED_LOCAL_ELEMENTS]; |
| 1783 usedElementNames = usedElements.elements.map((e) => e.name).toSet(); |
| 1784 } |
| 1785 } |
| 1786 |
| 1787 @reflectiveTest |
| 1788 class GenerateHintsTaskTest extends _AbstractDartTaskTest { |
| 1789 test_perform_bestPractices_missingReturn() { |
| 1790 Source source = newSource( |
| 1791 '/test.dart', |
| 1792 ''' |
| 1793 int main() { |
| 1794 } |
| 1795 '''); |
| 1796 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1797 computeResult(target, HINTS); |
| 1798 expect(task, new isInstanceOf<GenerateHintsTask>()); |
| 1799 // validate |
| 1800 _fillErrorListener(HINTS); |
| 1801 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.MISSING_RETURN]); |
| 1802 } |
| 1803 |
| 1804 test_perform_dart2js() { |
| 1805 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); |
| 1806 options.dart2jsHint = true; |
| 1807 prepareAnalysisContext(options); |
| 1808 Source source = newSource( |
| 1809 '/test.dart', |
| 1810 ''' |
| 1811 main(p) { |
| 1812 if (p is double) { |
| 1813 print('double'); |
| 1814 } |
| 1815 } |
| 1816 '''); |
| 1817 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1818 computeResult(target, HINTS); |
| 1819 expect(task, new isInstanceOf<GenerateHintsTask>()); |
| 1820 // validate |
| 1821 _fillErrorListener(HINTS); |
| 1822 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.IS_DOUBLE]); |
| 1823 } |
| 1824 |
| 1825 test_perform_deadCode() { |
| 1826 Source source = newSource( |
| 1827 '/test.dart', |
| 1828 ''' |
| 1829 main() { |
| 1830 if (false) { |
| 1831 print('how?'); |
| 1832 } |
| 1833 } |
| 1834 '''); |
| 1835 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1836 computeResult(target, HINTS); |
| 1837 expect(task, new isInstanceOf<GenerateHintsTask>()); |
| 1838 // validate |
| 1839 _fillErrorListener(HINTS); |
| 1840 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.DEAD_CODE]); |
| 1841 } |
| 1842 |
| 1843 test_perform_disabled() { |
| 1844 context.analysisOptions = |
| 1845 new AnalysisOptionsImpl.from(context.analysisOptions)..hint = false; |
| 1846 Source source = newSource( |
| 1847 '/test.dart', |
| 1848 ''' |
| 1849 int main() { |
| 1850 } |
| 1851 '''); |
| 1852 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1853 computeResult(target, HINTS); |
| 1854 expect(task, new isInstanceOf<GenerateHintsTask>()); |
| 1855 // validate |
| 1856 _fillErrorListener(HINTS); |
| 1857 errorListener.assertNoErrors(); |
| 1858 } |
| 1859 |
| 1860 test_perform_imports_duplicateImport() { |
| 1861 newSource( |
| 1862 '/a.dart', |
| 1863 r''' |
| 1864 library lib_a; |
| 1865 class A {} |
| 1866 '''); |
| 1867 Source source = newSource( |
| 1868 '/test.dart', |
| 1869 r''' |
| 1870 import 'a.dart'; |
| 1871 import 'a.dart'; |
| 1872 main() { |
| 1873 new A(); |
| 1874 } |
| 1875 '''); |
| 1876 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1877 computeResult(target, HINTS); |
| 1878 expect(task, new isInstanceOf<GenerateHintsTask>()); |
| 1879 // validate |
| 1880 _fillErrorListener(HINTS); |
| 1881 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.DUPLICATE_IMPORT]); |
| 1882 } |
| 1883 |
| 1884 test_perform_imports_unusedImport_one() { |
| 1885 newSource( |
| 1886 '/a.dart', |
| 1887 r''' |
| 1888 library lib_a; |
| 1889 class A {} |
| 1890 '''); |
| 1891 newSource( |
| 1892 '/b.dart', |
| 1893 r''' |
| 1894 library lib_b; |
| 1895 class B {} |
| 1896 '''); |
| 1897 Source source = newSource( |
| 1898 '/test.dart', |
| 1899 r''' |
| 1900 import 'a.dart'; |
| 1901 import 'b.dart'; |
| 1902 main() { |
| 1903 new A(); |
| 1904 }'''); |
| 1905 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1906 computeResult(target, HINTS); |
| 1907 expect(task, new isInstanceOf<GenerateHintsTask>()); |
| 1908 // validate |
| 1909 _fillErrorListener(HINTS); |
| 1910 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.UNUSED_IMPORT]); |
| 1911 } |
| 1912 |
| 1913 test_perform_imports_unusedImport_zero() { |
| 1914 newSource( |
| 1915 '/a.dart', |
| 1916 r''' |
| 1917 library lib_a; |
| 1918 class A {} |
| 1919 '''); |
| 1920 Source source = newSource( |
| 1921 '/test.dart', |
| 1922 r''' |
| 1923 import 'a.dart'; |
| 1924 main() { |
| 1925 new A(); |
| 1926 }'''); |
| 1927 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1928 computeResult(target, HINTS); |
| 1929 expect(task, new isInstanceOf<GenerateHintsTask>()); |
| 1930 // validate |
| 1931 _fillErrorListener(HINTS); |
| 1932 errorListener.assertNoErrors(); |
| 1933 } |
| 1934 |
| 1935 test_perform_overrideVerifier() { |
| 1936 Source source = newSource( |
| 1937 '/test.dart', |
| 1938 ''' |
| 1939 class A {} |
| 1940 class B { |
| 1941 @override |
| 1942 m() {} |
| 1943 } |
| 1944 '''); |
| 1945 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1946 computeResult(target, HINTS); |
| 1947 expect(task, new isInstanceOf<GenerateHintsTask>()); |
| 1948 // validate |
| 1949 _fillErrorListener(HINTS); |
| 1950 errorListener.assertErrorsWithCodes( |
| 1951 <ErrorCode>[HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]); |
| 1952 } |
| 1953 |
| 1954 test_perform_todo() { |
| 1955 Source source = newSource( |
| 1956 '/test.dart', |
| 1957 ''' |
| 1958 main() { |
| 1959 // TODO(developer) foo bar |
| 1960 } |
| 1961 '''); |
| 1962 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1963 computeResult(target, HINTS); |
| 1964 expect(task, new isInstanceOf<GenerateHintsTask>()); |
| 1965 // validate |
| 1966 _fillErrorListener(HINTS); |
| 1967 errorListener.assertErrorsWithCodes(<ErrorCode>[TodoCode.TODO]); |
| 1968 } |
| 1969 |
| 1970 test_perform_unusedLocalElements_class() { |
| 1971 Source source = newSource( |
| 1972 '/test.dart', |
| 1973 ''' |
| 1974 class _A {} |
| 1975 class _B {} |
| 1976 main() { |
| 1977 new _A(); |
| 1978 } |
| 1979 '''); |
| 1980 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1981 computeResult(target, HINTS); |
| 1982 expect(task, new isInstanceOf<GenerateHintsTask>()); |
| 1983 // validate |
| 1984 _fillErrorListener(HINTS); |
| 1985 errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.UNUSED_ELEMENT]); |
| 1986 } |
| 1987 |
| 1988 test_perform_unusedLocalElements_localVariable() { |
| 1989 Source source = newSource( |
| 1990 '/test.dart', |
| 1991 ''' |
| 1992 main() { |
| 1993 var v = 42; |
| 1994 } |
| 1995 '''); |
| 1996 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 1997 computeResult(target, HINTS); |
| 1998 expect(task, new isInstanceOf<GenerateHintsTask>()); |
| 1999 // validate |
| 2000 _fillErrorListener(HINTS); |
| 2001 errorListener |
| 2002 .assertErrorsWithCodes(<ErrorCode>[HintCode.UNUSED_LOCAL_VARIABLE]); |
| 2003 } |
| 2004 |
| 2005 test_perform_unusedLocalElements_method() { |
| 2006 Source source = newSource( |
| 2007 '/my_lib.dart', |
| 2008 ''' |
| 2009 library my_lib; |
| 2010 part 'my_part.dart'; |
| 2011 class A { |
| 2012 _ma() {} |
| 2013 _mb() {} |
| 2014 _mc() {} |
| 2015 } |
| 2016 '''); |
| 2017 newSource( |
| 2018 '/my_part.dart', |
| 2019 ''' |
| 2020 part of my_lib; |
| 2021 |
| 2022 f(A a) { |
| 2023 a._mb(); |
| 2024 } |
| 2025 '''); |
| 2026 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2027 computeResult(target, HINTS); |
| 2028 expect(task, new isInstanceOf<GenerateHintsTask>()); |
| 2029 // validate |
| 2030 _fillErrorListener(HINTS); |
| 2031 errorListener.assertErrorsWithCodes( |
| 2032 <ErrorCode>[HintCode.UNUSED_ELEMENT, HintCode.UNUSED_ELEMENT]); |
| 2033 } |
| 2034 } |
| 2035 |
| 2036 @reflectiveTest |
| 2037 class InferStaticVariableTypesInUnitTaskTest extends _AbstractDartTaskTest { |
| 2038 void test_perform() { |
| 2039 enableStrongMode(); |
| 2040 AnalysisTarget firstSource = newSource( |
| 2041 '/first.dart', |
| 2042 ''' |
| 2043 import 'second.dart'; |
| 2044 |
| 2045 var a = new M(); |
| 2046 var c = b; |
| 2047 '''); |
| 2048 AnalysisTarget secondSource = newSource( |
| 2049 '/second.dart', |
| 2050 ''' |
| 2051 import 'first.dart'; |
| 2052 |
| 2053 var b = a; |
| 2054 class M {} |
| 2055 '''); |
| 2056 computeResult(new LibrarySpecificUnit(firstSource, firstSource), |
| 2057 RESOLVED_UNIT6); // new isInstanceOf<InferStaticVariableTypesInUnitTask
>() |
| 2058 CompilationUnit firstUnit = outputs[RESOLVED_UNIT6]; |
| 2059 computeResult( |
| 2060 new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT6); |
| 2061 CompilationUnit secondUnit = outputs[RESOLVED_UNIT6]; |
| 2062 |
| 2063 VariableDeclaration variableA = getTopLevelVariable(firstUnit, 'a'); |
| 2064 VariableDeclaration variableB = getTopLevelVariable(secondUnit, 'b'); |
| 2065 VariableDeclaration variableC = getTopLevelVariable(firstUnit, 'c'); |
| 2066 ClassDeclaration classM = getClass(secondUnit, 'M'); |
| 2067 DartType typeM = classM.element.type; |
| 2068 |
| 2069 expect(variableA.element.type, typeM); |
| 2070 expect(variableB.element.type, typeM); |
| 2071 expect(variableB.initializer.staticType, typeM); |
| 2072 expect(variableC.element.type, typeM); |
| 2073 expect(variableC.initializer.staticType, typeM); |
| 2074 } |
| 2075 } |
| 2076 |
| 2077 @reflectiveTest |
| 2078 class InferStaticVariableTypeTaskTest extends _AbstractDartTaskTest { |
| 2079 void test_getDeclaration_staticField() { |
| 2080 AnalysisTarget source = newSource( |
| 2081 '/test.dart', |
| 2082 ''' |
| 2083 class C { |
| 2084 var field = ''; |
| 2085 } |
| 2086 '''); |
| 2087 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5); |
| 2088 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 2089 VariableDeclaration declaration = getFieldInClass(unit, 'C', 'field'); |
| 2090 VariableElement variable = declaration.name.staticElement; |
| 2091 InferStaticVariableTypeTask inferTask = |
| 2092 new InferStaticVariableTypeTask(task.context, variable); |
| 2093 expect(inferTask.getDeclaration(unit), declaration); |
| 2094 } |
| 2095 |
| 2096 void test_getDeclaration_topLevel() { |
| 2097 AnalysisTarget source = newSource( |
| 2098 '/test.dart', |
| 2099 ''' |
| 2100 var topLevel = ''; |
| 2101 '''); |
| 2102 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5); |
| 2103 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 2104 VariableDeclaration declaration = getTopLevelVariable(unit, 'topLevel'); |
| 2105 VariableElement variable = declaration.name.staticElement; |
| 2106 InferStaticVariableTypeTask inferTask = |
| 2107 new InferStaticVariableTypeTask(task.context, variable); |
| 2108 expect(inferTask.getDeclaration(unit), declaration); |
| 2109 } |
| 2110 |
| 2111 void test_perform() { |
| 2112 AnalysisTarget source = newSource( |
| 2113 '/test.dart', |
| 2114 ''' |
| 2115 var topLevel = ''; |
| 2116 class C { |
| 2117 var field = topLevel; |
| 2118 } |
| 2119 '''); |
| 2120 computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT5); |
| 2121 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 2122 VariableElement topLevel = |
| 2123 getTopLevelVariable(unit, 'topLevel').name.staticElement; |
| 2124 VariableElement field = |
| 2125 getFieldInClass(unit, 'C', 'field').name.staticElement; |
| 2126 |
| 2127 computeResult(field, INFERRED_STATIC_VARIABLE); |
| 2128 InterfaceType stringType = context.typeProvider.stringType; |
| 2129 expect(topLevel.type, stringType); |
| 2130 expect(field.type, stringType); |
| 2131 } |
| 2132 } |
| 2133 |
| 2134 @reflectiveTest |
| 2135 class LibraryErrorsReadyTaskTest extends _AbstractDartTaskTest { |
| 2136 test_perform() { |
| 2137 Source library = newSource( |
| 2138 '/lib.dart', |
| 2139 r''' |
| 2140 library lib; |
| 2141 part 'part1.dart'; |
| 2142 part 'part2.dart'; |
| 2143 X v1; |
| 2144 '''); |
| 2145 Source part1 = newSource( |
| 2146 '/part1.dart', |
| 2147 r''' |
| 2148 part of lib; |
| 2149 X v2; |
| 2150 '''); |
| 2151 Source part2 = newSource( |
| 2152 '/part2.dart', |
| 2153 r''' |
| 2154 part of lib; |
| 2155 X v3; |
| 2156 '''); |
| 2157 computeResult(library, LIBRARY_ERRORS_READY); |
| 2158 expect(task, new isInstanceOf<LibraryErrorsReadyTask>()); |
| 2159 expect(outputs, hasLength(1)); |
| 2160 bool ready = outputs[LIBRARY_ERRORS_READY]; |
| 2161 expect(ready, isTrue); |
| 2162 expect(context.getErrors(library).errors, hasLength(1)); |
| 2163 expect(context.getErrors(part1).errors, hasLength(1)); |
| 2164 expect(context.getErrors(part2).errors, hasLength(1)); |
| 2165 } |
| 2166 } |
| 2167 |
| 2168 @reflectiveTest |
| 2169 class LibraryUnitErrorsTaskTest extends _AbstractDartTaskTest { |
| 2170 test_buildInputs() { |
| 2171 Map<String, TaskInput> inputs = LibraryUnitErrorsTask |
| 2172 .buildInputs(new LibrarySpecificUnit(emptySource, emptySource)); |
| 2173 expect(inputs, isNotNull); |
| 2174 expect( |
| 2175 inputs.keys, |
| 2176 unorderedEquals([ |
| 2177 LibraryUnitErrorsTask.HINTS_INPUT, |
| 2178 LibraryUnitErrorsTask.RESOLVE_REFERENCES_ERRORS_INPUT, |
| 2179 LibraryUnitErrorsTask.RESOLVE_TYPE_NAMES_ERRORS_INPUT, |
| 2180 LibraryUnitErrorsTask.VARIABLE_REFERENCE_ERRORS_INPUT, |
| 2181 LibraryUnitErrorsTask.VERIFY_ERRORS_INPUT |
| 2182 ])); |
| 2183 } |
| 2184 |
| 2185 test_constructor() { |
| 2186 LibraryUnitErrorsTask task = |
| 2187 new LibraryUnitErrorsTask(context, emptySource); |
| 2188 expect(task, isNotNull); |
| 2189 expect(task.context, context); |
| 2190 expect(task.target, emptySource); |
| 2191 } |
| 2192 |
| 2193 test_createTask() { |
| 2194 LibraryUnitErrorsTask task = |
| 2195 LibraryUnitErrorsTask.createTask(context, emptySource); |
| 2196 expect(task, isNotNull); |
| 2197 expect(task.context, context); |
| 2198 expect(task.target, emptySource); |
| 2199 } |
| 2200 |
| 2201 test_description() { |
| 2202 LibraryUnitErrorsTask task = new LibraryUnitErrorsTask(null, emptySource); |
| 2203 expect(task.description, isNotNull); |
| 2204 } |
| 2205 |
| 2206 test_descriptor() { |
| 2207 TaskDescriptor descriptor = LibraryUnitErrorsTask.DESCRIPTOR; |
| 2208 expect(descriptor, isNotNull); |
| 2209 } |
| 2210 |
| 2211 test_perform_definingCompilationUnit() { |
| 2212 AnalysisTarget library = |
| 2213 newSource('/test.dart', 'library test; import "dart:math";'); |
| 2214 computeResult( |
| 2215 new LibrarySpecificUnit(library, library), LIBRARY_UNIT_ERRORS); |
| 2216 expect(task, new isInstanceOf<LibraryUnitErrorsTask>()); |
| 2217 expect(outputs, hasLength(1)); |
| 2218 List<AnalysisError> errors = outputs[LIBRARY_UNIT_ERRORS]; |
| 2219 expect(errors, hasLength(1)); |
| 2220 } |
| 2221 |
| 2222 test_perform_partInSingleLibrary() { |
| 2223 AnalysisTarget library = |
| 2224 newSource('/lib.dart', 'library test; part "part.dart";'); |
| 2225 AnalysisTarget part = newSource('/part.dart', 'part of test;'); |
| 2226 computeResult(new LibrarySpecificUnit(library, part), LIBRARY_UNIT_ERRORS); |
| 2227 expect(task, new isInstanceOf<LibraryUnitErrorsTask>()); |
| 2228 expect(outputs, hasLength(1)); |
| 2229 List<AnalysisError> errors = outputs[LIBRARY_UNIT_ERRORS]; |
| 2230 expect(errors, hasLength(0)); |
| 2231 } |
| 2232 } |
| 2233 |
| 2234 @reflectiveTest |
| 2235 class ParseDartTaskTest extends _AbstractDartTaskTest { |
| 2236 Source source; |
| 2237 |
| 2238 test_buildInputs() { |
| 2239 Map<String, TaskInput> inputs = ParseDartTask.buildInputs(emptySource); |
| 2240 expect(inputs, isNotNull); |
| 2241 expect( |
| 2242 inputs.keys, |
| 2243 unorderedEquals([ |
| 2244 ParseDartTask.LINE_INFO_INPUT_NAME, |
| 2245 ParseDartTask.MODIFICATION_TIME_INPUT_NAME, |
| 2246 ParseDartTask.TOKEN_STREAM_INPUT_NAME |
| 2247 ])); |
| 2248 } |
| 2249 |
| 2250 test_constructor() { |
| 2251 ParseDartTask task = new ParseDartTask(context, emptySource); |
| 2252 expect(task, isNotNull); |
| 2253 expect(task.context, context); |
| 2254 expect(task.target, emptySource); |
| 2255 } |
| 2256 |
| 2257 test_createTask() { |
| 2258 ParseDartTask task = ParseDartTask.createTask(context, emptySource); |
| 2259 expect(task, isNotNull); |
| 2260 expect(task.context, context); |
| 2261 expect(task.target, emptySource); |
| 2262 } |
| 2263 |
| 2264 test_description() { |
| 2265 ParseDartTask task = new ParseDartTask(null, emptySource); |
| 2266 expect(task.description, isNotNull); |
| 2267 } |
| 2268 |
| 2269 test_descriptor() { |
| 2270 TaskDescriptor descriptor = ParseDartTask.DESCRIPTOR; |
| 2271 expect(descriptor, isNotNull); |
| 2272 } |
| 2273 |
| 2274 test_perform() { |
| 2275 _performParseTask(r''' |
| 2276 part of lib; |
| 2277 class B {}'''); |
| 2278 expect(outputs, hasLength(8)); |
| 2279 expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0)); |
| 2280 expect(outputs[EXPORTED_LIBRARIES], hasLength(0)); |
| 2281 _assertHasCore(outputs[IMPORTED_LIBRARIES], 1); |
| 2282 expect(outputs[INCLUDED_PARTS], hasLength(0)); |
| 2283 expect(outputs[PARSE_ERRORS], hasLength(0)); |
| 2284 expect(outputs[PARSED_UNIT], isNotNull); |
| 2285 expect(outputs[SOURCE_KIND], SourceKind.PART); |
| 2286 expect(outputs[UNITS], hasLength(1)); |
| 2287 } |
| 2288 |
| 2289 test_perform_computeSourceKind_noDirectives_hasContainingLibrary() { |
| 2290 // Parse "lib.dart" to let the context know that "test.dart" is included. |
| 2291 computeResult( |
| 2292 newSource( |
| 2293 '/lib.dart', |
| 2294 r''' |
| 2295 library lib; |
| 2296 part 'test.dart'; |
| 2297 '''), |
| 2298 PARSED_UNIT); |
| 2299 // If there are no the "part of" directive, then it is not a part. |
| 2300 _performParseTask(''); |
| 2301 expect(outputs[SOURCE_KIND], SourceKind.LIBRARY); |
| 2302 } |
| 2303 |
| 2304 test_perform_computeSourceKind_noDirectives_noContainingLibrary() { |
| 2305 _performParseTask(''); |
| 2306 expect(outputs[SOURCE_KIND], SourceKind.LIBRARY); |
| 2307 } |
| 2308 |
| 2309 test_perform_doesNotExist() { |
| 2310 _performParseTask(null); |
| 2311 expect(outputs, hasLength(8)); |
| 2312 expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0)); |
| 2313 expect(outputs[EXPORTED_LIBRARIES], hasLength(0)); |
| 2314 _assertHasCore(outputs[IMPORTED_LIBRARIES], 1); |
| 2315 expect(outputs[INCLUDED_PARTS], hasLength(0)); |
| 2316 expect(outputs[PARSE_ERRORS], hasLength(0)); |
| 2317 expect(outputs[PARSED_UNIT], isNotNull); |
| 2318 expect(outputs[SOURCE_KIND], SourceKind.UNKNOWN); |
| 2319 expect(outputs[UNITS], hasLength(1)); |
| 2320 } |
| 2321 |
| 2322 test_perform_invalidDirectives() { |
| 2323 _performParseTask(r''' |
| 2324 library lib; |
| 2325 import '/does/not/exist.dart'; |
| 2326 import '://invaliduri.dart'; |
| 2327 export '${a}lib3.dart'; |
| 2328 part 'part.dart'; |
| 2329 class A {}'''); |
| 2330 expect(outputs, hasLength(8)); |
| 2331 expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1)); |
| 2332 expect(outputs[EXPORTED_LIBRARIES], hasLength(0)); |
| 2333 _assertHasCore(outputs[IMPORTED_LIBRARIES], 2); |
| 2334 expect(outputs[INCLUDED_PARTS], hasLength(1)); |
| 2335 expect(outputs[PARSE_ERRORS], hasLength(2)); |
| 2336 expect(outputs[PARSED_UNIT], isNotNull); |
| 2337 expect(outputs[SOURCE_KIND], SourceKind.LIBRARY); |
| 2338 expect(outputs[UNITS], hasLength(2)); |
| 2339 } |
| 2340 |
| 2341 test_perform_library() { |
| 2342 _performParseTask(r''' |
| 2343 library lib; |
| 2344 import 'lib2.dart'; |
| 2345 export 'lib3.dart'; |
| 2346 part 'part.dart'; |
| 2347 class A {'''); |
| 2348 expect(outputs, hasLength(8)); |
| 2349 expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1)); |
| 2350 expect(outputs[EXPORTED_LIBRARIES], hasLength(1)); |
| 2351 _assertHasCore(outputs[IMPORTED_LIBRARIES], 2); |
| 2352 expect(outputs[INCLUDED_PARTS], hasLength(1)); |
| 2353 expect(outputs[PARSE_ERRORS], hasLength(1)); |
| 2354 expect(outputs[PARSED_UNIT], isNotNull); |
| 2355 expect(outputs[SOURCE_KIND], SourceKind.LIBRARY); |
| 2356 expect(outputs[UNITS], hasLength(2)); |
| 2357 } |
| 2358 |
| 2359 test_perform_library_selfReferenceAsPart() { |
| 2360 _performParseTask(r''' |
| 2361 library lib; |
| 2362 part 'test.dart'; |
| 2363 '''); |
| 2364 expect(outputs[INCLUDED_PARTS], unorderedEquals(<Source>[source])); |
| 2365 } |
| 2366 |
| 2367 test_perform_part() { |
| 2368 _performParseTask(r''' |
| 2369 part of lib; |
| 2370 class B {}'''); |
| 2371 expect(outputs, hasLength(8)); |
| 2372 expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0)); |
| 2373 expect(outputs[EXPORTED_LIBRARIES], hasLength(0)); |
| 2374 _assertHasCore(outputs[IMPORTED_LIBRARIES], 1); |
| 2375 expect(outputs[INCLUDED_PARTS], hasLength(0)); |
| 2376 expect(outputs[PARSE_ERRORS], hasLength(0)); |
| 2377 expect(outputs[PARSED_UNIT], isNotNull); |
| 2378 expect(outputs[SOURCE_KIND], SourceKind.PART); |
| 2379 expect(outputs[UNITS], hasLength(1)); |
| 2380 } |
| 2381 |
| 2382 void _performParseTask(String content) { |
| 2383 source = newSource('/test.dart', content); |
| 2384 computeResult(source, PARSED_UNIT); |
| 2385 expect(task, new isInstanceOf<ParseDartTask>()); |
| 2386 } |
| 2387 |
| 2388 static void _assertHasCore(List<Source> sources, int lenght) { |
| 2389 expect(sources, hasLength(lenght)); |
| 2390 expect(sources, contains(predicate((Source s) { |
| 2391 return s.fullName.endsWith('core.dart'); |
| 2392 }))); |
| 2393 } |
| 2394 } |
| 2395 |
| 2396 @reflectiveTest |
| 2397 class PartiallyResolveReferencesTaskTest extends _AbstractDartTaskTest { |
| 2398 test_perform() { |
| 2399 enableStrongMode(); |
| 2400 Source source = newSource( |
| 2401 '/test.dart', |
| 2402 ''' |
| 2403 int a = b; |
| 2404 int b = c; |
| 2405 var d = 0; |
| 2406 class A {} |
| 2407 class C { |
| 2408 static final f = ''; |
| 2409 var g = 0; |
| 2410 } |
| 2411 '''); |
| 2412 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2413 computeResult(target, RESOLVED_UNIT5); |
| 2414 expect(task, new isInstanceOf<PartiallyResolveUnitReferencesTask>()); |
| 2415 // Test the outputs |
| 2416 expect(outputs[CLASSES_IN_UNIT], hasLength(2)); |
| 2417 expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(2)); |
| 2418 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 2419 expect(unit, same(outputs[RESOLVED_UNIT5])); |
| 2420 // Test the state of the AST |
| 2421 TopLevelVariableDeclaration a = unit.declarations[0]; |
| 2422 VariableDeclaration variableA = a.variables.variables[0]; |
| 2423 SimpleIdentifier initializer = variableA.initializer; |
| 2424 expect(initializer.staticElement, isNotNull); |
| 2425 // Test the error generation |
| 2426 _fillErrorListener(PARTIALLY_RESOLVE_REFERENCES_ERRORS); |
| 2427 errorListener.assertErrorsWithCodes( |
| 2428 <ErrorCode>[StaticWarningCode.UNDEFINED_IDENTIFIER]); |
| 2429 } |
| 2430 |
| 2431 test_perform_importExport() { |
| 2432 newSource( |
| 2433 '/a.dart', |
| 2434 ''' |
| 2435 library a; |
| 2436 class A<T> { |
| 2437 T m() {} |
| 2438 } |
| 2439 '''); |
| 2440 newSource( |
| 2441 '/b.dart', |
| 2442 ''' |
| 2443 library b; |
| 2444 export 'a.dart'; |
| 2445 '''); |
| 2446 Source sourceC = newSource( |
| 2447 '/c.dart', |
| 2448 ''' |
| 2449 library c; |
| 2450 import 'b.dart'; |
| 2451 main() { |
| 2452 new A<int>().m(); |
| 2453 } |
| 2454 '''); |
| 2455 computeResult(new LibrarySpecificUnit(sourceC, sourceC), RESOLVED_UNIT5); |
| 2456 expect(task, new isInstanceOf<PartiallyResolveUnitReferencesTask>()); |
| 2457 // validate |
| 2458 expect(outputs[CLASSES_IN_UNIT], hasLength(0)); |
| 2459 expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(0)); |
| 2460 CompilationUnit unit = outputs[RESOLVED_UNIT5]; |
| 2461 expect(unit, isNotNull); |
| 2462 |
| 2463 FunctionDeclaration functionDeclaration = unit.declarations[0]; |
| 2464 BlockFunctionBody body = functionDeclaration.functionExpression.body; |
| 2465 List<Statement> statements = body.block.statements; |
| 2466 ExpressionStatement statement = statements[0]; |
| 2467 MethodInvocation invocation = statement.expression; |
| 2468 MethodElement methodElement = invocation.methodName.staticElement; |
| 2469 expect(methodElement, isNotNull); |
| 2470 expect(methodElement.type, isNotNull); |
| 2471 expect(methodElement.returnType.toString(), 'int'); |
| 2472 } |
| 2473 } |
| 2474 |
| 2475 @reflectiveTest |
| 2476 class ResolveLibraryTypeNamesTaskTest extends _AbstractDartTaskTest { |
| 2477 test_perform() { |
| 2478 Source sourceLib = newSource( |
| 2479 '/my_lib.dart', |
| 2480 ''' |
| 2481 library my_lib; |
| 2482 part 'my_part.dart'; |
| 2483 class A {} |
| 2484 class B extends A {} |
| 2485 '''); |
| 2486 newSource( |
| 2487 '/my_part.dart', |
| 2488 ''' |
| 2489 part of my_lib; |
| 2490 class C extends A {} |
| 2491 '''); |
| 2492 computeResult(sourceLib, LIBRARY_ELEMENT5); |
| 2493 expect(task, new isInstanceOf<ResolveLibraryTypeNamesTask>()); |
| 2494 // validate |
| 2495 LibraryElement library = outputs[LIBRARY_ELEMENT5]; |
| 2496 { |
| 2497 ClassElement classB = library.getType('B'); |
| 2498 expect(classB.supertype.displayName, 'A'); |
| 2499 } |
| 2500 { |
| 2501 ClassElement classC = library.getType('C'); |
| 2502 expect(classC.supertype.displayName, 'A'); |
| 2503 } |
| 2504 } |
| 2505 |
| 2506 test_perform_external() { |
| 2507 Source sourceA = newSource( |
| 2508 '/a.dart', |
| 2509 ''' |
| 2510 library a; |
| 2511 import 'b.dart'; |
| 2512 class A extends B {} |
| 2513 '''); |
| 2514 newSource( |
| 2515 '/b.dart', |
| 2516 ''' |
| 2517 library b; |
| 2518 class B {} |
| 2519 '''); |
| 2520 // The reference A to B should be resolved, but there's no requirement that |
| 2521 // the full class hierarchy be resolved. |
| 2522 computeResult(sourceA, LIBRARY_ELEMENT5); |
| 2523 expect(task, new isInstanceOf<ResolveLibraryTypeNamesTask>()); |
| 2524 // validate |
| 2525 LibraryElement library = outputs[LIBRARY_ELEMENT5]; |
| 2526 { |
| 2527 ClassElement clazz = library.getType('A'); |
| 2528 expect(clazz.displayName, 'A'); |
| 2529 clazz = clazz.supertype.element; |
| 2530 expect(clazz.displayName, 'B'); |
| 2531 } |
| 2532 } |
| 2533 } |
| 2534 |
| 2535 @reflectiveTest |
| 2536 class ResolveReferencesTaskTest extends _AbstractDartTaskTest { |
| 2537 test_perform() { |
| 2538 Source source = newSource( |
| 2539 '/test.dart', |
| 2540 ''' |
| 2541 class A { |
| 2542 m() {} |
| 2543 } |
| 2544 main(A a) { |
| 2545 a.m(); |
| 2546 } |
| 2547 '''); |
| 2548 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2549 // prepare unit and "a.m()" invocation |
| 2550 computeResult(target, RESOLVED_UNIT8); |
| 2551 CompilationUnit unit = outputs[RESOLVED_UNIT8]; |
| 2552 // walk the AST |
| 2553 FunctionDeclaration function = unit.declarations[1]; |
| 2554 BlockFunctionBody body = function.functionExpression.body; |
| 2555 ExpressionStatement statement = body.block.statements[0]; |
| 2556 MethodInvocation invocation = statement.expression; |
| 2557 expect(task, new isInstanceOf<ResolveUnitReferencesTask>()); |
| 2558 expect(unit, same(outputs[RESOLVED_UNIT8])); |
| 2559 // a.m() is resolved now |
| 2560 expect(invocation.methodName.staticElement, isNotNull); |
| 2561 } |
| 2562 |
| 2563 test_perform_errors() { |
| 2564 Source source = newSource( |
| 2565 '/test.dart', |
| 2566 ''' |
| 2567 class A { |
| 2568 } |
| 2569 main(A a) { |
| 2570 a.unknownMethod(); |
| 2571 } |
| 2572 '''); |
| 2573 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2574 computeResult(target, RESOLVED_UNIT8); |
| 2575 expect(task, new isInstanceOf<ResolveUnitReferencesTask>()); |
| 2576 // validate |
| 2577 _fillErrorListener(RESOLVE_REFERENCES_ERRORS); |
| 2578 errorListener.assertErrorsWithCodes( |
| 2579 <ErrorCode>[StaticTypeWarningCode.UNDEFINED_METHOD]); |
| 2580 } |
| 2581 |
| 2582 test_perform_importExport() { |
| 2583 newSource( |
| 2584 '/a.dart', |
| 2585 ''' |
| 2586 library a; |
| 2587 class A<T> { |
| 2588 T m() {} |
| 2589 } |
| 2590 '''); |
| 2591 newSource( |
| 2592 '/b.dart', |
| 2593 ''' |
| 2594 library b; |
| 2595 export 'a.dart'; |
| 2596 '''); |
| 2597 Source sourceC = newSource( |
| 2598 '/c.dart', |
| 2599 ''' |
| 2600 library c; |
| 2601 import 'b.dart'; |
| 2602 main() { |
| 2603 new A<int>().m(); |
| 2604 } |
| 2605 '''); |
| 2606 computeResult(new LibrarySpecificUnit(sourceC, sourceC), RESOLVED_UNIT8); |
| 2607 expect(task, new isInstanceOf<ResolveUnitReferencesTask>()); |
| 2608 // validate |
| 2609 CompilationUnit unit = outputs[RESOLVED_UNIT8]; |
| 2610 expect(unit, isNotNull); |
| 2611 { |
| 2612 FunctionDeclaration functionDeclaration = unit.declarations[0]; |
| 2613 BlockFunctionBody body = functionDeclaration.functionExpression.body; |
| 2614 List<Statement> statements = body.block.statements; |
| 2615 ExpressionStatement statement = statements[0]; |
| 2616 MethodInvocation invocation = statement.expression; |
| 2617 MethodElement methodElement = invocation.methodName.staticElement; |
| 2618 expect(methodElement, isNotNull); |
| 2619 expect(methodElement.type, isNotNull); |
| 2620 expect(methodElement.returnType.toString(), 'int'); |
| 2621 } |
| 2622 } |
| 2623 } |
| 2624 |
| 2625 @reflectiveTest |
| 2626 class ResolveUnitTypeNamesTaskTest extends _AbstractDartTaskTest { |
| 2627 test_perform() { |
| 2628 Source source = newSource( |
| 2629 '/test.dart', |
| 2630 ''' |
| 2631 class A {} |
| 2632 class B extends A {} |
| 2633 int f(String p) => p.length; |
| 2634 '''); |
| 2635 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2636 computeResult(target, RESOLVED_UNIT3); |
| 2637 expect(task, new isInstanceOf<ResolveUnitTypeNamesTask>()); |
| 2638 // validate |
| 2639 CompilationUnit unit = outputs[RESOLVED_UNIT3]; |
| 2640 { |
| 2641 ClassDeclaration nodeA = unit.declarations[0]; |
| 2642 ClassDeclaration nodeB = unit.declarations[1]; |
| 2643 DartType extendsType = nodeB.extendsClause.superclass.type; |
| 2644 expect(extendsType, nodeA.element.type); |
| 2645 } |
| 2646 { |
| 2647 FunctionDeclaration functionNode = unit.declarations[2]; |
| 2648 DartType returnType = functionNode.returnType.type; |
| 2649 List<FormalParameter> parameters = |
| 2650 functionNode.functionExpression.parameters.parameters; |
| 2651 expect(returnType.displayName, 'int'); |
| 2652 expect(parameters[0].element.type.displayName, 'String'); |
| 2653 } |
| 2654 } |
| 2655 |
| 2656 test_perform_errors() { |
| 2657 Source source = newSource( |
| 2658 '/test.dart', |
| 2659 ''' |
| 2660 NoSuchClass f() => null; |
| 2661 '''); |
| 2662 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2663 computeResult(target, RESOLVE_TYPE_NAMES_ERRORS); |
| 2664 expect(task, new isInstanceOf<ResolveUnitTypeNamesTask>()); |
| 2665 // validate |
| 2666 _fillErrorListener(RESOLVE_TYPE_NAMES_ERRORS); |
| 2667 errorListener |
| 2668 .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]); |
| 2669 } |
| 2670 |
| 2671 test_perform_typedef() { |
| 2672 Source source = newSource( |
| 2673 '/test.dart', |
| 2674 ''' |
| 2675 typedef int F(G g); |
| 2676 typedef String G(int p); |
| 2677 '''); |
| 2678 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2679 computeResult(target, RESOLVED_UNIT3); |
| 2680 expect(task, new isInstanceOf<ResolveUnitTypeNamesTask>()); |
| 2681 // validate |
| 2682 CompilationUnit unit = outputs[RESOLVED_UNIT3]; |
| 2683 FunctionTypeAlias nodeF = unit.declarations[0]; |
| 2684 FunctionTypeAlias nodeG = unit.declarations[1]; |
| 2685 { |
| 2686 FormalParameter parameter = nodeF.parameters.parameters[0]; |
| 2687 DartType parameterType = parameter.element.type; |
| 2688 Element returnTypeElement = nodeF.returnType.type.element; |
| 2689 expect(returnTypeElement.displayName, 'int'); |
| 2690 expect(parameterType.element, nodeG.element); |
| 2691 } |
| 2692 { |
| 2693 FormalParameter parameter = nodeG.parameters.parameters[0]; |
| 2694 DartType parameterType = parameter.element.type; |
| 2695 expect(nodeG.returnType.type.element.displayName, 'String'); |
| 2696 expect(parameterType.element.displayName, 'int'); |
| 2697 } |
| 2698 } |
| 2699 |
| 2700 test_perform_typedef_errors() { |
| 2701 Source source = newSource( |
| 2702 '/test.dart', |
| 2703 ''' |
| 2704 typedef int F(NoSuchType p); |
| 2705 '''); |
| 2706 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2707 computeResult(target, RESOLVE_TYPE_NAMES_ERRORS); |
| 2708 expect(task, new isInstanceOf<ResolveUnitTypeNamesTask>()); |
| 2709 // validate |
| 2710 _fillErrorListener(RESOLVE_TYPE_NAMES_ERRORS); |
| 2711 errorListener |
| 2712 .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]); |
| 2713 } |
| 2714 } |
| 2715 |
| 2716 @reflectiveTest |
| 2717 class ResolveVariableReferencesTaskTest extends _AbstractDartTaskTest { |
| 2718 /** |
| 2719 * Verify that the mutated states of the given [variable] correspond to the |
| 2720 * [mutatedInClosure] and [mutatedInScope] matchers. |
| 2721 */ |
| 2722 void expectMutated(VariableElement variable, Matcher mutatedInClosure, |
| 2723 Matcher mutatedInScope) { |
| 2724 expect(variable.isPotentiallyMutatedInClosure, mutatedInClosure); |
| 2725 expect(variable.isPotentiallyMutatedInScope, mutatedInScope); |
| 2726 } |
| 2727 |
| 2728 test_perform_buildClosureLibraryElements() { |
| 2729 Source source = newSource( |
| 2730 '/test.dart', |
| 2731 ''' |
| 2732 main() { |
| 2733 } |
| 2734 '''); |
| 2735 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2736 computeResult(target, RESOLVED_UNIT4); |
| 2737 expect(task, new isInstanceOf<ResolveVariableReferencesTask>()); |
| 2738 } |
| 2739 |
| 2740 test_perform_local() { |
| 2741 Source source = newSource( |
| 2742 '/test.dart', |
| 2743 ''' |
| 2744 main() { |
| 2745 var v1 = 1; |
| 2746 var v2 = 1; |
| 2747 var v3 = 1; |
| 2748 var v4 = 1; |
| 2749 v2 = 2; |
| 2750 v4 = 2; |
| 2751 localFunction() { |
| 2752 v3 = 3; |
| 2753 v4 = 3; |
| 2754 } |
| 2755 } |
| 2756 '''); |
| 2757 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2758 computeResult(target, RESOLVED_UNIT4); |
| 2759 expect(task, new isInstanceOf<ResolveVariableReferencesTask>()); |
| 2760 // validate |
| 2761 CompilationUnit unit = outputs[RESOLVED_UNIT4]; |
| 2762 FunctionElement main = unit.element.functions[0]; |
| 2763 expectMutated(main.localVariables[0], isFalse, isFalse); |
| 2764 expectMutated(main.localVariables[1], isFalse, isTrue); |
| 2765 expectMutated(main.localVariables[2], isTrue, isTrue); |
| 2766 expectMutated(main.localVariables[3], isTrue, isTrue); |
| 2767 } |
| 2768 |
| 2769 test_perform_parameter() { |
| 2770 Source source = newSource( |
| 2771 '/test.dart', |
| 2772 ''' |
| 2773 main(p1, p2, p3, p4) { |
| 2774 p2 = 2; |
| 2775 p4 = 2; |
| 2776 localFunction() { |
| 2777 p3 = 3; |
| 2778 p4 = 3; |
| 2779 } |
| 2780 } |
| 2781 '''); |
| 2782 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2783 computeResult(target, RESOLVED_UNIT4); |
| 2784 expect(task, new isInstanceOf<ResolveVariableReferencesTask>()); |
| 2785 // validate |
| 2786 CompilationUnit unit = outputs[RESOLVED_UNIT4]; |
| 2787 FunctionElement main = unit.element.functions[0]; |
| 2788 expectMutated(main.parameters[0], isFalse, isFalse); |
| 2789 expectMutated(main.parameters[1], isFalse, isTrue); |
| 2790 expectMutated(main.parameters[2], isTrue, isTrue); |
| 2791 expectMutated(main.parameters[3], isTrue, isTrue); |
| 2792 } |
| 2793 } |
| 2794 |
| 2795 @reflectiveTest |
| 2796 class ScanDartTaskTest extends _AbstractDartTaskTest { |
| 2797 test_buildInputs() { |
| 2798 Map<String, TaskInput> inputs = ScanDartTask.buildInputs(emptySource); |
| 2799 expect(inputs, isNotNull); |
| 2800 expect(inputs.keys, unorderedEquals([ScanDartTask.CONTENT_INPUT_NAME])); |
| 2801 } |
| 2802 |
| 2803 test_constructor() { |
| 2804 ScanDartTask task = new ScanDartTask(context, emptySource); |
| 2805 expect(task, isNotNull); |
| 2806 expect(task.context, context); |
| 2807 expect(task.target, emptySource); |
| 2808 } |
| 2809 |
| 2810 test_createTask() { |
| 2811 ScanDartTask task = ScanDartTask.createTask(context, emptySource); |
| 2812 expect(task, isNotNull); |
| 2813 expect(task.context, context); |
| 2814 expect(task.target, emptySource); |
| 2815 } |
| 2816 |
| 2817 test_description() { |
| 2818 ScanDartTask task = new ScanDartTask(null, emptySource); |
| 2819 expect(task.description, isNotNull); |
| 2820 } |
| 2821 |
| 2822 test_descriptor() { |
| 2823 TaskDescriptor descriptor = ScanDartTask.DESCRIPTOR; |
| 2824 expect(descriptor, isNotNull); |
| 2825 } |
| 2826 |
| 2827 test_perform_errors() { |
| 2828 _performScanTask('import "'); |
| 2829 expect(outputs, hasLength(3)); |
| 2830 expect(outputs[LINE_INFO], isNotNull); |
| 2831 expect(outputs[SCAN_ERRORS], hasLength(1)); |
| 2832 expect(outputs[TOKEN_STREAM], isNotNull); |
| 2833 } |
| 2834 |
| 2835 test_perform_noErrors() { |
| 2836 _performScanTask('class A {}'); |
| 2837 expect(outputs, hasLength(3)); |
| 2838 expect(outputs[LINE_INFO], isNotNull); |
| 2839 expect(outputs[SCAN_ERRORS], hasLength(0)); |
| 2840 expect(outputs[TOKEN_STREAM], isNotNull); |
| 2841 } |
| 2842 |
| 2843 test_perform_script() { |
| 2844 String scriptContent = ''' |
| 2845 void buttonPressed() { |
| 2846 '''; |
| 2847 String htmlContent = ''' |
| 2848 <!DOCTYPE html> |
| 2849 <html> |
| 2850 <head> |
| 2851 <title>test page</title> |
| 2852 <script type='application/dart'>$scriptContent</script> |
| 2853 </head> |
| 2854 <body>Test</body> |
| 2855 </html> |
| 2856 '''; |
| 2857 Source source = newSource('/test.html', htmlContent); |
| 2858 DartScript script = |
| 2859 new DartScript(source, [new ScriptFragment(97, 5, 36, scriptContent)]); |
| 2860 |
| 2861 computeResult(script, TOKEN_STREAM); |
| 2862 expect(task, new isInstanceOf<ScanDartTask>()); |
| 2863 expect(outputs[LINE_INFO], isNotNull); |
| 2864 expect(outputs[SCAN_ERRORS], isEmpty); |
| 2865 Token tokenStream = outputs[TOKEN_STREAM]; |
| 2866 expect(tokenStream, isNotNull); |
| 2867 expect(tokenStream.lexeme, 'void'); |
| 2868 } |
| 2869 |
| 2870 void _performScanTask(String content) { |
| 2871 AnalysisTarget target = newSource('/test.dart', content); |
| 2872 computeResult(target, TOKEN_STREAM); |
| 2873 expect(task, new isInstanceOf<ScanDartTask>()); |
| 2874 } |
| 2875 } |
| 2876 |
| 2877 @reflectiveTest |
| 2878 class VerifyUnitTaskTest extends _AbstractDartTaskTest { |
| 2879 test_perform_constantError() { |
| 2880 Source source = newSource( |
| 2881 '/test.dart', |
| 2882 ''' |
| 2883 main(int p) { |
| 2884 const v = p; |
| 2885 } |
| 2886 '''); |
| 2887 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2888 computeResult(target, VERIFY_ERRORS); |
| 2889 expect(task, new isInstanceOf<VerifyUnitTask>()); |
| 2890 // validate |
| 2891 _fillErrorListener(VERIFY_ERRORS); |
| 2892 errorListener.assertErrorsWithCodes(<ErrorCode>[ |
| 2893 CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE |
| 2894 ]); |
| 2895 } |
| 2896 |
| 2897 test_perform_directiveError() { |
| 2898 Source source = newSource( |
| 2899 '/test.dart', |
| 2900 ''' |
| 2901 import 'no-such-file.dart'; |
| 2902 '''); |
| 2903 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2904 computeResult(target, VERIFY_ERRORS); |
| 2905 expect(task, new isInstanceOf<VerifyUnitTask>()); |
| 2906 // validate |
| 2907 _fillErrorListener(VERIFY_ERRORS); |
| 2908 errorListener.assertErrorsWithCodes( |
| 2909 <ErrorCode>[CompileTimeErrorCode.URI_DOES_NOT_EXIST]); |
| 2910 } |
| 2911 |
| 2912 test_perform_verifyError() { |
| 2913 Source source = newSource( |
| 2914 '/test.dart', |
| 2915 ''' |
| 2916 main() { |
| 2917 if (42) { |
| 2918 print('Not bool!'); |
| 2919 } |
| 2920 } |
| 2921 '''); |
| 2922 LibrarySpecificUnit target = new LibrarySpecificUnit(source, source); |
| 2923 computeResult(target, VERIFY_ERRORS); |
| 2924 expect(task, new isInstanceOf<VerifyUnitTask>()); |
| 2925 // validate |
| 2926 _fillErrorListener(VERIFY_ERRORS); |
| 2927 errorListener.assertErrorsWithCodes( |
| 2928 <ErrorCode>[StaticTypeWarningCode.NON_BOOL_CONDITION]); |
| 2929 } |
| 2930 } |
| 2931 |
| 2932 class _AbstractDartTaskTest extends AbstractContextTest { |
| 2933 Source emptySource; |
| 2934 |
| 2935 GatheringErrorListener errorListener = new GatheringErrorListener(); |
| 2936 |
| 2937 void assertIsInvalid(AnalysisTarget target, ResultDescriptor descriptor) { |
| 2938 CacheEntry entry = context.getCacheEntry(target); |
| 2939 expect(entry.isInvalid(descriptor), isTrue); |
| 2940 } |
| 2941 |
| 2942 void assertIsValid(AnalysisTarget target, ResultDescriptor descriptor) { |
| 2943 CacheEntry entry = context.getCacheEntry(target); |
| 2944 expect(entry.isValid(descriptor), isTrue); |
| 2945 } |
| 2946 |
| 2947 void assertSameResults(List<ResultDescriptor> descriptors) { |
| 2948 descriptors.forEach((descriptor) { |
| 2949 var oldResult = oldOutputs[descriptor]; |
| 2950 var newResult = outputs[descriptor]; |
| 2951 expect(newResult, same(oldResult), reason: descriptor.name); |
| 2952 }); |
| 2953 } |
| 2954 |
| 2955 /** |
| 2956 * Create a script object with a single fragment containing the given |
| 2957 * [scriptContent]. |
| 2958 */ |
| 2959 DartScript createScript(String scriptContent) { |
| 2960 String htmlContent = ''' |
| 2961 <!DOCTYPE html> |
| 2962 <html> |
| 2963 <head> |
| 2964 <title>test page</title> |
| 2965 <script type='application/dart'>$scriptContent</script> |
| 2966 </head> |
| 2967 <body>Test</body> |
| 2968 </html> |
| 2969 '''; |
| 2970 Source source = newSource('/test.html', htmlContent); |
| 2971 return new DartScript( |
| 2972 source, [new ScriptFragment(97, 5, 36, scriptContent)]); |
| 2973 } |
| 2974 |
| 2975 /** |
| 2976 * Enable strong mode in the current analysis context. |
| 2977 */ |
| 2978 void enableStrongMode() { |
| 2979 AnalysisOptionsImpl options = context.analysisOptions; |
| 2980 options.strongMode = true; |
| 2981 context.analysisOptions = options; |
| 2982 } |
| 2983 |
| 2984 /** |
| 2985 * Return the declaration of the class with the given [className] in the given |
| 2986 * compilation [unit]. |
| 2987 */ |
| 2988 ClassDeclaration getClass(CompilationUnit unit, String className) { |
| 2989 NodeList<CompilationUnitMember> unitMembers = unit.declarations; |
| 2990 for (CompilationUnitMember unitMember in unitMembers) { |
| 2991 if (unitMember is ClassDeclaration && unitMember.name.name == className) { |
| 2992 return unitMember; |
| 2993 } |
| 2994 } |
| 2995 return null; |
| 2996 } |
| 2997 |
| 2998 /** |
| 2999 * Return the declaration of the field with the given [fieldName] in the class |
| 3000 * with the given [className] in the given compilation [unit]. |
| 3001 */ |
| 3002 VariableDeclaration getFieldInClass( |
| 3003 CompilationUnit unit, String className, String fieldName) { |
| 3004 ClassDeclaration unitMember = getClass(unit, className); |
| 3005 if (unitMember == null) { |
| 3006 return null; |
| 3007 } |
| 3008 NodeList<ClassMember> classMembers = unitMember.members; |
| 3009 for (ClassMember classMember in classMembers) { |
| 3010 if (classMember is FieldDeclaration) { |
| 3011 NodeList<VariableDeclaration> fields = classMember.fields.variables; |
| 3012 for (VariableDeclaration field in fields) { |
| 3013 if (field.name.name == fieldName) { |
| 3014 return field; |
| 3015 } |
| 3016 } |
| 3017 } |
| 3018 } |
| 3019 return null; |
| 3020 } |
| 3021 |
| 3022 /** |
| 3023 * Return the declaration of the top-level variable with the given |
| 3024 * [variableName] in the given compilation [unit]. |
| 3025 */ |
| 3026 VariableDeclaration getTopLevelVariable( |
| 3027 CompilationUnit unit, String variableName) { |
| 3028 NodeList<CompilationUnitMember> unitMembers = unit.declarations; |
| 3029 for (CompilationUnitMember unitMember in unitMembers) { |
| 3030 if (unitMember is TopLevelVariableDeclaration) { |
| 3031 NodeList<VariableDeclaration> variables = |
| 3032 unitMember.variables.variables; |
| 3033 for (VariableDeclaration variable in variables) { |
| 3034 if (variable.name.name == variableName) { |
| 3035 return variable; |
| 3036 } |
| 3037 } |
| 3038 } |
| 3039 } |
| 3040 return null; |
| 3041 } |
| 3042 |
| 3043 void setUp() { |
| 3044 super.setUp(); |
| 3045 emptySource = newSource('/test.dart'); |
| 3046 } |
| 3047 |
| 3048 /** |
| 3049 * Fill [errorListener] with [result] errors in the current [task]. |
| 3050 */ |
| 3051 void _fillErrorListener(ResultDescriptor<List<AnalysisError>> result) { |
| 3052 List<AnalysisError> errors = task.outputs[result]; |
| 3053 expect(errors, isNotNull, reason: result.name); |
| 3054 errorListener = new GatheringErrorListener(); |
| 3055 errorListener.addAll(errors); |
| 3056 } |
| 3057 } |
OLD | NEW |