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 part of dart2js; | 5 part of dart2js; |
6 | 6 |
7 /// A [ConstantEnvironment] provides access for constants compiled for variable | 7 /// A [ConstantEnvironment] provides access for constants compiled for variable |
8 /// initializers. | 8 /// initializers. |
9 abstract class ConstantEnvironment { | 9 abstract class ConstantEnvironment { |
10 /// Returns the constant for the initializer of [element]. | 10 /// Returns the constant for the initializer of [element]. |
11 ConstExp getConstantForVariable(VariableElement element); | 11 ConstantExpression getConstantForVariable(VariableElement element); |
12 } | 12 } |
13 | 13 |
14 /// A class that can compile and provide constants for variables, nodes and | 14 /// A class that can compile and provide constants for variables, nodes and |
15 /// metadata. | 15 /// metadata. |
16 abstract class ConstantCompiler extends ConstantEnvironment { | 16 abstract class ConstantCompiler extends ConstantEnvironment { |
17 /// Compiles the compile-time constant for the initializer of [element], or | 17 /// Compiles the compile-time constant for the initializer of [element], or |
18 /// reports an error if the initializer is not a compile-time constant. | 18 /// reports an error if the initializer is not a compile-time constant. |
19 /// | 19 /// |
20 /// Depending on implementation, the constant compiler might also compute | 20 /// Depending on implementation, the constant compiler might also compute |
21 /// the compile-time constant for the backend interpretation of constants. | 21 /// the compile-time constant for the backend interpretation of constants. |
22 /// | 22 /// |
23 /// The returned constant is always of the frontend interpretation. | 23 /// The returned constant is always of the frontend interpretation. |
24 ConstExp compileConstant(VariableElement element); | 24 ConstantExpression compileConstant(VariableElement element); |
25 | 25 |
26 /// Computes the compile-time constant for the variable initializer, | 26 /// Computes the compile-time constant for the variable initializer, |
27 /// if possible. | 27 /// if possible. |
28 void compileVariable(VariableElement element); | 28 void compileVariable(VariableElement element); |
29 | 29 |
30 /// Compiles the compile-time constant for [node], or reports an error if | 30 /// Compiles the compile-time constant for [node], or reports an error if |
31 /// [node] is not a compile-time constant. | 31 /// [node] is not a compile-time constant. |
32 /// | 32 /// |
33 /// Depending on implementation, the constant compiler might also compute | 33 /// Depending on implementation, the constant compiler might also compute |
34 /// the compile-time constant for the backend interpretation of constants. | 34 /// the compile-time constant for the backend interpretation of constants. |
35 /// | 35 /// |
36 /// The returned constant is always of the frontend interpretation. | 36 /// The returned constant is always of the frontend interpretation. |
37 ConstExp compileNode(Node node, TreeElements elements); | 37 ConstantExpression compileNode(Node node, TreeElements elements); |
38 | 38 |
39 /// Compiles the compile-time constant for the value [metadata], or reports an | 39 /// Compiles the compile-time constant for the value [metadata], or reports an |
40 /// error if the value is not a compile-time constant. | 40 /// error if the value is not a compile-time constant. |
41 /// | 41 /// |
42 /// Depending on implementation, the constant compiler might also compute | 42 /// Depending on implementation, the constant compiler might also compute |
43 /// the compile-time constant for the backend interpretation of constants. | 43 /// the compile-time constant for the backend interpretation of constants. |
44 /// | 44 /// |
45 /// The returned constant is always of the frontend interpretation. | 45 /// The returned constant is always of the frontend interpretation. |
46 ConstExp compileMetadata(MetadataAnnotation metadata, | 46 ConstantExpression compileMetadata(MetadataAnnotation metadata, |
47 Node node, TreeElements elements); | 47 Node node, |
| 48 TreeElements elements); |
48 } | 49 } |
49 | 50 |
50 /// A [BackendConstantEnvironment] provides access to constants needed for | 51 /// A [BackendConstantEnvironment] provides access to constants needed for |
51 /// backend implementation. | 52 /// backend implementation. |
52 abstract class BackendConstantEnvironment extends ConstantEnvironment { | 53 abstract class BackendConstantEnvironment extends ConstantEnvironment { |
53 /// Returns the compile-time constant associated with [node]. | 54 /// Returns the compile-time constant associated with [node]. |
54 /// | 55 /// |
55 /// Depending on implementation, the constant might be stored in [elements]. | 56 /// Depending on implementation, the constant might be stored in [elements]. |
56 ConstExp getConstantForNode(Node node, TreeElements elements); | 57 ConstantExpression getConstantForNode(Node node, TreeElements elements); |
57 | 58 |
58 /// Returns the compile-time constant value of [metadata]. | 59 /// Returns the compile-time constant value of [metadata]. |
59 ConstExp getConstantForMetadata(MetadataAnnotation metadata); | 60 ConstantExpression getConstantForMetadata(MetadataAnnotation metadata); |
60 } | 61 } |
61 | 62 |
62 /// Interface for the task that compiles the constant environments for the | 63 /// Interface for the task that compiles the constant environments for the |
63 /// frontend and backend interpretation of compile-time constants. | 64 /// frontend and backend interpretation of compile-time constants. |
64 abstract class ConstantCompilerTask extends CompilerTask | 65 abstract class ConstantCompilerTask extends CompilerTask |
65 implements ConstantCompiler { | 66 implements ConstantCompiler { |
66 ConstantCompilerTask(Compiler compiler) : super(compiler); | 67 ConstantCompilerTask(Compiler compiler) : super(compiler); |
67 } | 68 } |
68 | 69 |
69 /** | 70 /** |
70 * The [ConstantCompilerBase] is provides base implementation for compilation of | 71 * The [ConstantCompilerBase] is provides base implementation for compilation of |
71 * compile-time constants for both the Dart and JavaScript interpretation of | 72 * compile-time constants for both the Dart and JavaScript interpretation of |
72 * constants. It keeps track of compile-time constants for initializations of | 73 * constants. It keeps track of compile-time constants for initializations of |
73 * global and static fields, and default values of optional parameters. | 74 * global and static fields, and default values of optional parameters. |
74 */ | 75 */ |
75 abstract class ConstantCompilerBase implements ConstantCompiler { | 76 abstract class ConstantCompilerBase implements ConstantCompiler { |
76 final Compiler compiler; | 77 final Compiler compiler; |
77 final ConstantSystem constantSystem; | 78 final ConstantSystem constantSystem; |
78 | 79 |
79 /** | 80 /** |
80 * Contains the initial value of fields. Must contain all static and global | 81 * Contains the initial value of fields. Must contain all static and global |
81 * initializations of const fields. May contain eagerly compiled values for | 82 * initializations of const fields. May contain eagerly compiled values for |
82 * statics and instance fields. | 83 * statics and instance fields. |
83 * | 84 * |
84 * Invariant: The keys in this map are declarations. | 85 * Invariant: The keys in this map are declarations. |
85 */ | 86 */ |
86 final Map<VariableElement, ConstExp> initialVariableValues = | 87 final Map<VariableElement, ConstantExpression> initialVariableValues = |
87 new Map<VariableElement, ConstExp>(); | 88 new Map<VariableElement, ConstantExpression>(); |
88 | 89 |
89 /** The set of variable elements that are in the process of being computed. */ | 90 /** The set of variable elements that are in the process of being computed. */ |
90 final Set<VariableElement> pendingVariables = new Set<VariableElement>(); | 91 final Set<VariableElement> pendingVariables = new Set<VariableElement>(); |
91 | 92 |
92 ConstantCompilerBase(this.compiler, this.constantSystem); | 93 ConstantCompilerBase(this.compiler, this.constantSystem); |
93 | 94 |
94 ConstExp getConstantForVariable(VariableElement element) { | 95 ConstantExpression getConstantForVariable(VariableElement element) { |
95 return initialVariableValues[element.declaration]; | 96 return initialVariableValues[element.declaration]; |
96 } | 97 } |
97 | 98 |
98 ConstExp compileConstant(VariableElement element) { | 99 ConstantExpression compileConstant(VariableElement element) { |
99 return compileVariable(element, isConst: true); | 100 return compileVariable(element, isConst: true); |
100 } | 101 } |
101 | 102 |
102 ConstExp compileVariable(VariableElement element, {bool isConst: false}) { | 103 ConstantExpression compileVariable(VariableElement element, |
| 104 {bool isConst: false}) { |
103 | 105 |
104 if (initialVariableValues.containsKey(element.declaration)) { | 106 if (initialVariableValues.containsKey(element.declaration)) { |
105 ConstExp result = initialVariableValues[element.declaration]; | 107 ConstantExpression result = initialVariableValues[element.declaration]; |
106 return result; | 108 return result; |
107 } | 109 } |
108 AstElement currentElement = element.analyzableElement; | 110 AstElement currentElement = element.analyzableElement; |
109 return compiler.withCurrentElement(currentElement, () { | 111 return compiler.withCurrentElement(currentElement, () { |
110 compiler.analyzeElement(currentElement.declaration); | 112 compiler.analyzeElement(currentElement.declaration); |
111 ConstExp constant = compileVariableWithDefinitions( | 113 ConstantExpression constant = compileVariableWithDefinitions( |
112 element, currentElement.resolvedAst.elements, isConst: isConst); | 114 element, currentElement.resolvedAst.elements, isConst: isConst); |
113 return constant; | 115 return constant; |
114 }); | 116 }); |
115 } | 117 } |
116 | 118 |
117 /** | 119 /** |
118 * Returns the a compile-time constant if the variable could be compiled | 120 * Returns the a compile-time constant if the variable could be compiled |
119 * eagerly. If the variable needs to be initialized lazily returns `null`. | 121 * eagerly. If the variable needs to be initialized lazily returns `null`. |
120 * If the variable is `const` but cannot be compiled eagerly reports an | 122 * If the variable is `const` but cannot be compiled eagerly reports an |
121 * error. | 123 * error. |
122 */ | 124 */ |
123 ConstExp compileVariableWithDefinitions(VariableElement element, | 125 ConstantExpression compileVariableWithDefinitions(VariableElement element, |
124 TreeElements definitions, | 126 TreeElements definitions, |
125 {bool isConst: false}) { | 127 {bool isConst: false}) { |
126 Node node = element.node; | 128 Node node = element.node; |
127 if (pendingVariables.contains(element)) { | 129 if (pendingVariables.contains(element)) { |
128 if (isConst) { | 130 if (isConst) { |
129 compiler.reportFatalError( | 131 compiler.reportFatalError( |
130 node, MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS); | 132 node, MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS); |
131 } | 133 } |
132 return null; | 134 return null; |
133 } | 135 } |
134 pendingVariables.add(element); | 136 pendingVariables.add(element); |
135 | 137 |
136 Expression initializer = element.initializer; | 138 Expression initializer = element.initializer; |
137 ConstExp value; | 139 ConstantExpression value; |
138 if (initializer == null) { | 140 if (initializer == null) { |
139 // No initial value. | 141 // No initial value. |
140 value = new PrimitiveConstExp(new NullConstant()); | 142 value = new PrimitiveConstantExpression(new NullConstantValue()); |
141 } else { | 143 } else { |
142 value = compileNodeWithDefinitions( | 144 value = compileNodeWithDefinitions( |
143 initializer, definitions, isConst: isConst); | 145 initializer, definitions, isConst: isConst); |
144 if (compiler.enableTypeAssertions && | 146 if (compiler.enableTypeAssertions && |
145 value != null && | 147 value != null && |
146 element.isField) { | 148 element.isField) { |
147 DartType elementType = element.type; | 149 DartType elementType = element.type; |
148 if (elementType.isMalformed && !value.value.isNull) { | 150 if (elementType.isMalformed && !value.value.isNull) { |
149 if (isConst) { | 151 if (isConst) { |
150 ErroneousElement element = elementType.element; | 152 ErroneousElement element = elementType.element; |
(...skipping 23 matching lines...) Expand all Loading... |
174 if (value != null) { | 176 if (value != null) { |
175 initialVariableValues[element.declaration] = value; | 177 initialVariableValues[element.declaration] = value; |
176 } else { | 178 } else { |
177 assert(invariant(element, !isConst, | 179 assert(invariant(element, !isConst, |
178 message: "Variable $element does not compile to a constant.")); | 180 message: "Variable $element does not compile to a constant.")); |
179 } | 181 } |
180 pendingVariables.remove(element); | 182 pendingVariables.remove(element); |
181 return value; | 183 return value; |
182 } | 184 } |
183 | 185 |
184 ConstExp compileNodeWithDefinitions(Node node, | 186 ConstantExpression compileNodeWithDefinitions(Node node, |
185 TreeElements definitions, | 187 TreeElements definitions, |
186 {bool isConst: true}) { | 188 {bool isConst: true}) { |
187 assert(node != null); | 189 assert(node != null); |
188 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator( | 190 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator( |
189 this, definitions, compiler, isConst: isConst); | 191 this, definitions, compiler, isConst: isConst); |
190 AstConstant constant = evaluator.evaluate(node); | 192 AstConstant constant = evaluator.evaluate(node); |
191 return constant != null ? constant.expression : null; | 193 return constant != null ? constant.expression : null; |
192 } | 194 } |
193 | 195 |
194 ConstExp compileNode(Node node, TreeElements elements) { | 196 ConstantExpression compileNode(Node node, TreeElements elements) { |
195 return compileNodeWithDefinitions(node, elements); | 197 return compileNodeWithDefinitions(node, elements); |
196 } | 198 } |
197 | 199 |
198 ConstExp compileMetadata(MetadataAnnotation metadata, | 200 ConstantExpression compileMetadata(MetadataAnnotation metadata, |
199 Node node, | 201 Node node, |
200 TreeElements elements) { | 202 TreeElements elements) { |
201 return compileNodeWithDefinitions(node, elements); | 203 return compileNodeWithDefinitions(node, elements); |
202 } | 204 } |
203 } | 205 } |
204 | 206 |
205 /// [ConstantCompiler] that uses the Dart semantics for the compile-time | 207 /// [ConstantCompiler] that uses the Dart semantics for the compile-time |
206 /// constant evaluation. | 208 /// constant evaluation. |
207 class DartConstantCompiler extends ConstantCompilerBase { | 209 class DartConstantCompiler extends ConstantCompilerBase { |
208 DartConstantCompiler(Compiler compiler) | 210 DartConstantCompiler(Compiler compiler) |
209 : super(compiler, const DartConstantSystem()); | 211 : super(compiler, const DartConstantSystem()); |
210 | 212 |
211 ConstExp getConstantForNode(Node node, TreeElements definitions) { | 213 ConstantExpression getConstantForNode(Node node, TreeElements definitions) { |
212 return definitions.getConstant(node); | 214 return definitions.getConstant(node); |
213 } | 215 } |
214 | 216 |
215 ConstExp getConstantForMetadata(MetadataAnnotation metadata) { | 217 ConstantExpression getConstantForMetadata(MetadataAnnotation metadata) { |
216 return metadata.constant; | 218 return metadata.constant; |
217 } | 219 } |
218 | 220 |
219 ConstExp compileNodeWithDefinitions(Node node, | 221 ConstantExpression compileNodeWithDefinitions(Node node, |
220 TreeElements definitions, | 222 TreeElements definitions, |
221 {bool isConst: true}) { | 223 {bool isConst: true}) { |
222 ConstExp constant = definitions.getConstant(node); | 224 ConstantExpression constant = definitions.getConstant(node); |
223 if (constant != null) { | 225 if (constant != null) { |
224 return constant; | 226 return constant; |
225 } | 227 } |
226 constant = | 228 constant = |
227 super.compileNodeWithDefinitions(node, definitions, isConst: isConst); | 229 super.compileNodeWithDefinitions(node, definitions, isConst: isConst); |
228 if (constant != null) { | 230 if (constant != null) { |
229 definitions.setConstant(node, constant); | 231 definitions.setConstant(node, constant); |
230 } | 232 } |
231 return constant; | 233 return constant; |
232 } | 234 } |
(...skipping 29 matching lines...) Expand all Loading... |
262 assert(result != null); | 264 assert(result != null); |
263 return result; | 265 return result; |
264 } | 266 } |
265 | 267 |
266 AstConstant visitNode(Node node) { | 268 AstConstant visitNode(Node node) { |
267 return signalNotCompileTimeConstant(node); | 269 return signalNotCompileTimeConstant(node); |
268 } | 270 } |
269 | 271 |
270 AstConstant visitLiteralBool(LiteralBool node) { | 272 AstConstant visitLiteralBool(LiteralBool node) { |
271 return new AstConstant( | 273 return new AstConstant( |
272 context, node, new PrimitiveConstExp( | 274 context, node, new PrimitiveConstantExpression( |
273 constantSystem.createBool(node.value))); | 275 constantSystem.createBool(node.value))); |
274 } | 276 } |
275 | 277 |
276 AstConstant visitLiteralDouble(LiteralDouble node) { | 278 AstConstant visitLiteralDouble(LiteralDouble node) { |
277 return new AstConstant( | 279 return new AstConstant( |
278 context, node, new PrimitiveConstExp( | 280 context, node, new PrimitiveConstantExpression( |
279 constantSystem.createDouble(node.value))); | 281 constantSystem.createDouble(node.value))); |
280 } | 282 } |
281 | 283 |
282 AstConstant visitLiteralInt(LiteralInt node) { | 284 AstConstant visitLiteralInt(LiteralInt node) { |
283 return new AstConstant( | 285 return new AstConstant( |
284 context, node, new PrimitiveConstExp( | 286 context, node, new PrimitiveConstantExpression( |
285 constantSystem.createInt(node.value))); | 287 constantSystem.createInt(node.value))); |
286 } | 288 } |
287 | 289 |
288 AstConstant visitLiteralList(LiteralList node) { | 290 AstConstant visitLiteralList(LiteralList node) { |
289 if (!node.isConst) { | 291 if (!node.isConst) { |
290 return signalNotCompileTimeConstant(node); | 292 return signalNotCompileTimeConstant(node); |
291 } | 293 } |
292 List<ConstExp> argumentExpressions = <ConstExp>[]; | 294 List<ConstantExpression> argumentExpressions = <ConstantExpression>[]; |
293 List<Constant> argumentValues = <Constant>[]; | 295 List<ConstantValue> argumentValues = <ConstantValue>[]; |
294 for (Link<Node> link = node.elements.nodes; | 296 for (Link<Node> link = node.elements.nodes; |
295 !link.isEmpty; | 297 !link.isEmpty; |
296 link = link.tail) { | 298 link = link.tail) { |
297 AstConstant argument = evaluateConstant(link.head); | 299 AstConstant argument = evaluateConstant(link.head); |
298 if (argument == null) { | 300 if (argument == null) { |
299 return null; | 301 return null; |
300 } | 302 } |
301 argumentExpressions.add(argument.expression); | 303 argumentExpressions.add(argument.expression); |
302 argumentValues.add(argument.value); | 304 argumentValues.add(argument.value); |
303 } | 305 } |
304 DartType type = elements.getType(node); | 306 DartType type = elements.getType(node); |
305 return new AstConstant( | 307 return new AstConstant( |
306 context, node, new ListConstExp( | 308 context, node, new ListConstantExpression( |
307 new ListConstant(type, argumentValues), | 309 new ListConstantValue(type, argumentValues), |
308 type, | 310 type, |
309 argumentExpressions)); | 311 argumentExpressions)); |
310 } | 312 } |
311 | 313 |
312 AstConstant visitLiteralMap(LiteralMap node) { | 314 AstConstant visitLiteralMap(LiteralMap node) { |
313 if (!node.isConst) { | 315 if (!node.isConst) { |
314 return signalNotCompileTimeConstant(node); | 316 return signalNotCompileTimeConstant(node); |
315 } | 317 } |
316 List<ConstExp> keyExpressions = <ConstExp>[]; | 318 List<ConstantExpression> keyExpressions = <ConstantExpression>[]; |
317 List<Constant> keyValues = <Constant>[]; | 319 List<ConstantValue> keyValues = <ConstantValue>[]; |
318 Map<Constant, ConstExp> map = new Map<Constant, ConstExp>(); | 320 Map<ConstantValue, ConstantExpression> map = |
| 321 new Map<ConstantValue, ConstantExpression>(); |
319 for (Link<Node> link = node.entries.nodes; | 322 for (Link<Node> link = node.entries.nodes; |
320 !link.isEmpty; | 323 !link.isEmpty; |
321 link = link.tail) { | 324 link = link.tail) { |
322 LiteralMapEntry entry = link.head; | 325 LiteralMapEntry entry = link.head; |
323 AstConstant key = evaluateConstant(entry.key); | 326 AstConstant key = evaluateConstant(entry.key); |
324 if (key == null) { | 327 if (key == null) { |
325 return null; | 328 return null; |
326 } | 329 } |
327 if (!map.containsKey(key.value)) { | 330 if (!map.containsKey(key.value)) { |
328 keyExpressions.add(key.expression); | 331 keyExpressions.add(key.expression); |
329 keyValues.add(key.value); | 332 keyValues.add(key.value); |
330 } else { | 333 } else { |
331 compiler.reportWarning(entry.key, MessageKind.EQUAL_MAP_ENTRY_KEY); | 334 compiler.reportWarning(entry.key, MessageKind.EQUAL_MAP_ENTRY_KEY); |
332 } | 335 } |
333 AstConstant value = evaluateConstant(entry.value); | 336 AstConstant value = evaluateConstant(entry.value); |
334 if (value == null) { | 337 if (value == null) { |
335 return null; | 338 return null; |
336 } | 339 } |
337 map[key.value] = value.expression; | 340 map[key.value] = value.expression; |
338 } | 341 } |
339 List<ConstExp> valueExpressions = map.values.toList(); | 342 List<ConstantExpression> valueExpressions = map.values.toList(); |
340 InterfaceType type = elements.getType(node); | 343 InterfaceType type = elements.getType(node); |
341 return new AstConstant( | 344 return new AstConstant( |
342 context, node, new MapConstExp( | 345 context, node, new MapConstantExpression( |
343 constantSystem.createMap(compiler, type, keyValues, | 346 constantSystem.createMap(compiler, type, keyValues, |
344 valueExpressions.map((e) => e.value).toList()), | 347 valueExpressions.map((e) => e.value).toList()), |
345 type, | 348 type, |
346 keyExpressions, | 349 keyExpressions, |
347 valueExpressions)); | 350 valueExpressions)); |
348 } | 351 } |
349 | 352 |
350 AstConstant visitLiteralNull(LiteralNull node) { | 353 AstConstant visitLiteralNull(LiteralNull node) { |
351 return new AstConstant( | 354 return new AstConstant( |
352 context, node, new PrimitiveConstExp( | 355 context, node, new PrimitiveConstantExpression( |
353 constantSystem.createNull())); | 356 constantSystem.createNull())); |
354 } | 357 } |
355 | 358 |
356 AstConstant visitLiteralString(LiteralString node) { | 359 AstConstant visitLiteralString(LiteralString node) { |
357 return new AstConstant( | 360 return new AstConstant( |
358 context, node, new PrimitiveConstExp( | 361 context, node, new PrimitiveConstantExpression( |
359 constantSystem.createString(node.dartString))); | 362 constantSystem.createString(node.dartString))); |
360 } | 363 } |
361 | 364 |
362 AstConstant visitStringJuxtaposition(StringJuxtaposition node) { | 365 AstConstant visitStringJuxtaposition(StringJuxtaposition node) { |
363 AstConstant left = evaluate(node.first); | 366 AstConstant left = evaluate(node.first); |
364 AstConstant right = evaluate(node.second); | 367 AstConstant right = evaluate(node.second); |
365 if (left == null || right == null) return null; | 368 if (left == null || right == null) return null; |
366 StringConstant leftValue = left.value; | 369 StringConstantValue leftValue = left.value; |
367 StringConstant rightValue = right.value; | 370 StringConstantValue rightValue = right.value; |
368 return new AstConstant( | 371 return new AstConstant( |
369 context, node, new ConcatenateConstExp( | 372 context, node, new ConcatenateConstantExpression( |
370 constantSystem.createString( | 373 constantSystem.createString( |
371 new DartString.concat(leftValue.value, rightValue.value)), | 374 new DartString.concat( |
| 375 leftValue.primitiveValue, rightValue.primitiveValue)), |
372 [left.expression, right.expression])); | 376 [left.expression, right.expression])); |
373 } | 377 } |
374 | 378 |
375 AstConstant visitStringInterpolation(StringInterpolation node) { | 379 AstConstant visitStringInterpolation(StringInterpolation node) { |
376 List<ConstExp> subexpressions = <ConstExp>[]; | 380 List<ConstantExpression> subexpressions = <ConstantExpression>[]; |
377 AstConstant initialString = evaluate(node.string); | 381 AstConstant initialString = evaluate(node.string); |
378 if (initialString == null) { | 382 if (initialString == null) { |
379 return null; | 383 return null; |
380 } | 384 } |
381 subexpressions.add(initialString.expression); | 385 subexpressions.add(initialString.expression); |
382 StringConstant initialStringValue = initialString.value; | 386 StringConstantValue initialStringValue = initialString.value; |
383 DartString accumulator = initialStringValue.value; | 387 DartString accumulator = initialStringValue.primitiveValue; |
384 for (StringInterpolationPart part in node.parts) { | 388 for (StringInterpolationPart part in node.parts) { |
385 AstConstant subexpression = evaluate(part.expression); | 389 AstConstant subexpression = evaluate(part.expression); |
386 if (subexpression == null) { | 390 if (subexpression == null) { |
387 return null; | 391 return null; |
388 } | 392 } |
389 subexpressions.add(subexpression.expression); | 393 subexpressions.add(subexpression.expression); |
390 Constant expression = subexpression.value; | 394 ConstantValue expression = subexpression.value; |
391 DartString expressionString; | 395 DartString expressionString; |
392 if (expression.isNum || expression.isBool) { | 396 if (expression.isNum || expression.isBool) { |
393 PrimitiveConstant primitive = expression; | 397 PrimitiveConstantValue primitive = expression; |
394 expressionString = new DartString.literal(primitive.value.toString()); | 398 expressionString = |
| 399 new DartString.literal(primitive.primitiveValue.toString()); |
395 } else if (expression.isString) { | 400 } else if (expression.isString) { |
396 PrimitiveConstant primitive = expression; | 401 PrimitiveConstantValue primitive = expression; |
397 expressionString = primitive.value; | 402 expressionString = primitive.primitiveValue; |
398 } else { | 403 } else { |
399 // TODO(johnniwinther): Specialize message to indicated that the problem | 404 // TODO(johnniwinther): Specialize message to indicated that the problem |
400 // is not constness but the types of the const expressions. | 405 // is not constness but the types of the const expressions. |
401 return signalNotCompileTimeConstant(part.expression); | 406 return signalNotCompileTimeConstant(part.expression); |
402 } | 407 } |
403 accumulator = new DartString.concat(accumulator, expressionString); | 408 accumulator = new DartString.concat(accumulator, expressionString); |
404 AstConstant partString = evaluate(part.string); | 409 AstConstant partString = evaluate(part.string); |
405 if (partString == null) return null; | 410 if (partString == null) return null; |
406 subexpressions.add(partString.expression); | 411 subexpressions.add(partString.expression); |
407 StringConstant partStringValue = partString.value; | 412 StringConstantValue partStringValue = partString.value; |
408 accumulator = new DartString.concat(accumulator, partStringValue.value); | 413 accumulator = |
| 414 new DartString.concat(accumulator, partStringValue.primitiveValue); |
409 }; | 415 }; |
410 return new AstConstant( | 416 return new AstConstant( |
411 context, node, new ConcatenateConstExp( | 417 context, node, new ConcatenateConstantExpression( |
412 constantSystem.createString(accumulator), | 418 constantSystem.createString(accumulator), |
413 subexpressions)); | 419 subexpressions)); |
414 } | 420 } |
415 | 421 |
416 AstConstant visitLiteralSymbol(LiteralSymbol node) { | 422 AstConstant visitLiteralSymbol(LiteralSymbol node) { |
417 InterfaceType type = compiler.symbolClass.rawType; | 423 InterfaceType type = compiler.symbolClass.rawType; |
418 String text = node.slowNameString; | 424 String text = node.slowNameString; |
419 List<AstConstant> arguments = | 425 List<AstConstant> arguments = |
420 <AstConstant>[new AstConstant(context, node, | 426 <AstConstant>[new AstConstant(context, node, |
421 new PrimitiveConstExp(constantSystem.createString( | 427 new PrimitiveConstantExpression(constantSystem.createString( |
422 new DartString.literal(text))))]; | 428 new DartString.literal(text))))]; |
423 AstConstant constant = makeConstructedConstant( | 429 AstConstant constant = makeConstructedConstant( |
424 compiler, handler, context, node, type, compiler.symbolConstructor, | 430 compiler, handler, context, node, type, compiler.symbolConstructor, |
425 new Selector.callConstructor('', null, 1), | 431 new Selector.callConstructor('', null, 1), |
426 arguments, arguments); | 432 arguments, arguments); |
427 return new AstConstant( | 433 return new AstConstant( |
428 context, node, new SymbolConstExp(constant.value, text)); | 434 context, node, new SymbolConstantExpression(constant.value, text)); |
429 } | 435 } |
430 | 436 |
431 AstConstant makeTypeConstant(Node node, DartType elementType) { | 437 AstConstant makeTypeConstant(Node node, DartType elementType) { |
432 DartType constantType = | 438 DartType constantType = |
433 compiler.backend.typeImplementation.computeType(compiler); | 439 compiler.backend.typeImplementation.computeType(compiler); |
434 return new AstConstant( | 440 return new AstConstant( |
435 context, node, new TypeConstExp( | 441 context, node, new TypeConstantExpression( |
436 new TypeConstant(elementType, constantType), | 442 new TypeConstantValue(elementType, constantType), |
437 elementType)); | 443 elementType)); |
438 } | 444 } |
439 | 445 |
440 /// Returns true if the prefix of the send resolves to a deferred import | 446 /// Returns true if the prefix of the send resolves to a deferred import |
441 /// prefix. | 447 /// prefix. |
442 bool isDeferredUse(Send send) { | 448 bool isDeferredUse(Send send) { |
443 if (send == null) return false; | 449 if (send == null) return false; |
444 return compiler.deferredLoadTask | 450 return compiler.deferredLoadTask |
445 .deferredPrefixElement(send, elements) != null; | 451 .deferredPrefixElement(send, elements) != null; |
446 } | 452 } |
(...skipping 11 matching lines...) Expand all Loading... |
458 // TODO(floitsch): provide better error-messages. | 464 // TODO(floitsch): provide better error-messages. |
459 AstConstant visitSend(Send send) { | 465 AstConstant visitSend(Send send) { |
460 Element element = elements[send]; | 466 Element element = elements[send]; |
461 if (send.isPropertyAccess) { | 467 if (send.isPropertyAccess) { |
462 if (isDeferredUse(send)) { | 468 if (isDeferredUse(send)) { |
463 return signalNotCompileTimeConstant(send, | 469 return signalNotCompileTimeConstant(send, |
464 message: MessageKind.DEFERRED_COMPILE_TIME_CONSTANT); | 470 message: MessageKind.DEFERRED_COMPILE_TIME_CONSTANT); |
465 } | 471 } |
466 if (Elements.isStaticOrTopLevelFunction(element)) { | 472 if (Elements.isStaticOrTopLevelFunction(element)) { |
467 return new AstConstant( | 473 return new AstConstant( |
468 context, send, new FunctionConstExp( | 474 context, send, new FunctionConstantExpression( |
469 new FunctionConstant(element), | 475 new FunctionConstantValue(element), |
470 element)); | 476 element)); |
471 } else if (Elements.isStaticOrTopLevelField(element)) { | 477 } else if (Elements.isStaticOrTopLevelField(element)) { |
472 ConstExp result; | 478 ConstantExpression result; |
473 if (element.isConst) { | 479 if (element.isConst) { |
474 result = handler.compileConstant(element); | 480 result = handler.compileConstant(element); |
475 } else if (element.isFinal && !isEvaluatingConstant) { | 481 } else if (element.isFinal && !isEvaluatingConstant) { |
476 result = handler.compileVariable(element); | 482 result = handler.compileVariable(element); |
477 } | 483 } |
478 if (result != null) { | 484 if (result != null) { |
479 return new AstConstant( | 485 return new AstConstant( |
480 context, send, new VariableConstExp(result.value, element)); | 486 context, send, |
| 487 new VariableConstantExpression(result.value, element)); |
481 } | 488 } |
482 } else if (Elements.isClass(element) || Elements.isTypedef(element)) { | 489 } else if (Elements.isClass(element) || Elements.isTypedef(element)) { |
483 assert(elements.isTypeLiteral(send)); | 490 assert(elements.isTypeLiteral(send)); |
484 return makeTypeConstant(send, elements.getTypeLiteralType(send)); | 491 return makeTypeConstant(send, elements.getTypeLiteralType(send)); |
485 } else if (send.receiver != null) { | 492 } else if (send.receiver != null) { |
486 // Fall through to error handling. | 493 // Fall through to error handling. |
487 } else if (!Elements.isUnresolved(element) | 494 } else if (!Elements.isUnresolved(element) |
488 && element.isVariable | 495 && element.isVariable |
489 && element.isConst) { | 496 && element.isConst) { |
490 ConstExp result = handler.compileConstant(element); | 497 ConstantExpression result = handler.compileConstant(element); |
491 if (result != null) { | 498 if (result != null) { |
492 return new AstConstant( | 499 return new AstConstant( |
493 context, send, new VariableConstExp(result.value, element)); | 500 context, send, |
| 501 new VariableConstantExpression(result.value, element)); |
494 } | 502 } |
495 } | 503 } |
496 return signalNotCompileTimeConstant(send); | 504 return signalNotCompileTimeConstant(send); |
497 } else if (send.isCall) { | 505 } else if (send.isCall) { |
498 if (identical(element, compiler.identicalFunction) | 506 if (identical(element, compiler.identicalFunction) |
499 && send.argumentCount() == 2) { | 507 && send.argumentCount() == 2) { |
500 AstConstant left = evaluate(send.argumentsNode.nodes.head); | 508 AstConstant left = evaluate(send.argumentsNode.nodes.head); |
501 AstConstant right = evaluate(send.argumentsNode.nodes.tail.head); | 509 AstConstant right = evaluate(send.argumentsNode.nodes.tail.head); |
502 if (left == null || right == null) { | 510 if (left == null || right == null) { |
503 return null; | 511 return null; |
504 } | 512 } |
505 Constant result = constantSystem.identity.fold(left.value, right.value); | 513 ConstantValue result = |
| 514 constantSystem.identity.fold(left.value, right.value); |
506 if (result != null) { | 515 if (result != null) { |
507 return new AstConstant( | 516 return new AstConstant( |
508 context, send, new BinaryConstExp(result, | 517 context, send, new BinaryConstantExpression(result, |
509 left.expression, 'identical', right.expression)); | 518 left.expression, 'identical', right.expression)); |
510 } | 519 } |
511 } | 520 } |
512 return signalNotCompileTimeConstant(send); | 521 return signalNotCompileTimeConstant(send); |
513 } else if (send.isPrefix) { | 522 } else if (send.isPrefix) { |
514 assert(send.isOperator); | 523 assert(send.isOperator); |
515 AstConstant receiverConstant = evaluate(send.receiver); | 524 AstConstant receiverConstant = evaluate(send.receiver); |
516 if (receiverConstant == null) { | 525 if (receiverConstant == null) { |
517 return null; | 526 return null; |
518 } | 527 } |
519 Operator op = send.selector; | 528 Operator op = send.selector; |
520 UnaryOperation operation = constantSystem.lookupUnary(op.source); | 529 UnaryOperation operation = constantSystem.lookupUnary(op.source); |
521 if (operation == null) { | 530 if (operation == null) { |
522 compiler.internalError(op, "Unexpected operator."); | 531 compiler.internalError(op, "Unexpected operator."); |
523 } | 532 } |
524 Constant folded = operation.fold(receiverConstant.value); | 533 ConstantValue folded = operation.fold(receiverConstant.value); |
525 if (folded == null) { | 534 if (folded == null) { |
526 return signalNotCompileTimeConstant(send); | 535 return signalNotCompileTimeConstant(send); |
527 } | 536 } |
528 return new AstConstant( | 537 return new AstConstant( |
529 context, send, new UnaryConstExp(folded, | 538 context, send, new UnaryConstantExpression(folded, |
530 op.source, receiverConstant.expression)); | 539 op.source, receiverConstant.expression)); |
531 } else if (send.isOperator && !send.isPostfix) { | 540 } else if (send.isOperator && !send.isPostfix) { |
532 assert(send.argumentCount() == 1); | 541 assert(send.argumentCount() == 1); |
533 AstConstant left = evaluate(send.receiver); | 542 AstConstant left = evaluate(send.receiver); |
534 AstConstant right = evaluate(send.argumentsNode.nodes.head); | 543 AstConstant right = evaluate(send.argumentsNode.nodes.head); |
535 if (left == null || right == null) { | 544 if (left == null || right == null) { |
536 return null; | 545 return null; |
537 } | 546 } |
538 Constant leftValue = left.value; | 547 ConstantValue leftValue = left.value; |
539 Constant rightValue = right.value; | 548 ConstantValue rightValue = right.value; |
540 Operator op = send.selector.asOperator(); | 549 Operator op = send.selector.asOperator(); |
541 Constant folded = null; | 550 ConstantValue folded = null; |
542 switch (op.source) { | 551 switch (op.source) { |
543 case "==": | 552 case "==": |
544 if (leftValue.isPrimitive && rightValue.isPrimitive) { | 553 if (leftValue.isPrimitive && rightValue.isPrimitive) { |
545 folded = constantSystem.equal.fold(leftValue, rightValue); | 554 folded = constantSystem.equal.fold(leftValue, rightValue); |
546 } | 555 } |
547 break; | 556 break; |
548 case "!=": | 557 case "!=": |
549 if (leftValue.isPrimitive && rightValue.isPrimitive) { | 558 if (leftValue.isPrimitive && rightValue.isPrimitive) { |
550 BoolConstant areEquals = | 559 BoolConstantValue areEquals = |
551 constantSystem.equal.fold(leftValue, rightValue); | 560 constantSystem.equal.fold(leftValue, rightValue); |
552 if (areEquals == null) { | 561 if (areEquals == null) { |
553 folded = null; | 562 folded = null; |
554 } else { | 563 } else { |
555 folded = areEquals.negate(); | 564 folded = areEquals.negate(); |
556 } | 565 } |
557 } | 566 } |
558 break; | 567 break; |
559 default: | 568 default: |
560 BinaryOperation operation = constantSystem.lookupBinary(op.source); | 569 BinaryOperation operation = constantSystem.lookupBinary(op.source); |
561 if (operation != null) { | 570 if (operation != null) { |
562 folded = operation.fold(leftValue, rightValue); | 571 folded = operation.fold(leftValue, rightValue); |
563 } | 572 } |
564 } | 573 } |
565 if (folded == null) { | 574 if (folded == null) { |
566 return signalNotCompileTimeConstant(send); | 575 return signalNotCompileTimeConstant(send); |
567 } | 576 } |
568 return new AstConstant( | 577 return new AstConstant( |
569 context, send, new BinaryConstExp(folded, | 578 context, send, new BinaryConstantExpression(folded, |
570 left.expression, op.source, right.expression)); | 579 left.expression, op.source, right.expression)); |
571 } | 580 } |
572 return signalNotCompileTimeConstant(send); | 581 return signalNotCompileTimeConstant(send); |
573 } | 582 } |
574 | 583 |
575 AstConstant visitConditional(Conditional node) { | 584 AstConstant visitConditional(Conditional node) { |
576 AstConstant condition = evaluate(node.condition); | 585 AstConstant condition = evaluate(node.condition); |
577 if (condition == null) { | 586 if (condition == null) { |
578 return null; | 587 return null; |
579 } else if (!condition.value.isBool) { | 588 } else if (!condition.value.isBool) { |
580 DartType conditionType = condition.value.computeType(compiler); | 589 DartType conditionType = condition.value.computeType(compiler); |
581 if (isEvaluatingConstant) { | 590 if (isEvaluatingConstant) { |
582 compiler.reportFatalError( | 591 compiler.reportFatalError( |
583 node.condition, MessageKind.NOT_ASSIGNABLE, | 592 node.condition, MessageKind.NOT_ASSIGNABLE, |
584 {'fromType': conditionType, 'toType': compiler.boolClass.rawType}); | 593 {'fromType': conditionType, 'toType': compiler.boolClass.rawType}); |
585 } | 594 } |
586 return null; | 595 return null; |
587 } | 596 } |
588 AstConstant thenExpression = evaluate(node.thenExpression); | 597 AstConstant thenExpression = evaluate(node.thenExpression); |
589 AstConstant elseExpression = evaluate(node.elseExpression); | 598 AstConstant elseExpression = evaluate(node.elseExpression); |
590 if (thenExpression == null || elseExpression == null) { | 599 if (thenExpression == null || elseExpression == null) { |
591 return null; | 600 return null; |
592 } | 601 } |
593 BoolConstant boolCondition = condition.value; | 602 BoolConstantValue boolCondition = condition.value; |
594 return new AstConstant( | 603 return new AstConstant( |
595 context, node, new ConditionalConstExp( | 604 context, node, new ConditionalConstantExpression( |
596 boolCondition.value ? thenExpression.value : elseExpression.value, | 605 boolCondition.primitiveValue |
| 606 ? thenExpression.value |
| 607 : elseExpression.value, |
597 condition.expression, | 608 condition.expression, |
598 thenExpression.expression, | 609 thenExpression.expression, |
599 elseExpression.expression)); | 610 elseExpression.expression)); |
600 } | 611 } |
601 | 612 |
602 AstConstant visitSendSet(SendSet node) { | 613 AstConstant visitSendSet(SendSet node) { |
603 return signalNotCompileTimeConstant(node); | 614 return signalNotCompileTimeConstant(node); |
604 } | 615 } |
605 | 616 |
606 /** | 617 /** |
607 * Returns the normalized list of constant arguments that are passed to the | 618 * Returns the normalized list of constant arguments that are passed to the |
608 * constructor including both the concrete arguments and default values for | 619 * constructor including both the concrete arguments and default values for |
609 * omitted optional arguments. | 620 * omitted optional arguments. |
610 * | 621 * |
611 * Invariant: [target] must be an implementation element. | 622 * Invariant: [target] must be an implementation element. |
612 */ | 623 */ |
613 List<AstConstant> evaluateArgumentsToConstructor( | 624 List<AstConstant> evaluateArgumentsToConstructor( |
614 Node node, | 625 Node node, |
615 Selector selector, | 626 Selector selector, |
616 Link<Node> arguments, | 627 Link<Node> arguments, |
617 FunctionElement target, | 628 FunctionElement target, |
618 {AstConstant compileArgument(Node node)}) { | 629 {AstConstant compileArgument(Node node)}) { |
619 assert(invariant(node, target.isImplementation)); | 630 assert(invariant(node, target.isImplementation)); |
620 List<AstConstant> compiledArguments = <AstConstant>[]; | 631 List<AstConstant> compiledArguments = <AstConstant>[]; |
621 | 632 |
622 AstConstant compileDefaultValue(VariableElement element) { | 633 AstConstant compileDefaultValue(VariableElement element) { |
623 ConstExp constant = handler.compileConstant(element); | 634 ConstantExpression constant = handler.compileConstant(element); |
624 return new AstConstant.fromDefaultValue(element, constant); | 635 return new AstConstant.fromDefaultValue(element, constant); |
625 } | 636 } |
626 target.computeSignature(compiler); | 637 target.computeSignature(compiler); |
627 bool succeeded = selector.addArgumentsToList(arguments, | 638 bool succeeded = selector.addArgumentsToList(arguments, |
628 compiledArguments, | 639 compiledArguments, |
629 target, | 640 target, |
630 compileArgument, | 641 compileArgument, |
631 compileDefaultValue, | 642 compileDefaultValue, |
632 compiler.world); | 643 compiler.world); |
633 if (!succeeded) { | 644 if (!succeeded) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 evaluateArgumentsToConstructor( | 693 evaluateArgumentsToConstructor( |
683 node, selector, send.arguments, constructor.implementation, | 694 node, selector, send.arguments, constructor.implementation, |
684 compileArgument: (node) => concreteArgumentMap[node]); | 695 compileArgument: (node) => concreteArgumentMap[node]); |
685 List<AstConstant> concreteArguments = | 696 List<AstConstant> concreteArguments = |
686 concreteArgumentMap.values.toList(); | 697 concreteArgumentMap.values.toList(); |
687 | 698 |
688 if (constructor == compiler.intEnvironment || | 699 if (constructor == compiler.intEnvironment || |
689 constructor == compiler.boolEnvironment || | 700 constructor == compiler.boolEnvironment || |
690 constructor == compiler.stringEnvironment) { | 701 constructor == compiler.stringEnvironment) { |
691 | 702 |
692 AstConstant createEvaluatedConstant(Constant value) { | 703 AstConstant createEvaluatedConstant(ConstantValue value) { |
693 return new AstConstant( | 704 return new AstConstant( |
694 context, node, new ConstructorConstExp( | 705 context, node, new ConstructedConstantExpresssion( |
695 value, | 706 value, |
696 type, | 707 type, |
697 constructor, | 708 constructor, |
698 elements.getSelector(send), | 709 elements.getSelector(send), |
699 concreteArguments.map((e) => e.expression).toList())); | 710 concreteArguments.map((e) => e.expression).toList())); |
700 } | 711 } |
701 | 712 |
702 var firstArgument = normalizedArguments[0].value; | 713 var firstArgument = normalizedArguments[0].value; |
703 Constant defaultValue = normalizedArguments[1].value; | 714 ConstantValue defaultValue = normalizedArguments[1].value; |
704 | 715 |
705 if (firstArgument is NullConstant) { | 716 if (firstArgument.isNull) { |
706 compiler.reportFatalError( | 717 compiler.reportFatalError( |
707 send.arguments.head, MessageKind.NULL_NOT_ALLOWED); | 718 send.arguments.head, MessageKind.NULL_NOT_ALLOWED); |
708 return null; | 719 return null; |
709 } | 720 } |
710 | 721 |
711 if (firstArgument is! StringConstant) { | 722 if (!firstArgument.isString) { |
712 DartType type = defaultValue.computeType(compiler); | 723 DartType type = defaultValue.computeType(compiler); |
713 compiler.reportFatalError( | 724 compiler.reportFatalError( |
714 send.arguments.head, MessageKind.NOT_ASSIGNABLE, | 725 send.arguments.head, MessageKind.NOT_ASSIGNABLE, |
715 {'fromType': type, 'toType': compiler.stringClass.rawType}); | 726 {'fromType': type, 'toType': compiler.stringClass.rawType}); |
716 return null; | 727 return null; |
717 } | 728 } |
718 | 729 |
719 if (constructor == compiler.intEnvironment | 730 if (constructor == compiler.intEnvironment && |
720 && !(defaultValue is NullConstant || defaultValue is IntConstant)) { | 731 !(defaultValue.isNull || defaultValue.isInt)) { |
721 DartType type = defaultValue.computeType(compiler); | 732 DartType type = defaultValue.computeType(compiler); |
722 compiler.reportFatalError( | 733 compiler.reportFatalError( |
723 send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE, | 734 send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE, |
724 {'fromType': type, 'toType': compiler.intClass.rawType}); | 735 {'fromType': type, 'toType': compiler.intClass.rawType}); |
725 return null; | 736 return null; |
726 } | 737 } |
727 | 738 |
728 if (constructor == compiler.boolEnvironment | 739 if (constructor == compiler.boolEnvironment && |
729 && !(defaultValue is NullConstant || defaultValue is BoolConstant)) { | 740 !(defaultValue.isNull || defaultValue.isBool)) { |
730 DartType type = defaultValue.computeType(compiler); | 741 DartType type = defaultValue.computeType(compiler); |
731 compiler.reportFatalError( | 742 compiler.reportFatalError( |
732 send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE, | 743 send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE, |
733 {'fromType': type, 'toType': compiler.boolClass.rawType}); | 744 {'fromType': type, 'toType': compiler.boolClass.rawType}); |
734 return null; | 745 return null; |
735 } | 746 } |
736 | 747 |
737 if (constructor == compiler.stringEnvironment | 748 if (constructor == compiler.stringEnvironment && |
738 && !(defaultValue is NullConstant | 749 !(defaultValue.isNull || defaultValue.isString)) { |
739 || defaultValue is StringConstant)) { | |
740 DartType type = defaultValue.computeType(compiler); | 750 DartType type = defaultValue.computeType(compiler); |
741 compiler.reportFatalError( | 751 compiler.reportFatalError( |
742 send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE, | 752 send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE, |
743 {'fromType': type, 'toType': compiler.stringClass.rawType}); | 753 {'fromType': type, 'toType': compiler.stringClass.rawType}); |
744 return null; | 754 return null; |
745 } | 755 } |
746 | 756 |
747 String value = | 757 String value = |
748 compiler.fromEnvironment(firstArgument.value.slowToString()); | 758 compiler.fromEnvironment(firstArgument.primitiveValue.slowToString()); |
749 | 759 |
750 if (value == null) { | 760 if (value == null) { |
751 return createEvaluatedConstant(defaultValue); | 761 return createEvaluatedConstant(defaultValue); |
752 } else if (constructor == compiler.intEnvironment) { | 762 } else if (constructor == compiler.intEnvironment) { |
753 int number = int.parse(value, onError: (_) => null); | 763 int number = int.parse(value, onError: (_) => null); |
754 return createEvaluatedConstant( | 764 return createEvaluatedConstant( |
755 (number == null) | 765 (number == null) |
756 ? defaultValue | 766 ? defaultValue |
757 : constantSystem.createInt(number)); | 767 : constantSystem.createInt(number)); |
758 } else if (constructor == compiler.boolEnvironment) { | 768 } else if (constructor == compiler.boolEnvironment) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 target = target.implementation; | 812 target = target.implementation; |
803 assert(invariant(node, target.isImplementation)); | 813 assert(invariant(node, target.isImplementation)); |
804 | 814 |
805 ConstructorEvaluator evaluator = new ConstructorEvaluator( | 815 ConstructorEvaluator evaluator = new ConstructorEvaluator( |
806 constructedType, target, handler, compiler); | 816 constructedType, target, handler, compiler); |
807 evaluator.evaluateConstructorFieldValues(normalizedArguments); | 817 evaluator.evaluateConstructorFieldValues(normalizedArguments); |
808 List<AstConstant> fieldConstants = | 818 List<AstConstant> fieldConstants = |
809 evaluator.buildFieldConstants(classElement); | 819 evaluator.buildFieldConstants(classElement); |
810 | 820 |
811 return new AstConstant( | 821 return new AstConstant( |
812 context, node, new ConstructorConstExp( | 822 context, node, new ConstructedConstantExpresssion( |
813 new ConstructedConstant( | 823 new ConstructedConstantValue( |
814 constructedType, | 824 constructedType, |
815 fieldConstants.map((e) => e.value).toList()), | 825 fieldConstants.map((e) => e.value).toList()), |
816 type, | 826 type, |
817 constructor, | 827 constructor, |
818 selector, | 828 selector, |
819 concreteArguments.map((e) => e.expression).toList())); | 829 concreteArguments.map((e) => e.expression).toList())); |
820 } | 830 } |
821 | 831 |
822 AstConstant visitParenthesizedExpression(ParenthesizedExpression node) { | 832 AstConstant visitParenthesizedExpression(ParenthesizedExpression node) { |
823 return node.expression.accept(this); | 833 return node.expression.accept(this); |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 return fieldConstants; | 1054 return fieldConstants; |
1045 } | 1055 } |
1046 } | 1056 } |
1047 | 1057 |
1048 /// A constant created from the front-end AST. | 1058 /// A constant created from the front-end AST. |
1049 /// | 1059 /// |
1050 /// [element] and [node] point to the source location of the constant. | 1060 /// [element] and [node] point to the source location of the constant. |
1051 /// [expression] holds the symbolic constant expression and [value] its constant | 1061 /// [expression] holds the symbolic constant expression and [value] its constant |
1052 /// value. | 1062 /// value. |
1053 /// | 1063 /// |
1054 /// This class differs from [ConstExp] in that it is coupled to the front-end | 1064 /// This class differs from [ConstantExpression] in that it is coupled to the |
1055 /// AST whereas [ConstExp] is only coupled to the element model. | 1065 /// front-end AST whereas [ConstantExpression] is only coupled to the element |
| 1066 /// model. |
1056 class AstConstant { | 1067 class AstConstant { |
1057 final Element element; | 1068 final Element element; |
1058 final Node node; | 1069 final Node node; |
1059 final ConstExp expression; | 1070 final ConstantExpression expression; |
1060 | 1071 |
1061 AstConstant(this.element, this.node, this.expression); | 1072 AstConstant(this.element, this.node, this.expression); |
1062 | 1073 |
1063 factory AstConstant.fromDefaultValue( | 1074 factory AstConstant.fromDefaultValue( |
1064 VariableElement element, | 1075 VariableElement element, |
1065 ConstExp constant) { | 1076 ConstantExpression constant) { |
1066 return new AstConstant( | 1077 return new AstConstant( |
1067 element, | 1078 element, |
1068 element.initializer != null ? element.initializer : element.node, | 1079 element.initializer != null ? element.initializer : element.node, |
1069 constant); | 1080 constant); |
1070 } | 1081 } |
1071 | 1082 |
1072 Constant get value => expression.value; | 1083 ConstantValue get value => expression.value; |
1073 | 1084 |
1074 String toString() => expression.toString(); | 1085 String toString() => expression.toString(); |
1075 } | 1086 } |
OLD | NEW |