-
Notifications
You must be signed in to change notification settings - Fork 121
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refix compact names w/o breaking local names
The previous fix phase-traveled to after flatten, which is the threshold for Symbol#name to start returning flattened names. Unfortunately there is a bug (one of a few in nsc) in that the owner of the local class symbols isn't changed as a part of a lambda lift info transform, it's changed as a side-effect of doing lambda lift tree transform. Additionally the flattened name is cached on first use, which in this case means using the wrong owner - that's why the compiler failed in pekko, because there's a check in the backend that the same classfile (by name) isn't emitted twice. Turns out, we don't need the full names of method local classes, so we can push that condition a bit higher in registerGeneratedClasses, avoiding useless work, useless phase travel, and erroneous caching. We also just straight up avoid phase traveling from xsbt-api (which runs after typer) all the way to flatten (which is almost at the end) for the flatten, compactified name, by reimplementing `flattenedName`, with the correct, recursive, flattened owner and name. By the by, the test case is pretty convoluted, despite trying to make it simpler - how many times have you defined and instantiated a method-local anonymous class, defining one of its methods using a case object?
- Loading branch information
Showing
9 changed files
with
146 additions
and
45 deletions.
There are no files selected for viewing
29 changes: 29 additions & 0 deletions
29
internal/compiler-bridge/src/main/scala/scala/reflect/ReflectAccess.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package scala.reflect | ||
|
||
import scala.tools.nsc.Global | ||
|
||
// Gives access to `private[reflect] def compactifyName` | ||
object ReflectAccess { | ||
def flattenedOwner(g: Global)(sym: g.Symbol): g.Symbol = { | ||
val chain = sym.owner.ownerChain.dropWhile(o => o.isClass && !o.hasPackageFlag) | ||
if (chain.isEmpty) g.NoSymbol else chain.head | ||
} | ||
|
||
def flattenedName(g: Global)(sym: g.Symbol): g.Name = { | ||
val owner = sym.owner | ||
|
||
val flat = | ||
if ( | ||
owner.hasPackageFlag || | ||
owner.isRoot || | ||
owner == g.NoSymbol || | ||
owner.hasPackageFlag | ||
) | ||
"" + sym.rawname | ||
else { | ||
"" + flattenedName(g)(owner) + NameTransformer.NAME_JOIN_STRING + sym.rawname | ||
} | ||
val nameString = if (owner.isJava) flat else g.compactifyName(flat) | ||
if (sym.isType) g.newTypeNameCached(nameString) else g.newTermNameCached(nameString) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package xsbt | ||
|
||
object trace extends TraceSyntax { | ||
object disable extends TraceSyntax { | ||
override def apply[T](q: String)(op: => T): T = op | ||
} | ||
object enable extends TraceSyntax | ||
} | ||
|
||
object TraceSyntax { | ||
private var indent = 0 | ||
} | ||
trait TraceSyntax { | ||
import TraceSyntax._ | ||
def apply[T](q: String)(op: => T): T = { | ||
val margin = " " * indent | ||
println(s"$margin$q?") | ||
val res = | ||
try { | ||
indent += 1 | ||
op | ||
} finally indent -= 1 | ||
println(s"$margin$q = $res") | ||
res | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
zinc/src/sbt-test/source-dependencies/compactify-nested-class/main.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package p1.p2 | ||
|
||
abstract class B { | ||
def m(): L | ||
abstract class L { | ||
def i: I | ||
abstract class I | ||
} | ||
} | ||
class D extends B { override def m() = new L { override case object i extends I } } | ||
class G extends B { override def m() = new L { override case object i extends I } } |
2 changes: 2 additions & 0 deletions
2
zinc/src/sbt-test/source-dependencies/compactify-nested-class/test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
> checkProducts main.scala: ${BASE}/target/classes/p1/p2/B$L$I.class ${BASE}/target/classes/p1/p2/B$L.class ${BASE}/target/classes/p1/p2/B.class ${BASE}/target/classes/p1/p2/D$$anon$1$i$.class ${BASE}/target/classes/p1/p2/D$$anon$1.class ${BASE}/target/classes/p1/p2/D.class ${BASE}/target/classes/p1/p2/G$$anon$2$i$.class ${BASE}/target/classes/p1/p2/G$$anon$2.class ${BASE}/target/classes/p1/p2/G.class | ||
> checkProductsExists main.scala |
15 changes: 15 additions & 0 deletions
15
zinc/src/sbt-test/source-dependencies/compactify-nested/main.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package p1.p2 | ||
|
||
class OuterLevelWithVeryVeryVeryLongClassName1 { | ||
class OuterLevelWithVeryVeryVeryLongClassName2 { | ||
class OuterLevelWithVeryVeryVeryLongClassName3 { | ||
class OuterLevelWithVeryVeryVeryLongClassName4 { | ||
class OuterLevelWithVeryVeryVeryLongClassName5 { | ||
class OuterLevelWithVeryVeryVeryLongClassName6 { | ||
class OuterLevelWithVeryVeryVeryLongClassName7 | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
> checkProducts main.scala: ${BASE}/target/classes/p1/p2/OuterLevelWithVeryVeryVeryLongClassName1.class ${BASE}/target/classes/p1/p2/OuterLevelWithVeryVeryVeryLongClassName1$OuterLevelWithVeryVeryVeryLongClassName2.class ${BASE}/target/classes/p1/p2/OuterLevelWithVeryVeryVeryLongClassName1$OuterLevelWithVeryVeryVeryLongClassName2$OuterLevelWithVeryVeryVeryLongClassName3.class ${BASE}/target/classes/p1/p2/OuterLevelWithVeryVeryVeryLongClassName1$OuterLevelWithVeryVeryVeryLongClassName2$OuterLevelWithVeryVeryVeryLongClassName3$OuterLevelWithVeryVeryVeryLongClassName4.class ${BASE}/target/classes/p1/p2/OuterLevelWithVeryVeryVeryLongClassName1$OuterLevelWithVeryVeryVeryLongClassName2$OuterLevelWithVeryVeryVeryLongClassName3$OuterLevelWithVeryVeryVeryLongClassName4$OuterLevelWithVeryVeryVeryLongClassName5.class ${BASE}/target/classes/p1/p2/OuterLevelWithVeryVeryVeryLongClassName1$OuterLevelWithVeryVeryVeryLongClassName2$OuterLevelWithVeryVeryVeryLongClassName3$OuterLevelWithVeryVeryVeryLongClassName4$OuterLevelWithVeryVeryVeryLongClassName5$OuterLevelWithVeryVeryVeryLongClassName6.class ${BASE}/target/classes/p1/p2/OuterLevelWithVeryVeryVeryLongClassName1$OuterLevelWithVeryVe$$$$6facba931fe42f8a8c3cee88c4087$$$$ryVeryLongClassName6$OuterLevelWithVeryVeryVeryLongClassName7.class | ||
> checkProductsExists main.scala |