================================================================================
Global empty class
================================================================================

public class F {}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (modifier)
    name: (identifier)
    body: (declaration_list)))

================================================================================
Class base is dynamic
================================================================================

public class F : dynamic { }

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (modifier)
    name: (identifier)
    bases: (base_list
      (identifier))
    body: (declaration_list)))

================================================================================
Class base is object with interfaces
================================================================================

public class F : object, IAlpha, IOmega { }

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (modifier)
    name: (identifier)
    bases: (base_list
      (predefined_type)
      (identifier)
      (identifier))
    body: (declaration_list)))

================================================================================
Partial class
================================================================================

public partial class F {}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (modifier)
    (modifier)
    (identifier)
    (declaration_list)))

================================================================================
Class with a single type parameter
================================================================================

class F<T> {}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (identifier)
    (type_parameter_list
      (type_parameter
        (identifier)))
    (declaration_list)))

================================================================================
Class with multiple type parameters
================================================================================

internal class F<T1, T2> {}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (modifier)
    (identifier)
    (type_parameter_list
      (type_parameter
        (identifier))
      (type_parameter
        (identifier)))
    (declaration_list)))

================================================================================
Class with co-variant and contra-variant type parameters
================================================================================

internal class F<in T1, out T2> {}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (modifier)
    (identifier)
    (type_parameter_list
      (type_parameter
        (identifier))
      (type_parameter
        (identifier)))
    (declaration_list)))

================================================================================
Class with a type parameter struct constraint
================================================================================

public class F<T> where T:struct {}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (modifier)
    (identifier)
    (type_parameter_list
      (type_parameter
        (identifier)))
    (type_parameter_constraints_clause
      (identifier)
      (type_parameter_constraint))
    (declaration_list)))

================================================================================
Class with a type parameter unmanaged constraint
================================================================================

public class F<T> where T:unmanaged {}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (modifier)
    (identifier)
    (type_parameter_list
      (type_parameter
        (identifier)))
    (type_parameter_constraints_clause
      (identifier)
      (type_parameter_constraint))
    (declaration_list)))

================================================================================
Class with a type parameter class constraint
================================================================================

public class F<T> where T:class {}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (modifier)
    (identifier)
    (type_parameter_list
      (type_parameter
        (identifier)))
    (type_parameter_constraints_clause
      (identifier)
      (type_parameter_constraint))
    (declaration_list)))

================================================================================
Class with a type parameter and nullable constraints
================================================================================

public class F<T> where T:class?, notnull, Mine? {}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (modifier)
    (identifier)
    (type_parameter_list
      (type_parameter
        (identifier)))
    (type_parameter_constraints_clause
      (identifier)
      (type_parameter_constraint)
      (type_parameter_constraint)
      (type_parameter_constraint
        (type_constraint
          (nullable_type
            (identifier)))))
    (declaration_list)))

================================================================================
Class with type parameter new constraint
================================================================================

public class F<T> where T: new() {}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (modifier)
    (identifier)
    (type_parameter_list
      (type_parameter
        (identifier)))
    (type_parameter_constraints_clause
      (identifier)
      (type_parameter_constraint
        (constructor_constraint)))
    (declaration_list)))

================================================================================
Class with type parameter identifier constraint
================================================================================

public class F<T> where T: I {}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (modifier)
    (identifier)
    (type_parameter_list
      (type_parameter
        (identifier)))
    (type_parameter_constraints_clause
      (identifier)
      (type_parameter_constraint
        (type_constraint
          (identifier))))
    (declaration_list)))

================================================================================
Class with type parameter identifier and new constraints
================================================================================

public class F<T> where T: I, new() {}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (modifier)
    (identifier)
    (type_parameter_list
      (type_parameter
        (identifier)))
    (type_parameter_constraints_clause
      (identifier)
      (type_parameter_constraint
        (type_constraint
          (identifier)))
      (type_parameter_constraint
        (constructor_constraint)))
    (declaration_list)))

================================================================================
Class with multiple type parameter constraints
================================================================================

private class F<T1,T2> where T1 : I1, I2, new() where T2 : I2 { }

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (modifier)
    (identifier)
    (type_parameter_list
      (type_parameter
        (identifier))
      (type_parameter
        (identifier)))
    (type_parameter_constraints_clause
      (identifier)
      (type_parameter_constraint
        (type_constraint
          (identifier)))
      (type_parameter_constraint
        (type_constraint
          (identifier)))
      (type_parameter_constraint
        (constructor_constraint)))
    (type_parameter_constraints_clause
      (identifier)
      (type_parameter_constraint
        (type_constraint
          (identifier))))
    (declaration_list)))

================================================================================
Class with public constructor
================================================================================

class Foo {
  public Foo() {}
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (identifier)
    (declaration_list
      (constructor_declaration
        (modifier)
        (identifier)
        (parameter_list)
        (block)))))

================================================================================
Class with expression bodied constructor
================================================================================

class Foo {
  public Foo(string name) => Name = name;
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (identifier)
    (declaration_list
      (constructor_declaration
        (modifier)
        (identifier)
        (parameter_list
          (parameter
            (predefined_type)
            (identifier)))
        (arrow_expression_clause
          (assignment_expression
            (identifier)
            (assignment_operator)
            (identifier)))))))

================================================================================
Class with static constructor
================================================================================

class Foo {
  static Foo() {}
  static extern Foo() {}
  extern static Foo() {}
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (identifier)
    (declaration_list
      (constructor_declaration
        (modifier)
        (identifier)
        (parameter_list)
        (block))
      (constructor_declaration
        (modifier)
        (modifier)
        (identifier)
        (parameter_list)
        (block))
      (constructor_declaration
        (modifier)
        (modifier)
        (identifier)
        (parameter_list)
        (block)))))

================================================================================
Class with extern destructor
================================================================================

class Foo {
  extern ~Foo() {}
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (identifier)
    (declaration_list
      (destructor_declaration
        (identifier)
        (parameter_list)
        (block)))))

================================================================================
Class with expression bodied destructor
================================================================================

class Foo {
  ~Foo() => DoSomething();
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (identifier)
    (declaration_list
      (destructor_declaration
        (identifier)
        (parameter_list)
        (arrow_expression_clause
          (invocation_expression
            (identifier)
            (argument_list)))))))

================================================================================
Class with constants
================================================================================

class Foo {
  private const int a = 1;
  const string b = $"hello";
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (identifier)
    (declaration_list
      (field_declaration
        (modifier)
        (modifier)
        (variable_declaration
          (predefined_type)
          (variable_declarator
            (identifier)
            (equals_value_clause
              (integer_literal)))))
      (field_declaration
        (modifier)
        (variable_declaration
          (predefined_type)
          (variable_declarator
            (identifier)
            (equals_value_clause
              (interpolated_string_expression
                (interpolated_string_text)))))))))

================================================================================
Class with indexer
================================================================================

class Foo {
  public bool this[int index] {
    get { return a; }
    set { a = value; }
  }
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (identifier)
    (declaration_list
      (indexer_declaration
        (modifier)
        (predefined_type)
        (bracketed_parameter_list
          (parameter
            (predefined_type)
            (identifier)))
        (accessor_list
          (accessor_declaration
            (block
              (return_statement
                (identifier))))
          (accessor_declaration
            (block
              (expression_statement
                (assignment_expression
                  (identifier)
                  (assignment_operator)
                  (identifier))))))))))

================================================================================
Class with expression bodied indexer
================================================================================

class Foo {
  public bool this[int index] => a[index];
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (identifier)
    (declaration_list
      (indexer_declaration
        (modifier)
        (predefined_type)
        (bracketed_parameter_list
          (parameter
            (predefined_type)
            (identifier)))
        (arrow_expression_clause
          (element_access_expression
            (identifier)
            (bracketed_argument_list
              (argument
                (identifier)))))))))

================================================================================
Class with expression bodied indexer accessors
================================================================================

class Foo {
    public string this[int index]
    {
        get => a[index];
        set => a[index] = value;
    }
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (identifier)
    (declaration_list
      (indexer_declaration
        (modifier)
        (predefined_type)
        (bracketed_parameter_list
          (parameter
            (predefined_type)
            (identifier)))
        (accessor_list
          (accessor_declaration
            (arrow_expression_clause
              (element_access_expression
                (identifier)
                (bracketed_argument_list
                  (argument
                    (identifier))))))
          (accessor_declaration
            (arrow_expression_clause
              (assignment_expression
                (element_access_expression
                  (identifier)
                  (bracketed_argument_list
                    (argument
                      (identifier))))
                (assignment_operator)
                (identifier)))))))))

================================================================================
Class with varargs indexer
================================================================================

class A {
    public int this[params string[] arguments] {
        get { return 1; }
    }
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (identifier)
    (declaration_list
      (indexer_declaration
        (modifier)
        (predefined_type)
        (bracketed_parameter_list
          (array_type
            (predefined_type)
            (array_rank_specifier))
          (identifier))
        (accessor_list
          (accessor_declaration
            (block
              (return_statement
                (integer_literal)))))))))

================================================================================
Method with qualified return type
================================================================================

class A {
  B.C d() {
    return null;
  }
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    name: (identifier)
    body: (declaration_list
      (method_declaration
        type: (qualified_name
          (identifier)
          (identifier))
        name: (identifier)
        parameters: (parameter_list)
        body: (block
          (return_statement
            (null_literal)))))))

================================================================================
Class and methods with Unicode identifiers
================================================================================

class Ωµ {
  B.C d() {
    return null;
  }
}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    name: (identifier)
    body: (declaration_list
      (method_declaration
        type: (qualified_name
          (identifier)
          (identifier))
        name: (identifier)
        parameters: (parameter_list)
        body: (block
          (return_statement
            (null_literal)))))))

================================================================================
File scoped class
================================================================================

file class A {}

--------------------------------------------------------------------------------

(compilation_unit
  (class_declaration
    (modifier)
    name: (identifier)
    body: (declaration_list)))
