Chromium Code Reviews| 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 summary_resynthesizer; | 5 library summary_resynthesizer; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 265 return true; | 265 return true; |
| 266 } | 266 } |
| 267 return hasLibrarySummary(uri); | 267 return hasLibrarySummary(uri); |
| 268 } | 268 } |
| 269 } | 269 } |
| 270 | 270 |
| 271 /** | 271 /** |
| 272 * Builder of [Expression]s from [UnlinkedConst]s. | 272 * Builder of [Expression]s from [UnlinkedConst]s. |
| 273 */ | 273 */ |
| 274 class _ConstExprBuilder { | 274 class _ConstExprBuilder { |
| 275 final _LibraryResynthesizer resynthesizer; | 275 final _UnitResynthesizer resynthesizer; |
| 276 final UnlinkedConst uc; | 276 final UnlinkedConst uc; |
| 277 | 277 |
| 278 int intPtr = 0; | 278 int intPtr = 0; |
| 279 int doublePtr = 0; | 279 int doublePtr = 0; |
| 280 int stringPtr = 0; | 280 int stringPtr = 0; |
| 281 int refPtr = 0; | 281 int refPtr = 0; |
| 282 final List<Expression> stack = <Expression>[]; | 282 final List<Expression> stack = <Expression>[]; |
| 283 | 283 |
| 284 _ConstExprBuilder(this.resynthesizer, this.uc); | 284 _ConstExprBuilder(this.resynthesizer, this.uc); |
| 285 | 285 |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 638 List<Expression> _removeTopItems(int count) { | 638 List<Expression> _removeTopItems(int count) { |
| 639 int start = stack.length - count; | 639 int start = stack.length - count; |
| 640 int end = stack.length; | 640 int end = stack.length; |
| 641 List<Expression> items = stack.getRange(start, end).toList(); | 641 List<Expression> items = stack.getRange(start, end).toList(); |
| 642 stack.removeRange(start, end); | 642 stack.removeRange(start, end); |
| 643 return items; | 643 return items; |
| 644 } | 644 } |
| 645 } | 645 } |
| 646 | 646 |
| 647 /** | 647 /** |
| 648 * The class element that has been resynthesized from a summary. The actual | |
|
Paul Berry
2016/03/24 19:40:14
s/The class element/A class element/
| |
| 649 * element won't be constructed until it is requested. But properties | |
| 650 * [context], [displayName], [enclosingElement] and [name] can be used without | |
| 651 * creating the actual element. This allows to put these elements into | |
| 652 * namespaces without creating actual elements until they are really needed. | |
| 653 */ | |
| 654 class _DeferredClassElement extends ClassElementHandle { | |
| 655 final _UnitResynthesizer unitResynthesizer; | |
| 656 final CompilationUnitElement unitElement; | |
| 657 final UnlinkedClass serializedClass; | |
| 658 | |
| 659 ClassElementImpl _actualElement; | |
| 660 | |
| 661 @override | |
| 662 final String name; | |
| 663 | |
| 664 factory _DeferredClassElement(_UnitResynthesizer unitResynthesizer, | |
| 665 CompilationUnitElement unitElement, UnlinkedClass serializedClass) { | |
| 666 String name = serializedClass.name; | |
| 667 List<String> components = | |
| 668 unitResynthesizer.unit.location.components.toList(); | |
| 669 components.add(name); | |
| 670 ElementLocationImpl location = new ElementLocationImpl.con3(components); | |
| 671 return new _DeferredClassElement._( | |
| 672 unitResynthesizer, unitElement, serializedClass, name, location); | |
| 673 } | |
| 674 | |
| 675 _DeferredClassElement._(this.unitResynthesizer, this.unitElement, | |
| 676 this.serializedClass, this.name, ElementLocation location) | |
| 677 : super(null, location); | |
| 678 | |
| 679 @override | |
| 680 ClassElementImpl get actualElement { | |
| 681 if (_actualElement == null) { | |
| 682 _actualElement = unitResynthesizer.buildClassImpl(serializedClass); | |
| 683 _actualElement.enclosingElement = unitElement; | |
| 684 } | |
| 685 return _actualElement; | |
| 686 } | |
| 687 | |
| 688 @override | |
| 689 AnalysisContext get context => unitElement.context; | |
| 690 | |
| 691 @override | |
| 692 String get displayName => name; | |
| 693 | |
| 694 @override | |
| 695 CompilationUnitElement get enclosingElement { | |
| 696 return unitElement; | |
| 697 } | |
| 698 } | |
| 699 | |
| 700 /** | |
| 648 * The constructor element that has been resynthesized from a summary. The | 701 * The constructor element that has been resynthesized from a summary. The |
| 649 * actual element won't be constructed until it is requested. But properties | 702 * actual element won't be constructed until it is requested. But properties |
| 650 * [displayName], [enclosingElement] and [name] can be used without creating | 703 * [displayName], [enclosingElement] and [name] can be used without creating |
| 651 * the actual element. | 704 * the actual element. |
| 652 */ | 705 */ |
| 653 class _DeferredConstructorElement extends ConstructorElementHandle { | 706 class _DeferredConstructorElement extends ConstructorElementHandle { |
| 654 /** | 707 /** |
| 655 * The type defining this constructor element. If [_isMember] is `false`, | 708 * The type defining this constructor element. If [_isMember] is `false`, |
| 656 * then the type parameters of [_definingType] are not guaranteed to be | 709 * then the type parameters of [_definingType] are not guaranteed to be |
| 657 * valid. | 710 * valid. |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 683 @override | 736 @override |
| 684 String get displayName => name; | 737 String get displayName => name; |
| 685 | 738 |
| 686 @override | 739 @override |
| 687 ClassElement get enclosingElement { | 740 ClassElement get enclosingElement { |
| 688 return _definingType.element; | 741 return _definingType.element; |
| 689 } | 742 } |
| 690 } | 743 } |
| 691 | 744 |
| 692 /** | 745 /** |
| 693 * Local function element representing the intializer for a variable that has | 746 * Local function element representing the initializer for a variable that has |
| 694 * been resynthesized from a summary. The actual element won't be constructed | 747 * been resynthesized from a summary. The actual element won't be constructed |
| 695 * until it is requested. But properties [context] and [enclosingElement] can | 748 * until it is requested. But properties [context] and [enclosingElement] can |
| 696 * be used without creating the actual element. | 749 * be used without creating the actual element. |
| 697 */ | 750 */ |
| 698 class _DeferredInitializerElement extends FunctionElementHandle { | 751 class _DeferredInitializerElement extends FunctionElementHandle { |
| 699 /** | 752 /** |
| 700 * The variable element containing this element. | 753 * The variable element containing this element. |
| 701 */ | 754 */ |
| 702 @override | 755 @override |
| 703 final VariableElement enclosingElement; | 756 final VariableElement enclosingElement; |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 815 */ | 868 */ |
| 816 bool isCoreLibrary; | 869 bool isCoreLibrary; |
| 817 | 870 |
| 818 /** | 871 /** |
| 819 * Classes which should have their supertype set to "object" once | 872 * Classes which should have their supertype set to "object" once |
| 820 * resynthesis is complete. Only used if [isCoreLibrary] is `true`. | 873 * resynthesis is complete. Only used if [isCoreLibrary] is `true`. |
| 821 */ | 874 */ |
| 822 List<ClassElementImpl> delayedObjectSubclasses = <ClassElementImpl>[]; | 875 List<ClassElementImpl> delayedObjectSubclasses = <ClassElementImpl>[]; |
| 823 | 876 |
| 824 /** | 877 /** |
| 878 * Map of compilation unit elements that have been resynthesized so far. The | |
| 879 * key is the URI of the compilation unit. | |
| 880 */ | |
| 881 final Map<String, CompilationUnitElement> resynthesizedUnits = | |
| 882 <String, CompilationUnitElement>{}; | |
| 883 | |
| 884 /** | |
| 885 * Map of top level elements that have been resynthesized so far. The first | |
| 886 * key is the URI of the compilation unit; the second is the name of the top | |
| 887 * level element. | |
| 888 */ | |
| 889 final Map<String, Map<String, Element>> resynthesizedElements = | |
| 890 <String, Map<String, Element>>{}; | |
| 891 | |
| 892 _LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary, | |
| 893 this.unlinkedUnits, this.librarySource) { | |
| 894 isCoreLibrary = librarySource.uri.toString() == 'dart:core'; | |
| 895 } | |
| 896 | |
| 897 /** | |
| 898 * Resynthesize a [NamespaceCombinator]. | |
| 899 */ | |
| 900 NamespaceCombinator buildCombinator(UnlinkedCombinator serializedCombinator) { | |
| 901 if (serializedCombinator.shows.isNotEmpty) { | |
| 902 ShowElementCombinatorImpl combinator = new ShowElementCombinatorImpl(); | |
| 903 // Note: we call toList() so that we don't retain a reference to the | |
| 904 // deserialized data structure. | |
| 905 combinator.shownNames = serializedCombinator.shows.toList(); | |
| 906 combinator.offset = serializedCombinator.offset; | |
| 907 combinator.end = serializedCombinator.end; | |
| 908 return combinator; | |
| 909 } else { | |
| 910 HideElementCombinatorImpl combinator = new HideElementCombinatorImpl(); | |
| 911 // Note: we call toList() so that we don't retain a reference to the | |
| 912 // deserialized data structure. | |
| 913 combinator.hiddenNames = serializedCombinator.hides.toList(); | |
| 914 return combinator; | |
| 915 } | |
| 916 } | |
| 917 | |
| 918 /** | |
| 919 * Resynthesize an [ExportElement], | |
| 920 */ | |
| 921 ExportElement buildExport( | |
| 922 _UnitResynthesizer definingUnitResynthesizer, | |
| 923 UnlinkedExportPublic serializedExportPublic, | |
| 924 UnlinkedExportNonPublic serializedExportNonPublic) { | |
| 925 ExportElementImpl exportElement = | |
| 926 new ExportElementImpl(serializedExportNonPublic.offset); | |
| 927 String exportedLibraryUri = summaryResynthesizer.sourceFactory | |
| 928 .resolveUri(librarySource, serializedExportPublic.uri) | |
| 929 .uri | |
| 930 .toString(); | |
| 931 exportElement.exportedLibrary = new LibraryElementHandle( | |
| 932 summaryResynthesizer, | |
| 933 new ElementLocationImpl.con3(<String>[exportedLibraryUri])); | |
| 934 exportElement.uri = serializedExportPublic.uri; | |
| 935 exportElement.combinators = | |
| 936 serializedExportPublic.combinators.map(buildCombinator).toList(); | |
| 937 exportElement.uriOffset = serializedExportNonPublic.uriOffset; | |
| 938 exportElement.uriEnd = serializedExportNonPublic.uriEnd; | |
| 939 definingUnitResynthesizer.buildAnnotations( | |
| 940 exportElement, serializedExportNonPublic.annotations); | |
| 941 return exportElement; | |
| 942 } | |
| 943 | |
| 944 /** | |
| 945 * Build an [ElementHandle] referring to the entity referred to by the given | |
| 946 * [exportName]. | |
| 947 */ | |
| 948 ElementHandle buildExportName(LinkedExportName exportName) { | |
| 949 String name = exportName.name; | |
| 950 if (exportName.kind == ReferenceKind.topLevelPropertyAccessor && | |
| 951 !name.endsWith('=')) { | |
| 952 name += '?'; | |
| 953 } | |
| 954 ElementLocationImpl location = new ElementLocationImpl.con3( | |
| 955 getReferencedLocationComponents( | |
| 956 exportName.dependency, exportName.unit, name)); | |
| 957 switch (exportName.kind) { | |
| 958 case ReferenceKind.classOrEnum: | |
| 959 return new ClassElementHandle(summaryResynthesizer, location); | |
| 960 case ReferenceKind.typedef: | |
| 961 return new FunctionTypeAliasElementHandle( | |
| 962 summaryResynthesizer, location); | |
| 963 case ReferenceKind.topLevelFunction: | |
| 964 return new FunctionElementHandle(summaryResynthesizer, location); | |
| 965 case ReferenceKind.topLevelPropertyAccessor: | |
| 966 return new PropertyAccessorElementHandle( | |
| 967 summaryResynthesizer, location); | |
| 968 case ReferenceKind.constructor: | |
| 969 case ReferenceKind.function: | |
| 970 case ReferenceKind.propertyAccessor: | |
| 971 case ReferenceKind.method: | |
| 972 case ReferenceKind.length: | |
| 973 case ReferenceKind.prefix: | |
| 974 case ReferenceKind.unresolved: | |
| 975 case ReferenceKind.variable: | |
| 976 // Should never happen. Exported names never refer to import prefixes, | |
| 977 // and they always refer to defined top-level entities. | |
| 978 throw new StateError('Unexpected export name kind: ${exportName.kind}'); | |
| 979 } | |
| 980 } | |
| 981 | |
| 982 /** | |
| 983 * Build the export namespace for the library by aggregating together its | |
| 984 * [publicNamespace] and [exportNames]. | |
| 985 */ | |
| 986 Namespace buildExportNamespace( | |
| 987 Namespace publicNamespace, List<LinkedExportName> exportNames) { | |
| 988 HashMap<String, Element> definedNames = new HashMap<String, Element>(); | |
| 989 // Start by populating all the public names from [publicNamespace]. | |
| 990 publicNamespace.definedNames.forEach((String name, Element element) { | |
| 991 definedNames[name] = element; | |
| 992 }); | |
| 993 // Add all the names from [exportNames]. | |
| 994 for (LinkedExportName exportName in exportNames) { | |
| 995 definedNames.putIfAbsent( | |
| 996 exportName.name, () => buildExportName(exportName)); | |
| 997 } | |
| 998 return new Namespace(definedNames); | |
| 999 } | |
| 1000 | |
| 1001 /** | |
| 1002 * Resynthesize an [ImportElement]. | |
| 1003 */ | |
| 1004 ImportElement buildImport(_UnitResynthesizer definingUnitResynthesizer, | |
| 1005 UnlinkedImport serializedImport, int dependency) { | |
| 1006 bool isSynthetic = serializedImport.isImplicit; | |
| 1007 ImportElementImpl importElement = | |
| 1008 new ImportElementImpl(isSynthetic ? -1 : serializedImport.offset); | |
| 1009 String absoluteUri = summaryResynthesizer.sourceFactory | |
| 1010 .resolveUri(librarySource, linkedLibrary.dependencies[dependency].uri) | |
| 1011 .uri | |
| 1012 .toString(); | |
| 1013 importElement.importedLibrary = new LibraryElementHandle( | |
| 1014 summaryResynthesizer, | |
| 1015 new ElementLocationImpl.con3(<String>[absoluteUri])); | |
| 1016 if (isSynthetic) { | |
| 1017 importElement.synthetic = true; | |
| 1018 } else { | |
| 1019 importElement.uri = serializedImport.uri; | |
| 1020 importElement.uriOffset = serializedImport.uriOffset; | |
| 1021 importElement.uriEnd = serializedImport.uriEnd; | |
| 1022 importElement.deferred = serializedImport.isDeferred; | |
| 1023 definingUnitResynthesizer.buildAnnotations( | |
| 1024 importElement, serializedImport.annotations); | |
| 1025 } | |
| 1026 importElement.prefixOffset = serializedImport.prefixOffset; | |
| 1027 if (serializedImport.prefixReference != 0) { | |
| 1028 UnlinkedReference serializedPrefix = | |
| 1029 unlinkedUnits[0].references[serializedImport.prefixReference]; | |
| 1030 importElement.prefix = new PrefixElementImpl( | |
| 1031 serializedPrefix.name, serializedImport.prefixOffset); | |
| 1032 } | |
| 1033 importElement.combinators = | |
| 1034 serializedImport.combinators.map(buildCombinator).toList(); | |
| 1035 return importElement; | |
| 1036 } | |
| 1037 | |
| 1038 /** | |
| 1039 * Main entry point. Resynthesize the [LibraryElement] and return it. | |
| 1040 */ | |
| 1041 LibraryElement buildLibrary() { | |
| 1042 CompilationUnitElementImpl definingUnit = | |
| 1043 new CompilationUnitElementImpl(librarySource.shortName); | |
| 1044 _UnitResynthesizer definingUnitResynthesizer = | |
| 1045 createUnitResynthesizer(definingUnit, 0); | |
| 1046 // Create LibraryElementImpl. | |
| 1047 bool hasName = unlinkedUnits[0].libraryName.isNotEmpty; | |
| 1048 LibraryElementImpl library = new LibraryElementImpl( | |
| 1049 summaryResynthesizer.context, | |
| 1050 unlinkedUnits[0].libraryName, | |
| 1051 hasName ? unlinkedUnits[0].libraryNameOffset : -1, | |
| 1052 unlinkedUnits[0].libraryNameLength); | |
| 1053 definingUnitResynthesizer.buildDocumentation( | |
| 1054 library, unlinkedUnits[0].libraryDocumentationComment); | |
| 1055 definingUnitResynthesizer.buildAnnotations( | |
| 1056 library, unlinkedUnits[0].libraryAnnotations); | |
| 1057 library.definingCompilationUnit = definingUnit; | |
| 1058 definingUnit.source = librarySource; | |
| 1059 definingUnit.librarySource = librarySource; | |
| 1060 // Create parts. | |
| 1061 List<CompilationUnitElement> partUnits = <CompilationUnitElement>[]; | |
| 1062 UnlinkedUnit unlinkedDefiningUnit = unlinkedUnits[0]; | |
| 1063 assert(unlinkedDefiningUnit.publicNamespace.parts.length + 1 == | |
| 1064 linkedLibrary.units.length); | |
| 1065 for (int i = 1; i < linkedLibrary.units.length; i++) { | |
| 1066 CompilationUnitElementImpl part = buildPart( | |
| 1067 definingUnitResynthesizer, | |
| 1068 unlinkedDefiningUnit.publicNamespace.parts[i - 1], | |
| 1069 unlinkedDefiningUnit.parts[i - 1], | |
| 1070 i); | |
| 1071 partUnits.add(part); | |
| 1072 } | |
| 1073 library.parts = partUnits; | |
| 1074 // Create imports. | |
| 1075 List<ImportElement> imports = <ImportElement>[]; | |
| 1076 for (int i = 0; i < unlinkedDefiningUnit.imports.length; i++) { | |
| 1077 imports.add(buildImport( | |
| 1078 definingUnitResynthesizer, | |
| 1079 unlinkedDefiningUnit.imports[i], | |
| 1080 linkedLibrary.importDependencies[i])); | |
| 1081 } | |
| 1082 library.imports = imports; | |
| 1083 // Create exports. | |
| 1084 List<ExportElement> exports = <ExportElement>[]; | |
| 1085 assert(unlinkedDefiningUnit.exports.length == | |
| 1086 unlinkedDefiningUnit.publicNamespace.exports.length); | |
| 1087 for (int i = 0; i < unlinkedDefiningUnit.exports.length; i++) { | |
| 1088 exports.add(buildExport( | |
| 1089 definingUnitResynthesizer, | |
| 1090 unlinkedDefiningUnit.publicNamespace.exports[i], | |
| 1091 unlinkedDefiningUnit.exports[i])); | |
| 1092 } | |
| 1093 library.exports = exports; | |
| 1094 // Populate units. | |
| 1095 populateUnit(definingUnitResynthesizer); | |
| 1096 for (int i = 0; i < partUnits.length; i++) { | |
| 1097 _UnitResynthesizer partResynthesizer = | |
| 1098 createUnitResynthesizer(partUnits[i], i + 1); | |
| 1099 populateUnit(partResynthesizer); | |
| 1100 } | |
| 1101 BuildLibraryElementUtils.patchTopLevelAccessors(library); | |
| 1102 // Update delayed Object class references. | |
| 1103 if (isCoreLibrary) { | |
| 1104 ClassElement objectElement = library.getType('Object'); | |
| 1105 assert(objectElement != null); | |
| 1106 for (ClassElementImpl classElement in delayedObjectSubclasses) { | |
| 1107 classElement.supertype = objectElement.type; | |
| 1108 } | |
| 1109 } | |
| 1110 // Compute namespaces. | |
| 1111 library.publicNamespace = | |
| 1112 new NamespaceBuilder().createPublicNamespaceForLibrary(library); | |
| 1113 library.exportNamespace = buildExportNamespace( | |
| 1114 library.publicNamespace, linkedLibrary.exportNames); | |
| 1115 // Find the entry point. Note: we can't use element.isEntryPoint because | |
| 1116 // that will trigger resynthesis of exported libraries. | |
| 1117 Element entryPoint = | |
| 1118 library.exportNamespace.get(FunctionElement.MAIN_FUNCTION_NAME); | |
| 1119 if (entryPoint is FunctionElement) { | |
| 1120 library.entryPoint = entryPoint; | |
| 1121 } | |
| 1122 // Create the synthetic element for `loadLibrary`. | |
| 1123 // Until the client received dart:core and dart:async, we cannot do this, | |
| 1124 // because the TypeProvider is not fully initialized. So, it is up to the | |
| 1125 // Dart SDK client to initialize TypeProvider and finish the dart:core and | |
| 1126 // dart:async libraries creation. | |
| 1127 if (library.name != 'dart.core' && library.name != 'dart.async') { | |
| 1128 library.createLoadLibraryFunction(summaryResynthesizer.typeProvider); | |
| 1129 } | |
| 1130 // Done. | |
| 1131 return library; | |
| 1132 } | |
| 1133 | |
| 1134 /** | |
| 1135 * Create, but do not populate, the [CompilationUnitElement] for a part other | |
| 1136 * than the defining compilation unit. | |
| 1137 */ | |
| 1138 CompilationUnitElementImpl buildPart( | |
| 1139 _UnitResynthesizer definingUnitResynthesizer, | |
| 1140 String uri, | |
| 1141 UnlinkedPart partDecl, | |
| 1142 int unitNum) { | |
| 1143 Source unitSource = | |
| 1144 summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri); | |
| 1145 CompilationUnitElementImpl partUnit = | |
| 1146 new CompilationUnitElementImpl(unitSource.shortName); | |
| 1147 partUnit.uriOffset = partDecl.uriOffset; | |
| 1148 partUnit.uriEnd = partDecl.uriEnd; | |
| 1149 partUnit.source = unitSource; | |
| 1150 partUnit.librarySource = librarySource; | |
| 1151 partUnit.uri = uri; | |
| 1152 definingUnitResynthesizer.buildAnnotations(partUnit, partDecl.annotations); | |
| 1153 return partUnit; | |
| 1154 } | |
| 1155 | |
| 1156 /** | |
| 1157 * Set up data structures for deserializing a compilation unit. | |
| 1158 */ | |
| 1159 _UnitResynthesizer createUnitResynthesizer( | |
| 1160 CompilationUnitElementImpl unit, int unitNum) { | |
| 1161 LinkedUnit linkedUnit = linkedLibrary.units[unitNum]; | |
| 1162 UnlinkedUnit unlinkedUnit = unlinkedUnits[unitNum]; | |
| 1163 return new _UnitResynthesizer(this, unlinkedUnit, linkedUnit, unit); | |
| 1164 } | |
| 1165 | |
| 1166 /** | |
| 1167 * Build the components of an [ElementLocationImpl] for the entity in the | |
| 1168 * given [unit] of the dependency located at [dependencyIndex], and having | |
| 1169 * the given [name]. | |
| 1170 */ | |
| 1171 List<String> getReferencedLocationComponents( | |
| 1172 int dependencyIndex, int unit, String name) { | |
| 1173 if (dependencyIndex == 0) { | |
| 1174 String referencedLibraryUri = librarySource.uri.toString(); | |
| 1175 String partUri; | |
| 1176 if (unit != 0) { | |
| 1177 String uri = unlinkedUnits[0].publicNamespace.parts[unit - 1]; | |
| 1178 Source partSource = | |
| 1179 summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri); | |
| 1180 partUri = partSource.uri.toString(); | |
| 1181 } else { | |
| 1182 partUri = referencedLibraryUri; | |
| 1183 } | |
| 1184 return <String>[referencedLibraryUri, partUri, name]; | |
| 1185 } | |
| 1186 LinkedDependency dependency = linkedLibrary.dependencies[dependencyIndex]; | |
| 1187 Source referencedLibrarySource = summaryResynthesizer.sourceFactory | |
| 1188 .resolveUri(librarySource, dependency.uri); | |
| 1189 String referencedLibraryUri = referencedLibrarySource.uri.toString(); | |
| 1190 String partUri; | |
| 1191 if (unit != 0) { | |
| 1192 String uri = dependency.parts[unit - 1]; | |
| 1193 Source partSource = summaryResynthesizer.sourceFactory | |
| 1194 .resolveUri(referencedLibrarySource, uri); | |
| 1195 partUri = partSource.uri.toString(); | |
| 1196 } else { | |
| 1197 partUri = referencedLibraryUri; | |
| 1198 } | |
| 1199 return <String>[referencedLibraryUri, partUri, name]; | |
| 1200 } | |
| 1201 | |
| 1202 /** | |
| 1203 * Populate a [CompilationUnitElement] by deserializing all the elements | |
| 1204 * contained in it. | |
| 1205 */ | |
| 1206 void populateUnit(_UnitResynthesizer unitResynthesized) { | |
| 1207 // TODO(scheglov) | |
| 1208 unitResynthesized.populateUnit(); | |
| 1209 String absoluteUri = unitResynthesized.unit.source.uri.toString(); | |
| 1210 resynthesizedUnits[absoluteUri] = unitResynthesized.unit; | |
| 1211 resynthesizedElements[absoluteUri] = unitResynthesized.elementMap; | |
| 1212 } | |
| 1213 } | |
| 1214 | |
| 1215 /** | |
| 1216 * Data structure used during resynthesis to record all the information that is | |
| 1217 * known about how to resynthesize a single entry in [LinkedUnit.references] | |
| 1218 * (and its associated entry in [UnlinkedUnit.references], if it exists). | |
| 1219 */ | |
| 1220 class _ReferenceInfo { | |
| 1221 /** | |
| 1222 * The enclosing [_ReferenceInfo], or `null` for top-level elements. | |
| 1223 */ | |
| 1224 final _ReferenceInfo enclosing; | |
| 1225 | |
| 1226 /** | |
| 1227 * The name of the entity referred to by this reference. | |
| 1228 */ | |
| 1229 final String name; | |
| 1230 | |
| 1231 /** | |
| 1232 * The element referred to by this reference, or `null` if there is no | |
| 1233 * associated element (e.g. because it is a reference to an undefined | |
| 1234 * entity). | |
| 1235 */ | |
| 1236 final Element element; | |
| 1237 | |
| 1238 /** | |
| 1239 * If this reference refers to a non-generic type, the type it refers to. | |
| 1240 * Otherwise `null`. | |
| 1241 */ | |
| 1242 DartType type; | |
| 1243 | |
| 1244 /** | |
| 1245 * The number of type parameters accepted by the entity referred to by this | |
| 1246 * reference, or zero if it doesn't accept any type parameters. | |
| 1247 */ | |
| 1248 final int numTypeParameters; | |
| 1249 | |
| 1250 /** | |
| 1251 * Create a new [_ReferenceInfo] object referring to an element called [name] | |
| 1252 * via the element handle [element], and having [numTypeParameters] type | |
| 1253 * parameters. | |
| 1254 * | |
| 1255 * For the special types `dynamic` and `void`, [specialType] should point to | |
| 1256 * the type itself. Otherwise, pass `null` and the type will be computed | |
| 1257 * when appropriate. | |
| 1258 */ | |
| 1259 _ReferenceInfo(this.enclosing, this.name, this.element, DartType specialType, | |
| 1260 this.numTypeParameters) { | |
| 1261 if (specialType != null) { | |
| 1262 type = specialType; | |
| 1263 } else { | |
| 1264 type = _buildType((_) => DynamicTypeImpl.instance, const []); | |
| 1265 } | |
| 1266 } | |
| 1267 | |
| 1268 /** | |
| 1269 * Build a [DartType] corresponding to the result of applying some type | |
| 1270 * arguments to the entity referred to by this [_ReferenceInfo]. The type | |
| 1271 * arguments are retrieved by calling [getTypeArgument]. | |
| 1272 * | |
| 1273 * If [implicitFunctionTypeIndices] is not empty, a [DartType] should be | |
| 1274 * created which refers to a function type implicitly defined by one of the | |
| 1275 * element's parameters. [implicitFunctionTypeIndices] is interpreted as in | |
| 1276 * [EntityRef.implicitFunctionTypeIndices]. | |
| 1277 * | |
| 1278 * If the entity referred to by this [_ReferenceInfo] is not a type, `null` | |
| 1279 * is returned. | |
| 1280 */ | |
| 1281 DartType buildType( | |
| 1282 DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) { | |
| 1283 DartType result = | |
| 1284 (numTypeParameters == 0 && implicitFunctionTypeIndices.isEmpty) | |
| 1285 ? type | |
| 1286 : _buildType(getTypeArgument, implicitFunctionTypeIndices); | |
| 1287 if (result == null) { | |
| 1288 // TODO(paulberry): figure out how to handle this case (which should | |
| 1289 // only occur in the event of erroneous code). | |
| 1290 throw new UnimplementedError(); | |
| 1291 } | |
| 1292 return result; | |
| 1293 } | |
| 1294 | |
| 1295 /** | |
| 1296 * If this reference refers to a type, build a [DartType] which instantiates | |
| 1297 * it with type arguments returned by [getTypeArgument]. Otherwise return | |
| 1298 * `null`. | |
| 1299 * | |
| 1300 * If [implicitFunctionTypeIndices] is not null, a [DartType] should be | |
| 1301 * created which refers to a function type implicitly defined by one of the | |
| 1302 * element's parameters. [implicitFunctionTypeIndices] is interpreted as in | |
| 1303 * [EntityRef.implicitFunctionTypeIndices]. | |
| 1304 */ | |
| 1305 DartType _buildType( | |
| 1306 DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) { | |
| 1307 ElementHandle element = this.element; // To allow type promotion | |
| 1308 if (element is ClassElementHandle) { | |
| 1309 return new InterfaceTypeImpl.elementWithNameAndArgs(element, name, | |
| 1310 _buildTypeArguments(numTypeParameters, getTypeArgument)); | |
| 1311 } else if (element is FunctionTypeAliasElementHandle) { | |
| 1312 return new FunctionTypeImpl.elementWithNameAndArgs( | |
| 1313 element, | |
| 1314 name, | |
| 1315 _buildTypeArguments(numTypeParameters, getTypeArgument), | |
| 1316 numTypeParameters != 0); | |
| 1317 } else if (element is FunctionTypedElement) { | |
| 1318 int numTypeArguments; | |
| 1319 FunctionTypedElementComputer computer; | |
| 1320 if (implicitFunctionTypeIndices.isNotEmpty) { | |
| 1321 numTypeArguments = numTypeParameters; | |
| 1322 computer = () { | |
| 1323 FunctionTypedElement element = this.element; | |
| 1324 for (int index in implicitFunctionTypeIndices) { | |
| 1325 element = element.parameters[index].type.element; | |
| 1326 } | |
| 1327 return element; | |
| 1328 }; | |
| 1329 } else { | |
| 1330 // For a type that refers to a generic executable, the type arguments ar e | |
| 1331 // not supposed to include the arguments to the executable itself. | |
| 1332 numTypeArguments = enclosing == null ? 0 : enclosing.numTypeParameters; | |
| 1333 computer = () => this.element; | |
| 1334 } | |
| 1335 // TODO(paulberry): Is it a bug that we have to pass `false` for | |
| 1336 // isInstantiated? | |
| 1337 return new DeferredFunctionTypeImpl(computer, null, | |
| 1338 _buildTypeArguments(numTypeArguments, getTypeArgument), false); | |
| 1339 } else { | |
| 1340 return null; | |
| 1341 } | |
| 1342 } | |
| 1343 | |
| 1344 /** | |
| 1345 * Build a list of type arguments having length [numTypeArguments] where each | |
| 1346 * type argument is obtained by calling [getTypeArgument]. | |
| 1347 */ | |
| 1348 List<DartType> _buildTypeArguments( | |
| 1349 int numTypeArguments, DartType getTypeArgument(int i)) { | |
| 1350 List<DartType> typeArguments = const <DartType>[]; | |
| 1351 if (numTypeArguments != 0) { | |
| 1352 typeArguments = <DartType>[]; | |
| 1353 for (int i = 0; i < numTypeArguments; i++) { | |
| 1354 typeArguments.add(getTypeArgument(i)); | |
| 1355 } | |
| 1356 } | |
| 1357 return typeArguments; | |
| 1358 } | |
| 1359 } | |
| 1360 | |
| 1361 /** | |
| 1362 * An instance of [_UnitResynthesizer] is responsible for resynthesizing the | |
| 1363 * elements in a single unit from that unit's summary. | |
| 1364 */ | |
| 1365 class _UnitResynthesizer { | |
| 1366 /** | |
| 1367 * The [_LibraryResynthesizer] which is being used to obtain summaries. | |
| 1368 */ | |
| 1369 final _LibraryResynthesizer libraryResynthesizer; | |
| 1370 | |
| 1371 /** | |
| 1372 * The [UnlinkedUnit] from which elements are currently being resynthesized. | |
| 1373 */ | |
| 1374 final UnlinkedUnit unlinkedUnit; | |
| 1375 | |
| 1376 /** | |
| 1377 * The [LinkedUnit] from which elements are currently being resynthesized. | |
| 1378 */ | |
| 1379 final LinkedUnit linkedUnit; | |
| 1380 | |
| 1381 /** | |
| 1382 * The [CompilationUnitElementImpl] for the compilation unit currently being | |
| 1383 * resynthesized. | |
| 1384 */ | |
| 1385 final CompilationUnitElementImpl unit; | |
| 1386 | |
| 1387 /** | |
| 825 * [ElementHolder] into which resynthesized elements should be placed. This | 1388 * [ElementHolder] into which resynthesized elements should be placed. This |
| 826 * object is recreated afresh for each unit in the library, and is used to | 1389 * object is recreated afresh for each unit in the library, and is used to |
| 827 * populate the [CompilationUnitElement]. | 1390 * populate the [CompilationUnitElement]. |
| 828 */ | 1391 */ |
| 829 ElementHolder unitHolder; | 1392 final ElementHolder unitHolder = new ElementHolder(); |
| 830 | 1393 |
| 831 /** | 1394 /** |
| 832 * The [LinkedUnit] from which elements are currently being resynthesized. | 1395 * Map of top-level elements that have been resynthesized so far. The key is |
| 833 */ | 1396 * the name of the top level element. |
| 834 LinkedUnit linkedUnit; | 1397 */ |
| 835 | 1398 Map<String, Element> elementMap = <String, Element>{}; |
| 836 /** | |
| 837 * The [UnlinkedUnit] from which elements are currently being resynthesized. | |
| 838 */ | |
| 839 UnlinkedUnit unlinkedUnit; | |
| 840 | 1399 |
| 841 /** | 1400 /** |
| 842 * Map from slot id to the corresponding [EntityRef] object for linked types | 1401 * Map from slot id to the corresponding [EntityRef] object for linked types |
| 843 * (i.e. propagated and inferred types). | 1402 * (i.e. propagated and inferred types). |
| 844 */ | 1403 */ |
| 845 Map<int, EntityRef> linkedTypeMap; | 1404 final Map<int, EntityRef> linkedTypeMap = <int, EntityRef>{}; |
| 846 | 1405 |
| 847 /** | 1406 /** |
| 848 * Set of slot ids corresponding to const constructors that are part of | 1407 * Set of slot ids corresponding to const constructors that are part of |
| 849 * cycles. | 1408 * cycles. |
| 850 */ | 1409 */ |
| 851 Set<int> constCycles; | 1410 Set<int> constCycles; |
| 852 | 1411 |
| 853 /** | 1412 /** |
| 854 * The [CompilationUnitElementImpl] for the compilation unit currently being | |
| 855 * resynthesized. | |
| 856 */ | |
| 857 CompilationUnitElementImpl currentCompilationUnit; | |
| 858 | |
| 859 /** | |
| 860 * The [ConstructorElementImpl] for the constructor currently being | 1413 * The [ConstructorElementImpl] for the constructor currently being |
| 861 * resynthesized. | 1414 * resynthesized. |
| 862 */ | 1415 */ |
| 863 ConstructorElementImpl currentConstructor; | 1416 ConstructorElementImpl currentConstructor; |
| 864 | 1417 |
| 865 /** | 1418 /** |
| 866 * Map of compilation unit elements that have been resynthesized so far. The | |
| 867 * key is the URI of the compilation unit. | |
| 868 */ | |
| 869 final Map<String, CompilationUnitElement> resynthesizedUnits = | |
| 870 <String, CompilationUnitElement>{}; | |
| 871 | |
| 872 /** | |
| 873 * Map of top level elements that have been resynthesized so far. The first | |
| 874 * key is the URI of the compilation unit; the second is the name of the top | |
| 875 * level element. | |
| 876 */ | |
| 877 final Map<String, Map<String, Element>> resynthesizedElements = | |
| 878 <String, Map<String, Element>>{}; | |
| 879 | |
| 880 /** | |
| 881 * Type parameters for the generic class, typedef, or executable currently | 1419 * Type parameters for the generic class, typedef, or executable currently |
| 882 * being resynthesized, if any. This is a list of lists; if multiple | 1420 * being resynthesized, if any. This is a list of lists; if multiple |
| 883 * entities with type parameters are nested (e.g. a generic executable inside | 1421 * entities with type parameters are nested (e.g. a generic executable inside |
| 884 * a generic class), then the zeroth element of [currentTypeParameters] | 1422 * a generic class), then the zeroth element of [currentTypeParameters] |
| 885 * contains the type parameters for the outermost nested entity, and further | 1423 * contains the type parameters for the outermost nested entity, and further |
| 886 * elements contain the type parameters for entities that are more deeply | 1424 * elements contain the type parameters for entities that are more deeply |
| 887 * nested. If we are not currently resynthesizing a class, typedef, or | 1425 * nested. If we are not currently resynthesizing a class, typedef, or |
| 888 * executable, then this is an empty list. | 1426 * executable, then this is an empty list. |
| 889 */ | 1427 */ |
| 890 final List<List<TypeParameterElement>> currentTypeParameters = | 1428 final List<List<TypeParameterElement>> currentTypeParameters = |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 903 * constructor initializers. | 1441 * constructor initializers. |
| 904 */ | 1442 */ |
| 905 Map<String, ConstructorElementImpl> constructors; | 1443 Map<String, ConstructorElementImpl> constructors; |
| 906 | 1444 |
| 907 /** | 1445 /** |
| 908 * List of [_ReferenceInfo] objects describing the references in the current | 1446 * List of [_ReferenceInfo] objects describing the references in the current |
| 909 * compilation unit. | 1447 * compilation unit. |
| 910 */ | 1448 */ |
| 911 List<_ReferenceInfo> referenceInfos; | 1449 List<_ReferenceInfo> referenceInfos; |
| 912 | 1450 |
| 913 _LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary, | 1451 _UnitResynthesizer(this.libraryResynthesizer, this.unlinkedUnit, |
| 914 this.unlinkedUnits, this.librarySource) { | 1452 this.linkedUnit, this.unit) { |
| 915 isCoreLibrary = librarySource.uri.toString() == 'dart:core'; | 1453 for (EntityRef t in linkedUnit.types) { |
| 1454 linkedTypeMap[t.slot] = t; | |
| 1455 } | |
| 1456 constCycles = linkedUnit.constCycles.toSet(); | |
| 1457 populateReferenceInfos(); | |
| 916 } | 1458 } |
| 917 | 1459 |
| 918 /** | 1460 /** |
| 1461 * TODO(scheglov) inline? | |
|
Paul Berry
2016/03/24 19:40:14
AFAIK, the VM is smart about inlining methods like
| |
| 1462 */ | |
| 1463 SummaryResynthesizer get summaryResynthesizer => | |
| 1464 libraryResynthesizer.summaryResynthesizer; | |
| 1465 | |
| 1466 /** | |
| 919 * Build the annotations for the given [element]. | 1467 * Build the annotations for the given [element]. |
| 920 */ | 1468 */ |
| 921 void buildAnnotations( | 1469 void buildAnnotations( |
| 922 ElementImpl element, List<UnlinkedConst> serializedAnnotations) { | 1470 ElementImpl element, List<UnlinkedConst> serializedAnnotations) { |
| 923 if (serializedAnnotations.isNotEmpty) { | 1471 if (serializedAnnotations.isNotEmpty) { |
| 924 element.metadata = serializedAnnotations.map((UnlinkedConst a) { | 1472 element.metadata = serializedAnnotations.map((UnlinkedConst a) { |
| 925 ElementAnnotationImpl elementAnnotation = | 1473 ElementAnnotationImpl elementAnnotation = |
| 926 new ElementAnnotationImpl(this.currentCompilationUnit); | 1474 new ElementAnnotationImpl(this.unit); |
| 927 Expression constExpr = _buildConstExpression(a); | 1475 Expression constExpr = _buildConstExpression(a); |
| 928 if (constExpr is Identifier) { | 1476 if (constExpr is Identifier) { |
| 929 elementAnnotation.element = constExpr.staticElement; | 1477 elementAnnotation.element = constExpr.staticElement; |
| 930 elementAnnotation.annotationAst = AstFactory.annotation(constExpr); | 1478 elementAnnotation.annotationAst = AstFactory.annotation(constExpr); |
| 931 } else if (constExpr is InstanceCreationExpression) { | 1479 } else if (constExpr is InstanceCreationExpression) { |
| 932 elementAnnotation.element = constExpr.staticElement; | 1480 elementAnnotation.element = constExpr.staticElement; |
| 933 Identifier typeName = constExpr.constructorName.type.name; | 1481 Identifier typeName = constExpr.constructorName.type.name; |
| 934 SimpleIdentifier constructorName = constExpr.constructorName.name; | 1482 SimpleIdentifier constructorName = constExpr.constructorName.name; |
| 935 if (typeName is SimpleIdentifier && constructorName != null) { | 1483 if (typeName is SimpleIdentifier && constructorName != null) { |
| 936 // E.g. `@cls.ctor()`. Since `cls.ctor` would have been parsed as | 1484 // E.g. `@cls.ctor()`. Since `cls.ctor` would have been parsed as |
| 937 // a PrefixedIdentifier, we need to resynthesize it as one. | 1485 // a PrefixedIdentifier, we need to resynthesize it as one. |
| 938 typeName = AstFactory.identifier(typeName, constructorName); | 1486 typeName = AstFactory.identifier(typeName, constructorName); |
| 939 constructorName = null; | 1487 constructorName = null; |
| 940 } | 1488 } |
| 941 elementAnnotation.annotationAst = AstFactory.annotation2( | 1489 elementAnnotation.annotationAst = AstFactory.annotation2( |
| 942 typeName, constructorName, constExpr.argumentList); | 1490 typeName, constructorName, constExpr.argumentList); |
| 943 } else { | 1491 } else { |
| 944 throw new StateError( | 1492 throw new StateError( |
| 945 'Unexpected annotation type: ${constExpr.runtimeType}'); | 1493 'Unexpected annotation type: ${constExpr.runtimeType}'); |
| 946 } | 1494 } |
| 947 return elementAnnotation; | 1495 return elementAnnotation; |
| 948 }).toList(); | 1496 }).toList(); |
| 949 } | 1497 } |
| 950 } | 1498 } |
| 951 | 1499 |
| 952 /** | 1500 /** |
| 953 * Resynthesize a [ClassElement] and place it in [unitHolder]. | 1501 * Resynthesize a [ClassElement] and place it in [unitHolder]. |
| 954 */ | 1502 */ |
| 955 void buildClass(UnlinkedClass serializedClass) { | 1503 void buildClass(UnlinkedClass serializedClass) { |
| 1504 ClassElement classElement; | |
| 1505 if (libraryResynthesizer.isCoreLibrary && | |
| 1506 serializedClass.supertype == null) { | |
| 1507 classElement = buildClassImpl(serializedClass); | |
| 1508 if (!serializedClass.hasNoSupertype) { | |
| 1509 libraryResynthesizer.delayedObjectSubclasses.add(classElement); | |
| 1510 } | |
| 1511 } else { | |
| 1512 classElement = new _DeferredClassElement(this, unit, serializedClass); | |
| 1513 } | |
| 1514 unitHolder.addType(classElement); | |
| 1515 } | |
| 1516 | |
| 1517 /** | |
| 1518 * Resynthesize a [ClassElementImpl]. | |
| 1519 */ | |
| 1520 ClassElementImpl buildClassImpl(UnlinkedClass serializedClass) { | |
| 956 ClassElementImpl classElement = | 1521 ClassElementImpl classElement = |
| 957 new ClassElementImpl(serializedClass.name, serializedClass.nameOffset); | 1522 new ClassElementImpl(serializedClass.name, serializedClass.nameOffset); |
| 958 classElement.hasBeenInferred = summaryResynthesizer.strongMode; | 1523 classElement.hasBeenInferred = summaryResynthesizer.strongMode; |
| 959 classElement.typeParameters = | 1524 classElement.typeParameters = |
| 960 buildTypeParameters(serializedClass.typeParameters); | 1525 buildTypeParameters(serializedClass.typeParameters); |
| 961 classElement.abstract = serializedClass.isAbstract; | 1526 classElement.abstract = serializedClass.isAbstract; |
| 962 classElement.mixinApplication = serializedClass.isMixinApplication; | 1527 classElement.mixinApplication = serializedClass.isMixinApplication; |
| 963 InterfaceTypeImpl correspondingType = new InterfaceTypeImpl(classElement); | 1528 InterfaceTypeImpl correspondingType = new InterfaceTypeImpl(classElement); |
| 964 if (serializedClass.supertype != null) { | 1529 if (serializedClass.supertype != null) { |
| 965 classElement.supertype = buildType(serializedClass.supertype); | 1530 classElement.supertype = buildType(serializedClass.supertype); |
| 966 } else if (!serializedClass.hasNoSupertype) { | 1531 } else if (!libraryResynthesizer.isCoreLibrary) { |
| 967 if (isCoreLibrary) { | 1532 classElement.supertype = summaryResynthesizer.typeProvider.objectType; |
| 968 delayedObjectSubclasses.add(classElement); | |
| 969 } else { | |
| 970 classElement.supertype = summaryResynthesizer.typeProvider.objectType; | |
| 971 } | |
| 972 } | 1533 } |
| 973 classElement.interfaces = | 1534 classElement.interfaces = |
| 974 serializedClass.interfaces.map(buildType).toList(); | 1535 serializedClass.interfaces.map(buildType).toList(); |
| 975 classElement.mixins = serializedClass.mixins.map(buildType).toList(); | 1536 classElement.mixins = serializedClass.mixins.map(buildType).toList(); |
| 976 ElementHolder memberHolder = new ElementHolder(); | 1537 ElementHolder memberHolder = new ElementHolder(); |
| 977 fields = <String, FieldElementImpl>{}; | 1538 fields = <String, FieldElementImpl>{}; |
| 978 for (UnlinkedVariable serializedVariable in serializedClass.fields) { | 1539 for (UnlinkedVariable serializedVariable in serializedClass.fields) { |
| 979 buildVariable(serializedVariable, memberHolder); | 1540 buildVariable(serializedVariable, memberHolder); |
| 980 } | 1541 } |
| 981 bool constructorFound = false; | 1542 bool constructorFound = false; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1015 } | 1576 } |
| 1016 classElement.accessors = memberHolder.accessors; | 1577 classElement.accessors = memberHolder.accessors; |
| 1017 classElement.fields = memberHolder.fields; | 1578 classElement.fields = memberHolder.fields; |
| 1018 classElement.methods = memberHolder.methods; | 1579 classElement.methods = memberHolder.methods; |
| 1019 correspondingType.typeArguments = getCurrentTypeArguments(); | 1580 correspondingType.typeArguments = getCurrentTypeArguments(); |
| 1020 classElement.type = correspondingType; | 1581 classElement.type = correspondingType; |
| 1021 buildDocumentation(classElement, serializedClass.documentationComment); | 1582 buildDocumentation(classElement, serializedClass.documentationComment); |
| 1022 buildAnnotations(classElement, serializedClass.annotations); | 1583 buildAnnotations(classElement, serializedClass.annotations); |
| 1023 buildCodeRange(classElement, serializedClass.codeRange); | 1584 buildCodeRange(classElement, serializedClass.codeRange); |
| 1024 resolveConstructorInitializers(classElement); | 1585 resolveConstructorInitializers(classElement); |
| 1025 unitHolder.addType(classElement); | |
| 1026 currentTypeParameters.removeLast(); | 1586 currentTypeParameters.removeLast(); |
| 1027 assert(currentTypeParameters.isEmpty); | 1587 assert(currentTypeParameters.isEmpty); |
| 1028 fields = null; | 1588 fields = null; |
| 1029 constructors = null; | 1589 constructors = null; |
| 1590 return classElement; | |
| 1030 } | 1591 } |
| 1031 | 1592 |
| 1032 void buildCodeRange(ElementImpl element, CodeRange codeRange) { | 1593 void buildCodeRange(ElementImpl element, CodeRange codeRange) { |
| 1033 if (codeRange != null) { | 1594 if (codeRange != null) { |
| 1034 element.setCodeRange(codeRange.offset, codeRange.length); | 1595 element.setCodeRange(codeRange.offset, codeRange.length); |
| 1035 } | 1596 } |
| 1036 } | 1597 } |
| 1037 | 1598 |
| 1038 /** | 1599 /** |
| 1039 * Resynthesize a [NamespaceCombinator]. | 1600 * Resynthesize a [NamespaceCombinator]. |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1109 .toList(); | 1670 .toList(); |
| 1110 if (serializedExecutable.isRedirectedConstructor) { | 1671 if (serializedExecutable.isRedirectedConstructor) { |
| 1111 if (serializedExecutable.isFactory) { | 1672 if (serializedExecutable.isFactory) { |
| 1112 EntityRef redirectedConstructor = | 1673 EntityRef redirectedConstructor = |
| 1113 serializedExecutable.redirectedConstructor; | 1674 serializedExecutable.redirectedConstructor; |
| 1114 _ReferenceInfo info = referenceInfos[redirectedConstructor.reference]; | 1675 _ReferenceInfo info = referenceInfos[redirectedConstructor.reference]; |
| 1115 List<EntityRef> typeArguments = redirectedConstructor.typeArguments; | 1676 List<EntityRef> typeArguments = redirectedConstructor.typeArguments; |
| 1116 currentConstructor.redirectedConstructor = _createConstructorElement( | 1677 currentConstructor.redirectedConstructor = _createConstructorElement( |
| 1117 _createConstructorDefiningType(info, typeArguments), info); | 1678 _createConstructorDefiningType(info, typeArguments), info); |
| 1118 } else { | 1679 } else { |
| 1119 List<String> locationComponents = | 1680 List<String> locationComponents = unit.location.components.toList(); |
| 1120 currentCompilationUnit.location.components.toList(); | |
| 1121 locationComponents.add(classType.name); | 1681 locationComponents.add(classType.name); |
| 1122 locationComponents.add(serializedExecutable.redirectedConstructorName); | 1682 locationComponents.add(serializedExecutable.redirectedConstructorName); |
| 1123 currentConstructor.redirectedConstructor = | 1683 currentConstructor.redirectedConstructor = |
| 1124 new _DeferredConstructorElement._( | 1684 new _DeferredConstructorElement._( |
| 1125 classType, | 1685 classType, |
| 1126 serializedExecutable.redirectedConstructorName, | 1686 serializedExecutable.redirectedConstructorName, |
| 1127 new ElementLocationImpl.con3(locationComponents)); | 1687 new ElementLocationImpl.con3(locationComponents)); |
| 1128 } | 1688 } |
| 1129 } | 1689 } |
| 1130 holder.addConstructor(currentConstructor); | 1690 holder.addConstructor(currentConstructor); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1142 element.setDocRange(serializedDocumentationComment.offset, | 1702 element.setDocRange(serializedDocumentationComment.offset, |
| 1143 serializedDocumentationComment.length); | 1703 serializedDocumentationComment.length); |
| 1144 } | 1704 } |
| 1145 } | 1705 } |
| 1146 | 1706 |
| 1147 /** | 1707 /** |
| 1148 * Resynthesize the [ClassElement] corresponding to an enum, along with the | 1708 * Resynthesize the [ClassElement] corresponding to an enum, along with the |
| 1149 * associated fields and implicit accessors. | 1709 * associated fields and implicit accessors. |
| 1150 */ | 1710 */ |
| 1151 void buildEnum(UnlinkedEnum serializedEnum) { | 1711 void buildEnum(UnlinkedEnum serializedEnum) { |
| 1152 assert(!isCoreLibrary); | 1712 assert(!libraryResynthesizer.isCoreLibrary); |
| 1153 ClassElementImpl classElement = | 1713 ClassElementImpl classElement = |
| 1154 new ClassElementImpl(serializedEnum.name, serializedEnum.nameOffset); | 1714 new ClassElementImpl(serializedEnum.name, serializedEnum.nameOffset); |
| 1155 classElement.enum2 = true; | 1715 classElement.enum2 = true; |
| 1156 InterfaceType enumType = new InterfaceTypeImpl(classElement); | 1716 InterfaceType enumType = new InterfaceTypeImpl(classElement); |
| 1157 classElement.type = enumType; | 1717 classElement.type = enumType; |
| 1158 classElement.supertype = summaryResynthesizer.typeProvider.objectType; | 1718 classElement.supertype = summaryResynthesizer.typeProvider.objectType; |
| 1159 buildDocumentation(classElement, serializedEnum.documentationComment); | 1719 buildDocumentation(classElement, serializedEnum.documentationComment); |
| 1160 buildAnnotations(classElement, serializedEnum.annotations); | 1720 buildAnnotations(classElement, serializedEnum.annotations); |
| 1161 buildCodeRange(classElement, serializedEnum.codeRange); | 1721 buildCodeRange(classElement, serializedEnum.codeRange); |
| 1162 ElementHolder memberHolder = new ElementHolder(); | 1722 ElementHolder memberHolder = new ElementHolder(); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1325 } | 1885 } |
| 1326 | 1886 |
| 1327 /** | 1887 /** |
| 1328 * Resynthesize an [ExportElement], | 1888 * Resynthesize an [ExportElement], |
| 1329 */ | 1889 */ |
| 1330 ExportElement buildExport(UnlinkedExportPublic serializedExportPublic, | 1890 ExportElement buildExport(UnlinkedExportPublic serializedExportPublic, |
| 1331 UnlinkedExportNonPublic serializedExportNonPublic) { | 1891 UnlinkedExportNonPublic serializedExportNonPublic) { |
| 1332 ExportElementImpl exportElement = | 1892 ExportElementImpl exportElement = |
| 1333 new ExportElementImpl(serializedExportNonPublic.offset); | 1893 new ExportElementImpl(serializedExportNonPublic.offset); |
| 1334 String exportedLibraryUri = summaryResynthesizer.sourceFactory | 1894 String exportedLibraryUri = summaryResynthesizer.sourceFactory |
| 1335 .resolveUri(librarySource, serializedExportPublic.uri) | 1895 .resolveUri( |
| 1896 libraryResynthesizer.librarySource, serializedExportPublic.uri) | |
| 1336 .uri | 1897 .uri |
| 1337 .toString(); | 1898 .toString(); |
| 1338 exportElement.exportedLibrary = new LibraryElementHandle( | 1899 exportElement.exportedLibrary = new LibraryElementHandle( |
| 1339 summaryResynthesizer, | 1900 summaryResynthesizer, |
| 1340 new ElementLocationImpl.con3(<String>[exportedLibraryUri])); | 1901 new ElementLocationImpl.con3(<String>[exportedLibraryUri])); |
| 1341 exportElement.uri = serializedExportPublic.uri; | 1902 exportElement.uri = serializedExportPublic.uri; |
| 1342 exportElement.combinators = | 1903 exportElement.combinators = |
| 1343 serializedExportPublic.combinators.map(buildCombinator).toList(); | 1904 serializedExportPublic.combinators.map(buildCombinator).toList(); |
| 1344 exportElement.uriOffset = serializedExportNonPublic.uriOffset; | 1905 exportElement.uriOffset = serializedExportNonPublic.uriOffset; |
| 1345 exportElement.uriEnd = serializedExportNonPublic.uriEnd; | 1906 exportElement.uriEnd = serializedExportNonPublic.uriEnd; |
| 1346 buildAnnotations(exportElement, serializedExportNonPublic.annotations); | 1907 buildAnnotations(exportElement, serializedExportNonPublic.annotations); |
| 1347 return exportElement; | 1908 return exportElement; |
| 1348 } | 1909 } |
| 1349 | 1910 |
| 1350 /** | 1911 /** |
| 1351 * Build an [ElementHandle] referring to the entity referred to by the given | |
| 1352 * [exportName]. | |
| 1353 */ | |
| 1354 ElementHandle buildExportName(LinkedExportName exportName) { | |
| 1355 String name = exportName.name; | |
| 1356 if (exportName.kind == ReferenceKind.topLevelPropertyAccessor && | |
| 1357 !name.endsWith('=')) { | |
| 1358 name += '?'; | |
| 1359 } | |
| 1360 ElementLocationImpl location = new ElementLocationImpl.con3( | |
| 1361 getReferencedLocationComponents( | |
| 1362 exportName.dependency, exportName.unit, name)); | |
| 1363 switch (exportName.kind) { | |
| 1364 case ReferenceKind.classOrEnum: | |
| 1365 return new ClassElementHandle(summaryResynthesizer, location); | |
| 1366 case ReferenceKind.typedef: | |
| 1367 return new FunctionTypeAliasElementHandle( | |
| 1368 summaryResynthesizer, location); | |
| 1369 case ReferenceKind.topLevelFunction: | |
| 1370 return new FunctionElementHandle(summaryResynthesizer, location); | |
| 1371 case ReferenceKind.topLevelPropertyAccessor: | |
| 1372 return new PropertyAccessorElementHandle( | |
| 1373 summaryResynthesizer, location); | |
| 1374 case ReferenceKind.constructor: | |
| 1375 case ReferenceKind.function: | |
| 1376 case ReferenceKind.propertyAccessor: | |
| 1377 case ReferenceKind.method: | |
| 1378 case ReferenceKind.length: | |
| 1379 case ReferenceKind.prefix: | |
| 1380 case ReferenceKind.unresolved: | |
| 1381 case ReferenceKind.variable: | |
| 1382 // Should never happen. Exported names never refer to import prefixes, | |
| 1383 // and they always refer to defined top-level entities. | |
| 1384 throw new StateError('Unexpected export name kind: ${exportName.kind}'); | |
| 1385 } | |
| 1386 } | |
| 1387 | |
| 1388 /** | |
| 1389 * Build the export namespace for the library by aggregating together its | |
| 1390 * [publicNamespace] and [exportNames]. | |
| 1391 */ | |
| 1392 Namespace buildExportNamespace( | |
| 1393 Namespace publicNamespace, List<LinkedExportName> exportNames) { | |
| 1394 HashMap<String, Element> definedNames = new HashMap<String, Element>(); | |
| 1395 // Start by populating all the public names from [publicNamespace]. | |
| 1396 publicNamespace.definedNames.forEach((String name, Element element) { | |
| 1397 definedNames[name] = element; | |
| 1398 }); | |
| 1399 // Add all the names from [exportNames]. | |
| 1400 for (LinkedExportName exportName in exportNames) { | |
| 1401 definedNames.putIfAbsent( | |
| 1402 exportName.name, () => buildExportName(exportName)); | |
| 1403 } | |
| 1404 return new Namespace(definedNames); | |
| 1405 } | |
| 1406 | |
| 1407 /** | |
| 1408 * Build the implicit getter and setter associated with [element], and place | 1912 * Build the implicit getter and setter associated with [element], and place |
| 1409 * them in [holder]. | 1913 * them in [holder]. |
| 1410 */ | 1914 */ |
| 1411 void buildImplicitAccessors( | 1915 void buildImplicitAccessors( |
| 1412 PropertyInducingElementImpl element, ElementHolder holder) { | 1916 PropertyInducingElementImpl element, ElementHolder holder) { |
| 1413 String name = element.name; | 1917 String name = element.name; |
| 1414 DartType type = element.type; | 1918 DartType type = element.type; |
| 1415 PropertyAccessorElementImpl getter = | 1919 PropertyAccessorElementImpl getter = |
| 1416 new PropertyAccessorElementImpl(name, element.nameOffset); | 1920 new PropertyAccessorElementImpl(name, element.nameOffset); |
| 1417 getter.getter = true; | 1921 getter.getter = true; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1478 holder.addTopLevelVariable(variable); | 1982 holder.addTopLevelVariable(variable); |
| 1479 return variable; | 1983 return variable; |
| 1480 } else { | 1984 } else { |
| 1481 // TODO(paulberry): what if the getter and setter have a type mismatch? | 1985 // TODO(paulberry): what if the getter and setter have a type mismatch? |
| 1482 variable.final2 = false; | 1986 variable.final2 = false; |
| 1483 return variable; | 1987 return variable; |
| 1484 } | 1988 } |
| 1485 } | 1989 } |
| 1486 | 1990 |
| 1487 /** | 1991 /** |
| 1488 * Resynthesize an [ImportElement]. | |
| 1489 */ | |
| 1490 ImportElement buildImport(UnlinkedImport serializedImport, int dependency) { | |
| 1491 bool isSynthetic = serializedImport.isImplicit; | |
| 1492 ImportElementImpl importElement = | |
| 1493 new ImportElementImpl(isSynthetic ? -1 : serializedImport.offset); | |
| 1494 String absoluteUri = summaryResynthesizer.sourceFactory | |
| 1495 .resolveUri(librarySource, linkedLibrary.dependencies[dependency].uri) | |
| 1496 .uri | |
| 1497 .toString(); | |
| 1498 importElement.importedLibrary = new LibraryElementHandle( | |
| 1499 summaryResynthesizer, | |
| 1500 new ElementLocationImpl.con3(<String>[absoluteUri])); | |
| 1501 if (isSynthetic) { | |
| 1502 importElement.synthetic = true; | |
| 1503 } else { | |
| 1504 importElement.uri = serializedImport.uri; | |
| 1505 importElement.uriOffset = serializedImport.uriOffset; | |
| 1506 importElement.uriEnd = serializedImport.uriEnd; | |
| 1507 importElement.deferred = serializedImport.isDeferred; | |
| 1508 buildAnnotations(importElement, serializedImport.annotations); | |
| 1509 } | |
| 1510 importElement.prefixOffset = serializedImport.prefixOffset; | |
| 1511 if (serializedImport.prefixReference != 0) { | |
| 1512 UnlinkedReference serializedPrefix = | |
| 1513 unlinkedUnits[0].references[serializedImport.prefixReference]; | |
| 1514 importElement.prefix = new PrefixElementImpl( | |
| 1515 serializedPrefix.name, serializedImport.prefixOffset); | |
| 1516 } | |
| 1517 importElement.combinators = | |
| 1518 serializedImport.combinators.map(buildCombinator).toList(); | |
| 1519 return importElement; | |
| 1520 } | |
| 1521 | |
| 1522 /** | |
| 1523 * Main entry point. Resynthesize the [LibraryElement] and return it. | |
| 1524 */ | |
| 1525 LibraryElement buildLibrary() { | |
| 1526 CompilationUnitElementImpl definingCompilationUnit = | |
| 1527 new CompilationUnitElementImpl(librarySource.shortName); | |
| 1528 prepareUnit(definingCompilationUnit, 0); | |
| 1529 bool hasName = unlinkedUnits[0].libraryName.isNotEmpty; | |
| 1530 LibraryElementImpl library = new LibraryElementImpl( | |
| 1531 summaryResynthesizer.context, | |
| 1532 unlinkedUnits[0].libraryName, | |
| 1533 hasName ? unlinkedUnits[0].libraryNameOffset : -1, | |
| 1534 unlinkedUnits[0].libraryNameLength); | |
| 1535 buildDocumentation(library, unlinkedUnits[0].libraryDocumentationComment); | |
| 1536 buildAnnotations(library, unlinkedUnits[0].libraryAnnotations); | |
| 1537 library.definingCompilationUnit = definingCompilationUnit; | |
| 1538 definingCompilationUnit.source = librarySource; | |
| 1539 definingCompilationUnit.librarySource = librarySource; | |
| 1540 List<CompilationUnitElement> parts = <CompilationUnitElement>[]; | |
| 1541 UnlinkedUnit unlinkedDefiningUnit = unlinkedUnits[0]; | |
| 1542 assert(unlinkedDefiningUnit.publicNamespace.parts.length + 1 == | |
| 1543 linkedLibrary.units.length); | |
| 1544 for (int i = 1; i < linkedLibrary.units.length; i++) { | |
| 1545 CompilationUnitElementImpl part = buildPart( | |
| 1546 unlinkedDefiningUnit.publicNamespace.parts[i - 1], | |
| 1547 unlinkedDefiningUnit.parts[i - 1], | |
| 1548 unlinkedUnits[i]); | |
| 1549 parts.add(part); | |
| 1550 } | |
| 1551 library.parts = parts; | |
| 1552 List<ImportElement> imports = <ImportElement>[]; | |
| 1553 for (int i = 0; i < unlinkedDefiningUnit.imports.length; i++) { | |
| 1554 imports.add(buildImport(unlinkedDefiningUnit.imports[i], | |
| 1555 linkedLibrary.importDependencies[i])); | |
| 1556 } | |
| 1557 library.imports = imports; | |
| 1558 List<ExportElement> exports = <ExportElement>[]; | |
| 1559 assert(unlinkedDefiningUnit.exports.length == | |
| 1560 unlinkedDefiningUnit.publicNamespace.exports.length); | |
| 1561 for (int i = 0; i < unlinkedDefiningUnit.exports.length; i++) { | |
| 1562 exports.add(buildExport(unlinkedDefiningUnit.publicNamespace.exports[i], | |
| 1563 unlinkedDefiningUnit.exports[i])); | |
| 1564 } | |
| 1565 library.exports = exports; | |
| 1566 populateUnit(definingCompilationUnit, 0); | |
| 1567 finishUnit(); | |
| 1568 for (int i = 0; i < parts.length; i++) { | |
| 1569 prepareUnit(parts[i], i + 1); | |
| 1570 populateUnit(parts[i], i + 1); | |
| 1571 finishUnit(); | |
| 1572 } | |
| 1573 BuildLibraryElementUtils.patchTopLevelAccessors(library); | |
| 1574 // Update delayed Object class references. | |
| 1575 if (isCoreLibrary) { | |
| 1576 ClassElement objectElement = library.getType('Object'); | |
| 1577 assert(objectElement != null); | |
| 1578 for (ClassElementImpl classElement in delayedObjectSubclasses) { | |
| 1579 classElement.supertype = objectElement.type; | |
| 1580 } | |
| 1581 } | |
| 1582 // Compute namespaces. | |
| 1583 library.publicNamespace = | |
| 1584 new NamespaceBuilder().createPublicNamespaceForLibrary(library); | |
| 1585 library.exportNamespace = buildExportNamespace( | |
| 1586 library.publicNamespace, linkedLibrary.exportNames); | |
| 1587 // Find the entry point. Note: we can't use element.isEntryPoint because | |
| 1588 // that will trigger resynthesis of exported libraries. | |
| 1589 Element entryPoint = | |
| 1590 library.exportNamespace.get(FunctionElement.MAIN_FUNCTION_NAME); | |
| 1591 if (entryPoint is FunctionElement) { | |
| 1592 library.entryPoint = entryPoint; | |
| 1593 } | |
| 1594 // Create the synthetic element for `loadLibrary`. | |
| 1595 // Until the client received dart:core and dart:async, we cannot do this, | |
| 1596 // because the TypeProvider is not fully initialized. So, it is up to the | |
| 1597 // Dart SDK client to initialize TypeProvider and finish the dart:core and | |
| 1598 // dart:async libraries creation. | |
| 1599 if (library.name != 'dart.core' && library.name != 'dart.async') { | |
| 1600 library.createLoadLibraryFunction(summaryResynthesizer.typeProvider); | |
| 1601 } | |
| 1602 // Done. | |
| 1603 return library; | |
| 1604 } | |
| 1605 | |
| 1606 /** | |
| 1607 * Build the appropriate [DartType] object corresponding to a slot id in the | 1992 * Build the appropriate [DartType] object corresponding to a slot id in the |
| 1608 * [LinkedUnit.types] table. | 1993 * [LinkedUnit.types] table. |
| 1609 */ | 1994 */ |
| 1610 DartType buildLinkedType(int slot) { | 1995 DartType buildLinkedType(int slot) { |
| 1611 if (slot == 0) { | 1996 if (slot == 0) { |
| 1612 // A slot id of 0 means there is no [DartType] object to build. | 1997 // A slot id of 0 means there is no [DartType] object to build. |
| 1613 return null; | 1998 return null; |
| 1614 } | 1999 } |
| 1615 EntityRef type = linkedTypeMap[slot]; | 2000 EntityRef type = linkedTypeMap[slot]; |
| 1616 if (type == null) { | 2001 if (type == null) { |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1754 break; | 2139 break; |
| 1755 } | 2140 } |
| 1756 if (serializedParameter.visibleOffset != 0) { | 2141 if (serializedParameter.visibleOffset != 0) { |
| 1757 parameterElement.setVisibleRange( | 2142 parameterElement.setVisibleRange( |
| 1758 serializedParameter.visibleOffset, serializedParameter.visibleLength); | 2143 serializedParameter.visibleOffset, serializedParameter.visibleLength); |
| 1759 } | 2144 } |
| 1760 return parameterElement; | 2145 return parameterElement; |
| 1761 } | 2146 } |
| 1762 | 2147 |
| 1763 /** | 2148 /** |
| 1764 * Create, but do not populate, the [CompilationUnitElement] for a part other | |
| 1765 * than the defining compilation unit. | |
| 1766 */ | |
| 1767 CompilationUnitElementImpl buildPart( | |
| 1768 String uri, UnlinkedPart partDecl, UnlinkedUnit serializedPart) { | |
| 1769 Source unitSource = | |
| 1770 summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri); | |
| 1771 CompilationUnitElementImpl partUnit = | |
| 1772 new CompilationUnitElementImpl(unitSource.shortName); | |
| 1773 partUnit.uriOffset = partDecl.uriOffset; | |
| 1774 partUnit.uriEnd = partDecl.uriEnd; | |
| 1775 partUnit.source = unitSource; | |
| 1776 partUnit.librarySource = librarySource; | |
| 1777 partUnit.uri = uri; | |
| 1778 buildAnnotations(partUnit, partDecl.annotations); | |
| 1779 return partUnit; | |
| 1780 } | |
| 1781 | |
| 1782 /** | |
| 1783 * Handle the parts that are common to top level variables and fields. | 2149 * Handle the parts that are common to top level variables and fields. |
| 1784 */ | 2150 */ |
| 1785 void buildPropertyIntroducingElementCommonParts( | 2151 void buildPropertyIntroducingElementCommonParts( |
| 1786 PropertyInducingElementImpl element, | 2152 PropertyInducingElementImpl element, |
| 1787 UnlinkedVariable serializedVariable) { | 2153 UnlinkedVariable serializedVariable) { |
| 1788 buildVariableCommonParts(element, serializedVariable); | 2154 buildVariableCommonParts(element, serializedVariable); |
| 1789 element.propagatedType = | 2155 element.propagatedType = |
| 1790 buildLinkedType(serializedVariable.propagatedTypeSlot); | 2156 buildLinkedType(serializedVariable.propagatedTypeSlot); |
| 1791 } | 2157 } |
| 1792 | 2158 |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1968 * Finish creating a [TypeParameterElement] by deserializing its bound. | 2334 * Finish creating a [TypeParameterElement] by deserializing its bound. |
| 1969 */ | 2335 */ |
| 1970 void finishTypeParameter(UnlinkedTypeParam serializedTypeParameter, | 2336 void finishTypeParameter(UnlinkedTypeParam serializedTypeParameter, |
| 1971 TypeParameterElementImpl typeParameterElement) { | 2337 TypeParameterElementImpl typeParameterElement) { |
| 1972 if (serializedTypeParameter.bound != null) { | 2338 if (serializedTypeParameter.bound != null) { |
| 1973 typeParameterElement.bound = buildType(serializedTypeParameter.bound); | 2339 typeParameterElement.bound = buildType(serializedTypeParameter.bound); |
| 1974 } | 2340 } |
| 1975 } | 2341 } |
| 1976 | 2342 |
| 1977 /** | 2343 /** |
| 1978 * Tear down data structures used during deserialization of a compilation | |
| 1979 * unit. | |
| 1980 */ | |
| 1981 void finishUnit() { | |
| 1982 unitHolder = null; | |
| 1983 linkedUnit = null; | |
| 1984 unlinkedUnit = null; | |
| 1985 linkedTypeMap = null; | |
| 1986 constCycles = null; | |
| 1987 referenceInfos = null; | |
| 1988 currentCompilationUnit = null; | |
| 1989 } | |
| 1990 | |
| 1991 /** | |
| 1992 * Return a list of type arguments corresponding to [currentTypeParameters], | 2344 * Return a list of type arguments corresponding to [currentTypeParameters], |
| 1993 * skipping the innermost [skipLevels] nesting levels. | 2345 * skipping the innermost [skipLevels] nesting levels. |
| 1994 * | 2346 * |
| 1995 * Type parameters are listed in nesting order from innermost to outermost, | 2347 * Type parameters are listed in nesting order from innermost to outermost, |
| 1996 * and then in declaration order. So for instance if we are resynthesizing a | 2348 * and then in declaration order. So for instance if we are resynthesizing a |
| 1997 * method declared as `class C<T, U> { void m<V, W>() { ... } }`, then the | 2349 * method declared as `class C<T, U> { void m<V, W>() { ... } }`, then the |
| 1998 * type parameters will be returned in the order `[V, W, T, U]`. | 2350 * type parameters will be returned in the order `[V, W, T, U]`. |
| 1999 */ | 2351 */ |
| 2000 List<DartType> getCurrentTypeArguments({int skipLevels: 0}) { | 2352 List<DartType> getCurrentTypeArguments({int skipLevels: 0}) { |
| 2001 assert(currentTypeParameters.length >= skipLevels); | 2353 assert(currentTypeParameters.length >= skipLevels); |
| 2002 List<DartType> result = <DartType>[]; | 2354 List<DartType> result = <DartType>[]; |
| 2003 for (int i = currentTypeParameters.length - 1 - skipLevels; i >= 0; i--) { | 2355 for (int i = currentTypeParameters.length - 1 - skipLevels; i >= 0; i--) { |
| 2004 result.addAll(currentTypeParameters[i] | 2356 result.addAll(currentTypeParameters[i] |
| 2005 .map((TypeParameterElement param) => param.type)); | 2357 .map((TypeParameterElement param) => param.type)); |
| 2006 } | 2358 } |
| 2007 return result; | 2359 return result; |
| 2008 } | 2360 } |
| 2009 | 2361 |
| 2010 /** | 2362 /** |
| 2011 * Build the components of an [ElementLocationImpl] for the entity in the | |
| 2012 * given [unit] of the dependency located at [dependencyIndex], and having | |
| 2013 * the given [name]. | |
| 2014 */ | |
| 2015 List<String> getReferencedLocationComponents( | |
| 2016 int dependencyIndex, int unit, String name) { | |
| 2017 if (dependencyIndex == 0) { | |
| 2018 String referencedLibraryUri = librarySource.uri.toString(); | |
| 2019 String partUri; | |
| 2020 if (unit != 0) { | |
| 2021 String uri = unlinkedUnits[0].publicNamespace.parts[unit - 1]; | |
| 2022 Source partSource = | |
| 2023 summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri); | |
| 2024 partUri = partSource.uri.toString(); | |
| 2025 } else { | |
| 2026 partUri = referencedLibraryUri; | |
| 2027 } | |
| 2028 return <String>[referencedLibraryUri, partUri, name]; | |
| 2029 } | |
| 2030 LinkedDependency dependency = linkedLibrary.dependencies[dependencyIndex]; | |
| 2031 Source referencedLibrarySource = summaryResynthesizer.sourceFactory | |
| 2032 .resolveUri(librarySource, dependency.uri); | |
| 2033 String referencedLibraryUri = referencedLibrarySource.uri.toString(); | |
| 2034 String partUri; | |
| 2035 if (unit != 0) { | |
| 2036 String uri = dependency.parts[unit - 1]; | |
| 2037 Source partSource = summaryResynthesizer.sourceFactory | |
| 2038 .resolveUri(referencedLibrarySource, uri); | |
| 2039 partUri = partSource.uri.toString(); | |
| 2040 } else { | |
| 2041 partUri = referencedLibraryUri; | |
| 2042 } | |
| 2043 return <String>[referencedLibraryUri, partUri, name]; | |
| 2044 } | |
| 2045 | |
| 2046 /** | |
| 2047 * Get the type parameter from the surrounding scope whose De Bruijn index is | 2363 * Get the type parameter from the surrounding scope whose De Bruijn index is |
| 2048 * [index]. | 2364 * [index]. |
| 2049 */ | 2365 */ |
| 2050 DartType getTypeParameterFromScope(int index) { | 2366 DartType getTypeParameterFromScope(int index) { |
| 2051 for (int i = currentTypeParameters.length - 1; i >= 0; i--) { | 2367 for (int i = currentTypeParameters.length - 1; i >= 0; i--) { |
| 2052 List<TypeParameterElement> paramsAtThisNestingLevel = | 2368 List<TypeParameterElement> paramsAtThisNestingLevel = |
| 2053 currentTypeParameters[i]; | 2369 currentTypeParameters[i]; |
| 2054 int numParamsAtThisNestingLevel = paramsAtThisNestingLevel.length; | 2370 int numParamsAtThisNestingLevel = paramsAtThisNestingLevel.length; |
| 2055 if (index <= numParamsAtThisNestingLevel) { | 2371 if (index <= numParamsAtThisNestingLevel) { |
| 2056 return paramsAtThisNestingLevel[numParamsAtThisNestingLevel - index] | 2372 return paramsAtThisNestingLevel[numParamsAtThisNestingLevel - index] |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2099 element = null; | 2415 element = null; |
| 2100 } else { | 2416 } else { |
| 2101 List<String> locationComponents; | 2417 List<String> locationComponents; |
| 2102 if (enclosingInfo != null && enclosingInfo.element is ClassElement) { | 2418 if (enclosingInfo != null && enclosingInfo.element is ClassElement) { |
| 2103 String identifier = _getElementIdentifier(name, linkedReference.kind); | 2419 String identifier = _getElementIdentifier(name, linkedReference.kind); |
| 2104 locationComponents = | 2420 locationComponents = |
| 2105 enclosingInfo.element.location.components.toList(); | 2421 enclosingInfo.element.location.components.toList(); |
| 2106 locationComponents.add(identifier); | 2422 locationComponents.add(identifier); |
| 2107 } else { | 2423 } else { |
| 2108 String identifier = _getElementIdentifier(name, linkedReference.kind); | 2424 String identifier = _getElementIdentifier(name, linkedReference.kind); |
| 2109 locationComponents = getReferencedLocationComponents( | 2425 locationComponents = |
| 2110 linkedReference.dependency, linkedReference.unit, identifier); | 2426 libraryResynthesizer.getReferencedLocationComponents( |
| 2427 linkedReference.dependency, linkedReference.unit, identifier); | |
| 2111 } | 2428 } |
| 2112 ElementLocation location = | 2429 ElementLocation location = |
| 2113 new ElementLocationImpl.con3(locationComponents); | 2430 new ElementLocationImpl.con3(locationComponents); |
| 2114 if (enclosingInfo != null) { | 2431 if (enclosingInfo != null) { |
| 2115 numTypeParameters += enclosingInfo.numTypeParameters; | 2432 numTypeParameters += enclosingInfo.numTypeParameters; |
| 2116 } | 2433 } |
| 2117 switch (linkedReference.kind) { | 2434 switch (linkedReference.kind) { |
| 2118 case ReferenceKind.classOrEnum: | 2435 case ReferenceKind.classOrEnum: |
| 2119 element = new ClassElementHandle(summaryResynthesizer, location); | 2436 element = new ClassElementHandle(summaryResynthesizer, location); |
| 2120 break; | 2437 break; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2176 } | 2493 } |
| 2177 referenceInfos[i] = new _ReferenceInfo( | 2494 referenceInfos[i] = new _ReferenceInfo( |
| 2178 enclosingInfo, name, element, type, numTypeParameters); | 2495 enclosingInfo, name, element, type, numTypeParameters); |
| 2179 } | 2496 } |
| 2180 } | 2497 } |
| 2181 | 2498 |
| 2182 /** | 2499 /** |
| 2183 * Populate a [CompilationUnitElement] by deserializing all the elements | 2500 * Populate a [CompilationUnitElement] by deserializing all the elements |
| 2184 * contained in it. | 2501 * contained in it. |
| 2185 */ | 2502 */ |
| 2186 void populateUnit(CompilationUnitElementImpl unit, int unitNum) { | 2503 void populateUnit() { |
| 2187 unlinkedUnit.classes.forEach(buildClass); | 2504 unlinkedUnit.classes.forEach(buildClass); |
| 2188 unlinkedUnit.enums.forEach(buildEnum); | 2505 unlinkedUnit.enums.forEach(buildEnum); |
| 2189 unlinkedUnit.executables.forEach(buildExecutable); | 2506 unlinkedUnit.executables.forEach(buildExecutable); |
| 2190 unlinkedUnit.typedefs.forEach(buildTypedef); | 2507 unlinkedUnit.typedefs.forEach(buildTypedef); |
| 2191 unlinkedUnit.variables.forEach(buildVariable); | 2508 unlinkedUnit.variables.forEach(buildVariable); |
| 2192 String absoluteUri = unit.source.uri.toString(); | |
| 2193 unit.accessors = unitHolder.accessors; | 2509 unit.accessors = unitHolder.accessors; |
| 2194 unit.enums = unitHolder.enums; | 2510 unit.enums = unitHolder.enums; |
| 2195 unit.functions = unitHolder.functions; | 2511 unit.functions = unitHolder.functions; |
| 2196 List<FunctionTypeAliasElement> typeAliases = unitHolder.typeAliases; | 2512 List<FunctionTypeAliasElement> typeAliases = unitHolder.typeAliases; |
| 2197 for (FunctionTypeAliasElementImpl typeAlias in typeAliases) { | 2513 for (FunctionTypeAliasElementImpl typeAlias in typeAliases) { |
| 2198 if (typeAlias.isSynthetic) { | 2514 if (typeAlias.isSynthetic) { |
| 2199 typeAlias.enclosingElement = unit; | 2515 typeAlias.enclosingElement = unit; |
| 2200 } | 2516 } |
| 2201 } | 2517 } |
| 2202 unit.typeAliases = typeAliases.where((e) => !e.isSynthetic).toList(); | 2518 unit.typeAliases = typeAliases.where((e) => !e.isSynthetic).toList(); |
| 2203 unit.types = unitHolder.types; | 2519 unit.types = unitHolder.types; |
| 2204 unit.topLevelVariables = unitHolder.topLevelVariables; | 2520 unit.topLevelVariables = unitHolder.topLevelVariables; |
| 2205 Map<String, Element> elementMap = <String, Element>{}; | |
| 2206 for (ClassElement cls in unit.types) { | 2521 for (ClassElement cls in unit.types) { |
| 2207 elementMap[cls.name] = cls; | 2522 elementMap[cls.name] = cls; |
| 2208 } | 2523 } |
| 2209 for (ClassElement cls in unit.enums) { | 2524 for (ClassElement cls in unit.enums) { |
| 2210 elementMap[cls.name] = cls; | 2525 elementMap[cls.name] = cls; |
| 2211 } | 2526 } |
| 2212 for (FunctionTypeAliasElement typeAlias in unit.functionTypeAliases) { | 2527 for (FunctionTypeAliasElement typeAlias in unit.functionTypeAliases) { |
| 2213 elementMap[typeAlias.name] = typeAlias; | 2528 elementMap[typeAlias.name] = typeAlias; |
| 2214 } | 2529 } |
| 2215 for (FunctionElement function in unit.functions) { | 2530 for (FunctionElement function in unit.functions) { |
| 2216 elementMap[function.name] = function; | 2531 elementMap[function.name] = function; |
| 2217 } | 2532 } |
| 2218 for (PropertyAccessorElementImpl accessor in unit.accessors) { | 2533 for (PropertyAccessorElementImpl accessor in unit.accessors) { |
| 2219 elementMap[accessor.identifier] = accessor; | 2534 elementMap[accessor.identifier] = accessor; |
| 2220 } | 2535 } |
| 2221 buildCodeRange(unit, unlinkedUnit.codeRange); | 2536 buildCodeRange(unit, unlinkedUnit.codeRange); |
| 2222 resynthesizedUnits[absoluteUri] = unit; | |
| 2223 resynthesizedElements[absoluteUri] = elementMap; | |
| 2224 assert(currentTypeParameters.isEmpty); | 2537 assert(currentTypeParameters.isEmpty); |
| 2225 } | 2538 } |
| 2226 | 2539 |
| 2227 /** | 2540 /** |
| 2228 * Set up data structures for deserializing a compilation unit. | |
| 2229 */ | |
| 2230 void prepareUnit(CompilationUnitElementImpl unit, int unitNum) { | |
| 2231 linkedUnit = linkedLibrary.units[unitNum]; | |
| 2232 unlinkedUnit = unlinkedUnits[unitNum]; | |
| 2233 linkedTypeMap = <int, EntityRef>{}; | |
| 2234 currentCompilationUnit = unit; | |
| 2235 for (EntityRef t in linkedUnit.types) { | |
| 2236 linkedTypeMap[t.slot] = t; | |
| 2237 } | |
| 2238 constCycles = linkedUnit.constCycles.toSet(); | |
| 2239 populateReferenceInfos(); | |
| 2240 unitHolder = new ElementHolder(); | |
| 2241 } | |
| 2242 | |
| 2243 /** | |
| 2244 * Constructor initializers can reference fields and other constructors of | 2541 * Constructor initializers can reference fields and other constructors of |
| 2245 * the same class, including forward references. So, we need to delay | 2542 * the same class, including forward references. So, we need to delay |
| 2246 * resolution until after class elements are built. | 2543 * resolution until after class elements are built. |
| 2247 */ | 2544 */ |
| 2248 void resolveConstructorInitializers(ClassElementImpl classElement) { | 2545 void resolveConstructorInitializers(ClassElementImpl classElement) { |
| 2249 for (ConstructorElementImpl constructor in constructors.values) { | 2546 for (ConstructorElementImpl constructor in constructors.values) { |
| 2250 for (ConstructorInitializer initializer | 2547 for (ConstructorInitializer initializer |
| 2251 in constructor.constantInitializers) { | 2548 in constructor.constantInitializers) { |
| 2252 if (initializer is ConstructorFieldInitializer) { | 2549 if (initializer is ConstructorFieldInitializer) { |
| 2253 SimpleIdentifier nameNode = initializer.fieldName; | 2550 SimpleIdentifier nameNode = initializer.fieldName; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2326 static String _getElementIdentifier(String name, ReferenceKind kind) { | 2623 static String _getElementIdentifier(String name, ReferenceKind kind) { |
| 2327 if (kind == ReferenceKind.topLevelPropertyAccessor || | 2624 if (kind == ReferenceKind.topLevelPropertyAccessor || |
| 2328 kind == ReferenceKind.propertyAccessor) { | 2625 kind == ReferenceKind.propertyAccessor) { |
| 2329 if (!name.endsWith('=')) { | 2626 if (!name.endsWith('=')) { |
| 2330 return name + '?'; | 2627 return name + '?'; |
| 2331 } | 2628 } |
| 2332 } | 2629 } |
| 2333 return name; | 2630 return name; |
| 2334 } | 2631 } |
| 2335 } | 2632 } |
| 2336 | |
| 2337 /** | |
| 2338 * Data structure used during resynthesis to record all the information that is | |
| 2339 * known about how to resynthesize a single entry in [LinkedUnit.references] | |
| 2340 * (and its associated entry in [UnlinkedUnit.references], if it exists). | |
| 2341 */ | |
| 2342 class _ReferenceInfo { | |
| 2343 /** | |
| 2344 * The enclosing [_ReferenceInfo], or `null` for top-level elements. | |
| 2345 */ | |
| 2346 final _ReferenceInfo enclosing; | |
| 2347 | |
| 2348 /** | |
| 2349 * The name of the entity referred to by this reference. | |
| 2350 */ | |
| 2351 final String name; | |
| 2352 | |
| 2353 /** | |
| 2354 * The element referred to by this reference, or `null` if there is no | |
| 2355 * associated element (e.g. because it is a reference to an undefined | |
| 2356 * entity). | |
| 2357 */ | |
| 2358 final Element element; | |
| 2359 | |
| 2360 /** | |
| 2361 * If this reference refers to a non-generic type, the type it refers to. | |
| 2362 * Otherwise `null`. | |
| 2363 */ | |
| 2364 DartType type; | |
| 2365 | |
| 2366 /** | |
| 2367 * The number of type parameters accepted by the entity referred to by this | |
| 2368 * reference, or zero if it doesn't accept any type parameters. | |
| 2369 */ | |
| 2370 final int numTypeParameters; | |
| 2371 | |
| 2372 /** | |
| 2373 * Create a new [_ReferenceInfo] object referring to an element called [name] | |
| 2374 * via the element handle [element], and having [numTypeParameters] type | |
| 2375 * parameters. | |
| 2376 * | |
| 2377 * For the special types `dynamic` and `void`, [specialType] should point to | |
| 2378 * the type itself. Otherwise, pass `null` and the type will be computed | |
| 2379 * when appropriate. | |
| 2380 */ | |
| 2381 _ReferenceInfo(this.enclosing, this.name, this.element, DartType specialType, | |
| 2382 this.numTypeParameters) { | |
| 2383 if (specialType != null) { | |
| 2384 type = specialType; | |
| 2385 } else { | |
| 2386 type = _buildType((_) => DynamicTypeImpl.instance, const []); | |
| 2387 } | |
| 2388 } | |
| 2389 | |
| 2390 /** | |
| 2391 * Build a [DartType] corresponding to the result of applying some type | |
| 2392 * arguments to the entity referred to by this [_ReferenceInfo]. The type | |
| 2393 * arguments are retrieved by calling [getTypeArgument]. | |
| 2394 * | |
| 2395 * If [implicitFunctionTypeIndices] is not empty, a [DartType] should be | |
| 2396 * created which refers to a function type implicitly defined by one of the | |
| 2397 * element's parameters. [implicitFunctionTypeIndices] is interpreted as in | |
| 2398 * [EntityRef.implicitFunctionTypeIndices]. | |
| 2399 * | |
| 2400 * If the entity referred to by this [_ReferenceInfo] is not a type, `null` | |
| 2401 * is returned. | |
| 2402 */ | |
| 2403 DartType buildType( | |
| 2404 DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) { | |
| 2405 DartType result = | |
| 2406 (numTypeParameters == 0 && implicitFunctionTypeIndices.isEmpty) | |
| 2407 ? type | |
| 2408 : _buildType(getTypeArgument, implicitFunctionTypeIndices); | |
| 2409 if (result == null) { | |
| 2410 // TODO(paulberry): figure out how to handle this case (which should | |
| 2411 // only occur in the event of erroneous code). | |
| 2412 throw new UnimplementedError(); | |
| 2413 } | |
| 2414 return result; | |
| 2415 } | |
| 2416 | |
| 2417 /** | |
| 2418 * If this reference refers to a type, build a [DartType] which instantiates | |
| 2419 * it with type arguments returned by [getTypeArgument]. Otherwise return | |
| 2420 * `null`. | |
| 2421 * | |
| 2422 * If [implicitFunctionTypeIndices] is not null, a [DartType] should be | |
| 2423 * created which refers to a function type implicitly defined by one of the | |
| 2424 * element's parameters. [implicitFunctionTypeIndices] is interpreted as in | |
| 2425 * [EntityRef.implicitFunctionTypeIndices]. | |
| 2426 */ | |
| 2427 DartType _buildType( | |
| 2428 DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) { | |
| 2429 ElementHandle element = this.element; // To allow type promotion | |
| 2430 if (element is ClassElementHandle) { | |
| 2431 return new InterfaceTypeImpl.elementWithNameAndArgs(element, name, | |
| 2432 _buildTypeArguments(numTypeParameters, getTypeArgument)); | |
| 2433 } else if (element is FunctionTypeAliasElementHandle) { | |
| 2434 return new FunctionTypeImpl.elementWithNameAndArgs( | |
| 2435 element, | |
| 2436 name, | |
| 2437 _buildTypeArguments(numTypeParameters, getTypeArgument), | |
| 2438 numTypeParameters != 0); | |
| 2439 } else if (element is FunctionTypedElement) { | |
| 2440 int numTypeArguments; | |
| 2441 FunctionTypedElementComputer computer; | |
| 2442 if (implicitFunctionTypeIndices.isNotEmpty) { | |
| 2443 numTypeArguments = numTypeParameters; | |
| 2444 computer = () { | |
| 2445 FunctionTypedElement element = this.element; | |
| 2446 for (int index in implicitFunctionTypeIndices) { | |
| 2447 element = element.parameters[index].type.element; | |
| 2448 } | |
| 2449 return element; | |
| 2450 }; | |
| 2451 } else { | |
| 2452 // For a type that refers to a generic executable, the type arguments ar e | |
| 2453 // not supposed to include the arguments to the executable itself. | |
| 2454 numTypeArguments = enclosing == null ? 0 : enclosing.numTypeParameters; | |
| 2455 computer = () => this.element; | |
| 2456 } | |
| 2457 // TODO(paulberry): Is it a bug that we have to pass `false` for | |
| 2458 // isInstantiated? | |
| 2459 return new DeferredFunctionTypeImpl(computer, null, | |
| 2460 _buildTypeArguments(numTypeArguments, getTypeArgument), false); | |
| 2461 } else { | |
| 2462 return null; | |
| 2463 } | |
| 2464 } | |
| 2465 | |
| 2466 /** | |
| 2467 * Build a list of type arguments having length [numTypeArguments] where each | |
| 2468 * type argument is obtained by calling [getTypeArgument]. | |
| 2469 */ | |
| 2470 List<DartType> _buildTypeArguments( | |
| 2471 int numTypeArguments, DartType getTypeArgument(int i)) { | |
| 2472 List<DartType> typeArguments = const <DartType>[]; | |
| 2473 if (numTypeArguments != 0) { | |
| 2474 typeArguments = <DartType>[]; | |
| 2475 for (int i = 0; i < numTypeArguments; i++) { | |
| 2476 typeArguments.add(getTypeArgument(i)); | |
| 2477 } | |
| 2478 } | |
| 2479 return typeArguments; | |
| 2480 } | |
| 2481 } | |
| OLD | NEW |