Many of the Tree objects has Modifier field, which adds extra attribute about the tree such as access level and mutability. For both classes and their members modifier flags can be given using withFlags(...), which takes a PRIVATEWITHIN or vararg of Long.
To define class members with access modifiers use Flags.PRIVATE, Flags.PROTECTED, and PRIVATEWITHIN("scope"):
CLASSDEF("C") := BLOCK(
DEF("x") withFlags(Flags.PRIVATE) := LIT(0)
DEF("y") withFlags(Flags.PROTECTED) := LIT(0)
DEF("z") withFlags(PRIVATEWITHIN("this")) := LIT(0)
)
This prints as:
class C {
private def x = 0
protected def y = 0
private[this] def z = 0
}
To override class members use Flags.OVERRIDE:
CLASSDEF("C") withParents("B") := BLOCK(
DEF("x") withFlags(Flags.OVERRIDE) := LIT(0)
)
This prints as:
class C extends B {
override def x = 0
}
To prohibit overriding by subclasses class members are marked final using Flags.FINAL:
CLASSDEF("C") := BLOCK(
DEF("x") withFlags(Flags.FINAL) := LIT(0)
)
This prints as:
class C {
final def x = 0
}
To define abstract classes use Flags.ABSTRACT on CLASSDEF(...):
val IntQueue: ClassSymbol = RootClass.newClass("IntQueue")
CLASSDEF(IntQueue) withFlags(Flags.ABSTRACT) := BLOCK(
DEF("get", IntClass)
DEF("put") withParams(PARAM("x", IntClass))
)
This prints as:
abstract class IntQueue {
def get: Int
def put(x: Int)
}
To define final classes, which prohibits extension, use Flags.FINAL on CLASSDEF(...):
(CLASSDEF("C") withFlags(Flags.FINAL): Tree)
This prints as:
final class C
To define sealed classes use Flags.SEALED on CLASSDEF(...):
CLASSDEF("Animal") withFlags(Flags.ABSTRACT, Flags.SEALED)
This prints as:
sealed abstract class Animal
To define private constructors use Flags.PRIVATE with withCtorFlags(...) on CLASSDEF(...):
(CLASSDEF("C") withCtorFlags(Flags.PRIVATE)
withParams(PARAM("x", IntClass)): Tree)
This prints as:
class C private (x: Int)