@@ -9,7 +9,7 @@ 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
14
15
15
import scala .annotation .tailrec
@@ -252,6 +252,7 @@ class Definitions {
252
252
* or classes with the same name. But their binary artifacts are
253
253
* in `scalaShadowing` so they don't clash with the same-named `scala`
254
254
* members at runtime.
255
+ * It is used only for non-bootstrapped code
255
256
*/
256
257
@ tu lazy val ScalaShadowingPackage : TermSymbol = requiredPackage(nme.scalaShadowing)
257
258
@@ -481,12 +482,12 @@ class Definitions {
481
482
newPermanentSymbol(ScalaPackageClass , tpnme.IMPLICITkw , EmptyFlags , TypeBounds .empty).entered
482
483
def ImplicitScrutineeTypeRef : TypeRef = ImplicitScrutineeTypeSym .typeRef
483
484
484
-
485
485
@ tu lazy val ScalaPredefModule : Symbol = requiredModule(" scala.Predef" )
486
486
@ tu lazy val Predef_conforms : Symbol = ScalaPredefModule .requiredMethod(nme.conforms_)
487
487
@ tu lazy val Predef_classOf : Symbol = ScalaPredefModule .requiredMethod(nme.classOf )
488
488
@ tu lazy val Predef_identity : Symbol = ScalaPredefModule .requiredMethod(nme.identity)
489
489
@ tu lazy val Predef_undefined : Symbol = ScalaPredefModule .requiredMethod(nme.??? )
490
+ @ tu lazy val ScalaPredefModuleClass : ClassSymbol = ScalaPredefModule .moduleClass.asClass
490
491
491
492
@ tu lazy val SubTypeClass : ClassSymbol = requiredClass(" scala.<:<" )
492
493
@ tu lazy val SubType_refl : Symbol = SubTypeClass .companionModule.requiredMethod(nme.refl)
@@ -510,7 +511,7 @@ class Definitions {
510
511
// will return "null" when called recursively, see #1856.
511
512
def DottyPredefModule : Symbol = {
512
513
if (myDottyPredefModule == null ) {
513
- myDottyPredefModule = requiredModule (" dotty.DottyPredef" )
514
+ myDottyPredefModule = getModuleIfDefined (" dotty.DottyPredef" )
514
515
assert(myDottyPredefModule != null )
515
516
}
516
517
myDottyPredefModule
@@ -782,6 +783,7 @@ class Definitions {
782
783
@ tu lazy val Mirror_SingletonProxyClass : ClassSymbol = requiredClass(" scala.deriving.Mirror.SingletonProxy" )
783
784
784
785
@ tu lazy val LanguageModule : Symbol = requiredModule(" scala.language" )
786
+ @ tu lazy val LanguageModuleClass : Symbol = LanguageModule .moduleClass.asClass
785
787
@ tu lazy val LanguageExperimentalModule : Symbol = requiredModule(" scala.language.experimental" )
786
788
@ tu lazy val NonLocalReturnControlClass : ClassSymbol = requiredClass(" scala.runtime.NonLocalReturnControl" )
787
789
@ tu lazy val SelectableClass : ClassSymbol = requiredClass(" scala.Selectable" )
@@ -1101,6 +1103,65 @@ class Definitions {
1101
1103
|| sym.owner == CompiletimeOpsPackageObjectString .moduleClass && compiletimePackageStringTypes.contains(sym.name)
1102
1104
)
1103
1105
1106
+ // ----- Scala-2 library patches --------------------------------------
1107
+
1108
+ /** The `scala.runtime.stdLibPacthes` package contains objects
1109
+ * that contain defnitions that get added as members to standard library
1110
+ * objects with the same name.
1111
+ */
1112
+ @ tu lazy val StdLibPatchesPackage : TermSymbol = requiredPackage(" scala.runtime.stdLibPatches" )
1113
+ @ tu private lazy val ScalaPredefModuleClassPatch : Symbol = getModuleIfDefined(" scala.runtime.stdLibPatches.Predef" ).moduleClass
1114
+ @ tu private lazy val LanguageModuleClassPatch : Symbol = getModuleIfDefined(" scala.runtime.stdLibPatches.language" ).moduleClass
1115
+
1116
+ /** If `sym` is a patched library class, the source file of its patch class,
1117
+ * otherwise `NoSource`
1118
+ */
1119
+ def patchSource (sym : Symbol )(using Context ): SourceFile =
1120
+ if sym == ScalaPredefModuleClass then ScalaPredefModuleClassPatch .source
1121
+ else if sym == LanguageModuleClass then LanguageModuleClassPatch .source
1122
+ else NoSource
1123
+
1124
+ /** A finalizer that patches standard library classes.
1125
+ * It copies all non-private, non-synthetic definitions from `patchCls`
1126
+ * to `denot` while changing their owners to `denot`. Before that it deletes
1127
+ * any definitions of `denot` that have the same name as one of the copied
1128
+ * definitions.
1129
+ *
1130
+ * If an object is present in both the original class and the patch class,
1131
+ * it is not overwritten. Instead its members are copied recursively.
1132
+ *
1133
+ * To avpid running into cycles on bootstrap, patching happens only if `patchCls`
1134
+ * is read from a classfile.
1135
+ */
1136
+ def patchStdLibClass (denot : ClassDenotation )(using Context ): Unit =
1137
+
1138
+ def patch2 (denot : ClassDenotation , patchCls : Symbol ): Unit =
1139
+ val scope = denot.info.decls.openForMutations
1140
+ def recurse (patch : Symbol ) = patch.is(Module ) && scope.lookup(patch.name).exists
1141
+ if patchCls.exists then
1142
+ val patches = patchCls.info.decls.filter(patch =>
1143
+ ! patch.isConstructor && ! patch.isOneOf(PrivateOrSynthetic ))
1144
+ for patch <- patches if ! recurse(patch) do
1145
+ val e = scope.lookupEntry(patch.name)
1146
+ if e != null then scope.unlink(e)
1147
+ for patch <- patches do
1148
+ patch.ensureCompleted()
1149
+ if ! recurse(patch) then
1150
+ patch.denot = patch.denot.copySymDenotation(owner = denot.symbol)
1151
+ scope.enter(patch)
1152
+ else if patch.isClass then
1153
+ patch2(scope.lookup(patch.name).asClass, patch)
1154
+
1155
+ def patchWith (patchCls : Symbol ) =
1156
+ denot.sourceModule.info = denot.typeRef // we run into a cyclic reference when patching if this line is omitted
1157
+ patch2(denot, patchCls)
1158
+
1159
+ if denot.name == tpnme.Predef .moduleClassName && denot.symbol == ScalaPredefModuleClass then
1160
+ patchWith(ScalaPredefModuleClassPatch )
1161
+ else if denot.name == tpnme.language.moduleClassName && denot.symbol == LanguageModuleClass then
1162
+ patchWith(LanguageModuleClassPatch )
1163
+ end patchStdLibClass
1164
+
1104
1165
// ----- Symbol sets ---------------------------------------------------
1105
1166
1106
1167
@ tu lazy val AbstractFunctionType : Array [TypeRef ] = mkArityArray(" scala.runtime.AbstractFunction" , MaxImplementedFunctionArity , 0 )
0 commit comments