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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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); |
72 } | 72 } |
73 | 73 |
74 /** | 74 /** |
75 * Returns the a compile-time constant if the variable could be compiled | 75 * Returns the a compile-time constant if the variable could be compiled |
76 * eagerly. Otherwise returns `null`. | 76 * eagerly. Otherwise returns `null`. |
77 */ | 77 */ |
78 Constant compileVariable(VariableElement element, [bool isConst = false]) { | 78 Constant compileVariable(VariableElement element, {bool isConst: false}) { |
79 return measure(() { | 79 return measure(() { |
80 if (initialVariableValues.containsKey(element)) { | 80 if (initialVariableValues.containsKey(element)) { |
81 Constant result = initialVariableValues[element]; | 81 Constant result = initialVariableValues[element]; |
82 return result; | 82 return result; |
83 } | 83 } |
84 TreeElements definitions = compiler.analyzeElement(element); | 84 TreeElements definitions = compiler.analyzeElement(element); |
85 Constant constant = compileVariableWithDefinitions( | 85 Constant constant = compileVariableWithDefinitions( |
86 element, definitions, isConst: isConst); | 86 element, definitions, isConst: isConst); |
87 return constant; | 87 return constant; |
88 }); | 88 }); |
89 } | 89 } |
90 | 90 |
91 /** | 91 /** |
92 * Returns the a compile-time constant if the variable could be compiled | 92 * Returns the a compile-time constant if the variable could be compiled |
93 * eagerly. If the variable needs to be initialized lazily returns `null`. | 93 * eagerly. If the variable needs to be initialized lazily returns `null`. |
94 * If the variable is `const` but cannot be compiled eagerly reports an | 94 * If the variable is `const` but cannot be compiled eagerly reports an |
95 * error. | 95 * error. |
96 */ | 96 */ |
97 Constant compileVariableWithDefinitions(VariableElement element, | 97 Constant compileVariableWithDefinitions(VariableElement element, |
98 TreeElements definitions, | 98 TreeElements definitions, |
99 [bool isConst = false]) { | 99 {bool isConst: false}) { |
100 return measure(() { | 100 return measure(() { |
101 // Initializers for parameters must be const. | 101 // Initializers for parameters must be const. |
102 isConst = isConst || element.modifiers.isConst() | 102 isConst = isConst || element.modifiers.isConst() |
103 || !Elements.isStaticOrTopLevel(element); | 103 || !Elements.isStaticOrTopLevel(element); |
104 if (!isConst && lazyStatics.contains(element)) return null; | 104 if (!isConst && lazyStatics.contains(element)) return null; |
105 | 105 |
106 Node node = element.parseNode(compiler); | 106 Node node = element.parseNode(compiler); |
107 if (pendingVariables.contains(element)) { | 107 if (pendingVariables.contains(element)) { |
108 if (isConst) { | 108 if (isConst) { |
109 MessageKind kind = MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS; | 109 MessageKind kind = MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 assert(!isConst); | 149 assert(!isConst); |
150 lazyStatics.add(element); | 150 lazyStatics.add(element); |
151 } | 151 } |
152 pendingVariables.remove(element); | 152 pendingVariables.remove(element); |
153 return value; | 153 return value; |
154 }); | 154 }); |
155 } | 155 } |
156 | 156 |
157 Constant compileNodeWithDefinitions(Node node, | 157 Constant compileNodeWithDefinitions(Node node, |
158 TreeElements definitions, | 158 TreeElements definitions, |
159 [bool isConst]) { | 159 {bool isConst}) { |
160 return measure(() { | 160 return measure(() { |
161 assert(node !== null); | 161 assert(node !== null); |
162 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator( | 162 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator( |
163 constantSystem, definitions, compiler, isConst); | 163 constantSystem, definitions, compiler, isConst: isConst); |
164 return evaluator.evaluate(node); | 164 return evaluator.evaluate(node); |
165 }); | 165 }); |
166 } | 166 } |
167 | 167 |
168 /** Attempts to compile a constant expression. Returns null if not possible */ | 168 /** Attempts to compile a constant expression. Returns null if not possible */ |
169 Constant tryCompileNodeWithDefinitions(Node node, TreeElements definitions) { | 169 Constant tryCompileNodeWithDefinitions(Node node, TreeElements definitions) { |
170 return measure(() { | 170 return measure(() { |
171 assert(node !== null); | 171 assert(node !== null); |
172 try { | 172 try { |
173 TryCompileTimeConstantEvaluator evaluator = | 173 TryCompileTimeConstantEvaluator evaluator = |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 | 241 |
242 class CompileTimeConstantEvaluator extends Visitor { | 242 class CompileTimeConstantEvaluator extends Visitor { |
243 bool isEvaluatingConstant; | 243 bool isEvaluatingConstant; |
244 final ConstantSystem constantSystem; | 244 final ConstantSystem constantSystem; |
245 final TreeElements elements; | 245 final TreeElements elements; |
246 final Compiler compiler; | 246 final Compiler compiler; |
247 | 247 |
248 CompileTimeConstantEvaluator(this.constantSystem, | 248 CompileTimeConstantEvaluator(this.constantSystem, |
249 this.elements, | 249 this.elements, |
250 this.compiler, | 250 this.compiler, |
251 [bool isConst]) | 251 {bool isConst}) |
252 : this.isEvaluatingConstant = isConst; | 252 : this.isEvaluatingConstant = isConst; |
253 | 253 |
254 Constant evaluate(Node node) { | 254 Constant evaluate(Node node) { |
255 return node.accept(this); | 255 return node.accept(this); |
256 } | 256 } |
257 | 257 |
258 Constant evaluateConstant(Node node) { | 258 Constant evaluateConstant(Node node) { |
259 bool oldIsEvaluatingConstant = isEvaluatingConstant; | 259 bool oldIsEvaluatingConstant = isEvaluatingConstant; |
260 isEvaluatingConstant = true; | 260 isEvaluatingConstant = true; |
261 Constant result = node.accept(this); | 261 Constant result = node.accept(this); |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
794 void evaluateConstructorFieldValues(List<Constant> arguments) { | 794 void evaluateConstructorFieldValues(List<Constant> arguments) { |
795 compiler.withCurrentElement(constructor, () { | 795 compiler.withCurrentElement(constructor, () { |
796 assignArgumentsToParameters(arguments); | 796 assignArgumentsToParameters(arguments); |
797 evaluateConstructorInitializers(); | 797 evaluateConstructorInitializers(); |
798 }); | 798 }); |
799 } | 799 } |
800 | 800 |
801 List<Constant> buildJsNewArguments(ClassElement classElement) { | 801 List<Constant> buildJsNewArguments(ClassElement classElement) { |
802 List<Constant> jsNewArguments = <Constant>[]; | 802 List<Constant> jsNewArguments = <Constant>[]; |
803 classElement.implementation.forEachInstanceField( | 803 classElement.implementation.forEachInstanceField( |
| 804 (ClassElement enclosing, Element field) { |
| 805 Constant fieldValue = fieldValues[field]; |
| 806 if (fieldValue === null) { |
| 807 // Use the default value. |
| 808 fieldValue = compiler.compileConstant(field); |
| 809 } |
| 810 jsNewArguments.add(fieldValue); |
| 811 }, |
804 includeBackendMembers: true, | 812 includeBackendMembers: true, |
805 includeSuperMembers: true, | 813 includeSuperMembers: true); |
806 f: (ClassElement enclosing, Element field) { | |
807 Constant fieldValue = fieldValues[field]; | |
808 if (fieldValue === null) { | |
809 // Use the default value. | |
810 fieldValue = compiler.compileConstant(field); | |
811 } | |
812 jsNewArguments.add(fieldValue); | |
813 }); | |
814 return jsNewArguments; | 814 return jsNewArguments; |
815 } | 815 } |
816 } | 816 } |
OLD | NEW |