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

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

Issue 1995763003: Build top-level variables and property accessors lazily. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fixes for review comments. Created 4 years, 7 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 * Indicates whether the summary should be resynthesized assuming strong mode 55 * Indicates whether the summary should be resynthesized assuming strong mode
56 * semantics. 56 * semantics.
57 */ 57 */
58 final bool strongMode; 58 final bool strongMode;
59 59
60 /** 60 /**
61 * Map of compilation units resynthesized from summaries. The two map keys 61 * Map of compilation units resynthesized from summaries. The two map keys
62 * are the first two elements of the element's location (the library URI and 62 * are the first two elements of the element's location (the library URI and
63 * the compilation unit URI). 63 * the compilation unit URI).
64 */ 64 */
65 final Map<String, Map<String, CompilationUnitElement>> _resynthesizedUnits = 65 final Map<String, Map<String, CompilationUnitElementImpl>>
66 <String, Map<String, CompilationUnitElement>>{}; 66 _resynthesizedUnits = <String, Map<String, CompilationUnitElementImpl>>{};
67 67
68 /** 68 /**
69 * Map of top level elements resynthesized from summaries. The three map 69 * Map of top level elements resynthesized from summaries. The three map
70 * keys are the first three elements of the element's location (the library 70 * keys are the first three elements of the element's location (the library
71 * URI, the compilation unit URI, and the name of the top level declaration). 71 * URI, the compilation unit URI, and the name of the top level declaration).
72 */ 72 */
73 final Map<String, Map<String, Map<String, Element>>> _resynthesizedElements = 73 final Map<String, Map<String, Map<String, Element>>> _resynthesizedElements =
74 <String, Map<String, Map<String, Element>>>{}; 74 <String, Map<String, Map<String, Element>>>{};
75 75
76 /** 76 /**
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 libraryMap = _resynthesizedUnits[libraryUri]; 118 libraryMap = _resynthesizedUnits[libraryUri];
119 assert(libraryMap != null); 119 assert(libraryMap != null);
120 } 120 }
121 String unitUri = components[1]; 121 String unitUri = components[1];
122 CompilationUnitElement element = libraryMap[unitUri]; 122 CompilationUnitElement element = libraryMap[unitUri];
123 if (element == null) { 123 if (element == null) {
124 throw new Exception('Unit element not found in summary: $location'); 124 throw new Exception('Unit element not found in summary: $location');
125 } 125 }
126 return element; 126 return element;
127 } else if (components.length == 3 || components.length == 4) { 127 } else if (components.length == 3 || components.length == 4) {
128 Map<String, Map<String, Element>> libraryMap = 128 String unitUri = components[1];
129 // Prepare elements-in-units in the library.
130 Map<String, Map<String, Element>> unitsInLibrary =
129 _resynthesizedElements[libraryUri]; 131 _resynthesizedElements[libraryUri];
130 if (libraryMap == null) { 132 if (unitsInLibrary == null) {
131 getLibraryElement(libraryUri); 133 unitsInLibrary = new HashMap<String, Map<String, Element>>();
132 libraryMap = _resynthesizedElements[libraryUri]; 134 _resynthesizedElements[libraryUri] = unitsInLibrary;
133 assert(libraryMap != null);
134 } 135 }
135 Map<String, Element> compilationUnitElements = libraryMap[components[1]]; 136 // Prepare elements in the unit.
136 Element element; 137 Map<String, Element> elementsInUnit = unitsInLibrary[unitUri];
137 if (compilationUnitElements != null) { 138 if (elementsInUnit == null) {
138 element = compilationUnitElements[components[2]]; 139 // Prepare the CompilationUnitElementImpl.
140 Map<String, CompilationUnitElementImpl> libraryMap =
141 _resynthesizedUnits[libraryUri];
142 if (libraryMap == null) {
143 getLibraryElement(libraryUri);
144 libraryMap = _resynthesizedUnits[libraryUri];
145 assert(libraryMap != null);
146 }
147 CompilationUnitElementImpl unitElement = libraryMap[unitUri];
148 // Fill elements in the unit map.
149 if (unitElement != null) {
150 elementsInUnit = new HashMap<String, Element>();
151 void putElement(Element e) {
152 String id =
153 e is PropertyAccessorElementImpl ? e.identifier : e.name;
154 elementsInUnit[id] = e;
155 }
156 unitElement.accessors.forEach(putElement);
157 unitElement.enums.forEach(putElement);
158 unitElement.functions.forEach(putElement);
159 unitElement.functionTypeAliases.forEach(putElement);
160 unitElement.topLevelVariables.forEach(putElement);
161 unitElement.types.forEach(putElement);
162 unitsInLibrary[unitUri] = elementsInUnit;
163 }
139 } 164 }
165 // Get the element.
166 Element element = elementsInUnit[components[2]];
140 if (element != null && components.length == 4) { 167 if (element != null && components.length == 4) {
141 String name = components[3]; 168 String name = components[3];
142 Element parentElement = element; 169 Element parentElement = element;
143 if (parentElement is ClassElement) { 170 if (parentElement is ClassElement) {
144 if (name.endsWith('?')) { 171 if (name.endsWith('?')) {
145 element = 172 element =
146 parentElement.getGetter(name.substring(0, name.length - 1)); 173 parentElement.getGetter(name.substring(0, name.length - 1));
147 } else if (name.endsWith('=')) { 174 } else if (name.endsWith('=')) {
148 element = 175 element =
149 parentElement.getSetter(name.substring(0, name.length - 1)); 176 parentElement.getSetter(name.substring(0, name.length - 1));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 Source librarySource = _getSource(uri); 213 Source librarySource = _getSource(uri);
187 for (String part in serializedUnits[0].publicNamespace.parts) { 214 for (String part in serializedUnits[0].publicNamespace.parts) {
188 Source partSource = sourceFactory.resolveUri(librarySource, part); 215 Source partSource = sourceFactory.resolveUri(librarySource, part);
189 String partAbsUri = partSource.uri.toString(); 216 String partAbsUri = partSource.uri.toString();
190 serializedUnits.add(_getUnlinkedSummaryOrThrow(partAbsUri)); 217 serializedUnits.add(_getUnlinkedSummaryOrThrow(partAbsUri));
191 } 218 }
192 _LibraryResynthesizer libraryResynthesizer = new _LibraryResynthesizer( 219 _LibraryResynthesizer libraryResynthesizer = new _LibraryResynthesizer(
193 this, serializedLibrary, serializedUnits, librarySource); 220 this, serializedLibrary, serializedUnits, librarySource);
194 LibraryElement library = libraryResynthesizer.buildLibrary(); 221 LibraryElement library = libraryResynthesizer.buildLibrary();
195 _resynthesizedUnits[uri] = libraryResynthesizer.resynthesizedUnits; 222 _resynthesizedUnits[uri] = libraryResynthesizer.resynthesizedUnits;
196 _resynthesizedElements[uri] = libraryResynthesizer.resynthesizedElements;
197 return library; 223 return library;
198 }); 224 });
199 } 225 }
200 226
201 /** 227 /**
202 * Return the [LinkedLibrary] for the given [uri] or `null` if it could not 228 * Return the [LinkedLibrary] for the given [uri] or `null` if it could not
203 * be found. Caller has already checked that `parent.hasLibrarySummary(uri)` 229 * be found. Caller has already checked that `parent.hasLibrarySummary(uri)`
204 * returns `false`. 230 * returns `false`.
205 */ 231 */
206 LinkedLibrary getLinkedSummary(String uri); 232 LinkedLibrary getLinkedSummary(String uri);
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 /** 1044 /**
1019 * Classes which should have their supertype set to "object" once 1045 * Classes which should have their supertype set to "object" once
1020 * resynthesis is complete. Only used if [isCoreLibrary] is `true`. 1046 * resynthesis is complete. Only used if [isCoreLibrary] is `true`.
1021 */ 1047 */
1022 List<ClassElementImpl> delayedObjectSubclasses = <ClassElementImpl>[]; 1048 List<ClassElementImpl> delayedObjectSubclasses = <ClassElementImpl>[];
1023 1049
1024 /** 1050 /**
1025 * Map of compilation unit elements that have been resynthesized so far. The 1051 * Map of compilation unit elements that have been resynthesized so far. The
1026 * key is the URI of the compilation unit. 1052 * key is the URI of the compilation unit.
1027 */ 1053 */
1028 final Map<String, CompilationUnitElement> resynthesizedUnits = 1054 final Map<String, CompilationUnitElementImpl> resynthesizedUnits =
1029 <String, CompilationUnitElement>{}; 1055 <String, CompilationUnitElementImpl>{};
1030
1031 /**
1032 * Map of top level elements that have been resynthesized so far. The first
1033 * key is the URI of the compilation unit; the second is the name of the top
1034 * level element.
1035 */
1036 final Map<String, Map<String, Element>> resynthesizedElements =
1037 <String, Map<String, Element>>{};
1038 1056
1039 /** 1057 /**
1040 * Types with implicit type arguments, which are the same as type parameter 1058 * Types with implicit type arguments, which are the same as type parameter
1041 * bounds (in strong mode), or `dynamic` (in spec mode). 1059 * bounds (in strong mode), or `dynamic` (in spec mode).
1042 */ 1060 */
1043 final Set<DartType> typesWithImplicitTypeArguments = 1061 final Set<DartType> typesWithImplicitTypeArguments =
1044 new Set<DartType>.identity(); 1062 new Set<DartType>.identity();
1045 1063
1046 _LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary, 1064 _LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary,
1047 this.unlinkedUnits, this.librarySource) { 1065 this.unlinkedUnits, this.librarySource) {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1195 serializedImport.combinators.map(buildCombinator).toList(); 1213 serializedImport.combinators.map(buildCombinator).toList();
1196 return importElement; 1214 return importElement;
1197 } 1215 }
1198 1216
1199 /** 1217 /**
1200 * Main entry point. Resynthesize the [LibraryElement] and return it. 1218 * Main entry point. Resynthesize the [LibraryElement] and return it.
1201 */ 1219 */
1202 LibraryElement buildLibrary() { 1220 LibraryElement buildLibrary() {
1203 // Create LibraryElementImpl. 1221 // Create LibraryElementImpl.
1204 bool hasName = unlinkedUnits[0].libraryName.isNotEmpty; 1222 bool hasName = unlinkedUnits[0].libraryName.isNotEmpty;
1205 library = new LibraryElementImpl( 1223 library = new LibraryElementImpl.forSerialized(
1206 summaryResynthesizer.context, 1224 summaryResynthesizer.context,
1207 unlinkedUnits[0].libraryName, 1225 unlinkedUnits[0].libraryName,
1208 hasName ? unlinkedUnits[0].libraryNameOffset : -1, 1226 hasName ? unlinkedUnits[0].libraryNameOffset : -1,
1209 unlinkedUnits[0].libraryNameLength); 1227 unlinkedUnits[0].libraryNameLength,
1228 new _LibraryResynthesizerContext(this),
1229 unlinkedUnits[0]);
1210 // Create the defining unit. 1230 // Create the defining unit.
1211 _UnitResynthesizer definingUnitResynthesizer = 1231 _UnitResynthesizer definingUnitResynthesizer =
1212 createUnitResynthesizer(0, librarySource, null); 1232 createUnitResynthesizer(0, librarySource, null);
1213 CompilationUnitElementImpl definingUnit = definingUnitResynthesizer.unit; 1233 CompilationUnitElementImpl definingUnit = definingUnitResynthesizer.unit;
1214 definingUnitResynthesizer.buildDocumentation(
1215 library, unlinkedUnits[0].libraryDocumentationComment);
1216 definingUnitResynthesizer.buildAnnotations(
1217 library, unlinkedUnits[0].libraryAnnotations);
1218 library.definingCompilationUnit = definingUnit; 1234 library.definingCompilationUnit = definingUnit;
1219 definingUnit.source = librarySource; 1235 definingUnit.source = librarySource;
1220 definingUnit.librarySource = librarySource; 1236 definingUnit.librarySource = librarySource;
1221 // Create parts. 1237 // Create parts.
1222 List<_UnitResynthesizer> partResynthesizers = <_UnitResynthesizer>[]; 1238 List<_UnitResynthesizer> partResynthesizers = <_UnitResynthesizer>[];
1223 UnlinkedUnit unlinkedDefiningUnit = unlinkedUnits[0]; 1239 UnlinkedUnit unlinkedDefiningUnit = unlinkedUnits[0];
1224 assert(unlinkedDefiningUnit.publicNamespace.parts.length + 1 == 1240 assert(unlinkedDefiningUnit.publicNamespace.parts.length + 1 ==
1225 linkedLibrary.units.length); 1241 linkedLibrary.units.length);
1226 for (int i = 1; i < linkedLibrary.units.length; i++) { 1242 for (int i = 1; i < linkedLibrary.units.length; i++) {
1227 _UnitResynthesizer partResynthesizer = buildPart( 1243 _UnitResynthesizer partResynthesizer = buildPart(
(...skipping 23 matching lines...) Expand all
1251 definingUnitResynthesizer, 1267 definingUnitResynthesizer,
1252 unlinkedDefiningUnit.publicNamespace.exports[i], 1268 unlinkedDefiningUnit.publicNamespace.exports[i],
1253 unlinkedDefiningUnit.exports[i])); 1269 unlinkedDefiningUnit.exports[i]));
1254 } 1270 }
1255 library.exports = exports; 1271 library.exports = exports;
1256 // Populate units. 1272 // Populate units.
1257 populateUnit(definingUnitResynthesizer); 1273 populateUnit(definingUnitResynthesizer);
1258 for (_UnitResynthesizer partResynthesizer in partResynthesizers) { 1274 for (_UnitResynthesizer partResynthesizer in partResynthesizers) {
1259 populateUnit(partResynthesizer); 1275 populateUnit(partResynthesizer);
1260 } 1276 }
1261 BuildLibraryElementUtils.patchTopLevelAccessors(library);
1262 // Update delayed Object class references. 1277 // Update delayed Object class references.
1263 if (isCoreLibrary) { 1278 if (isCoreLibrary) {
1264 ClassElement objectElement = library.getType('Object'); 1279 ClassElement objectElement = library.getType('Object');
1265 assert(objectElement != null); 1280 assert(objectElement != null);
1266 for (ClassElementImpl classElement in delayedObjectSubclasses) { 1281 for (ClassElementImpl classElement in delayedObjectSubclasses) {
1267 classElement.supertype = objectElement.type; 1282 classElement.supertype = objectElement.type;
1268 } 1283 }
1269 } 1284 }
1270 // Compute namespaces.
1271 library.publicNamespace =
1272 new NamespaceBuilder().createPublicNamespaceForLibrary(library);
1273 library.exportNamespace = buildExportNamespace(
1274 library.publicNamespace, linkedLibrary.exportNames);
1275 // Find the entry point. Note: we can't use element.isEntryPoint because
1276 // that will trigger resynthesis of exported libraries.
1277 Element entryPoint =
1278 library.exportNamespace.get(FunctionElement.MAIN_FUNCTION_NAME);
1279 if (entryPoint is FunctionElement) {
1280 library.entryPoint = entryPoint;
1281 }
1282 // Create the synthetic element for `loadLibrary`. 1285 // Create the synthetic element for `loadLibrary`.
1283 // Until the client received dart:core and dart:async, we cannot do this, 1286 // Until the client received dart:core and dart:async, we cannot do this,
1284 // because the TypeProvider is not fully initialized. So, it is up to the 1287 // because the TypeProvider is not fully initialized. So, it is up to the
1285 // Dart SDK client to initialize TypeProvider and finish the dart:core and 1288 // Dart SDK client to initialize TypeProvider and finish the dart:core and
1286 // dart:async libraries creation. 1289 // dart:async libraries creation.
1287 if (library.name != 'dart.core' && library.name != 'dart.async') { 1290 if (library.name != 'dart.core' && library.name != 'dart.async') {
1288 library.createLoadLibraryFunction(summaryResynthesizer.typeProvider); 1291 library.createLoadLibraryFunction(summaryResynthesizer.typeProvider);
1289 } 1292 }
1290 // Done. 1293 // Done.
1291 return library; 1294 return library;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 1362
1360 /** 1363 /**
1361 * Populate a [CompilationUnitElement] by deserializing all the elements 1364 * Populate a [CompilationUnitElement] by deserializing all the elements
1362 * contained in it. 1365 * contained in it.
1363 */ 1366 */
1364 void populateUnit(_UnitResynthesizer unitResynthesized) { 1367 void populateUnit(_UnitResynthesizer unitResynthesized) {
1365 // TODO(scheglov) 1368 // TODO(scheglov)
1366 unitResynthesized.populateUnit(); 1369 unitResynthesized.populateUnit();
1367 String absoluteUri = unitResynthesized.unit.source.uri.toString(); 1370 String absoluteUri = unitResynthesized.unit.source.uri.toString();
1368 resynthesizedUnits[absoluteUri] = unitResynthesized.unit; 1371 resynthesizedUnits[absoluteUri] = unitResynthesized.unit;
1369 resynthesizedElements[absoluteUri] = unitResynthesized.elementMap;
1370 } 1372 }
1371 } 1373 }
1372 1374
1375 /**
1376 * Implementation of [LibraryResynthesizerContext] for [_LibraryResynthesizer].
1377 */
1378 class _LibraryResynthesizerContext implements LibraryResynthesizerContext {
1379 final _LibraryResynthesizer resynthesizer;
1380
1381 _LibraryResynthesizerContext(this.resynthesizer);
1382
1383 @override
1384 Namespace buildExportNamespace() {
1385 LibraryElementImpl library = resynthesizer.library;
1386 return resynthesizer.buildExportNamespace(
1387 library.publicNamespace, resynthesizer.linkedLibrary.exportNames);
1388 }
1389
1390 @override
1391 Namespace buildPublicNamespace() {
1392 LibraryElementImpl library = resynthesizer.library;
1393 return new NamespaceBuilder().createPublicNamespaceForLibrary(library);
1394 }
1395
1396 @override
1397 FunctionElement findEntryPoint() {
1398 LibraryElementImpl library = resynthesizer.library;
1399 Element entryPoint =
1400 library.exportNamespace.get(FunctionElement.MAIN_FUNCTION_NAME);
1401 if (entryPoint is FunctionElement) {
1402 return entryPoint;
1403 }
1404 return null;
1405 }
1406
1407 @override
1408 void patchTopLevelAccessors() {
1409 LibraryElementImpl library = resynthesizer.library;
1410 BuildLibraryElementUtils.patchTopLevelAccessors(library);
1411 }
1412 }
1413
1373 /** 1414 /**
1374 * Data structure used during resynthesis to record all the information that is 1415 * Data structure used during resynthesis to record all the information that is
1375 * known about how to resynthesize a single entry in [LinkedUnit.references] 1416 * known about how to resynthesize a single entry in [LinkedUnit.references]
1376 * (and its associated entry in [UnlinkedUnit.references], if it exists). 1417 * (and its associated entry in [UnlinkedUnit.references], if it exists).
1377 */ 1418 */
1378 class _ReferenceInfo { 1419 class _ReferenceInfo {
1379 /** 1420 /**
1380 * The [_LibraryResynthesizer] which is being used to obtain summaries. 1421 * The [_LibraryResynthesizer] which is being used to obtain summaries.
1381 */ 1422 */
1382 final _LibraryResynthesizer libraryResynthesizer; 1423 final _LibraryResynthesizer libraryResynthesizer;
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1561 ElementAnnotationImpl buildAnnotation(UnlinkedConst uc) { 1602 ElementAnnotationImpl buildAnnotation(UnlinkedConst uc) {
1562 return _unitResynthesizer.buildAnnotation(uc); 1603 return _unitResynthesizer.buildAnnotation(uc);
1563 } 1604 }
1564 1605
1565 @override 1606 @override
1566 Expression buildExpression(UnlinkedConst uc) { 1607 Expression buildExpression(UnlinkedConst uc) {
1567 return _unitResynthesizer._buildConstExpression(uc); 1608 return _unitResynthesizer._buildConstExpression(uc);
1568 } 1609 }
1569 1610
1570 @override 1611 @override
1612 UnitExplicitTopLevelAccessors buildTopLevelAccessors() {
1613 return _unitResynthesizer.buildUnitExplicitTopLevelAccessors();
1614 }
1615
1616 @override
1617 UnitExplicitTopLevelVariables buildTopLevelVariables() {
1618 return _unitResynthesizer.buildUnitExplicitTopLevelVariables();
1619 }
1620
1621 @override
1571 DartType resolveTypeRef( 1622 DartType resolveTypeRef(
1572 EntityRef type, TypeParameterizedElementMixin typeParameterContext, 1623 EntityRef type, TypeParameterizedElementMixin typeParameterContext,
1573 {bool defaultVoid: false, bool instantiateToBoundsAllowed: true}) { 1624 {bool defaultVoid: false, bool instantiateToBoundsAllowed: true}) {
1574 return _unitResynthesizer.buildType(type, typeParameterContext, 1625 return _unitResynthesizer.buildType(type, typeParameterContext,
1575 defaultVoid: defaultVoid, 1626 defaultVoid: defaultVoid,
1576 instantiateToBoundsAllowed: instantiateToBoundsAllowed); 1627 instantiateToBoundsAllowed: instantiateToBoundsAllowed);
1577 } 1628 }
1578 } 1629 }
1579 1630
1580 /** 1631 /**
(...skipping 23 matching lines...) Expand all
1604 CompilationUnitElementImpl unit; 1655 CompilationUnitElementImpl unit;
1605 1656
1606 /** 1657 /**
1607 * [ElementHolder] into which resynthesized elements should be placed. This 1658 * [ElementHolder] into which resynthesized elements should be placed. This
1608 * object is recreated afresh for each unit in the library, and is used to 1659 * object is recreated afresh for each unit in the library, and is used to
1609 * populate the [CompilationUnitElement]. 1660 * populate the [CompilationUnitElement].
1610 */ 1661 */
1611 final ElementHolder unitHolder = new ElementHolder(); 1662 final ElementHolder unitHolder = new ElementHolder();
1612 1663
1613 /** 1664 /**
1614 * Map of top-level elements that have been resynthesized so far. The key is
1615 * the name of the top level element.
1616 */
1617 Map<String, Element> elementMap = <String, Element>{};
1618
1619 /**
1620 * Map from slot id to the corresponding [EntityRef] object for linked types 1665 * Map from slot id to the corresponding [EntityRef] object for linked types
1621 * (i.e. propagated and inferred types). 1666 * (i.e. propagated and inferred types).
1622 */ 1667 */
1623 final Map<int, EntityRef> linkedTypeMap = <int, EntityRef>{}; 1668 final Map<int, EntityRef> linkedTypeMap = <int, EntityRef>{};
1624 1669
1625 /** 1670 /**
1626 * Set of slot ids corresponding to const constructors that are part of 1671 * Set of slot ids corresponding to const constructors that are part of
1627 * cycles. 1672 * cycles.
1628 */ 1673 */
1629 Set<int> constCycles; 1674 Set<int> constCycles;
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
2067 } else { 2112 } else {
2068 MethodElementImpl executableElement = 2113 MethodElementImpl executableElement =
2069 new MethodElementImpl.forSerialized( 2114 new MethodElementImpl.forSerialized(
2070 serializedExecutable, enclosingElement); 2115 serializedExecutable, enclosingElement);
2071 buildExecutableCommonParts(executableElement, serializedExecutable); 2116 buildExecutableCommonParts(executableElement, serializedExecutable);
2072 holder.addMethod(executableElement); 2117 holder.addMethod(executableElement);
2073 } 2118 }
2074 break; 2119 break;
2075 case UnlinkedExecutableKind.getter: 2120 case UnlinkedExecutableKind.getter:
2076 case UnlinkedExecutableKind.setter: 2121 case UnlinkedExecutableKind.setter:
2122 // Top-level accessors are created lazily.
2123 if (isTopLevel) {
2124 break;
2125 }
2126 // Class member accessors.
2077 PropertyAccessorElementImpl executableElement = 2127 PropertyAccessorElementImpl executableElement =
2078 new PropertyAccessorElementImpl.forSerialized( 2128 new PropertyAccessorElementImpl.forSerialized(
2079 serializedExecutable, enclosingElement); 2129 serializedExecutable, enclosingElement);
2080 buildExecutableCommonParts(executableElement, serializedExecutable); 2130 buildExecutableCommonParts(executableElement, serializedExecutable);
2081 DartType type; 2131 DartType type;
2082 if (kind == UnlinkedExecutableKind.getter) { 2132 if (kind == UnlinkedExecutableKind.getter) {
2083 type = executableElement.returnType; 2133 type = executableElement.returnType;
2084 } else { 2134 } else {
2085 type = executableElement.parameters[0].type; 2135 type = executableElement.parameters[0].type;
2086 } 2136 }
2087 holder.addAccessor(executableElement); 2137 holder.addAccessor(executableElement);
2088 PropertyInducingElementImpl implicitVariable; 2138 FieldElementImpl field = buildImplicitField(name, type, kind, holder);
2089 if (isTopLevel) { 2139 field.static = serializedExecutable.isStatic;
2090 implicitVariable = buildImplicitTopLevelVariable(name, kind, holder); 2140 executableElement.variable = field;
2141 if (kind == UnlinkedExecutableKind.getter) {
2142 field.getter = executableElement;
2091 } else { 2143 } else {
2092 FieldElementImpl field = buildImplicitField(name, type, kind, holder); 2144 field.setter = executableElement;
2093 field.static = serializedExecutable.isStatic;
2094 implicitVariable = field;
2095 }
2096 executableElement.variable = implicitVariable;
2097 if (kind == UnlinkedExecutableKind.getter) {
2098 implicitVariable.getter = executableElement;
2099 } else {
2100 implicitVariable.setter = executableElement;
2101 } 2145 }
2102 break; 2146 break;
2103 default: 2147 default:
2104 // The only other executable type is a constructor, and that is handled 2148 // The only other executable type is a constructor, and that is handled
2105 // separately (in [buildConstructor]. So this code should be 2149 // separately (in [buildConstructor]. So this code should be
2106 // unreachable. 2150 // unreachable.
2107 assert(false); 2151 assert(false);
2108 } 2152 }
2109 } 2153 }
2110 2154
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2147 2191
2148 /** 2192 /**
2149 * Build the implicit getter and setter associated with [element], and place 2193 * Build the implicit getter and setter associated with [element], and place
2150 * them in [holder]. 2194 * them in [holder].
2151 */ 2195 */
2152 void buildImplicitAccessors( 2196 void buildImplicitAccessors(
2153 PropertyInducingElementImpl element, ElementHolder holder) { 2197 PropertyInducingElementImpl element, ElementHolder holder) {
2154 String name = element.name; 2198 String name = element.name;
2155 DartType type = element.type; 2199 DartType type = element.type;
2156 PropertyAccessorElementImpl getter = 2200 PropertyAccessorElementImpl getter =
2157 new PropertyAccessorElementImpl(name, element.nameOffset); 2201 buildImplicitGetter(element, name, type);
2158 getter.getter = true; 2202 holder?.addAccessor(getter);
2159 getter.static = element.isStatic;
2160 getter.synthetic = true;
2161 getter.returnType = type;
2162 getter.type = new FunctionTypeImpl(getter);
2163 getter.variable = element;
2164 getter.hasImplicitReturnType = element.hasImplicitType;
2165 holder.addAccessor(getter);
2166 element.getter = getter;
2167 if (!(element.isConst || element.isFinal)) { 2203 if (!(element.isConst || element.isFinal)) {
2168 PropertyAccessorElementImpl setter = 2204 PropertyAccessorElementImpl setter =
2169 new PropertyAccessorElementImpl(name, element.nameOffset); 2205 buildImplicitSetter(element, name, type);
2170 setter.setter = true; 2206 holder?.addAccessor(setter);
2171 setter.static = element.isStatic;
2172 setter.synthetic = true;
2173 setter.parameters = <ParameterElement>[
2174 new ParameterElementImpl('_$name', element.nameOffset)
2175 ..synthetic = true
2176 ..type = type
2177 ..parameterKind = ParameterKind.REQUIRED
2178 ];
2179 setter.returnType = VoidTypeImpl.instance;
2180 setter.type = new FunctionTypeImpl(setter);
2181 setter.variable = element;
2182 holder.addAccessor(setter);
2183 element.setter = setter;
2184 } 2207 }
2185 } 2208 }
2186 2209
2187 /** 2210 /**
2188 * Build the implicit field associated with a getter or setter, and place it 2211 * Build the implicit field associated with a getter or setter, and place it
2189 * in [holder]. 2212 * in [holder].
2190 */ 2213 */
2191 FieldElementImpl buildImplicitField(String name, DartType type, 2214 FieldElementImpl buildImplicitField(String name, DartType type,
2192 UnlinkedExecutableKind kind, ElementHolder holder) { 2215 UnlinkedExecutableKind kind, ElementHolder holder) {
2193 FieldElementImpl field = holder.getField(name); 2216 FieldElementImpl field = holder.getField(name);
2194 if (field == null) { 2217 if (field == null) {
2195 field = new FieldElementImpl(name, -1); 2218 field = new FieldElementImpl(name, -1);
2196 field.synthetic = true; 2219 field.synthetic = true;
2197 field.final2 = kind == UnlinkedExecutableKind.getter; 2220 field.final2 = kind == UnlinkedExecutableKind.getter;
2198 field.type = type; 2221 field.type = type;
2199 holder.addField(field); 2222 holder.addField(field);
2200 return field; 2223 return field;
2201 } else { 2224 } else {
2202 // TODO(paulberry): what if the getter and setter have a type mismatch? 2225 // TODO(paulberry): what if the getter and setter have a type mismatch?
2203 field.final2 = false; 2226 field.final2 = false;
2204 return field; 2227 return field;
2205 } 2228 }
2206 } 2229 }
2207 2230
2208 /** 2231 /**
2209 * Build the implicit top level variable associated with a getter or setter, 2232 * Build an implicit getter for the given [property] and bind it to the
2210 * and place it in [holder]. 2233 * [property] and to its enclosing element.
2211 */ 2234 */
2212 PropertyInducingElementImpl buildImplicitTopLevelVariable( 2235 PropertyAccessorElementImpl buildImplicitGetter(
2213 String name, UnlinkedExecutableKind kind, ElementHolder holder) { 2236 PropertyInducingElementImpl property, String name, DartType type) {
2214 TopLevelVariableElementImpl variable = holder.getTopLevelVariable(name); 2237 PropertyAccessorElementImpl getter =
2215 if (variable == null) { 2238 new PropertyAccessorElementImpl(name, property.nameOffset);
2216 variable = new TopLevelVariableElementImpl(name, -1); 2239 getter.enclosingElement = property.enclosingElement;
2217 variable.synthetic = true; 2240 getter.getter = true;
2218 variable.final2 = kind == UnlinkedExecutableKind.getter; 2241 getter.static = property.isStatic;
2219 holder.addTopLevelVariable(variable); 2242 getter.synthetic = true;
2220 return variable; 2243 getter.returnType = type;
2221 } else { 2244 getter.type = new FunctionTypeImpl(getter);
2222 // TODO(paulberry): what if the getter and setter have a type mismatch? 2245 getter.variable = property;
2223 variable.final2 = false; 2246 getter.hasImplicitReturnType = property.hasImplicitType;
2224 return variable; 2247 property.getter = getter;
2225 } 2248 return getter;
2226 } 2249 }
2227 2250
2228 /** 2251 /**
2252 * Build an implicit setter for the given [property] and bind it to the
2253 * [property] and to its enclosing element.
2254 */
2255 PropertyAccessorElementImpl buildImplicitSetter(
2256 PropertyInducingElementImpl property, String name, DartType type) {
2257 PropertyAccessorElementImpl setter =
2258 new PropertyAccessorElementImpl(name, property.nameOffset);
2259 setter.enclosingElement = property.enclosingElement;
2260 setter.setter = true;
2261 setter.static = property.isStatic;
2262 setter.synthetic = true;
2263 setter.parameters = <ParameterElement>[
2264 new ParameterElementImpl('_$name', property.nameOffset)
2265 ..synthetic = true
2266 ..type = type
2267 ..parameterKind = ParameterKind.REQUIRED
2268 ];
2269 setter.returnType = VoidTypeImpl.instance;
2270 setter.type = new FunctionTypeImpl(setter);
2271 setter.variable = property;
2272 property.setter = setter;
2273 return setter;
2274 }
2275
2276 /**
2229 * Build the appropriate [DartType] object corresponding to a slot id in the 2277 * Build the appropriate [DartType] object corresponding to a slot id in the
2230 * [LinkedUnit.types] table. 2278 * [LinkedUnit.types] table.
2231 */ 2279 */
2232 DartType buildLinkedType( 2280 DartType buildLinkedType(
2233 int slot, TypeParameterizedElementMixin typeParameterContext) { 2281 int slot, TypeParameterizedElementMixin typeParameterContext) {
2234 if (slot == 0) { 2282 if (slot == 0) {
2235 // A slot id of 0 means there is no [DartType] object to build. 2283 // A slot id of 0 means there is no [DartType] object to build.
2236 return null; 2284 return null;
2237 } 2285 }
2238 EntityRef type = linkedTypeMap[slot]; 2286 EntityRef type = linkedTypeMap[slot];
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
2397 serializedParameter.visibleLength); 2445 serializedParameter.visibleLength);
2398 } 2446 }
2399 } 2447 }
2400 return parameterElement; 2448 return parameterElement;
2401 } 2449 }
2402 2450
2403 /** 2451 /**
2404 * Handle the parts that are common to top level variables and fields. 2452 * Handle the parts that are common to top level variables and fields.
2405 */ 2453 */
2406 void buildPropertyIntroducingElementCommonParts( 2454 void buildPropertyIntroducingElementCommonParts(
2407 PropertyInducingElementImpl element, 2455 PropertyInducingElementImpl element, UnlinkedVariable serializedVariable,
2408 UnlinkedVariable serializedVariable) { 2456 {bool isLazilyResynthesized: false}) {
2409 buildVariableCommonParts(element, serializedVariable); 2457 buildVariableCommonParts(element, serializedVariable,
2458 isLazilyResynthesized: isLazilyResynthesized);
2410 element.propagatedType = buildLinkedType( 2459 element.propagatedType = buildLinkedType(
2411 serializedVariable.propagatedTypeSlot, 2460 serializedVariable.propagatedTypeSlot,
2412 _currentTypeParameterizedElement); 2461 _currentTypeParameterizedElement);
2413 } 2462 }
2414 2463
2415 /** 2464 /**
2416 * Build a [DartType] object based on a [EntityRef]. This [DartType] 2465 * Build a [DartType] object based on a [EntityRef]. This [DartType]
2417 * may refer to elements in other libraries than the library being 2466 * may refer to elements in other libraries than the library being
2418 * deserialized, so handles are used to avoid having to deserialize other 2467 * deserialized, so handles are used to avoid having to deserialize other
2419 * libraries in the process. 2468 * libraries in the process.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
2510 List<UnlinkedTypeParam> serializedTypeParameters) { 2559 List<UnlinkedTypeParam> serializedTypeParameters) {
2511 List<TypeParameterElement> typeParameters = 2560 List<TypeParameterElement> typeParameters =
2512 serializedTypeParameters.map(buildTypeParameter).toList(); 2561 serializedTypeParameters.map(buildTypeParameter).toList();
2513 currentTypeParameters.add(typeParameters); 2562 currentTypeParameters.add(typeParameters);
2514 for (int i = 0; i < serializedTypeParameters.length; i++) { 2563 for (int i = 0; i < serializedTypeParameters.length; i++) {
2515 finishTypeParameter(serializedTypeParameters[i], typeParameters[i]); 2564 finishTypeParameter(serializedTypeParameters[i], typeParameters[i]);
2516 } 2565 }
2517 return typeParameters; 2566 return typeParameters;
2518 } 2567 }
2519 2568
2569 UnitExplicitTopLevelAccessors buildUnitExplicitTopLevelAccessors() {
2570 HashMap<String, TopLevelVariableElementImpl> implicitVariables =
2571 new HashMap<String, TopLevelVariableElementImpl>();
2572 UnitExplicitTopLevelAccessors accessorsData =
2573 new UnitExplicitTopLevelAccessors();
2574 for (UnlinkedExecutable unlinkedExecutable in unlinkedUnit.executables) {
2575 UnlinkedExecutableKind kind = unlinkedExecutable.kind;
2576 if (kind == UnlinkedExecutableKind.getter ||
2577 kind == UnlinkedExecutableKind.setter) {
2578 // name
2579 String name = unlinkedExecutable.name;
2580 if (kind == UnlinkedExecutableKind.setter) {
2581 assert(name.endsWith('='));
2582 name = name.substring(0, name.length - 1);
2583 }
2584 // create
2585 PropertyAccessorElementImpl accessor =
2586 new PropertyAccessorElementImpl.forSerialized(
2587 unlinkedExecutable, unit);
2588 accessorsData.accessors.add(accessor);
2589 buildExecutableCommonParts(accessor, unlinkedExecutable);
2590 // implicit variable
2591 TopLevelVariableElementImpl variable = implicitVariables[name];
2592 if (variable == null) {
2593 variable = new TopLevelVariableElementImpl(name, -1);
2594 variable.enclosingElement = unit;
2595 implicitVariables[name] = variable;
2596 accessorsData.implicitVariables.add(variable);
2597 variable.synthetic = true;
2598 variable.final2 = kind == UnlinkedExecutableKind.getter;
2599 } else {
2600 variable.final2 = false;
2601 }
2602 accessor.variable = variable;
2603 // link
2604 if (kind == UnlinkedExecutableKind.getter) {
2605 variable.getter = accessor;
2606 } else {
2607 variable.setter = accessor;
2608 }
2609 }
2610 }
2611 return accessorsData;
2612 }
2613
2614 UnitExplicitTopLevelVariables buildUnitExplicitTopLevelVariables() {
2615 UnitExplicitTopLevelVariables variablesData =
2616 new UnitExplicitTopLevelVariables();
2617 for (UnlinkedVariable unlinkedVariable in unlinkedUnit.variables) {
2618 TopLevelVariableElementImpl element;
2619 if (unlinkedVariable.constExpr != null && unlinkedVariable.isConst) {
2620 ConstTopLevelVariableElementImpl constElement =
2621 new ConstTopLevelVariableElementImpl.forSerialized(
2622 unlinkedVariable, unit);
2623 element = constElement;
2624 constElement.constantInitializer =
2625 _buildConstExpression(unlinkedVariable.constExpr);
2626 } else {
2627 element = new TopLevelVariableElementImpl.forSerialized(
2628 unlinkedVariable, unit);
2629 }
2630 buildPropertyIntroducingElementCommonParts(element, unlinkedVariable,
2631 isLazilyResynthesized: true);
2632 variablesData.variables.add(element);
2633 // implicit accessors
2634 String name = element.name;
2635 DartType type = element.type;
2636 variablesData.implicitAccessors
2637 .add(buildImplicitGetter(element, name, type));
2638 if (!(element.isConst || element.isFinal)) {
2639 variablesData.implicitAccessors
2640 .add(buildImplicitSetter(element, name, type));
2641 }
2642 }
2643 return variablesData;
2644 }
2645
2520 /** 2646 /**
2521 * Resynthesize a [TopLevelVariableElement] or [FieldElement]. 2647 * Resynthesize a [TopLevelVariableElement] or [FieldElement].
2522 */ 2648 */
2523 void buildVariable(UnlinkedVariable serializedVariable, 2649 void buildVariable(UnlinkedVariable serializedVariable,
2524 [ElementHolder holder]) { 2650 [ElementHolder holder]) {
2525 if (holder == null) { 2651 if (holder == null) {
2526 TopLevelVariableElementImpl element; 2652 throw new UnimplementedError('Must be lazy');
2527 if (serializedVariable.constExpr != null && serializedVariable.isConst) {
2528 ConstTopLevelVariableElementImpl constElement =
2529 new ConstTopLevelVariableElementImpl(
2530 serializedVariable.name, serializedVariable.nameOffset);
2531 element = constElement;
2532 constElement.constantInitializer =
2533 _buildConstExpression(serializedVariable.constExpr);
2534 } else {
2535 element = new TopLevelVariableElementImpl(
2536 serializedVariable.name, serializedVariable.nameOffset);
2537 }
2538 buildPropertyIntroducingElementCommonParts(element, serializedVariable);
2539 unitHolder.addTopLevelVariable(element);
2540 buildImplicitAccessors(element, unitHolder);
2541 } else { 2653 } else {
2542 FieldElementImpl element; 2654 FieldElementImpl element;
2543 if (serializedVariable.constExpr != null && 2655 if (serializedVariable.constExpr != null &&
2544 (serializedVariable.isConst || 2656 (serializedVariable.isConst ||
2545 serializedVariable.isFinal && !serializedVariable.isStatic)) { 2657 serializedVariable.isFinal && !serializedVariable.isStatic)) {
2546 ConstFieldElementImpl constElement = new ConstFieldElementImpl( 2658 ConstFieldElementImpl constElement = new ConstFieldElementImpl(
2547 serializedVariable.name, serializedVariable.nameOffset); 2659 serializedVariable.name, serializedVariable.nameOffset);
2548 element = constElement; 2660 element = constElement;
2549 constElement.constantInitializer = 2661 constElement.constantInitializer =
2550 _buildConstExpression(serializedVariable.constExpr); 2662 _buildConstExpression(serializedVariable.constExpr);
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
2762 2874
2763 /** 2875 /**
2764 * Populate a [CompilationUnitElement] by deserializing all the elements 2876 * Populate a [CompilationUnitElement] by deserializing all the elements
2765 * contained in it. 2877 * contained in it.
2766 */ 2878 */
2767 void populateUnit() { 2879 void populateUnit() {
2768 unlinkedUnit.classes.forEach(buildClass); 2880 unlinkedUnit.classes.forEach(buildClass);
2769 unlinkedUnit.enums.forEach(buildEnum); 2881 unlinkedUnit.enums.forEach(buildEnum);
2770 unlinkedUnit.executables.forEach((e) => buildExecutable(e, unit)); 2882 unlinkedUnit.executables.forEach((e) => buildExecutable(e, unit));
2771 unlinkedUnit.typedefs.forEach(buildTypedef); 2883 unlinkedUnit.typedefs.forEach(buildTypedef);
2772 unlinkedUnit.variables.forEach(buildVariable);
2773 unit.accessors = unitHolder.accessors;
2774 unit.enums = unitHolder.enums; 2884 unit.enums = unitHolder.enums;
2775 unit.functions = unitHolder.functions; 2885 unit.functions = unitHolder.functions;
2776 List<FunctionTypeAliasElement> typeAliases = unitHolder.typeAliases; 2886 List<FunctionTypeAliasElement> typeAliases = unitHolder.typeAliases;
2777 for (FunctionTypeAliasElementImpl typeAlias in typeAliases) { 2887 for (FunctionTypeAliasElementImpl typeAlias in typeAliases) {
2778 if (typeAlias.isSynthetic) { 2888 if (typeAlias.isSynthetic) {
2779 typeAlias.enclosingElement = unit; 2889 typeAlias.enclosingElement = unit;
2780 } 2890 }
2781 } 2891 }
2782 unit.typeAliases = typeAliases.where((e) => !e.isSynthetic).toList(); 2892 unit.typeAliases = typeAliases.where((e) => !e.isSynthetic).toList();
2783 unit.types = unitHolder.types; 2893 unit.types = unitHolder.types;
2784 unit.topLevelVariables = unitHolder.topLevelVariables;
2785 for (ClassElement cls in unit.types) {
2786 elementMap[cls.name] = cls;
2787 }
2788 for (ClassElement cls in unit.enums) {
2789 elementMap[cls.name] = cls;
2790 }
2791 for (FunctionTypeAliasElement typeAlias in unit.functionTypeAliases) {
2792 elementMap[typeAlias.name] = typeAlias;
2793 }
2794 for (FunctionElement function in unit.functions) {
2795 elementMap[function.name] = function;
2796 }
2797 for (PropertyAccessorElementImpl accessor in unit.accessors) {
2798 elementMap[accessor.identifier] = accessor;
2799 }
2800 assert(currentTypeParameters.isEmpty); 2894 assert(currentTypeParameters.isEmpty);
2801 } 2895 }
2802 2896
2803 /** 2897 /**
2804 * Constructor initializers can reference fields and other constructors of 2898 * Constructor initializers can reference fields and other constructors of
2805 * the same class, including forward references. So, we need to delay 2899 * the same class, including forward references. So, we need to delay
2806 * resolution until after class elements are built. 2900 * resolution until after class elements are built.
2807 */ 2901 */
2808 void resolveConstructorInitializers(ClassElementImpl classElement) { 2902 void resolveConstructorInitializers(ClassElementImpl classElement) {
2809 for (ConstructorElementImpl constructor in constructors.values) { 2903 for (ConstructorElementImpl constructor in constructors.values) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2879 static String _getElementIdentifier(String name, ReferenceKind kind) { 2973 static String _getElementIdentifier(String name, ReferenceKind kind) {
2880 if (kind == ReferenceKind.topLevelPropertyAccessor || 2974 if (kind == ReferenceKind.topLevelPropertyAccessor ||
2881 kind == ReferenceKind.propertyAccessor) { 2975 kind == ReferenceKind.propertyAccessor) {
2882 if (!name.endsWith('=')) { 2976 if (!name.endsWith('=')) {
2883 return name + '?'; 2977 return name + '?';
2884 } 2978 }
2885 } 2979 }
2886 return name; 2980 return name;
2887 } 2981 }
2888 } 2982 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/dart/element/element.dart ('k') | pkg/analyzer/test/src/summary/resynthesize_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698