-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix case class decompilation #4633
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 1 commit
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 |
---|---|---|
|
@@ -112,8 +112,24 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
} | ||
} | ||
|
||
def keepDefinition(d: Definition): Boolean = { | ||
val flags = d.flags | ||
import flags._ | ||
def isCaseUnOverridableMethod: Boolean = { | ||
d.flags.isSynthetic && | ||
(d match { | ||
case DefDef("apply" | "unapply", _, _, _, _) if d.owner.flags.isObject => true | ||
case DefDef(n, _, _, _, _) if d.owner.flags.isCase => | ||
n == "copy" || | ||
n.matches("copy\\$default\\$[1-9][0-9]*") || // default parameters for the copy method | ||
n.matches("_[1-9][0-9]*") // Getters from Product | ||
case _ => false | ||
}) | ||
} | ||
!isParam && !isParamAccessor && !isCaseUnOverridableMethod | ||
} | ||
val stats1 = stats.collect { | ||
case stat@Definition() if !stat.flags.isParam && !stat.flags.isParamAccessor => stat | ||
case stat@Definition() if keepDefinition(stat) => stat | ||
case stat@Import(_, _) => stat | ||
case stat@Term() => stat | ||
} | ||
|
@@ -721,6 +737,10 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty | |
|
||
case Type.ThisType(tp) => | ||
printType(tp) | ||
tp match { | ||
case Type.SymRef(cdef @ ClassDef(_, _, _, _, _), _) if !cdef.flags.isObject => this += ".this" | ||
case _ => 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. Could you explain why special case object here? 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. When refering to the this type of a module we just refere directly to the module itself. For example |
||
|
||
case _ => | ||
throw new MatchError(tpe.show) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/** Decompiled from out/posTestFromTasty/pos/simpleCaseClass-1/A.class */ | ||
case class A() { | ||
override def hashCode(): scala.Int = 1914112431 | ||
override def equals(x$0: scala.Any): scala.Boolean = this.eq(x$0.asInstanceOf[java.lang.Object]).||(x$0 match { | ||
case x$0: A => | ||
true | ||
case _ => | ||
false | ||
}) | ||
override def toString(): java.lang.String = scala.runtime.ScalaRunTime._toString(this) | ||
override def canEqual(that: scala.Any): scala.Boolean = that.isInstanceOf[A] | ||
override def productArity: scala.Int = 0 | ||
override def productPrefix: java.lang.String = "A" | ||
override def productElement(n: scala.Int): scala.Any = n match { | ||
case _ => | ||
throw new java.lang.IndexOutOfBoundsException(n.toString()) | ||
} | ||
} | ||
object A extends scala.Function0[A] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
case class A() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/** Decompiled from out/posTestFromTasty/pos/simpleCaseClass-2/A.class */ | ||
case class A(x: scala.Int) { | ||
override def hashCode(): scala.Int = { | ||
var acc: scala.Int = 65 | ||
acc = scala.runtime.Statics.mix(acc, A.this.x) | ||
scala.runtime.Statics.finalizeHash(acc, 1) | ||
} | ||
override def equals(x$0: scala.Any): scala.Boolean = this.eq(x$0.asInstanceOf[java.lang.Object]).||(x$0 match { | ||
case x$0: A => | ||
this.x.==(x$0.x) | ||
case _ => | ||
false | ||
}) | ||
override def toString(): java.lang.String = scala.runtime.ScalaRunTime._toString(this) | ||
override def canEqual(that: scala.Any): scala.Boolean = that.isInstanceOf[A] | ||
override def productArity: scala.Int = 1 | ||
override def productPrefix: java.lang.String = "A" | ||
override def productElement(n: scala.Int): scala.Any = n match { | ||
case 0 => | ||
this._1 | ||
case _ => | ||
throw new java.lang.IndexOutOfBoundsException(n.toString()) | ||
} | ||
} | ||
object A extends scala.Function1[scala.Int, A] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
case class A(x: Int) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/** Decompiled from out/posTestFromTasty/pos/simpleCaseClass-3/A.class */ | ||
case class A[T](x: T) { | ||
override def hashCode(): scala.Int = { | ||
var acc: scala.Int = 65 | ||
acc = scala.runtime.Statics.mix(acc, scala.runtime.Statics.anyHash(A.this.x)) | ||
scala.runtime.Statics.finalizeHash(acc, 1) | ||
} | ||
override def equals(x$0: scala.Any): scala.Boolean = this.eq(x$0.asInstanceOf[java.lang.Object]).||(x$0 match { | ||
case x$0: A[A.this.T] => | ||
this.x.==(x$0.x) | ||
case _ => | ||
false | ||
}) | ||
override def toString(): java.lang.String = scala.runtime.ScalaRunTime._toString(this) | ||
override def canEqual(that: scala.Any): scala.Boolean = that.isInstanceOf[A[A.this.T]] | ||
override def productArity: scala.Int = 1 | ||
override def productPrefix: java.lang.String = "A" | ||
override def productElement(n: scala.Int): scala.Any = n match { | ||
case 0 => | ||
this._1 | ||
case _ => | ||
throw new java.lang.IndexOutOfBoundsException(n.toString()) | ||
} | ||
} | ||
object A extends scala.AnyRef |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
case class A[T](x: T) |
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.
I think
import flags._
doesn't help in terms of readability: it takes me some time to realize thatisParam
is a method ond.flags
. InisCaseUnOverridableMethod
, it still usesd.flags
.A short doc can help better understand the motivation for the method
isCaseUnOverridableMethod
. A naive question: why not just ignore all synthetic definitions?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.
Will improve code and add docs.
I decided to print the synthetic methods to allow users to see what was generated. I will add some
/* synthetic */
comment on them later. And I'm considering adding a mode that those not print them. I started printing them because I can test more code, therefore more of the Tasty reflect API.