Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 dart2js.compile_time_constant_evaluator; | 5 library dart2js.compile_time_constant_evaluator; |
| 6 | 6 |
| 7 import 'common.dart'; | 7 import 'common.dart'; |
| 8 import 'common/resolution.dart' show Resolution; | 8 import 'common/resolution.dart' show Resolution; |
| 9 import 'common/tasks.dart' show CompilerTask; | 9 import 'common/tasks.dart' show CompilerTask; |
| 10 import 'compiler.dart' show Compiler; | 10 import 'compiler.dart' show Compiler; |
| 11 import 'constant_system_dart.dart'; | 11 import 'constant_system_dart.dart'; |
| 12 import 'constants/constant_system.dart'; | 12 import 'constants/constant_system.dart'; |
| 13 import 'constants/evaluation.dart'; | 13 import 'constants/evaluation.dart'; |
| 14 import 'constants/expressions.dart'; | 14 import 'constants/expressions.dart'; |
| 15 import 'constants/values.dart'; | 15 import 'constants/values.dart'; |
| 16 import 'core_types.dart' show CoreTypes; | 16 import 'core_types.dart' show CoreTypes; |
| 17 import 'dart_types.dart'; | 17 import 'dart_types.dart'; |
| 18 import 'elements/elements.dart'; | 18 import 'elements/elements.dart'; |
| 19 import 'elements/modelx.dart' show FieldElementX, FunctionElementX; | 19 import 'elements/modelx.dart' show FieldElementX, FunctionElementX, ConstantVari ableMixin; |
| 20 import 'resolution/tree_elements.dart' show TreeElements; | 20 import 'resolution/tree_elements.dart' show TreeElements; |
| 21 import 'resolution/operators.dart'; | 21 import 'resolution/operators.dart'; |
| 22 import 'tree/tree.dart'; | 22 import 'tree/tree.dart'; |
| 23 import 'util/util.dart' show Link; | 23 import 'util/util.dart' show Link; |
| 24 import 'universe/call_structure.dart' show CallStructure; | 24 import 'universe/call_structure.dart' show CallStructure; |
| 25 | 25 |
| 26 /// A [ConstantEnvironment] provides access for constants compiled for variable | 26 /// A [ConstantEnvironment] provides access for constants compiled for variable |
| 27 /// initializers. | 27 /// initializers. |
| 28 abstract class ConstantEnvironment { | 28 abstract class ConstantEnvironment { |
| 29 /// The [ConstantSystem] used by this environment. | 29 /// The [ConstantSystem] used by this environment. |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 180 | 180 |
| 181 /// Compile [element] into a constant expression. If [isConst] is true, | 181 /// Compile [element] into a constant expression. If [isConst] is true, |
| 182 /// then [element] is a constant variable. If [checkType] is true, then | 182 /// then [element] is a constant variable. If [checkType] is true, then |
| 183 /// report an error if [element] does not typecheck. | 183 /// report an error if [element] does not typecheck. |
| 184 ConstantExpression internalCompileVariable( | 184 ConstantExpression internalCompileVariable( |
| 185 VariableElement element, bool isConst, bool checkType) { | 185 VariableElement element, bool isConst, bool checkType) { |
| 186 if (initialVariableValues.containsKey(element.declaration)) { | 186 if (initialVariableValues.containsKey(element.declaration)) { |
| 187 ConstantExpression result = initialVariableValues[element.declaration]; | 187 ConstantExpression result = initialVariableValues[element.declaration]; |
| 188 return result; | 188 return result; |
| 189 } | 189 } |
| 190 if (element.hasConstant) { | |
| 191 if (element.constant != null) { | |
| 192 evaluate(element.constant); | |
|
Siggi Cherem (dart-lang)
2016/05/19 16:46:45
could this add more evaluations than what we had i
Johnni Winther
2016/05/20 11:02:13
I'll put it behind a test for deserialization.
Siggi Cherem (dart-lang)
2016/05/20 21:08:02
Not sure I follow why it is needed then. I would e
Johnni Winther
2016/05/23 07:54:41
Yes. Will add an assertion.
| |
| 193 } | |
| 194 return element.constant; | |
| 195 } | |
| 190 AstElement currentElement = element.analyzableElement; | 196 AstElement currentElement = element.analyzableElement; |
| 191 return reporter.withCurrentElement(currentElement, () { | 197 return reporter.withCurrentElement(element, () { |
| 192 // TODO(johnniwinther): Avoid this eager analysis. | 198 // TODO(johnniwinther): Avoid this eager analysis. |
| 193 compiler.resolution.ensureResolved(currentElement.declaration); | 199 compiler.resolution.ensureResolved(currentElement.declaration); |
| 194 | 200 |
| 195 ConstantExpression constant = compileVariableWithDefinitions( | 201 ConstantExpression constant = compileVariableWithDefinitions( |
| 196 element, currentElement.resolvedAst.elements, | 202 element, currentElement.resolvedAst.elements, |
| 197 isConst: isConst, checkType: checkType); | 203 isConst: isConst, checkType: checkType); |
| 198 return constant; | 204 return constant; |
| 199 }); | 205 }); |
| 200 } | 206 } |
| 201 | 207 |
| 202 /** | 208 /** |
| 203 * Returns the a compile-time constant if the variable could be compiled | 209 * Returns the a compile-time constant if the variable could be compiled |
| 204 * eagerly. If the variable needs to be initialized lazily returns `null`. | 210 * eagerly. If the variable needs to be initialized lazily returns `null`. |
| 205 * If the variable is `const` but cannot be compiled eagerly reports an | 211 * If the variable is `const` but cannot be compiled eagerly reports an |
| 206 * error. | 212 * error. |
| 207 */ | 213 */ |
| 208 ConstantExpression compileVariableWithDefinitions( | 214 ConstantExpression compileVariableWithDefinitions( |
| 209 VariableElement element, TreeElements definitions, | 215 ConstantVariableMixin element, TreeElements definitions, |
| 210 {bool isConst: false, bool checkType: true}) { | 216 {bool isConst: false, bool checkType: true}) { |
| 211 Node node = element.node; | 217 Node node = element.node; |
| 212 if (pendingVariables.contains(element)) { | 218 if (pendingVariables.contains(element)) { |
| 213 if (isConst) { | 219 if (isConst) { |
| 214 reporter.reportErrorMessage( | 220 reporter.reportErrorMessage( |
| 215 node, MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS); | 221 node, MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS); |
| 216 ConstantExpression expression = new ErroneousConstantExpression(); | 222 ConstantExpression expression = new ErroneousConstantExpression(); |
| 217 constantValueMap[expression] = constantSystem.createNull(); | 223 constantValueMap[expression] = constantSystem.createNull(); |
| 218 return expression; | 224 return expression; |
| 219 } | 225 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 255 } else { | 261 } else { |
| 256 // If the field cannot be lazily initialized, we will throw | 262 // If the field cannot be lazily initialized, we will throw |
| 257 // the exception at runtime. | 263 // the exception at runtime. |
| 258 expression = null; | 264 expression = null; |
| 259 } | 265 } |
| 260 } | 266 } |
| 261 } | 267 } |
| 262 } | 268 } |
| 263 } | 269 } |
| 264 if (expression != null) { | 270 if (expression != null) { |
| 271 element.constant = expression; | |
| 265 initialVariableValues[element.declaration] = expression; | 272 initialVariableValues[element.declaration] = expression; |
| 266 } else { | 273 } else { |
| 267 assert(invariant(element, !isConst, | 274 assert(invariant(element, !isConst, |
| 268 message: "Variable $element does not compile to a constant.")); | 275 message: "Variable $element does not compile to a constant.")); |
| 269 } | 276 } |
| 270 pendingVariables.remove(element); | 277 pendingVariables.remove(element); |
| 271 return expression; | 278 return expression; |
| 272 } | 279 } |
| 273 | 280 |
| 274 void cacheConstantValue(ConstantExpression expression, ConstantValue value) { | 281 void cacheConstantValue(ConstantExpression expression, ConstantValue value) { |
| (...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1273 }); | 1280 }); |
| 1274 } | 1281 } |
| 1275 | 1282 |
| 1276 /// Builds a normalized list of the constant values for each field in the | 1283 /// Builds a normalized list of the constant values for each field in the |
| 1277 /// inheritance chain of [classElement]. | 1284 /// inheritance chain of [classElement]. |
| 1278 Map<FieldElement, AstConstant> buildFieldConstants( | 1285 Map<FieldElement, AstConstant> buildFieldConstants( |
| 1279 ClassElement classElement) { | 1286 ClassElement classElement) { |
| 1280 Map<FieldElement, AstConstant> fieldConstants = | 1287 Map<FieldElement, AstConstant> fieldConstants = |
| 1281 <FieldElement, AstConstant>{}; | 1288 <FieldElement, AstConstant>{}; |
| 1282 classElement.implementation.forEachInstanceField( | 1289 classElement.implementation.forEachInstanceField( |
| 1283 (ClassElement enclosing, FieldElementX field) { | 1290 (ClassElement enclosing, FieldElement field) { |
| 1284 AstConstant fieldValue = fieldValues[field]; | 1291 AstConstant fieldValue = fieldValues[field]; |
| 1285 if (fieldValue == null) { | 1292 if (fieldValue == null) { |
| 1286 // Use the default value. | 1293 // Use the default value. |
| 1287 ConstantExpression fieldExpression = | 1294 ConstantExpression fieldExpression = |
| 1288 handler.internalCompileVariable(field, true, false); | 1295 handler.internalCompileVariable(field, true, false); |
| 1289 field.constant = fieldExpression; | |
| 1290 fieldValue = new AstConstant.fromDefaultValue( | 1296 fieldValue = new AstConstant.fromDefaultValue( |
| 1291 field, fieldExpression, handler.getConstantValue(fieldExpression)); | 1297 field, fieldExpression, handler.getConstantValue(fieldExpression)); |
| 1292 // TODO(het): If the field value doesn't typecheck due to the type | 1298 // TODO(het): If the field value doesn't typecheck due to the type |
| 1293 // variable in the constructor invocation, then report the error on the | 1299 // variable in the constructor invocation, then report the error on the |
| 1294 // invocation rather than the field. | 1300 // invocation rather than the field. |
| 1295 potentiallyCheckType(field, fieldValue); | 1301 potentiallyCheckType(field, fieldValue); |
| 1296 } | 1302 } |
| 1297 fieldConstants[field] = fieldValue; | 1303 fieldConstants[field] = fieldValue; |
| 1298 }, includeSuperAndInjectedMembers: true); | 1304 }, includeSuperAndInjectedMembers: true); |
| 1299 return fieldConstants; | 1305 return fieldConstants; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1343 class _CompilerEnvironment implements Environment { | 1349 class _CompilerEnvironment implements Environment { |
| 1344 final Compiler compiler; | 1350 final Compiler compiler; |
| 1345 | 1351 |
| 1346 _CompilerEnvironment(this.compiler); | 1352 _CompilerEnvironment(this.compiler); |
| 1347 | 1353 |
| 1348 @override | 1354 @override |
| 1349 String readFromEnvironment(String name) { | 1355 String readFromEnvironment(String name) { |
| 1350 return compiler.fromEnvironment(name); | 1356 return compiler.fromEnvironment(name); |
| 1351 } | 1357 } |
| 1352 } | 1358 } |
| OLD | NEW |