| 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/resolution.dart' show Resolution; | 7 import 'common/resolution.dart' show Resolution; |
| 8 import 'common/tasks.dart' show CompilerTask, Measurer; | 8 import 'common/tasks.dart' show CompilerTask, Measurer; |
| 9 import 'common.dart'; | 9 import 'common.dart'; |
| 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/constructors.dart'; |
| 13 import 'constants/evaluation.dart'; | 14 import 'constants/evaluation.dart'; |
| 14 import 'constants/expressions.dart'; | 15 import 'constants/expressions.dart'; |
| 15 import 'constants/values.dart'; | 16 import 'constants/values.dart'; |
| 16 import 'core_types.dart' show CommonElements; | 17 import 'core_types.dart' show CommonElements; |
| 17 import 'elements/resolution_types.dart'; | 18 import 'elements/resolution_types.dart'; |
| 18 import 'elements/elements.dart'; | 19 import 'elements/elements.dart'; |
| 20 import 'elements/entities.dart'; |
| 19 import 'elements/modelx.dart' show ConstantVariableMixin; | 21 import 'elements/modelx.dart' show ConstantVariableMixin; |
| 20 import 'resolution/operators.dart'; | 22 import 'resolution/operators.dart'; |
| 21 import 'resolution/tree_elements.dart' show TreeElements; | 23 import 'resolution/tree_elements.dart' show TreeElements; |
| 22 import 'tree/tree.dart'; | 24 import 'tree/tree.dart'; |
| 23 import 'universe/call_structure.dart' show CallStructure; | 25 import 'universe/call_structure.dart' show CallStructure; |
| 24 import 'util/util.dart' show Link; | 26 import 'util/util.dart' show Link; |
| 25 | 27 |
| 26 /// A [ConstantEnvironment] provides access for constants compiled for variable | 28 /// A [ConstantEnvironment] provides access for constants compiled for variable |
| 27 /// initializers. | 29 /// initializers. |
| 28 abstract class ConstantEnvironment { | 30 abstract class ConstantEnvironment { |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 for (Link<Node> link = node.elements.nodes; | 465 for (Link<Node> link = node.elements.nodes; |
| 464 !link.isEmpty; | 466 !link.isEmpty; |
| 465 link = link.tail) { | 467 link = link.tail) { |
| 466 AstConstant argument = evaluateConstant(link.head); | 468 AstConstant argument = evaluateConstant(link.head); |
| 467 if (argument == null || argument.isError) { | 469 if (argument == null || argument.isError) { |
| 468 return argument; | 470 return argument; |
| 469 } | 471 } |
| 470 argumentExpressions.add(argument.expression); | 472 argumentExpressions.add(argument.expression); |
| 471 argumentValues.add(argument.value); | 473 argumentValues.add(argument.value); |
| 472 } | 474 } |
| 473 ResolutionDartType type = elements.getType(node); | 475 ResolutionInterfaceType type = elements.getType(node); |
| 474 return new AstConstant( | 476 return new AstConstant( |
| 475 context, | 477 context, |
| 476 node, | 478 node, |
| 477 new ListConstantExpression(type, argumentExpressions), | 479 new ListConstantExpression(type, argumentExpressions), |
| 478 constantSystem.createList(type, argumentValues)); | 480 constantSystem.createList(type, argumentValues)); |
| 479 } | 481 } |
| 480 | 482 |
| 481 AstConstant visitLiteralMap(LiteralMap node) { | 483 AstConstant visitLiteralMap(LiteralMap node) { |
| 482 if (!node.isConst) { | 484 if (!node.isConst) { |
| 483 return signalNotCompileTimeConstant(node); | 485 return signalNotCompileTimeConstant(node); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 if (send == null) return false; | 620 if (send == null) return false; |
| 619 return compiler.deferredLoadTask.deferredPrefixElement(send, elements) != | 621 return compiler.deferredLoadTask.deferredPrefixElement(send, elements) != |
| 620 null; | 622 null; |
| 621 } | 623 } |
| 622 | 624 |
| 623 AstConstant visitIdentifier(Identifier node) { | 625 AstConstant visitIdentifier(Identifier node) { |
| 624 Element element = elements[node]; | 626 Element element = elements[node]; |
| 625 if (Elements.isClass(element) || Elements.isTypedef(element)) { | 627 if (Elements.isClass(element) || Elements.isTypedef(element)) { |
| 626 TypeDeclarationElement typeDeclarationElement = element; | 628 TypeDeclarationElement typeDeclarationElement = element; |
| 627 ResolutionDartType type = typeDeclarationElement.rawType; | 629 ResolutionDartType type = typeDeclarationElement.rawType; |
| 628 return new AstConstant(element, node, new TypeConstantExpression(type), | 630 return new AstConstant( |
| 631 element, |
| 632 node, |
| 633 new TypeConstantExpression(type, typeDeclarationElement.name), |
| 629 makeTypeConstant(type)); | 634 makeTypeConstant(type)); |
| 630 } | 635 } |
| 631 return signalNotCompileTimeConstant(node); | 636 return signalNotCompileTimeConstant(node); |
| 632 } | 637 } |
| 633 | 638 |
| 634 // TODO(floitsch): provide better error-messages. | 639 // TODO(floitsch): provide better error-messages. |
| 635 AstConstant visitSend(Send send) { | 640 AstConstant visitSend(Send send) { |
| 636 Element element = elements[send]; | 641 Element element = elements[send]; |
| 637 if (send.isPropertyAccess) { | 642 if (send.isPropertyAccess) { |
| 638 AstConstant result; | 643 AstConstant result; |
| 639 if (Elements.isStaticOrTopLevelFunction(element)) { | 644 if (Elements.isStaticOrTopLevelFunction(element)) { |
| 640 MethodElement function = element; | 645 MethodElement function = element; |
| 641 function.computeType(resolution); | 646 function.computeType(resolution); |
| 642 result = new AstConstant( | 647 result = new AstConstant( |
| 643 context, | 648 context, |
| 644 send, | 649 send, |
| 645 new FunctionConstantExpression(function), | 650 new FunctionConstantExpression(function, function.type), |
| 646 new FunctionConstantValue(function, function.type)); | 651 new FunctionConstantValue(function, function.type)); |
| 647 } else if (Elements.isStaticOrTopLevelField(element)) { | 652 } else if (Elements.isStaticOrTopLevelField(element)) { |
| 648 ConstantExpression elementExpression; | 653 ConstantExpression elementExpression; |
| 649 if (element.isConst) { | 654 if (element.isConst) { |
| 650 elementExpression = handler.compileConstant(element); | 655 elementExpression = handler.compileConstant(element); |
| 651 } else if (element.isFinal && !isEvaluatingConstant) { | 656 } else if (element.isFinal && !isEvaluatingConstant) { |
| 652 elementExpression = handler.compileVariable(element); | 657 elementExpression = handler.compileVariable(element); |
| 653 } | 658 } |
| 654 if (elementExpression != null) { | 659 if (elementExpression != null) { |
| 660 FieldElement field = element; |
| 655 result = new AstConstant( | 661 result = new AstConstant( |
| 656 context, | 662 context, |
| 657 send, | 663 send, |
| 658 new VariableConstantExpression(element), | 664 new FieldConstantExpression(field), |
| 659 handler.getConstantValue(elementExpression)); | 665 handler.getConstantValue(elementExpression)); |
| 660 } | 666 } |
| 661 } else if (Elements.isClass(element) || Elements.isTypedef(element)) { | 667 } else if (Elements.isClass(element) || Elements.isTypedef(element)) { |
| 662 assert(elements.isTypeLiteral(send)); | 668 assert(elements.isTypeLiteral(send)); |
| 663 ResolutionDartType elementType = elements.getTypeLiteralType(send); | 669 ResolutionDartType elementType = elements.getTypeLiteralType(send); |
| 664 result = new AstConstant( | 670 result = new AstConstant( |
| 665 context, | 671 context, |
| 666 send, | 672 send, |
| 667 new TypeConstantExpression(elementType), | 673 new TypeConstantExpression(elementType, element.name), |
| 668 makeTypeConstant(elementType)); | 674 makeTypeConstant(elementType)); |
| 669 } else if (send.receiver != null) { | 675 } else if (send.receiver != null) { |
| 670 if (send.selector.asIdentifier().source == "length") { | 676 if (send.selector.asIdentifier().source == "length") { |
| 671 AstConstant left = evaluate(send.receiver); | 677 AstConstant left = evaluate(send.receiver); |
| 672 if (left != null && left.value.isString) { | 678 if (left != null && left.value.isString) { |
| 673 StringConstantValue stringConstantValue = left.value; | 679 StringConstantValue stringConstantValue = left.value; |
| 674 DartString string = stringConstantValue.primitiveValue; | 680 DartString string = stringConstantValue.primitiveValue; |
| 675 IntConstantValue length = constantSystem.createInt(string.length); | 681 IntConstantValue length = constantSystem.createInt(string.length); |
| 676 result = new AstConstant(context, send, | 682 result = new AstConstant(context, send, |
| 677 new StringLengthConstantExpression(left.expression), length); | 683 new StringLengthConstantExpression(left.expression), length); |
| 678 } | 684 } |
| 679 } | 685 } |
| 680 // Fall through to error handling. | 686 // Fall through to error handling. |
| 681 } else if (!Elements.isUnresolved(element) && | 687 } else if (!Elements.isUnresolved(element) && |
| 682 element.isVariable && | 688 element.isVariable && |
| 683 element.isConst) { | 689 element.isConst) { |
| 684 ConstantExpression variableExpression = | 690 LocalVariableElement local = element; |
| 685 handler.compileConstant(element); | 691 ConstantExpression variableExpression = handler.compileConstant(local); |
| 686 if (variableExpression != null) { | 692 if (variableExpression != null) { |
| 687 result = new AstConstant( | 693 result = new AstConstant( |
| 688 context, | 694 context, |
| 689 send, | 695 send, |
| 690 new VariableConstantExpression(element), | 696 new LocalVariableConstantExpression(local), |
| 691 handler.getConstantValue(variableExpression)); | 697 handler.getConstantValue(variableExpression)); |
| 692 } | 698 } |
| 693 } | 699 } |
| 694 if (result == null) { | 700 if (result == null) { |
| 695 return signalNotCompileTimeConstant(send); | 701 return signalNotCompileTimeConstant(send); |
| 696 } | 702 } |
| 697 if (isDeferredUse(send)) { | 703 if (isDeferredUse(send)) { |
| 698 if (isEvaluatingConstant) { | 704 if (isEvaluatingConstant) { |
| 699 reporter.reportErrorMessage( | 705 reporter.reportErrorMessage( |
| 700 send, MessageKind.DEFERRED_COMPILE_TIME_CONSTANT); | 706 send, MessageKind.DEFERRED_COMPILE_TIME_CONSTANT); |
| (...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1257 CallStructure callStructure, ConstructorElement targetConstructor) { | 1263 CallStructure callStructure, ConstructorElement targetConstructor) { |
| 1258 ResolutionInterfaceType type = | 1264 ResolutionInterfaceType type = |
| 1259 constructedType.asInstanceOf(targetConstructor.enclosingClass); | 1265 constructedType.asInstanceOf(targetConstructor.enclosingClass); |
| 1260 if (compiler.serialization.isDeserialized(targetConstructor)) { | 1266 if (compiler.serialization.isDeserialized(targetConstructor)) { |
| 1261 List<ConstantExpression> arguments = | 1267 List<ConstantExpression> arguments = |
| 1262 compiledArguments.map((c) => c.expression).toList(); | 1268 compiledArguments.map((c) => c.expression).toList(); |
| 1263 ConstructedConstantExpression expression = | 1269 ConstructedConstantExpression expression = |
| 1264 new ConstructedConstantExpression( | 1270 new ConstructedConstantExpression( |
| 1265 type, targetConstructor, callStructure, arguments); | 1271 type, targetConstructor, callStructure, arguments); |
| 1266 | 1272 |
| 1267 Map<FieldElement, ConstantExpression> fields = | 1273 Map<FieldEntity, ConstantExpression> fields = |
| 1268 expression.computeInstanceFields(); | 1274 expression.computeInstanceFields(new _CompilerEnvironment(compiler)); |
| 1269 fields.forEach((FieldElement field, ConstantExpression expression) { | 1275 fields.forEach((FieldElement field, ConstantExpression expression) { |
| 1270 ConstantValue value = expression.evaluate( | 1276 ConstantValue value = expression.evaluate( |
| 1271 new _CompilerEnvironment(compiler), constantSystem); | 1277 new _CompilerEnvironment(compiler), constantSystem); |
| 1272 fieldValues[field] = new AstConstant(context, null, expression, value); | 1278 fieldValues[field] = new AstConstant(context, null, expression, value); |
| 1273 }); | 1279 }); |
| 1274 } else { | 1280 } else { |
| 1275 ConstructorEvaluator evaluator = | 1281 ConstructorEvaluator evaluator = |
| 1276 new ConstructorEvaluator(type, targetConstructor, handler, compiler); | 1282 new ConstructorEvaluator(type, targetConstructor, handler, compiler); |
| 1277 evaluator.evaluateConstructorFieldValues(compiledArguments); | 1283 evaluator.evaluateConstructorFieldValues(compiledArguments); |
| 1278 // Copy over the fieldValues from the super/redirect-constructor. | 1284 // Copy over the fieldValues from the super/redirect-constructor. |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1447 | 1453 |
| 1448 class _CompilerEnvironment implements Environment { | 1454 class _CompilerEnvironment implements Environment { |
| 1449 final Compiler compiler; | 1455 final Compiler compiler; |
| 1450 | 1456 |
| 1451 _CompilerEnvironment(this.compiler); | 1457 _CompilerEnvironment(this.compiler); |
| 1452 | 1458 |
| 1453 @override | 1459 @override |
| 1454 String readFromEnvironment(String name) { | 1460 String readFromEnvironment(String name) { |
| 1455 return compiler.fromEnvironment(name); | 1461 return compiler.fromEnvironment(name); |
| 1456 } | 1462 } |
| 1463 |
| 1464 @override |
| 1465 ResolutionInterfaceType substByContext( |
| 1466 ResolutionInterfaceType base, ResolutionInterfaceType target) { |
| 1467 return base.substByContext(target); |
| 1468 } |
| 1469 |
| 1470 @override |
| 1471 ConstantConstructor getConstructorConstant(ConstructorElement constructor) { |
| 1472 return constructor.constantConstructor; |
| 1473 } |
| 1474 |
| 1475 @override |
| 1476 ConstantExpression getFieldConstant(FieldElement field) { |
| 1477 return field.constant; |
| 1478 } |
| 1479 |
| 1480 @override |
| 1481 ConstantExpression getLocalConstant(LocalVariableElement local) { |
| 1482 return local.constant; |
| 1483 } |
| 1457 } | 1484 } |
| OLD | NEW |