Skip to content

Commit a0d703b

Browse files
authored
Merge pull request #2999 from dotty-staging/fix-#2964
Fix #2964: Refresh names for anonymous classes
2 parents 717904b + fe7ac0a commit a0d703b

18 files changed

+319
-6
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ class Compiler {
100100
new ElimStaticThis, // Replace `this` references to static objects by global identifiers
101101
new Flatten, // Lift all inner classes to package scope
102102
new RestoreScopes), // Repair scopes rendered invalid by moving definitions in prior phases of the group
103-
List(new TransformWildcards, // Replace wildcards with default values
103+
List(new RenameLifted, // Renames lifted classes to local numbering scheme
104+
new TransformWildcards, // Replace wildcards with default values
104105
new MoveStatics, // Move static methods to companion classes
105106
new ExpandPrivate, // Widen private definitions accessed from nested classes
106107
new SelectStatic, // get rid of selects that would be compiled into GetStatic
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package dotty.tools.dotc.transform
2+
3+
import dotty.tools.dotc.core.Contexts.Context
4+
import dotty.tools.dotc.core.Decorators._
5+
import dotty.tools.dotc.core.DenotTransformers.SymTransformer
6+
import dotty.tools.dotc.core.Flags._
7+
import dotty.tools.dotc.core.NameKinds._
8+
import dotty.tools.dotc.core.Names._
9+
import dotty.tools.dotc.core.Phases
10+
import dotty.tools.dotc.core.SymDenotations.SymDenotation
11+
import dotty.tools.dotc.core.Symbols._
12+
import dotty.tools.dotc.transform.TreeTransforms.MiniPhaseTransform
13+
14+
/** Renames lifted classes to local numbering scheme */
15+
class RenameLifted extends MiniPhaseTransform with SymTransformer { thisTransformer =>
16+
17+
override def phaseName = "renameLifted"
18+
19+
override def runsAfterGroupsOf: Set[Class[_ <: Phases.Phase]] = Set(classOf[RestoreScopes])
20+
21+
def transformSym(ref: SymDenotation)(implicit ctx: Context): SymDenotation =
22+
if (needsRefresh(ref.symbol)) ref.copySymDenotation(name = refreshedName(ref.symbol))
23+
else ref
24+
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+
*/
29+
private def needsRefresh(sym: Symbol)(implicit ctx: Context): Boolean =
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+
def rewriteUnique: PartialFunction[Name, Name] = {
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.rewrite(rewriteUnique), info)
40+
case DerivedName(underlying, info: QualifiedInfo) =>
41+
underlying.rewrite(rewriteUnique).derived(info)
42+
}
43+
44+
sym.name.rewrite(rewriteUnique)
45+
}
46+
}

tests/run/i2738.check

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

tests/run/i2964.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class Foo$$anon$1
2+
class Bar$$anon$1
3+
class Bar$$anon$2
4+
class Baz$$anon$1

tests/run/i2964.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
object Test {
3+
def main(args: Array[String]): Unit = {
4+
new Foo
5+
new Bar
6+
new Baz
7+
}
8+
}
9+
10+
class Foo {
11+
new Object {
12+
println(this.getClass) // Foo$$anon$1
13+
}
14+
}
15+
class Bar {
16+
new Object {
17+
println(this.getClass) // Bar$$anon$1
18+
}
19+
new Object {
20+
println(this.getClass) // Bar$$anon$2
21+
}
22+
}
23+
class Baz {
24+
new Object {
25+
println(this.getClass) // Baz$$anon$1
26+
}
27+
}

tests/run/i2964b.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class Foo$$anon$1
2+
class Bar$$anon$1
3+
class Bar$$anon$2
4+
class Baz$$anon$1

tests/run/i2964b.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
object Test {
3+
def main(args: Array[String]): Unit = {
4+
Foo
5+
Bar
6+
Baz
7+
}
8+
}
9+
10+
object Foo {
11+
new Object {
12+
println(this.getClass) // Foo$$anon$1
13+
}
14+
}
15+
object Bar {
16+
new Object {
17+
println(this.getClass) // Bar$$anon$1
18+
}
19+
new Object {
20+
println(this.getClass) // Bar$$anon$2
21+
}
22+
}
23+
object Baz {
24+
new Object {
25+
println(this.getClass) // Baz$$anon$1
26+
}
27+
}

tests/run/i2964c.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class Foo$Inner$1
2+
class Bar$Inner$1
3+
class Bar$Inner$2
4+
class Baz$Inner$1

tests/run/i2964c.scala

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

tests/run/i2964d.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class Foo$Inner$1$
2+
class Bar$Inner$1$
3+
class Bar$Inner$2$
4+
class Baz$Inner$1$

tests/run/i2964d.scala

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

tests/run/i2964e.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class foo.bar.Foo$$anon$1
2+
class foo.bar.Foo$$anon$2
3+
class foo.Foo$$anon$1
4+
class Foo$$anon$1

tests/run/i2964e.scala

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
object Test {
3+
def main(args: Array[String]): Unit = {
4+
new foo.bar.Foo
5+
new foo.Foo
6+
new Foo
7+
}
8+
}
9+
10+
package foo {
11+
package bar {
12+
class Foo {
13+
new Object {
14+
println(this.getClass) // Foo$$anon$1
15+
}
16+
new Object {
17+
println(this.getClass) // Foo$$anon$2
18+
}
19+
}
20+
}
21+
class Foo {
22+
new Object {
23+
println(this.getClass) // Foo$$anon$1
24+
}
25+
}
26+
}
27+
28+
class Foo {
29+
new Object {
30+
println(this.getClass) // Foo$$anon$1
31+
}
32+
}

tests/run/i3000b.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
Foo$$anon$1
2-
bar.Bar$$anon$2
2+
bar.Bar$$anon$1

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)