| Index: pkg/compiler/lib/src/ssa/builder.dart
|
| diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
|
| index 22ef5e1cbb376f88a58e1076a896391c63b95481..ef146154006dfab1e48fbdab30c4641679eba80e 100644
|
| --- a/pkg/compiler/lib/src/ssa/builder.dart
|
| +++ b/pkg/compiler/lib/src/ssa/builder.dart
|
| @@ -7150,21 +7150,64 @@ class SsaBuilder extends ast.Visitor
|
| FunctionSignature targetSignature = targetConstructor.functionSignature;
|
| FunctionSignature redirectingSignature =
|
| redirectingConstructor.functionSignature;
|
| - redirectingSignature.forEachRequiredParameter((ParameterElement element) {
|
| - inputs.add(localsHandler.readLocal(element));
|
| - });
|
| +
|
| + List<Element> targetRequireds = targetSignature.requiredParameters;
|
| + List<Element> redirectingRequireds
|
| + = redirectingSignature.requiredParameters;
|
| +
|
| List<Element> targetOptionals =
|
| targetSignature.orderedOptionalParameters;
|
| List<Element> redirectingOptionals =
|
| redirectingSignature.orderedOptionalParameters;
|
| - int i = 0;
|
| - for (; i < redirectingOptionals.length; i++) {
|
| - ParameterElement parameter = redirectingOptionals[i];
|
| +
|
| + // TODO(25579): This code can do the wrong thing redirecting constructor and
|
| + // the target do not correspond. It is correct if there is no
|
| + // warning. Ideally the redirecting constructor and the target would be the
|
| + // same function.
|
| +
|
| + void loadLocal(ParameterElement parameter) {
|
| inputs.add(localsHandler.readLocal(parameter));
|
| }
|
| - for (; i < targetOptionals.length; i++) {
|
| - inputs.add(handleConstantForOptionalParameter(targetOptionals[i]));
|
| + void loadPosition(int position, ParameterElement optionalParameter) {
|
| + if (position < redirectingRequireds.length) {
|
| + loadLocal(redirectingRequireds[position]);
|
| + } else if (position < redirectingSignature.parameterCount &&
|
| + !redirectingSignature.optionalParametersAreNamed) {
|
| + loadLocal(redirectingOptionals[position - redirectingRequireds.length]);
|
| + } else if (optionalParameter != null) {
|
| + inputs.add(handleConstantForOptionalParameter(optionalParameter));
|
| + } else {
|
| + // Wrong.
|
| + inputs.add(graph.addConstantNull(compiler));
|
| + }
|
| + }
|
| +
|
| + int position = 0;
|
| +
|
| + for (ParameterElement targetParameter in targetRequireds) {
|
| + loadPosition(position++, null);
|
| }
|
| +
|
| + if (targetOptionals.isNotEmpty) {
|
| + if (targetSignature.optionalParametersAreNamed) {
|
| + for (ParameterElement parameter in targetOptionals) {
|
| + ParameterElement redirectingParameter =
|
| + redirectingOptionals.firstWhere(
|
| + (p) => p.name == parameter.name,
|
| + orElse: () => null);
|
| + if (redirectingParameter == null) {
|
| + inputs.add(handleConstantForOptionalParameter(parameter));
|
| + } else {
|
| + inputs.add(localsHandler.readLocal(redirectingParameter));
|
| + }
|
| + }
|
| + } else {
|
| + for (ParameterElement parameter in targetOptionals) {
|
| + loadPosition(position++, parameter);
|
| + }
|
| + }
|
| + }
|
| +
|
| ClassElement targetClass = targetConstructor.enclosingClass;
|
| if (backend.classNeedsRti(targetClass)) {
|
| ClassElement cls = redirectingConstructor.enclosingClass;
|
|
|