I'm trying to fix this Github issue: http://ift.tt/2dwGj3s
Essentially, WartRemover provides a Wart that is supposed to check for usages of asInstanceOf
. The implementation (link) has allowances to skip things such as compiler generated classes, which it doesn't make sense to check. However, when I use implicit TypeTag
s, the generated code still seems to be inspected - and fails the checks.
This is my sample code:
import scala.reflect.runtime.universe.TypeTag
class GoodAsInstanceOf {
def takesTypeTag[A : TypeTag](a: A): String = {
val tt = implicitly[TypeTag[A]]
s"The tt of A is $tt"
}
def exerciseIt(): String = {
takesTypeTag("Hello")
}
}
I'm using scala 2.10.6.
The -Xtyper
output is:
// GoodAsInstanceOf.scala
package <empty> {
import scala.reflect.runtime.`package`.universe.TypeTag;
class GoodAsInstanceOf extends scala.AnyRef {
def <init>(): GoodAsInstanceOf = {
GoodAsInstanceOf.super.<init>();
()
};
def takesTypeTag[A >: Nothing <: Any](a: A)(implicit evidence$1: reflect.runtime.universe.TypeTag[A]): String = {
val tt: reflect.runtime.universe.TypeTag[A] = scala.this.Predef.implicitly[reflect.runtime.universe.TypeTag[A]](evidence$1);
scala.StringContext.apply("The tt of A is ", "").s(tt)
};
def exerciseIt(): String = GoodAsInstanceOf.this.takesTypeTag[String]("Hello")({
val $u: reflect.runtime.universe.type = scala.reflect.runtime.`package`.universe;
val $m: $u.Mirror = scala.reflect.runtime.`package`.universe.runtimeMirror(classOf[GoodAsInstanceOf].getClassLoader());
$u.TypeTag.apply[String]($m, {
final class $typecreator1 extends TypeCreator {
def <init>(): $typecreator1 = {
$typecreator1.super.<init>();
()
};
def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.Mirror[U]): U#Type = {
val $u: U = $m$untyped.universe;
val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
$m.staticClass("java.lang.String").asType.toTypeConstructor
}
};
new $typecreator1()
})
})
}
}
Unfortunately, there is a false positive on the call to takesTypeTag
- which I'm trying to rectify.
I would imagine that calling isSynthetic
on the relevant symbols within the generated code should return true
- particularly the ClassDef
$typecreator1
, or the code it contains. This could then be used to skip those parts of the tree - which is how the default Wart expects it to behave:
// Ignore usage in synthetic classes
case ClassDef(_, _, _, _) if synthetic =>
However - isSynthetic
always returns false within this code. (I am testing using a modified copy of the Wart class above, and producing warnings containing debug information as the tree is traversed. I've tried checking the generated Block
and apply method also).
Am I misunderstanding how isSynthetic
works? Is there a better way to do this?
Aucun commentaire:
Enregistrer un commentaire