Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library dart2js.ir_builder; | 5 library dart2js.ir_builder; |
| 6 | 6 |
| 7 import '../closure.dart' hide ClosureScope; | 7 import '../closure.dart' hide ClosureScope; |
| 8 import '../common.dart'; | 8 import '../common.dart'; |
| 9 import '../common/names.dart' show | 9 import '../common/names.dart' show |
| 10 Names, | 10 Names, |
| (...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 661 return v; | 661 return v; |
| 662 } | 662 } |
| 663 | 663 |
| 664 ir.Primitive _buildInvokeStatic(Element element, | 664 ir.Primitive _buildInvokeStatic(Element element, |
| 665 Selector selector, | 665 Selector selector, |
| 666 List<ir.Primitive> arguments, | 666 List<ir.Primitive> arguments, |
| 667 SourceInformation sourceInformation) { | 667 SourceInformation sourceInformation) { |
| 668 assert(!element.isLocal); | 668 assert(!element.isLocal); |
| 669 assert(!element.isInstanceMember); | 669 assert(!element.isInstanceMember); |
| 670 assert(isOpen); | 670 assert(isOpen); |
| 671 return _continueWithExpression( | 671 return addPrimitive( |
| 672 (k) => new ir.InvokeStatic(element, selector, arguments, k, | 672 new ir.InvokeStatic(element, selector, arguments, sourceInformation)); |
| 673 sourceInformation)); | |
| 674 } | 673 } |
| 675 | 674 |
| 676 ir.Primitive _buildInvokeSuper(Element target, | 675 ir.Primitive _buildInvokeSuper(Element target, |
| 677 Selector selector, | 676 Selector selector, |
| 678 List<ir.Primitive> arguments, | 677 List<ir.Primitive> arguments, |
| 679 SourceInformation sourceInformation) { | 678 SourceInformation sourceInformation) { |
| 680 assert(target.isInstanceMember); | 679 assert(target.isInstanceMember); |
| 681 assert(isOpen); | 680 assert(isOpen); |
| 682 return _continueWithExpression( | 681 return addPrimitive(new ir.InvokeMethodDirectly( |
| 683 (k) => new ir.InvokeMethodDirectly( | 682 buildThis(), target, selector, arguments, sourceInformation)); |
| 684 buildThis(), target, selector, arguments, k, sourceInformation)); | |
| 685 } | 683 } |
| 686 | 684 |
| 687 ir.Primitive _buildInvokeDynamic(ir.Primitive receiver, | 685 ir.Primitive _buildInvokeDynamic(ir.Primitive receiver, |
| 688 Selector selector, | 686 Selector selector, |
| 689 TypeMask mask, | 687 TypeMask mask, |
| 690 List<ir.Primitive> arguments, | 688 List<ir.Primitive> arguments, |
| 691 SourceInformation sourceInformation) { | 689 SourceInformation sourceInformation) { |
| 692 assert(isOpen); | 690 assert(isOpen); |
| 693 return _continueWithExpression( | 691 return addPrimitive(new ir.InvokeMethod( |
| 694 (k) => new ir.InvokeMethod(receiver, selector, mask, arguments, k, | 692 receiver, selector, mask, arguments, sourceInformation)); |
| 695 sourceInformation)); | |
| 696 } | 693 } |
| 697 | 694 |
| 698 ir.Primitive _buildInvokeCall(ir.Primitive target, | 695 ir.Primitive _buildInvokeCall(ir.Primitive target, |
| 699 CallStructure callStructure, | 696 CallStructure callStructure, |
| 700 TypeMask mask, | 697 TypeMask mask, |
| 701 List<ir.Definition> arguments, | 698 List<ir.Definition> arguments, |
| 702 {SourceInformation sourceInformation}) { | 699 {SourceInformation sourceInformation}) { |
| 703 Selector selector = callStructure.callSelector; | 700 Selector selector = callStructure.callSelector; |
| 704 return _buildInvokeDynamic( | 701 return _buildInvokeDynamic( |
| 705 target, selector, mask, arguments, sourceInformation); | 702 target, selector, mask, arguments, sourceInformation); |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1040 /// Create a read access of the static [field]. | 1037 /// Create a read access of the static [field]. |
| 1041 ir.Primitive buildStaticFieldGet(FieldElement field, | 1038 ir.Primitive buildStaticFieldGet(FieldElement field, |
| 1042 SourceInformation sourceInformation) { | 1039 SourceInformation sourceInformation) { |
| 1043 return addPrimitive(new ir.GetStatic(field, sourceInformation)); | 1040 return addPrimitive(new ir.GetStatic(field, sourceInformation)); |
| 1044 } | 1041 } |
| 1045 | 1042 |
| 1046 /// Create a read access of a static [field] that might not have been | 1043 /// Create a read access of a static [field] that might not have been |
| 1047 /// initialized yet. | 1044 /// initialized yet. |
| 1048 ir.Primitive buildStaticFieldLazyGet(FieldElement field, | 1045 ir.Primitive buildStaticFieldLazyGet(FieldElement field, |
| 1049 SourceInformation sourceInformation) { | 1046 SourceInformation sourceInformation) { |
| 1050 return _continueWithExpression( | 1047 return addPrimitive(new ir.GetLazyStatic(field, sourceInformation)); |
| 1051 (k) => new ir.GetLazyStatic(field, k, sourceInformation)); | |
| 1052 } | 1048 } |
| 1053 | 1049 |
| 1054 /// Create a getter invocation of the static [getter]. | 1050 /// Create a getter invocation of the static [getter]. |
| 1055 ir.Primitive buildStaticGetterGet(MethodElement getter, | 1051 ir.Primitive buildStaticGetterGet(MethodElement getter, |
| 1056 SourceInformation sourceInformation) { | 1052 SourceInformation sourceInformation) { |
| 1057 Selector selector = new Selector.getter(getter.memberName); | 1053 Selector selector = new Selector.getter(getter.memberName); |
| 1058 return _buildInvokeStatic( | 1054 return _buildInvokeStatic( |
| 1059 getter, selector, const <ir.Primitive>[], sourceInformation); | 1055 getter, selector, const <ir.Primitive>[], sourceInformation); |
| 1060 } | 1056 } |
| 1061 | 1057 |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1386 // s; | 1382 // s; |
| 1387 // } | 1383 // } |
| 1388 | 1384 |
| 1389 // Fill the current hole with: | 1385 // Fill the current hole with: |
| 1390 // let prim expressionReceiver = [[e]] in | 1386 // let prim expressionReceiver = [[e]] in |
| 1391 // let cont iteratorInvoked(iterator) = | 1387 // let cont iteratorInvoked(iterator) = |
| 1392 // [ ] | 1388 // [ ] |
| 1393 // in expressionReceiver.iterator () iteratorInvoked | 1389 // in expressionReceiver.iterator () iteratorInvoked |
| 1394 ir.Primitive expressionReceiver = buildExpression(this); | 1390 ir.Primitive expressionReceiver = buildExpression(this); |
| 1395 List<ir.Primitive> emptyArguments = <ir.Primitive>[]; | 1391 List<ir.Primitive> emptyArguments = <ir.Primitive>[]; |
| 1396 ir.Parameter iterator = new ir.Parameter(null); | 1392 ir.Primitive iterator = addPrimitive( |
| 1397 ir.Continuation iteratorInvoked = new ir.Continuation([iterator]); | |
| 1398 add(new ir.LetCont(iteratorInvoked, | |
| 1399 new ir.InvokeMethod(expressionReceiver, | 1393 new ir.InvokeMethod(expressionReceiver, |
| 1400 Selectors.iterator, | 1394 Selectors.iterator, |
| 1401 iteratorMask, | 1395 iteratorMask, |
| 1402 emptyArguments, | 1396 emptyArguments)); |
| 1403 iteratorInvoked))); | |
| 1404 | 1397 |
| 1405 // Fill with: | 1398 // Fill with: |
| 1406 // let cont loop(x, ...) = | 1399 // let cont loop(x, ...) = |
| 1407 // let cont moveNextInvoked(condition) = | 1400 // let cont moveNextInvoked(condition) = |
| 1408 // [ ] | 1401 // [ ] |
| 1409 // in iterator.moveNext () moveNextInvoked | 1402 // in iterator.moveNext () moveNextInvoked |
| 1410 // in loop(v, ...) | 1403 // in loop(v, ...) |
| 1411 JumpCollector loop = new BackwardJumpCollector(environment, target: target); | 1404 JumpCollector loop = new BackwardJumpCollector(environment, target: target); |
| 1412 addRecursiveContinuation(loop); | 1405 addRecursiveContinuation(loop); |
| 1413 ir.Parameter condition = new ir.Parameter(null); | 1406 ir.Primitive condition = addPrimitive( |
| 1414 ir.Continuation moveNextInvoked = new ir.Continuation([condition]); | |
| 1415 add(new ir.LetCont(moveNextInvoked, | |
| 1416 new ir.InvokeMethod(iterator, | 1407 new ir.InvokeMethod(iterator, |
| 1417 Selectors.moveNext, | 1408 Selectors.moveNext, |
| 1418 moveNextMask, | 1409 moveNextMask, |
| 1419 emptyArguments, | 1410 emptyArguments)); |
| 1420 moveNextInvoked))); | |
| 1421 | 1411 |
| 1422 // As a delimited term, build: | 1412 // As a delimited term, build: |
| 1423 // <<BODY>> = | 1413 // <<BODY>> = |
| 1424 // _enterScope(); | 1414 // _enterScope(); |
| 1425 // [[variableDeclaration]] | 1415 // [[variableDeclaration]] |
| 1426 // let cont currentInvoked(currentValue) = | 1416 // let cont currentInvoked(currentValue) = |
| 1427 // [[a = currentValue]]; | 1417 // [[a = currentValue]]; |
| 1428 // [ ] | 1418 // [ ] |
| 1429 // in iterator.current () currentInvoked | 1419 // in iterator.current () currentInvoked |
| 1430 IrBuilder bodyBuilder = makeDelimitedBuilder(); | 1420 IrBuilder bodyBuilder = makeDelimitedBuilder(); |
| 1431 bodyBuilder._enterScope(closureScope); | 1421 bodyBuilder._enterScope(closureScope); |
| 1432 if (buildVariableDeclaration != null) { | 1422 if (buildVariableDeclaration != null) { |
| 1433 buildVariableDeclaration(bodyBuilder); | 1423 buildVariableDeclaration(bodyBuilder); |
| 1434 } | 1424 } |
| 1435 ir.Parameter currentValue = new ir.Parameter(null); | 1425 ir.Primitive currentValue = bodyBuilder.addPrimitive( |
| 1436 ir.Continuation currentInvoked = new ir.Continuation([currentValue]); | |
| 1437 bodyBuilder.add(new ir.LetCont(currentInvoked, | |
| 1438 new ir.InvokeMethod( | 1426 new ir.InvokeMethod( |
| 1439 iterator, | 1427 iterator, |
| 1440 Selectors.current, | 1428 Selectors.current, |
| 1441 currentMask, | 1429 currentMask, |
| 1442 emptyArguments, currentInvoked))); | 1430 emptyArguments)); |
| 1443 // TODO(sra): Does this cover all cases? The general setter case include | 1431 // TODO(sra): Does this cover all cases? The general setter case include |
| 1444 // super. | 1432 // super. |
| 1445 // TODO(johnniwinther): Extract this as a provided strategy. | 1433 // TODO(johnniwinther): Extract this as a provided strategy. |
| 1446 if (Elements.isLocal(variableElement)) { | 1434 if (Elements.isLocal(variableElement)) { |
| 1447 bodyBuilder.buildLocalVariableSet(variableElement, currentValue); | 1435 bodyBuilder.buildLocalVariableSet(variableElement, currentValue); |
| 1448 } else if (Elements.isMalformed(variableElement)) { | 1436 } else if (Elements.isMalformed(variableElement)) { |
| 1449 bodyBuilder.buildErroneousInvocation(variableElement, | 1437 bodyBuilder.buildErroneousInvocation(variableElement, |
| 1450 new Selector.setter( | 1438 new Selector.setter( |
| 1451 new Name(variableElement.name, variableElement.library)), | 1439 new Name(variableElement.name, variableElement.library)), |
| 1452 <ir.Primitive>[currentValue]); | 1440 <ir.Primitive>[currentValue]); |
| (...skipping 1147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2600 return value; | 2588 return value; |
| 2601 } | 2589 } |
| 2602 | 2590 |
| 2603 ir.Primitive buildInvokeDirectly(MethodElement target, | 2591 ir.Primitive buildInvokeDirectly(MethodElement target, |
| 2604 ir.Primitive receiver, | 2592 ir.Primitive receiver, |
| 2605 List<ir.Primitive> arguments, | 2593 List<ir.Primitive> arguments, |
| 2606 {SourceInformation sourceInformation}) { | 2594 {SourceInformation sourceInformation}) { |
| 2607 assert(isOpen); | 2595 assert(isOpen); |
| 2608 Selector selector = | 2596 Selector selector = |
| 2609 new Selector.call(target.memberName, new CallStructure(arguments.length) ); | 2597 new Selector.call(target.memberName, new CallStructure(arguments.length) ); |
| 2610 return _continueWithExpression( | 2598 return addPrimitive(new ir.InvokeMethodDirectly( |
| 2611 (k) => new ir.InvokeMethodDirectly( | 2599 receiver, target, selector, arguments, sourceInformation)); |
|
Kevin Millikin (Google)
2015/11/23 10:22:44
Indentation is strange in some places where a func
asgerf
2015/11/23 10:48:57
Done.
| |
| 2612 receiver, target, selector, arguments, k, sourceInformation)); | |
| 2613 } | 2600 } |
| 2614 | 2601 |
| 2615 /// Loads parameters to a constructor body into the environment. | 2602 /// Loads parameters to a constructor body into the environment. |
| 2616 /// | 2603 /// |
| 2617 /// The header for a constructor body differs from other functions in that | 2604 /// The header for a constructor body differs from other functions in that |
| 2618 /// some parameters are already boxed, and the box is passed as an argument | 2605 /// some parameters are already boxed, and the box is passed as an argument |
| 2619 /// instead of being created in the header. | 2606 /// instead of being created in the header. |
| 2620 void buildConstructorBodyHeader(Iterable<Local> parameters, | 2607 void buildConstructorBodyHeader(Iterable<Local> parameters, |
| 2621 ClosureScope closureScope) { | 2608 ClosureScope closureScope) { |
| 2622 _createThisParameter(); | 2609 _createThisParameter(); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 2647 InterfaceType interface = type; | 2634 InterfaceType interface = type; |
| 2648 Iterable<ir.Primitive> typeArguments = | 2635 Iterable<ir.Primitive> typeArguments = |
| 2649 interface.typeArguments.map((DartType argument) { | 2636 interface.typeArguments.map((DartType argument) { |
| 2650 return type.treatAsRaw | 2637 return type.treatAsRaw |
| 2651 ? buildNullConstant() | 2638 ? buildNullConstant() |
| 2652 : buildTypeExpression(argument); | 2639 : buildTypeExpression(argument); |
| 2653 }); | 2640 }); |
| 2654 arguments = new List<ir.Primitive>.from(arguments) | 2641 arguments = new List<ir.Primitive>.from(arguments) |
| 2655 ..addAll(typeArguments); | 2642 ..addAll(typeArguments); |
| 2656 } | 2643 } |
| 2657 return _continueWithExpression( | 2644 return addPrimitive(new ir.InvokeConstructor( |
|
Kevin Millikin (Google)
2015/11/23 10:22:44
And here.
asgerf
2015/11/23 10:48:57
Done.
| |
| 2658 (k) => new ir.InvokeConstructor( | 2645 type, element, selector, arguments, sourceInformation, |
| 2659 type, element, selector, arguments, k, sourceInformation, | |
| 2660 allocationSiteType: allocationSiteType)); | 2646 allocationSiteType: allocationSiteType)); |
| 2661 } | 2647 } |
| 2662 | 2648 |
| 2663 ir.Primitive buildTypeExpression(DartType type) { | 2649 ir.Primitive buildTypeExpression(DartType type) { |
| 2664 type = program.unaliasType(type); | 2650 type = program.unaliasType(type); |
| 2665 if (type is TypeVariableType) { | 2651 if (type is TypeVariableType) { |
| 2666 return buildTypeVariableAccess(type); | 2652 return buildTypeVariableAccess(type); |
| 2667 } else if (type is InterfaceType || type is FunctionType) { | 2653 } else if (type is InterfaceType || type is FunctionType) { |
| 2668 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2654 List<ir.Primitive> arguments = <ir.Primitive>[]; |
| 2669 type.forEachTypeVariable((TypeVariableType variable) { | 2655 type.forEachTypeVariable((TypeVariableType variable) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2723 List<ir.Primitive> arguments) { | 2709 List<ir.Primitive> arguments) { |
| 2724 return addPrimitive(new ir.CreateInvocationMirror(selector, arguments)); | 2710 return addPrimitive(new ir.CreateInvocationMirror(selector, arguments)); |
| 2725 } | 2711 } |
| 2726 | 2712 |
| 2727 ir.Primitive buildForeignCode(js.Template codeTemplate, | 2713 ir.Primitive buildForeignCode(js.Template codeTemplate, |
| 2728 List<ir.Primitive> arguments, | 2714 List<ir.Primitive> arguments, |
| 2729 NativeBehavior behavior, | 2715 NativeBehavior behavior, |
| 2730 {Element dependency}) { | 2716 {Element dependency}) { |
| 2731 assert(behavior != null); | 2717 assert(behavior != null); |
| 2732 TypeMask type = program.getTypeMaskForForeign(behavior); | 2718 TypeMask type = program.getTypeMaskForForeign(behavior); |
| 2733 ir.Primitive result = _continueWithExpression((k) => new ir.ForeignCode( | 2719 ir.Primitive result = addPrimitive(new ir.ForeignCode( |
| 2734 codeTemplate, | 2720 codeTemplate, |
| 2735 type, | 2721 type, |
| 2736 arguments, | 2722 arguments, |
| 2737 behavior, | 2723 behavior, |
| 2738 k, | |
| 2739 dependency: dependency)); | 2724 dependency: dependency)); |
| 2740 if (!codeTemplate.isExpression) { | 2725 if (!codeTemplate.isExpression) { |
| 2741 // Close the term if this is a "throw" expression or native body. | 2726 // Close the term if this is a "throw" expression or native body. |
| 2742 add(new ir.Unreachable()); | 2727 add(new ir.Unreachable()); |
| 2743 _current = null; | 2728 _current = null; |
| 2744 } | 2729 } |
| 2745 return result; | 2730 return result; |
| 2746 } | 2731 } |
| 2747 | 2732 |
| 2748 /// Creates a type test or type cast of [value] against [type]. | 2733 /// Creates a type test or type cast of [value] against [type]. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2785 if (type is InterfaceType && type.element == program.nullClass) { | 2770 if (type is InterfaceType && type.element == program.nullClass) { |
| 2786 // `x is Null` is true if and only if x is null. | 2771 // `x is Null` is true if and only if x is null. |
| 2787 return _buildCheckNull(value); | 2772 return _buildCheckNull(value); |
| 2788 } | 2773 } |
| 2789 return addPrimitive(new ir.TypeTest(value, type, typeArguments)); | 2774 return addPrimitive(new ir.TypeTest(value, type, typeArguments)); |
| 2790 } else { | 2775 } else { |
| 2791 if (type.isObject || type.isDynamic) { | 2776 if (type.isObject || type.isDynamic) { |
| 2792 // `x as Object` and `x as dynamic` are the same as `x`. | 2777 // `x as Object` and `x as dynamic` are the same as `x`. |
| 2793 return value; | 2778 return value; |
| 2794 } | 2779 } |
| 2795 return _continueWithExpression( | 2780 return addPrimitive(new ir.TypeCast(value, type, typeArguments)); |
| 2796 (k) => new ir.TypeCast(value, type, typeArguments, k)); | |
| 2797 } | 2781 } |
| 2798 } | 2782 } |
| 2799 | 2783 |
| 2800 /// Create an if-null expression. This is equivalent to a conditional | 2784 /// Create an if-null expression. This is equivalent to a conditional |
| 2801 /// expression whose result is either [value] if [value] is not null, or | 2785 /// expression whose result is either [value] if [value] is not null, or |
| 2802 /// `right` if [value] is null. Only when [value] is null, [buildRight] is | 2786 /// `right` if [value] is null. Only when [value] is null, [buildRight] is |
| 2803 /// evaluated to produce the `right` value. | 2787 /// evaluated to produce the `right` value. |
| 2804 ir.Primitive buildIfNull(ir.Primitive value, | 2788 ir.Primitive buildIfNull(ir.Primitive value, |
| 2805 ir.Primitive buildRight(IrBuilder builder), | 2789 ir.Primitive buildRight(IrBuilder builder), |
| 2806 {SourceInformation sourceInformation}) { | 2790 {SourceInformation sourceInformation}) { |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 2829 } | 2813 } |
| 2830 | 2814 |
| 2831 /// Convert the given value to a string. | 2815 /// Convert the given value to a string. |
| 2832 ir.Primitive buildStringify(ir.Primitive value) { | 2816 ir.Primitive buildStringify(ir.Primitive value) { |
| 2833 return buildStaticFunctionInvocation( | 2817 return buildStaticFunctionInvocation( |
| 2834 program.stringifyFunction, | 2818 program.stringifyFunction, |
| 2835 new CallStructure.unnamed(1), | 2819 new CallStructure.unnamed(1), |
| 2836 <ir.Primitive>[value]); | 2820 <ir.Primitive>[value]); |
| 2837 } | 2821 } |
| 2838 | 2822 |
| 2839 ir.Node buildAwait(ir.Primitive value) { | 2823 ir.Primitive buildAwait(ir.Primitive value) { |
| 2840 return _continueWithExpression((k) => new ir.Await(value, k)); | 2824 return addPrimitive(new ir.Await(value)); |
| 2841 } | 2825 } |
| 2842 | 2826 |
| 2843 void buildYield(ir.Primitive value, bool hasStar) { | 2827 void buildYield(ir.Primitive value, bool hasStar) { |
| 2844 _continueWithExpression((k) { | 2828 addPrimitive(new ir.Yield(value, hasStar)); |
| 2845 return new ir.Yield(value, hasStar, k); | |
| 2846 }); | |
| 2847 } | 2829 } |
| 2848 | 2830 |
| 2849 ir.Primitive buildRefinement(ir.Primitive value, TypeMask type) { | 2831 ir.Primitive buildRefinement(ir.Primitive value, TypeMask type) { |
| 2850 return addPrimitive(new ir.Refinement(value, type)); | 2832 return addPrimitive(new ir.Refinement(value, type)); |
| 2851 } | 2833 } |
| 2852 } | 2834 } |
| 2853 | 2835 |
| 2854 /// Location of a variable relative to a given closure. | 2836 /// Location of a variable relative to a given closure. |
| 2855 class ClosureLocation { | 2837 class ClosureLocation { |
| 2856 /// If not `null`, this location is [box].[field]. | 2838 /// If not `null`, this location is [box].[field]. |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2922 } | 2904 } |
| 2923 | 2905 |
| 2924 class SwitchCaseInfo { | 2906 class SwitchCaseInfo { |
| 2925 final List<ir.Primitive> constants = <ir.Primitive>[]; | 2907 final List<ir.Primitive> constants = <ir.Primitive>[]; |
| 2926 final SubbuildFunction buildBody; | 2908 final SubbuildFunction buildBody; |
| 2927 | 2909 |
| 2928 SwitchCaseInfo(this.buildBody); | 2910 SwitchCaseInfo(this.buildBody); |
| 2929 | 2911 |
| 2930 void addConstant(ir.Primitive constant) => constants.add(constant); | 2912 void addConstant(ir.Primitive constant) => constants.add(constant); |
| 2931 } | 2913 } |
| OLD | NEW |