diff options
author | VladimirNik <vladimir.nikolaev9@gmail.com> | 2016-03-07 17:00:47 +0100 |
---|---|---|
committer | VladimirNik <vladimir.nikolaev9@gmail.com> | 2016-03-07 17:09:47 +0100 |
commit | f1348f79566277ce72e1e4e070bf94a54b0f787e (patch) | |
tree | 99f23fd5ab12c2b33ad87731ac6816b2e5c8d052 /src/dotty/tools/dotc/transform/FirstTransform.scala | |
parent | 742ae7552cc0ebea700ddcb5892a673a1eaca967 (diff) | |
download | dotty-f1348f79566277ce72e1e4e070bf94a54b0f787e.tar.gz dotty-f1348f79566277ce72e1e4e070bf94a54b0f787e.tar.bz2 dotty-f1348f79566277ce72e1e4e070bf94a54b0f787e.zip |
Fix for separate compilation with value class issue (missing companion object - #1137)
Diffstat (limited to 'src/dotty/tools/dotc/transform/FirstTransform.scala')
-rw-r--r-- | src/dotty/tools/dotc/transform/FirstTransform.scala | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/src/dotty/tools/dotc/transform/FirstTransform.scala b/src/dotty/tools/dotc/transform/FirstTransform.scala index c24c5bbd9..7be1a7bd1 100644 --- a/src/dotty/tools/dotc/transform/FirstTransform.scala +++ b/src/dotty/tools/dotc/transform/FirstTransform.scala @@ -44,15 +44,32 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer wi this } - def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type = tp - - override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = tree match { - case Select(qual, _) if tree.symbol.exists => - assert(qual.tpe derivesFrom tree.symbol.owner, i"non member selection of ${tree.symbol.showLocated} from ${qual.tpe}") - case _: TypeTree => - case _: Import | _: NamedArg | _: TypTree => - assert(false, i"illegal tree: $tree") - case _ => + def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type = { + tp match { + //create companions for value classes that are not from currently compiled source file + case tp@ClassInfo(_, cls, _, decls, _) + if (ValueClasses.isDerivedValueClass(cls)) && + !sym.isDefinedInCurrentRun && sym.scalacLinkedClass == NoSymbol => + println(s"needsCompanion for: $sym") + val newDecls = decls.cloneScope + val (modul, mcMethod, symMethod) = newCompanion(sym.name.toTermName, sym) + modul.entered + mcMethod.entered + newDecls.enter(symMethod) + tp.derivedClassInfo(decls = newDecls) + case _ => tp + } + } + + override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = { + tree match { + case Select(qual, _) if tree.symbol.exists => + assert(qual.tpe derivesFrom tree.symbol.owner, i"non member selection of ${tree.symbol.showLocated} from ${qual.tpe}") + case _: TypeTree => + case _: Import | _: NamedArg | _: TypTree => + assert(false, i"illegal tree: $tree") + case _ => + } } /** Reorder statements so that module classes always come after their companion classes, add missing companion classes */ @@ -81,14 +98,12 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer wi case Nil => Nil } - def newCompanion(name: TermName, forClass: Symbol): Thicket = { - val modul = ctx.newCompleteModuleSymbol(ctx.owner, name, Synthetic, Synthetic, - defn.ObjectType :: Nil, Scopes.newScope) - val mc = modul.moduleClass + def registerCompanion(name: TermName, forClass: Symbol): TermSymbol = { + val (modul, mcCompanion, classCompanion) = newCompanion(name, forClass) if (ctx.owner.isClass) modul.enteredAfter(thisTransformer) - ctx.synthesizeCompanionMethod(nme.COMPANION_CLASS_METHOD, forClass, mc).enteredAfter(thisTransformer) - ctx.synthesizeCompanionMethod(nme.COMPANION_MODULE_METHOD, mc, forClass).enteredAfter(thisTransformer) - ModuleDef(modul, Nil) + mcCompanion.enteredAfter(thisTransformer) + classCompanion.enteredAfter(thisTransformer) + modul } def addMissingCompanions(stats: List[Tree]): List[Tree] = stats map { @@ -101,13 +116,23 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer wi false } val uniqueName = if (nameClash) objName.avoidClashName else objName - Thicket(stat :: newCompanion(uniqueName, stat.symbol).trees) + Thicket(stat :: ModuleDef(registerCompanion(uniqueName, stat.symbol), Nil).trees) case stat => stat } addMissingCompanions(reorder(stats)) } + private def newCompanion(name: TermName, forClass: Symbol)(implicit ctx: Context) = { + val modul = ctx.newCompleteModuleSymbol(forClass.owner, name, Synthetic, Synthetic, + defn.ObjectType :: Nil, Scopes.newScope) + val mc = modul.moduleClass + + val mcComp = ctx.synthesizeCompanionMethod(nme.COMPANION_CLASS_METHOD, forClass, mc) + val classComp = ctx.synthesizeCompanionMethod(nme.COMPANION_MODULE_METHOD, mc, forClass) + (modul, mcComp, classComp) + } + override def transformDefDef(ddef: DefDef)(implicit ctx: Context, info: TransformerInfo) = { if (ddef.symbol.hasAnnotation(defn.NativeAnnot)) { ddef.symbol.resetFlag(Deferred) |