Skip to content

Commit 760d0c8

Browse files
committed
Use unencoded names internally
Don't encode operator symbols internally. Instead, let the backend convert them when generating code.
1 parent d1bcde1 commit 760d0c8

21 files changed

+146
-189
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
547547
def len: Int = n.mangled.toSimpleName.length
548548
def offset: Int = n.mangled.toSimpleName.start
549549
def isTermName: Boolean = n.isTermName
550-
def startsWith(s: String): Boolean = n.startsWith(s)
550+
def startsWith(s: String): Boolean = n.mangled.startsWith(s)
551551
}
552552

553553

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ class Definitions {
137137
}
138138

139139
private def newMethod(cls: ClassSymbol, name: TermName, info: Type, flags: FlagSet = EmptyFlags): TermSymbol =
140-
newSymbol(cls, name.encode, flags | Method, info).asTerm
140+
newSymbol(cls, name, flags | Method, info).asTerm
141141

142142
private def enterMethod(cls: ClassSymbol, name: TermName, info: Type, flags: FlagSet = EmptyFlags): TermSymbol =
143143
newMethod(cls, name, info, flags).entered
@@ -299,7 +299,7 @@ class Definitions {
299299
lazy val ScalaPredefModuleRef = ctx.requiredModuleRef("scala.Predef")
300300
def ScalaPredefModule(implicit ctx: Context) = ScalaPredefModuleRef.symbol
301301

302-
lazy val Predef_ConformsR = ScalaPredefModule.requiredClass("$less$colon$less").typeRef
302+
lazy val Predef_ConformsR = ScalaPredefModule.requiredClass("<:<").typeRef
303303
def Predef_Conforms(implicit ctx: Context) = Predef_ConformsR.symbol
304304
lazy val Predef_conformsR = ScalaPredefModule.requiredMethodRef("$conforms")
305305
def Predef_conforms(implicit ctx: Context) = Predef_conformsR.symbol

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

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import printing.{Showable, Texts, Printer}
88
import Texts.Text
99
import Decorators._
1010
import Contexts.Context
11+
import StdNames.str
1112
import collection.IndexedSeqOptimized
1213
import collection.generic.CanBuildFrom
1314
import collection.mutable.{ Builder, StringBuilder, AnyRefMap }
@@ -70,9 +71,9 @@ object Names {
7071
@sharable // because it's just a cache for performance
7172
private[this] var myMangled: Name = null
7273

73-
def mangle: ThisName
74+
protected[Names] def mangle: ThisName
7475

75-
def mangled: ThisName = {
76+
final def mangled: ThisName = {
7677
if (myMangled == null) myMangled = mangle
7778
myMangled.asInstanceOf[ThisName]
7879
}
@@ -274,9 +275,7 @@ object Names {
274275
def isSimple = true
275276
def asSimpleName = this
276277
def toSimpleName = this
277-
final def mangle = this
278-
279-
final override def mangled: SimpleTermName = this.asSimpleName
278+
final def mangle = encode
280279

281280
def rewrite(f: PartialFunction[Name, Name]): ThisName =
282281
if (f.isDefinedAt(this)) likeSpaced(f(this)) else this
@@ -285,11 +284,10 @@ object Names {
285284
def mapParts(f: SimpleTermName => SimpleTermName) = f(this)
286285

287286
def encode: SimpleTermName =
288-
if (dontEncode(toTermName)) this else NameTransformer.encode(this)
287+
if (dontEncode(this)) this else NameTransformer.encode(this)
289288

290289
/** Replace \$op_name's by corresponding operator symbols. */
291-
def decode: SimpleTermName =
292-
if (contains('$')) termName(NameTransformer.decode(toString)) else this
290+
def decode: SimpleTermName = NameTransformer.decode(this)
293291

294292
def firstPart = this
295293
def lastPart = this
@@ -299,6 +297,9 @@ object Names {
299297
override def toString =
300298
if (length == 0) "" else new String(chrs, start, length)
301299

300+
def sliceToString(from: Int, end: Int) =
301+
if (end <= from) "" else new String(chrs, start + from, end - from)
302+
302303
def debugString: String = toString
303304
}
304305

@@ -358,7 +359,7 @@ object Names {
358359
def asSimpleName = throw new UnsupportedOperationException(s"$debugString is not a simple name")
359360

360361
def toSimpleName = termName(toString)
361-
final def mangle = toSimpleName
362+
final def mangle = encode.toSimpleName
362363

363364
def rewrite(f: PartialFunction[Name, Name]): ThisName =
364365
if (f.isDefinedAt(this)) likeSpaced(f(this))
@@ -527,8 +528,13 @@ object Names {
527528
val STATIC_CONSTRUCTOR: TermName = termName("<clinit>")
528529
val EMPTY_PACKAGE: TermName = termName("<empty>")
529530
val REFINEMENT: TermName = termName("<refinement>")
531+
val LOCALDUMMY_PREFIX: TermName = termName("<local ")
532+
533+
val dontEncodeNames = Set(CONSTRUCTOR, STATIC_CONSTRUCTOR, EMPTY_PACKAGE, REFINEMENT)
530534

531-
val dontEncode = Set(CONSTRUCTOR, EMPTY_PACKAGE, REFINEMENT)
535+
def dontEncode(name: SimpleTermName) =
536+
name.length > 0 && name(0) == '<' &&
537+
(dontEncodeNames.contains(name) || name.startsWith(str.LOCALDUMMY_PREFIX))
532538

533539
implicit val NameOrdering: Ordering[Name] = new Ordering[Name] {
534540
private def compareInfos(x: NameInfo, y: NameInfo): Int =

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

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ object StdNames {
1616
/** Base strings from which synthetic names are derived. */
1717

1818
object str {
19-
final val SETTER_SUFFIX = "_$eq"
19+
final val SETTER_SUFFIX = "_="
2020
final val EXPAND_SEPARATOR = "$$"
2121
final val TRAIT_SETTER_SEPARATOR = "$_setter_$"
2222
final val SUPER_PREFIX = "super$"
@@ -260,7 +260,6 @@ object StdNames {
260260
val MODULE_INSTANCE_FIELD: N = "MODULE$"
261261
val OUTER: N = "$outer"
262262
val REFINE_CLASS: N = "<refinement>"
263-
val REFINE_CLASS_ENCODED: N = "$lessrefinement$greater"
264263
val ROOTPKG: N = "_root_"
265264
val SELECTOR_DUMMY: N = "<unapply-selector>"
266265
val SELF: N = "$this"
@@ -309,7 +308,7 @@ object StdNames {
309308
val _21 : N = "_21"
310309
val _22 : N = "_22"
311310

312-
val ??? = encode("???")
311+
val ??? : N = "???"
313312

314313
val genericWrapArray: N = "genericWrapArray"
315314
def wrapRefArray: N = "wrapRefArray"
@@ -592,36 +591,36 @@ object StdNames {
592591
def newLazyValSlowComputeName(lzyValName: N) = lzyValName ++ LAZY_SLOW_SUFFIX
593592

594593
// ASCII names for operators
595-
val ADD = encode("+")
596-
val AND = encode("&")
597-
val ASR = encode(">>")
598-
val DIV = encode("/")
599-
val EQ = encode("==")
600-
val EQL = encode("=")
601-
val GE = encode(">=")
602-
val GT = encode(">")
603-
val HASHHASH = encode("##")
604-
val LE = encode("<=")
605-
val LSL = encode("<<")
606-
val LSR = encode(">>>")
607-
val LT = encode("<")
608-
val MINUS = encode("-")
609-
val MOD = encode("%")
610-
val MUL = encode("*")
611-
val NE = encode("!=")
612-
val OR = encode("|")
594+
val ADD : N = "+"
595+
val AND : N = "&"
596+
val ASR : N = ">>"
597+
val DIV : N = "/"
598+
val EQ : N = "=="
599+
val EQL : N = "="
600+
val GE : N = ">="
601+
val GT : N = ">"
602+
val HASHHASH : N = "##"
603+
val LE : N = "<="
604+
val LSL : N = "<<"
605+
val LSR : N = ">>>"
606+
val LT : N = "<"
607+
val MINUS : N = "-"
608+
val MOD : N = "%"
609+
val MUL : N = "*"
610+
val NE : N = "!="
611+
val OR : N = "|"
613612
val PLUS = ADD // technically redundant, but ADD looks funny with MINUS
614613
val SUB = MINUS // ... as does SUB with PLUS
615-
val XOR = encode("^")
616-
val ZAND = encode("&&")
617-
val ZOR = encode("||")
614+
val XOR : N = "^"
615+
val ZAND : N = "&&"
616+
val ZOR : N = "||"
618617

619618
// unary operators
620619
val UNARY_PREFIX: N = "unary_"
621-
val UNARY_~ = encode("unary_~")
622-
val UNARY_+ = encode("unary_+")
623-
val UNARY_- = encode("unary_-")
624-
val UNARY_! = encode("unary_!")
620+
val UNARY_~ : N = "unary_~"
621+
val UNARY_+ : N = "unary_+"
622+
val UNARY_- : N = "unary_-"
623+
val UNARY_! : N = "unary_!"
625624

626625
// Grouped here so Cleanup knows what tests to perform.
627626
val CommonOpNames = Set[Name](OR, XOR, AND, EQ, NE)
@@ -733,7 +732,7 @@ object StdNames {
733732
def syntheticTypeParamNames(num: Int): List[TypeName] =
734733
(0 until num).map(syntheticTypeParamName)(breakOut)
735734

736-
final val Conforms = encode("<:<")
735+
final val Conforms: TypeName = "<:<"
737736

738737
final val Uninstantiated: TypeName = "?$"
739738
}

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -370,11 +370,7 @@ object SymDenotations {
370370
/** The expanded name of this denotation. */
371371
final def expandedName(implicit ctx: Context) =
372372
if (name.is(ExpandedName) || isConstructor) name
373-
else {
374-
def legalize(name: Name): Name = // JVM method names may not contain `<' or `>' characters
375-
if (is(Method)) name.replace('<', '(').replace('>', ')') else name
376-
legalize(name.expandedName(initial.owner))
377-
}
373+
else name.expandedName(initial.owner)
378374
// need to use initial owner to disambiguate, as multiple private symbols with the same name
379375
// might have been moved from different origins into the same class
380376

compiler/src/dotty/tools/dotc/core/tasty/TastyUnpickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class TastyUnpickler(reader: TastyReader) {
4848
val result = tag match {
4949
case UTF8 =>
5050
goto(end)
51-
termName(bytes, start.index, length)
51+
termName(bytes, start.index, length).decode
5252
case QUALIFIED | FLATTENED | EXPANDED | EXPANDPREFIX =>
5353
qualifiedNameKindOfTag(tag)(readName(), readName().asSimpleName)
5454
case UNIQUE =>

compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
336336
def atEnd = readIndex == end
337337

338338
def readExtSymbol(): Symbol = {
339-
val name = readNameRef()
339+
val name = readNameRef().decode
340340
val owner = if (atEnd) loadingMirror.RootClass else readSymbolRef()
341341

342342
def adjust(denot: Denotation) = {
@@ -399,7 +399,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
399399
// println(owner.info.decls.toList.map(_.debugString).mkString("\n ")) // !!! DEBUG
400400
// }
401401
// (5) Create a stub symbol to defer hard failure a little longer.
402-
System.err.println(i"***** missing reference, looking for $name in $owner")
402+
System.err.println(i"***** missing reference, looking for ${name.debugString} in $owner")
403403
System.err.println(i"decls = ${owner.info.decls}")
404404
owner.info.decls.checkConsistent()
405405
if (slowSearch(name).exists)
@@ -449,6 +449,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
449449
name = name.asTermName.unmangle(SuperAccessorName)
450450
flags = flags &~ Scala2SuperAccessor
451451
}
452+
name = name.mapLast(_.decode)
452453

453454
def nameMatches(rootName: Name) = mangledName == rootName.mangled
454455
def isClassRoot = nameMatches(classRoot.name) && (owner == classRoot.owner) && !(flags is ModuleClass)

compiler/src/dotty/tools/dotc/parsing/Scanners.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import core.StdNames._, core.Comments._
77
import util.SourceFile
88
import java.lang.Character.isDigit
99
import util.Chars._
10+
import util.NameTransformer.avoidIllegalChars
1011
import Tokens._
1112
import scala.annotation.{ switch, tailrec }
1213
import scala.collection.mutable
@@ -629,6 +630,7 @@ object Scanners {
629630
if (ch == '`') {
630631
nextChar()
631632
finishNamed(BACKQUOTED_IDENT)
633+
name = avoidIllegalChars(name)
632634
if (name.length == 0)
633635
error("empty quoted identifier")
634636
else if (name == nme.WILDCARD)

compiler/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class SymbolicXMLBuilder(parser: Parser, preserveWS: Boolean)(implicit ctx: Cont
5454
val __Text: TermName = "Text"
5555
val _buf: TermName = "$buf"
5656
val _md: TermName = "$md"
57-
val _plus: TermName = "$amp$plus"
57+
val _plus: TermName = "&+"
5858
val _tmpscope: TermName = "$tmpscope"
5959
val _xml: TermName = "xml"
6060
}

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
6060
protected val PrintableFlags = (SourceModifierFlags | Label | Module | Local).toCommonFlags
6161

6262
override def nameString(name: Name): String =
63-
if (ctx.settings.debugNames.value) name.debugString else name.decode.toString
63+
if (ctx.settings.debugNames.value) name.debugString else name.toString
6464

6565
override protected def simpleNameString(sym: Symbol): String = {
6666
val name = if (ctx.property(XprintMode).isEmpty) sym.originalName else sym.name

compiler/src/dotty/tools/dotc/repl/CompilingInterpreter.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ class CompilingInterpreter(
742742
override def shouldShowResult(req: Request): Boolean =
743743
!statement.mods.is(Flags.AccessFlags) &&
744744
!(isGeneratedVarName(statement.name.toString) &&
745-
req.typeOf(statement.name.encode) == "Unit")
745+
req.typeOf(statement.name) == "Unit")
746746
}
747747

748748

@@ -812,7 +812,7 @@ class CompilingInterpreter(
812812
/** Print out lhs instead of the generated varName */
813813
override def resultExtractionCode(req: Request, code: PrintWriter): Unit = {
814814
code.print(" + \"" + lhs.show + ": " +
815-
string2code(req.typeOf(helperName.encode)) +
815+
string2code(req.typeOf(helperName)) +
816816
" = \" + " +
817817
string2code(req.fullPath(helperName))
818818
+ " + \"\\n\"")

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
259259
case Import(expr, selectors) =>
260260
val exprTpe = expr.tpe
261261
def checkIdent(ident: Ident): Unit = {
262-
val name = ident.name.asTermName.encode
262+
val name = ident.name.asTermName
263263
if (name != nme.WILDCARD && !exprTpe.member(name).exists && !exprTpe.member(name.toTypeName).exists)
264264
ctx.error(s"${ident.name} is not a member of ${expr.show}", ident.pos)
265265
}

compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
107107
// ParamForwaders as installed ParamForwarding.scala do use super calls to vals
108108
ctx.error(s"super may be not be used on ${sym.underlyingSymbol}", sel.pos)
109109
else if (isDisallowed(sym))
110-
ctx.error(s"super not allowed here: use this.${sel.name.decode} instead", sel.pos)
110+
ctx.error(s"super not allowed here: use this.${sel.name} instead", sel.pos)
111111
else if (sym is Deferred) {
112112
val member = sym.overridingSymbol(clazz)
113113
if (!mix.name.isEmpty ||

compiler/src/dotty/tools/dotc/transform/SyntheticMethods.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class SyntheticMethods(thisTransformer: DenotTransformer) {
8181
ref(defn.runtimeMethodRef("_" + sym.name.toString)).appliedToArgs(This(clazz) :: vrefss.head)
8282

8383
def ownName(vrefss: List[List[Tree]]): Tree =
84-
Literal(Constant(clazz.name.stripModuleClassSuffix.decode.toString))
84+
Literal(Constant(clazz.name.stripModuleClassSuffix.toString))
8585

8686
def syntheticRHS(implicit ctx: Context): List[List[Tree]] => Tree = synthetic.name match {
8787
case nme.hashCode_ if isDerivedValueClass(clazz) => vrefss => valueHashCodeBody

compiler/src/dotty/tools/dotc/transform/TreeChecker.scala

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import reporting.ThrowingReporter
2424
import ast.Trees._
2525
import ast.{tpd, untpd}
2626
import util.SourcePosition
27+
import util.Chars._
2728
import collection.mutable
2829
import ProtoTypes._
2930
import config.Printers
@@ -46,15 +47,12 @@ import scala.util.control.NonFatal
4647
class TreeChecker extends Phase with SymTransformer {
4748
import ast.tpd._
4849

49-
5050
private val seenClasses = collection.mutable.HashMap[String, Symbol]()
5151
private val seenModuleVals = collection.mutable.HashMap[String, Symbol]()
5252

53-
def isValidJVMName(name: Name) =
54-
!name.toString.exists(c => c == '.' || c == ';' || c =='[' || c == '/')
53+
def isValidJVMName(name: Name) = name.toString.forall(isValidJVMChar)
5554

56-
def isValidJVMMethodName(name: Name) =
57-
!name.toString.exists(c => c == '.' || c == ';' || c =='[' || c == '/' || c == '<' || c == '>')
55+
def isValidJVMMethodName(name: Name) = name.toString.forall(isValidJVMMethodChar)
5856

5957
def printError(str: String)(implicit ctx: Context) = {
6058
ctx.echo(Console.RED + "[error] " + Console.WHITE + str)
@@ -148,7 +146,7 @@ class TreeChecker extends Phase with SymTransformer {
148146
def withDefinedSym[T](tree: untpd.Tree)(op: => T)(implicit ctx: Context): T = tree match {
149147
case tree: DefTree =>
150148
val sym = tree.symbol
151-
assert(isValidJVMName(sym.name), s"${sym.fullName} name is invalid on jvm")
149+
assert(isValidJVMName(sym.name.encode), s"${sym.name.debugString} name is invalid on jvm")
152150
everDefinedSyms.get(sym) match {
153151
case Some(t) =>
154152
if (t ne tree)
@@ -405,7 +403,7 @@ class TreeChecker extends Phase with SymTransformer {
405403
withDefinedSyms(ddef.tparams) {
406404
withDefinedSymss(ddef.vparamss) {
407405
if (!sym.isClassConstructor && !(sym.name eq Names.STATIC_CONSTRUCTOR))
408-
assert(isValidJVMMethodName(sym.name), s"${sym.name.debugString} name is invalid on jvm")
406+
assert(isValidJVMMethodName(sym.name.encode), s"${sym.name.debugString} name is invalid on jvm")
409407

410408
ddef.vparamss.foreach(_.foreach { vparam =>
411409
assert(vparam.symbol.is(Param),

0 commit comments

Comments
 (0)