diff options
author | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2015-03-26 15:42:44 +0100 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2015-03-26 16:20:33 +0100 |
commit | 7baead9f9644bffe51a5c6e884cd6c516205fbe2 (patch) | |
tree | 596bce20dc201f1d8c52410cf7b8385a0016ee99 /src/dotty/tools/dotc/typer/Namer.scala | |
parent | 25af81475b3e4f387caa67194409e9b595a3b2ea (diff) | |
download | dotty-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.scala | 50 |
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) */ |