aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-08-16 19:01:08 +0200
committerMartin Odersky <odersky@gmail.com>2013-08-16 19:01:08 +0200
commit502f426981105df448896f635ef559cd72787c43 (patch)
treeca3a85271ae10c7f697dd3e88b07b7045bf81e2e /src/dotty/tools/dotc/typer
parentf540194f1b04c044c969772d5989d129264ea781 (diff)
downloaddotty-502f426981105df448896f635ef559cd72787c43.tar.gz
dotty-502f426981105df448896f635ef559cd72787c43.tar.bz2
dotty-502f426981105df448896f635ef559cd72787c43.zip
Various bugfixes for namer/typer/trees
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala10
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala74
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala13
3 files changed, 73 insertions, 24 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 334e21ccb..439210af4 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -154,13 +154,13 @@ trait Applications extends Compatibility { self: Typer =>
/** The arguments re-ordered so that each named argument matches the
* same-named formal parameter.
*/
- val orderedArgs =
+ lazy val orderedArgs =
if (hasNamedArg(args))
reorder(args.asInstanceOf[List[untpd.Tree]]).asInstanceOf[List[Arg]]
else
args
- methType match {
+ protected def init() = methType match {
case methType: MethodType =>
// apply the result type constraint, unless method type is dependent
if (!methType.isDependent)
@@ -248,9 +248,9 @@ trait Applications extends Compatibility { self: Typer =>
def findDefault(cx: Context): Type = {
if (cx eq NoContext) NoType
else if (cx.scope != cx.outer.scope &&
- cx.lookup(methRef.name)
+ cx.denotsNamed(methRef.name)
.filterWithPredicate(_.symbol == meth).exists) {
- val denot = cx.lookup(getterName).toDenot(NoPrefix)
+ val denot = cx.denotsNamed(getterName).toDenot(NoPrefix)
NamedType(NoPrefix, getterName).withDenot(denot)
} else findDefault(cx.outer)
}
@@ -368,6 +368,7 @@ trait Applications extends Compatibility { self: Typer =>
def fail(msg: => String) =
ok = false
def normalizedFun = EmptyTree
+ init()
}
/** Subtrait of Application for the cases where arguments are (typed or
@@ -403,6 +404,7 @@ trait Applications extends Compatibility { self: Typer =>
private var typedArgBuf = new mutable.ListBuffer[Tree]
private var liftedDefs: mutable.ListBuffer[Tree] = null
private var myNormalizedFun: Tree = fun
+ init()
def addArg(arg: Tree, formal: Type): Unit =
typedArgBuf += adapt(arg, formal)
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 12c812c22..024577b47 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -12,6 +12,7 @@ import util.Positions._
import util.SourcePosition
import collection.mutable
import annotation.tailrec
+import ErrorReporting._
import language.implicitConversions
trait NamerContextOps { this: Context =>
@@ -24,9 +25,13 @@ trait NamerContextOps { this: Context =>
sym
}
- def lookup(name: Name): PreDenotation =
- if (isClassDefContext) owner.asClass.membersNamed(name)
+ def denotsNamed(name: Name): PreDenotation =
+ if (owner.isClass) owner.asClass.membersNamed(name)
else scope.denotsNamed(name)
+
+ def effectiveScope =
+ if (owner != null && owner.isClass) owner.asClass.decls
+ else scope
}
/** This class attaches creates symbols from definitions and imports and gives them
@@ -106,25 +111,49 @@ class Namer { typer: Typer =>
* and store in symOfTree map.
*/
def createSymbol(tree: Tree)(implicit ctx: Context): Symbol = {
+
def privateWithinClass(mods: Modifiers) =
enclosingClassNamed(mods.privateWithin, mods.pos)
- val sym = tree match {
+
+ def record(tree: Tree, sym: Symbol): Symbol = {
+ symOfTree(tree) = sym
+ println(s"entered: $sym in ${ctx.owner} and ${ctx.effectiveScope}")
+ sym
+ }
+
+ def recordEnter(tree: Tree, sym: Symbol) = {
+ if (sym.owner is PackageClass) {
+ val preExisting = sym.owner.decls.lookup(sym.name)
+ if (preExisting.defRunId == ctx.runId)
+ ctx.error(s"${sym.showLocated} is compiled twice", tree.pos)
+ }
+ record(tree, ctx.enter(sym))
+ }
+
+ println(i"creating symbol for $tree")
+ tree match {
case tree: TypeDef if tree.isClassDef =>
- ctx.enter(ctx.newClassSymbol(
+ recordEnter(tree, ctx.newClassSymbol(
ctx.owner, tree.name, tree.mods.flags, new ClassCompleter(tree),
privateWithinClass(tree.mods), tree.pos, ctx.source.file))
+ case Thicket((moduleDef: ValDef) :: (modclsDef: TypeDef) :: Nil) =>
+ assert(moduleDef.mods is Module)
+ val module = ctx.newModuleSymbol(
+ ctx.owner, moduleDef.name, moduleDef.mods.flags, modclsDef.mods.flags,
+ (modul, modcls) => new ClassCompleter(modclsDef, modul),
+ privateWithinClass(moduleDef.mods), modclsDef.pos, ctx.source.file)
+ recordEnter(modclsDef, module.moduleClass)
+ recordEnter(moduleDef, module)
case tree: MemberDef =>
- ctx.enter(ctx.newSymbol(
+ recordEnter(tree, ctx.newSymbol(
ctx.owner, tree.name, tree.mods.flags, new Completer(tree),
privateWithinClass(tree.mods), tree.pos))
case imp: Import =>
- ctx.newSymbol(
- ctx.owner, nme.IMPORT, Synthetic, new Completer(tree), NoSymbol, tree.pos)
+ record(imp, ctx.newSymbol(
+ ctx.owner, nme.IMPORT, Synthetic, new Completer(tree), NoSymbol, tree.pos))
case _ =>
NoSymbol
}
- if (sym.exists) symOfTree(tree) = sym
- sym
}
/** All PackageClassInfoTypes come from here. */
@@ -165,6 +194,9 @@ class Namer { typer: Typer =>
ctx
case imp: Import =>
importContext(createSymbol(imp), imp.selectors)
+ case mdef: ModuleDef =>
+ createSymbol(expansion(mdef))
+ ctx
case mdef: MemberDef =>
expansion(mdef).toList foreach createSymbol
ctx
@@ -234,12 +266,13 @@ class Namer { typer: Typer =>
}
/** The completer for a symbol defined by a class definition */
- class ClassCompleter(original: TypeDef, override val decls: MutableScope = newScope)(implicit ctx: Context)
- extends ClassCompleterWithDecls(decls) {
+ class ClassCompleter(original: TypeDef, override val sourceModule: Symbol = NoSymbol)(implicit ctx: Context)
+ extends ClassCompleterWithDecls(newScope) {
override def complete(denot: SymDenotation): Unit = {
val cls = denot.symbol.asClass
def localContext = ctx.fresh.withOwner(cls)
- cls.info = classDefSig(original, cls, decls)(localContext)
+ println(s"completing ${cls.show}, sourceModule = ${sourceModule.show}")
+ cls.info = classDefSig(original, cls, decls.asInstanceOf[MutableScope])(localContext)
}
}
@@ -248,7 +281,7 @@ class Namer { typer: Typer =>
typedTree.getOrElseUpdate(tree, typer.typedExpanded(tree, pt))
def typedAheadType(tree: Tree, pt: Type = WildcardType)(implicit ctx: Context): tpd.Tree =
- typedAheadImpl(tree, WildcardType)(ctx retractMode Mode.PatternOrType addMode Mode.Type)
+ typedAheadImpl(tree, pt)(ctx retractMode Mode.PatternOrType addMode Mode.Type)
def typedAheadExpr(tree: Tree, pt: Type = WildcardType)(implicit ctx: Context): tpd.Tree =
typedAheadImpl(tree, pt)(ctx retractMode Mode.PatternOrType)
@@ -342,7 +375,7 @@ class Namer { typer: Typer =>
else typedAheadExpr(constr).tpe
}
- val TypeDef(_, _, impl @ Template(_, parents, self, body)) = cdef
+ val TypeDef(_, _, impl @ Template(constr, parents, self, body)) = cdef
val (params, rest) = body span {
case td: TypeDef => td.mods is Param
@@ -350,9 +383,20 @@ class Namer { typer: Typer =>
case _ => false
}
enterSyms(params)
+ def defaultSelfType =
+ if (cls is Module) TermRef.withSym(ctx.owner.thisType, cls.sourceModule.asTerm)
+ else NoType
+ // pre-set info, so that parent types can refer to type params
+ cls.info = ClassInfo(cls.owner.thisType, cls, Nil, decls, defaultSelfType)
val parentTypes = parents map parentType
val parentRefs = ctx.normalizeToRefs(parentTypes, cls, decls)
- val optSelfType = if (self.tpt.isEmpty) NoType else typedAheadType(self.tpt).tpe
+ val optSelfType =
+ if (self.tpt.isEmpty) defaultSelfType
+ else {
+ val t = typedAheadType(self.tpt).tpe
+ if (!t.isError) t else defaultSelfType
+ }
+ enterSym(constr)
enterSyms(rest)(inClassContext(cls, self.name))
ClassInfo(cls.owner.thisType, cls, parentRefs, decls, optSelfType)
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index b4e1335f8..6922111f4 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -268,11 +268,11 @@ class Typer extends Namer with Applications with Implicits {
}
// begin findRef
- if (ctx eq NoContext) previous
+ if (ctx.scope == null) previous
else {
val outer = ctx.outer
- if (ctx.scope ne outer.scope) {
- val defDenots = ctx.lookup(name)
+ if ((ctx.scope ne outer.scope) || (ctx.owner ne outer.owner)) {
+ val defDenots = ctx.denotsNamed(name)
if (defDenots.exists) {
val curOwner = ctx.owner
val pre = curOwner.thisType
@@ -299,6 +299,8 @@ class Typer extends Namer with Applications with Implicits {
}
// begin typedIdent
+ def kind = if (name.isTermName) "term" else "type" // !!! DEBUG
+ println(s"typed ident $kind $name in ${ctx.owner}")
if (ctx.mode is Mode.Pattern) {
if (name == nme.WILDCARD)
return tree.withType(pt)
@@ -369,7 +371,7 @@ class Typer extends Namer with Applications with Implicits {
case _ =>
val tpt1 = typedType(tree.tpt)
val cls = checkClassTypeWithStablePrefix(tpt1.tpe, tpt1.pos)
- checkInstantiatable(cls, tpt1.pos)
+ // todo in a later phase: checkInstantiatable(cls, tpt1.pos)
cpy.New(tree, tpt1).withType(tpt1.tpe)
}
@@ -594,7 +596,7 @@ class Typer extends Namer with Applications with Implicits {
assert(isFullyDefined(pt))
(EmptyTree, pt)
case original: DefDef =>
- val meth = ctx.lookup(original.name).first
+ val meth = symbolOfTree(original)
assert(meth.exists, meth)
(EmptyTree, meth.info.resultType)
case original =>
@@ -815,6 +817,7 @@ class Typer extends Namer with Applications with Implicits {
case tree: untpd.Import => typedImport(tree, sym)
case tree: untpd.PackageDef => typedPackageDef(tree)
case tree: untpd.Annotated => typedAnnotated(tree, pt)
+ case tree: untpd.TypedSplice => tree.tree
case untpd.EmptyTree => tpd.EmptyTree
case _ => typed(desugar(tree), pt)
}