Classes

Class definitions

Class definitions are written using CLASSDEF(...):

(CLASSDEF("C"): Tree)
CLASSDEF("C") := BLOCK(
  VAL("x") := LIT(0)
)

The above examples print as:

class C
class C {
  val x = 0
}

The general form of the first example is:

CLASSDEF(sym|"C").empty

As with value and function names, CLASSDEF can accept either a symbol or a String.

Constructor parameters

Primary constructor parameters are written using withParams(...) similar to function definitions. Except, it could use VAL(...) and VAR(...) in addition to PARAM(...):

CLASSDEF("C")
  withParams(PARAM("x", IntClass),
    VAL("y", StringClass),
    VAR("z", TYPE_LIST(StringClass))) := BLOCK(
  DEF("hi") := LIT("hi") 
)

This prints as:

class C(x: Int, val y: String, var z: List[String]) {
  def hi = "hi"
}

Extending classes

To define classes by extending super classes use withParents(tree|typ|"T"):

CLASSDEF("C") withParents("B") := BLOCK(
  DEF("x") := LIT(0)
)

This prints as:

class C extends B {
  def x = 0
}

Self type annotations

To define self type annotations use withSelf(sym|"self", [typ1, ...]):

CLASSDEF("C") withSelf("self", "T1", "T2") := BLOCK(
  VAL("x") := REF("self")
)

This prints as:

class C { self: T1 with T2 => 
  val x = self
}

Early denifitions

To define field values before supertype constructor is called add early definitions using withEarlyDefs(tree, ...):

CLASSDEF("C") withEarlyDefs(
  VAL("name") := LIT("Bob")
) withParents("B") := BLOCK(
  LIT(0)
)

This prints as:

class C extends {
  val name = "Bob"
} with B {
  0
}