Modifiers
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.
Access modifiers
To define class members with access modifiers use Flags.PRIVATE, Flags.PROTECTED, and PRIVATEWITHIN("scope"):
import treehugger.forest._, definitions._, treehuggerDSL._
val tree = CLASSDEF("C") := BLOCK(
DEF("x") withFlags(Flags.PRIVATE) := LIT(0),
DEF("y") withFlags(Flags.PROTECTED) := LIT(0),
DEF("z") withFlags(PRIVATEWITHIN("this")) := LIT(0)
)
treeToString(tree)
// res0: String = """class C {
// private def x = 0
// protected def y = 0
// private[this] def z = 0
// }"""
Overriding
To override class members use Flags.OVERRIDE:
val tree2 = CLASSDEF("C") withParents("B") := BLOCK(
DEF("x") withFlags(Flags.OVERRIDE) := LIT(0)
)
treeToString(tree2)
// res1: String = """class C extends B {
// override def x = 0
// }"""
Final members
To prohibit overriding by subclasses class members are marked final using Flags.FINAL:
val tree3 = CLASSDEF("C") := BLOCK(
DEF("x") withFlags(Flags.FINAL) := LIT(0)
)
treeToString(tree3)
// res2: String = """class C {
// final def x = 0
// }"""
Abstract classes
To define abstract classes use Flags.ABSTRACT on CLASSDEF(...):
object sym {
val IntQueue: ClassSymbol = RootClass.newClass("IntQueue")
}
val tree4 = CLASSDEF(sym.IntQueue) withFlags(Flags.ABSTRACT) := BLOCK(
DEF("get", IntClass),
PROC("put") withParams(PARAM("x", IntClass))
)
treeToString(tree4)
// res3: String = """abstract class IntQueue {
// def get: Int
// def put(x: Int)
// }"""
Final classes
To define final classes, which prohibits extension, use Flags.FINAL on CLASSDEF(...):
val tree5 = (CLASSDEF("C") withFlags(Flags.FINAL): Tree)
treeToString(tree5)
// res4: String = "final class C"
Sealed classes
To define sealed classes use Flags.SEALED on CLASSDEF(...):
val tree6 = CLASSDEF("Animal") withFlags(Flags.ABSTRACT, Flags.SEALED)
treeToString(tree6)
// res5: String = "treehugger.TreehuggerDSLs$treehuggerDSL$ClassDefStart@662458cb"
Private constructors
To define private constructors use Flags.PRIVATE with withCtorFlags(...) on CLASSDEF(...):
val tree7 = (CLASSDEF("C") withCtorFlags(Flags.PRIVATE)
withParams(PARAM("x", IntClass)): Tree)
treeToString(tree7)
// res6: String = "class C private (x: Int)"