| 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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 /** | 137 /** |
| 138 * Builds the [ir.ExecutableDefinition] for an executable element. In case the | 138 * Builds the [ir.ExecutableDefinition] for an executable element. In case the |
| 139 * function uses features that cannot be expressed in the IR, this element | 139 * function uses features that cannot be expressed in the IR, this element |
| 140 * returns `null`. | 140 * returns `null`. |
| 141 */ | 141 */ |
| 142 ir.ExecutableDefinition buildExecutable(ExecutableElement element); | 142 ir.ExecutableDefinition buildExecutable(ExecutableElement element); |
| 143 | 143 |
| 144 ClosureScope getClosureScopeForNode(ast.Node node); | 144 ClosureScope getClosureScopeForNode(ast.Node node); |
| 145 ClosureEnvironment getClosureEnvironment(); | 145 ClosureEnvironment getClosureEnvironment(); |
| 146 | 146 |
| 147 /// Normalizes the argument list to a static invocation (i.e. where the target | |
| 148 /// element is known). | |
| 149 /// | |
| 150 /// For the JS backend, inserts default arguments and normalizes order of | |
| 151 /// named arguments. | |
| 152 /// | |
| 153 /// For the Dart backend, returns [arguments]. | |
| 154 List<ir.Primitive> normalizeStaticArguments( | |
| 155 Selector selector, | |
| 156 FunctionElement target, | |
| 157 List<ir.Primitive> arguments); | |
| 158 | 147 |
| 159 /// Normalizes the argument list of a dynamic invocation (i.e. where the | |
| 160 /// target element is unknown). | |
| 161 /// | |
| 162 /// For the JS backend, normalizes order of named arguments. | |
| 163 /// | |
| 164 /// For the Dart backend, returns [arguments]. | |
| 165 List<ir.Primitive> normalizeDynamicArguments( | |
| 166 Selector selector, | |
| 167 List<ir.Primitive> arguments); | |
| 168 | 148 |
| 169 ir.FunctionDefinition _makeFunctionBody(FunctionElement element, | 149 ir.FunctionDefinition _makeFunctionBody(FunctionElement element, |
| 170 ast.FunctionExpression node) { | 150 ast.FunctionExpression node) { |
| 171 FunctionSignature signature = element.functionSignature; | 151 FunctionSignature signature = element.functionSignature; |
| 172 List<ParameterElement> parameters = []; | 152 List<ParameterElement> parameters = []; |
| 173 signature.orderedForEachParameter(parameters.add); | 153 signature.orderedForEachParameter(parameters.add); |
| 174 | 154 |
| 175 irBuilder.buildFunctionHeader(parameters, | 155 irBuilder.buildFunctionHeader(parameters, |
| 176 closureScope: getClosureScopeForNode(node), | 156 closureScope: getClosureScopeForNode(node), |
| 177 env: getClosureEnvironment()); | 157 env: getClosureEnvironment()); |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 } | 542 } |
| 563 | 543 |
| 564 ir.Primitive visitNamedArgument(ast.NamedArgument node) { | 544 ir.Primitive visitNamedArgument(ast.NamedArgument node) { |
| 565 assert(irBuilder.isOpen); | 545 assert(irBuilder.isOpen); |
| 566 return visit(node.expression); | 546 return visit(node.expression); |
| 567 } | 547 } |
| 568 | 548 |
| 569 ir.Primitive visitClosureSend(ast.Send node) { | 549 ir.Primitive visitClosureSend(ast.Send node) { |
| 570 assert(irBuilder.isOpen); | 550 assert(irBuilder.isOpen); |
| 571 Element element = elements[node]; | 551 Element element = elements[node]; |
| 572 Selector selector = elements.getSelector(node); | 552 Selector closureSelector = elements.getSelector(node); |
| 573 ir.Primitive receiver = (element == null) | 553 if (element == null) { |
| 574 ? visit(node.selector) | 554 ir.Primitive closureTarget = visit(node.selector); |
| 575 : irBuilder.buildLocalGet(element); | 555 List<ir.Primitive> args = |
| 576 List<ir.Primitive> arguments = node.arguments.mapToList(visit); | 556 node.arguments.mapToList(visit, growable:false); |
| 577 arguments = normalizeDynamicArguments(selector, arguments); | 557 return irBuilder.buildFunctionExpressionInvocation( |
| 578 return irBuilder.buildFunctionExpressionInvocation( | 558 closureTarget, elements.getSelector(node), args); |
| 579 receiver, selector, arguments); | 559 } else { |
| 560 List<ir.Primitive> args = |
| 561 node.arguments.mapToList(visit, growable:false); |
| 562 return irBuilder.buildLocalInvocation( |
| 563 element, elements.getSelector(node), args); |
| 564 } |
| 580 } | 565 } |
| 581 | 566 |
| 582 /// If [node] is null, returns this. | 567 /// If [node] is null, returns this. |
| 583 /// If [node] is super, returns null (for special handling) | 568 /// If [node] is super, returns null (for special handling) |
| 584 /// Otherwise visits [node] and returns the result. | 569 /// Otherwise visits [node] and returns the result. |
| 585 ir.Primitive visitReceiver(ast.Expression node) { | 570 ir.Primitive visitReceiver(ast.Expression node) { |
| 586 if (node == null) return irBuilder.buildThis(); | 571 if (node == null) return irBuilder.buildThis(); |
| 587 if (node.isSuper()) return null; | 572 if (node.isSuper()) return null; |
| 588 return visit(node); | 573 return visit(node); |
| 589 } | 574 } |
| 590 | 575 |
| 591 /// Returns `true` if [node] is a super call. | 576 /// Returns `true` if [node] is a super call. |
| 592 // TODO(johnniwinther): Remove the need for this. | 577 // TODO(johnniwinther): Remove the need for this. |
| 593 bool isSuperCall(ast.Send node) { | 578 bool isSuperCall(ast.Send node) { |
| 594 return node != null && node.receiver != null && node.receiver.isSuper(); | 579 return node != null && node.receiver != null && node.receiver.isSuper(); |
| 595 } | 580 } |
| 596 | 581 |
| 597 ir.Primitive visitDynamicSend(ast.Send node) { | 582 ir.Primitive visitDynamicSend(ast.Send node) { |
| 598 assert(irBuilder.isOpen); | 583 assert(irBuilder.isOpen); |
| 599 Selector selector = elements.getSelector(node); | 584 Selector selector = elements.getSelector(node); |
| 600 ir.Primitive receiver = visitReceiver(node.receiver); | 585 ir.Primitive receiver = visitReceiver(node.receiver); |
| 601 List<ir.Primitive> arguments = node.arguments.mapToList(visit); | 586 List<ir.Primitive> arguments = new List<ir.Primitive>(); |
| 602 arguments = normalizeDynamicArguments(selector, arguments); | 587 for (ast.Node n in node.arguments) { |
| 588 arguments.add(visit(n)); |
| 589 } |
| 603 return irBuilder.buildDynamicInvocation(receiver, selector, arguments); | 590 return irBuilder.buildDynamicInvocation(receiver, selector, arguments); |
| 604 } | 591 } |
| 605 | 592 |
| 606 _GetterElements translateGetter(ast.Send node, Selector selector) { | 593 _GetterElements translateGetter(ast.Send node, Selector selector) { |
| 607 Element element = elements[node]; | 594 Element element = elements[node]; |
| 608 ir.Primitive result; | 595 ir.Primitive result; |
| 609 ir.Primitive receiver; | 596 ir.Primitive receiver; |
| 610 ir.Primitive index; | 597 ir.Primitive index; |
| 611 | 598 |
| 612 if (element != null && element.isConst) { | 599 if (element != null && element.isConst) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 assert(irBuilder.isOpen); | 705 assert(irBuilder.isOpen); |
| 719 Element element = elements[node]; | 706 Element element = elements[node]; |
| 720 assert(!element.isConstructor); | 707 assert(!element.isConstructor); |
| 721 // TODO(lry): support foreign functions. | 708 // TODO(lry): support foreign functions. |
| 722 if (element.isForeign(compiler.backend)) { | 709 if (element.isForeign(compiler.backend)) { |
| 723 return giveup(node, 'StaticSend: foreign'); | 710 return giveup(node, 'StaticSend: foreign'); |
| 724 } | 711 } |
| 725 | 712 |
| 726 Selector selector = elements.getSelector(node); | 713 Selector selector = elements.getSelector(node); |
| 727 | 714 |
| 715 // TODO(lry): support default arguments, need support for locals. |
| 728 List<ir.Primitive> arguments = | 716 List<ir.Primitive> arguments = |
| 729 node.arguments.mapToList(visit, growable:false); | 717 node.arguments.mapToList(visit, growable:false); |
| 730 arguments = normalizeStaticArguments(selector, element, arguments); | |
| 731 return irBuilder.buildStaticInvocation(element, selector, arguments); | 718 return irBuilder.buildStaticInvocation(element, selector, arguments); |
| 732 } | 719 } |
| 733 | 720 |
| 734 ir.Primitive visitSuperSend(ast.Send node) { | 721 ir.Primitive visitSuperSend(ast.Send node) { |
| 735 assert(irBuilder.isOpen); | 722 assert(irBuilder.isOpen); |
| 736 if (node.isPropertyAccess) { | 723 if (node.isPropertyAccess) { |
| 737 return visitGetterSend(node); | 724 return visitGetterSend(node); |
| 738 } else { | 725 } else { |
| 739 Selector selector = elements.getSelector(node); | 726 Selector selector = elements.getSelector(node); |
| 740 Element target = elements[node]; | 727 Element target = elements[node]; |
| 741 List<ir.Primitive> arguments = node.arguments.mapToList(visit); | 728 List<ir.Primitive> arguments = new List<ir.Primitive>(); |
| 742 arguments = normalizeStaticArguments(selector, target, arguments); | 729 for (ast.Node n in node.arguments) { |
| 730 arguments.add(visit(n)); |
| 731 } |
| 743 return irBuilder.buildSuperInvocation(target, selector, arguments); | 732 return irBuilder.buildSuperInvocation(target, selector, arguments); |
| 744 } | 733 } |
| 745 } | 734 } |
| 746 | 735 |
| 747 visitTypePrefixSend(ast.Send node) { | 736 visitTypePrefixSend(ast.Send node) { |
| 748 compiler.internalError(node, "visitTypePrefixSend should not be called."); | 737 compiler.internalError(node, "visitTypePrefixSend should not be called."); |
| 749 } | 738 } |
| 750 | 739 |
| 751 ir.Primitive visitTypeLiteralSend(ast.Send node) { | 740 ir.Primitive visitTypeLiteralSend(ast.Send node) { |
| 752 assert(irBuilder.isOpen); | 741 assert(irBuilder.isOpen); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 } | 854 } |
| 866 | 855 |
| 867 ir.Primitive visitNewExpression(ast.NewExpression node) { | 856 ir.Primitive visitNewExpression(ast.NewExpression node) { |
| 868 if (node.isConst) { | 857 if (node.isConst) { |
| 869 return translateConstant(node); | 858 return translateConstant(node); |
| 870 } | 859 } |
| 871 FunctionElement element = elements[node.send]; | 860 FunctionElement element = elements[node.send]; |
| 872 Selector selector = elements.getSelector(node.send); | 861 Selector selector = elements.getSelector(node.send); |
| 873 DartType type = elements.getType(node); | 862 DartType type = elements.getType(node); |
| 874 ast.Node selectorNode = node.send.selector; | 863 ast.Node selectorNode = node.send.selector; |
| 875 List<ir.Primitive> arguments = | 864 List<ir.Definition> arguments = |
| 876 node.send.arguments.mapToList(visit, growable:false); | 865 node.send.arguments.mapToList(visit, growable:false); |
| 877 arguments = normalizeStaticArguments(selector, element, arguments); | |
| 878 return irBuilder.buildConstructorInvocation( | 866 return irBuilder.buildConstructorInvocation( |
| 879 element, selector, type, arguments); | 867 element, selector, type, arguments); |
| 880 } | 868 } |
| 881 | 869 |
| 882 ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) { | 870 ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) { |
| 883 assert(irBuilder.isOpen); | 871 assert(irBuilder.isOpen); |
| 884 ir.Primitive first = visit(node.first); | 872 ir.Primitive first = visit(node.first); |
| 885 ir.Primitive second = visit(node.second); | 873 ir.Primitive second = visit(node.second); |
| 886 return irBuilder.buildStringConcatenation([first, second]); | 874 return irBuilder.buildStringConcatenation([first, second]); |
| 887 } | 875 } |
| 888 | 876 |
| 889 ir.Primitive visitStringInterpolation(ast.StringInterpolation node) { | 877 ir.Primitive visitStringInterpolation(ast.StringInterpolation node) { |
| 890 assert(irBuilder.isOpen); | 878 assert(irBuilder.isOpen); |
| 891 List<ir.Primitive> arguments = []; | 879 List<ir.Primitive> arguments = []; |
| 892 arguments.add(visitLiteralString(node.string)); | 880 arguments.add(visitLiteralString(node.string)); |
| 893 var it = node.parts.iterator; | 881 var it = node.parts.iterator; |
| 894 while (it.moveNext()) { | 882 while (it.moveNext()) { |
| 895 ast.StringInterpolationPart part = it.current; | 883 ast.StringInterpolationPart part = it.current; |
| 896 arguments.add(visit(part.expression)); | 884 arguments.add(visit(part.expression)); |
| 897 arguments.add(visitLiteralString(part.string)); | 885 arguments.add(visitLiteralString(part.string)); |
| 898 } | 886 } |
| 899 return irBuilder.buildStringConcatenation(arguments); | 887 return irBuilder.buildStringConcatenation(arguments); |
| 900 } | 888 } |
| 901 | 889 |
| 902 ir.Primitive translateConstant(ast.Node node) { | 890 ir.Primitive translateConstant(ast.Node node, [ConstantExpression constant]) { |
| 903 assert(irBuilder.isOpen); | 891 assert(irBuilder.isOpen); |
| 904 return irBuilder.buildConstantLiteral(getConstantForNode(node)); | 892 if (constant == null) { |
| 893 constant = getConstantForNode(node); |
| 894 } |
| 895 return irBuilder.buildConstantLiteral(constant); |
| 905 } | 896 } |
| 906 | 897 |
| 907 ir.ExecutableDefinition nullIfGiveup(ir.ExecutableDefinition action()) { | 898 ir.ExecutableDefinition nullIfGiveup(ir.ExecutableDefinition action()) { |
| 908 try { | 899 try { |
| 909 return action(); | 900 return action(); |
| 910 } catch(e, tr) { | 901 } catch(e, tr) { |
| 911 if (e == ABORT_IRNODE_BUILDER) { | 902 if (e == ABORT_IRNODE_BUILDER) { |
| 912 return null; | 903 return null; |
| 913 } | 904 } |
| 914 rethrow; | 905 rethrow; |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1109 SynthesizedConstructorElementX constructor = element; | 1100 SynthesizedConstructorElementX constructor = element; |
| 1110 if (!constructor.isDefaultConstructor) { | 1101 if (!constructor.isDefaultConstructor) { |
| 1111 giveup(null, 'cannot handle synthetic forwarding constructors'); | 1102 giveup(null, 'cannot handle synthetic forwarding constructors'); |
| 1112 } | 1103 } |
| 1113 } | 1104 } |
| 1114 | 1105 |
| 1115 IrBuilder builder = makeIRBuilder(node, element); | 1106 IrBuilder builder = makeIRBuilder(node, element); |
| 1116 | 1107 |
| 1117 return withBuilder(builder, () => _makeFunctionBody(element, node)); | 1108 return withBuilder(builder, () => _makeFunctionBody(element, node)); |
| 1118 } | 1109 } |
| 1119 | |
| 1120 List<ir.Primitive> normalizeStaticArguments( | |
| 1121 Selector selector, | |
| 1122 FunctionElement target, | |
| 1123 List<ir.Primitive> arguments) { | |
| 1124 return arguments; | |
| 1125 } | |
| 1126 | |
| 1127 List<ir.Primitive> normalizeDynamicArguments( | |
| 1128 Selector selector, | |
| 1129 List<ir.Primitive> arguments) { | |
| 1130 return arguments; | |
| 1131 } | |
| 1132 } | 1110 } |
| 1133 | 1111 |
| 1134 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. | 1112 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. |
| 1135 class JsIrBuilderVisitor extends IrBuilderVisitor { | 1113 class JsIrBuilderVisitor extends IrBuilderVisitor { |
| 1136 /// Promote the type of [irBuilder] to [JsIrBuilder]. | 1114 /// Promote the type of [irBuilder] to [JsIrBuilder]. |
| 1137 JsIrBuilder get irBuilder => super.irBuilder; | 1115 JsIrBuilder get irBuilder => super.irBuilder; |
| 1138 | 1116 |
| 1139 /// Result of closure conversion for the current body of code. | 1117 /// Result of closure conversion for the current body of code. |
| 1140 /// | 1118 /// |
| 1141 /// Will be initialized upon entering the body of a function. | 1119 /// Will be initialized upon entering the body of a function. |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1257 /// Such expressions need to be compiled with a different [sourceFile] and | 1235 /// Such expressions need to be compiled with a different [sourceFile] and |
| 1258 /// [elements] mapping. | 1236 /// [elements] mapping. |
| 1259 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { | 1237 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { |
| 1260 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( | 1238 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( |
| 1261 context.resolvedAst.elements, | 1239 context.resolvedAst.elements, |
| 1262 compiler, | 1240 compiler, |
| 1263 elementSourceFile(context)); | 1241 elementSourceFile(context)); |
| 1264 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); | 1242 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); |
| 1265 } | 1243 } |
| 1266 | 1244 |
| 1267 /// Builds the IR for a constant taken from a different [context]. | |
| 1268 /// | |
| 1269 /// Such constants need to be compiled with a different [sourceFile] and | |
| 1270 /// [elements] mapping. | |
| 1271 ir.Primitive inlineConstant(AstElement context, ast.Expression exp) { | |
| 1272 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( | |
| 1273 context.resolvedAst.elements, | |
| 1274 compiler, | |
| 1275 elementSourceFile(context)); | |
| 1276 return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp)); | |
| 1277 } | |
| 1278 | |
| 1279 /// Builds the IR for a given constructor. | 1245 /// Builds the IR for a given constructor. |
| 1280 /// | 1246 /// |
| 1281 /// 1. Evaluates all own or inherited field initializers. | 1247 /// 1. Evaluates all own or inherited field initializers. |
| 1282 /// 2. Creates the object and assigns its fields. | 1248 /// 2. Creates the object and assigns its fields. |
| 1283 /// 3. Calls constructor body and super constructor bodies. | 1249 /// 3. Calls constructor body and super constructor bodies. |
| 1284 /// 4. Returns the created object. | 1250 /// 4. Returns the created object. |
| 1285 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { | 1251 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { |
| 1286 constructor = constructor.implementation; | 1252 constructor = constructor.implementation; |
| 1287 ClassElement classElement = constructor.enclosingClass.implementation; | 1253 ClassElement classElement = constructor.enclosingClass.implementation; |
| 1288 | 1254 |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1573 | 1539 |
| 1574 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( | 1540 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( |
| 1575 element, | 1541 element, |
| 1576 node, | 1542 node, |
| 1577 elements); | 1543 elements); |
| 1578 IrBuilder builder = | 1544 IrBuilder builder = |
| 1579 new JsIrBuilder(compiler.backend.constantSystem, element); | 1545 new JsIrBuilder(compiler.backend.constantSystem, element); |
| 1580 return withBuilder(builder, () => _makeFunctionBody(element, node)); | 1546 return withBuilder(builder, () => _makeFunctionBody(element, node)); |
| 1581 } | 1547 } |
| 1582 | 1548 |
| 1583 /// Creates a primitive for the default value of [parameter]. | |
| 1584 ir.Primitive translateDefaultValue(ParameterElement parameter) { | |
| 1585 if (parameter.initializer == null) { | |
| 1586 return irBuilder.buildNullLiteral(); | |
| 1587 } else { | |
| 1588 return inlineConstant(parameter.executableContext, parameter.initializer); | |
| 1589 } | |
| 1590 } | |
| 1591 | |
| 1592 /// Inserts default arguments and normalizes order of named arguments. | |
| 1593 List<ir.Primitive> normalizeStaticArguments( | |
| 1594 Selector selector, | |
| 1595 FunctionElement target, | |
| 1596 List<ir.Primitive> arguments) { | |
| 1597 target = target.implementation; | |
| 1598 FunctionSignature signature = target.functionSignature; | |
| 1599 if (!signature.optionalParametersAreNamed && | |
| 1600 signature.parameterCount == arguments.length) { | |
| 1601 // Optimization: don't copy the argument list for trivial cases. | |
| 1602 return arguments; | |
| 1603 } | |
| 1604 | |
| 1605 List<ir.Primitive> result = <ir.Primitive>[]; | |
| 1606 int i = 0; | |
| 1607 signature.forEachRequiredParameter((ParameterElement element) { | |
| 1608 result.add(arguments[i]); | |
| 1609 ++i; | |
| 1610 }); | |
| 1611 | |
| 1612 if (!signature.optionalParametersAreNamed) { | |
| 1613 signature.forEachOptionalParameter((ParameterElement element) { | |
| 1614 if (i < arguments.length) { | |
| 1615 result.add(arguments[i]); | |
| 1616 ++i; | |
| 1617 } else { | |
| 1618 result.add(translateDefaultValue(element)); | |
| 1619 } | |
| 1620 }); | |
| 1621 } else { | |
| 1622 int offset = i; | |
| 1623 // Iterate over the optional parameters of the signature, and try to | |
| 1624 // find them in [compiledNamedArguments]. If found, we use the | |
| 1625 // value in the temporary list, otherwise the default value. | |
| 1626 signature.orderedOptionalParameters.forEach((ParameterElement element) { | |
| 1627 int nameIndex = selector.namedArguments.indexOf(element.name); | |
| 1628 if (nameIndex != -1) { | |
| 1629 int translatedIndex = offset + nameIndex; | |
| 1630 result.add(arguments[translatedIndex]); | |
| 1631 } else { | |
| 1632 result.add(translateDefaultValue(element)); | |
| 1633 } | |
| 1634 }); | |
| 1635 } | |
| 1636 return result; | |
| 1637 } | |
| 1638 | |
| 1639 /// Normalizes order of named arguments. | |
| 1640 List<ir.Primitive> normalizeDynamicArguments( | |
| 1641 Selector selector, | |
| 1642 List<ir.Primitive> arguments) { | |
| 1643 assert(arguments.length == selector.argumentCount); | |
| 1644 // Optimization: don't copy the argument list for trivial cases. | |
| 1645 if (selector.namedArguments.isEmpty) return arguments; | |
| 1646 List<ir.Primitive> result = <ir.Primitive>[]; | |
| 1647 for (int i=0; i < selector.positionalArgumentCount; i++) { | |
| 1648 result.add(arguments[i]); | |
| 1649 } | |
| 1650 for (String argName in selector.getOrderedNamedArguments()) { | |
| 1651 int nameIndex = selector.namedArguments.indexOf(argName); | |
| 1652 int translatedIndex = selector.positionalArgumentCount + nameIndex; | |
| 1653 result.add(arguments[translatedIndex]); | |
| 1654 } | |
| 1655 return result; | |
| 1656 } | |
| 1657 | |
| 1658 } | 1549 } |
| 1659 | 1550 |
| OLD | NEW |