From e4af2ce209abd7565bb45eae1b80ec798b813035 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Wed, 2 Dec 2009 16:12:14 +0000 Subject: closes #2750: cooking java raw types in info of... closes #2750: cooking java raw types in info of type parameters of Java classes review by: odersky --- src/compiler/scala/tools/nsc/symtab/Symbols.scala | 78 +++++++++++++--------- .../scala/tools/nsc/typechecker/RefChecks.scala | 2 + test/files/jvm/t2570.check | 0 test/files/jvm/t2570/Test.scala | 3 + test/files/jvm/t2570/Test1.java | 2 + test/files/jvm/t2570/Test3.java | 2 + 6 files changed, 57 insertions(+), 30 deletions(-) create mode 100644 test/files/jvm/t2570.check create mode 100644 test/files/jvm/t2570/Test.scala create mode 100644 test/files/jvm/t2570/Test1.java create mode 100644 test/files/jvm/t2570/Test3.java diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index 2369456b11..3f9f266132 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -892,40 +892,13 @@ trait Symbols { */ private var triedCooking: Boolean = false final def cookJavaRawInfo() { - require(isTerm) // println("cookJavaRawInfo: "+(rawname, triedCooking)) - if(triedCooking) return else triedCooking = true // only try once... - - def cook(sym: Symbol) { - require(sym hasFlag JAVA) - // @M: I think this is more desirable, but Martin prefers to leave raw-types as-is as much as possible - // object rawToExistentialInJava extends TypeMap { - // def apply(tp: Type): Type = tp match { - // // any symbol that occurs in a java sig, not just java symbols - // // see http://lampsvn.epfl.ch/trac/scala/ticket/2454#comment:14 - // case TypeRef(pre, sym, List()) if !sym.typeParams.isEmpty => - // val eparams = typeParamsToExistentials(sym, sym.typeParams) - // existentialAbstraction(eparams, TypeRef(pre, sym, eparams map (_.tpe))) - // case _ => - // mapOver(tp) - // } - // } - val tpe1 = rawToExistential(sym.tpe) - // println("cooking: "+ sym +": "+ sym.tpe +" to "+ tpe1) - if (tpe1 ne sym.tpe) { - sym.setInfo(tpe1) - } - } - - if (hasFlag(JAVA)) - cook(this) - else if (hasFlag(OVERLOADED)) - for (sym2 <- alternatives) - if (sym2 hasFlag JAVA) - cook(sym2) + doCookJavaRawInfo() } + protected def doCookJavaRawInfo(): Unit + /** The type constructor of a symbol is: * For a type symbol, the type corresponding to the symbol itself, @@ -1744,6 +1717,36 @@ trait Symbols { assert(hasFlag(LAZY), this) referenced } + + protected def doCookJavaRawInfo() { + def cook(sym: Symbol) { + require(sym hasFlag JAVA) + // @M: I think this is more desirable, but Martin prefers to leave raw-types as-is as much as possible + // object rawToExistentialInJava extends TypeMap { + // def apply(tp: Type): Type = tp match { + // // any symbol that occurs in a java sig, not just java symbols + // // see http://lampsvn.epfl.ch/trac/scala/ticket/2454#comment:14 + // case TypeRef(pre, sym, List()) if !sym.typeParams.isEmpty => + // val eparams = typeParamsToExistentials(sym, sym.typeParams) + // existentialAbstraction(eparams, TypeRef(pre, sym, eparams map (_.tpe))) + // case _ => + // mapOver(tp) + // } + // } + val tpe1 = rawToExistential(sym.tpe) + // println("cooking: "+ sym +": "+ sym.tpe +" to "+ tpe1) + if (tpe1 ne sym.tpe) { + sym.setInfo(tpe1) + } + } + + if (hasFlag(JAVA)) + cook(this) + else if (hasFlag(OVERLOADED)) + for (sym2 <- alternatives) + if (sym2 hasFlag JAVA) + cook(sym2) + } } /** A class for module symbols */ @@ -1852,6 +1855,20 @@ trait Symbols { tyconRunId = NoRunId } + /*** example: + * public class Test3 {} + * public class Test1 {} + * info for T in Test1 should be >: Nothing <: Test3[_] + */ + protected def doCookJavaRawInfo() { + // don't require hasFlag(JAVA), since T in the above example does not have that flag + val tpe1 = rawToExistential(info) + // println("cooking type: "+ this +": "+ info +" to "+ tpe1) + if (tpe1 ne info) { + setInfo(tpe1) + } + } + def cloneSymbolImpl(owner: Symbol): Symbol = new TypeSymbol(owner, pos, name) @@ -2034,6 +2051,7 @@ trait Symbols { override def reset(completer: Type) {} override def info: Type = NoType override def rawInfo: Type = NoType + protected def doCookJavaRawInfo() {} override def accessBoundary(base: Symbol): Symbol = RootClass def cloneSymbolImpl(owner: Symbol): Symbol = throw new Error() } diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index c4a3981a51..d945e213c0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -955,6 +955,8 @@ abstract class RefChecks extends InfoTransform { private def checkTypeRef(tp: Type, pos: Position) = tp match { case TypeRef(pre, sym, args) => checkDeprecated(sym, pos) + if(sym.hasFlag(JAVA)) + sym.typeParams foreach (_.cookJavaRawInfo()) if (!tp.isHigherKinded) checkBounds(pre, sym.owner, sym.typeParams, args, pos) case _ => diff --git a/test/files/jvm/t2570.check b/test/files/jvm/t2570.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/jvm/t2570/Test.scala b/test/files/jvm/t2570/Test.scala new file mode 100644 index 0000000000..d7b7632e22 --- /dev/null +++ b/test/files/jvm/t2570/Test.scala @@ -0,0 +1,3 @@ +class Test2 extends Test1[Test3[Test4]] +class Test4 +object Test extends Application {} \ No newline at end of file diff --git a/test/files/jvm/t2570/Test1.java b/test/files/jvm/t2570/Test1.java new file mode 100644 index 0000000000..f305736581 --- /dev/null +++ b/test/files/jvm/t2570/Test1.java @@ -0,0 +1,2 @@ +public class Test1 { +} \ No newline at end of file diff --git a/test/files/jvm/t2570/Test3.java b/test/files/jvm/t2570/Test3.java new file mode 100644 index 0000000000..97603b5ca6 --- /dev/null +++ b/test/files/jvm/t2570/Test3.java @@ -0,0 +1,2 @@ +public class Test3 { +} \ No newline at end of file -- cgit v1.2.3