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

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: 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 Map<String, CompilationUnitElement> libraryMap =
129 _resynthesizedElements[libraryUri]; 129 _resynthesizedUnits[libraryUri];
130 if (libraryMap == null) { 130 if (libraryMap == null) {
131 getLibraryElement(libraryUri); 131 getLibraryElement(libraryUri);
132 libraryMap = _resynthesizedElements[libraryUri]; 132 libraryMap = _resynthesizedUnits[libraryUri];
133 assert(libraryMap != null); 133 assert(libraryMap != null);
134 } 134 }
135 Map<String, Element> compilationUnitElements = libraryMap[components[1]]; 135 CompilationUnitElementImpl unitElement = libraryMap[components[1]];
136 Element element; 136 Element element = unitElement?.getChildNotImpl(components[2]);
Paul Berry 2016/05/19 11:27:30 I have an efficiency concern here. You're replaci
scheglov 2016/05/19 16:54:57 That's fair. I think that the approach with `getCh
137 if (compilationUnitElements != null) {
138 element = compilationUnitElements[components[2]];
139 }
140 if (element != null && components.length == 4) { 137 if (element != null && components.length == 4) {
141 String name = components[3]; 138 String name = components[3];
142 Element parentElement = element; 139 Element parentElement = element;
143 if (parentElement is ClassElement) { 140 if (parentElement is ClassElement) {
144 if (name.endsWith('?')) { 141 if (name.endsWith('?')) {
145 element = 142 element =
146 parentElement.getGetter(name.substring(0, name.length - 1)); 143 parentElement.getGetter(name.substring(0, name.length - 1));
147 } else if (name.endsWith('=')) { 144 } else if (name.endsWith('=')) {
148 element = 145 element =
149 parentElement.getSetter(name.substring(0, name.length - 1)); 146 parentElement.getSetter(name.substring(0, name.length - 1));
(...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 /** 1015 /**
1019 * Classes which should have their supertype set to "object" once 1016 * Classes which should have their supertype set to "object" once
1020 * resynthesis is complete. Only used if [isCoreLibrary] is `true`. 1017 * resynthesis is complete. Only used if [isCoreLibrary] is `true`.
1021 */ 1018 */
1022 List<ClassElementImpl> delayedObjectSubclasses = <ClassElementImpl>[]; 1019 List<ClassElementImpl> delayedObjectSubclasses = <ClassElementImpl>[];
1023 1020
1024 /** 1021 /**
1025 * Map of compilation unit elements that have been resynthesized so far. The 1022 * Map of compilation unit elements that have been resynthesized so far. The
1026 * key is the URI of the compilation unit. 1023 * key is the URI of the compilation unit.
1027 */ 1024 */
1028 final Map<String, CompilationUnitElement> resynthesizedUnits = 1025 final Map<String, CompilationUnitElementImpl> resynthesizedUnits =
1029 <String, CompilationUnitElement>{}; 1026 <String, CompilationUnitElementImpl>{};
1030 1027
1031 /** 1028 /**
1032 * Map of top level elements that have been resynthesized so far. The first 1029 * 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 1030 * key is the URI of the compilation unit; the second is the name of the top
1034 * level element. 1031 * level element.
1035 */ 1032 */
1036 final Map<String, Map<String, Element>> resynthesizedElements = 1033 final Map<String, Map<String, Element>> resynthesizedElements =
1037 <String, Map<String, Element>>{}; 1034 <String, Map<String, Element>>{};
1038 1035
1039 /** 1036 /**
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1195 serializedImport.combinators.map(buildCombinator).toList(); 1192 serializedImport.combinators.map(buildCombinator).toList();
1196 return importElement; 1193 return importElement;
1197 } 1194 }
1198 1195
1199 /** 1196 /**
1200 * Main entry point. Resynthesize the [LibraryElement] and return it. 1197 * Main entry point. Resynthesize the [LibraryElement] and return it.
1201 */ 1198 */
1202 LibraryElement buildLibrary() { 1199 LibraryElement buildLibrary() {
1203 // Create LibraryElementImpl. 1200 // Create LibraryElementImpl.
1204 bool hasName = unlinkedUnits[0].libraryName.isNotEmpty; 1201 bool hasName = unlinkedUnits[0].libraryName.isNotEmpty;
1205 library = new LibraryElementImpl( 1202 library = new LibraryElementImpl.forSerialized(
1206 summaryResynthesizer.context, 1203 summaryResynthesizer.context,
1207 unlinkedUnits[0].libraryName, 1204 unlinkedUnits[0].libraryName,
1208 hasName ? unlinkedUnits[0].libraryNameOffset : -1, 1205 hasName ? unlinkedUnits[0].libraryNameOffset : -1,
1209 unlinkedUnits[0].libraryNameLength); 1206 unlinkedUnits[0].libraryNameLength,
1207 new _LibraryResynthesizerContext(this),
1208 unlinkedUnits[0]);
1210 // Create the defining unit. 1209 // Create the defining unit.
1211 _UnitResynthesizer definingUnitResynthesizer = 1210 _UnitResynthesizer definingUnitResynthesizer =
1212 createUnitResynthesizer(0, librarySource, null); 1211 createUnitResynthesizer(0, librarySource, null);
1213 CompilationUnitElementImpl definingUnit = definingUnitResynthesizer.unit; 1212 CompilationUnitElementImpl definingUnit = definingUnitResynthesizer.unit;
1214 definingUnitResynthesizer.buildDocumentation(
1215 library, unlinkedUnits[0].libraryDocumentationComment);
1216 definingUnitResynthesizer.buildAnnotations(
1217 library, unlinkedUnits[0].libraryAnnotations);
1218 library.definingCompilationUnit = definingUnit; 1213 library.definingCompilationUnit = definingUnit;
1219 definingUnit.source = librarySource; 1214 definingUnit.source = librarySource;
1220 definingUnit.librarySource = librarySource; 1215 definingUnit.librarySource = librarySource;
1221 // Create parts. 1216 // Create parts.
1222 List<_UnitResynthesizer> partResynthesizers = <_UnitResynthesizer>[]; 1217 List<_UnitResynthesizer> partResynthesizers = <_UnitResynthesizer>[];
1223 UnlinkedUnit unlinkedDefiningUnit = unlinkedUnits[0]; 1218 UnlinkedUnit unlinkedDefiningUnit = unlinkedUnits[0];
1224 assert(unlinkedDefiningUnit.publicNamespace.parts.length + 1 == 1219 assert(unlinkedDefiningUnit.publicNamespace.parts.length + 1 ==
1225 linkedLibrary.units.length); 1220 linkedLibrary.units.length);
1226 for (int i = 1; i < linkedLibrary.units.length; i++) { 1221 for (int i = 1; i < linkedLibrary.units.length; i++) {
1227 _UnitResynthesizer partResynthesizer = buildPart( 1222 _UnitResynthesizer partResynthesizer = buildPart(
(...skipping 23 matching lines...) Expand all
1251 definingUnitResynthesizer, 1246 definingUnitResynthesizer,
1252 unlinkedDefiningUnit.publicNamespace.exports[i], 1247 unlinkedDefiningUnit.publicNamespace.exports[i],
1253 unlinkedDefiningUnit.exports[i])); 1248 unlinkedDefiningUnit.exports[i]));
1254 } 1249 }
1255 library.exports = exports; 1250 library.exports = exports;
1256 // Populate units. 1251 // Populate units.
1257 populateUnit(definingUnitResynthesizer); 1252 populateUnit(definingUnitResynthesizer);
1258 for (_UnitResynthesizer partResynthesizer in partResynthesizers) { 1253 for (_UnitResynthesizer partResynthesizer in partResynthesizers) {
1259 populateUnit(partResynthesizer); 1254 populateUnit(partResynthesizer);
1260 } 1255 }
1261 BuildLibraryElementUtils.patchTopLevelAccessors(library);
1262 // Update delayed Object class references. 1256 // Update delayed Object class references.
1263 if (isCoreLibrary) { 1257 if (isCoreLibrary) {
1264 ClassElement objectElement = library.getType('Object'); 1258 ClassElement objectElement = library.getType('Object');
1265 assert(objectElement != null); 1259 assert(objectElement != null);
1266 for (ClassElementImpl classElement in delayedObjectSubclasses) { 1260 for (ClassElementImpl classElement in delayedObjectSubclasses) {
1267 classElement.supertype = objectElement.type; 1261 classElement.supertype = objectElement.type;
1268 } 1262 }
1269 } 1263 }
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`. 1264 // Create the synthetic element for `loadLibrary`.
1283 // Until the client received dart:core and dart:async, we cannot do this, 1265 // 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 1266 // 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 1267 // Dart SDK client to initialize TypeProvider and finish the dart:core and
1286 // dart:async libraries creation. 1268 // dart:async libraries creation.
1287 if (library.name != 'dart.core' && library.name != 'dart.async') { 1269 if (library.name != 'dart.core' && library.name != 'dart.async') {
1288 library.createLoadLibraryFunction(summaryResynthesizer.typeProvider); 1270 library.createLoadLibraryFunction(summaryResynthesizer.typeProvider);
1289 } 1271 }
1290 // Done. 1272 // Done.
1291 return library; 1273 return library;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 */ 1345 */
1364 void populateUnit(_UnitResynthesizer unitResynthesized) { 1346 void populateUnit(_UnitResynthesizer unitResynthesized) {
1365 // TODO(scheglov) 1347 // TODO(scheglov)
1366 unitResynthesized.populateUnit(); 1348 unitResynthesized.populateUnit();
1367 String absoluteUri = unitResynthesized.unit.source.uri.toString(); 1349 String absoluteUri = unitResynthesized.unit.source.uri.toString();
1368 resynthesizedUnits[absoluteUri] = unitResynthesized.unit; 1350 resynthesizedUnits[absoluteUri] = unitResynthesized.unit;
1369 resynthesizedElements[absoluteUri] = unitResynthesized.elementMap; 1351 resynthesizedElements[absoluteUri] = unitResynthesized.elementMap;
1370 } 1352 }
1371 } 1353 }
1372 1354
1355 class _LibraryResynthesizerContext implements LibraryResynthesizerContext {
Paul Berry 2016/05/19 11:27:30 Nit: a doc comment would be helpful here.
scheglov 2016/05/19 16:54:57 Done.
1356 final _LibraryResynthesizer resynthesizer;
1357
1358 _LibraryResynthesizerContext(this.resynthesizer);
1359
1360 @override
1361 Namespace buildExportNamespace() {
1362 LibraryElementImpl library = resynthesizer.library;
1363 return resynthesizer.buildExportNamespace(
1364 library.publicNamespace, resynthesizer.linkedLibrary.exportNames);
1365 }
1366
1367 @override
1368 Namespace buildPublicNamespace() {
1369 LibraryElementImpl library = resynthesizer.library;
1370 return new NamespaceBuilder().createPublicNamespaceForLibrary(library);
1371 }
1372
1373 @override
1374 FunctionElement findEntryPoint() {
1375 LibraryElementImpl library = resynthesizer.library;
1376 Element entryPoint =
1377 library.exportNamespace.get(FunctionElement.MAIN_FUNCTION_NAME);
1378 if (entryPoint is FunctionElement) {
1379 return entryPoint;
1380 }
1381 return null;
1382 }
1383
1384 @override
1385 void patchTopLevelAccessors() {
1386 LibraryElementImpl library = resynthesizer.library;
1387 BuildLibraryElementUtils.patchTopLevelAccessors(library);
1388 }
1389 }
1390
1373 /** 1391 /**
1374 * Data structure used during resynthesis to record all the information that is 1392 * Data structure used during resynthesis to record all the information that is
1375 * known about how to resynthesize a single entry in [LinkedUnit.references] 1393 * known about how to resynthesize a single entry in [LinkedUnit.references]
1376 * (and its associated entry in [UnlinkedUnit.references], if it exists). 1394 * (and its associated entry in [UnlinkedUnit.references], if it exists).
1377 */ 1395 */
1378 class _ReferenceInfo { 1396 class _ReferenceInfo {
1379 /** 1397 /**
1380 * The [_LibraryResynthesizer] which is being used to obtain summaries. 1398 * The [_LibraryResynthesizer] which is being used to obtain summaries.
1381 */ 1399 */
1382 final _LibraryResynthesizer libraryResynthesizer; 1400 final _LibraryResynthesizer libraryResynthesizer;
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1561 ElementAnnotationImpl buildAnnotation(UnlinkedConst uc) { 1579 ElementAnnotationImpl buildAnnotation(UnlinkedConst uc) {
1562 return _unitResynthesizer.buildAnnotation(uc); 1580 return _unitResynthesizer.buildAnnotation(uc);
1563 } 1581 }
1564 1582
1565 @override 1583 @override
1566 Expression buildExpression(UnlinkedConst uc) { 1584 Expression buildExpression(UnlinkedConst uc) {
1567 return _unitResynthesizer._buildConstExpression(uc); 1585 return _unitResynthesizer._buildConstExpression(uc);
1568 } 1586 }
1569 1587
1570 @override 1588 @override
1589 UnitExplicitTopLevelAccessors buildTopLevelAccessors() {
1590 return _unitResynthesizer.buildUnitExplicitTopLevelAccessors();
1591 }
1592
1593 @override
1594 UnitExplicitTopLevelVariables buildTopLevelVariables() {
1595 return _unitResynthesizer.buildUnitExplicitTopLevelVariables();
1596 }
1597
1598 @override
1571 DartType resolveTypeRef( 1599 DartType resolveTypeRef(
1572 EntityRef type, TypeParameterizedElementMixin typeParameterContext, 1600 EntityRef type, TypeParameterizedElementMixin typeParameterContext,
1573 {bool defaultVoid: false, bool instantiateToBoundsAllowed: true}) { 1601 {bool defaultVoid: false, bool instantiateToBoundsAllowed: true}) {
1574 return _unitResynthesizer.buildType(type, typeParameterContext, 1602 return _unitResynthesizer.buildType(type, typeParameterContext,
1575 defaultVoid: defaultVoid, 1603 defaultVoid: defaultVoid,
1576 instantiateToBoundsAllowed: instantiateToBoundsAllowed); 1604 instantiateToBoundsAllowed: instantiateToBoundsAllowed);
1577 } 1605 }
1578 } 1606 }
1579 1607
1580 /** 1608 /**
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
2067 } else { 2095 } else {
2068 MethodElementImpl executableElement = 2096 MethodElementImpl executableElement =
2069 new MethodElementImpl.forSerialized( 2097 new MethodElementImpl.forSerialized(
2070 serializedExecutable, enclosingElement); 2098 serializedExecutable, enclosingElement);
2071 buildExecutableCommonParts(executableElement, serializedExecutable); 2099 buildExecutableCommonParts(executableElement, serializedExecutable);
2072 holder.addMethod(executableElement); 2100 holder.addMethod(executableElement);
2073 } 2101 }
2074 break; 2102 break;
2075 case UnlinkedExecutableKind.getter: 2103 case UnlinkedExecutableKind.getter:
2076 case UnlinkedExecutableKind.setter: 2104 case UnlinkedExecutableKind.setter:
2105 // Top-level accessors are created lazily.
2106 if (isTopLevel) {
2107 break;
2108 }
2109 // Class member accessors.
2077 PropertyAccessorElementImpl executableElement = 2110 PropertyAccessorElementImpl executableElement =
2078 new PropertyAccessorElementImpl.forSerialized( 2111 new PropertyAccessorElementImpl.forSerialized(
2079 serializedExecutable, enclosingElement); 2112 serializedExecutable, enclosingElement);
2080 buildExecutableCommonParts(executableElement, serializedExecutable); 2113 buildExecutableCommonParts(executableElement, serializedExecutable);
2081 DartType type; 2114 DartType type;
2082 if (kind == UnlinkedExecutableKind.getter) { 2115 if (kind == UnlinkedExecutableKind.getter) {
2083 type = executableElement.returnType; 2116 type = executableElement.returnType;
2084 } else { 2117 } else {
2085 type = executableElement.parameters[0].type; 2118 type = executableElement.parameters[0].type;
2086 } 2119 }
2087 holder.addAccessor(executableElement); 2120 holder.addAccessor(executableElement);
2088 PropertyInducingElementImpl implicitVariable; 2121 FieldElementImpl field = buildImplicitField(name, type, kind, holder);
2089 if (isTopLevel) { 2122 field.static = serializedExecutable.isStatic;
2090 implicitVariable = buildImplicitTopLevelVariable(name, kind, holder); 2123 executableElement.variable = field;
2124 if (kind == UnlinkedExecutableKind.getter) {
2125 field.getter = executableElement;
2091 } else { 2126 } else {
2092 FieldElementImpl field = buildImplicitField(name, type, kind, holder); 2127 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 } 2128 }
2102 break; 2129 break;
2103 default: 2130 default:
2104 // The only other executable type is a constructor, and that is handled 2131 // The only other executable type is a constructor, and that is handled
2105 // separately (in [buildConstructor]. So this code should be 2132 // separately (in [buildConstructor]. So this code should be
2106 // unreachable. 2133 // unreachable.
2107 assert(false); 2134 assert(false);
2108 } 2135 }
2109 } 2136 }
2110 2137
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2147 2174
2148 /** 2175 /**
2149 * Build the implicit getter and setter associated with [element], and place 2176 * Build the implicit getter and setter associated with [element], and place
2150 * them in [holder]. 2177 * them in [holder].
2151 */ 2178 */
2152 void buildImplicitAccessors( 2179 void buildImplicitAccessors(
2153 PropertyInducingElementImpl element, ElementHolder holder) { 2180 PropertyInducingElementImpl element, ElementHolder holder) {
2154 String name = element.name; 2181 String name = element.name;
2155 DartType type = element.type; 2182 DartType type = element.type;
2156 PropertyAccessorElementImpl getter = 2183 PropertyAccessorElementImpl getter =
2157 new PropertyAccessorElementImpl(name, element.nameOffset); 2184 buildImplicitGetter(element, name, type);
2158 getter.getter = true; 2185 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)) { 2186 if (!(element.isConst || element.isFinal)) {
2168 PropertyAccessorElementImpl setter = 2187 PropertyAccessorElementImpl setter =
2169 new PropertyAccessorElementImpl(name, element.nameOffset); 2188 buildImplicitSetter(element, name, type);
2170 setter.setter = true; 2189 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 } 2190 }
2185 } 2191 }
2186 2192
2187 /** 2193 /**
2188 * Build the implicit field associated with a getter or setter, and place it 2194 * Build the implicit field associated with a getter or setter, and place it
2189 * in [holder]. 2195 * in [holder].
2190 */ 2196 */
2191 FieldElementImpl buildImplicitField(String name, DartType type, 2197 FieldElementImpl buildImplicitField(String name, DartType type,
2192 UnlinkedExecutableKind kind, ElementHolder holder) { 2198 UnlinkedExecutableKind kind, ElementHolder holder) {
2193 FieldElementImpl field = holder.getField(name); 2199 FieldElementImpl field = holder.getField(name);
2194 if (field == null) { 2200 if (field == null) {
2195 field = new FieldElementImpl(name, -1); 2201 field = new FieldElementImpl(name, -1);
2196 field.synthetic = true; 2202 field.synthetic = true;
2197 field.final2 = kind == UnlinkedExecutableKind.getter; 2203 field.final2 = kind == UnlinkedExecutableKind.getter;
2198 field.type = type; 2204 field.type = type;
2199 holder.addField(field); 2205 holder.addField(field);
2200 return field; 2206 return field;
2201 } else { 2207 } else {
2202 // TODO(paulberry): what if the getter and setter have a type mismatch? 2208 // TODO(paulberry): what if the getter and setter have a type mismatch?
2203 field.final2 = false; 2209 field.final2 = false;
2204 return field; 2210 return field;
2205 } 2211 }
2206 } 2212 }
2207 2213
2208 /** 2214 PropertyAccessorElementImpl buildImplicitGetter(
Paul Berry 2016/05/19 11:27:30 Please add a doc comment here.
scheglov 2016/05/19 16:54:57 Done.
2209 * Build the implicit top level variable associated with a getter or setter, 2215 PropertyInducingElementImpl element, String name, DartType type) {
2210 * and place it in [holder]. 2216 PropertyAccessorElementImpl getter =
2211 */ 2217 new PropertyAccessorElementImpl(name, element.nameOffset);
2212 PropertyInducingElementImpl buildImplicitTopLevelVariable( 2218 getter.getter = true;
2213 String name, UnlinkedExecutableKind kind, ElementHolder holder) { 2219 getter.static = element.isStatic;
2214 TopLevelVariableElementImpl variable = holder.getTopLevelVariable(name); 2220 getter.synthetic = true;
2215 if (variable == null) { 2221 getter.returnType = type;
2216 variable = new TopLevelVariableElementImpl(name, -1); 2222 getter.type = new FunctionTypeImpl(getter);
2217 variable.synthetic = true; 2223 getter.variable = element;
2218 variable.final2 = kind == UnlinkedExecutableKind.getter; 2224 getter.hasImplicitReturnType = element.hasImplicitType;
2219 holder.addTopLevelVariable(variable); 2225 element.getter = getter;
2220 return variable; 2226 return getter;
2221 } else { 2227 }
2222 // TODO(paulberry): what if the getter and setter have a type mismatch? 2228
2223 variable.final2 = false; 2229 PropertyAccessorElementImpl buildImplicitSetter(
Paul Berry 2016/05/19 11:27:30 Ditto.
scheglov 2016/05/19 16:54:57 Done.
2224 return variable; 2230 PropertyInducingElementImpl element, String name, DartType type) {
2225 } 2231 PropertyAccessorElementImpl setter =
2232 new PropertyAccessorElementImpl(name, element.nameOffset);
2233 setter.setter = true;
2234 setter.static = element.isStatic;
2235 setter.synthetic = true;
2236 setter.parameters = <ParameterElement>[
2237 new ParameterElementImpl('_$name', element.nameOffset)
2238 ..synthetic = true
2239 ..type = type
2240 ..parameterKind = ParameterKind.REQUIRED
2241 ];
2242 setter.returnType = VoidTypeImpl.instance;
2243 setter.type = new FunctionTypeImpl(setter);
2244 setter.variable = element;
2245 element.setter = setter;
2246 return setter;
2226 } 2247 }
2227 2248
2228 /** 2249 /**
2229 * Build the appropriate [DartType] object corresponding to a slot id in the 2250 * Build the appropriate [DartType] object corresponding to a slot id in the
2230 * [LinkedUnit.types] table. 2251 * [LinkedUnit.types] table.
2231 */ 2252 */
2232 DartType buildLinkedType( 2253 DartType buildLinkedType(
2233 int slot, TypeParameterizedElementMixin typeParameterContext) { 2254 int slot, TypeParameterizedElementMixin typeParameterContext) {
2234 if (slot == 0) { 2255 if (slot == 0) {
2235 // A slot id of 0 means there is no [DartType] object to build. 2256 // A slot id of 0 means there is no [DartType] object to build.
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2397 serializedParameter.visibleLength); 2418 serializedParameter.visibleLength);
2398 } 2419 }
2399 } 2420 }
2400 return parameterElement; 2421 return parameterElement;
2401 } 2422 }
2402 2423
2403 /** 2424 /**
2404 * Handle the parts that are common to top level variables and fields. 2425 * Handle the parts that are common to top level variables and fields.
2405 */ 2426 */
2406 void buildPropertyIntroducingElementCommonParts( 2427 void buildPropertyIntroducingElementCommonParts(
2407 PropertyInducingElementImpl element, 2428 PropertyInducingElementImpl element, UnlinkedVariable serializedVariable,
2408 UnlinkedVariable serializedVariable) { 2429 {bool isLazilyResynthesized: false}) {
2409 buildVariableCommonParts(element, serializedVariable); 2430 buildVariableCommonParts(element, serializedVariable,
2431 isLazilyResynthesized: isLazilyResynthesized);
2410 element.propagatedType = buildLinkedType( 2432 element.propagatedType = buildLinkedType(
2411 serializedVariable.propagatedTypeSlot, 2433 serializedVariable.propagatedTypeSlot,
2412 _currentTypeParameterizedElement); 2434 _currentTypeParameterizedElement);
2413 } 2435 }
2414 2436
2415 /** 2437 /**
2416 * Build a [DartType] object based on a [EntityRef]. This [DartType] 2438 * Build a [DartType] object based on a [EntityRef]. This [DartType]
2417 * may refer to elements in other libraries than the library being 2439 * may refer to elements in other libraries than the library being
2418 * deserialized, so handles are used to avoid having to deserialize other 2440 * deserialized, so handles are used to avoid having to deserialize other
2419 * libraries in the process. 2441 * libraries in the process.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
2510 List<UnlinkedTypeParam> serializedTypeParameters) { 2532 List<UnlinkedTypeParam> serializedTypeParameters) {
2511 List<TypeParameterElement> typeParameters = 2533 List<TypeParameterElement> typeParameters =
2512 serializedTypeParameters.map(buildTypeParameter).toList(); 2534 serializedTypeParameters.map(buildTypeParameter).toList();
2513 currentTypeParameters.add(typeParameters); 2535 currentTypeParameters.add(typeParameters);
2514 for (int i = 0; i < serializedTypeParameters.length; i++) { 2536 for (int i = 0; i < serializedTypeParameters.length; i++) {
2515 finishTypeParameter(serializedTypeParameters[i], typeParameters[i]); 2537 finishTypeParameter(serializedTypeParameters[i], typeParameters[i]);
2516 } 2538 }
2517 return typeParameters; 2539 return typeParameters;
2518 } 2540 }
2519 2541
2542 UnitExplicitTopLevelAccessors buildUnitExplicitTopLevelAccessors() {
2543 HashMap<String, TopLevelVariableElementImpl> implicitVariables =
2544 new HashMap<String, TopLevelVariableElementImpl>();
2545 UnitExplicitTopLevelAccessors accessorsData =
2546 new UnitExplicitTopLevelAccessors();
2547 for (UnlinkedExecutable unlinkedExecutable in unlinkedUnit.executables) {
2548 UnlinkedExecutableKind kind = unlinkedExecutable.kind;
2549 if (kind == UnlinkedExecutableKind.getter ||
2550 kind == UnlinkedExecutableKind.setter) {
2551 // name
2552 String name = unlinkedExecutable.name;
2553 if (kind == UnlinkedExecutableKind.setter) {
2554 assert(name.endsWith('='));
2555 name = name.substring(0, name.length - 1);
2556 }
2557 // create
2558 PropertyAccessorElementImpl accessor =
2559 new PropertyAccessorElementImpl.forSerialized(
2560 unlinkedExecutable, unit);
2561 accessorsData.accessors.add(accessor);
2562 buildExecutableCommonParts(accessor, unlinkedExecutable);
2563 // implicit variable
2564 TopLevelVariableElementImpl variable = implicitVariables[name];
2565 if (variable == null) {
2566 variable = new TopLevelVariableElementImpl(name, -1);
2567 implicitVariables[name] = variable;
2568 accessorsData.implicitVariables.add(variable);
2569 variable.synthetic = true;
2570 variable.final2 = kind == UnlinkedExecutableKind.getter;
2571 } else {
2572 variable.final2 = false;
2573 }
2574 accessor.variable = variable;
2575 // link
2576 if (kind == UnlinkedExecutableKind.getter) {
2577 variable.getter = accessor;
2578 } else {
2579 variable.setter = accessor;
2580 }
2581 }
2582 }
2583 return accessorsData;
2584 }
2585
2586 UnitExplicitTopLevelVariables buildUnitExplicitTopLevelVariables() {
2587 UnitExplicitTopLevelVariables variablesData =
2588 new UnitExplicitTopLevelVariables();
2589 for (UnlinkedVariable unlinkedVariable in unlinkedUnit.variables) {
2590 TopLevelVariableElementImpl element;
2591 if (unlinkedVariable.constExpr != null && unlinkedVariable.isConst) {
2592 ConstTopLevelVariableElementImpl constElement =
2593 new ConstTopLevelVariableElementImpl.forSerialized(
2594 unlinkedVariable, unit);
2595 element = constElement;
2596 constElement.constantInitializer =
2597 _buildConstExpression(unlinkedVariable.constExpr);
2598 } else {
2599 element = new TopLevelVariableElementImpl.forSerialized(
2600 unlinkedVariable, unit);
2601 }
2602 buildPropertyIntroducingElementCommonParts(element, unlinkedVariable,
2603 isLazilyResynthesized: true);
2604 variablesData.variables.add(element);
2605 // implicit accessors
2606 String name = element.name;
2607 DartType type = element.type;
2608 variablesData.implicitAccessors
2609 .add(buildImplicitGetter(element, name, type));
2610 if (!(element.isConst || element.isFinal)) {
2611 variablesData.implicitAccessors
2612 .add(buildImplicitSetter(element, name, type));
2613 }
2614 }
2615 return variablesData;
2616 }
2617
2520 /** 2618 /**
2521 * Resynthesize a [TopLevelVariableElement] or [FieldElement]. 2619 * Resynthesize a [TopLevelVariableElement] or [FieldElement].
2522 */ 2620 */
2523 void buildVariable(UnlinkedVariable serializedVariable, 2621 void buildVariable(UnlinkedVariable serializedVariable,
2524 [ElementHolder holder]) { 2622 [ElementHolder holder]) {
2525 if (holder == null) { 2623 if (holder == null) {
2526 TopLevelVariableElementImpl element; 2624 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 { 2625 } else {
2542 FieldElementImpl element; 2626 FieldElementImpl element;
2543 if (serializedVariable.constExpr != null && 2627 if (serializedVariable.constExpr != null &&
2544 (serializedVariable.isConst || 2628 (serializedVariable.isConst ||
2545 serializedVariable.isFinal && !serializedVariable.isStatic)) { 2629 serializedVariable.isFinal && !serializedVariable.isStatic)) {
2546 ConstFieldElementImpl constElement = new ConstFieldElementImpl( 2630 ConstFieldElementImpl constElement = new ConstFieldElementImpl(
2547 serializedVariable.name, serializedVariable.nameOffset); 2631 serializedVariable.name, serializedVariable.nameOffset);
2548 element = constElement; 2632 element = constElement;
2549 constElement.constantInitializer = 2633 constElement.constantInitializer =
2550 _buildConstExpression(serializedVariable.constExpr); 2634 _buildConstExpression(serializedVariable.constExpr);
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
2762 2846
2763 /** 2847 /**
2764 * Populate a [CompilationUnitElement] by deserializing all the elements 2848 * Populate a [CompilationUnitElement] by deserializing all the elements
2765 * contained in it. 2849 * contained in it.
2766 */ 2850 */
2767 void populateUnit() { 2851 void populateUnit() {
2768 unlinkedUnit.classes.forEach(buildClass); 2852 unlinkedUnit.classes.forEach(buildClass);
2769 unlinkedUnit.enums.forEach(buildEnum); 2853 unlinkedUnit.enums.forEach(buildEnum);
2770 unlinkedUnit.executables.forEach((e) => buildExecutable(e, unit)); 2854 unlinkedUnit.executables.forEach((e) => buildExecutable(e, unit));
2771 unlinkedUnit.typedefs.forEach(buildTypedef); 2855 unlinkedUnit.typedefs.forEach(buildTypedef);
2772 unlinkedUnit.variables.forEach(buildVariable);
2773 unit.accessors = unitHolder.accessors;
2774 unit.enums = unitHolder.enums; 2856 unit.enums = unitHolder.enums;
2775 unit.functions = unitHolder.functions; 2857 unit.functions = unitHolder.functions;
2776 List<FunctionTypeAliasElement> typeAliases = unitHolder.typeAliases; 2858 List<FunctionTypeAliasElement> typeAliases = unitHolder.typeAliases;
2777 for (FunctionTypeAliasElementImpl typeAlias in typeAliases) { 2859 for (FunctionTypeAliasElementImpl typeAlias in typeAliases) {
2778 if (typeAlias.isSynthetic) { 2860 if (typeAlias.isSynthetic) {
2779 typeAlias.enclosingElement = unit; 2861 typeAlias.enclosingElement = unit;
2780 } 2862 }
2781 } 2863 }
2782 unit.typeAliases = typeAliases.where((e) => !e.isSynthetic).toList(); 2864 unit.typeAliases = typeAliases.where((e) => !e.isSynthetic).toList();
2783 unit.types = unitHolder.types; 2865 unit.types = unitHolder.types;
2784 unit.topLevelVariables = unitHolder.topLevelVariables;
2785 for (ClassElement cls in unit.types) { 2866 for (ClassElement cls in unit.types) {
2786 elementMap[cls.name] = cls; 2867 elementMap[cls.name] = cls;
2787 } 2868 }
2788 for (ClassElement cls in unit.enums) { 2869 for (ClassElement cls in unit.enums) {
2789 elementMap[cls.name] = cls; 2870 elementMap[cls.name] = cls;
2790 } 2871 }
2791 for (FunctionTypeAliasElement typeAlias in unit.functionTypeAliases) { 2872 for (FunctionTypeAliasElement typeAlias in unit.functionTypeAliases) {
2792 elementMap[typeAlias.name] = typeAlias; 2873 elementMap[typeAlias.name] = typeAlias;
2793 } 2874 }
2794 for (FunctionElement function in unit.functions) { 2875 for (FunctionElement function in unit.functions) {
2795 elementMap[function.name] = function; 2876 elementMap[function.name] = function;
2796 } 2877 }
2797 for (PropertyAccessorElementImpl accessor in unit.accessors) {
2798 elementMap[accessor.identifier] = accessor;
2799 }
2800 assert(currentTypeParameters.isEmpty); 2878 assert(currentTypeParameters.isEmpty);
2801 } 2879 }
2802 2880
2803 /** 2881 /**
2804 * Constructor initializers can reference fields and other constructors of 2882 * Constructor initializers can reference fields and other constructors of
2805 * the same class, including forward references. So, we need to delay 2883 * the same class, including forward references. So, we need to delay
2806 * resolution until after class elements are built. 2884 * resolution until after class elements are built.
2807 */ 2885 */
2808 void resolveConstructorInitializers(ClassElementImpl classElement) { 2886 void resolveConstructorInitializers(ClassElementImpl classElement) {
2809 for (ConstructorElementImpl constructor in constructors.values) { 2887 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) { 2957 static String _getElementIdentifier(String name, ReferenceKind kind) {
2880 if (kind == ReferenceKind.topLevelPropertyAccessor || 2958 if (kind == ReferenceKind.topLevelPropertyAccessor ||
2881 kind == ReferenceKind.propertyAccessor) { 2959 kind == ReferenceKind.propertyAccessor) {
2882 if (!name.endsWith('=')) { 2960 if (!name.endsWith('=')) {
2883 return name + '?'; 2961 return name + '?';
2884 } 2962 }
2885 } 2963 }
2886 return name; 2964 return name;
2887 } 2965 }
2888 } 2966 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698