aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Namer.scala
diff options
context:
space:
mode:
authorDmitry Petrashko <dmitry.petrashko@gmail.com>2015-03-26 15:42:44 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2015-03-26 16:20:33 +0100
commit7baead9f9644bffe51a5c6e884cd6c516205fbe2 (patch)
tree596bce20dc201f1d8c52410cf7b8385a0016ee99 /src/dotty/tools/dotc/typer/Namer.scala
parent25af81475b3e4f387caa67194409e9b595a3b2ea (diff)
downloaddotty-7baead9f9644bffe51a5c6e884cd6c516205fbe2.tar.gz
dotty-7baead9f9644bffe51a5c6e884cd6c516205fbe2.tar.bz2
dotty-7baead9f9644bffe51a5c6e884cd6c516205fbe2.zip
Add companion link symbols early only if companion actually exists
Otherwise we'll trigger early creation of companions that could shadow something.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Namer.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala50
1 files changed, 45 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 357860290..414f6e517 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -395,32 +395,72 @@ class Namer { typer: Typer =>
/** Create top-level symbols for statements and enter them into symbol table */
def index(stats: List[Tree])(implicit ctx: Context): Context = {
+ val classDef = mutable.Map[TypeName, TypeDef]()
+ val moduleDef = mutable.Map[TypeName, TypeDef]()
+
/** Merge the definitions of a synthetic companion generated by a case class
* and the real companion, if both exist.
*/
def mergeCompanionDefs() = {
- val classDef = mutable.Map[TypeName, TypeDef]()
for (cdef @ TypeDef(name, _) <- stats)
- if (cdef.isClassDef) classDef(name) = cdef
- for (mdef @ ModuleDef(name, _) <- stats)
+ if (cdef.isClassDef) {
+ classDef(name) = cdef
+ cdef.attachmentOrElse(ExpandedTree, cdef) match {
+ case Thicket(cls :: mval :: (mcls @ TypeDef(_, _: Template)) :: crest) =>
+ moduleDef(name) = mcls
+ case _ =>
+ }
+ }
+ for (mdef @ ModuleDef(name, _) <- stats) {
+ val typName = name.toTypeName
+ val Thicket(vdef :: (mcls @ TypeDef(_, impl: Template)) :: Nil) = mdef.attachment(ExpandedTree)
+ moduleDef(typName) = mcls
classDef get name.toTypeName match {
case Some(cdef) =>
- val Thicket(vdef :: (mcls @ TypeDef(_, impl: Template)) :: Nil) = mdef.attachment(ExpandedTree)
cdef.attachmentOrElse(ExpandedTree, cdef) match {
case Thicket(cls :: mval :: TypeDef(_, compimpl: Template) :: crest) =>
val mcls1 = cpy.TypeDef(mcls)(
rhs = cpy.Template(impl)(body = compimpl.body ++ impl.body))
mdef.putAttachment(ExpandedTree, Thicket(vdef :: mcls1 :: Nil))
+ moduleDef(typName) = mcls1
cdef.putAttachment(ExpandedTree, Thicket(cls :: crest))
case _ =>
}
case none =>
}
+ }
+ }
+
+ def createLinks(classTree: TypeDef, moduleTree: TypeDef)(implicit ctx: Context) = {
+ val claz = ctx.denotNamed(classTree.name.encode)
+ val modl = ctx.denotNamed(moduleTree.name.encode)
+ ctx.newSymbol(
+ owner = modl.symbol,
+ name = nme.COMPANION_CLASS_METHOD,
+ flags = Flags.Synthetic | Flags.Private,
+ info = ExprType(claz.symbol.typeRef)).entered
+ ctx.newSymbol(
+ owner = claz.symbol,
+ name = nme.COMPANION_MODULE_METHOD,
+ flags = Flags.Synthetic | Flags.Private,
+ info = ExprType(modl.symbol.typeRef)).entered
+ }
+
+ def createCompanionLinks(implicit ctx: Context): Unit = {
+ for (cdef @ TypeDef(name, _) <- classDef.values) {
+ moduleDef.getOrElse(name, EmptyTree) match {
+ case t: TypeDef =>
+ createLinks(cdef, t)
+ case EmptyTree =>
+ }
+ }
}
stats foreach expand
mergeCompanionDefs()
- (ctx /: stats) ((ctx, stat) => indexExpanded(stat)(ctx))
+ val ctxWithStats = (ctx /: stats) ((ctx, stat) => indexExpanded(stat)(ctx))
+ createCompanionLinks(ctxWithStats)
+ ctxWithStats
}
/** The completer of a symbol defined by a member def or import (except ClassSymbols) */