aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Typer.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-08-10 23:12:16 +0200
committerMartin Odersky <odersky@gmail.com>2013-08-10 23:12:16 +0200
commit775b2a1857290f5e83036148dbbfcdc3a29a12d2 (patch)
treeafe3f69a6be42879a8b25590f84bb2bb2a2c251e /src/dotty/tools/dotc/typer/Typer.scala
parent4b32ec471bafe988b64563aaabf2d273220a8644 (diff)
downloaddotty-775b2a1857290f5e83036148dbbfcdc3a29a12d2.tar.gz
dotty-775b2a1857290f5e83036148dbbfcdc3a29a12d2.tar.bz2
dotty-775b2a1857290f5e83036148dbbfcdc3a29a12d2.zip
Finished rest of typer.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Typer.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala298
1 files changed, 198 insertions, 100 deletions
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index e81672eda..9bdfea871 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -14,6 +14,7 @@ import Contexts._
import Symbols._
import Types._
import SymDenotations._
+import Annotations._
import Names._
import NameOps._
import Flags._
@@ -56,6 +57,8 @@ object Typer {
value
}
}
+
+ class SelectionProto(name: Name, tp: Type) extends RefinedType(WildcardType, name)(_ => tp)
}
class Typer extends Namer with Applications with Implicits {
@@ -90,6 +93,12 @@ class Typer extends Namer with Applications with Implicits {
ownType
}
+ def checkValue(tpe: Type, proto: Type, pos: Position)(implicit ctx: Context): Unit =
+ if (!(proto.isInstanceOf[SelectionProto])) {
+ val sym = tpe.termSymbol
+ if ((sym is Package) || (sym is JavaModule)) ctx.error(s"${sym.show} is not a value", pos)
+ }
+
def checkAccessible(tpe: Type, superAccess: Boolean, pos: Position)(implicit ctx: Context): Type = tpe match {
case tpe: NamedType =>
val pre = tpe.prefix
@@ -286,29 +295,36 @@ class Typer extends Namer with Applications with Implicits {
}
// begin typedIdent
- if (name == nme.WILDCARD && (ctx.mode is Mode.Pattern))
- tree.withType(pt)
- else {
- val saved = importedFromRoot
- importedFromRoot = Set()
+ if (ctx.mode is Mode.Pattern) {
+ if (name == nme.WILDCARD)
+ return tree.withType(pt)
+ if (isVarPattern(tree))
+ return typed(untpd.Bind(name, untpd.Ident(nme.WILDCARD)).withPos(tree.pos), pt)
+ }
- val rawType =
- try findRef(NoType, BindingPrec.nothingBound, NoContext)
- finally importedFromRoot = saved
+ val saved = importedFromRoot
+ importedFromRoot = Set()
- val ownType =
- if (rawType.exists) checkAccessible(rawType, superAccess = false, tree.pos)
- else {
- ctx.error(s"not found: $name", tree.pos)
- ErrorType
- }
- tree.withType(ownType.underlyingIfRepeated)
- }
+ val rawType =
+ try findRef(NoType, BindingPrec.nothingBound, NoContext)
+ finally importedFromRoot = saved
+ checkValue(rawType, pt, tree.pos)
+
+ val ownType =
+ if (rawType.exists)
+ checkAccessible(rawType, superAccess = false, tree.pos)
+ else {
+ ctx.error(s"not found: $name", tree.pos)
+ ErrorType
+ }
+ tree.withType(ownType.underlyingIfRepeated)
}
def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = {
- val qual1 = typedExpr(tree.qualifier, RefinedType(WildcardType, tree.name, pt))
- cpy.Select(tree, qual1, tree.name).withType(checkedSelectionType(qual1, tree))
+ val qual1 = typedExpr(tree.qualifier, new SelectionProto(tree.name, pt))
+ val ownType = checkedSelectionType(qual1, tree)
+ checkValue(ownType, pt, tree.pos)
+ cpy.Select(tree, qual1, tree.name).withType(ownType)
}
def typedThis(tree: untpd.This)(implicit ctx: Context): Tree = {
@@ -340,23 +356,37 @@ class Typer extends Namer with Applications with Implicits {
def typedLiteral(tree: untpd.Literal)(implicit ctx: Context) =
tree.withType(if (tree.const.tag == UnitTag) defn.UnitType else ConstantType(tree.const))
- def typedNew(tree: untpd.New)(implicit ctx: Context) = {
- val tpt1 = typedType(tree.tpt)
- val cls = checkClassTypeWithStablePrefix(tpt1.tpe, tpt1.pos)
- checkInstantiatable(cls, tpt1.pos)
- cpy.New(tree, tpt1).withType(tpt1.tpe)
+ def typedNew(tree: untpd.New, pt: Type)(implicit ctx: Context) = tree.tpt match {
+ case templ: Template =>
+ import untpd._
+ val x = tpnme.ANON_CLASS
+ val clsDef = TypeDef(Modifiers(Final), x, templ)
+ typed(cpy.Block(tree, clsDef :: Nil, New(Ident(x), Nil)), pt)
+ case _ =>
+ val tpt1 = typedType(tree.tpt)
+ val cls = checkClassTypeWithStablePrefix(tpt1.tpe, tpt1.pos)
+ checkInstantiatable(cls, tpt1.pos)
+ cpy.New(tree, tpt1).withType(tpt1.tpe)
}
- def typedPair(tree: untpd.Pair)(implicit ctx: Context) = {
- val left1 = typed(tree.left)
- val right1 = typed(tree.right)
+ def typedPair(tree: untpd.Pair, pt: Type)(implicit ctx: Context) = {
+ val (leftProto, rightProto) = pt.typeArgs match {
+ case l :: r :: Nil if pt.typeSymbol == defn.PairClass => (l, r)
+ case _ => (WildcardType, WildcardType)
+ }
+ val left1 = typed(tree.left, leftProto)
+ val right1 = typed(tree.right, rightProto)
cpy.Pair(tree, left1, right1).withType(defn.PairType.appliedTo(left1.tpe :: right1.tpe :: Nil))
}
- def typedTyped(tree: untpd.Typed)(implicit ctx: Context) = {
- val tpt1 = typedType(tree.tpt)
- val expr1 = typedExpr(tree.expr, tpt1.tpe)
- cpy.Typed(tree, tpt1, expr1).withType(tpt1.tpe)
+ def typedTyped(tree: untpd.Typed, pt: Type)(implicit ctx: Context): Tree = tree.expr match {
+ case id: Ident if (ctx.mode is Mode.Pattern) && isVarPattern(id) && id.name != nme.WILDCARD =>
+ import untpd._
+ typed(Bind(id.name, Typed(Ident(nme.WILDCARD), tree.tpt)).withPos(id.pos))
+ case _ =>
+ val tpt1 = typedType(tree.tpt)
+ val expr1 = typedExpr(tree.expr, tpt1.tpe)
+ cpy.Typed(tree, tpt1, expr1).withType(tpt1.tpe)
}
def typedNamedArg(tree: untpd.NamedArg, pt: Type)(implicit ctx: Context) = {
@@ -364,9 +394,9 @@ class Typer extends Namer with Applications with Implicits {
cpy.NamedArg(tree, tree.name, arg1).withType(arg1.tpe)
}
- def typedAssign(tree: untpd.Assign)(implicit ctx: Context) = tree.lhs match {
+ def typedAssign(tree: untpd.Assign, pt: Type)(implicit ctx: Context) = tree.lhs match {
case lhs @ Apply(fn, args) =>
- typed(cpy.Apply(lhs, untpd.Select(fn, nme.update), args :+ tree.rhs))
+ typed(cpy.Apply(lhs, untpd.Select(fn, nme.update), args :+ tree.rhs), pt)
case lhs =>
val lhs1 = typed(lhs)
def reassignmentToVal =
@@ -393,7 +423,7 @@ class Typer extends Namer with Applications with Implicits {
}
}
- def typedBlock(tree: Block, pt: Type)(implicit ctx: Context) = {
+ def typedBlock(tree: untpd.Block, pt: Type)(implicit ctx: Context) = {
val exprCtx = enterSyms(tree.stats)
val stats1 = typedStats(tree.stats, ctx.owner)
val expr1 = typedExpr(tree.expr, pt)(exprCtx)
@@ -410,31 +440,37 @@ class Typer extends Namer with Applications with Implicits {
def typedIf(tree: untpd.If, pt: Type)(implicit ctx: Context) = {
val cond1 = typed(tree.cond, defn.BooleanType)
val thenp1 = typed(tree.thenp, pt)
- val elsep1 = typed(tree.elsep, pt)
+ val elsep1 = typed(if (tree.elsep.isEmpty) unitLiteral else tree.elsep, pt)
cpy.If(tree, cond1, thenp1, elsep1).withType(thenp1.tpe | elsep1.tpe)
}
def typedFunction(tree: untpd.Function, pt: Type)(implicit ctx: Context) = {
- val params = tree.args.asInstanceOf[List[ValDef]]
- val protoFormals: List[Type] = pt match {
- case _ if pt.typeSymbol == defn.FunctionClass(params.length) =>
- pt.typeArgs take params.length
- case SAMType(meth) =>
- val MethodType(_, paramTypes) = meth.info
- paramTypes
- case _ =>
- params map Function.const(WildcardType)
+ val untpd.Function(args, body) = tree
+ if (ctx.mode is Mode.Type)
+ typed(cpy.AppliedTypeTree(tree,
+ ref(defn.FunctionClass(args.length).typeConstructor), args :+ body), pt)
+ else {
+ val params = args.asInstanceOf[List[ValDef]]
+ val protoFormals: List[Type] = pt match {
+ case _ if pt.typeSymbol == defn.FunctionClass(params.length) =>
+ pt.typeArgs take params.length
+ case SAMType(meth) =>
+ val MethodType(_, paramTypes) = meth.info
+ paramTypes
+ case _ =>
+ params map Function.const(WildcardType)
+ }
+ val inferredParams: List[untpd.ValDef] =
+ for ((param, formal) <- params zip protoFormals) yield
+ if (!param.tpt.isEmpty) param
+ else {
+ val paramType =
+ if (isFullyDefined(formal)) formal
+ else errorType(s"missing parameter type", param.pos)
+ cpy.ValDef(param, param.mods, param.name, untpd.TypeTree(paramType), param.rhs)
+ }
+ typed(desugar.makeClosure(inferredParams, body), pt)
}
- val inferredParams: List[untpd.ValDef] =
- for ((param, formal) <- params zip protoFormals) yield
- if (!param.tpt.isEmpty) param
- else {
- val paramType =
- if (isFullyDefined(formal)) formal
- else errorType(s"missing parameter type", param.pos)
- cpy.ValDef(param, param.mods, param.name, untpd.TypeTree(paramType), param.rhs)
- }
- typed(desugar.makeClosure(inferredParams, tree.body), pt)
}
def typedClosure(tree: untpd.Closure, pt: Type)(implicit ctx: Context) = {
@@ -451,27 +487,31 @@ class Typer extends Namer with Applications with Implicits {
cpy.Closure(tree, env1, meth1, EmptyTree).withType(ownType)
}
- def typedMatch(tree: untpd.Match, pt: Type)(implicit ctx: Context) = {
- val sel1 = typedExpr(tree.selector)
- val selType =
- if (isFullyDefined(sel1.tpe)) sel1.tpe
- else errorType("internal error: type of pattern selector is not fully defined", tree.pos)
-
- /** gadtSyms = "all type parameters of enclosing methods that appear
- * non-variantly in the selector type */
- val gadtSyms: Set[Symbol] = {
- val accu = new TypeAccumulator[Set[Symbol]] {
- def apply(tsyms: Set[Symbol], t: Type): Set[Symbol] = {
- val tsyms1 = t match {
- case tr: TypeRef if (tr.symbol is TypeParam) && tr.symbol.owner.isTerm && variance == 0 =>
- tsyms + tr.symbol
- case _ =>
- tsyms
+ def typedMatch(tree: untpd.Match, pt: Type)(implicit ctx: Context) = tree.selector match {
+ case EmptyTree =>
+ typed(desugar.makeCaseLambda(tree.cases) withPos tree.pos, pt)
+ case _ =>
+ val sel1 = typedExpr(tree.selector)
+ val selType =
+ if (isFullyDefined(sel1.tpe)) sel1.tpe
+ else errorType("internal error: type of pattern selector is not fully defined", tree.pos)
+
+ /** gadtSyms = "all type parameters of enclosing methods that appear
+ * non-variantly in the selector type
+ */
+ val gadtSyms: Set[Symbol] = {
+ val accu = new TypeAccumulator[Set[Symbol]] {
+ def apply(tsyms: Set[Symbol], t: Type): Set[Symbol] = {
+ val tsyms1 = t match {
+ case tr: TypeRef if (tr.symbol is TypeParam) && tr.symbol.owner.isTerm && variance == 0 =>
+ tsyms + tr.symbol
+ case _ =>
+ tsyms
+ }
+ foldOver(tsyms1, t)
}
- foldOver(tsyms1, t)
}
- }
- accu(Set.empty, selType)
+ accu(Set.empty, selType)
}
def typedCase(tree: untpd.CaseDef): CaseDef = {
@@ -544,10 +584,11 @@ 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 = {
+ def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree = {
val (original1, ownType) = tree.original match {
case untpd.EmptyTree =>
- (EmptyTree, errorType("internal error: missing type in TypeTree", tree.pos))
+ assert(isFullyDefined(pt))
+ (EmptyTree, pt)
case original: DefDef =>
val meth = ctx.lookup(original.name).first
assert(meth.exists, meth)
@@ -566,19 +607,19 @@ class Typer extends Namer with Applications with Implicits {
}
def typedSelectFromTypeTree(tree: untpd.SelectFromTypeTree, pt: Type)(implicit ctx: Context): SelectFromTypeTree = {
- val qual1 = typedType(tree.qualifier, RefinedType(WildcardType, tree.name, pt))
+ val qual1 = typedType(tree.qualifier, new SelectionProto(tree.name, pt))
cpy.SelectFromTypeTree(tree, qual1, tree.name).withType(checkedSelectionType(qual1, tree))
}
- def typedAndTypeTree(tree: untpd.AndTypeTree, pt: Type)(implicit ctx: Context): AndTypeTree = {
+ def typedAndTypeTree(tree: untpd.AndTypeTree)(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)
+ def typedOrTypeTree(tree: untpd.OrTypeTree)(implicit ctx: Context): OrTypeTree = {
+ val left1 = typed(tree.left)
+ val right1 = typed(tree.right)
cpy.OrTypeTree(tree, left1, right1) withType left1.tpe | right1.tpe
}
@@ -614,7 +655,7 @@ class Typer extends Namer with Applications with Implicits {
cpy.AppliedTypeTree(tree, tpt1, args1) withType tpt1.tpe.appliedTo(args1.tpes)
}
- def typedTypeBounds(tree: untpd.TypeBoundsTree)(implicit ctx: Context): TypeBoundsTree = {
+ def typedTypeBoundsTree(tree: untpd.TypeBoundsTree)(implicit ctx: Context): TypeBoundsTree = {
val lo1 = typed(tree.lo)
val hi1 = typed(tree.hi)
if (!(lo1.tpe <:< hi1.tpe))
@@ -698,6 +739,29 @@ class Typer extends Namer with Applications with Implicits {
cpy.Import(imp, expr1, imp.selectors).withType(sym.symRef)
}
+ def typedAnnotated(tree: untpd.Annotated, pt: Type)(implicit ctx: Context): Tree = {
+ val annot1 = typed(tree.annot, defn.AnnotationClass.typeConstructor)
+ val arg1 = typed(tree.arg, pt)
+ val ownType = AnnotatedType(Annotation(annot1), arg1.tpe)
+ if (ctx.mode is Mode.Type)
+ cpy.Annotated(tree, annot1, arg1) withType ownType
+ else
+ cpy.Typed(tree, arg1, TypeTree(ownType)) withType ownType
+ }
+
+ def typedPackageDef(tree: untpd.PackageDef)(implicit ctx: Context): Tree = {
+ val pid1 = typed(tree.pid)
+ val pkg = pid1.symbol
+ val nestedCtx =
+ if (pkg is Package) ctx.fresh withOwner pkg.moduleClass
+ else {
+ ctx.error(s"${pkg.show} is not a packge")
+ ctx
+ }
+ val stats1 = typedStats(tree.stats, NoSymbol)(nestedCtx)
+ cpy.PackageDef(tree, pid1.asInstanceOf[RefTree], stats1) withType pkg.symRef
+ }
+
def typedExpanded(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = {
val sym = symOfTree.remove(tree).getOrElse(NoSymbol)
sym.ensureCompleted()
@@ -705,6 +769,37 @@ class Typer extends Namer with Applications with Implicits {
typedTree remove tree match {
case Some(tree1) => tree1
case none => tree match {
+ case tree: untpd.Ident => typedIdent(tree, pt)
+ case tree: untpd.Select => typedSelect(tree, pt)
+ case tree: untpd.This => typedThis(tree)
+ case tree: untpd.Super => typedSuper(tree)
+ case tree: untpd.Apply => typedApply(tree, pt)
+ case tree: untpd.TypeApply => typedTypeApply(tree, pt)
+ case tree: untpd.Literal => typedLiteral(tree)
+ case tree: untpd.New => typedNew(tree, pt)
+ case tree: untpd.Pair => typedPair(tree, pt)
+ case tree: untpd.Typed => typedTyped(tree, pt)
+ case tree: untpd.NamedArg => typedNamedArg(tree, pt)
+ case tree: untpd.Assign => typedAssign(tree, pt)
+ case tree: untpd.Block => typedBlock(tree, pt)
+ case tree: untpd.If => typedIf(tree, pt)
+ case tree: untpd.Function => typedFunction(tree, pt)
+ case tree: untpd.Closure => typedClosure(tree, pt)
+ case tree: untpd.Match => typedMatch(tree, pt)
+ case tree: untpd.Return => typedReturn(tree)
+ case tree: untpd.Try => typedTry(tree, pt)
+ case tree: untpd.Throw => typedThrow(tree)
+ case tree: untpd.SeqLiteral => typedSeqLiteral(tree, pt)
+ case tree: untpd.TypeTree => typedTypeTree(tree, pt)
+ case tree: untpd.SingletonTypeTree => typedSingletonTypeTree(tree)
+ case tree: untpd.SelectFromTypeTree => typedSelectFromTypeTree(tree, pt)
+ case tree: untpd.AndTypeTree => typedAndTypeTree(tree)
+ case tree: untpd.OrTypeTree => typedOrTypeTree(tree)
+ case tree: untpd.RefinedTypeTree => typedRefinedTypeTree(tree)
+ case tree: untpd.AppliedTypeTree => typedAppliedTypeTree(tree)
+ case tree: untpd.TypeBoundsTree => typedTypeBoundsTree(tree)
+ case tree: untpd.Bind => typedBind(tree, pt)
+ case tree: untpd.Alternative => typedAlternative(tree, pt)
case tree: untpd.ValDef =>
typedValDef(tree, sym)(localContext)
case tree: untpd.DefDef =>
@@ -713,31 +808,32 @@ class Typer extends Namer with Applications with Implicits {
case tree: untpd.TypeDef =>
if (tree.isClassDef) typedClassDef(tree, sym.asClass)(localContext)
else typedTypeDef(tree, sym)(localContext.withNewScope)
- case tree: untpd.Import =>
- typedImport(tree, sym)
- case tree: untpd.TypeTree =>
- if (!tree.isEmpty) typedType(tree.original, pt)
- else {
- assert(!pt.isInstanceOf[WildcardType])
- tree.withType(pt)
- }
- case untpd.EmptyTree =>
- tpd.EmptyTree
+ case tree: untpd.Import => typedImport(tree, sym)
+ case tree: untpd.PackageDef => typedPackageDef(tree)
+ case tree: untpd.Annotated => typedAnnotated(tree, pt)
+ case untpd.EmptyTree => tpd.EmptyTree
+ case _ => typed(desugar(tree), pt)
}
}
}
def typed(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = {
- val xtree =
- tree match {
- case tree: untpd.MemberDef =>
- expandedTree remove tree match {
- case Some(xtree) => xtree
- case none => tree
- }
- case _ => tree
- }
- val tree1 = typedExpanded(xtree, pt)
+
+ def getExpansion(tree: untpd.Tree) = tree match {
+ case tree: untpd.MemberDef =>
+ expandedTree remove tree match {
+ case Some(xtree) => xtree
+ case none => tree
+ }
+ case _ => tree
+ }
+
+ def encodeName(tree: untpd.Tree) = tree match {
+ case tree: NameTree => tree.withName(tree.name.encode)
+ case _ => tree
+ }
+
+ val tree1 = typedExpanded(encodeName(getExpansion(tree)), pt)
ctx.interpolateUndetVars(tree1.tpe.widen, tree1.pos)
adapt(tree1, pt)
}
@@ -755,6 +851,8 @@ class Typer extends Namer with Applications with Implicits {
case (mdef: untpd.MemberDef) :: rest =>
buf += typed(mdef)
traverse(rest)
+ case Thicket(stats) :: rest =>
+ traverse(stats ++ rest)
case stat :: rest =>
val nestedCtx = if (exprOwner == ctx.owner) ctx else ctx.fresh.withOwner(exprOwner)
buf += typed(stat)(nestedCtx)