diff options
author | Martin Odersky <odersky@gmail.com> | 2013-04-30 18:02:10 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-04-30 18:02:10 +0200 |
commit | ad80e82469b6fe298a5cbdb0beac736fc01ec5fb (patch) | |
tree | 8a60eecfed1bb89708c8fda16e59c846b8f3f6a1 | |
parent | 273873d09c2e0e5080612a7f8a40cab138b41daa (diff) | |
download | dotty-ad80e82469b6fe298a5cbdb0beac736fc01ec5fb.tar.gz dotty-ad80e82469b6fe298a5cbdb0beac736fc01ec5fb.tar.bz2 dotty-ad80e82469b6fe298a5cbdb0beac736fc01ec5fb.zip |
New tree organization, with untyped trees that closely model source.
-rw-r--r-- | src/dotty/tools/dotc/core/Trees.scala | 292 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypedTrees.scala | 23 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/UntypedTrees.scala | 43 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/UnPickler.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/parsing/TreeBuilder.scala | 127 | ||||
-rw-r--r-- | src/dotty/tools/dotc/util/Positions.scala | 2 |
7 files changed, 229 insertions, 264 deletions
diff --git a/src/dotty/tools/dotc/core/Trees.scala b/src/dotty/tools/dotc/core/Trees.scala index 07a6ada69..0fd99b1ad 100644 --- a/src/dotty/tools/dotc/core/Trees.scala +++ b/src/dotty/tools/dotc/core/Trees.scala @@ -20,6 +20,32 @@ object Trees { type TypedTree = Tree[Type] type UntypedTree = Tree[Untyped] + abstract class Positioned extends DotClass { + + protected var curPos: Position = initialPos + + protected def initialPos: Position + + /** The tree's position. Except + * for SharedTree nodes, it is always ensured that a tree's position + * contains the envelopes of all its immediate subtrees. However, it need not + * contain positions of other tree elements such as Modifiers. + */ + def pos: Position = curPos + + def withPos(pos: Position): this.type = { + val newpd = (if (curPos.isSynthetic) this else clone).asInstanceOf[Positioned] + val newpos = pos union this.pos + newpd.curPos = if (pos.isSynthetic) newpos else newpos withPoint pos.point + newpd.asInstanceOf[this.type] + } + + protected def unionPos(pos: Position, xs: List[_]): Position = xs match { + case (t: Tree[_]) :: xs1 => unionPos(pos union t.envelope, xs1) + case _ => pos + } + } + /** Modifiers and annotations for definitions * @param flags The set flags * @param privateWithin If a private or protected has is followed by a @@ -36,11 +62,11 @@ object Trees { flags: FlagSet = EmptyFlags, privateWithin: TypeName = tpnme.EMPTY, annotations: List[Tree[T]] = Nil, - positions: FlagPositions = NoFlagPositions)(implicit val cpos: Position = NoPosition) { + positions: FlagPositions = NoFlagPositions) extends Positioned { - def | (fs: FlagSet): Modifiers[T] = copy(flags = flags | fs)(cpos) - def & (fs: FlagSet): Modifiers[T] = copy(flags = flags & fs)(cpos) - def &~(fs: FlagSet): Modifiers[T] = copy(flags = flags &~ fs)(cpos) + def | (fs: FlagSet): Modifiers[T] = copy(flags = flags | fs) + def & (fs: FlagSet): Modifiers[T] = copy(flags = flags & fs) + def &~(fs: FlagSet): Modifiers[T] = copy(flags = flags &~ fs) def is(fs: FlagSet): Boolean = flags is fs def is(fc: FlagConjunction): Boolean = flags is fc @@ -50,15 +76,13 @@ object Trees { def withAnnotations(annots: List[Tree[T]]) = if (annots.isEmpty) this - else copy(annotations = annotations ++ annots)(cpos) + else copy(annotations = annotations ++ annots) def withPrivateWithin(pw: TypeName) = if (pw.isEmpty) this - else copy(privateWithin = pw)(cpos) - - def withPos(pos: Position) = copy()(pos) + else copy(privateWithin = pw) - val pos: Position = unionPos(cpos, annotations) + protected def initialPos: Position = unionPos(NoPosition, annotations) } private final val OffsetShift = 6 @@ -118,17 +142,7 @@ object Trees { * - Type checking an untyped tree should remove all embedded `TypedSplice` * nodes. */ - abstract class Tree[T >: Untyped] extends DotClass with Showable with Cloneable { - - /** The tree's position. Except - * for SharedTree nodes, it is always ensured that a tree's position - * contains the positions of all its immediate subtrees. However, it need not - * contain positions of other tree elements such as Modifiers. - */ - def pos: Position - - /** The extended position. Unlike `pos`, this one contains positions of modifiers */ - def xpos: Position = pos + abstract class Tree[T >: Untyped] extends Positioned with Product with Showable with Cloneable { /** The type constructor at the root of the tree */ type ThisTree[T >: Untyped] <: Tree[T] @@ -158,7 +172,7 @@ object Trees { val tree = (if (_tpe == null || (_tpe.asInstanceOf[AnyRef] eq tpe.asInstanceOf[AnyRef])) this - else clone).asInstanceOf[Tree[Type]] + else clone).asInstanceOf[Tree[Type]] tree._tpe = tpe tree.asInstanceOf[ThisTree[Type]] } @@ -175,7 +189,14 @@ object Trees { case _ => NoType } - /** The denotation referred to by this tree. + /** The envelope containing the tree in its entirety. + * Unlile `pos`, `envelope` is always a synthetic position which does not contain + * a point. Also unlike `pos`, this contains the modifiers and annotations of + * a definition of type ModDefTree. + */ + def envelope: Position = curPos.toSynthetic + + /** The denotation referred tno by this tree. * Defined for `DenotingTree`s and `ProxyTree`s, NoDenotation for other * kinds of trees */ @@ -203,6 +224,20 @@ object Trees { def orElse(that: => Tree[T]): Tree[T] = if (this eq theEmptyTree) that else this + protected def initialPos = { + var n = productArity + var pos = NoPosition + while (n > 0) { + n -= 1 + productElement(n) match { + case t: Tree[_] => pos = pos union t.pos + case xs: List[_] => pos = unionPos(pos, xs) + case _ => + } + } + pos + } + override def toText(implicit ctx: Context) = ctx.toText(this) override def hashCode(): Int = System.identityHashCode(this) @@ -289,41 +324,37 @@ object Trees { trait ModDefTree[T >: Untyped] extends DefTree[T] { type ThisTree[T >: Untyped] <: ModDefTree[T] def mods: Modifiers[T] - override def xpos = mods.pos union pos + override def envelope: Position = mods.pos union pos } // ----------- Tree case classes ------------------------------------ /** name */ - case class Ident[T >: Untyped](name: Name)(implicit cpos: Position) + case class Ident[T >: Untyped](name: Name) extends RefTree[T] { type ThisTree[T >: Untyped] = Ident[T] - val pos = cpos def qualifier: Tree[T] = EmptyTree[T] } - class BackquotedIdent[T >: Untyped](name: Name)(implicit cpos: Position) + class BackquotedIdent[T >: Untyped](name: Name) extends Ident[T](name) /** qualifier.name */ - case class Select[T >: Untyped](qualifier: Tree[T], name: Name)(implicit cpos: Position) + case class Select[T >: Untyped](qualifier: Tree[T], name: Name) extends RefTree[T] { type ThisTree[T >: Untyped] = Select[T] - val pos = cpos union qualifier.pos } /** qual.this */ - case class This[T >: Untyped](qual: TypeName)(implicit cpos: Position) + case class This[T >: Untyped](qual: TypeName) extends DenotingTree[T] with TermTree[T] { type ThisTree[T >: Untyped] = This[T] - val pos = cpos } /** C.super[mix], where qual = C.this */ - case class Super[T >: Untyped](qual: Tree[T], mix: TypeName)(implicit cpos: Position) + case class Super[T >: Untyped](qual: Tree[T], mix: TypeName) extends ProxyTree[T] with TermTree[T] { type ThisTree[T >: Untyped] = Super[T] - val pos = cpos union qual.pos def forwardTo = qual } @@ -335,102 +366,84 @@ object Trees { } /** fun(args) */ - case class Apply[T >: Untyped](fun: Tree[T], args: List[Tree[T]])(implicit cpos: Position) + case class Apply[T >: Untyped](fun: Tree[T], args: List[Tree[T]]) extends GenericApply[T] { type ThisTree[T >: Untyped] = Apply[T] - val pos = unionPos(cpos union fun.pos, args) } /** fun[args] */ - case class TypeApply[T >: Untyped](fun: Tree[T], args: List[Tree[T]])(implicit cpos: Position) + case class TypeApply[T >: Untyped](fun: Tree[T], args: List[Tree[T]]) extends GenericApply[T] { type ThisTree[T >: Untyped] = TypeApply[T] - val pos = unionPos(cpos union fun.pos, args) } /** const */ - case class Literal[T >: Untyped](const: Constant)(implicit cpos: Position) + case class Literal[T >: Untyped](const: Constant) extends TermTree[T] { type ThisTree[T >: Untyped] = Literal[T] - val pos = cpos } /** new tpt, but no constructor call */ - case class New[T >: Untyped](tpt: Tree[T])(implicit cpos: Position) + case class New[T >: Untyped](tpt: Tree[T]) extends TermTree[T] { type ThisTree[T >: Untyped] = New[T] - val pos = cpos union tpt.pos } /** new tpt(args1)...(args_n) - * @param cpos A position spanning the new. */ - def New[T >: Untyped](tpt: Tree[T], argss: List[List[Tree[T]]])(implicit cpos: Position): Tree[T] = { - val newPos = cpos.withEnd(tpt.pos.end min cpos.end) - locally { - implicit val cpos: Position = newPos - ((Select(New(tpt), nme.CONSTRUCTOR): Tree[T]) /: argss)(Apply(_, _)) - } - } + def New[T >: Untyped](tpt: Tree[T], argss: List[List[Tree[T]]]): Tree[T] = + ((Select(New(tpt), nme.CONSTRUCTOR): Tree[T]) /: argss)(Apply(_, _)) /** (left, right) */ - case class Pair[T >: Untyped](left: Tree[T], right: Tree[T])(implicit cpos: Position) + case class Pair[T >: Untyped](left: Tree[T], right: Tree[T]) extends TermTree[T] { type ThisTree[T >: Untyped] = Pair[T] - val pos = cpos union left.pos union right.pos override def isTerm = left.isTerm && right.isTerm override def isType = left.isType && right.isType override def isPattern = !isTerm && (left.isPattern || left.isTerm) && (right.isPattern || right.isTerm) } /** expr : tpt */ - case class Typed[T >: Untyped](expr: Tree[T], tpt: Tree[T])(implicit cpos: Position) + case class Typed[T >: Untyped](expr: Tree[T], tpt: Tree[T]) extends ProxyTree[T] with TermTree[T] { type ThisTree[T >: Untyped] = Typed[T] - val pos = cpos union expr.pos union tpt.pos def forwardTo = expr } /** name = arg, in a parameter list */ - case class NamedArg[T >: Untyped](name: Name, arg: Tree[T])(implicit cpos: Position) + case class NamedArg[T >: Untyped](name: Name, arg: Tree[T]) extends Tree[T] { type ThisTree[T >: Untyped] = NamedArg[T] - val pos = cpos union arg.pos } /** name = arg, outside a parameter list */ - case class Assign[T >: Untyped](lhs: Tree[T], rhs: Tree[T])(implicit cpos: Position) + case class Assign[T >: Untyped](lhs: Tree[T], rhs: Tree[T]) extends TermTree[T] { type ThisTree[T >: Untyped] = Assign[T] - val pos = cpos union lhs.pos union rhs.pos } /** { stats; expr } */ - case class Block[T >: Untyped](stats: List[Tree[T]], expr: Tree[T])(implicit cpos: Position) + case class Block[T >: Untyped](stats: List[Tree[T]], expr: Tree[T]) extends TermTree[T] { type ThisTree[T >: Untyped] = Block[T] - val pos = unionPos(cpos union expr.pos, stats) } /** if cond then thenp else elsep */ - case class If[T >: Untyped](cond: Tree[T], thenp: Tree[T], elsep: Tree[T])(implicit cpos: Position) + case class If[T >: Untyped](cond: Tree[T], thenp: Tree[T], elsep: Tree[T]) extends TermTree[T] { type ThisTree[T >: Untyped] = If[T] - val pos = cpos union cond.pos union thenp.pos union elsep.pos } /** selector match { cases } */ - case class Match[T >: Untyped](selector: Tree[T], cases: List[CaseDef[T]])(implicit cpos: Position) + case class Match[T >: Untyped](selector: Tree[T], cases: List[CaseDef[T]]) extends TermTree[T] { type ThisTree[T >: Untyped] = Match[T] - val pos = unionPos(cpos union selector.pos, cases) } /** case pat if guard => body */ - case class CaseDef[T >: Untyped](pat: Tree[T], guard: Tree[T], body: Tree[T])(implicit cpos: Position) + case class CaseDef[T >: Untyped](pat: Tree[T], guard: Tree[T], body: Tree[T]) extends Tree[T] { type ThisTree[T >: Untyped] = CaseDef[T] - val pos = cpos union pat.pos union guard.pos union body.pos } /** return expr @@ -438,180 +451,158 @@ object Trees { * After program transformations this is not necessarily the enclosing method, because * closures can intervene. */ - case class Return[T >: Untyped](expr: Tree[T], from: Tree[T] = EmptyTree[T]())(implicit cpos: Position) + case class Return[T >: Untyped](expr: Tree[T], from: Tree[T] = EmptyTree[T]()) extends TermTree[T] { type ThisTree[T >: Untyped] = Return[T] - val pos = cpos union expr.pos // from is synthetic, does not influence pos } /** try block catch { catches } */ - case class Try[T >: Untyped](block: Tree[T], catches: List[CaseDef[T]], finalizer: Tree[T])(implicit cpos: Position) + case class Try[T >: Untyped](block: Tree[T], catches: List[CaseDef[T]], finalizer: Tree[T]) extends TermTree[T] { type ThisTree[T >: Untyped] = Try[T] - val pos = unionPos(cpos union block.pos union finalizer.pos, catches) } /** throw expr */ - case class Throw[T >: Untyped](expr: Tree[T])(implicit cpos: Position) + case class Throw[T >: Untyped](expr: Tree[T]) extends TermTree[T] { type ThisTree[T >: Untyped] = Throw[T] - val pos = cpos union expr.pos } /** Array[elemtpt](elems) */ - case class SeqLiteral[T >: Untyped](elemtpt: Tree[T], elems: List[Tree[T]])(implicit cpos: Position) + case class SeqLiteral[T >: Untyped](elemtpt: Tree[T], elems: List[Tree[T]]) extends Tree[T] { type ThisTree[T >: Untyped] = SeqLiteral[T] - val pos = unionPos(cpos union elemtpt.pos, elems) } /** A type tree that represents an existing or inferred type */ - case class TypeTree[T >: Untyped](original: Tree[T] = EmptyTree[T])(implicit cpos: Position) + case class TypeTree[T >: Untyped](original: Tree[T] = EmptyTree[T]) extends DenotingTree[T] with TypTree[T] { type ThisTree[T >: Untyped] = TypeTree[T] - val pos = if (original.pos.exists) original.pos else cpos.focus + override def initialPos = NoPosition } /** ref.type */ - case class SingletonTypeTree[T >: Untyped](ref: Tree[T])(implicit cpos: Position) + case class SingletonTypeTree[T >: Untyped](ref: Tree[T]) extends DenotingTree[T] with TypTree[T] { type ThisTree[T >: Untyped] = SingletonTypeTree[T] - val pos = cpos union ref.pos } /** qualifier # name */ - case class SelectFromTypeTree[T >: Untyped](qualifier: Tree[T], name: Name)(implicit cpos: Position) + case class SelectFromTypeTree[T >: Untyped](qualifier: Tree[T], name: Name) extends RefTree[T] { type ThisTree[T >: Untyped] = SelectFromTypeTree[T] - val pos = cpos union qualifier.pos } /** left & right */ - case class AndTypeTree[T >: Untyped](left: Tree[T], right: Tree[T])(implicit cpos: Position) + case class AndTypeTree[T >: Untyped](left: Tree[T], right: Tree[T]) extends TypTree[T] { type ThisTree[T >: Untyped] = AndTypeTree[T] - val pos = cpos union left.pos union right.pos } /** left | right */ - case class OrTypeTree[T >: Untyped](left: Tree[T], right: Tree[T])(implicit cpos: Position) + case class OrTypeTree[T >: Untyped](left: Tree[T], right: Tree[T]) extends TypTree[T] { type ThisTree[T >: Untyped] = OrTypeTree[T] - val pos = cpos union left.pos union right.pos } /** tpt { refinements } */ - case class RefineTypeTree[T >: Untyped](tpt: Tree[T], refinements: List[Tree[T]])(implicit cpos: Position) + case class RefineTypeTree[T >: Untyped](tpt: Tree[T], refinements: List[Tree[T]]) extends ProxyTree[T] with TypTree[T] { type ThisTree[T >: Untyped] = RefineTypeTree[T] - val pos = unionPos(cpos union tpt.pos, refinements) def forwardTo = tpt } /** tpt[args] */ - case class AppliedTypeTree[T >: Untyped](tpt: Tree[T], args: List[Tree[T]])(implicit cpos: Position) + case class AppliedTypeTree[T >: Untyped](tpt: Tree[T], args: List[Tree[T]]) extends ProxyTree[T] with TypTree[T] { type ThisTree[T >: Untyped] = AppliedTypeTree[T] - val pos = unionPos(cpos union tpt.pos, args) def forwardTo = tpt } - def AppliedTypeTree[T >: Untyped](tpt: Tree[T], arg: Tree[T])(implicit cpos: Position): AppliedTypeTree[T] = + def AppliedTypeTree[T >: Untyped](tpt: Tree[T], arg: Tree[T]): AppliedTypeTree[T] = AppliedTypeTree(tpt, arg :: Nil) /** >: lo <: hi */ - case class TypeBoundsTree[T >: Untyped](lo: Tree[T], hi: Tree[T])(implicit cpos: Position) + case class TypeBoundsTree[T >: Untyped](lo: Tree[T], hi: Tree[T]) extends Tree[T] { type ThisTree[T >: Untyped] = TypeBoundsTree[T] - val pos = cpos union lo.pos union hi.pos } /** name @ body */ - case class Bind[T >: Untyped](name: Name, body: Tree[T])(implicit cpos: Position) + case class Bind[T >: Untyped](name: Name, body: Tree[T]) extends NameTree[T] with DefTree[T] with PatternTree[T] { type ThisTree[T >: Untyped] = Bind[T] - val pos = cpos union body.pos } /** tree_1 | ... | tree_n */ - case class Alternative[T >: Untyped](trees: List[Tree[T]])(implicit cpos: Position) + case class Alternative[T >: Untyped](trees: List[Tree[T]]) extends PatternTree[T] { type ThisTree[T >: Untyped] = Alternative[T] - val pos = unionPos(cpos, trees) } /** fun(args) in a pattern, if fun is an extractor */ - case class UnApply[T >: Untyped](fun: Tree[T], args: List[Tree[T]])(implicit cpos: Position) + case class UnApply[T >: Untyped](fun: Tree[T], args: List[Tree[T]]) extends PatternTree[T] { type ThisTree[T >: Untyped] = UnApply[T] - val pos = unionPos(cpos union fun.pos, args) } /** mods val name: tpt = rhs */ - case class ValDef[T >: Untyped](mods: Modifiers[T], name: TermName, tpt: Tree[T], rhs: Tree[T])(implicit cpos: Position) + case class ValDef[T >: Untyped](mods: Modifiers[T], name: TermName, tpt: Tree[T], rhs: Tree[T]) extends NameTree[T] with ModDefTree[T] { type ThisTree[T >: Untyped] = ValDef[T] - val pos = cpos union tpt.pos union rhs.pos } /** mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs */ - case class DefDef[T >: Untyped](mods: Modifiers[T], name: TermName, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])(implicit cpos: Position) + case class DefDef[T >: Untyped](mods: Modifiers[T], name: TermName, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T]) extends NameTree[T] with ModDefTree[T] { type ThisTree[T >: Untyped] = DefDef[T] - val pos = (unionPos(cpos union tpt.pos union rhs.pos, tparams) /: vparamss)(unionPos) } - class ImplicitDefDef[T >: Untyped](mods: Modifiers[T], name: TermName, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])(implicit pos: Position) extends DefDef[T](mods, name, tparams, vparamss, tpt, rhs) { - override def copy[T >: Untyped](mods: Modifiers[T], name: TermName, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])(implicit pos: Position) = + class ImplicitDefDef[T >: Untyped](mods: Modifiers[T], name: TermName, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T]) extends DefDef[T](mods, name, tparams, vparamss, tpt, rhs) { + override def copy[T >: Untyped](mods: Modifiers[T], name: TermName, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T]) = new ImplicitDefDef[T](mods, name, tparams, vparamss, tpt, rhs) } /** mods type name = rhs or * mods type name >: lo <: hi, if rhs = TypeBoundsTree(lo, hi) */ - case class TypeDef[T >: Untyped](mods: Modifiers[T], name: TypeName, tparams: List[TypeDef[T]], rhs: Tree[T])(implicit cpos: Position) + case class TypeDef[T >: Untyped](mods: Modifiers[T], name: TypeName, tparams: List[TypeDef[T]], rhs: Tree[T]) extends NameTree[T] with ModDefTree[T] { type ThisTree[T >: Untyped] = TypeDef[T] - val pos = unionPos(cpos union rhs.pos, tparams) } /** extends parents { self => body } */ - case class Template[T >: Untyped](parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]])(implicit cpos: Position) + case class Template[T >: Untyped](constr: Tree[T], parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]]) extends DefTree[T] { type ThisTree[T >: Untyped] = Template[T] - val pos = unionPos(unionPos(cpos union self.xpos, parents), body) } /** mods class name[tparams] impl */ - case class ClassDef[T >: Untyped](mods: Modifiers[T], name: TypeName, tparams: List[TypeDef[T]], impl: Template[T])(implicit cpos: Position) + case class ClassDef[T >: Untyped](mods: Modifiers[T], name: TypeName, tparams: List[TypeDef[T]], impl: Template[T]) extends NameTree[T] with ModDefTree[T] { type ThisTree[T >: Untyped] = ClassDef[T] - val pos = unionPos(cpos union impl.pos, tparams) } /** import expr.selectors * where a selector is either an untyped `Ident`, `name` or * an untyped `Pair` `name => rename` */ - case class Import[T >: Untyped](expr: Tree[T], selectors: List[UntypedTree])(implicit cpos: Position) + case class Import[T >: Untyped](expr: Tree[T], selectors: List[UntypedTree]) extends DenotingTree[T] { type ThisTree[T >: Untyped] = Import[T] - val pos = unionPos(cpos union expr.pos, selectors) } /** package pid { stats } */ - case class PackageDef[T >: Untyped](pid: RefTree[T], stats: List[Tree[T]])(implicit cpos: Position) + case class PackageDef[T >: Untyped](pid: RefTree[T], stats: List[Tree[T]]) extends ProxyTree[T] { type ThisTree[T >: Untyped] = PackageDef[T] - val pos = unionPos(cpos union pid.pos, stats) def forwardTo = pid } /** arg @annot */ - case class Annotated[T >: Untyped](annot: Tree[T], arg: Tree[T])(implicit cpos: Position) + case class Annotated[T >: Untyped](annot: Tree[T], arg: Tree[T]) extends ProxyTree[T] { type ThisTree[T >: Untyped] = Annotated[T] - val pos = cpos union annot.pos union arg.pos def forwardTo = arg } @@ -635,7 +626,7 @@ object Trees { } class EmptyValDef[T >: Untyped] extends ValDef[T]( - Modifiers[T](Private)(NoPosition), nme.WILDCARD, EmptyTree[T], EmptyTree[T])(NoPosition) with AlwaysEmpty[T] + Modifiers[T](Private), nme.WILDCARD, EmptyTree[T], EmptyTree[T]) with AlwaysEmpty[T] private object theEmptyValDef extends EmptyValDef[Untyped] @@ -650,50 +641,17 @@ object Trees { case class SharedTree[T >: Untyped](shared: Tree[T]) extends ProxyTree[T] { type ThisTree[T >: Untyped] = SharedTree[T] def forwardTo: Tree[T] = shared - val pos = NoPosition - } - - // ----- Tree cases that exist in untyped form only ------------------ - - /** A typed subtree of an untyped tree needs to be wrapped in a TypedSlice */ - case class TypedSplice(tree: TypedTree) extends UntypedTree { - val pos = tree.pos - } - - /** mods object name impl */ - case class ModuleDef(mods: Modifiers[Untyped], name: TermName, impl: Template[Untyped])(implicit cpos: Position) - extends NameTree[Untyped] with ModDefTree[Untyped] { - type ThisTree[T >: Untyped] <: NameTree[T] with ModDefTree[T] with ModuleDef - val pos = cpos union impl.pos - def derivedModuleDef(mods: Modifiers[Untyped], name: TermName, impl: Template[Untyped]) = - if (mods == this.mods && name == this.name && (impl eq this.impl)) this - else ModuleDef(mods, name, impl) } - /** (vparams) => body */ - case class Function(vparams: List[ValDef[Untyped]], body: Tree[Untyped])(implicit cpos: Position) - extends TermTree[Untyped] { - type ThisTree[T >: Untyped] <: TermTree[T] with Function - val pos = unionPos(cpos union body.pos, vparams) - } - - /** Something in parentheses */ - case class Parens(trees: List[Tree[Untyped]])(implicit cpos: Position) extends Tree[Untyped] { - type ThisTree[T >: Untyped] <: Tree[T] with Parens - val pos = unionPos(cpos, trees) - } // ----- Auxiliary creation methods ------------------ - def Block[T >: Untyped](stat: Tree[T], expr: Tree[T])(implicit cpos: Position): Block[T] = + def Block[T >: Untyped](stat: Tree[T], expr: Tree[T]): Block[T] = Block(stat :: Nil, expr) - def Apply[T >: Untyped](fn: Tree[T], arg: Tree[T])(implicit cpos: Position): Apply[T] = + def Apply[T >: Untyped](fn: Tree[T], arg: Tree[T]): Apply[T] = Apply(fn, arg :: Nil) - def Function(vparam: ValDef[Untyped], body: Tree[Untyped])(implicit cpos: Position): Function = - Function(vparam :: Nil, body) - // ----- Generic Tree Instances, inherited from `tpt` and `untpd`. abstract class Instance[T >: Untyped] { @@ -708,6 +666,7 @@ object Trees { type NameTree = Trees.NameTree[T] type RefTree = Trees.RefTree[T] type DefTree = Trees.DefTree[T] + type ModDefTree = Trees.ModDefTree[T] type TreeCopier = Trees.TreeCopier[T] type TreeAccumulator[U] = Trees.TreeAccumulator[U, T] @@ -758,17 +717,14 @@ object Trees { protected implicit def pos(implicit ctx: Context): Position = ctx.position def defPos(sym: Symbol)(implicit ctx: Context) = ctx.position union sym.coord.toPosition + + def Parameter(pname: TermName, tpe: Tree, mods: Modifiers = Modifiers()): ValDef = + ValDef(mods | Param, pname, tpe, EmptyTree()) } // ----- Helper functions and classes --------------------------------------- - @tailrec final def unionPos(base: Position, trees: List[Tree[_]]): Position = trees match { - case t :: ts => unionPos(base union t.xpos, ts) - case nil => base - } - implicit class TreeCopier[T >: Untyped](val tree: Tree[T]) extends AnyVal { - implicit def cpos = tree.pos def derivedIdent(name: Name): Ident[T] = tree match { case tree: BackquotedIdent[_] => if (name == tree.name) tree @@ -852,10 +808,6 @@ object Trees { case tree: SeqLiteral[_] if (elemtpt eq tree.elemtpt) && (elems eq tree.elems) => tree case _ => SeqLiteral(elemtpt, elems).copyAttr(tree) } - def derivedTypeTree(original: Tree[T] = EmptyTree[T]): TypeTree[T] = tree match { - case tree: TypeTree[_] if (original eq tree.original) => tree - case _ => TypeTree(original).copyAttr(tree) - } def derivedSingletonTypeTree(ref: Tree[T]): SingletonTypeTree[T] = tree match { case tree: SingletonTypeTree[_] if (ref eq tree.ref) => tree case _ => SingletonTypeTree(ref).copyAttr(tree) @@ -908,9 +860,9 @@ object Trees { case tree: TypeDef[_] if (mods == tree.mods) && (name == tree.name) && (tparams eq tree.tparams) && (rhs eq tree.rhs) => tree case _ => TypeDef(mods, name, tparams, rhs).copyAttr(tree) } - def derivedTemplate(parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]]): Template[T] = tree match { - case tree: Template[_] if (parents eq tree.parents) && (self eq tree.self) && (body eq tree.body) => tree - case _ => Template(parents, self, body).copyAttr(tree) + def derivedTemplate(constr: Tree[T], parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]]): Template[T] = tree match { + case tree: Template[_] if (constr eq tree.constr) && (parents eq tree.parents) && (self eq tree.self) && (body eq tree.body) => tree + case _ => Template(constr, parents, self, body).copyAttr(tree) } def derivedClassDef(mods: Modifiers[T], name: TypeName, tparams: List[TypeDef[T]], impl: Template[T]): ClassDef[T] = tree match { case tree: ClassDef[_] if (mods == tree.mods) && (name == tree.name) && (tparams eq tree.tparams) && (impl eq tree.impl) => tree @@ -979,7 +931,7 @@ object Trees { case SeqLiteral(elemtpt, elems) => finishSeqLiteral(tree.derivedSeqLiteral(transform(elemtpt, c), transform(elems, c)), tree, c, plugins) case TypeTree(original) => - finishTypeTree(tree.derivedTypeTree(transform(original, c)), tree, c, plugins) + finishTypeTree(tree, tree, c, plugins) case SingletonTypeTree(ref) => finishSingletonTypeTree(tree.derivedSingletonTypeTree(transform(ref, c)), tree, c, plugins) case SelectFromTypeTree(qualifier, name) => @@ -1006,8 +958,8 @@ object Trees { finishDefDef(tree.derivedDefDef(mods, name, transformSub(tparams, c), vparamss mapConserve (transformSub(_, c)), transform(tpt, c), transform(rhs, c)), tree, c, plugins) case TypeDef(mods, name, tparams, rhs) => finishTypeDef(tree.derivedTypeDef(mods, name, transformSub(tparams, c), transform(rhs, c)), tree, c, plugins) - case Template(parents, self, body) => - finishTemplate(tree.derivedTemplate(transform(parents, c), transformSub(self, c), transform(body, c)), tree, c, plugins) + case Template(constr, parents, self, body) => + finishTemplate(tree.derivedTemplate(transform(constr, c), transform(parents, c), transformSub(self, c), transform(body, c)), tree, c, plugins) case ClassDef(mods, name, tparams, impl) => finishClassDef(tree.derivedClassDef(mods, name, transformSub(tparams, c), transformSub(impl, c)), tree, c, plugins) case Import(expr, selectors) => @@ -1128,7 +1080,7 @@ object Trees { case SeqLiteral(elemtpt, elems) => tree.derivedSeqLiteral(transform(elemtpt), transform(elems)) case TypeTree(original) => - tree.derivedTypeTree(transform(original)) + tree case SingletonTypeTree(ref) => tree.derivedSingletonTypeTree(transform(ref)) case SelectFromTypeTree(qualifier, name) => @@ -1155,8 +1107,8 @@ object Trees { tree.derivedDefDef(mods, name, transformSub(tparams), vparamss mapConserve (transformSub(_)), transform(tpt), transform(rhs)) case TypeDef(mods, name, tparams, rhs) => tree.derivedTypeDef(mods, name, transformSub(tparams), transform(rhs)) - case Template(parents, self, body) => - tree.derivedTemplate(transform(parents), transformSub(self), transform(body)) + case Template(constr, parents, self, body) => + tree.derivedTemplate(transform(constr), transform(parents), transformSub(self), transform(body)) case ClassDef(mods, name, tparams, impl) => tree.derivedClassDef(mods, name, transformSub(tparams), transformSub(impl)) case Import(expr, selectors) => @@ -1257,8 +1209,8 @@ object Trees { this(this((this(x, tparams) /: vparamss)(apply), tpt), rhs) case TypeDef(mods, name, tparams, rhs) => this(this(x, tparams), rhs) - case Template(parents, self, body) => - this(this(this(x, parents), self), body) + case Template(constr, parents, self, body) => + this(this(this(this(x, constr), parents), self), body) case ClassDef(mods, name, tparams, impl) => this(this(x, tparams), impl) case Import(expr, selectors) => diff --git a/src/dotty/tools/dotc/core/TypedTrees.scala b/src/dotty/tools/dotc/core/TypedTrees.scala index 348b2c37b..99be9bf50 100644 --- a/src/dotty/tools/dotc/core/TypedTrees.scala +++ b/src/dotty/tools/dotc/core/TypedTrees.scala @@ -142,7 +142,7 @@ object TypedTrees { Trees.TypeBoundsTree(lo, hi).withType(TypeBounds(lo.tpe, hi.tpe)).checked def Bind(sym: TermSymbol, body: Tree)(implicit ctx: Context): Bind = - Trees.Bind(sym.name, body)(defPos(sym)).withType(refType(sym)).checked + Trees.Bind(sym.name, body).withType(refType(sym)).checked def Alternative(trees: List[Tree])(implicit ctx: Context): Alternative = Trees.Alternative(trees).withType(ctx.lub(trees map (_.tpe))).checked @@ -156,8 +156,7 @@ object TypedTrees { } def ValDef(sym: TermSymbol, rhs: Tree = EmptyTree)(implicit ctx: Context): ValDef = - Trees.ValDef(Modifiers(sym), sym.name, TypeTree(sym.info), rhs)(defPos(sym)) - .withType(refType(sym)).checked + Trees.ValDef(Modifiers(sym), sym.name, TypeTree(sym.info), rhs).withType(refType(sym)).checked def DefDef(sym: TermSymbol, rhs: Tree = EmptyTree)(implicit ctx: Context): DefDef = { @@ -181,15 +180,15 @@ object TypedTrees { Trees.DefDef( Modifiers(sym), sym.name, tparams map TypeDef, - vparamss map (_ map (ValDef(_))), TypeTree(rtp), rhs)(defPos(sym)) - .withType(refType(sym)).checked + vparamss map (_ map (ValDef(_))), TypeTree(rtp), rhs) + .withType(refType(sym)).checked } def TypeDef(sym: TypeSymbol)(implicit ctx: Context): TypeDef = - Trees.TypeDef(Modifiers(sym), sym.name, Nil, TypeTree(sym.info))(defPos(sym)) // !!! fill in typeParams + Trees.TypeDef(Modifiers(sym), sym.name, Nil, TypeTree(sym.info)) // !!! fill in typeParams .withType(refType(sym)).checked - def ClassDef(cls: ClassSymbol, typeParams: List[TypeSymbol], body: List[Tree])(implicit ctx: Context): ClassDef = { + def ClassDef(cls: ClassSymbol, typeParams: List[TypeSymbol], constr: Tree, body: List[Tree])(implicit ctx: Context): ClassDef = { val parents = cls.info.parents map (TypeTree(_)) val selfType = if (cls.classInfo.optSelfType.exists) ValDef(ctx.newSelfSym(cls)) @@ -205,9 +204,9 @@ object TypedTrees { val findLocalDummy = new FindLocalDummyAccumulator(cls) val localDummy = ((NoSymbol: Symbol) /: body)(findLocalDummy) .orElse(ctx.newLocalDummy(cls)) - val impl = Trees.Template(parents, selfType, rest) + val impl = Trees.Template(constr, parents, selfType, rest) .withType(refType(localDummy)).checked - Trees.ClassDef(Modifiers(cls), cls.name, tparams, impl)(defPos(cls)) + Trees.ClassDef(Modifiers(cls), cls.name, tparams, impl) .withType(refType(cls)).checked } @@ -279,7 +278,8 @@ object TypedTrees { */ def ModuleDef(sym: TermSymbol, body: List[Tree])(implicit ctx: Context): TempTrees = { val modcls = sym.moduleClass.asClass - val clsdef = ClassDef(modcls, Nil, body) + val constr = DefDef(modcls.primaryConstructor.asTerm, EmptyTree) + val clsdef = ClassDef(modcls, Nil, constr, body) val valdef = ValDef(sym, New(modcls.typeConstructor)) TempTrees(valdef :: clsdef :: Nil) } @@ -324,7 +324,6 @@ object TypedTrees { * The contained trees will be integrated in enclosing Blocks or Templates */ case class TempTrees(trees: List[Tree]) extends Tree { - override def pos: Position = unsupported("pos") override def tpe: Type = unsupported("tpe") } @@ -555,7 +554,7 @@ object TypedTrees { } case TypeDef(mods, name, _, tpt) => check(tpt.tpe.isInstanceOf[TypeBounds]) - case Template(parents, selfType, body) => + case Template(constr, parents, selfType, body) => case ClassDef(mods, name, tparams, impl) => case Import(expr, selectors) => check(expr.isValue) diff --git a/src/dotty/tools/dotc/core/UntypedTrees.scala b/src/dotty/tools/dotc/core/UntypedTrees.scala index 509c0abfb..7e187864b 100644 --- a/src/dotty/tools/dotc/core/UntypedTrees.scala +++ b/src/dotty/tools/dotc/core/UntypedTrees.scala @@ -3,28 +3,49 @@ package core import util.Positions._, Types._, Contexts._, Constants._, Names._, Flags._ import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, TypedTrees._ +import language.higherKinds object UntypedTrees { object untpd extends Trees.Instance[Untyped] { + // ----- Tree cases that exist in untyped form only ------------------ + + /** A typed subtree of an untyped tree needs to be wrapped in a TypedSlice */ + case class TypedSplice(tree: TypedTree) extends UntypedTree + + /** mods object name impl */ + case class ModuleDef(mods: Modifiers, name: TermName, impl: Template) + extends NameTree with ModDefTree { + type ThisTree[T >: Untyped] <: Trees.NameTree[T] with Trees.ModDefTree[T] with ModuleDef + } + + /** (vparams) => body */ + case class Function(args: List[Tree], body: Tree) extends Tree + case class InfixOp(left: Tree, op: Name, right: Tree) extends Tree + case class Postfixop(tree: Tree, op: Name) extends Tree + case class Prefixop(op: Name, tree: Tree) extends Tree + case class Parens(trees: List[Tree]) extends Tree + case class WhileDo(cond: Tree, body: Tree) extends TermTree + case class DoWhile(body: Tree, cond: Tree) extends TermTree + case class ForYield(enums: List[Tree], expr: Tree) extends TermTree + case class ForDo(enums: List[Tree], body: Tree) extends TermTree + case class GenFrom(pat: Tree, expr: Tree) extends Tree + case class GenAlias(pat: Tree, expr: Tree) extends Tree + case class TypeParamBounds(below: Tree, above: Tree, view: Tree, context: Tree) extends TypTree + case class PatDef(mods: Modifiers, pats: List[Tree], tpt: Tree, rhs: Tree) extends ModDefTree + + def Function(vparam: ValDef, body: Tree): Function = + Function(vparam :: Nil, body) + + def syntheticParameter(pname: TermName): ValDef = + ValDef(Modifiers(SyntheticTermParam), pname, TypeTree(), EmptyTree()) } import untpd._ class UGen(implicit ctx: Context) { def constructor(mods: Modifiers, vparamAccessorss: List[List[Tree]], ofTrait: Boolean): DefDef = ??? - - def Template( - constrMods: Modifiers, - vparamAccessorss: List[List[Tree]], - parents: List[Tree], - self: ValDef, - stats: List[Tree], - ofTrait: Boolean): Template = { - val constr = constructor(constrMods, vparamAccessorss, ofTrait) - Trees.Template(parents, self, vparamAccessorss.flatten ++ (constr :: stats))(NoPosition) - } } def ugen(implicit ctx: Context) = diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala index f817cf9b9..60214465e 100644 --- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala @@ -903,7 +903,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: setSymModsName() val impl = readTemplateRef() val tparams = until(end, readTypeDefRef) - ClassDef(symbol.asClass, tparams map (_.symbol.asType), impl.body) + ClassDef(symbol.asClass, tparams map (_.symbol.asType), EmptyTree, impl.body) // !!! TODO: pull out primary constructor case MODULEtree => setSymModsName() @@ -956,7 +956,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: val parents = times(readNat(), readTreeRef) val self = readValDefRef() val body = until(end, readTreeRef) - Trees.Template[Type](parents, self, body) + Trees.Template[Type](EmptyTree, parents, self, body) // !!! TODO: pull out primary constructor .withType(refType(symbol)) case BLOCKtree => diff --git a/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala b/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala index 77e336b34..2073b8a3f 100644 --- a/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala +++ b/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala @@ -181,7 +181,7 @@ class SymbolicXMLBuilder(preserveWS: Boolean)(implicit ctx: Context) { New(_scala_xml_Unparsed, LL(const(str))) def element(qname: String, attrMap: mutable.Map[String, Tree], empty: Boolean, args: Seq[Tree])(implicit cpos: Position): Tree = { - val tpos = cpos.transparent + val tpos = cpos.toSynthetic locally { implicit val cpos: Position = tpos diff --git a/src/dotty/tools/dotc/parsing/TreeBuilder.scala b/src/dotty/tools/dotc/parsing/TreeBuilder.scala index 772849e98..0a008af9d 100644 --- a/src/dotty/tools/dotc/parsing/TreeBuilder.scala +++ b/src/dotty/tools/dotc/parsing/TreeBuilder.scala @@ -11,20 +11,20 @@ import TreeInfo._ /** Methods for building trees, used in the parser. All the trees * returned by this class must be untyped. */ -class TreeBuilder()(implicit ctx: Context) { +class TreeBuilder(implicit ctx: Context) { import untpd._ - def scalaDot(name: Name)(implicit cpos: Position): Select = + def scalaDot(name: Name): Select = Select(new TypedSplice(tpd.Ident(defn.ScalaPackageVal.termRef)), name) - def scalaAnyRefConstr(implicit cpos: Position) = scalaDot(tpnme.AnyRef) - def scalaAnyValConstr(implicit cpos: Position) = scalaDot(tpnme.AnyVal) - def scalaAnyConstr(implicit cpos: Position) = scalaDot(tpnme.Any) - def scalaUnitConstr(implicit cpos: Position) = scalaDot(tpnme.Unit) - def productConstr(implicit cpos: Position) = scalaDot(tpnme.Product) - def productConstrN(n: Int)(implicit cpos: Position) = scalaDot(("Product" + n).toTypeName) - def serializableConstr(implicit cpos: Position) = scalaDot(tpnme.Serializable) + def scalaAnyRefConstr = scalaDot(tpnme.AnyRef) + def scalaAnyValConstr = scalaDot(tpnme.AnyVal) + def scalaAnyConstr = scalaDot(tpnme.Any) + def scalaUnitConstr = scalaDot(tpnme.Unit) + def productConstr = scalaDot(tpnme.Product) + def productConstrN(n: Int) = scalaDot(("Product" + n).toTypeName) + def serializableConstr = scalaDot(tpnme.Serializable) def convertToTypeName(t: Tree): Tree = ??? @@ -40,16 +40,16 @@ class TreeBuilder()(implicit ctx: Context) { override def transform(tree: Tree): Tree = tree match { case Ident(name) if isVarPattern(tree) && name != nme.WILDCARD => Bind( - name, Ident(nme.WILDCARD)(tree.pos.focus) - )(tree.pos) + name, Ident(nme.WILDCARD).withPos(tree.pos.focus) + ).withPos(tree.pos) case Typed(id @ Ident(name), tpt) if isVarPattern(id) && name != nme.WILDCARD => Bind( name, Typed( - Ident(nme.WILDCARD)(tree.pos.focus), + Ident(nme.WILDCARD).withPos(tree.pos.focus), transform(tpt) - )(tree.pos.withStart(tree.pos.point)) - )(tree.pos.withPoint(id.pos.point)) + ).withPos(tree.pos.withStart(tree.pos.point)) + ).withPos(tree.pos.withPoint(id.pos.point)) case Apply(fn @ Apply(_, _), args) => tree.derivedApply(transform(fn), transform(args)) case Apply(fn, args) => @@ -109,15 +109,13 @@ class TreeBuilder()(implicit ctx: Context) { private def getVariables(tree: Tree): List[VariableInfo] = getVars(new ListBuffer[VariableInfo], tree).toList - def byNameApplication(tpe: Tree)(implicit cpos: Position): Tree = + def byNameApplication(tpe: Tree): Tree = AppliedTypeTree(scalaDot(tpnme.BYNAME_PARAM_CLASS), List(tpe)) - def repeatedApplication(tpe: Tree)(implicit cpos: Position): Tree = + def repeatedApplication(tpe: Tree): Tree = AppliedTypeTree(scalaDot(tpnme.REPEATED_PARAM_CLASS), List(tpe)) - def makeTuple(trees: List[Tree])(implicit cpos: Position): Tree = { - val endPos = cpos.endPos + def makeTuple(trees: List[Tree])(implicit cpos: Position): Tree = { def mkPair(t1: Tree, t2: Tree) = { - implicit val cpos = endPos if (t1.isType) AppliedTypeTree(scalaDot(tpnme.Pair), List(t1, t2)) else Pair(t1, t2) } @@ -129,7 +127,7 @@ class TreeBuilder()(implicit ctx: Context) { case _ => t } - def makeSelfDef(name: TermName, tpt: Tree)(implicit cpos: Position): ValDef = + def makeSelfDef(name: TermName, tpt: Tree): ValDef = ValDef(Modifiers(Private), name, tpt, EmptyTree()) /** If tree is a variable pattern, return its variable info. @@ -153,7 +151,7 @@ class TreeBuilder()(implicit ctx: Context) { def makeBinop(isExpr: Boolean, left: Tree, op: TermName, right: Tree, opPos: Position): Tree = { def mkNamed(args: List[Tree]) = if (isExpr) args map { - case arg @ Assign(Ident(name), rhs) => NamedArg(name, rhs)(arg.pos) + case arg @ Assign(Ident(name), rhs) => NamedArg(name, rhs).withPos(arg.pos) case arg => arg } else args val arguments = right match { @@ -162,20 +160,20 @@ class TreeBuilder()(implicit ctx: Context) { } if (isExpr) { if (isLeftAssoc(op)) { - Apply(Select(stripParens(left), op.encode)(opPos), arguments) + Apply(Select(stripParens(left), op.encode).withPos(opPos), arguments) } else { val x = ctx.freshName().toTermName Block( List(ValDef(Modifiers(Synthetic), x, TypeTree(), stripParens(left))), - Apply(Select(stripParens(right), op.encode)(opPos), List(Ident(x)(left.pos)))) + Apply(Select(stripParens(right), op.encode).withPos(opPos), List(Ident(x).withPos(left.pos)))) } } else { - Apply(Ident(op.encode)(opPos), stripParens(left) :: arguments) + Apply(Ident(op.encode).withPos(opPos), stripParens(left) :: arguments) } } /** tpt.<init> */ - def SelectConstructor(tpt: Tree)(implicit cpos: Position): Tree = + def SelectConstructor(tpt: Tree): Tree = Select(tpt, nme.CONSTRUCTOR) private def splitArgss(constr: Tree, outerArgss: List[List[Tree]]): (Tree, List[List[Tree]]) = constr match { @@ -186,14 +184,14 @@ class TreeBuilder()(implicit ctx: Context) { /** new tpt(argss_1)...(argss_n) * @param npos the position spanning <new tpt>, without any arguments */ - def makeNew(parentConstr: Tree)(implicit cpos: Position) = { + def makeNew(parentConstr: Tree) = { val (tpt, argss) = splitArgss(parentConstr, Nil) New(tpt, argss) } /** Create positioned tree representing an object creation <new parents { self => stats } */ - def makeNew(templ: Template)(implicit cpos: Position): Tree = { + def makeNew(templ: Template): Tree = { val x = tpnme.ANON_CLASS val nu = makeNew(Ident(x)) val clsDef = { @@ -206,26 +204,26 @@ class TreeBuilder()(implicit ctx: Context) { /** Create positioned tree representing an object creation <new parents { self => stats } * @param cpos the position of the new, focus should be the first parent's start. */ - def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree])(implicit cpos: Position): Tree = { + def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree]): Tree = { val newPos = Position(cpos.start, cpos.point) val clsPos = Position(cpos.point, cpos.end) if (parents.isEmpty) - makeNew(List(scalaAnyRefConstr(newPos.endPos)), self, stats) + makeNew(List(scalaAnyRefConstr.withPos(newPos.endPos)), self, stats) else if (parents.tail.isEmpty && stats.isEmpty) makeNew(parents.head) else { val x = tpnme.ANON_CLASS - val nu = makeNew(Ident(x)(newPos))(newPos) + val nu = makeNew(Ident(x).withPos(newPos)).withPos(newPos) val clsDef = { implicit val cpos = clsPos - ClassDef(Modifiers(Final), x, Nil, Template(parents, self, stats)) + ClassDef(Modifiers(Final), x, Nil, Template(???, parents, self, stats)) } Block(clsDef, nu) } } /** Create a tree representing an assignment <lhs = rhs> */ - def makeAssign(lhs: Tree, rhs: Tree)(implicit cpos: Position): Tree = lhs match { + def makeAssign(lhs: Tree, rhs: Tree): Tree = lhs match { case Apply(fn, args) => Apply(Select(fn, nme.update), args :+ rhs) case _ => @@ -237,35 +235,35 @@ class TreeBuilder()(implicit ctx: Context) { if (tps.tail.isEmpty) tps.head else CompoundTypeTree(Template(tps, emptyValDef, Nil))*/ - private def labelDefAndCall(lname: TermName, rhs: Tree, call: Tree)(implicit cpos: Position) = { - val ldef = DefDef(Modifiers(Label)(cpos.startPos), lname, Nil, ListOfNil, TypeTree(), rhs) + private def labelDefAndCall(lname: TermName, rhs: Tree, call: Tree) = { + val ldef = DefDef(Modifiers(Label).withPos(cpos.startPos), lname, Nil, ListOfNil, TypeTree(), rhs) Block(ldef, call) } - private def labelCall(lname: TermName)(implicit cpos: Position): Apply = + private def labelCall(lname: TermName): Apply = Apply(Ident(lname), Nil) /** Create tree representing a while loop */ - def makeWhile(lname: TermName, cond: Tree, body: Tree)(implicit cpos: Position): Tree = { - val continu = labelCall(lname)((cond.pos union body.pos).endPos) + def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = { + val continu = labelCall(lname).withPos((cond.pos union body.pos).endPos) val rhs = { implicit val cpos = NoPosition - If(cond, Block(body, continu), Literal(Constant())(continu.pos)) + If(cond, Block(body, continu), Literal(Constant()).withPos(continu.pos)) } labelDefAndCall(lname, rhs, continu) } /** Create tree representing a do-while loop */ - def makeDoWhile(lname: TermName, body: Tree, cond: Tree)(implicit cpos: Position): Tree = { - val continu = labelCall(lname)((cond.pos union body.pos).endPos) - val rhs = Block(body, If(cond, continu, Literal(Constant())(continu.pos))) + def makeDoWhile(lname: TermName, body: Tree, cond: Tree): Tree = { + val continu = labelCall(lname).withPos((cond.pos union body.pos).endPos) + val rhs = Block(body, If(cond, continu, Literal(Constant()).withPos(continu.pos))) labelDefAndCall(lname, rhs, continu) } /** Create block of statements `stats` */ - def makeBlock(stats: List[Tree])(implicit cpos: Position): Tree = + def makeBlock(stats: List[Tree]): Tree = if (stats.isEmpty) Literal(Constant()) - else if (!stats.last.isTerm) Block(stats, Literal(Constant())(cpos.endPos)) + else if (!stats.last.isTerm) Block(stats, Literal(Constant()).withPos(cpos.endPos)) else if (stats.length == 1) stats.head else Block(stats.init, stats.last) @@ -282,29 +280,24 @@ class TreeBuilder()(implicit ctx: Context) { } /** Create tree for for-comprehension generator <pat <- rhs> or <pat = rhs> */ - def makeGenerator(pat: Tree, valeq: Boolean, rhs: Tree)(implicit cpos: Position): Enumerator = { + def makeGenerator(pat: Tree, valeq: Boolean, rhs: Tree): Enumerator = { val pat1 = patvarTransformer.transform(pat) - if (valeq) ValEq(pat1, rhs)(cpos) - else ValFrom(pat1, makePatFilter(rhs, pat1, canDrop = true))(cpos) + if (valeq) ValEq(pat1, rhs) + else ValFrom(pat1, makePatFilter(rhs, pat1, canDrop = true)) } - def makeParam(pname: TermName, tpe: Tree)(implicit cpos: Position) = - ValDef(Modifiers(Param)(cpos.startPos), pname, tpe, EmptyTree()) - - def makeSyntheticParam(pname: TermName)(implicit cpos: Position) = - ValDef(Modifiers(SyntheticTermParam)(cpos.startPos), pname, TypeTree(), EmptyTree()) /* def makeSyntheticTypeParam(pname: TypeName, bounds: Tree) = TypeDef(Modifiers(DEFERRED | SYNTHETIC), pname, Nil, bounds) */ abstract class Enumerator { def pos: Position } - case class ValFrom(pat: Tree, rhs: Tree)(implicit cpos: Position) extends Enumerator { + case class ValFrom(pat: Tree, rhs: Tree) extends Enumerator { val pos = cpos union pat.pos union rhs.pos } - case class ValEq(pat: Tree, rhs: Tree)(implicit cpos: Position) extends Enumerator { + case class ValEq(pat: Tree, rhs: Tree) extends Enumerator { val pos = cpos union pat.pos union rhs.pos } - case class Filter(test: Tree)(implicit cpos: Position) extends Enumerator { + case class Filter(test: Tree) extends Enumerator { val pos = cpos union test.pos } @@ -362,18 +355,18 @@ class TreeBuilder()(implicit ctx: Context) { * The closure is assigned a transparent position with the point at pos.point and * the limits given by pat and body. */ - def makeClosure(pat: Tree, body: Tree)(implicit cpos: Position): Tree = + def makeClosure(pat: Tree, body: Tree): Tree = matchVarPattern(pat) match { case Some(VariableInfo(name, tpt, pos)) => - Function(ValDef(Modifiers(Param)(cpos.startPos), name.toTermName, tpt, EmptyTree())(pos), body) + Function(ValDef(Modifiers(Param).withPos(cpos.startPos), name.toTermName, tpt, EmptyTree()).withPos(pos), body) case None => makeVisitor(List(CaseDef(pat, EmptyTree(), body)), checkExhaustive = false) } /** Make an application qual.meth(pat => body) positioned at `pos`. */ - def makeCombination(meth: TermName, qual: Tree, pat: Tree, body: Tree)(implicit cpos: Position): Tree = - Apply(Select(qual, meth)(NoPosition), makeClosure(pat, body)) + def makeCombination(meth: TermName, qual: Tree, pat: Tree, body: Tree): Tree = + Apply(Select(qual, meth).withPos(NoPosition), makeClosure(pat, body)) /** Optionally, if pattern is a `Bind`, the bound name, otherwise None. */ @@ -392,18 +385,18 @@ class TreeBuilder()(implicit ctx: Context) { /** A reference to the name bound in Bind `pat`. */ def makeValue(pat: Tree): Tree = pat match { - case Bind(name, _) => Ident(name)(pat.pos.focus) + case Bind(name, _) => Ident(name).withPos(pat.pos.focus) } enums match { case (enum @ ValFrom(pat, rhs)) :: Nil => - makeCombination(mapName, rhs, pat, body)(enum.pos) + makeCombination(mapName, rhs, pat, body).withPos(enum.pos) case ValFrom(pat, rhs) :: (rest @ (ValFrom( _, _) :: _)) => makeCombination(flatMapName, rhs, pat, makeFor(mapName, flatMapName, rest, body)) case (enum @ ValFrom(pat, rhs)) :: Filter(test) :: rest => makeFor(mapName, flatMapName, - ValFrom(pat, makeCombination(nme.withFilter, rhs, pat, test))(enum.pos) :: rest, + ValFrom(pat, makeCombination(nme.withFilter, rhs, pat, test)) :: rest, body) case (enum @ ValFrom(pat, rhs)) :: rest => val (valeqs, rest1) = rest.span(_.isInstanceOf[ValEq]) @@ -416,7 +409,7 @@ class TreeBuilder()(implicit ctx: Context) { val ids = (defpat1 :: defpats) map makeValue val rhs1 = makeForYield(ValFrom(defpat1, rhs) :: Nil, Block(pdefs, makeTuple(ids))) val allpats = pat :: pats - val vfrom1 = ValFrom(makeTuple(allpats), rhs1)(enum.pos) + val vfrom1 = ValFrom(makeTuple(allpats), rhs1) makeFor(mapName, flatMapName, vfrom1 :: rest1, body) case _ => EmptyTree() //may happen for erroneous input @@ -450,7 +443,7 @@ class TreeBuilder()(implicit ctx: Context) { if (canDrop) mkAnnotated(defn.DropIfRedundantAnnot, id) else if (!checkExhaustive) mkAnnotated(defn.UncheckedAnnot, id) else id - Function(List(makeSyntheticParam(x)), Match(sel, cases)) + Function(List(untpd.syntheticParameter(x)), Match(sel, cases)) } /** Create tree for case definition <case pat if guard => rhs> */ @@ -464,7 +457,7 @@ class TreeBuilder()(implicit ctx: Context) { /** Create tree for pattern definition <mods val pat0 = rhs> */ def makePatDef(mods: Modifiers, pat: Tree, rhs: Tree, varsArePatterns: Boolean = false): List[Tree] = matchVarPattern(pat) match { case Some(VariableInfo(name, tpt, pos)) if varsArePatterns => - ValDef(mods, name.toTermName, tpt, rhs)(pos) :: Nil // point comes from pat.pos + ValDef(mods, name.toTermName, tpt, rhs).withPos(pos) :: Nil // point comes from pat.pos case _ => // in case there is exactly one variable x_1 in pattern @@ -494,7 +487,7 @@ class TreeBuilder()(implicit ctx: Context) { (ok, rhsUnchecked) } val vars = getVariables(pat1) - val ids = vars map (v => Ident(v.name)(v.pos)) + val ids = vars map (v => Ident(v.name).withPos(v.pos)) val caseDef = CaseDef(pat1, EmptyTree(), makeTuple(ids)) val matchExpr = Match(rhs1, caseDef :: Nil) vars match { @@ -511,14 +504,14 @@ class TreeBuilder()(implicit ctx: Context) { implicit val cpos = pos.focus Select(Ident(tmpName), ("_" + n).toTermName) } - ValDef(mods, vname.toTermName, tpt, rhs)(pos) + ValDef(mods, vname.toTermName, tpt, rhs).withPos(pos) } firstDef :: restDefs } } /** Create a tree representing the function type (argtpes) => restpe */ - def makeFunctionTypeTree(argtpes: List[Tree], restpe: Tree)(implicit cpos: Position): Tree = + def makeFunctionTypeTree(argtpes: List[Tree], restpe: Tree): Tree = AppliedTypeTree(scalaDot(("Function" + argtpes.length).toTypeName), argtpes ::: List(restpe)) /** Append implicit parameter section if `contextBounds` nonempty */ diff --git a/src/dotty/tools/dotc/util/Positions.scala b/src/dotty/tools/dotc/util/Positions.scala index 274ba80cb..bc3f6c83d 100644 --- a/src/dotty/tools/dotc/util/Positions.scala +++ b/src/dotty/tools/dotc/util/Positions.scala @@ -86,7 +86,7 @@ object Positions { Position(this.start, this.end, point - this.start) /** A synthetic copy of this position */ - def toSynthetic = Position(start, end) + def toSynthetic = if (isSynthetic) this else Position(start, end) } private def fromOffsets(start: Int, end: Int, pointDelta: Int) = |