Skip to content

Commit

Permalink
Merge pull request #572 from scalacenter/find-outter
Browse files Browse the repository at this point in the history
find outter getters symbols
  • Loading branch information
adpi2 committed Aug 22, 2023
2 parents 7b82a53 + 70c6008 commit e5a6def
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 126 deletions.
4 changes: 3 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,9 @@ lazy val unpickler3: Project = project
"org.scala-lang" %% "tasty-core" % scalaVersion.value,
Dependencies.munit % Test
),
Test / fork := true
Test / fork := true,
// do not use sbt logger, otherwise the output of a test only appears at the end of the suite
Test / testOptions += Tests.Argument(TestFrameworks.MUnit, "+l")
)

lazy val scalacOptionsSetting = Def.settings(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ enum BinaryClassKind:
enum BinaryMethodSymbol:
case BinaryMethod(binaryOwner: BinaryClassSymbol, term: TermSymbol, kind: BinaryMethodKind)
case BinaryByNameArg(binaryOwner: BinaryClassSymbol)
case BinaryOuter(binaryOwner: BinaryClassSymbol, outerClass: ClassSymbol)

def symbol = this match
case BinaryMethod(_, term, _) => Some(term)
case BinaryByNameArg(binaryOwner: BinaryClassSymbol) => None
case _ => None

def symbolKind = this match
case BinaryMethod(_, _, kind) => kind
case BinaryByNameArg(_) => BinaryMethodKind.ByNameArg
case BinaryOuter(_, _) => BinaryMethodKind.Outer

enum BinaryMethodKind:
case InstanceDef, LocalDef, AnonFun, Getter, Setter, LazyInit, LocalLazyInit, Constructor, TraitConstructor,
MixinForwarder, TraitStaticAccessor, SuperAccessor, DefaultParameter, ByNameArg
MixinForwarder, TraitStaticAccessor, SuperAccessor, DefaultParameter, ByNameArg, Outer

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package ch.epfl.scala.debugadapter.internal.stacktrace

import ch.epfl.scala.debugadapter.internal.binary

object Patterns:
object LocalClass:
def unapply(cls: binary.ClassType): Option[(String, String, Option[String])] =
val decodedClassName = NameTransformer.decode(cls.name.split('.').last)
unapply(decodedClassName)

def unapply(decodedClassName: String): Option[(String, String, Option[String])] =
"(.+)\\$([^$]+)\\$\\d+(\\$.*)?".r
.unapplySeq(NameTransformer.decode(decodedClassName))
.filter(xs => xs(1) != "anon")
.map(xs => (xs(0), xs(1), Option(xs(2)).map(_.stripPrefix("$")).filter(_.nonEmpty)))

object AnonClass:
def unapply(cls: binary.ClassType): Option[(String, Option[String])] =
val decodedClassName = NameTransformer.decode(cls.name.split('.').last)
unapply(decodedClassName)
def unapply(decodedClassName: String): Option[(String, Option[String])] =
"(.+)\\$\\$anon\\$\\d+(\\$.*)?".r
.unapplySeq(NameTransformer.decode(decodedClassName))
.map(xs => (xs(0), Option(xs(1)).map(_.stripPrefix("$")).filter(_.nonEmpty)))

object InnerClass:
def unapply(cls: binary.ClassType): Option[String] =
val decodedClassName = NameTransformer.decode(cls.name.split('.').last)
unapply(decodedClassName)

def unapply(decodedClassName: String): Option[String] =
"(.+)\\$(.+)".r
.unapplySeq(NameTransformer.decode(decodedClassName))
.map(_ => decodedClassName)

object LazyInit:
def unapply(method: binary.Method): Option[String] =
val lazyInit = "(.*)\\$lzyINIT\\d+".r
lazyInit.unapplySeq(NameTransformer.decode(method.name)).map(xs => xs(0))

object StaticAccessor:
def unapply(method: binary.Method): Option[String] =
if method.isTraitStaticAccessor then Some(method.name.stripSuffix("$"))
else None

object Outer:
def unapply(method: binary.Method): Option[String] =
val anonFun = "(.*)\\$\\$\\$outer".r
anonFun.unapplySeq(NameTransformer.decode(method.name)).map(xs => xs(0))

object AnonFun:
def unapply(method: binary.Method): Option[String] =
val anonFun = "(.*)\\$anonfun\\$\\d+".r
anonFun.unapplySeq(NameTransformer.decode(method.name)).map(xs => xs(0).stripSuffix("$"))

object LocalMethod:
def unapply(method: binary.Method): Option[(String, Int)] =
if method.name.contains("$default") || method.name.contains("$proxy") then None
else
val javaPrefix = method.declaringClass.name.replace('.', '$') + "$$"
val decodedName = NameTransformer.decode(method.name.stripPrefix(javaPrefix).split("_\\$").last)
"(.+)\\$(\\d+)".r.unapplySeq(decodedName).map(xs => (xs(0), xs(1).toInt))

object LocalLazyInit:
def unapply(method: binary.Method): Option[(String, Int)] =
if method.declaredParams.nonEmpty then None
else
val javaPrefix = method.declaringClass.name.replace('.', '$') + "$$"
val decodedName = NameTransformer.decode(method.name.stripPrefix(javaPrefix).split("\\$_\\$").last)
"(.+)\\$lzyINIT\\d+\\$(\\d+)".r.unapplySeq(decodedName).map(xs => (xs(0), xs(1).toInt))
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,33 @@ import tastyquery.Symbols.*
import tastyquery.Types.*
import tastyquery.Names.*
import ch.epfl.scala.debugadapter.internal.stacktrace.BinaryMethodKind.*
import ch.epfl.scala.debugadapter.internal.stacktrace.BinaryClassKind.*
import ch.epfl.scala.debugadapter.internal.stacktrace.BinaryClassSymbol.*
import ch.epfl.scala.debugadapter.internal.stacktrace.BinaryMethodSymbol.*

class Scala3Formatter(warnLogger: String => Unit, testMode: Boolean) extends ThrowOrWarn(warnLogger, testMode):
private def formatSymbolWithType(symbol: TermSymbol): String =
val sep = if !symbol.declaredType.isInstanceOf[MethodicType] then ": " else ""
s"${formatSymbol(symbol)}$sep${formatType(symbol.declaredType)}"

def formatClassSymbol(bcls: BinaryClassSymbol) =
bcls match
case BinaryClassSymbol.BinaryClass(symbol, BinaryClassKind.Anon) =>
def format(binaryClass: BinaryClassSymbol) =
binaryClass match
case BinaryClass(symbol, Anon) =>
val prefix = formatOwner(symbol.owner)
s"$prefix.<anon class>"
case BinaryClassSymbol.BinaryClass(symbol, _) => formatSymbol(bcls.symbol)
case BinaryClassSymbol.BinarySAMClass(symbol, samClass) =>
case BinaryClass(symbol, _) => formatSymbol(symbol)
case BinarySAMClass(symbol, samClass) =>
val prefix = formatOwner(symbol.owner)
s"$prefix.<anon ${formatType(samClass)}>"

def formatMethodSymbol(bmthd: BinaryMethodSymbol): String =
bmthd match
case BinaryMethodSymbol.BinaryMethod(_, term, BinaryMethodKind.DefaultParameter) =>
def format(method: BinaryMethodSymbol): String =
method match
case BinaryMethod(_, term, BinaryMethodKind.DefaultParameter) =>
val sep = if !term.declaredType.isInstanceOf[MethodicType] then ": " else ""
term.name match
case DefaultGetterName(termName, num) =>
s"${formatOwner(term.owner)}.$termName.<default ${num + 1}>$sep${formatType(term.declaredType)}"
case BinaryMethodSymbol.BinaryMethod(binaryOwner, term, kind) =>
case BinaryMethod(binaryOwner, term, kind) =>
val sep = if !term.declaredType.isInstanceOf[MethodicType] then ": " else ""
val symbolStr = kind match
case BinaryMethodKind.AnonFun => formatOwner(term.owner) + ".<anon fun>"
Expand All @@ -39,13 +42,15 @@ class Scala3Formatter(warnLogger: String => Unit, testMode: Boolean) extends Thr
case _ => formatSymbol(term)

s"$symbolStr$sep${formatType(term.declaredType)}"
case _ => throw new UnsupportedOperationException(bmthd.toString)
case BinaryOuter(owner, outer) =>
s"${format(owner)}.<outer>: ${formatOwner(outer)}"
case _ => throw new UnsupportedOperationException(method.toString)

private def formatOwner(sym: Symbol): String =
sym match
case owner: ClassSymbol if owner.name.isPackageObject => formatSymbol(owner.owner)
case owner: TermOrTypeSymbol => formatSymbol(owner)
case owner: PackageSymbol => ""
case sym: ClassSymbol if sym.name.isPackageObject => formatSymbol(sym.owner)
case sym: TermOrTypeSymbol => formatSymbol(sym)
case sym: PackageSymbol => ""

private def formatSymbol(sym: Symbol): String =
val prefix = formatOwner(sym.owner)
Expand Down
Loading

0 comments on commit e5a6def

Please sign in to comment.