| 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 /** | 5 /** |
| 6 * The [ConstantHandler] keeps track of compile-time constants, | 6 * The [ConstantHandler] keeps track of compile-time constants, |
| 7 * initializations of global and static fields, and default values of | 7 * initializations of global and static fields, and default values of |
| 8 * optional parameters. | 8 * optional parameters. |
| 9 */ | 9 */ |
| 10 class ConstantHandler extends CompilerTask { | 10 class ConstantHandler extends CompilerTask { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 return measure(() { | 51 return measure(() { |
| 52 assert(work.element.kind == ElementKind.FIELD | 52 assert(work.element.kind == ElementKind.FIELD |
| 53 || work.element.kind == ElementKind.PARAMETER | 53 || work.element.kind == ElementKind.PARAMETER |
| 54 || work.element.kind == ElementKind.FIELD_PARAMETER); | 54 || work.element.kind == ElementKind.FIELD_PARAMETER); |
| 55 VariableElement element = work.element; | 55 VariableElement element = work.element; |
| 56 // Shortcut if it has already been compiled. | 56 // Shortcut if it has already been compiled. |
| 57 Constant result = initialVariableValues[element]; | 57 Constant result = initialVariableValues[element]; |
| 58 if (result != null) return result; | 58 if (result != null) return result; |
| 59 if (lazyStatics.contains(element)) return null; | 59 if (lazyStatics.contains(element)) return null; |
| 60 result = compileVariableWithDefinitions(element, work.resolutionTree); | 60 result = compileVariableWithDefinitions(element, work.resolutionTree); |
| 61 assert(pendingVariables.isEmpty()); | 61 assert(pendingVariables.isEmpty); |
| 62 return result; | 62 return result; |
| 63 }); | 63 }); |
| 64 } | 64 } |
| 65 | 65 |
| 66 /** | 66 /** |
| 67 * Returns a compile-time constant, or reports an error if the element is not | 67 * Returns a compile-time constant, or reports an error if the element is not |
| 68 * a compile-time constant. | 68 * a compile-time constant. |
| 69 */ | 69 */ |
| 70 Constant compileConstant(VariableElement element) { | 70 Constant compileConstant(VariableElement element) { |
| 71 return compileVariable(element, isConst: true); | 71 return compileVariable(element, isConst: true); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 Constant visitLiteralInt(LiteralInt node) { | 279 Constant visitLiteralInt(LiteralInt node) { |
| 280 return constantSystem.createInt(node.value); | 280 return constantSystem.createInt(node.value); |
| 281 } | 281 } |
| 282 | 282 |
| 283 Constant visitLiteralList(LiteralList node) { | 283 Constant visitLiteralList(LiteralList node) { |
| 284 if (!node.isConst()) { | 284 if (!node.isConst()) { |
| 285 return signalNotCompileTimeConstant(node); | 285 return signalNotCompileTimeConstant(node); |
| 286 } | 286 } |
| 287 List<Constant> arguments = <Constant>[]; | 287 List<Constant> arguments = <Constant>[]; |
| 288 for (Link<Node> link = node.elements.nodes; | 288 for (Link<Node> link = node.elements.nodes; |
| 289 !link.isEmpty(); | 289 !link.isEmpty; |
| 290 link = link.tail) { | 290 link = link.tail) { |
| 291 arguments.add(evaluateConstant(link.head)); | 291 arguments.add(evaluateConstant(link.head)); |
| 292 } | 292 } |
| 293 // TODO(floitsch): get type parameters. | 293 // TODO(floitsch): get type parameters. |
| 294 DartType type = new InterfaceType(compiler.listClass); | 294 DartType type = new InterfaceType(compiler.listClass); |
| 295 Constant constant = new ListConstant(type, arguments); | 295 Constant constant = new ListConstant(type, arguments); |
| 296 compiler.constantHandler.registerCompileTimeConstant(constant); | 296 compiler.constantHandler.registerCompileTimeConstant(constant); |
| 297 return constant; | 297 return constant; |
| 298 } | 298 } |
| 299 | 299 |
| 300 Constant visitLiteralMap(LiteralMap node) { | 300 Constant visitLiteralMap(LiteralMap node) { |
| 301 if (!node.isConst()) { | 301 if (!node.isConst()) { |
| 302 signalNotCompileTimeConstant(node); | 302 signalNotCompileTimeConstant(node); |
| 303 error(node); | 303 error(node); |
| 304 } | 304 } |
| 305 List<StringConstant> keys = <StringConstant>[]; | 305 List<StringConstant> keys = <StringConstant>[]; |
| 306 Map<StringConstant, Constant> map = new Map<StringConstant, Constant>(); | 306 Map<StringConstant, Constant> map = new Map<StringConstant, Constant>(); |
| 307 for (Link<Node> link = node.entries.nodes; | 307 for (Link<Node> link = node.entries.nodes; |
| 308 !link.isEmpty(); | 308 !link.isEmpty; |
| 309 link = link.tail) { | 309 link = link.tail) { |
| 310 LiteralMapEntry entry = link.head; | 310 LiteralMapEntry entry = link.head; |
| 311 Constant key = evaluateConstant(entry.key); | 311 Constant key = evaluateConstant(entry.key); |
| 312 if (!key.isString() || entry.key.asStringNode() == null) { | 312 if (!key.isString() || entry.key.asStringNode() == null) { |
| 313 MessageKind kind = MessageKind.KEY_NOT_A_STRING_LITERAL; | 313 MessageKind kind = MessageKind.KEY_NOT_A_STRING_LITERAL; |
| 314 compiler.reportError(entry.key, new ResolutionError(kind, const [])); | 314 compiler.reportError(entry.key, new ResolutionError(kind, const [])); |
| 315 } | 315 } |
| 316 StringConstant keyConstant = key; | 316 StringConstant keyConstant = key; |
| 317 if (!map.containsKey(key)) keys.add(key); | 317 if (!map.containsKey(key)) keys.add(key); |
| 318 map[key] = evaluateConstant(entry.value); | 318 map[key] = evaluateConstant(entry.value); |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 * the [fieldValues] map. | 730 * the [fieldValues] map. |
| 731 */ | 731 */ |
| 732 void evaluateConstructorInitializers() { | 732 void evaluateConstructorInitializers() { |
| 733 FunctionExpression functionNode = constructor.parseNode(compiler); | 733 FunctionExpression functionNode = constructor.parseNode(compiler); |
| 734 NodeList initializerList = functionNode.initializers; | 734 NodeList initializerList = functionNode.initializers; |
| 735 | 735 |
| 736 bool foundSuperOrRedirect = false; | 736 bool foundSuperOrRedirect = false; |
| 737 | 737 |
| 738 if (initializerList != null) { | 738 if (initializerList != null) { |
| 739 for (Link<Node> link = initializerList.nodes; | 739 for (Link<Node> link = initializerList.nodes; |
| 740 !link.isEmpty(); | 740 !link.isEmpty; |
| 741 link = link.tail) { | 741 link = link.tail) { |
| 742 assert(link.head is Send); | 742 assert(link.head is Send); |
| 743 if (link.head is !SendSet) { | 743 if (link.head is !SendSet) { |
| 744 // A super initializer or constructor redirection. | 744 // A super initializer or constructor redirection. |
| 745 Send call = link.head; | 745 Send call = link.head; |
| 746 FunctionElement targetConstructor = elements[call]; | 746 FunctionElement targetConstructor = elements[call]; |
| 747 Selector selector = elements.getSelector(call); | 747 Selector selector = elements.getSelector(call); |
| 748 Link<Node> arguments = call.arguments; | 748 Link<Node> arguments = call.arguments; |
| 749 evaluateSuperOrRedirectSend( | 749 evaluateSuperOrRedirectSend( |
| 750 call, selector, arguments, targetConstructor); | 750 call, selector, arguments, targetConstructor); |
| 751 foundSuperOrRedirect = true; | 751 foundSuperOrRedirect = true; |
| 752 } else { | 752 } else { |
| 753 // A field initializer. | 753 // A field initializer. |
| 754 SendSet init = link.head; | 754 SendSet init = link.head; |
| 755 Link<Node> initArguments = init.arguments; | 755 Link<Node> initArguments = init.arguments; |
| 756 assert(!initArguments.isEmpty() && initArguments.tail.isEmpty()); | 756 assert(!initArguments.isEmpty && initArguments.tail.isEmpty); |
| 757 Constant fieldValue = evaluate(initArguments.head); | 757 Constant fieldValue = evaluate(initArguments.head); |
| 758 updateFieldValue(init, elements[init], fieldValue); | 758 updateFieldValue(init, elements[init], fieldValue); |
| 759 } | 759 } |
| 760 } | 760 } |
| 761 } | 761 } |
| 762 | 762 |
| 763 if (!foundSuperOrRedirect) { | 763 if (!foundSuperOrRedirect) { |
| 764 // No super initializer found. Try to find the default constructor if | 764 // No super initializer found. Try to find the default constructor if |
| 765 // the class is not Object. | 765 // the class is not Object. |
| 766 ClassElement enclosingClass = constructor.getEnclosingClass(); | 766 ClassElement enclosingClass = constructor.getEnclosingClass(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 // Use the default value. | 808 // Use the default value. |
| 809 fieldValue = compiler.compileConstant(field); | 809 fieldValue = compiler.compileConstant(field); |
| 810 } | 810 } |
| 811 jsNewArguments.add(fieldValue); | 811 jsNewArguments.add(fieldValue); |
| 812 }, | 812 }, |
| 813 includeBackendMembers: true, | 813 includeBackendMembers: true, |
| 814 includeSuperMembers: true); | 814 includeSuperMembers: true); |
| 815 return jsNewArguments; | 815 return jsNewArguments; |
| 816 } | 816 } |
| 817 } | 817 } |
| OLD | NEW |