| 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'; |
| 8 |
| 7 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 8 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; | 10 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; |
| 9 import 'package:analyzer/dart/ast/visitor.dart'; | 11 import 'package:analyzer/dart/ast/visitor.dart'; |
| 10 import 'package:analyzer/dart/element/element.dart'; | 12 import 'package:analyzer/dart/element/element.dart'; |
| 11 import 'package:analyzer/dart/element/type.dart'; | 13 import 'package:analyzer/dart/element/type.dart'; |
| 12 import 'package:analyzer/error/error.dart'; | 14 import 'package:analyzer/error/error.dart'; |
| 13 import 'package:analyzer/file_system/memory_file_system.dart'; | 15 import 'package:analyzer/file_system/memory_file_system.dart'; |
| 14 import 'package:analyzer/src/dart/element/element.dart'; | 16 import 'package:analyzer/src/dart/element/element.dart'; |
| 15 import 'package:analyzer/src/dart/element/type.dart'; | 17 import 'package:analyzer/src/dart/element/type.dart'; |
| 16 import 'package:analyzer/src/error/codes.dart'; | 18 import 'package:analyzer/src/error/codes.dart'; |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 } | 357 } |
| 356 | 358 |
| 357 /** | 359 /** |
| 358 * Add a source file named 'test.dart' in the root of the file system. The | 360 * Add a source file named 'test.dart' in the root of the file system. The |
| 359 * file will have the given [contents] set in the content provider. Return the | 361 * file will have the given [contents] set in the content provider. Return the |
| 360 * source representing the added file. | 362 * source representing the added file. |
| 361 */ | 363 */ |
| 362 Source addSource(String contents) => addNamedSource("/test.dart", contents); | 364 Source addSource(String contents) => addNamedSource("/test.dart", contents); |
| 363 | 365 |
| 364 /** | 366 /** |
| 365 * Assert that the number of errors reported against the given source matches
the number of errors | 367 * Assert that the number of errors reported against the given |
| 366 * that are given and that they have the expected error codes. The order in wh
ich the errors were | 368 * [source] matches the number of errors that are given and that they have |
| 367 * gathered is ignored. | 369 * the expected error codes. The order in which the errors were gathered is |
| 368 * | 370 * ignored. |
| 369 * @param source the source against which the errors should have been reported | |
| 370 * @param expectedErrorCodes the error codes of the errors that should have be
en reported | |
| 371 * @throws AnalysisException if the reported errors could not be computed | |
| 372 * @throws AssertionFailedError if a different number of errors have been repo
rted than were | |
| 373 * expected | |
| 374 */ | 371 */ |
| 375 void assertErrors(Source source, | 372 Future<Null> assertErrors(Source source, |
| 376 [List<ErrorCode> expectedErrorCodes = const <ErrorCode>[]]) { | 373 [List<ErrorCode> expectedErrorCodes = const <ErrorCode>[]]) async { |
| 377 GatheringErrorListener errorListener = new GatheringErrorListener(); | 374 GatheringErrorListener errorListener = new GatheringErrorListener(); |
| 378 for (AnalysisError error in analysisContext2.computeErrors(source)) { | 375 for (AnalysisError error in analysisContext2.computeErrors(source)) { |
| 379 expect(error.source, source); | 376 expect(error.source, source); |
| 380 ErrorCode errorCode = error.errorCode; | 377 ErrorCode errorCode = error.errorCode; |
| 381 if (!enableUnusedElement && | 378 if (!enableUnusedElement && |
| 382 (errorCode == HintCode.UNUSED_ELEMENT || | 379 (errorCode == HintCode.UNUSED_ELEMENT || |
| 383 errorCode == HintCode.UNUSED_FIELD)) { | 380 errorCode == HintCode.UNUSED_FIELD)) { |
| 384 continue; | 381 continue; |
| 385 } | 382 } |
| 386 if (!enableUnusedLocalVariable && | 383 if (!enableUnusedLocalVariable && |
| 387 (errorCode == HintCode.UNUSED_CATCH_CLAUSE || | 384 (errorCode == HintCode.UNUSED_CATCH_CLAUSE || |
| 388 errorCode == HintCode.UNUSED_CATCH_STACK || | 385 errorCode == HintCode.UNUSED_CATCH_STACK || |
| 389 errorCode == HintCode.UNUSED_LOCAL_VARIABLE)) { | 386 errorCode == HintCode.UNUSED_LOCAL_VARIABLE)) { |
| 390 continue; | 387 continue; |
| 391 } | 388 } |
| 392 errorListener.onError(error); | 389 errorListener.onError(error); |
| 393 } | 390 } |
| 394 errorListener.assertErrorsWithCodes(expectedErrorCodes); | 391 errorListener.assertErrorsWithCodes(expectedErrorCodes); |
| 395 } | 392 } |
| 396 | 393 |
| 397 /** | 394 /** |
| 398 * Asserts that [code] verifies, but has errors with the given error codes. | 395 * Asserts that [code] verifies, but has errors with the given error codes. |
| 399 * | 396 * |
| 400 * Like [assertErrors], but takes a string of source code. | 397 * Like [assertErrors], but takes a string of source code. |
| 401 */ | 398 */ |
| 402 // TODO(rnystrom): Use this in more tests that have the same structure. | 399 // TODO(rnystrom): Use this in more tests that have the same structure. |
| 403 void assertErrorsInCode(String code, List<ErrorCode> errors) { | 400 Future<Null> assertErrorsInCode(String code, List<ErrorCode> errors) async { |
| 404 Source source = addSource(code); | 401 Source source = addSource(code); |
| 405 assertErrors(source, errors); | 402 await assertErrors(source, errors); |
| 406 verify([source]); | 403 verify([source]); |
| 407 } | 404 } |
| 408 | 405 |
| 409 /** | 406 /** |
| 410 * Asserts that [code] has errors with the given error codes. | 407 * Asserts that [code] has errors with the given error codes. |
| 411 * | 408 * |
| 412 * Like [assertErrors], but takes a string of source code. | 409 * Like [assertErrors], but takes a string of source code. |
| 413 */ | 410 */ |
| 414 void assertErrorsInUnverifiedCode(String code, List<ErrorCode> errors) { | 411 Future<Null> assertErrorsInUnverifiedCode( |
| 412 String code, List<ErrorCode> errors) async { |
| 415 Source source = addSource(code); | 413 Source source = addSource(code); |
| 416 assertErrors(source, errors); | 414 await assertErrors(source, errors); |
| 417 } | 415 } |
| 418 | 416 |
| 419 /** | 417 /** |
| 420 * Assert that no errors have been reported against the given source. | 418 * Assert that no errors have been reported against the given source. |
| 421 * | 419 * |
| 422 * @param source the source against which no errors should have been reported | 420 * @param source the source against which no errors should have been reported |
| 423 * @throws AnalysisException if the reported errors could not be computed | 421 * @throws AnalysisException if the reported errors could not be computed |
| 424 * @throws AssertionFailedError if any errors have been reported | 422 * @throws AssertionFailedError if any errors have been reported |
| 425 */ | 423 */ |
| 426 void assertNoErrors(Source source) { | 424 Future<Null> assertNoErrors(Source source) async { |
| 427 assertErrors(source); | 425 await assertErrors(source); |
| 428 } | 426 } |
| 429 | 427 |
| 430 /** | 428 /** |
| 431 * Asserts that [code] has no errors or warnings. | 429 * Asserts that [code] has no errors or warnings. |
| 432 */ | 430 */ |
| 433 // TODO(rnystrom): Use this in more tests that have the same structure. | 431 // TODO(rnystrom): Use this in more tests that have the same structure. |
| 434 void assertNoErrorsInCode(String code) { | 432 Future<Null> assertNoErrorsInCode(String code) async { |
| 435 Source source = addSource(code); | 433 Source source = addSource(code); |
| 436 assertNoErrors(source); | 434 await assertNoErrors(source); |
| 437 verify([source]); | 435 verify([source]); |
| 438 } | 436 } |
| 439 | 437 |
| 440 /** | 438 /** |
| 441 * @param code the code that assigns the value to the variable "v", no matter
how. We check that | 439 * @param code the code that assigns the value to the variable "v", no matter
how. We check that |
| 442 * "v" has expected static and propagated type. | 440 * "v" has expected static and propagated type. |
| 443 */ | 441 */ |
| 444 void assertPropagatedAssignedType(String code, DartType expectedStaticType, | 442 Future<Null> assertPropagatedAssignedType(String code, |
| 445 DartType expectedPropagatedType) { | 443 DartType expectedStaticType, DartType expectedPropagatedType) async { |
| 446 SimpleIdentifier identifier = findMarkedIdentifier(code, "v = "); | 444 SimpleIdentifier identifier = await findMarkedIdentifier(code, "v = "); |
| 447 expect(identifier.staticType, same(expectedStaticType)); | 445 expect(identifier.staticType, same(expectedStaticType)); |
| 448 expect(identifier.propagatedType, same(expectedPropagatedType)); | 446 expect(identifier.propagatedType, same(expectedPropagatedType)); |
| 449 } | 447 } |
| 450 | 448 |
| 451 /** | 449 /** |
| 452 * @param code the code that iterates using variable "v". We check that | 450 * @param code the code that iterates using variable "v". We check that |
| 453 * "v" has expected static and propagated type. | 451 * "v" has expected static and propagated type. |
| 454 */ | 452 */ |
| 455 void assertPropagatedIterationType(String code, DartType expectedStaticType, | 453 Future<Null> assertPropagatedIterationType(String code, |
| 456 DartType expectedPropagatedType) { | 454 DartType expectedStaticType, DartType expectedPropagatedType) async { |
| 457 SimpleIdentifier identifier = findMarkedIdentifier(code, "v in "); | 455 SimpleIdentifier identifier = await findMarkedIdentifier(code, "v in "); |
| 458 expect(identifier.staticType, same(expectedStaticType)); | 456 expect(identifier.staticType, same(expectedStaticType)); |
| 459 expect(identifier.propagatedType, same(expectedPropagatedType)); | 457 expect(identifier.propagatedType, same(expectedPropagatedType)); |
| 460 } | 458 } |
| 461 | 459 |
| 462 /** | 460 /** |
| 463 * Check the static and propagated types of the expression marked with "; // m
arker" comment. | 461 * Check the static and propagated types of the expression marked with "; // m
arker" comment. |
| 464 * | 462 * |
| 465 * @param code source code to analyze, with the expression to check marked wit
h "// marker". | 463 * @param code source code to analyze, with the expression to check marked wit
h "// marker". |
| 466 * @param expectedStaticType if non-null, check actual static type is equal to
this. | 464 * @param expectedStaticType if non-null, check actual static type is equal to
this. |
| 467 * @param expectedPropagatedType if non-null, check actual static type is equa
l to this. | 465 * @param expectedPropagatedType if non-null, check actual static type is equa
l to this. |
| 468 * @throws Exception | 466 * @throws Exception |
| 469 */ | 467 */ |
| 470 void assertTypeOfMarkedExpression(String code, DartType expectedStaticType, | 468 Future<Null> assertTypeOfMarkedExpression(String code, |
| 471 DartType expectedPropagatedType) { | 469 DartType expectedStaticType, DartType expectedPropagatedType) async { |
| 472 SimpleIdentifier identifier = findMarkedIdentifier(code, "; // marker"); | 470 SimpleIdentifier identifier = |
| 471 await findMarkedIdentifier(code, "; // marker"); |
| 473 if (expectedStaticType != null) { | 472 if (expectedStaticType != null) { |
| 474 expect(identifier.staticType, expectedStaticType); | 473 expect(identifier.staticType, expectedStaticType); |
| 475 } | 474 } |
| 476 expect(identifier.propagatedType, expectedPropagatedType); | 475 expect(identifier.propagatedType, expectedPropagatedType); |
| 477 } | 476 } |
| 478 | 477 |
| 479 /** | 478 /** |
| 480 * Cache the [contents] for the file at the given [filePath] but don't add the | 479 * Cache the [contents] for the file at the given [filePath] but don't add the |
| 481 * source to the analysis context. The file path must be absolute. | 480 * source to the analysis context. The file path must be absolute. |
| 482 */ | 481 */ |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 | 558 |
| 560 /** | 559 /** |
| 561 * Return the `SimpleIdentifier` marked by `marker`. The source code must have
no | 560 * Return the `SimpleIdentifier` marked by `marker`. The source code must have
no |
| 562 * errors and be verifiable. | 561 * errors and be verifiable. |
| 563 * | 562 * |
| 564 * @param code source code to analyze. | 563 * @param code source code to analyze. |
| 565 * @param marker marker identifying sought after expression in source code. | 564 * @param marker marker identifying sought after expression in source code. |
| 566 * @return expression marked by the marker. | 565 * @return expression marked by the marker. |
| 567 * @throws Exception | 566 * @throws Exception |
| 568 */ | 567 */ |
| 569 SimpleIdentifier findMarkedIdentifier(String code, String marker) { | 568 Future<SimpleIdentifier> findMarkedIdentifier( |
| 569 String code, String marker) async { |
| 570 try { | 570 try { |
| 571 Source source = addSource(code); | 571 Source source = addSource(code); |
| 572 LibraryElement library = resolve2(source); | 572 LibraryElement library = resolve2(source); |
| 573 assertNoErrors(source); | 573 await assertNoErrors(source); |
| 574 verify([source]); | 574 verify([source]); |
| 575 CompilationUnit unit = resolveCompilationUnit(source, library); | 575 CompilationUnit unit = resolveCompilationUnit(source, library); |
| 576 // Could generalize this further by making [SimpleIdentifier.class] a | 576 // Could generalize this further by making [SimpleIdentifier.class] a |
| 577 // parameter. | 577 // parameter. |
| 578 return EngineTestCase.findNode( | 578 return EngineTestCase.findNode( |
| 579 unit, code, marker, (node) => node is SimpleIdentifier); | 579 unit, code, marker, (node) => node is SimpleIdentifier); |
| 580 } catch (exception) { | 580 } catch (exception) { |
| 581 // Is there a better exception to throw here? The point is that an | 581 // 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 | 582 // assertion failure here should be a failure, in both "test_*" and |
| 583 // "fail_*" tests. However, an assertion failure is success for the | 583 // "fail_*" tests. However, an assertion failure is success for the |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 CompilationUnit unit = | 661 CompilationUnit unit = |
| 662 resolveSource2("/lib${i + 1}.dart", sourceTexts[i]); | 662 resolveSource2("/lib${i + 1}.dart", sourceTexts[i]); |
| 663 // reference the source if this is the last source | 663 // reference the source if this is the last source |
| 664 if (i + 1 == sourceTexts.length) { | 664 if (i + 1 == sourceTexts.length) { |
| 665 return resolutionMap.elementDeclaredByCompilationUnit(unit).source; | 665 return resolutionMap.elementDeclaredByCompilationUnit(unit).source; |
| 666 } | 666 } |
| 667 } | 667 } |
| 668 return null; | 668 return null; |
| 669 } | 669 } |
| 670 | 670 |
| 671 void resolveWithAndWithoutExperimental( | 671 Future<Null> resolveWithAndWithoutExperimental( |
| 672 List<String> strSources, | 672 List<String> strSources, |
| 673 List<ErrorCode> codesWithoutExperimental, | 673 List<ErrorCode> codesWithoutExperimental, |
| 674 List<ErrorCode> codesWithExperimental) { | 674 List<ErrorCode> codesWithExperimental) async { |
| 675 // Setup analysis context as non-experimental | 675 // Setup analysis context as non-experimental |
| 676 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | 676 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); |
| 677 // options.enableDeferredLoading = false; | 677 // options.enableDeferredLoading = false; |
| 678 resetWithOptions(options); | 678 resetWithOptions(options); |
| 679 // Analysis and assertions | 679 // Analysis and assertions |
| 680 Source source = resolveSources(strSources); | 680 Source source = resolveSources(strSources); |
| 681 assertErrors(source, codesWithoutExperimental); | 681 await assertErrors(source, codesWithoutExperimental); |
| 682 verify([source]); | 682 verify([source]); |
| 683 // Setup analysis context as experimental | 683 // Setup analysis context as experimental |
| 684 reset(); | 684 reset(); |
| 685 // Analysis and assertions | 685 // Analysis and assertions |
| 686 source = resolveSources(strSources); | 686 source = resolveSources(strSources); |
| 687 assertErrors(source, codesWithExperimental); | 687 await assertErrors(source, codesWithExperimental); |
| 688 verify([source]); | 688 verify([source]); |
| 689 } | 689 } |
| 690 | 690 |
| 691 void resolveWithErrors(List<String> strSources, List<ErrorCode> codes) { | 691 Future<Null> resolveWithErrors( |
| 692 List<String> strSources, List<ErrorCode> codes) async { |
| 692 // Analysis and assertions | 693 // Analysis and assertions |
| 693 Source source = resolveSources(strSources); | 694 Source source = resolveSources(strSources); |
| 694 assertErrors(source, codes); | 695 await assertErrors(source, codes); |
| 695 verify([source]); | 696 verify([source]); |
| 696 } | 697 } |
| 697 | 698 |
| 698 @override | 699 @override |
| 699 void setUp() { | 700 void setUp() { |
| 700 ElementFactory.flushStaticState(); | 701 ElementFactory.flushStaticState(); |
| 701 super.setUp(); | 702 super.setUp(); |
| 702 reset(); | 703 reset(); |
| 703 } | 704 } |
| 704 | 705 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 809 _expectType(initializer.propagatedType, propagatedType); | 810 _expectType(initializer.propagatedType, propagatedType); |
| 810 } | 811 } |
| 811 } | 812 } |
| 812 | 813 |
| 813 SimpleIdentifier findIdentifier(String search) { | 814 SimpleIdentifier findIdentifier(String search) { |
| 814 SimpleIdentifier identifier = EngineTestCase.findNode( | 815 SimpleIdentifier identifier = EngineTestCase.findNode( |
| 815 testUnit, testCode, search, (node) => node is SimpleIdentifier); | 816 testUnit, testCode, search, (node) => node is SimpleIdentifier); |
| 816 return identifier; | 817 return identifier; |
| 817 } | 818 } |
| 818 | 819 |
| 819 void resolveTestUnit(String code) { | 820 Future<Null> resolveTestUnit(String code) async { |
| 820 testCode = code; | 821 testCode = code; |
| 821 testSource = addSource(testCode); | 822 testSource = addSource(testCode); |
| 822 LibraryElement library = resolve2(testSource); | 823 LibraryElement library = resolve2(testSource); |
| 823 assertNoErrors(testSource); | 824 await assertNoErrors(testSource); |
| 824 verify([testSource]); | 825 verify([testSource]); |
| 825 testUnit = resolveCompilationUnit(testSource, library); | 826 testUnit = resolveCompilationUnit(testSource, library); |
| 826 } | 827 } |
| 827 | 828 |
| 828 /** | 829 /** |
| 829 * Validates that [type] matches [expected]. | 830 * Validates that [type] matches [expected]. |
| 830 * | 831 * |
| 831 * If [expected] is a string, validates that the type stringifies to that | 832 * If [expected] is a string, validates that the type stringifies to that |
| 832 * text. Otherwise, [expected] is used directly a [Matcher] to match the type. | 833 * text. Otherwise, [expected] is used directly a [Matcher] to match the type. |
| 833 */ | 834 */ |
| 834 _expectType(DartType type, expected) { | 835 _expectType(DartType type, expected) { |
| 835 if (expected is String) { | 836 if (expected is String) { |
| 836 expect(type.toString(), expected); | 837 expect(type.toString(), expected); |
| 837 } else { | 838 } else { |
| 838 expect(type, expected); | 839 expect(type, expected); |
| 839 } | 840 } |
| 840 } | 841 } |
| 841 } | 842 } |
| OLD | NEW |