diff options
4 files changed, 31 insertions, 8 deletions
diff --git a/compiler/src/dotty/tools/dotc/config/Config.scala b/compiler/src/dotty/tools/dotc/config/Config.scala index 46b1896f1..a225b3019 100644 --- a/compiler/src/dotty/tools/dotc/config/Config.scala +++ b/compiler/src/dotty/tools/dotc/config/Config.scala @@ -10,6 +10,8 @@ object Config { final val checkCacheMembersNamed = false + final val semanticNames = true + /** When updating a constraint bound, check that the constrained parameter * does not appear at the top-level of either of its bounds. */ diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala index a6e5fefc7..38eb21446 100644 --- a/compiler/src/dotty/tools/dotc/core/NameOps.scala +++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala @@ -9,6 +9,7 @@ import Decorators.PreNamedString import util.{Chars, NameTransformer} import Chars.isOperatorPart import Definitions._ +import config.Config object NameOps { @@ -73,7 +74,9 @@ object NameOps { def isTraitSetterName = name containsSlice TRAIT_SETTER_SEPARATOR def isSetterName = name endsWith SETTER_SUFFIX def isSingletonName = name endsWith SINGLETON_SUFFIX - def isModuleClassName = name endsWith MODULE_SUFFIX + def isModuleClassName = + if (Config.semanticNames) name.is(NameInfo.ModuleClass.kind) + else name endsWith MODULE_SUFFIX def isAvoidClashName = name endsWith AVOID_CLASH_SUFFIX def isImportName = name startsWith IMPORT def isFieldName = name endsWith LOCAL_SUFFIX @@ -119,14 +122,19 @@ object NameOps { } /** Convert this module name to corresponding module class name */ - def moduleClassName: TypeName = (name ++ tpnme.MODULE_SUFFIX).toTypeName + def moduleClassName: TypeName = + if (Config.semanticNames) name.derived(NameInfo.ModuleClass).toTypeName + else (name ++ tpnme.MODULE_SUFFIX).toTypeName /** Convert this module class name to corresponding source module name */ def sourceModuleName: TermName = stripModuleClassSuffix.toTermName /** If name ends in module class suffix, drop it */ def stripModuleClassSuffix: Name = - if (isModuleClassName) name dropRight MODULE_SUFFIX.length else name + if (isModuleClassName) + if (Config.semanticNames) name.without(NameInfo.ModuleClass.kind) + else name dropRight MODULE_SUFFIX.length + else name /** Append a suffix so that this name does not clash with another name in the same scope */ def avoidClashName: TermName = (name ++ AVOID_CLASH_SUFFIX).toTermName @@ -194,7 +202,7 @@ object NameOps { likeTyped( if (name.isModuleClassName) name.stripModuleClassSuffix.freshened.moduleClassName else likeTyped(ctx.freshName(name ++ NameTransformer.NAME_JOIN_STRING))) - +/* /** Name with variance prefix: `+` for covariant, `-` for contravariant */ def withVariance(v: Int): N = if (hasVariance) dropVariance.withVariance(v) @@ -220,6 +228,14 @@ object NameOps { case _ => 0 } +*/ + def unmangleClassName: N = + if (Config.semanticNames) + if (name.endsWith(MODULE_SUFFIX)) + likeTyped(name.dropRight(MODULE_SUFFIX.length).moduleClassName) + else name + else name + /** Translate a name into a list of simple TypeNames and TermNames. * In all segments before the last, type/term is determined by whether * the following separator char is '.' or '#'. The last segment diff --git a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala index 79f8a6a45..40e561d3f 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, flags, completer, assocFile = completer.sourceFileOrNull) + val cls = ctx.newClassSymbol(owner, name.toTypeName.unmangleClassName, flags, completer, assocFile = completer.sourceFileOrNull) enterNew(owner, cls, completer, scope) } @@ -152,7 +152,7 @@ class SymbolLoaders { def doComplete(root: SymDenotation)(implicit ctx: Context): Unit = { assert(root is PackageClass, root) - def maybeModuleClass(classRep: ClassPath#ClassRep) = classRep.name.last == '$' + def maybeModuleClass(classRep: ClassPath#ClassRep) = classRep.name.last == '$' val pre = root.owner.thisType root.info = ClassInfo(pre, root.symbol.asClass, Nil, currentDecls, pre select sourceModule) if (!sourceModule.isCompleted) @@ -162,7 +162,8 @@ class SymbolLoaders { if (!maybeModuleClass(classRep)) initializeFromClassPath(root.symbol, classRep) for (classRep <- classpath.classes) - if (maybeModuleClass(classRep) && !root.unforcedDecls.lookup(classRep.name.toTypeName).exists) + if (maybeModuleClass(classRep) && + !root.unforcedDecls.lookup(classRep.name.toTypeName.unmangleClassName).exists) initializeFromClassPath(root.symbol, classRep) } if (!root.isEmptyPackage) @@ -247,8 +248,11 @@ class ClassfileLoader(val classfile: AbstractFile) extends SymbolLoader { (module, _) => new NoCompleter() withDecls newScope withSourceModule (_ => module)) .moduleClass.denot.asClass } + val res = if (rootDenot is ModuleClass) (linkedDenot, rootDenot) else (rootDenot, linkedDenot) + println(s"root denots of ${rootDenot.name.debugString} = ${res._1.name.debugString}, ${res._2.name.debugString} / ${rootDenot is ModuleClass}") + res } override def doComplete(root: SymDenotation)(implicit ctx: Context): Unit = diff --git a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala index cf99bb022..a49379327 100644 --- a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala @@ -432,7 +432,8 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas } val name1 = name0.adjustIfModuleClass(flags) - val name = if (name1 == nme.TRAIT_CONSTRUCTOR) nme.CONSTRUCTOR else name1 + val name2 = if (name1 == nme.TRAIT_CONSTRUCTOR) nme.CONSTRUCTOR else name1 + val name = if (flags is ModuleClass) name2.unmangleClassName else name2 def isClassRoot = (name == classRoot.name) && (owner == classRoot.owner) && !(flags is ModuleClass) def isModuleClassRoot = (name == moduleClassRoot.name) && (owner == moduleClassRoot.owner) && (flags is Module) |