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)"