aa6353b6da
R=kmillikin@google.com BUG= Review-Url: https://codereview.chromium.org/2850783002 .
57 lines
2.4 KiB
Dart
57 lines
2.4 KiB
Dart
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
/// A library to help move super calls last in the initializer list.
|
|
library kernel.frontend.super_calls;
|
|
|
|
import '../ast.dart';
|
|
|
|
/// Mutates the initializer list of [node] so that its super initializer occurs
|
|
/// last, while its arguments are evaluated at the correct place.
|
|
///
|
|
/// Does nothing if there is no super initializer or if it is already last.
|
|
void moveSuperInitializerLast(Constructor node) {
|
|
List<Initializer> initializers = node.initializers;
|
|
if (initializers.isEmpty) return;
|
|
if (initializers.last is SuperInitializer) return;
|
|
int superIndex = -1;
|
|
for (int i = initializers.length - 1; i >= 0; --i) {
|
|
Initializer initializer = initializers[i];
|
|
if (initializer is SuperInitializer) {
|
|
superIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
if (superIndex == -1) return;
|
|
SuperInitializer superCall = initializers[superIndex];
|
|
Arguments arguments = superCall.arguments;
|
|
int argumentCount = arguments.positional.length + arguments.named.length;
|
|
|
|
// We move all initializers after the super call to the place where the super
|
|
// call was, but reserve [argumentCount] slots before that for
|
|
// [LocalInitializer]s.
|
|
initializers.length += argumentCount;
|
|
initializers.setRange(
|
|
superIndex + argumentCount, // destination start (inclusive)
|
|
initializers.length - 1, // destination end (exclusive)
|
|
initializers, // source list
|
|
superIndex + 1); // source start index
|
|
initializers[initializers.length - 1] = superCall;
|
|
|
|
// Fill in the [argumentCount] reserved slots with the evaluation expressions
|
|
// of the arguments to the super constructor call.
|
|
int storeIndex = superIndex;
|
|
for (int i = 0; i < arguments.positional.length; ++i) {
|
|
var variable = new VariableDeclaration.forValue(arguments.positional[i]);
|
|
arguments.positional[i] = new VariableGet(variable)..parent = arguments;
|
|
initializers[storeIndex++] = new LocalInitializer(variable)..parent = node;
|
|
}
|
|
for (int i = 0; i < arguments.named.length; ++i) {
|
|
NamedExpression argument = arguments.named[i];
|
|
var variable = new VariableDeclaration.forValue(argument.value);
|
|
arguments.named[i].value = new VariableGet(variable)..parent = argument;
|
|
initializers[storeIndex++] = new LocalInitializer(variable)..parent = node;
|
|
}
|
|
}
|