// 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 components.
///
/// The frontend should never generate invalid components, 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',
    (TestHarness test) {
      test.addNode(NullLiteral());
    },
  );
  negative1Test(
    'VariableGet out of scope',
    (TestHarness test) {
      VariableDeclaration node = test.makeVariable();
      test.addNode(VariableGet(node));
      return node;
    },
    (Node? node) => "Variable '$node' used out of scope.",
  );
  negative1Test(
    'VariableSet out of scope',
    (TestHarness test) {
      VariableDeclaration variable = test.makeVariable();
      test.addNode(VariableSet(variable, new NullLiteral()));
      return variable;
    },
    (Node? node) => "Variable '$node' used out of scope.",
  );
  negative1Test(
    'Variable block scope',
    (TestHarness test) {
      VariableDeclaration variable = test.makeVariable();
      test.addNode(Block([
        new Block([variable]),
        new ReturnStatement(new VariableGet(variable))
      ]));
      return variable;
    },
    (Node? node) => "Variable '$node' used out of scope.",
  );
  negative1Test(
    'Variable let scope',
    (TestHarness test) {
      VariableDeclaration variable = test.makeVariable();
      test.addNode(LogicalExpression(
          new Let(variable, new VariableGet(variable)),
          LogicalExpressionOperator.AND,
          new VariableGet(variable)));
      return variable;
    },
    (Node? node) => "Variable '$node' used out of scope.",
  );
  negative1Test(
    'Variable redeclared',
    (TestHarness test) {
      VariableDeclaration variable = test.makeVariable();
      test.addNode(Block([variable, variable]));
      return variable;
    },
    (Node? node) => "Variable '$node' declared more than once.",
  );
  negative1Test(
    'Member redeclared',
    (TestHarness test) {
      Field field = new Field.mutable(new Name('field'),
          initializer: new NullLiteral(), fileUri: dummyUri);
      test.addNode(Class(
          name: 'Test',
          supertype: test.objectClass.asRawSupertype,
          fields: [field, field],
          fileUri: dummyUri));
      return field;
    },
    (Node? node) => "Member '$node' has been declared more than once.",
  );
  negative1Test(
    'Class redeclared',
    (TestHarness test) {
      Class otherClass = test.otherClass;
      test.addNode(
          otherClass); // Test harness also adds otherClass to component.
      return test.otherClass;
    },
    (Node? node) => "Class '$node' declared more than once.",
  );
  negative1Test(
    'Class type parameter redeclared',
    (TestHarness test) {
      TypeParameter parameter = test.makeTypeParameter();
      test.addNode(Class(
          name: 'Test',
          supertype: test.objectClass.asRawSupertype,
          typeParameters: [parameter, parameter],
          fileUri: dummyUri));
      return parameter;
    },
    (Node? node) => "Type parameter '$node' redeclared.",
  );
  negative1Test(
    'Member type parameter redeclared',
    (TestHarness test) {
      TypeParameter parameter = test.makeTypeParameter();
      test.addNode(Procedure(
          new Name('bar'),
          ProcedureKind.Method,
          new FunctionNode(new ReturnStatement(new NullLiteral()),
              typeParameters: [parameter, parameter]),
          fileUri: dummyUri));

      return parameter;
    },
    (Node? node) => "Type parameter '$node' redeclared.",
  );
  negative2Test(
    'Type parameter out of scope',
    (TestHarness test) {
      TypeParameter parameter = test.makeTypeParameter();
      test.addNode(ListLiteral([],
          typeArgument: new TypeParameterType(parameter, Nullability.legacy)));
      return [parameter, null];
    },
    (Node? node, Node? parent) =>
        "Type parameter '$node' referenced out of scope,"
        " owner is: '$parent'.",
  );
  negative2Test(
    'Class type parameter from another class',
    (TestHarness test) {
      TypeParameter node = test.otherClass.typeParameters[0];
      test.addNode(
          TypeLiteral(new TypeParameterType(node, Nullability.legacy)));
      return [node, test.otherClass];
    },
    (Node? node, Node? parent) =>
        "Type parameter '$node' referenced out of scope,"
        " owner is: '$parent'.",
  );
  negative2Test(
    'Class type parameter in static method',
    (TestHarness test) {
      TypeParameter node = test.classTypeParameter;
      test.addNode(Procedure(
          new Name('bar'),
          ProcedureKind.Method,
          new FunctionNode(new ReturnStatement(new TypeLiteral(
              new TypeParameterType(node, Nullability.legacy)))),
          isStatic: true,
          fileUri: dummyUri));

      return [node, test.enclosingClass];
    },
    (Node? node, Node? parent) =>
        "Type parameter '$node' referenced from static context,"
        " parent is: '$parent'.",
  );
  negative2Test(
    'Class type parameter in static field',
    (TestHarness test) {
      TypeParameter node = test.classTypeParameter;
      test.addNode(Field.mutable(new Name('field'),
          initializer:
              new TypeLiteral(new TypeParameterType(node, Nullability.legacy)),
          isStatic: true,
          fileUri: dummyUri));
      return [node, test.enclosingClass];
    },
    (Node? node, Node? parent) =>
        "Type parameter '$node' referenced from static context,"
        " parent is: '$parent'.",
  );
  negative2Test(
    'Method type parameter out of scope',
    (TestHarness test) {
      TypeParameter parameter = test.makeTypeParameter();
      FunctionNode parent =
          new FunctionNode(new EmptyStatement(), typeParameters: [parameter]);
      test.addNode(Class(
          name: 'Test',
          supertype: test.objectClass.asRawSupertype,
          procedures: [
            new Procedure(new Name('generic'), ProcedureKind.Method, parent,
                fileUri: dummyUri),
            new Procedure(
                new Name('use'),
                ProcedureKind.Method,
                new FunctionNode(new ReturnStatement(new TypeLiteral(
                    new TypeParameterType(parameter, Nullability.legacy)))),
                fileUri: dummyUri)
          ],
          fileUri: dummyUri));

      return [parameter, parent];
    },
    (Node? node, Node? parent) =>
        "Type parameter '$node' referenced out of scope,"
        " owner is: '${(parent as TreeNode).parent}'.",
  );
  negative1Test(
    'Interface type arity too low',
    (TestHarness test) {
      InterfaceType node =
          new InterfaceType(test.otherClass, Nullability.legacy, []);
      test.addNode(TypeLiteral(node));
      return node;
    },
    (Node? node) => "Type $node provides 0 type arguments,"
        " but the class declares 1 parameters.",
  );
  negative1Test(
    'Interface type arity too high',
    (TestHarness test) {
      InterfaceType node = new InterfaceType(test.otherClass,
          Nullability.legacy, [new DynamicType(), new DynamicType()]);
      test.addNode(TypeLiteral(node));
      return node;
    },
    (Node? node) => "Type $node provides 2 type arguments,"
        " but the class declares 1 parameters.",
  );
  negative1Test(
    'Dangling interface type',
    (TestHarness test) {
      Class orphan = new Class(name: 'Class', fileUri: dummyUri);
      test.addNode(
          new TypeLiteral(new InterfaceType(orphan, Nullability.legacy)));
      return orphan;
    },
    (Node? node) => "Dangling reference to '$node', parent is: 'null'.",
  );
  negative1Test(
    'Dangling field get',
    (TestHarness test) {
      Field orphan = new Field.mutable(new Name('foo'), fileUri: dummyUri);
      test.addNode(new InstanceGet(
          InstanceAccessKind.Instance, new NullLiteral(), orphan.name,
          interfaceTarget: orphan, resultType: orphan.getterType));
      return orphan;
    },
    (Node? node) => "Dangling reference to '$node', parent is: 'null'.",
  );
  simpleNegativeTest(
    'Missing block parent pointer',
    "Incorrect parent pointer on ReturnStatement:"
        " expected 'Block', but found: 'Null'.",
    (TestHarness test) {
      var block = new Block([]);
      block.statements.add(new ReturnStatement());
      test.addNode(block);
    },
  );
  simpleNegativeTest(
    'Missing function parent pointer',
    "Incorrect parent pointer on FunctionNode:"
        " expected 'Procedure', but found: 'Null'.",
    (TestHarness test) {
      var procedure = new Procedure(
          new Name('bar'), ProcedureKind.Method, dummyFunctionNode,
          fileUri: dummyUri);
      procedure.function = new FunctionNode(new EmptyStatement());
      test.addNode(procedure);
    },
  );
  positiveTest(
    'Correct StaticInvocation',
    (TestHarness test) {
      var method = new Procedure(
          new Name('foo'),
          ProcedureKind.Method,
          new FunctionNode(new EmptyStatement(),
              positionalParameters: [new VariableDeclaration('p')]),
          isStatic: true,
          fileUri: dummyUri);
      test.enclosingClass.addProcedure(method);
      test.addNode(
          StaticInvocation(method, new Arguments([new NullLiteral()])));
    },
  );
  negative1Test(
    'StaticInvocation with too many parameters',
    (TestHarness test) {
      var method = new Procedure(new Name('bar'), ProcedureKind.Method,
          new FunctionNode(new EmptyStatement()),
          isStatic: true, fileUri: dummyUri);
      test.enclosingClass.addProcedure(method);
      test.addNode(
          StaticInvocation(method, new Arguments([new NullLiteral()])));
      return method;
    },
    (Node? node) => "StaticInvocation with incompatible arguments for"
        " '$node'.",
  );
  negative1Test(
    'StaticInvocation with too few parameters',
    (TestHarness test) {
      var method = new Procedure(
          new Name('bar'),
          ProcedureKind.Method,
          new FunctionNode(new EmptyStatement(),
              positionalParameters: [new VariableDeclaration('p')]),
          isStatic: true,
          fileUri: dummyUri);
      test.enclosingClass.addProcedure(method);
      test.addNode(StaticInvocation(method, new Arguments.empty()));
      return method;
    },
    (Node? node) => "StaticInvocation with incompatible arguments for '$node'.",
  );
  negative1Test(
    'StaticInvocation with unmatched named parameter',
    (TestHarness test) {
      var method = new Procedure(new Name('bar'), ProcedureKind.Method,
          new FunctionNode(new EmptyStatement()),
          isStatic: true, fileUri: dummyUri);
      test.enclosingClass.addProcedure(method);
      test.addNode(StaticInvocation(
          method,
          new Arguments([],
              named: [new NamedExpression('p', new NullLiteral())])));
      return method;
    },
    (Node? node) => "StaticInvocation with incompatible arguments for"
        " '$node'.",
  );
  negative1Test(
    'StaticInvocation with missing type argument',
    (TestHarness test) {
      Procedure method = new Procedure(
          new Name('bar'),
          ProcedureKind.Method,
          new FunctionNode(new EmptyStatement(),
              typeParameters: [test.makeTypeParameter()]),
          isStatic: true,
          fileUri: dummyUri);
      test.enclosingClass.addProcedure(method);
      test.addNode(StaticInvocation(method, new Arguments.empty()));
      return method;
    },
    (Node? node) => "StaticInvocation with wrong number of type arguments for"
        " '$node'.",
  );
  negative1Test(
    'ConstructorInvocation with missing type argument',
    (TestHarness test) {
      var constructor = new Constructor(new FunctionNode(new EmptyStatement()),
          name: new Name('foo'), fileUri: dummyUri);
      test.enclosingClass.addConstructor(constructor);
      test.addNode(ConstructorInvocation(constructor, new Arguments.empty()));
      return constructor;
    },
    (Node? node) =>
        "ConstructorInvocation with wrong number of type arguments for"
        " '$node'.",
  );
  positiveTest(
    'Valid typedef Foo = `(C) => void`',
    (TestHarness test) {
      var typedef_ = new Typedef(
          'Foo',
          new FunctionType(
              [test.otherLegacyRawType], const VoidType(), Nullability.legacy),
          fileUri: dummyUri);
      test.addNode(typedef_);
    },
  );
  positiveTest(
    'Valid typedef Foo = C<dynamic>',
    (TestHarness test) {
      var typedef_ = new Typedef(
          'Foo',
          new InterfaceType(
              test.otherClass, Nullability.legacy, [const DynamicType()]),
          fileUri: dummyUri);
      test.addNode(typedef_);
    },
  );
  positiveTest(
    'Valid typedefs Foo = Bar, Bar = C',
    (TestHarness test) {
      var foo = new Typedef('Foo', null, fileUri: dummyUri);
      var bar = new Typedef('Bar', null, fileUri: dummyUri);
      foo.type = new TypedefType(bar, Nullability.legacy);
      bar.type = test.otherLegacyRawType;
      test.enclosingLibrary.addTypedef(foo);
      test.enclosingLibrary.addTypedef(bar);
    },
  );
  positiveTest(
    'Valid typedefs Foo = C<Bar>, Bar = C',
    (TestHarness test) {
      var foo = new Typedef('Foo', null, fileUri: dummyUri);
      var bar = new Typedef('Bar', null, fileUri: dummyUri);
      foo.type = new InterfaceType(test.otherClass, Nullability.legacy,
          [new TypedefType(bar, Nullability.legacy)]);
      bar.type = test.otherLegacyRawType;
      test.enclosingLibrary.addTypedef(foo);
      test.enclosingLibrary.addTypedef(bar);
    },
  );
  positiveTest(
    'Valid typedef type in field',
    (TestHarness test) {
      var typedef_ = new Typedef(
          'Foo',
          new FunctionType(
              [test.otherLegacyRawType], const VoidType(), Nullability.legacy),
          fileUri: dummyUri);
      var field = new Field.mutable(new Name('field'),
          type: new TypedefType(typedef_, Nullability.legacy),
          isStatic: true,
          fileUri: dummyUri);
      test.enclosingLibrary.addTypedef(typedef_);
      test.enclosingLibrary.addField(field);
    },
  );
  negative1Test(
    'Invalid typedef Foo = Foo',
    (TestHarness test) {
      var typedef_ = new Typedef('Foo', null, fileUri: dummyUri);
      typedef_.type = new TypedefType(typedef_, Nullability.legacy);
      test.addNode(typedef_);
      return typedef_;
    },
    (Node? node) => "The typedef '$node' refers to itself",
  );
  negative1Test(
    'Invalid typedef Foo = `(Foo) => void`',
    (TestHarness test) {
      var typedef_ = new Typedef('Foo', null, fileUri: dummyUri);
      typedef_.type = new FunctionType(
          [new TypedefType(typedef_, Nullability.legacy)],
          const VoidType(),
          Nullability.legacy);
      test.addNode(typedef_);
      return typedef_;
    },
    (Node? node) => "The typedef '$node' refers to itself",
  );
  negative1Test(
    'Invalid typedef Foo = `() => Foo`',
    (TestHarness test) {
      var typedef_ = new Typedef('Foo', null, fileUri: dummyUri);
      typedef_.type = new FunctionType([],
          new TypedefType(typedef_, Nullability.legacy), Nullability.legacy);
      test.addNode(typedef_);
      return typedef_;
    },
    (Node? node) => "The typedef '$node' refers to itself",
  );
  negative1Test(
    'Invalid typedef Foo = C<Foo>',
    (TestHarness test) {
      var typedef_ = new Typedef('Foo', null, fileUri: dummyUri);
      typedef_.type = new InterfaceType(test.otherClass, Nullability.legacy,
          [new TypedefType(typedef_, Nullability.legacy)]);
      test.addNode(typedef_);
      return typedef_;
    },
    (Node? node) => "The typedef '$node' refers to itself",
  );
  negative1Test(
    'Invalid typedefs Foo = Bar, Bar = Foo',
    (TestHarness test) {
      var foo = new Typedef('Foo', null, fileUri: dummyUri);
      var bar = new Typedef('Bar', null, fileUri: dummyUri);
      foo.type = new TypedefType(bar, Nullability.legacy);
      bar.type = new TypedefType(foo, Nullability.legacy);
      test.enclosingLibrary.addTypedef(foo);
      test.enclosingLibrary.addTypedef(bar);
      return foo;
    },
    (Node? foo) => "The typedef '$foo' refers to itself",
  );
  negative1Test(
    'Invalid typedefs Foo = Bar, Bar = C<Foo>',
    (TestHarness test) {
      var foo = new Typedef('Foo', null, fileUri: dummyUri);
      var bar = new Typedef('Bar', null, fileUri: dummyUri);
      foo.type = new TypedefType(bar, Nullability.legacy);
      bar.type = new InterfaceType(test.otherClass, Nullability.legacy,
          [new TypedefType(foo, Nullability.legacy)]);
      test.enclosingLibrary.addTypedef(foo);
      test.enclosingLibrary.addTypedef(bar);
      return foo;
    },
    (Node? foo) => "The typedef '$foo' refers to itself",
  );
  negative1Test(
    'Invalid typedefs Foo = C<Bar>, Bar = C<Foo>',
    (TestHarness test) {
      var foo = new Typedef('Foo', null, fileUri: dummyUri);
      var bar = new Typedef('Bar', null, fileUri: dummyUri);
      foo.type = new InterfaceType(test.otherClass, Nullability.legacy,
          [new TypedefType(bar, Nullability.legacy)]);
      bar.type = new InterfaceType(test.otherClass, Nullability.legacy,
          [new TypedefType(foo, Nullability.legacy)]);
      test.enclosingLibrary.addTypedef(foo);
      test.enclosingLibrary.addTypedef(bar);
      return foo;
    },
    (Node? foo) => "The typedef '$foo' refers to itself",
  );
  positiveTest(
    'Valid long typedefs C20 = C19 = ... = C1 = C0 = dynamic',
    (TestHarness test) {
      var typedef_ = new Typedef('C0', const DynamicType(), fileUri: dummyUri);
      test.enclosingLibrary.addTypedef(typedef_);
      for (int i = 1; i < 20; ++i) {
        typedef_ = new Typedef(
            'C$i', new TypedefType(typedef_, Nullability.legacy),
            fileUri: dummyUri);
        test.enclosingLibrary.addTypedef(typedef_);
      }
    },
  );
  negative1Test(
    'Invalid long typedefs C20 = C19 = ... = C1 = C0 = C20',
    (TestHarness test) {
      Typedef firstTypedef = new Typedef('C0', null, fileUri: dummyUri);
      Typedef typedef_ = firstTypedef;
      test.enclosingLibrary.addTypedef(typedef_);
      var first = typedef_;
      for (int i = 1; i < 20; ++i) {
        typedef_ = new Typedef(
            'C$i', new TypedefType(typedef_, Nullability.legacy),
            fileUri: dummyUri);
        test.enclosingLibrary.addTypedef(typedef_);
      }
      first.type = new TypedefType(typedef_, Nullability.legacy);
      return firstTypedef;
    },
    (Node? node) => "The typedef '$node' refers to itself",
  );
  positiveTest(
    'Valid typedef Foo<T extends C> = C<T>',
    (TestHarness test) {
      var param = new TypeParameter('T', test.otherLegacyRawType);
      var foo = new Typedef(
          'Foo',
          new InterfaceType(test.otherClass, Nullability.legacy,
              [new TypeParameterType(param, Nullability.legacy)]),
          typeParameters: [param],
          fileUri: dummyUri);
      test.addNode(foo);
    },
  );
  positiveTest(
    'Valid typedef Foo<T extends C<T>> = C<T>',
    (TestHarness test) {
      var param = new TypeParameter('T', test.otherLegacyRawType);
      param.bound = new InterfaceType(test.otherClass, Nullability.legacy,
          [new TypeParameterType(param, Nullability.legacy)]);
      var foo = new Typedef(
          'Foo',
          new InterfaceType(test.otherClass, Nullability.legacy,
              [new TypeParameterType(param, Nullability.legacy)]),
          typeParameters: [param],
          fileUri: dummyUri);
      test.addNode(foo);
    },
  );
  positiveTest(
    'Valid typedef Foo<T> = dynamic, Bar<T extends Foo<T>> = C<T>',
    (TestHarness test) {
      var fooParam = test.makeTypeParameter('T');
      var foo = new Typedef('Foo', const DynamicType(),
          typeParameters: [fooParam], fileUri: dummyUri);
      var barParam = new TypeParameter('T', null);
      barParam.bound = new TypedefType(foo, Nullability.legacy,
          [new TypeParameterType(barParam, Nullability.legacy)]);
      var bar = new Typedef(
          'Bar',
          new InterfaceType(test.otherClass, Nullability.legacy,
              [new TypeParameterType(barParam, Nullability.legacy)]),
          typeParameters: [barParam],
          fileUri: dummyUri);
      test.enclosingLibrary.addTypedef(foo);
      test.enclosingLibrary.addTypedef(bar);
    },
  );
  negative1Test(
    'Invalid typedefs Foo<T extends Bar<T>>, Bar<T extends Foo<T>>',
    (TestHarness test) {
      var fooParam = test.makeTypeParameter('T');
      var foo = new Typedef('Foo', const DynamicType(),
          typeParameters: [fooParam], fileUri: dummyUri);
      var barParam = new TypeParameter('T', null);
      barParam.bound = new TypedefType(foo, Nullability.legacy,
          [new TypeParameterType(barParam, Nullability.legacy)]);
      var bar = new Typedef(
          'Bar',
          new InterfaceType(test.otherClass, Nullability.legacy,
              [new TypeParameterType(barParam, Nullability.legacy)]),
          typeParameters: [barParam],
          fileUri: dummyUri);
      fooParam.bound = new TypedefType(bar, Nullability.legacy,
          [new TypeParameterType(fooParam, Nullability.legacy)]);
      test.enclosingLibrary.addTypedef(foo);
      test.enclosingLibrary.addTypedef(bar);
      return foo;
    },
    (Node? foo) => "The typedef '$foo' refers to itself",
  );
  negative1Test(
    'Invalid typedef Foo<T extends Foo<dynamic> = C<T>',
    (TestHarness test) {
      var param = new TypeParameter('T', null);
      var foo = new Typedef(
          'Foo',
          new InterfaceType(test.otherClass, Nullability.legacy,
              [new TypeParameterType(param, Nullability.legacy)]),
          typeParameters: [param],
          fileUri: dummyUri);
      param.bound =
          new TypedefType(foo, Nullability.legacy, [const DynamicType()]);
      test.addNode(foo);
      return foo;
    },
    (Node? foo) => "The typedef '$foo' refers to itself",
  );
  negative1Test(
    'Typedef arity error',
    (TestHarness test) {
      var param = test.makeTypeParameter('T');
      var foo = new Typedef('Foo', test.otherLegacyRawType,
          typeParameters: [param], fileUri: dummyUri);
      var typedefType = new TypedefType(foo, Nullability.legacy, []);
      var field = new Field.mutable(new Name('field'),
          type: typedefType, isStatic: true, fileUri: dummyUri);
      test.enclosingLibrary.addTypedef(foo);
      test.enclosingLibrary.addField(field);
      return typedefType;
    },
    (Node? typedefType) =>
        "The typedef type $typedefType provides 0 type arguments,"
        " but the typedef declares 1 parameters.",
  );
  negative1Test(
    'Dangling typedef reference',
    (TestHarness test) {
      var foo = new Typedef('Foo', test.otherLegacyRawType,
          typeParameters: [], fileUri: dummyUri);
      var field = new Field.mutable(new Name('field'),
          type: new TypedefType(foo, Nullability.legacy, []),
          isStatic: true,
          fileUri: dummyUri);
      test.enclosingLibrary.addField(field);
      return foo;
    },
    (Node? foo) => "Dangling reference to '$foo', parent is: 'null'",
  );
  negative1Test(
    'Non-static top-level field',
    (TestHarness test) {
      var field = new Field.mutable(new Name('field'), fileUri: dummyUri);
      test.enclosingLibrary.addField(field);
      return null;
    },
    (Node? node) => "The top-level field 'field' should be static",
  );
}

checkHasError(Component component, Matcher matcher) {
  try {
    verifyComponent(component);
  } on VerificationError catch (e) {
    expect(e.details, matcher);
    return;
  }
  fail('Failed to reject invalid component:\n${componentToString(component)}');
}

class TestHarness {
  late Component component;
  late Class objectClass;
  late Library stubLibrary;

  late TypeParameter classTypeParameter;

  late Library enclosingLibrary;
  late Class enclosingClass;
  late Procedure enclosingMember;

  late Class otherClass;

  late InterfaceType objectLegacyRawType;
  late InterfaceType enclosingLegacyRawType;
  late InterfaceType otherLegacyRawType;

  void addNode(TreeNode node) {
    if (node is Expression) {
      addExpression(node);
    } else if (node is Statement) {
      addStatement(node);
    } else if (node is Member) {
      addClassMember(node);
    } else if (node is Class) {
      addClass(node);
    } else if (node is Typedef) {
      addTypedef(node);
    }
  }

  void addExpression(Expression node) {
    addStatement(new ReturnStatement(node));
  }

  void addStatement(Statement node) {
    var function = enclosingMember.function;
    function.body = node..parent = function;
  }

  void addClassMember(Member node) {
    if (node is Procedure) {
      enclosingClass.addProcedure(node);
    } else if (node is Field) {
      enclosingClass.addField(node);
    } else if (node is Constructor) {
      enclosingClass.addConstructor(node);
    } else if (node is RedirectingFactory) {
      enclosingClass.addRedirectingFactory(node);
    } else {
      throw "Unexpected class member: ${node.runtimeType}";
    }
  }

  void addTopLevelMember(Member node) {
    if (node is Procedure) {
      enclosingLibrary.addProcedure(node);
    } else if (node is Field) {
      enclosingLibrary.addField(node);
    } else {
      throw "Unexpected top level member: ${node.runtimeType}";
    }
  }

  void addClass(Class node) {
    enclosingLibrary.addClass(node);
  }

  void addTypedef(Typedef node) {
    enclosingLibrary.addTypedef(node);
  }

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

  TypeParameter makeTypeParameter([String? name]) {
    return new TypeParameter(name, objectLegacyRawType, const DynamicType());
  }

  TestHarness() {
    setupComponent();
  }

  void setupComponent() {
    component = new Component();
    Uri dartCoreUri = Uri.parse('dart:core');
    stubLibrary = new Library(dartCoreUri, fileUri: dartCoreUri);
    component.libraries.add(stubLibrary..parent = component);
    stubLibrary.name = 'dart.core';
    objectClass = new Class(name: 'Object', fileUri: dartCoreUri);
    objectLegacyRawType =
        new InterfaceType(objectClass, Nullability.legacy, const <DartType>[]);
    stubLibrary.addClass(objectClass);
    Uri testUri = Uri.parse('file://test.dart');
    enclosingLibrary = new Library(testUri, fileUri: testUri);
    component.libraries.add(enclosingLibrary..parent = component);
    enclosingLibrary.name = 'test_lib';
    classTypeParameter = makeTypeParameter('T');
    enclosingClass = new Class(
        name: 'TestClass',
        typeParameters: [classTypeParameter],
        supertype: objectClass.asRawSupertype,
        fileUri: testUri);
    enclosingLegacyRawType = new InterfaceType(enclosingClass,
        Nullability.legacy, const <DartType>[const DynamicType()]);
    enclosingLibrary.addClass(enclosingClass);
    enclosingMember = new Procedure(new Name('test'), ProcedureKind.Method,
        new FunctionNode(new EmptyStatement()),
        fileUri: dummyUri);
    enclosingClass.addProcedure(enclosingMember);
    otherClass = new Class(
        name: 'OtherClass',
        typeParameters: [makeTypeParameter('OtherT')],
        supertype: objectClass.asRawSupertype,
        fileUri: testUri);
    otherLegacyRawType = new InterfaceType(
        otherClass, Nullability.legacy, const <DartType>[const DynamicType()]);
    enclosingLibrary.addClass(otherClass);
  }
}

negative1Test(String name, Node? Function(TestHarness test) nodeProvider,
    dynamic Function(Node? node) matcher) {
  TestHarness testHarness = new TestHarness();
  Node? node = nodeProvider(testHarness);
  test(
    name,
    () {
      dynamic matcherResult = matcher(node);
      if (matcherResult is String) {
        matcherResult = equals(matcherResult);
      }
      checkHasError(testHarness.component, matcherResult);
    },
  );
}

negative2Test(String name, List<Node?> Function(TestHarness test) nodeProvider,
    dynamic Function(Node? node, Node? other) matcher) {
  TestHarness testHarness = new TestHarness();
  List<Node?> nodes = nodeProvider(testHarness);
  if (nodes.length != 2) throw "Needs exactly 2 nodes: Node and other!";
  test(
    name,
    () {
      dynamic matcherResult = matcher(nodes[0], nodes[1]);
      if (matcherResult is String) {
        matcherResult = equals(matcherResult);
      }
      checkHasError(testHarness.component, matcherResult);
    },
  );
}

simpleNegativeTest(String name, dynamic matcher,
    void Function(TestHarness test) makeTestCase) {
  TestHarness testHarness = new TestHarness();
  test(
    name,
    () {
      makeTestCase(testHarness);
      if (matcher is String) {
        matcher = equals(matcher);
      }
      checkHasError(testHarness.component, matcher);
    },
  );
}

positiveTest(String name, void makeTestCase(TestHarness test)) {
  test(
    name,
    () {
      var test = new TestHarness();
      makeTestCase(test);
      verifyComponent(test.component);
    },
  );
}
