Skip to content

Commit f1a7f09

Browse files
authored
Merge pull request #381 from adpi2/fix-target-name
Fix stepping into method with @TargetNAME
2 parents 75f7f72 + bdeb4e6 commit f1a7f09

File tree

3 files changed

+42
-31
lines changed

3 files changed

+42
-31
lines changed

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ lazy val scala3StepFilter: Project = project
201201
scalaVersion := Dependencies.scala31Plus,
202202
Compile / doc / sources := Seq.empty,
203203
libraryDependencies ++= Seq(
204-
"ch.epfl.scala" %% "tasty-query" % "0.5.7",
204+
"ch.epfl.scala" %% "tasty-query" % "0.6.1",
205205
"org.scala-lang" %% "tasty-core" % scalaVersion.value,
206206
Dependencies.munit % Test
207207
),

modules/scala-3-step-filter/src/main/scala/ch/epfl/scala/debugadapter/internal/stepfilter/ScalaStepFilterBridge.scala

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,7 @@ class ScalaStepFilterBridge(
6363
.collect { case sym: TermSymbol if sym.isTerm => sym }
6464
yield term
6565

66-
private def findDeclaringType(
67-
fqcn: String,
68-
isExtensionMethod: Boolean
69-
): Option[DeclaringSymbol] =
66+
private def findDeclaringType(fqcn: String, isExtensionMethod: Boolean): Option[DeclaringSymbol] =
7067
val javaParts = fqcn.split('.')
7168
val isObject = fqcn.endsWith("$")
7269
val packageNames = javaParts.dropRight(1).toList.map(SimpleName.apply)
@@ -75,36 +72,30 @@ class ScalaStepFilterBridge(
7572
then ctx.findSymbolFromRoot(packageNames).asInstanceOf[PackageSymbol]
7673
else ctx.defn.EmptyPackage
7774
val className = javaParts.last
78-
def findRec(
79-
owner: DeclaringSymbol,
80-
encodedName: String
81-
): Seq[DeclaringSymbol] =
82-
owner.declarations
83-
.collect { case sym: DeclaringSymbol => sym }
84-
.flatMap { sym =>
85-
val encodedSymName = NameTransformer.encode(sym.name.toString)
86-
val Symbol = s"${Regex.quote(encodedSymName)}\\$$?(.*)".r
87-
encodedName match
88-
case Symbol(remaining) =>
89-
if remaining.isEmpty then Some(sym)
90-
else findRec(sym, remaining)
91-
case _ => None
92-
}
93-
val clsSymbols = findRec(packageSym, className)
75+
val clsSymbols = findSymbolsRecursively(packageSym, className)
9476
val obj = clsSymbols.filter(_.is(Flags.Module))
9577
val cls = clsSymbols.filter(!_.is(Flags.Module))
9678
assert(obj.size <= 1 && cls.size <= 1)
9779
if isObject && !isExtensionMethod then obj.headOption else cls.headOption
9880

99-
private def matchSymbol(
100-
method: jdi.Method,
101-
symbol: TermSymbol,
102-
isExtensionMethod: Boolean
103-
): Boolean =
104-
matchName(method, symbol, isExtensionMethod) &&
81+
private def findSymbolsRecursively(owner: DeclaringSymbol, encodedName: String): Seq[DeclaringSymbol] =
82+
owner.declarations
83+
.collect { case sym: DeclaringSymbol => sym }
84+
.flatMap { sym =>
85+
val encodedSymName = NameTransformer.encode(sym.name.toString)
86+
val Symbol = s"${Regex.quote(encodedSymName)}\\$$?(.*)".r
87+
encodedName match
88+
case Symbol(remaining) =>
89+
if remaining.isEmpty then Some(sym)
90+
else findSymbolsRecursively(sym, remaining)
91+
case _ => None
92+
}
93+
94+
private def matchSymbol(method: jdi.Method, symbol: TermSymbol, isExtensionMethod: Boolean): Boolean =
95+
matchTargetName(method, symbol, isExtensionMethod) &&
10596
matchSignature(method, symbol, isExtensionMethod)
10697

107-
def matchName(
98+
def matchTargetName(
10899
method: jdi.Method,
109100
symbol: TermSymbol,
110101
isExtensionMethod: Boolean
@@ -114,7 +105,7 @@ class ScalaStepFilterBridge(
114105
// and prefixes its name with the full class name.
115106
// Example: method foo in class example.Inner becomes example$Inner$$foo
116107
val expectedName = method.name.stripPrefix(javaPrefix)
117-
val encodedScalaName = NameTransformer.encode(symbol.name.toString)
108+
val encodedScalaName = NameTransformer.encode(symbol.targetName.toString)
118109
if isExtensionMethod then encodedScalaName == expectedName.stripSuffix("$extension")
119110
else encodedScalaName == expectedName
120111

modules/tests/src/test/scala/ch/epfl/scala/debugadapter/StepFilterTests.scala

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,27 @@ package ch.epfl.scala.debugadapter
22

33
import ch.epfl.scala.debugadapter.testfmk.*
44

5-
class Scala3StepFilterTests extends StepFilterTests(ScalaVersion.`3.1+`)
5+
class Scala3StepFilterTests extends StepFilterTests(ScalaVersion.`3.1+`) {
6+
test("step into method with @targetName") {
7+
val source =
8+
"""|package example
9+
|
10+
|import scala.annotation.targetName
11+
|
12+
|object Main {
13+
| def main(args: Array[String]): Unit =
14+
| m("Hello")
15+
|
16+
| @targetName("mTarget")
17+
| def m(message: String): Unit =
18+
| println(message)
19+
|}
20+
|""".stripMargin
21+
implicit val debuggee: TestingDebuggee = TestingDebuggee.mainClass(source, "example.Main", scalaVersion)
22+
check(Breakpoint(7), StepIn.method("Main$.mTarget(String)"))
23+
}
24+
}
25+
626
class Scala212StepFilterTests extends StepFilterTests(ScalaVersion.`2.12`)
727
class Scala213StepFilterTests extends StepFilterTests(ScalaVersion.`2.13`) {
828
test("should match all kinds of Scala 2 types (not valid in Scala 3)") {
@@ -31,7 +51,7 @@ class Scala213StepFilterTests extends StepFilterTests(ScalaVersion.`2.13`) {
3151
}
3252
}
3353

34-
abstract class StepFilterTests(scalaVersion: ScalaVersion) extends DebugTestSuite {
54+
abstract class StepFilterTests(protected val scalaVersion: ScalaVersion) extends DebugTestSuite {
3555
test("should not step into mixin forwarder") {
3656
val source =
3757
"""|package example

0 commit comments

Comments
 (0)