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 |