From e4780e574f9613346e6908f7947f40a58327e376 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 1 Apr 2017 17:21:39 +0200 Subject: Keep package member names mangled Once we start using unencoded operators internally, we will face the problem that one cannot decode realiably a class file filename. We therefore turn things around, keeping members of package scopes in mangled and encoded form. This is compensated by (1) mangling names for lookup of such members and (2) when unpickling from Scala 2 info or Tasty, comparing mangled names when matching a read class or module object against a root. --- compiler/src/dotty/tools/dotc/core/Denotations.scala | 2 +- compiler/src/dotty/tools/dotc/core/Scopes.scala | 10 +++++++++- compiler/src/dotty/tools/dotc/core/SymDenotations.scala | 13 ++++++++++--- compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala | 4 ++-- .../src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala | 4 +++- .../tools/dotc/core/unpickleScala2/Scala2Unpickler.scala | 9 ++++++--- 6 files changed, 31 insertions(+), 11 deletions(-) (limited to 'compiler') diff --git a/compiler/src/dotty/tools/dotc/core/Denotations.scala b/compiler/src/dotty/tools/dotc/core/Denotations.scala index fca77fc06..fd42bde36 100644 --- a/compiler/src/dotty/tools/dotc/core/Denotations.scala +++ b/compiler/src/dotty/tools/dotc/core/Denotations.scala @@ -1207,7 +1207,7 @@ object Denotations { } recurSimple(path.length, wrap) } - recur(path.unmangleClassName) + recur(path) } /** If we are looking for a non-existing term name in a package, diff --git a/compiler/src/dotty/tools/dotc/core/Scopes.scala b/compiler/src/dotty/tools/dotc/core/Scopes.scala index 6090079e5..032442421 100644 --- a/compiler/src/dotty/tools/dotc/core/Scopes.scala +++ b/compiler/src/dotty/tools/dotc/core/Scopes.scala @@ -394,6 +394,14 @@ object Scopes { } } + class PackageScope extends MutableScope { + override final def newScopeEntry(name: Name, sym: Symbol)(implicit ctx: Context): ScopeEntry = + super.newScopeEntry(name.toSimpleName, sym) + + override final def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = + super.lookupEntry(name.toSimpleName) + } + /** Create a new scope */ def newScope: MutableScope = new MutableScope() @@ -408,7 +416,7 @@ object Scopes { } /** Create new scope for the members of package `pkg` */ - def newPackageScope(pkgClass: Symbol): MutableScope = newScope + def newPackageScope(pkgClass: Symbol): MutableScope = new PackageScope() /** Transform scope of members of `owner` using operation `op` * This is overridden by the reflective compiler to avoid creating new scopes for packages diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 1c7206533..b8cd7bb18 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -107,7 +107,7 @@ object SymDenotations { class SymDenotation private[SymDenotations] ( symbol: Symbol, ownerIfExists: Symbol, - final val name: Name, + initName: Name, initFlags: FlagSet, initInfo: Type, initPrivateWithin: Symbol = NoSymbol) extends SingleDenotation(symbol) { @@ -125,11 +125,18 @@ object SymDenotations { // ------ Getting and setting fields ----------------------------- + private[this] var myName = initName private[this] var myFlags: FlagSet = adaptFlags(initFlags) private[this] var myInfo: Type = initInfo private[this] var myPrivateWithin: Symbol = initPrivateWithin private[this] var myAnnotations: List[Annotation] = Nil + /** The name of the symbol */ + def name = myName + + /** Update the name; only called when unpickling top-level classes */ + def name_=(n: Name) = myName = n + /** The owner of the symbol; overridden in NoDenotation */ def owner: Symbol = ownerIfExists @@ -1208,12 +1215,12 @@ object SymDenotations { class ClassDenotation private[SymDenotations] ( symbol: Symbol, ownerIfExists: Symbol, - name: Name, + initName: Name, initFlags: FlagSet, initInfo: Type, initPrivateWithin: Symbol, initRunId: RunId) - extends SymDenotation(symbol, ownerIfExists, name, initFlags, initInfo, initPrivateWithin) { + extends SymDenotation(symbol, ownerIfExists, initName, initFlags, initInfo, initPrivateWithin) { import util.LRUCache diff --git a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala index 0ea643e0d..75deb8bb5 100644 --- a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala +++ b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala @@ -39,7 +39,7 @@ class SymbolLoaders { 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.unmangleClassName, flags, completer, assocFile = completer.sourceFileOrNull) + val cls = ctx.newClassSymbol(owner, name.toTypeName, flags, completer, assocFile = completer.sourceFileOrNull) enterNew(owner, cls, completer, scope) } @@ -163,7 +163,7 @@ class SymbolLoaders { initializeFromClassPath(root.symbol, classRep) for (classRep <- classpath.classes) if (maybeModuleClass(classRep) && - !root.unforcedDecls.lookup(classRep.name.toTypeName.unmangleClassName).exists) + !root.unforcedDecls.lookup(classRep.name.toTypeName).exists) initializeFromClassPath(root.symbol, classRep) } if (!root.isEmptyPackage) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index 96bf29a70..81519727c 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -416,6 +416,7 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi val tag = readByte() val end = readEnd() var name: Name = readName() + val sname = name.toSimpleName if (tag == TYPEDEF || tag == TYPEPARAM) name = name.toTypeName skipParams() val ttag = nextUnsharedTag @@ -432,9 +433,10 @@ class TreeUnpickler(reader: TastyReader, nameAtRef: NameRef => TermName, posUnpi def adjustIfModule(completer: LazyType) = if (flags is Module) ctx.adjustModuleCompleter(completer, name) else completer val sym = - roots.find(root => (root.owner eq ctx.owner) && root.name == name) match { + roots.find(root => (root.owner eq ctx.owner) && root.name.toSimpleName == sname && root.isType == name.isTypeName) match { case Some(rootd) => pickling.println(i"overwriting ${rootd.symbol} # ${rootd.hashCode}") + rootd.name = name rootd.info = adjustIfModule( new Completer(ctx.owner, subReader(start, end)) with SymbolLoaders.SecondCompleter) rootd.flags = flags &~ Touched // allow one more completion diff --git a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala index 5871ec46c..1e8fbe54b 100644 --- a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala @@ -448,15 +448,18 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas flags = flags &~ Scala2SuperAccessor } - def isClassRoot = (name == classRoot.name) && (owner == classRoot.owner) && !(flags is ModuleClass) - def isModuleClassRoot = (name == moduleClassRoot.name) && (owner == moduleClassRoot.owner) && (flags is Module) - def isModuleRoot = (name == moduleClassRoot.name.sourceModuleName) && (owner == moduleClassRoot.owner) && (flags is Module) + val sname = name.toSimpleName + def nameMatches(rootName: Name) = sname == rootName.toSimpleName + def isClassRoot = nameMatches(classRoot.name) && (owner == classRoot.owner) && !(flags is ModuleClass) + def isModuleClassRoot = nameMatches(moduleClassRoot.name) && (owner == moduleClassRoot.owner) && (flags is Module) + def isModuleRoot = nameMatches(moduleClassRoot.name.sourceModuleName) && (owner == moduleClassRoot.owner) && (flags is Module) //if (isClassRoot) println(s"classRoot of $classRoot found at $readIndex, flags = $flags") // !!! DEBUG //if (isModuleRoot) println(s"moduleRoot of $moduleRoot found at $readIndex, flags = $flags") // !!! DEBUG //if (isModuleClassRoot) println(s"moduleClassRoot of $moduleClassRoot found at $readIndex, flags = $flags") // !!! DEBUG def completeRoot(denot: ClassDenotation, completer: LazyType): Symbol = { + denot.name = name denot.setFlag(flags) denot.resetFlag(Touched) // allow one more completion denot.info = completer -- cgit v1.2.3