aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/core/Annotations.scala12
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala23
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala3
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala8
-rw-r--r--src/dotty/tools/dotc/core/Trees.scala108
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala6
-rw-r--r--src/dotty/tools/dotc/core/TypedTreeGen.scala209
-rw-r--r--src/dotty/tools/dotc/core/Types.scala11
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala8
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala14
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