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

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

Issue 1649533005: Compute literal constant values. (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 | pkg/analyzer/test/src/summary/resynthesize_test.dart » ('j') | 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/element/element.dart'; 10 import 'package:analyzer/dart/element/element.dart';
10 import 'package:analyzer/dart/element/type.dart'; 11 import 'package:analyzer/dart/element/type.dart';
11 import 'package:analyzer/src/dart/element/element.dart'; 12 import 'package:analyzer/src/dart/element/element.dart';
12 import 'package:analyzer/src/dart/element/type.dart'; 13 import 'package:analyzer/src/dart/element/type.dart';
14 import 'package:analyzer/src/generated/constant.dart';
13 import 'package:analyzer/src/generated/element_handle.dart'; 15 import 'package:analyzer/src/generated/element_handle.dart';
14 import 'package:analyzer/src/generated/engine.dart'; 16 import 'package:analyzer/src/generated/engine.dart';
15 import 'package:analyzer/src/generated/resolver.dart'; 17 import 'package:analyzer/src/generated/resolver.dart';
18 import 'package:analyzer/src/generated/scanner.dart';
16 import 'package:analyzer/src/generated/source_io.dart'; 19 import 'package:analyzer/src/generated/source_io.dart';
20 import 'package:analyzer/src/generated/testing/ast_factory.dart';
21 import 'package:analyzer/src/generated/testing/token_factory.dart';
17 import 'package:analyzer/src/generated/utilities_dart.dart'; 22 import 'package:analyzer/src/generated/utilities_dart.dart';
18 import 'package:analyzer/src/summary/format.dart'; 23 import 'package:analyzer/src/summary/format.dart';
24 import 'package:analyzer/src/task/dart.dart' show ConstantEvaluationTarget;
19 25
20 /** 26 /**
21 * Implementation of [ElementResynthesizer] used when resynthesizing an element 27 * Implementation of [ElementResynthesizer] used when resynthesizing an element
22 * model from summaries. 28 * model from summaries.
23 */ 29 */
24 abstract class SummaryResynthesizer extends ElementResynthesizer { 30 abstract class SummaryResynthesizer extends ElementResynthesizer {
25 /** 31 /**
26 * The parent [SummaryResynthesizer] which is asked to resynthesize elements 32 * The parent [SummaryResynthesizer] which is asked to resynthesize elements
27 * and get summaries before this resynthesizer attempts to do this. 33 * and get summaries before this resynthesizer attempts to do this.
28 * Can be `null`. 34 * Can be `null`.
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 */ 239 */
234 bool _hasLibrarySummary(String uri) { 240 bool _hasLibrarySummary(String uri) {
235 if (parent != null && parent._hasLibrarySummary(uri)) { 241 if (parent != null && parent._hasLibrarySummary(uri)) {
236 return true; 242 return true;
237 } 243 }
238 return hasLibrarySummary(uri); 244 return hasLibrarySummary(uri);
239 } 245 }
240 } 246 }
241 247
242 /** 248 /**
249 * Builder of [Expression]s from [UnlinkedConst]s.
250 */
251 class _ConstExprBuilder {
252 final SummaryResynthesizer resynthesizer;
253 final UnlinkedConst uc;
254
255 int intPtr = 0;
256 int doublePtr = 0;
257 int stringPtr = 0;
258 int refPtr = 0;
259 final List<Expression> stack = <Expression>[];
260
261 _ConstExprBuilder(this.resynthesizer, this.uc);
262
263 Expression get expr => stack.single;
264
265 Expression build() {
266 // TODO(scheglov) complete implementation
267 for (UnlinkedConstOperation operation in uc.operations) {
268 switch (operation) {
269 case UnlinkedConstOperation.pushNull:
270 stack.add(AstFactory.nullLiteral());
271 break;
272 case UnlinkedConstOperation.pushFalse:
273 stack.add(AstFactory.booleanLiteral(false));
274 break;
275 case UnlinkedConstOperation.pushTrue:
276 stack.add(AstFactory.booleanLiteral(true));
277 break;
278 case UnlinkedConstOperation.pushInt:
279 int value = uc.ints[intPtr++];
280 stack.add(AstFactory.integer(value));
281 break;
282 case UnlinkedConstOperation.pushDouble:
283 double value = uc.doubles[doublePtr++];
284 stack.add(AstFactory.doubleLiteral(value));
285 break;
286 case UnlinkedConstOperation.pushString:
287 String value = uc.strings[stringPtr++];
288 stack.add(AstFactory.string2(value));
289 break;
290 case UnlinkedConstOperation.concatenate:
291 int count = uc.ints[intPtr++];
292 List<InterpolationElement> elements = <InterpolationElement>[];
293 for (int i = 0; i < count; i++) {
294 Expression expr = stack.removeLast();
295 InterpolationElement element = _newInterpolationElement(expr);
296 elements.insert(0, element);
297 }
298 stack.add(AstFactory.string(elements));
299 break;
300 default:
301 return AstFactory.nullLiteral();
302 // throw new StateError('Unsupported constant operation $operation');
303 }
304 }
305 return stack.single;
306 }
307
308 InterpolationElement _newInterpolationElement(Expression expr) {
309 if (expr is SimpleStringLiteral) {
310 return new InterpolationString(expr.literal, expr.value);
311 } else {
312 return new InterpolationExpression(
313 TokenFactory.tokenFromType(TokenType.STRING_INTERPOLATION_EXPRESSION),
314 expr,
315 TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET));
316 }
317 }
318 }
319
320 /**
321 * A single constant variable for which the constant value should be computed.
322 *
323 * TODO(scheglov) we will probably need to add dependency list
324 */
325 class _ConstVariable {
326 final ConstVariableElement element;
327
328 _ConstVariable(this.element);
329 }
330
331 /**
243 * An instance of [_LibraryResynthesizer] is responsible for resynthesizing the 332 * An instance of [_LibraryResynthesizer] is responsible for resynthesizing the
244 * elements in a single library from that library's summary. 333 * elements in a single library from that library's summary.
245 */ 334 */
246 class _LibraryResynthesizer { 335 class _LibraryResynthesizer {
247 /** 336 /**
248 * The [SummaryResynthesizer] which is being used to obtain summaries. 337 * The [SummaryResynthesizer] which is being used to obtain summaries.
249 */ 338 */
250 final SummaryResynthesizer summaryResynthesizer; 339 final SummaryResynthesizer summaryResynthesizer;
251 340
252 /** 341 /**
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 */ 406 */
318 List<TypeParameterElement> currentTypeParameters = <TypeParameterElement>[]; 407 List<TypeParameterElement> currentTypeParameters = <TypeParameterElement>[];
319 408
320 /** 409 /**
321 * If a class is currently being resynthesized, map from field name to the 410 * If a class is currently being resynthesized, map from field name to the
322 * corresponding field element. This is used when resynthesizing 411 * corresponding field element. This is used when resynthesizing
323 * initializing formal parameters. 412 * initializing formal parameters.
324 */ 413 */
325 Map<String, FieldElementImpl> fields; 414 Map<String, FieldElementImpl> fields;
326 415
416 /**
417 * List of constant variables to compute values for.
418 */
419 List<_ConstVariable> constVariables = <_ConstVariable>[];
420
327 _LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary, 421 _LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary,
328 this.unlinkedUnits, this.librarySource) { 422 this.unlinkedUnits, this.librarySource) {
329 isCoreLibrary = librarySource.uri.toString() == 'dart:core'; 423 isCoreLibrary = librarySource.uri.toString() == 'dart:core';
330 } 424 }
331 425
332 /** 426 /**
333 * Return a list of type arguments corresponding to [currentTypeParameters]. 427 * Return a list of type arguments corresponding to [currentTypeParameters].
334 */ 428 */
335 List<TypeParameterType> get currentTypeArguments => currentTypeParameters 429 List<TypeParameterType> get currentTypeArguments => currentTypeParameters
336 ?.map((TypeParameterElement param) => param.type) 430 ?.map((TypeParameterElement param) => param.type)
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 library.entryPoint = entryPoint; 984 library.entryPoint = entryPoint;
891 } 985 }
892 // Create the synthetic element for `loadLibrary`. 986 // Create the synthetic element for `loadLibrary`.
893 // Until the client received dart:core and dart:async, we cannot do this, 987 // Until the client received dart:core and dart:async, we cannot do this,
894 // because the TypeProvider is not fully initialized. So, it is up to the 988 // because the TypeProvider is not fully initialized. So, it is up to the
895 // Dart SDK client to initialize TypeProvider and finish the dart:core and 989 // Dart SDK client to initialize TypeProvider and finish the dart:core and
896 // dart:async libraries creation. 990 // dart:async libraries creation.
897 if (library.name != 'dart.core' && library.name != 'dart.async') { 991 if (library.name != 'dart.core' && library.name != 'dart.async') {
898 library.createLoadLibraryFunction(summaryResynthesizer.typeProvider); 992 library.createLoadLibraryFunction(summaryResynthesizer.typeProvider);
899 } 993 }
994 // Compute constants.
995 for (_ConstVariable constVariable in constVariables) {
996 AnalysisContext context = summaryResynthesizer.context;
997 ConstantEvaluationEngine constantEvaluationEngine =
998 new ConstantEvaluationEngine(
999 summaryResynthesizer.typeProvider, context.declaredVariables,
1000 typeSystem: context.typeSystem);
1001 ConstantEvaluationTarget constTarget =
1002 constVariable.element as ConstantEvaluationTarget;
1003 constantEvaluationEngine.computeConstantValue(constTarget);
1004 }
900 // Done. 1005 // Done.
901 return library; 1006 return library;
902 } 1007 }
903 1008
904 /** 1009 /**
905 * Build the appropriate [DartType] object corresponding to a slot id in the 1010 * Build the appropriate [DartType] object corresponding to a slot id in the
906 * [LinkedUnit.types] table. 1011 * [LinkedUnit.types] table.
907 */ 1012 */
908 DartType buildLinkedType(int slot) { 1013 DartType buildLinkedType(int slot) {
909 if (slot == 0) { 1014 if (slot == 0) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 if (type == null) { 1103 if (type == null) {
999 if (defaultVoid) { 1104 if (defaultVoid) {
1000 return VoidTypeImpl.instance; 1105 return VoidTypeImpl.instance;
1001 } else { 1106 } else {
1002 return summaryResynthesizer.typeProvider.dynamicType; 1107 return summaryResynthesizer.typeProvider.dynamicType;
1003 } 1108 }
1004 } 1109 }
1005 if (type.paramReference != 0) { 1110 if (type.paramReference != 0) {
1006 // TODO(paulberry): make this work for generic methods. 1111 // TODO(paulberry): make this work for generic methods.
1007 return currentTypeParameters[ 1112 return currentTypeParameters[
1008 currentTypeParameters.length - type.paramReference].type; 1113 currentTypeParameters.length - type.paramReference]
1114 .type;
1009 } else { 1115 } else {
1010 LinkedReference referenceResolution = 1116 LinkedReference referenceResolution =
1011 linkedUnit.references[type.reference]; 1117 linkedUnit.references[type.reference];
1012 String name; 1118 String name;
1013 if (type.reference < unlinkedUnit.references.length) { 1119 if (type.reference < unlinkedUnit.references.length) {
1014 name = unlinkedUnit.references[type.reference].name; 1120 name = unlinkedUnit.references[type.reference].name;
1015 } else { 1121 } else {
1016 name = referenceResolution.name; 1122 name = referenceResolution.name;
1017 } 1123 }
1018 ElementLocationImpl location; 1124 ElementLocationImpl location;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 typeParameterElement.type = new TypeParameterTypeImpl(typeParameterElement); 1226 typeParameterElement.type = new TypeParameterTypeImpl(typeParameterElement);
1121 return typeParameterElement; 1227 return typeParameterElement;
1122 } 1228 }
1123 1229
1124 /** 1230 /**
1125 * Resynthesize a [TopLevelVariableElement] or [FieldElement]. 1231 * Resynthesize a [TopLevelVariableElement] or [FieldElement].
1126 */ 1232 */
1127 void buildVariable(UnlinkedVariable serializedVariable, 1233 void buildVariable(UnlinkedVariable serializedVariable,
1128 [ElementHolder holder]) { 1234 [ElementHolder holder]) {
1129 if (holder == null) { 1235 if (holder == null) {
1130 TopLevelVariableElementImpl element = new TopLevelVariableElementImpl( 1236 TopLevelVariableElementImpl element;
1131 serializedVariable.name, serializedVariable.nameOffset); 1237 if (serializedVariable.constExpr != null) {
1238 ConstTopLevelVariableElementImpl constElement =
1239 new ConstTopLevelVariableElementImpl(
1240 serializedVariable.name, serializedVariable.nameOffset);
1241 element = constElement;
1242 // TODO(scheglov) share const builder?
1243 _ConstExprBuilder builder = new _ConstExprBuilder(
1244 summaryResynthesizer, serializedVariable.constExpr);
1245 constElement.constantInitializer = builder.build();
1246 constVariables.add(new _ConstVariable(constElement));
1247 } else {
1248 element = new TopLevelVariableElementImpl(
1249 serializedVariable.name, serializedVariable.nameOffset);
1250 }
1132 buildVariableCommonParts(element, serializedVariable); 1251 buildVariableCommonParts(element, serializedVariable);
1133 unitHolder.addTopLevelVariable(element); 1252 unitHolder.addTopLevelVariable(element);
1134 buildImplicitAccessors(element, unitHolder); 1253 buildImplicitAccessors(element, unitHolder);
1135 } else { 1254 } else {
1136 FieldElementImpl element = new FieldElementImpl( 1255 FieldElementImpl element = new FieldElementImpl(
1137 serializedVariable.name, serializedVariable.nameOffset); 1256 serializedVariable.name, serializedVariable.nameOffset);
1138 buildVariableCommonParts(element, serializedVariable); 1257 buildVariableCommonParts(element, serializedVariable);
1139 element.static = serializedVariable.isStatic; 1258 element.static = serializedVariable.isStatic;
1140 holder.addField(element); 1259 holder.addField(element);
1141 buildImplicitAccessors(element, holder); 1260 buildImplicitAccessors(element, holder);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1242 for (PropertyAccessorElementImpl accessor in unit.accessors) { 1361 for (PropertyAccessorElementImpl accessor in unit.accessors) {
1243 elementMap[accessor.identifier] = accessor; 1362 elementMap[accessor.identifier] = accessor;
1244 } 1363 }
1245 resummarizedElements[absoluteUri] = elementMap; 1364 resummarizedElements[absoluteUri] = elementMap;
1246 unitHolder = null; 1365 unitHolder = null;
1247 linkedUnit = null; 1366 linkedUnit = null;
1248 unlinkedUnit = null; 1367 unlinkedUnit = null;
1249 linkedTypeMap = null; 1368 linkedTypeMap = null;
1250 } 1369 }
1251 } 1370 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/resynthesize_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698