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")
:
scala> import treehugger.forest._, definitions._, treehuggerDSL._
import treehugger.forest._
import definitions._
import treehuggerDSL._
scala> 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)
)
[1m[34mtree[0m: [1m[32mtreehugger.forest.ClassDef[0m = ClassDef(Modifiers(, , Map()),Modifiers(, , Map()),C,List(),List(),Template(List(),ValDef(Modifiers(private, , Map()),Ident(_),EmptyTree),List(DefDef(Modifiers(private, , Map()),x,List(),List(),TypeTree(),Literal(Constant(0))), DefDef(Modifiers(protected, , Map()),y,List(),List(),TypeTree(),Literal(Constant(0))), DefDef(Modifiers(private[this], , Map()),z,List(),List(),TypeTree(),Literal(Constant(0))))))
scala> treeToString(tree)
[1m[34mres0[0m: [1m[32mString[0m =
class C {
private def x = 0
protected def y = 0
private[this] def z = 0
}
To override class members use Flags.OVERRIDE
:
scala> val tree2 = CLASSDEF("C") withParents("B") := BLOCK(
DEF("x") withFlags(Flags.OVERRIDE) := LIT(0)
)
[1m[34mtree2[0m: [1m[32mtreehugger.forest.ClassDef[0m = ClassDef(Modifiers(, , Map()),Modifiers(, , Map()),C,List(),List(),Template(List(TypeTree()),ValDef(Modifiers(private, , Map()),Ident(_),EmptyTree),List(DefDef(Modifiers(override, , Map()),x,List(),List(),TypeTree(),Literal(Constant(0))))))
scala> treeToString(tree2)
[1m[34mres1[0m: [1m[32mString[0m =
class C extends B {
override def x = 0
}
To prohibit overriding by subclasses class members are marked final
using Flags.FINAL
:
scala> val tree3 = CLASSDEF("C") := BLOCK(
DEF("x") withFlags(Flags.FINAL) := LIT(0)
)
[1m[34mtree3[0m: [1m[32mtreehugger.forest.ClassDef[0m = ClassDef(Modifiers(, , Map()),Modifiers(, , Map()),C,List(),List(),Template(List(),ValDef(Modifiers(private, , Map()),Ident(_),EmptyTree),List(DefDef(Modifiers(final, , Map()),x,List(),List(),TypeTree(),Literal(Constant(0))))))
scala> treeToString(tree3)
[1m[34mres2[0m: [1m[32mString[0m =
class C {
final def x = 0
}
To define abstract classes use Flags.ABSTRACT
on CLASSDEF(...)
:
scala> object sym {
val IntQueue: ClassSymbol = RootClass.newClass("IntQueue")
}
defined object sym
scala> val tree4 = CLASSDEF(sym.IntQueue) withFlags(Flags.ABSTRACT) := BLOCK(
DEF("get", IntClass),
PROC("put") withParams(PARAM("x", IntClass))
)
[1m[34mtree4[0m: [1m[32mtreehugger.forest.ClassDef[0m = ClassDef(Modifiers(abstract, , Map()),Modifiers(, , Map()),IntQueue,List(),List(),Template(List(),ValDef(Modifiers(private, , Map()),Ident(_),EmptyTree),List(DefDef(Modifiers(, , Map()),get,List(),List(),TypeTree(),EmptyTree), ProcDef(Modifiers(, , Map()),put,List(),List(List(ValDef(Modifiers(<param>, , Map()),Typed(Ident(x),TypeTree()),EmptyTree))),EmptyTree))))
scala> treeToString(tree4)
[1m[34mres3[0m: [1m[32mString[0m =
abstract class IntQueue {
def get: Int
def put(x: Int)
}
To define final classes, which prohibits extension, use Flags.FINAL
on CLASSDEF(...)
:
scala> val tree5 = (CLASSDEF("C") withFlags(Flags.FINAL): Tree)
[1m[34mtree5[0m: [1m[32mtreehugger.forest.Tree[0m = ClassDef(Modifiers(final, , Map()),Modifiers(, , Map()),C,List(),List(),Template(List(),ValDef(Modifiers(private, , Map()),Ident(_),EmptyTree),List()))
scala> treeToString(tree5)
[1m[34mres4[0m: [1m[32mString[0m = final class C
To define sealed classes use Flags.SEALED
on CLASSDEF(...)
:
scala> val tree6 = CLASSDEF("Animal") withFlags(Flags.ABSTRACT, Flags.SEALED)
[1m[34mtree6[0m: [1m[32mtreehugger.forest.treehuggerDSL.ClassDefStart[0m = treehugger.TreehuggerDSLs$treehuggerDSL$ClassDefStart@428d18c6
scala> treeToString(tree6)
[1m[34mres5[0m: [1m[32mString[0m = treehugger.TreehuggerDSLs$treehuggerDSL$ClassDefStart@428d18c6
To define private constructors use Flags.PRIVATE
with withCtorFlags(...)
on CLASSDEF(...)
:
scala> val tree7 = (CLASSDEF("C") withCtorFlags(Flags.PRIVATE)
withParams(PARAM("x", IntClass)): Tree)
[1m[34mtree7[0m: [1m[32mtreehugger.forest.Tree[0m = ClassDef(Modifiers(, , Map()),Modifiers(private, , Map()),C,List(),List(ValDef(Modifiers(<param>, , Map()),Typed(Ident(x),TypeTree()),EmptyTree)),Template(List(),ValDef(Modifiers(private, , Map()),Ident(_),EmptyTree),List()))
scala> treeToString(tree7)
[1m[34mres6[0m: [1m[32mString[0m = class C private (x: Int)