| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library analyzer.test.generated.resolver_test_case; | 5 library analyzer.test.generated.resolver_test_case; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; | 10 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; |
| 11 import 'package:analyzer/dart/ast/visitor.dart'; | 11 import 'package:analyzer/dart/ast/visitor.dart'; |
| 12 import 'package:analyzer/dart/element/element.dart'; | 12 import 'package:analyzer/dart/element/element.dart'; |
| 13 import 'package:analyzer/dart/element/type.dart'; | 13 import 'package:analyzer/dart/element/type.dart'; |
| 14 import 'package:analyzer/error/error.dart'; | 14 import 'package:analyzer/error/error.dart'; |
| 15 import 'package:analyzer/file_system/file_system.dart'; |
| 15 import 'package:analyzer/file_system/memory_file_system.dart'; | 16 import 'package:analyzer/file_system/memory_file_system.dart'; |
| 17 import 'package:analyzer/source/package_map_resolver.dart'; |
| 18 import 'package:analyzer/src/dart/analysis/byte_store.dart'; |
| 19 import 'package:analyzer/src/dart/analysis/driver.dart'; |
| 20 import 'package:analyzer/src/dart/analysis/file_state.dart'; |
| 16 import 'package:analyzer/src/dart/element/element.dart'; | 21 import 'package:analyzer/src/dart/element/element.dart'; |
| 17 import 'package:analyzer/src/dart/element/type.dart'; | 22 import 'package:analyzer/src/dart/element/type.dart'; |
| 18 import 'package:analyzer/src/error/codes.dart'; | 23 import 'package:analyzer/src/error/codes.dart'; |
| 19 import 'package:analyzer/src/generated/engine.dart'; | 24 import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult; |
| 20 import 'package:analyzer/src/generated/java_engine.dart'; | 25 import 'package:analyzer/src/generated/java_engine.dart'; |
| 21 import 'package:analyzer/src/generated/resolver.dart'; | 26 import 'package:analyzer/src/generated/resolver.dart'; |
| 22 import 'package:analyzer/src/generated/source_io.dart'; | 27 import 'package:analyzer/src/generated/source_io.dart'; |
| 23 import 'package:analyzer/src/generated/testing/ast_test_factory.dart'; | 28 import 'package:analyzer/src/generated/testing/ast_test_factory.dart'; |
| 24 import 'package:analyzer/src/generated/testing/element_factory.dart'; | 29 import 'package:analyzer/src/generated/testing/element_factory.dart'; |
| 25 import 'package:test/test.dart'; | 30 import 'package:test/test.dart'; |
| 26 | 31 |
| 32 import '../src/dart/analysis/physical_sdk.dart' as physical_sdk; |
| 27 import 'analysis_context_factory.dart'; | 33 import 'analysis_context_factory.dart'; |
| 28 import 'test_support.dart'; | 34 import 'test_support.dart'; |
| 29 | 35 |
| 30 /** | 36 /** |
| 31 * An AST visitor used to verify that all of the nodes in an AST structure that | 37 * An AST visitor used to verify that all of the nodes in an AST structure that |
| 32 * should have been resolved were resolved. | 38 * should have been resolved were resolved. |
| 33 */ | 39 */ |
| 34 class ResolutionVerifier extends RecursiveAstVisitor<Object> { | 40 class ResolutionVerifier extends RecursiveAstVisitor<Object> { |
| 35 /** | 41 /** |
| 36 * A set containing nodes that are known to not be resolvable and should | 42 * A set containing nodes that are known to not be resolvable and should |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 */ | 326 */ |
| 321 bool enableUnusedElement = false; | 327 bool enableUnusedElement = false; |
| 322 | 328 |
| 323 /** | 329 /** |
| 324 * Specifies if [assertErrors] should check for [HintCode.UNUSED_LOCAL_VARIABL
E]. | 330 * Specifies if [assertErrors] should check for [HintCode.UNUSED_LOCAL_VARIABL
E]. |
| 325 */ | 331 */ |
| 326 bool enableUnusedLocalVariable = false; | 332 bool enableUnusedLocalVariable = false; |
| 327 | 333 |
| 328 final Map<Source, TestAnalysisResult> analysisResults = {}; | 334 final Map<Source, TestAnalysisResult> analysisResults = {}; |
| 329 | 335 |
| 336 StringBuffer _logBuffer = new StringBuffer(); |
| 337 FileContentOverlay _fileContentOverlay = new FileContentOverlay(); |
| 338 AnalysisDriver driver; |
| 339 |
| 330 AnalysisContext get analysisContext => analysisContext2; | 340 AnalysisContext get analysisContext => analysisContext2; |
| 331 | 341 |
| 342 bool get enableNewAnalysisDriver => false; |
| 343 |
| 332 /** | 344 /** |
| 333 * Return a type provider that can be used to test the results of resolution. | 345 * Return a type provider that can be used to test the results of resolution. |
| 334 * | 346 * |
| 335 * @return a type provider | 347 * @return a type provider |
| 336 * @throws AnalysisException if dart:core cannot be resolved | 348 * @throws AnalysisException if dart:core cannot be resolved |
| 337 */ | 349 */ |
| 338 TypeProvider get typeProvider => analysisContext2.typeProvider; | 350 TypeProvider get typeProvider { |
| 351 if (enableNewAnalysisDriver) { |
| 352 return driver.sourceFactory.dartSdk.context.typeProvider; |
| 353 } else { |
| 354 return analysisContext2.typeProvider; |
| 355 } |
| 356 } |
| 339 | 357 |
| 340 /** | 358 /** |
| 341 * Return a type system that can be used to test the results of resolution. | 359 * Return a type system that can be used to test the results of resolution. |
| 342 * | 360 * |
| 343 * @return a type system | 361 * @return a type system |
| 344 */ | 362 */ |
| 345 TypeSystem get typeSystem => analysisContext2.typeSystem; | 363 TypeSystem get typeSystem => analysisContext2.typeSystem; |
| 346 | 364 |
| 347 /** | 365 /** |
| 348 * Add a source file with the given [filePath] in the root of the file system. | 366 * Add a source file with the given [filePath] in the root of the file system. |
| 349 * The file path should be absolute. The file will have the given [contents] | 367 * The file path should be absolute. The file will have the given [contents] |
| 350 * set in the content provider. Return the source representing the added file. | 368 * set in the content provider. Return the source representing the added file. |
| 351 */ | 369 */ |
| 352 Source addNamedSource(String filePath, String contents) { | 370 Source addNamedSource(String filePath, String contents) { |
| 353 Source source = | 371 filePath = resourceProvider.convertPath(filePath); |
| 354 cacheSource(resourceProvider.convertPath(filePath), contents); | 372 File file = resourceProvider.newFile(filePath, contents); |
| 355 ChangeSet changeSet = new ChangeSet(); | 373 Source source = file.createSource(); |
| 356 changeSet.addedSource(source); | 374 if (enableNewAnalysisDriver) { |
| 357 analysisContext2.applyChanges(changeSet); | 375 driver.addFile(filePath); |
| 376 } else { |
| 377 analysisContext2.setContents(source, contents); |
| 378 ChangeSet changeSet = new ChangeSet(); |
| 379 changeSet.addedSource(source); |
| 380 analysisContext2.applyChanges(changeSet); |
| 381 } |
| 358 return source; | 382 return source; |
| 359 } | 383 } |
| 360 | 384 |
| 361 /** | 385 /** |
| 362 * Add a source file named 'test.dart' in the root of the file system. The | 386 * Add a source file named 'test.dart' in the root of the file system. The |
| 363 * file will have the given [contents] set in the content provider. Return the | 387 * file will have the given [contents] set in the content provider. Return the |
| 364 * source representing the added file. | 388 * source representing the added file. |
| 365 */ | 389 */ |
| 366 Source addSource(String contents) => addNamedSource("/test.dart", contents); | 390 Source addSource(String contents) => addNamedSource("/test.dart", contents); |
| 367 | 391 |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 DartType expectedStaticType, DartType expectedPropagatedType) async { | 501 DartType expectedStaticType, DartType expectedPropagatedType) async { |
| 478 SimpleIdentifier identifier = | 502 SimpleIdentifier identifier = |
| 479 await findMarkedIdentifier(code, "; // marker"); | 503 await findMarkedIdentifier(code, "; // marker"); |
| 480 if (expectedStaticType != null) { | 504 if (expectedStaticType != null) { |
| 481 expect(identifier.staticType, expectedStaticType); | 505 expect(identifier.staticType, expectedStaticType); |
| 482 } | 506 } |
| 483 expect(identifier.propagatedType, expectedPropagatedType); | 507 expect(identifier.propagatedType, expectedPropagatedType); |
| 484 } | 508 } |
| 485 | 509 |
| 486 /** | 510 /** |
| 487 * Cache the [contents] for the file at the given [filePath] but don't add the | |
| 488 * source to the analysis context. The file path must be absolute. | |
| 489 */ | |
| 490 Source cacheSource(String filePath, String contents) { | |
| 491 Source source = resourceProvider.getFile(filePath).createSource(); | |
| 492 analysisContext2.setContents(source, contents); | |
| 493 return source; | |
| 494 } | |
| 495 | |
| 496 /** | |
| 497 * Change the contents of the given [source] to the given [contents]. | 511 * Change the contents of the given [source] to the given [contents]. |
| 498 */ | 512 */ |
| 499 void changeSource(Source source, String contents) { | 513 void changeSource(Source source, String contents) { |
| 500 analysisContext2.setContents(source, contents); | 514 analysisContext2.setContents(source, contents); |
| 501 ChangeSet changeSet = new ChangeSet(); | 515 ChangeSet changeSet = new ChangeSet(); |
| 502 changeSet.changedSource(source); | 516 changeSet.changedSource(source); |
| 503 analysisContext2.applyChanges(changeSet); | 517 analysisContext2.applyChanges(changeSet); |
| 504 } | 518 } |
| 505 | 519 |
| 506 Future<Null> computeAnalysisResult(Source source) async { | 520 Future<Null> computeAnalysisResult(Source source) async { |
| 507 analysisContext2.computeKindOf(source); | 521 if (enableNewAnalysisDriver) { |
| 508 List<Source> libraries = analysisContext2.getLibrariesContaining(source); | 522 AnalysisResult result = await driver.getResult(source.fullName); |
| 509 if (libraries.length > 0) { | 523 analysisResults[source] = |
| 510 CompilationUnit unit = | 524 new TestAnalysisResult(source, result.unit, result.errors); |
| 511 analysisContext.resolveCompilationUnit2(source, libraries.first); | 525 } else { |
| 512 List<AnalysisError> errors = analysisContext.computeErrors(source); | 526 analysisContext2.computeKindOf(source); |
| 513 analysisResults[source] = new TestAnalysisResult(source, unit, errors); | 527 List<Source> libraries = analysisContext2.getLibrariesContaining(source); |
| 528 if (libraries.length > 0) { |
| 529 CompilationUnit unit = |
| 530 analysisContext.resolveCompilationUnit2(source, libraries.first); |
| 531 List<AnalysisError> errors = analysisContext.computeErrors(source); |
| 532 analysisResults[source] = new TestAnalysisResult(source, unit, errors); |
| 533 } |
| 514 } | 534 } |
| 515 } | 535 } |
| 516 | 536 |
| 517 /** | 537 /** |
| 518 * Create a library element that represents a library named `"test"` containin
g a single | 538 * Create a library element that represents a library named `"test"` containin
g a single |
| 519 * empty compilation unit. | 539 * empty compilation unit. |
| 520 * | 540 * |
| 521 * @return the library element that was created | 541 * @return the library element that was created |
| 522 */ | 542 */ |
| 523 LibraryElementImpl createDefaultTestLibrary() => | 543 LibraryElementImpl createDefaultTestLibrary() => |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 * | 601 * |
| 582 * @param code source code to analyze. | 602 * @param code source code to analyze. |
| 583 * @param marker marker identifying sought after expression in source code. | 603 * @param marker marker identifying sought after expression in source code. |
| 584 * @return expression marked by the marker. | 604 * @return expression marked by the marker. |
| 585 * @throws Exception | 605 * @throws Exception |
| 586 */ | 606 */ |
| 587 Future<SimpleIdentifier> findMarkedIdentifier( | 607 Future<SimpleIdentifier> findMarkedIdentifier( |
| 588 String code, String marker) async { | 608 String code, String marker) async { |
| 589 try { | 609 try { |
| 590 Source source = addSource(code); | 610 Source source = addSource(code); |
| 591 LibraryElement library = resolve2(source); | |
| 592 await computeAnalysisResult(source); | 611 await computeAnalysisResult(source); |
| 593 assertNoErrors(source); | 612 assertNoErrors(source); |
| 594 verify([source]); | 613 verify([source]); |
| 595 CompilationUnit unit = resolveCompilationUnit(source, library); | 614 CompilationUnit unit = analysisResults[source].unit; |
| 596 // Could generalize this further by making [SimpleIdentifier.class] a | |
| 597 // parameter. | |
| 598 return EngineTestCase.findNode( | 615 return EngineTestCase.findNode( |
| 599 unit, code, marker, (node) => node is SimpleIdentifier); | 616 unit, code, marker, (node) => node is SimpleIdentifier); |
| 600 } catch (exception) { | 617 } catch (exception) { |
| 601 // Is there a better exception to throw here? The point is that an | 618 // Is there a better exception to throw here? The point is that an |
| 602 // assertion failure here should be a failure, in both "test_*" and | 619 // assertion failure here should be a failure, in both "test_*" and |
| 603 // "fail_*" tests. However, an assertion failure is success for the | 620 // "fail_*" tests. However, an assertion failure is success for the |
| 604 // purpose of "fail_*" tests, so without catching them here "fail_*" tests | 621 // purpose of "fail_*" tests, so without catching them here "fail_*" tests |
| 605 // can succeed by failing for the wrong reason. | 622 // can succeed by failing for the wrong reason. |
| 606 throw new StateError("Unexpected assertion failure: $exception"); | 623 throw new StateError("Unexpected assertion failure: $exception"); |
| 607 } | 624 } |
| 608 } | 625 } |
| 609 | 626 |
| 610 Expression findTopLevelConstantExpression( | 627 Expression findTopLevelConstantExpression( |
| 611 CompilationUnit compilationUnit, String name) => | 628 CompilationUnit compilationUnit, String name) => |
| 612 findTopLevelDeclaration(compilationUnit, name).initializer; | 629 findTopLevelDeclaration(compilationUnit, name).initializer; |
| 613 | |
| 614 VariableDeclaration findTopLevelDeclaration( | 630 VariableDeclaration findTopLevelDeclaration( |
| 615 CompilationUnit compilationUnit, String name) { | 631 CompilationUnit compilationUnit, String name) { |
| 616 for (CompilationUnitMember member in compilationUnit.declarations) { | 632 for (CompilationUnitMember member in compilationUnit.declarations) { |
| 617 if (member is TopLevelVariableDeclaration) { | 633 if (member is TopLevelVariableDeclaration) { |
| 618 for (VariableDeclaration variable in member.variables.variables) { | 634 for (VariableDeclaration variable in member.variables.variables) { |
| 619 if (variable.name.name == name) { | 635 if (variable.name.name == name) { |
| 620 return variable; | 636 return variable; |
| 621 } | 637 } |
| 622 } | 638 } |
| 623 } | 639 } |
| 624 } | 640 } |
| 625 return null; | 641 return null; |
| 626 // Not found | 642 // Not found |
| 627 } | 643 } |
| 628 | 644 |
| 629 /** | 645 /** |
| 630 * Re-create the analysis context being used by the test case. | 646 * Re-create the analysis context being used by the test case. |
| 631 */ | 647 */ |
| 632 void reset() { | 648 void reset({List<List<String>> packages}) { |
| 633 analysisContext2 = AnalysisContextFactory.contextWithCore( | 649 if (enableNewAnalysisDriver) { |
| 634 resourceProvider: resourceProvider); | 650 PerformanceLog log = new PerformanceLog(_logBuffer); |
| 651 AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(log); |
| 652 |
| 653 List<UriResolver> resolvers = <UriResolver>[ |
| 654 new DartUriResolver(physical_sdk.sdk), |
| 655 new ResourceUriResolver(resourceProvider) |
| 656 ]; |
| 657 if (packages != null) { |
| 658 var packageMap = <String, List<Folder>>{}; |
| 659 packages.forEach((args) { |
| 660 String name = args[0]; |
| 661 String path = |
| 662 resourceProvider.convertPath('/packages/$name/$name.dart'); |
| 663 String content = args[1]; |
| 664 File file = resourceProvider.newFile(path, content); |
| 665 packageMap[name] = <Folder>[file.parent]; |
| 666 }); |
| 667 resolvers.add(new PackageMapUriResolver(resourceProvider, packageMap)); |
| 668 } |
| 669 SourceFactory sourceFactory = new SourceFactory(resolvers); |
| 670 |
| 671 driver = new AnalysisDriver( |
| 672 scheduler, |
| 673 log, |
| 674 resourceProvider, |
| 675 new MemoryByteStore(), |
| 676 _fileContentOverlay, |
| 677 sourceFactory, |
| 678 new AnalysisOptionsImpl()); |
| 679 scheduler.start(); |
| 680 } else { |
| 681 if (packages != null) { |
| 682 var packageMap = <String, String>{}; |
| 683 packages.forEach((args) { |
| 684 String name = args[0]; |
| 685 String content = args[1]; |
| 686 packageMap['package:$name/$name.dart'] = content; |
| 687 }); |
| 688 analysisContext2 = AnalysisContextFactory.contextWithCoreAndPackages( |
| 689 packageMap, |
| 690 resourceProvider: resourceProvider); |
| 691 } else { |
| 692 analysisContext2 = AnalysisContextFactory.contextWithCore( |
| 693 resourceProvider: resourceProvider); |
| 694 } |
| 695 } |
| 635 } | 696 } |
| 636 | 697 |
| 637 /** | 698 /** |
| 638 * Re-create the analysis context being used by the test case and set the | 699 * Re-create the analysis context being used by the test case and set the |
| 639 * [options] in the newly created context to the given [options]. | 700 * [options] in the newly created context to the given [options]. |
| 640 */ | 701 */ |
| 641 void resetWithOptions(AnalysisOptions options) { | 702 void resetWithOptions(AnalysisOptions options) { |
| 642 analysisContext2 = AnalysisContextFactory.contextWithCoreAndOptions(options, | 703 // TODO(scheglov) remove duplication |
| 643 resourceProvider: resourceProvider); | 704 if (enableNewAnalysisDriver) { |
| 705 PerformanceLog log = new PerformanceLog(_logBuffer); |
| 706 AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(log); |
| 707 |
| 708 List<UriResolver> resolvers = <UriResolver>[ |
| 709 new DartUriResolver( |
| 710 options.strongMode ? physical_sdk.strongSdk : physical_sdk.sdk), |
| 711 new ResourceUriResolver(resourceProvider) |
| 712 ]; |
| 713 SourceFactory sourceFactory = new SourceFactory(resolvers); |
| 714 driver = new AnalysisDriver(scheduler, log, resourceProvider, |
| 715 new MemoryByteStore(), _fileContentOverlay, sourceFactory, options); |
| 716 scheduler.start(); |
| 717 } else { |
| 718 analysisContext2 = AnalysisContextFactory.contextWithCoreAndOptions( |
| 719 options, |
| 720 resourceProvider: resourceProvider); |
| 721 } |
| 644 } | 722 } |
| 645 | 723 |
| 646 /** | 724 /** |
| 647 * Given a library and all of its parts, resolve the contents of the library a
nd the contents of | 725 * Given a library and all of its parts, resolve the contents of the library a
nd the contents of |
| 648 * the parts. This assumes that the sources for the library and its parts have
already been added | 726 * the parts. This assumes that the sources for the library and its parts have
already been added |
| 649 * to the content provider using the method [addNamedSource]. | 727 * to the content provider using the method [addNamedSource]. |
| 650 * | 728 * |
| 651 * @param librarySource the source for the compilation unit that defines the l
ibrary | 729 * @param librarySource the source for the compilation unit that defines the l
ibrary |
| 652 * @return the element representing the resolved library | 730 * @return the element representing the resolved library |
| 653 * @throws AnalysisException if the analysis could not be performed | 731 * @throws AnalysisException if the analysis could not be performed |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 859 } | 937 } |
| 860 } | 938 } |
| 861 } | 939 } |
| 862 | 940 |
| 863 class TestAnalysisResult { | 941 class TestAnalysisResult { |
| 864 final Source source; | 942 final Source source; |
| 865 final CompilationUnit unit; | 943 final CompilationUnit unit; |
| 866 final List<AnalysisError> errors; | 944 final List<AnalysisError> errors; |
| 867 TestAnalysisResult(this.source, this.unit, this.errors); | 945 TestAnalysisResult(this.source, this.unit, this.errors); |
| 868 } | 946 } |
| OLD | NEW |