summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/internal/Symbols.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-08-02 10:07:19 -0700
committerPaul Phillips <paulp@improving.org>2012-08-11 20:27:46 -0700
commita55788e275faed91cb9223686a3aef6ee54213a8 (patch)
tree4ac92fc704d7e06edb38680114321309c84dbd5b /src/reflect/scala/reflect/internal/Symbols.scala
parent4459e5abb2b765cbdca34eb19c5d8b705203f771 (diff)
downloadscala-a55788e275faed91cb9223686a3aef6ee54213a8.tar.gz
scala-a55788e275faed91cb9223686a3aef6ee54213a8.tar.bz2
scala-a55788e275faed91cb9223686a3aef6ee54213a8.zip
More resilience to missing classes.
The situation (I don't know how to make partest test this) is package s class A ; class S { def f(): A = ??? } If one compiles this and removes A.class, should references to class S cause the compiler to explode eagerly and fail to load S, or explode lazily if and when it needs to know something about A? This patch takes us from the former strategy to the latter. Review by @xeno-by.
Diffstat (limited to 'src/reflect/scala/reflect/internal/Symbols.scala')
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 161d04b6ff..9311a74f18 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -392,6 +392,16 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
case x: TermName => newErrorValue(x)
}
+ /** Creates a placeholder symbol for when a name is encountered during
+ * unpickling for which there is no corresponding classfile. This defers
+ * failure to the point when that name is used for something, which is
+ * often to the point of never.
+ */
+ def newStubSymbol(name: Name): Symbol = name match {
+ case n: TypeName => new StubClassSymbol(this, n)
+ case _ => new StubTermSymbol(this, name.toTermName)
+ }
+
@deprecated("Use the other signature", "2.10.0")
def newClass(pos: Position, name: TypeName): Symbol = newClass(name, pos)
@deprecated("Use the other signature", "2.10.0")
@@ -2998,6 +3008,37 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
|| info.parents.exists(_.typeSymbol hasTransOwner sym)
)
}
+ trait StubSymbol extends Symbol {
+ protected def stubWarning = {
+ val from = if (associatedFile == null) "" else s" - referenced from ${associatedFile.canonicalPath}"
+ s"$kindString $nameString$locationString$from (a classfile may be missing)"
+ }
+ private def fail[T](alt: T): T = {
+ // Avoid issuing lots of redundant errors
+ if (!hasFlag(IS_ERROR)) {
+ globalError(s"bad symbolic reference to " + stubWarning)
+ if (settings.debug.value)
+ (new Throwable).printStackTrace
+
+ this setFlag IS_ERROR
+ }
+ alt
+ }
+ // This one doesn't call fail because SpecializeTypes winds up causing
+ // isMonomorphicType to be called, which calls this, which would fail us
+ // in all the scenarios we're trying to keep from failing.
+ override def originalInfo = NoType
+ override def associatedFile = owner.associatedFile
+ override def info = fail(NoType)
+ override def rawInfo = fail(NoType)
+ override def companionSymbol = fail(NoSymbol)
+
+ locally {
+ debugwarn("creating stub symbol for " + stubWarning)
+ }
+ }
+ class StubClassSymbol(owner0: Symbol, name0: TypeName) extends ClassSymbol(owner0, owner0.pos, name0) with StubSymbol
+ class StubTermSymbol(owner0: Symbol, name0: TermName) extends TermSymbol(owner0, owner0.pos, name0) with StubSymbol
trait FreeSymbol extends Symbol {
def origin: String