summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-12-08 04:23:29 +0000
committerPaul Phillips <paulp@improving.org>2010-12-08 04:23:29 +0000
commit9a7e511b3e851eba9e8cd7a422d21af9b8023204 (patch)
tree323e839113a971b0588ed1cf3f9b9b8e841525b5
parent8aed49aba930520b4b26b81beb57ffd6cc626765 (diff)
downloadscala-9a7e511b3e851eba9e8cd7a422d21af9b8023204.tar.gz
scala-9a7e511b3e851eba9e8cd7a422d21af9b8023204.tar.bz2
scala-9a7e511b3e851eba9e8cd7a422d21af9b8023204.zip
I learned from #4067 that we don't have any kin...
I learned from #4067 that we don't have any kind of signature validation yet. I could swear someone did that. Anyway, I did. If you give option -Yverify-generics it will yell at you for any that are invalid. For instance, the one in the ticket. % scalac -Yverify-generics -d /tmp src/library/scala/collection/immutable/List.scala [BAD!] method orElse in scala.collection.immutable.List <A1:IB1:Ljava/lang/Object;>(Lscala/PartialFunction<TA1;TB1;>;)Lscala/Par tialFunction<TA1;TB1;>; [BAD!] method orElse in scala.collection.immutable.List <A1:IB1:Ljava/lang/Object;>(Lscala/PartialFunction<TA1;TB1;>;)Lscala/Par tialFunction<TA1;TB1;>; Of course you still have to figure out what is wrong and why. Review by moors, dragos.
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala14
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala1
-rw-r--r--src/compiler/scala/tools/reflect/SigParser.scala37
3 files changed, 52 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 1a0cb4f197..c158d951a7 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -81,6 +81,17 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
*/
class BytecodeGenerator extends BytecodeUtil {
def debugLevel = settings.debuginfo.indexOfChoice
+ import scala.tools.reflect.SigParser
+ def verifySig(sym: Symbol, sig: String) = {
+ val ok =
+ if (sym.isMethod) SigParser verifyMethod sig
+ else if (sym.isTerm) SigParser verifyType sig
+ else SigParser verifyClass sig
+
+ def label = if (ok) "[ OK ] " else "[BAD!] "
+ if (settings.verbose.value || !ok)
+ Console.println(label + sym + " in " + sym.owner.skipPackageObject.fullName + "\n " + sig)
+ }
val MIN_SWITCH_DENSITY = 0.7
val INNER_CLASSES_FLAGS =
@@ -513,6 +524,9 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
// println("addGenericSignature sym: " + sym.fullName + " : " + memberTpe + " sym.info: " + sym.info)
// println("addGenericSignature: "+ (sym.ownerChain map (x => (x.name, x.isImplClass))))
erasure.javaSig(sym, memberTpe) foreach { sig =>
+ if (settings.Yverifysigs.value)
+ verifySig(sym, sig)
+
val index = jmember.getConstantPool().addUtf8(sig).toShort
if (settings.debug.value && settings.verbose.value)
atPhase(currentRun.erasurePhase) {
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index 360a19d54b..27bdd8a391 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -112,6 +112,7 @@ trait ScalaSettings extends AbsScalaSettings with StandardScalaSettings {
val log = PhasesSetting ("-Ylog", "Log operations during")
val Ylogcp = BooleanSetting ("-Ylog-classpath", "Output information about what classpath is being applied.")
val Ynogenericsig = BooleanSetting ("-Yno-generic-signatures", "Suppress generation of generic signatures for Java.")
+ val Yverifysigs = BooleanSetting ("-Yverify-generics", "Validated generated generic signatures.")
val noimports = BooleanSetting ("-Yno-imports", "Compile without any implicit imports.")
// Not actually doing anything, so disabled.
// val nopredefs = BooleanSetting ("-Yno-predefs", "Compile without any implicit predefined values.")
diff --git a/src/compiler/scala/tools/reflect/SigParser.scala b/src/compiler/scala/tools/reflect/SigParser.scala
new file mode 100644
index 0000000000..bdbc57377c
--- /dev/null
+++ b/src/compiler/scala/tools/reflect/SigParser.scala
@@ -0,0 +1,37 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2010 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools
+package reflect
+
+import java.lang.reflect.GenericSignatureFormatError
+
+/** The usual reflection song and dance to avoid referencing
+ * any sun.* classes.
+ */
+class SigParser {
+ val SunSignatureParser = "sun.reflect.generics.parser.SignatureParser"
+ lazy val makeMethod = Class.forName(SunSignatureParser) getMethod "make"
+ def make() = makeMethod.invoke(null).asInstanceOf[SignatureParserInterface]
+
+ private def wrap(op: => Any) =
+ try { op ; true }
+ catch { case _: GenericSignatureFormatError => false }
+
+ def verifyClass(s: String) = wrap(make() parseClassSig s)
+ def verifyMethod(s: String) = wrap(make() parseMethodSig s)
+ def verifyType(s: String) = wrap(make() parseTypeSig s)
+
+ type ClassSignature <: AnyRef
+ type MethodTypeSignature <: AnyRef
+ type TypeSignature <: AnyRef
+
+ type SignatureParserInterface = {
+ def parseClassSig(s: String): ClassSignature
+ def parseMethodSig(s: String): MethodTypeSignature
+ def parseTypeSig(s: String): TypeSignature
+ }
+}
+object SigParser extends SigParser { }