Skip to content

Commit

Permalink
Merge pull request #656 from adpi2/rename-decoder
Browse files Browse the repository at this point in the history
Rename unpickler to decoder
  • Loading branch information
adpi2 committed Feb 13, 2024
2 parents 47671b2 + 2a2fff5 commit 4bfc0bc
Show file tree
Hide file tree
Showing 66 changed files with 70 additions and 69 deletions.
2 changes: 1 addition & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ rewrite.redundantBraces.generalExpressions = true
rewrite.redundantBraces.stringInterpolation = true
rewrite.redundantBraces.defnBodies = none
fileOverride {
"glob:**/modules/unpickler/**.scala" {
"glob:**/modules/decoder/**.scala" {
rewrite.scala3.convertToNewSyntax = yes
rewrite.scala3.removeOptionalBraces = yes
}
Expand Down
12 changes: 6 additions & 6 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ lazy val root = project
expressionCompiler30,
expressionCompiler33,
expressionCompiler34,
unpickler3
decoder3
)
.settings(
publish / skip := true
Expand Down Expand Up @@ -93,7 +93,7 @@ lazy val core = projectMatrix
BuildInfoKey.action("organization")(organization.value),
BuildInfoKey.action("version")(version.value),
BuildInfoKey.action("expressionCompilerName")((LocalProject("expressionCompiler2_12") / name).value),
BuildInfoKey.action("unpicklerName")((LocalProject("unpickler3") / name).value),
BuildInfoKey.action("decoderName")((LocalProject("decoder3") / name).value),
BuildInfoKey.action("scala212")(Dependencies.scala212),
BuildInfoKey.action("scala213")(Dependencies.scala213),
BuildInfoKey.action("scala30")(Dependencies.scala30),
Expand Down Expand Up @@ -194,12 +194,12 @@ lazy val expressionCompiler = projectMatrix
scalacOptionsSettings
)

lazy val unpickler3: Project = project
.in(file("modules/unpickler"))
lazy val decoder3: Project = project
.in(file("modules/decoder"))
.disablePlugins(SbtJdiTools)
.dependsOn(tests3 % Test)
.settings(
name := "scala-debug-unpickler",
name := "scala-debug-decoder",
scalaVersion := Dependencies.scala33,
Compile / doc / sources := Seq.empty,
libraryDependencies ++= Seq(
Expand All @@ -222,7 +222,7 @@ lazy val testOptionsSettings = Def.settings(
LocalProject("expressionCompiler2_13") / publishLocal,
LocalProject("expressionCompiler3_3") / publishLocal,
LocalProject("expressionCompiler3_4") / publishLocal,
LocalProject("unpickler3") / publishLocal
LocalProject("decoder3") / publishLocal
)
.value
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import scala.util.Try

trait DebugToolsResolver {
def resolveExpressionCompiler(scalaVersion: ScalaVersion): Try[ClassLoader]
def resolveUnpickler(scalaVersion: ScalaVersion): Try[ClassLoader]
def resolveDecoder(scalaVersion: ScalaVersion): Try[ClassLoader]
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import scala.reflect.io.File

private[debugadapter] final class DebugTools(
val expressionCompilers: Map[ClassEntry, ExpressionCompiler],
val unpickler: Option[ClassLoader],
val decoder: Option[ClassLoader],
val sourceLookUp: SourceLookUpProvider
)

Expand All @@ -28,12 +28,12 @@ object DebugTools {
loadExpressionCompiler(debuggee, resolver, logger)
}

val unpickler =
val decoder =
if (debuggee.scalaVersion.isScala3) {
TimeUtils.logTime(logger, "Loaded step filter") {
resolver
.resolveUnpickler(debuggee.scalaVersion)
.warnFailure(logger, s"Cannot fetch unpickler of Scala ${debuggee.scalaVersion}")
.resolveDecoder(debuggee.scalaVersion)
.warnFailure(logger, s"Cannot fetch decoder of Scala ${debuggee.scalaVersion}")
}
} else None

Expand All @@ -49,7 +49,7 @@ object DebugTools {
SourceLookUpProvider(distinctEntries, logger)
}

new DebugTools(allCompilers, unpickler, sourceLookUp)
new DebugTools(allCompilers, decoder, sourceLookUp)
}

/* At most 2 expression compilers are resolved, one for Scala 2 and one for Scala 3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ import java.util.Optional

class StackTraceProvider(
runtimeFilter: RuntimeStepFilter,
scalaUnpickler: ScalaUnpickler,
decoder: ScalaDecoder,
logger: Logger,
testMode: Boolean
) extends JavaStackTraceProvider() {

private val stepFilters: Seq[StepFilter] = Seq(ClassLoadingFilter, runtimeFilter, scalaUnpickler)
private val stepFilters: Seq[StepFilter] = Seq(ClassLoadingFilter, runtimeFilter, decoder)

def reload(): Unit = scalaUnpickler.reload()
def reload(): Unit = decoder.reload()

override def formatMethod(method: Method): Optional[String] = {
scalaUnpickler.format(method) match {
decoder.format(method) match {
case None => Optional.empty()
case Some(s) => Optional.of(s)
}
Expand Down Expand Up @@ -62,11 +62,11 @@ object StackTraceProvider {
logger: Logger,
testMode: Boolean
): StackTraceProvider = {
val scalaUnpickler: ScalaUnpickler = ScalaUnpickler(debuggee, tools, logger, testMode)
val decoder: ScalaDecoder = ScalaDecoder(debuggee, tools, logger, testMode)
val runtimeStepFilter = RuntimeStepFilter(debuggee.scalaVersion)
new StackTraceProvider(
runtimeStepFilter,
scalaUnpickler,
decoder,
logger,
testMode
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import com.sun.jdi
import scala.jdk.CollectionConverters.*
import scala.util.matching.Regex

class Scala2Unpickler(
class Scala2Decoder(
sourceLookUp: SourceLookUpProvider,
scalaVersion: ScalaVersion,
logger: Logger,
testMode: Boolean
) extends ScalaUnpickler(scalaVersion, testMode) {
) extends ScalaDecoder(scalaVersion, testMode) {
override protected def skipScala(method: jdi.Method): Boolean = {
if (isLazyInitializer(method)) {
skipLazyInitializer(method)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ import scala.jdk.CollectionConverters._
import scala.jdk.OptionConverters._
import scala.util.Try

class Scala3UnpicklerBridge(
class Scala3DecoderBridge(
debuggee: Debuggee,
cls: Class[?],
var bridge: Any,
skipMethod: Method,
formatMethod: Method,
testMode: Boolean,
logger: Logger
) extends ScalaUnpickler(debuggee.scalaVersion, testMode) {
) extends ScalaDecoder(debuggee.scalaVersion, testMode) {

override def reload(): Unit =
bridge = Scala3UnpicklerBridge.load(debuggee, cls, logger, testMode)
bridge = Scala3DecoderBridge.load(debuggee, cls, logger, testMode)

override protected def skipScala(method: jdi.Method): Boolean = {
try skipMethod.invoke(bridge, method).asInstanceOf[Boolean]
Expand All @@ -46,8 +46,8 @@ class Scala3UnpicklerBridge(
}
}

object Scala3UnpicklerBridge {
def load(debuggee: Debuggee, unpicklerClass: Class[?], logger: Logger, testMode: Boolean) = {
object Scala3DecoderBridge {
def load(debuggee: Debuggee, decoderClass: Class[?], logger: Logger, testMode: Boolean) = {
val javaRuntimeJars = debuggee.javaRuntime.toSeq.flatMap {
case Java8(_, classJars, _) => classJars
case java9OrAbove: Java9OrAbove =>
Expand All @@ -57,7 +57,7 @@ object Scala3UnpicklerBridge {
}
val debuggeeClasspath = debuggee.classPath.toArray ++ javaRuntimeJars
val warnLogger: Consumer[String] = msg => logger.warn(msg)
val ctr = unpicklerClass.getConstructor(classOf[Array[Path]], classOf[Consumer[String]], classOf[Boolean])
val ctr = decoderClass.getConstructor(classOf[Array[Path]], classOf[Consumer[String]], classOf[Boolean])

ctr.newInstance(debuggeeClasspath, warnLogger, testMode: java.lang.Boolean)
}
Expand All @@ -67,16 +67,16 @@ object Scala3UnpicklerBridge {
classLoader: ClassLoader,
logger: Logger,
testMode: Boolean
): Try[Scala3UnpicklerBridge] = {
): Try[Scala3DecoderBridge] = {
Try {
val className = "ch.epfl.scala.debugadapter.internal.stacktrace.Scala3UnpicklerBridge"
val className = "ch.epfl.scala.debugadapter.internal.stacktrace.Scala3DecoderBridge"
val cls = classLoader.loadClass(className)

val bridge = load(debuggee, cls, logger, testMode)
val skipMethod = cls.getMethod("skipMethod", classOf[Any])
val formatMethod = cls.getMethod("formatMethod", classOf[Any])

new Scala3UnpicklerBridge(debuggee, cls, bridge, skipMethod, formatMethod, testMode, logger)
new Scala3DecoderBridge(debuggee, cls, bridge, skipMethod, formatMethod, testMode, logger)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import com.sun.jdi.ReferenceType
import scala.jdk.CollectionConverters.*
import scala.util.control.NonFatal

abstract class ScalaUnpickler(scalaVersion: ScalaVersion, testMode: Boolean) extends StepFilter {
abstract class ScalaDecoder(scalaVersion: ScalaVersion, testMode: Boolean) extends StepFilter {
protected def skipScala(method: Method): Boolean
protected def formatScala(method: Method): Option[String] = Some(formatJava(method))

Expand Down Expand Up @@ -145,27 +145,27 @@ abstract class ScalaUnpickler(scalaVersion: ScalaVersion, testMode: Boolean) ext
method.name.matches(""".+\$access\$\d+""")
}

object ScalaUnpickler {
object ScalaDecoder {
def apply(
debuggee: Debuggee,
tools: DebugTools,
logger: Logger,
testMode: Boolean
): ScalaUnpickler = {
): ScalaDecoder = {
if (debuggee.scalaVersion.isScala2)
new Scala2Unpickler(tools.sourceLookUp, debuggee.scalaVersion, logger, testMode)
new Scala2Decoder(tools.sourceLookUp, debuggee.scalaVersion, logger, testMode)
else
tools.unpickler
tools.decoder
.flatMap { classLoader =>
Scala3UnpicklerBridge
Scala3DecoderBridge
.tryLoad(debuggee, classLoader, logger, testMode)
.warnFailure(logger, s"Cannot load step filter for Scala ${debuggee.scalaVersion}")
}
.getOrElse(fallback(debuggee.scalaVersion, testMode))
}

private def fallback(scalaVersion: ScalaVersion, testMode: Boolean): ScalaUnpickler =
new ScalaUnpickler(scalaVersion, testMode) {
private def fallback(scalaVersion: ScalaVersion, testMode: Boolean): ScalaDecoder =
new ScalaDecoder(scalaVersion, testMode) {
override protected def skipScala(method: Method): Boolean = false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import java.util.function.Consumer
import scala.jdk.OptionConverters.*
import scala.util.matching.Regex

class Scala3UnpicklerBridge(
class Scala3DecoderBridge(
classEntries: Array[Path],
warnLogger: Consumer[String],
testMode: Boolean
Expand All @@ -28,17 +28,18 @@ class Scala3UnpicklerBridge(
// make it quiet, or it would be too verbose when things go wrong
using ThrowOrWarn(_ => (), testMode)
)
val formatter: StackTraceFormatter = StackTraceFormatter(using ThrowOrWarn(s => warnLogger.accept(s), testMode))
val unpickler: Scala3Unpickler = Scala3Unpickler(decoder, formatter)
private val formatter = StackTraceFormatter(using ThrowOrWarn(s => warnLogger.accept(s), testMode))
private val impl: Scala3Decoder = Scala3Decoder(formatter)

def skipMethod(obj: Any): Boolean =
val decodedMethod = decoder.decode(JdiMethod(obj))
unpickler.skip(decodedMethod)
impl.skip(decodedMethod)

def formatMethod(obj: Any): Optional[String] =
unpickler.format(JdiMethod(obj)).toJava
val decodedMethod = decoder.decode(JdiMethod(obj))
impl.format(decodedMethod).toJava

class Scala3Unpickler(decoder: BinaryDecoder, formatter: StackTraceFormatter):
class Scala3Decoder(formatter: StackTraceFormatter):
def skip(method: DecodedMethod): Boolean =
method match
case method: DecodedMethod.ValOrDefDef =>
Expand All @@ -65,7 +66,7 @@ class Scala3Unpickler(decoder: BinaryDecoder, formatter: StackTraceFormatter):
case method: DecodedMethod.InlinedMethod => skip(method.underlying)
case _ => false

def format(method: binary.Method): Option[String] =
def format(method: DecodedMethod): Option[String] =
def rec(method: DecodedMethod): Option[String] =
method match
case method: DecodedMethod.LazyInit if method.symbol.owner.isTrait => None
Expand All @@ -80,4 +81,4 @@ class Scala3Unpickler(decoder: BinaryDecoder, formatter: StackTraceFormatter):
case _: DecodedMethod.AdaptedFun => None
case method: DecodedMethod.InlinedMethod => rec(method.underlying)
case m => Some(formatter.format(m))
rec(decoder.decode(method))
rec(method)
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import scala.jdk.CollectionConverters.*
trait BinaryDecoderSuite extends CommonFunSuite:
protected def throwOrWarn: ThrowOrWarn = ThrowOrWarn.printAndThrow
private def formatter(using ThrowOrWarn) = StackTraceFormatter()
private def debugDecoder = Scala3Decoder(formatter)

given ThrowOrWarn = throwOrWarn

Expand All @@ -35,7 +36,6 @@ trait BinaryDecoderSuite extends CommonFunSuite:
TestingDecoder(library, libraries)

extension (decoder: TestingDecoder)
private def unpickler = Scala3Unpickler(decoder.decoder, formatter)

def assertDecode(className: String, expected: String)(using munit.Location): Unit =
val cls = decoder.classLoader.loadClass(className)
Expand All @@ -48,7 +48,7 @@ trait BinaryDecoderSuite extends CommonFunSuite:
val binaryMethod = loadBinaryMethod(className, method)
val decodedMethod = decoder.decode(binaryMethod)
assertEquals(formatter.format(decodedMethod), expected)
assertEquals(unpickler.skip(decodedMethod), skip)
assertEquals(debugDecoder.skip(decodedMethod), skip)

def assertNotFound(declaringType: String, javaSig: String)(using munit.Location): Unit =
val method = loadBinaryMethod(declaringType, javaSig)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,18 @@ class SbtDebugToolsResolver(
}
}

override def resolveUnpickler(scalaVersion: ScalaVersion): Try[ClassLoader] = {
override def resolveDecoder(scalaVersion: ScalaVersion): Try[ClassLoader] = {
val org = BuildInfo.organization
val artifact = s"${BuildInfo.unpicklerName}_3"
val artifact = s"${BuildInfo.decoderName}_3"
val version = BuildInfo.version
val tastyDep = "org.scala-lang" % "tasty-core_3" % scalaVersion.value

for (report <- fetchArtifactsOf(org % artifact % version, Seq(tastyDep))) yield {
val unpicklerJars = report
val decoderJars = report
.select(configurationFilter(Runtime.name), moduleFilter(), artifactFilter(extension = "jar", classifier = ""))
.map(_.toURI.toURL)
.toArray
new URLClassLoader(unpicklerJars, null)
new URLClassLoader(decoderJars, null)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ sealed abstract class ScalaInstance(
val libraryJars: Seq[Library],
compilerJars: Seq[Library],
expressionCompilerJar: Library,
unpicklerJars: Seq[Library]
decoderJars: Seq[Library]
) {
val libraryClassLoader = new URLClassLoader(libraryJars.map(_.toURL).toArray, null)
val compilerClassLoader = new URLClassLoader(compilerJars.map(_.toURL).toArray, libraryClassLoader)
val expressionCompilerClassLoader = new URLClassLoader(Array(expressionCompilerJar.toURL), compilerClassLoader)
val unpicklerClassLoader = new URLClassLoader(unpicklerJars.map(_.toURL).toArray, null)
val decoderClassLoader = new URLClassLoader(decoderJars.map(_.toURL).toArray, null)

def compile(
classDir: Path,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ object TestingResolver extends DebugToolsResolver {
override def resolveExpressionCompiler(scalaVersion: ScalaVersion): Try[ClassLoader] =
Try(get(scalaVersion).expressionCompilerClassLoader)

override def resolveUnpickler(scalaVersion: ScalaVersion): Try[ClassLoader] =
Try(get(scalaVersion).unpicklerClassLoader)
override def resolveDecoder(scalaVersion: ScalaVersion): Try[ClassLoader] =
Try(get(scalaVersion).decoderClassLoader)

def get(scalaVersion: ScalaVersion): ScalaInstance = {
if (!cache.contains(scalaVersion)) {
Expand Down Expand Up @@ -110,8 +110,8 @@ object TestingResolver extends DebugToolsResolver {
BuildInfo.version
)

val unpicklerDep = Dependency(
coursier.Module(Organization(BuildInfo.organization), ModuleName(s"${BuildInfo.unpicklerName}_3")),
val decoderDep = Dependency(
coursier.Module(Organization(BuildInfo.organization), ModuleName(s"${BuildInfo.decoderName}_3")),
BuildInfo.version
)

Expand All @@ -121,12 +121,12 @@ object TestingResolver extends DebugToolsResolver {
)

val jars = fetch(expressionCompilerDep)
val unpicklerJars = fetch(unpicklerDep, tastyDep)
val decoderJars = fetch(decoderDep, tastyDep)
val libraryJars =
jars.filter(jar => jar.name.startsWith("scala-library") || jar.name.startsWith("scala3-library_3"))
val expressionCompilerJar = jars.find(jar => jar.name.startsWith(expressionCompilerArtifact)).get
val compilerJars = jars.filter(jar => !libraryJars.contains(jar) && jar != expressionCompilerJar)

new Scala3Instance(libraryJars, compilerJars, expressionCompilerJar, unpicklerJars)
new Scala3Instance(libraryJars, compilerJars, expressionCompilerJar, decoderJars)
}
}
Loading

0 comments on commit 4bfc0bc

Please sign in to comment.