Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(442)

Side by Side Diff: pkg/analyzer/test/generated/resolver_test_case.dart

Issue 2625783002: Explicitly compute analysis results for sources to check errors. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698