summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-06-29 20:44:55 +0000
committerPaul Phillips <paulp@improving.org>2011-06-29 20:44:55 +0000
commite87bab490fddafe67841a39c06e68f8dec9e0868 (patch)
treea8abeb6d5680ea385e36b7d37354affdca716bce
parent6fdce5324dc2d774445ff92146c79ca9505c9a26 (diff)
downloadscala-e87bab490fddafe67841a39c06e68f8dec9e0868.tar.gz
scala-e87bab490fddafe67841a39c06e68f8dec9e0868.tar.bz2
scala-e87bab490fddafe67841a39c06e68f8dec9e0868.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.scala28
-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, 81 insertions, 13 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index d40450d9d0..5b46fec5fd 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -203,8 +203,8 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
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)
}
@@ -217,9 +217,11 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
// 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 '$'.
@@ -234,6 +236,8 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
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.
@@ -250,7 +254,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
case tp => List(tp)
}
- 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 =>
@@ -282,7 +286,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
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)
@@ -346,15 +350,13 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
else jsig(etp)
}
}
- if (needsJavaSig(info)) {
- try {
- //println("Java sig of "+sym0+" is "+jsig2(true, List(), sym0.info))//DEBUG
- Some(jsig2(true, List(), 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[_, _]])
+ }
+}