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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 /** | 77 /** |
78 * Returns the a compile-time constant if the variable could be compiled | 78 * Returns the a compile-time constant if the variable could be compiled |
79 * eagerly. Otherwise returns `null`. | 79 * eagerly. Otherwise returns `null`. |
80 */ | 80 */ |
81 Constant compileVariable(VariableElement element, {bool isConst: false}) { | 81 Constant compileVariable(VariableElement element, {bool isConst: false}) { |
82 return measure(() { | 82 return measure(() { |
83 if (initialVariableValues.containsKey(element)) { | 83 if (initialVariableValues.containsKey(element)) { |
84 Constant result = initialVariableValues[element]; | 84 Constant result = initialVariableValues[element]; |
85 return result; | 85 return result; |
86 } | 86 } |
87 TreeElements definitions = compiler.analyzeElement(element); | 87 return compiler.withCurrentElement(element, () { |
88 Constant constant = compileVariableWithDefinitions( | 88 TreeElements definitions = compiler.analyzeElement(element); |
89 element, definitions, isConst: isConst); | 89 Constant constant = compileVariableWithDefinitions( |
90 return constant; | 90 element, definitions, isConst: isConst); |
| 91 return constant; |
| 92 }); |
91 }); | 93 }); |
92 } | 94 } |
93 | 95 |
94 /** | 96 /** |
95 * Returns the a compile-time constant if the variable could be compiled | 97 * Returns the a compile-time constant if the variable could be compiled |
96 * eagerly. If the variable needs to be initialized lazily returns `null`. | 98 * eagerly. If the variable needs to be initialized lazily returns `null`. |
97 * If the variable is `const` but cannot be compiled eagerly reports an | 99 * If the variable is `const` but cannot be compiled eagerly reports an |
98 * error. | 100 * error. |
99 */ | 101 */ |
100 Constant compileVariableWithDefinitions(VariableElement element, | 102 Constant compileVariableWithDefinitions(VariableElement element, |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 return value; | 158 return value; |
157 }); | 159 }); |
158 } | 160 } |
159 | 161 |
160 Constant compileNodeWithDefinitions(Node node, | 162 Constant compileNodeWithDefinitions(Node node, |
161 TreeElements definitions, | 163 TreeElements definitions, |
162 {bool isConst: false}) { | 164 {bool isConst: false}) { |
163 return measure(() { | 165 return measure(() { |
164 assert(node != null); | 166 assert(node != null); |
165 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator( | 167 CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator( |
166 constantSystem, definitions, compiler, isConst: isConst); | 168 this, definitions, compiler, isConst: isConst); |
167 return evaluator.evaluate(node); | 169 return evaluator.evaluate(node); |
168 }); | 170 }); |
169 } | 171 } |
170 | 172 |
171 /** Attempts to compile a constant expression. Returns null if not possible */ | 173 /** Attempts to compile a constant expression. Returns null if not possible */ |
172 Constant tryCompileNodeWithDefinitions(Node node, TreeElements definitions) { | 174 Constant tryCompileNodeWithDefinitions(Node node, TreeElements definitions) { |
173 return measure(() { | 175 return measure(() { |
174 assert(node != null); | 176 assert(node != null); |
175 try { | 177 try { |
176 TryCompileTimeConstantEvaluator evaluator = | 178 TryCompileTimeConstantEvaluator evaluator = |
177 new TryCompileTimeConstantEvaluator(constantSystem, | 179 new TryCompileTimeConstantEvaluator(this, definitions, compiler); |
178 definitions, | |
179 compiler); | |
180 return evaluator.evaluate(node); | 180 return evaluator.evaluate(node); |
181 } on CompileTimeConstantError catch (exn) { | 181 } on CompileTimeConstantError catch (exn) { |
182 return null; | 182 return null; |
183 } | 183 } |
184 }); | 184 }); |
185 } | 185 } |
186 | 186 |
187 /** | 187 /** |
188 * Returns a [List] of static non final fields that need to be initialized. | 188 * Returns a [List] of static non final fields that need to be initialized. |
189 * The list must be evaluated in order since the fields might depend on each | 189 * The list must be evaluated in order since the fields might depend on each |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 if (initialValue == null) { | 237 if (initialValue == null) { |
238 compiler.internalError("No initial value for given element", | 238 compiler.internalError("No initial value for given element", |
239 element: element); | 239 element: element); |
240 } | 240 } |
241 return initialValue; | 241 return initialValue; |
242 } | 242 } |
243 } | 243 } |
244 | 244 |
245 class CompileTimeConstantEvaluator extends Visitor { | 245 class CompileTimeConstantEvaluator extends Visitor { |
246 bool isEvaluatingConstant; | 246 bool isEvaluatingConstant; |
247 final ConstantSystem constantSystem; | 247 final ConstantHandler handler; |
248 final TreeElements elements; | 248 final TreeElements elements; |
249 final Compiler compiler; | 249 final Compiler compiler; |
250 bool enabledRuntimeTypeSupport = false; | 250 bool enabledRuntimeTypeSupport = false; |
251 | 251 |
252 CompileTimeConstantEvaluator(this.constantSystem, | 252 CompileTimeConstantEvaluator(this.handler, |
253 this.elements, | 253 this.elements, |
254 this.compiler, | 254 this.compiler, |
255 {bool isConst: false}) | 255 {bool isConst: false}) |
256 : this.isEvaluatingConstant = isConst; | 256 : this.isEvaluatingConstant = isConst; |
257 | 257 |
| 258 ConstantSystem get constantSystem => handler.constantSystem; |
| 259 |
258 Constant evaluate(Node node) { | 260 Constant evaluate(Node node) { |
259 return node.accept(this); | 261 return node.accept(this); |
260 } | 262 } |
261 | 263 |
262 Constant evaluateConstant(Node node) { | 264 Constant evaluateConstant(Node node) { |
263 bool oldIsEvaluatingConstant = isEvaluatingConstant; | 265 bool oldIsEvaluatingConstant = isEvaluatingConstant; |
264 isEvaluatingConstant = true; | 266 isEvaluatingConstant = true; |
265 Constant result = node.accept(this); | 267 Constant result = node.accept(this); |
266 isEvaluatingConstant = oldIsEvaluatingConstant; | 268 isEvaluatingConstant = oldIsEvaluatingConstant; |
267 assert(result != null); | 269 assert(result != null); |
(...skipping 22 matching lines...) Expand all Loading... |
290 } | 292 } |
291 List<Constant> arguments = <Constant>[]; | 293 List<Constant> arguments = <Constant>[]; |
292 for (Link<Node> link = node.elements.nodes; | 294 for (Link<Node> link = node.elements.nodes; |
293 !link.isEmpty; | 295 !link.isEmpty; |
294 link = link.tail) { | 296 link = link.tail) { |
295 arguments.add(evaluateConstant(link.head)); | 297 arguments.add(evaluateConstant(link.head)); |
296 } | 298 } |
297 // TODO(floitsch): get type parameters. | 299 // TODO(floitsch): get type parameters. |
298 DartType type = new InterfaceType(compiler.listClass); | 300 DartType type = new InterfaceType(compiler.listClass); |
299 Constant constant = new ListConstant(type, arguments); | 301 Constant constant = new ListConstant(type, arguments); |
300 compiler.constantHandler.registerCompileTimeConstant(constant); | 302 handler.registerCompileTimeConstant(constant); |
301 return constant; | 303 return constant; |
302 } | 304 } |
303 | 305 |
304 Constant visitLiteralMap(LiteralMap node) { | 306 Constant visitLiteralMap(LiteralMap node) { |
305 if (!node.isConst()) { | 307 if (!node.isConst()) { |
306 return signalNotCompileTimeConstant(node); | 308 return signalNotCompileTimeConstant(node); |
307 } | 309 } |
308 List<StringConstant> keys = <StringConstant>[]; | 310 List<StringConstant> keys = <StringConstant>[]; |
309 Map<StringConstant, Constant> map = new Map<StringConstant, Constant>(); | 311 Map<StringConstant, Constant> map = new Map<StringConstant, Constant>(); |
310 for (Link<Node> link = node.entries.nodes; | 312 for (Link<Node> link = node.entries.nodes; |
(...skipping 15 matching lines...) Expand all Loading... |
326 if (key.value == MapConstant.PROTO_PROPERTY) { | 328 if (key.value == MapConstant.PROTO_PROPERTY) { |
327 protoValue = map[key]; | 329 protoValue = map[key]; |
328 } else { | 330 } else { |
329 values.add(map[key]); | 331 values.add(map[key]); |
330 } | 332 } |
331 } | 333 } |
332 bool hasProtoKey = (protoValue != null); | 334 bool hasProtoKey = (protoValue != null); |
333 // TODO(floitsch): this should be a List<String> type. | 335 // TODO(floitsch): this should be a List<String> type. |
334 DartType keysType = new InterfaceType(compiler.listClass); | 336 DartType keysType = new InterfaceType(compiler.listClass); |
335 ListConstant keysList = new ListConstant(keysType, keys); | 337 ListConstant keysList = new ListConstant(keysType, keys); |
336 compiler.constantHandler.registerCompileTimeConstant(keysList); | 338 handler.registerCompileTimeConstant(keysList); |
337 SourceString className = hasProtoKey | 339 SourceString className = hasProtoKey |
338 ? MapConstant.DART_PROTO_CLASS | 340 ? MapConstant.DART_PROTO_CLASS |
339 : MapConstant.DART_CLASS; | 341 : MapConstant.DART_CLASS; |
340 ClassElement classElement = compiler.jsHelperLibrary.find(className); | 342 ClassElement classElement = compiler.jsHelperLibrary.find(className); |
341 classElement.ensureResolved(compiler); | 343 classElement.ensureResolved(compiler); |
342 // TODO(floitsch): copy over the generic type. | 344 // TODO(floitsch): copy over the generic type. |
343 DartType type = new InterfaceType(classElement); | 345 DartType type = new InterfaceType(classElement); |
344 registerInstantiatedClass(classElement); | 346 registerInstantiatedClass(classElement); |
345 Constant constant = new MapConstant(type, keysList, values, protoValue); | 347 Constant constant = new MapConstant(type, keysList, values, protoValue); |
346 compiler.constantHandler.registerCompileTimeConstant(constant); | 348 handler.registerCompileTimeConstant(constant); |
347 return constant; | 349 return constant; |
348 } | 350 } |
349 | 351 |
350 Constant visitLiteralNull(LiteralNull node) { | 352 Constant visitLiteralNull(LiteralNull node) { |
351 return constantSystem.createNull(); | 353 return constantSystem.createNull(); |
352 } | 354 } |
353 | 355 |
354 void registerInstantiatedClass(ClassElement element) { | 356 void registerInstantiatedClass(ClassElement element) { |
355 compiler.enqueuer.codegen.registerInstantiatedClass(element); | 357 compiler.enqueuer.codegen.registerInstantiatedClass(element); |
356 } | 358 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 SourceString helperName = const SourceString('createRuntimeType'); | 410 SourceString helperName = const SourceString('createRuntimeType'); |
409 Element helper = compiler.findHelper(helperName); | 411 Element helper = compiler.findHelper(helperName); |
410 compiler.enqueuer.resolution.addToWorkList(helper); | 412 compiler.enqueuer.resolution.addToWorkList(helper); |
411 compiler.enqueuer.codegen.addToWorkList(helper); | 413 compiler.enqueuer.codegen.addToWorkList(helper); |
412 enabledRuntimeTypeSupport = true; | 414 enabledRuntimeTypeSupport = true; |
413 } | 415 } |
414 | 416 |
415 DartType elementType = element.computeType(compiler).asRaw(); | 417 DartType elementType = element.computeType(compiler).asRaw(); |
416 DartType constantType = compiler.typeClass.computeType(compiler); | 418 DartType constantType = compiler.typeClass.computeType(compiler); |
417 Constant constant = new TypeConstant(elementType, constantType); | 419 Constant constant = new TypeConstant(elementType, constantType); |
418 compiler.constantHandler.registerCompileTimeConstant(constant); | 420 handler.registerCompileTimeConstant(constant); |
419 return constant; | 421 return constant; |
420 } | 422 } |
421 | 423 |
422 // TODO(floitsch): provide better error-messages. | 424 // TODO(floitsch): provide better error-messages. |
423 Constant visitSend(Send send) { | 425 Constant visitSend(Send send) { |
424 Element element = elements[send]; | 426 Element element = elements[send]; |
425 if (send.isPropertyAccess) { | 427 if (send.isPropertyAccess) { |
426 if (Elements.isStaticOrTopLevelFunction(element)) { | 428 if (Elements.isStaticOrTopLevelFunction(element)) { |
427 compiler.codegenWorld.staticFunctionsNeedingGetter.add(element); | 429 compiler.codegenWorld.staticFunctionsNeedingGetter.add(element); |
428 Constant constant = new FunctionConstant(element); | 430 Constant constant = new FunctionConstant(element); |
429 compiler.constantHandler.registerCompileTimeConstant(constant); | 431 handler.registerCompileTimeConstant(constant); |
430 compiler.enqueuer.codegen.registerStaticUse(element); | 432 compiler.enqueuer.codegen.registerStaticUse(element); |
431 return constant; | 433 return constant; |
432 } else if (Elements.isStaticOrTopLevelField(element)) { | 434 } else if (Elements.isStaticOrTopLevelField(element)) { |
433 Constant result; | 435 Constant result; |
434 if (element.modifiers.isConst()) { | 436 if (element.modifiers.isConst()) { |
435 result = compiler.compileConstant(element); | 437 result = handler.compileConstant(element); |
436 } else if (element.modifiers.isFinal() && !isEvaluatingConstant) { | 438 } else if (element.modifiers.isFinal() && !isEvaluatingConstant) { |
437 result = compiler.compileVariable(element); | 439 result = handler.compileVariable(element); |
438 } | 440 } |
439 if (result != null) return result; | 441 if (result != null) return result; |
440 } else if (Elements.isClass(element) || Elements.isTypedef(element)) { | 442 } else if (Elements.isClass(element) || Elements.isTypedef(element)) { |
441 return makeTypeConstant(element); | 443 return makeTypeConstant(element); |
442 } | 444 } |
443 return signalNotCompileTimeConstant(send); | 445 return signalNotCompileTimeConstant(send); |
444 } else if (send.isCall) { | 446 } else if (send.isCall) { |
445 if (identical(element, compiler.identicalFunction) | 447 if (identical(element, compiler.identicalFunction) |
446 && send.argumentCount() == 2) { | 448 && send.argumentCount() == 2) { |
447 Constant left = evaluate(send.argumentsNode.nodes.head); | 449 Constant left = evaluate(send.argumentsNode.nodes.head); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 * Invariant: [target] must be an implementation element. | 579 * Invariant: [target] must be an implementation element. |
578 */ | 580 */ |
579 List<Constant> evaluateArgumentsToConstructor(Node node, | 581 List<Constant> evaluateArgumentsToConstructor(Node node, |
580 Selector selector, | 582 Selector selector, |
581 Link<Node> arguments, | 583 Link<Node> arguments, |
582 FunctionElement target) { | 584 FunctionElement target) { |
583 assert(invariant(node, target.isImplementation)); | 585 assert(invariant(node, target.isImplementation)); |
584 List<Constant> compiledArguments = <Constant>[]; | 586 List<Constant> compiledArguments = <Constant>[]; |
585 | 587 |
586 Function compileArgument = evaluateConstant; | 588 Function compileArgument = evaluateConstant; |
587 Function compileConstant = compiler.compileConstant; | 589 Function compileConstant = handler.compileConstant; |
588 bool succeeded = selector.addArgumentsToList(arguments, | 590 bool succeeded = selector.addArgumentsToList(arguments, |
589 compiledArguments, | 591 compiledArguments, |
590 target, | 592 target, |
591 compileArgument, | 593 compileArgument, |
592 compileConstant, | 594 compileConstant, |
593 compiler); | 595 compiler); |
594 if (!succeeded) { | 596 if (!succeeded) { |
595 MessageKind kind = MessageKind.INVALID_ARGUMENTS; | 597 MessageKind kind = MessageKind.INVALID_ARGUMENTS; |
596 compiler.reportError(node, | 598 compiler.reportError(node, |
597 new CompileTimeConstantError(kind, [target.name.slowToString()])); | 599 new CompileTimeConstantError(kind, [target.name.slowToString()])); |
(...skipping 17 matching lines...) Expand all Loading... |
615 } | 617 } |
616 // The constructor must be an implementation to ensure that field | 618 // The constructor must be an implementation to ensure that field |
617 // initializers are handled correctly. | 619 // initializers are handled correctly. |
618 constructor = constructor.implementation; | 620 constructor = constructor.implementation; |
619 assert(invariant(node, constructor.isImplementation)); | 621 assert(invariant(node, constructor.isImplementation)); |
620 | 622 |
621 Selector selector = elements.getSelector(send); | 623 Selector selector = elements.getSelector(send); |
622 List<Constant> arguments = evaluateArgumentsToConstructor( | 624 List<Constant> arguments = evaluateArgumentsToConstructor( |
623 node, selector, send.arguments, constructor); | 625 node, selector, send.arguments, constructor); |
624 ConstructorEvaluator evaluator = | 626 ConstructorEvaluator evaluator = |
625 new ConstructorEvaluator(node, constructor, constantSystem, compiler); | 627 new ConstructorEvaluator(node, constructor, handler, compiler); |
626 evaluator.evaluateConstructorFieldValues(arguments); | 628 evaluator.evaluateConstructorFieldValues(arguments); |
627 List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement); | 629 List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement); |
628 | 630 |
629 compiler.enqueuer.codegen.registerInstantiatedClass(classElement); | 631 compiler.enqueuer.codegen.registerInstantiatedClass(classElement); |
630 // TODO(floitsch): take generic types into account. | 632 // TODO(floitsch): take generic types into account. |
631 DartType type = classElement.computeType(compiler); | 633 DartType type = classElement.computeType(compiler); |
632 Constant constant = new ConstructedConstant(type, jsNewArguments); | 634 Constant constant = new ConstructedConstant(type, jsNewArguments); |
633 compiler.constantHandler.registerCompileTimeConstant(constant); | 635 handler.registerCompileTimeConstant(constant); |
634 return constant; | 636 return constant; |
635 } | 637 } |
636 | 638 |
637 Constant visitParenthesizedExpression(ParenthesizedExpression node) { | 639 Constant visitParenthesizedExpression(ParenthesizedExpression node) { |
638 return node.expression.accept(this); | 640 return node.expression.accept(this); |
639 } | 641 } |
640 | 642 |
641 error(Node node) { | 643 error(Node node) { |
642 // TODO(floitsch): get the list of constants that are currently compiled | 644 // TODO(floitsch): get the list of constants that are currently compiled |
643 // and present some kind of stack-trace. | 645 // and present some kind of stack-trace. |
644 MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT; | 646 MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT; |
645 compiler.reportError(node, new CompileTimeConstantError(kind, const [])); | 647 compiler.reportError(node, new CompileTimeConstantError(kind, const [])); |
646 } | 648 } |
647 | 649 |
648 Constant signalNotCompileTimeConstant(Node node) { | 650 Constant signalNotCompileTimeConstant(Node node) { |
649 if (isEvaluatingConstant) { | 651 if (isEvaluatingConstant) { |
650 error(node); | 652 error(node); |
651 } | 653 } |
652 // Else we don't need to do anything. The final handler is only | 654 // Else we don't need to do anything. The final handler is only |
653 // optimistically trying to compile constants. So it is normal that we | 655 // optimistically trying to compile constants. So it is normal that we |
654 // sometimes see non-compile time constants. | 656 // sometimes see non-compile time constants. |
655 // Simply return [:null:] which is used to propagate a failing | 657 // Simply return [:null:] which is used to propagate a failing |
656 // compile-time compilation. | 658 // compile-time compilation. |
657 return null; | 659 return null; |
658 } | 660 } |
659 } | 661 } |
660 | 662 |
661 class TryCompileTimeConstantEvaluator extends CompileTimeConstantEvaluator { | 663 class TryCompileTimeConstantEvaluator extends CompileTimeConstantEvaluator { |
662 TryCompileTimeConstantEvaluator(ConstantSystem constantSystem, | 664 TryCompileTimeConstantEvaluator(ConstantHandler handler, |
663 TreeElements elements, | 665 TreeElements elements, |
664 Compiler compiler) | 666 Compiler compiler) |
665 : super(constantSystem, elements, compiler, isConst: true); | 667 : super(handler, elements, compiler, isConst: true); |
666 | 668 |
667 error(Node node) { | 669 error(Node node) { |
668 // Just fail without reporting it anywhere. | 670 // Just fail without reporting it anywhere. |
669 throw new CompileTimeConstantError( | 671 throw new CompileTimeConstantError( |
670 MessageKind.NOT_A_COMPILE_TIME_CONSTANT, const []); | 672 MessageKind.NOT_A_COMPILE_TIME_CONSTANT, const []); |
671 } | 673 } |
672 } | 674 } |
673 | 675 |
674 class ConstructorEvaluator extends CompileTimeConstantEvaluator { | 676 class ConstructorEvaluator extends CompileTimeConstantEvaluator { |
675 final FunctionElement constructor; | 677 final FunctionElement constructor; |
676 final Map<Element, Constant> definitions; | 678 final Map<Element, Constant> definitions; |
677 final Map<Element, Constant> fieldValues; | 679 final Map<Element, Constant> fieldValues; |
678 | 680 |
679 /** | 681 /** |
680 * Documentation wanted -- johnniwinther | 682 * Documentation wanted -- johnniwinther |
681 * | 683 * |
682 * Invariant: [constructor] must be an implementation element. | 684 * Invariant: [constructor] must be an implementation element. |
683 */ | 685 */ |
684 ConstructorEvaluator(Node node, | 686 ConstructorEvaluator(Node node, |
685 FunctionElement constructor, | 687 FunctionElement constructor, |
686 ConstantSystem constantSystem, | 688 ConstantHandler handler, |
687 Compiler compiler) | 689 Compiler compiler) |
688 : this.constructor = constructor, | 690 : this.constructor = constructor, |
689 this.definitions = new Map<Element, Constant>(), | 691 this.definitions = new Map<Element, Constant>(), |
690 this.fieldValues = new Map<Element, Constant>(), | 692 this.fieldValues = new Map<Element, Constant>(), |
691 super(constantSystem, | 693 super(handler, |
692 compiler.resolver.resolveMethodElement(constructor.declaration), | 694 compiler.resolver.resolveMethodElement(constructor.declaration), |
693 compiler, | 695 compiler, |
694 isConst: true) { | 696 isConst: true) { |
695 assert(invariant(node, constructor.isImplementation)); | 697 assert(invariant(node, constructor.isImplementation)); |
696 } | 698 } |
697 | 699 |
698 Constant visitSend(Send send) { | 700 Constant visitSend(Send send) { |
699 Element element = elements[send]; | 701 Element element = elements[send]; |
700 if (Elements.isLocal(element)) { | 702 if (Elements.isLocal(element)) { |
701 Constant constant = definitions[element]; | 703 Constant constant = definitions[element]; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
748 } | 750 } |
749 | 751 |
750 void evaluateSuperOrRedirectSend(Node currentNode, | 752 void evaluateSuperOrRedirectSend(Node currentNode, |
751 Selector selector, | 753 Selector selector, |
752 Link<Node> arguments, | 754 Link<Node> arguments, |
753 FunctionElement targetConstructor) { | 755 FunctionElement targetConstructor) { |
754 List<Constant> compiledArguments = evaluateArgumentsToConstructor( | 756 List<Constant> compiledArguments = evaluateArgumentsToConstructor( |
755 currentNode, selector, arguments, targetConstructor); | 757 currentNode, selector, arguments, targetConstructor); |
756 | 758 |
757 ConstructorEvaluator evaluator = new ConstructorEvaluator( | 759 ConstructorEvaluator evaluator = new ConstructorEvaluator( |
758 currentNode, targetConstructor, constantSystem, compiler); | 760 currentNode, targetConstructor, handler, compiler); |
759 evaluator.evaluateConstructorFieldValues(compiledArguments); | 761 evaluator.evaluateConstructorFieldValues(compiledArguments); |
760 // Copy over the fieldValues from the super/redirect-constructor. | 762 // Copy over the fieldValues from the super/redirect-constructor. |
761 // No need to go through [updateFieldValue] because the | 763 // No need to go through [updateFieldValue] because the |
762 // assignments have already been checked in checked mode. | 764 // assignments have already been checked in checked mode. |
763 evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value); | 765 evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value); |
764 } | 766 } |
765 | 767 |
766 /** | 768 /** |
767 * Runs through the initializers of the given [constructor] and updates | 769 * Runs through the initializers of the given [constructor] and updates |
768 * the [fieldValues] map. | 770 * the [fieldValues] map. |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 }); | 839 }); |
838 } | 840 } |
839 | 841 |
840 List<Constant> buildJsNewArguments(ClassElement classElement) { | 842 List<Constant> buildJsNewArguments(ClassElement classElement) { |
841 List<Constant> jsNewArguments = <Constant>[]; | 843 List<Constant> jsNewArguments = <Constant>[]; |
842 classElement.implementation.forEachInstanceField( | 844 classElement.implementation.forEachInstanceField( |
843 (ClassElement enclosing, Element field) { | 845 (ClassElement enclosing, Element field) { |
844 Constant fieldValue = fieldValues[field]; | 846 Constant fieldValue = fieldValues[field]; |
845 if (fieldValue == null) { | 847 if (fieldValue == null) { |
846 // Use the default value. | 848 // Use the default value. |
847 fieldValue = compiler.compileConstant(field); | 849 fieldValue = handler.compileConstant(field); |
848 } | 850 } |
849 jsNewArguments.add(fieldValue); | 851 jsNewArguments.add(fieldValue); |
850 }, | 852 }, |
851 includeBackendMembers: true, | 853 includeBackendMembers: true, |
852 includeSuperMembers: true); | 854 includeSuperMembers: true); |
853 return jsNewArguments; | 855 return jsNewArguments; |
854 } | 856 } |
855 } | 857 } |
OLD | NEW |