-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Print decompiled refinements #4698
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
93f0307
127b07b
fd4317a
14a5ec5
1a21558
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 |
---|---|---|
|
@@ -69,11 +69,13 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
|
||
val flags = cdef.flags | ||
if (flags.isImplicit) this += "implicit " | ||
if (flags.isSealed) this += "sealed " | ||
if (flags.isFinal && !flags.isObject) this += "final " | ||
if (flags.isCase) this += "case " | ||
|
||
if (flags.isObject) this += "object " += name.stripSuffix("$") | ||
else if (flags.isTrait) this += "trait " += name | ||
else if (flags.isAbstract) this += "abstract class " += name | ||
else this += "class " += name | ||
|
||
if (!flags.isObject) { | ||
|
@@ -504,29 +506,14 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
|
||
def printTargDef(arg: TypeDef, isMember: Boolean = false): Buffer = { | ||
val TypeDef(name, rhs) = arg | ||
def printBounds(bounds: TypeBoundsTree): Buffer = { | ||
val TypeBoundsTree(lo, hi) = bounds | ||
lo match { | ||
case TypeTree.Synthetic() => | ||
case _ => | ||
this += " >: " | ||
printTypeTree(lo) | ||
} | ||
hi match { | ||
case TypeTree.Synthetic() => this | ||
case _ => | ||
this += " <: " | ||
printTypeTree(hi) | ||
} | ||
} | ||
this += name | ||
rhs match { | ||
case rhs @ TypeBoundsTree(lo, hi) => printBounds(rhs) | ||
case rhs @ TypeBoundsTree(lo, hi) => printBoundsTree(rhs) | ||
case rhs @ SyntheticBounds() => | ||
printTypeOrBound(rhs.tpe) | ||
case rhs @ TypeTree.TypeLambdaTree(tparams, body) => | ||
def printParam(t: TypeOrBoundsTree): Unit = t match { | ||
case t @ TypeBoundsTree(_, _) => printBounds(t) | ||
case t @ TypeBoundsTree(_, _) => printBoundsTree(t) | ||
case t @ TypeTree() => printTypeTree(t) | ||
} | ||
def printSeparated(list: List[TypeDef]): Unit = list match { | ||
|
@@ -793,12 +780,14 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
case Type.SymRef(sym, prefix) => | ||
prefix match { | ||
case Types.EmptyPrefix() => | ||
case prefix@Type.SymRef(ClassDef(_, _, _, _, _), _) => | ||
case prefix @ Type.SymRef(ClassDef(_, _, _, _, _), _) => | ||
printType(prefix) | ||
this += "#" | ||
case prefix@Type() => | ||
printType(prefix) | ||
this += "." | ||
case prefix @ Type() => | ||
if (!sym.flags.isLocal) { | ||
printType(prefix) | ||
this += "." | ||
} | ||
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 seems it is also OK to print the prefix here? For hygiene, we do need to print the prefix for local members as well. 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. This is to not print prefixes in references inside the parents of a class. 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. Could you please explain what do you mean by 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. I will reprint the prefix and add test cases where this fails |
||
} | ||
printDefinitionName(sym) | ||
|
||
|
@@ -822,9 +811,8 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
} | ||
this += name.stripSuffix("$") | ||
|
||
case Type.Refinement(parent, name, info) => | ||
printType(parent) | ||
// TODO add refinements | ||
case tpe @ Type.Refinement(_, _, _) => | ||
printRefinement(tpe) | ||
|
||
case Type.AppliedType(tp, args) => | ||
printType(tp) | ||
|
@@ -861,25 +849,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
|
||
case Type.TypeLambda(paramNames, tparams, body) => | ||
this += "[" | ||
def printBounds(bounds: TypeBounds): Buffer = { | ||
val TypeBounds(lo, hi) = bounds | ||
this += " >: " | ||
printType(lo) | ||
this += " <: " | ||
printType(hi) | ||
} | ||
def printSeparated(list: List[(String, TypeBounds)]): Unit = list match { | ||
case Nil => | ||
case (name, bounds) :: Nil => | ||
this += name | ||
printBounds(bounds) | ||
case (name, bounds) :: xs => | ||
this += name | ||
printBounds(bounds) | ||
this += ", " | ||
printSeparated(xs) | ||
} | ||
printSeparated(paramNames.zip(tparams)) | ||
printMethodicTypeParams(paramNames, tparams) | ||
this += "] => " | ||
printTypeOrBound(body) | ||
|
||
|
@@ -932,6 +902,95 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
else this | ||
} | ||
|
||
def printRefinement(tpe: Type): Buffer = { | ||
def printMethodicType(tp: TypeOrBounds): Unit = tp match { | ||
case tp @ Type.MethodType(paramNames, params, res) => | ||
this += "(" | ||
printMethodicTypeParams(paramNames, params) | ||
this += ")" | ||
printMethodicType(res) | ||
case tp @ Type.TypeLambda(paramNames, params, res) => | ||
this += "[" | ||
printMethodicTypeParams(paramNames, params) | ||
this += "]" | ||
printMethodicType(res) | ||
case Type.ByNameType(t) => | ||
this += ": " | ||
printType(t) | ||
case tp @ Type() => | ||
this += ": " | ||
printType(tp) | ||
} | ||
def rec(tp: Type): Unit = tp match { | ||
case Type.Refinement(parent, name, info) => | ||
rec(parent) | ||
indented { | ||
this += lineBreak() | ||
info match { | ||
case info @ TypeBounds(_, _) => | ||
this += "type " += name | ||
printBounds(info) | ||
case Type.ByNameType(_) | Type.MethodType(_, _, _) | Type.TypeLambda(_, _, _) => | ||
this += "def " += name | ||
printMethodicType(info) | ||
case info @ Type() => | ||
this += "val " += name | ||
printMethodicType(info) | ||
} | ||
} | ||
case tp => | ||
printType(tp) | ||
this += " {" | ||
} | ||
rec(tpe) | ||
this += lineBreak() += "}" | ||
} | ||
|
||
def printMethodicTypeParams(paramNames: List[String], params: List[TypeOrBounds]): Unit = { | ||
def printInfo(info: TypeOrBounds) = info match { | ||
case info @ TypeBounds(_, _) => printBounds(info) | ||
case info @ Type() => | ||
this += ": " | ||
printType(info) | ||
} | ||
def printSeparated(list: List[(String, TypeOrBounds)]): Unit = list match { | ||
case Nil => | ||
case (name, info) :: Nil => | ||
this += name | ||
printInfo(info) | ||
case (name, info) :: xs => | ||
this += name | ||
printInfo(info) | ||
this += ", " | ||
printSeparated(xs) | ||
} | ||
printSeparated(paramNames.zip(params)) | ||
} | ||
|
||
def printBoundsTree(bounds: TypeBoundsTree): Buffer = { | ||
val TypeBoundsTree(lo, hi) = bounds | ||
lo match { | ||
case TypeTree.Synthetic() => | ||
case _ => | ||
this += " >: " | ||
printTypeTree(lo) | ||
} | ||
hi match { | ||
case TypeTree.Synthetic() => this | ||
case _ => | ||
this += " <: " | ||
printTypeTree(hi) | ||
} | ||
} | ||
|
||
def printBounds(bounds: TypeBounds): Buffer = { | ||
val TypeBounds(lo, hi) = bounds | ||
this += " >: " | ||
printType(lo) | ||
this += " <: " | ||
printType(hi) | ||
} | ||
|
||
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 } | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/** Decompiled from out/posTestFromTasty/pos/simpleRefinement/Bar.class */ | ||
trait Bar() extends java.lang.Object { | ||
type S | ||
type T | ||
type U <: [X] => scala.Any | ||
val x: scala.Any | ||
def y: scala.Any | ||
def z(): scala.Any | ||
def z2()(): scala.Any | ||
def w[T]: scala.Any | ||
def w2[T](a: scala.Null)(b: scala.Null): scala.Any | ||
} | ||
/** Decompiled from out/posTestFromTasty/pos/simpleRefinement/Foo.class */ | ||
class Foo() { | ||
val bar: Bar { | ||
type S >: scala.Int <: scala.Int | ||
type T >: scala.Function1[scala.Int, scala.Int] <: scala.Function1[scala.Int, scala.Int] | ||
type U >: [X >: scala.Nothing <: scala.Any] => scala.Int <: [X >: scala.Nothing <: scala.Any] => scala.Int | ||
val x: scala.Long | ||
def y: scala.Boolean | ||
def z(): scala.Char | ||
def z2()(): scala.Char | ||
def w[T >: scala.Nothing <: scala.Any]: scala.Predef.String | ||
def w2[T >: scala.Nothing <: scala.Any](a: scala.Null)(b: scala.Null): scala.Null | ||
} = { | ||
final class $anon() extends Bar { | ||
type S = scala.Int | ||
type T = scala.Function1[scala.Int, scala.Int] | ||
type U[X] = scala.Int | ||
val x: scala.Long = 2L | ||
def y: scala.Boolean = true | ||
def z(): scala.Char = 'f' | ||
def z2()(): scala.Char = 'g' | ||
def w[T]: scala.Predef.String = "a" | ||
def w2[T](a: scala.Null)(b: scala.Null): scala.Null = null | ||
} | ||
(new $anon(): Bar { | ||
type S >: scala.Int <: scala.Int | ||
type T >: scala.Function1[scala.Int, scala.Int] <: scala.Function1[scala.Int, scala.Int] | ||
type U >: [X >: scala.Nothing <: scala.Any] => scala.Int <: [X >: scala.Nothing <: scala.Any] => scala.Int | ||
val x: scala.Long | ||
def y: scala.Boolean | ||
def z(): scala.Char | ||
def z2()(): scala.Char | ||
def w[T >: scala.Nothing <: scala.Any]: scala.Predef.String | ||
def w2[T >: scala.Nothing <: scala.Any](a: scala.Null)(b: scala.Null): scala.Null | ||
}) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
|
||
class Foo { | ||
val bar = new Bar { | ||
type S = Int | ||
type T = Int => Int | ||
type U = [X] => Int | ||
val x: Long = 2L | ||
def y: Boolean = true | ||
def z(): Char = 'f' | ||
def z2()(): Char = 'g' | ||
def w[T]: String = "a" | ||
def w2[T](a: Null)(b: Null): Null = null | ||
} | ||
} | ||
|
||
trait Bar { | ||
type S | ||
type T | ||
type U <: [X] => Any | ||
val x: Any | ||
def y: Any | ||
def z(): Any | ||
def z2()(): Any | ||
def w[T]: Any | ||
def w2[T](a: Null)(b: Null): Any | ||
} |
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.
sealed
,final
and access modifiers are missing here.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.
final
is a few lines above. I will addsealed
.