================================
Package
================================

package a.b
package c {
  object A
}

---

(compilation_unit
  (package_clause (package_identifier (identifier) (identifier)))
  (package_clause (package_identifier (identifier))
    (template_body
      (object_definition (identifier)))))

================================
Package object
================================

package object d extends A {
  val hello: String = "there"
}

---

(compilation_unit
  (package_object
    (identifier)
    (extends_clause (type_identifier))
    (template_body
      (val_definition (identifier) (type_identifier) (string)))))

================================
Imports
================================

import PartialFunction.condOpt
import a.b, c.e
import reflect.io.{Directory, File, Path}

---

(compilation_unit
  (import_declaration
    (stable_identifier (identifier) (identifier)))
  (import_declaration
    (stable_identifier (identifier) (identifier))
    (stable_identifier (identifier) (identifier)))
  (import_declaration
    (stable_identifier (identifier) (identifier))
    (import_selectors (identifier) (identifier) (identifier))))

================================
Imports: Wildcard
================================

import tools.nsc.classpath._

---

(compilation_unit
  (import_declaration
    (stable_identifier (stable_identifier (identifier) (identifier)) (identifier))
    (import_wildcard)))

================================
Imports: Wildcard (Scala 3 syntax)
================================

import tools.nsc.classpath.*

---

(compilation_unit
  (import_declaration
    (stable_identifier (stable_identifier (identifier) (identifier)) (identifier))
    (import_wildcard)))

================================
Imports: Wildcard and wildcard givens (Scala 3 syntax)
================================

import tools.nsc.classpath.{*, given}
import tools.given

---

(compilation_unit
  (import_declaration
    (stable_identifier (stable_identifier (identifier) (identifier)) (identifier))
    (import_selectors 
      (import_wildcard)
      (import_wildcard)))
  (import_declaration
    (identifier)
    (import_wildcard))) 

================================
Imports: Givens by type (Scala 3 syntax)
================================

import tools.nsc.classpath.{given Test, given Test2, Test3}

---

(compilation_unit
  (import_declaration
    (stable_identifier (stable_identifier (identifier) (identifier)) (identifier))
    (import_selectors 
      (type_identifier)
      (type_identifier)
      (identifier))))

================================
Imports: Rename (Scala 3 Syntax)
================================

import lang.System.{lineSeparator as EOL}

---

(compilation_unit
  (import_declaration
    (stable_identifier (identifier) (identifier))
    (import_selectors (renamed_identifier (identifier) (identifier)))))

================================
Imports: Rename
================================

import lang.System.{lineSeparator => EOL}

---

(compilation_unit
  (import_declaration
    (stable_identifier (identifier) (identifier))
    (import_selectors (renamed_identifier (identifier) (identifier)))))


=================================
Object definitions
=================================

// o1
object O1 {
}

case object O2 {
}

object O3 extends A {
}

---

(compilation_unit
  (comment)
  (object_definition (identifier) (template_body))
  (object_definition (identifier) (template_body))
  (object_definition (identifier) (extends_clause (type_identifier)) (template_body)))

=======================================
Class definitions
=======================================

class C[T, U] {
}
---

(compilation_unit
  (class_definition
    (identifier)
    (type_parameters (identifier) (identifier))
    (template_body)))

=======================================
Subclass definitions
=======================================

class A extends B.C[D, E] {
}

class A(b: B) extends C(b || ok) {
}

object C {
    class A
        extends B[T]
        with C[T]
}

---

(compilation_unit
  (class_definition
    (identifier)
    (extends_clause
      (generic_type
        (stable_type_identifier
          (identifier)
          (type_identifier))
        (type_arguments (type_identifier) (type_identifier))))
    (template_body))
  (class_definition
    (identifier)
    (class_parameters
      (class_parameter (identifier) (type_identifier)))
    (extends_clause
      (type_identifier)
      (arguments
        (infix_expression (identifier) (operator_identifier) (identifier))))
    (template_body))
  (object_definition
    (identifier)
    (template_body
        (class_definition (identifier) (extends_clause
          (compound_type
            (generic_type (type_identifier) (type_arguments (type_identifier)))
            (generic_type (type_identifier) (type_arguments (type_identifier)))))))))

=======================================
Class definitions with parameters
=======================================

class Point(val x: Int, val y: Int)(implicit coord: Coord)

---

(compilation_unit
  (class_definition
    (identifier)
    (class_parameters
      (class_parameter (identifier) (type_identifier))
      (class_parameter (identifier) (type_identifier)))
    (class_parameters
      (class_parameter (identifier) (type_identifier)))))

=======================================
Modifiers
=======================================

implicit final sealed class Point {
  private override def getX() = 1
}

private[a] class D[T] private (x: T) {
  private[a] def b: Byte
}

---

(compilation_unit
  (class_definition
    (modifiers)
    (identifier)
    (template_body
      (function_definition
        (modifiers (access_modifier))
        (identifier)
        (parameters)
        (integer_literal))))
    (class_definition (modifiers (access_modifier (access_qualifier (identifier))))
      (identifier) (type_parameters (identifier))
      (access_modifier) (class_parameters (class_parameter (identifier) (type_identifier)))
      (template_body (function_declaration
        (modifiers (access_modifier (access_qualifier (identifier))))
        (identifier) (type_identifier)))))

=======================================
Trait definitions
=======================================

trait A extends B

trait A extends B with C

trait T[U] {
}

trait T[U] extends V.W[U] {
}

---

(compilation_unit
  (trait_definition
    (identifier)
    (extends_clause (type_identifier)))
  (trait_definition
    (identifier)
    (extends_clause (compound_type (type_identifier) (type_identifier))))
  (trait_definition
    (identifier)
    (type_parameters (identifier))
    (template_body))
  (trait_definition
    (identifier)
    (type_parameters (identifier))
    (extends_clause (generic_type
      (stable_type_identifier (identifier) (type_identifier))
      (type_arguments (type_identifier))))
    (template_body)))

=======================================
Value declarations
=======================================

class A {
  val b, c : Int
  val d : String
}

---

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (val_declaration
        (identifier)
        (identifier)
        (type_identifier))
      (val_declaration
        (identifier)
        (type_identifier)))))

=======================================
Value definitions
=======================================

class A {
  val b = 1
  val c : String = "d"
}

---

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (val_definition
        (identifier)
        (integer_literal))
      (val_definition
        (identifier)
        (type_identifier)
        (string)))))

=======================================
Variable declarations
=======================================

class A {
  var b, c : Int
  var d : String
}

---

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (var_declaration
        (identifier)
        (identifier)
        (type_identifier))
      (var_declaration
        (identifier)
        (type_identifier)))))

=======================================
Variable definitions
=======================================

class A {
  var b : Int = 1
}

---

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (var_definition
        (identifier)
        (type_identifier)
        (integer_literal)))))

=======================================
Type definitions
=======================================

class A {
  type B = C
  type D[E] = F
}

---

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (type_definition
        (type_identifier)
        (type_identifier))
      (type_definition
        (type_identifier)
        (type_parameters (identifier))
        (type_identifier)))))

=======================================
Function declarations
=======================================

class A {
  def b(c: D) : E
  def <*[B](that: IO[B]): IO[A]
}

---

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (function_declaration
        (identifier)
        (parameters (parameter (identifier) (type_identifier)))
        (type_identifier))
      (function_declaration
        (operator_identifier)
        (type_parameters (identifier))
        (parameters (parameter (identifier) (generic_type (type_identifier) (type_arguments (type_identifier)))))
        (generic_type (type_identifier) (type_arguments (type_identifier)))))))

=======================================
Function definitions
=======================================

class A {
  def b(c: D, e: F) = 1
  def g[H](i) {
    j
  }
  def h(x: T)(implicit ev: Reads[T])
}

---

(compilation_unit
  (class_definition
    (identifier)
    (template_body
      (function_definition
        (identifier)
        (parameters
          (parameter (identifier) (type_identifier))
          (parameter (identifier) (type_identifier)))
        (integer_literal))
      (function_definition
        (identifier)
        (type_parameters (identifier))
        (parameters (parameter (identifier)))
        (block (identifier)))
      (function_declaration
        (identifier)
        (parameters (parameter (identifier) (type_identifier)))
        (parameters (parameter (identifier) (generic_type (type_identifier) (type_arguments (type_identifier)))))))))

=======================================
Initialization expressions
=======================================

class A(val x: Int, val y: Int) {
  assert(x != 0)
}

---

(compilation_unit
  (class_definition
    (identifier)
    (class_parameters
      (class_parameter (identifier) (type_identifier))
      (class_parameter (identifier) (type_identifier)))
    (template_body
      (call_expression (identifier)
        (arguments (infix_expression (identifier) (operator_identifier) (integer_literal)))))))

=======================================
Optional parameters
=======================================

def mkLines(header: String, indented: Boolean = false, repeated: Long = 0L): String = {}

---

(compilation_unit
  (function_definition
    (identifier)
    (parameters
      (parameter (identifier) (type_identifier))
      (parameter (identifier) (type_identifier) (boolean_literal))
      (parameter (identifier) (type_identifier) (integer_literal)))
    (type_identifier) (block)))
