8000 Squash: Another arrangement, where PrimTypeWithRef creates its PrimRef. · scala-js/scala-js@2b49a67 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2b49a67

Browse files
committed
Squash: Another arrangement, where PrimTypeWithRef creates its PrimRef.
1 parent ae7235a commit 2b49a67

File tree

2 files changed

+51
-58
lines changed

2 files changed

+51
-58
lines changed

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

Lines changed: 44 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212

1313
package org.scalajs.ir
1414

15-
import scala.annotation.switch
16-
1715
import Names._
1816
import Trees._
1917

@@ -62,25 +60,14 @@ object Types {
6260
}
6361
}
6462

65-
sealed abstract class PrimTypeWithRef(private[Types] val charCode: Char) extends PrimType {
66-
/* The `charCode` arguably belongs to the corresponding `PrimRef` more than
67-
* to this class. We define it this way so that we don't have an apparent
68-
* circular dependency between the `PrimTypeWithRef`s and their `PrimRef`s.
69-
*/
70-
71-
def primRef: PrimRef = (charCode: @switch) match {
72-
case 'V' => VoidRef
73-
case 'Z' => BooleanRef
74-
case 'C' => CharRef
75-
case 'B' => ByteRef
76-
case 'S' => ShortRef
77-
case 'I' => IntRef
78-
case 'J' => LongRef
79-
case 'F' => FloatRef
80-
case 'D' => DoubleRef
81-
case 'N' => NullRef
82-
case 'E' => NothingRef
83-
}
63+
/* Each PrimTypeWithRef creates its corresponding `PrimRef`. Therefore, it
64+
* takes the parameters that need to be passed to the `PrimRef` constructor.
65+
* This little dance ensures proper initialization safety between
66+
* `PrimTypeWithRef`s and `PrimRef`s.
67+
*/
68+
sealed abstract class PrimTypeWithRef(primRefCharCode: Char, primRefDisplayName: String)
69+
extends PrimType {
70+
val primRef: PrimRef = new PrimRef(this)(primRefCharCode, primRefDisplayName)
8471
}
8572

8673
/** Any type.
@@ -111,50 +98,50 @@ object Types {
11198
* Expressions from which one can never come back are typed as `Nothing`.
11299
* For example, `throw` and `return`.
113100
*/
114-
case object NothingType extends PrimTypeWithRef('E')
101+
case object NothingType extends PrimTypeWithRef('E', "nothing")
115102

116103
/** The type of `undefined`. */
117104
case object UndefType extends PrimType
118105

119106
/** Boolean type.
120107
* It does not accept `null` nor `undefined`.
121108
*/
122-
case object BooleanType extends PrimTypeWithRef('Z')
109+
case object BooleanType extends PrimTypeWithRef('Z', "boolean")
123110

124111
/** `Char` type, a 16-bit UTF-16 code unit.
125112
* It does not accept `null` nor `undefined`.
126113
*/
127-
case object CharType extends PrimTypeWithRef('C')
114+
case object CharType extends PrimTypeWithRef('C', "char")
128115

129116
/** 8-bit signed integer type.
130117
* It does not accept `null` nor `undefined`.
131118
*/
132-
case object ByteType extends PrimTypeWithRef('B')
119+
case object ByteType extends PrimTypeWithRef('B', "byte")
133120

134121
/** 16-bit signed integer type.
135122
* It does not accept `null` nor `undefined`.
136123
*/
137-
case object ShortType extends PrimTypeWithRef('S')
124+
case object ShortType extends PrimTypeWithRef('S', "short")
138125

139126
/** 32-bit signed integer type.
140127
* It does not accept `null` nor `undefined`.
141128
*/
142-
case object IntType extends PrimTypeWithRef('I')
129+
case object IntType extends PrimTypeWithRef('I', "int")
143130

144131
/** 64-bit signed integer type.
145132
* It does not accept `null` nor `undefined`.
146133
*/
147-
case object LongType extends PrimTypeWithRef('J')
134+
case object LongType extends PrimTypeWithRef('J', "long")
148135

149136
/** Float type (32-bit).
150137
* It does not accept `null` nor `undefined`.
151138
*/
152-
case object FloatType extends PrimTypeWithRef('F')
139+
case object FloatType extends PrimTypeWithRef('F', "float")
153140

154141
/** Double type (64-bit).
155142
* It does not accept `null` nor `undefined`.
156143
*/
157-
case object DoubleType extends PrimTypeWithRef('D')
144+
case object DoubleType extends PrimTypeWithRef('D', "double")
158145

159146
/** String type.
160147
* It does not accept `null` nor `undefined`.
@@ -165,7 +152,7 @@ object Types {
165152
* It does not accept `undefined`.
166153
* The null type is a subtype of all class types and array types.
167154
*/
168-
case object NullType extends PrimTypeWithRef('N')
155+
case object NullType extends PrimTypeWithRef('N', "null")
169156

170157
/** Class (or interface) type. */
171158
final case class ClassType(className: ClassName, nullable: Boolean) extends Type {
@@ -215,7 +202,7 @@ object Types {
215202
}
216203

217204
/** Void type, the top of type of our type system. */
218-
case object VoidType extends PrimTypeWithRef('V')
205+
case object VoidType extends PrimTypeWithRef('V', "void")
219206

220207
@deprecated("Use VoidType instead", since = "1.18.0")
221208
lazy val NoType: VoidType.type = VoidType
@@ -271,7 +258,8 @@ object Types {
271258
sealed abstract class NonArrayTypeRef extends TypeRef
272259

273260
/** Primitive type reference. */
274-
final case class PrimRef private[ir] (tpe: PrimTypeWithRef)
261+
final case class PrimRef private[Types] (tpe: PrimTypeWithRef)(
262+
charCodeInit: Char, displayNameInit: String) // "Init" variants so we can have good Scaladoc on the val's
275263
extends NonArrayTypeRef {
276264

277265
/** The display name of this primitive type.
@@ -283,19 +271,7 @@ object Types {
283271
* For `NullType` and `NothingType`, the names are `"null"` and
284272
* `"nothing"`, respectively.
285273
*/
286-
val displayName: String = (tpe.charCode: @switch) match {
287-
case 'V' => "void"
288-
case 'Z' => "boolean"
289-
case 'C' => "char"
290-
case 'B' => "byte"
291-
case 'S' => "short"
292-
case 'I' => "int"
293-
case 'J' => "long"
294-
case 'F' => "float"
295-
case 'D' => "double"
296-
case 'N' => "null"
297-
case 'E' => "nothing"
298-
}
274+
val displayName: String = displayNameInit
299275

300276
/** The char code of this primitive type.
301277
*
@@ -307,20 +283,30 @@ object Types {
307283
* For `NullType` and `NothingType`, the char codes are `'N'` and `'E'`,
308284
* respectively.
309285
*/
310-
val charCode: Char = tpe.charCode
286+
val charCode: Char = charCodeInit
287+
288+
// Make sure the `case class` does not produce a public copy method
289+
private def copy(tpe: PrimTypeWithRef)(charCodeInit: Char, displayNameInit: String): PrimRef =
290+
throw new Error("dead code")
291+
}
292+
293+
object PrimRef {
294+
// Make sure the `case class` does not produce a public apply method
295+
private def apply(tpe: PrimTypeWithRef)(charCodeInit: Char, displayNameInit: String): PrimRef =
296+
throw new Error("dead code")
311297
}
312298

313-
final val VoidRef = PrimRef(VoidType)
314-
final val BooleanRef = PrimRef(BooleanType)
315-
final val CharRef = PrimRef(CharType)
316-
final val ByteRef = PrimRef(ByteType)
317-
final val ShortRef = PrimRef(ShortType)
318-
final val IntRef = PrimRef(IntType)
319-
final val LongRef = PrimRef(LongType)
320-
final val FloatRef = PrimRef(FloatType)
321-
final val DoubleRef = PrimRef(DoubleType)
322-
final val NullRef = PrimRef(NullType)
323-
final val NothingRef = PrimRef(NothingType)
299+
final val VoidRef = VoidType.primRef
300+
final val BooleanRef = BooleanType.primRef
301+
final val CharRef = CharType.primRef
302+
final val ByteRef = ByteType.primRef
303+
final val ShortRef = ShortType.primRef
304+
final val IntRef = IntType.primRef
305+
final val LongRef = LongType.primRef
306+
final val FloatRef = FloatType.primRef
307+
final val DoubleRef = DoubleType.primRef
308+
final val NullRef = NullType.primRef
309+
final val NothingRef = NothingType.primRef
324310

325311
/** Class (or interface) type. */
326312
final case class ClassRef(className: ClassName) extends NonArrayTypeRef {

project/BinaryIncompatibilities.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ object BinaryIncompatibilities {
1616
ProblemFilters.exclude[DirectMissingMethodProblem]("org.scalajs.ir.Types.BoxedClassToPrimType"),
1717
ProblemFilters.exclude[DirectMissingMethodProblem]("org.scalajs.ir.Types.PrimTypeToBoxedClass"),
1818

19+
// !!! Breaking I guess ... we used to leak public things out of a `case class` with a private[ir] constructor
20+
ProblemFilters.exclude[DirectMissingMethodProblem]("org.scalajs.ir.Types#PrimRef.this"),
21+
ProblemFilters.exclude[DirectMissingMethodProblem]("org.scalajs.ir.Types#PrimRef.apply"),
22+
ProblemFilters.exclude[DirectMissingMethodProblem]("org.scalajs.ir.Types#PrimRef.copy"),
23+
ProblemFilters.exclude[DirectMissingMethodProblem]("org.scalajs.ir.Types#PrimRef.copy$default$1"),
24+
ProblemFilters.exclude[MissingTypesProblem]("org.scalajs.ir.Types$PrimRef$"),
25+
1926
// constructor of a sealed abstract class, not an issue
2027
ProblemFilters.exclude[DirectMissingMethodProblem]("org.scalajs.ir.Types#PrimTypeWithRef.this"),
2128

0 commit comments

Comments
 (0)
0