Skip to content

Commit 54d610a

Browse files
committed
Fix #3006: Refresh names for lifted methods
1 parent 2dd41c3 commit 54d610a

File tree

7 files changed

+96
-27
lines changed

7 files changed

+96
-27
lines changed
Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
package dotty.tools.dotc.transform
22

3-
import dotty.tools.dotc.ast.tpd
43
import dotty.tools.dotc.core.Contexts.Context
54
import dotty.tools.dotc.core.Decorators._
65
import dotty.tools.dotc.core.DenotTransformers.SymTransformer
76
import dotty.tools.dotc.core.Flags._
87
import dotty.tools.dotc.core.NameKinds._
98
import dotty.tools.dotc.core.Names._
109
import dotty.tools.dotc.core.Phases
11-
import dotty.tools.dotc.core.StdNames._
1210
import dotty.tools.dotc.core.SymDenotations.SymDenotation
1311
import dotty.tools.dotc.core.Symbols._
14-
import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo}
12+
import dotty.tools.dotc.transform.TreeTransforms.MiniPhaseTransform
1513

1614
/** Renames lifted classes to local numbering scheme */
1715
class RenameLifted extends MiniPhaseTransform with SymTransformer { thisTransformer =>
@@ -24,25 +22,21 @@ class RenameLifted extends MiniPhaseTransform with SymTransformer { thisTransfor
2422
if (needsRefresh(ref.symbol)) ref.copySymDenotation(name = refreshedName(ref.symbol))
2523
else ref
2624

27-
override def transformTypeDef(tree: tpd.TypeDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree =
28-
if (needsRefresh(tree.symbol)) cpy.TypeDef(tree)(name = tree.symbol.name.asTypeName)
29-
else tree
30-
25+
/** If the name of the symbol with a unique name needs to be refreshed
26+
* - if it is a lifted class
27+
* - if it is a lifted method
28+
*/
3129
private def needsRefresh(sym: Symbol)(implicit ctx: Context): Boolean =
32-
sym.isClass && sym.name.is(UniqueName)
33-
34-
/* Makes a new unique name based on a unique name that was flatten */
35-
private def refreshedName(sym: Symbol)(implicit ctx: Context): TypeName = {
36-
val packName = sym.owner.fullName.toString
37-
val name = sym.name
38-
val newName = (packName + name.firstPart + str.NAME_JOIN + name.lastPart).toTermName
39-
40-
var freshName = UniqueName.fresh(newName).toTypeName
41-
val prefix = if (sym.owner.isEmptyPackage) "$empty$" else packName
42-
freshName = freshName.toString.substring(prefix.length).toTypeName
43-
if (name.toSimpleName.endsWith(str.MODULE_SUFFIX))
44-
freshName = (freshName + str.MODULE_SUFFIX).toTypeName
45-
46-
freshName
30+
(sym.isClass || sym.is(Private | Method | JavaStatic)) && sym.name.is(UniqueName)
31+
32+
/** Refreshes the number of the name based on the full name of the symbol */
33+
private def refreshedName(sym: Symbol)(implicit ctx: Context): Name = {
34+
sym.name.rewrite {
35+
case name: DerivedName if name.info.kind == UniqueName =>
36+
val fullName = (sym.owner.fullName.toString + name.underlying).toTermName
37+
val freshName = UniqueName.fresh(fullName)
38+
val info = freshName.asInstanceOf[DerivedName].info
39+
DerivedName(name.underlying, info)
40+
}
4741
}
4842
}

compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import TreeTransforms._
55
import core.DenotTransformers._
66
import core.Contexts._
77
import ast.tpd
8-
import dotty.tools.dotc.core.Phases
98

109
/** This phase transforms wildcards in valdefs with their default value.
1110
* In particular for every valdef that is declared:
@@ -17,8 +16,6 @@ class TransformWildcards extends MiniPhaseTransform with IdentityDenotTransforme
1716

1817
override def phaseName = "transformWildcards"
1918

20-
override def runsAfter: Set[Class[_ <: Phases.Phase]] = Set(classOf[RenameLifted])
21-
2219
override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = {
2320
tree match {
2421
case vDef: ValDef => assert(!tpd.isWildcardArg(vDef.rhs))

tests/run/i2738.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
foo
2-
bar$1
3-
foo
42
bar$2
3+
foo
4+
bar$1
55
baz
66
Test$qux$1$
77
baz

tests/run/i3006.check

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
f$3
2+
f$2
3+
f$1
4+
f$2
5+
f$1

tests/run/i3006.scala

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
class Foo {
2+
def foo() = {
3+
def f() = println(Thread.currentThread.getStackTrace.apply(1).getMethodName)
4+
f()
5+
}
6+
def bar() = {
7+
def f() = println(Thread.currentThread.getStackTrace.apply(1).getMethodName)
8+
f()
9+
}
10+
def baz() = {
11+
def f() = println(Thread.currentThread.getStackTrace.apply(1).getMethodName)
12+
f()
13+
}
14+
}
15+
16+
class Bar {
17+
def foo() = {
18+
def f() = println(Thread.currentThread.getStackTrace.apply(1).getMethodName)
19+
f()
20+
}
21+
def bar() = {
22+
def f() = println(Thread.currentThread.getStackTrace.apply(1).getMethodName)
23+
f()
24+
}
25+
}
26+
27+
object Test {
28+
def main(args: Array[String]): Unit = {
29+
new Foo().foo()
30+
new Foo().bar()
31+
new Foo().baz()
32+
new Bar().foo()
33+
new Bar().bar()
34+
}
35+
}

tests/run/i3006b.check

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Foo$$init$$$bar$2
2+
Foo$$init$$$bar$1
3+
Bar$$init$$$bar$1

tests/run/i3006b.scala

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
class Foo(i: Int) {
2+
def this() = this({
3+
def bar() = {
4+
println(Thread.currentThread.getStackTrace.apply(1).getMethodName)
5+
5
6+
}
7+
bar()
8+
})
9+
10+
def this(i: String) = this({
11+
def bar() = {
12+
println(Thread.currentThread.getStackTrace.apply(1).getMethodName)
13+
5
14+
}
15+
bar()
16+
})
17+
}
18+
19+
class Bar(i: Int) {
20+
def this() = this({
21+
def bar() = {
22+
println(Thread.currentThread.getStackTrace.apply(1).getMethodName)
23+
5
24+
}
25+
bar()
26+
})
27+
}
28+
29+
object Test {
30+
def main(args: Array[String]): Unit = {
31+
new Foo()
32+
new Foo("")
33+
new Bar()
34+
}
35+
}

0 commit comments

Comments
 (0)