diff options
author | Paul Phillips <paulp@improving.org> | 2012-03-27 07:50:20 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-03-27 08:16:44 -0700 |
commit | 2b90e85b68fca963ae66106d1ff1c21b1428056f (patch) | |
tree | 3b9930be8cf6ec2dcb1941f7698417c06682a495 | |
parent | d078b58961014c5eaa7540c4cec733679dc8965c (diff) | |
download | scala-2b90e85b68fca963ae66106d1ff1c21b1428056f.tar.gz scala-2b90e85b68fca963ae66106d1ff1c21b1428056f.tar.bz2 scala-2b90e85b68fca963ae66106d1ff1c21b1428056f.zip |
Workaround for "package is not a value".
Not actually a fix, but when we see a package where a module is
expected, it's not a great stretch to try the package object.
References SI-5604.
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/icode/GenICode.scala | 53 | ||||
-rw-r--r-- | test/files/pos/t5604/ReplConfig.scala | 53 | ||||
-rw-r--r-- | test/files/pos/t5604/ReplReporter.scala | 30 |
3 files changed, 112 insertions, 24 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index 41d9d93e7a..8e568eca79 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -944,11 +944,10 @@ abstract class GenICode extends SubComponent { "Trying to access the this of another class: " + "tree.symbol = " + tree.symbol + ", ctx.clazz.symbol = " + ctx.clazz.symbol + " compilation unit:"+unit) if (tree.symbol.isModuleClass && tree.symbol != ctx.clazz.symbol) { - debuglog("LOAD_MODULE from 'This': " + tree.symbol); - assert(!tree.symbol.isPackageClass, "Cannot use package as value: " + tree) - genLoadModule(ctx, tree.symbol, tree.pos) + genLoadModule(ctx, tree) generatedType = REFERENCE(tree.symbol) - } else { + } + else { ctx.bb.emit(THIS(ctx.clazz.symbol), tree.pos) generatedType = REFERENCE( if (tree.symbol == ArrayClass) ObjectClass else ctx.clazz.symbol @@ -961,11 +960,7 @@ abstract class GenICode extends SubComponent { "Selection of non-module from empty package: " + tree + " sym: " + tree.symbol + " at: " + (tree.pos) ) - debuglog("LOAD_MODULE from Select(<emptypackage>): " + tree.symbol) - - assert(!tree.symbol.isPackageClass, "Cannot use package as value: " + tree) - genLoadModule(ctx, tree.symbol, tree.pos) - ctx + genLoadModule(ctx, tree) case Select(qualifier, selector) => val sym = tree.symbol @@ -973,14 +968,13 @@ abstract class GenICode extends SubComponent { val hostClass = qualifier.tpe.typeSymbol.orElse(sym.owner) if (sym.isModule) { - debuglog("LOAD_MODULE from Select(qualifier, selector): " + sym) - assert(!tree.symbol.isPackageClass, "Cannot use package as value: " + tree) - genLoadModule(ctx, sym, tree.pos) - ctx - } else if (sym.isStaticMember) { + genLoadModule(ctx, tree) + } + else if (sym.isStaticMember) { ctx.bb.emit(LOAD_FIELD(sym, true) setHostClass hostClass, tree.pos) ctx - } else { + } + else { val ctx1 = genLoadQualifier(tree, ctx) ctx1.bb.emit(LOAD_FIELD(sym, false) setHostClass hostClass, tree.pos) ctx1 @@ -990,11 +984,10 @@ abstract class GenICode extends SubComponent { val sym = tree.symbol if (!sym.isPackage) { if (sym.isModule) { - debuglog("LOAD_MODULE from Ident(name): " + sym) - assert(!sym.isPackageClass, "Cannot use package as value: " + tree) - genLoadModule(ctx, sym, tree.pos) + genLoadModule(ctx, tree) generatedType = toTypeKind(sym.info) - } else { + } + else { try { val Some(l) = ctx.method.lookupLocal(sym) ctx.bb.emit(LOAD_LOCAL(l), tree.pos) @@ -1207,8 +1200,19 @@ abstract class GenICode extends SubComponent { genLoad(arg, res, toTypeKind(tpe)) } - private def genLoadModule(ctx: Context, sym: Symbol, pos: Position) { - ctx.bb.emit(LOAD_MODULE(sym), pos) + private def genLoadModule(ctx: Context, tree: Tree): Context = { + // Working around SI-5604. Rather than failing the compile when we see + // a package here, check if there's a package object. + val sym = ( + if (!tree.symbol.isPackageClass) tree.symbol + else tree.symbol.info.member(nme.PACKAGE) match { + case NoSymbol => assert(false, "Cannot use package as value: " + tree) ; NoSymbol + case s => Console.err.println("Bug: found package class where package object expected. Converting.") ; s.moduleClass + } + ) + debuglog("LOAD_MODULE from %s: %s".format(tree.shortClass, sym)) + ctx.bb.emit(LOAD_MODULE(sym), tree.pos) + ctx } def genConversion(from: TypeKind, to: TypeKind, ctx: Context, cast: Boolean) = { @@ -1567,9 +1571,10 @@ abstract class GenICode extends SubComponent { val ctx1 = genLoad(l, ctx, ObjectReference) val ctx2 = genLoad(r, ctx1, ObjectReference) - ctx2.bb.emit(CALL_METHOD(equalsMethod, if (settings.optimise.value) Dynamic else Static(false))) - ctx2.bb.emit(CZJUMP(thenCtx.bb, elseCtx.bb, NE, BOOL)) - ctx2.bb.close + ctx2.bb.emitOnly( + CALL_METHOD(equalsMethod, if (settings.optimise.value) Dynamic else Static(false)), + CZJUMP(thenCtx.bb, elseCtx.bb, NE, BOOL) + ) } else { if (isNull(l)) diff --git a/test/files/pos/t5604/ReplConfig.scala b/test/files/pos/t5604/ReplConfig.scala new file mode 100644 index 0000000000..8c589eba60 --- /dev/null +++ b/test/files/pos/t5604/ReplConfig.scala @@ -0,0 +1,53 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.nsc +package interpreter + +import util.Exceptional.unwrap +import util.stackTraceString + +trait ReplConfig { + lazy val replProps = new ReplProps + + class TapMaker[T](x: T) { + def tapInfo(msg: => String): T = tap(x => replinfo(parens(x))) + def tapDebug(msg: => String): T = tap(x => repldbg(parens(x))) + def tapTrace(msg: => String): T = tap(x => repltrace(parens(x))) + def tap[U](f: T => U): T = { + f(x) + x + } + } + + private def parens(x: Any) = "(" + x + ")" + private def echo(msg: => String) = + try Console println msg + catch { case x: AssertionError => Console.println("Assertion error printing debugging output: " + x) } + + private[nsc] def repldbg(msg: => String) = if (isReplDebug) echo(msg) + private[nsc] def repltrace(msg: => String) = if (isReplTrace) echo(msg) + private[nsc] def replinfo(msg: => String) = if (isReplInfo) echo(msg) + + private[nsc] def logAndDiscard[T](label: String, alt: => T): PartialFunction[Throwable, T] = { + case t => + repldbg(label + ": " + unwrap(t)) + repltrace(stackTraceString(unwrap(t))) + alt + } + private[nsc] def substituteAndLog[T](alt: => T)(body: => T): T = + substituteAndLog("" + alt, alt)(body) + private[nsc] def substituteAndLog[T](label: String, alt: => T)(body: => T): T = { + try body + catch logAndDiscard(label, alt) + } + private[nsc] def squashAndLog(label: String)(body: => Unit): Unit = + substituteAndLog(label, ())(body) + + def isReplTrace: Boolean = replProps.trace + def isReplDebug: Boolean = replProps.debug || isReplTrace + def isReplInfo: Boolean = replProps.info || isReplDebug + def isReplPower: Boolean = replProps.power +} diff --git a/test/files/pos/t5604/ReplReporter.scala b/test/files/pos/t5604/ReplReporter.scala new file mode 100644 index 0000000000..130af990ad --- /dev/null +++ b/test/files/pos/t5604/ReplReporter.scala @@ -0,0 +1,30 @@ +/* NSC -- new Scala compiler + * Copyright 2002-2011 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.nsc +package interpreter + +import reporters._ +import IMain._ + +class ReplReporter(intp: IMain) extends ConsoleReporter(intp.settings, Console.in, new ReplStrippingWriter(intp)) { + override def printMessage(msg: String) { + // Avoiding deadlock if the compiler starts logging before + // the lazy val is complete. + if (intp.isInitializeComplete) { + if (intp.totalSilence) { + if (isReplTrace) + super.printMessage("[silent] " + msg) + } + else super.printMessage(msg) + } + else Console.println("[init] " + msg) + } + + override def displayPrompt() { + if (intp.totalSilence) () + else super.displayPrompt() + } +} |