aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-04-23 17:04:34 +0200
committerMartin Odersky <odersky@gmail.com>2013-04-23 17:04:34 +0200
commitfc8fc177d2dfd270e57996099deef2e4a3a975ed (patch)
treec4c143f88249c6a40a9f1e4c886260d26267b75e
parent8566b093c35d5cc5b29544b5b2c3f01b0ec4c1bd (diff)
downloaddotty-fc8fc177d2dfd270e57996099deef2e4a3a975ed.tar.gz
dotty-fc8fc177d2dfd270e57996099deef2e4a3a975ed.tar.bz2
dotty-fc8fc177d2dfd270e57996099deef2e4a3a975ed.zip
Modifications in prepation of parsing.
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala1
-rw-r--r--src/dotty/tools/dotc/core/Flags.scala4
-rw-r--r--src/dotty/tools/dotc/core/StdNames.scala2
-rw-r--r--src/dotty/tools/dotc/core/TreeInfo.scala10
-rw-r--r--src/dotty/tools/dotc/core/Trees.scala172
-rw-r--r--src/dotty/tools/dotc/core/TypedTrees.scala11
-rw-r--r--src/dotty/tools/dotc/core/UntypedTrees.scala21
-rw-r--r--src/dotty/tools/dotc/parsing/Scanners.scala46
-rw-r--r--src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala2
-rw-r--r--src/dotty/tools/dotc/parsing/Tokens.scala9
-rw-r--r--src/dotty/tools/dotc/parsing/TreeBuilder.scala147
-rw-r--r--src/dotty/tools/dotc/util/Positions.scala14
12 files changed, 285 insertions, 154 deletions
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index 2838f1c7f..6e089dde6 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -294,6 +294,7 @@ object Contexts {
def freshName(): String = freshNames.newName()
def freshName(prefix: String): String = freshNames.newName(prefix)
+ def freshName(prefix: Name): String = freshName(prefix.toString)
/** The loader that loads the members of _root_ */
def rootLoader(root: TermSymbol)(implicit ctx: Context): SymbolLoader = platform.rootLoader(root)
diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala
index 4e88515e9..df4d873a5 100644
--- a/src/dotty/tools/dotc/core/Flags.scala
+++ b/src/dotty/tools/dotc/core/Flags.scala
@@ -84,6 +84,9 @@ object Flags {
/** The number of non-kind flags in this set */
def numFlags: Int = java.lang.Long.bitCount(bits & ~KINDFLAGS)
+ /** The lowest non-kind bit set in this flagset */
+ def firstBit: Int = java.lang.Long.numberOfTrailingZeros(bits & ~KINDFLAGS)
+
/** The list of non-empty names of flags with given index idx that are set in this FlagSet */
private def flagString(idx: Int): List[String] =
if ((bits & (1L << idx)) == 0) Nil
@@ -444,6 +447,7 @@ object Flags {
final val SyntheticTermParam = allOf(Synthetic, TermParam)
final val SyntheticTypeParam = allOf(Synthetic, TypeParam)
final val SyntheticCase = allOf(Synthetic, Case)
+ final val AbstractAndOverride = allOf(Abstract, Override)
implicit def conjToFlagSet(conj: FlagConjunction): FlagSet =
FlagSet(conj.bits)
diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala
index 4ef3456df..80d3ac6b6 100644
--- a/src/dotty/tools/dotc/core/StdNames.scala
+++ b/src/dotty/tools/dotc/core/StdNames.scala
@@ -290,6 +290,7 @@ object StdNames {
val NoPrefix: N = "NoPrefix"
val NoSymbol: N = "NoSymbol"
val NoType: N = "NoType"
+ val Pair: N = "Pair"
val Ref: N = "Ref"
val RootPackage: N = "RootPackage"
val RootClass: N = "RootClass"
@@ -540,6 +541,7 @@ object StdNames {
val ZOR = encode("||")
// unary operators
+ val UNARY_PREFIX: N = "unary_"
val UNARY_~ = encode("unary_~")
val UNARY_+ = encode("unary_+")
val UNARY_- = encode("unary_-")
diff --git a/src/dotty/tools/dotc/core/TreeInfo.scala b/src/dotty/tools/dotc/core/TreeInfo.scala
index cb621164c..c3d0d4ece 100644
--- a/src/dotty/tools/dotc/core/TreeInfo.scala
+++ b/src/dotty/tools/dotc/core/TreeInfo.scala
@@ -16,7 +16,7 @@ abstract class TreeInfo {
def isDeclarationOrTypeDef(tree: Tree[_ >: Untyped]): Boolean = tree match {
case DefDef(_, _, _, _, _, EmptyTree())
| ValDef(_, _, _, EmptyTree())
- | TypeDef(_, _, _) => true
+ | TypeDef(_, _, _, _) => true
case _ => false
}
@@ -25,7 +25,7 @@ abstract class TreeInfo {
def isInterfaceMember(tree: Tree[_ >: Untyped]): Boolean = tree match {
case EmptyTree() => true
case Import(_, _) => true
- case TypeDef(_, _, _) => true
+ case TypeDef(_, _, _, _) => true
case DefDef(mods, _, _, _, _, __) => mods.flags is Deferred
case ValDef(mods, _, _, _) => mods is Deferred
case _ => false
@@ -37,7 +37,7 @@ abstract class TreeInfo {
def isIdempotentDef(tree: Tree[Type])(implicit ctx: Context): Boolean = tree match {
case EmptyTree()
| ClassDef(_, _, _, _)
- | TypeDef(_, _, _)
+ | TypeDef(_, _, _, _)
| Import(_, _)
| DefDef(_, _, _, _, _, _) =>
true
@@ -231,7 +231,7 @@ abstract class TreeInfo {
}
def isEarlyTypeDef(tree: Tree[_ >: Untyped]) = tree match {
- case TypeDef(mods, _, _) => mods is Scala2PreSuper
+ case TypeDef(mods, _, _, _) => mods is Scala2PreSuper
case _ => false
}
@@ -476,4 +476,4 @@ abstract class TreeInfo {
case _ => false
})*/
}
-object treeInfo extends TreeInfo \ No newline at end of file
+object TreeInfo extends TreeInfo \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/Trees.scala b/src/dotty/tools/dotc/core/Trees.scala
index 7befc9956..07a6ada69 100644
--- a/src/dotty/tools/dotc/core/Trees.scala
+++ b/src/dotty/tools/dotc/core/Trees.scala
@@ -6,6 +6,7 @@ import Denotations._, StdNames._
import annotation.tailrec
import language.higherKinds
import collection.mutable
+import collection.mutable.ArrayBuffer
object Trees {
@@ -19,22 +20,87 @@ object Trees {
type TypedTree = Tree[Type]
type UntypedTree = Tree[Untyped]
+ /** Modifiers and annotations for definitions
+ * @param flags The set flags
+ * @param privateWithin If a private or protected has is followed by a
+ * qualifier [q], the name q, "" as a typename otherwise.
+ * @param annotations The annotations preceding the modifers
+ * @param positions A flagPositions structure that records the positions
+ * of et flags.
+ * @param pos The position of the modifiers. This should start with
+ * the first modifier or annotation and have as point
+ * the start of the opening keyword(s) of the definition.
+ * It should have as end the end of the opening keywords(s).
+ */
case class Modifiers[T >: Untyped](
flags: FlagSet = EmptyFlags,
privateWithin: TypeName = tpnme.EMPTY,
- annotations: List[Tree[T]] = Nil) {
+ annotations: List[Tree[T]] = Nil,
+ positions: FlagPositions = NoFlagPositions)(implicit val cpos: Position = NoPosition) {
+
+ 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 is(fs: FlagSet): Boolean = flags is fs
+ def is(fc: FlagConjunction): Boolean = flags is fc
+
+ def add(flag: FlagSet, start: Int) =
+ copy(flags = flags | flag, positions = positions.add(flag, start))
+
+ def withAnnotations(annots: List[Tree[T]]) =
+ if (annots.isEmpty) this
+ else copy(annotations = annotations ++ annots)(cpos)
+
+ def withPrivateWithin(pw: TypeName) =
+ if (pw.isEmpty) this
+ else copy(privateWithin = pw)(cpos)
+
+ def withPos(pos: Position) = copy()(pos)
- def | (fs: FlagSet) = copy(flags = flags | fs)
- def & (fs: FlagSet) = copy(flags = flags & fs)
- def &~(fs: FlagSet) = copy(flags = flags &~ fs)
- def is(fs: FlagSet) = flags is fs
- def is(fc: FlagConjunction) = flags is fc
+ val pos: Position = unionPos(cpos, annotations)
}
- private val modCache = mutable.Map[FlagSet, Modifiers[Untyped]]()
+ private final val OffsetShift = 6
+ private final val FlagMask = (1 << OffsetShift) - 1
- def apply[T >: Untyped](flags: FlagSet = EmptyFlags): Modifiers[T] =
- modCache.getOrElseUpdate(flags, Modifiers(flags, tpnme.EMPTY, Nil)).asInstanceOf[Modifiers[T]]
+ class FlagPositions(val arr: Array[Int]) extends AnyVal {
+ def get(flag: FlagSet): Position = {
+ val str :: Nil = flag.flagStrings.toList
+ val code = flag.firstBit
+ var i = 0
+ while (i < arr.length && ((arr(i) & FlagMask) != code)) i += 1
+ if (i < arr.length) {
+ val start = arr(i) >>> OffsetShift
+ val end = start + str.length
+ Position(start, end)
+ } else
+ NoPosition
+ }
+ def add(flag: FlagSet, start: Int) = {
+ val newarr = new Array[Int](arr.length + 1)
+ arr.copyToArray(newarr)
+ setFlagPosition(newarr, arr.length, flag, start)
+ new FlagPositions(newarr)
+ }
+ }
+
+ private def setFlagPosition(arr: Array[Int], idx: Int, flag: FlagSet, start: Int): Unit = {
+ val code = flag.firstBit
+ assert(code <= 64)
+ arr(idx) = code | (start << OffsetShift)
+ }
+
+ def FlagPositions(assocs: ArrayBuffer[(FlagSet, Int)]): FlagPositions = {
+ val arr = Array[Int](assocs.size)
+ for (i <- 0 until assocs.size) {
+ val (flag, start) = assocs(i)
+ setFlagPosition(arr, i, flag, start)
+ }
+ FlagPositions(assocs)
+ }
+
+ val NoFlagPositions = new FlagPositions(Array())
/** Trees take a parameter indicating what the type of their `tpe` field
* is. Two choices: `Type` or `Untyped`.
@@ -56,10 +122,14 @@ object Trees {
/** The tree's position. Except
* for SharedTree nodes, it is always ensured that a tree's position
- * contains the positions of all its subtrees.
+ * 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
+
/** The type constructor at the root of the tree */
type ThisTree[T >: Untyped] <: Tree[T]
@@ -129,6 +199,10 @@ object Trees {
/** Is this tree either the empty tree or the empty ValDef? */
def isEmpty: Boolean = false
+ /** if this tree is the empty tree, the alternative, else this tree */
+ def orElse(that: => Tree[T]): Tree[T] =
+ if (this eq theEmptyTree) that else this
+
override def toText(implicit ctx: Context) = ctx.toText(this)
override def hashCode(): Int = System.identityHashCode(this)
@@ -205,6 +279,19 @@ object Trees {
override def isDef = true
}
+ /** Tree defines a new symbol and carries modifiers.
+ * The position of a ModDefTree usually starts
+ * at the symbol that's being defined (known exception:
+ * A type definition starts at the +/- if there is one).
+ * The annotations, modifiers and keyword that come before
+ * are subsumed in the modifier position.
+ */
+ trait ModDefTree[T >: Untyped] extends DefTree[T] {
+ type ThisTree[T >: Untyped] <: ModDefTree[T]
+ def mods: Modifiers[T]
+ override def xpos = mods.pos union pos
+ }
+
// ----------- Tree case classes ------------------------------------
/** name */
@@ -275,8 +362,16 @@ object Trees {
val pos = cpos union tpt.pos
}
- def New[T >: Untyped](tpt: Tree[T], argss: List[List[Tree[T]]])(implicit cpos: Position): Tree[T] =
- ((Select(New(tpt), nme.CONSTRUCTOR): Tree[T]) /: argss)(Apply(_, _))
+ /** 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(_, _))
+ }
+ }
/** (left, right) */
case class Pair[T >: Untyped](left: Tree[T], right: Tree[T])(implicit cpos: Position)
@@ -343,7 +438,7 @@ 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: Ident[T])(implicit cpos: Position)
+ case class Return[T >: Untyped](expr: Tree[T], from: Tree[T] = EmptyTree[T]())(implicit cpos: Position)
extends TermTree[T] {
type ThisTree[T >: Untyped] = Return[T]
val pos = cpos union expr.pos // from is synthetic, does not influence pos
@@ -406,7 +501,7 @@ object Trees {
}
/** tpt { refinements } */
- case class RefineTypeTree[T >: Untyped](tpt: Tree[T], refinements: List[DefTree[T]])(implicit cpos: Position)
+ case class RefineTypeTree[T >: Untyped](tpt: Tree[T], refinements: List[Tree[T]])(implicit cpos: Position)
extends ProxyTree[T] with TypTree[T] {
type ThisTree[T >: Untyped] = RefineTypeTree[T]
val pos = unionPos(cpos union tpt.pos, refinements)
@@ -421,6 +516,9 @@ object Trees {
def forwardTo = tpt
}
+ def AppliedTypeTree[T >: Untyped](tpt: Tree[T], arg: Tree[T])(implicit cpos: Position): AppliedTypeTree[T] =
+ AppliedTypeTree(tpt, arg :: Nil)
+
/** >: lo <: hi */
case class TypeBoundsTree[T >: Untyped](lo: Tree[T], hi: Tree[T])(implicit cpos: Position)
extends Tree[T] {
@@ -451,14 +549,14 @@ object Trees {
/** mods val name: tpt = rhs */
case class ValDef[T >: Untyped](mods: Modifiers[T], name: TermName, tpt: Tree[T], rhs: Tree[T])(implicit cpos: Position)
- extends NameTree[T] with DefTree[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)
- extends NameTree[T] with DefTree[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)
}
@@ -471,22 +569,22 @@ object Trees {
/** 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, rhs: Tree[T])(implicit cpos: Position)
- extends NameTree[T] with DefTree[T] {
+ case class TypeDef[T >: Untyped](mods: Modifiers[T], name: TypeName, tparams: List[TypeDef[T]], rhs: Tree[T])(implicit cpos: Position)
+ extends NameTree[T] with ModDefTree[T] {
type ThisTree[T >: Untyped] = TypeDef[T]
- val pos = cpos union rhs.pos
+ 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)
extends DefTree[T] {
type ThisTree[T >: Untyped] = Template[T]
- val pos = unionPos(unionPos(cpos union self.pos, parents), body)
+ 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)
- extends NameTree[T] with DefTree[T] {
+ extends NameTree[T] with ModDefTree[T] {
type ThisTree[T >: Untyped] = ClassDef[T]
val pos = unionPos(cpos union impl.pos, tparams)
}
@@ -537,7 +635,7 @@ object Trees {
}
class EmptyValDef[T >: Untyped] extends ValDef[T](
- Modifiers[T](Private), nme.WILDCARD, EmptyTree[T], EmptyTree[T])(NoPosition) with AlwaysEmpty[T]
+ Modifiers[T](Private)(NoPosition), nme.WILDCARD, EmptyTree[T], EmptyTree[T])(NoPosition) with AlwaysEmpty[T]
private object theEmptyValDef extends EmptyValDef[Untyped]
@@ -564,8 +662,8 @@ object Trees {
/** mods object name impl */
case class ModuleDef(mods: Modifiers[Untyped], name: TermName, impl: Template[Untyped])(implicit cpos: Position)
- extends NameTree[Untyped] with DefTree[Untyped] {
- type ThisTree[T >: Untyped] <: NameTree[T] with DefTree[T] with ModuleDef
+ 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
@@ -665,7 +763,7 @@ object Trees {
// ----- Helper functions and classes ---------------------------------------
@tailrec final def unionPos(base: Position, trees: List[Tree[_]]): Position = trees match {
- case t :: ts => unionPos(base union t.pos, ts)
+ case t :: ts => unionPos(base union t.xpos, ts)
case nil => base
}
@@ -738,7 +836,7 @@ object Trees {
case tree: CaseDef[_] if (pat eq tree.pat) && (guard eq tree.guard) && (body eq tree.body) => tree
case _ => CaseDef(pat, guard, body).copyAttr(tree)
}
- def derivedReturn(expr: Tree[T], from: Ident[T]): Return[T] = tree match {
+ def derivedReturn(expr: Tree[T], from: Tree[T]): Return[T] = tree match {
case tree: Return[_] if (expr eq tree.expr) && (from eq tree.from) => tree
case _ => Return(expr, from).copyAttr(tree)
}
@@ -774,7 +872,7 @@ object Trees {
case tree: OrTypeTree[_] if (left eq tree.left) && (right eq tree.right) => tree
case _ => OrTypeTree(left, right).copyAttr(tree)
}
- def derivedRefineTypeTree(tpt: Tree[T], refinements: List[DefTree[T]]): RefineTypeTree[T] = tree match {
+ def derivedRefineTypeTree(tpt: Tree[T], refinements: List[Tree[T]]): RefineTypeTree[T] = tree match {
case tree: RefineTypeTree[_] if (tpt eq tree.tpt) && (refinements eq tree.refinements) => tree
case _ => RefineTypeTree(tpt, refinements).copyAttr(tree)
}
@@ -806,9 +904,9 @@ object Trees {
case tree: DefDef[_] if (mods == tree.mods) && (name == tree.name) && (tparams eq tree.tparams) && (vparamss eq tree.vparamss) && (tpt eq tree.tpt) && (rhs eq tree.rhs) => tree
case _ => DefDef(mods, name, tparams, vparamss, tpt, rhs).copyAttr(tree)
}
- def derivedTypeDef(mods: Modifiers[T], name: TypeName, rhs: Tree[T]): TypeDef[T] = tree match {
- case tree: TypeDef[_] if (mods == tree.mods) && (name == tree.name) && (rhs eq tree.rhs) => tree
- case _ => TypeDef(mods, name, rhs).copyAttr(tree)
+ def derivedTypeDef(mods: Modifiers[T], name: TypeName, tparams: List[TypeDef[T]], rhs: Tree[T]): TypeDef[T] = tree match {
+ 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
@@ -873,7 +971,7 @@ object Trees {
case CaseDef(pat, guard, body) =>
finishCaseDef(tree.derivedCaseDef(transform(pat, c), transform(guard, c), transform(body, c)), tree, c, plugins)
case Return(expr, from) =>
- finishReturn(tree.derivedReturn(transform(expr, c), transformSub(from, c)), tree, c, plugins)
+ finishReturn(tree.derivedReturn(transform(expr, c), transform(from, c)), tree, c, plugins)
case Try(block, catches, finalizer) =>
finishTry(tree.derivedTry(transform(block, c), transformSub(catches, c), transform(finalizer, c)), tree, c, plugins)
case Throw(expr) =>
@@ -906,8 +1004,8 @@ object Trees {
finishValDef(tree.derivedValDef(mods, name, transform(tpt, c), transform(rhs, c)), tree, c, plugins)
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
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, rhs) =>
- finishTypeDef(tree.derivedTypeDef(mods, name, 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 ClassDef(mods, name, tparams, impl) =>
@@ -1055,8 +1153,8 @@ object Trees {
tree.derivedValDef(mods, name, transform(tpt), transform(rhs))
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
tree.derivedDefDef(mods, name, transformSub(tparams), vparamss mapConserve (transformSub(_)), transform(tpt), transform(rhs))
- case TypeDef(mods, name, rhs) =>
- tree.derivedTypeDef(mods, name, 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 ClassDef(mods, name, tparams, impl) =>
@@ -1157,8 +1255,8 @@ object Trees {
this(this(x, tpt), rhs)
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
this(this((this(x, tparams) /: vparamss)(apply), tpt), rhs)
- case TypeDef(mods, name, rhs) =>
- this(x, 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 ClassDef(mods, name, tparams, impl) =>
diff --git a/src/dotty/tools/dotc/core/TypedTrees.scala b/src/dotty/tools/dotc/core/TypedTrees.scala
index bfe2c957d..348b2c37b 100644
--- a/src/dotty/tools/dotc/core/TypedTrees.scala
+++ b/src/dotty/tools/dotc/core/TypedTrees.scala
@@ -186,7 +186,7 @@ object TypedTrees {
}
def TypeDef(sym: TypeSymbol)(implicit ctx: Context): TypeDef =
- Trees.TypeDef(Modifiers(sym), sym.name, TypeTree(sym.info))(defPos(sym))
+ Trees.TypeDef(Modifiers(sym), sym.name, Nil, TypeTree(sym.info))(defPos(sym)) // !!! fill in typeParams
.withType(refType(sym)).checked
def ClassDef(cls: ClassSymbol, typeParams: List[TypeSymbol], body: List[Tree])(implicit ctx: Context): ClassDef = {
@@ -227,7 +227,7 @@ object TypedTrees {
def SharedTree(tree: Tree): SharedTree =
Trees.SharedTree(tree).withType(tree.tpe)
- def refType(sym: Symbol)(implicit ctx: Context) = NamedType.withSym(sym.owner.thisType, sym)
+ def refType(sym: Symbol)(implicit ctx: Context): NamedType = NamedType.withSym(sym.owner.thisType, sym)
// ------ Creating typed equivalents of trees that exist only in untyped form -------
@@ -239,7 +239,8 @@ object TypedTrees {
case pre => SelectFromTypeTree(TypeTree(pre), tp)
} // no checks necessary
- def ref(sym: TermSymbol)(implicit ctx: Context): tpd.NameTree = ref(sym.termRef)
+ def ref(sym: Symbol)(implicit ctx: Context): tpd.NameTree =
+ ref(NamedType(sym.owner.thisType, sym.name).withDenot(sym))
/** new C(args) */
def New(tp: Type, args: List[Tree])(implicit ctx: Context): Apply =
@@ -479,7 +480,7 @@ object TypedTrees {
check(left.isValueType); check(right.isValueType)
case RefineTypeTree(tpt, refinements) =>
check(tpt.isValueType)
- def checkRefinements(forbidden: Set[Symbol], rs: List[tpd.DefTree]): Unit = rs match {
+ def checkRefinements(forbidden: Set[Symbol], rs: List[tpd.Tree]): Unit = rs match {
case r :: rs1 =>
val rsym = r.symbol
check(rsym.isTerm || rsym.isAbstractOrAliasType)
@@ -552,7 +553,7 @@ object TypedTrees {
check(rhs.isValue)
check(rhs.tpe <:< tpt.tpe)
}
- case TypeDef(mods, name, tpt) =>
+ case TypeDef(mods, name, _, tpt) =>
check(tpt.tpe.isInstanceOf[TypeBounds])
case Template(parents, selfType, body) =>
case ClassDef(mods, name, tparams, impl) =>
diff --git a/src/dotty/tools/dotc/core/UntypedTrees.scala b/src/dotty/tools/dotc/core/UntypedTrees.scala
index 2b1d6a0d6..509c0abfb 100644
--- a/src/dotty/tools/dotc/core/UntypedTrees.scala
+++ b/src/dotty/tools/dotc/core/UntypedTrees.scala
@@ -2,7 +2,7 @@ package dotty.tools.dotc
package core
import util.Positions._, Types._, Contexts._, Constants._, Names._, Flags._
-import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
+import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, TypedTrees._
object UntypedTrees {
@@ -10,5 +10,24 @@ object UntypedTrees {
}
+ 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) =
+ new UGen
}
diff --git a/src/dotty/tools/dotc/parsing/Scanners.scala b/src/dotty/tools/dotc/parsing/Scanners.scala
index 2b3ec9bc2..7260269f9 100644
--- a/src/dotty/tools/dotc/parsing/Scanners.scala
+++ b/src/dotty/tools/dotc/parsing/Scanners.scala
@@ -91,7 +91,7 @@ object Scanners {
/** we need one token lookahead and one token history
*/
- private val next : TokenData = new TokenData0
+ val next : TokenData = new TokenData0
private val prev : TokenData = new TokenData0
/** a stack of tokens which indicates whether line-ends can be statement separators
@@ -193,32 +193,30 @@ object Scanners {
def postProcessToken() = {
// Join CASE + CLASS => CASECLASS, CASE + OBJECT => CASEOBJECT, SEMI + ELSE => ELSE
- if (token == CASE) {
+ def lookahead() = {
prev copyFrom this
- val nextLastOffset = lastCharOffset
fetchToken()
- def resetOffset() {
- offset = prev.offset
- lastOffset = prev.lastOffset
- }
- if (token == CLASS) {
- token = CASECLASS
- resetOffset()
- } else if (token == OBJECT) {
- token = CASEOBJECT
- resetOffset()
- } else {
- lastOffset = nextLastOffset
- next copyFrom this
- this copyFrom prev
- }
+ }
+ def reset(nextLastOffset: Offset) = {
+ lastOffset = nextLastOffset
+ next copyFrom this
+ this copyFrom prev
+ }
+ def fuse(tok: Int) = {
+ token = tok
+ offset = prev.offset
+ lastOffset = prev.lastOffset
+ }
+ if (token == CASE) {
+ val nextLastOffset = lastCharOffset
+ lookahead()
+ if (token == CLASS) fuse(CASECLASS)
+ else if (token == OBJECT) fuse(CASEOBJECT)
+ else reset(nextLastOffset)
} else if (token == SEMI) {
- prev copyFrom this
- fetchToken()
- if (token != ELSE) {
- next copyFrom this
- this copyFrom prev
- }
+ val nextLastOffset = lastCharOffset
+ lookahead()
+ if (token != ELSE) reset(nextLastOffset)
}
}
diff --git a/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala b/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala
index 3c7a1ec4f..77e336b34 100644
--- a/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala
+++ b/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala
@@ -24,7 +24,7 @@ import scala.language.implicitConversions
* @author Burak Emir
* @version 1.0
*/
-abstract class SymbolicXMLBuilder(preserveWS: Boolean)(implicit ctx: Context) {
+class SymbolicXMLBuilder(preserveWS: Boolean)(implicit ctx: Context) {
import Constants.Constant
import untpd._
diff --git a/src/dotty/tools/dotc/parsing/Tokens.scala b/src/dotty/tools/dotc/parsing/Tokens.scala
index f573df49d..4483818c9 100644
--- a/src/dotty/tools/dotc/parsing/Tokens.scala
+++ b/src/dotty/tools/dotc/parsing/Tokens.scala
@@ -156,8 +156,11 @@ object Tokens {
final val localModifierTokens = BitSet(
ABSTRACT, FINAL, SEALED, IMPLICIT, LAZY)
- final val modifierTokens = localModifierTokens | BitSet(
- PRIVATE, PROTECTED, OVERRIDE)
+ final val accessModifierTokens = BitSet(
+ PRIVATE, PROTECTED)
+
+ final val modifierTokens = localModifierTokens | accessModifierTokens | BitSet(
+ OVERRIDE)
/** Is token only legal as start of statement (eof also included)? */
final val mustStartStatTokens = defIntroTokens | modifierTokens | BitSet(
@@ -168,4 +171,6 @@ object Tokens {
final val canEndStatTokens = atomicExprTokens | BitSet(
TYPE, RPAREN, RBRACE, RBRACKET)
+
+ final val numericLitTokens = BitSet(INTLIT, LONGLIT, FLOATLIT, DOUBLELIT)
}
diff --git a/src/dotty/tools/dotc/parsing/TreeBuilder.scala b/src/dotty/tools/dotc/parsing/TreeBuilder.scala
index 2f415e6a5..772849e98 100644
--- a/src/dotty/tools/dotc/parsing/TreeBuilder.scala
+++ b/src/dotty/tools/dotc/parsing/TreeBuilder.scala
@@ -6,17 +6,15 @@ import core._
import Flags._, Trees._, TypedTrees._, UntypedTrees._, Names._, StdNames._, NameOps._, Contexts._
import scala.collection.mutable.ListBuffer
import util.Positions._, Symbols._, Decorators._, Flags._, Constants._
+import TreeInfo._
/** Methods for building trees, used in the parser. All the trees
* returned by this class must be untyped.
*/
-abstract class TreeBuilder(implicit ctx: Context) {
+class TreeBuilder()(implicit ctx: Context) {
import untpd._
- def o2p(offset: Int): Position
- def r2p(start: Int, point: Int, end: Int): Position
-
def scalaDot(name: Name)(implicit cpos: Position): Select =
Select(new TypedSplice(tpd.Ident(defn.ScalaPackageVal.termRef)), name)
@@ -28,26 +26,28 @@ abstract class TreeBuilder(implicit ctx: Context) {
def productConstrN(n: Int)(implicit cpos: Position) = scalaDot(("Product" + n).toTypeName)
def serializableConstr(implicit cpos: Position) = scalaDot(tpnme.Serializable)
- def convertToTypeName(t: Tree) = ???
+ def convertToTypeName(t: Tree): Tree = ???
- implicit val cpos = NoPosition
+ private implicit val cpos = NoPosition
/** Convert all occurrences of (lower-case) variables in a pattern as follows:
* x becomes x @ _
* x: T becomes x @ (_: T)
+ * Also covert all toplevel lower-case type arguments as follows:
+ * t becomes t @ _
*/
private object patvarTransformer extends TreeTransformer {
override def transform(tree: Tree): Tree = tree match {
- case Ident(name) if (treeInfo.isVarPattern(tree) && name != nme.WILDCARD) =>
+ case Ident(name) if isVarPattern(tree) && name != nme.WILDCARD =>
Bind(
name, Ident(nme.WILDCARD)(tree.pos.focus)
)(tree.pos)
- case Typed(id @ Ident(name), tpt) if (treeInfo.isVarPattern(id) && name != nme.WILDCARD) =>
+ case Typed(id @ Ident(name), tpt) if isVarPattern(id) && name != nme.WILDCARD =>
Bind(
name,
Typed(
Ident(nme.WILDCARD)(tree.pos.focus),
- tpt
+ transform(tpt)
)(tree.pos.withStart(tree.pos.point))
)(tree.pos.withPoint(id.pos.point))
case Apply(fn @ Apply(_, _), args) =>
@@ -55,17 +55,21 @@ abstract class TreeBuilder(implicit ctx: Context) {
case Apply(fn, args) =>
tree.derivedApply(fn, transform(args))
case Typed(expr, tpt) =>
- tree.derivedTyped(transform(expr), tpt)
+ tree.derivedTyped(transform(expr), transform(tpt))
case Bind(name, body) =>
tree.derivedBind(name, transform(body))
- case Alternative(_) =>
+ case AppliedTypeTree(tycon, args) =>
+ tree.derivedAppliedTypeTree(tycon, args map transform)
+ case Alternative(_) | Typed(_, _) | AndTypeTree(_, _) | Annotated(_, _) =>
super.transform(tree)
+ case Parens(_) =>
+ stripParens(tree)
case _ =>
tree
}
}
-case class VariableInfo(name: Name, tree: Tree, pos: Position)
+ case class VariableInfo(name: Name, tree: Tree, pos: Position)
/** Traverse pattern and collect all variable names with their types in buffer
* The variables keep their positions; whereas the pattern is converted to be
@@ -89,7 +93,7 @@ case class VariableInfo(name: Name, tree: Tree, pos: Position)
tree match {
case Bind(nme.WILDCARD, _) =>
foldOver(buf, tree)
- case Bind(name, Typed(tree1, tpt)) if !treeInfo.mayBeTypePat(tpt) =>
+ case Bind(name, Typed(tree1, tpt)) if !mayBeTypePat(tpt) =>
apply(add(name, tpt), tree1)
case Bind(name, tree1) =>
apply(add(name, TypeTree()), tree1)
@@ -110,8 +114,13 @@ case class VariableInfo(name: Name, tree: Tree, pos: Position)
def repeatedApplication(tpe: Tree)(implicit cpos: Position): Tree =
AppliedTypeTree(scalaDot(tpnme.REPEATED_PARAM_CLASS), List(tpe))
- private def makeTuple(trees: List[Tree])(implicit cpos: Position): Tree = {
- def mkPair(t1: Tree, t2: Tree) = Pair(t1, t2)(Position(t1.pos.start, cpos.end))
+ def makeTuple(trees: List[Tree])(implicit cpos: Position): Tree = {
+ val endPos = cpos.endPos
+ def mkPair(t1: Tree, t2: Tree) = {
+ implicit val cpos = endPos
+ if (t1.isType) AppliedTypeTree(scalaDot(tpnme.Pair), List(t1, t2))
+ else Pair(t1, t2)
+ }
trees reduce mkPair
}
@@ -123,18 +132,19 @@ case class VariableInfo(name: Name, tree: Tree, pos: Position)
def makeSelfDef(name: TermName, tpt: Tree)(implicit cpos: Position): ValDef =
ValDef(Modifiers(Private), name, tpt, EmptyTree())
- /** If tree is a variable pattern, return Some("its name and type").
- * Otherwise return none */
- private def matchVarPattern(tree: Tree): Option[(Name, Tree)] = {
+ /** If tree is a variable pattern, return its variable info.
+ * Otherwise return none.
+ */
+ private def matchVarPattern(tree: Tree): Option[VariableInfo] = {
def wildType(t: Tree): Option[Tree] = t match {
case Ident(x) if x.toTermName == nme.WILDCARD => Some(TypeTree())
case Typed(Ident(x), tpt) if x.toTermName == nme.WILDCARD => Some(tpt)
case _ => None
}
tree match {
- case Ident(name) => Some((name, TypeTree()))
- case Bind(name, body) => wildType(body) map (x => (name, x))
- case Typed(Ident(name), tpt) => Some((name, tpt))
+ case Ident(name) => Some(VariableInfo(name, TypeTree(), tree.pos))
+ case Bind(name, body) => wildType(body) map (x => VariableInfo(name, x, tree.pos))
+ case Typed(id @ Ident(name), tpt) => Some(VariableInfo(name, tpt, id.pos))
case _ => None
}
}
@@ -151,7 +161,7 @@ case class VariableInfo(name: Name, tree: Tree, pos: Position)
case _ => right :: Nil
}
if (isExpr) {
- if (treeInfo.isLeftAssoc(op)) {
+ if (isLeftAssoc(op)) {
Apply(Select(stripParens(left), op.encode)(opPos), arguments)
} else {
val x = ctx.freshName().toTermName
@@ -164,20 +174,11 @@ case class VariableInfo(name: Name, tree: Tree, pos: Position)
}
}
- /** Creates a tree representing new Object { stats }.
- * To make sure an anonymous subclass of Object is created,
- * if there are no stats, a () is added.
- */
- def makeAnonymousNew(stats: List[Tree])(implicit cpos: Position): Tree = {
- val stats1 = if (stats.isEmpty) Literal(Constant(())) :: Nil else stats
- makeNew(Nil, EmptyValDef(), stats1)
- }
-
/** tpt.<init> */
def SelectConstructor(tpt: Tree)(implicit cpos: Position): Tree =
Select(tpt, nme.CONSTRUCTOR)
- def splitArgss(constr: Tree, outerArgss: List[List[Tree]]): (Tree, List[List[Tree]]) = constr match {
+ private def splitArgss(constr: Tree, outerArgss: List[List[Tree]]): (Tree, List[List[Tree]]) = constr match {
case Apply(tree, args) => splitArgss(tree, args :: outerArgss)
case _ => (constr, if (outerArgss.isEmpty) ListOfNil else outerArgss)
}
@@ -185,24 +186,36 @@ case class VariableInfo(name: Name, tree: Tree, pos: Position)
/** new tpt(argss_1)...(argss_n)
* @param npos the position spanning <new tpt>, without any arguments
*/
- def makeNew(parentConstr: Tree, npos: Position) = {
- val (tpt, argss1) = splitArgss(parentConstr, Nil)
- (SelectConstructor(tpt)(npos) /: argss1)(Apply(_, _))
+ def makeNew(parentConstr: Tree)(implicit cpos: Position) = {
+ val (tpt, argss) = splitArgss(parentConstr, Nil)
+ New(tpt, argss)
}
/** Create positioned tree representing an object creation <new parents { self => stats }
- * @param pos the position of the new, focus should be the first parent's start.
+ */
+ def makeNew(templ: Template)(implicit cpos: Position): Tree = {
+ val x = tpnme.ANON_CLASS
+ val nu = makeNew(Ident(x))
+ val clsDef = {
+ implicit val cpos = NoPosition
+ ClassDef(Modifiers(Final), x, Nil, templ)
+ }
+ Block(clsDef, nu)
+ }
+
+ /** 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 = {
val newPos = Position(cpos.start, cpos.point)
val clsPos = Position(cpos.point, cpos.end)
if (parents.isEmpty)
- makeNew(List(scalaAnyRefConstr(cpos.startPos)), self, stats)
+ makeNew(List(scalaAnyRefConstr(newPos.endPos)), self, stats)
else if (parents.tail.isEmpty && stats.isEmpty)
- makeNew(parents.head, newPos)
+ makeNew(parents.head)
else {
val x = tpnme.ANON_CLASS
- val nu = makeNew(Ident(x)(newPos), newPos)
+ val nu = makeNew(Ident(x)(newPos))(newPos)
val clsDef = {
implicit val cpos = clsPos
ClassDef(Modifiers(Final), x, Nil, Template(parents, self, stats))
@@ -212,7 +225,7 @@ case class VariableInfo(name: Name, tree: Tree, pos: Position)
}
/** Create a tree representing an assignment <lhs = rhs> */
- def makeAssign(lhs: Tree, rhs: Tree): Tree = lhs match {
+ def makeAssign(lhs: Tree, rhs: Tree)(implicit cpos: Position): Tree = lhs match {
case Apply(fn, args) =>
Apply(Select(fn, nme.update), args :+ rhs)
case _ =>
@@ -225,7 +238,7 @@ case class VariableInfo(name: Name, tree: Tree, pos: Position)
else CompoundTypeTree(Template(tps, emptyValDef, Nil))*/
private def labelDefAndCall(lname: TermName, rhs: Tree, call: Tree)(implicit cpos: Position) = {
- val ldef = DefDef(Modifiers(Label), lname, Nil, ListOfNil, TypeTree(), rhs)
+ val ldef = DefDef(Modifiers(Label)(cpos.startPos), lname, Nil, ListOfNil, TypeTree(), rhs)
Block(ldef, call)
}
@@ -256,7 +269,7 @@ case class VariableInfo(name: Name, tree: Tree, pos: Position)
else if (stats.length == 1) stats.head
else Block(stats.init, stats.last)
- def makeFilter(tree: Tree, condition: Tree, canDrop: Boolean): Tree = {
+ def makePatFilter(tree: Tree, condition: Tree, canDrop: Boolean): Tree = {
val cases = List(
CaseDef(condition, EmptyTree(), Literal(Constant(true))),
CaseDef(Ident(nme.WILDCARD), EmptyTree(), Literal(Constant(false)))
@@ -272,14 +285,14 @@ case class VariableInfo(name: Name, tree: Tree, pos: Position)
def makeGenerator(pat: Tree, valeq: Boolean, rhs: Tree)(implicit cpos: Position): Enumerator = {
val pat1 = patvarTransformer.transform(pat)
if (valeq) ValEq(pat1, rhs)(cpos)
- else ValFrom(pat1, makeFilter(rhs, pat1, canDrop = true))(cpos)
+ else ValFrom(pat1, makePatFilter(rhs, pat1, canDrop = true))(cpos)
}
def makeParam(pname: TermName, tpe: Tree)(implicit cpos: Position) =
- ValDef(Modifiers(Param), pname, tpe, EmptyTree())
+ ValDef(Modifiers(Param)(cpos.startPos), pname, tpe, EmptyTree())
def makeSyntheticParam(pname: TermName)(implicit cpos: Position) =
- ValDef(Modifiers(SyntheticTermParam), pname, TypeTree(), EmptyTree())
+ ValDef(Modifiers(SyntheticTermParam)(cpos.startPos), pname, TypeTree(), EmptyTree())
/*
def makeSyntheticTypeParam(pname: TypeName, bounds: Tree) =
TypeDef(Modifiers(DEFERRED | SYNTHETIC), pname, Nil, bounds)
@@ -351,8 +364,8 @@ case class VariableInfo(name: Name, tree: Tree, pos: Position)
*/
def makeClosure(pat: Tree, body: Tree)(implicit cpos: Position): Tree =
matchVarPattern(pat) match {
- case Some((name, tpt)) =>
- Function(ValDef(Modifiers(Param), name.toTermName, tpt, EmptyTree())(pat.pos), body)
+ case Some(VariableInfo(name, tpt, pos)) =>
+ Function(ValDef(Modifiers(Param)(cpos.startPos), name.toTermName, tpt, EmptyTree())(pos), body)
case None =>
makeVisitor(List(CaseDef(pat, EmptyTree(), body)), checkExhaustive = false)
}
@@ -399,7 +412,7 @@ case class VariableInfo(name: Name, tree: Tree, pos: Position)
val rhss = valeqs map { case ValEq(_, rhs) => rhs }
val defpat1 = makeBind(pat)
val defpats = pats map makeBind
- val pdefs = (defpats, rhss).zipped flatMap makePatDef
+ val pdefs = (defpats, rhss).zipped flatMap (makePatDef)
val ids = (defpat1 :: defpats) map makeValue
val rhs1 = makeForYield(ValFrom(defpat1, rhs) :: Nil, Block(pdefs, makeTuple(ids)))
val allpats = pat :: pats
@@ -419,12 +432,11 @@ case class VariableInfo(name: Name, tree: Tree, pos: Position)
makeFor(nme.map, nme.flatMap, enums, body)
/** Create tree for a pattern alternative */
- def makeAlternative(ts: List[Tree]): Tree = {
- def alternatives(t: Tree): List[Tree] = t match {
- case Alternative(ts) => ts
- case _ => List(t)
- }
- Alternative(ts flatMap alternatives)
+ def makeAlternative(ts: List[Tree]): Tree = Alternative(ts flatMap alternatives)
+
+ def alternatives(t: Tree): List[Tree] = t match {
+ case Alternative(ts) => ts
+ case _ => List(t)
}
def mkAnnotated(cls: Symbol, tree: Tree) =
@@ -445,33 +457,14 @@ case class VariableInfo(name: Name, tree: Tree, pos: Position)
def makeCaseDef(pat: Tree, guard: Tree, rhs: Tree): CaseDef =
CaseDef(patvarTransformer.transform(pat), guard, rhs)
- /** Creates tree representing:
- * { case x: Throwable =>
- * val catchFn = catchExpr
- * if (catchFn isDefinedAt x) catchFn(x) else throw x
- * }
- */
- def makeCatchFromExpr(catchExpr: Tree): CaseDef = {
- implicit val cpos = catchExpr.pos.startPos
- val binder = ctx.freshName("x").toTermName
- val pat = Bind(binder, Typed(Ident(nme.WILDCARD), Ident(tpnme.Throwable)))
- val catchDef = ValDef(Modifiers(), ctx.freshName("catchExpr").toTermName, TypeTree(), catchExpr)
- val catchFn = Ident(catchDef.name)
- val cond = Apply(Select(catchFn, nme.isDefinedAt), Ident(binder))
- val app = Apply(Select(catchFn, nme.apply), List(Ident(binder)))
- val thro = Throw(Ident(binder))
- val body = Block(catchDef, If(cond, app, thro))
- makeCaseDef(pat, EmptyTree(), body)
- }
-
/** Create tree for pattern definition <val pat0 = rhs> */
def makePatDef(pat: Tree, rhs: Tree): List[Tree] =
makePatDef(Modifiers(), pat, rhs)
/** 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((name, tpt)) if varsArePatterns =>
- ValDef(mods, name.toTermName, tpt, rhs) :: Nil
+ case Some(VariableInfo(name, tpt, pos)) if varsArePatterns =>
+ ValDef(mods, name.toTermName, tpt, rhs)(pos) :: Nil // point comes from pat.pos
case _ =>
// in case there is exactly one variable x_1 in pattern
@@ -525,7 +518,7 @@ case class VariableInfo(name: Name, tree: Tree, pos: Position)
}
/** Create a tree representing the function type (argtpes) => restpe */
- def makeFunctionTypeTree(argtpes: List[Tree], restpe: Tree): Tree =
+ def makeFunctionTypeTree(argtpes: List[Tree], restpe: Tree)(implicit cpos: Position): Tree =
AppliedTypeTree(scalaDot(("Function" + argtpes.length).toTypeName), argtpes ::: List(restpe))
/** Append implicit parameter section if `contextBounds` nonempty */
@@ -534,7 +527,7 @@ case class VariableInfo(name: Name, tree: Tree, pos: Position)
else {
val mods = Modifiers(if (owner.isTypeName) PrivateLocal | ParamAccessor else Param)
val evidenceParams = for (tpt <- contextBounds) yield {
- val pname = ctx.freshName(nme.EVIDENCE_PARAM_PREFIX.toString).toTermName
+ val pname = ctx.freshName(nme.EVIDENCE_PARAM_PREFIX).toTermName
ValDef(mods | Implicit | Synthetic, pname, tpt, EmptyTree())
}
vparamss.reverse match {
diff --git a/src/dotty/tools/dotc/util/Positions.scala b/src/dotty/tools/dotc/util/Positions.scala
index 2ab6c1920..056af00d1 100644
--- a/src/dotty/tools/dotc/util/Positions.scala
+++ b/src/dotty/tools/dotc/util/Positions.scala
@@ -11,12 +11,12 @@ package util
object Positions {
private val StartEndBits = 26
- private val StartEndMask = (1 << StartEndBits) - 1
+ private val StartEndMask: Long = (1L << StartEndBits) - 1
private val PointOffsetLimit = 1L << (64 - StartEndBits * 2)
class Position(val coords: Long) extends AnyVal {
- def point: Int = start + (coords >>> (StartEndBits * 2)).toInt
def start: Int = (coords & StartEndMask).toInt
+ def point: Int = start + (coords >>> (StartEndBits * 2)).toInt
def end: Int = ((coords >>> StartEndBits) & StartEndMask).toInt
/** The union of two positions. Tries to keep the point offset of
@@ -59,6 +59,16 @@ object Positions {
val NoPosition = new Position(-1L)
+ case class PositionPrefix(val coords: Long) extends AnyVal {
+ def start: Int = (coords & StartEndMask).toInt
+ def point: Int = start + (coords >>> StartEndBits).toInt
+ def toPosition(end: Int) = Position(start, end, point - start max 0)
+ }
+
+ def PositionPrefix(start: Int, pointOffset: Int = 0): PositionPrefix =
+ new PositionPrefix(
+ (start & StartEndMask).toLong | pointOffset.toLong << StartEndBits)
+
case class SourcePosition(source: SourceFile, pos: Position) {
def point: Int = pos.point
def start: Int = pos.start