| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |