================================================================================
CLASS simple
================================================================================

public class Me {}

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

(parser_output
  (class_declaration
    (modifiers
      (modifier))
    (identifier)
    (class_body)))

================================================================================
CLASS private with sharing
================================================================================

private with sharing class Me {}

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

(parser_output
  (class_declaration
    (modifiers
      (modifier)
      (modifier))
    (identifier)
    (class_body)))

================================================================================
CLASS global without sharing
================================================================================

global without sharing class Me {}

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

(parser_output
  (class_declaration
    (modifiers
      (modifier)
      (modifier))
    (identifier)
    (class_body)))

================================================================================
CLASS public inherited sharing
================================================================================

public inherited sharing class Me {}

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

(parser_output
  (class_declaration
    (modifiers
      (modifier)
      (modifier))
    (identifier)
    (class_body)))

================================================================================
CLASS virtual
================================================================================

public inherited sharing virtual class Me {}

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

(parser_output
  (class_declaration
    (modifiers
      (modifier)
      (modifier)
      (modifier))
    (identifier)
    (class_body)))

================================================================================
CLASS abstract
================================================================================

public abstract class Me {}

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

(parser_output
  (class_declaration
    (modifiers
      (modifier)
      (modifier))
    (identifier)
    (class_body)))

================================================================================
CLASS initializer
================================================================================

public class Me {
    {
        Integer i = 1;
    }
}

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

(parser_output
  (class_declaration
    (modifiers
      (modifier))
    (identifier)
    (class_body
      (block
        (local_variable_declaration
          (type_identifier)
          (variable_declarator
            (identifier)
            (assignment_operator)
            (int)))))))

================================================================================
CLASS static initializer
================================================================================

public class Me {
    {
        Integer i = 1;
    }
}

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

(parser_output
  (class_declaration
    (modifiers
      (modifier))
    (identifier)
    (class_body
      (block
        (local_variable_declaration
          (type_identifier)
          (variable_declarator
            (identifier)
            (assignment_operator)
            (int)))))))

================================================================================
CLASS inner class
================================================================================

public class Me {

    public class Inside {
        {}
    }
}

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

(parser_output
  (class_declaration
    (modifiers
      (modifier))
    (identifier)
    (class_body
      (class_declaration
        (modifiers
          (modifier))
        (identifier)
        (class_body
          (block))))))

================================================================================
CLASS extending class
================================================================================

public class Me extends OtherClass {
}

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

(parser_output
  (class_declaration
    (modifiers
      (modifier))
    (identifier)
    (superclass
      (type_identifier))
    (class_body)))

================================================================================
CLASS extending class
================================================================================

public class Me implements Interface1 {
}

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

(parser_output
  (class_declaration
    (modifiers
      (modifier))
    (identifier)
    (interfaces
      (type_list
        (type_identifier)))
    (class_body)))

================================================================================
CLASS extending class multi
================================================================================

public class Me implements Interface1, Interface2 {
}

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

(parser_output
  (class_declaration
    (modifiers
      (modifier))
    (identifier)
    (interfaces
      (type_list
        (type_identifier)
        (type_identifier)))
    (class_body)))

================================================================================
CLASS super
================================================================================

public class Subclass extends Superclass {
  public override void printName() {
        super.printName();
        System.debug('But you can call me ' + super.getFirstName());
    }
}

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

(parser_output
  (class_declaration
    (modifiers
      (modifier))
    (identifier)
    (superclass
      (type_identifier))
    (class_body
      (method_declaration
        (modifiers
          (modifier)
          (modifier))
        (void_type)
        (identifier)
        (formal_parameters)
        (block
          (expression_statement
            (method_invocation
              (super)
              (identifier)
              (argument_list)))
          (expression_statement
            (method_invocation
              (identifier)
              (identifier)
              (argument_list
                (binary_expression
                  (string_literal)
                  (method_invocation
                    (super)
                    (identifier)
                    (argument_list)))))))))))

================================================================================
CLASS Extended Class Example
================================================================================
// https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_example.htm

// Top-level (outer) class must be public or global (usually public unless they contain
// a Web Service, then they must be global)
public class OuterClass {

  // Static final variable (constant) – outer class level only
  private static final Integer MY_INT;

  // Non-final static variable - use this to communicate state across triggers
  // within a single request)
  public static String sharedState;

  // Static method - outer class level only
  public static Integer getInt() { return MY_INT; }

  // Static initialization (can be included where the variable is defined)
  static {
    MY_INT = 2;
  }

  // Member variable for outer class
  private final String m;

  // Instance initialization block - can be done where the variable is declared,
  // or in a constructor
  {
    m = 'a';
  }

  // Because no constructor is explicitly defined in this outer class, an implicit,
  // no-argument, public constructor exists

  // Inner interface
  public virtual interface MyInterface {

    // No access modifier is necessary for interface methods - these are always
    // public or global depending on the interface visibility
    void myMethod();
  }

  // Interface extension
  interface MySecondInterface extends MyInterface {
    Integer method2(Integer i);
  }

  // Inner class - because it is virtual it can be extended.
  // This class implements an interface that, in turn, extends another interface.
  // Consequently the class must implement all methods.
  public virtual class InnerClass implements MySecondInterface {

    // Inner member variables
    private final String s;
    private final String s2;

    // Inner instance initialization block (this code could be located above)
    {
       this.s = 'x';
    }

    // Inline initialization (happens after the block above executes)
    private final Integer i = s.length();

    // Explicit no argument constructor
    InnerClass() {
       // This invokes another constructor that is defined later
       this('none');
    }

    // Constructor that assigns a final variable value
    public InnerClass(String s2) {
      this.s2 = s2;
    }

    // Instance method that implements a method from MyInterface.
    // Because it is declared virtual it can be overridden by a subclass.
    public virtual void myMethod() { /* does nothing */ }

    // Implementation of the second interface method above.
    // This method references member variables (with and without the "this" prefix)
    public Integer method2(Integer i) { return this.i + s.length(); }
  }

  // Abstract class (that subclasses the class above). No constructor is needed since
  // parent class has a no-argument constructor
  public abstract class AbstractChildClass extends InnerClass {

    // Override the parent class method with this signature.
    // Must use the override keyword
    public override void myMethod() { /* do something else */ }

    // Same name as parent class method, but different signature.
    // This is a different method (displaying polymorphism) so it does not need
    // to use the override keyword
    protected void method2() {}

    // Abstract method - subclasses of this class must implement this method
    abstract Integer abstractMethod();
  }

  // Complete the abstract class by implementing its abstract method
  public class ConcreteChildClass extends AbstractChildClass {
    // Here we expand the visibility of the parent method - note that visibility
    // cannot be restricted by a sub-class
    public override Integer abstractMethod() { return 5; }
  }

  // A second sub-class of the original InnerClass
  public class AnotherChildClass extends InnerClass {
    AnotherChildClass(String s) {
      // Explicitly invoke a different super constructor than one with no arguments
      super(s);
    }
  }

  // Exception inner class
  public virtual class MyException extends Exception {
    // Exception class member variable
    public Double d;

    // Exception class constructor
    MyException(Double d) {
      this.d = d;
    }

    // Exception class method, marked as protected
    protected void doIt() {}
  }

  // Exception classes can be abstract and implement interfaces
  public abstract class MySecondException extends Exception implements MyInterface {
  }
}

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

(parser_output
  (line_comment)
  (line_comment)
  (line_comment)
  (class_declaration
    (modifiers
      (modifier))
    (identifier)
    (class_body
      (line_comment)
      (field_declaration
        (modifiers
          (modifier)
          (modifier)
          (modifier))
        (type_identifier)
        (variable_declarator
          (identifier)))
      (line_comment)
      (line_comment)
      (field_declaration
        (modifiers
          (modifier)
          (modifier))
        (type_identifier)
        (variable_declarator
          (identifier)))
      (line_comment)
      (method_declaration
        (modifiers
          (modifier)
          (modifier))
        (type_identifier)
        (identifier)
        (formal_parameters)
        (block
          (return_statement
            (identifier))))
      (line_comment)
      (static_initializer
        (block
          (expression_statement
            (assignment_expression
              (identifier)
              (assignment_operator)
              (int)))))
      (line_comment)
      (field_declaration
        (modifiers
          (modifier)
          (modifier))
        (type_identifier)
        (variable_declarator
          (identifier)))
      (line_comment)
      (line_comment)
      (block
        (expression_statement
          (assignment_expression
            (identifier)
            (assignment_operator)
            (string_literal))))
      (line_comment)
      (line_comment)
      (line_comment)
      (interface_declaration
        (modifiers
          (modifier)
          (modifier))
        (identifier)
        (interface_body
          (line_comment)
          (line_comment)
          (method_declaration
            (void_type)
            (identifier)
            (formal_parameters))))
      (line_comment)
      (interface_declaration
        (identifier)
        (extends_interfaces
          (type_list
            (type_identifier)))
        (interface_body
          (method_declaration
            (type_identifier)
            (identifier)
            (formal_parameters
              (formal_parameter
                (type_identifier)
                (identifier))))))
      (line_comment)
      (line_comment)
      (line_comment)
      (class_declaration
        (modifiers
          (modifier)
          (modifier))
        (identifier)
        (interfaces
          (type_list
            (type_identifier)))
        (class_body
          (line_comment)
          (field_declaration
            (modifiers
              (modifier)
              (modifier))
            (type_identifier)
            (variable_declarator
              (identifier)))
          (field_declaration
            (modifiers
              (modifier)
              (modifier))
            (type_identifier)
            (variable_declarator
              (identifier)))
          (line_comment)
          (block
            (expression_statement
              (assignment_expression
                (field_access
                  (this)
                  (identifier))
                (assignment_operator)
                (string_literal))))
          (line_comment)
          (field_declaration
            (modifiers
              (modifier)
              (modifier))
            (type_identifier)
            (variable_declarator
              (identifier)
              (assignment_operator)
              (method_invocation
                (identifier)
                (identifier)
                (argument_list))))
          (line_comment)
          (constructor_declaration
            (identifier)
            (formal_parameters)
            (constructor_body
              (line_comment)
              (explicit_constructor_invocation
                (this)
                (argument_list
                  (string_literal)))))
          (line_comment)
          (constructor_declaration
            (modifiers
              (modifier))
            (identifier)
            (formal_parameters
              (formal_parameter
                (type_identifier)
                (identifier)))
            (constructor_body
              (expression_statement
                (assignment_expression
                  (field_access
                    (this)
                    (identifier))
                  (assignment_operator)
                  (identifier)))))
          (line_comment)
          (line_comment)
          (method_declaration
            (modifiers
              (modifier)
              (modifier))
            (void_type)
            (identifier)
            (formal_parameters)
            (block
              (block_comment)))
          (line_comment)
          (line_comment)
          (method_declaration
            (modifiers
              (modifier))
            (type_identifier)
            (identifier)
            (formal_parameters
              (formal_parameter
                (type_identifier)
                (identifier)))
            (block
              (return_statement
                (binary_expression
                  (field_access
                    (this)
                    (identifier))
                  (method_invocation
                    (identifier)
                    (identifier)
                    (argument_list))))))))
      (line_comment)
      (line_comment)
      (class_declaration
        (modifiers
          (modifier)
          (modifier))
        (identifier)
        (superclass
          (type_identifier))
        (class_body
          (line_comment)
          (line_comment)
          (method_declaration
            (modifiers
              (modifier)
              (modifier))
            (void_type)
            (identifier)
            (formal_parameters)
            (block
              (block_comment)))
          (line_comment)
          (line_comment)
          (line_comment)
          (method_declaration
            (modifiers
              (modifier))
            (void_type)
            (identifier)
            (formal_parameters)
            (block))
          (line_comment)
          (method_declaration
            (modifiers
              (modifier))
            (type_identifier)
            (identifier)
            (formal_parameters))))
      (line_comment)
      (class_declaration
        (modifiers
          (modifier))
        (identifier)
        (superclass
          (type_identifier))
        (class_body
          (line_comment)
          (line_comment)
          (method_declaration
            (modifiers
              (modifier)
              (modifier))
            (type_identifier)
            (identifier)
            (formal_parameters)
            (block
              (return_statement
                (int))))))
      (line_comment)
      (class_declaration
        (modifiers
          (modifier))
        (identifier)
        (superclass
          (type_identifier))
        (class_body
          (constructor_declaration
            (identifier)
            (formal_parameters
              (formal_parameter
                (type_identifier)
                (identifier)))
            (constructor_body
              (line_comment)
              (explicit_constructor_invocation
                (super)
                (argument_list
                  (identifier)))))))
      (line_comment)
      (class_declaration
        (modifiers
          (modifier)
          (modifier))
        (identifier)
        (superclass
          (type_identifier))
        (class_body
          (line_comment)
          (field_declaration
            (modifiers
              (modifier))
            (type_identifier)
            (variable_declarator
              (identifier)))
          (line_comment)
          (constructor_declaration
            (identifier)
            (formal_parameters
              (formal_parameter
                (type_identifier)
                (identifier)))
            (constructor_body
              (expression_statement
                (assignment_expression
                  (field_access
                    (this)
                    (identifier))
                  (assignment_operator)
                  (identifier)))))
          (line_comment)
          (method_declaration
            (modifiers
              (modifier))
            (void_type)
            (identifier)
            (formal_parameters)
            (block))))
      (line_comment)
      (class_declaration
        (modifiers
          (modifier)
          (modifier))
        (identifier)
        (superclass
          (type_identifier))
        (interfaces
          (type_list
            (type_identifier)))
        (class_body)))))

================================================================================
CLASS extending class
================================================================================

/*
"super" https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_keywords_super.htm
Is that different??

"this" keyword https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_keywords_this.htm
*/

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

(parser_output
  (block_comment))
