| 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'; |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 * Specifies if [assertErrors] should check for [HintCode.UNUSED_ELEMENT] and | 318 * Specifies if [assertErrors] should check for [HintCode.UNUSED_ELEMENT] and |
| 319 * [HintCode.UNUSED_FIELD]. | 319 * [HintCode.UNUSED_FIELD]. |
| 320 */ | 320 */ |
| 321 bool enableUnusedElement = false; | 321 bool enableUnusedElement = false; |
| 322 | 322 |
| 323 /** | 323 /** |
| 324 * Specifies if [assertErrors] should check for [HintCode.UNUSED_LOCAL_VARIABL
E]. | 324 * Specifies if [assertErrors] should check for [HintCode.UNUSED_LOCAL_VARIABL
E]. |
| 325 */ | 325 */ |
| 326 bool enableUnusedLocalVariable = false; | 326 bool enableUnusedLocalVariable = false; |
| 327 | 327 |
| 328 final Map<Source, TestAnalysisResult> analysisResults = {}; |
| 329 |
| 328 AnalysisContext get analysisContext => analysisContext2; | 330 AnalysisContext get analysisContext => analysisContext2; |
| 329 | 331 |
| 330 /** | 332 /** |
| 331 * Return a type provider that can be used to test the results of resolution. | 333 * Return a type provider that can be used to test the results of resolution. |
| 332 * | 334 * |
| 333 * @return a type provider | 335 * @return a type provider |
| 334 * @throws AnalysisException if dart:core cannot be resolved | 336 * @throws AnalysisException if dart:core cannot be resolved |
| 335 */ | 337 */ |
| 336 TypeProvider get typeProvider => analysisContext2.typeProvider; | 338 TypeProvider get typeProvider => analysisContext2.typeProvider; |
| 337 | 339 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 364 Source addSource(String contents) => addNamedSource("/test.dart", contents); | 366 Source addSource(String contents) => addNamedSource("/test.dart", contents); |
| 365 | 367 |
| 366 /** | 368 /** |
| 367 * Assert that the number of errors reported against the given | 369 * Assert that the number of errors reported against the given |
| 368 * [source] matches the number of errors that are given and that they have | 370 * [source] matches the number of errors that are given and that they have |
| 369 * the expected error codes. The order in which the errors were gathered is | 371 * the expected error codes. The order in which the errors were gathered is |
| 370 * ignored. | 372 * ignored. |
| 371 */ | 373 */ |
| 372 Future<Null> assertErrors(Source source, | 374 Future<Null> assertErrors(Source source, |
| 373 [List<ErrorCode> expectedErrorCodes = const <ErrorCode>[]]) async { | 375 [List<ErrorCode> expectedErrorCodes = const <ErrorCode>[]]) async { |
| 376 TestAnalysisResult result = analysisResults[source]; |
| 377 expect(result, isNotNull); |
| 378 |
| 374 GatheringErrorListener errorListener = new GatheringErrorListener(); | 379 GatheringErrorListener errorListener = new GatheringErrorListener(); |
| 375 for (AnalysisError error in analysisContext2.computeErrors(source)) { | 380 for (AnalysisError error in result.errors) { |
| 376 expect(error.source, source); | 381 expect(error.source, source); |
| 377 ErrorCode errorCode = error.errorCode; | 382 ErrorCode errorCode = error.errorCode; |
| 378 if (!enableUnusedElement && | 383 if (!enableUnusedElement && |
| 379 (errorCode == HintCode.UNUSED_ELEMENT || | 384 (errorCode == HintCode.UNUSED_ELEMENT || |
| 380 errorCode == HintCode.UNUSED_FIELD)) { | 385 errorCode == HintCode.UNUSED_FIELD)) { |
| 381 continue; | 386 continue; |
| 382 } | 387 } |
| 383 if (!enableUnusedLocalVariable && | 388 if (!enableUnusedLocalVariable && |
| 384 (errorCode == HintCode.UNUSED_CATCH_CLAUSE || | 389 (errorCode == HintCode.UNUSED_CATCH_CLAUSE || |
| 385 errorCode == HintCode.UNUSED_CATCH_STACK || | 390 errorCode == HintCode.UNUSED_CATCH_STACK || |
| 386 errorCode == HintCode.UNUSED_LOCAL_VARIABLE)) { | 391 errorCode == HintCode.UNUSED_LOCAL_VARIABLE)) { |
| 387 continue; | 392 continue; |
| 388 } | 393 } |
| 389 errorListener.onError(error); | 394 errorListener.onError(error); |
| 390 } | 395 } |
| 391 errorListener.assertErrorsWithCodes(expectedErrorCodes); | 396 errorListener.assertErrorsWithCodes(expectedErrorCodes); |
| 392 } | 397 } |
| 393 | 398 |
| 394 /** | 399 /** |
| 395 * Asserts that [code] verifies, but has errors with the given error codes. | 400 * Asserts that [code] verifies, but has errors with the given error codes. |
| 396 * | 401 * |
| 397 * Like [assertErrors], but takes a string of source code. | 402 * Like [assertErrors], but takes a string of source code. |
| 398 */ | 403 */ |
| 399 // TODO(rnystrom): Use this in more tests that have the same structure. | 404 // TODO(rnystrom): Use this in more tests that have the same structure. |
| 400 Future<Null> assertErrorsInCode(String code, List<ErrorCode> errors) async { | 405 Future<Null> assertErrorsInCode(String code, List<ErrorCode> errors) async { |
| 401 Source source = addSource(code); | 406 Source source = addSource(code); |
| 407 await computeAnalysisResult(source); |
| 402 await assertErrors(source, errors); | 408 await assertErrors(source, errors); |
| 403 verify([source]); | 409 verify([source]); |
| 404 } | 410 } |
| 405 | 411 |
| 406 /** | 412 /** |
| 407 * Asserts that [code] has errors with the given error codes. | 413 * Asserts that [code] has errors with the given error codes. |
| 408 * | 414 * |
| 409 * Like [assertErrors], but takes a string of source code. | 415 * Like [assertErrors], but takes a string of source code. |
| 410 */ | 416 */ |
| 411 Future<Null> assertErrorsInUnverifiedCode( | 417 Future<Null> assertErrorsInUnverifiedCode( |
| 412 String code, List<ErrorCode> errors) async { | 418 String code, List<ErrorCode> errors) async { |
| 413 Source source = addSource(code); | 419 Source source = addSource(code); |
| 420 await computeAnalysisResult(source); |
| 414 await assertErrors(source, errors); | 421 await assertErrors(source, errors); |
| 415 } | 422 } |
| 416 | 423 |
| 417 /** | 424 /** |
| 418 * Assert that no errors have been reported against the given source. | 425 * Assert that no errors have been reported against the given source. |
| 419 * | 426 * |
| 420 * @param source the source against which no errors should have been reported | 427 * @param source the source against which no errors should have been reported |
| 421 * @throws AnalysisException if the reported errors could not be computed | 428 * @throws AnalysisException if the reported errors could not be computed |
| 422 * @throws AssertionFailedError if any errors have been reported | 429 * @throws AssertionFailedError if any errors have been reported |
| 423 */ | 430 */ |
| 424 Future<Null> assertNoErrors(Source source) async { | 431 Future<Null> assertNoErrors(Source source) async { |
| 425 await assertErrors(source); | 432 await assertErrors(source); |
| 426 } | 433 } |
| 427 | 434 |
| 428 /** | 435 /** |
| 429 * Asserts that [code] has no errors or warnings. | 436 * Asserts that [code] has no errors or warnings. |
| 430 */ | 437 */ |
| 431 // TODO(rnystrom): Use this in more tests that have the same structure. | 438 // TODO(rnystrom): Use this in more tests that have the same structure. |
| 432 Future<Null> assertNoErrorsInCode(String code) async { | 439 Future<Null> assertNoErrorsInCode(String code) async { |
| 433 Source source = addSource(code); | 440 Source source = addSource(code); |
| 441 await computeAnalysisResult(source); |
| 434 await assertNoErrors(source); | 442 await assertNoErrors(source); |
| 435 verify([source]); | 443 verify([source]); |
| 436 } | 444 } |
| 437 | 445 |
| 438 /** | 446 /** |
| 439 * @param code the code that assigns the value to the variable "v", no matter
how. We check that | 447 * @param code the code that assigns the value to the variable "v", no matter
how. We check that |
| 440 * "v" has expected static and propagated type. | 448 * "v" has expected static and propagated type. |
| 441 */ | 449 */ |
| 442 Future<Null> assertPropagatedAssignedType(String code, | 450 Future<Null> assertPropagatedAssignedType(String code, |
| 443 DartType expectedStaticType, DartType expectedPropagatedType) async { | 451 DartType expectedStaticType, DartType expectedPropagatedType) async { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 /** | 496 /** |
| 489 * Change the contents of the given [source] to the given [contents]. | 497 * Change the contents of the given [source] to the given [contents]. |
| 490 */ | 498 */ |
| 491 void changeSource(Source source, String contents) { | 499 void changeSource(Source source, String contents) { |
| 492 analysisContext2.setContents(source, contents); | 500 analysisContext2.setContents(source, contents); |
| 493 ChangeSet changeSet = new ChangeSet(); | 501 ChangeSet changeSet = new ChangeSet(); |
| 494 changeSet.changedSource(source); | 502 changeSet.changedSource(source); |
| 495 analysisContext2.applyChanges(changeSet); | 503 analysisContext2.applyChanges(changeSet); |
| 496 } | 504 } |
| 497 | 505 |
| 506 Future<Null> computeAnalysisResult(Source source) async { |
| 507 analysisContext2.computeKindOf(source); |
| 508 List<Source> libraries = analysisContext2.getLibrariesContaining(source); |
| 509 if (libraries.length > 0) { |
| 510 CompilationUnit unit = |
| 511 analysisContext.resolveCompilationUnit2(source, libraries.first); |
| 512 List<AnalysisError> errors = analysisContext.computeErrors(source); |
| 513 analysisResults[source] = new TestAnalysisResult(source, unit, errors); |
| 514 } |
| 515 } |
| 516 |
| 498 /** | 517 /** |
| 499 * Create a library element that represents a library named `"test"` containin
g a single | 518 * Create a library element that represents a library named `"test"` containin
g a single |
| 500 * empty compilation unit. | 519 * empty compilation unit. |
| 501 * | 520 * |
| 502 * @return the library element that was created | 521 * @return the library element that was created |
| 503 */ | 522 */ |
| 504 LibraryElementImpl createDefaultTestLibrary() => | 523 LibraryElementImpl createDefaultTestLibrary() => |
| 505 createTestLibrary(AnalysisContextFactory.contextWithCore(), "test"); | 524 createTestLibrary(AnalysisContextFactory.contextWithCore(), "test"); |
| 506 | 525 |
| 507 /** | 526 /** |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 * @param code source code to analyze. | 582 * @param code source code to analyze. |
| 564 * @param marker marker identifying sought after expression in source code. | 583 * @param marker marker identifying sought after expression in source code. |
| 565 * @return expression marked by the marker. | 584 * @return expression marked by the marker. |
| 566 * @throws Exception | 585 * @throws Exception |
| 567 */ | 586 */ |
| 568 Future<SimpleIdentifier> findMarkedIdentifier( | 587 Future<SimpleIdentifier> findMarkedIdentifier( |
| 569 String code, String marker) async { | 588 String code, String marker) async { |
| 570 try { | 589 try { |
| 571 Source source = addSource(code); | 590 Source source = addSource(code); |
| 572 LibraryElement library = resolve2(source); | 591 LibraryElement library = resolve2(source); |
| 592 await computeAnalysisResult(source); |
| 573 await assertNoErrors(source); | 593 await assertNoErrors(source); |
| 574 verify([source]); | 594 verify([source]); |
| 575 CompilationUnit unit = resolveCompilationUnit(source, library); | 595 CompilationUnit unit = resolveCompilationUnit(source, library); |
| 576 // Could generalize this further by making [SimpleIdentifier.class] a | 596 // Could generalize this further by making [SimpleIdentifier.class] a |
| 577 // parameter. | 597 // parameter. |
| 578 return EngineTestCase.findNode( | 598 return EngineTestCase.findNode( |
| 579 unit, code, marker, (node) => node is SimpleIdentifier); | 599 unit, code, marker, (node) => node is SimpleIdentifier); |
| 580 } catch (exception) { | 600 } catch (exception) { |
| 581 // Is there a better exception to throw here? The point is that an | 601 // Is there a better exception to throw here? The point is that an |
| 582 // assertion failure here should be a failure, in both "test_*" and | 602 // assertion failure here should be a failure, in both "test_*" and |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 | 669 |
| 650 CompilationUnit resolveSource(String sourceText) => | 670 CompilationUnit resolveSource(String sourceText) => |
| 651 resolveSource2("/test.dart", sourceText); | 671 resolveSource2("/test.dart", sourceText); |
| 652 | 672 |
| 653 CompilationUnit resolveSource2(String fileName, String sourceText) { | 673 CompilationUnit resolveSource2(String fileName, String sourceText) { |
| 654 Source source = addNamedSource(fileName, sourceText); | 674 Source source = addNamedSource(fileName, sourceText); |
| 655 LibraryElement library = analysisContext.computeLibraryElement(source); | 675 LibraryElement library = analysisContext.computeLibraryElement(source); |
| 656 return analysisContext.resolveCompilationUnit(source, library); | 676 return analysisContext.resolveCompilationUnit(source, library); |
| 657 } | 677 } |
| 658 | 678 |
| 659 Source resolveSources(List<String> sourceTexts) { | 679 Future<Source> resolveSources2(List<String> sourceTexts) async { |
| 660 for (int i = 0; i < sourceTexts.length; i++) { | 680 for (int i = 0; i < sourceTexts.length; i++) { |
| 661 CompilationUnit unit = | 681 Source source = addNamedSource('/lib${i + 1}.dart', sourceTexts[i]); |
| 662 resolveSource2("/lib${i + 1}.dart", sourceTexts[i]); | 682 await computeAnalysisResult(source); |
| 663 // reference the source if this is the last source | 683 // reference the source if this is the last source |
| 664 if (i + 1 == sourceTexts.length) { | 684 if (i + 1 == sourceTexts.length) { |
| 665 return resolutionMap.elementDeclaredByCompilationUnit(unit).source; | 685 return source; |
| 666 } | 686 } |
| 667 } | 687 } |
| 668 return null; | 688 return null; |
| 669 } | 689 } |
| 670 | 690 |
| 671 Future<Null> resolveWithAndWithoutExperimental( | 691 Future<Null> resolveWithAndWithoutExperimental( |
| 672 List<String> strSources, | 692 List<String> strSources, |
| 673 List<ErrorCode> codesWithoutExperimental, | 693 List<ErrorCode> codesWithoutExperimental, |
| 674 List<ErrorCode> codesWithExperimental) async { | 694 List<ErrorCode> codesWithExperimental) async { |
| 675 // Setup analysis context as non-experimental | 695 // Setup analysis context as non-experimental |
| 676 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | 696 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); |
| 677 // options.enableDeferredLoading = false; | 697 // options.enableDeferredLoading = false; |
| 678 resetWithOptions(options); | 698 resetWithOptions(options); |
| 679 // Analysis and assertions | 699 // Analysis and assertions |
| 680 Source source = resolveSources(strSources); | 700 Source source = await resolveSources2(strSources); |
| 701 await computeAnalysisResult(source); |
| 681 await assertErrors(source, codesWithoutExperimental); | 702 await assertErrors(source, codesWithoutExperimental); |
| 682 verify([source]); | 703 verify([source]); |
| 683 // Setup analysis context as experimental | 704 // Setup analysis context as experimental |
| 684 reset(); | 705 reset(); |
| 685 // Analysis and assertions | 706 // Analysis and assertions |
| 686 source = resolveSources(strSources); | 707 source = await resolveSources2(strSources); |
| 708 await computeAnalysisResult(source); |
| 687 await assertErrors(source, codesWithExperimental); | 709 await assertErrors(source, codesWithExperimental); |
| 688 verify([source]); | 710 verify([source]); |
| 689 } | 711 } |
| 690 | 712 |
| 691 Future<Null> resolveWithErrors( | 713 Future<Null> resolveWithErrors( |
| 692 List<String> strSources, List<ErrorCode> codes) async { | 714 List<String> strSources, List<ErrorCode> codes) async { |
| 693 // Analysis and assertions | 715 Source source = await resolveSources2(strSources); |
| 694 Source source = resolveSources(strSources); | |
| 695 await assertErrors(source, codes); | 716 await assertErrors(source, codes); |
| 696 verify([source]); | 717 verify([source]); |
| 697 } | 718 } |
| 698 | 719 |
| 699 @override | 720 @override |
| 700 void setUp() { | 721 void setUp() { |
| 701 ElementFactory.flushStaticState(); | 722 ElementFactory.flushStaticState(); |
| 702 super.setUp(); | 723 super.setUp(); |
| 703 reset(); | 724 reset(); |
| 704 } | 725 } |
| 705 | 726 |
| 706 @override | 727 @override |
| 707 void tearDown() { | 728 void tearDown() { |
| 708 analysisContext2 = null; | 729 analysisContext2 = null; |
| 709 super.tearDown(); | 730 super.tearDown(); |
| 710 } | 731 } |
| 711 | 732 |
| 712 /** | 733 /** |
| 713 * Verify that all of the identifiers in the compilation units associated with | 734 * Verify that all of the identifiers in the compilation units associated with |
| 714 * the given [sources] have been resolved. | 735 * the given [sources] have been resolved. |
| 715 */ | 736 */ |
| 716 void verify(List<Source> sources) { | 737 void verify(List<Source> sources) { |
| 717 ResolutionVerifier verifier = new ResolutionVerifier(); | 738 ResolutionVerifier verifier = new ResolutionVerifier(); |
| 718 for (Source source in sources) { | 739 for (Source source in sources) { |
| 719 List<Source> libraries = analysisContext2.getLibrariesContaining(source); | 740 TestAnalysisResult result = analysisResults[source]; |
| 720 for (Source library in libraries) { | 741 expect(result, isNotNull); |
| 721 analysisContext2 | 742 result.unit.accept(verifier); |
| 722 .resolveCompilationUnit2(source, library) | |
| 723 .accept(verifier); | |
| 724 } | |
| 725 } | 743 } |
| 726 verifier.assertResolved(); | 744 verifier.assertResolved(); |
| 727 } | 745 } |
| 728 } | 746 } |
| 729 | 747 |
| 730 /** | 748 /** |
| 731 * Shared infrastructure for [StaticTypeAnalyzer2Test] and | 749 * Shared infrastructure for [StaticTypeAnalyzer2Test] and |
| 732 * [StrongModeStaticTypeAnalyzer2Test]. | 750 * [StrongModeStaticTypeAnalyzer2Test]. |
| 733 */ | 751 */ |
| 734 class StaticTypeAnalyzer2TestShared extends ResolverTestCase { | 752 class StaticTypeAnalyzer2TestShared extends ResolverTestCase { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 814 SimpleIdentifier findIdentifier(String search) { | 832 SimpleIdentifier findIdentifier(String search) { |
| 815 SimpleIdentifier identifier = EngineTestCase.findNode( | 833 SimpleIdentifier identifier = EngineTestCase.findNode( |
| 816 testUnit, testCode, search, (node) => node is SimpleIdentifier); | 834 testUnit, testCode, search, (node) => node is SimpleIdentifier); |
| 817 return identifier; | 835 return identifier; |
| 818 } | 836 } |
| 819 | 837 |
| 820 Future<Null> resolveTestUnit(String code) async { | 838 Future<Null> resolveTestUnit(String code) async { |
| 821 testCode = code; | 839 testCode = code; |
| 822 testSource = addSource(testCode); | 840 testSource = addSource(testCode); |
| 823 LibraryElement library = resolve2(testSource); | 841 LibraryElement library = resolve2(testSource); |
| 842 await computeAnalysisResult(testSource); |
| 824 await assertNoErrors(testSource); | 843 await assertNoErrors(testSource); |
| 825 verify([testSource]); | 844 verify([testSource]); |
| 826 testUnit = resolveCompilationUnit(testSource, library); | 845 testUnit = resolveCompilationUnit(testSource, library); |
| 827 } | 846 } |
| 828 | 847 |
| 829 /** | 848 /** |
| 830 * Validates that [type] matches [expected]. | 849 * Validates that [type] matches [expected]. |
| 831 * | 850 * |
| 832 * If [expected] is a string, validates that the type stringifies to that | 851 * If [expected] is a string, validates that the type stringifies to that |
| 833 * text. Otherwise, [expected] is used directly a [Matcher] to match the type. | 852 * text. Otherwise, [expected] is used directly a [Matcher] to match the type. |
| 834 */ | 853 */ |
| 835 _expectType(DartType type, expected) { | 854 _expectType(DartType type, expected) { |
| 836 if (expected is String) { | 855 if (expected is String) { |
| 837 expect(type.toString(), expected); | 856 expect(type.toString(), expected); |
| 838 } else { | 857 } else { |
| 839 expect(type, expected); | 858 expect(type, expected); |
| 840 } | 859 } |
| 841 } | 860 } |
| 842 } | 861 } |
| 862 |
| 863 class TestAnalysisResult { |
| 864 final Source source; |
| 865 final CompilationUnit unit; |
| 866 final List<AnalysisError> errors; |
| 867 TestAnalysisResult(this.source, this.unit, this.errors); |
| 868 } |
| OLD | NEW |