| 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 /** | 7 /** |
| 8 * The [ConstantHandler] keeps track of compile-time constants, | 8 * The [ConstantHandler] keeps track of compile-time constants, |
| 9 * initializations of global and static fields, and default values of | 9 * initializations of global and static fields, and default values of |
| 10 * optional parameters. | 10 * optional parameters. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 | 22 |
| 23 /** Set of all registered compiled constants. */ | 23 /** Set of all registered compiled constants. */ |
| 24 final Set<Constant> compiledConstants; | 24 final Set<Constant> compiledConstants; |
| 25 | 25 |
| 26 /** The set of variable elements that are in the process of being computed. */ | 26 /** The set of variable elements that are in the process of being computed. */ |
| 27 final Set<VariableElement> pendingVariables; | 27 final Set<VariableElement> pendingVariables; |
| 28 | 28 |
| 29 /** Caches the statics where the initial value cannot be eagerly compiled. */ | 29 /** Caches the statics where the initial value cannot be eagerly compiled. */ |
| 30 final Set<VariableElement> lazyStatics; | 30 final Set<VariableElement> lazyStatics; |
| 31 | 31 |
| 32 /** Caches the createRuntimeType function if registered. */ | |
| 33 Element createRuntimeTypeFunction = null; | |
| 34 | |
| 35 /** Caches the setRuntimeTypeInfo function if registered. */ | |
| 36 Element setRuntimeTypeInfoFunction = null; | |
| 37 | |
| 38 ConstantHandler(Compiler compiler, this.constantSystem, | 32 ConstantHandler(Compiler compiler, this.constantSystem, |
| 39 { bool this.isMetadata: false }) | 33 { bool this.isMetadata: false }) |
| 40 : initialVariableValues = new Map<VariableElement, dynamic>(), | 34 : initialVariableValues = new Map<VariableElement, dynamic>(), |
| 41 compiledConstants = new Set<Constant>(), | 35 compiledConstants = new Set<Constant>(), |
| 42 pendingVariables = new Set<VariableElement>(), | 36 pendingVariables = new Set<VariableElement>(), |
| 43 lazyStatics = new Set<VariableElement>(), | 37 lazyStatics = new Set<VariableElement>(), |
| 44 super(compiler); | 38 super(compiler); |
| 45 | 39 |
| 46 String get name => 'ConstantHandler'; | 40 String get name => 'ConstantHandler'; |
| 47 | 41 |
| 48 void registerCompileTimeConstant(Constant constant, TreeElements elements) { | 42 void addCompileTimeConstantForEmission(Constant constant) { |
| 49 registerInstantiatedType(constant.computeType(compiler), elements); | |
| 50 if (constant.isFunction()) { | |
| 51 FunctionConstant function = constant; | |
| 52 registerGetOfStaticFunction(function.element); | |
| 53 } else if (constant.isInterceptor()) { | |
| 54 // An interceptor constant references the class's prototype chain. | |
| 55 InterceptorConstant interceptor = constant; | |
| 56 registerInstantiatedType(interceptor.dispatchedType, elements); | |
| 57 } | |
| 58 compiledConstants.add(constant); | 43 compiledConstants.add(constant); |
| 59 } | 44 } |
| 60 | 45 |
| 61 void registerInstantiatedType(DartType type, TreeElements elements) { | 46 Constant getConstantForVariable(VariableElement element) { |
| 62 if (isMetadata) { | 47 return initialVariableValues[element]; |
| 63 compiler.backend.registerMetadataInstantiatedType(type, elements); | |
| 64 return; | |
| 65 } | |
| 66 compiler.enqueuer.codegen.registerInstantiatedType(type, elements); | |
| 67 if (type is InterfaceType && | |
| 68 !type.treatAsRaw && | |
| 69 compiler.backend.classNeedsRti(type.element)) { | |
| 70 registerSetRuntimeTypeInfoFunction(); | |
| 71 } | |
| 72 } | |
| 73 | |
| 74 void registerStaticUse(Element element) { | |
| 75 if (isMetadata) { | |
| 76 compiler.backend.registerMetadataStaticUse(element); | |
| 77 return; | |
| 78 } | |
| 79 compiler.analyzeElement(element.declaration); | |
| 80 compiler.enqueuer.codegen.registerStaticUse(element); | |
| 81 } | |
| 82 | |
| 83 void registerGetOfStaticFunction(FunctionElement element) { | |
| 84 if (isMetadata) { | |
| 85 compiler.backend.registerMetadataGetOfStaticFunction(element); | |
| 86 return; | |
| 87 } | |
| 88 compiler.analyzeElement(element.declaration); | |
| 89 compiler.enqueuer.codegen.registerGetOfStaticFunction(element); | |
| 90 } | |
| 91 | |
| 92 void registerStringInstance(TreeElements elements) { | |
| 93 registerInstantiatedType(compiler.stringClass.rawType, elements); | |
| 94 } | |
| 95 | |
| 96 void registerSetRuntimeTypeInfoFunction() { | |
| 97 if (setRuntimeTypeInfoFunction != null) return; | |
| 98 SourceString helperName = const SourceString('setRuntimeTypeInfo'); | |
| 99 setRuntimeTypeInfoFunction = compiler.findHelper(helperName); | |
| 100 registerStaticUse(setRuntimeTypeInfoFunction); | |
| 101 } | |
| 102 | |
| 103 void registerCreateRuntimeTypeFunction() { | |
| 104 if (createRuntimeTypeFunction != null) return; | |
| 105 SourceString helperName = const SourceString('createRuntimeType'); | |
| 106 createRuntimeTypeFunction = compiler.findHelper(helperName); | |
| 107 registerStaticUse(createRuntimeTypeFunction); | |
| 108 } | 48 } |
| 109 | 49 |
| 110 /** | 50 /** |
| 111 * Compiles the initial value of the given field and stores it in an internal | |
| 112 * map. Returns the initial value (a constant) if it can be computed | |
| 113 * statically. Returns [:null:] if the variable must be initialized lazily. | |
| 114 * | |
| 115 * [work] must contain a [VariableElement] refering to a global or | |
| 116 * static field. | |
| 117 */ | |
| 118 Constant compileWorkItem(CodegenWorkItem work) { | |
| 119 return measure(() { | |
| 120 assert(work.element.kind == ElementKind.FIELD | |
| 121 || work.element.kind == ElementKind.PARAMETER | |
| 122 || work.element.kind == ElementKind.FIELD_PARAMETER); | |
| 123 VariableElement element = work.element; | |
| 124 // Shortcut if it has already been compiled. | |
| 125 Constant result = initialVariableValues[element]; | |
| 126 if (result != null) return result; | |
| 127 if (lazyStatics.contains(element)) return null; | |
| 128 result = compileVariableWithDefinitions(element, work.resolutionTree); | |
| 129 assert(pendingVariables.isEmpty); | |
| 130 return result; | |
| 131 }); | |
| 132 } | |
| 133 | |
| 134 /** | |
| 135 * Returns a compile-time constant, or reports an error if the element is not | 51 * Returns a compile-time constant, or reports an error if the element is not |
| 136 * a compile-time constant. | 52 * a compile-time constant. |
| 137 */ | 53 */ |
| 138 Constant compileConstant(VariableElement element) { | 54 Constant compileConstant(VariableElement element) { |
| 139 return compileVariable(element, isConst: true); | 55 return compileVariable(element, isConst: true); |
| 140 } | 56 } |
| 141 | 57 |
| 142 /** | 58 /** |
| 143 * Returns the a compile-time constant if the variable could be compiled | 59 * Returns the a compile-time constant if the variable could be compiled |
| 144 * eagerly. Otherwise returns `null`. | 60 * eagerly. Otherwise returns `null`. |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 TreeElements definitions, | 150 TreeElements definitions, |
| 235 {bool isConst: false}) { | 151 {bool isConst: false}) { |
| 236 return measure(() { | 152 return measure(() { |
| 237 assert(node != null); | 153 assert(node != null); |
| 238 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator( | 154 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator( |
| 239 this, definitions, compiler, isConst: isConst); | 155 this, definitions, compiler, isConst: isConst); |
| 240 return evaluator.evaluate(node); | 156 return evaluator.evaluate(node); |
| 241 }); | 157 }); |
| 242 } | 158 } |
| 243 | 159 |
| 244 /** Attempts to compile a constant expression. Returns null if not possible */ | |
| 245 Constant tryCompileNodeWithDefinitions(Node node, TreeElements definitions) { | |
| 246 return measure(() { | |
| 247 assert(node != null); | |
| 248 try { | |
| 249 TryCompileTimeConstantEvaluator evaluator = | |
| 250 new TryCompileTimeConstantEvaluator(this, definitions, compiler); | |
| 251 return evaluator.evaluate(node); | |
| 252 } on CompileTimeConstantError catch (exn) { | |
| 253 return null; | |
| 254 } | |
| 255 }); | |
| 256 } | |
| 257 | |
| 258 /** | 160 /** |
| 259 * Returns an [Iterable] of static non final fields that need to be | 161 * Returns an [Iterable] of static non final fields that need to be |
| 260 * initialized. The fields list must be evaluated in order since they might | 162 * initialized. The fields list must be evaluated in order since they might |
| 261 * depend on each other. | 163 * depend on each other. |
| 262 */ | 164 */ |
| 263 Iterable<VariableElement> getStaticNonFinalFieldsForEmission() { | 165 Iterable<VariableElement> getStaticNonFinalFieldsForEmission() { |
| 264 return initialVariableValues.keys.where((element) { | 166 return initialVariableValues.keys.where((element) { |
| 265 return element.kind == ElementKind.FIELD | 167 return element.kind == ElementKind.FIELD |
| 266 && !element.isInstanceMember() | 168 && !element.isInstanceMember() |
| 267 && !element.modifiers.isFinal() | 169 && !element.modifiers.isFinal() |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 isEvaluatingConstant = oldIsEvaluatingConstant; | 253 isEvaluatingConstant = oldIsEvaluatingConstant; |
| 352 assert(result != null); | 254 assert(result != null); |
| 353 return result; | 255 return result; |
| 354 } | 256 } |
| 355 | 257 |
| 356 Constant visitNode(Node node) { | 258 Constant visitNode(Node node) { |
| 357 return signalNotCompileTimeConstant(node); | 259 return signalNotCompileTimeConstant(node); |
| 358 } | 260 } |
| 359 | 261 |
| 360 Constant visitLiteralBool(LiteralBool node) { | 262 Constant visitLiteralBool(LiteralBool node) { |
| 361 handler.registerInstantiatedType(compiler.boolClass.rawType, elements); | |
| 362 return constantSystem.createBool(node.value); | 263 return constantSystem.createBool(node.value); |
| 363 } | 264 } |
| 364 | 265 |
| 365 Constant visitLiteralDouble(LiteralDouble node) { | 266 Constant visitLiteralDouble(LiteralDouble node) { |
| 366 handler.registerInstantiatedType(compiler.doubleClass.rawType, elements); | |
| 367 return constantSystem.createDouble(node.value); | 267 return constantSystem.createDouble(node.value); |
| 368 } | 268 } |
| 369 | 269 |
| 370 Constant visitLiteralInt(LiteralInt node) { | 270 Constant visitLiteralInt(LiteralInt node) { |
| 371 handler.registerInstantiatedType(compiler.intClass.rawType, elements); | |
| 372 return constantSystem.createInt(node.value); | 271 return constantSystem.createInt(node.value); |
| 373 } | 272 } |
| 374 | 273 |
| 375 Constant visitLiteralList(LiteralList node) { | 274 Constant visitLiteralList(LiteralList node) { |
| 376 if (!node.isConst()) { | 275 if (!node.isConst()) { |
| 377 return signalNotCompileTimeConstant(node); | 276 return signalNotCompileTimeConstant(node); |
| 378 } | 277 } |
| 379 List<Constant> arguments = <Constant>[]; | 278 List<Constant> arguments = <Constant>[]; |
| 380 for (Link<Node> link = node.elements.nodes; | 279 for (Link<Node> link = node.elements.nodes; |
| 381 !link.isEmpty; | 280 !link.isEmpty; |
| 382 link = link.tail) { | 281 link = link.tail) { |
| 383 arguments.add(evaluateConstant(link.head)); | 282 arguments.add(evaluateConstant(link.head)); |
| 384 } | 283 } |
| 385 DartType type = elements.getType(node); | 284 DartType type = elements.getType(node); |
| 386 handler.registerInstantiatedType(type, elements); | 285 return new ListConstant(type, arguments); |
| 387 Constant constant = new ListConstant(type, arguments); | |
| 388 handler.registerCompileTimeConstant(constant, elements); | |
| 389 return constant; | |
| 390 } | 286 } |
| 391 | 287 |
| 392 Constant visitLiteralMap(LiteralMap node) { | 288 Constant visitLiteralMap(LiteralMap node) { |
| 393 if (!node.isConst()) { | 289 if (!node.isConst()) { |
| 394 return signalNotCompileTimeConstant(node); | 290 return signalNotCompileTimeConstant(node); |
| 395 } | 291 } |
| 396 List<Constant> keys = <Constant>[]; | 292 List<Constant> keys = <Constant>[]; |
| 397 Map<Constant, Constant> map = new Map<Constant, Constant>(); | 293 Map<Constant, Constant> map = new Map<Constant, Constant>(); |
| 398 for (Link<Node> link = node.entries.nodes; | 294 for (Link<Node> link = node.entries.nodes; |
| 399 !link.isEmpty; | 295 !link.isEmpty; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 424 InterfaceType sourceType = elements.getType(node); | 320 InterfaceType sourceType = elements.getType(node); |
| 425 DartType keysType; | 321 DartType keysType; |
| 426 if (sourceType.treatAsRaw) { | 322 if (sourceType.treatAsRaw) { |
| 427 keysType = compiler.listClass.rawType; | 323 keysType = compiler.listClass.rawType; |
| 428 } else { | 324 } else { |
| 429 Link<DartType> arguments = | 325 Link<DartType> arguments = |
| 430 new Link<DartType>.fromList([sourceType.typeArguments.head]); | 326 new Link<DartType>.fromList([sourceType.typeArguments.head]); |
| 431 keysType = new InterfaceType(compiler.listClass, arguments); | 327 keysType = new InterfaceType(compiler.listClass, arguments); |
| 432 } | 328 } |
| 433 ListConstant keysList = new ListConstant(keysType, keys); | 329 ListConstant keysList = new ListConstant(keysType, keys); |
| 434 if (onlyStringKeys) { | |
| 435 handler.registerCompileTimeConstant(keysList, elements); | |
| 436 } | |
| 437 SourceString className = onlyStringKeys | 330 SourceString className = onlyStringKeys |
| 438 ? (hasProtoKey ? MapConstant.DART_PROTO_CLASS | 331 ? (hasProtoKey ? MapConstant.DART_PROTO_CLASS |
| 439 : MapConstant.DART_STRING_CLASS) | 332 : MapConstant.DART_STRING_CLASS) |
| 440 : MapConstant.DART_GENERAL_CLASS; | 333 : MapConstant.DART_GENERAL_CLASS; |
| 441 ClassElement classElement = compiler.jsHelperLibrary.find(className); | 334 ClassElement classElement = compiler.jsHelperLibrary.find(className); |
| 442 classElement.ensureResolved(compiler); | 335 classElement.ensureResolved(compiler); |
| 443 Link<DartType> typeArgument = sourceType.typeArguments; | 336 Link<DartType> typeArgument = sourceType.typeArguments; |
| 444 InterfaceType type; | 337 InterfaceType type; |
| 445 if (sourceType.treatAsRaw) { | 338 if (sourceType.treatAsRaw) { |
| 446 type = classElement.rawType; | 339 type = classElement.rawType; |
| 447 } else { | 340 } else { |
| 448 type = new InterfaceType(classElement, typeArgument); | 341 type = new InterfaceType(classElement, typeArgument); |
| 449 } | 342 } |
| 450 Constant constant = | 343 return new MapConstant(type, keysList, values, protoValue, onlyStringKeys); |
| 451 new MapConstant(type, keysList, values, protoValue, onlyStringKeys); | |
| 452 handler.registerCompileTimeConstant(constant, elements); | |
| 453 return constant; | |
| 454 } | 344 } |
| 455 | 345 |
| 456 Constant visitLiteralNull(LiteralNull node) { | 346 Constant visitLiteralNull(LiteralNull node) { |
| 457 return constantSystem.createNull(); | 347 return constantSystem.createNull(); |
| 458 } | 348 } |
| 459 | 349 |
| 460 Constant visitLiteralString(LiteralString node) { | 350 Constant visitLiteralString(LiteralString node) { |
| 461 handler.registerStringInstance(elements); | |
| 462 return constantSystem.createString(node.dartString, node); | 351 return constantSystem.createString(node.dartString, node); |
| 463 } | 352 } |
| 464 | 353 |
| 465 Constant visitStringJuxtaposition(StringJuxtaposition node) { | 354 Constant visitStringJuxtaposition(StringJuxtaposition node) { |
| 466 StringConstant left = evaluate(node.first); | 355 StringConstant left = evaluate(node.first); |
| 467 StringConstant right = evaluate(node.second); | 356 StringConstant right = evaluate(node.second); |
| 468 if (left == null || right == null) return null; | 357 if (left == null || right == null) return null; |
| 469 handler.registerStringInstance(elements); | |
| 470 return constantSystem.createString( | 358 return constantSystem.createString( |
| 471 new DartString.concat(left.value, right.value), node); | 359 new DartString.concat(left.value, right.value), node); |
| 472 } | 360 } |
| 473 | 361 |
| 474 Constant visitStringInterpolation(StringInterpolation node) { | 362 Constant visitStringInterpolation(StringInterpolation node) { |
| 475 StringConstant initialString = evaluate(node.string); | 363 StringConstant initialString = evaluate(node.string); |
| 476 if (initialString == null) return null; | 364 if (initialString == null) return null; |
| 477 DartString accumulator = initialString.value; | 365 DartString accumulator = initialString.value; |
| 478 for (StringInterpolationPart part in node.parts) { | 366 for (StringInterpolationPart part in node.parts) { |
| 479 Constant expression = evaluate(part.expression); | 367 Constant expression = evaluate(part.expression); |
| 480 DartString expressionString; | 368 DartString expressionString; |
| 481 if (expression == null) { | 369 if (expression == null) { |
| 482 return signalNotCompileTimeConstant(part.expression); | 370 return signalNotCompileTimeConstant(part.expression); |
| 483 } else if (expression.isNum() || expression.isBool()) { | 371 } else if (expression.isNum() || expression.isBool()) { |
| 484 PrimitiveConstant primitive = expression; | 372 PrimitiveConstant primitive = expression; |
| 485 expressionString = new DartString.literal(primitive.value.toString()); | 373 expressionString = new DartString.literal(primitive.value.toString()); |
| 486 } else if (expression.isString()) { | 374 } else if (expression.isString()) { |
| 487 PrimitiveConstant primitive = expression; | 375 PrimitiveConstant primitive = expression; |
| 488 expressionString = primitive.value; | 376 expressionString = primitive.value; |
| 489 } else { | 377 } else { |
| 490 return signalNotCompileTimeConstant(part.expression); | 378 return signalNotCompileTimeConstant(part.expression); |
| 491 } | 379 } |
| 492 accumulator = new DartString.concat(accumulator, expressionString); | 380 accumulator = new DartString.concat(accumulator, expressionString); |
| 493 StringConstant partString = evaluate(part.string); | 381 StringConstant partString = evaluate(part.string); |
| 494 if (partString == null) return null; | 382 if (partString == null) return null; |
| 495 accumulator = new DartString.concat(accumulator, partString.value); | 383 accumulator = new DartString.concat(accumulator, partString.value); |
| 496 }; | 384 }; |
| 497 handler.registerStringInstance(elements); | |
| 498 return constantSystem.createString(accumulator, node); | 385 return constantSystem.createString(accumulator, node); |
| 499 } | 386 } |
| 500 | 387 |
| 501 Constant visitLiteralSymbol(LiteralSymbol node) { | 388 Constant visitLiteralSymbol(LiteralSymbol node) { |
| 502 handler.registerStringInstance(elements); | |
| 503 InterfaceType type = compiler.symbolClass.computeType(compiler); | 389 InterfaceType type = compiler.symbolClass.computeType(compiler); |
| 504 List<Constant> createArguments(_) { | 390 List<Constant> createArguments(_) { |
| 505 return [constantSystem.createString( | 391 return [constantSystem.createString( |
| 506 new DartString.literal(node.slowNameString), node)]; | 392 new DartString.literal(node.slowNameString), node)]; |
| 507 } | 393 } |
| 508 return makeConstructedConstant( | 394 return makeConstructedConstant( |
| 509 node, type, compiler.symbolConstructor, createArguments); | 395 node, type, compiler.symbolConstructor, createArguments); |
| 510 } | 396 } |
| 511 | 397 |
| 512 Constant makeTypeConstant(Element element) { | 398 Constant makeTypeConstant(Element element) { |
| 513 DartType elementType = element.computeType(compiler).asRaw(); | 399 DartType elementType = element.computeType(compiler).asRaw(); |
| 514 compiler.backend.registerTypeLiteral( | 400 compiler.backend.registerTypeLiteral( |
| 515 element, compiler.enqueuer.codegen, elements); | 401 element, compiler.enqueuer.codegen, elements); |
| 516 DartType constantType = | 402 DartType constantType = |
| 517 compiler.backend.typeImplementation.computeType(compiler); | 403 compiler.backend.typeImplementation.computeType(compiler); |
| 518 Constant constant = new TypeConstant(elementType, constantType); | 404 return new TypeConstant(elementType, constantType); |
| 519 // If we use a type literal in a constant, the compile time | |
| 520 // constant emitter will generate a call to the createRuntimeType | |
| 521 // helper so we register a use of that. | |
| 522 handler.registerCreateRuntimeTypeFunction(); | |
| 523 handler.registerCompileTimeConstant(constant, elements); | |
| 524 return constant; | |
| 525 } | 405 } |
| 526 | 406 |
| 527 // TODO(floitsch): provide better error-messages. | 407 // TODO(floitsch): provide better error-messages. |
| 528 Constant visitSend(Send send) { | 408 Constant visitSend(Send send) { |
| 529 Element element = elements[send]; | 409 Element element = elements[send]; |
| 530 if (send.isPropertyAccess) { | 410 if (send.isPropertyAccess) { |
| 531 if (Elements.isStaticOrTopLevelFunction(element)) { | 411 if (Elements.isStaticOrTopLevelFunction(element)) { |
| 532 Constant constant = new FunctionConstant(element); | 412 return new FunctionConstant(element); |
| 533 handler.registerCompileTimeConstant(constant, elements); | |
| 534 return constant; | |
| 535 } else if (Elements.isStaticOrTopLevelField(element)) { | 413 } else if (Elements.isStaticOrTopLevelField(element)) { |
| 536 Constant result; | 414 Constant result; |
| 537 if (element.modifiers.isConst()) { | 415 if (element.modifiers.isConst()) { |
| 538 result = handler.compileConstant(element); | 416 result = handler.compileConstant(element); |
| 539 } else if (element.modifiers.isFinal() && !isEvaluatingConstant) { | 417 } else if (element.modifiers.isFinal() && !isEvaluatingConstant) { |
| 540 result = handler.compileVariable(element); | 418 result = handler.compileVariable(element); |
| 541 } | 419 } |
| 542 if (result != null) return result; | 420 if (result != null) return result; |
| 543 } else if (Elements.isClass(element) || Elements.isTypedef(element)) { | 421 } else if (Elements.isClass(element) || Elements.isTypedef(element)) { |
| 544 return makeTypeConstant(element); | 422 return makeTypeConstant(element); |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 // initializers are handled correctly. | 624 // initializers are handled correctly. |
| 747 constructor = constructor.implementation; | 625 constructor = constructor.implementation; |
| 748 assert(invariant(node, constructor.isImplementation)); | 626 assert(invariant(node, constructor.isImplementation)); |
| 749 | 627 |
| 750 List<Constant> arguments = getArguments(constructor); | 628 List<Constant> arguments = getArguments(constructor); |
| 751 ConstructorEvaluator evaluator = | 629 ConstructorEvaluator evaluator = |
| 752 new ConstructorEvaluator(constructor, handler, compiler); | 630 new ConstructorEvaluator(constructor, handler, compiler); |
| 753 evaluator.evaluateConstructorFieldValues(arguments); | 631 evaluator.evaluateConstructorFieldValues(arguments); |
| 754 List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement); | 632 List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement); |
| 755 | 633 |
| 756 handler.registerInstantiatedType(type, elements); | 634 return new ConstructedConstant(type, jsNewArguments); |
| 757 Constant constant = new ConstructedConstant(type, jsNewArguments); | |
| 758 handler.registerCompileTimeConstant(constant, elements); | |
| 759 return constant; | |
| 760 } | 635 } |
| 761 | 636 |
| 762 Constant visitParenthesizedExpression(ParenthesizedExpression node) { | 637 Constant visitParenthesizedExpression(ParenthesizedExpression node) { |
| 763 return node.expression.accept(this); | 638 return node.expression.accept(this); |
| 764 } | 639 } |
| 765 | 640 |
| 766 error(Node node) { | 641 error(Node node) { |
| 767 // TODO(floitsch): get the list of constants that are currently compiled | 642 // TODO(floitsch): get the list of constants that are currently compiled |
| 768 // and present some kind of stack-trace. | 643 // and present some kind of stack-trace. |
| 769 compiler.reportFatalError( | 644 compiler.reportFatalError( |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 if (fieldValue == null) { | 852 if (fieldValue == null) { |
| 978 // Use the default value. | 853 // Use the default value. |
| 979 fieldValue = handler.compileConstant(field); | 854 fieldValue = handler.compileConstant(field); |
| 980 } | 855 } |
| 981 jsNewArguments.add(fieldValue); | 856 jsNewArguments.add(fieldValue); |
| 982 }, | 857 }, |
| 983 includeSuperAndInjectedMembers: true); | 858 includeSuperAndInjectedMembers: true); |
| 984 return jsNewArguments; | 859 return jsNewArguments; |
| 985 } | 860 } |
| 986 } | 861 } |
| OLD | NEW |