// 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.

library bitops1_test;

import 'dart:async';
import 'package:expect/async_helper.dart';
import '../helpers/compiler_helper.dart';

const COMMON = r"""
int g1 = 0, g2 = 0;
int sink1 = 0, sink2 = 0;

main() {
  for (int i = 0; i < 0x100000000; i = i + (i >> 4) + 1) {
    g1 = g2 = i;
    sink1 = callFoo(i, 1 - i, i);
    sink2 = callFoo(2 - i, i, 3 - i);
  }
}
""";

const String TEST1 = r"""
int foo(int param) {
  return param & 15;
  // present: 'return param & 15;'
}
""";

const String TEST2 = r"""
int foo(int param) {
  return 15 & param;
  // Constant position canonicalization.
  // present: 'return param & 15;'
}
""";

const String TEST3 = r"""
int foo(int param) {
  return param & 0;
  // present: 'return 0;'
}
""";

const String TEST4 = r"""
int foo(int param) {
  return param & 12 & 6;
  // Reassociation and constant folding.
  // present: 'return param & 4'
  // absent: '12'
  // absent: '6'
}
""";

const String TEST5 = r"""
int foo(int param) {
  return 12 & param & 6;
  // Reassociation and constant folding.
  // present: 'return param & 4'
  // absent: '12'
  // absent: '6'
}
""";

const String TEST6 = r"""
foo(param) {
  return 15 | 7 & param;
  // Constant position canonicalization.
  // present: 'return param & 7 | 15;'
}
""";

const String TEST7 = r"""
foo(param) {
  param = toUInt32(param + 1);
  if (param == 0) return -1;
  return param & 0xFFFFFFFF | 1;
  // Removal of identity mask.
  // present: 'return (param | 1) >>> 0;'
}
int toUInt32(int x) => x & 0xFFFFFFFF;
""";

const String TEST8 = r"""
int foo(int aaa, int bbb, int ccc) {
  return 1 | aaa | bbb | 2 | ccc | 4;
  // Reassociation and constant folding.
  // present: 'aaa | bbb | ccc | 7'
}
int callFoo(int a, int b, int c) => foo(a, b, c);
""";

const String TEST9 = r"""
int foo(int aaa, int bbb, int ccc) {
  return 255 & aaa & bbb & 126 & ccc & 15;
  // Reassociation and constant folding not yet implemented for '&'.
  // We want to avoid moving the constants too far right, since masking can
  // enable a more efficient representation.
  // TODO(sra): constant-fold later masks into earlier mask.
  //
  // present: 'aaa & 255 & bbb & 126 & ccc & 15'
}
int callFoo(int a, int b, int c) => foo(a, b, c);
""";

main() {
  runTests() async {
    Future check(String test) {
      String program = COMMON + '\n\n' + test;
      if (!test.contains('callFoo')) {
        program += 'int callFoo(int a, int b, int c) => foo(a);\n';
      }
      return compile(
        program,
        entry: 'main',
        methodName: 'foo',
        disableTypeInference: false,
        check: checkerForAbsentPresent(test),
      );
    }

    await check(TEST1);
    await check(TEST2);
    await check(TEST3);
    await check(TEST4);
    await check(TEST5);
    await check(TEST6);
    await check(TEST7);
    await check(TEST8);
    await check(TEST9);
  }

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