Skip to content

Commit 6acaa1b

Browse files
Remove PreName
PreName was abusing the implementation of implicit class by using the underlying implicit conversion. For instance, several method form Definitions where expecting an argument of type PreName and called with a String. This commit completely removes the PreName abstraction by explicitly calling .toTermName and .toTypeName as required. This change should be beneficial for both readability (more precise types) and performance. Indeed by "pushing out" all the calls to .toTermName and .toTypeName to the call site, these methods will never use virtual dispatch. To keep the concisness of string literals a couple of methods where duplicated to take String arguments (and forward to the TypeName/TermName version).
1 parent f1d7850 commit 6acaa1b

16 files changed

+97
-105
lines changed

compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,9 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
154154
lazy val Predef_classOf: Symbol = defn.ScalaPredefModule.requiredMethod(nme.classOf)
155155

156156
lazy val AnnotationRetentionAttr = ctx.requiredClass("java.lang.annotation.Retention")
157-
lazy val AnnotationRetentionSourceAttr = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("SOURCE")
158-
lazy val AnnotationRetentionClassAttr = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("CLASS")
159-
lazy val AnnotationRetentionRuntimeAttr = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("RUNTIME")
157+
lazy val AnnotationRetentionSourceAttr = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("SOURCE".toTermName)
158+
lazy val AnnotationRetentionClassAttr = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("CLASS".toTermName)
159+
lazy val AnnotationRetentionRuntimeAttr = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("RUNTIME".toTermName)
160160
lazy val JavaAnnotationClass = ctx.requiredClass("java.lang.annotation.Annotation")
161161

162162
def boxMethods: Map[Symbol, Symbol] = defn.ScalaValueClasses().map{x => // @darkdimius Are you sure this should be a def?
@@ -366,7 +366,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
366366
def getAnnotPickle(jclassName: String, sym: Symbol): Option[Annotation] = None
367367

368368

369-
def getRequiredClass(fullname: String): Symbol = ctx.requiredClass(fullname.toTermName)
369+
def getRequiredClass(fullname: String): Symbol = ctx.requiredClass(fullname)
370370

371371
def getClassIfDefined(fullname: String): Symbol = NoSymbol // used only for android. todo: implement
372372

@@ -376,12 +376,12 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
376376
}
377377

378378
def requiredClass[T](implicit evidence: ClassTag[T]): Symbol =
379-
ctx.requiredClass(erasureString(evidence.runtimeClass).toTermName)
379+
ctx.requiredClass(erasureString(evidence.runtimeClass))
380380

381381
def requiredModule[T](implicit evidence: ClassTag[T]): Symbol = {
382382
val moduleName = erasureString(evidence.runtimeClass)
383383
val className = if (moduleName.endsWith("$")) moduleName.dropRight(1) else moduleName
384-
ctx.requiredModule(className.toTermName)
384+
ctx.requiredModule(className)
385385
}
386386

387387

@@ -1193,8 +1193,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
11931193
val arity = field.meth.tpe.widenDealias.paramTypes.size - _1.size
11941194
val returnsUnit = field.meth.tpe.widenDealias.resultType.classSymbol == UnitClass
11951195
if (returnsUnit)
1196-
ctx.requiredClass(("scala.compat.java8.JProcedure" + arity).toTermName)
1197-
else ctx.requiredClass(("scala.compat.java8.JFunction" + arity).toTermName)
1196+
ctx.requiredClass("scala.compat.java8.JProcedure" + arity)
1197+
else ctx.requiredClass("scala.compat.java8.JFunction" + arity)
11981198
}
11991199
}
12001200
}

compiler/src/dotty/tools/dotc/core/Decorators.scala

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,10 @@ import printing.Formatting._
1313

1414
/** This object provides useful implicit decorators for types defined elsewhere */
1515
object Decorators {
16-
17-
/** Turns Strings into PreNames, adding toType/TermName methods */
18-
implicit class PreNamedString(val s: String) extends AnyVal with PreName {
16+
implicit class StringDecorator(val s: String) extends AnyVal {
1917
def toTypeName: TypeName = typeName(s)
2018
def toTermName: TermName = termName(s)
21-
def toText(printer: Printer): Text = Str(s)
22-
}
2319

24-
implicit class StringDecorator(val s: String) extends AnyVal {
2520
def splitWhere(f: Char => Boolean, doDropIndex: Boolean): Option[(String, String)] = {
2621
def splitAt(idx: Int, doDropIndex: Boolean): Option[(String, String)] =
2722
if (idx == -1) None

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ class Definitions {
204204
lazy val OpsPackageVal = ctx.newCompletePackageSymbol(RootClass, nme.OPS_PACKAGE).entered
205205
lazy val OpsPackageClass = OpsPackageVal.moduleClass.asClass
206206

207-
lazy val ScalaPackageVal = ctx.requiredPackage("scala")
208-
lazy val ScalaMathPackageVal = ctx.requiredPackage("scala.math")
207+
lazy val ScalaPackageVal = ctx.requiredPackage(nme.scala_)
208+
lazy val ScalaMathPackageVal = ctx.requiredPackage("scala.math".toTermName)
209209
lazy val ScalaPackageClass = {
210210
val cls = ScalaPackageVal.moduleClass.asClass
211211
cls.info.decls.openForMutations.useSynthesizer(
@@ -215,8 +215,8 @@ class Definitions {
215215
cls
216216
}
217217
lazy val ScalaPackageObjectRef = ctx.requiredModuleRef("scala.package")
218-
lazy val JavaPackageVal = ctx.requiredPackage("java")
219-
lazy val JavaLangPackageVal = ctx.requiredPackage("java.lang")
218+
lazy val JavaPackageVal = ctx.requiredPackage(nme.java)
219+
lazy val JavaLangPackageVal = ctx.requiredPackage(jnme.JavaLang)
220220
// fundamental modules
221221
lazy val SysPackage = ctx.requiredModule("scala.sys.package")
222222
lazy val Sys_errorR = SysPackage.moduleClass.requiredMethodRef(nme.error)
@@ -339,13 +339,13 @@ class Definitions {
339339
lazy val ScalaPredefModuleRef = ctx.requiredModuleRef("scala.Predef")
340340
def ScalaPredefModule(implicit ctx: Context) = ScalaPredefModuleRef.symbol
341341

342-
lazy val Predef_ConformsR = ScalaPredefModule.requiredClass("<:<").typeRef
342+
lazy val Predef_ConformsR = ScalaPredefModule.requiredClass("<:<".toTypeName).typeRef
343343
def Predef_Conforms(implicit ctx: Context) = Predef_ConformsR.symbol
344-
lazy val Predef_conformsR = ScalaPredefModule.requiredMethodRef("$conforms")
344+
lazy val Predef_conformsR = ScalaPredefModule.requiredMethodRef(nme.conforms_)
345345
def Predef_conforms(implicit ctx: Context) = Predef_conformsR.symbol
346-
lazy val Predef_classOfR = ScalaPredefModule.requiredMethodRef("classOf")
346+
lazy val Predef_classOfR = ScalaPredefModule.requiredMethodRef(nme.classOf)
347347
def Predef_classOf(implicit ctx: Context) = Predef_classOfR.symbol
348-
lazy val Predef_undefinedR = ScalaPredefModule.requiredMethodRef("???")
348+
lazy val Predef_undefinedR = ScalaPredefModule.requiredMethodRef(nme.???)
349349
def Predef_undefined(implicit ctx: Context) = Predef_undefinedR.symbol
350350
// The set of all wrap{X, Ref}Array methods, where X is a value type
351351
val Predef_wrapArray = new PerRun[collection.Set[Symbol]]({ implicit ctx =>
@@ -357,7 +357,7 @@ class Definitions {
357357
def ScalaRuntimeModule(implicit ctx: Context) = ScalaRuntimeModuleRef.symbol
358358
def ScalaRuntimeClass(implicit ctx: Context) = ScalaRuntimeModule.moduleClass.asClass
359359

360-
def runtimeMethodRef(name: PreName) = ScalaRuntimeModule.requiredMethodRef(name)
360+
def runtimeMethodRef(name: TermName) = ScalaRuntimeModule.requiredMethodRef(name)
361361
def ScalaRuntime_dropR(implicit ctx: Context) = runtimeMethodRef(nme.drop)
362362
def ScalaRuntime_drop(implicit ctx: Context) = ScalaRuntime_dropR.symbol
363363

@@ -368,8 +368,8 @@ class Definitions {
368368
def ScalaStaticsModule(implicit ctx: Context) = ScalaStaticsModuleRef.symbol
369369
def ScalaStaticsClass(implicit ctx: Context) = ScalaStaticsModule.moduleClass.asClass
370370

371-
def staticsMethodRef(name: PreName) = ScalaStaticsModule.requiredMethodRef(name)
372-
def staticsMethod(name: PreName) = ScalaStaticsModule.requiredMethod(name)
371+
def staticsMethodRef(name: TermName) = ScalaStaticsModule.requiredMethodRef(name)
372+
def staticsMethod(name: TermName): TermSymbol = ScalaStaticsModule.requiredMethod(name)
373373

374374
// Dotty deviation: we cannot use a lazy val here because lazy vals in dotty
375375
// will return "null" when called recursively, see #1856.
@@ -384,13 +384,13 @@ class Definitions {
384384

385385
def DottyPredefModule(implicit ctx: Context) = DottyPredefModuleRef.symbol
386386

387-
lazy val Predef_ImplicitConverterR = DottyPredefModule.requiredClass("ImplicitConverter").typeRef
387+
lazy val Predef_ImplicitConverterR = DottyPredefModule.requiredClass("ImplicitConverter".toTypeName).typeRef
388388
def Predef_ImplicitConverter(implicit ctx: Context) = Predef_ImplicitConverterR.symbol
389389

390390
lazy val DottyArraysModuleRef = ctx.requiredModuleRef("dotty.runtime.Arrays")
391391
def DottyArraysModule(implicit ctx: Context) = DottyArraysModuleRef.symbol
392-
def newGenericArrayMethod(implicit ctx: Context) = DottyArraysModule.requiredMethod("newGenericArray")
393-
def newArrayMethod(implicit ctx: Context) = DottyArraysModule.requiredMethod("newArray")
392+
def newGenericArrayMethod(implicit ctx: Context) = DottyArraysModule.requiredMethod("newGenericArray".toTermName)
393+
def newArrayMethod(implicit ctx: Context) = DottyArraysModule.requiredMethod("newArray".toTermName)
394394

395395
lazy val NilModuleRef = ctx.requiredModuleRef("scala.collection.immutable.Nil")
396396
def NilModule(implicit ctx: Context) = NilModuleRef.symbol
@@ -497,7 +497,7 @@ class Definitions {
497497
lazy val BoxedUnitType: TypeRef = ctx.requiredClassRef("scala.runtime.BoxedUnit")
498498
def BoxedUnitClass(implicit ctx: Context) = BoxedUnitType.symbol.asClass
499499

500-
def BoxedUnit_UNIT(implicit ctx: Context) = BoxedUnitClass.linkedClass.requiredValue("UNIT")
500+
def BoxedUnit_UNIT(implicit ctx: Context) = BoxedUnitClass.linkedClass.requiredValue("UNIT".toTermName)
501501

502502
lazy val BoxedBooleanType: TypeRef = ctx.requiredClassRef("java.lang.Boolean")
503503
def BoxedBooleanClass(implicit ctx: Context) = BoxedBooleanType.symbol.asClass
@@ -638,8 +638,8 @@ class Definitions {
638638
lazy val QuotedType_applyR = QuotedTypeModule.requiredMethodRef(nme.apply)
639639
def QuotedType_apply(implicit ctx: Context) = QuotedType_applyR.symbol
640640

641-
def Unpickler_unpickleExpr = ctx.requiredMethod("scala.runtime.quoted.Unpickler.unpickleExpr")
642-
def Unpickler_unpickleType = ctx.requiredMethod("scala.runtime.quoted.Unpickler.unpickleType")
641+
def Unpickler_unpickleExpr = ctx.requiredMethod("scala.runtime.quoted.Unpickler.unpickleExpr".toTermName)
642+
def Unpickler_unpickleType = ctx.requiredMethod("scala.runtime.quoted.Unpickler.unpickleType".toTermName)
643643

644644
lazy val EqType = ctx.requiredClassRef("scala.Eq")
645645
def EqClass(implicit ctx: Context) = EqType.symbol.asClass
@@ -1189,5 +1189,4 @@ class Definitions {
11891189
_isInitialized = true
11901190
}
11911191
}
1192-
11931192
}

compiler/src/dotty/tools/dotc/core/Denotations.scala

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -287,13 +287,14 @@ object Denotations {
287287
denot.symbol
288288
}
289289

290-
def requiredMethod(name: PreName)(implicit ctx: Context): TermSymbol =
291-
info.member(name.toTermName).requiredSymbol(_ is Method).asTerm
292-
def requiredMethodRef(name: PreName)(implicit ctx: Context): TermRef =
290+
def requiredMethod(name: TermName)(implicit ctx: Context): TermSymbol =
291+
info.member(name).requiredSymbol(_ is Method).asTerm
292+
293+
def requiredMethodRef(name: TermName)(implicit ctx: Context): TermRef =
293294
requiredMethod(name).termRef
294295

295-
def requiredMethod(name: PreName, argTypes: List[Type])(implicit ctx: Context): TermSymbol = {
296-
info.member(name.toTermName).requiredSymbol { x =>
296+
def requiredMethod(name: TermName, argTypes: List[Type])(implicit ctx: Context): TermSymbol = {
297+
info.member(name).requiredSymbol { x =>
297298
(x is Method) && {
298299
x.info.paramInfoss match {
299300
case paramInfos :: Nil => paramInfos.corresponds(argTypes)(_ =:= _)
@@ -302,19 +303,18 @@ object Denotations {
302303
}
303304
}.asTerm
304305
}
305-
def requiredMethodRef(name: PreName, argTypes: List[Type])(implicit ctx: Context): TermRef =
306+
307+
def requiredMethodRef(name: TermName, argTypes: List[Type])(implicit ctx: Context): TermRef =
306308
requiredMethod(name, argTypes).termRef
307309

308-
def requiredValue(name: PreName)(implicit ctx: Context): TermSymbol =
309-
info.member(name.toTermName).requiredSymbol(_.info.isParameterless).asTerm
310-
def requiredValueRef(name: PreName)(implicit ctx: Context): TermRef =
311-
requiredValue(name).termRef
310+
def requiredValue(name: TermName)(implicit ctx: Context): TermSymbol =
311+
info.member(name).requiredSymbol(_.info.isParameterless).asTerm
312312

313-
def requiredClass(name: PreName)(implicit ctx: Context): ClassSymbol =
313+
def requiredClass(name: TypeName)(implicit ctx: Context): ClassSymbol =
314314
info.member(name.toTypeName).requiredSymbol(_.isClass).asClass
315315

316-
def requiredType(name: PreName)(implicit ctx: Context): TypeSymbol =
317-
info.member(name.toTypeName).requiredSymbol(_.isType).asType
316+
def requiredType(name: TypeName)(implicit ctx: Context): TypeSymbol =
317+
info.member(name).requiredSymbol(_.isType).asType
318318

319319
/** The alternative of this denotation that has a type matching `targetType` when seen
320320
* as a member of type `site`, `NoDenotation` if none exists.

compiler/src/dotty/tools/dotc/core/NameOps.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import java.security.MessageDigest
55
import scala.annotation.switch
66
import scala.io.Codec
77
import Names._, StdNames._, Contexts._, Symbols._, Flags._, NameKinds._
8-
import Decorators.PreNamedString
8+
import Decorators.StringDecorator
99
import util.{Chars, NameTransformer}
1010
import Chars.isOperatorPart
1111
import Definitions._
@@ -58,7 +58,7 @@ object NameOps {
5858
case _ => false
5959
}
6060

61-
def likeSpaced(n: PreName): N =
61+
def likeSpaced(n: Name): N =
6262
(if (name.isTermName) n.toTermName else n.toTypeName).asInstanceOf[N]
6363

6464
def isConstructorName = name == CONSTRUCTOR || name == TRAIT_CONSTRUCTOR

compiler/src/dotty/tools/dotc/core/Names.scala

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,6 @@ import java.util.HashMap
1919
object Names {
2020
import NameKinds._
2121

22-
/** A common class for things that can be turned into names.
23-
* Instances are both names and strings, the latter via a decorator.
24-
*/
25-
trait PreName extends Any with Showable {
26-
def toTypeName: TypeName
27-
def toTermName: TermName
28-
}
29-
3022
implicit def eqName: Eq[Name, Name] = Eq
3123

3224
/** A common superclass of Name and Symbol. After bootstrap, this should be
@@ -39,7 +31,7 @@ object Names {
3931
* in a name table. A derived term name adds a tag, and possibly a number
4032
* or a further simple name to some other name.
4133
*/
42-
abstract class Name extends Designator with PreName {
34+
abstract class Name extends Designator with Showable {
4335

4436
/** A type for names of the same kind as this name */
4537
type ThisName <: Name

compiler/src/dotty/tools/dotc/core/StdNames.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import scala.annotation.switch
77
import Names._
88
import Symbols._
99
import Contexts._
10-
import Decorators.PreNamedString
10+
import Decorators.StringDecorator
1111
import util.NameTransformer
1212
import scala.collection.breakOut
1313

@@ -393,7 +393,7 @@ object StdNames {
393393
val ClassManifestFactory: N = "ClassManifestFactory"
394394
val classOf: N = "classOf"
395395
val clone_ : N = "clone"
396-
// val conforms : N = "conforms" // Dotty deviation: no special treatment of conforms, so the occurrence of the name here would cause to unintended implicit shadowing. Should find a less common name for it in Predef.
396+
val conforms_ : N = "$conforms"
397397
val copy: N = "copy"
398398
val currentMirror: N = "currentMirror"
399399
val create: N = "create"

compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import dotty.tools.io.{ ClassPath, ClassRepresentation, AbstractFile }
88
import classpath._
99
import Contexts._, Symbols._, Flags._, SymDenotations._, Types._, Scopes._, util.Positions._, Names._
1010
import StdNames._, NameOps._
11-
import Decorators.{PreNamedString, StringInterpolators}
11+
import Decorators.{StringDecorator, StringInterpolators}
1212
import classfile.ClassfileParser
1313
import util.Stats
1414
import Decorators._
@@ -43,19 +43,19 @@ class SymbolLoaders {
4343
/** Enter class with given `name` into scope of `owner`.
4444
*/
4545
def enterClass(
46-
owner: Symbol, name: PreName, completer: SymbolLoader,
46+
owner: Symbol, name: TypeName, completer: SymbolLoader,
4747
flags: FlagSet = EmptyFlags, scope: Scope = EmptyScope)(implicit ctx: Context): Symbol = {
48-
val cls = ctx.newClassSymbol(owner, name.toTypeName.unmangleClassName.decode, flags, completer, assocFile = completer.sourceFileOrNull)
48+
val cls = ctx.newClassSymbol(owner, name.unmangleClassName.decode, flags, completer, assocFile = completer.sourceFileOrNull)
4949
enterNew(owner, cls, completer, scope)
5050
}
5151

5252
/** Enter module with given `name` into scope of `owner`.
5353
*/
5454
def enterModule(
55-
owner: Symbol, name: PreName, completer: SymbolLoader,
55+
owner: Symbol, name: TermName, completer: SymbolLoader,
5656
modFlags: FlagSet = EmptyFlags, clsFlags: FlagSet = EmptyFlags, scope: Scope = EmptyScope)(implicit ctx: Context): Symbol = {
5757
val module = ctx.newModuleSymbol(
58-
owner, name.toTermName.decode, modFlags, clsFlags,
58+
owner, name.decode, modFlags, clsFlags,
5959
(module, _) => completer.proxy withDecls newScope withSourceModule (_ => module),
6060
assocFile = completer.sourceFileOrNull)
6161
enterNew(owner, module, completer, scope)
@@ -95,11 +95,11 @@ class SymbolLoaders {
9595
* and give them `completer` as type.
9696
*/
9797
def enterClassAndModule(
98-
owner: Symbol, name: PreName, completer: SymbolLoader,
98+
owner: Symbol, name: Name, completer: SymbolLoader,
9999
flags: FlagSet = EmptyFlags, scope: Scope = EmptyScope)(implicit ctx: Context): Unit = {
100-
val clazz = enterClass(owner, name, completer, flags, scope)
100+
val clazz = enterClass(owner, name.toTypeName, completer, flags, scope)
101101
val module = enterModule(
102-
owner, name, completer,
102+
owner, name.toTermName, completer,
103103
modFlags = flags.toTermFlags & RetainedModuleValFlags,
104104
clsFlags = flags.toTypeFlags & RetainedModuleClassFlags,
105105
scope = scope)
@@ -115,7 +115,7 @@ class SymbolLoaders {
115115
* All entered symbols are given a source completer of `src` as info.
116116
*/
117117
def enterToplevelsFromSource(
118-
owner: Symbol, name: PreName, src: AbstractFile,
118+
owner: Symbol, name: TermName, src: AbstractFile,
119119
scope: Scope = EmptyScope)(implicit ctx: Context): Unit = {
120120

121121
val completer = new SourcefileLoader(src)
@@ -186,12 +186,12 @@ class SymbolLoaders {
186186
((classRep.binary, classRep.source): @unchecked) match {
187187
case (Some(bin), Some(src)) if needCompile(bin, src) && !binaryOnly(owner, classRep.name) =>
188188
if (ctx.settings.verbose.value) ctx.inform("[symloader] picked up newer source file for " + src.path)
189-
enterToplevelsFromSource(owner, classRep.name, src)
189+
enterToplevelsFromSource(owner, classRep.name.toTermName, src)
190190
case (None, Some(src)) =>
191191
if (ctx.settings.verbose.value) ctx.inform("[symloader] no class, picked up source file for " + src.path)
192-
enterToplevelsFromSource(owner, classRep.name, src)
192+
enterToplevelsFromSource(owner, classRep.name.toTermName, src)
193193
case (Some(bin), _) =>
194-
enterClassAndModule(owner, classRep.name, ctx.platform.newClassLoader(bin))
194+
enterClassAndModule(owner, classRep.name.toTermName, ctx.platform.newClassLoader(bin))
195195
}
196196
}
197197

0 commit comments

Comments
 (0)