From 9bf9998fee392c9930211cb20e68281a4c2a1c2b Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 21 Aug 2017 13:50:40 +0200 Subject: [PATCH 1/7] Fix #2964: Refresh names for anonymous classes --- compiler/src/dotty/tools/dotc/Compiler.scala | 3 +- .../tools/dotc/transform/LiftedClasses.scala | 47 +++++++++++++++++++ .../dotc/transform/TransformWildcards.scala | 3 ++ tests/run/i2738.check | 4 +- tests/run/i2964.check | 4 ++ tests/run/i2964.scala | 27 +++++++++++ tests/run/i2964b.check | 4 ++ tests/run/i2964b.scala | 27 +++++++++++ tests/run/i2964c.check | 4 ++ tests/run/i2964c.scala | 41 ++++++++++++++++ tests/run/i2964d.check | 4 ++ tests/run/i2964d.scala | 41 ++++++++++++++++ 12 files changed, 206 insertions(+), 3 deletions(-) create mode 100644 compiler/src/dotty/tools/dotc/transform/LiftedClasses.scala create mode 100644 tests/run/i2964.check create mode 100644 tests/run/i2964.scala create mode 100644 tests/run/i2964b.check create mode 100644 tests/run/i2964b.scala create mode 100644 tests/run/i2964c.check create mode 100644 tests/run/i2964c.scala create mode 100644 tests/run/i2964d.check create mode 100644 tests/run/i2964d.scala diff --git a/compiler/src/dotty/tools/dotc/Compiler.scala b/compiler/src/dotty/tools/dotc/Compiler.scala index a6555cdcd50e..b0f588874bb3 100644 --- a/compiler/src/dotty/tools/dotc/Compiler.scala +++ b/compiler/src/dotty/tools/dotc/Compiler.scala @@ -100,7 +100,8 @@ class Compiler { new ElimStaticThis, // Replace `this` references to static objects by global identifiers new Flatten, // Lift all inner classes to package scope new RestoreScopes), // Repair scopes rendered invalid by moving definitions in prior phases of the group - List(new TransformWildcards, // Replace wildcards with default values + List(new LiftedClasses, // Renames lifted classes to local numbering scheme + new TransformWildcards, // Replace wildcards with default values new MoveStatics, // Move static methods to companion classes new ExpandPrivate, // Widen private definitions accessed from nested classes new SelectStatic, // get rid of selects that would be compiled into GetStatic diff --git a/compiler/src/dotty/tools/dotc/transform/LiftedClasses.scala b/compiler/src/dotty/tools/dotc/transform/LiftedClasses.scala new file mode 100644 index 000000000000..4ac899f2902b --- /dev/null +++ b/compiler/src/dotty/tools/dotc/transform/LiftedClasses.scala @@ -0,0 +1,47 @@ +package dotty.tools.dotc.transform + +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Decorators._ +import dotty.tools.dotc.core.DenotTransformers.SymTransformer +import dotty.tools.dotc.core.Flags._ +import dotty.tools.dotc.core.NameKinds._ +import dotty.tools.dotc.core.Names._ +import dotty.tools.dotc.core.Phases +import dotty.tools.dotc.core.StdNames._ +import dotty.tools.dotc.core.SymDenotations.SymDenotation +import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo} + +/** Renames lifted classes to local numbering scheme */ +class LiftedClasses extends MiniPhaseTransform with SymTransformer { thisTransformer => + + override def phaseName = "liftedClasses" + + override def runsAfterGroupsOf: Set[Class[_ <: Phases.Phase]] = Set(classOf[Flatten]) + + def transformSym(ref: SymDenotation)(implicit ctx: Context): SymDenotation = + if (needsRefresh(ref.symbol)) ref.copySymDenotation(name = refreshedName(ref.symbol)) + else ref + + override def transformTypeDef(tree: tpd.TypeDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = + if (needsRefresh(tree.symbol)) cpy.TypeDef(tree)(name = tree.symbol.name.asTypeName) + else tree + + private def needsRefresh(sym: Symbol)(implicit ctx: Context): Boolean = + sym.isClass && !sym.is(Package) && sym.name.is(UniqueName) + + /* Makes a new unique name based on a unique name that was flatten */ + private def refreshedName(sym: Symbol)(implicit ctx: Context): TypeName = { + // TODO: Refresh names not only based on their full name? + // Include package to distinguish $anon from .$anon + val name = sym.name + val newName = (name.firstPart.toString + str.NAME_JOIN + name.lastPart).toTermName + + var freshName = UniqueName.fresh(newName).toTypeName + if (name.toSimpleName.endsWith(str.MODULE_SUFFIX)) + freshName = (freshName + str.MODULE_SUFFIX).toTypeName + + freshName + } +} diff --git a/compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala b/compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala index 946722227af9..a2bcede2a38d 100644 --- a/compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala +++ b/compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala @@ -5,6 +5,7 @@ import TreeTransforms._ import core.DenotTransformers._ import core.Contexts._ import ast.tpd +import dotty.tools.dotc.core.Phases /** This phase transforms wildcards in valdefs with their default value. * In particular for every valdef that is declared: @@ -16,6 +17,8 @@ class TransformWildcards extends MiniPhaseTransform with IdentityDenotTransforme override def phaseName = "transformWildcards" + override def runsAfter: Set[Class[_ <: Phases.Phase]] = Set(classOf[LiftedClasses]) + override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = { tree match { case vDef: ValDef => assert(!tpd.isWildcardArg(vDef.rhs)) diff --git a/tests/run/i2738.check b/tests/run/i2738.check index 1261ac914586..0521c21711ed 100644 --- a/tests/run/i2738.check +++ b/tests/run/i2738.check @@ -3,6 +3,6 @@ bar$1 foo bar$2 baz -Test$qux$2$ +Test$qux$1$ baz -Test$qux$4$ +Test$qux$2$ diff --git a/tests/run/i2964.check b/tests/run/i2964.check new file mode 100644 index 000000000000..748b2a47faf1 --- /dev/null +++ b/tests/run/i2964.check @@ -0,0 +1,4 @@ +class Foo$$anon$1 +class Bar$$anon$1 +class Bar$$anon$2 +class Baz$$anon$1 diff --git a/tests/run/i2964.scala b/tests/run/i2964.scala new file mode 100644 index 000000000000..8b76c5e05da2 --- /dev/null +++ b/tests/run/i2964.scala @@ -0,0 +1,27 @@ + +object Test { + def main(args: Array[String]): Unit = { + new Foo + new Bar + new Baz + } +} + +class Foo { + new Object { + println(this.getClass) // Foo$$anon$1 + } +} +class Bar { + new Object { + println(this.getClass) // Bar$$anon$1 + } + new Object { + println(this.getClass) // Bar$$anon$2 + } +} +class Baz { + new Object { + println(this.getClass) // Baz$$anon$1 + } +} diff --git a/tests/run/i2964b.check b/tests/run/i2964b.check new file mode 100644 index 000000000000..748b2a47faf1 --- /dev/null +++ b/tests/run/i2964b.check @@ -0,0 +1,4 @@ +class Foo$$anon$1 +class Bar$$anon$1 +class Bar$$anon$2 +class Baz$$anon$1 diff --git a/tests/run/i2964b.scala b/tests/run/i2964b.scala new file mode 100644 index 000000000000..26177b85d993 --- /dev/null +++ b/tests/run/i2964b.scala @@ -0,0 +1,27 @@ + +object Test { + def main(args: Array[String]): Unit = { + Foo + Bar + Baz + } +} + +object Foo { + new Object { + println(this.getClass) // Foo$$anon$1 + } +} +object Bar { + new Object { + println(this.getClass) // Bar$$anon$1 + } + new Object { + println(this.getClass) // Bar$$anon$2 + } +} +object Baz { + new Object { + println(this.getClass) // Baz$$anon$1 + } +} diff --git a/tests/run/i2964c.check b/tests/run/i2964c.check new file mode 100644 index 000000000000..f7cc0f12df69 --- /dev/null +++ b/tests/run/i2964c.check @@ -0,0 +1,4 @@ +class Foo$Inner$1 +class Bar$Inner$1 +class Bar$Inner$2 +class Baz$Inner$1 diff --git a/tests/run/i2964c.scala b/tests/run/i2964c.scala new file mode 100644 index 000000000000..3683823764c6 --- /dev/null +++ b/tests/run/i2964c.scala @@ -0,0 +1,41 @@ + +object Test { + def main(args: Array[String]): Unit = { + new Foo().foo + new Bar().bar + new Bar().bar2 + new Baz().baz + } +} + +class Foo { + def foo: Unit = { + class Inner { + println(this.getClass) + } + new Inner + } +} +class Bar { + def bar: Unit = { + class Inner { + println(this.getClass) + } + new Inner + } + + def bar2: Unit = { + class Inner { + println(this.getClass) + } + new Inner + } +} +class Baz { + def baz: Unit = { + class Inner { + println(this.getClass) + } + new Inner + } +} diff --git a/tests/run/i2964d.check b/tests/run/i2964d.check new file mode 100644 index 000000000000..f1a0e8bb51c4 --- /dev/null +++ b/tests/run/i2964d.check @@ -0,0 +1,4 @@ +class Foo$Inner$1$ +class Bar$Inner$1$ +class Bar$Inner$2$ +class Baz$Inner$1$ diff --git a/tests/run/i2964d.scala b/tests/run/i2964d.scala new file mode 100644 index 000000000000..4090bfc084f7 --- /dev/null +++ b/tests/run/i2964d.scala @@ -0,0 +1,41 @@ + +object Test { + def main(args: Array[String]): Unit = { + new Foo().foo + new Bar().bar + new Bar().bar2 + new Baz().baz + } +} + +class Foo { + def foo: Unit = { + object Inner { + println(this.getClass) + } + Inner + } +} +class Bar { + def bar: Unit = { + object Inner { + println(this.getClass) + } + Inner + } + + def bar2: Unit = { + object Inner { + println(this.getClass) + } + Inner + } +} +class Baz { + def baz: Unit = { + object Inner { + println(this.getClass) + } + Inner + } +} From b1bcbde345459099206c30390017f751ce5df470 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 22 Aug 2017 08:06:32 +0200 Subject: [PATCH 2/7] Use local fresh indices for lifted classes in diferent packages --- .../tools/dotc/transform/LiftedClasses.scala | 7 ++-- tests/run/i2964e.check | 4 +++ tests/run/i2964e.scala | 32 +++++++++++++++++++ tests/run/i3000b.check | 2 +- 4 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 tests/run/i2964e.check create mode 100644 tests/run/i2964e.scala diff --git a/compiler/src/dotty/tools/dotc/transform/LiftedClasses.scala b/compiler/src/dotty/tools/dotc/transform/LiftedClasses.scala index 4ac899f2902b..fef9dce0ca2e 100644 --- a/compiler/src/dotty/tools/dotc/transform/LiftedClasses.scala +++ b/compiler/src/dotty/tools/dotc/transform/LiftedClasses.scala @@ -33,12 +33,13 @@ class LiftedClasses extends MiniPhaseTransform with SymTransformer { thisTransfo /* Makes a new unique name based on a unique name that was flatten */ private def refreshedName(sym: Symbol)(implicit ctx: Context): TypeName = { - // TODO: Refresh names not only based on their full name? - // Include package to distinguish $anon from .$anon + val packName = sym.owner.fullName.toString val name = sym.name - val newName = (name.firstPart.toString + str.NAME_JOIN + name.lastPart).toTermName + val newName = (packName + name.firstPart + str.NAME_JOIN + name.lastPart).toTermName var freshName = UniqueName.fresh(newName).toTypeName + val prefix = if (sym.owner.isEmptyPackage) "$empty$" else packName + freshName = freshName.toString.substring(prefix.length).toTypeName if (name.toSimpleName.endsWith(str.MODULE_SUFFIX)) freshName = (freshName + str.MODULE_SUFFIX).toTypeName diff --git a/tests/run/i2964e.check b/tests/run/i2964e.check new file mode 100644 index 000000000000..a42348b97b00 --- /dev/null +++ b/tests/run/i2964e.check @@ -0,0 +1,4 @@ +class foo.bar.Foo$$anon$1 +class foo.bar.Foo$$anon$2 +class foo.Foo$$anon$1 +class Foo$$anon$1 diff --git a/tests/run/i2964e.scala b/tests/run/i2964e.scala new file mode 100644 index 000000000000..2c6b0d1d4542 --- /dev/null +++ b/tests/run/i2964e.scala @@ -0,0 +1,32 @@ + +object Test { + def main(args: Array[String]): Unit = { + new foo.bar.Foo + new foo.Foo + new Foo + } +} + +package foo { + package bar { + class Foo { + new Object { + println(this.getClass) // Foo$$anon$1 + } + new Object { + println(this.getClass) // Foo$$anon$2 + } + } + } + class Foo { + new Object { + println(this.getClass) // Foo$$anon$1 + } + } +} + +class Foo { + new Object { + println(this.getClass) // Foo$$anon$1 + } +} diff --git a/tests/run/i3000b.check b/tests/run/i3000b.check index 605021c9b2c0..c5980c545f33 100644 --- a/tests/run/i3000b.check +++ b/tests/run/i3000b.check @@ -1,2 +1,2 @@ Foo$$anon$1 -bar.Bar$$anon$2 +bar.Bar$$anon$1 From 10672c04eebcc37858a9543c5e3255f6616e97ca Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 22 Aug 2017 10:03:50 +0200 Subject: [PATCH 3/7] Rename transform --- compiler/src/dotty/tools/dotc/Compiler.scala | 2 +- .../transform/{LiftedClasses.scala => RenameLifted.scala} | 4 ++-- .../src/dotty/tools/dotc/transform/TransformWildcards.scala | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename compiler/src/dotty/tools/dotc/transform/{LiftedClasses.scala => RenameLifted.scala} (93%) diff --git a/compiler/src/dotty/tools/dotc/Compiler.scala b/compiler/src/dotty/tools/dotc/Compiler.scala index b0f588874bb3..d31035f83a25 100644 --- a/compiler/src/dotty/tools/dotc/Compiler.scala +++ b/compiler/src/dotty/tools/dotc/Compiler.scala @@ -100,7 +100,7 @@ class Compiler { new ElimStaticThis, // Replace `this` references to static objects by global identifiers new Flatten, // Lift all inner classes to package scope new RestoreScopes), // Repair scopes rendered invalid by moving definitions in prior phases of the group - List(new LiftedClasses, // Renames lifted classes to local numbering scheme + List(new RenameLifted, // Renames lifted classes to local numbering scheme new TransformWildcards, // Replace wildcards with default values new MoveStatics, // Move static methods to companion classes new ExpandPrivate, // Widen private definitions accessed from nested classes diff --git a/compiler/src/dotty/tools/dotc/transform/LiftedClasses.scala b/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala similarity index 93% rename from compiler/src/dotty/tools/dotc/transform/LiftedClasses.scala rename to compiler/src/dotty/tools/dotc/transform/RenameLifted.scala index fef9dce0ca2e..2ca315c6c13e 100644 --- a/compiler/src/dotty/tools/dotc/transform/LiftedClasses.scala +++ b/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala @@ -14,9 +14,9 @@ import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo} /** Renames lifted classes to local numbering scheme */ -class LiftedClasses extends MiniPhaseTransform with SymTransformer { thisTransformer => +class RenameLifted extends MiniPhaseTransform with SymTransformer { thisTransformer => - override def phaseName = "liftedClasses" + override def phaseName = "renameLifted" override def runsAfterGroupsOf: Set[Class[_ <: Phases.Phase]] = Set(classOf[Flatten]) diff --git a/compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala b/compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala index a2bcede2a38d..b273e440d045 100644 --- a/compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala +++ b/compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala @@ -17,7 +17,7 @@ class TransformWildcards extends MiniPhaseTransform with IdentityDenotTransforme override def phaseName = "transformWildcards" - override def runsAfter: Set[Class[_ <: Phases.Phase]] = Set(classOf[LiftedClasses]) + override def runsAfter: Set[Class[_ <: Phases.Phase]] = Set(classOf[RenameLifted]) override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = { tree match { From 2dd41c34e24425ff3db1f2b711e37011e00a6a8a Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 22 Aug 2017 10:07:53 +0200 Subject: [PATCH 4/7] Remove uneccesary condition --- compiler/src/dotty/tools/dotc/transform/RenameLifted.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala b/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala index 2ca315c6c13e..ae6c44f9ec17 100644 --- a/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala +++ b/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala @@ -18,7 +18,7 @@ class RenameLifted extends MiniPhaseTransform with SymTransformer { thisTransfor override def phaseName = "renameLifted" - override def runsAfterGroupsOf: Set[Class[_ <: Phases.Phase]] = Set(classOf[Flatten]) + override def runsAfterGroupsOf: Set[Class[_ <: Phases.Phase]] = Set(classOf[RestoreScopes]) def transformSym(ref: SymDenotation)(implicit ctx: Context): SymDenotation = if (needsRefresh(ref.symbol)) ref.copySymDenotation(name = refreshedName(ref.symbol)) @@ -29,7 +29,7 @@ class RenameLifted extends MiniPhaseTransform with SymTransformer { thisTransfor else tree private def needsRefresh(sym: Symbol)(implicit ctx: Context): Boolean = - sym.isClass && !sym.is(Package) && sym.name.is(UniqueName) + sym.isClass && sym.name.is(UniqueName) /* Makes a new unique name based on a unique name that was flatten */ private def refreshedName(sym: Symbol)(implicit ctx: Context): TypeName = { From 54d610a97e474fb46da6446bbfdc4d00e4c57c21 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 29 Aug 2017 14:22:29 +0200 Subject: [PATCH 5/7] Fix #3006: Refresh names for lifted methods --- .../tools/dotc/transform/RenameLifted.scala | 38 ++++++++----------- .../dotc/transform/TransformWildcards.scala | 3 -- tests/run/i2738.check | 4 +- tests/run/i3006.check | 5 +++ tests/run/i3006.scala | 35 +++++++++++++++++ tests/run/i3006b.check | 3 ++ tests/run/i3006b.scala | 35 +++++++++++++++++ 7 files changed, 96 insertions(+), 27 deletions(-) create mode 100644 tests/run/i3006.check create mode 100644 tests/run/i3006.scala create mode 100644 tests/run/i3006b.check create mode 100644 tests/run/i3006b.scala diff --git a/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala b/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala index ae6c44f9ec17..ae5654ca735c 100644 --- a/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala +++ b/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala @@ -1,6 +1,5 @@ package dotty.tools.dotc.transform -import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.DenotTransformers.SymTransformer @@ -8,10 +7,9 @@ import dotty.tools.dotc.core.Flags._ import dotty.tools.dotc.core.NameKinds._ import dotty.tools.dotc.core.Names._ import dotty.tools.dotc.core.Phases -import dotty.tools.dotc.core.StdNames._ import dotty.tools.dotc.core.SymDenotations.SymDenotation import dotty.tools.dotc.core.Symbols._ -import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo} +import dotty.tools.dotc.transform.TreeTransforms.MiniPhaseTransform /** Renames lifted classes to local numbering scheme */ class RenameLifted extends MiniPhaseTransform with SymTransformer { thisTransformer => @@ -24,25 +22,21 @@ class RenameLifted extends MiniPhaseTransform with SymTransformer { thisTransfor if (needsRefresh(ref.symbol)) ref.copySymDenotation(name = refreshedName(ref.symbol)) else ref - override def transformTypeDef(tree: tpd.TypeDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = - if (needsRefresh(tree.symbol)) cpy.TypeDef(tree)(name = tree.symbol.name.asTypeName) - else tree - + /** If the name of the symbol with a unique name needs to be refreshed + * - if it is a lifted class + * - if it is a lifted method + */ private def needsRefresh(sym: Symbol)(implicit ctx: Context): Boolean = - sym.isClass && sym.name.is(UniqueName) - - /* Makes a new unique name based on a unique name that was flatten */ - private def refreshedName(sym: Symbol)(implicit ctx: Context): TypeName = { - val packName = sym.owner.fullName.toString - val name = sym.name - val newName = (packName + name.firstPart + str.NAME_JOIN + name.lastPart).toTermName - - var freshName = UniqueName.fresh(newName).toTypeName - val prefix = if (sym.owner.isEmptyPackage) "$empty$" else packName - freshName = freshName.toString.substring(prefix.length).toTypeName - if (name.toSimpleName.endsWith(str.MODULE_SUFFIX)) - freshName = (freshName + str.MODULE_SUFFIX).toTypeName - - freshName + (sym.isClass || sym.is(Private | Method | JavaStatic)) && sym.name.is(UniqueName) + + /** Refreshes the number of the name based on the full name of the symbol */ + private def refreshedName(sym: Symbol)(implicit ctx: Context): Name = { + sym.name.rewrite { + case name: DerivedName if name.info.kind == UniqueName => + val fullName = (sym.owner.fullName.toString + name.underlying).toTermName + val freshName = UniqueName.fresh(fullName) + val info = freshName.asInstanceOf[DerivedName].info + DerivedName(name.underlying, info) + } } } diff --git a/compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala b/compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala index b273e440d045..946722227af9 100644 --- a/compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala +++ b/compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala @@ -5,7 +5,6 @@ import TreeTransforms._ import core.DenotTransformers._ import core.Contexts._ import ast.tpd -import dotty.tools.dotc.core.Phases /** This phase transforms wildcards in valdefs with their default value. * In particular for every valdef that is declared: @@ -17,8 +16,6 @@ class TransformWildcards extends MiniPhaseTransform with IdentityDenotTransforme override def phaseName = "transformWildcards" - override def runsAfter: Set[Class[_ <: Phases.Phase]] = Set(classOf[RenameLifted]) - override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = { tree match { case vDef: ValDef => assert(!tpd.isWildcardArg(vDef.rhs)) diff --git a/tests/run/i2738.check b/tests/run/i2738.check index 0521c21711ed..e4d27e3fc332 100644 --- a/tests/run/i2738.check +++ b/tests/run/i2738.check @@ -1,7 +1,7 @@ foo -bar$1 -foo bar$2 +foo +bar$1 baz Test$qux$1$ baz diff --git a/tests/run/i3006.check b/tests/run/i3006.check new file mode 100644 index 000000000000..4fc525c0d632 --- /dev/null +++ b/tests/run/i3006.check @@ -0,0 +1,5 @@ +f$3 +f$2 +f$1 +f$2 +f$1 diff --git a/tests/run/i3006.scala b/tests/run/i3006.scala new file mode 100644 index 000000000000..199fd29194d8 --- /dev/null +++ b/tests/run/i3006.scala @@ -0,0 +1,35 @@ +class Foo { + def foo() = { + def f() = println(Thread.currentThread.getStackTrace.apply(1).getMethodName) + f() + } + def bar() = { + def f() = println(Thread.currentThread.getStackTrace.apply(1).getMethodName) + f() + } + def baz() = { + def f() = println(Thread.currentThread.getStackTrace.apply(1).getMethodName) + f() + } +} + +class Bar { + def foo() = { + def f() = println(Thread.currentThread.getStackTrace.apply(1).getMethodName) + f() + } + def bar() = { + def f() = println(Thread.currentThread.getStackTrace.apply(1).getMethodName) + f() + } +} + +object Test { + def main(args: Array[String]): Unit = { + new Foo().foo() + new Foo().bar() + new Foo().baz() + new Bar().foo() + new Bar().bar() + } +} diff --git a/tests/run/i3006b.check b/tests/run/i3006b.check new file mode 100644 index 000000000000..e0e763177e0c --- /dev/null +++ b/tests/run/i3006b.check @@ -0,0 +1,3 @@ +Foo$$init$$$bar$2 +Foo$$init$$$bar$1 +Bar$$init$$$bar$1 diff --git a/tests/run/i3006b.scala b/tests/run/i3006b.scala new file mode 100644 index 000000000000..051a06f266c8 --- /dev/null +++ b/tests/run/i3006b.scala @@ -0,0 +1,35 @@ +class Foo(i: Int) { + def this() = this({ + def bar() = { + println(Thread.currentThread.getStackTrace.apply(1).getMethodName) + 5 + } + bar() + }) + + def this(i: String) = this({ + def bar() = { + println(Thread.currentThread.getStackTrace.apply(1).getMethodName) + 5 + } + bar() + }) +} + +class Bar(i: Int) { + def this() = this({ + def bar() = { + println(Thread.currentThread.getStackTrace.apply(1).getMethodName) + 5 + } + bar() + }) +} + +object Test { + def main(args: Array[String]): Unit = { + new Foo() + new Foo("") + new Bar() + } +} From da14d0d4e0e76eb79d423f9dec4459714c8f433c Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 29 Aug 2017 15:58:39 +0200 Subject: [PATCH 6/7] Rewrite nested unique names --- .../src/dotty/tools/dotc/transform/RenameLifted.scala | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala b/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala index ae5654ca735c..97e05bd4ef09 100644 --- a/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala +++ b/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala @@ -31,12 +31,16 @@ class RenameLifted extends MiniPhaseTransform with SymTransformer { thisTransfor /** Refreshes the number of the name based on the full name of the symbol */ private def refreshedName(sym: Symbol)(implicit ctx: Context): Name = { - sym.name.rewrite { + lazy val rewriteUnique: PartialFunction[Name, Name] = { case name: DerivedName if name.info.kind == UniqueName => val fullName = (sym.owner.fullName.toString + name.underlying).toTermName val freshName = UniqueName.fresh(fullName) val info = freshName.asInstanceOf[DerivedName].info - DerivedName(name.underlying, info) + DerivedName(name.underlying.rewrite(rewriteUnique), info) + case DerivedName(underlying, info: QualifiedInfo) => + underlying.rewrite(rewriteUnique).derived(info) } + + sym.name.rewrite(rewriteUnique) } } From fe7ac0a5718fdbedf614b8269a65400b95f7e10e Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 4 Sep 2017 13:12:29 +0200 Subject: [PATCH 7/7] Use def for recursive partial function --- compiler/src/dotty/tools/dotc/transform/RenameLifted.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala b/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala index 97e05bd4ef09..fca24d71b8cf 100644 --- a/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala +++ b/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala @@ -31,7 +31,7 @@ class RenameLifted extends MiniPhaseTransform with SymTransformer { thisTransfor /** Refreshes the number of the name based on the full name of the symbol */ private def refreshedName(sym: Symbol)(implicit ctx: Context): Name = { - lazy val rewriteUnique: PartialFunction[Name, Name] = { + def rewriteUnique: PartialFunction[Name, Name] = { case name: DerivedName if name.info.kind == UniqueName => val fullName = (sym.owner.fullName.toString + name.underlying).toTermName val freshName = UniqueName.fresh(fullName)