Chromium Code Reviews| Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
| diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
| index 829f94247f275b8b74420fbd4198d44d03a7f38b..bd11dbda8303fe5dbf8119b7d983dba303064b8b 100644 |
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart |
| @@ -185,25 +185,25 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| ClosureScope getClosureScopeForNode(ast.Node node); |
| ClosureEnvironment getClosureEnvironment(); |
| - /// Normalizes the argument list to a static invocation (i.e. where the target |
| - /// element is known). |
| + /// Normalizes the argument list of a static invocation. |
| /// |
| - /// For the JS backend, inserts default arguments and normalizes order of |
| - /// named arguments. |
| - /// |
| - /// For the Dart backend, returns [arguments]. |
| - List<ir.Primitive> normalizeStaticArguments( |
| + /// A static invocation is one where the target is known. The argument list |
| + /// [arguments] is normalized by adding default values for optional arguments |
| + /// that are not passed, and by sorting it in place so that named arguments |
| + /// appear in a canonical order. A [CallStructure] reflecting this order |
| + /// is returned. |
| + CallStructure normalizeStaticArguments( |
| CallStructure callStructure, |
| FunctionElement target, |
| List<ir.Primitive> arguments); |
| - /// Normalizes the argument list of a dynamic invocation (i.e. where the |
| - /// target element is unknown). |
| - /// |
| - /// For the JS backend, normalizes order of named arguments. |
| + /// Normalizes the argument list of a dynamic invocation. |
| /// |
| - /// For the Dart backend, returns [arguments]. |
| - List<ir.Primitive> normalizeDynamicArguments( |
| + /// A dynamic invocation is one where the target is not known. The argument |
| + /// list [arguments] is normalized by sorting it in place so that the named |
| + /// arguments appear in a canonical order. A [CallStructure] reflecting this |
| + /// order is returned. |
| + CallStructure normalizeDynamicArguments( |
| CallStructure callStructure, |
| List<ir.Primitive> arguments); |
| @@ -316,8 +316,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| CallStructure callStructure = new CallStructure( |
| redirectingSignature.parameterCount, |
| namedParameters); |
| - arguments = normalizeStaticArguments(callStructure, targetConstructor, |
| - arguments); |
| + callStructure = normalizeStaticArguments( |
| + callStructure, targetConstructor, arguments); |
| ir.Primitive instance = irBuilder.buildConstructorInvocation( |
| targetConstructor, |
| callStructure, |
| @@ -720,9 +720,10 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| CallStructure callStructure, _) { |
| ir.Primitive receiver = visit(expression); |
| List<ir.Primitive> arguments = node.arguments.mapToList(visit); |
| - arguments = normalizeDynamicArguments(callStructure, arguments); |
| + CallStructure normalizedCallStructure = |
| + normalizeDynamicArguments(callStructure, arguments); |
| return irBuilder.buildCallInvocation( |
| - receiver, callStructure, arguments, |
| + receiver, normalizedCallStructure, arguments, |
| sourceInformation: |
| sourceInformationBuilder.buildCall(node, argumentsNode)); |
| } |
| @@ -953,9 +954,13 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| Selector selector = new Selector.binaryOperator(operator.selectorName); |
| ir.Primitive receiver = visit(left); |
| List<ir.Primitive> arguments = <ir.Primitive>[visit(right)]; |
| - arguments = normalizeDynamicArguments(selector.callStructure, arguments); |
| + CallStructure callStructure = |
| + normalizeDynamicArguments(selector.callStructure, arguments); |
| return irBuilder.buildDynamicInvocation( |
| - receiver, selector, elements.getTypeMask(node), arguments, |
| + receiver, |
| + new Selector(selector.kind, selector.memberName, callStructure), |
| + elements.getTypeMask(node), |
| + arguments, |
| sourceInformation: |
| sourceInformationBuilder.buildCall(node, node.selector)); |
| } |
| @@ -975,9 +980,13 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| Selector selector = new Selector.index(); |
| ir.Primitive target = visit(receiver); |
| List<ir.Primitive> arguments = <ir.Primitive>[visit(index)]; |
| - arguments = normalizeDynamicArguments(selector.callStructure, arguments); |
| + CallStructure callStructure = |
| + normalizeDynamicArguments(selector.callStructure, arguments); |
| return irBuilder.buildDynamicInvocation( |
| - target, selector, elements.getTypeMask(node), arguments, |
| + target, |
| + new Selector(selector.kind, selector.memberName, callStructure), |
| + elements.getTypeMask(node), |
| + arguments, |
| sourceInformation: |
| sourceInformationBuilder.buildCall(receiver, node.selector)); |
| } |
| @@ -985,9 +994,9 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| ir.Primitive translateSuperBinary(FunctionElement function, |
| op.BinaryOperator operator, |
| ast.Node argument) { |
| - CallStructure callStructure = CallStructure.ONE_ARG; |
| List<ir.Primitive> arguments = <ir.Primitive>[visit(argument)]; |
| - arguments = normalizeDynamicArguments(callStructure, arguments); |
| + CallStructure callStructure = |
| + normalizeDynamicArguments(CallStructure.ONE_ARG, arguments); |
| return irBuilder.buildSuperMethodInvocation( |
| function, callStructure, arguments); |
| } |
| @@ -1081,18 +1090,22 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct |
| // semantic correlation between arguments and invocation. |
| - List<ir.Primitive> translateDynamicArguments(ast.NodeList nodeList, |
| - CallStructure callStructure) { |
| - List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit); |
| + CallStructure translateDynamicArguments(ast.NodeList nodeList, |
| + CallStructure callStructure, |
| + List<ir.Primitive> arguments) { |
| + assert(arguments.isEmpty); |
| + for (ast.Node node in nodeList) arguments.add(visit(node)); |
| return normalizeDynamicArguments(callStructure, arguments); |
| } |
| // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct |
| // semantic correlation between arguments and invocation. |
| - List<ir.Primitive> translateStaticArguments(ast.NodeList nodeList, |
| - Element element, |
| - CallStructure callStructure) { |
| - List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit); |
| + CallStructure translateStaticArguments(ast.NodeList nodeList, |
| + Element element, |
| + CallStructure callStructure, |
| + List<ir.Primitive> arguments) { |
| + assert(arguments.isEmpty); |
| + for (ast.Node node in nodeList) arguments.add(visit(node)); |
| return normalizeStaticArguments(callStructure, element, arguments); |
| } |
| @@ -1100,9 +1113,11 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| ast.NodeList arguments, |
| CallStructure callStructure, |
| SourceInformation sourceInformation) { |
| - |
| - return irBuilder.buildCallInvocation(target, callStructure, |
| - translateDynamicArguments(arguments, callStructure), |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + CallStructure normalizedCallStructure = translateDynamicArguments( |
| + arguments, callStructure, normalizedArguments); |
| + return irBuilder.buildCallInvocation(target, normalizedCallStructure, |
| + normalizedArguments, |
| sourceInformation: sourceInformation); |
| } |
| @@ -1126,9 +1141,16 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| ast.NodeList arguments, |
| Selector selector, |
| _) { |
| + ir.Primitive target = translateReceiver(receiver); |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + CallStructure normalizedCallStructure = translateDynamicArguments( |
| + arguments, selector.callStructure, normalizedArguments); |
| return irBuilder.buildDynamicInvocation( |
| - translateReceiver(receiver), selector, elements.getTypeMask(node), |
| - translateDynamicArguments(arguments, selector.callStructure), |
| + target, |
| + new Selector(selector.kind, selector.memberName, |
| + normalizedCallStructure), |
| + elements.getTypeMask(node), |
| + normalizedArguments, |
| sourceInformation: |
| sourceInformationBuilder.buildCall(node, node.selector)); |
| } |
| @@ -1143,9 +1165,17 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| ir.Primitive target = visit(receiver); |
| return irBuilder.buildIfNotNullSend( |
| target, |
| - nested(() => irBuilder.buildDynamicInvocation( |
| - target, selector, elements.getTypeMask(node), |
| - translateDynamicArguments(arguments, selector.callStructure)))); |
| + nested(() { |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + CallStructure normalizedCallStructure = translateDynamicArguments( |
| + arguments, selector.callStructure, normalizedArguments); |
| + return irBuilder.buildDynamicInvocation( |
| + target, |
| + new Selector(selector.kind, selector.memberName, |
| + normalizedCallStructure), |
| + elements.getTypeMask(node), |
| + normalizedArguments); |
| + })); |
| } |
| ir.Primitive handleLocalInvoke( |
| @@ -1154,8 +1184,13 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| ast.NodeList arguments, |
| CallStructure callStructure, |
| _) { |
| - return irBuilder.buildLocalVariableInvocation(element, callStructure, |
| - translateDynamicArguments(arguments, callStructure), |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + CallStructure normalizedCallStructure = translateDynamicArguments( |
| + arguments, callStructure, normalizedArguments); |
| + return irBuilder.buildLocalVariableInvocation( |
| + element, |
| + normalizedCallStructure, |
| + normalizedArguments, |
| callSourceInformation: |
| sourceInformationBuilder.buildCall(node, arguments)); |
| } |
| @@ -1167,8 +1202,13 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| ast.NodeList arguments, |
| CallStructure callStructure, |
| _) { |
| - return irBuilder.buildLocalFunctionInvocation(function, callStructure, |
| - translateDynamicArguments(arguments, callStructure), |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + CallStructure normalizedCallStructure = translateDynamicArguments( |
| + arguments, callStructure, normalizedArguments); |
| + return irBuilder.buildLocalFunctionInvocation( |
| + function, |
| + normalizedCallStructure, |
| + normalizedArguments, |
| sourceInformationBuilder.buildCall(node, arguments)); |
| } |
| @@ -1186,9 +1226,13 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| _) { |
| SourceInformation src = sourceInformationBuilder.buildGet(node); |
| ir.Primitive target = buildStaticFieldGet(field, src); |
| - return irBuilder.buildCallInvocation(target, |
| - callStructure, |
| - translateDynamicArguments(arguments, callStructure), |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + CallStructure normalizedCallStructure = translateDynamicArguments( |
| + arguments, callStructure, normalizedArguments); |
| + return irBuilder.buildCallInvocation( |
| + target, |
| + normalizedCallStructure, |
| + normalizedArguments, |
| sourceInformation: |
| sourceInformationBuilder.buildCall(node, arguments)); |
| } |
| @@ -1221,9 +1265,13 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| _) { |
| ir.Primitive target = irBuilder.buildStaticGetterGet( |
| getter, sourceInformationBuilder.buildGet(node)); |
| - return irBuilder.buildCallInvocation(target, |
| - callStructure, |
| - translateDynamicArguments(arguments, callStructure), |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + CallStructure normalizedCallStructure = translateDynamicArguments( |
| + arguments, callStructure, normalizedArguments); |
| + return irBuilder.buildCallInvocation( |
| + target, |
| + normalizedCallStructure, |
| + normalizedArguments, |
| sourceInformation: |
| sourceInformationBuilder.buildCall(node, arguments)); |
| } |
| @@ -1236,9 +1284,13 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| CallStructure callStructure, |
| _) { |
| ir.Primitive target = irBuilder.buildSuperFieldGet(field); |
| - return irBuilder.buildCallInvocation(target, |
| - callStructure, |
| - translateDynamicArguments(arguments, callStructure), |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + CallStructure normalizedCallStructure = translateDynamicArguments( |
| + arguments, callStructure, normalizedArguments); |
| + return irBuilder.buildCallInvocation( |
| + target, |
| + normalizedCallStructure, |
| + normalizedArguments, |
| sourceInformation: |
| sourceInformationBuilder.buildCall(node, arguments)); |
| } |
| @@ -1252,9 +1304,13 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| _) { |
| ir.Primitive target = irBuilder.buildSuperGetterGet( |
| getter, sourceInformationBuilder.buildGet(node)); |
| - return irBuilder.buildCallInvocation(target, |
| - callStructure, |
| - translateDynamicArguments(arguments, callStructure), |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + CallStructure normalizedCallStructure = translateDynamicArguments( |
| + arguments, callStructure, normalizedArguments); |
| + return irBuilder.buildCallInvocation( |
| + target, |
| + normalizedCallStructure, |
| + normalizedArguments, |
| sourceInformation: |
| sourceInformationBuilder.buildCall(node, arguments)); |
| } |
| @@ -1266,8 +1322,13 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| ast.NodeList arguments, |
| CallStructure callStructure, |
| _) { |
| - return irBuilder.buildSuperMethodInvocation(method, callStructure, |
| - translateDynamicArguments(arguments, callStructure), |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + CallStructure normalizedCallStructure = translateDynamicArguments( |
| + arguments, callStructure, normalizedArguments); |
| + return irBuilder.buildSuperMethodInvocation( |
| + method, |
| + normalizedCallStructure, |
| + normalizedArguments, |
| sourceInformation: |
| sourceInformationBuilder.buildCall(node, node.selector)); |
| } |
| @@ -1278,10 +1339,12 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| MethodElement method, |
| ast.NodeList arguments, |
| CallStructure callStructure, _) { |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + translateDynamicArguments(arguments, callStructure, normalizedArguments); |
| return buildInstanceNoSuchMethod( |
| elements.getSelector(node), |
|
Kevin Millikin (Google)
2015/12/02 15:45:31
It's not obvious whether this selector should matc
Johnni Winther
2015/12/03 12:15:42
We should. Create the new selector by:
CallStruct
Kevin Millikin (Google)
2015/12/09 12:49:13
Done.
|
| elements.getTypeMask(node), |
| - translateDynamicArguments(arguments, callStructure)); |
| + normalizedArguments); |
| } |
| @override |
| @@ -1290,10 +1353,13 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| Element element, |
| ast.NodeList arguments, |
| Selector selector, _) { |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + translateDynamicArguments(arguments, selector.callStructure, |
| + normalizedArguments); |
| return buildInstanceNoSuchMethod( |
| elements.getSelector(node), |
|
Kevin Millikin (Google)
2015/12/02 15:45:31
It's not obvious whether this selector should matc
Johnni Winther
2015/12/03 12:15:42
Also here. Obtain the member name from `elements.g
Kevin Millikin (Google)
2015/12/09 12:49:13
Done.
|
| elements.getTypeMask(node), |
| - translateDynamicArguments(arguments, selector.callStructure)); |
| + normalizedArguments); |
| } |
| @override |
| @@ -1371,15 +1437,19 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| rhsValue = irBuilder.buildIntegerConstant(1); |
| } |
| List<ir.Primitive> arguments = <ir.Primitive>[rhsValue]; |
| - arguments = normalizeDynamicArguments( |
| - operatorSelector.callStructure, arguments); |
| + CallStructure callStructure = |
| + normalizeDynamicArguments(operatorSelector.callStructure, arguments); |
| TypeMask operatorTypeMask = |
| elements.getOperatorTypeMaskInComplexSendSet(node); |
| SourceInformation operatorSourceInformation = |
| sourceInformationBuilder.buildCall(node, node.assignmentOperator); |
| ir.Primitive result = irBuilder.buildDynamicInvocation( |
| - value, operatorSelector, operatorTypeMask, arguments, |
| - sourceInformation: operatorSourceInformation); |
| + value, |
| + new Selector(operatorSelector.kind, operatorSelector.memberName, |
| + callStructure), |
| + operatorTypeMask, |
| + arguments, |
| + sourceInformation: operatorSourceInformation); |
| setValue(result); |
| return rhs.kind == CompoundKind.POSTFIX ? value : result; |
| } |
| @@ -1858,11 +1928,11 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| getValue: () { |
| Selector selector = new Selector.index(); |
| List<ir.Primitive> arguments = <ir.Primitive>[indexValue]; |
| - arguments = |
| + CallStructure callStructure = |
| normalizeDynamicArguments(selector.callStructure, arguments); |
| return irBuilder.buildDynamicInvocation( |
| target, |
| - selector, |
| + new Selector(selector.kind, selector.memberName, callStructure), |
| elements.getGetterTypeMaskInComplexSendSet(node), |
| arguments, |
| sourceInformation: |
| @@ -2011,8 +2081,10 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| ast.NodeList arguments, |
| Selector selector, _) { |
| // If the class is there but the constructor is missing, it's an NSM error. |
| - return buildStaticNoSuchMethod(selector, |
| - translateDynamicArguments(arguments, selector.callStructure)); |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + translateDynamicArguments(arguments, selector.callStructure, |
| + normalizedArguments); |
| + return buildStaticNoSuchMethod(selector, normalizedArguments); |
|
Kevin Millikin (Google)
2015/12/02 15:45:31
This selector doesn't seem to matter because it lo
Johnni Winther
2015/12/03 12:15:42
Similar to the super-cases above. We should normal
Kevin Millikin (Google)
2015/12/09 12:49:13
Done.
|
| } |
| @override |
| @@ -2022,8 +2094,10 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| DartType type, |
| ast.NodeList arguments, |
| CallStructure callStructure, _) { |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + translateDynamicArguments(arguments, callStructure, normalizedArguments); |
| return buildStaticNoSuchMethod(elements.getSelector(node.send), |
|
Kevin Millikin (Google)
2015/12/02 15:45:31
It's not clear if this selector should match the n
|
| - translateDynamicArguments(arguments, callStructure)); |
| + normalizedArguments); |
| } |
| @override |
| @@ -2052,9 +2126,12 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| CallStructure callStructure, _) { |
| String nameString = Elements.reconstructConstructorName(constructor); |
| Name name = new Name(nameString, constructor.library); |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + CallStructure normalizedCallStructure = translateDynamicArguments( |
| + arguments, callStructure, normalizedArguments); |
| return buildStaticNoSuchMethod( |
|
Kevin Millikin (Google)
2015/12/02 15:45:31
It's not clear if this selector should match the n
|
| - new Selector.call(name, callStructure), |
| - translateDynamicArguments(arguments, callStructure)); |
| + new Selector.call(name, normalizedCallStructure), |
| + normalizedArguments); |
| } |
| @override |
| @@ -2275,12 +2352,13 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| SetterElement setter, |
| ast.NodeList arguments, |
| CallStructure callStructure, _) { |
| - List<ir.Primitive> args = |
| - translateDynamicArguments(arguments, callStructure); |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + CallStructure normalizedCallStructure = translateDynamicArguments( |
| + arguments, callStructure, normalizedArguments); |
| return buildInstanceNoSuchMethod( |
| - new Selector.call(setter.memberName, callStructure), |
| + new Selector.call(setter.memberName, normalizedCallStructure), |
|
Kevin Millikin (Google)
2015/12/02 15:45:31
It's not obvious if this selector should match the
|
| elements.getTypeMask(node), |
| - args); |
| + normalizedArguments); |
| } |
| ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) { |
| @@ -3207,70 +3285,56 @@ class JsIrBuilderVisitor extends IrBuilderVisitor { |
| } |
| } |
| - /// Inserts default arguments and normalizes order of named arguments. |
| - List<ir.Primitive> normalizeStaticArguments( |
| - CallStructure callStructure, |
| - FunctionElement target, |
| - List<ir.Primitive> arguments) { |
| + CallStructure normalizeStaticArguments(CallStructure callStructure, |
| + FunctionElement target, |
| + List<ir.Primitive> arguments) { |
| target = target.implementation; |
| FunctionSignature signature = target.functionSignature; |
| if (!signature.optionalParametersAreNamed && |
| signature.parameterCount == arguments.length) { |
| - // Optimization: don't copy the argument list for trivial cases. |
| - return arguments; |
| + return callStructure; |
| } |
| - List<ir.Primitive> result = <ir.Primitive>[]; |
| - int i = 0; |
| - signature.forEachRequiredParameter((ParameterElement element) { |
| - result.add(arguments[i]); |
| - ++i; |
| - }); |
| - |
| if (!signature.optionalParametersAreNamed) { |
| + int i = signature.requiredParameterCount; |
| signature.forEachOptionalParameter((ParameterElement element) { |
| - if (i < arguments.length) { |
| - result.add(arguments[i]); |
| + if (i < callStructure.positionalArgumentCount) { |
| ++i; |
| } else { |
| - result.add(translateDefaultValue(element)); |
| - } |
| - }); |
| - } else { |
| - int offset = i; |
| - // Iterate over the optional parameters of the signature, and try to |
| - // find them in [compiledNamedArguments]. If found, we use the |
| - // value in the temporary list, otherwise the default value. |
| - signature.orderedOptionalParameters.forEach((ParameterElement element) { |
| - int nameIndex = callStructure.namedArguments.indexOf(element.name); |
| - if (nameIndex != -1) { |
| - int translatedIndex = offset + nameIndex; |
| - result.add(arguments[translatedIndex]); |
| - } else { |
| - result.add(translateDefaultValue(element)); |
| + arguments.add(translateDefaultValue(element)); |
| } |
| }); |
| + return new CallStructure(signature.parameterCount); |
| } |
| - return result; |
| + |
| + int offset = signature.requiredParameterCount; |
| + List<ir.Primitive> namedArguments = arguments.sublist(offset); |
| + arguments.length = offset; |
| + List<String> normalizedNames = <String>[]; |
| + // Iterate over the optional parameters of the signature, and try to |
| + // find them in the callStructure's named arguments. If found, we use the |
| + // value in the temporary list, otherwise the default value. |
| + signature.orderedOptionalParameters.forEach((ParameterElement element) { |
| + int nameIndex = callStructure.namedArguments.indexOf(element.name); |
| + arguments.add(nameIndex == -1 ? translateDefaultValue(element) |
| + : namedArguments[nameIndex]); |
| + normalizedNames.add(element.name); |
| + }); |
| + return new CallStructure(signature.parameterCount, normalizedNames); |
| } |
| - /// Normalizes order of named arguments. |
| - List<ir.Primitive> normalizeDynamicArguments( |
| - CallStructure callStructure, |
| - List<ir.Primitive> arguments) { |
| + CallStructure normalizeDynamicArguments(CallStructure callStructure, |
| + List<ir.Primitive> arguments) { |
| assert(arguments.length == callStructure.argumentCount); |
| - // Optimization: don't copy the argument list for trivial cases. |
| - if (callStructure.namedArguments.isEmpty) return arguments; |
| - List<ir.Primitive> result = <ir.Primitive>[]; |
| - for (int i=0; i < callStructure.positionalArgumentCount; i++) { |
| - result.add(arguments[i]); |
| - } |
| + if (callStructure.namedArguments.isEmpty) return callStructure; |
| + int destinationIndex = callStructure.positionalArgumentCount; |
| + List<ir.Primitive> namedArguments = arguments.sublist(destinationIndex); |
| for (String argName in callStructure.getOrderedNamedArguments()) { |
| - int nameIndex = callStructure.namedArguments.indexOf(argName); |
| - int translatedIndex = callStructure.positionalArgumentCount + nameIndex; |
| - result.add(arguments[translatedIndex]); |
| + int sourceIndex = callStructure.namedArguments.indexOf(argName); |
| + arguments[destinationIndex++] = namedArguments[sourceIndex]; |
| } |
| - return result; |
| + return new CallStructure(callStructure.argumentCount, |
| + callStructure.getOrderedNamedArguments()); |
| } |
| @override |
| @@ -3281,11 +3345,11 @@ class JsIrBuilderVisitor extends IrBuilderVisitor { |
| ast.NodeList arguments, |
| CallStructure callStructure, |
| _) { |
| - List<ir.Primitive> arguments = |
| - node.send.arguments.mapToList(visit, growable:false); |
| + List<ir.Primitive> arguments = node.send.arguments.mapToList(visit); |
| // Use default values from the effective target, not the immediate target. |
| ConstructorElement target = constructor.effectiveTarget; |
| - arguments = normalizeStaticArguments(callStructure, target, arguments); |
| + CallStructure normalizedCallStructure = |
| + normalizeStaticArguments(callStructure, target, arguments); |
| TypeMask allocationSiteType; |
| ast.Node send = node.send; |
| if (Elements.isFixedListConstructorCall(constructor, send, compiler) || |
| @@ -3296,7 +3360,7 @@ class JsIrBuilderVisitor extends IrBuilderVisitor { |
| } |
| return irBuilder.buildConstructorInvocation( |
| target, |
| - callStructure, |
| + normalizedCallStructure, |
| constructor.computeEffectiveTargetType(type), |
| arguments, |
| sourceInformationBuilder.buildNew(node), |
| @@ -3396,12 +3460,15 @@ class JsIrBuilderVisitor extends IrBuilderVisitor { |
| reporter.internalError(node, |
| 'Isolate library and compiler mismatch.'); |
| } |
| - List<ir.Primitive> arguments = translateStaticArguments(argumentList, |
| - element, callStructure); |
| - return irBuilder.buildStaticFunctionInvocation(element, |
| - callStructure, arguments, |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + CallStructure normalizedCallStructure = translateStaticArguments( |
| + argumentList, element, callStructure, normalizedArguments); |
| + return irBuilder.buildStaticFunctionInvocation( |
| + element, |
| + normalizedCallStructure, |
| + normalizedArguments, |
| sourceInformation: |
| - sourceInformationBuilder.buildCall(node, node.selector)); |
| + sourceInformationBuilder.buildCall(node, node.selector)); |
| } |
| /// Lookup the value of the enum described by [node]. |
| @@ -3597,8 +3664,12 @@ class JsIrBuilderVisitor extends IrBuilderVisitor { |
| if (compiler.backend.isForeign(function)) { |
| return handleForeignCode(node, function, argumentList, callStructure); |
| } else { |
| - return irBuilder.buildStaticFunctionInvocation(function, callStructure, |
| - translateStaticArguments(argumentList, function, callStructure), |
| + List<ir.Primitive> normalizedArguments = <ir.Primitive>[]; |
| + CallStructure normalizedCallStructure = translateStaticArguments( |
| + argumentList, function, callStructure, normalizedArguments); |
| + return irBuilder.buildStaticFunctionInvocation(function, |
| + normalizedCallStructure, |
| + normalizedArguments, |
| sourceInformation: |
| sourceInformationBuilder.buildCall(node, node.selector)); |
| } |