// Copyright (c) 2015, 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.

import "package:expect/async_helper.dart";
import "package:expect/expect.dart";

import '../helpers/compiler_helper.dart';

String SHOULD_NOT_BE_BOXED_TEST = r'''
main() {
  var a;
  for (var i=0; i<10; i++) {
    a = () => i;
  }
  print(a());
}
''';

String SHOULD_BE_BOXED_TEST = r'''
run(f) => f();
main() {
  var a;
  for (var i=0; i<10; run(() => i++)) {
    a = () => i;
  }
  print(a());
}
''';

String ONLY_UPDATE_LOOP_VAR_TEST = r'''
run(f) => f();
main() {
  var a;
  for (var i=0; i<10; run(() => i++)) {
    var b = 3;
    a = () => b = i;
  }
  print(a());
}
''';

main() {
  runTests() async {
    String generated1 = await compileAll(SHOULD_NOT_BE_BOXED_TEST);
    Expect.isTrue(
      generated1.contains('main_closure(i)'),
      'for-loop variable should not have been boxed',
    );

    String generated2 = await compileAll(SHOULD_BE_BOXED_TEST);
    Expect.isFalse(
      generated2.contains('main_closure(i)'),
      'for-loop variable should have been boxed',
    );

    String generated3 = await compileAll(ONLY_UPDATE_LOOP_VAR_TEST);
    Expect.isFalse(
      generated3.contains('main_closure(i)'),
      'for-loop variable should have been boxed',
    );
    Expect.isFalse(
      generated3.contains(', _box_0.b = 3,'),
      'non for-loop captured variable should not be updated in loop',
    );
  }

  asyncTest(() async {
    print('--test from kernel------------------------------------------------');
    await runTests();
  });
}
