From 79db562690a46d167ab5328da51729b28bed8415 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 24 Jul 2018 19:23:35 +0200 Subject: [PATCH 1/6] Simplify type of NameOps.specializedFor The current type is inconsistent with other uses of likeSpaced. And mentioning `name` in a return type would prevent making it private as in next commit. --- compiler/src/dotty/tools/dotc/core/NameOps.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala index 52a0cbb735b5..609aa5e48b69 100644 --- a/compiler/src/dotty/tools/dotc/core/NameOps.scala +++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala @@ -233,12 +233,12 @@ object NameOps { case nme.clone_ => nme.clone_ } - def specializedFor(classTargs: List[Types.Type], classTargsNames: List[Name], methodTargs: List[Types.Type], methodTarsNames: List[Name])(implicit ctx: Context): name.ThisName = { + def specializedFor(classTargs: List[Types.Type], classTargsNames: List[Name], methodTargs: List[Types.Type], methodTarsNames: List[Name])(implicit ctx: Context): N = { val methodTags: Seq[Name] = (methodTargs zip methodTarsNames).sortBy(_._2).map(x => defn.typeTag(x._1)) val classTags: Seq[Name] = (classTargs zip classTargsNames).sortBy(_._2).map(x => defn.typeTag(x._1)) - name.likeSpaced(name ++ nme.specializedTypeNames.prefix ++ + likeSpaced(name ++ nme.specializedTypeNames.prefix ++ methodTags.fold(nme.EMPTY)(_ ++ _) ++ nme.specializedTypeNames.separator ++ classTags.fold(nme.EMPTY)(_ ++ _) ++ nme.specializedTypeNames.suffix) } From a4f4a047d2e089e906134607aca79a9a0d960f3b Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Fri, 29 Jun 2018 18:47:34 +0200 Subject: [PATCH 2/6] Stop accidental support for `.name` on Name This is easy for `TermNameDecorator`, and last commit makes it easy for `NameDecorator`. --- compiler/src/dotty/tools/dotc/core/NameOps.scala | 4 ++-- .../dotty/tools/dotc/reporting/diagnostic/messages.scala | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala index 609aa5e48b69..8d9b597a0b58 100644 --- a/compiler/src/dotty/tools/dotc/core/NameOps.scala +++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala @@ -49,7 +49,7 @@ object NameOps { } } - implicit class NameDecorator[N <: Name](val name: N) extends AnyVal { + implicit class NameDecorator[N <: Name](private val name: N) extends AnyVal { import nme._ def testSimple(f: SimpleName => Boolean): Boolean = name match { @@ -271,7 +271,7 @@ object NameOps { } } - implicit class TermNameDecorator(val name: TermName) extends AnyVal { + implicit class TermNameDecorator(private val name: TermName) extends AnyVal { import nme._ def setterName: TermName = name.exclude(FieldName) ++ str.SETTER_SUFFIX diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index 2df2e49e85e2..a77f8af5af04 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -1266,20 +1266,20 @@ object messages { val msg = hl"""overloaded or recursive method ${tree} needs return type""" val explanation = hl"""Case 1: ${tree} is overloaded - |If there are multiple methods named `${tree.name}` and at least one definition of + |If there are multiple methods named `${tree}` and at least one definition of |it calls another, you need to specify the calling method's return type. | |Case 2: ${tree} is recursive - |If `${tree.name}` calls itself on any path, you need to specify its return type. + |If `${tree}` calls itself on any path, you need to specify its return type. |""".stripMargin } case class RecursiveValueNeedsResultType(tree: Names.TermName)(implicit ctx: Context) extends Message(RecursiveValueNeedsResultTypeID) { val kind = "Syntax" - val msg = hl"""recursive value ${tree.name} needs type""" + val msg = hl"""recursive value ${tree} needs type""" val explanation = - hl"""The definition of `${tree.name}` is recursive and you need to specify its type. + hl"""The definition of `${tree}` is recursive and you need to specify its type. |""".stripMargin } From 9d7cc7916638ad0254aea4a45293541757150d91 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Fri, 29 Jun 2018 18:48:50 +0200 Subject: [PATCH 3/6] Avoid misleading `tree: Name` This lets you think that `tree.name` is sensible tho it isn't, and for more than an year (since ce333b1fe852c2a6cb62486f31d336f4ecaac275). --- .../dotc/reporting/diagnostic/messages.scala | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index a77f8af5af04..818e38ffb4b7 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -1260,26 +1260,26 @@ object messages { |""".stripMargin } - case class OverloadedOrRecursiveMethodNeedsResultType(tree: Names.TermName)(implicit ctx: Context) + case class OverloadedOrRecursiveMethodNeedsResultType(method: Names.TermName)(implicit ctx: Context) extends Message(OverloadedOrRecursiveMethodNeedsResultTypeID) { val kind = "Syntax" - val msg = hl"""overloaded or recursive method ${tree} needs return type""" + val msg = hl"""overloaded or recursive method ${method} needs return type""" val explanation = - hl"""Case 1: ${tree} is overloaded - |If there are multiple methods named `${tree}` and at least one definition of + hl"""Case 1: ${method} is overloaded + |If there are multiple methods named `${method}` and at least one definition of |it calls another, you need to specify the calling method's return type. | - |Case 2: ${tree} is recursive - |If `${tree}` calls itself on any path, you need to specify its return type. + |Case 2: ${method} is recursive + |If `${method}` calls itself on any path, you need to specify its return type. |""".stripMargin } - case class RecursiveValueNeedsResultType(tree: Names.TermName)(implicit ctx: Context) + case class RecursiveValueNeedsResultType(value: Names.TermName)(implicit ctx: Context) extends Message(RecursiveValueNeedsResultTypeID) { val kind = "Syntax" - val msg = hl"""recursive value ${tree} needs type""" + val msg = hl"""recursive value ${value} needs type""" val explanation = - hl"""The definition of `${tree}` is recursive and you need to specify its type. + hl"""The definition of `${value}` is recursive and you need to specify its type. |""".stripMargin } From 60c11e07934a2cab3e6937c7a6759b6a2ac29a74 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 24 Jul 2018 19:27:24 +0200 Subject: [PATCH 4/6] Generalize Name.likeSpaced and hide the one from NameDecorator --- compiler/src/dotty/tools/dotc/core/NameOps.scala | 4 ++-- compiler/src/dotty/tools/dotc/core/Names.scala | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala index 8d9b597a0b58..20aa35f626f2 100644 --- a/compiler/src/dotty/tools/dotc/core/NameOps.scala +++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala @@ -58,8 +58,8 @@ object NameOps { case _ => false } - def likeSpaced(n: PreName): N = - (if (name.isTermName) n.toTermName else n.toTypeName).asInstanceOf[N] + private def likeSpaced(n: PreName): N = + name.likeSpaced(n).asInstanceOf[N] def isConstructorName = name == CONSTRUCTOR || name == TRAIT_CONSTRUCTOR def isStaticConstructorName = name == STATIC_CONSTRUCTOR diff --git a/compiler/src/dotty/tools/dotc/core/Names.scala b/compiler/src/dotty/tools/dotc/core/Names.scala index 1c2af332f8eb..ce9ebfbcd85a 100644 --- a/compiler/src/dotty/tools/dotc/core/Names.scala +++ b/compiler/src/dotty/tools/dotc/core/Names.scala @@ -98,7 +98,7 @@ object Names { /** A name in the same (term or type) namespace as this name and * with same characters as given `name`. */ - def likeSpaced(name: Name): ThisName + def likeSpaced(name: PreName): ThisName /** A derived name consisting of this name and the added info, unless it is * already present in this name. @@ -181,7 +181,7 @@ object Names { _typeName } - override def likeSpaced(name: Name): TermName = name.toTermName + override def likeSpaced(name: PreName): TermName = name.toTermName def info: NameInfo = SimpleNameKind.info def underlying: TermName = unsupported("underlying") @@ -450,7 +450,7 @@ object Names { override def mapLast(f: SimpleName => SimpleName) = toTermName.mapLast(f).toTypeName override def mapParts(f: SimpleName => SimpleName) = toTermName.mapParts(f).toTypeName - override def likeSpaced(name: Name): TypeName = name.toTypeName + override def likeSpaced(name: PreName): TypeName = name.toTypeName override def derived(info: NameInfo): TypeName = toTermName.derived(info).toTypeName override def exclude(kind: NameKind): TypeName = toTermName.exclude(kind).toTypeName From b6dc031512ed7404423417aa159576f49ea759d6 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 24 Jul 2018 19:28:21 +0200 Subject: [PATCH 5/6] Rename NameOps.likeSpaced to prevent confusion --- .../src/dotty/tools/dotc/core/NameOps.scala | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala index 20aa35f626f2..663655ebb054 100644 --- a/compiler/src/dotty/tools/dotc/core/NameOps.scala +++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala @@ -58,7 +58,7 @@ object NameOps { case _ => false } - private def likeSpaced(n: PreName): N = + private def likeSpacedN(n: PreName): N = name.likeSpaced(n).asInstanceOf[N] def isConstructorName = name == CONSTRUCTOR || name == TRAIT_CONSTRUCTOR @@ -100,7 +100,7 @@ object NameOps { * method needs to work on mangled as well as unmangled names because * it is also called from the backend. */ - def stripModuleClassSuffix: N = likeSpaced { + def stripModuleClassSuffix: N = likeSpacedN { val semName = name.toTermName match { case name: SimpleName if name.endsWith("$") => name.unmangleClassName case _ => name @@ -109,7 +109,7 @@ object NameOps { } /** If flags is a ModuleClass but not a Package, add module class suffix */ - def adjustIfModuleClass(flags: Flags.FlagSet): N = likeSpaced { + def adjustIfModuleClass(flags: Flags.FlagSet): N = likeSpacedN { if (flags is (ModuleClass, butNot = Package)) name.asTypeName.moduleClassName else name.toTermName.exclude(AvoidClashName) } @@ -119,27 +119,27 @@ object NameOps { * followed by `kind` and the name. */ def expandedName(base: Symbol, kind: QualifiedNameKind = ExpandedName)(implicit ctx: Context): N = - likeSpaced { base.fullNameSeparated(ExpandPrefixName, kind, name) } + likeSpacedN { base.fullNameSeparated(ExpandPrefixName, kind, name) } /** Revert the expanded name. */ - def unexpandedName: N = likeSpaced { + def unexpandedName: N = likeSpacedN { name.rewrite { case ExpandedName(_, unexp) => unexp } } /** Remove the variance from the name. */ - def invariantName: N = likeSpaced { + def invariantName: N = likeSpacedN { name.rewrite { case VariantName(invariant, _) => invariant } } - def implClassName: N = likeSpaced(name ++ tpnme.IMPL_CLASS_SUFFIX) + def implClassName: N = likeSpacedN(name ++ tpnme.IMPL_CLASS_SUFFIX) def traitOfImplClassName: N = { val suffix = tpnme.IMPL_CLASS_SUFFIX.toString assert(name.endsWith(suffix), name) - likeSpaced(name.mapLast(_.dropRight(suffix.length))) + likeSpacedN(name.mapLast(_.dropRight(suffix.length))) } - def errorName: N = likeSpaced(name ++ nme.ERROR) + def errorName: N = likeSpacedN(name ++ nme.ERROR) /** Map variance value -1, +1 to 0, 1 */ private def varianceToNat(v: Int) = (v + 1) / 2 @@ -150,7 +150,7 @@ object NameOps { /** Name with variance prefix: `+` for covariant, `-` for contravariant */ def withVariance(v: Int): N = { val underlying = name.exclude(VariantName) - likeSpaced( + likeSpacedN( if (v == 0) underlying else VariantName(underlying.toTermName, varianceToNat(v))) } @@ -160,7 +160,7 @@ object NameOps { */ def variance = name.collect { case VariantName(_, n) => natToVariance(n) }.getOrElse(0) - def freshened(implicit ctx: Context): N = likeSpaced { + def freshened(implicit ctx: Context): N = likeSpacedN { name.toTermName match { case ModuleClassName(original) => ModuleClassName(original.freshened) case name => UniqueName.fresh(name) @@ -238,7 +238,7 @@ object NameOps { val methodTags: Seq[Name] = (methodTargs zip methodTarsNames).sortBy(_._2).map(x => defn.typeTag(x._1)) val classTags: Seq[Name] = (classTargs zip classTargsNames).sortBy(_._2).map(x => defn.typeTag(x._1)) - likeSpaced(name ++ nme.specializedTypeNames.prefix ++ + likeSpacedN(name ++ nme.specializedTypeNames.prefix ++ methodTags.fold(nme.EMPTY)(_ ++ _) ++ nme.specializedTypeNames.separator ++ classTags.fold(nme.EMPTY)(_ ++ _) ++ nme.specializedTypeNames.suffix) } @@ -249,11 +249,11 @@ object NameOps { def unmangleClassName: N = name.toTermName match { case name: SimpleName if name.endsWith(str.MODULE_SUFFIX) && !nme.falseModuleClassNames.contains(name) => - likeSpaced(name.dropRight(str.MODULE_SUFFIX.length).moduleClassName) + likeSpacedN(name.dropRight(str.MODULE_SUFFIX.length).moduleClassName) case _ => name } - def unmangle(kind: NameKind): N = likeSpaced { + def unmangle(kind: NameKind): N = likeSpacedN { name rewrite { case unmangled: SimpleName => kind.unmangle(unmangled) From 7ae6478c3b8e92a76b4868e6dce1e12748f61e45 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Wed, 25 Jul 2018 00:41:47 +0200 Subject: [PATCH 6/6] Address review: Make likeSpaced* take Name, not PreName --- compiler/src/dotty/tools/dotc/core/NameOps.scala | 2 +- compiler/src/dotty/tools/dotc/core/Names.scala | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala index 663655ebb054..a3f021001158 100644 --- a/compiler/src/dotty/tools/dotc/core/NameOps.scala +++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala @@ -58,7 +58,7 @@ object NameOps { case _ => false } - private def likeSpacedN(n: PreName): N = + private def likeSpacedN(n: Name): N = name.likeSpaced(n).asInstanceOf[N] def isConstructorName = name == CONSTRUCTOR || name == TRAIT_CONSTRUCTOR diff --git a/compiler/src/dotty/tools/dotc/core/Names.scala b/compiler/src/dotty/tools/dotc/core/Names.scala index ce9ebfbcd85a..1c2af332f8eb 100644 --- a/compiler/src/dotty/tools/dotc/core/Names.scala +++ b/compiler/src/dotty/tools/dotc/core/Names.scala @@ -98,7 +98,7 @@ object Names { /** A name in the same (term or type) namespace as this name and * with same characters as given `name`. */ - def likeSpaced(name: PreName): ThisName + def likeSpaced(name: Name): ThisName /** A derived name consisting of this name and the added info, unless it is * already present in this name. @@ -181,7 +181,7 @@ object Names { _typeName } - override def likeSpaced(name: PreName): TermName = name.toTermName + override def likeSpaced(name: Name): TermName = name.toTermName def info: NameInfo = SimpleNameKind.info def underlying: TermName = unsupported("underlying") @@ -450,7 +450,7 @@ object Names { override def mapLast(f: SimpleName => SimpleName) = toTermName.mapLast(f).toTypeName override def mapParts(f: SimpleName => SimpleName) = toTermName.mapParts(f).toTypeName - override def likeSpaced(name: PreName): TypeName = name.toTypeName + override def likeSpaced(name: Name): TypeName = name.toTypeName override def derived(info: NameInfo): TypeName = toTermName.derived(info).toTypeName override def exclude(kind: NameKind): TypeName = toTermName.exclude(kind).toTypeName