diff options
author | Martin Odersky <odersky@gmail.com> | 2013-02-19 16:24:16 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-02-19 16:24:16 +0100 |
commit | 2c864fae1dd861392368de5be8488ea6842de72e (patch) | |
tree | be6ca9b7d376889ca981c092c924c0459063e8f7 | |
parent | 5c9433161e116704730693254fdaf161c69cbcb5 (diff) | |
parent | 51f7cf3cc33fc357881c0e413eb55b9253e2c22d (diff) | |
download | dotty-2c864fae1dd861392368de5be8488ea6842de72e.tar.gz dotty-2c864fae1dd861392368de5be8488ea6842de72e.tar.bz2 dotty-2c864fae1dd861392368de5be8488ea6842de72e.zip |
Merge branch 'simplified-completers'
-rw-r--r-- | src/dotty/tools/dotc/core/Annotations.scala | 34 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/PluggableTransformers.scala | 102 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 67 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymbolLoaders.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 55 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Trees.scala | 405 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypedTreeGen.scala | 236 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypedTrees.scala | 293 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/ClassfileParser.scala | 98 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/UnPickler.scala | 37 |
10 files changed, 927 insertions, 402 deletions
diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala index 9cbf5c8e4..c91d0c409 100644 --- a/src/dotty/tools/dotc/core/Annotations.scala +++ b/src/dotty/tools/dotc/core/Annotations.scala @@ -1,53 +1,53 @@ package dotty.tools.dotc.core -import Symbols._, Trees._, Types._, Positions._, Contexts._, Constants._, TypedTrees._ +import Symbols._, Types._, Positions._, Contexts._, Constants._, TypedTrees._ object Annotations { abstract class Annotation { - def tree: TypedTree + def tree: Tree def symbol(implicit ctx: Context): Symbol = tree.tpe.typeSymbol def matches(cls: Symbol)(implicit ctx: Context): Boolean = symbol.isNonBottomSubClass(cls) def appliesToModule: Boolean = ??? } - case class ConcreteAnnotation(val tree: TypedTree) extends Annotation + case class ConcreteAnnotation(val tree: Tree) extends Annotation object Annotation { - def apply(tree: TypedTree) = ConcreteAnnotation(tree) + def apply(tree: Tree) = ConcreteAnnotation(tree) - def apply(cls: ClassSymbol, arg: TypedTree)(implicit ctx: Context): Annotation = + def apply(cls: ClassSymbol, arg: Tree)(implicit ctx: Context): Annotation = apply(cls, arg :: Nil) - def apply(cls: ClassSymbol, arg1: TypedTree, arg2: TypedTree)(implicit ctx: Context): Annotation = + def apply(cls: ClassSymbol, arg1: Tree, arg2: Tree)(implicit ctx: Context): Annotation = apply(cls, arg1 :: arg2 :: Nil) - def apply(cls: ClassSymbol, args: List[TypedTree])(implicit ctx: Context): Annotation = + def apply(cls: ClassSymbol, args: List[Tree])(implicit ctx: Context): Annotation = apply(cls.typeConstructor, args) - def apply(atp: Type, arg: TypedTree)(implicit ctx: Context): Annotation = + def apply(atp: Type, arg: Tree)(implicit ctx: Context): Annotation = apply(atp, arg :: Nil) - def apply(atp: Type, arg1: TypedTree, arg2: TypedTree)(implicit ctx: Context): Annotation = + def apply(atp: Type, arg1: Tree, arg2: Tree)(implicit ctx: Context): Annotation = apply(atp, arg1 :: arg2 :: Nil) - def apply(atp: Type, args: List[TypedTree])(implicit ctx: Context): Annotation = - apply(tpd.New(atp, args)) + def apply(atp: Type, args: List[Tree])(implicit ctx: Context): Annotation = + apply(New(atp, args)) def makeAlias(sym: TermSymbol)(implicit ctx: Context) = - apply(defn.AliasAnnot, List(tpd.Ident(TermRef(sym.owner.thisType, sym.name, sym.signature)))) + apply(defn.AliasAnnot, List(Ident(TermRef(sym.owner.thisType, sym.name, sym.signature)))) def makeChild(sym: Symbol)(implicit ctx: Context) = - apply(defn.ChildAnnot, List(tpd.Ident(NamedType(sym.owner.thisType, sym.name)))) + apply(defn.ChildAnnot, List(Ident(NamedType(sym.owner.thisType, sym.name)))) } - def makeLiteralAnnotArg(const: Constant): TypedTree = ??? + def makeLiteralAnnotArg(const: Constant): Tree = ??? - def makeArrayAnnotArg(elems: Array[TypedTree]): TypedTree = ??? + def makeArrayAnnotArg(elems: Array[Tree]): Tree = ??? - def makeNestedAnnotArg(annot: Annotation): TypedTree = annot.tree + def makeNestedAnnotArg(annot: Annotation): Tree = annot.tree def ThrowsAnnotation(cls: ClassSymbol)(implicit ctx: Context) = - Annotation(defn.ThrowsAnnot, tpd.Ident(TypeRef(cls.owner.thisType, cls.name))) + Annotation(defn.ThrowsAnnot, Ident(TypeRef(cls.owner.thisType, cls.name))) }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/PluggableTransformers.scala b/src/dotty/tools/dotc/core/PluggableTransformers.scala new file mode 100644 index 000000000..b0b2ca134 --- /dev/null +++ b/src/dotty/tools/dotc/core/PluggableTransformers.scala @@ -0,0 +1,102 @@ +package dotty.tools.dotc +package core + + +object PluggableTransformers { + + import Trees._, Contexts._ + + abstract class PluggableTransformer[T] extends TreeTransformer[T, Context] { + type PluginOp[-N <: Tree[T]] = N => Tree[T] + + private[this] var _ctx: Context = _ + private[this] var _oldTree: Tree[T] = _ + + protected implicit def ctx: Context = _ctx + protected def oldTree: Tree[T] = _oldTree + protected def thisTransformer: PluggableTransformer[T] = this + + class PluginOps[-N <: Tree[T]](op: PluginOp[N], val next: Plugins) { + def apply(tree: N, old: Tree[T], c: Context): Tree[T] = { + val savedCtx = _ctx + val savedOld = _oldTree + try { + op(tree) + } finally { + _oldTree = savedOld + _ctx = savedCtx + } + } + } + + val NoOp: PluginOp[Tree[T]] = identity + val NoOps = new PluginOps(NoOp, null) + + class Plugins { + def next: Plugins = null + + def processIdent: PluginOp[Ident[T]] = NoOp + def processSelect: PluginOp[Select[T]] = NoOp + + val IdentOps: PluginOps[Ident[T]] = NoOps + val SelectOps: PluginOps[Select[T]] = NoOps + } + + val EmptyPlugin = new Plugins + + private[this] var _plugins: Plugins = EmptyPlugin + + override def plugins: Plugins = _plugins + + class Plugin extends Plugins { + override val next = _plugins + _plugins = this + + private def push[N <: Tree[T]](op: PluginOp[N], ops: => PluginOps[N]): PluginOps[N] = + if (op == NoOp) ops else new PluginOps(op, next) + + override val IdentOps: PluginOps[Ident[T]] = push(processIdent, next.IdentOps) + override val SelectOps: PluginOps[Select[T]] = push(processSelect, next.SelectOps) + } + + def postIdent(tree: Ident[T], old: Tree[T], c: Context, ops: PluginOps[Ident[T]]) = + if (ops eq NoOps) tree + else finishIdent(ops(tree, old, c), old, c, ops.next) + + override def finishIdent(tree: Tree[T], old: Tree[T], c: Context, plugins: Plugins): Tree[T] = tree match { + case tree: Ident[_] => postIdent(tree, old, c, plugins.IdentOps) + case _ => postProcess(tree, old, c, plugins) + } + + def postSelect(tree: Select[T], old: Tree[T], c: Context, ops: PluginOps[Select[T]]) = + if (ops eq NoOps) tree + else finishSelect(ops(tree, old, c), old, c, ops.next) + + override def finishSelect(tree: Tree[T], old: Tree[T], c: Context, plugins: Plugins): Tree[T] = tree match { + case tree: Select[_] => postSelect(tree, old, c, plugins.SelectOps) + case _ => postProcess(tree, old, c, plugins) + } + + protected def postProcess(tree: Tree[T], old: Tree[T], c: Context, plugins: Plugins): Tree[T] = tree match { + case tree: Ident[_] => finishIdent(tree, old, c, plugins) + case tree: Select[_] => finishSelect(tree, old, c, plugins) + } + } +} + +import PluggableTransformers._, Types._, TypedTrees._ + +class ExampleTransformer extends PluggableTransformer[Type] { + + class ExamplePlugin extends Plugin { + override def processIdent = { + case tree @ Ident(x) if x.isTypeName => tree.derivedSelect(tree, x) + case tree => tree + } + override def processSelect = { tree => + if (tree.isType) tree.derivedIdent(tree.name) + else EmptyTree + } + } + +}
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 79f2b7817..73d14141c 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -75,7 +75,7 @@ object SymDenotations { private[this] var _flags: FlagSet = initFlags /** The flag set */ - def flags: FlagSet = { ensureLoaded(); _flags } + def flags: FlagSet = { ensureCompleted(); _flags } /** Update the flag set */ private[core] def flags_=(flags: FlagSet): Unit = { _flags = flags } @@ -109,23 +109,14 @@ object SymDenotations { // ----- completion ------------------------------ - // The following 4 members are overridden by instances of isLazy - - /** The denotation is loaded: flags and privateWithin are fully defined. */ - def isLoaded = true + // The following 2 members are overridden by instances of isLazy /** The denotation is completed: all attributes are fully defined */ def isCompleted = true - /** Try to load denotation. May throw `CyclicReference`. */ - protected[core] def tryLoad(): Unit = unsupported("tryLoad") - /** Try to complete denotation. May throw `CyclicReference`. */ protected[core] def tryComplete(): Unit = unsupported("tryComplete") - /** Make sure denotation is loaded */ - final def ensureLoaded() = if (!isLoaded) tryLoad() - /** Make sure denotation is completed */ final def ensureCompleted() = if (!isCompleted) tryComplete() @@ -544,14 +535,13 @@ object SymDenotations { private[this] var _typeParams: List[TypeSymbol] = _ - /** The type parameters of this class. Loads the class but does not complete it. */ + /** The type parameters of this class */ override final def typeParams(implicit ctx: Context): List[TypeSymbol] = { val tparams = _typeParams if (tparams != null) tparams else computeTypeParams } - /** The symbols defined in this class when the class is loaded but - * not yet completed. + /** The symbols defined in this class when the class is not yet completed. */ protected def preCompleteDecls: Scope @@ -892,8 +882,8 @@ object SymDenotations { final def parents: List[TypeRef] = { if (_parents == null) tryComplete(); _parents } def selfType: Type = { if (_selfType == null) tryComplete(); _selfType } - final def preCompleteDecls = { if (_decls == null) tryLoad(); _decls } - final def decls: Scope = { if (_parents == null) tryComplete(); _decls } + final def preCompleteDecls = { if (_decls == null) tryComplete(); _decls } + final def decls: Scope = { ensureCompleted(); _decls } // cannot check on decls because decls might be != null even if class is not completed final override def exists(implicit ctx: Context) = { ensureCompleted(); _parents != null } @@ -922,66 +912,39 @@ object SymDenotations { protected def completer: Completer[Denot] protected def completer_= (c: Completer[Denot]) - override def isLoaded = _privateWithin != null override def isCompleted = completer == null - override protected[core] def tryLoad(): Unit = - try { - if (flags is Locked) throw new CyclicReference(symbol) - setFlag(Locked) - completer.load(this) - } finally { - flags &~= Locked - } - override protected[core] def tryComplete(): Unit = try { if (flags is Locked) throw new CyclicReference(symbol) setFlag(Locked) val c = completer + if (c == null) throw new CompletionError(this) completer = null // set completer to null to avoid space leaks // and to make any subsequent completion attempt a CompletionError - c.complete(this) - } catch { - case _: NullPointerException => throw new CompletionError(this) + c(this) } finally { flags &~= Locked } private[this] var _privateWithin: Symbol = _ - def privateWithin: Symbol = { if (_privateWithin == null) tryLoad(); _privateWithin } + def privateWithin: Symbol = { if (_privateWithin == null) tryComplete(); _privateWithin } protected[core] def privateWithin_=(sym: Symbol): Unit = { _privateWithin = sym } } - abstract class Completer[Denot <: SymDenotation] extends DotClass { - /** Load symbol, setting flags and privateWithin, and typeParams for classes - * By default same as complete but can be overridden - */ - def load(denot: Denot): Unit = complete(denot) - - /** Complete symbol, setting all its properties */ - def complete(denot: Denot): Unit - } - + /** When called, complete denotation, setting all its properties */ + type Completer[Denot <: SymDenotation] = Denot => Unit type SymCompleter = Completer[LazySymDenotation] type ClassCompleter = Completer[LazyClassDenotation] - class ModuleCompleter(cctx: CondensedContext) extends Completer[LazySymDenotation] { + class ModuleCompleter(cctx: CondensedContext) extends SymCompleter { implicit protected def ctx: Context = cctx - def classDenot(denot: LazySymDenotation) = - denot.moduleClass.denot.asInstanceOf[LazyClassDenotation] - def copyLoadedFields(denot: LazySymDenotation, from: LazyClassDenotation) = { + def apply(denot: LazySymDenotation): Unit = { + val from = denot.moduleClass.denot.asInstanceOf[LazyClassDenotation] denot.setFlag(from.flags.toTermFlags & RetainedModuleFlags) denot.privateWithin = from.privateWithin - } - def copyCompletedFields(denot: LazySymDenotation, from: LazyClassDenotation) = { - copyLoadedFields(denot, from) denot.annotations = from.annotations filter (_.appliesToModule) } - override def load(denot: LazySymDenotation): Unit = - copyLoadedFields(denot, classDenot(denot)) - def complete(denot: LazySymDenotation): Unit = - copyCompletedFields(denot, classDenot(denot)) } /** A completer for missing references */ @@ -996,7 +959,7 @@ object SymDenotations { denot.decls = EmptyScope } - def complete(denot: LazyClassDenotation): Unit = { + def apply(denot: LazyClassDenotation): Unit = { val sym = denot.symbol val file = denot.associatedFile val (location, src) = diff --git a/src/dotty/tools/dotc/core/SymbolLoaders.scala b/src/dotty/tools/dotc/core/SymbolLoaders.scala index 8a5dd70d2..2e37d8124 100644 --- a/src/dotty/tools/dotc/core/SymbolLoaders.scala +++ b/src/dotty/tools/dotc/core/SymbolLoaders.scala @@ -164,7 +164,7 @@ abstract class SymbolLoader extends ClassCompleter { */ protected def description: String - override def complete(root: LazyClassDenotation) = { + override def apply(root: LazyClassDenotation) = { def signalError(ex: Exception) { if (ctx.settings.debug.value) ex.printStackTrace() val msg = ex.getMessage() diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index cd644df4e..68579f15f 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -19,6 +19,8 @@ import io.AbstractFile /** Creation methods for symbols */ trait Symbols { this: Context => +// ---- Fundamental symbol creation methods ---------------------------------- + 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 @@ -45,9 +47,6 @@ trait Symbols { this: Context => (module, modcls) } - 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, coord: Coord = NoCoord) = new Symbol(coord, CompleteSymDenotation(_, owner, name, flags, info, privateWithin)) { type ThisName = N @@ -90,13 +89,6 @@ trait Symbols { this: Context => (module, modcls) } - def newPackageSymbols( - owner: Symbol, - name: TermName, - decls: Scope = newScope) = - newModuleSymbols( - owner, name, PackageCreationFlags, PackageCreationFlags, Nil, NoSymbol, decls) - def newStubSymbol(owner: Symbol, name: Name, file: AbstractFile = null): Symbol = { def stub = new StubCompleter(ctx.condensed) name match { @@ -105,12 +97,55 @@ trait Symbols { this: Context => } } +// ---- Derived symbol creation methods ------------------------------------- + + def newLazyPackageSymbols(owner: Symbol, name: TermName, completer: ClassCompleter) = + newLazyModuleSymbols(owner, name, PackageCreationFlags, completer) + + def newPackageSymbols( + owner: Symbol, + name: TermName, + decls: Scope = newScope) = + newModuleSymbols( + owner, name, PackageCreationFlags, PackageCreationFlags, Nil, NoSymbol, decls) + def newLocalDummy(cls: Symbol, coord: Coord = NoCoord) = newSymbol(cls, nme.localDummyName(cls), EmptyFlags, NoType) def newImportSymbol(expr: TypedTree, coord: Coord = NoCoord) = newSymbol(NoSymbol, nme.IMPORT, EmptyFlags, ImportType(expr), coord = coord) + def newConstructor(cls: ClassSymbol, flags: FlagSet, paramNames: List[TermName], paramTypes: List[Type], privateWithin: Symbol = NoSymbol, coord: Coord = NoCoord) = + newSymbol(cls, nme.CONSTRUCTOR, flags, MethodType(paramNames, paramTypes)(_ => cls.typeConstructor), privateWithin, coord) + + def newDefaultConstructor(cls: ClassSymbol) = + newConstructor(cls, EmptyFlags, Nil, Nil) + + def newSelfSym(cls: ClassSymbol) = + ctx.newSymbol(cls, nme.THIS, SyntheticArtifact, cls.selfType) + + /** Create new type parameters with given owner, names, and flags. + * @param boundsFn A function that, given type refs to the newly created + * parameters returns a list of their bounds. + */ + def newTypeParams( + owner: Symbol, + names: List[TypeName], + flags: FlagSet, + boundsFn: List[TypeRef] => List[Type]) = { + lazy val tparams: List[TypeSymbol] = names map { name => + newLazySymbol(owner, name, flags | TypeParam, { denot => + denot.info = bounds(denot.symbol.asType) + }) + } + lazy val bounds = (tparams zip boundsFn(tparams map (_.typeConstructor))).toMap + tparams + } + + private val reverseApply = (x: TypeSymbol, f: TypeSymbol => TypeBounds) => f(x) + +// ----- Locating predefined symbols ---------------------------------------- + def requiredPackage(path: PreName): TermSymbol = base.staticRef(path.toTermName).requiredSymbol(_.isPackage).asTerm diff --git a/src/dotty/tools/dotc/core/Trees.scala b/src/dotty/tools/dotc/core/Trees.scala index 1245119f2..7d48641ee 100644 --- a/src/dotty/tools/dotc/core/Trees.scala +++ b/src/dotty/tools/dotc/core/Trees.scala @@ -41,7 +41,7 @@ object Trees { /** The typeconstructor at the root of the tree */ type ThisTree[T] <: Tree[T] - protected var _tpe: T = _ + private var _tpe: T = _ /** The type of the tree. In case of an untyped tree, * an UnAssignedTypeException is thrown. @@ -51,6 +51,14 @@ object Trees { _tpe } + /** Copy `tpe` attribute from tree `from` into this tree, independently + * whether it is null or not. + */ + def copyAttr(from: Tree[T]): ThisTree[T] = { + _tpe = from._tpe + this.asInstanceOf[ThisTree[T]] + } + /** Return a typed tree that's isomorphic to this tree, but has given * type. */ @@ -58,7 +66,7 @@ object Trees { val tree = (if (_tpe == null || (_tpe.asInstanceOf[AnyRef] eq tpe.asInstanceOf[AnyRef])) this - else clone).asInstanceOf[TypedTree] + else clone).asInstanceOf[Tree[Type]] tree._tpe = tpe tree.asInstanceOf[ThisTree[Type]] } @@ -80,6 +88,9 @@ object Trees { /** Is this tree either the empty tree or the empty ValDef? */ def isEmpty: Boolean = false + + override def hashCode(): Int = System.identityHashCode(this) + override def equals(that: Any) = this eq that.asInstanceOf[AnyRef] } class UnAssignedTypeException[T](tree: Tree[T]) extends RuntimeException { @@ -368,7 +379,7 @@ object Trees { /** >: lo <: hi */ case class TypeBoundsTree[T](lo: Tree[T], hi: Tree[T])(implicit cpos: Position) - extends Tree[T] { + extends Tree[T] { type ThisTree[T] = TypeBoundsTree[T] val pos = cpos union lo.pos union hi.pos } @@ -490,8 +501,11 @@ object Trees { def apply[T]: EmptyValDef[T] = theEmptyValDef.asInstanceOf } - /** A tree that can be shared without its position polluting containing trees */ - case class Shared[T](tree: Tree[T]) extends Tree[T] { + /** A tree that can be shared without its position + * polluting containing trees. Accumulators and tranformers + * memoize results of shared subtrees + */ + case class Shared[T](shared: Tree[T]) extends Tree[T] { type ThisTree[T] = Shared[T] val pos = NoPosition } @@ -509,15 +523,382 @@ object Trees { 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 --------------------------------------------- +// ----- 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 nil => base } -}
\ No newline at end of file + + implicit class TreeCopier[T](val tree: Tree[T]) extends AnyVal { + implicit def cpos = tree.pos + def derivedIdent(name: Name): Ident[T] = tree match { + case tree: Ident[_] if (name == tree.name) => tree + case _ => Ident(name).copyAttr(tree) + } + def derivedSelect(qualifier: Tree[T], name: Name): Select[T] = tree match { + case tree: Select[_] if (qualifier eq tree.qualifier) && (name == tree.name) => tree + case _ => Select(qualifier, name).copyAttr(tree) + } + def derivedThis(qual: TypeName): This[T] = tree match { + case tree: This[_] if (qual == tree.qual) => tree + case _ => This(qual).copyAttr(tree) + } + def derivedSuper(qual: Tree[T], mix: TypeName): Super[T] = tree match { + case tree: Super[_] if (qual eq tree.qual) && (mix == tree.mix) => tree + case _ => Super(qual, mix).copyAttr(tree) + } + def derivedApply(fun: Tree[T], args: List[Tree[T]]): Apply[T] = tree match { + case tree: Apply[_] if (fun eq tree.fun) && (args eq tree.args) => tree + case _ => Apply(fun, args).copyAttr(tree) + } + def derivedTypeApply(fun: Tree[T], args: List[Tree[T]]): TypeApply[T] = tree match { + case tree: TypeApply[_] if (fun eq tree.fun) && (args eq tree.args) => tree + case _ => TypeApply(fun, args).copyAttr(tree) + } + def derivedLiteral(const: Constant): Literal[T] = tree match { + case tree: Literal[_] if (const == tree.const) => tree + case _ => Literal(const).copyAttr(tree) + } + def derivedNew(tpt: Tree[T]): New[T] = tree match { + case tree: New[_] if (tpt eq tree.tpt) => tree + case _ => New(tpt).copyAttr(tree) + } + def derivedPair(left: Tree[T], right: Tree[T]): Pair[T] = tree match { + case tree: Pair[_] if (left eq tree.left) && (right eq tree.right) => tree + case _ => Pair(left, right).copyAttr(tree) + } + def derivedTyped(expr: Tree[T], tpt: Tree[T]): Typed[T] = tree match { + case tree: Typed[_] if (expr eq tree.expr) && (tpt eq tree.tpt) => tree + case _ => Typed(expr, tpt).copyAttr(tree) + } + def derivedNamedArg(name: Name, arg: Tree[T]): NamedArg[T] = tree match { + case tree: NamedArg[_] if (name == tree.name) && (arg eq tree.arg) => tree + case _ => NamedArg(name, arg).copyAttr(tree) + } + def derivedAssign(lhs: Tree[T], rhs: Tree[T]): Assign[T] = tree match { + case tree: Assign[_] if (lhs eq tree.lhs) && (rhs eq tree.rhs) => tree + case _ => Assign(lhs, rhs).copyAttr(tree) + } + def derivedFunction(vparams: List[ValDef[T]], body: Tree[T]): Function[T] = tree match { + case tree: Function[_] if (vparams eq tree.vparams) && (body eq tree.body) => tree + case _ => Function(vparams, body).copyAttr(tree) + } + def derivedBlock(stats: List[Tree[T]], expr: Tree[T]): Block[T] = tree match { + case tree: Block[_] if (stats eq tree.stats) && (expr eq tree.expr) => tree + case _ => Block(stats, expr).copyAttr(tree) + } + def derivedIf(cond: Tree[T], thenp: Tree[T], elsep: Tree[T]): If[T] = tree match { + case tree: If[_] if (cond eq tree.cond) && (thenp eq tree.thenp) && (elsep eq tree.elsep) => tree + case _ => If(cond, thenp, elsep).copyAttr(tree) + } + def derivedMatch(selector: Tree[T], cases: List[CaseDef[T]]): Match[T] = tree match { + case tree: Match[_] if (selector eq tree.selector) && (cases eq tree.cases) => tree + case _ => Match(selector, cases).copyAttr(tree) + } + def derivedCaseDef(pat: Tree[T], guard: Tree[T], body: Tree[T]): CaseDef[T] = tree match { + 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 { + case tree: Return[_] if (expr eq tree.expr) && (from eq tree.from) => tree + case _ => Return(expr, from).copyAttr(tree) + } + def derivedTry(block: Tree[T], catches: List[CaseDef[T]], finalizer: Tree[T]): Try[T] = tree match { + case tree: Try[_] if (block eq tree.block) && (catches eq tree.catches) && (finalizer eq tree.finalizer) => tree + case _ => Try(block, catches, finalizer).copyAttr(tree) + } + def derivedThrow(expr: Tree[T]): Throw[T] = tree match { + case tree: Throw[_] if (expr eq tree.expr) => tree + case _ => Throw(expr).copyAttr(tree) + } + def derivedArrayValue(elemtpt: Tree[T], elems: List[Tree[T]]): ArrayValue[T] = tree match { + case tree: ArrayValue[_] if (elemtpt eq tree.elemtpt) && (elems eq tree.elems) => tree + case _ => ArrayValue(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) + } + def derivedSelectFromTypeTree(qualifier: Tree[T], name: TypeName): SelectFromTypeTree[T] = tree match { + case tree: SelectFromTypeTree[_] if (qualifier eq tree.qualifier) && (name == tree.name) => tree + case _ => SelectFromTypeTree(qualifier, name).copyAttr(tree) + } + def derivedAndTypeTree(left: Tree[T], right: Tree[T]): AndTypeTree[T] = tree match { + case tree: AndTypeTree[_] if (left eq tree.left) && (right eq tree.right) => tree + case _ => AndTypeTree(left, right).copyAttr(tree) + } + def derivedOrTypeTree(left: Tree[T], right: Tree[T]): OrTypeTree[T] = tree match { + 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 { + case tree: RefineTypeTree[_] if (tpt eq tree.tpt) && (refinements eq tree.refinements) => tree + case _ => RefineTypeTree(tpt, refinements).copyAttr(tree) + } + def derivedAppliedTypeTree(tpt: Tree[T], args: List[Tree[T]]): AppliedTypeTree[T] = tree match { + case tree: AppliedTypeTree[_] if (tpt eq tree.tpt) && (args eq tree.args) => tree + case _ => AppliedTypeTree(tpt, args).copyAttr(tree) + } + def derivedTypeBoundsTree(lo: Tree[T], hi: Tree[T]): TypeBoundsTree[T] = tree match { + case tree: TypeBoundsTree[_] if (lo eq tree.lo) && (hi eq tree.hi) => tree + case _ => TypeBoundsTree(lo, hi).copyAttr(tree) + } + def derivedBind(name: Name, body: Tree[T]): Bind[T] = tree match { + case tree: Bind[_] if (name eq tree.name) && (body eq tree.body) => tree + case _ => Bind(name, body).copyAttr(tree) + } + def derivedAlternative(trees: List[Tree[T]]): Alternative[T] = tree match { + case tree: Alternative[_] if (trees eq tree.trees) => tree + case _ => Alternative(trees).copyAttr(tree) + } + def derivedUnApply(fun: Tree[T], args: List[Tree[T]]): UnApply[T] = tree match { + case tree: UnApply[_] if (fun eq tree.fun) && (args eq tree.args) => tree + case _ => UnApply(fun, args).copyAttr(tree) + } + def derivedValDef(mods: Modifiers[T], name: Name, tpt: Tree[T], rhs: Tree[T]): ValDef[T] = tree match { + case tree: ValDef[_] if (mods == tree.mods) && (name == tree.name) && (tpt eq tree.tpt) && (rhs eq tree.rhs) => tree + case _ => ValDef(mods, name, tpt, rhs).copyAttr(tree) + } + def derivedDefDef(mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T]): DefDef[T] = tree match { + 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: Name, 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 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 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 + case _ => ClassDef(mods, name, tparams, impl).copyAttr(tree) + } + def derivedImport(expr: Tree[T], selectors: List[UntypedTree]): Import[T] = tree match { + case tree: Import[_] if (expr eq tree.expr) && (selectors eq tree.selectors) => tree + case _ => Import(expr, selectors).copyAttr(tree) + } + def derivedPackageDef(pid: RefTree[T], stats: List[Tree[T]]): PackageDef[T] = tree match { + case tree: PackageDef[_] if (pid eq tree.pid) && (stats eq tree.stats) => tree + case _ => PackageDef(pid, stats).copyAttr(tree) + } + def derivedAnnotated(annot: Tree[T], arg: Tree[T]): Annotated[T] = tree match { + case tree: Annotated[_] if (annot eq tree.annot) && (arg eq tree.arg) => tree + case _ => Annotated(annot, arg).copyAttr(tree) + } + def derivedShared(shared: Tree[T]): Shared[T] = tree match { + case tree: Shared[_] if (shared eq tree.shared) => tree + case _ => Shared(shared).copyAttr(tree) + } + } + + abstract class TreeTransformer[T, C] { + var sharedMemo: Map[Shared[T], Shared[T]] = Map() + type Plugins >: Null + def plugins: Plugins = null + def finishIdent(tree: Tree[T], old: Tree[T], c: C, plugins: Plugins) = tree + def finishSelect(tree: Tree[T], old: Tree[T], c: C, plugins: Plugins) = tree + def transform(tree: Tree[T], c: C): Tree[T] = tree match { + case Ident(name) => + finishIdent(tree, tree, c, plugins) + case Select(qualifier, name) => + finishSelect(tree.derivedSelect(transform(qualifier, c), name), tree, c, plugins) + case This(qual) => + tree + case Super(qual, mix) => + tree.derivedSuper(transform(qual, c), mix) + case Apply(fun, args) => + tree.derivedApply(transform(fun, c), transform(args, c)) + case TypeApply(fun, args) => + tree.derivedTypeApply(transform(fun, c), transform(args, c)) + case Literal(const) => + tree + case New(tpt) => + tree.derivedNew(transform(tpt, c)) + case Pair(left, right) => + tree.derivedPair(transform(left, c), transform(right, c)) + case Typed(expr, tpt) => + tree.derivedTyped(transform(expr, c), transform(tpt, c)) + case NamedArg(name, arg) => + tree.derivedNamedArg(name, transform(arg, c)) + case Assign(lhs, rhs) => + tree.derivedAssign(transform(lhs, c), transform(rhs, c)) + case Function(vparams, body) => + tree.derivedFunction(transformSub(vparams, c), transform(body, c)) + case Block(stats, expr) => + tree.derivedBlock(transform(stats, c), transform(expr, c)) + case If(cond, thenp, elsep) => + tree.derivedIf(transform(cond, c), transform(thenp, c), transform(elsep, c)) + case Match(selector, cases) => + tree.derivedMatch(transform(selector, c), transformSub(cases, c)) + case CaseDef(pat, guard, body) => + tree.derivedCaseDef(transform(pat, c), transform(guard, c), transform(body, c)) + case Return(expr, from) => + tree.derivedReturn(transform(expr, c), transformSub(from, c)) + case Try(block, catches, finalizer) => + tree.derivedTry(transform(block, c), transformSub(catches, c), transform(finalizer, c)) + case Throw(expr) => + tree.derivedThrow(transform(expr, c)) + case ArrayValue(elemtpt, elems) => + tree.derivedArrayValue(transform(elemtpt, c), transform(elems, c)) + case TypeTree(original) => + tree.derivedTypeTree(transform(original, c)) + case SingletonTypeTree(ref) => + tree.derivedSingletonTypeTree(transform(ref, c)) + case SelectFromTypeTree(qualifier, name) => + tree.derivedSelectFromTypeTree(transform(qualifier, c), name) + case AndTypeTree(left, right) => + tree.derivedAndTypeTree(transform(left, c), transform(right, c)) + case OrTypeTree(left, right) => + tree.derivedOrTypeTree(transform(left, c), transform(right, c)) + case RefineTypeTree(tpt, refinements) => + tree.derivedRefineTypeTree(transform(tpt, c), transformSub(refinements, c)) + case AppliedTypeTree(tpt, args) => + tree.derivedAppliedTypeTree(transform(tpt, c), transform(args, c)) + case TypeBoundsTree(lo, hi) => + tree.derivedTypeBoundsTree(transform(lo, c), transform(hi, c)) + case Bind(name, body) => + tree.derivedBind(name, transform(body, c)) + case Alternative(trees) => + tree.derivedAlternative(transform(trees, c)) + case UnApply(fun, args) => + tree.derivedUnApply(transform(fun, c), transform(args, c)) + case ValDef(mods, name, tpt, rhs) => + tree.derivedValDef(mods, name, transform(tpt, c), transform(rhs, c)) + case DefDef(mods, name, tparams, vparamss, tpt, rhs) => + tree.derivedDefDef(mods, name, transformSub(tparams, c), vparamss mapConserve (transformSub(_, c)), transform(tpt, c), transform(rhs, c)) + case TypeDef(mods, name, rhs) => + tree.derivedTypeDef(mods, name, transform(rhs, c)) + case Template(parents, self, body) => + tree.derivedTemplate(transform(parents, c), transformSub(self, c), transform(body, c)) + case ClassDef(mods, name, tparams, impl) => + tree.derivedClassDef(mods, name, transformSub(tparams, c), transformSub(impl, c)) + case Import(expr, selectors) => + tree.derivedImport(transform(expr, c), selectors) + case PackageDef(pid, stats) => + tree.derivedPackageDef(transformSub(pid, c), transform(stats, c)) + case Annotated(annot, arg) => + tree.derivedAnnotated(transform(annot, c), transform(arg, c)) + case EmptyTree() => + tree + case tree @ Shared(shared) => + sharedMemo get tree match { + case Some(tree1) => tree1 + case None => + val tree1 = tree.derivedShared(transform(shared, c)) + sharedMemo = sharedMemo.updated(tree, tree1) + tree1 + } + } + def transform(trees: List[Tree[T]], c: C): List[Tree[T]] = + trees mapConserve (transform(_, c)) + def transformSub(tree: Tree[T], c: C): tree.ThisTree[T] = + transform(tree, c).asInstanceOf[tree.ThisTree[T ]] + def transformSub[TT <: Tree[T]](trees: List[TT], c: C): List[TT] = + (trees mapConserve (transformSub(_, c))).asInstanceOf[List[TT]] + } + + abstract class TreeAccumulator[T, U] extends ((T, Tree[U]) => T) { + var sharedMemo: Map[Shared[U], T] = Map() + def apply(x: T, tree: Tree[U]): T + def apply(x: T, trees: List[Tree[U]]): T = (x /: trees)(apply) + def foldOver(x: T, tree: Tree[U]): T = tree match { + case Ident(name) => + x + case Select(qualifier, name) => + this(x, qualifier) + case This(qual) => + x + case Super(qual, mix) => + this(x, qual) + case Apply(fun, args) => + this(this(x, fun), args) + case TypeApply(fun, args) => + this(this(x, fun), args) + case Literal(const) => + x + case New(tpt) => + this(x, tpt) + case Pair(left, right) => + this(this(x, left), right) + case Typed(expr, tpt) => + this(this(x, expr), tpt) + case NamedArg(name, arg) => + this(x, arg) + case Assign(lhs, rhs) => + this(this(x, lhs), rhs) + case Function(vparams, body) => + this(this(x, vparams), body) + case Block(stats, expr) => + this(this(x, stats), expr) + case If(cond, thenp, elsep) => + this(this(this(x, cond), thenp), elsep) + case Match(selector, cases) => + this(this(x, selector), cases) + case CaseDef(pat, guard, body) => + this(this(this(x, pat), guard), body) + case Return(expr, from) => + this(this(x, expr), from) + case Try(block, catches, finalizer) => + this(this(this(x, block), catches), finalizer) + case Throw(expr) => + this(x, expr) + case ArrayValue(elemtpt, elems) => + this(this(x, elemtpt), elems) + case TypeTree(original) => + x + case SingletonTypeTree(ref) => + this(x, ref) + case SelectFromTypeTree(qualifier, name) => + this(x, qualifier) + case AndTypeTree(left, right) => + this(this(x, left), right) + case OrTypeTree(left, right) => + this(this(x, left), right) + case RefineTypeTree(tpt, refinements) => + this(this(x, tpt), refinements) + case AppliedTypeTree(tpt, args) => + this(this(x, tpt), args) + case TypeBoundsTree(lo, hi) => + this(this(x, lo), hi) + case Bind(name, body) => + this(x, body) + case Alternative(trees) => + this(x, trees) + case UnApply(fun, args) => + this(this(x, fun), args) + case ValDef(mods, name, tpt, rhs) => + 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 Template(parents, self, body) => + this(this(this(x, parents), self), body) + case ClassDef(mods, name, tparams, impl) => + this(this(x, tparams), impl) + case Import(expr, selectors) => + this(x, expr) + case PackageDef(pid, stats) => + this(this(x, pid), stats) + case Annotated(annot, arg) => + this(this(x, annot), arg) + case EmptyTree() => + x + case tree @ Shared(shared) => + sharedMemo get tree match { + case Some(x1) => x1 + case None => + val x1 = this(x, shared) + sharedMemo = sharedMemo.updated(tree, x1) + x1 + } + } + } +} diff --git a/src/dotty/tools/dotc/core/TypedTreeGen.scala b/src/dotty/tools/dotc/core/TypedTreeGen.scala deleted file mode 100644 index 7672f1f77..000000000 --- a/src/dotty/tools/dotc/core/TypedTreeGen.scala +++ /dev/null @@ -1,236 +0,0 @@ -package dotty.tools.dotc -package core - -import Trees._, Positions._, Types._, Contexts._, Constants._, Names._, Flags._ -import SymDenotations._, Symbols._, StdNames._, Annotations._ - -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, - sym.annotations map (_.tree)) - - def Ident(tp: NamedType)(implicit ctx: Context): Ident[Type] = - Trees.Ident(tp.name).withType(tp) - - def Select(pre: TypedTree, tp: NamedType)(implicit ctx: Context): Select[Type] = - Trees.Select(pre, tp.name).withType(tp) - - def This(cls: ClassSymbol)(implicit ctx: Context): This[Type] = - Trees.This(cls.name).withType(cls.thisType) - - def Super(qual: TypedTree, mixin: Symbol = NoSymbol)(implicit ctx: Context): Super[Type] = { - val cls = qual.tpe.typeSymbol - val (owntype, mix) = - if (mixin.exists) (mixin.typeConstructor, mixin.asType.name) - else (ctx.glb(cls.info.parents), tpnme.EMPTY) - Trees.Super(qual, mix).withType(SuperType(qual.tpe, owntype)) - } - - def Apply(fn: TypedTree, args: List[TypedTree])(implicit ctx: Context): Apply[Type] = { - val fntpe @ MethodType(pnames, ptypes) = fn.tpe - assert(sameLength(ptypes, args)) - Trees.Apply(fn, args).withType(fntpe.instantiate(args map (_.tpe))) - } - - def TypeApply(fn: TypedTree, args: List[TypedTree])(implicit ctx: Context): TypeApply[Type] = { - val fntpe @ PolyType(pnames) = fn.tpe - assert(sameLength(pnames, args)) - Trees.TypeApply(fn, args).withType(fntpe.instantiate(args map (_.tpe))) - } - - def Literal(const: Constant)(implicit ctx: Context): Literal[Type] = - Trees.Literal(const).withType(const.tpe) - - def New(tp: Type)(implicit ctx: Context): New[Type] = - Trees.New(TypeTree(tp)) - - def Pair(left: TypedTree, right: TypedTree)(implicit ctx: Context): Pair[Type] = - Trees.Pair(left, right).withType(defn.PairType.appliedTo(left.tpe, right.tpe)) - - def Typed(expr: TypedTree, tpt: TypedTree)(implicit ctx: Context): Typed[Type] = - Trees.Typed(expr, tpt).withType(tpt.tpe) - - def NamedArg[Type](name: Name, arg: TypedTree)(implicit ctx: Context) = - Trees.NamedArg(name, arg).withType(arg.tpe) - - def Assign(lhs: TypedTree, rhs: TypedTree)(implicit ctx: Context): Assign[Type] = - Trees.Assign(lhs, rhs).withType(defn.UnitType) - - def Function(vparams: List[ValDef[Type]], body: TypedTree)(implicit ctx: Context): Function[Type] = - Trees.Function(vparams, body) - .withType(defn.FunctionType(vparams map (_.tpt.tpe), body.tpe)) - - def Block(stats: List[TypedTree], expr: TypedTree)(implicit ctx: Context): Block[Type] = - Trees.Block(stats, expr).withType(expr.tpe) // !!! need to make sure that type does not refer to locals - - def If(cond: TypedTree, thenp: TypedTree, elsep: TypedTree)(implicit ctx: Context): If[Type] = - Trees.If(cond, thenp, elsep).withType(thenp.tpe | elsep.tpe) - - def Match(selector: TypedTree, cases: List[CaseDef[Type]])(implicit ctx: Context): Match[Type] = - Trees.Match(selector, cases).withType(ctx.lub(cases map (_.body.tpe))) - - def CaseDef(pat: TypedTree, guard: TypedTree, body: TypedTree)(implicit ctx: Context): CaseDef[Type] = - Trees.CaseDef(pat, guard, body).withType(body.tpe) - - def Return(expr: TypedTree, from: Ident[Type])(implicit ctx: Context): Return[Type] = - Trees.Return(expr, from).withType(defn.NothingType) - - def Throw(expr: TypedTree)(implicit ctx: Context): Throw[Type] = - Trees.Throw(expr).withType(defn.NothingType) - - def ArrayValue(elemtpt: TypedTree, elems: List[TypedTree])(implicit ctx: Context): ArrayValue[Type] = - Trees.ArrayValue(elemtpt, elems).withType(defn.ArrayType.appliedTo(elemtpt.tpe)) - - def TypeTree(tp: Type, original: TypedTree = EmptyTree)(implicit ctx: Context): TypeTree[Type] = - Trees.TypeTree(original).withType(tp) - - def SingletonTypeTree(ref: TypedTree)(implicit ctx: Context): SingletonTypeTree[Type] = - Trees.SingletonTypeTree(ref).withType(ref.tpe) - - def SelectFromTypeTree(qualifier: TypedTree, name: TypeName)(implicit ctx: Context): SelectFromTypeTree[Type] = - Trees.SelectFromTypeTree(qualifier, name).withType(TypeRef(qualifier.tpe, name)) - - def AndTypeTree(left: TypedTree, right: TypedTree)(implicit ctx: Context): AndTypeTree[Type] = - Trees.AndTypeTree(left, right).withType(left.tpe & right.tpe) - - def OrTypeTree(left: TypedTree, right: TypedTree)(implicit ctx: Context): OrTypeTree[Type] = - Trees.OrTypeTree(left, right).withType(left.tpe | right.tpe) - - def RefineTypeTree(tpt: TypedTree, refinements: List[DefTree[Type]])(implicit ctx: Context): RefineTypeTree[Type] = { - def refineType(tp: Type, refinement: Symbol): Type = - RefinedType(tp, refinement.name, refinement.info) - Trees.RefineTypeTree(tpt, refinements) - .withType((tpt.tpe /: (refinements map (_.symbol)))(refineType)) - } - - def refineType(tp: Type, refinement: Symbol)(implicit ctx: Context): Type = - RefinedType(tp, refinement.name, refinement.info) - - def AppliedTypeTree(tpt: TypedTree, args: List[TypedTree])(implicit ctx: Context): AppliedTypeTree[Type] = - Trees.AppliedTypeTree(tpt, args).withType(tpt.tpe.appliedTo(args map (_.tpe))) - - def TypeBoundsTree(lo: TypedTree, hi: TypedTree)(implicit ctx: Context): TypeBoundsTree[Type] = - 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)(defPos(sym)).withType(sym.info) - - def Alternative(trees: List[TypedTree])(implicit ctx: Context): Alternative[Type] = - Trees.Alternative(trees).withType(ctx.lub(trees map (_.tpe))) - - def UnApply(fun: TypedTree, args: List[TypedTree])(implicit ctx: Context): UnApply[Type] = - Trees.UnApply(fun, args).withType(fun.tpe match { - case MethodType(_, paramTypes) => paramTypes.head - }) - - 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)(defPos(sym)) - .withType(refType(sym)) - - def DefDef(sym: TermSymbol, rhs: TypedTree = EmptyTree)(implicit ctx: Context): DefDef[Type] = { - - val (tparams, mtp) = sym.info match { - case tp: PolyType => - val paramBounds = (tp.paramNames zip tp.paramBounds).toMap - def typeParam(name: TypeName): TypeSymbol = - ctx.newLazySymbol(sym, name, TypeParam, typeParamCompleter) - def typeParamCompleter = new SymCompleter { - def complete(denot: LazySymDenotation) = - denot.info = new InstPolyMap(tp, tparamRefs) apply - paramBounds(denot.symbol.asType.name) - } - lazy val tparams = tp.paramNames map typeParam - lazy val tparamRefs = tparams map (_.typeConstructor) - (tparams, tp.instantiate(tparamRefs)) - case tp => (Nil, tp) - } - - def valueParamss(tp: Type): (List[List[TermSymbol]], Type) = tp match { - case tp @ MethodType(paramNames, paramTypes) => - def valueParam(name: TermName, info: Type): TermSymbol = - ctx.newSymbol(sym, name, TermParam, info) - val params = (paramNames, paramTypes).zipped.map(valueParam) - val (paramss, rtp) = valueParamss(tp.instantiate(params map (_.typeConstructor))) - (params :: paramss, rtp) - case tp => (Nil, tp) - } - val (vparamss, rtp) = valueParamss(mtp) - - Trees.DefDef( - Modifiers(sym), sym.name, tparams map TypeDef, - 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))(defPos(sym)) - .withType(refType(sym)) - - def ClassDef(cls: ClassSymbol, typeParams: List[TypeSymbol], body: List[TypedTree])(implicit ctx: Context): ClassDef[Type] = { - val parents = cls.info.parents map (TypeTree(_)) - val selfType = - if (cls.selfType eq cls.typeConstructor) EmptyValDef - else ValDef(ctx.newSymbol(cls, nme.THIS, SyntheticArtifact, cls.selfType)) - def isOwnTypeParamAccessor(stat: TypedTree) = - stat.symbol.owner == cls && (stat.symbol is TypeParam) - val (tparamAccessors, rest) = body partition isOwnTypeParamAccessor - val tparams = - (typeParams map TypeDef) ++ - (tparamAccessors collect { - case td: TypeDef[_] if !(typeParams contains td.symbol) => td - }) - val findLocalDummy = new FindLocalDummyAccumulator(cls) - val localDummy = ((NoSymbol: Symbol) /: body)(findLocalDummy) - .orElse(ctx.newLocalDummy(cls)) - val impl = Trees.Template(parents, selfType, rest) - .withType(refType(localDummy)) - Trees.ClassDef(Modifiers(cls), cls.name, tparams, impl)(defPos(cls)) - .withType(refType(cls)) - } - - def Import(expr: TypedTree, selectors: List[UntypedTree])(implicit ctx: Context): Import[Type] = - Trees.Import(expr, selectors).withType(refType(ctx.newImportSymbol(expr))) - - def PackageDef(pid: RefTree[Type], stats: List[TypedTree])(implicit ctx: Context): PackageDef[Type] = - Trees.PackageDef(pid, stats).withType(refType(pid.symbol)) - - def Annotated(annot: TypedTree, arg: TypedTree)(implicit ctx: Context): Annotated[Type] = - Trees.Annotated(annot, arg).withType(AnnotatedType(List(Annotation(annot)), arg.tpe)) - - def EmptyTree: TypedTree = Trees.EmptyTree[Type] - - def EmptyValDef: ValDef[Type] = Trees.EmptyValDef[Type] - - // ---------------------------------------------------------- - - def New(tp: Type, args: List[TypedTree])(implicit ctx: Context): Apply[Type] = - Apply( - Select( - New(tp), - TermRef(tp.normalizedPrefix, tp.typeSymbol.primaryConstructor.asTerm)), - args) - } - - object tpd extends TypeTreeGen - - class FindLocalDummyAccumulator(cls: ClassSymbol)(implicit ctx: Context) extends TreeAccumulator[Symbol, Type] { - def apply(sym: Symbol, tree: TypedTree) = - if (sym.exists) sym - else if (tree.isDef) { - val owner = tree.symbol.owner - if (owner.isLocalDummy && owner.owner == cls) owner - else if (owner == cls) foldOver(sym, tree) - else sym - } else foldOver(sym, tree) - } -} - diff --git a/src/dotty/tools/dotc/core/TypedTrees.scala b/src/dotty/tools/dotc/core/TypedTrees.scala new file mode 100644 index 000000000..c8e468107 --- /dev/null +++ b/src/dotty/tools/dotc/core/TypedTrees.scala @@ -0,0 +1,293 @@ +package dotty.tools.dotc +package core + +import Positions._, Types._, Contexts._, Constants._, Names._, Flags._ +import SymDenotations._, Symbols._, StdNames._, Annotations._ + +object TypedTrees { + + type Modifiers = Trees.Modifiers[Type] + type Tree = Trees.Tree[Type] + type TypTree = Trees.TypTree[Type] + type TermTree = Trees.TermTree[Type] + type SymTree = Trees.SymTree[Type] + type ProxyTree = Trees.ProxyTree[Type] + type NameTree = Trees.NameTree[Type] + type RefTree = Trees.RefTree[Type] + type DefTree = Trees.DefTree[Type] + + type TreeCopier = Trees.TreeCopier[Type] + type TreeAccumulator[T] = Trees.TreeAccumulator[T, Type] + type TreeTransformer[C] = Trees.TreeTransformer[Type, C] + + type Ident = Trees.Ident[Type] + type Select = Trees.Select[Type] + type This = Trees.This[Type] + type Super = Trees.Super[Type] + type Apply = Trees.Apply[Type] + type TypeApply = Trees.TypeApply[Type] + type Literal = Trees.Literal[Type] + type New = Trees.New[Type] + type Pair = Trees.Pair[Type] + type Typed = Trees.Typed[Type] + type NamedArg = Trees.NamedArg[Type] + type Assign = Trees.Assign[Type] + type Function = Trees.Function[Type] + type Block = Trees.Block[Type] + type If = Trees.If[Type] + type Match = Trees.Match[Type] + type CaseDef = Trees.CaseDef[Type] + type Return = Trees.Return[Type] + type Try = Trees.Try[Type] + type Throw = Trees.Throw[Type] + type ArrayValue = Trees.ArrayValue[Type] + type TypeTree = Trees.TypeTree[Type] + type SingletonTypeTree = Trees.SingletonTypeTree[Type] + type SelectFromTypeTree = Trees.SelectFromTypeTree[Type] + type AndTypeTree = Trees.AndTypeTree[Type] + type OrTypeTree = Trees.OrTypeTree[Type] + type RefineTypeTree = Trees.RefineTypeTree[Type] + type AppliedTypeTree = Trees.AppliedTypeTree[Type] + type TypeBoundsTree = Trees.TypeBoundsTree[Type] + type Bind = Trees.Bind[Type] + type Alternative = Trees.Alternative[Type] + type UnApply = Trees.UnApply[Type] + type ValDef = Trees.ValDef[Type] + type DefDef = Trees.DefDef[Type] + type TypeDef = Trees.TypeDef[Type] + type Template = Trees.Template[Type] + type ClassDef = Trees.ClassDef[Type] + type Import = Trees.Import[Type] + type PackageDef = Trees.PackageDef[Type] + type Annotated = Trees.Annotated[Type] + type EmptyTree = Trees.EmptyTree[Type] + type Shared = Trees.Shared[Type] + + private 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 = Trees.Modifiers[Type]( + sym.flags & ModifierFlags, + if (sym.privateWithin.exists) sym.privateWithin.asType.name else tpnme.EMPTY, + sym.annotations map (_.tree)) + + val Ident = Trees.Ident + def Ident(tp: NamedType)(implicit ctx: Context): Ident = + Trees.Ident(tp.name).withType(tp) + + def Select(pre: Tree, tp: NamedType)(implicit ctx: Context): Select = + Trees.Select(pre, tp.name).withType(tp) + + def This(cls: ClassSymbol)(implicit ctx: Context): This = + Trees.This(cls.name).withType(cls.thisType) + + def Super(qual: Tree, mixin: Symbol = NoSymbol)(implicit ctx: Context): Super = { + val cls = qual.tpe.typeSymbol + val (owntype, mix) = + if (mixin.exists) (mixin.typeConstructor, mixin.asType.name) + else (ctx.glb(cls.info.parents), tpnme.EMPTY) + Trees.Super(qual, mix).withType(SuperType(qual.tpe, owntype)) + } + + def Apply(fn: Tree, args: List[Tree])(implicit ctx: Context): Apply = { + val fntpe @ MethodType(pnames, ptypes) = fn.tpe + assert(sameLength(ptypes, args)) + Trees.Apply(fn, args).withType(fntpe.instantiate(args map (_.tpe))) + } + + def TypeApply(fn: Tree, args: List[Tree])(implicit ctx: Context): TypeApply = { + val fntpe @ PolyType(pnames) = fn.tpe + assert(sameLength(pnames, args)) + Trees.TypeApply(fn, args).withType(fntpe.instantiate(args map (_.tpe))) + } + + def Literal(const: Constant)(implicit ctx: Context): Literal = + Trees.Literal(const).withType(const.tpe) + + def New(tp: Type)(implicit ctx: Context): New = + Trees.New(TypeTree(tp)) + + def Pair(left: Tree, right: Tree)(implicit ctx: Context): Pair = + Trees.Pair(left, right).withType(defn.PairType.appliedTo(left.tpe, right.tpe)) + + def Typed(expr: Tree, tpt: Tree)(implicit ctx: Context): Typed = + Trees.Typed(expr, tpt).withType(tpt.tpe) + + def NamedArg(name: Name, arg: Tree)(implicit ctx: Context) = + Trees.NamedArg(name, arg).withType(arg.tpe) + + def Assign(lhs: Tree, rhs: Tree)(implicit ctx: Context): Assign = + Trees.Assign(lhs, rhs).withType(defn.UnitType) + + def Function(vparams: List[ValDef], body: Tree)(implicit ctx: Context): Function = + Trees.Function(vparams, body) + .withType(defn.FunctionType(vparams map (_.tpt.tpe), body.tpe)) + + def Block(stats: List[Tree], expr: Tree)(implicit ctx: Context): Block = + Trees.Block(stats, expr).withType(expr.tpe) // !!! need to make sure that type does not refer to locals + + def If(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If = + Trees.If(cond, thenp, elsep).withType(thenp.tpe | elsep.tpe) + + def Match(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match = + Trees.Match(selector, cases).withType(ctx.lub(cases map (_.body.tpe))) + + def CaseDef(pat: Tree, guard: Tree, body: Tree)(implicit ctx: Context): CaseDef = + Trees.CaseDef(pat, guard, body).withType(body.tpe) + + def Return(expr: Tree, from: Ident)(implicit ctx: Context): Return = + Trees.Return(expr, from).withType(defn.NothingType) + + def Throw(expr: Tree)(implicit ctx: Context): Throw = + Trees.Throw(expr).withType(defn.NothingType) + + def ArrayValue(elemtpt: Tree, elems: List[Tree])(implicit ctx: Context): ArrayValue = + Trees.ArrayValue(elemtpt, elems).withType(defn.ArrayType.appliedTo(elemtpt.tpe)) + + def TypeTree(tp: Type, original: Tree = EmptyTree)(implicit ctx: Context): TypeTree = + Trees.TypeTree(original).withType(tp) + + def SingletonTypeTree(ref: Tree)(implicit ctx: Context): SingletonTypeTree = + Trees.SingletonTypeTree(ref).withType(ref.tpe) + + def SelectFromTypeTree(qualifier: Tree, name: TypeName)(implicit ctx: Context): SelectFromTypeTree = + Trees.SelectFromTypeTree(qualifier, name).withType(TypeRef(qualifier.tpe, name)) + + def AndTypeTree(left: Tree, right: Tree)(implicit ctx: Context): AndTypeTree = + Trees.AndTypeTree(left, right).withType(left.tpe & right.tpe) + + def OrTypeTree(left: Tree, right: Tree)(implicit ctx: Context): OrTypeTree = + Trees.OrTypeTree(left, right).withType(left.tpe | right.tpe) + + def RefineTypeTree(tpt: Tree, refinements: List[DefTree])(implicit ctx: Context): RefineTypeTree = { + def refineType(tp: Type, refinement: Symbol): Type = + RefinedType(tp, refinement.name, refinement.info) + Trees.RefineTypeTree(tpt, refinements) + .withType((tpt.tpe /: (refinements map (_.symbol)))(refineType)) + } + + def refineType(tp: Type, refinement: Symbol)(implicit ctx: Context): Type = + RefinedType(tp, refinement.name, refinement.info) + + def AppliedTypeTree(tpt: Tree, args: List[Tree])(implicit ctx: Context): AppliedTypeTree = + Trees.AppliedTypeTree(tpt, args).withType(tpt.tpe.appliedTo(args map (_.tpe))) + + def TypeBoundsTree(lo: Tree, hi: Tree)(implicit ctx: Context): TypeBoundsTree = + Trees.TypeBoundsTree(lo, hi).withType(TypeBounds(lo.tpe, hi.tpe)) + + def Bind(sym: Symbol, body: Tree)(implicit ctx: Context): Bind = + Trees.Bind(sym.name, body)(defPos(sym)).withType(sym.info) + + def Alternative(trees: List[Tree])(implicit ctx: Context): Alternative = + Trees.Alternative(trees).withType(ctx.lub(trees map (_.tpe))) + + def UnApply(fun: Tree, args: List[Tree])(implicit ctx: Context): UnApply = + Trees.UnApply(fun, args).withType(fun.tpe match { + case MethodType(_, paramTypes) => paramTypes.head + }) + + def refType(sym: Symbol)(implicit ctx: Context) = NamedType(sym.owner.thisType, sym) + + 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)) + + def DefDef(sym: TermSymbol, rhs: Tree = EmptyTree)(implicit ctx: Context): DefDef = { + + val (tparams, mtp) = sym.info match { + case tp: PolyType => + def paramBounds(trefs: List[TypeRef]): List[Type] = + tp.paramBounds map new InstPolyMap(tp, trefs) + val tparams = ctx.newTypeParams(sym, tp.paramNames, EmptyFlags, paramBounds) + (tparams, tp.instantiate(tparams map (_.typeConstructor))) + case tp => (Nil, tp) + } + + def valueParamss(tp: Type): (List[List[TermSymbol]], Type) = tp match { + case tp @ MethodType(paramNames, paramTypes) => + def valueParam(name: TermName, info: Type): TermSymbol = + ctx.newSymbol(sym, name, TermParam, info) + val params = (paramNames, paramTypes).zipped.map(valueParam) + val (paramss, rtp) = valueParamss(tp.instantiate(params map (_.typeConstructor))) + (params :: paramss, rtp) + case tp => (Nil, tp) + } + val (vparamss, rtp) = valueParamss(mtp) + + Trees.DefDef( + Modifiers(sym), sym.name, tparams map TypeDef, + vparamss map (_ map (ValDef(_))), TypeTree(rtp), rhs)(defPos(sym)) + .withType(refType(sym)) + } + + def TypeDef(sym: TypeSymbol)(implicit ctx: Context): TypeDef = + Trees.TypeDef(Modifiers(sym), sym.name, TypeTree(sym.info))(defPos(sym)) + .withType(refType(sym)) + + def ClassDef(cls: ClassSymbol, typeParams: List[TypeSymbol], body: List[Tree])(implicit ctx: Context): ClassDef = { + val parents = cls.info.parents map (TypeTree(_)) + val selfType = + if (cls.selfType eq cls.typeConstructor) EmptyValDef + else ValDef(ctx.newSelfSym(cls)) + def isOwnTypeParamAccessor(stat: Tree) = + stat.symbol.owner == cls && (stat.symbol is TypeParam) + val (tparamAccessors, rest) = body partition isOwnTypeParamAccessor + val tparams = + (typeParams map TypeDef) ++ + (tparamAccessors collect { + case td: TypeDef if !(typeParams contains td.symbol) => td + }) + val findLocalDummy = new FindLocalDummyAccumulator(cls) + val localDummy = ((NoSymbol: Symbol) /: body)(findLocalDummy) + .orElse(ctx.newLocalDummy(cls)) + val impl = Trees.Template(parents, selfType, rest) + .withType(refType(localDummy)) + Trees.ClassDef(Modifiers(cls), cls.name, tparams, impl)(defPos(cls)) + .withType(refType(cls)) + } + + def Import(expr: Tree, selectors: List[Trees.UntypedTree])(implicit ctx: Context): Import = + Trees.Import(expr, selectors).withType(refType(ctx.newImportSymbol(expr))) + + def PackageDef(pid: RefTree, stats: List[Tree])(implicit ctx: Context): PackageDef = + Trees.PackageDef(pid, stats).withType(refType(pid.symbol)) + + def Annotated(annot: Tree, arg: Tree)(implicit ctx: Context): Annotated = + Trees.Annotated(annot, arg).withType(AnnotatedType(List(Annotation(annot)), arg.tpe)) + + val EmptyTree: Tree = Trees.EmptyTree[Type] + + val EmptyValDef: ValDef = Trees.EmptyValDef[Type] + + def Shared(tree: Tree): Shared = + Trees.Shared(tree).withType(tree.tpe) + + // ----------------------------------------------------------------------------- + + def New(tp: Type, args: List[Tree])(implicit ctx: Context): Apply = + Apply( + Select( + New(tp), + TermRef(tp.normalizedPrefix, tp.typeSymbol.primaryConstructor.asTerm)), + args) + + def ModuleDef(sym: TermSymbol, body: List[Tree])(implicit ctx: Context): ValDef = { + val modcls = sym.moduleClass.asClass + val clsdef = ClassDef(modcls, Nil, body) + val rhs = Block(List(clsdef), New(modcls.typeConstructor)) + ValDef(sym, rhs) + } + + private class FindLocalDummyAccumulator(cls: ClassSymbol)(implicit ctx: Context) extends TreeAccumulator[Symbol] { + def apply(sym: Symbol, tree: Tree) = + if (sym.exists) sym + else if (tree.isDef) { + val owner = tree.symbol.owner + if (owner.isLocalDummy && owner.owner == cls) owner + else if (owner == cls) foldOver(sym, tree) + else sym + } else foldOver(sym, tree) + } +} + diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala index 9955d8b56..d131fe8f8 100644 --- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala +++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala @@ -4,7 +4,7 @@ package core package pickling import Contexts._, Symbols._, Types._, Names._, StdNames._, NameOps._, Scopes._, Decorators._ -import SymDenotations._, UnPickler._, Constants._, Trees._, Annotations._, Positions._ +import SymDenotations._, UnPickler._, Constants._, Annotations._, Positions._ import TypedTrees._ import java.io.{ File, IOException } import java.lang.Integer.toHexString @@ -125,11 +125,7 @@ class ClassfileParser( instanceScope.lookup(nme.CONSTRUCTOR) == NoSymbol && !(sflags is Flags.Interface) if (needsConstructor) - instanceScope enter - cctx.newSymbol( - classRoot.symbol, - nme.CONSTRUCTOR, Flags.EmptyFlags, - MethodType(Nil, Nil)(_ => classRoot.typeConstructor)) + instanceScope enter cctx.newDefaultConstructor(classRoot.symbol.asClass) classInfo = parseAttributes(classRoot.symbol, classInfo) assignClassFields(classRoot, classInfo, classRoot.typeConstructor) @@ -158,41 +154,39 @@ class ClassfileParser( cctx.newLazySymbol(getOwner(jflags), name, sflags, memberCompleter, start).entered } - object memberCompleter extends SymCompleter { - def complete(denot: LazySymDenotation) = { - val oldbp = in.bp - try { - in.bp = denot.symbol.coord.toIndex - val sym = denot.symbol - val jflags = in.nextChar - val isEnum = (jflags & JAVA_ACC_ENUM) != 0 - val name = pool.getName(in.nextChar) - val info = pool.getType(in.nextChar) - - denot.info = if (isEnum) ConstantType(Constant(sym)) else info - if (name == nme.CONSTRUCTOR) - // if this is a non-static inner class, remove the explicit outer parameter - innerClasses.get(currentClassName) match { - case Some(entry) if !isStatic(entry.jflags) => - val mt @ MethodType(paramnames, paramtypes) = info - denot.info = mt.derivedMethodType(paramnames.tail, paramtypes.tail, mt.resultType) - - } - setPrivateWithin(denot, jflags) - denot.info = parseAttributes(sym, info) + val memberCompleter: SymCompleter = { denot => + val oldbp = in.bp + try { + in.bp = denot.symbol.coord.toIndex + val sym = denot.symbol + val jflags = in.nextChar + val isEnum = (jflags & JAVA_ACC_ENUM) != 0 + val name = pool.getName(in.nextChar) + val info = pool.getType(in.nextChar) - if ((denot is Flags.Method) && (jflags & JAVA_ACC_VARARGS) != 0) - denot.info = arrayToRepeated(denot.info) + denot.info = if (isEnum) ConstantType(Constant(sym)) else info + if (name == nme.CONSTRUCTOR) + // if this is a non-static inner class, remove the explicit outer parameter + innerClasses.get(currentClassName) match { + case Some(entry) if !isStatic(entry.jflags) => + val mt @ MethodType(paramnames, paramtypes) = info + denot.info = mt.derivedMethodType(paramnames.tail, paramtypes.tail, mt.resultType) - // seal java enums - if (isEnum) { - val enumClass = sym.owner.linkedClass - if (!(enumClass is Flags.Sealed)) enumClass.setFlag(Flags.AbstractSealed) - enumClass.addAnnotation(Annotation.makeChild(sym)) } - } finally { - in.bp = oldbp + setPrivateWithin(denot, jflags) + denot.info = parseAttributes(sym, info) + + if ((denot is Flags.Method) && (jflags & JAVA_ACC_VARARGS) != 0) + denot.info = arrayToRepeated(denot.info) + + // seal java enums + if (isEnum) { + val enumClass = sym.owner.linkedClass + if (!(enumClass is Flags.Sealed)) enumClass.setFlag(Flags.AbstractSealed) + enumClass.addAnnotation(Annotation.makeChild(sym)) } + } finally { + in.bp = oldbp } } @@ -315,15 +309,13 @@ class ClassfileParser( var tparams = classTParams - class TypeParamCompleter(start: Int) extends SymCompleter { - override def complete(denot: LazySymDenotation): Unit = { - val savedIndex = index - try { - index = start - denot.info = sig2typeBounds(tparams, skiptvs = false) - } finally { - index = savedIndex - } + def typeParamCompleter(start: Int): SymCompleter = { denot => + val savedIndex = index + try { + index = start + denot.info = sig2typeBounds(tparams, skiptvs = false) + } finally { + index = savedIndex } } @@ -335,7 +327,7 @@ class ClassfileParser( while (sig(index) != '>') { val tpname = subName(':'.==).toTypeName val s = cctx.newLazySymbol( - owner, tpname, Flags.TypeParam, new TypeParamCompleter(index), indexCoord(index)) + owner, tpname, Flags.TypeParam, typeParamCompleter(index), indexCoord(index)) tparams = tparams + (tpname -> s) sig2typeBounds(tparams, skiptvs = true) newTParams += s @@ -356,7 +348,7 @@ class ClassfileParser( if (ownTypeParams.isEmpty) tpe else TempPolyType(ownTypeParams, tpe) } // sigToType - def parseAnnotArg(skip: Boolean = false): Option[TypedTree] = { + def parseAnnotArg(skip: Boolean = false): Option[Tree] = { val tag = in.nextByte.toChar val index = in.nextChar tag match { @@ -374,7 +366,7 @@ class ClassfileParser( assert(s != NoSymbol, t) if (skip) None else Some(makeLiteralAnnotArg(Constant(s))) case ARRAY_TAG => - val arr = new ArrayBuffer[TypedTree]() + val arr = new ArrayBuffer[Tree]() var hasError = false for (i <- 0 until index) parseAnnotArg(skip) match { @@ -394,12 +386,12 @@ class ClassfileParser( def parseAnnotation(attrNameIndex: Char, skip: Boolean = false): Option[Annotation] = try { val attrType = pool.getType(attrNameIndex) val nargs = in.nextChar - val argbuf = new ListBuffer[TypedTree] + val argbuf = new ListBuffer[Tree] var hasError = false for (i <- 0 until nargs) { val name = pool.getName(in.nextChar) parseAnnotArg(skip) match { - case Some(arg) => argbuf += tpd.NamedArg(name, arg) + case Some(arg) => argbuf += NamedArg(name, arg) case None => hasError = !skip } } @@ -444,8 +436,8 @@ class ClassfileParser( case tpnme.BridgeATTR => sym.setFlag(Flags.Bridge) case tpnme.DeprecatedATTR => - val msg = tpd.Literal(Constant("see corresponding Javadoc for more information.")) - val since = tpd.Literal(Constant("")) + val msg = Literal(Constant("see corresponding Javadoc for more information.")) + val since = Literal(Constant("")) sym.addAnnotation(Annotation(defn.DeprecatedAnnot, msg, since)) case tpnme.ConstantValueATTR => val c = pool.getConstant(in.nextChar) diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala index e3d08b304..7a06b098e 100644 --- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala @@ -9,7 +9,7 @@ import java.lang.Double.longBitsToDouble import Contexts._, Symbols._, Types._, Scopes._, SymDenotations._, Names._ import StdNames._, Denotations._, NameOps._, Flags._, Constants._, Annotations._ -import Trees._, Positions._, TypedTrees._ +import Positions._, TypedTrees._ import io.AbstractFile import scala.reflect.internal.pickling.PickleFormat._ import scala.collection.{ mutable, immutable } @@ -422,13 +422,8 @@ class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot: atReadPos(denot.symbol.coord.toIndex, parseToCompletion) } - private object symUnpickler extends SymCompleter { - override def complete(denot: LazySymDenotation): Unit = completeLocal(denot) - } - - private object classUnpickler extends ClassCompleter { - override def complete(denot: LazyClassDenotation): Unit = completeLocal(denot) - } + val symUnpickler: SymCompleter = completeLocal + val classUnpickler: ClassCompleter = completeLocal /** Convert * tp { type name = sym } forSome { sym >: L <: H } @@ -625,36 +620,36 @@ class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot: protected def readAnnotationRef(): Annotation = at(readNat(), readAnnotation) // protected def readModifiersRef(): Modifiers = at(readNat(), readModifiers) - protected def readTreeRef(): TypedTree = at(readNat(), readTree) + protected def readTreeRef(): Tree = at(readNat(), readTree) - protected def readTree(): TypedTree = ??? + protected def readTree(): Tree = ??? /** Read an annotation argument, which is pickled either * as a Constant or a Tree. */ - protected def readAnnotArg(i: Int): TypedTree = bytes(index(i)) match { + protected def readAnnotArg(i: Int): Tree = bytes(index(i)) match { case TREE => at(i, readTree) - case _ => tpd.Literal(at(i, readConstant)) + case _ => Literal(at(i, readConstant)) } /** Read a ClassfileAnnotArg (argument to a classfile annotation) */ - private def readArrayAnnotArg(): TypedTree = { + private def readArrayAnnotArg(): Tree = { readByte() // skip the `annotargarray` tag val end = readNat() + readIndex // array elements are trees representing instances of scala.annotation.Annotation - tpd.ArrayValue( - tpd.TypeTree(defn.AnnotationClass.typeConstructor), + ArrayValue( + TypeTree(defn.AnnotationClass.typeConstructor), until(end, () => readClassfileAnnotArg(readNat()))) } - private def readAnnotInfoArg(): TypedTree = { + private def readAnnotInfoArg(): Tree = { readByte() // skip the `annotinfo` tag val end = readNat() + readIndex readAnnotationContents(end) } - protected def readClassfileAnnotArg(i: Int): TypedTree = bytes(index(i)) match { + protected def readClassfileAnnotArg(i: Int): Tree = bytes(index(i)) match { case ANNOTINFO => at(i, readAnnotInfoArg) case ANNOTARGARRAY => at(i, readArrayAnnotArg) case _ => readAnnotArg(i) @@ -663,20 +658,20 @@ class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot: /** Read an annotation's contents. Not to be called directly, use * readAnnotation, readSymbolAnnotation, or readAnnotInfoArg */ - protected def readAnnotationContents(end: Int): TypedTree = { + protected def readAnnotationContents(end: Int): Tree = { val atp = readTypeRef() - val args = new ListBuffer[TypedTree] + val args = new ListBuffer[Tree] while (readIndex != end) { val argref = readNat() args += { if (isNameEntry(argref)) { val name = at(argref, readName) val arg = readClassfileAnnotArg(readNat()) - tpd.NamedArg(name, arg) + NamedArg(name, arg) } else readAnnotArg(argref) } } - tpd.New(atp, args.toList) + New(atp, args.toList) } /** Read an annotation and as a side effect store it into |