===============
local variable
===============

class A {
  public int b() {
    int c = 5;
  }
}

---

(program
  (class_declaration
    name: (identifier)
    body: (class_body
      (method_declaration
        (modifiers)
        type: (integral_type)
        name: (identifier)
        parameters: (formal_parameters)
        body: (block
          (local_variable_declaration
            type: (integral_type)
            declarator: (variable_declarator
              name: (identifier)
              value: (decimal_integer_literal))))))))

=====================
local array variable
=====================

String[] nodeNames = internalCluster().getNodeNames();
Integer[][] inputArrays = new Integer[0x100][];

---

(program
  (local_variable_declaration
    type: (array_type
      element: (type_identifier)
      dimensions: (dimensions))
    declarator: (variable_declarator
      name: (identifier)
      value: (method_invocation
        object: (method_invocation
          name: (identifier)
          arguments: (argument_list))
        name: (identifier)
        arguments: (argument_list))))
  (local_variable_declaration
    type: (array_type
      element: (type_identifier)
      dimensions: (dimensions))
    declarator: (variable_declarator
      name: (identifier)
      value: (array_creation_expression
        type: (type_identifier)
        dimensions: (dimensions_expr (hex_integer_literal))
        dimensions: (dimensions)))))

==========
module
==========

module com.foo { }
open module com.foo { }

---

(program
  (module_declaration
    name: (scoped_identifier
      scope: (identifier)
      name: (identifier))
    body: (module_body))
  (module_declaration
    name: (scoped_identifier
      scope: (identifier)
      name: (identifier))
    body: (module_body)))

==============================
module with normal annotation
==============================

@RequestForEnhancement(
    id       = 2868724,
    synopsis = "Provide time-travel functionality",
    engineer = "Mr. Peabody",
    date     = "4/1/2004"
)
module com.foo { }

---

(program
  (module_declaration
    (annotation
      (identifier)
      (annotation_argument_list
        (element_value_pair (identifier) (decimal_integer_literal))
        (element_value_pair (identifier) (string_literal (string_fragment)))
        (element_value_pair (identifier) (string_literal (string_fragment)))
        (element_value_pair (identifier) (string_literal (string_fragment)))))
    (scoped_identifier (identifier) (identifier))
    (module_body)))

==============================
module with marker annotation
==============================

@Preliminary module com.foo { }
@Preliminary open module com.foo { }

---

(program
  (module_declaration
    (marker_annotation (identifier))
    (scoped_identifier (identifier) (identifier))
    (module_body))
  (module_declaration
    (marker_annotation (identifier))
    (scoped_identifier (identifier) (identifier))
    (module_body)))

======================================
module with single element annotation
======================================

@Copyright("a")
module com.foo {}

---

(program
  (module_declaration
    (annotation
      (identifier)
      (annotation_argument_list (string_literal (string_fragment))))
    (scoped_identifier
      (identifier)
      (identifier))
    (module_body)))

====================
package_declaration
====================

package myVector;

---

 (program (package_declaration (identifier)))

=================
module directive
=================

module com.example.foo {
    requires com.example.foo.http;
}

---

(program
  (module_declaration
    name: (scoped_identifier
      scope: (scoped_identifier
        scope: (identifier)
        name: (identifier))
      name: (identifier))
    body: (module_body
      (requires_module_directive
        module: (scoped_identifier
          scope: (scoped_identifier
            scope: (scoped_identifier
              scope: (identifier)
              name: (identifier))
            name: (identifier))
          name: (identifier))))))

==================================================================
module directive with requires, exports, opens, uses and provides
==================================================================

module com.example.foo {
    requires com.example.http;
    requires java.logging;

    requires transitive com.example.network;

    exports com.example.bar;
    exports com.example.internal to com.example.probe;

    opens com.example.quux;
    opens com.example.internal to com.example.network, com.example.probe;

    uses com.example.Intf;
    provides com.example.Intf with com.example.Impl;
}

---

(program
  (module_declaration
    (scoped_identifier (scoped_identifier (identifier) (identifier)) (identifier))
    (module_body
      (requires_module_directive
        (scoped_identifier (scoped_identifier (identifier) (identifier)) (identifier)))
      (requires_module_directive
        (scoped_identifier (identifier) (identifier)))
      (requires_module_directive
        (requires_modifier)
        (scoped_identifier (scoped_identifier (identifier) (identifier)) (identifier)))
      (exports_module_directive
        (scoped_identifier (scoped_identifier (identifier) (identifier)) (identifier)))
      (exports_module_directive
        (scoped_identifier (scoped_identifier (identifier) (identifier)) (identifier))
        (scoped_identifier (scoped_identifier (identifier) (identifier)) (identifier)))
      (opens_module_directive
        (scoped_identifier (scoped_identifier (identifier) (identifier)) (identifier)))
      (opens_module_directive
        (scoped_identifier (scoped_identifier (identifier) (identifier)) (identifier))
        (scoped_identifier (scoped_identifier (identifier) (identifier)) (identifier))
        (scoped_identifier (scoped_identifier (identifier) (identifier)) (identifier)))
      (uses_module_directive
        (scoped_identifier (scoped_identifier (identifier) (identifier)) (identifier)))
      (provides_module_directive
        (scoped_identifier (scoped_identifier (identifier) (identifier)) (identifier))
        (scoped_identifier (scoped_identifier (identifier) (identifier)) (identifier))))))

===============================
single type import declaration
===============================

import java.util.Vector;

---

(program (import_declaration
  (scoped_identifier (scoped_identifier (identifier) (identifier)) (identifier))))

===========================
type_import_on_declaraction
===========================

import java.util.*;

---

(program (import_declaration
  (scoped_identifier (identifier) (identifier)) (asterisk)))

=================================
single static import declaration
=================================

import static java.util.Vector;

---

(program (import_declaration
  (scoped_identifier
    (scoped_identifier (identifier) (identifier))
    (identifier))))

===================================
static import on demand declaration
===================================

import static java.util.*;

---

(program (import_declaration
  (scoped_identifier (identifier) (identifier))
  (asterisk)))

=================
class declaration
=================

class Point {
}

---

(program
  (class_declaration
    (identifier)
      (class_body)))

=====================================================================
class declaration involving public, private, abstract and superclass
=====================================================================

public class Point {
}

private class Point {
}

abstract class ColoredPoint extends Point {
}

---

(program
  (class_declaration (modifiers) (identifier) (class_body))
  (class_declaration (modifiers) (identifier) (class_body))
  (class_declaration (modifiers) (identifier) (superclass (type_identifier)) (class_body)))

==================================
class declaration with implements
==================================

public class Dog implements ISpeak {
}

---

(program
  (class_declaration
     (modifiers) (identifier)
     (super_interfaces (type_list (type_identifier))) (class_body)))

============================
class declaration with body
============================

class Point {
  int x;

  void bar() {
    x = 2;
  }
}

---

(program
  (class_declaration
    (identifier)
    (class_body
      (field_declaration
        (integral_type)
        (variable_declarator (identifier)))
      (method_declaration
        (void_type)
        (identifier)
        (formal_parameters)
        (block
          (expression_statement
            (assignment_expression (identifier) (decimal_integer_literal))))))))

======================
interface declaration
======================

interface Top {
}

---

(program
  (interface_declaration
    (identifier)
    (interface_body)))

===================================
interface declaration with extends
===================================

interface Left extends Top {
}

interface Bottom extends Left, Right {}

---

(program
  (interface_declaration
    (identifier)
    (extends_interfaces (type_list (type_identifier)))
    (interface_body))
  (interface_declaration
    (identifier)
    (extends_interfaces (type_list (type_identifier) (type_identifier))) (interface_body)))

===========================================
interface with annotation type declaration
===========================================

@interface SelfRef {}

---

(program
  (annotation_type_declaration (identifier) (annotation_type_body)))

===================
method declaration
===================

class Beyonce {
  void calculateAnswer(double wingSpan, int numberOfEngines,
                       double length, double grossTons) {
      //do the calculation here
  }
}

---

(program
  (class_declaration
    (identifier)
    (class_body
      (method_declaration
        (void_type)
        (identifier)
        (formal_parameters
          (formal_parameter (floating_point_type) (identifier))
          (formal_parameter (integral_type) (identifier))
          (formal_parameter (floating_point_type) (identifier))
          (formal_parameter (floating_point_type) (identifier)))
        (block (line_comment))))))

========================
constructor declaration
========================

class Point {
  int x, y;
  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }

  Point() {
    this(0, 0);
  }
}

---

(program
  (class_declaration
    name: (identifier)
    body: (class_body
      (field_declaration
        type: (integral_type)
        declarator: (variable_declarator name: (identifier))
        declarator: (variable_declarator name: (identifier)))
      (constructor_declaration
        name: (identifier)
        parameters: (formal_parameters
          (formal_parameter
            type: (integral_type)
            name: (identifier))
          (formal_parameter
            type: (integral_type)
            name: (identifier)))
        body: (constructor_body
          (expression_statement (assignment_expression
            left: (field_access
              object: (this)
              field: (identifier))
            right: (identifier)))
          (expression_statement (assignment_expression
            left: (field_access
              object: (this)
              field: (identifier))
            right: (identifier)))))
      (constructor_declaration
        name: (identifier)
        parameters: (formal_parameters)
        body: (constructor_body
          (explicit_constructor_invocation
            constructor: (this)
            arguments: (argument_list
              (decimal_integer_literal)
              (decimal_integer_literal))))))))

=======
throws
=======

class Beyonce {
  BufferedReader newReader() throws FileNotFoundException {
    new BufferedReader(new InputStreamReader(new FileInputStream(file), charset));
  }
}

---

(program
  (class_declaration
    (identifier)
      (class_body
        (method_declaration
          (type_identifier)
          (identifier)
          (formal_parameters)
          (throws (type_identifier))
          (block
            (expression_statement
              (object_creation_expression
                (type_identifier)
                (argument_list
                  (object_creation_expression
                    (type_identifier)
                    (argument_list
                      (object_creation_expression
                        (type_identifier)
                        (argument_list (identifier)))
                      (identifier)))))))))))

======================
object instantiation
======================

class Point {
  public double Foo() {
    new BufferedWriter();
    Foo.new BufferedWriter();
  }
}

---

(program
  (class_declaration
    (identifier)
    (class_body
      (method_declaration
        (modifiers)
        (floating_point_type)
        (identifier)
        (formal_parameters)
        (block
          (expression_statement
            (object_creation_expression
              (type_identifier)
              (argument_list)))
          (expression_statement
            (object_creation_expression
              (identifier)
              (type_identifier)
              (argument_list))))))))

=====================
variable declaration
=====================

class JayZ {
  public void Beyonce() {
    int blue_ivy_carter;
  };
}

---

(program
  (class_declaration
    (identifier)
    (class_body
      (method_declaration
        (modifiers)
        (void_type)
        (identifier)
        (formal_parameters)
        (block
          (local_variable_declaration
            (integral_type)
            (variable_declarator
              (identifier))))))))

=================
enum declaration
=================

enum HandSign {
   SCISSOR, PAPER, STONE
}

---

(program
  (enum_declaration
    name: (identifier)
    body: (enum_body
      (enum_constant name: (identifier))
      (enum_constant name: (identifier))
      (enum_constant name: (identifier)))))


=================
enum declaration inside an interface
=================

public @interface Foo {
  enum HandSign {
     SCISSOR, PAPER, STONE
  }
}

---

    (program
      (annotation_type_declaration
        (modifiers)
        name: (identifier)
        body: (annotation_type_body
          (enum_declaration
            name: (identifier)
            body: (enum_body
              (enum_constant
                name: (identifier))
              (enum_constant
                name: (identifier))
              (enum_constant
                name: (identifier)))))))

=================
record declaration
==================

public record Foo(int bar) {
}

---

(program
  (record_declaration
        (modifiers)
        name: (identifier)
        parameters: (formal_parameters
          (formal_parameter
            type: (integral_type)
            name: (identifier)))
        body: (class_body)))

================================
record declaration with generics
================================

public record Foo<T>(T bar) {
}

---

(program
  (record_declaration
        (modifiers)
        name: (identifier)
        type_parameters: (type_parameters
          (type_parameter
            (type_identifier)))
        parameters: (formal_parameters
          (formal_parameter
            type: (type_identifier)
            name: (identifier)))
        body: (class_body)))

=================================
record declaration inside a class
=================================

public class Usecase {
    public static record Commande(@NotNull String param) {
        public Commande foo() {
            return new Commande("");
        }
    }
}

---

(program
  (class_declaration
    (modifiers)
    name: (identifier)
    body: (class_body
      (record_declaration
        (modifiers)
        name: (identifier)
        parameters: (formal_parameters
          (formal_parameter
            (modifiers
              (marker_annotation
                name: (identifier)))
            type: (type_identifier)
            name: (identifier)))
        body: (class_body
          (method_declaration
            (modifiers)
            type: (type_identifier)
            name: (identifier)
            parameters: (formal_parameters)
            body: (block
              (return_statement
                (object_creation_expression
                  type: (type_identifier)
                  arguments: (argument_list
                    (string_literal)))))))))))

======================================
record declaration inside an interface
======================================

interface I { record R(int a) {} }

---

(program
  (interface_declaration
    (identifier)
    (interface_body
      (record_declaration
        (identifier)
        (formal_parameters
          (formal_parameter
            (integral_type)
            (identifier)))
        (class_body)))))


===========================================
record declaration with compact constructor
===========================================

record Person(int age) {
  public Person {
    if (age < 0) throw new IllegalArgumentException("invalid age"); 
  }
}

---

(program
  (record_declaration
    (identifier)
    (formal_parameters
      (formal_parameter
        (integral_type)
        (identifier)))
    (class_body
      (compact_constructor_declaration
        (modifiers)
        (identifier)
        (block
          (if_statement
            (condition
              (binary_expression
                (identifier)
                (decimal_integer_literal)))
            (throw_statement
              (object_creation_expression
                (type_identifier)
                (argument_list
                  (string_literal
                        (string_fragment)))))))))))

============================================
record declaration that implements interface
============================================

record R() implements I {}

---

(program
  (record_declaration
    (identifier)
    (formal_parameters)
    (super_interfaces
      (type_list
        (type_identifier)))
    (class_body)))


==============================================
class declaration with dollar-sign identifiers
==============================================

class A$B {
  void func() {
    $object.$property;
    $hello();
  }
}

---

(program
  (class_declaration
    (identifier)
    (class_body
      (method_declaration
        (void_type)
        (identifier)
        (formal_parameters)
        (block
          (expression_statement
            (field_access
              (identifier)
              (identifier)))
          (expression_statement
            (method_invocation
              (identifier)
              (argument_list))))))))

================
 Sealed classes
================

sealed interface A permits B, C {

}

final class B implements A {}
non-sealed interface C extends A {}

---

(program
      (interface_declaration
        (modifiers)
        (identifier)
        (permits
          (type_list
            (type_identifier)
            (type_identifier)))
        (interface_body))
      (class_declaration
        (modifiers)
        (identifier)
        (super_interfaces
          (type_list
            (type_identifier)))
        (class_body))
      (interface_declaration
        (modifiers)
        (identifier)
        (extends_interfaces
          (type_list
            (type_identifier)))
        (interface_body)))
