Skip to content

Commit 9bf9998

Browse files
committed
Fix #2964: Refresh names for anonymous classes
1 parent 8ca8cd9 commit 9bf9998

File tree

12 files changed

+206
-3
lines changed

12 files changed

+206
-3
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 LiftedClasses, // 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: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package dotty.tools.dotc.transform
2+
3+
import dotty.tools.dotc.ast.tpd
4+
import dotty.tools.dotc.core.Contexts.Context
5+
import dotty.tools.dotc.core.Decorators._
6+
import dotty.tools.dotc.core.DenotTransformers.SymTransformer
7+
import dotty.tools.dotc.core.Flags._
8+
import dotty.tools.dotc.core.NameKinds._
9+
import dotty.tools.dotc.core.Names._
10+
import dotty.tools.dotc.core.Phases
11+
import dotty.tools.dotc.core.StdNames._
12+
import dotty.tools.dotc.core.SymDenotations.SymDenotation
13+
import dotty.tools.dotc.core.Symbols._
14+
import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo}
15+
16+
/** Renames lifted classes to local numbering scheme */
17+
class LiftedClasses extends MiniPhaseTransform with SymTransformer { thisTransformer =>
18+
19+
override def phaseName = "liftedClasses"
20+
21+
override def runsAfterGroupsOf: Set[Class[_ <: Phases.Phase]] = Set(classOf[Flatten])
22+
23+
def transformSym(ref: SymDenotation)(implicit ctx: Context): SymDenotation =
24+
if (needsRefresh(ref.symbol)) ref.copySymDenotation(name = refreshedName(ref.symbol))
25+
else ref
26+
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+
31+
private def needsRefresh(sym: Symbol)(implicit ctx: Context): Boolean =
32+
sym.isClass && !sym.is(Package) && 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+
// TODO: Refresh names not only based on their full name?
37+
// Include package to distinguish <class>$anon from <pack>.<class>$anon
38+
val name = sym.name
39+
val newName = (name.firstPart.toString + str.NAME_JOIN + name.lastPart).toTermName
40+
41+
var freshName = UniqueName.fresh(newName).toTypeName
42+
if (name.toSimpleName.endsWith(str.MODULE_SUFFIX))
43+
freshName = (freshName + str.MODULE_SUFFIX).toTypeName
44+
45+
freshName
46+
}
47+
}

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

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

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

1718
override def phaseName = "transformWildcards"
1819

20+
override def runsAfter: Set[Class[_ <: Phases.Phase]] = Set(classOf[LiftedClasses])
21+
1922
override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = {
2023
tree match {
2124
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
@@ -3,6 +3,6 @@ bar$1
33
foo
44
bar$2
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+
}

0 commit comments

Comments
 (0)