From 250418e830bc7ccacf13cb0d3a9121238d99632a Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 30 Oct 2014 17:09:34 +0100 Subject: New phase: PrivateToStatic Make private methods in traits static, so that we do not need to give a default for them. --- src/dotty/tools/dotc/Compiler.scala | 3 +- src/dotty/tools/dotc/ast/tpd.scala | 2 +- src/dotty/tools/dotc/core/Flags.scala | 3 + src/dotty/tools/dotc/printing/RefinedPrinter.scala | 6 +- .../tools/dotc/transform/PrivateToStatic.scala | 90 ++++++++++++++++++++++ 5 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 src/dotty/tools/dotc/transform/PrivateToStatic.scala (limited to 'src/dotty/tools/dotc') diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala index d4fa7e671..f4690df08 100644 --- a/src/dotty/tools/dotc/Compiler.scala +++ b/src/dotty/tools/dotc/Compiler.scala @@ -57,7 +57,8 @@ class Compiler { new Constructors), List(new LambdaLift, new Flatten, - new RestoreScopes) + new RestoreScopes), + List(new PrivateToStatic) ) var runId = 1 diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala index d0f64f5a7..74ba79176 100644 --- a/src/dotty/tools/dotc/ast/tpd.scala +++ b/src/dotty/tools/dotc/ast/tpd.scala @@ -263,7 +263,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { case _ => false } - try test + try test || tp.symbol.is(JavaStatic) catch { // See remark in SymDenotations#accessWithin case ex: NotDefinedHere => test(ctx.addMode(Mode.FutureDefsOK)) } diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala index e5bf27eae..804f6af1a 100644 --- a/src/dotty/tools/dotc/core/Flags.scala +++ b/src/dotty/tools/dotc/core/Flags.scala @@ -512,6 +512,9 @@ object Flags { /** Labeled `private` or `final` */ final val PrivateOrFinal = Private | Final + /** A private method */ + final val PrivateMethod = allOf(Private, Method) + /** A type parameter with synthesized name */ final val ExpandedTypeParam = allOf(ExpandedName, TypeParam) diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala index f0d558824..e43aaa24f 100644 --- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -36,7 +36,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { override def nameString(name: Name): String = name.decode.toString override protected def simpleNameString(sym: Symbol): String = - sym.originalName.decode.toString + sym.name.decode.toString override protected def fullNameOwner(sym: Symbol) = { val owner = super.fullNameOwner(sym) @@ -222,7 +222,9 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { "`" ~ toText(id.name) ~ "`" case Ident(name) => tree.typeOpt match { - case tp: NamedType if name != nme.WILDCARD => toTextPrefix(tp.prefix) ~ selectionString(tp) + case tp: NamedType if name != nme.WILDCARD => + val pre = if (tp.symbol is JavaStatic) tp.prefix.widen else tp.prefix + toTextPrefix(pre) ~ selectionString(tp) case _ => toText(name) } case tree @ Select(qual, name) => diff --git a/src/dotty/tools/dotc/transform/PrivateToStatic.scala b/src/dotty/tools/dotc/transform/PrivateToStatic.scala new file mode 100644 index 000000000..17f176855 --- /dev/null +++ b/src/dotty/tools/dotc/transform/PrivateToStatic.scala @@ -0,0 +1,90 @@ +package dotty.tools.dotc +package transform + +import core._ +import DenotTransformers.SymTransformer +import Contexts.Context +import Symbols._ +import Scopes._ +import Flags._ +import StdNames._ +import SymDenotations._ +import Types._ +import collection.mutable +import TreeTransforms._ +import Decorators._ +import ast.Trees._ +import TreeTransforms.TransformerInfo + +/** The preceding lambda lift and flatten phases move symbols to different scopes + * and rename them. This miniphase cleans up afterwards and makes sure that all + * class scopes contain the symbols defined in them. + */ +class PrivateToStatic extends MiniPhase with SymTransformer { thisTransform => + import ast.tpd._ + override def phaseName = "privateToStatic" + override def relaxedTyping = true + + private val Immovable = Deferred | Accessor | JavaStatic + + def shouldBeStatic(sd: SymDenotation)(implicit ctx: Context) = + sd.current(ctx.withPhase(thisTransform)).asInstanceOf[SymDenotation] + .is(PrivateMethod, butNot = Immovable) && + (sd.owner.is(Trait) || sd.is(NotJavaPrivate)) + + override def transformSym(sd: SymDenotation)(implicit ctx: Context): SymDenotation = + if (shouldBeStatic(sd)) { + val mt @ MethodType(pnames, ptypes) = sd.info + sd.copySymDenotation( + initFlags = sd.flags | JavaStatic, + info = MethodType(nme.SELF :: pnames, sd.owner.thisType :: ptypes, mt.resultType)) + } + else sd + + val treeTransform = new Transform(NoSymbol) + + class Transform(thisParam: Symbol) extends TreeTransform { + def phase = thisTransform + override def treeTransformPhase = thisTransform.next + + override def prepareForDefDef(tree: DefDef)(implicit ctx: Context) = + if (shouldBeStatic(tree.symbol)) { + val selfParam = ctx.newSymbol(tree.symbol, nme.SELF, Param, tree.symbol.owner.thisType, coord = tree.pos) + new Transform(selfParam) + } + else this + + override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo) = + if (shouldBeStatic(tree.symbol)) { + val thisParamDef = ValDef(thisParam.asTerm) + val vparams :: Nil = tree.vparamss + cpy.DefDef(tree)( + mods = tree.mods | JavaStatic, + vparamss = (thisParamDef :: vparams) :: Nil) + } + else tree + + override def transformThis(tree: This)(implicit ctx: Context, info: TransformerInfo) = + if (shouldBeStatic(ctx.owner.enclosingMethod)) ref(thisParam).withPos(tree.pos) + else tree + + override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo) = + tree.fun match { + case fun @ Select(qual, name) if shouldBeStatic(fun.symbol) => + println(i"mapping $tree to ${cpy.Ident(fun)(name)} (${qual :: tree.args}%, %)") + cpy.Apply(tree)(ref(fun.symbol).withPos(fun.pos), qual :: tree.args) + case _ => + tree + } + + override def transformClosure(tree: Closure)(implicit ctx: Context, info: TransformerInfo) = + tree.meth match { + case meth @ Select(qual, name) if shouldBeStatic(meth.symbol) => + cpy.Closure(tree)( + env = qual :: tree.env, + meth = ref(meth.symbol).withPos(meth.pos)) + case _ => + tree + } + } +} -- cgit v1.2.3