diff options
author | Paul Phillips <paulp@improving.org> | 2011-03-03 05:59:01 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-03-03 05:59:01 +0000 |
commit | ebeb8c51e434f0a1e1b0de4fa9740a158f57b1ab (patch) | |
tree | d67ef34148df775e4acff9936a29849bc2b7ee9c | |
parent | 4e0d7b8e223511e05fd67c6c90a4af369e99787f (diff) | |
download | scala-ebeb8c51e434f0a1e1b0de4fa9740a158f57b1ab.tar.gz scala-ebeb8c51e434f0a1e1b0de4fa9740a158f57b1ab.tar.bz2 scala-ebeb8c51e434f0a1e1b0de4fa9740a158f57b1ab.zip |
Seem to have made a breakthrough with signature...
Seem to have made a breakthrough with signature correctness. Most of
the remaining troubles were due to inherited members and their foreign
identifiers, but I think I found a simple way to make everyone happy.
Closes #4238, review by moors.
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Erasure.scala | 26 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/util/Tracer.scala | 37 | ||||
-rw-r--r-- | test/files/run/bug4238/J.java | 4 | ||||
-rw-r--r-- | test/files/run/sigtp.check | 7 | ||||
-rw-r--r-- | test/files/run/sigtp.scala | 18 |
5 files changed, 82 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 015481b97a..a04f1d972c 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -190,8 +190,8 @@ abstract class Erasure extends AddInterfaces if (!parents.isEmpty) traverse(parents.head) case ClassInfoType(parents, _, _) => parents foreach traverse - case AnnotatedType(_, atp, _) => - traverse(atp) + case AnnotatedType(_, atp, _) => + traverse(atp) case _ => mapOver(tp) } @@ -204,9 +204,11 @@ abstract class Erasure extends AddInterfaces // only refer to type params that will actually make it into the sig, this excludes: // * higher-order type parameters (aka !sym.owner.isTypeParameterOrSkolem) // * parameters of methods - private def isTypeParameterInSig(sym: Symbol) = ( + // * type members not visible in the enclosing template + private def isTypeParameterInSig(sym: Symbol, nestedIn: Symbol) = ( + !sym.owner.isTypeParameterOrSkolem && sym.isTypeParameterOrSkolem && - !sym.owner.isTypeParameterOrSkolem + (sym isNestedIn nestedIn) ) // Ensure every '.' in the generated signature immediately follows // a close angle bracket '>'. Any which do not are replaced with '$'. @@ -221,6 +223,8 @@ abstract class Erasure extends AddInterfaces case ch => last = ch ; ch } } + // for debugging signatures: traces logic given system property + private val traceSig = util.Tracer(sys.props contains "scalac.sigs.trace") /** The Java signature of type 'info', for symbol sym. The symbol is used to give the right return * type for constructors. @@ -238,7 +242,7 @@ abstract class Erasure extends AddInterfaces case tp => tp :: Nil }) map squashBoxed - def jsig2(toplevel: Boolean, tparams: List[Symbol], tp0: Type): String = { + def jsig2(toplevel: Boolean, tparams: List[Symbol], tp0: Type): String = traceSig("jsig2", toplevel, tparams, tp0) { val tp = tp0.dealias tp match { case st: SubType => @@ -270,7 +274,7 @@ abstract class Erasure extends AddInterfaces if (unboundedGenericArrayLevel(tp) == 1) jsig(ObjectClass.tpe) else ARRAY_TAG.toString+(args map jsig).mkString } - else if (isTypeParameterInSig(sym)) + else if (isTypeParameterInSig(sym, sym0.enclClass)) TVAR_TAG.toString+sym.name+";" else if (sym == AnyClass || sym == AnyValClass || sym == SingletonClass) jsig(ObjectClass.tpe) @@ -334,11 +338,13 @@ abstract class Erasure extends AddInterfaces else jsig(etp) } } - if (needsJavaSig(info)) { - try Some(jsig2(true, Nil, info)) - catch { case ex: UnknownSig => None } + traceSig("javaSig", sym0, info) { + if (needsJavaSig(info)) { + try Some(jsig2(true, Nil, info)) + catch { case ex: UnknownSig => None } + } + else None } - else None } class UnknownSig extends Exception diff --git a/src/compiler/scala/tools/nsc/util/Tracer.scala b/src/compiler/scala/tools/nsc/util/Tracer.scala new file mode 100644 index 0000000000..c5d3fd3753 --- /dev/null +++ b/src/compiler/scala/tools/nsc/util/Tracer.scala @@ -0,0 +1,37 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.nsc +package util + +class Tracer(enabled: () => Boolean) { + private var indentLevel = 0 + private def ind(s: String) = (" " * (indentLevel*2)) + s + private def indented[T](body: => T): T = { + indentLevel += 1 + try body + finally indentLevel -= 1 + } + private def p(s: String) = { + System.out.print(s) + System.out.flush() + } + private def pin[T](x: T): T = { + p(ind("" + x)) + x + } + def apply[T](name: String, args: Any*)(body: => T): T = { + if (enabled()) { + p(ind("%s(%s) = {\n".format(name, args mkString ", "))) + try indented(pin(body)) + finally println("\n" + ind("}")) + } + else body + } +} + +object Tracer { + def apply(enabled: => Boolean): Tracer = new Tracer(() => enabled) +} diff --git a/test/files/run/bug4238/J.java b/test/files/run/bug4238/J.java new file mode 100644 index 0000000000..948989b4e7 --- /dev/null +++ b/test/files/run/bug4238/J.java @@ -0,0 +1,4 @@ +class J { + scala.collection.mutable.HashMap<String, String> x = + new scala.collection.mutable.HashMap<String, String>(); +} diff --git a/test/files/run/sigtp.check b/test/files/run/sigtp.check new file mode 100644 index 0000000000..6b961be3d0 --- /dev/null +++ b/test/files/run/sigtp.check @@ -0,0 +1,7 @@ +public A Bug.key() +public Bug<A, B> Bug.foo() +public Bug<A, B> Bug.next() +public void Bug.next_$eq(Bug<A, B>) +public abstract A BugBase.key() +public abstract E BugBase.next() +public abstract void BugBase.next_$eq(E) diff --git a/test/files/run/sigtp.scala b/test/files/run/sigtp.scala new file mode 100644 index 0000000000..f0cac859f5 --- /dev/null +++ b/test/files/run/sigtp.scala @@ -0,0 +1,18 @@ +trait BugBase [A, E] { + val key: A + var next: E = _ +} + +final class Bug[A, B](val key: A) extends BugBase[A, Bug[A, B]] { + def foo = next +} + +object Test { + def f(clazz: Class[_]) = + clazz.getDeclaredMethods.toList.map(_.toGenericString).sorted foreach println + + def main(args: Array[String]): Unit = { + f(classOf[Bug[_, _]]) + f(classOf[BugBase[_, _]]) + } +} |