Skip to content

Commit

Permalink
Merge pull request #563 from scalacenter/inlined-sym
Browse files Browse the repository at this point in the history
find inlined local symbols
  • Loading branch information
adpi2 committed Aug 10, 2023
2 parents 28cc8ca + cd1ac9b commit f3a6ee0
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import scala.jdk.OptionConverters.*
import scala.util.matching.Regex
import tastyquery.Modifiers.TermSymbolKind
import tastyquery.SourceLanguage
import scala.util.control.NonFatal

class Scala3Unpickler(
classpaths: Array[Path],
Expand Down Expand Up @@ -139,21 +140,27 @@ class Scala3Unpickler(
): Seq[S] =
val f = partialF.lift.andThen(_.toSeq)

def collectSymbols(tree: Tree): Seq[S] =
def isInline(tree: Ident): Boolean =
try tree.symbol.isTerm && tree.symbol.asTerm.isInline
catch case NonFatal(e) => false

def collectSymbols(tree: Tree, inlineSet: Set[Symbol]): Seq[S] =
tree.walkTree {
case ValDef(_, _, _, symbol) if symbol.isLocal && (symbol.isLazyVal || symbol.isModuleVal) => f((symbol, None))
case DefDef(_, _, _, _, symbol) if symbol.isLocal => f(symbol, None)
case ClassDef(_, _, symbol) if symbol.isLocal => f(symbol, None)
case lambda: Lambda =>
val sym = lambda.meth.asInstanceOf[TermReferenceTree].symbol
f(sym, Some(lambda.samClassSymbol))
case tree: Ident if isInline(tree) && !inlineSet.contains(tree.symbol) =>
tree.symbol.tree.toSeq.flatMap(collectSymbols(_, inlineSet + tree.symbol))
case _ => Seq.empty
}(_ ++ _, Seq.empty)

for
decl <- cls.declarations
tree <- decl.tree.toSeq
localSym <- collectSymbols(tree)
localSym <- collectSymbols(tree, Set.empty)
yield localSym

def formatType(t: TermType | TypeOrWildcard): String =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,30 @@ abstract class Scala3UnpicklerTests(val scalaVersion: ScalaVersion) extends FunS
debuggee.assertFormat("example.A", "example.A m()", "A.m(): A")
}

test("inline def with anonymous class and method") {
val source =
"""|package example
|class A
|
|inline def m: Unit =
| val f = (x : Int) => x + 1
| val a = new A {
| println("")
| }
| if true then () else m
|
|class B :
| def n =
| m
|""".stripMargin

val debuggee = TestingDebuggee.mainClass(source, "example.Main", scalaVersion)
debuggee.assertFormat("example.B", "int $anonfun$1(int x)", "example.m.f.$anonfun(x: Int): Int")
debuggee.assertFormat("example.B$$anon$1", "example.m.a.$anon")
// debuggee.assertFormat("example.A", "example.A m()", "A.m(): A")

}

test("anonClass from SAM class") {
val source =
"""|package example
Expand Down

0 comments on commit f3a6ee0

Please sign in to comment.