diff options
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Positions.scala | 58 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 52 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Trees.scala | 176 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypedTreeGen.scala | 12 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/ClassfileParser.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/UnPickler.scala | 13 |
7 files changed, 213 insertions, 106 deletions
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index 461f574c5..e805f59d6 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -41,7 +41,7 @@ class Definitions(implicit ctx: Context) { val parentRefs: List[TypeRef] = ctx.normalizeToRefs(parents, cls, paramDecls) CompleteClassDenotation(cls, ScalaPackageClass, name, flags, parentRefs, decls = paramDecls)(ctx) } - new ClassSymbol(NoOffset, classDenot) + new ClassSymbol(NoCoord, classDenot) } private def mkArityArray(name: String, arity: Int, countFrom: Int): Array[ClassSymbol] = { diff --git a/src/dotty/tools/dotc/core/Positions.scala b/src/dotty/tools/dotc/core/Positions.scala index 3a7d51b33..1d455e6f2 100644 --- a/src/dotty/tools/dotc/core/Positions.scala +++ b/src/dotty/tools/dotc/core/Positions.scala @@ -1,27 +1,55 @@ package dotty.tools.dotc.core +/** Position format in little endian: + * Start: unsigned 26 Bits (works for source files up to 64M) + * End: unsigned 26 Bits + * Point: unsigned 12 Bits relative to start + * NoPosition encoded as -1L (this is a normally invalid position + * because point would lie beyond end. + */ object Positions { - /** The bit position of the end part of a range position */ - private val Shift = 32 + private val StartEndBits = 26 + private val StartEndMask = (1 << StartEndBits) - 1 class Position(val coords: Long) extends AnyVal { - def isRange = coords < 0 - def point: Int = if (isRange) start else coords.toInt - def start: Int = coords.abs.toInt - def end: Int = (if (isRange) coords.abs >>> Shift else coords).toInt + def point: Int = start + (coords >>> (StartEndBits * 2)).toInt + def start: Int = (coords & StartEndMask).toInt + def end: Int = ((coords >>> StartEndBits) & StartEndMask).toInt + def union(that: Position) = + if (this == NoPosition) that + else if (that == NoPosition) this + else Position(this.start min that.start, this.end max that.end) } - class Offset(val value: Int) extends AnyVal { - def toPosition = new Position(value.toLong & 0xffff) - } - - def rangePos(start: Int, end: Int) = - new Position(-(start + (end.toLong << Shift))) + def Position(start: Int, end: Int, pointOffset: Int = 0): Position = + new Position( + (start & StartEndMask).toLong | + ((end & StartEndMask).toLong << StartEndBits) | + (pointOffset.toLong << (StartEndBits * 2))) - def offsetPos(point: Int) = - new Position(point.toLong) + def Position(point: Int): Position = Position(point, point, 0) val NoPosition = new Position(-1L) - val NoOffset = new Offset(-1) + + /** The coordinate of a symbol. This is either an index or + * a point position. + */ + class Coord(val encoding: Int) extends AnyVal { + def isIndex = encoding > 0 + def isPosition = encoding <= 0 + def toIndex: Int = { + assert(isIndex) + encoding - 1 + } + def toPosition = { + assert(isPosition) + if (this == NoCoord) NoPosition else Position(1 - encoding) + } + } + + def indexCoord(n: Int) = new Coord(n + 1) + def positionCoord(n: Int) = new Coord(-(n + 1)) + + val NoCoord = new Coord(0) }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index 815e1bbaa..cd644df4e 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -19,25 +19,25 @@ import io.AbstractFile /** Creation methods for symbols */ trait Symbols { this: Context => - def newLazySymbol[N <: Name](owner: Symbol, name: N, initFlags: FlagSet, completer: SymCompleter, off: Offset = NoOffset) = - new Symbol(off, new LazySymDenotation(_, owner, name, initFlags, completer)) { + def newLazySymbol[N <: Name](owner: Symbol, name: N, initFlags: FlagSet, completer: SymCompleter, coord: Coord = NoCoord) = + new Symbol(coord, new LazySymDenotation(_, owner, name, initFlags, completer)) { type ThisName = N } - def newLazyClassSymbol(owner: Symbol, name: TypeName, initFlags: FlagSet, completer: ClassCompleter, assocFile: AbstractFile = null, off: Offset = NoOffset) = - new ClassSymbol(off, new LazyClassDenotation(_, owner, name, initFlags, completer, assocFile)(this)) + def newLazyClassSymbol(owner: Symbol, name: TypeName, initFlags: FlagSet, completer: ClassCompleter, assocFile: AbstractFile = null, coord: Coord = NoCoord) = + new ClassSymbol(coord, new LazyClassDenotation(_, owner, name, initFlags, completer, assocFile)(this)) def newLazyModuleSymbols(owner: Symbol, name: TermName, flags: FlagSet, completer: ClassCompleter, assocFile: AbstractFile = null, - off: Offset = NoOffset): (TermSymbol, ClassSymbol) + coord: Coord = NoCoord): (TermSymbol, ClassSymbol) = { val module = newLazySymbol( - owner, name, flags | ModuleCreationFlags, new ModuleCompleter(condensed), off) + owner, name, flags | ModuleCreationFlags, new ModuleCompleter(condensed), coord) val modcls = newLazyClassSymbol( - owner, name.toTypeName, flags | ModuleClassCreationFlags, completer, assocFile, off) + owner, name.toTypeName, flags | ModuleClassCreationFlags, completer, assocFile, coord) module.denot.asInstanceOf[LazySymDenotation].info = TypeRef(owner.thisType(ctx), modcls) modcls.denot.asInstanceOf[LazyClassDenotation].selfType = @@ -48,8 +48,8 @@ trait Symbols { this: Context => def newLazyPackageSymbols(owner: Symbol, name: TermName, completer: ClassCompleter) = newLazyModuleSymbols(owner, name, PackageCreationFlags, completer) - def newSymbol[N <: Name](owner: Symbol, name: N, flags: FlagSet, info: Type, privateWithin: Symbol = NoSymbol, off: Offset = NoOffset) = - new Symbol(off, CompleteSymDenotation(_, owner, name, flags, info, privateWithin)) { + def newSymbol[N <: Name](owner: Symbol, name: N, flags: FlagSet, info: Type, privateWithin: Symbol = NoSymbol, coord: Coord = NoCoord) = + new Symbol(coord, CompleteSymDenotation(_, owner, name, flags, info, privateWithin)) { type ThisName = N } @@ -62,9 +62,9 @@ trait Symbols { this: Context => optSelfType: Type = NoType, decls: Scope = newScope, assocFile: AbstractFile = null, - off: Offset = NoOffset) + coord: Coord = NoCoord) = - new ClassSymbol(off, new CompleteClassDenotation( + new ClassSymbol(coord, new CompleteClassDenotation( _, owner, name, flags, parents, privateWithin, optSelfType, decls, assocFile)(this)) def newModuleSymbols( @@ -76,15 +76,15 @@ trait Symbols { this: Context => privateWithin: Symbol = NoSymbol, decls: Scope = newScope, assocFile: AbstractFile = null, - off: Offset = NoOffset): (TermSymbol, ClassSymbol) + coord: Coord = NoCoord): (TermSymbol, ClassSymbol) = { val module = newLazySymbol( owner, name, flags | ModuleCreationFlags, - new ModuleCompleter(condensed), off) + new ModuleCompleter(condensed), coord) val modcls = newClassSymbol( owner, name.toTypeName, classFlags | ModuleClassCreationFlags, parents, privateWithin, optSelfType = TermRef(owner.thisType, module), - decls, assocFile, off) + decls, assocFile, coord) module.denot.asInstanceOf[LazySymDenotation].info = TypeRef(owner.thisType, modcls) (module, modcls) @@ -105,11 +105,11 @@ trait Symbols { this: Context => } } - def newLocalDummy(cls: Symbol, off: Offset = NoOffset) = + def newLocalDummy(cls: Symbol, coord: Coord = NoCoord) = newSymbol(cls, nme.localDummyName(cls), EmptyFlags, NoType) - def newImportSymbol(expr: TypedTree, off: Offset = NoOffset) = - newSymbol(NoSymbol, nme.IMPORT, EmptyFlags, ImportType(expr), off = off) + def newImportSymbol(expr: TypedTree, coord: Coord = NoCoord) = + newSymbol(NoSymbol, nme.IMPORT, EmptyFlags, ImportType(expr), coord = coord) def requiredPackage(path: PreName): TermSymbol = base.staticRef(path.toTermName).requiredSymbol(_.isPackage).asTerm @@ -125,7 +125,7 @@ object Symbols { /** A Symbol represents a Scala definition/declaration or a package. */ - class Symbol(val offset: Offset, denotf: Symbol => SymDenotation) extends DotClass { + class Symbol(val coord: Coord, denotf: Symbol => SymDenotation) extends DotClass { type ThisName <: Name @@ -197,7 +197,7 @@ object Symbols { type TermSymbol = Symbol { type ThisName = TermName } type TypeSymbol = Symbol { type ThisName = TypeName } - class ClassSymbol(off: Offset, denotf: ClassSymbol => ClassDenotation) extends Symbol(off, s => denotf(s.asClass)) { + class ClassSymbol(coord: Coord, denotf: ClassSymbol => ClassDenotation) extends Symbol(coord, s => denotf(s.asClass)) { type ThisName = TypeName @@ -227,11 +227,11 @@ object Symbols { } } - class ErrorSymbol(val underlying: Symbol, msg: => String)(implicit ctx: Context) extends Symbol(NoOffset, sym => underlying.denot) { + class ErrorSymbol(val underlying: Symbol, msg: => String)(implicit ctx: Context) extends Symbol(NoCoord, sym => underlying.denot) { type ThisName = underlying.ThisName } - object NoSymbol extends Symbol(NoOffset, sym => NoDenotation) { + object NoSymbol extends Symbol(NoCoord, sym => NoDenotation) { override def exists = false } @@ -243,12 +243,12 @@ object Symbols { flags: FlagSet = sym.flags, privateWithin: Symbol = sym.privateWithin, info: Type = sym.info, - off: Offset = sym.offset): Symbol = + coord: Coord = sym.coord): Symbol = if (sym.isClass) { assert(info eq sym.info) - new ClassCopier(sym.asClass).copy(owner, name.asTypeName, flags, privateWithin = privateWithin, off = off) + new ClassCopier(sym.asClass).copy(owner, name.asTypeName, flags, privateWithin = privateWithin, coord = coord) } else - ctx.newSymbol(owner, name, flags, info, privateWithin, sym.offset) + ctx.newSymbol(owner, name, flags, info, privateWithin, sym.coord) } implicit class ClassCopier(cls: ClassSymbol)(implicit ctx: Context) { @@ -262,8 +262,8 @@ object Symbols { selfType: Type = cls.selfType, decls: Scope = cls.decls, associatedFile: AbstractFile = cls.associatedFile, - off: Offset = cls.offset) = - ctx.newClassSymbol(owner, name, flags, parents, privateWithin, selfType, decls, associatedFile, off) + coord: Coord = cls.coord) = + ctx.newClassSymbol(owner, name, flags, parents, privateWithin, selfType, decls, associatedFile, coord) } implicit def defn(implicit ctx: Context): Definitions = ctx.definitions diff --git a/src/dotty/tools/dotc/core/Trees.scala b/src/dotty/tools/dotc/core/Trees.scala index 25226c660..1245119f2 100644 --- a/src/dotty/tools/dotc/core/Trees.scala +++ b/src/dotty/tools/dotc/core/Trees.scala @@ -2,6 +2,7 @@ package dotty.tools.dotc.core import Types._, Names._, Flags._, Positions._, Contexts._, Constants._, SymDenotations._, Symbols._ import Denotations._, StdNames._ +import annotation.tailrec object Trees { @@ -30,17 +31,29 @@ object Trees { * nodes. */ abstract class Tree[T] extends DotClass { + + /** The tree's position. Except + * for Shared nodes, it is always ensured that a tree's position + * contains the positions of all its subtrees. + */ def pos: Position + /** The typeconstructor at the root of the tree */ type ThisTree[T] <: Tree[T] protected var _tpe: T = _ + /** The type of the tree. In case of an untyped tree, + * an UnAssignedTypeException is thrown. + */ def tpe: T = { if (_tpe == null) throw new UnAssignedTypeException(this) _tpe } + /** Return a typed tree that's isomorphic to this tree, but has given + * type. + */ def withType(tpe: Type): ThisTree[Type] = { val tree = (if (_tpe == null || @@ -50,12 +63,22 @@ object Trees { tree.asInstanceOf[ThisTree[Type]] } + /** The denotation referred to by this tree, NoDenotation where not applicable */ def denot(implicit ctx: Context): Denotation = NoDenotation + + /** The symbol defined by ot referred to by this tree, NoSymbol where not applicable */ def symbol(implicit ctx: Context): Symbol = NoSymbol + /** Does this tree represent a type? */ def isType: Boolean = false + + /** Does this tree represent a term? */ def isTerm: Boolean = false + + /** Does this tree represent a definition or declaration? */ def isDef: Boolean = false + + /** Is this tree either the empty tree or the empty ValDef? */ def isEmpty: Boolean = false } @@ -68,16 +91,16 @@ object Trees { // ------ Categories of trees ----------------------------------- - /** Tree is definitely a type. Note that some trees - * have isType = true without being TypTrees (e.g. Ident, AnnotatedTree) + /** Instances of this class are trees for which isType is definitely true. + * Note that some trees have isType = true without being TypTrees (e.g. Ident, AnnotatedTree) */ trait TypTree[T] extends Tree[T] { type ThisTree[T] <: TypTree[T] override def isType = true } - /** Tree is definitely a term. Note that some trees - * have isType = true without being TypTrees (e.g. Ident, AnnotatedTree) + /** Instances of this class are trees for which isTerm is definitely true. + * Note that some trees have isTerm = true without being TermTrees (e.g. Ident, AnnotatedTree) */ trait TermTree[T] extends Tree[T] { type ThisTree[T] <: TermTree[T] @@ -97,7 +120,7 @@ object Trees { } } - /** Tree's symbol/isType/isTerm properties come from a subtree identifier + /** Tree's symbol/isType/isTerm properties come from a subtree identified * by `forwardTo`. */ abstract class ProxyTree[T] extends Tree[T] { @@ -123,6 +146,7 @@ object Trees { override def isTerm = name.isTermName } + /** Tree represents a definition */ abstract class DefTree[T] extends NameTree[T] { type ThisTree[T] <: DefTree[T] override def isDef = true @@ -131,28 +155,32 @@ object Trees { // ----------- Tree case classes ------------------------------------ /** name */ - case class Ident[T] (name: Name)(implicit val pos: Position) + case class Ident[T] (name: Name)(implicit cpos: Position) extends RefTree[T] { type ThisTree[T] = Ident[T] + val pos = cpos def qualifier: Tree[T] = EmptyTree[T] } /** qualifier.name */ - case class Select[T](qualifier: Tree[T], name: Name)(implicit val pos: Position) + case class Select[T](qualifier: Tree[T], name: Name)(implicit cpos: Position) extends RefTree[T] { type ThisTree[T] = Select[T] + val pos = cpos union qualifier.pos } /** qual.this */ - case class This[T](qual: TypeName)(implicit val pos: Position) + case class This[T](qual: TypeName)(implicit cpos: Position) extends SymTree[T] with TermTree[T] { type ThisTree[T] = This[T] + val pos = cpos } /** C.super[mix], where qual = C.this */ - case class Super[T](qual: Tree[T], mix: TypeName)(implicit val pos: Position) + case class Super[T](qual: Tree[T], mix: TypeName)(implicit cpos: Position) extends ProxyTree[T] with TermTree[T] { type ThisTree[T] = Super[T] + val pos = cpos union qual.pos def forwardTo = qual } @@ -164,82 +192,95 @@ object Trees { } /** fun(args) */ - case class Apply[T](fun: Tree[T], args: List[Tree[T]])(implicit val pos: Position) + case class Apply[T](fun: Tree[T], args: List[Tree[T]])(implicit cpos: Position) extends GenericApply[T] { type ThisTree[T] = Apply[T] + val pos = unionPos(cpos union fun.pos, args) } /** fun[args] */ - case class TypeApply[T](fun: Tree[T], args: List[Tree[T]])(implicit val pos: Position) + case class TypeApply[T](fun: Tree[T], args: List[Tree[T]])(implicit cpos: Position) extends GenericApply[T] { type ThisTree[T] = TypeApply[T] + val pos = unionPos(cpos union fun.pos, args) } /** const */ - case class Literal[T](const: Constant)(implicit val pos: Position) + case class Literal[T](const: Constant)(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = Literal[T] + val pos = cpos } /** new tpt, but no constructor call */ - case class New[T](tpt: Tree[T])(implicit val pos: Position) + case class New[T](tpt: Tree[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = New[T] + val pos = cpos union tpt.pos } /** (left, right) */ - case class Pair[T](left: Tree[T], right: Tree[T])(implicit val pos: Position) + case class Pair[T](left: Tree[T], right: Tree[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = Pair[T] + val pos = cpos union left.pos union right.pos } /** expr : tpt */ - case class Typed[T](expr: Tree[T], tpt: Tree[T])(implicit val pos: Position) + case class Typed[T](expr: Tree[T], tpt: Tree[T])(implicit cpos: Position) extends ProxyTree[T] with TermTree[T] { type ThisTree[T] = Typed[T] + val pos = cpos union expr.pos union tpt.pos def forwardTo = expr } /** name = arg, in a parameter list */ - case class NamedArg[T](name: Name, arg: Tree[T])(implicit val pos: Position) + case class NamedArg[T](name: Name, arg: Tree[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = NamedArg[T] + val pos = cpos union arg.pos } /** name = arg, outside a parameter list */ - case class Assign[T](lhs: Tree[T], rhs: Tree[T])(implicit val pos: Position) + case class Assign[T](lhs: Tree[T], rhs: Tree[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = Assign[T] + val pos = cpos union lhs.pos union rhs.pos } /** (vparams) => body */ - case class Function[T](vparams: List[ValDef[T]], body: Tree[T])(implicit val pos: Position) + case class Function[T](vparams: List[ValDef[T]], body: Tree[T])(implicit cpos: Position) extends SymTree[T] with TermTree[T] { type ThisTree[T] = Function[T] + val pos = unionPos(cpos union body.pos, vparams) } /** { stats; expr } */ - case class Block[T](stats: List[Tree[T]], expr: Tree[T])(implicit val pos: Position) + case class Block[T](stats: List[Tree[T]], expr: Tree[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = Block[T] + val pos = unionPos(cpos union expr.pos, stats) } /** if cond then thenp else elsep */ - case class If[T](cond: Tree[T], thenp: Tree[T], elsep: Tree[T])(implicit val pos: Position) + case class If[T](cond: Tree[T], thenp: Tree[T], elsep: Tree[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = If[T] + val pos = cpos union cond.pos union thenp.pos union elsep.pos } /** selector match { cases } */ - case class Match[T](selector: Tree[T], cases: List[CaseDef[T]])(implicit val pos: Position) + case class Match[T](selector: Tree[T], cases: List[CaseDef[T]])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = Match[T] + val pos = unionPos(cpos union selector.pos, cases) } /** case pat if guard => body */ - case class CaseDef[T](pat: Tree[T], guard: Tree[T], body: Tree[T])(implicit val pos: Position) + case class CaseDef[T](pat: Tree[T], guard: Tree[T], body: Tree[T])(implicit cpos: Position) extends Tree[T] { type ThisTree[T] = CaseDef[T] + val pos = cpos union pat.pos union guard.pos union body.pos } /** return expr @@ -247,107 +288,124 @@ object Trees { * After program transformations this is not necessarily the enclosing method, because * closures can intervene. */ - case class Return[T](expr: Tree[T], from: Ident[T])(implicit val pos: Position) + case class Return[T](expr: Tree[T], from: Ident[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = Return[T] + val pos = cpos union expr.pos // from is synthetic, does not influence pos } /** try block catch { catches } */ - case class Try[T](block: Tree[T], catches: List[CaseDef[T]], finalizer: Tree[T])(implicit val pos: Position) + case class Try[T](block: Tree[T], catches: List[CaseDef[T]], finalizer: Tree[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = Try[T] + val pos = unionPos(cpos union block.pos union finalizer.pos, catches) } /** throw expr */ - case class Throw[T](expr: Tree[T])(implicit val pos: Position) + case class Throw[T](expr: Tree[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = Throw[T] + val pos = cpos union expr.pos } /** Array[elemtpt](elems) */ - case class ArrayValue[T](elemtpt: Tree[T], elems: List[Tree[T]])(implicit val pos: Position) + case class ArrayValue[T](elemtpt: Tree[T], elems: List[Tree[T]])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = ArrayValue[T] + val pos = unionPos(cpos union elemtpt.pos, elems) } /** A type tree that represents an existing or inferred type */ - case class TypeTree[T](original: Tree[T] = EmptyTree[T])(implicit val pos: Position) + case class TypeTree[T](original: Tree[T] = EmptyTree[T])(implicit cpos: Position) extends SymTree[T] with TypTree[T] { type ThisTree[T] = TypeTree[T] + val pos = cpos union original.pos } /** ref.type */ - case class SingletonTypeTree[T](ref: Tree[T])(implicit val pos: Position) + case class SingletonTypeTree[T](ref: Tree[T])(implicit cpos: Position) extends SymTree[T] with TypTree[T] { type ThisTree[T] = SingletonTypeTree[T] + val pos = cpos union ref.pos } /** qualifier # name */ - case class SelectFromTypeTree[T](qualifier: Tree[T], name: TypeName)(implicit val pos: Position) + case class SelectFromTypeTree[T](qualifier: Tree[T], name: TypeName)(implicit cpos: Position) extends RefTree[T] with TypTree[T] { type ThisTree[T] = SelectFromTypeTree[T] + val pos = cpos union qualifier.pos } /** left & right */ - case class AndTypeTree[T](left: Tree[T], right: Tree[T])(implicit val pos: Position) + case class AndTypeTree[T](left: Tree[T], right: Tree[T])(implicit cpos: Position) extends TypTree[T] { type ThisTree[T] = AndTypeTree[T] + val pos = cpos union left.pos union right.pos } /** left | right */ - case class OrTypeTree[T](left: Tree[T], right: Tree[T])(implicit val pos: Position) + case class OrTypeTree[T](left: Tree[T], right: Tree[T])(implicit cpos: Position) extends TypTree[T] { type ThisTree[T] = OrTypeTree[T] + val pos = cpos union left.pos union right.pos } /** tpt { refinements } */ - case class RefineTypeTree[T](tpt: Tree[T], refinements: List[DefTree[T]])(implicit val pos: Position) + case class RefineTypeTree[T](tpt: Tree[T], refinements: List[DefTree[T]])(implicit cpos: Position) extends ProxyTree[T] with TypTree[T] { type ThisTree[T] = RefineTypeTree[T] + val pos = unionPos(cpos union tpt.pos, refinements) def forwardTo = tpt } /** tpt[args] */ - case class AppliedTypeTree[T](tpt: Tree[T], args: List[Tree[T]])(implicit val pos: Position) + case class AppliedTypeTree[T](tpt: Tree[T], args: List[Tree[T]])(implicit cpos: Position) extends ProxyTree[T] with TypTree[T] { type ThisTree[T] = AppliedTypeTree[T] + val pos = unionPos(cpos union tpt.pos, args) def forwardTo = tpt } /** >: lo <: hi */ - case class TypeBoundsTree[T](lo: Tree[T], hi: Tree[T])(implicit val pos: Position) + case class TypeBoundsTree[T](lo: Tree[T], hi: Tree[T])(implicit cpos: Position) extends Tree[T] { type ThisTree[T] = TypeBoundsTree[T] + val pos = cpos union lo.pos union hi.pos } /** name @ body */ - case class Bind[T](name: Name, body: Tree[T])(implicit val pos: Position) + case class Bind[T](name: Name, body: Tree[T])(implicit cpos: Position) extends DefTree[T] { type ThisTree[T] = Bind[T] + val pos = cpos union body.pos } /** tree_1 | ... | tree_n */ - case class Alternative[T](trees: List[Tree[T]])(implicit val pos: Position) + case class Alternative[T](trees: List[Tree[T]])(implicit cpos: Position) extends Tree[T] { type ThisTree[T] = Alternative[T] + val pos = unionPos(cpos, trees) } /** fun(args) in a pattern, if fun is an extractor */ - case class UnApply[T](fun: Tree[T], args: List[Tree[T]])(implicit val pos: Position) + case class UnApply[T](fun: Tree[T], args: List[Tree[T]])(implicit cpos: Position) extends Tree[T] { type ThisTree[T] = UnApply[T] + val pos = unionPos(cpos union fun.pos, args) } /** mods val name: tpt = rhs */ - case class ValDef[T](mods: Modifiers[T], name: Name, tpt: Tree[T], rhs: Tree[T])(implicit val pos: Position) + case class ValDef[T](mods: Modifiers[T], name: Name, tpt: Tree[T], rhs: Tree[T])(implicit cpos: Position) extends DefTree[T] { type ThisTree[T] = 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](mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])(implicit val pos: Position) + case class DefDef[T](mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])(implicit cpos: Position) extends DefTree[T] { type ThisTree[T] = DefDef[T] + val pos = (unionPos(cpos union tpt.pos union rhs.pos, tparams) /: vparamss)(unionPos) } class ImplicitDefDef[T](mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T]) @@ -358,43 +416,49 @@ object Trees { /** mods type name = rhs or * mods type name >: lo <: hi, if rhs = TypeBoundsTree(lo, hi) */ - case class TypeDef[T](mods: Modifiers[T], name: Name, rhs: Tree[T])(implicit val pos: Position) + case class TypeDef[T](mods: Modifiers[T], name: Name, rhs: Tree[T])(implicit cpos: Position) extends DefTree[T] { type ThisTree[T] = TypeDef[T] + val pos = cpos union rhs.pos } /** extends parents { self => body } */ - case class Template[T](parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]])(implicit val pos: Position) + case class Template[T](parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]])(implicit cpos: Position) extends SymTree[T] { type ThisTree[T] = Template[T] + val pos = unionPos(unionPos(cpos union self.pos, parents), body) } /** mods class name[tparams] impl */ - case class ClassDef[T](mods: Modifiers[T], name: TypeName, tparams: List[TypeDef[T]], impl: Template[T])(implicit val pos: Position) + case class ClassDef[T](mods: Modifiers[T], name: TypeName, tparams: List[TypeDef[T]], impl: Template[T])(implicit cpos: Position) extends DefTree[T] { type ThisTree[T] = 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](expr: Tree[T], selectors: List[UntypedTree])(implicit val pos: Position) + case class Import[T](expr: Tree[T], selectors: List[UntypedTree])(implicit cpos: Position) extends SymTree[T] { type ThisTree[T] = Import[T] + val pos = unionPos(cpos union expr.pos, selectors) } /** package pid { stats } */ - case class PackageDef[T](pid: RefTree[T], stats: List[Tree[T]])(implicit val pos: Position) + case class PackageDef[T](pid: RefTree[T], stats: List[Tree[T]])(implicit cpos: Position) extends DefTree[T] { type ThisTree[T] = PackageDef[T] + val pos = unionPos(cpos union pid.pos, stats) override def name = pid.name } /** arg @annot */ - case class Annotated[T](annot: Tree[T], arg: Tree[T])(implicit val pos: Position) + case class Annotated[T](annot: Tree[T], arg: Tree[T])(implicit cpos: Position) extends ProxyTree[T] { type ThisTree[T] = Annotated[T] + val pos = cpos union annot.pos union arg.pos def forwardTo = arg } @@ -426,20 +490,34 @@ object Trees { def apply[T]: EmptyValDef[T] = theEmptyValDef.asInstanceOf } -// ----- Tree cases that exist in untyped form only ------------------ + /** A tree that can be shared without its position polluting containing trees */ + case class Shared[T](tree: Tree[T]) extends Tree[T] { + type ThisTree[T] = Shared[T] + 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 { - def pos = tree.pos + class TypedSplice(tree: TypedTree) extends UntypedTree { + val pos = tree.pos } /** mods object name impl */ - case class ModuleDef(mods: Modifiers[Nothing], name: TermName, impl: Template[Nothing])(implicit val pos: Position) + case class ModuleDef(mods: Modifiers[Nothing], name: TermName, impl: Template[Nothing])(implicit cpos: Position) extends DefTree[Nothing] { + val pos = cpos union impl.pos } abstract class TreeAccumulator[T, U] extends ((T, Tree[U]) => T) { def apply(x: T, tree: Tree[U]): T def foldOver(x: T, tree: Tree[U]): T = ??? } + +// ----- Helper functions --------------------------------------------- + + @tailrec final def unionPos(base: Position, trees: List[Tree[_]]): Position = trees match { + case t :: ts => unionPos(base union t.pos, ts) + case nil => base + } }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/TypedTreeGen.scala b/src/dotty/tools/dotc/core/TypedTreeGen.scala index b081a6ba7..7672f1f77 100644 --- a/src/dotty/tools/dotc/core/TypedTreeGen.scala +++ b/src/dotty/tools/dotc/core/TypedTreeGen.scala @@ -9,6 +9,8 @@ object TypedTrees { class TypeTreeGen { implicit def pos(implicit ctx: Context): Position = ctx.position + def defPos(sym: Symbol)(implicit ctx: Context) = ctx.position union sym.coord.toPosition + def Modifiers(sym: Symbol)(implicit ctx: Context): Modifiers[Type] = Trees.Modifiers[Type]( sym.flags & ModifierFlags, if (sym.privateWithin.exists) sym.privateWithin.asType.name else tpnme.EMPTY, @@ -118,7 +120,7 @@ object TypedTrees { Trees.TypeBoundsTree(lo, hi).withType(TypeBounds(lo.tpe, hi.tpe)) def Bind(sym: Symbol, body: TypedTree)(implicit ctx: Context): Bind[Type] = - Trees.Bind(sym.name, body).withType(sym.info) + Trees.Bind(sym.name, body)(defPos(sym)).withType(sym.info) def Alternative(trees: List[TypedTree])(implicit ctx: Context): Alternative[Type] = Trees.Alternative(trees).withType(ctx.lub(trees map (_.tpe))) @@ -131,7 +133,7 @@ object TypedTrees { def refType(sym: Symbol)(implicit ctx: Context) = NamedType(sym.owner.thisType, sym) def ValDef(sym: TermSymbol, rhs: TypedTree = EmptyTree)(implicit ctx: Context): ValDef[Type] = - Trees.ValDef(Modifiers(sym), sym.name, TypeTree(sym.info), rhs) + Trees.ValDef(Modifiers(sym), sym.name, TypeTree(sym.info), rhs)(defPos(sym)) .withType(refType(sym)) def DefDef(sym: TermSymbol, rhs: TypedTree = EmptyTree)(implicit ctx: Context): DefDef[Type] = { @@ -165,12 +167,12 @@ object TypedTrees { Trees.DefDef( Modifiers(sym), sym.name, tparams map TypeDef, - vparamss map (_ map (ValDef(_))), TypeTree(rtp), rhs) + vparamss map (_ map (ValDef(_))), TypeTree(rtp), rhs)(defPos(sym)) .withType(refType(sym)) } def TypeDef(sym: TypeSymbol)(implicit ctx: Context): TypeDef[Type] = - Trees.TypeDef(Modifiers(sym), sym.name, TypeTree(sym.info)) + Trees.TypeDef(Modifiers(sym), sym.name, TypeTree(sym.info))(defPos(sym)) .withType(refType(sym)) def ClassDef(cls: ClassSymbol, typeParams: List[TypeSymbol], body: List[TypedTree])(implicit ctx: Context): ClassDef[Type] = { @@ -191,7 +193,7 @@ object TypedTrees { .orElse(ctx.newLocalDummy(cls)) val impl = Trees.Template(parents, selfType, rest) .withType(refType(localDummy)) - Trees.ClassDef(Modifiers(cls), cls.name, tparams, impl) + Trees.ClassDef(Modifiers(cls), cls.name, tparams, impl)(defPos(cls)) .withType(refType(cls)) } diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala index 9ba2c46e5..9955d8b56 100644 --- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala +++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala @@ -148,7 +148,7 @@ class ClassfileParser( } def parseMember(method: Boolean): Unit = { - val start = new Offset(in.bp) + val start = indexCoord(in.bp) val jflags = in.nextChar val sflags = if (method) FlagTranslation.methodFlags(jflags) @@ -162,7 +162,7 @@ class ClassfileParser( def complete(denot: LazySymDenotation) = { val oldbp = in.bp try { - in.bp = denot.symbol.offset.value + in.bp = denot.symbol.coord.toIndex val sym = denot.symbol val jflags = in.nextChar val isEnum = (jflags & JAVA_ACC_ENUM) != 0 @@ -335,7 +335,7 @@ class ClassfileParser( while (sig(index) != '>') { val tpname = subName(':'.==).toTypeName val s = cctx.newLazySymbol( - owner, tpname, Flags.TypeParam, new TypeParamCompleter(index), new Offset(index)) + owner, tpname, Flags.TypeParam, new TypeParamCompleter(index), indexCoord(index)) tparams = tparams + (tpname -> s) sig2typeBounds(tparams, skiptvs = true) newTParams += s diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala index 3d8be89b9..e3d08b304 100644 --- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala @@ -68,7 +68,6 @@ object UnPickler { /** Unpickle symbol table information descending from a class and/or module root * from an array of bytes. * @param bytes bytearray from which we unpickle - * @param offset offset from which unpickling starts * @param classroot the top-level class which is unpickled, or NoSymbol if inapplicable * @param moduleroot the top-level module class which is unpickled, or NoSymbol if inapplicable * @param filename filename associated with bytearray, only used for error messages @@ -274,7 +273,7 @@ class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot: /** Read a symbol, with possible disambiguation */ protected def readDisambiguatedSymbol(p: Symbol => Boolean)(): Symbol = { - val start = new Offset(readIndex) + val start = indexCoord(readIndex) val tag = readByte() val end = readNat() + readIndex def atEnd = readIndex == end @@ -349,7 +348,7 @@ class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot: def isModuleRoot = (name.toTermName == moduleRoot.name.toTermName) && (owner == moduleRoot.owner) def completeRoot(denot: LazyClassDenotation): Symbol = { - atReadPos(start.value, () => completeLocal(denot)) + atReadPos(start.toIndex, () => completeLocal(denot)) denot.symbol } @@ -370,16 +369,16 @@ class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot: name1 = name1.expandedName(owner) flags1 |= TypeParamFlags } - cctx.newLazySymbol(owner, name1, flags1, symUnpickler, off = start) + cctx.newLazySymbol(owner, name1, flags1, symUnpickler, coord = start) case CLASSsym => if (isClassRoot) completeRoot(classRoot) else if (isModuleRoot) completeRoot(moduleRoot) - else cctx.newLazyClassSymbol(owner, name.asTypeName, flags, classUnpickler, off = start) + else cctx.newLazyClassSymbol(owner, name.asTypeName, flags, classUnpickler, coord = start) case MODULEsym | VALsym => if (isModuleRoot) { moduleRoot.flags = flags moduleRoot.symbol - } else cctx.newLazySymbol(owner, name.asTermName, flags, symUnpickler, off = start) + } else cctx.newLazySymbol(owner, name.asTermName, flags, symUnpickler, coord = start) case _ => errorBadSignature("bad symbol tag: " + tag) }) @@ -420,7 +419,7 @@ class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot: assignClassFields(denot, tp, selfType) } } - atReadPos(denot.symbol.offset.value, parseToCompletion) + atReadPos(denot.symbol.coord.toIndex, parseToCompletion) } private object symUnpickler extends SymCompleter { |