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

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

Issue 1649893002: Refactor code for resynthesizing references in summaries. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/element/element.dart'; 10 import 'package:analyzer/dart/element/element.dart';
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 * corresponding field element. This is used when resynthesizing 411 * corresponding field element. This is used when resynthesizing
412 * initializing formal parameters. 412 * initializing formal parameters.
413 */ 413 */
414 Map<String, FieldElementImpl> fields; 414 Map<String, FieldElementImpl> fields;
415 415
416 /** 416 /**
417 * List of constant variables to compute values for. 417 * List of constant variables to compute values for.
418 */ 418 */
419 List<_ConstVariable> constVariables = <_ConstVariable>[]; 419 List<_ConstVariable> constVariables = <_ConstVariable>[];
420 420
421 /**
422 * List of [_ReferenceInfo] objects describing the references in the current
423 * compilation unit.
424 */
425 List<_ReferenceInfo> referenceInfos;
426
421 _LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary, 427 _LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary,
422 this.unlinkedUnits, this.librarySource) { 428 this.unlinkedUnits, this.librarySource) {
423 isCoreLibrary = librarySource.uri.toString() == 'dart:core'; 429 isCoreLibrary = librarySource.uri.toString() == 'dart:core';
424 } 430 }
425 431
426 /** 432 /**
427 * Return a list of type arguments corresponding to [currentTypeParameters]. 433 * Return a list of type arguments corresponding to [currentTypeParameters].
428 */ 434 */
429 List<TypeParameterType> get currentTypeArguments => currentTypeParameters 435 List<TypeParameterType> get currentTypeArguments => currentTypeParameters
430 ?.map((TypeParameterElement param) => param.type) 436 ?.map((TypeParameterElement param) => param.type)
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after
1106 } else { 1112 } else {
1107 return summaryResynthesizer.typeProvider.dynamicType; 1113 return summaryResynthesizer.typeProvider.dynamicType;
1108 } 1114 }
1109 } 1115 }
1110 if (type.paramReference != 0) { 1116 if (type.paramReference != 0) {
1111 // TODO(paulberry): make this work for generic methods. 1117 // TODO(paulberry): make this work for generic methods.
1112 return currentTypeParameters[ 1118 return currentTypeParameters[
1113 currentTypeParameters.length - type.paramReference] 1119 currentTypeParameters.length - type.paramReference]
1114 .type; 1120 .type;
1115 } else { 1121 } else {
1116 LinkedReference referenceResolution = 1122 DartType getTypeParameter(int i) {
1117 linkedUnit.references[type.reference]; 1123 if (i < type.typeArguments.length) {
1118 String name; 1124 return buildType(type.typeArguments[i]);
1119 if (type.reference < unlinkedUnit.references.length) {
1120 name = unlinkedUnit.references[type.reference].name;
1121 } else {
1122 name = referenceResolution.name;
1123 }
1124 ElementLocationImpl location;
1125 if (referenceResolution.dependency != 0) {
1126 location = getReferencedLocation(
1127 linkedLibrary.dependencies[referenceResolution.dependency],
1128 referenceResolution.unit,
1129 name);
1130 } else if (referenceResolution.kind == ReferenceKind.unresolved) {
1131 return summaryResynthesizer.typeProvider.undefinedType;
1132 } else if (name == 'dynamic') {
1133 return summaryResynthesizer.typeProvider.dynamicType;
1134 } else if (name == 'void') {
1135 return VoidTypeImpl.instance;
1136 } else {
1137 String referencedLibraryUri = librarySource.uri.toString();
1138 String partUri;
1139 if (referenceResolution.unit != 0) {
1140 String uri = unlinkedUnits[0].publicNamespace.parts[
1141 referenceResolution.unit - 1];
1142 Source partSource =
1143 summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
1144 partUri = partSource.uri.toString();
1145 } else { 1125 } else {
1146 partUri = referencedLibraryUri; 1126 return summaryResynthesizer.typeProvider.dynamicType;
1147 }
1148 location = new ElementLocationImpl.con3(
1149 <String>[referencedLibraryUri, partUri, name]);
1150 }
1151 List<DartType> typeArguments = const <DartType>[];
1152 if (referenceResolution.numTypeParameters != 0) {
1153 typeArguments = <DartType>[];
1154 for (int i = 0; i < referenceResolution.numTypeParameters; i++) {
1155 if (i < type.typeArguments.length) {
1156 typeArguments.add(buildType(type.typeArguments[i]));
1157 } else {
1158 typeArguments.add(summaryResynthesizer.typeProvider.dynamicType);
1159 }
1160 } 1127 }
1161 } 1128 }
1162 switch (referenceResolution.kind) { 1129 _ReferenceInfo referenceInfo = referenceInfos[type.reference];
1163 case ReferenceKind.classOrEnum: 1130 return referenceInfo.buildType(getTypeParameter);
1164 return new InterfaceTypeImpl.elementWithNameAndArgs(
1165 new ClassElementHandle(summaryResynthesizer, location),
1166 name,
1167 typeArguments);
1168 case ReferenceKind.typedef:
1169 return new FunctionTypeImpl.elementWithNameAndArgs(
1170 new FunctionTypeAliasElementHandle(
1171 summaryResynthesizer, location),
1172 name,
1173 typeArguments,
1174 typeArguments.isNotEmpty);
1175 default:
1176 // TODO(paulberry): figure out how to handle this case (which should
1177 // only occur in the event of erroneous code).
1178 throw new UnimplementedError();
1179 }
1180 } 1131 }
1181 } 1132 }
1182 1133
1183 /** 1134 /**
1184 * Resynthesize a [FunctionTypeAliasElement] and place it in the 1135 * Resynthesize a [FunctionTypeAliasElement] and place it in the
1185 * [unitHolder]. 1136 * [unitHolder].
1186 */ 1137 */
1187 void buildTypedef(UnlinkedTypedef serializedTypedef) { 1138 void buildTypedef(UnlinkedTypedef serializedTypedef) {
1188 try { 1139 try {
1189 currentTypeParameters = 1140 currentTypeParameters =
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1309 .resolveUri(referencedLibrarySource, uri); 1260 .resolveUri(referencedLibrarySource, uri);
1310 partUri = partSource.uri.toString(); 1261 partUri = partSource.uri.toString();
1311 } else { 1262 } else {
1312 partUri = referencedLibraryUri; 1263 partUri = referencedLibraryUri;
1313 } 1264 }
1314 return new ElementLocationImpl.con3( 1265 return new ElementLocationImpl.con3(
1315 <String>[referencedLibraryUri, partUri, name]); 1266 <String>[referencedLibraryUri, partUri, name]);
1316 } 1267 }
1317 1268
1318 /** 1269 /**
1270 * Populate [referenceInfos] with the correct information for the current
1271 * compilation unit.
1272 */
1273 void populateReferenceInfos() {
1274 int numLinkedReferences = linkedUnit.references.length;
1275 int numUnlinkedReferences = unlinkedUnit.references.length;
1276 referenceInfos = new List<_ReferenceInfo>(numLinkedReferences);
1277 for (int i = 0; i < numLinkedReferences; i++) {
1278 LinkedReference linkedReference = linkedUnit.references[i];
1279 String name;
1280 if (i < numUnlinkedReferences) {
1281 name = unlinkedUnit.references[i].name;
1282 } else {
1283 name = linkedUnit.references[i].name;
1284 }
1285 ElementHandle element;
1286 DartType type;
1287 if (linkedReference.kind == ReferenceKind.unresolved) {
1288 type = summaryResynthesizer.typeProvider.undefinedType;
1289 } else if (name == 'dynamic') {
1290 type = summaryResynthesizer.typeProvider.dynamicType;
1291 } else if (name == 'void') {
1292 type = VoidTypeImpl.instance;
1293 } else {
1294 ElementLocation location;
1295 if (linkedReference.dependency != 0) {
1296 location = getReferencedLocation(
1297 linkedLibrary.dependencies[linkedReference.dependency],
1298 linkedReference.unit,
1299 name);
1300 } else {
1301 String referencedLibraryUri = librarySource.uri.toString();
1302 String partUri;
1303 if (linkedReference.unit != 0) {
1304 String uri = unlinkedUnits[0].publicNamespace.parts[
1305 linkedReference.unit - 1];
1306 Source partSource = summaryResynthesizer.sourceFactory
1307 .resolveUri(librarySource, uri);
1308 partUri = partSource.uri.toString();
1309 } else {
1310 partUri = referencedLibraryUri;
1311 }
1312 location = new ElementLocationImpl.con3(
1313 <String>[referencedLibraryUri, partUri, name]);
1314 }
1315 switch (linkedReference.kind) {
1316 case ReferenceKind.classOrEnum:
1317 element = new ClassElementHandle(summaryResynthesizer, location);
1318 break;
1319 case ReferenceKind.typedef:
1320 element = new FunctionTypeAliasElementHandle(
1321 summaryResynthesizer, location);
1322 break;
1323 default:
1324 // This is an element that doesn't (yet) need to be referred to
1325 // directly, so don't bother populating an element for it.
1326 // TODO(paulberry): add support for more kinds, as needed.
1327 break;
1328 }
1329 }
1330 referenceInfos[i] = new _ReferenceInfo(
1331 name, element, type, linkedReference.numTypeParameters);
1332 }
1333 }
1334
1335 /**
1319 * Populate a [CompilationUnitElement] by deserializing all the elements 1336 * Populate a [CompilationUnitElement] by deserializing all the elements
1320 * contained in it. 1337 * contained in it.
1321 */ 1338 */
1322 void populateUnit(CompilationUnitElementImpl unit, int unitNum) { 1339 void populateUnit(CompilationUnitElementImpl unit, int unitNum) {
1323 linkedUnit = linkedLibrary.units[unitNum]; 1340 linkedUnit = linkedLibrary.units[unitNum];
1324 unlinkedUnit = unlinkedUnits[unitNum]; 1341 unlinkedUnit = unlinkedUnits[unitNum];
1325 linkedTypeMap = <int, EntityRef>{}; 1342 linkedTypeMap = <int, EntityRef>{};
1326 for (EntityRef t in linkedUnit.types) { 1343 for (EntityRef t in linkedUnit.types) {
1327 linkedTypeMap[t.slot] = t; 1344 linkedTypeMap[t.slot] = t;
1328 } 1345 }
1346 populateReferenceInfos();
1329 unitHolder = new ElementHolder(); 1347 unitHolder = new ElementHolder();
1330 unlinkedUnit.classes.forEach(buildClass); 1348 unlinkedUnit.classes.forEach(buildClass);
1331 unlinkedUnit.enums.forEach(buildEnum); 1349 unlinkedUnit.enums.forEach(buildEnum);
1332 unlinkedUnit.executables.forEach(buildExecutable); 1350 unlinkedUnit.executables.forEach(buildExecutable);
1333 unlinkedUnit.typedefs.forEach(buildTypedef); 1351 unlinkedUnit.typedefs.forEach(buildTypedef);
1334 unlinkedUnit.variables.forEach(buildVariable); 1352 unlinkedUnit.variables.forEach(buildVariable);
1335 String absoluteUri = unit.source.uri.toString(); 1353 String absoluteUri = unit.source.uri.toString();
1336 unit.accessors = unitHolder.accessors; 1354 unit.accessors = unitHolder.accessors;
1337 unit.enums = unitHolder.enums; 1355 unit.enums = unitHolder.enums;
1338 unit.functions = unitHolder.functions; 1356 unit.functions = unitHolder.functions;
(...skipping 20 matching lines...) Expand all
1359 elementMap[function.name] = function; 1377 elementMap[function.name] = function;
1360 } 1378 }
1361 for (PropertyAccessorElementImpl accessor in unit.accessors) { 1379 for (PropertyAccessorElementImpl accessor in unit.accessors) {
1362 elementMap[accessor.identifier] = accessor; 1380 elementMap[accessor.identifier] = accessor;
1363 } 1381 }
1364 resummarizedElements[absoluteUri] = elementMap; 1382 resummarizedElements[absoluteUri] = elementMap;
1365 unitHolder = null; 1383 unitHolder = null;
1366 linkedUnit = null; 1384 linkedUnit = null;
1367 unlinkedUnit = null; 1385 unlinkedUnit = null;
1368 linkedTypeMap = null; 1386 linkedTypeMap = null;
1387 referenceInfos = null;
1369 } 1388 }
1370 } 1389 }
1390
1391 /**
1392 * Data structure used during resynthesis to record all the information that is
1393 * known about how to reserialize a single entry in [LinkedUnit.references]
1394 * (and its associated entry in [UnlinkedUnit.references], if it exists).
1395 */
1396 class _ReferenceInfo {
1397 /**
1398 * The name of the entity referred to by this reference.
1399 */
1400 final String name;
1401
1402 /**
1403 * The element referred to by this reference, or `null` if there is no
1404 * associated element (e.g. because it is a reference to an undefined
1405 * entity).
1406 */
1407 final ElementHandle element;
1408
1409 /**
1410 * If this reference refers to a non-generic type, the type it refers to.
1411 * Otherwise `null`.
1412 */
1413 DartType type;
1414
1415 /**
1416 * The number of type parameters accepted by the entity referred to by this
1417 * reference, or zero if it doesn't accept any type parameters.
1418 */
1419 final int numTypeParameters;
1420
1421 /**
1422 * Create a new [_ReferenceInfo] object referring to an element called [name]
1423 * via the element handle [elementHandle], and having [numTypeParameters]
1424 * type parameters.
1425 *
1426 * For the special types `dynamic` and `void`, [specialType] should point to
1427 * the type itself. Otherwise, pass `null` and the type will be computed
1428 * when appropriate.
1429 */
1430 _ReferenceInfo(
1431 this.name, this.element, DartType specialType, this.numTypeParameters) {
1432 if (specialType != null) {
1433 type = specialType;
1434 } else if (numTypeParameters == 0) {
1435 // We can precompute the type because it doesn't depend on type
1436 // parameters.
1437 type = _buildType(null);
1438 }
1439 }
1440
1441 /**
1442 * Build a [DartType] corresponding to the result of applying the entity
1443 * referred to by this [_ReferenceInfo] to some type parameters. The type
scheglov 2016/01/28 22:52:51 I guess the "apply" operation is commutative, but
Paul Berry 2016/01/28 23:05:56 Done.
1444 * parameters are retrieved by calling [getTypeParameter].
1445 *
1446 * If the entity referred to by this [_ReferenceInfo] is not a type, `null`
1447 * is returned.
1448 */
1449 DartType buildType(DartType getTypeParameter(int i)) {
1450 DartType result =
1451 numTypeParameters == 0 ? type : _buildType(getTypeParameter);
1452 if (result == null) {
1453 // TODO(paulberry): figure out how to handle this case (which should
1454 // only occur in the event of erroneous code).
1455 throw new UnimplementedError();
1456 }
1457 return result;
1458 }
1459
1460 /**
1461 * If this reference refers to a type, build a [DartType] which instantiates
1462 * it with type arguments returned by [getTypeParameter]. Otherwise return
1463 * `null`.
1464 */
1465 DartType _buildType(DartType getTypeParameter(int i)) {
scheglov 2016/01/28 22:52:51 Would it be better to name this function "getTypeA
Paul Berry 2016/01/28 23:05:56 Done.
1466 List<DartType> typeArguments = const <DartType>[];
1467 if (numTypeParameters != 0) {
1468 typeArguments = <DartType>[];
1469 for (int i = 0; i < numTypeParameters; i++) {
1470 typeArguments.add(getTypeParameter(i));
1471 }
1472 }
1473 ElementHandle element = this.element; // To allow type promotion
1474 if (element is ClassElementHandle) {
1475 return new InterfaceTypeImpl.elementWithNameAndArgs(
1476 element, name, typeArguments);
1477 } else if (element is FunctionTypeAliasElementHandle) {
1478 return new FunctionTypeImpl.elementWithNameAndArgs(
1479 element, name, typeArguments, typeArguments.isNotEmpty);
1480 } else {
1481 return null;
1482 }
1483 }
1484 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698