-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Print annotation in decompiler #4676
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,6 +65,8 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
printImportSelectors(selectors) | ||
|
||
case cdef @ ClassDef(name, DefDef(_, targs, argss, _, _), parents, self, stats) => | ||
printDefAnnotations(cdef) | ||
|
||
val flags = cdef.flags | ||
if (flags.isFinal && !flags.isObject) this += "final " | ||
if (flags.isCase) this += "case " | ||
|
@@ -146,11 +148,14 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
} | ||
this | ||
|
||
case tdef@TypeDef(name, rhs) => | ||
case tdef @ TypeDef(name, rhs) => | ||
printDefAnnotations(tdef) | ||
this += "type " | ||
printTargDef(tdef) | ||
|
||
case vdef@ValDef(name, tpt, rhs) => | ||
case vdef @ ValDef(name, tpt, rhs) => | ||
printDefAnnotations(vdef) | ||
|
||
val flags = vdef.flags | ||
if (flags.isOverride) this += "override " | ||
|
||
|
@@ -201,7 +206,9 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
printTree(cond) | ||
this += ")" | ||
|
||
case ddef@DefDef(name, targs, argss, tpt, rhs) => | ||
case ddef @ DefDef(name, targs, argss, tpt, rhs) => | ||
printDefAnnotations(ddef) | ||
|
||
val flags = ddef.flags | ||
if (flags.isOverride) sb.append("override ") | ||
|
||
|
@@ -220,8 +227,16 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
} | ||
this | ||
|
||
case [email protected](name) => | ||
printType(tree.tpe) | ||
case tree @ Term.Ident(name) => | ||
tree.tpe match { | ||
case Type.SymRef(_, Types.EmptyPrefix()) | Type.TermRef(_, Types.EmptyPrefix()) => this += name | ||
case Type.SymRef(_, prefix) => | ||
printTypeOrBound(prefix) | ||
this += "." += name | ||
case Type.TermRef(_, prefix) => | ||
printTypeOrBound(prefix) | ||
this += "." += name | ||
} | ||
|
||
case Term.Select(qual, name, sig) => | ||
printTree(qual) | ||
|
@@ -272,7 +287,17 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
this += "(" | ||
printTree(term) | ||
this += ": " | ||
printTypeTree(tpt) | ||
def printTypeOrAnnots(tpe: Type): Unit = tpe match { | ||
case Type.AnnotatedType(tp, annot) if tp == term.tpe => | ||
printAnnotation(annot) | ||
case Type.AnnotatedType(tp, annot) => | ||
printTypeOrAnnots(tp) | ||
this += " " | ||
printAnnotation(annot) | ||
case tpe => | ||
printType(tpe) | ||
} | ||
printTypeOrAnnots(tpt.tpe) | ||
this += ")" | ||
} | ||
|
||
|
@@ -516,6 +541,19 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
this += ")" | ||
} | ||
|
||
def printAnnotations(trees: List[Term]): Buffer = { | ||
def printSeparated(list: List[Term]): Unit = list match { | ||
case Nil => | ||
case x :: Nil => printAnnotation(x) | ||
case x :: xs => | ||
printAnnotation(x) | ||
this += " " | ||
printSeparated(xs) | ||
} | ||
printSeparated(trees) | ||
this | ||
} | ||
|
||
def printArgDef(arg: ValDef): Unit = { | ||
val ValDef(name, tpt, rhs) = arg | ||
this += name += ": " | ||
|
@@ -616,11 +654,23 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
|
||
def printTypeTree(tree: TypeTree): Buffer = tree match { | ||
case TypeTree.Synthetic() => | ||
printType(tree.tpe) | ||
tree.tpe match { | ||
case tpe @ Type.TypeRef(name, _) if name.endsWith("$") => this += ".type" | ||
case tpe => this | ||
} | ||
def printTypeAndAnnots(tpe: Type): Buffer = tpe match { | ||
case Type.AnnotatedType(tp, annot) => | ||
printTypeAndAnnots(tp) | ||
this += " " | ||
printAnnotation(annot) | ||
case tpe @ Type.TypeRef(name, _) if name.endsWith("$") => | ||
printType(tpe) | ||
this += ".type" | ||
case Type.SymRef(ClassDef("Null$" | "Nothing$", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("runtime", _), NoPrefix()))) => | ||
// scala.runtime.Null$ and scala.runtime.Nothing$ are not modules, those are their actual names | ||
printType(tpe) | ||
case tpe @ Type.SymRef(ClassDef(name, _, _, _, _), _) if name.endsWith("$") => | ||
printType(tpe) | ||
this += ".type" | ||
case tpe => printType(tpe) | ||
} | ||
printTypeAndAnnots(tree.tpe) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was because |
||
|
||
case TypeTree.TypeIdent(name) => | ||
printType(tree.tpe) | ||
|
@@ -654,9 +704,11 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
printTypeTrees(args, ", ") | ||
this += "]" | ||
|
||
case TypeTree.Annotated(tpt, annots) => | ||
case TypeTree.Annotated(tpt, annot) => | ||
val Annotation(ref, args) = annot | ||
printTypeTree(tpt) | ||
// TODO print annots | ||
this += " " | ||
printAnnotation(annot) | ||
|
||
case TypeTree.And(left, right) => | ||
printTypeTree(left) | ||
|
@@ -692,14 +744,13 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
|
||
case Type.SymRef(sym, prefix) => | ||
prefix match { | ||
case Type.ThisType(Types.EmptyPackage() | Types.RootPackage()) => | ||
case Types.EmptyPrefix() => | ||
case [email protected](ClassDef(_, _, _, _, _), _) => | ||
printType(prefix) | ||
this += "#" | ||
case prefix@Type() => | ||
printType(prefix) | ||
this += "." | ||
case prefix@NoPrefix() => | ||
} | ||
printDefinitionName(sym) | ||
|
||
|
@@ -734,7 +785,10 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
this += "]" | ||
|
||
case Type.AnnotatedType(tp, annot) => | ||
val Annotation(ref, args) = annot | ||
printType(tp) | ||
this += " " | ||
printAnnotation(annot) | ||
|
||
case Type.AndType(left, right) => | ||
printType(left) | ||
|
@@ -775,6 +829,28 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
case PackageDef(name, _) => this += name | ||
} | ||
|
||
def printAnnotation(annot: Term): Buffer = { | ||
val Annotation(ref, args) = annot | ||
this += "@" | ||
printTypeTree(ref) | ||
this += "(" | ||
printTrees(args, ", ") | ||
this += ")" | ||
} | ||
|
||
def printDefAnnotations(definition: Definition): Buffer = { | ||
val annots = definition.annots.filter { | ||
case Annotation(annot, _) => | ||
annot.tpe match { | ||
case Type.TypeRef(_, Type.SymRef(PackageDef("internal", _), Type.ThisType(Type.SymRef(PackageDef("annotation", _), NoPrefix())))) => false | ||
case _ => true | ||
} | ||
} | ||
printAnnotations(annots) | ||
if (annots.nonEmpty) this += " " | ||
else this | ||
} | ||
|
||
def +=(x: Boolean): this.type = { sb.append(x); this } | ||
def +=(x: Byte): this.type = { sb.append(x); this } | ||
def +=(x: Short): this.type = { sb.append(x); this } | ||
|
@@ -829,6 +905,13 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
} | ||
} | ||
|
||
private object Annotation { | ||
def unapply(arg: Tree)(implicit ctx: Context): Option[(TypeTree, List[Term])] = arg match { | ||
case Term.Apply(Term.Select(Term.New(annot), "<init>", _), args) => Some((annot, args)) | ||
case _ => None | ||
} | ||
} | ||
|
||
// TODO Provide some of these in scala.tasty.Tasty.scala and implement them using checks on symbols for performance | ||
private object Types { | ||
|
||
|
@@ -866,6 +949,13 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
case _ => false | ||
} | ||
} | ||
|
||
object EmptyPrefix { | ||
def unapply(tpe: TypeOrBounds)(implicit ctx: Context): Boolean = tpe match { | ||
case NoPrefix() | Type.ThisType(Types.EmptyPackage() | Types.RootPackage()) => true | ||
case _ => false | ||
} | ||
} | ||
} | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** Decompiled from out/posTestFromTasty/pos/simpleAnnot/Foo.class */ | ||
class Foo() { | ||
@annot() type A = scala.Int | ||
@annot() val a: scala.Int = scala.Predef.??? | ||
val b: scala.Int @annot() = scala.Predef.??? | ||
def c(x: scala.Int): scala.Int = (x: @annot()) | ||
} | ||
/** Decompiled from out/posTestFromTasty/pos/simpleAnnot/annot.class */ | ||
class annot() extends scala.annotation.Annotation |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
|
||
class Foo { | ||
@annot type A = Int | ||
@annot val a: Int = ??? | ||
val b: Int @annot = ??? | ||
def c(x: Int) = (x : @annot) | ||
} | ||
|
||
class annot extends scala.annotation.Annotation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems
SymRef
subsumesTermRef
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, both are
core.Types.NamedType
s butSymRef
as a symbol asdesignator
andTermRef
has aTermName
asdesignator
.