Skip to content

Commit a9dca51

Browse files
committed
synchronizes symbols
Synchronization via decoration would be neat if it actually worked. Unfortunately, root symbols never got decorated, therefore their children also never got decorated and all the way down to the very turtles. This commit fixes this sad issue by turning root symbols from objects to lazy vals. Yes, this is going to induce a performance penalty, which will hopefully not be high enough to invalidate this cornerstone of our synchronization strategy. Now when root symbols are lazy vals, they can be overridden in the runtime reflexive universe and decorated with SynchronizedSymbol, which makes their children sync and sound.
1 parent 0262941 commit a9dca51

File tree

3 files changed

+35
-16
lines changed

3 files changed

+35
-16
lines changed

src/reflect/scala/reflect/internal/Mirrors.scala

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -262,34 +262,45 @@ trait Mirrors extends api.Mirrors {
262262
def mirror = thisMirror.asInstanceOf[Mirror]
263263
}
264264

265-
// This is the package _root_. The actual root cannot be referenced at
266-
// the source level, but _root_ is essentially a function => <root>.
267-
final object RootPackage extends ModuleSymbol(rootOwner, NoPosition, nme.ROOTPKG) with RootSymbol {
265+
class RootPackage extends ModuleSymbol(rootOwner, NoPosition, nme.ROOTPKG) with RootSymbol {
268266
this setInfo NullaryMethodType(RootClass.tpe)
269267
RootClass.sourceModule = this
270268

271269
override def isRootPackage = true
272270
}
271+
272+
// This is the package _root_. The actual root cannot be referenced at
273+
// the source level, but _root_ is essentially a function => <root>.
274+
lazy val RootPackage = new RootPackage
275+
276+
class RootClass extends PackageClassSymbol(rootOwner, NoPosition, tpnme.ROOT) with RootSymbol {
277+
this setInfo rootLoader
278+
279+
override def isRoot = true
280+
override def isEffectiveRoot = true
281+
override def isNestedClass = false
282+
}
283+
273284
// This is <root>, the actual root of everything except the package _root_.
274285
// <root> and _root_ (RootPackage and RootClass) should be the only "well known"
275286
// symbols owned by NoSymbol. All owner chains should go through RootClass,
276287
// although it is probable that some symbols are created as direct children
277288
// of NoSymbol to ensure they will not be stumbled upon. (We should designate
278289
// a better encapsulated place for that.)
279-
final object RootClass extends PackageClassSymbol(rootOwner, NoPosition, tpnme.ROOT) with RootSymbol {
280-
this setInfo rootLoader
290+
lazy val RootClass = new RootClass
281291

282-
override def isRoot = true
283-
override def isEffectiveRoot = true
284-
override def isNestedClass = false
285-
}
286-
// The empty package, which holds all top level types without given packages.
287-
final object EmptyPackage extends ModuleSymbol(RootClass, NoPosition, nme.EMPTY_PACKAGE_NAME) with WellKnownSymbol {
292+
class EmptyPackage extends ModuleSymbol(RootClass, NoPosition, nme.EMPTY_PACKAGE_NAME) with WellKnownSymbol {
288293
override def isEmptyPackage = true
289294
}
290-
final object EmptyPackageClass extends PackageClassSymbol(RootClass, NoPosition, tpnme.EMPTY_PACKAGE_NAME) with WellKnownSymbol {
295+
296+
// The empty package, which holds all top level types without given packages.
297+
lazy val EmptyPackage = new EmptyPackage
298+
299+
class EmptyPackageClass extends PackageClassSymbol(RootClass, NoPosition, tpnme.EMPTY_PACKAGE_NAME) with WellKnownSymbol {
291300
override def isEffectiveRoot = true
292301
override def isEmptyPackageClass = true
293302
}
303+
304+
lazy val EmptyPackageClass = new EmptyPackageClass
294305
}
295306
}

src/reflect/scala/reflect/runtime/JavaMirrors.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
7171

7272
import definitions._
7373

74+
override lazy val RootPackage = new RootPackage with SynchronizedTermSymbol
75+
override lazy val RootClass = new RootClass with SynchronizedModuleClassSymbol
76+
override lazy val EmptyPackage = new EmptyPackage with SynchronizedTermSymbol
77+
override lazy val EmptyPackageClass = new EmptyPackageClass with SynchronizedModuleClassSymbol
78+
7479
/** The lazy type for root.
7580
*/
7681
override lazy val rootLoader = new LazyType with FlagAgnosticCompleter {

src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,14 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb
9292
override protected def createModuleSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol =
9393
new ModuleSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags
9494

95-
override protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol = createModuleSymbol(name, pos, newFlags)
95+
override protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol =
96+
createModuleSymbol(name, pos, newFlags)
9697

97-
// TODO
98-
// override protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long)
99-
// override protected def createValueMemberSymbol(name: TermName, pos: Position, newFlags: Long)
98+
override protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long) =
99+
new TermSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags
100+
101+
override protected def createValueMemberSymbol(name: TermName, pos: Position, newFlags: Long) =
102+
new TermSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags
100103
}
101104

102105
// ------- subclasses ---------------------------------------------------------------------

0 commit comments

Comments
 (0)