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

library test.generic_bounded;

import 'dart:mirrors';

import 'package:expect/expect.dart';

import 'generics_helper.dart';

class Super<T extends num> {}

class Fixed extends Super<int> {}
class Generic<R> extends Super<R> {} // //# 02: compile-time error
class Malbounded extends Super<String> {} //# 01: compile-time error

main() {
  ClassMirror superDecl = reflectClass(Super);
  ClassMirror superOfInt = reflectClass(Fixed).superclass!;
  ClassMirror genericDecl = reflectClass(Generic); // //# 02: continued
  ClassMirror superOfR = genericDecl.superclass!; // //# 02: continued
  ClassMirror genericOfDouble = reflect(new Generic<double>()).type; // //# 02: continued
  ClassMirror superOfDouble = genericOfDouble.superclass!; // //# 02: continued
  ClassMirror genericOfBool = reflect(new Generic<bool>()).type; // //# 02: compile-time error
  ClassMirror superOfBool = genericOfBool.superclass!; // //# 02: continued
  Expect.isFalse(genericOfBool.isOriginalDeclaration); // //# 02: continued
  Expect.isFalse(superOfBool.isOriginalDeclaration); // //# 02: continued
  typeParameters(genericOfBool, [#R]); // //# 02: continued
  typeParameters(superOfBool, [#T]); // //# 02: continued
  typeArguments(genericOfBool, [reflectClass(bool)]); // //# 02: continued
  typeArguments(superOfBool, [reflectClass(bool)]); // //# 02: continued

  ClassMirror superOfString = reflectClass(Malbounded).superclass!; // //# 01: continued

  Expect.isTrue(superDecl.isOriginalDeclaration);
  Expect.isFalse(superOfInt.isOriginalDeclaration);
  Expect.isTrue(genericDecl.isOriginalDeclaration); // //# 02: continued
  Expect.isFalse(superOfR.isOriginalDeclaration); // //# 02: continued
  Expect.isFalse(genericOfDouble.isOriginalDeclaration); // //# 02: continued
  Expect.isFalse(superOfDouble.isOriginalDeclaration); // //# 02: continued

  Expect.isFalse(superOfString.isOriginalDeclaration); // //# 01: continued

  TypeVariableMirror tFromSuper = superDecl.typeVariables.single;
  TypeVariableMirror rFromGeneric = genericDecl.typeVariables.single; // //# 02: continued

  Expect.equals(reflectClass(num), tFromSuper.upperBound);
  Expect.equals(reflectClass(Object), rFromGeneric.upperBound); // //# 02: continued

  typeParameters(superDecl, [#T]);
  typeParameters(superOfInt, [#T]);
  typeParameters(genericDecl, [#R]); // //# 02: continued
  typeParameters(superOfR, [#T]); // //# 02: continued
  typeParameters(genericOfDouble, [#R]); // //# 02: continued
  typeParameters(superOfDouble, [#T]); // //# 02: continued
  typeParameters(superOfString, [#T]); // //# 01: continued

  typeArguments(superDecl, []);
  typeArguments(superOfInt, [reflectClass(int)]);
  typeArguments(genericDecl, []); // //# 02: continued
  typeArguments(superOfR, [rFromGeneric]); // //# 02: continued
  typeArguments(genericOfDouble, [reflectClass(double)]); // //# 02: continued
  typeArguments(superOfDouble, [reflectClass(double)]); // //# 02: continued
  typeArguments(superOfString, [reflectClass(String)]); // //# 01: continued
}
