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

Side by Side Diff: pkg/analyzer/lib/src/summary/resynthesize.dart

Issue 1833743002: Resynthesize _DeferredClassElement instead of actual ClassElementImpl. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698