Skip to content

Commit

Permalink
Simplifications, move isPackageObject to compiler api for reuse
Browse files Browse the repository at this point in the history
  • Loading branch information
kubukoz committed May 11, 2021
1 parent 7ac6850 commit 25a6c43
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 21 deletions.
5 changes: 1 addition & 4 deletions plugin/src/main/scala-2/BetterToStringPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,7 @@ final class BetterToStringPluginComponent(val global: Global) extends PluginComp
tree match {
case p: PackageDef => p.copy(stats = p.stats.map(modifyClasses(_, None)))
case m: ModuleDef =>
// couldn't find any nice api for this. `m.symbol.isPackageObject` does not work
val isPackageObject = m.symbol.isInstanceOf[NoSymbol] && m.name.toString == "package"
val enclosingObject = if (!isPackageObject) Some(m) else None
m.copy(impl = m.impl.copy(body = m.impl.body.map(modifyClasses(_, enclosingObject))))
m.copy(impl = m.impl.copy(body = m.impl.body.map(modifyClasses(_, Some(m)))))
case clazz: ClassDef =>
impl.transformClass(
clazz,
Expand Down
7 changes: 6 additions & 1 deletion plugin/src/main/scala-2/Scala2CompilerApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ object Scala2CompilerApi {
}

def className(clazz: Clazz): String = clazz.name.toString
def enclosingObjectName(enclosingObject: EnclosingObject) = enclosingObject.name.toString

def isPackageOrPackageObject(enclosingObject: EnclosingObject): Boolean =
// couldn't find any nice api for this. `m.symbol.isPackageObject` does not work after the parser compiler phase (needs to run later).
enclosingObject.symbol.isInstanceOf[NoSymbol] && enclosingObject.name.toString == "package"

def enclosingObjectName(enclosingObject: EnclosingObject): String = enclosingObject.name.toString
def literalConstant(value: String): Tree = Literal(Constant(value))
def paramName(param: Param): ParamName = param.name
def selectInThis(clazz: Clazz, name: ParamName): Tree = q"this.$name"
Expand Down
16 changes: 2 additions & 14 deletions plugin/src/main/scala-3/BetterToStringPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,13 @@ final class BetterToStringPluginPhase extends PluginPhase:
val clazz = ctx.owner.asClass

val ownerOwner = ctx.owner.owner
val isNested = !(ownerOwner.isPackageObject || ownerOwner.is(Module)) || isAnyAncestorAClass(ownerOwner)
val isNested = ownerOwner.ownersIterator.exists(!_.is(Module))

val enclosingObject =
if (
ownerOwner.is(Module) &&
!ownerOwner.is(Package) &&
!ownerOwner.isPackageObject
) then Some(ctx.owner.owner)
if (ownerOwner.is(Module)) then Some(ownerOwner)
else None

BetterToStringImpl
.instance(Scala3CompilerApi.instance)
.transformClass(Scala3CompilerApi.ClassContext(t, clazz), isNested, enclosingObject)
.t

@tailrec private def isAnyAncestorAClass(sym: Symbols.Symbol)(using Context): Boolean =
if sym == Symbols.NoSymbol then return false

// we want a class-class not an object (Module) or a package object (which are both also classes)
if !sym.is(Module) && !sym.is(Package) && !sym.isPackageObject then return true

isAnyAncestorAClass(sym.owner)
9 changes: 8 additions & 1 deletion plugin/src/main/scala-3/Scala3CompilerApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import dotty.tools.dotc.core.Symbols
import dotty.tools.dotc.core.Flags.CaseAccessor
import dotty.tools.dotc.core.Flags.CaseClass
import dotty.tools.dotc.core.Flags.Override
import dotty.tools.dotc.core.Flags.Package
import dotty.tools.dotc.core.Types
import dotty.tools.dotc.core.Names
import dotty.tools.dotc.core.Constants.Constant
Expand Down Expand Up @@ -33,7 +34,13 @@ object Scala3CompilerApi:
}

def className(clazz: Clazz): String = clazz.clazz.name.toString
def enclosingObjectName(enclosingObject: EnclosingObject): String = enclosingObject.effectiveName.toString

def isPackageOrPackageObject(enclosingObject: EnclosingObject): Boolean =
enclosingObject.is(Package) || enclosingObject.isPackageObject

def enclosingObjectName(enclosingObject: EnclosingObject): String =
enclosingObject.effectiveName.toString

def literalConstant(value: String): Tree = Literal(Constant(value))
def paramName(param: Param): ParamName = param.name
def selectInThis(clazz: Clazz, name: ParamName): Tree = This(clazz.clazz).select(name)
Expand Down
3 changes: 2 additions & 1 deletion plugin/src/main/scala/BetterToStringImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ trait CompilerApi {
type EnclosingObject

def className(clazz: Clazz): String
def isPackageOrPackageObject(enclosingObject: EnclosingObject): Boolean
def enclosingObjectName(enclosingObject: EnclosingObject): String
def params(clazz: Clazz): List[Param]
def literalConstant(value: String): Tree
Expand Down Expand Up @@ -65,7 +66,7 @@ object BetterToStringImpl {

private def toStringImpl(clazz: Clazz, enclosingObject: Option[EnclosingObject]): Tree = {
val className = api.className(clazz)
val parentPrefix = enclosingObject.map(p => api.enclosingObjectName(p) ++ ".").getOrElse("")
val parentPrefix = enclosingObject.filterNot(api.isPackageOrPackageObject).fold("")(api.enclosingObjectName(_) ++ ".")

val paramListParts: List[Tree] = params(clazz).zipWithIndex.flatMap { case (v, index) =>
val commaPrefix = if (index > 0) ", " else ""
Expand Down

0 comments on commit 25a6c43

Please sign in to comment.