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 part of dart2js.ir_builder; | 5 part of dart2js.ir_builder; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * This task iterates through all resolved elements and builds [ir.Node]s. The | 8 * This task iterates through all resolved elements and builds [ir.Node]s. The |
| 9 * nodes are stored in the [nodes] map and accessible through [hasIr] and | 9 * nodes are stored in the [nodes] map and accessible through [hasIr] and |
| 10 * [getIr]. | 10 * [getIr]. |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 142 /** | 142 /** |
| 143 * Builds the [ir.ExecutableDefinition] for an executable element. In case the | 143 * Builds the [ir.ExecutableDefinition] for an executable element. In case the |
| 144 * function uses features that cannot be expressed in the IR, this element | 144 * function uses features that cannot be expressed in the IR, this element |
| 145 * returns `null`. | 145 * returns `null`. |
| 146 */ | 146 */ |
| 147 ir.ExecutableDefinition buildExecutable(ExecutableElement element); | 147 ir.ExecutableDefinition buildExecutable(ExecutableElement element); |
| 148 | 148 |
| 149 ClosureScope getClosureScopeForNode(ast.Node node); | 149 ClosureScope getClosureScopeForNode(ast.Node node); |
| 150 ClosureEnvironment getClosureEnvironment(); | 150 ClosureEnvironment getClosureEnvironment(); |
| 151 | 151 |
| 152 /// Normalizes the argument list to a static invocation (i.e. where the target | |
| 153 /// element is known). | |
| 154 /// | |
| 155 /// For the JS backend, inserts default arguments and normalizes order of | |
| 156 /// named arguments. | |
| 157 /// | |
| 158 /// For the Dart backend, returns [arguments]. | |
| 159 List<ir.Primitive> normalizeStaticArguments( | |
| 160 Selector selector, | |
| 161 FunctionElement target, | |
| 162 List<ir.Primitive> arguments); | |
| 152 | 163 |
| 164 /// Normalizes the argument list of a dynamic invocation (i.e. where the | |
| 165 /// target element is unknown). | |
| 166 /// | |
| 167 /// For the JS backend, normalizes order of named arguments. | |
| 168 /// | |
| 169 /// For the Dart backend, returns [arguments]. | |
| 170 List<ir.Primitive> normalizeDynamicArguments( | |
| 171 Selector selector, | |
| 172 List<ir.Primitive> arguments); | |
| 153 | 173 |
| 154 ir.FunctionDefinition _makeFunctionBody(FunctionElement element, | 174 ir.FunctionDefinition _makeFunctionBody(FunctionElement element, |
| 155 ast.FunctionExpression node) { | 175 ast.FunctionExpression node) { |
| 156 FunctionSignature signature = element.functionSignature; | 176 FunctionSignature signature = element.functionSignature; |
| 157 List<ParameterElement> parameters = []; | 177 List<ParameterElement> parameters = []; |
| 158 signature.orderedForEachParameter(parameters.add); | 178 signature.orderedForEachParameter(parameters.add); |
| 159 | 179 |
| 160 irBuilder.buildFunctionHeader(parameters, | 180 irBuilder.buildFunctionHeader(parameters, |
| 161 closureScope: getClosureScopeForNode(node), | 181 closureScope: getClosureScopeForNode(node), |
| 162 env: getClosureEnvironment()); | 182 env: getClosureEnvironment()); |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 547 } | 567 } |
| 548 | 568 |
| 549 ir.Primitive visitNamedArgument(ast.NamedArgument node) { | 569 ir.Primitive visitNamedArgument(ast.NamedArgument node) { |
| 550 assert(irBuilder.isOpen); | 570 assert(irBuilder.isOpen); |
| 551 return visit(node.expression); | 571 return visit(node.expression); |
| 552 } | 572 } |
| 553 | 573 |
| 554 ir.Primitive visitClosureSend(ast.Send node) { | 574 ir.Primitive visitClosureSend(ast.Send node) { |
| 555 assert(irBuilder.isOpen); | 575 assert(irBuilder.isOpen); |
| 556 Element element = elements[node]; | 576 Element element = elements[node]; |
| 557 Selector closureSelector = elements.getSelector(node); | 577 Selector selector = elements.getSelector(node); |
| 558 if (element == null) { | 578 ir.Primitive receiver = (element == null) |
| 559 ir.Primitive closureTarget = visit(node.selector); | 579 ? visit(node.selector) |
| 560 List<ir.Primitive> args = | 580 : irBuilder.buildLocalGet(element); |
| 561 node.arguments.mapToList(visit, growable:false); | 581 List<ir.Primitive> arguments = node.arguments.mapToList(visit); |
| 562 return irBuilder.buildFunctionExpressionInvocation( | 582 arguments = normalizeDynamicArguments(selector, arguments); |
| 563 closureTarget, elements.getSelector(node), args); | 583 return irBuilder.buildCallInvocation(receiver, selector, arguments); |
| 564 } else { | |
| 565 List<ir.Primitive> args = | |
| 566 node.arguments.mapToList(visit, growable:false); | |
| 567 return irBuilder.buildLocalInvocation( | |
| 568 element, elements.getSelector(node), args); | |
| 569 } | |
| 570 } | 584 } |
| 571 | 585 |
| 572 /// If [node] is null, returns this. | 586 /// If [node] is null, returns this. |
| 573 /// If [node] is super, returns null (for special handling) | 587 /// If [node] is super, returns null (for special handling) |
| 574 /// Otherwise visits [node] and returns the result. | 588 /// Otherwise visits [node] and returns the result. |
| 575 ir.Primitive visitReceiver(ast.Expression node) { | 589 ir.Primitive visitReceiver(ast.Expression node) { |
| 576 if (node == null) return irBuilder.buildThis(); | 590 if (node == null) return irBuilder.buildThis(); |
| 577 if (node.isSuper()) return null; | 591 if (node.isSuper()) return null; |
| 578 return visit(node); | 592 return visit(node); |
| 579 } | 593 } |
| 580 | 594 |
| 581 /// Returns `true` if [node] is a super call. | 595 /// Returns `true` if [node] is a super call. |
| 582 // TODO(johnniwinther): Remove the need for this. | 596 // TODO(johnniwinther): Remove the need for this. |
| 583 bool isSuperCall(ast.Send node) { | 597 bool isSuperCall(ast.Send node) { |
| 584 return node != null && node.receiver != null && node.receiver.isSuper(); | 598 return node != null && node.receiver != null && node.receiver.isSuper(); |
| 585 } | 599 } |
| 586 | 600 |
| 587 ir.Primitive visitDynamicSend(ast.Send node) { | 601 ir.Primitive visitDynamicSend(ast.Send node) { |
| 588 assert(irBuilder.isOpen); | 602 assert(irBuilder.isOpen); |
| 589 Selector selector = elements.getSelector(node); | 603 Selector selector = elements.getSelector(node); |
| 590 ir.Primitive receiver = visitReceiver(node.receiver); | 604 ir.Primitive receiver = visitReceiver(node.receiver); |
| 591 List<ir.Primitive> arguments = new List<ir.Primitive>(); | 605 List<ir.Primitive> arguments = node.arguments.mapToList(visit); |
| 592 for (ast.Node n in node.arguments) { | 606 arguments = normalizeDynamicArguments(selector, arguments); |
| 593 arguments.add(visit(n)); | |
| 594 } | |
| 595 return irBuilder.buildDynamicInvocation(receiver, selector, arguments); | 607 return irBuilder.buildDynamicInvocation(receiver, selector, arguments); |
| 596 } | 608 } |
| 597 | 609 |
| 598 _GetterElements translateGetter(ast.Send node, Selector selector) { | 610 _GetterElements translateGetter(ast.Send node, Selector selector) { |
| 599 Element element = elements[node]; | 611 Element element = elements[node]; |
| 600 ir.Primitive result; | 612 ir.Primitive result; |
| 601 ir.Primitive receiver; | 613 ir.Primitive receiver; |
| 602 ir.Primitive index; | 614 ir.Primitive index; |
| 603 | 615 |
| 604 if (element != null && element.isConst) { | 616 if (element != null && element.isConst) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 710 assert(irBuilder.isOpen); | 722 assert(irBuilder.isOpen); |
| 711 Element element = elements[node]; | 723 Element element = elements[node]; |
| 712 assert(!element.isConstructor); | 724 assert(!element.isConstructor); |
| 713 // TODO(lry): support foreign functions. | 725 // TODO(lry): support foreign functions. |
| 714 if (element.isForeign(compiler.backend)) { | 726 if (element.isForeign(compiler.backend)) { |
| 715 return giveup(node, 'StaticSend: foreign'); | 727 return giveup(node, 'StaticSend: foreign'); |
| 716 } | 728 } |
| 717 | 729 |
| 718 Selector selector = elements.getSelector(node); | 730 Selector selector = elements.getSelector(node); |
| 719 | 731 |
| 720 // TODO(lry): support default arguments, need support for locals. | 732 if (selector.isCall && (element.isGetter || element.isField)) { |
|
karlklose
2015/02/11 14:54:43
Could you add a few comments for the different cas
asgerf
2015/02/11 15:04:31
Done.
| |
| 721 List<ir.Primitive> arguments = | 733 Selector getter = new Selector.getterFrom(selector); |
| 722 node.arguments.mapToList(visit, growable:false); | 734 Selector call = new Selector.callClosureFrom(selector); |
| 723 return irBuilder.buildStaticInvocation(element, selector, arguments); | 735 ir.Primitive receiver = irBuilder.buildStaticGet(element, getter); |
| 736 List<ir.Primitive> arguments = node.arguments.mapToList(visit); | |
| 737 arguments = normalizeDynamicArguments(selector, arguments); | |
| 738 return irBuilder.buildCallInvocation(receiver, call, arguments); | |
| 739 } else if (selector.isGetter) { | |
| 740 return irBuilder.buildStaticGet(element, selector); | |
| 741 } else { | |
| 742 assert(selector.isCall); | |
| 743 assert(element is FunctionElement); | |
| 744 List<ir.Primitive> arguments = node.arguments.mapToList(visit); | |
| 745 arguments = normalizeStaticArguments(selector, element, arguments); | |
| 746 return irBuilder.buildStaticInvocation(element, selector, arguments); | |
| 747 } | |
| 724 } | 748 } |
| 725 | 749 |
| 726 ir.Primitive visitSuperSend(ast.Send node) { | 750 ir.Primitive visitSuperSend(ast.Send node) { |
| 727 assert(irBuilder.isOpen); | 751 assert(irBuilder.isOpen); |
| 728 if (node.isPropertyAccess) { | 752 if (node.isPropertyAccess) { |
| 729 return visitGetterSend(node); | 753 return visitGetterSend(node); |
| 730 } else { | 754 } else { |
| 731 Selector selector = elements.getSelector(node); | 755 Selector selector = elements.getSelector(node); |
| 732 Element target = elements[node]; | 756 Element target = elements[node]; |
| 733 List<ir.Primitive> arguments = new List<ir.Primitive>(); | 757 List<ir.Primitive> arguments = node.arguments.mapToList(visit); |
| 734 for (ast.Node n in node.arguments) { | 758 if (selector.isCall) { |
| 735 arguments.add(visit(n)); | 759 arguments = normalizeStaticArguments(selector, target, arguments); |
| 736 } | 760 } |
| 737 return irBuilder.buildSuperInvocation(target, selector, arguments); | 761 return irBuilder.buildSuperInvocation(target, selector, arguments); |
| 738 } | 762 } |
| 739 } | 763 } |
| 740 | 764 |
| 741 visitTypePrefixSend(ast.Send node) { | 765 visitTypePrefixSend(ast.Send node) { |
| 742 compiler.internalError(node, "visitTypePrefixSend should not be called."); | 766 compiler.internalError(node, "visitTypePrefixSend should not be called."); |
| 743 } | 767 } |
| 744 | 768 |
| 745 ir.Primitive visitTypeLiteralSend(ast.Send node) { | 769 ir.Primitive visitTypeLiteralSend(ast.Send node) { |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 859 } | 883 } |
| 860 | 884 |
| 861 ir.Primitive visitNewExpression(ast.NewExpression node) { | 885 ir.Primitive visitNewExpression(ast.NewExpression node) { |
| 862 if (node.isConst) { | 886 if (node.isConst) { |
| 863 return translateConstant(node); | 887 return translateConstant(node); |
| 864 } | 888 } |
| 865 FunctionElement element = elements[node.send]; | 889 FunctionElement element = elements[node.send]; |
| 866 Selector selector = elements.getSelector(node.send); | 890 Selector selector = elements.getSelector(node.send); |
| 867 DartType type = elements.getType(node); | 891 DartType type = elements.getType(node); |
| 868 ast.Node selectorNode = node.send.selector; | 892 ast.Node selectorNode = node.send.selector; |
| 869 List<ir.Definition> arguments = | 893 List<ir.Primitive> arguments = |
| 870 node.send.arguments.mapToList(visit, growable:false); | 894 node.send.arguments.mapToList(visit, growable:false); |
| 895 arguments = normalizeStaticArguments(selector, element, arguments); | |
| 871 return irBuilder.buildConstructorInvocation( | 896 return irBuilder.buildConstructorInvocation( |
| 872 element, selector, type, arguments); | 897 element, selector, type, arguments); |
| 873 } | 898 } |
| 874 | 899 |
| 875 ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) { | 900 ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) { |
| 876 assert(irBuilder.isOpen); | 901 assert(irBuilder.isOpen); |
| 877 ir.Primitive first = visit(node.first); | 902 ir.Primitive first = visit(node.first); |
| 878 ir.Primitive second = visit(node.second); | 903 ir.Primitive second = visit(node.second); |
| 879 return irBuilder.buildStringConcatenation([first, second]); | 904 return irBuilder.buildStringConcatenation([first, second]); |
| 880 } | 905 } |
| 881 | 906 |
| 882 ir.Primitive visitStringInterpolation(ast.StringInterpolation node) { | 907 ir.Primitive visitStringInterpolation(ast.StringInterpolation node) { |
| 883 assert(irBuilder.isOpen); | 908 assert(irBuilder.isOpen); |
| 884 List<ir.Primitive> arguments = []; | 909 List<ir.Primitive> arguments = []; |
| 885 arguments.add(visitLiteralString(node.string)); | 910 arguments.add(visitLiteralString(node.string)); |
| 886 var it = node.parts.iterator; | 911 var it = node.parts.iterator; |
| 887 while (it.moveNext()) { | 912 while (it.moveNext()) { |
| 888 ast.StringInterpolationPart part = it.current; | 913 ast.StringInterpolationPart part = it.current; |
| 889 arguments.add(visit(part.expression)); | 914 arguments.add(visit(part.expression)); |
| 890 arguments.add(visitLiteralString(part.string)); | 915 arguments.add(visitLiteralString(part.string)); |
| 891 } | 916 } |
| 892 return irBuilder.buildStringConcatenation(arguments); | 917 return irBuilder.buildStringConcatenation(arguments); |
| 893 } | 918 } |
| 894 | 919 |
| 895 ir.Primitive translateConstant(ast.Node node, [ConstantExpression constant]) { | 920 ir.Primitive translateConstant(ast.Node node) { |
| 896 assert(irBuilder.isOpen); | 921 assert(irBuilder.isOpen); |
| 897 if (constant == null) { | 922 return irBuilder.buildConstantLiteral(getConstantForNode(node)); |
| 898 constant = getConstantForNode(node); | |
| 899 } | |
| 900 return irBuilder.buildConstantLiteral(constant); | |
| 901 } | 923 } |
| 902 | 924 |
| 903 ir.ExecutableDefinition nullIfGiveup(ir.ExecutableDefinition action()) { | 925 ir.ExecutableDefinition nullIfGiveup(ir.ExecutableDefinition action()) { |
| 904 try { | 926 try { |
| 905 return action(); | 927 return action(); |
| 906 } catch(e, tr) { | 928 } catch(e, tr) { |
| 907 if (e == ABORT_IRNODE_BUILDER) { | 929 if (e == ABORT_IRNODE_BUILDER) { |
| 908 return null; | 930 return null; |
| 909 } | 931 } |
| 910 rethrow; | 932 rethrow; |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1105 SynthesizedConstructorElementX constructor = element; | 1127 SynthesizedConstructorElementX constructor = element; |
| 1106 if (!constructor.isDefaultConstructor) { | 1128 if (!constructor.isDefaultConstructor) { |
| 1107 giveup(null, 'cannot handle synthetic forwarding constructors'); | 1129 giveup(null, 'cannot handle synthetic forwarding constructors'); |
| 1108 } | 1130 } |
| 1109 } | 1131 } |
| 1110 | 1132 |
| 1111 IrBuilder builder = makeIRBuilder(node, element); | 1133 IrBuilder builder = makeIRBuilder(node, element); |
| 1112 | 1134 |
| 1113 return withBuilder(builder, () => _makeFunctionBody(element, node)); | 1135 return withBuilder(builder, () => _makeFunctionBody(element, node)); |
| 1114 } | 1136 } |
| 1137 | |
| 1138 List<ir.Primitive> normalizeStaticArguments( | |
| 1139 Selector selector, | |
| 1140 FunctionElement target, | |
| 1141 List<ir.Primitive> arguments) { | |
| 1142 return arguments; | |
| 1143 } | |
| 1144 | |
| 1145 List<ir.Primitive> normalizeDynamicArguments( | |
| 1146 Selector selector, | |
| 1147 List<ir.Primitive> arguments) { | |
| 1148 return arguments; | |
| 1149 } | |
| 1115 } | 1150 } |
| 1116 | 1151 |
| 1117 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. | 1152 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. |
| 1118 class JsIrBuilderVisitor extends IrBuilderVisitor { | 1153 class JsIrBuilderVisitor extends IrBuilderVisitor { |
| 1119 /// Promote the type of [irBuilder] to [JsIrBuilder]. | 1154 /// Promote the type of [irBuilder] to [JsIrBuilder]. |
| 1120 JsIrBuilder get irBuilder => super.irBuilder; | 1155 JsIrBuilder get irBuilder => super.irBuilder; |
| 1121 | 1156 |
| 1122 /// Result of closure conversion for the current body of code. | 1157 /// Result of closure conversion for the current body of code. |
| 1123 /// | 1158 /// |
| 1124 /// Will be initialized upon entering the body of a function. | 1159 /// Will be initialized upon entering the body of a function. |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1240 /// Such expressions need to be compiled with a different [sourceFile] and | 1275 /// Such expressions need to be compiled with a different [sourceFile] and |
| 1241 /// [elements] mapping. | 1276 /// [elements] mapping. |
| 1242 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { | 1277 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { |
| 1243 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( | 1278 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( |
| 1244 context.resolvedAst.elements, | 1279 context.resolvedAst.elements, |
| 1245 compiler, | 1280 compiler, |
| 1246 elementSourceFile(context)); | 1281 elementSourceFile(context)); |
| 1247 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); | 1282 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); |
| 1248 } | 1283 } |
| 1249 | 1284 |
| 1285 /// Builds the IR for a constant taken from a different [context]. | |
| 1286 /// | |
| 1287 /// Such constants need to be compiled with a different [sourceFile] and | |
| 1288 /// [elements] mapping. | |
| 1289 ir.Primitive inlineConstant(AstElement context, ast.Expression exp) { | |
| 1290 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( | |
| 1291 context.resolvedAst.elements, | |
| 1292 compiler, | |
| 1293 elementSourceFile(context)); | |
| 1294 return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp)); | |
| 1295 } | |
| 1296 | |
| 1250 /// Builds the IR for a given constructor. | 1297 /// Builds the IR for a given constructor. |
| 1251 /// | 1298 /// |
| 1252 /// 1. Evaluates all own or inherited field initializers. | 1299 /// 1. Evaluates all own or inherited field initializers. |
| 1253 /// 2. Creates the object and assigns its fields. | 1300 /// 2. Creates the object and assigns its fields. |
| 1254 /// 3. Calls constructor body and super constructor bodies. | 1301 /// 3. Calls constructor body and super constructor bodies. |
| 1255 /// 4. Returns the created object. | 1302 /// 4. Returns the created object. |
| 1256 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { | 1303 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { |
| 1257 constructor = constructor.implementation; | 1304 constructor = constructor.implementation; |
| 1258 ClassElement classElement = constructor.enclosingClass.implementation; | 1305 ClassElement classElement = constructor.enclosingClass.implementation; |
| 1259 | 1306 |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1544 | 1591 |
| 1545 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( | 1592 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( |
| 1546 element, | 1593 element, |
| 1547 node, | 1594 node, |
| 1548 elements); | 1595 elements); |
| 1549 IrBuilder builder = | 1596 IrBuilder builder = |
| 1550 new JsIrBuilder(compiler.backend.constantSystem, element); | 1597 new JsIrBuilder(compiler.backend.constantSystem, element); |
| 1551 return withBuilder(builder, () => _makeFunctionBody(element, node)); | 1598 return withBuilder(builder, () => _makeFunctionBody(element, node)); |
| 1552 } | 1599 } |
| 1553 | 1600 |
| 1601 /// Creates a primitive for the default value of [parameter]. | |
| 1602 ir.Primitive translateDefaultValue(ParameterElement parameter) { | |
| 1603 if (parameter.initializer == null) { | |
| 1604 return irBuilder.buildNullLiteral(); | |
| 1605 } else { | |
| 1606 return inlineConstant(parameter.executableContext, parameter.initializer); | |
| 1607 } | |
| 1608 } | |
| 1609 | |
| 1610 /// Inserts default arguments and normalizes order of named arguments. | |
| 1611 List<ir.Primitive> normalizeStaticArguments( | |
| 1612 Selector selector, | |
| 1613 FunctionElement target, | |
| 1614 List<ir.Primitive> arguments) { | |
| 1615 target = target.implementation; | |
| 1616 FunctionSignature signature = target.functionSignature; | |
| 1617 if (!signature.optionalParametersAreNamed && | |
| 1618 signature.parameterCount == arguments.length) { | |
| 1619 // Optimization: don't copy the argument list for trivial cases. | |
| 1620 return arguments; | |
| 1621 } | |
| 1622 | |
| 1623 List<ir.Primitive> result = <ir.Primitive>[]; | |
| 1624 int i = 0; | |
| 1625 signature.forEachRequiredParameter((ParameterElement element) { | |
| 1626 result.add(arguments[i]); | |
| 1627 ++i; | |
| 1628 }); | |
| 1629 | |
| 1630 if (!signature.optionalParametersAreNamed) { | |
| 1631 signature.forEachOptionalParameter((ParameterElement element) { | |
| 1632 if (i < arguments.length) { | |
| 1633 result.add(arguments[i]); | |
| 1634 ++i; | |
| 1635 } else { | |
| 1636 result.add(translateDefaultValue(element)); | |
| 1637 } | |
| 1638 }); | |
| 1639 } else { | |
| 1640 int offset = i; | |
| 1641 // Iterate over the optional parameters of the signature, and try to | |
| 1642 // find them in [compiledNamedArguments]. If found, we use the | |
| 1643 // value in the temporary list, otherwise the default value. | |
| 1644 signature.orderedOptionalParameters.forEach((ParameterElement element) { | |
| 1645 int nameIndex = selector.namedArguments.indexOf(element.name); | |
| 1646 if (nameIndex != -1) { | |
| 1647 int translatedIndex = offset + nameIndex; | |
| 1648 result.add(arguments[translatedIndex]); | |
| 1649 } else { | |
| 1650 result.add(translateDefaultValue(element)); | |
| 1651 } | |
| 1652 }); | |
| 1653 } | |
| 1654 return result; | |
| 1655 } | |
| 1656 | |
| 1657 /// Normalizes order of named arguments. | |
| 1658 List<ir.Primitive> normalizeDynamicArguments( | |
| 1659 Selector selector, | |
| 1660 List<ir.Primitive> arguments) { | |
| 1661 assert(arguments.length == selector.argumentCount); | |
| 1662 // Optimization: don't copy the argument list for trivial cases. | |
| 1663 if (selector.namedArguments.isEmpty) return arguments; | |
| 1664 List<ir.Primitive> result = <ir.Primitive>[]; | |
| 1665 for (int i=0; i < selector.positionalArgumentCount; i++) { | |
| 1666 result.add(arguments[i]); | |
| 1667 } | |
| 1668 for (String argName in selector.getOrderedNamedArguments()) { | |
| 1669 int nameIndex = selector.namedArguments.indexOf(argName); | |
| 1670 int translatedIndex = selector.positionalArgumentCount + nameIndex; | |
| 1671 result.add(arguments[translatedIndex]); | |
| 1672 } | |
| 1673 return result; | |
| 1674 } | |
| 1675 | |
| 1554 } | 1676 } |
| 1555 | 1677 |
| OLD | NEW |