<commit_before>// 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 call occurs last,
/// while its arguments are evaluated at the correct place.
///
/// Does nothing if there is no super call or if the super call is already last.
void moveSuperCallLast(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;
  initializers.add(superCall);
  _insertEntriesAt(initializers, superIndex, argumentCount - 1);
  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;
  }
}

/// Inserts new entries at the given index, shifting entries after that index
/// towards the end of the list.
void _insertEntriesAt(List<Initializer> list, int index, int count) {
  int originalLength = list.length;
  list.length += count;
  for (int i = 0; i < count; ++i) {
    list[list.length - i - 1] = list[originalLength - i - 1];
  }
}<commit_msg>[kernel] Fix moving super initializer to the end<commit_after>// 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 call occurs last,
/// while its arguments are evaluated at the correct place.
///
/// Does nothing if there is no super call or if the super call is already last.
void moveSuperCallLast(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,  // desination start (inclusive)
      initializers.length - 1,     // desination 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;
  }
}

{'fraction_non_alphanumeric': 0.10407703339479615, 'fraction_numerical': 0.005531653349723417, 'mean_word_length': 3.6362773029439697, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1997982', 'n_tokens_mistral': 1393, 'n_tokens_neox': 1352, 'n_words': 489}