| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 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 | 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.src.summary.summary_test; | 5 library analyzer.test.src.summary.summary_test; |
| 6 | 6 |
| 7 import 'package:analyzer/analyzer.dart'; |
| 7 import 'package:analyzer/dart/ast/ast.dart'; | 8 import 'package:analyzer/dart/ast/ast.dart'; |
| 8 import 'package:analyzer/dart/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
| 9 import 'package:analyzer/src/generated/engine.dart'; | 10 import 'package:analyzer/src/generated/engine.dart'; |
| 10 import 'package:analyzer/src/generated/error.dart'; | 11 import 'package:analyzer/src/generated/error.dart'; |
| 11 import 'package:analyzer/src/generated/java_engine_io.dart'; | 12 import 'package:analyzer/src/generated/java_engine_io.dart'; |
| 12 import 'package:analyzer/src/generated/parser.dart'; | 13 import 'package:analyzer/src/generated/parser.dart'; |
| 13 import 'package:analyzer/src/generated/scanner.dart'; | 14 import 'package:analyzer/src/generated/scanner.dart'; |
| 14 import 'package:analyzer/src/generated/source.dart'; | 15 import 'package:analyzer/src/generated/source.dart'; |
| 15 import 'package:analyzer/src/generated/source_io.dart'; | 16 import 'package:analyzer/src/generated/source_io.dart'; |
| 16 import 'package:analyzer/src/summary/base.dart'; | 17 import 'package:analyzer/src/summary/base.dart'; |
| 17 import 'package:analyzer/src/summary/format.dart'; | 18 import 'package:analyzer/src/summary/format.dart'; |
| 18 import 'package:analyzer/src/summary/prelink.dart'; | 19 import 'package:analyzer/src/summary/prelink.dart'; |
| 19 import 'package:analyzer/src/summary/public_namespace_computer.dart' | 20 import 'package:analyzer/src/summary/public_namespace_computer.dart' |
| 20 as public_namespace; | 21 as public_namespace; |
| 22 import 'package:analyzer/src/summary/summarize_ast.dart'; |
| 21 import 'package:analyzer/src/summary/summarize_elements.dart' | 23 import 'package:analyzer/src/summary/summarize_elements.dart' |
| 22 as summarize_elements; | 24 as summarize_elements; |
| 23 import 'package:unittest/unittest.dart'; | 25 import 'package:unittest/unittest.dart'; |
| 24 | 26 |
| 25 import '../../generated/resolver_test.dart'; | 27 import '../../generated/resolver_test.dart'; |
| 26 import '../../reflective_tests.dart'; | 28 import '../../reflective_tests.dart'; |
| 27 | 29 |
| 28 main() { | 30 main() { |
| 29 groupSep = ' | '; | 31 groupSep = ' | '; |
| 30 runReflectiveTests(SummarizeElementsTest); | 32 runReflectiveTests(SummarizeElementsTest); |
| 31 runReflectiveTests(PrelinkerTest); | 33 runReflectiveTests(PrelinkerTest); |
| 34 runReflectiveTests(UnlinkedSummarizeAstTest); |
| 32 } | 35 } |
| 33 | 36 |
| 34 /** | 37 /** |
| 38 * The public namespaces of the sdk are computed once so that we don't bog |
| 39 * down the test. Structured as a map from absolute URI to the corresponding |
| 40 * public namespace. |
| 41 * |
| 42 * Note: should an exception occur during computation of this variable, it |
| 43 * will silently be set to null to allow other tests to run. |
| 44 */ |
| 45 final Map<String, UnlinkedPublicNamespace> sdkPublicNamespace = () { |
| 46 try { |
| 47 AnalysisContext analysisContext = AnalysisContextFactory.contextWithCore(); |
| 48 Map<String, UnlinkedPublicNamespace> uriToNamespace = |
| 49 <String, UnlinkedPublicNamespace>{}; |
| 50 List<LibraryElement> libraries = [ |
| 51 analysisContext.typeProvider.objectType.element.library, |
| 52 analysisContext.typeProvider.futureType.element.library |
| 53 ]; |
| 54 for (LibraryElement library in libraries) { |
| 55 summarize_elements.LibrarySerializationResult serializedLibrary = |
| 56 summarize_elements.serializeLibrary( |
| 57 library, analysisContext.typeProvider); |
| 58 for (int i = 0; i < serializedLibrary.unlinkedUnits.length; i++) { |
| 59 uriToNamespace[serializedLibrary.unitUris[i]] = |
| 60 new UnlinkedUnit.fromBuffer( |
| 61 serializedLibrary.unlinkedUnits[i].toBuffer()).publicNamespace; |
| 62 } |
| 63 } |
| 64 return uriToNamespace; |
| 65 } catch (_) { |
| 66 return null; |
| 67 } |
| 68 }(); |
| 69 |
| 70 /** |
| 35 * Convert a summary object (or a portion of one) into a canonical form that | 71 * Convert a summary object (or a portion of one) into a canonical form that |
| 36 * can be easily compared using [expect]. If [orderByName] is true, and the | 72 * can be easily compared using [expect]. If [orderByName] is true, and the |
| 37 * object is a [List], it is sorted by the `name` field of its elements. | 73 * object is a [List], it is sorted by the `name` field of its elements. |
| 38 */ | 74 */ |
| 39 Object canonicalize(Object obj, {bool orderByName: false}) { | 75 Object canonicalize(Object obj, {bool orderByName: false}) { |
| 40 if (obj is SummaryClass) { | 76 if (obj is SummaryClass) { |
| 41 Map<String, Object> result = <String, Object>{}; | 77 Map<String, Object> result = <String, Object>{}; |
| 42 obj.toMap().forEach((String key, Object value) { | 78 obj.toMap().forEach((String key, Object value) { |
| 43 bool orderByName = false; | 79 bool orderByName = false; |
| 44 if (obj is UnlinkedPublicNamespace && key == 'names') { | 80 if (obj is UnlinkedPublicNamespace && key == 'names') { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 return namespace; | 118 return namespace; |
| 83 } | 119 } |
| 84 | 120 |
| 85 /** | 121 /** |
| 86 * Override of [SummaryTest] which verifies the correctness of the prelinker by | 122 * Override of [SummaryTest] which verifies the correctness of the prelinker by |
| 87 * creating summaries from the element model, discarding their prelinked | 123 * creating summaries from the element model, discarding their prelinked |
| 88 * information, and then recreating it using the prelinker. | 124 * information, and then recreating it using the prelinker. |
| 89 */ | 125 */ |
| 90 @reflectiveTest | 126 @reflectiveTest |
| 91 class PrelinkerTest extends SummarizeElementsTest { | 127 class PrelinkerTest extends SummarizeElementsTest { |
| 92 /** | |
| 93 * The public namespaces of the sdk are computed once so that we don't bog | |
| 94 * down the test. Structured as a map from absolute URI to the corresponding | |
| 95 * public namespace. | |
| 96 * | |
| 97 * Note: should an exception occur during computation of this variable, it | |
| 98 * will silently be set to null to allow other tests to run. | |
| 99 */ | |
| 100 static final Map<String, UnlinkedPublicNamespace> sdkPublicNamespace = () { | |
| 101 try { | |
| 102 AnalysisContext analysisContext = | |
| 103 AnalysisContextFactory.contextWithCore(); | |
| 104 Map<String, UnlinkedPublicNamespace> uriToNamespace = | |
| 105 <String, UnlinkedPublicNamespace>{}; | |
| 106 List<LibraryElement> libraries = [ | |
| 107 analysisContext.typeProvider.objectType.element.library, | |
| 108 analysisContext.typeProvider.futureType.element.library | |
| 109 ]; | |
| 110 for (LibraryElement library in libraries) { | |
| 111 summarize_elements.LibrarySerializationResult serializedLibrary = | |
| 112 summarize_elements.serializeLibrary( | |
| 113 library, analysisContext.typeProvider); | |
| 114 for (int i = 0; i < serializedLibrary.unlinkedUnits.length; i++) { | |
| 115 uriToNamespace[serializedLibrary.unitUris[i]] = | |
| 116 new UnlinkedUnit.fromBuffer( | |
| 117 serializedLibrary.unlinkedUnits[i].toBuffer()) | |
| 118 .publicNamespace; | |
| 119 } | |
| 120 } | |
| 121 return uriToNamespace; | |
| 122 } catch (_) { | |
| 123 return null; | |
| 124 } | |
| 125 }(); | |
| 126 | |
| 127 final Map<String, UnlinkedPublicNamespace> uriToPublicNamespace = | 128 final Map<String, UnlinkedPublicNamespace> uriToPublicNamespace = |
| 128 <String, UnlinkedPublicNamespace>{}; | 129 <String, UnlinkedPublicNamespace>{}; |
| 129 | 130 |
| 130 @override | 131 @override |
| 131 bool get expectAbsoluteUrisInDependencies => false; | 132 bool get expectAbsoluteUrisInDependencies => false; |
| 132 | 133 |
| 133 @override | 134 @override |
| 134 Source addNamedSource(String filePath, String contents) { | 135 Source addNamedSource(String filePath, String contents) { |
| 135 Source source = super.addNamedSource(filePath, contents); | 136 Source source = super.addNamedSource(filePath, contents); |
| 136 uriToPublicNamespace[absUri(filePath)] = | 137 uriToPublicNamespace[absUri(filePath)] = |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 */ | 194 */ |
| 194 List<String> unitUris; | 195 List<String> unitUris; |
| 195 | 196 |
| 196 /** | 197 /** |
| 197 * Map containing all source files in this test, and their corresponding file | 198 * Map containing all source files in this test, and their corresponding file |
| 198 * contents. | 199 * contents. |
| 199 */ | 200 */ |
| 200 final Map<Source, String> _fileContents = <Source, String>{}; | 201 final Map<Source, String> _fileContents = <Source, String>{}; |
| 201 | 202 |
| 202 @override | 203 @override |
| 204 LinkedLibrary linked; |
| 205 |
| 206 @override |
| 207 List<UnlinkedUnit> unlinkedUnits; |
| 208 |
| 209 @override |
| 203 bool get checkAstDerivedData => false; | 210 bool get checkAstDerivedData => false; |
| 204 | 211 |
| 205 @override | 212 @override |
| 206 bool get expectAbsoluteUrisInDependencies => true; | 213 bool get expectAbsoluteUrisInDependencies => true; |
| 207 | 214 |
| 208 @override | 215 @override |
| 209 Source addNamedSource(String filePath, String contents) { | 216 Source addNamedSource(String filePath, String contents) { |
| 210 Source source = super.addNamedSource(filePath, contents); | 217 Source source = super.addNamedSource(filePath, contents); |
| 211 _fileContents[source] = contents; | 218 _fileContents[source] = contents; |
| 212 return source; | 219 return source; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 } | 303 } |
| 297 | 304 |
| 298 /** | 305 /** |
| 299 * Base class containing most summary tests. This allows summary tests to be | 306 * Base class containing most summary tests. This allows summary tests to be |
| 300 * re-used to exercise all the different ways in which summaries can be | 307 * re-used to exercise all the different ways in which summaries can be |
| 301 * generated (e.g. direct from the AST, from the element model, from a | 308 * generated (e.g. direct from the AST, from the element model, from a |
| 302 * "relinking" process, etc.) | 309 * "relinking" process, etc.) |
| 303 */ | 310 */ |
| 304 abstract class SummaryTest { | 311 abstract class SummaryTest { |
| 305 /** | 312 /** |
| 306 * Linked summary that results from serializing and then deserializing the | |
| 307 * library under test. | |
| 308 */ | |
| 309 LinkedLibrary linked; | |
| 310 | |
| 311 /** | |
| 312 * Unlinked compilation unit summaries that result from serializing and | |
| 313 * deserializing the library under test. | |
| 314 */ | |
| 315 List<UnlinkedUnit> unlinkedUnits; | |
| 316 | |
| 317 /** | |
| 318 * A test will set this to `true` if it contains `import`, `export`, or | 313 * A test will set this to `true` if it contains `import`, `export`, or |
| 319 * `part` declarations that deliberately refer to non-existent files. | 314 * `part` declarations that deliberately refer to non-existent files. |
| 320 */ | 315 */ |
| 321 bool allowMissingFiles = false; | 316 bool allowMissingFiles = false; |
| 322 | 317 |
| 323 /** | 318 /** |
| 324 * `true` if the summary was created directly from the AST (and hence | 319 * `true` if the summary was created directly from the AST (and hence |
| 325 * contains information that is not obtainable from the element model alone). | 320 * contains information that is not obtainable from the element model alone). |
| 326 * TODO(paulberry): modify the element model so that it contains all the data | 321 * TODO(paulberry): modify the element model so that it contains all the data |
| 327 * that summaries need, so that this flag is no longer needed. | 322 * that summaries need, so that this flag is no longer needed. |
| 328 */ | 323 */ |
| 329 bool get checkAstDerivedData; | 324 bool get checkAstDerivedData; |
| 330 | 325 |
| 331 /** | 326 /** |
| 332 * Get access to the linked defining compilation unit. | 327 * Get access to the linked defining compilation unit. |
| 333 */ | 328 */ |
| 334 LinkedUnit get definingUnit => linked.units[0]; | 329 LinkedUnit get definingUnit => linked.units[0]; |
| 335 | 330 |
| 336 /** | 331 /** |
| 337 * `true` if the linked portion of the summary is expected to contain | 332 * `true` if the linked portion of the summary is expected to contain |
| 338 * absolute URIs. This happens because the element model doesn't (yet) store | 333 * absolute URIs. This happens because the element model doesn't (yet) store |
| 339 * enough information to recover relative URIs, TODO(paulberry): fix this. | 334 * enough information to recover relative URIs, TODO(paulberry): fix this. |
| 340 */ | 335 */ |
| 341 bool get expectAbsoluteUrisInDependencies; | 336 bool get expectAbsoluteUrisInDependencies; |
| 342 | 337 |
| 343 /** | 338 /** |
| 339 * Get access to the linked summary that results from serializing and |
| 340 * then deserializing the library under test. |
| 341 */ |
| 342 LinkedLibrary get linked; |
| 343 |
| 344 /** |
| 345 * Get access to the unlinked compilation unit summaries that result from |
| 346 * serializing and deserializing the library under test. |
| 347 */ |
| 348 List<UnlinkedUnit> get unlinkedUnits; |
| 349 |
| 350 /** |
| 344 * Convert [path] to a suitably formatted absolute path URI for the current | 351 * Convert [path] to a suitably formatted absolute path URI for the current |
| 345 * platform. | 352 * platform. |
| 346 */ | 353 */ |
| 347 String absUri(String path) { | 354 String absUri(String path) { |
| 348 return FileUtilities2.createFile(path).toURI().toString(); | 355 return FileUtilities2.createFile(path).toURI().toString(); |
| 349 } | 356 } |
| 350 | 357 |
| 351 /** | 358 /** |
| 352 * Add the given source file so that it may be referenced by the file under | 359 * Add the given source file so that it may be referenced by the file under |
| 353 * test. | 360 * test. |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 expect(reference.prefixReference, 0); | 543 expect(reference.prefixReference, 0); |
| 537 } | 544 } |
| 538 if (absoluteUri == null) { | 545 if (absoluteUri == null) { |
| 539 expect(referenceResolution.dependency, 0); | 546 expect(referenceResolution.dependency, 0); |
| 540 } else { | 547 } else { |
| 541 checkDependency(referenceResolution.dependency, absoluteUri, relativeUri); | 548 checkDependency(referenceResolution.dependency, absoluteUri, relativeUri); |
| 542 } | 549 } |
| 543 if (!allowTypeParameters) { | 550 if (!allowTypeParameters) { |
| 544 expect(typeRef.typeArguments, isEmpty); | 551 expect(typeRef.typeArguments, isEmpty); |
| 545 } | 552 } |
| 546 if (expectedKind == ReferenceKind.unresolved) { | 553 if (expectedKind == ReferenceKind.unresolved && !checkAstDerivedData) { |
| 547 // summarize_elements.dart isn't yet able to record the name of | 554 // summarize_elements.dart isn't yet able to record the name or prefix of |
| 548 // unresolved references. TODO(paulberry): fix this. | 555 // unresolved references. TODO(paulberry): fix this. |
| 549 expect(reference.name, '*unresolved*'); | 556 expect(reference.name, '*unresolved*'); |
| 550 } else if (expectedName == null) { | |
| 551 expect(reference.name, isEmpty); | |
| 552 } else { | |
| 553 expect(reference.name, expectedName); | |
| 554 } | |
| 555 if (expectedPrefix == null) { | |
| 556 expect(reference.prefixReference, 0); | 557 expect(reference.prefixReference, 0); |
| 557 } else { | 558 } else { |
| 558 checkPrefix(reference.prefixReference, expectedPrefix); | 559 if (expectedName == null) { |
| 560 expect(reference.name, isEmpty); |
| 561 } else { |
| 562 expect(reference.name, expectedName); |
| 563 } |
| 564 if (expectedPrefix == null) { |
| 565 expect(reference.prefixReference, 0); |
| 566 } else { |
| 567 checkPrefix(reference.prefixReference, expectedPrefix); |
| 568 } |
| 559 } | 569 } |
| 560 expect(referenceResolution.kind, expectedKind); | 570 expect(referenceResolution.kind, expectedKind); |
| 561 expect(referenceResolution.unit, expectedTargetUnit); | 571 expect(referenceResolution.unit, expectedTargetUnit); |
| 562 expect(referenceResolution.numTypeParameters, numTypeParameters); | 572 expect(referenceResolution.numTypeParameters, numTypeParameters); |
| 563 } | 573 } |
| 564 | 574 |
| 565 /** | 575 /** |
| 566 * Verify that the given [typeRef] represents a reference to an unresolved | 576 * Verify that the given [typeRef] represents a reference to an unresolved |
| 567 * type. | 577 * type. |
| 568 */ | 578 */ |
| (...skipping 12 matching lines...) Expand all Loading... |
| 581 /** | 591 /** |
| 582 * Docs | 592 * Docs |
| 583 */ | 593 */ |
| 584 v | 594 v |
| 585 }'''; | 595 }'''; |
| 586 UnlinkedEnumValue value = serializeEnumText(text).values[0]; | 596 UnlinkedEnumValue value = serializeEnumText(text).values[0]; |
| 587 expect(value.documentationComment, isNotNull); | 597 expect(value.documentationComment, isNotNull); |
| 588 checkDocumentationComment(value.documentationComment, text); | 598 checkDocumentationComment(value.documentationComment, text); |
| 589 } | 599 } |
| 590 | 600 |
| 591 fail_test_import_missing() { | |
| 592 // TODO(paulberry): At the moment unresolved imports are not included in | |
| 593 // the element model, so we can't pass this test. | |
| 594 // Unresolved imports are included since this is necessary for proper | |
| 595 // dependency tracking. | |
| 596 allowMissingFiles = true; | |
| 597 serializeLibraryText('import "foo.dart";', allowErrors: true); | |
| 598 // Second import is the implicit import of dart:core | |
| 599 expect(unlinkedUnits[0].imports, hasLength(2)); | |
| 600 checkDependency( | |
| 601 linked.importDependencies[0], absUri('/foo.dart'), 'foo.dart'); | |
| 602 } | |
| 603 | |
| 604 fail_type_reference_to_nonexistent_file_via_prefix() { | |
| 605 // TODO(paulberry): this test currently fails because there is not enough | |
| 606 // information in the element model to figure out that the unresolved | |
| 607 // reference `p.C` uses the prefix `p`. | |
| 608 allowMissingFiles = true; | |
| 609 UnlinkedTypeRef typeRef = serializeTypeText('p.C', | |
| 610 otherDeclarations: 'import "foo.dart" as p;', allowErrors: true); | |
| 611 checkUnresolvedTypeRef(typeRef, 'p', 'C'); | |
| 612 } | |
| 613 | |
| 614 fail_type_reference_to_type_visible_via_multiple_import_prefixes() { | |
| 615 // TODO(paulberry): this test currently fails because the element model | |
| 616 // doesn't record enough information to track which prefix is used to refer | |
| 617 // to a type. | |
| 618 addNamedSource('/lib1.dart', 'class C'); | |
| 619 addNamedSource('/lib2.dart', 'export "lib1.dart";'); | |
| 620 addNamedSource('/lib3.dart', 'export "lib1.dart";'); | |
| 621 addNamedSource('/lib4.dart', 'export "lib1.dart";'); | |
| 622 serializeLibraryText(''' | |
| 623 import 'lib2.dart'; | |
| 624 import 'lib3.dart' as a; | |
| 625 import 'lib4.dart' as b; | |
| 626 C c2; | |
| 627 a.C c3; | |
| 628 b.C c4;'''); | |
| 629 // Note: it is important that each reference to class C records the prefix | |
| 630 // used to find it; otherwise it's possible that relinking might produce an | |
| 631 // incorrect result after a change to lib2.dart, lib3.dart, or lib4.dart. | |
| 632 checkTypeRef( | |
| 633 findVariable('c2').type, absUri('/lib1.dart'), 'lib1.dart', 'C'); | |
| 634 checkTypeRef( | |
| 635 findVariable('c3').type, absUri('/lib1.dart'), 'lib1.dart', 'C', | |
| 636 expectedPrefix: 'a'); | |
| 637 checkTypeRef( | |
| 638 findVariable('c4').type, absUri('/lib1.dart'), 'lib1.dart', 'C', | |
| 639 expectedPrefix: 'b'); | |
| 640 } | |
| 641 | |
| 642 /** | 601 /** |
| 643 * Find the class with the given [className] in the summary, and return its | 602 * Find the class with the given [className] in the summary, and return its |
| 644 * [UnlinkedClass] data structure. If [unit] is not given, the class is | 603 * [UnlinkedClass] data structure. If [unit] is not given, the class is |
| 645 * looked for in the defining compilation unit. | 604 * looked for in the defining compilation unit. |
| 646 */ | 605 */ |
| 647 UnlinkedClass findClass(String className, | 606 UnlinkedClass findClass(String className, |
| 648 {bool failIfAbsent: false, UnlinkedUnit unit}) { | 607 {bool failIfAbsent: false, UnlinkedUnit unit}) { |
| 649 unit ??= unlinkedUnits[0]; | 608 unit ??= unlinkedUnits[0]; |
| 650 UnlinkedClass result; | 609 UnlinkedClass result; |
| 651 for (UnlinkedClass cls in unit.classes) { | 610 for (UnlinkedClass cls in unit.classes) { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 if (result == null && failIfAbsent) { | 711 if (result == null && failIfAbsent) { |
| 753 fail('Variable $variableName not found in serialized output'); | 712 fail('Variable $variableName not found in serialized output'); |
| 754 } | 713 } |
| 755 return result; | 714 return result; |
| 756 } | 715 } |
| 757 | 716 |
| 758 /** | 717 /** |
| 759 * Serialize the given library [text] and return the summary of the class | 718 * Serialize the given library [text] and return the summary of the class |
| 760 * with the given [className]. | 719 * with the given [className]. |
| 761 */ | 720 */ |
| 762 UnlinkedClass serializeClassText(String text, [String className = 'C']) { | 721 UnlinkedClass serializeClassText(String text, |
| 763 serializeLibraryText(text); | 722 {String className: 'C', bool allowErrors: false}) { |
| 723 serializeLibraryText(text, allowErrors: allowErrors); |
| 764 return findClass(className, failIfAbsent: true); | 724 return findClass(className, failIfAbsent: true); |
| 765 } | 725 } |
| 766 | 726 |
| 767 /** | 727 /** |
| 768 * Serialize the given library [text] and return the summary of the enum with | 728 * Serialize the given library [text] and return the summary of the enum with |
| 769 * the given [enumName]. | 729 * the given [enumName]. |
| 770 */ | 730 */ |
| 771 UnlinkedEnum serializeEnumText(String text, [String enumName = 'E']) { | 731 UnlinkedEnum serializeEnumText(String text, [String enumName = 'E']) { |
| 772 serializeLibraryText(text); | 732 serializeLibraryText(text); |
| 773 return findEnum(enumName, failIfAbsent: true); | 733 return findEnum(enumName, failIfAbsent: true); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 | 773 |
| 814 /** | 774 /** |
| 815 * Serialize a type declaration using the given [text] as a type name, and | 775 * Serialize a type declaration using the given [text] as a type name, and |
| 816 * return a summary of the corresponding [UnlinkedTypeRef]. If the type | 776 * return a summary of the corresponding [UnlinkedTypeRef]. If the type |
| 817 * declaration needs to refer to types that are not available in core, those | 777 * declaration needs to refer to types that are not available in core, those |
| 818 * types may be declared in [otherDeclarations]. | 778 * types may be declared in [otherDeclarations]. |
| 819 */ | 779 */ |
| 820 UnlinkedTypeRef serializeTypeText(String text, | 780 UnlinkedTypeRef serializeTypeText(String text, |
| 821 {String otherDeclarations: '', bool allowErrors: false}) { | 781 {String otherDeclarations: '', bool allowErrors: false}) { |
| 822 return serializeVariableText('$otherDeclarations\n$text v;', | 782 return serializeVariableText('$otherDeclarations\n$text v;', |
| 823 allowErrors: allowErrors) | 783 allowErrors: allowErrors).type; |
| 824 .type; | |
| 825 } | 784 } |
| 826 | 785 |
| 827 /** | 786 /** |
| 828 * Serialize the given library [text] and return the summary of the variable | 787 * Serialize the given library [text] and return the summary of the variable |
| 829 * with the given [variableName]. | 788 * with the given [variableName]. |
| 830 */ | 789 */ |
| 831 UnlinkedVariable serializeVariableText(String text, | 790 UnlinkedVariable serializeVariableText(String text, |
| 832 {String variableName: 'v', bool allowErrors: false}) { | 791 {String variableName: 'v', bool allowErrors: false}) { |
| 833 serializeLibraryText(text, allowErrors: allowErrors); | 792 serializeLibraryText(text, allowErrors: allowErrors); |
| 834 return findVariable(variableName, failIfAbsent: true); | 793 return findVariable(variableName, failIfAbsent: true); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1028 class D { | 987 class D { |
| 1029 D.foo(); | 988 D.foo(); |
| 1030 D.bar(); | 989 D.bar(); |
| 1031 } | 990 } |
| 1032 class E {} | 991 class E {} |
| 1033 '''); | 992 '''); |
| 1034 expect(cls.executables, isEmpty); | 993 expect(cls.executables, isEmpty); |
| 1035 } | 994 } |
| 1036 | 995 |
| 1037 test_class_alias_private() { | 996 test_class_alias_private() { |
| 1038 serializeClassText('class _C = _D with _E; class _D {} class _E {}', '_C'); | 997 serializeClassText('class _C = _D with _E; class _D {} class _E {}', |
| 998 className: '_C'); |
| 1039 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); | 999 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); |
| 1040 } | 1000 } |
| 1041 | 1001 |
| 1042 test_class_alias_reference_generic() { | 1002 test_class_alias_reference_generic() { |
| 1043 UnlinkedTypeRef typeRef = serializeTypeText('C', | 1003 UnlinkedTypeRef typeRef = serializeTypeText('C', |
| 1044 otherDeclarations: 'class C<D, E> = F with G; class F {} class G {}'); | 1004 otherDeclarations: 'class C<D, E> = F with G; class F {} class G {}'); |
| 1045 checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2); | 1005 checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2); |
| 1046 } | 1006 } |
| 1047 | 1007 |
| 1048 test_class_alias_reference_generic_imported() { | 1008 test_class_alias_reference_generic_imported() { |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1172 UnlinkedClass cls = serializeClassText('class C {}'); | 1132 UnlinkedClass cls = serializeClassText('class C {}'); |
| 1173 expect(cls.typeParameters, isEmpty); | 1133 expect(cls.typeParameters, isEmpty); |
| 1174 } | 1134 } |
| 1175 | 1135 |
| 1176 test_class_non_alias_flag() { | 1136 test_class_non_alias_flag() { |
| 1177 UnlinkedClass cls = serializeClassText('class C {}'); | 1137 UnlinkedClass cls = serializeClassText('class C {}'); |
| 1178 expect(cls.isMixinApplication, false); | 1138 expect(cls.isMixinApplication, false); |
| 1179 } | 1139 } |
| 1180 | 1140 |
| 1181 test_class_private() { | 1141 test_class_private() { |
| 1182 serializeClassText('class _C {}', '_C'); | 1142 serializeClassText('class _C {}', className: '_C'); |
| 1183 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); | 1143 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); |
| 1184 } | 1144 } |
| 1185 | 1145 |
| 1186 test_class_reference_generic() { | 1146 test_class_reference_generic() { |
| 1187 UnlinkedTypeRef typeRef = | 1147 UnlinkedTypeRef typeRef = |
| 1188 serializeTypeText('C', otherDeclarations: 'class C<D, E> {}'); | 1148 serializeTypeText('C', otherDeclarations: 'class C<D, E> {}'); |
| 1189 checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2); | 1149 checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2); |
| 1190 } | 1150 } |
| 1191 | 1151 |
| 1192 test_class_reference_generic_imported() { | 1152 test_class_reference_generic_imported() { |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1898 expect(executable.isConst, false); | 1858 expect(executable.isConst, false); |
| 1899 expect(executable.isFactory, false); | 1859 expect(executable.isFactory, false); |
| 1900 expect(executable.isStatic, false); | 1860 expect(executable.isStatic, false); |
| 1901 expect(executable.parameters, hasLength(1)); | 1861 expect(executable.parameters, hasLength(1)); |
| 1902 checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'bool'); | 1862 checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'bool'); |
| 1903 expect(executable.typeParameters, isEmpty); | 1863 expect(executable.typeParameters, isEmpty); |
| 1904 } | 1864 } |
| 1905 | 1865 |
| 1906 test_executable_operator_index_set() { | 1866 test_executable_operator_index_set() { |
| 1907 UnlinkedExecutable executable = serializeClassText( | 1867 UnlinkedExecutable executable = serializeClassText( |
| 1908 'class C { void operator[]=(int i, bool v) => null; }') | 1868 'class C { void operator[]=(int i, bool v) => null; }').executables[0]; |
| 1909 .executables[0]; | |
| 1910 expect(executable.kind, UnlinkedExecutableKind.functionOrMethod); | 1869 expect(executable.kind, UnlinkedExecutableKind.functionOrMethod); |
| 1911 expect(executable.name, '[]='); | 1870 expect(executable.name, '[]='); |
| 1912 expect(executable.hasImplicitReturnType, false); | 1871 expect(executable.hasImplicitReturnType, false); |
| 1913 expect(executable.isAbstract, false); | 1872 expect(executable.isAbstract, false); |
| 1914 expect(executable.isConst, false); | 1873 expect(executable.isConst, false); |
| 1915 expect(executable.isFactory, false); | 1874 expect(executable.isFactory, false); |
| 1916 expect(executable.isStatic, false); | 1875 expect(executable.isStatic, false); |
| 1917 expect(executable.parameters, hasLength(2)); | 1876 expect(executable.parameters, hasLength(2)); |
| 1918 expect(executable.returnType, isNull); | 1877 expect(executable.returnType, isNull); |
| 1919 expect(executable.typeParameters, isEmpty); | 1878 expect(executable.typeParameters, isEmpty); |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2471 expect(unlinkedUnits[0].imports, hasLength(1)); | 2430 expect(unlinkedUnits[0].imports, hasLength(1)); |
| 2472 checkDependency(linked.importDependencies[0], 'dart:core', 'dart:core'); | 2431 checkDependency(linked.importDependencies[0], 'dart:core', 'dart:core'); |
| 2473 expect(unlinkedUnits[0].imports[0].uri, isEmpty); | 2432 expect(unlinkedUnits[0].imports[0].uri, isEmpty); |
| 2474 expect(unlinkedUnits[0].imports[0].uriOffset, 0); | 2433 expect(unlinkedUnits[0].imports[0].uriOffset, 0); |
| 2475 expect(unlinkedUnits[0].imports[0].uriEnd, 0); | 2434 expect(unlinkedUnits[0].imports[0].uriEnd, 0); |
| 2476 expect(unlinkedUnits[0].imports[0].prefixReference, 0); | 2435 expect(unlinkedUnits[0].imports[0].prefixReference, 0); |
| 2477 expect(unlinkedUnits[0].imports[0].combinators, isEmpty); | 2436 expect(unlinkedUnits[0].imports[0].combinators, isEmpty); |
| 2478 expect(unlinkedUnits[0].imports[0].isImplicit, isTrue); | 2437 expect(unlinkedUnits[0].imports[0].isImplicit, isTrue); |
| 2479 } | 2438 } |
| 2480 | 2439 |
| 2440 test_import_missing() { |
| 2441 if (!checkAstDerivedData) { |
| 2442 // TODO(paulberry): At the moment unresolved imports are not included in |
| 2443 // the element model, so we can't pass this test. |
| 2444 return; |
| 2445 } |
| 2446 // Unresolved imports are included since this is necessary for proper |
| 2447 // dependency tracking. |
| 2448 allowMissingFiles = true; |
| 2449 serializeLibraryText('import "foo.dart";', allowErrors: true); |
| 2450 // Second import is the implicit import of dart:core |
| 2451 expect(unlinkedUnits[0].imports, hasLength(2)); |
| 2452 checkDependency( |
| 2453 linked.importDependencies[0], absUri('/foo.dart'), 'foo.dart'); |
| 2454 } |
| 2455 |
| 2481 test_import_no_combinators() { | 2456 test_import_no_combinators() { |
| 2482 serializeLibraryText('import "dart:async"; Future x;'); | 2457 serializeLibraryText('import "dart:async"; Future x;'); |
| 2483 // Second import is the implicit import of dart:core | 2458 // Second import is the implicit import of dart:core |
| 2484 expect(unlinkedUnits[0].imports, hasLength(2)); | 2459 expect(unlinkedUnits[0].imports, hasLength(2)); |
| 2485 expect(unlinkedUnits[0].imports[0].combinators, isEmpty); | 2460 expect(unlinkedUnits[0].imports[0].combinators, isEmpty); |
| 2486 } | 2461 } |
| 2487 | 2462 |
| 2488 test_import_no_flags() { | 2463 test_import_no_flags() { |
| 2489 serializeLibraryText('import "dart:async"; Future x;'); | 2464 serializeLibraryText('import "dart:async"; Future x;'); |
| 2490 expect(unlinkedUnits[0].imports[0].isImplicit, isFalse); | 2465 expect(unlinkedUnits[0].imports[0].isImplicit, isFalse); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2643 | 2618 |
| 2644 test_import_uri() { | 2619 test_import_uri() { |
| 2645 String uriString = '"dart:async"'; | 2620 String uriString = '"dart:async"'; |
| 2646 String libraryText = 'import $uriString; Future x;'; | 2621 String libraryText = 'import $uriString; Future x;'; |
| 2647 serializeLibraryText(libraryText); | 2622 serializeLibraryText(libraryText); |
| 2648 // Second import is the implicit import of dart:core | 2623 // Second import is the implicit import of dart:core |
| 2649 expect(unlinkedUnits[0].imports, hasLength(2)); | 2624 expect(unlinkedUnits[0].imports, hasLength(2)); |
| 2650 expect(unlinkedUnits[0].imports[0].uri, 'dart:async'); | 2625 expect(unlinkedUnits[0].imports[0].uri, 'dart:async'); |
| 2651 } | 2626 } |
| 2652 | 2627 |
| 2628 test_invalid_prefix_dynamic() { |
| 2629 if (checkAstDerivedData) { |
| 2630 // TODO(paulberry): get this to work properly. |
| 2631 return; |
| 2632 } |
| 2633 checkUnresolvedTypeRef( |
| 2634 serializeTypeText('dynamic.T', allowErrors: true), 'dynamic', 'T'); |
| 2635 } |
| 2636 |
| 2637 test_invalid_prefix_type_parameter() { |
| 2638 if (checkAstDerivedData) { |
| 2639 // TODO(paulberry): get this to work properly. |
| 2640 return; |
| 2641 } |
| 2642 checkUnresolvedTypeRef( |
| 2643 serializeClassText('class C<T> { T.U x; }', allowErrors: true).fields[0] |
| 2644 .type, |
| 2645 'T', |
| 2646 'U'); |
| 2647 } |
| 2648 |
| 2649 test_invalid_prefix_void() { |
| 2650 if (checkAstDerivedData) { |
| 2651 // TODO(paulberry): get this to work properly. |
| 2652 return; |
| 2653 } |
| 2654 checkUnresolvedTypeRef( |
| 2655 serializeTypeText('void.T', allowErrors: true), 'void', 'T'); |
| 2656 } |
| 2657 |
| 2653 test_library_documented() { | 2658 test_library_documented() { |
| 2654 String text = ''' | 2659 String text = ''' |
| 2655 // Extra comment so doc comment offset != 0 | 2660 // Extra comment so doc comment offset != 0 |
| 2656 /** | 2661 /** |
| 2657 * Docs | 2662 * Docs |
| 2658 */ | 2663 */ |
| 2659 library foo;'''; | 2664 library foo;'''; |
| 2660 serializeLibraryText(text); | 2665 serializeLibraryText(text); |
| 2661 expect(unlinkedUnits[0].libraryDocumentationComment, isNotNull); | 2666 expect(unlinkedUnits[0].libraryDocumentationComment, isNotNull); |
| 2662 checkDocumentationComment( | 2667 checkDocumentationComment( |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2827 allowTypeParameters: true, numTypeParameters: 2); | 2832 allowTypeParameters: true, numTypeParameters: 2); |
| 2828 expect(typeRef.typeArguments, hasLength(2)); | 2833 expect(typeRef.typeArguments, hasLength(2)); |
| 2829 checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int'); | 2834 checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int'); |
| 2830 checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'Object'); | 2835 checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'Object'); |
| 2831 } | 2836 } |
| 2832 | 2837 |
| 2833 test_type_dynamic() { | 2838 test_type_dynamic() { |
| 2834 checkDynamicTypeRef(serializeTypeText('dynamic')); | 2839 checkDynamicTypeRef(serializeTypeText('dynamic')); |
| 2835 } | 2840 } |
| 2836 | 2841 |
| 2842 test_type_param_not_shadowed_by_constructor() { |
| 2843 UnlinkedClass cls = |
| 2844 serializeClassText('class C<D> { D x; C.D(); } class D {}'); |
| 2845 checkParamTypeRef(cls.fields[0].type, 1); |
| 2846 } |
| 2847 |
| 2848 test_type_param_not_shadowed_by_field_in_extends() { |
| 2849 UnlinkedClass cls = |
| 2850 serializeClassText('class C<T> extends D<T> { T x; } class D<T> {}'); |
| 2851 checkParamTypeRef(cls.supertype.typeArguments[0], 1); |
| 2852 } |
| 2853 |
| 2854 test_type_param_not_shadowed_by_field_in_implements() { |
| 2855 UnlinkedClass cls = |
| 2856 serializeClassText('class C<T> implements D<T> { T x; } class D<T> {}'); |
| 2857 checkParamTypeRef(cls.interfaces[0].typeArguments[0], 1); |
| 2858 } |
| 2859 |
| 2860 test_type_param_not_shadowed_by_field_in_with() { |
| 2861 UnlinkedClass cls = serializeClassText( |
| 2862 'class C<T> extends Object with D<T> { T x; } class D<T> {}'); |
| 2863 checkParamTypeRef(cls.mixins[0].typeArguments[0], 1); |
| 2864 } |
| 2865 |
| 2866 test_type_param_not_shadowed_by_method_parameter() { |
| 2867 UnlinkedClass cls = serializeClassText('class C<T> { f(int T, T x) {} }'); |
| 2868 checkParamTypeRef(cls.executables[0].parameters[1].type, 1); |
| 2869 } |
| 2870 |
| 2871 test_type_param_not_shadowed_by_setter() { |
| 2872 // The code under test should not produce a compile-time error, but it |
| 2873 // does. |
| 2874 bool workAroundBug25525 = true; |
| 2875 UnlinkedClass cls = serializeClassText( |
| 2876 'class C<D> { D x; void set D(value) {} } class D {}', |
| 2877 allowErrors: workAroundBug25525); |
| 2878 checkParamTypeRef(cls.fields[0].type, 1); |
| 2879 } |
| 2880 |
| 2881 test_type_param_not_shadowed_by_typedef_parameter() { |
| 2882 UnlinkedTypedef typedef = |
| 2883 serializeTypedefText('typedef void F<T>(int T, T x);'); |
| 2884 checkParamTypeRef(typedef.parameters[1].type, 1); |
| 2885 } |
| 2886 |
| 2887 test_type_param_shadowed_by_field() { |
| 2888 UnlinkedClass cls = serializeClassText( |
| 2889 'class C<D> { D x; int D; } class D {}', |
| 2890 allowErrors: true); |
| 2891 checkDynamicTypeRef(cls.fields[0].type); |
| 2892 } |
| 2893 |
| 2894 test_type_param_shadowed_by_getter() { |
| 2895 UnlinkedClass cls = serializeClassText( |
| 2896 'class C<D> { D x; int get D => null; } class D {}', |
| 2897 allowErrors: true); |
| 2898 checkDynamicTypeRef(cls.fields[0].type); |
| 2899 } |
| 2900 |
| 2901 test_type_param_shadowed_by_method() { |
| 2902 UnlinkedClass cls = serializeClassText( |
| 2903 'class C<D> { D x; void D() {} } class D {}', |
| 2904 allowErrors: true); |
| 2905 checkDynamicTypeRef(cls.fields[0].type); |
| 2906 } |
| 2907 |
| 2908 test_type_param_shadowed_by_type_param() { |
| 2909 UnlinkedClass cls = |
| 2910 serializeClassText('class C<T> { T f<T>(T x) => null; }'); |
| 2911 checkParamTypeRef(cls.executables[0].returnType, 1); |
| 2912 checkParamTypeRef(cls.executables[0].parameters[0].type, 1); |
| 2913 } |
| 2914 |
| 2837 test_type_reference_from_part() { | 2915 test_type_reference_from_part() { |
| 2838 addNamedSource('/a.dart', 'part of foo; C v;'); | 2916 addNamedSource('/a.dart', 'part of foo; C v;'); |
| 2839 serializeLibraryText('library foo; part "a.dart"; class C {}'); | 2917 serializeLibraryText('library foo; part "a.dart"; class C {}'); |
| 2840 checkTypeRef(findVariable('v', variables: unlinkedUnits[1].variables).type, | 2918 checkTypeRef(findVariable('v', variables: unlinkedUnits[1].variables).type, |
| 2841 null, null, 'C', | 2919 null, null, 'C', |
| 2842 expectedKind: ReferenceKind.classOrEnum, | 2920 expectedKind: ReferenceKind.classOrEnum, |
| 2843 linkedSourceUnit: linked.units[1], | 2921 linkedSourceUnit: linked.units[1], |
| 2844 unlinkedSourceUnit: unlinkedUnits[1]); | 2922 unlinkedSourceUnit: unlinkedUnits[1]); |
| 2845 } | 2923 } |
| 2846 | 2924 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2937 addNamedSource('/a.dart', 'part of my.lib; class C {}'); | 3015 addNamedSource('/a.dart', 'part of my.lib; class C {}'); |
| 2938 checkTypeRef( | 3016 checkTypeRef( |
| 2939 serializeTypeText('C', | 3017 serializeTypeText('C', |
| 2940 otherDeclarations: 'library my.lib; part "a.dart";'), | 3018 otherDeclarations: 'library my.lib; part "a.dart";'), |
| 2941 null, | 3019 null, |
| 2942 null, | 3020 null, |
| 2943 'C', | 3021 'C', |
| 2944 expectedTargetUnit: 1); | 3022 expectedTargetUnit: 1); |
| 2945 } | 3023 } |
| 2946 | 3024 |
| 3025 test_type_reference_to_nonexistent_file_via_prefix() { |
| 3026 if (!checkAstDerivedData) { |
| 3027 // TODO(paulberry): this test currently fails because there is not enough |
| 3028 // information in the element model to figure out that the unresolved |
| 3029 // reference `p.C` uses the prefix `p`. |
| 3030 return; |
| 3031 } |
| 3032 allowMissingFiles = true; |
| 3033 UnlinkedTypeRef typeRef = serializeTypeText('p.C', |
| 3034 otherDeclarations: 'import "foo.dart" as p;', allowErrors: true); |
| 3035 checkUnresolvedTypeRef(typeRef, 'p', 'C'); |
| 3036 } |
| 3037 |
| 2947 test_type_reference_to_part() { | 3038 test_type_reference_to_part() { |
| 2948 addNamedSource('/a.dart', 'part of foo; class C { C(); }'); | 3039 addNamedSource('/a.dart', 'part of foo; class C { C(); }'); |
| 2949 serializeLibraryText('library foo; part "a.dart"; C c;'); | 3040 serializeLibraryText('library foo; part "a.dart"; C c;'); |
| 2950 checkTypeRef(unlinkedUnits[0].variables.single.type, null, null, 'C', | 3041 checkTypeRef(unlinkedUnits[0].variables.single.type, null, null, 'C', |
| 2951 expectedKind: ReferenceKind.classOrEnum, expectedTargetUnit: 1); | 3042 expectedKind: ReferenceKind.classOrEnum, expectedTargetUnit: 1); |
| 2952 } | 3043 } |
| 2953 | 3044 |
| 3045 test_type_reference_to_type_visible_via_multiple_import_prefixes() { |
| 3046 if (!checkAstDerivedData) { |
| 3047 // TODO(paulberry): this test currently fails because the element model |
| 3048 // doesn't record enough information to track which prefix is used to |
| 3049 // refer to a type. |
| 3050 return; |
| 3051 } |
| 3052 addNamedSource('/lib1.dart', 'class C'); |
| 3053 addNamedSource('/lib2.dart', 'export "lib1.dart";'); |
| 3054 addNamedSource('/lib3.dart', 'export "lib1.dart";'); |
| 3055 addNamedSource('/lib4.dart', 'export "lib1.dart";'); |
| 3056 serializeLibraryText(''' |
| 3057 import 'lib2.dart'; |
| 3058 import 'lib3.dart' as a; |
| 3059 import 'lib4.dart' as b; |
| 3060 C c2; |
| 3061 a.C c3; |
| 3062 b.C c4;'''); |
| 3063 // Note: it is important that each reference to class C records the prefix |
| 3064 // used to find it; otherwise it's possible that relinking might produce an |
| 3065 // incorrect result after a change to lib2.dart, lib3.dart, or lib4.dart. |
| 3066 checkTypeRef( |
| 3067 findVariable('c2').type, absUri('/lib1.dart'), 'lib1.dart', 'C'); |
| 3068 checkTypeRef( |
| 3069 findVariable('c3').type, absUri('/lib1.dart'), 'lib1.dart', 'C', |
| 3070 expectedPrefix: 'a'); |
| 3071 checkTypeRef( |
| 3072 findVariable('c4').type, absUri('/lib1.dart'), 'lib1.dart', 'C', |
| 3073 expectedPrefix: 'b'); |
| 3074 } |
| 3075 |
| 2954 test_type_reference_to_typedef() { | 3076 test_type_reference_to_typedef() { |
| 2955 checkTypeRef(serializeTypeText('F', otherDeclarations: 'typedef void F();'), | 3077 checkTypeRef(serializeTypeText('F', otherDeclarations: 'typedef void F();'), |
| 2956 null, null, 'F', | 3078 null, null, 'F', |
| 2957 expectedKind: ReferenceKind.typedef); | 3079 expectedKind: ReferenceKind.typedef); |
| 2958 } | 3080 } |
| 2959 | 3081 |
| 2960 test_type_unit_counts_unreferenced_units() { | 3082 test_type_unit_counts_unreferenced_units() { |
| 2961 addNamedSource('/a.dart', 'library a; part "b.dart"; part "c.dart";'); | 3083 addNamedSource('/a.dart', 'library a; part "b.dart"; part "c.dart";'); |
| 2962 addNamedSource('/b.dart', 'part of a;'); | 3084 addNamedSource('/b.dart', 'part of a;'); |
| 2963 addNamedSource('/c.dart', 'part of a; class C {}'); | 3085 addNamedSource('/c.dart', 'part of a; class C {}'); |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3161 UnlinkedVariable variable = | 3283 UnlinkedVariable variable = |
| 3162 serializeVariableText('int i;', variableName: 'i'); | 3284 serializeVariableText('int i;', variableName: 'i'); |
| 3163 checkTypeRef(variable.type, 'dart:core', 'dart:core', 'int'); | 3285 checkTypeRef(variable.type, 'dart:core', 'dart:core', 'int'); |
| 3164 } | 3286 } |
| 3165 | 3287 |
| 3166 test_varible_private() { | 3288 test_varible_private() { |
| 3167 serializeVariableText('int _i;', variableName: '_i'); | 3289 serializeVariableText('int _i;', variableName: '_i'); |
| 3168 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); | 3290 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); |
| 3169 } | 3291 } |
| 3170 } | 3292 } |
| 3293 |
| 3294 /** |
| 3295 * Override of [SummaryTest] which creates unlinked summaries directly from the |
| 3296 * AST. |
| 3297 */ |
| 3298 @reflectiveTest |
| 3299 class UnlinkedSummarizeAstTest extends Object with SummaryTest { |
| 3300 @override |
| 3301 LinkedLibrary linked; |
| 3302 |
| 3303 @override |
| 3304 List<UnlinkedUnit> unlinkedUnits; |
| 3305 |
| 3306 /** |
| 3307 * Map from absolute URI to the [UnlinkedUnit] for each compilation unit |
| 3308 * passed to [addNamedSource]. |
| 3309 */ |
| 3310 Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{}; |
| 3311 |
| 3312 @override |
| 3313 bool get checkAstDerivedData => true; |
| 3314 |
| 3315 @override |
| 3316 bool get expectAbsoluteUrisInDependencies => false; |
| 3317 |
| 3318 @override |
| 3319 addNamedSource(String filePath, String contents) { |
| 3320 CompilationUnit unit = _parseText(contents); |
| 3321 UnlinkedUnit unlinkedUnit = |
| 3322 new UnlinkedUnit.fromBuffer(serializeAstUnlinked(unit).toBuffer()); |
| 3323 uriToUnit[absUri(filePath)] = unlinkedUnit; |
| 3324 } |
| 3325 |
| 3326 @override |
| 3327 void serializeLibraryText(String text, {bool allowErrors: false}) { |
| 3328 Uri testDartUri = Uri.parse(absUri('/test.dart')); |
| 3329 String resolveToAbsoluteUri(String relativeUri) => |
| 3330 testDartUri.resolve(relativeUri).toString(); |
| 3331 CompilationUnit unit = _parseText(text); |
| 3332 UnlinkedUnit definingUnit = |
| 3333 new UnlinkedUnit.fromBuffer(serializeAstUnlinked(unit).toBuffer()); |
| 3334 UnlinkedUnit getPart(String relativeUri) { |
| 3335 String absoluteUri = resolveToAbsoluteUri(relativeUri); |
| 3336 UnlinkedUnit unit = uriToUnit[absoluteUri]; |
| 3337 if (unit == null && !allowMissingFiles) { |
| 3338 fail('Prelinker unexpectedly requested unit for "$relativeUri"' |
| 3339 ' (resolves to "$absoluteUri").'); |
| 3340 } |
| 3341 return unit; |
| 3342 } |
| 3343 UnlinkedPublicNamespace getImport(String relativeUri) { |
| 3344 String absoluteUri = resolveToAbsoluteUri(relativeUri); |
| 3345 UnlinkedPublicNamespace namespace = sdkPublicNamespace[absoluteUri]; |
| 3346 if (namespace == null) { |
| 3347 namespace = uriToUnit[absoluteUri]?.publicNamespace; |
| 3348 } |
| 3349 if (namespace == null && !allowMissingFiles) { |
| 3350 fail('Prelinker unexpectedly requested namespace for "$relativeUri"' |
| 3351 ' (resolves to "$absoluteUri").' |
| 3352 ' Namespaces available: ${uriToUnit.keys}'); |
| 3353 } |
| 3354 return namespace; |
| 3355 } |
| 3356 linked = new LinkedLibrary.fromBuffer( |
| 3357 prelink(definingUnit, getPart, getImport).toBuffer()); |
| 3358 unlinkedUnits = <UnlinkedUnit>[definingUnit]; |
| 3359 for (String relativeUri in definingUnit.publicNamespace.parts) { |
| 3360 UnlinkedUnit unit = uriToUnit[resolveToAbsoluteUri(relativeUri)]; |
| 3361 if (unit == null) { |
| 3362 if (!allowMissingFiles) { |
| 3363 fail('Test referred to unknown unit $relativeUri'); |
| 3364 } |
| 3365 } else { |
| 3366 unlinkedUnits.add(unit); |
| 3367 } |
| 3368 } |
| 3369 } |
| 3370 |
| 3371 CompilationUnit _parseText(String text) { |
| 3372 CharSequenceReader reader = new CharSequenceReader(text); |
| 3373 Scanner scanner = |
| 3374 new Scanner(null, reader, AnalysisErrorListener.NULL_LISTENER); |
| 3375 Token token = scanner.tokenize(); |
| 3376 Parser parser = new Parser(null, AnalysisErrorListener.NULL_LISTENER); |
| 3377 parser.parseGenericMethods = true; |
| 3378 return parser.parseCompilationUnit(token); |
| 3379 } |
| 3380 } |
| OLD | NEW |