summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-03-03 05:59:01 +0000
committerPaul Phillips <paulp@improving.org>2011-03-03 05:59:01 +0000
commitebeb8c51e434f0a1e1b0de4fa9740a158f57b1ab (patch)
treed67ef34148df775e4acff9936a29849bc2b7ee9c
parent4e0d7b8e223511e05fd67c6c90a4af369e99787f (diff)
downloadscala-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.scala26
-rw-r--r--src/compiler/scala/tools/nsc/util/Tracer.scala37
-rw-r--r--test/files/run/bug4238/J.java4
-rw-r--r--test/files/run/sigtp.check7
-rw-r--r--test/files/run/sigtp.scala18
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[_, _]])
+ }
+}