Skip to content

Commit 82910a0

Browse files
committed
Fix #5135: Move well-known names to a new object WellKnownNames.
This breaks the circular dependency between the initialization of `object Types` and `object Names`.
1 parent cf05126 commit 82910a0

File tree

59 files changed

+281
-177
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+281
-177
lines changed

compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala

+28-22
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,22 @@ import scala.annotation.tailrec
2626
import scala.reflect.internal.Flags
2727

2828
import org.scalajs.ir
29-
import org.scalajs.ir.{Trees => js, Types => jstpe, ClassKind, Hashers, OriginalName}
29+
import org.scalajs.ir.{
30+
Trees => js,
31+
Types => jstpe,
32+
WellKnownNames => jswkn,
33+
ClassKind,
34+
Hashers,
35+
OriginalName
36+
}
3037
import org.scalajs.ir.Names.{
3138
LocalName,
3239
LabelName,
3340
SimpleFieldName,
3441
FieldName,
3542
SimpleMethodName,
3643
MethodName,
37-
ClassName,
38-
BoxedStringClass
44+
ClassName
3945
}
4046
import org.scalajs.ir.OriginalName.NoOriginalName
4147
import org.scalajs.ir.Trees.OptimizerHints
@@ -168,7 +174,7 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
168174
def currentThisType: jstpe.Type = {
169175
currentThisTypeNullable match {
170176
case tpe @ jstpe.ClassType(cls, _) =>
171-
jstpe.BoxedClassToPrimType.getOrElse(cls, tpe.toNonNullable)
177+
jswkn.BoxedClassToPrimType.getOrElse(cls, tpe.toNonNullable)
172178
case tpe @ jstpe.AnyType =>
173179
// We are in a JS class, in which even `this` is nullable
174180
tpe
@@ -692,7 +698,7 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
692698
reflectInit.toList ::: staticModuleInit.toList
693699
if (staticInitializerStats.nonEmpty) {
694700
List(genStaticConstructorWithStats(
695-
ir.Names.StaticInitializerName,
701+
jswkn.StaticInitializerName,
696702
js.Block(staticInitializerStats)))
697703
} else {
698704
Nil
@@ -723,7 +729,7 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
723729
originalName,
724730
ClassKind.Class,
725731
None,
726-
Some(js.ClassIdent(ir.Names.ObjectClass)),
732+
Some(js.ClassIdent(jswkn.ObjectClass)),
727733
Nil,
728734
None,
729735
None,
@@ -838,7 +844,7 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
838844

839845
if (staticFields.nonEmpty) {
840846
generatedMethods += genStaticConstructorWithStats(
841-
ir.Names.ClassInitializerName, genLoadModule(companionModuleClass))
847+
jswkn.ClassInitializerName, genLoadModule(companionModuleClass))
842848
}
843849

844850
(staticFields, staticExports)
@@ -943,7 +949,7 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
943949
// Make new class def with static members
944950
val newClassDef = {
945951
implicit val pos = origJsClass.pos
946-
val parent = js.ClassIdent(ir.Names.ObjectClass)
952+
val parent = js.ClassIdent(jswkn.ObjectClass)
947953
js.ClassDef(origJsClass.name, origJsClass.originalName,
948954
ClassKind.AbstractJSType, None, Some(parent), interfaces = Nil,
949955
jsSuperClass = None, jsNativeLoadSpec = None, fields = Nil,
@@ -5438,8 +5444,8 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
54385444
// LinkingInfo.linkTimePropertyXXX("...")
54395445
val arg = genArgs1
54405446
val tpe: jstpe.Type = toIRType(tree.tpe) match {
5441-
case jstpe.ClassType(BoxedStringClass, _) => jstpe.StringType
5442-
case irType => irType
5447+
case jstpe.ClassType(jswkn.BoxedStringClass, _) => jstpe.StringType
5448+
case irType => irType
54435449
}
54445450
arg match {
54455451
case js.StringLiteral(name) =>
@@ -6431,8 +6437,8 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
64316437
fParamDef.ref),
64326438
js.ApplyStatically(js.ApplyFlags.empty.withConstructor(true),
64336439
js.This()(thisType),
6434-
ir.Names.ObjectClass,
6435-
js.MethodIdent(ir.Names.NoArgConstructorName),
6440+
jswkn.ObjectClass,
6441+
js.MethodIdent(jswkn.NoArgConstructorName),
64366442
Nil)(jstpe.VoidType)))))(
64376443
js.OptimizerHints.empty, Unversioned)
64386444
}
@@ -6491,7 +6497,7 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
64916497
NoOriginalName,
64926498
ClassKind.Class,
64936499
None,
6494-
Some(js.ClassIdent(ir.Names.ObjectClass)),
6500+
Some(js.ClassIdent(jswkn.ObjectClass)),
64956501
List(js.ClassIdent(intfName)),
64966502
None,
64976503
None,
@@ -7133,37 +7139,37 @@ private object GenJSCode {
71337139
private val newSimpleMethodName = SimpleMethodName("new")
71347140

71357141
private val ObjectArgConstructorName =
7136-
MethodName.constructor(List(jstpe.ClassRef(ir.Names.ObjectClass)))
7142+
MethodName.constructor(List(jswkn.ObjectRef))
71377143

71387144
private val lengthMethodName =
71397145
MethodName("length", Nil, jstpe.IntRef)
71407146
private val charAtMethodName =
71417147
MethodName("charAt", List(jstpe.IntRef), jstpe.CharRef)
71427148

71437149
private val getNameMethodName =
7144-
MethodName("getName", Nil, jstpe.ClassRef(ir.Names.BoxedStringClass))
7150+
MethodName("getName", Nil, jstpe.ClassRef(jswkn.BoxedStringClass))
71457151
private val isPrimitiveMethodName =
71467152
MethodName("isPrimitive", Nil, jstpe.BooleanRef)
71477153
private val isInterfaceMethodName =
71487154
MethodName("isInterface", Nil, jstpe.BooleanRef)
71497155
private val isArrayMethodName =
71507156
MethodName("isArray", Nil, jstpe.BooleanRef)
71517157
private val getComponentTypeMethodName =
7152-
MethodName("getComponentType", Nil, jstpe.ClassRef(ir.Names.ClassClass))
7158+
MethodName("getComponentType", Nil, jstpe.ClassRef(jswkn.ClassClass))
71537159
private val getSuperclassMethodName =
7154-
MethodName("getSuperclass", Nil, jstpe.ClassRef(ir.Names.ClassClass))
7160+
MethodName("getSuperclass", Nil, jstpe.ClassRef(jswkn.ClassClass))
71557161

71567162
private val isInstanceMethodName =
7157-
MethodName("isInstance", List(jstpe.ClassRef(ir.Names.ObjectClass)), jstpe.BooleanRef)
7163+
MethodName("isInstance", List(jstpe.ClassRef(jswkn.ObjectClass)), jstpe.BooleanRef)
71587164
private val isAssignableFromMethodName =
7159-
MethodName("isAssignableFrom", List(jstpe.ClassRef(ir.Names.ClassClass)), jstpe.BooleanRef)
7165+
MethodName("isAssignableFrom", List(jstpe.ClassRef(jswkn.ClassClass)), jstpe.BooleanRef)
71607166
private val castMethodName =
7161-
MethodName("cast", List(jstpe.ClassRef(ir.Names.ObjectClass)), jstpe.ClassRef(ir.Names.ObjectClass))
7167+
MethodName("cast", List(jstpe.ClassRef(jswkn.ObjectClass)), jstpe.ClassRef(jswkn.ObjectClass))
71627168

71637169
private val arrayNewInstanceMethodName = {
71647170
MethodName("newInstance",
7165-
List(jstpe.ClassRef(ir.Names.ClassClass), jstpe.IntRef),
7166-
jstpe.ClassRef(ir.Names.ObjectClass))
7171+
List(jstpe.ClassRef(jswkn.ClassClass), jstpe.IntRef),
7172+
jstpe.ClassRef(jswkn.ObjectClass))
71677173
}
71687174

71697175
private val thisOriginalName = OriginalName("this")

compiler/src/main/scala/org/scalajs/nscplugin/GenJSExports.scala

+3-5
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import scala.reflect.{ClassTag, classTag}
2020
import scala.reflect.internal.Flags
2121

2222
import org.scalajs.ir
23-
import org.scalajs.ir.{Trees => js, Types => jstpe}
23+
import org.scalajs.ir.{Trees => js, Types => jstpe, WellKnownNames => jswkn}
2424
import org.scalajs.ir.Names.LocalName
2525
import org.scalajs.ir.OriginalName.NoOriginalName
2626
import org.scalajs.ir.Trees.OptimizerHints
@@ -970,8 +970,6 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
970970
InstanceOfTypeTest(tpe.valueClazz.typeConstructor)
971971

972972
case _ =>
973-
import org.scalajs.ir.Names
974-
975973
(toIRType(tpe): @unchecked) match {
976974
case jstpe.AnyType | jstpe.AnyNotNullType => NoTypeTest
977975

@@ -985,8 +983,8 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
985983
case jstpe.FloatType => PrimitiveTypeTest(jstpe.FloatType, 7)
986984
case jstpe.DoubleType => PrimitiveTypeTest(jstpe.DoubleType, 8)
987985

988-
case jstpe.ClassType(Names.BoxedUnitClass, _) => PrimitiveTypeTest(jstpe.UndefType, 0)
989-
case jstpe.ClassType(Names.BoxedStringClass, _) => PrimitiveTypeTest(jstpe.StringType, 9)
986+
case jstpe.ClassType(jswkn.BoxedUnitClass, _) => PrimitiveTypeTest(jstpe.UndefType, 0)
987+
case jstpe.ClassType(jswkn.BoxedStringClass, _) => PrimitiveTypeTest(jstpe.StringType, 9)
990988
case jstpe.ClassType(_, _) => InstanceOfTypeTest(tpe)
991989

992990
case jstpe.ArrayType(_, _) => InstanceOfTypeTest(tpe)

compiler/src/main/scala/org/scalajs/nscplugin/JSEncoding.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import scala.collection.mutable
1717
import scala.tools.nsc._
1818

1919
import org.scalajs.ir
20-
import org.scalajs.ir.{Trees => js, Types => jstpe}
20+
import org.scalajs.ir.{Trees => js, Types => jstpe, WellKnownNames => jswkn}
2121
import org.scalajs.ir.Names.{LocalName, LabelName, SimpleFieldName, FieldName, SimpleMethodName, MethodName, ClassName}
2222
import org.scalajs.ir.OriginalName
2323
import org.scalajs.ir.OriginalName.NoOriginalName
@@ -237,7 +237,7 @@ trait JSEncoding[G <: Global with Singleton] extends SubComponent {
237237
def encodeDynamicImportForwarderIdent(params: List[Symbol])(
238238
implicit pos: Position): js.MethodIdent = {
239239
val paramTypeRefs = params.map(sym => paramOrResultTypeRef(sym.tpe))
240-
val resultTypeRef = jstpe.ClassRef(ir.Names.ObjectClass)
240+
val resultTypeRef = jstpe.ClassRef(jswkn.ObjectClass)
241241
val methodName =
242242
MethodName(dynamicImportForwarderSimpleName, paramTypeRefs, resultTypeRef)
243243

@@ -288,13 +288,13 @@ trait JSEncoding[G <: Global with Singleton] extends SubComponent {
288288
assert(!sym.isPrimitiveValueClass,
289289
s"Illegal encodeClassName(${sym.fullName}")
290290
if (sym == jsDefinitions.HackedStringClass) {
291-
ir.Names.BoxedStringClass
291+
jswkn.BoxedStringClass
292292
} else if (sym == jsDefinitions.HackedStringModClass) {
293293
BoxedStringModuleClassName
294294
} else if (sym == definitions.BoxedUnitClass || sym == jsDefinitions.BoxedUnitModClass) {
295295
// Rewire scala.runtime.BoxedUnit to java.lang.Void, as the IR expects
296296
// BoxedUnit$ is a JVM artifact
297-
ir.Names.BoxedUnitClass
297+
jswkn.BoxedUnitClass
298298
} else {
299299
ClassName(sym.fullName + (if (needsModuleClassSuffix(sym)) "$" else ""))
300300
}

compiler/src/main/scala/org/scalajs/nscplugin/PrepJSExports.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import scala.collection.mutable
1616

1717
import scala.tools.nsc.Global
1818

19-
import org.scalajs.ir.Names.DefaultModuleID
2019
import org.scalajs.ir.Trees.TopLevelExportDef.isValidTopLevelExportName
20+
import org.scalajs.ir.WellKnownNames.DefaultModuleID
2121

2222
/**
2323
* Prepare export generation

ir/shared/src/main/scala/org/scalajs/ir/Names.scala

+16-123
Original file line numberDiff line numberDiff line change
@@ -471,21 +471,25 @@ object Names {
471471
}
472472

473473
object MethodName {
474-
private val ReflectiveProxyResultTypeRef = ClassRef(ObjectClass)
475-
private final val ReflectiveProxyResultTypeName = "java.lang.Object"
476-
477474
def apply(simpleName: SimpleMethodName, paramTypeRefs: List[TypeRef],
478475
resultTypeRef: TypeRef, isReflectiveProxy: Boolean): MethodName = {
479476
if ((simpleName.isConstructor || simpleName.isStaticInitializer ||
480477
simpleName.isClassInitializer) && resultTypeRef != VoidRef) {
481478
throw new IllegalArgumentException(
482479
"A constructor or static initializer must have a void result type")
483480
}
484-
if (isReflectiveProxy && resultTypeRef != ReflectiveProxyResultTypeRef) {
485-
throw new IllegalArgumentException(
486-
"A reflective proxy must have a result type of " +
487-
ReflectiveProxyResultTypeName)
481+
482+
if (isReflectiveProxy) {
483+
/* It is fine to use WellKnownNames here because nothing in `Names`
484+
* nor `Types` ever creates a reflective proxy name. So this code path
485+
* is not reached during their initialization.
486+
*/
487+
if (resultTypeRef != WellKnownNames.ObjectRef) {
488+
throw new IllegalArgumentException(
489+
"A reflective proxy must have a result type of java.lang.Object")
490+
}
488491
}
492+
489493
new MethodName(simpleName, paramTypeRefs, resultTypeRef,
490494
isReflectiveProxy)
491495
}
@@ -509,7 +513,11 @@ object Names {
509513

510514
def reflectiveProxy(simpleName: SimpleMethodName,
511515
paramTypeRefs: List[TypeRef]): MethodName = {
512-
apply(simpleName, paramTypeRefs, ReflectiveProxyResultTypeRef,
516+
/* It is fine to use WellKnownNames here because nothing in `Names`
517+
* nor `Types` ever creates a reflective proxy name. So this code path
518+
* is not reached during their initialization.
519+
*/
520+
apply(simpleName, paramTypeRefs, WellKnownNames.ObjectRef,
513521
isReflectiveProxy = true)
514522
}
515523

@@ -553,121 +561,6 @@ object Names {
553561

554562
// scalastyle:on equals.hash.code
555563

556-
/** `java.lang.Object`, the root of the class hierarchy. */
557-
val ObjectClass: ClassName = ClassName("java.lang.Object")
558-
559-
// Hijacked classes
560-
val BoxedUnitClass: ClassName = ClassName("java.lang.Void")
561-
val BoxedBooleanClass: ClassName = ClassName("java.lang.Boolean")
562-
val BoxedCharacterClass: ClassName = ClassName("java.lang.Character")
563-
val BoxedByteClass: ClassName = ClassName("java.lang.Byte")
564-
val BoxedShortClass: ClassName = ClassName("java.lang.Short")
565-
val BoxedIntegerClass: ClassName = ClassName("java.lang.Integer")
566-
val BoxedLongClass: ClassName = ClassName("java.lang.Long")
567-
val BoxedFloatClass: ClassName = ClassName("java.lang.Float")
568-
val BoxedDoubleClass: ClassName = ClassName("java.lang.Double")
569-
val BoxedStringClass: ClassName = ClassName("java.lang.String")
570-
571-
/** The set of all hijacked classes. */
572-
val HijackedClasses: Set[ClassName] = Set(
573-
BoxedUnitClass,
574-
BoxedBooleanClass,
575-
BoxedCharacterClass,
576-
BoxedByteClass,
577-
BoxedShortClass,
578-
BoxedIntegerClass,
579-
BoxedLongClass,
580-
BoxedFloatClass,
581-
BoxedDoubleClass,
582-
BoxedStringClass
583-
)
584-
585-
/** The class of things returned by `ClassOf` and `GetClass`. */
586-
val ClassClass: ClassName = ClassName("java.lang.Class")
587-
588-
/** `java.lang.Cloneable`, which is an ancestor of array classes and is used
589-
* by `Clone`.
590-
*/
591-
val CloneableClass: ClassName = ClassName("java.lang.Cloneable")
592-
593-
/** `java.io.Serializable`, which is an ancestor of array classes. */
594-
val SerializableClass: ClassName = ClassName("java.io.Serializable")
595-
596-
/** The superclass of all throwables.
597-
*
598-
* This is the result type of `WrapAsThrowable` nodes, as well as the input
599-
* type of `UnwrapFromThrowable`.
600-
*/
601-
val ThrowableClass = ClassName("java.lang.Throwable")
602-
603-
/** The exception thrown by a division by 0. */
604-
val ArithmeticExceptionClass: ClassName =
605-
ClassName("java.lang.ArithmeticException")
606-
607-
/** The exception thrown by an `ArraySelect` that is out of bounds. */
608-
val ArrayIndexOutOfBoundsExceptionClass: ClassName =
609-
ClassName("java.lang.ArrayIndexOutOfBoundsException")
610-
611-
/** The exception thrown by an `Assign(ArraySelect, ...)` where the value cannot be stored. */
612-
val ArrayStoreExceptionClass: ClassName =
613-
ClassName("java.lang.ArrayStoreException")
614-
615-
/** The exception thrown by a `NewArray(...)` with a negative size. */
616-
val NegativeArraySizeExceptionClass: ClassName =
617-
ClassName("java.lang.NegativeArraySizeException")
618-
619-
/** The exception thrown by a variety of nodes for `null` arguments.
620-
*
621-
* - `Apply` and `ApplyStatically` for the receiver,
622-
* - `Select` for the qualifier,
623-
* - `ArrayLength` and `ArraySelect` for the array,
624-
* - `GetClass`, `Clone` and `UnwrapFromException` for their respective only arguments.
625-
*/
626-
val NullPointerExceptionClass: ClassName =
627-
ClassName("java.lang.NullPointerException")
628-
629-
/** The exception thrown by a `BinaryOp.String_charAt` that is out of bounds. */
630-
val StringIndexOutOfBoundsExceptionClass: ClassName =
631-
ClassName("java.lang.StringIndexOutOfBoundsException")
632-
633-
/** The exception thrown by an `AsInstanceOf` that fails. */
634-
val ClassCastExceptionClass: ClassName =
635-
ClassName("java.lang.ClassCastException")
636-
637-
/** The exception thrown by a `Class_newArray` if the first argument is `classOf[Unit]`. */
638-
val IllegalArgumentExceptionClass: ClassName =
639-
ClassName("java.lang.IllegalArgumentException")
640-
641-
/** The set of classes and interfaces that are ancestors of array classes. */
642-
private[ir] val AncestorsOfPseudoArrayClass: Set[ClassName] = {
643-
/* This would logically be defined in Types, but that introduces a cyclic
644-
* dependency between the initialization of Names and Types.
645-
*/
646-
Set(ObjectClass, CloneableClass, SerializableClass)
647-
}
648-
649-
/** Name of a constructor without argument.
650-
*
651-
* This is notably the signature of constructors of module classes.
652-
*/
653-
final val NoArgConstructorName: MethodName =
654-
MethodName.constructor(Nil)
655-
656-
/** This is used to construct a java.lang.Class. */
657-
final val ObjectArgConstructorName: MethodName =
658-
MethodName.constructor(List(ClassRef(ObjectClass)))
659-
660-
/** Name of the static initializer method. */
661-
final val StaticInitializerName: MethodName =
662-
MethodName(SimpleMethodName.StaticInitializer, Nil, VoidRef)
663-
664-
/** Name of the class initializer method. */
665-
final val ClassInitializerName: MethodName =
666-
MethodName(SimpleMethodName.ClassInitializer, Nil, VoidRef)
667-
668-
/** ModuleID of the default module */
669-
final val DefaultModuleID: String = "main"
670-
671564
// ---------------------------------------------------
672565
// ----- Private helpers for validation of names -----
673566
// ---------------------------------------------------

ir/shared/src/main/scala/org/scalajs/ir/Serializers.scala

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import LinkTimeProperty.{ProductionMode, ESVersion, UseECMAScript2015Semantics,
2929
import Types._
3030
import Tags._
3131
import Version.Unversioned
32+
import WellKnownNames._
3233

3334
import Utils.JumpBackByteArrayOutputStream
3435

0 commit comments

Comments
 (0)