aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2012-12-18 15:13:34 +0100
committerMartin Odersky <odersky@gmail.com>2012-12-18 15:13:34 +0100
commit0b0338721ba7c040204dcb44cfb4bc750acbcc5c (patch)
tree49216a813442309d116aef38974b664536bfc3c8 /src/dotty/tools/dotc
parent5991fd353278dd8b4e30d080fdfb846b060ea327 (diff)
downloaddotty-0b0338721ba7c040204dcb44cfb4bc750acbcc5c.tar.gz
dotty-0b0338721ba7c040204dcb44cfb4bc750acbcc5c.tar.bz2
dotty-0b0338721ba7c040204dcb44cfb4bc750acbcc5c.zip
First rough draft of trees. They use copy on write semantics for the tpe attribute, following Paul's suggestion.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/core/Trees.scala101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/core/Trees.scala b/src/dotty/tools/dotc/core/Trees.scala
new file mode 100644
index 000000000..a909e37bc
--- /dev/null
+++ b/src/dotty/tools/dotc/core/Trees.scala
@@ -0,0 +1,101 @@
+package dotty.tools.dotc.core
+
+import Types._, Names._, Flags._, Positions._
+
+object Trees {
+
+ abstract class Modifiers {
+ val flags: FlagSet
+ }
+
+ class MissingType {
+ type Type
+ }
+
+ val missing: MissingType =
+ new MissingType {
+ type Type = Types.Type
+ }
+
+ /** Trees take a parameter indicating what the type of their `tpe` field
+ * is. Two choices: `Types.Type` or `missing.Type`.
+ * Untyped trees have type `Tree[missing.Type]`. Because `missing.Type`
+ * is a completely abstract type, there's nothing one can do with it.
+ *
+ * Tree typing uses a copy-on-write implementation:
+ *
+ * - You can never observe a `tpe` which is `null` (throws an exception)
+ * - So when creating a typed tree with `withType` we can re-use
+ * the existing tree transparently, assigning its `tpe` field,
+ * provided it was `null` before.
+ * - It is impossible to embed untyped trees in typed ones.
+ * - It is possible to embed typed trees in untyped ones. In fact
+ * there is an implicit conversion from `Tree[Types.Type]` to
+ * `Tree[missing.Type]` which wraps the typed tree in a
+ * `TypedSplice` node.
+ * - Type checking an untyped tree will remove all embedded `TypedSplice`
+ * nodes.
+ */
+ abstract class Tree[T] {
+ def pos: Position
+
+ private var _tpe: T = _
+
+ def tpe: T = {
+ if (_tpe == null) throw new UnAssignedTypeException(this)
+ _tpe
+ }
+
+ def withType(tpe: Type): Tree[Type] = {
+ val tree =
+ (if (_tpe == null ||
+ (_tpe.asInstanceOf[AnyRef] eq tpe.asInstanceOf[AnyRef])) this
+ else shallowCopy).asInstanceOf[Tree[Type]]
+ tree._tpe = tpe
+ tree
+ }
+
+ def shallowCopy: Tree[T]
+
+ }
+
+ case class Ident[T](name: Name)(implicit val pos: Position) extends Tree[T] {
+ def shallowCopy = copy()
+ }
+
+ case class Select[T](qualifier: Tree[T], name: Name)(implicit val pos: Position) extends Tree[T] {
+ def shallowCopy = copy()
+ }
+
+ case class Apply[T](fun: Tree[T], arg: Tree[T])(implicit val pos: Position) extends Tree[T] {
+ def shallowCopy = copy()
+ }
+
+ case class Pair[T](left: Tree[T], right: Tree[T])(implicit val pos: Position) extends Tree[T] {
+ def shallowCopy = copy()
+ }
+
+ case class ValDef[T](mods: Modifiers, name: Name, rtpe: Tree[T], rhs: Tree[T])(implicit val pos: Position) extends Tree[T] {
+ def shallowCopy = copy()
+ }
+
+ case class TypeDef[T](mods: Modifiers, name: Name, rhs: Tree[T])(implicit val pos: Position) extends Tree[T] {
+ def shallowCopy = copy()
+ }
+
+ case class DefDef[T](mods: Modifiers, name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], rtpe: Tree[T], rhs: Tree[T])(implicit val pos: Position) extends Tree[T] {
+ def shallowCopy = copy()
+ }
+
+ case class TypedSplice(tree: Tree[Type]) extends Tree[missing.Type] {
+ def pos = tree.pos
+ def shallowCopy = copy()
+ }
+
+ implicit def embedTyped(tree: Tree[Type]): Tree[missing.Type] = TypedSplice(tree)
+
+ class UnAssignedTypeException[T](tree: Tree[T]) extends Exception {
+ override def getMessage: String = s"type of $tree is not assigned"
+ }
+
+} \ No newline at end of file