// Copyright (c) 2013, 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/expect.dart';
import "package:async_helper/async_helper.dart";
import 'compiler_helper.dart';
import 'parser_helper.dart';

const String TEST = """

class A {
  get foo => 'string';
  set foo(value) {}
  operator[](index) => 'string';
  operator[]=(index, value) {}

  returnDynamic1() => foo--;
  returnNum1() => --foo;
  returnNum2() => foo -= 42;

  returnDynamic2() => this[index]--;
  returnNum3() => --this[index];
  returnNum4() => this[index] -= 42;

  returnEmpty3() => this.bar--;
  returnEmpty1() => --this.bar;
  returnEmpty2() => this.bar -= 42;
}

class B extends A {
  get foo => 42;
  operator[](index) => 42;

  returnString1() => super.foo--;
  returnDynamic1() => --super.foo;
  returnDynamic2() => super.foo -= 42;

  returnString2() => super[index]--;
  returnDynamic3() => --super[index];
  returnDynamic4() => super[index] -= 42;
}

main() {
  new A()..returnNum1()
         ..returnNum2()
         ..returnNum3()
         ..returnNum4()
         ..returnNum5()
         ..returnNum6()
         ..returnDynamic1()
         ..returnDynamic2()
         ..returnDynamic3();

  new B()..returnString1()
         ..returnString2()
         ..returnDynamic1()
         ..returnDynamic2()
         ..returnDynamic3()
         ..returnDynamic4();
}
""";

void main() {
  Uri uri = new Uri(scheme: 'source');
  var compiler = compilerFor(TEST, uri);
  asyncTest(() => compiler.runCompiler(uri).then((_) {
    var typesTask = compiler.typesTask;
    var typesInferrer = typesTask.typesInferrer;

    checkReturnInClass(String className, String methodName, type) {
      var cls = findElement(compiler, className);
      var element = cls.lookupLocalMember(methodName);
      Expect.equals(type,
          typesInferrer.getReturnTypeOfElement(element).simplify(compiler),
          methodName);
    }

    var subclassOfInterceptor =
        findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');

    checkReturnInClass('A', 'returnNum1', typesTask.numType);
    checkReturnInClass('A', 'returnNum2', typesTask.numType);
    checkReturnInClass('A', 'returnNum3', typesTask.numType);
    checkReturnInClass('A', 'returnNum4', typesTask.numType);
    checkReturnInClass('A', 'returnEmpty1', const TypeMask.nonNullEmpty());
    checkReturnInClass('A', 'returnEmpty2', const TypeMask.nonNullEmpty());
    checkReturnInClass('A', 'returnDynamic1', subclassOfInterceptor);
    checkReturnInClass('A', 'returnDynamic2', subclassOfInterceptor);
    checkReturnInClass('A', 'returnEmpty3', const TypeMask.nonNullEmpty());

    checkReturnInClass('B', 'returnString1', typesTask.stringType);
    checkReturnInClass('B', 'returnString2', typesTask.stringType);
    checkReturnInClass('B', 'returnDynamic1', const TypeMask.nonNullEmpty());
    checkReturnInClass('B', 'returnDynamic2', const TypeMask.nonNullEmpty());
    checkReturnInClass('B', 'returnDynamic3', const TypeMask.nonNullEmpty());
    checkReturnInClass('B', 'returnDynamic4', const TypeMask.nonNullEmpty());
  }));
}
