Skip to content

Commit 3a5897b

Browse files
committed
Isolate the state of local name generation in a class.
1 parent 3d9f348 commit 3a5897b

File tree

2 files changed

+41
-33
lines changed

2 files changed

+41
-33
lines changed

src/dotty/tools/backend/sjs/JSCodeGen.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,13 @@ class JSCodeGen()(implicit ctx: Context) {
5656
private val primitives = new JSPrimitives(ctx)
5757

5858
private val positionConversions = new JSPositions()
59-
import positionConversions._
59+
import positionConversions.{pos2irPos, implicitPos2irPos}
6060

6161
// Some state --------------------------------------------------------------
6262

6363
private val currentClassSym = new ScopedVar[Symbol]
6464
private val currentMethodSym = new ScopedVar[Symbol]
65+
private val localNames = new ScopedVar[LocalNameGenerator]
6566
/*
6667
private val thisLocalVarIdent = new ScopedVar[Option[js.Ident]](None)
6768
private val fakeTailJumpParamRepl = new ScopedVar[(Symbol, Symbol)]((NoSymbol, NoSymbol))
@@ -74,6 +75,9 @@ class JSCodeGen()(implicit ctx: Context) {
7475
private val paramAccessorLocals = new ScopedVar(Map.empty[Symbol, js.ParamDef])
7576
*/
7677

78+
/** Implicitly materializes the current local name generator. */
79+
private implicit def implicitLocalNames: LocalNameGenerator = localNames.get
80+
7781
private var isModuleInitialized: Boolean = false // see genApply for super calls
7882

7983
//val countsOfReturnsToMatchEnd = mutable.Map.empty[Symbol, Int]
@@ -605,7 +609,9 @@ class JSCodeGen()(implicit ctx: Context) {
605609
// Generate a method -------------------------------------------------------
606610

607611
private def genMethod(dd: DefDef): Option[js.MethodDef] = {
608-
withNewLocalNameScope {
612+
withScopedVars(
613+
localNames := new LocalNameGenerator
614+
) {
609615
genMethodWithCurrentLocalNameScope(dd)
610616
}
611617
}

src/dotty/tools/backend/sjs/JSEncoding.scala

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -54,42 +54,44 @@ object JSEncoding {
5454

5555
// Fresh local name generator ----------------------------------------------
5656

57-
private val usedLocalNames = new ScopedVar[mutable.Set[String]]
58-
private val localSymbolNames = new ScopedVar[mutable.Map[Symbol, String]]
59-
private val isReserved =
60-
Set("arguments", "eval", ScalaJSEnvironmentName)
61-
62-
def withNewLocalNameScope[A](body: => A): A =
63-
withScopedVars(
64-
usedLocalNames := mutable.Set.empty,
65-
localSymbolNames := mutable.Map.empty
66-
)(body)
67-
68-
private def freshName(base: String = "x"): String = {
69-
var suffix = 1
70-
var longName = base
71-
while (usedLocalNames(longName) || isReserved(longName)) {
72-
suffix += 1
73-
longName = base+"$"+suffix
74-
}
75-
usedLocalNames += longName
76-
mangleJSName(longName)
77-
}
57+
class LocalNameGenerator {
58+
import LocalNameGenerator._
59+
60+
private val usedLocalNames = mutable.Set.empty[String]
61+
private val localSymbolNames = mutable.Map.empty[Symbol, String]
62+
63+
def localSymbolName(sym: Symbol)(implicit ctx: Context): String =
64+
localSymbolNames.getOrElseUpdate(sym, freshName(sym.name.toString))
65+
66+
def freshLocalIdent()(implicit pos: ir.Position): js.Ident =
67+
js.Ident(freshName(), None)
7868

79-
def freshLocalIdent()(implicit pos: ir.Position): js.Ident =
80-
js.Ident(freshName(), None)
69+
def freshLocalIdent(base: String)(implicit pos: ir.Position): js.Ident =
70+
js.Ident(freshName(base), Some(base))
8171

82-
def freshLocalIdent(base: String)(implicit pos: ir.Position): js.Ident =
83-
js.Ident(freshName(base), Some(base))
72+
private def freshName(base: String = "x"): String = {
73+
var suffix = 1
74+
var longName = base
75+
while (usedLocalNames(longName) || isReserved(longName)) {
76+
suffix += 1
77+
longName = base+"$"+suffix
78+
}
79+
usedLocalNames += longName
80+
mangleJSName(longName)
81+
}
82+
}
8483

85-
private def localSymbolName(sym: Symbol)(implicit ctx: Context): String =
86-
localSymbolNames.getOrElseUpdate(sym, freshName(sym.name.toString))
84+
private object LocalNameGenerator {
85+
private val isReserved =
86+
Set("arguments", "eval", ScalaJSEnvironmentName)
87+
}
8788

8889
// Encoding methods ----------------------------------------------------------
8990

90-
def encodeLabelSym(sym: Symbol)(implicit ctx: Context, pos: ir.Position): js.Ident = {
91+
def encodeLabelSym(sym: Symbol)(
92+
implicit ctx: Context, pos: ir.Position, localNames: LocalNameGenerator): js.Ident = {
9193
require(sym.is(Flags.Label), "encodeLabelSym called with non-label symbol: " + sym)
92-
js.Ident(localSymbolName(sym), Some(sym.unexpandedName.decoded))
94+
js.Ident(localNames.localSymbolName(sym), Some(sym.unexpandedName.decoded))
9395
}
9496

9597
private def allRefClasses(implicit ctx: Context): Set[Symbol] = {
@@ -190,10 +192,10 @@ object JSEncoding {
190192
}
191193

192194
def encodeLocalSym(sym: Symbol)(
193-
implicit ctx: Context, pos: ir.Position): js.Ident = {
195+
implicit ctx: Context, pos: ir.Position, localNames: LocalNameGenerator): js.Ident = {
194196
require(!sym.owner.isClass && sym.isTerm && !sym.is(Flags.Method) && !sym.is(Flags.Module),
195197
"encodeLocalSym called with non-local symbol: " + sym)
196-
js.Ident(localSymbolName(sym), Some(sym.unexpandedName.decoded))
198+
js.Ident(localNames.localSymbolName(sym), Some(sym.unexpandedName.decoded))
197199
}
198200

199201
def foreignIsImplClass(sym: Symbol)(implicit ctx: Context): Boolean =

0 commit comments

Comments
 (0)