From ebeb8c51e434f0a1e1b0de4fa9740a158f57b1ab Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 3 Mar 2011 05:59:01 +0000 Subject: 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. --- .../scala/tools/nsc/transform/Erasure.scala | 26 +++++++++------ src/compiler/scala/tools/nsc/util/Tracer.scala | 37 ++++++++++++++++++++++ 2 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 src/compiler/scala/tools/nsc/util/Tracer.scala (limited to 'src/compiler') 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) +} -- cgit v1.2.3