@@ -9,8 +9,9 @@ import unpickleScala2.Scala2Unpickler.ensureConstructor
9
9
import scala .collection .mutable
10
10
import collection .mutable
11
11
import Denotations .SingleDenotation
12
- import util .SimpleIdentityMap
12
+ import util .{ SimpleIdentityMap , SourceFile , NoSource }
13
13
import typer .ImportInfo .RootRef
14
+ import typer .Namer
14
15
15
16
import scala .annotation .tailrec
16
17
@@ -186,13 +187,45 @@ class Definitions {
186
187
cls
187
188
}
188
189
190
+ /** Run given finalizer function when `cls` is completed. The finalizer
191
+ * gets the class and the current context as arguments.
192
+ */
189
193
extension (cls : ClassSymbol )
190
194
private def withFinalizer (f : ClassSymbol => Context ?=> Unit ): ClassSymbol =
191
195
cls.infoOrCompleter match
192
196
case completer : SymbolLoader =>
193
197
cls.info = completer.withFinalizer(d => f(d.asClass.classSymbol))
194
198
cls
195
199
200
+ /** A finalizer that patches standard library classes.
201
+ * It copies all non-private, non-synthetic definitions from `patchCls`
202
+ * to `cls` while changing their owners to `cls`. Before that it deletes
203
+ * any definitions of `cls` that have the same name as one of the copied
204
+ * definitions.
205
+ *
206
+ * To avpid running into cycles on bootstrap, patching happens only if `patchCls`
207
+ * is read from a classfile.
208
+ */
209
+ private def patchStdLibClass (cls : ClassSymbol , patchCls : Symbol )(using Context ): Unit =
210
+ val scope = cls.info.decls.openForMutations
211
+ if patchCls.exists && ! patchCls.infoOrCompleter.isInstanceOf [Namer # ClassCompleter ] then
212
+ val patches = patchCls.info.decls.filter(patch =>
213
+ ! patch.isConstructor && ! patch.isOneOf(PrivateOrSynthetic ))
214
+ for patch <- patches do
215
+ val e = scope.lookupEntry(patch.name)
216
+ if e != null then scope.unlink(e)
217
+ for patch <- patches do
218
+ patch.ensureCompleted()
219
+ patch.denot = patch.denot.copySymDenotation(owner = cls)
220
+ scope.enter(patch)
221
+
222
+ /** If `sym` is a patched library class, the source file of its patch class,
223
+ * otherwise `NoSource`
224
+ */
225
+ def patchSource (sym : Symbol ): SourceFile =
226
+ if sym == ScalaPredefModuleClass then ScalaPredefModuleClassPatch .source
227
+ else NoSource
228
+
196
229
@ tu lazy val RootClass : ClassSymbol = newPackageSymbol(
197
230
NoSymbol , nme.ROOT , (root, rootcls) => ctx.base.rootLoader(root)).moduleClass.asClass
198
231
@ tu lazy val RootPackage : TermSymbol = newSymbol(
@@ -488,13 +521,18 @@ class Definitions {
488
521
newPermanentSymbol(ScalaPackageClass , tpnme.IMPLICITkw , EmptyFlags , TypeBounds .empty).entered
489
522
def ImplicitScrutineeTypeRef : TypeRef = ImplicitScrutineeTypeSym .typeRef
490
523
491
-
492
524
@ tu lazy val ScalaPredefModule : Symbol = requiredModule(" scala.Predef" )
493
525
@ tu lazy val Predef_conforms : Symbol = ScalaPredefModule .requiredMethod(nme.conforms_)
494
526
@ tu lazy val Predef_classOf : Symbol = ScalaPredefModule .requiredMethod(nme.classOf )
495
527
@ tu lazy val Predef_identity : Symbol = ScalaPredefModule .requiredMethod(nme.identity)
496
528
@ tu lazy val Predef_undefined : Symbol = ScalaPredefModule .requiredMethod(nme.??? )
497
529
530
+ @ tu lazy val ScalaPredefModuleClass : ClassSymbol = ScalaPredefModule .moduleClass.asClass
531
+ .withFinalizer(patchStdLibClass(_, ScalaPredefModuleClassPatch ))
532
+
533
+ @ tu private lazy val ScalaPredefModuleClassPatch : Symbol =
534
+ getModuleIfDefined(" scala.runtime.stdLibPatches.Predef" ).moduleClass
535
+
498
536
@ tu lazy val SubTypeClass : ClassSymbol = requiredClass(" scala.<:<" )
499
537
@ tu lazy val SubType_refl : Symbol = SubTypeClass .companionModule.requiredMethod(nme.refl)
500
538
@@ -779,6 +817,7 @@ class Definitions {
779
817
@ tu lazy val Mirror_SingletonProxyClass : ClassSymbol = requiredClass(" scala.deriving.Mirror.SingletonProxy" )
780
818
781
819
@ tu lazy val LanguageModule : Symbol = requiredModule(" scala.language" )
820
+ @ tu lazy val LanguageModuleClass : Symbol = LanguageModule .moduleClass.asClass
782
821
@ tu lazy val LanguageExperimentalModule : Symbol = requiredModule(" scala.language.experimental" )
783
822
@ tu lazy val NonLocalReturnControlClass : ClassSymbol = requiredClass(" scala.runtime.NonLocalReturnControl" )
784
823
@ tu lazy val SelectableClass : ClassSymbol = requiredClass(" scala.Selectable" )
@@ -1650,7 +1689,11 @@ class Definitions {
1650
1689
ScalaPackageClass .enter(m)
1651
1690
1652
1691
// force initialization of every symbol that is synthesized or hijacked by the compiler
1653
- val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses () :+ JavaEnumClass
1692
+ val forced =
1693
+ syntheticCoreClasses
1694
+ ++ syntheticCoreMethods
1695
+ ++ ScalaValueClasses ()
1696
+ ++ List (JavaEnumClass , ScalaPredefModuleClass )
1654
1697
1655
1698
isInitialized = true
1656
1699
}
0 commit comments