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.buildFunctionExpressionInvocation( |
| 564 } else { | 584 receiver, selector, arguments); |
| 565 List<ir.Primitive> args = | |
| 566 node.arguments.mapToList(visit, growable:false); | |
| 567 return irBuilder.buildLocalInvocation( | |
| 568 element, elements.getSelector(node), args); | |
| 569 } | |
| 570 } | 585 } |
| 571 | 586 |
| 572 /// If [node] is null, returns this. | 587 /// If [node] is null, returns this. |
| 573 /// If [node] is super, returns null (for special handling) | 588 /// If [node] is super, returns null (for special handling) |
| 574 /// Otherwise visits [node] and returns the result. | 589 /// Otherwise visits [node] and returns the result. |
| 575 ir.Primitive visitReceiver(ast.Expression node) { | 590 ir.Primitive visitReceiver(ast.Expression node) { |
| 576 if (node == null) return irBuilder.buildThis(); | 591 if (node == null) return irBuilder.buildThis(); |
| 577 if (node.isSuper()) return null; | 592 if (node.isSuper()) return null; |
| 578 return visit(node); | 593 return visit(node); |
| 579 } | 594 } |
| 580 | 595 |
| 581 /// Returns `true` if [node] is a super call. | 596 /// Returns `true` if [node] is a super call. |
| 582 // TODO(johnniwinther): Remove the need for this. | 597 // TODO(johnniwinther): Remove the need for this. |
| 583 bool isSuperCall(ast.Send node) { | 598 bool isSuperCall(ast.Send node) { |
| 584 return node != null && node.receiver != null && node.receiver.isSuper(); | 599 return node != null && node.receiver != null && node.receiver.isSuper(); |
| 585 } | 600 } |
| 586 | 601 |
| 587 ir.Primitive visitDynamicSend(ast.Send node) { | 602 ir.Primitive visitDynamicSend(ast.Send node) { |
| 588 assert(irBuilder.isOpen); | 603 assert(irBuilder.isOpen); |
| 589 Selector selector = elements.getSelector(node); | 604 Selector selector = elements.getSelector(node); |
| 590 ir.Primitive receiver = visitReceiver(node.receiver); | 605 ir.Primitive receiver = visitReceiver(node.receiver); |
| 591 List<ir.Primitive> arguments = new List<ir.Primitive>(); | 606 List<ir.Primitive> arguments = node.arguments.mapToList(visit); |
| 592 for (ast.Node n in node.arguments) { | 607 arguments = normalizeDynamicArguments(selector, arguments); |
| 593 arguments.add(visit(n)); | |
| 594 } | |
| 595 return irBuilder.buildDynamicInvocation(receiver, selector, arguments); | 608 return irBuilder.buildDynamicInvocation(receiver, selector, arguments); |
| 596 } | 609 } |
| 597 | 610 |
| 598 _GetterElements translateGetter(ast.Send node, Selector selector) { | 611 _GetterElements translateGetter(ast.Send node, Selector selector) { |
| 599 Element element = elements[node]; | 612 Element element = elements[node]; |
| 600 ir.Primitive result; | 613 ir.Primitive result; |
| 601 ir.Primitive receiver; | 614 ir.Primitive receiver; |
| 602 ir.Primitive index; | 615 ir.Primitive index; |
| 603 | 616 |
| 604 if (element != null && element.isConst) { | 617 if (element != null && element.isConst) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 710 assert(irBuilder.isOpen); | 723 assert(irBuilder.isOpen); |
| 711 Element element = elements[node]; | 724 Element element = elements[node]; |
| 712 assert(!element.isConstructor); | 725 assert(!element.isConstructor); |
| 713 // TODO(lry): support foreign functions. | 726 // TODO(lry): support foreign functions. |
| 714 if (element.isForeign(compiler.backend)) { | 727 if (element.isForeign(compiler.backend)) { |
| 715 return giveup(node, 'StaticSend: foreign'); | 728 return giveup(node, 'StaticSend: foreign'); |
| 716 } | 729 } |
| 717 | 730 |
| 718 Selector selector = elements.getSelector(node); | 731 Selector selector = elements.getSelector(node); |
| 719 | 732 |
| 720 // TODO(lry): support default arguments, need support for locals. | |
| 721 List<ir.Primitive> arguments = | 733 List<ir.Primitive> arguments = |
| 722 node.arguments.mapToList(visit, growable:false); | 734 node.arguments.mapToList(visit, growable:false); |
| 735 arguments = normalizeStaticArguments(selector, element, arguments); | |
|
asgerf
2015/02/11 10:31:32
This would fail in checked-mode when the element w
| |
| 723 return irBuilder.buildStaticInvocation(element, selector, arguments); | 736 return irBuilder.buildStaticInvocation(element, selector, arguments); |
| 724 } | 737 } |
| 725 | 738 |
| 726 ir.Primitive visitSuperSend(ast.Send node) { | 739 ir.Primitive visitSuperSend(ast.Send node) { |
| 727 assert(irBuilder.isOpen); | 740 assert(irBuilder.isOpen); |
| 728 if (node.isPropertyAccess) { | 741 if (node.isPropertyAccess) { |
| 729 return visitGetterSend(node); | 742 return visitGetterSend(node); |
| 730 } else { | 743 } else { |
| 731 Selector selector = elements.getSelector(node); | 744 Selector selector = elements.getSelector(node); |
| 732 Element target = elements[node]; | 745 Element target = elements[node]; |
| 733 List<ir.Primitive> arguments = new List<ir.Primitive>(); | 746 List<ir.Primitive> arguments = node.arguments.mapToList(visit); |
| 734 for (ast.Node n in node.arguments) { | 747 arguments = normalizeStaticArguments(selector, target, arguments); |
| 735 arguments.add(visit(n)); | |
| 736 } | |
| 737 return irBuilder.buildSuperInvocation(target, selector, arguments); | 748 return irBuilder.buildSuperInvocation(target, selector, arguments); |
| 738 } | 749 } |
| 739 } | 750 } |
| 740 | 751 |
| 741 visitTypePrefixSend(ast.Send node) { | 752 visitTypePrefixSend(ast.Send node) { |
| 742 compiler.internalError(node, "visitTypePrefixSend should not be called."); | 753 compiler.internalError(node, "visitTypePrefixSend should not be called."); |
| 743 } | 754 } |
| 744 | 755 |
| 745 ir.Primitive visitTypeLiteralSend(ast.Send node) { | 756 ir.Primitive visitTypeLiteralSend(ast.Send node) { |
| 746 assert(irBuilder.isOpen); | 757 assert(irBuilder.isOpen); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 859 } | 870 } |
| 860 | 871 |
| 861 ir.Primitive visitNewExpression(ast.NewExpression node) { | 872 ir.Primitive visitNewExpression(ast.NewExpression node) { |
| 862 if (node.isConst) { | 873 if (node.isConst) { |
| 863 return translateConstant(node); | 874 return translateConstant(node); |
| 864 } | 875 } |
| 865 FunctionElement element = elements[node.send]; | 876 FunctionElement element = elements[node.send]; |
| 866 Selector selector = elements.getSelector(node.send); | 877 Selector selector = elements.getSelector(node.send); |
| 867 DartType type = elements.getType(node); | 878 DartType type = elements.getType(node); |
| 868 ast.Node selectorNode = node.send.selector; | 879 ast.Node selectorNode = node.send.selector; |
| 869 List<ir.Definition> arguments = | 880 List<ir.Primitive> arguments = |
| 870 node.send.arguments.mapToList(visit, growable:false); | 881 node.send.arguments.mapToList(visit, growable:false); |
| 882 arguments = normalizeStaticArguments(selector, element, arguments); | |
| 871 return irBuilder.buildConstructorInvocation( | 883 return irBuilder.buildConstructorInvocation( |
| 872 element, selector, type, arguments); | 884 element, selector, type, arguments); |
| 873 } | 885 } |
| 874 | 886 |
| 875 ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) { | 887 ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) { |
| 876 assert(irBuilder.isOpen); | 888 assert(irBuilder.isOpen); |
| 877 ir.Primitive first = visit(node.first); | 889 ir.Primitive first = visit(node.first); |
| 878 ir.Primitive second = visit(node.second); | 890 ir.Primitive second = visit(node.second); |
| 879 return irBuilder.buildStringConcatenation([first, second]); | 891 return irBuilder.buildStringConcatenation([first, second]); |
| 880 } | 892 } |
| 881 | 893 |
| 882 ir.Primitive visitStringInterpolation(ast.StringInterpolation node) { | 894 ir.Primitive visitStringInterpolation(ast.StringInterpolation node) { |
| 883 assert(irBuilder.isOpen); | 895 assert(irBuilder.isOpen); |
| 884 List<ir.Primitive> arguments = []; | 896 List<ir.Primitive> arguments = []; |
| 885 arguments.add(visitLiteralString(node.string)); | 897 arguments.add(visitLiteralString(node.string)); |
| 886 var it = node.parts.iterator; | 898 var it = node.parts.iterator; |
| 887 while (it.moveNext()) { | 899 while (it.moveNext()) { |
| 888 ast.StringInterpolationPart part = it.current; | 900 ast.StringInterpolationPart part = it.current; |
| 889 arguments.add(visit(part.expression)); | 901 arguments.add(visit(part.expression)); |
| 890 arguments.add(visitLiteralString(part.string)); | 902 arguments.add(visitLiteralString(part.string)); |
| 891 } | 903 } |
| 892 return irBuilder.buildStringConcatenation(arguments); | 904 return irBuilder.buildStringConcatenation(arguments); |
| 893 } | 905 } |
| 894 | 906 |
| 895 ir.Primitive translateConstant(ast.Node node, [ConstantExpression constant]) { | 907 ir.Primitive translateConstant(ast.Node node) { |
| 896 assert(irBuilder.isOpen); | 908 assert(irBuilder.isOpen); |
| 897 if (constant == null) { | 909 return irBuilder.buildConstantLiteral(getConstantForNode(node)); |
| 898 constant = getConstantForNode(node); | |
| 899 } | |
| 900 return irBuilder.buildConstantLiteral(constant); | |
| 901 } | 910 } |
| 902 | 911 |
| 903 ir.ExecutableDefinition nullIfGiveup(ir.ExecutableDefinition action()) { | 912 ir.ExecutableDefinition nullIfGiveup(ir.ExecutableDefinition action()) { |
| 904 try { | 913 try { |
| 905 return action(); | 914 return action(); |
| 906 } catch(e, tr) { | 915 } catch(e, tr) { |
| 907 if (e == ABORT_IRNODE_BUILDER) { | 916 if (e == ABORT_IRNODE_BUILDER) { |
| 908 return null; | 917 return null; |
| 909 } | 918 } |
| 910 rethrow; | 919 rethrow; |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1105 SynthesizedConstructorElementX constructor = element; | 1114 SynthesizedConstructorElementX constructor = element; |
| 1106 if (!constructor.isDefaultConstructor) { | 1115 if (!constructor.isDefaultConstructor) { |
| 1107 giveup(null, 'cannot handle synthetic forwarding constructors'); | 1116 giveup(null, 'cannot handle synthetic forwarding constructors'); |
| 1108 } | 1117 } |
| 1109 } | 1118 } |
| 1110 | 1119 |
| 1111 IrBuilder builder = makeIRBuilder(node, element); | 1120 IrBuilder builder = makeIRBuilder(node, element); |
| 1112 | 1121 |
| 1113 return withBuilder(builder, () => _makeFunctionBody(element, node)); | 1122 return withBuilder(builder, () => _makeFunctionBody(element, node)); |
| 1114 } | 1123 } |
| 1124 | |
| 1125 List<ir.Primitive> normalizeStaticArguments( | |
| 1126 Selector selector, | |
| 1127 FunctionElement target, | |
| 1128 List<ir.Primitive> arguments) { | |
| 1129 return arguments; | |
| 1130 } | |
| 1131 | |
| 1132 List<ir.Primitive> normalizeDynamicArguments( | |
| 1133 Selector selector, | |
| 1134 List<ir.Primitive> arguments) { | |
| 1135 return arguments; | |
| 1136 } | |
| 1115 } | 1137 } |
| 1116 | 1138 |
| 1117 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. | 1139 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. |
| 1118 class JsIrBuilderVisitor extends IrBuilderVisitor { | 1140 class JsIrBuilderVisitor extends IrBuilderVisitor { |
| 1119 /// Promote the type of [irBuilder] to [JsIrBuilder]. | 1141 /// Promote the type of [irBuilder] to [JsIrBuilder]. |
| 1120 JsIrBuilder get irBuilder => super.irBuilder; | 1142 JsIrBuilder get irBuilder => super.irBuilder; |
| 1121 | 1143 |
| 1122 /// Result of closure conversion for the current body of code. | 1144 /// Result of closure conversion for the current body of code. |
| 1123 /// | 1145 /// |
| 1124 /// Will be initialized upon entering the body of a function. | 1146 /// 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 | 1262 /// Such expressions need to be compiled with a different [sourceFile] and |
| 1241 /// [elements] mapping. | 1263 /// [elements] mapping. |
| 1242 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { | 1264 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { |
| 1243 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( | 1265 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( |
| 1244 context.resolvedAst.elements, | 1266 context.resolvedAst.elements, |
| 1245 compiler, | 1267 compiler, |
| 1246 elementSourceFile(context)); | 1268 elementSourceFile(context)); |
| 1247 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); | 1269 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); |
| 1248 } | 1270 } |
| 1249 | 1271 |
| 1272 /// Builds the IR for a constant taken from a different [context]. | |
| 1273 /// | |
| 1274 /// Such constants need to be compiled with a different [sourceFile] and | |
| 1275 /// [elements] mapping. | |
| 1276 ir.Primitive inlineConstant(AstElement context, ast.Expression exp) { | |
| 1277 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( | |
| 1278 context.resolvedAst.elements, | |
| 1279 compiler, | |
| 1280 elementSourceFile(context)); | |
| 1281 return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp)); | |
| 1282 } | |
| 1283 | |
| 1250 /// Builds the IR for a given constructor. | 1284 /// Builds the IR for a given constructor. |
| 1251 /// | 1285 /// |
| 1252 /// 1. Evaluates all own or inherited field initializers. | 1286 /// 1. Evaluates all own or inherited field initializers. |
| 1253 /// 2. Creates the object and assigns its fields. | 1287 /// 2. Creates the object and assigns its fields. |
| 1254 /// 3. Calls constructor body and super constructor bodies. | 1288 /// 3. Calls constructor body and super constructor bodies. |
| 1255 /// 4. Returns the created object. | 1289 /// 4. Returns the created object. |
| 1256 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { | 1290 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { |
| 1257 constructor = constructor.implementation; | 1291 constructor = constructor.implementation; |
| 1258 ClassElement classElement = constructor.enclosingClass.implementation; | 1292 ClassElement classElement = constructor.enclosingClass.implementation; |
| 1259 | 1293 |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1544 | 1578 |
| 1545 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( | 1579 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( |
| 1546 element, | 1580 element, |
| 1547 node, | 1581 node, |
| 1548 elements); | 1582 elements); |
| 1549 IrBuilder builder = | 1583 IrBuilder builder = |
| 1550 new JsIrBuilder(compiler.backend.constantSystem, element); | 1584 new JsIrBuilder(compiler.backend.constantSystem, element); |
| 1551 return withBuilder(builder, () => _makeFunctionBody(element, node)); | 1585 return withBuilder(builder, () => _makeFunctionBody(element, node)); |
| 1552 } | 1586 } |
| 1553 | 1587 |
| 1588 /// Creates a primitive for the default value of [parameter]. | |
| 1589 ir.Primitive translateDefaultValue(ParameterElement parameter) { | |
| 1590 if (parameter.initializer == null) { | |
| 1591 return irBuilder.buildNullLiteral(); | |
| 1592 } else { | |
| 1593 return inlineConstant(parameter.executableContext, parameter.initializer); | |
| 1594 } | |
| 1595 } | |
| 1596 | |
| 1597 /// Inserts default arguments and normalizes order of named arguments. | |
| 1598 List<ir.Primitive> normalizeStaticArguments( | |
| 1599 Selector selector, | |
| 1600 FunctionElement target, | |
| 1601 List<ir.Primitive> arguments) { | |
| 1602 target = target.implementation; | |
| 1603 FunctionSignature signature = target.functionSignature; | |
| 1604 if (!signature.optionalParametersAreNamed && | |
| 1605 signature.parameterCount == arguments.length) { | |
| 1606 // Optimization: don't copy the argument list for trivial cases. | |
| 1607 return arguments; | |
| 1608 } | |
| 1609 | |
| 1610 List<ir.Primitive> result = <ir.Primitive>[]; | |
| 1611 int i = 0; | |
| 1612 signature.forEachRequiredParameter((ParameterElement element) { | |
| 1613 result.add(arguments[i]); | |
| 1614 ++i; | |
| 1615 }); | |
| 1616 | |
| 1617 if (!signature.optionalParametersAreNamed) { | |
| 1618 signature.forEachOptionalParameter((ParameterElement element) { | |
| 1619 if (i < arguments.length) { | |
| 1620 result.add(arguments[i]); | |
| 1621 ++i; | |
| 1622 } else { | |
| 1623 result.add(translateDefaultValue(element)); | |
| 1624 } | |
| 1625 }); | |
| 1626 } else { | |
| 1627 int offset = i; | |
| 1628 // Iterate over the optional parameters of the signature, and try to | |
| 1629 // find them in [compiledNamedArguments]. If found, we use the | |
| 1630 // value in the temporary list, otherwise the default value. | |
| 1631 signature.orderedOptionalParameters.forEach((ParameterElement element) { | |
| 1632 int nameIndex = selector.namedArguments.indexOf(element.name); | |
| 1633 if (nameIndex != -1) { | |
| 1634 int translatedIndex = offset + nameIndex; | |
| 1635 result.add(arguments[translatedIndex]); | |
| 1636 } else { | |
| 1637 result.add(translateDefaultValue(element)); | |
| 1638 } | |
| 1639 }); | |
| 1640 } | |
| 1641 return result; | |
| 1642 } | |
| 1643 | |
| 1644 /// Normalizes order of named arguments. | |
| 1645 List<ir.Primitive> normalizeDynamicArguments( | |
| 1646 Selector selector, | |
| 1647 List<ir.Primitive> arguments) { | |
| 1648 assert(arguments.length == selector.argumentCount); | |
| 1649 // Optimization: don't copy the argument list for trivial cases. | |
| 1650 if (selector.namedArguments.isEmpty) return arguments; | |
| 1651 List<ir.Primitive> result = <ir.Primitive>[]; | |
| 1652 for (int i=0; i < selector.positionalArgumentCount; i++) { | |
| 1653 result.add(arguments[i]); | |
| 1654 } | |
| 1655 for (String argName in selector.getOrderedNamedArguments()) { | |
| 1656 int nameIndex = selector.namedArguments.indexOf(argName); | |
| 1657 int translatedIndex = selector.positionalArgumentCount + nameIndex; | |
| 1658 result.add(arguments[translatedIndex]); | |
| 1659 } | |
| 1660 return result; | |
| 1661 } | |
| 1662 | |
| 1554 } | 1663 } |
| 1555 | 1664 |
| OLD | NEW |