aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/core/NameOps.scala15
-rw-r--r--src/dotty/tools/dotc/core/StdNames.scala1
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala9
-rw-r--r--src/dotty/tools/dotc/transform/FirstTransform.scala10
4 files changed, 29 insertions, 6 deletions
diff --git a/src/dotty/tools/dotc/core/NameOps.scala b/src/dotty/tools/dotc/core/NameOps.scala
index a6b40fe66..240447e6d 100644
--- a/src/dotty/tools/dotc/core/NameOps.scala
+++ b/src/dotty/tools/dotc/core/NameOps.scala
@@ -72,6 +72,7 @@ object NameOps {
def isSetterName = name endsWith SETTER_SUFFIX
def isSingletonName = name endsWith SINGLETON_SUFFIX
def isModuleClassName = name endsWith MODULE_SUFFIX
+ def isAvoidClashName = name endsWith AVOID_CLASH_SUFFIX
def isImportName = name startsWith IMPORT
def isFieldName = name endsWith LOCAL_SUFFIX
def isInheritedName = name.length > 0 && name.head == '(' && name.startsWith(nme.INHERITED)
@@ -129,11 +130,19 @@ object NameOps {
/** If name ends in module class suffix, drop it */
def stripModuleClassSuffix: Name =
if (isModuleClassName) 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
+
+ /** If name ends in "avoid clash" suffix, drop it */
+ def stripAvoidClashSuffix: Name =
+ if (isAvoidClashName) name dropRight AVOID_CLASH_SUFFIX.length else name
/** If flags is a ModuleClass but not a Package, add module class suffix */
- def adjustIfModuleClass(flags: Flags.FlagSet): N =
- if (flags is (ModuleClass, butNot = Package)) name.asTypeName.moduleClassName.asInstanceOf[N]
- else name
+ def adjustIfModuleClass(flags: Flags.FlagSet): N = {
+ if (flags is (ModuleClass, butNot = Package)) name.asTypeName.moduleClassName
+ else stripAvoidClashSuffix
+ }.asInstanceOf[N]
/** The superaccessor for method with given name */
def superName: TermName = (nme.SUPER_PREFIX ++ name).toTermName
diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala
index 04bcf616d..27aa00392 100644
--- a/src/dotty/tools/dotc/core/StdNames.scala
+++ b/src/dotty/tools/dotc/core/StdNames.scala
@@ -107,6 +107,7 @@ object StdNames {
val INTERPRETER_WRAPPER_SUFFIX: N = "$object"
val LOCALDUMMY_PREFIX: N = "<local " // owner of local blocks
val MODULE_SUFFIX: N = NameTransformer.MODULE_SUFFIX_STRING
+ val AVOID_CLASH_SUFFIX: N = "$_avoid_name_clash_$"
val MODULE_VAR_SUFFIX: N = "$module"
val NAME_JOIN: N = NameTransformer.NAME_JOIN_STRING
val USCORE_PARAM_PREFIX: N = "_$"
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index eccdcbfb9..613d4b29c 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -171,9 +171,14 @@ object SymDenotations {
myInfo = tp
}
- /** The name, except if this is a module class, strip the module class suffix */
+ /** The name, except
+ * - if this is a module class, strip the module class suffix
+ * - if this is a companion object with a clash-avoiding name, strip the
+ * "avoid clash" suffix
+ */
def effectiveName(implicit ctx: Context) =
- if (this is ModuleClass) name.stripModuleClassSuffix else name
+ if (this is ModuleClass) name.stripModuleClassSuffix
+ else name.stripAvoidClashSuffix
/** The privateWithin boundary, NoSymbol if no boundary is given.
*/
diff --git a/src/dotty/tools/dotc/transform/FirstTransform.scala b/src/dotty/tools/dotc/transform/FirstTransform.scala
index 62045890e..bde17c854 100644
--- a/src/dotty/tools/dotc/transform/FirstTransform.scala
+++ b/src/dotty/tools/dotc/transform/FirstTransform.scala
@@ -81,7 +81,15 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer wi
def addMissingCompanions(stats: List[Tree]): List[Tree] = stats map {
case stat: TypeDef if singleClassDefs contains stat.name =>
- Thicket(stat :: newCompanion(stat.name.toTermName).trees)
+ val objName = stat.name.toTermName
+ val nameClash = stats.exists {
+ case other: MemberDef =>
+ other.name == objName && other.symbol.info.isParameterless
+ case _ =>
+ false
+ }
+ val uniqueName = if (nameClash) objName.avoidClashName else objName
+ Thicket(stat :: newCompanion(uniqueName).trees)
case stat => stat
}