aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-03-23 12:02:32 +0100
committerMartin Odersky <odersky@gmail.com>2013-03-23 12:02:32 +0100
commitf73792d9c6a41c692cc689c52e481e15120bccc4 (patch)
tree683c0e622164f447430700505347ee4fbec31fee
parentb440606b0f0d1772d8a1c3bc1c36b3aa3cb576b5 (diff)
downloaddotty-f73792d9c6a41c692cc689c52e481e15120bccc4.tar.gz
dotty-f73792d9c6a41c692cc689c52e481e15120bccc4.tar.bz2
dotty-f73792d9c6a41c692cc689c52e481e15120bccc4.zip
More fixes to classfile reading.
Most important one: Getting equality of NamedTypes right.
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala1
-rw-r--r--src/dotty/tools/dotc/core/Scopes.scala4
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala6
-rw-r--r--src/dotty/tools/dotc/core/SymbolLoaders.scala49
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala2
-rw-r--r--src/dotty/tools/dotc/core/Types.scala12
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala22
-rw-r--r--src/test/showClass.scala25
8 files changed, 80 insertions, 41 deletions
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index 6dfd2050d..e8e2fa6dc 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -254,6 +254,7 @@ object Contexts {
new InitialContext(this, settings)
.withSetting(settings.verbose, true) // !!! for now
.withSetting(settings.debug, true)
+// .withSetting(settings.debugNames, true)
.withSetting(settings.Ylogcp, true)
.withSetting(settings.printtypes, true)
.withSetting(settings.pageWidth, 90)
diff --git a/src/dotty/tools/dotc/core/Scopes.scala b/src/dotty/tools/dotc/core/Scopes.scala
index 57d9446f1..f8147c8f0 100644
--- a/src/dotty/tools/dotc/core/Scopes.scala
+++ b/src/dotty/tools/dotc/core/Scopes.scala
@@ -169,7 +169,9 @@ object Scopes {
/** enter a symbol in this scope. */
final def enter[T <: Symbol](sym: T)(implicit ctx: Context): T = {
- if (sym.isType) assert(lookup(sym.name) == NoSymbol, sym.debugString) // !!! DEBUG
+ if (sym.isType) {
+ assert(lookup(sym.name) == NoSymbol, sym.debugString) // !!! DEBUG
+ }
newScopeEntry(sym)
sym
}
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index c973fea72..7b4f215b5 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -1015,10 +1015,10 @@ object SymDenotations {
val (location, src) =
if (file != null) (s" in $file", file.toString)
else ("", "the signature")
+ val name = cctx.fresh.withSetting(cctx.settings.debugNames, true).nameString(denot.name)
cctx.error(
- s"""|bad symbolic reference. A signature$location refers to
- |${cctx.fresh.withSetting(cctx.settings.debugNames, true).nameString(denot.name)}
- |in ${denot.owner.showKind} ${denot.owner.showFullName} which is not available.
+ s"""|bad symbolic reference. A signature$location
+ |refers to $name in ${denot.owner.showKind} ${denot.owner.showFullName} which is not available.
|It may be completely missing from the current classpath, or the version on
|the classpath might be incompatible with the version used when compiling $src.""".stripMargin)
if (cctx.debug) throw new Error()
diff --git a/src/dotty/tools/dotc/core/SymbolLoaders.scala b/src/dotty/tools/dotc/core/SymbolLoaders.scala
index 9231a97bf..aa29e9d0c 100644
--- a/src/dotty/tools/dotc/core/SymbolLoaders.scala
+++ b/src/dotty/tools/dotc/core/SymbolLoaders.scala
@@ -25,27 +25,35 @@ object SymbolLoaders {
/** A base class for Symbol loaders with some overridable behavior */
class SymbolLoaders {
- protected def enterNew(owner: Symbol, member: Symbol, completer: SymbolLoader)
- (implicit ctx: Context): Symbol = {
- assert(owner.info.decls.lookup(member.name) == NoSymbol, owner.fullName + "." + member.name)
- owner.asClass.enter(member)
+ protected def enterNew(
+ owner: Symbol, member: Symbol,
+ completer: SymbolLoader, scope: Scope = EmptyScope)(implicit ctx: Context): Symbol = {
+ assert(scope.lookup(member.name) == NoSymbol, owner.fullName + "." + member.name)
+ scope match {
+ case scope: MutableScope => scope.enter(member)
+ case _ => owner.asClass.enter(member)
+ }
member
}
/** Enter class with given `name` into scope of `owner`.
*/
- def enterClass(owner: Symbol, name: PreName, completer: SymbolLoader, flags: FlagSet = EmptyFlags)(implicit ctx: Context): Symbol = {
+ def enterClass(
+ owner: Symbol, name: PreName, completer: SymbolLoader,
+ flags: FlagSet = EmptyFlags, scope: Scope = EmptyScope)(implicit ctx: Context): Symbol = {
val cls = ctx.newClassSymbol(owner, name.toTypeName, flags, completer, assocFile = completer.sourceFileOrNull)
- enterNew(owner, cls, completer)
+ enterNew(owner, cls, completer, scope)
}
/** Enter module with given `name` into scope of `owner`.
*/
- def enterModule(owner: Symbol, name: PreName, completer: SymbolLoader, modFlags: FlagSet = EmptyFlags, clsFlags: FlagSet = EmptyFlags)(implicit ctx: CondensedContext): Symbol = {
+ def enterModule(
+ owner: Symbol, name: PreName, completer: SymbolLoader,
+ modFlags: FlagSet = EmptyFlags, clsFlags: FlagSet = EmptyFlags, scope: Scope = EmptyScope)(implicit ctx: CondensedContext): Symbol = {
def moduleCompleterFn(modul: TermSymbol, cls: ClassSymbol): LazyType =
new ModuleClassCompleter(modul, completer)
val module = ctx.newModuleSymbol(owner, name.toTermName, modFlags, clsFlags, moduleCompleterFn, assocFile = completer.sourceFileOrNull)
- enterNew(owner, module, completer)
+ enterNew(owner, module, completer, scope)
}
/** Enter package with given `name` into scope of `owner`
@@ -81,16 +89,15 @@ class SymbolLoaders {
/** Enter class and module with given `name` into scope of `owner`
* and give them `completer` as type.
*/
- def enterClassAndModule(owner: Symbol, name: PreName, completer: SymbolLoader, flags: FlagSet = EmptyFlags)(implicit ctx: CondensedContext) {
- val clazz = enterClass(owner, name, completer, flags)
- val module = enterModule(owner, name, completer, flags)
- /*
- * !!! disabled for now because it causes CyclicReference. Need to revisit
- * if (!clazz.isAnonymousClass) {
- assert(clazz.companionModule == module, module)
- assert(module.companionClass == clazz, clazz)
- }
- */
+ def enterClassAndModule(
+ owner: Symbol, name: PreName, completer: SymbolLoader,
+ flags: FlagSet = EmptyFlags, scope: Scope = EmptyScope)(implicit ctx: CondensedContext) {
+ val clazz = enterClass(owner, name, completer, flags, scope)
+ val module = enterModule(
+ owner, name, completer,
+ modFlags = flags & RetainedModuleValFlags,
+ clsFlags = flags & RetainedModuleClassFlags,
+ scope = scope)
}
/** In batch mode: Enter class and module with given `name` into scope of `owner`
@@ -99,8 +106,10 @@ class SymbolLoaders {
* with source completer for given `src` as type.
* (overridden in interactive.Global).
*/
- def enterToplevelsFromSource(owner: Symbol, name: PreName, src: AbstractFile)(implicit ctx: CondensedContext) {
- enterClassAndModule(owner, name, new SourcefileLoader(src)(ctx.condensed))
+ def enterToplevelsFromSource(
+ owner: Symbol, name: PreName, src: AbstractFile,
+ scope: Scope = EmptyScope)(implicit ctx: CondensedContext) {
+ enterClassAndModule(owner, name, new SourcefileLoader(src)(ctx.condensed), scope = scope)
}
/** The package objects of scala and scala.reflect should always
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index d39dabe1d..ecb2e2857 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -395,7 +395,7 @@ object Symbols {
/** The source or class file from which this class was generated, null if not applicable. */
override def associatedFile(implicit ctx: Context): AbstractFile =
- if (this.owner is PackageClass) assocFile
+ if (assocFile != null || (this.owner is PackageClass)) assocFile
else super.associatedFile
final def classDenot(implicit ctx: Context): ClassDenotation =
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index b061a1227..74bf684e1 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -532,7 +532,7 @@ object Types {
def recur(tp: Type, tparams: List[TypeSymbol], args: List[Type]): Type = args match {
case arg :: args1 =>
if (tparams.isEmpty) {
- println(s"applied type mismatch: $this $args, $typeParams = typeParams") // !!! DEBUG
+ println(s"applied type mismatch: $this $args, typeParams = $typeParams, tsym = ${this.typeSymbol.debugString}") // !!! DEBUG
println(s"precomplete decls = ${typeSymbol.preCompleteDecls.toList.map(_.denot).mkString("\n ")}")
}
val tparam = tparams.head
@@ -913,6 +913,16 @@ object Types {
NamedType(prefix, name)
override def computeHash = doHash(name, prefix)
+
+ override def equals(that: Any) = that match {
+ case that: HasFixedSym => false
+ case that: TermRefWithSignature => false
+ case that: NamedType =>
+ this.prefix == that.prefix &&
+ this.name == that.name
+ case _ =>
+ false
+ }
}
abstract case class TermRef(override val prefix: Type, name: TermName) extends NamedType with SingletonType
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
index 7d885eaf1..60dfc9d9b 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
@@ -36,7 +36,7 @@ class ClassfileParser(
def srcfile = srcfile0
- private def currentIsTopLevel = !(classRoot.name contains '$')
+ private def currentIsTopLevel = classRoot.owner is Flags.PackageClass
private def mismatchError(c: Symbol) =
throw new IOException(s"class file '${in.file}' has location not matching its contents: contains $c")
@@ -514,12 +514,27 @@ class ClassfileParser(
private def enterOwnInnerClasses() {
def className(name: Name): Name = name.drop(name.lastIndexOf('.') + 1)
- def enterClassAndModule(entry: InnerClassEntry, file: AbstractFile, jflags: Int) =
+ def enterClassAndModule(entry: InnerClassEntry, file: AbstractFile, jflags: Int) = {
loaders.enterClassAndModule(
getOwner(jflags),
entry.originalName,
new ClassfileLoader(file),
- FlagTranslation.classFlags(jflags))
+ FlagTranslation.classFlags(jflags),
+ getScope(jflags))
+ // println(s"entered inner class of ${getOwner(jflags)}: ${entry.originalName} from file $file") // !!! DEBUG
+ /* alternative:
+ val owner = getOwner(jflags)
+ val name = entry.originalName
+ val completer = new ClassfileLoader(file)
+ val flags = FlagTranslation.classFlags(jflags)
+ val cls = cctx.newClassSymbol(owner, name.toTypeName, flags, completer, assocFile = file)
+ def moduleCompleterFn(modul: TermSymbol, cls: ClassSymbol): LazyType =
+ new ModuleClassCompleter(modul, completer)
+ getScope(jflags).enter(cls)
+ val module = cctx.newModuleSymbol(owner, name.toTermName, Flags.EmptyFlags, Flags.EmptyFlags, /*???*/ moduleCompleterFn, assocFile = file)
+ getScope(jflags).enter(module)
+ */
+ }
for (entry <- innerClasses.values) {
// create a new class member for immediate inner classes
@@ -603,6 +618,7 @@ class ClassfileParser(
}
if (scan(tpnme.InnerClassesATTR)) {
+ val attrLen = in.nextInt
val entries = in.nextChar.toInt
for (i <- 0 until entries) {
val innerIndex = in.nextChar
diff --git a/src/test/showClass.scala b/src/test/showClass.scala
index 07d5ce297..4866d536f 100644
--- a/src/test/showClass.scala
+++ b/src/test/showClass.scala
@@ -42,18 +42,19 @@ object showClass {
for (arg <- args) showClasses(arg)
-// showClasses("java.lang.Class")
-// showClasses("scala.Boolean")
-// showClasses("scala.Array")
-// showClasses("scala.math.Ordering")
-// showClasses("scala.collection.Traversable")
-// showClasses("scala.collection.LinearSeqLike")
-// showClasses("scala.collection.immutable.List")
- showClasses("scala.collection.JavaConversions")
-// showClasses("scala.collection.generic.package")
-// showClasses("scala.collection.MapLike")
-// showClasses("scala.Function1")
-// showClasses("dotty.tools.dotc.core.Types")
+// showClasses("java.util.Map")
+// showClasses("scala.Boolean")
+// showClasses("scala.Array")
+// showClasses("scala.math.Ordering")
+ showClasses("scala.collection.mutable.LinkedHashMap")
+// showClasses("scala.collection.Traversable")
+// showClasses("scala.collection.LinearSeqLike")
+// showClasses("scala.collection.immutable.List")
+// showClasses("scala.collection.convert.Wrappers")
+// showClasses("scala.collection.generic.package")
+// showClasses("scala.collection.MapLike")
+// showClasses("scala.Function1")
+// showClasses("dotty.tools.dotc.core.Types")
println("done")
}
} \ No newline at end of file