aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/Compiler.scala3
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala2
-rw-r--r--src/dotty/tools/dotc/core/Flags.scala3
-rw-r--r--src/dotty/tools/dotc/printing/RefinedPrinter.scala6
-rw-r--r--src/dotty/tools/dotc/transform/PrivateToStatic.scala90
-rw-r--r--tests/pos/CoderTrait.scala63
-rw-r--r--tests/pos/privates.scala9
-rw-r--r--tests/pos/traits.scala25
8 files changed, 197 insertions, 4 deletions
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
+ }
+ }
+}
diff --git a/tests/pos/CoderTrait.scala b/tests/pos/CoderTrait.scala
new file mode 100644
index 000000000..1eba60097
--- /dev/null
+++ b/tests/pos/CoderTrait.scala
@@ -0,0 +1,63 @@
+import collection.mutable.HashMap
+
+trait CoderTrait {
+
+ val words: List[String]
+
+ (2 -> "ABC", new ArrowAssoc('3') -> "DEF")
+
+ private val mnemonics = Map(
+ '2' -> "ABC", '3' -> "DEF", '4' -> "GHI", '5' -> "JKL",
+ '6' -> "MNO", '7' -> "PQRS", '8' -> "TUV", '9' -> "WXYZ")
+
+
+ ('1', "1") match {
+ case (digit, str) => true
+ case _ => false
+ }
+
+ /** Invert the mnemonics map to give a map from chars 'A' ... 'Z' to '2' ... '9' */
+ private val charCode0: Map[Char, Char] = mnemonics withFilter {
+ case (digit, str) => true
+ case _ => false
+ } flatMap { x$1 =>
+ x$1 match {
+ case (digit, str) => str map (ltr => ltr -> digit)
+ }
+ }
+
+ private val charCode: Map[Char, Char] =
+ for ((digit, str) <- mnemonics; ltr <- str) yield ltr -> digit
+
+ /** Maps a word to the digit string it can represent */
+ private def wordCode(word: String): String = word map charCode
+
+ /** A map from digit strings to the words that represent them */
+ private val wordsForNum: Map[String, List[String]] =
+ words groupBy wordCode withDefaultValue Nil
+
+ /** All ways to encode a number as a list of words */
+ def encode(number: String): Set[List[String]] =
+ if (number.isEmpty) Set(Nil)
+ else {
+ for {
+ splitPoint <- 1 to number.length
+ word <- wordsForNum(number take splitPoint)
+ rest <- encode(number drop splitPoint)
+ } yield word :: rest
+ }.toSet
+
+ /** Maps a number to a list of all word phrases that can represent it */
+ def translate(number: String): Set[String] = encode(number) map (_ mkString " ")
+
+}
+
+object Coder {
+ def main(args : Array[String]) : Unit = {
+ val coder = new CoderTrait {
+ val words = List("Scala", "sobls", "Python", "Ruby", "C", "A", "rocks", "sucks", "works", "Racka")
+ }
+// println(coder.wordsForNum)
+ println(coder.translate("7225276257"))
+ }
+}
diff --git a/tests/pos/privates.scala b/tests/pos/privates.scala
new file mode 100644
index 000000000..edaa10cb6
--- /dev/null
+++ b/tests/pos/privates.scala
@@ -0,0 +1,9 @@
+trait Test {
+
+ private val x = 2
+
+ private def foo() = x * x
+
+ private def bar() = foo()
+
+}
diff --git a/tests/pos/traits.scala b/tests/pos/traits.scala
new file mode 100644
index 000000000..15310d5a4
--- /dev/null
+++ b/tests/pos/traits.scala
@@ -0,0 +1,25 @@
+trait B {
+
+ val z: Int
+
+}
+
+trait T {
+
+ var x = 2
+
+ private var xp = 2
+
+ val y = 3
+
+ private val yp = 3
+
+ val z = 4
+
+ x = 4
+
+ xp = 4
+
+}
+
+class C extends T