Skip to content

Improve Tasty reflect modifiers api #4632

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 14 additions & 52 deletions compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -137,17 +137,24 @@ object TastyImpl extends scala.tasty.Tasty {

def owner(implicit ctx: Context): Definition = FromSymbol.definition(x.symbol.owner)

def flags(implicit ctx: Contexts.Context): FlagSet =
def flags(implicit ctx: Context): FlagSet =
new FlagSet(x.symbol.flags)

def mods(implicit ctx: Context): List[Modifier] = {
val privateWithin = x.symbol.privateWithin
val isProtected = x.symbol.is(core.Flags.Protected)
ModFlags(new FlagSet(x.symbol.flags)) ::
(if (privateWithin.exists) List(ModQual(privateWithin.typeRef, isProtected)) else Nil) :::
x.symbol.annotations.map(t => ModAnnot(t.tree))
def privateWithin(implicit ctx: Context): Option[Type] = {
val within = x.symbol.privateWithin
if (within.exists && !x.symbol.is(core.Flags.Protected)) Some(within.typeRef)
else None
}

def protectedWithin(implicit ctx: Context): Option[Type] = {
val within = x.symbol.privateWithin
if (within.exists && x.symbol.is(core.Flags.Protected)) Some(within.typeRef)
else None
}

def annots(implicit ctx: Context): List[Term] =
x.symbol.annotations.map(_.tree)

def localContext(implicit ctx: Context): Context =
if (x.hasType && x.symbol.exists) ctx.withOwner(x.symbol)
else ctx
Expand Down Expand Up @@ -909,51 +916,6 @@ object TastyImpl extends scala.tasty.Tasty {

}


// ===== Modifier =================================================

type Modifier = ModImpl

trait ModImpl
case class ModAnnot(tree: Term) extends ModImpl
case class ModFlags(flags: FlagSet) extends ModImpl
case class ModQual(tp: Type, protect: Boolean) extends ModImpl

def modifierClassTag: ClassTag[Modifier] = implicitly[ClassTag[Modifier]]


object Modifier extends ModifierModule {

object Annotation extends AnnotationExtractor {
def unapply(x: Modifier)(implicit ctx: Context): Option[Term] = x match {
case ModAnnot(tree) => Some(tree)
case _ => None
}
}

object Flags extends FlagsExtractor {
def unapply(x: Modifier)(implicit ctx: Context): Option[FlagSet] = x match {
case ModFlags(flags) => Some(flags)
case _ => None
}
}

object QualifiedPrivate extends QualifiedPrivateExtractor {
def unapply(x: Modifier)(implicit ctx: Context): Option[Type] = x match {
case ModQual(tp, false) => Some(tp)
case _ => None
}
}

object QualifiedProtected extends QualifiedProtectedExtractor {
def unapply(x: Modifier)(implicit ctx: Context): Option[Type] = x match {
case ModQual(tp, true) => Some(tp)
case _ => None
}
}

}

// ===== Signature ================================================

type Signature = core.Signature
Expand Down
36 changes: 3 additions & 33 deletions library/src/scala/tasty/Tasty.scala
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ abstract class Tasty { tasty =>

trait AbstractDefinition {
def flags(implicit ctx: Context): FlagSet
def mods(implicit ctx: Context): List[Modifier]
def privateWithin(implicit ctx: Context): Option[Type]
def protectedWithin(implicit ctx: Context): Option[Type]
def annots(implicit ctx: Context): List[Term]
def owner(implicit ctx: Context): Definition
def localContext(implicit ctx: Context): Context
}
Expand Down Expand Up @@ -680,38 +682,6 @@ abstract class Tasty { tasty =>

}

// ===== Modifiers ================================================

type Modifier

implicit def modifierClassTag: ClassTag[Modifier]

val Modifier: ModifierModule
abstract class ModifierModule {

val Annotation: AnnotationExtractor
abstract class AnnotationExtractor {
def unapply(x: Modifier)(implicit ctx: Context): Option[Term]
}

val Flags: FlagsExtractor
abstract class FlagsExtractor {
def unapply(x: Modifier)(implicit ctx: Context): Option[FlagSet]
}

val QualifiedPrivate: QualifiedPrivateExtractor
abstract class QualifiedPrivateExtractor {
def unapply(x: Modifier)(implicit ctx: Context): Option[Type]
}

val QualifiedProtected: QualifiedProtectedExtractor
abstract class QualifiedProtectedExtractor {
def unapply(x: Modifier)(implicit ctx: Context): Option[Type]
}

}


// ===== Signature ================================================

type Signature
Expand Down
7 changes: 0 additions & 7 deletions library/src/scala/tasty/util/ShowExtractors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,6 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
this += "NoPrefix()"
}

def visitModifier(x: Modifier): Buffer = x match {
case Modifier.Flags(flags) => this += "Modifier.Flags(" += flags.toString += ")"
case Modifier.QualifiedPrivate(tp) => this += "Modifier.QualifiedPrivate(" += tp += ")"
case Modifier.QualifiedProtected(tp) => this += "Modifier.QualifiedProtected(" += tp += ")"
case Modifier.Annotation(tree) => this += "Modifier.Annotation(" += tree += ")"
}

def visitId(x: Id): Buffer = {
val Id(name) = x
this += "Id(\"" += name += "\")"
Expand Down
20 changes: 16 additions & 4 deletions tests/pos/tasty/definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,30 @@ object definitions {

// Does DefDef need a `def tpe: MethodType | PolyType`?
case class ValDef(name: String, tpt: TypeTree, rhs: Option[Term]) extends Definition {
def mods: List[Modifier] = ???
def flags: FlagSet = ???
def privateWithin: Option[Type] = ???
def protectedWithin: Option[Type] = ???
def annots: List[Term] = ???
}
case class DefDef(name: String, typeParams: List[TypeDef], paramss: List[List[ValDef]],
returnTpt: TypeTree, rhs: Option[Term]) extends Definition {
def mods: List[Modifier] = ???
def flags: FlagSet = ???
def privateWithin: Option[Type] = ???
def protectedWithin: Option[Type] = ???
def annots: List[Term] = ???
}
case class TypeDef(name: String, rhs: TypeTree | TypeBoundsTree) extends Definition {
def mods: List[Modifier] = ???
def flags: FlagSet = ???
def privateWithin: Option[Type] = ???
def protectedWithin: Option[Type] = ???
def annots: List[Term] = ???
}
case class ClassDef(name: String, constructor: DefDef, parents: List[Term | TypeTree],
self: Option[ValDef], body: List[Statement]) extends Definition {
def mods: List[Modifier] = ???
def flags: FlagSet = ???
def privateWithin: Option[Type] = ???
def protectedWithin: Option[Type] = ???
def annots: List[Term] = ???
}
case class PackageDef(name: String, override val owner: PackageDef) extends Definition {
def members: List[Statement] = ???
Expand Down