diff options
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/core/Annotations.scala | 12 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 23 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Trees.scala | 108 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeOps.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypedTreeGen.scala | 209 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/ClassfileParser.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/UnPickler.scala | 14 |
10 files changed, 303 insertions, 99 deletions
diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala index fae8082bd..9cbf5c8e4 100644 --- a/src/dotty/tools/dotc/core/Annotations.scala +++ b/src/dotty/tools/dotc/core/Annotations.scala @@ -1,6 +1,6 @@ package dotty.tools.dotc.core -import Symbols._, Trees._, Types._, Positions._, Contexts._, Constants._ +import Symbols._, Trees._, Types._, Positions._, Contexts._, Constants._, TypedTrees._ object Annotations { @@ -15,6 +15,8 @@ object Annotations { object Annotation { + def apply(tree: TypedTree) = ConcreteAnnotation(tree) + def apply(cls: ClassSymbol, arg: TypedTree)(implicit ctx: Context): Annotation = apply(cls, arg :: Nil) @@ -31,13 +33,13 @@ object Annotations { apply(atp, arg1 :: arg2 :: Nil) def apply(atp: Type, args: List[TypedTree])(implicit ctx: Context): Annotation = - ConcreteAnnotation(makeTypedTree.New(atp, args)) + apply(tpd.New(atp, args)) def makeAlias(sym: TermSymbol)(implicit ctx: Context) = - apply(defn.AliasAnnot, List(makeTypedTree.Ident(TermRef(sym.owner.thisType, sym.name, sym.signature)))) + apply(defn.AliasAnnot, List(tpd.Ident(TermRef(sym.owner.thisType, sym.name, sym.signature)))) def makeChild(sym: Symbol)(implicit ctx: Context) = - apply(defn.ChildAnnot, List(makeTypedTree.Ident(NamedType(sym.owner.thisType, sym.name)))) + apply(defn.ChildAnnot, List(tpd.Ident(NamedType(sym.owner.thisType, sym.name)))) } def makeLiteralAnnotArg(const: Constant): TypedTree = ??? @@ -47,5 +49,5 @@ object Annotations { def makeNestedAnnotArg(annot: Annotation): TypedTree = annot.tree def ThrowsAnnotation(cls: ClassSymbol)(implicit ctx: Context) = - Annotation(defn.ThrowsAnnot, makeTypedTree.Ident(TypeRef(cls.owner.thisType, cls.name))) + Annotation(defn.ThrowsAnnot, tpd.Ident(TypeRef(cls.owner.thisType, cls.name))) }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index 587f244e0..461f574c5 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -111,6 +111,7 @@ class Definitions(implicit ctx: Context) { lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS, Covariant, AnyRefType, SeqType) // fundamental reference classes + lazy val PairClass = requiredClass("dotty.Pair") lazy val PartialFunctionClass = requiredClass("scala.PartialFunction") lazy val AbstractPartialFunctionClass = requiredClass("scala.runtime.AbstractPartialFunction") lazy val SymbolClass = requiredClass("scala.Symbol") @@ -127,6 +128,16 @@ class Definitions(implicit ctx: Context) { lazy val ClassfileAnnotationClass = requiredClass("scala.annotation.ClassfileAnnotation") lazy val StaticAnnotationClass = requiredClass("scala.annotation.StaticAnnotation") + // Annotation classes + lazy val AliasAnnot = requiredClass("dotty.annotation.internal.Alias") + lazy val ChildAnnot = requiredClass("dotty.annotation.internal.Alias") + lazy val ScalaSignatureAnnot = requiredClass("scala.reflect.ScalaSignature") + lazy val ScalaLongSignatureAnnot = requiredClass("scala.reflect.ScalaLongSignature") + lazy val DeprecatedAnnot = requiredClass("scala.deprecated") + lazy val AnnotationDefaultAnnot = requiredClass("dotty.runtime.AnnotationDefault") + lazy val ThrowsAnnot = requiredClass("scala.throws") + + // Derived types lazy val AnyType: Type = AnyClass.typeConstructor lazy val AnyValType: Type = AnyValClass.typeConstructor lazy val ObjectType: Type = ObjectClass.typeConstructor @@ -146,16 +157,9 @@ class Definitions(implicit ctx: Context) { lazy val LongType: Type = LongClass.typeConstructor lazy val FloatType: Type = FloatClass.typeConstructor lazy val DoubleType: Type = DoubleClass.typeConstructor + lazy val PairType: Type = PairClass.typeConstructor lazy val JavaRepeatedParamType = JavaRepeatedParamClass.typeConstructor - lazy val AliasAnnot = requiredClass("dotty.annotation.internal.Alias") - lazy val ChildAnnot = requiredClass("dotty.annotation.internal.Alias") - lazy val ScalaSignatureAnnot = requiredClass("scala.reflect.ScalaSignature") - lazy val ScalaLongSignatureAnnot = requiredClass("scala.reflect.ScalaLongSignature") - lazy val DeprecatedAnnot = requiredClass("scala.deprecated") - lazy val AnnotationDefaultAnnot = requiredClass("dotty.runtime.AnnotationDefault") - lazy val ThrowsAnnot = requiredClass("scala.throws") - def ClassType(arg: Type)(implicit ctx: Context) = { val ctype = ClassClass.typeConstructor if (ctx.phase.erasedTypes) ctype else ctype.appliedTo(arg) @@ -168,6 +172,9 @@ class Definitions(implicit ctx: Context) { // - .linkedClassOfClass: the ClassSymbol of the enumeration (class E) sym.owner.linkedClass.typeConstructor + def FunctionType(args: List[Type], resultType: Type) = + FunctionClass(args.length).typeConstructor.appliedTo(args :+ resultType) + // ----- Class sets --------------------------------------------------- lazy val FunctionClass = mkArityArray("Function", MaxFunctionArity, 0) diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index a6f4e5001..79f2b7817 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -239,6 +239,9 @@ object SymDenotations { /** Is this the constructor of a trait or a class */ def isConstructor = name.isConstructorName + /** Is this a local template dummmy? */ + def isLocalDummy: Boolean = name.isLocalDummyName + /** Does this symbol denote the primary constructor of its enclosing class? */ final def isPrimaryConstructor(implicit ctx: Context) = isConstructor && owner.primaryConstructor == this diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index 06f29ac9c..815e1bbaa 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -11,7 +11,7 @@ import Decorators._ import Symbols._ import Contexts._ import SymDenotations._ -import Types._, Annotations._, Positions._ +import Types._, Annotations._, Positions._, StdNames._, Trees._ import Denotations.{ Denotation, SingleDenotation, MultiDenotation } import collection.mutable import io.AbstractFile @@ -105,6 +105,12 @@ trait Symbols { this: Context => } } + def newLocalDummy(cls: Symbol, off: Offset = NoOffset) = + newSymbol(cls, nme.localDummyName(cls), EmptyFlags, NoType) + + def newImportSymbol(expr: TypedTree, off: Offset = NoOffset) = + newSymbol(NoSymbol, nme.IMPORT, EmptyFlags, ImportType(expr), off = off) + 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 ccc20ab97..25226c660 100644 --- a/src/dotty/tools/dotc/core/Trees.scala +++ b/src/dotty/tools/dotc/core/Trees.scala @@ -1,15 +1,14 @@ package dotty.tools.dotc.core import Types._, Names._, Flags._, Positions._, Contexts._, Constants._, SymDenotations._, Symbols._ -import Denotations._ +import Denotations._, StdNames._ object Trees { - abstract class Modifiers[T] { - val flags: FlagSet - val privateWithin: Name - val annotations: List[Tree[T]] - } + case class Modifiers[T]( + flags: FlagSet, + privateWithin: TypeName = tpnme.EMPTY, + annotations: List[Tree[T]] = Nil) /** Trees take a parameter indicating what the type of their `tpe` field * is. Two choices: `Types.Type` or `missing.Type`. @@ -57,8 +56,7 @@ object Trees { def isType: Boolean = false def isTerm: Boolean = false def isDef: Boolean = false - - def withPosition(pos: Position) = ??? + def isEmpty: Boolean = false } class UnAssignedTypeException[T](tree: Tree[T]) extends RuntimeException { @@ -209,7 +207,7 @@ object Trees { } /** name = arg, outside a parameter list */ - case class Assign[T](name: Name, arg: Tree[T])(implicit val pos: Position) + case class Assign[T](lhs: Tree[T], rhs: Tree[T])(implicit val pos: Position) extends TermTree[T] { type ThisTree[T] = Assign[T] } @@ -238,6 +236,12 @@ object Trees { type ThisTree[T] = Match[T] } + /** case pat if guard => body */ + case class CaseDef[T](pat: Tree[T], guard: Tree[T], body: Tree[T])(implicit val pos: Position) + extends Tree[T] { + type ThisTree[T] = CaseDef[T] + } + /** return expr * where `from` refers to the method from which the return takes place * After program transformations this is not necessarily the enclosing method, because @@ -322,12 +326,6 @@ object Trees { type ThisTree[T] = Bind[T] } - /** case pat if guard => body */ - case class CaseDef[T](pat: Tree[T], guard: Tree[T], body: Tree[T])(implicit val pos: Position) - extends Tree[T] { - type ThisTree[T] = CaseDef[T] - } - /** tree_1 | ... | tree_n */ case class Alternative[T](trees: List[Tree[T]])(implicit val pos: Position) extends Tree[T] { @@ -340,22 +338,22 @@ object Trees { type ThisTree[T] = UnApply[T] } - /** mods val name: rtpe = rhs */ - case class ValDef[T](mods: Modifiers[T], name: Name, rtpe: Tree[T], rhs: Tree[T])(implicit val pos: Position) + /** mods val name: tpt = rhs */ + case class ValDef[T](mods: Modifiers[T], name: Name, tpt: Tree[T], rhs: Tree[T])(implicit val pos: Position) extends DefTree[T] { type ThisTree[T] = ValDef[T] } - /** mods def name[tparams](vparams_1)...(vparams_n): rtpe = rhs */ - case class DefDef[T](mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], rtpe: Tree[T], rhs: Tree[T])(implicit val pos: Position) + /** 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) extends DefTree[T] { type ThisTree[T] = DefDef[T] } - class ImplicitDefDef[T](mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], rtpe: Tree[T], rhs: Tree[T]) - (implicit pos: Position) extends DefDef[T](mods, name, tparams, vparamss, rtpe, rhs) { - override def copy[T](mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], rtpe: Tree[T], rhs: Tree[T])(implicit pos: Position) = - new ImplicitDefDef[T](mods, name, tparams, vparamss, rtpe, rhs) + class ImplicitDefDef[T](mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T]) + (implicit pos: Position) extends DefDef[T](mods, name, tparams, vparamss, tpt, rhs) { + override def copy[T](mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])(implicit pos: Position) = + new ImplicitDefDef[T](mods, name, tparams, vparamss, tpt, rhs) } /** mods type name = rhs or @@ -400,11 +398,32 @@ object Trees { def forwardTo = arg } + trait AlwaysEmpty[T] extends Tree[T] { + override val pos = NoPosition + override def tpe = unsupported("tpe") + override def withType(tpe: Type) = unsupported("withType") + override def isEmpty: Boolean = true + } + /** A missing tree */ - case class EmptyTree[T]() - extends Tree[T] { + abstract case class EmptyTree[T]() + extends Tree[T] with AlwaysEmpty[T] { type ThisTree[T] = EmptyTree[T] - val pos = NoPosition + } + + private object theEmptyTree extends EmptyTree[Nothing] + + object EmptyTree { + def apply[T]: EmptyTree[T] = theEmptyTree.asInstanceOf + } + + class EmptyValDef[T] extends ValDef[T]( + Modifiers[T](Private), nme.WILDCARD, EmptyTree[T], EmptyTree[T])(NoPosition) with AlwaysEmpty[T] + + private object theEmptyValDef extends EmptyValDef[Nothing] + + object EmptyValDef { + def apply[T]: EmptyValDef[T] = theEmptyValDef.asInstanceOf } // ----- Tree cases that exist in untyped form only ------------------ @@ -419,39 +438,8 @@ object Trees { extends DefTree[Nothing] { } - // this will probably to its own file at some point. - class MakeTypedTree(implicit val ctx: Context) extends AnyVal { - implicit def pos = NoPosition - def Ident(tp: NamedType) = - Trees.Ident(tp.name).withType(tp) - def Select(pre: TypedTree, tp: NamedType) = - Trees.Select(pre, tp.name).withType(tp) - def Apply(fn: TypedTree, args: List[TypedTree]) = { - val fntpe @ MethodType(pnames, ptypes) = fn.tpe - assert(sameLength(ptypes, args)) - Trees.Apply(fn, args).withType(fntpe.instantiate(args map (_.tpe))) - } - def TypeTree(tp: Type) = - Trees.TypeTree().withType(tp) - def New(tp: Type): TypedTree = - Trees.New(TypeTree(tp)) - def Literal(const: Constant) = - Trees.Literal(const).withType(const.tpe) - def ArrayValue(elemtpt: TypedTree, elems: List[TypedTree]) = - Trees.ArrayValue(elemtpt, elems).withType(defn.ArrayType.appliedTo(elemtpt.tpe)) - def NamedArg[T](name: Name, arg: TypedTree) = - Trees.NamedArg(name, arg).withType(arg.tpe) - - // ---------------------------------------------------------- - - def New(tp: Type, args: List[TypedTree]): TypedTree = - Apply( - Select( - New(tp), - TermRef(tp.normalizedPrefix, tp.typeSymbol.primaryConstructor.asTerm)), - args) + 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 = ??? } - - def makeTypedTree(implicit ctx: Context) = new MakeTypedTree()(ctx) - }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index 52f0ef23e..f3193a95f 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -130,6 +130,9 @@ trait TypeOps { this: Context => } } + final def glb(tps: List[Type]): Type = + (defn.AnyType /: tps)(glb) + def lub(tp1: Type, tp2: Type): Type = if (tp1 eq tp2) tp1 else if (tp1.isWrong) tp1 @@ -144,6 +147,9 @@ trait TypeOps { this: Context => } } + final def lub(tps: List[Type]): Type = + (defn.NothingType /: tps)(lub) + /** Merge `t1` into `tp2` if t1 is a subtype of some part of tp2. */ private def mergeIfSub(tp1: Type, tp2: Type)(implicit ctx: Context): Type = diff --git a/src/dotty/tools/dotc/core/TypedTreeGen.scala b/src/dotty/tools/dotc/core/TypedTreeGen.scala index 0b47c4489..b081a6ba7 100644 --- a/src/dotty/tools/dotc/core/TypedTreeGen.scala +++ b/src/dotty/tools/dotc/core/TypedTreeGen.scala @@ -1,33 +1,213 @@ package dotty.tools.dotc package core -import Trees._, Positions._, Types._, Contexts._, Constants._, Names._ -import SymDenotations._, Symbols._ +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 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 TypeTree(tp: Type)(implicit ctx: Context):TypeTree[Type] = - Trees.TypeTree().withType(tp) - def New(tp: Type)(implicit ctx: Context): New[Type] = - Trees.New(TypeTree(tp)) + + 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 ArrayValue(elemtpt: TypedTree, elems: List[TypedTree])(implicit ctx: Context) = - Trees.ArrayValue(elemtpt, elems).withType(defn.ArrayType.appliedTo(elemtpt.tpe)) - def NamedArg[T](name: Name, arg: TypedTree)(implicit ctx: Context) = + + 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).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) + .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) + .withType(refType(sym)) + } + + def TypeDef(sym: TypeSymbol)(implicit ctx: Context): TypeDef[Type] = + Trees.TypeDef(Modifiers(sym), sym.name, TypeTree(sym.info)) + .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) + .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] = @@ -39,5 +219,16 @@ object TypedTrees { } 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/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 26d6fa312..c9b8afb90 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -12,7 +12,7 @@ import Contexts._ import Annotations._ import SymDenotations._ import Denotations._ -import Periods._ +import Periods._, Trees._ import scala.util.hashing.{ MurmurHash3 => hashing } import collection.mutable @@ -460,7 +460,8 @@ object Types { if (args.isEmpty) this else recur(this, typeParams, args) } - final def appliedTo(args: Type*)(implicit ctx: Context): Type = appliedTo(args.toList) + final def appliedTo(arg: Type)(implicit ctx: Context): Type = appliedTo(arg :: Nil) + final def appliedTo(arg1: Type, arg2: Type)(implicit ctx: Context): Type = appliedTo(arg1 :: arg2 :: Nil) final def objToAny(implicit ctx: Context) = if (typeSymbol == defn.ObjectClass && !ctx.phase.erasedTypes) defn.AnyType else this @@ -831,7 +832,7 @@ object Types { unique(new CachedRefinedType(parent, name, infof)) def apply(parent: Type, name: Name, info: Type)(implicit ctx: Context): RefinedType = - apply(parent, name, Function const info: (RefinedType => Type)) + apply(parent, name, scala.Function const info: (RefinedType => Type)) } // --- AndType/OrType --------------------------------------------------------------- @@ -1094,7 +1095,7 @@ object Types { } } - // ----- AnnotatedTypes ----------------------------------------------------------- + // ----- Annotated and Import types ----------------------------------------------- case class AnnotatedType(annots: List[Annotation], tpe: Type) extends UncachedProxyType { override def underlying(implicit ctx: Context): Type = tpe @@ -1109,6 +1110,8 @@ object Types { else AnnotatedType(annots, underlying) } + case class ImportType(expr: TypedTree) extends UncachedGroundType + // Special type objects ------------------------------------------------------------ case object NoType extends UncachedGroundType { diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala index 12b0971cf..9ba2c46e5 100644 --- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala +++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala @@ -5,6 +5,7 @@ package pickling import Contexts._, Symbols._, Types._, Names._, StdNames._, NameOps._, Scopes._, Decorators._ import SymDenotations._, UnPickler._, Constants._, Trees._, Annotations._, Positions._ +import TypedTrees._ import java.io.{ File, IOException } import java.lang.Integer.toHexString import scala.collection.{ mutable, immutable } @@ -36,7 +37,6 @@ class ClassfileParser( def srcfile = srcfile0 private def currentIsTopLevel = !(classRoot.name contains '$') - private val mk = makeTypedTree private def mismatchError(c: Symbol) = { throw new IOException("class file '%s' has location not matching its contents: contains ".format(in.file) + c) @@ -399,7 +399,7 @@ class ClassfileParser( for (i <- 0 until nargs) { val name = pool.getName(in.nextChar) parseAnnotArg(skip) match { - case Some(arg) => argbuf += mk.NamedArg(name, arg) + case Some(arg) => argbuf += tpd.NamedArg(name, arg) case None => hasError = !skip } } @@ -444,8 +444,8 @@ class ClassfileParser( case tpnme.BridgeATTR => sym.setFlag(Flags.Bridge) case tpnme.DeprecatedATTR => - val msg = mk.Literal(Constant("see corresponding Javadoc for more information.")) - val since = mk.Literal(Constant("")) + val msg = tpd.Literal(Constant("see corresponding Javadoc for more information.")) + val since = tpd.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 ee60f89ad..3d8be89b9 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._ +import Trees._, Positions._, TypedTrees._ import io.AbstractFile import scala.reflect.internal.pickling.PickleFormat._ import scala.collection.{ mutable, immutable } @@ -96,8 +96,6 @@ class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot: /** A map from refinement classes to their associated refinement types */ private val refinementTypes = mutable.HashMap[Symbol, RefinedType]() - private val mk = makeTypedTree - protected def errorBadSignature(msg: String) = { val ex = new BadSignature( s"""error reading Scala signature of $classRoot from $source: @@ -637,7 +635,7 @@ class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot: */ protected def readAnnotArg(i: Int): TypedTree = bytes(index(i)) match { case TREE => at(i, readTree) - case _ => mk.Literal(at(i, readConstant)) + case _ => tpd.Literal(at(i, readConstant)) } /** Read a ClassfileAnnotArg (argument to a classfile annotation) @@ -646,8 +644,8 @@ class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot: readByte() // skip the `annotargarray` tag val end = readNat() + readIndex // array elements are trees representing instances of scala.annotation.Annotation - mk.ArrayValue( - mk.TypeTree(defn.AnnotationClass.typeConstructor), + tpd.ArrayValue( + tpd.TypeTree(defn.AnnotationClass.typeConstructor), until(end, () => readClassfileAnnotArg(readNat()))) } @@ -675,11 +673,11 @@ class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot: if (isNameEntry(argref)) { val name = at(argref, readName) val arg = readClassfileAnnotArg(readNat()) - mk.NamedArg(name, arg) + tpd.NamedArg(name, arg) } else readAnnotArg(argref) } } - mk.New(atp, args.toList) + tpd.New(atp, args.toList) } /** Read an annotation and as a side effect store it into |