diff options
author | Paul Phillips <paulp@improving.org> | 2011-06-29 20:44:55 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-06-29 20:44:55 +0000 |
commit | e87bab490fddafe67841a39c06e68f8dec9e0868 (patch) | |
tree | a8abeb6d5680ea385e36b7d37354affdca716bce | |
parent | 6fdce5324dc2d774445ff92146c79ca9505c9a26 (diff) | |
download | scala-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.scala | 28 | ||||
-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, 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[_, _]]) + } +} |