diff options
author | Paul Phillips <paulp@improving.org> | 2010-12-08 04:23:29 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-12-08 04:23:29 +0000 |
commit | 9a7e511b3e851eba9e8cd7a422d21af9b8023204 (patch) | |
tree | 323e839113a971b0588ed1cf3f9b9b8e841525b5 | |
parent | 8aed49aba930520b4b26b81beb57ffd6cc626765 (diff) | |
download | scala-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.scala | 14 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/settings/ScalaSettings.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/reflect/SigParser.scala | 37 |
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 { } |