// 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.
import 'package:kernel/ast.dart';
import 'package:kernel/text/ast_to_text.dart';
import 'package:kernel/verifier.dart';
import 'package:test/test.dart';

/// Checks that the verifier correctly find errors in invalid programs.
///
/// The frontend should never generate invalid programs, so we have to test
/// these by manually constructing invalid ASTs.
///
/// We mostly test negative cases here, as we get plenty of positive cases by
/// compiling the Dart test suite with the verifier enabled.
main() {
  positiveTest('Test harness has no errors', () {
    return new NullLiteral();
  });
  negativeTest('VariableGet out of scope', () {
    return new VariableGet(makeVariable());
  });
  negativeTest('VariableSet out of scope', () {
    return new VariableSet(makeVariable(), new NullLiteral());
  });
  negativeTest('Variable block scope', () {
    VariableDeclaration variable = makeVariable();
    return new Block([
      new Block([variable]),
      new ReturnStatement(new VariableGet(variable))
    ]);
  });
  negativeTest('Variable let scope', () {
    VariableDeclaration variable = makeVariable();
    return new LogicalExpression(new Let(variable, new VariableGet(variable)),
        '&&', new VariableGet(variable));
  });
  negativeTest('Variable redeclared', () {
    VariableDeclaration variable = makeVariable();
    return new Block([variable, variable]);
  });
  negativeTest('Member redeclared', () {
    Field field = new Field(new Name('field'), initializer: new NullLiteral());
    return new Class(
        name: 'Test',
        supertype: objectClass.asRawSupertype,
        fields: [field, field]);
  });
  negativeTest('Class redeclared', () {
    return otherClass; // Test harness also adds otherClass to program.
  });
  negativeTest('Class type parameter redeclared', () {
    var parameter = makeTypeParameter();
    return new Class(
        name: 'Test',
        supertype: objectClass.asRawSupertype,
        typeParameters: [parameter, parameter]);
  });
  negativeTest('Member type parameter redeclared', () {
    var parameter = makeTypeParameter();
    return new Procedure(
        new Name('test'),
        ProcedureKind.Method,
        new FunctionNode(new ReturnStatement(new NullLiteral()),
            typeParameters: [parameter, parameter]));
  });
  negativeTest('Type parameter out of scope', () {
    var parameter = makeTypeParameter();
    return new ListLiteral([], typeArgument: new TypeParameterType(parameter));
  });
  negativeTest('Class type parameter from another class', () {
    return new TypeLiteral(new TypeParameterType(otherClass.typeParameters[0]));
  });
  negativeTest('Class type parameter in static method', () {
    return new Procedure(
        new Name('test'),
        ProcedureKind.Method,
        new FunctionNode(new ReturnStatement(
            new TypeLiteral(new TypeParameterType(classTypeParameter)))),
        isStatic: true);
  });
  negativeTest('Class type parameter in static field', () {
    return new Field(new Name('field'),
        initializer: new TypeLiteral(new TypeParameterType(classTypeParameter)),
        isStatic: true);
  });
  negativeTest('Method type parameter out of scope', () {
    var parameter = makeTypeParameter();
    return new Class(
        name: 'Test',
        supertype: objectClass.asRawSupertype,
        procedures: [
          new Procedure(
              new Name('generic'),
              ProcedureKind.Method,
              new FunctionNode(new EmptyStatement(),
                  typeParameters: [parameter])),
          new Procedure(
              new Name('use'),
              ProcedureKind.Method,
              new FunctionNode(new ReturnStatement(
                  new TypeLiteral(new TypeParameterType(parameter)))))
        ]);
  });
  negativeTest('Interface type arity too low', () {
    return new TypeLiteral(new InterfaceType(otherClass, []));
  });
  negativeTest('Interface type arity too high', () {
    return new TypeLiteral(
        new InterfaceType(otherClass, [new DynamicType(), new DynamicType()]));
  });
  negativeTest('Dangling interface type', () {
    return new TypeLiteral(new InterfaceType(new Class()));
  });
  negativeTest('Dangling field get', () {
    return new DirectPropertyGet(new NullLiteral(), new Field(new Name('foo')));
  });
  negativeTest('Missing block parent pointer', () {
    var block = new Block([]);
    block.statements.add(new ReturnStatement());
    return block;
  });
  negativeTest('Missing function parent pointer', () {
    var procedure = new Procedure(new Name('test'), ProcedureKind.Method, null);
    procedure.function = new FunctionNode(new EmptyStatement());
    return procedure;
  });
}

checkHasError(Program program) {
  bool passed = false;
  try {
    verifyProgram(program);
    passed = true;
  } catch (e) {}
  if (passed) {
    fail('Failed to reject invalid program:\n${programToString(program)}');
  }
}

Class objectClass = new Class(name: 'Object');

Library stubLibrary = new Library(Uri.parse('dart:core'))
  ..addClass(objectClass);

TypeParameter classTypeParameter = makeTypeParameter('T');

Class otherClass = new Class(
    name: 'OtherClass',
    typeParameters: [makeTypeParameter('OtherT')],
    supertype: objectClass.asRawSupertype);

Program makeProgram(TreeNode makeBody()) {
  var node = makeBody();
  if (node is Expression) {
    node = new ReturnStatement(node);
  }
  if (node is Statement) {
    node = new FunctionNode(node);
  }
  if (node is FunctionNode) {
    node = new Procedure(new Name('test'), ProcedureKind.Method, node);
  }
  if (node is Member) {
    node = new Class(
        name: 'Test',
        typeParameters: [classTypeParameter],
        supertype: objectClass.asRawSupertype)..addMember(node);
  }
  if (node is Class) {
    node =
        new Library(Uri.parse('test.dart'), classes: <Class>[node, otherClass]);
  }
  if (node is Library) {
    node = new Program(<Library>[node, stubLibrary]);
  }
  assert(node is Program);
  return node;
}

negativeTest(String name, TreeNode makeBody()) {
  test(name, () {
    checkHasError(makeProgram(makeBody));
  });
}

positiveTest(String name, TreeNode makeBody()) {
  test(name, () {
    verifyProgram(makeProgram(makeBody));
  });
}

VariableDeclaration makeVariable() => new VariableDeclaration(null);

TypeParameter makeTypeParameter([String name]) {
  return new TypeParameter(name, new InterfaceType(objectClass));
}
