aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Typer.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-08-10 11:43:01 +0200
committerMartin Odersky <odersky@gmail.com>2013-08-10 12:10:10 +0200
commitd318cafbb92518a39c84539c0387c2c93815bb7a (patch)
tree0d822de681719bc4d01c91bda4e3064ea4c33e85 /src/dotty/tools/dotc/typer/Typer.scala
parent2fffa023502cbaffe0e282495e18aefe2bff0d22 (diff)
downloaddotty-d318cafbb92518a39c84539c0387c2c93815bb7a.tar.gz
dotty-d318cafbb92518a39c84539c0387c2c93815bb7a.tar.bz2
dotty-d318cafbb92518a39c84539c0387c2c93815bb7a.zip
Added typing of all forms of type trees.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Typer.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala97
1 files changed, 90 insertions, 7 deletions
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 7995da312..0869aff43 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -43,8 +43,9 @@ object Typer {
}
implicit class TreeDecorator(tree: Tree) {
- def exprType(implicit ctx: Context): Type = tree.tpe match {
+ def qualifierType(implicit ctx: Context): Type = tree.tpe match {
case tpe: TermRef if !tpe.symbol.isStable => tpe.info
+ case tpe: TypeRef => tpe.info
case tpe => tpe
}
}
@@ -69,7 +70,7 @@ class Typer extends Namer with Applications with Implicits {
*/
private var importedFromRoot: Set[Symbol] = Set()
- def typedSelection(site: Type, name: Name, pos: Position)(implicit ctx: Context): Type = {
+ def selectionType(site: Type, name: Name, pos: Position)(implicit ctx: Context): Type = {
val ref =
if (name == nme.CONSTRUCTOR) site.decl(name)
else site.member(name)
@@ -83,6 +84,12 @@ class Typer extends Namer with Applications with Implicits {
}
}
+ def checkedSelectionType(qual1: Tree, tree: untpd.RefTree)(implicit ctx: Context): Type = {
+ val ownType = selectionType(qual1.qualifierType, tree.name, tree.pos)
+ if (!ownType.isError) checkAccessible(ownType, qual1.isInstanceOf[Super], tree.pos)
+ ownType
+ }
+
def checkAccessible(tpe: Type, superAccess: Boolean, pos: Position)(implicit ctx: Context): Type = tpe match {
case tpe: NamedType =>
val pre = tpe.prefix
@@ -215,9 +222,9 @@ class Typer extends Namer with Applications with Implicits {
}
selectors match {
case Pair(Ident(from), Ident(`name`)) :: rest =>
- checkUnambiguous(typedSelection(site, name, tree.pos))
+ checkUnambiguous(selectionType(site, name, tree.pos))
case Ident(`name`) :: rest =>
- checkUnambiguous(typedSelection(site, name, tree.pos))
+ checkUnambiguous(selectionType(site, name, tree.pos))
case _ :: rest =>
namedImportRef(site, rest)
case nil =>
@@ -301,9 +308,7 @@ class Typer extends Namer with Applications with Implicits {
def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = {
val qual1 = typedExpr(tree.qualifier, RefinedType(WildcardType, tree.name, pt))
- val ownType = typedSelection(qual1.exprType, tree.name, tree.pos)
- if (!ownType.isError) checkAccessible(ownType, qual1.isInstanceOf[Super], tree.pos)
- cpy.Select(tree, qual1, tree.name).withType(ownType)
+ cpy.Select(tree, qual1, tree.name).withType(checkedSelectionType(qual1, tree))
}
def typedThis(tree: untpd.This)(implicit ctx: Context): Tree = {
@@ -539,6 +544,84 @@ class Typer extends Namer with Applications with Implicits {
cpy.SeqLiteral(tree, elems1) withType ctx.lub(elems1.tpes)
}
+ def typedTypeTree(tree: untpd.TypeTree)(implicit ctx: Context): TypeTree = {
+ val (original1, ownType) = tree.original match {
+ case untpd.EmptyTree =>
+ (EmptyTree, errorType("internal error: missing type in TypeTree", tree.pos))
+ case original: DefDef =>
+ val meth = ctx.lookup(original.name).first
+ assert(meth.exists, meth)
+ (EmptyTree, meth.info.resultType)
+ case original =>
+ val original1 = typed(original)
+ (original1, original1.tpe)
+ }
+ cpy.TypeTree(tree, original1) withType ownType
+ }
+
+ def typedSingletonTypeTree(tree: untpd.SingletonTypeTree)(implicit ctx: Context): SingletonTypeTree = {
+ val ref1 = typedExpr(tree.ref)
+ checkStable(ref1.qualifierType, tree.pos)
+ cpy.SingletonTypeTree(tree, ref1) withType ref1.tpe
+ }
+
+ def typedSelectFromTypeTree(tree: untpd.SelectFromTypeTree, pt: Type)(implicit ctx: Context): SelectFromTypeTree = {
+ val qual1 = typedType(tree.qualifier, RefinedType(WildcardType, tree.name, pt))
+ cpy.SelectFromTypeTree(tree, qual1, tree.name).withType(checkedSelectionType(qual1, tree))
+ }
+
+ def typedAndTypeTree(tree: untpd.AndTypeTree, pt: Type)(implicit ctx: Context): AndTypeTree = {
+ val left1 = typed(tree.left)
+ val right1 = typed(tree.right)
+ cpy.AndTypeTree(tree, left1, right1) withType left1.tpe & right1.tpe
+ }
+
+ def typedOrTypeTree(tree: untpd.OrTypeTree, pt: Type)(implicit ctx: Context): OrTypeTree = {
+ val left1 = typed(tree.left, pt)
+ val right1 = typed(tree.right, pt)
+ cpy.OrTypeTree(tree, left1, right1) withType left1.tpe | right1.tpe
+ }
+
+ def typedRefinedTypeTree(tree: untpd.RefinedTypeTree)(implicit ctx: Context): RefinedTypeTree = {
+ val tpt1 = typedAheadType(tree.tpt)
+ val refineClsDef = desugar.refinedTypeToClass(tree)
+ val throwAwayScopeCtx = ctx.fresh.withNewScope
+ val refineCls = createSymbol(refineClsDef)(throwAwayScopeCtx).asClass
+ val TypeDef(_, _, Template(_, _, _, refinements1)) = typed(refineClsDef)
+ assert(tree.refinements.length == refinements1.length, s"${tree.refinements} != $refinements1")
+ def addRefinement(parent: Type, refinement: Tree): Type = {
+ foreachSubTreeOf(refinement) {
+ case tree: RefTree =>
+ if (tree.symbol.owner == refineCls && tree.pos.start <= tree.symbol.pos.end)
+ ctx.error(s"illegal forward reference in refinement", tree.pos)
+ case _ =>
+ }
+ val rsym = refinement.symbol
+ val rinfo = if (rsym is Accessor) rsym.info.resultType else rsym.info
+ RefinedType(parent, rsym.name, rt => rinfo.substThis(refineCls, RefinedThis(rt)))
+ }
+ cpy.RefinedTypeTree(tree, tpt1, refinements1) withType
+ (tpt1.tpe /: refinements1)(addRefinement)
+ }
+
+ def typedAppliedTypeTree(tree: untpd.AppliedTypeTree)(implicit ctx: Context): AppliedTypeTree = {
+ val tpt1 = typed(tree.tpt)
+ val args1 = tree.args map (typed(_))
+ val tparams = tpt1.tpe.typeParams
+ if (args1.length != tparams.length)
+ ctx.error(s"wrong number of type arguments for ${tpt1.tpe.show}, should be ${tparams.length}")
+ // todo in later phase: check arguments conform to parameter bounds
+ cpy.AppliedTypeTree(tree, tpt1, args1) withType tpt1.tpe.appliedTo(args1.tpes)
+ }
+
+ def typedTypeBounds(tree: untpd.TypeBoundsTree)(implicit ctx: Context): TypeBoundsTree = {
+ val lo1 = typed(tree.lo)
+ val hi1 = typed(tree.hi)
+ if (!(lo1.tpe <:< hi1.tpe))
+ ctx.error(s"lower bound ${lo1.tpe.show} does not conform to upper bound ${hi1.tpe.show}", tree.pos)
+ cpy.TypeBoundsTree(tree, lo1, hi1) withType TypeBounds(lo1.tpe, hi1.tpe)
+ }
+
def typedBind(tree: untpd.Bind, pt: Type)(implicit ctx: Context): Bind = {
val body1 = typed(tree.body, pt)
val sym = ctx.newSymbol(ctx.owner, tree.name.asTermName, EmptyFlags, pt, coord = tree.pos)