Skip to content

Commit 2212dc0

Browse files
committed
use string names for runsAfter
Quote @sjrd: For inter-plugin dependencies, it will be impossible for a plugin A to get hold of the `Class[_]` value for a plugin B coming from a different jar (hence in a different `ClassLoader`, so not even reflectively available). #3438 (comment)
1 parent 2737820 commit 2212dc0

Some content is hidden

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

48 files changed

+184
-114
lines changed

compiler/src/dotty/tools/dotc/core/Phases.scala

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ object Phases {
8282
final def squashPhases(phasess: List[List[Phase]],
8383
phasesToSkip: List[String], stopBeforePhases: List[String], stopAfterPhases: List[String], YCheckAfter: List[String]): List[Phase] = {
8484
val squashedPhases = ListBuffer[Phase]()
85-
var prevPhases: Set[Class[_ <: Phase]] = Set.empty
85+
var prevPhases: Set[String] = Set.empty
8686
val YCheckAll = YCheckAfter.contains("all")
8787

8888
var stop = false
@@ -99,7 +99,6 @@ object Phases {
9999
val filteredPhaseBlock = filteredPhases(i)
100100
val phaseToAdd =
101101
if (filteredPhaseBlock.length > 1) {
102-
val phasesInBlock: Set[String] = filteredPhaseBlock.map(_.phaseName).toSet
103102
for (phase <- filteredPhaseBlock) {
104103
phase match {
105104
case p: MiniPhase =>
@@ -112,11 +111,11 @@ object Phases {
112111
}
113112
}
114113
val superPhase = new MegaPhase(filteredPhaseBlock.asInstanceOf[List[MiniPhase]].toArray)
115-
prevPhases ++= filteredPhaseBlock.map(_.getClazz)
114+
prevPhases ++= filteredPhaseBlock.map(_.phaseName)
116115
superPhase
117116
} else { // block of a single phase, no squashing
118117
val phase = filteredPhaseBlock.head
119-
prevPhases += phase.getClazz
118+
prevPhases += phase.phaseName
120119
phase
121120
}
122121
squashedPhases += phaseToAdd
@@ -147,7 +146,7 @@ object Phases {
147146

148147
phases = (NoPhase :: flatPhases.toList ::: new TerminalPhase :: Nil).toArray
149148
setSpecificPhases()
150-
var phasesAfter:Set[Class[_ <: Phase]] = Set.empty
149+
var phasesAfter: Set[String] = Set.empty
151150
nextDenotTransformerId = new Array[Int](phases.length)
152151
denotTransformers = new Array[DenotTransformer](phases.length)
153152

@@ -161,7 +160,7 @@ object Phases {
161160
val unmetPrecedeRequirements = p.runsAfter -- phasesAfter
162161
assert(unmetPrecedeRequirements.isEmpty,
163162
s"phase ${p} has unmet requirement: ${unmetPrecedeRequirements.mkString(", ")} should precede this phase")
164-
phasesAfter += p.getClazz
163+
phasesAfter += p.phaseName
165164

166165
}
167166
var i = 0
@@ -281,7 +280,7 @@ object Phases {
281280
def allowsImplicitSearch: Boolean = false
282281

283282
/** List of names of phases that should precede this phase */
284-
def runsAfter: Set[Class[_ <: Phase]] = Set.empty
283+
def runsAfter: Set[String] = Set.empty
285284

286285
/** @pre `isRunnable` returns true */
287286
def run(implicit ctx: Context): Unit
@@ -393,12 +392,4 @@ object Phases {
393392
def replace(oldPhaseClass: Class[_ <: Phase], newPhases: Phase => List[Phase], current: List[List[Phase]]): List[List[Phase]] =
394393
current.map(_.flatMap(phase =>
395394
if (oldPhaseClass.isInstance(phase)) newPhases(phase) else phase :: Nil))
396-
397-
/** Dotty deviation: getClass yields Class[_], instead of [Class <: <type of receiver>].
398-
* We can get back the old behavior using this decorator. We should also use the same
399-
* trick for standard getClass.
400-
*/
401-
private implicit class getClassDeco[T](val x: T) extends AnyVal {
402-
def getClazz: Class[_ <: T] = x.getClass.asInstanceOf[Class[_ <: T]]
403-
}
404395
}

compiler/src/dotty/tools/dotc/plugins/Plugin.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import scala.collection.mutable
1313
import scala.util.{ Try, Success, Failure }
1414

1515
trait PluginPhase extends MiniPhase {
16-
def runsBefore: Set[Class[_ <: Phase]] = Set.empty
16+
def runsBefore: Set[String] = Set.empty
1717
}
1818

1919
sealed trait Plugin {

compiler/src/dotty/tools/dotc/plugins/Plugins.scala

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,9 @@ object Plugins {
146146
*/
147147
def schedule(plan: List[List[Phase]], pluginPhases: List[PluginPhase]): List[List[Phase]] = {
148148
import scala.collection.mutable.{ Map => MMap }
149-
type OrderingReq = (Set[Class[_]], Set[Class[_]])
149+
type OrderingReq = (Set[String], Set[String])
150150

151-
val orderRequirements = MMap[Class[_], OrderingReq]()
151+
val orderRequirements = MMap[String, OrderingReq]()
152152

153153
// 1. already inserted phases don't need constraints themselves.
154154
// 2. no need to propagate beyond boundary of inserted phases, as the information
@@ -158,13 +158,13 @@ object Plugins {
158158
// of primitive phases (`plan`) are used to check `runAfter` and `runBefore`, thus
159159
// there is no need to propagate the primitive phases.
160160

161-
var insertedPhase = plan.flatMap(ps => ps.map(_.getClass : Class[_])).toSet
162-
def isInserted(phase: Class[_]): Boolean = insertedPhase.contains(phase)
161+
var insertedPhase = plan.flatMap(ps => ps.map(_.phaseName)).toSet
162+
def isInserted(phase: String): Boolean = insertedPhase.contains(phase)
163163

164164
var updatedPlan = plan
165165

166166
def constraintConflict(phase: Phase): String = {
167-
val (runsAfter, runsBefore) = orderRequirements(phase.getClass)
167+
val (runsAfter, runsBefore) = orderRequirements(phase.phaseName)
168168
s"""
169169
|Ordering conflict for phase ${phase.phaseName}
170170
|after: ${runsAfter.mkString("[", ", ", "]")}
@@ -174,26 +174,26 @@ object Plugins {
174174

175175
// init ordering map, no propagation
176176
pluginPhases.foreach { phase =>
177-
val runsAfter : Set[Class[_]] = phase.runsAfter.asInstanceOf[Set[Class[_]]]
178-
val runsBefore : Set[Class[_]] = phase.runsBefore.asInstanceOf[Set[Class[_]]]
177+
val runsAfter = phase.runsAfter
178+
val runsBefore = phase.runsBefore
179179

180-
orderRequirements.update(phase.getClass, (runsAfter, runsBefore))
180+
orderRequirements.update(phase.phaseName, (runsAfter, runsBefore))
181181
}
182182

183183
// propagate ordering constraint : reflexivity
184184
pluginPhases.foreach { phase =>
185185

186-
var (runsAfter, runsBefore) = orderRequirements(phase.getClass)
186+
var (runsAfter, runsBefore) = orderRequirements(phase.phaseName)
187187

188188
// propagate transitive constraints to related phases
189-
runsAfter.filter(!isInserted(_)).foreach { phaseClass =>
190-
val (runsAfter1, runsBefore1) = orderRequirements(phaseClass)
191-
orderRequirements.update(phaseClass, (runsAfter1, runsBefore1 + phase.getClass))
189+
runsAfter.filter(!isInserted(_)).foreach { phaseName =>
190+
val (runsAfter1, runsBefore1) = orderRequirements(phaseName)
191+
orderRequirements.update(phaseName, (runsAfter1, runsBefore1 + phase.phaseName))
192192
}
193193

194-
runsBefore.filter(!isInserted(_)).foreach { phaseClass =>
195-
val (runsAfter1, runsBefore1) = orderRequirements(phaseClass)
196-
orderRequirements.update(phaseClass, (runsAfter1 + phase.getClass, runsBefore1))
194+
runsBefore.filter(!isInserted(_)).foreach { phaseName =>
195+
val (runsAfter1, runsBefore1) = orderRequirements(phaseName)
196+
orderRequirements.update(phaseName, (runsAfter1 + phase.phaseName, runsBefore1))
197197
}
198198

199199
}
@@ -206,8 +206,8 @@ object Plugins {
206206

207207
// propagate constraints from related phases to current phase: transitivity
208208
def propagate(phase: Phase): OrderingReq = {
209-
def propagateRunsBefore(beforePhase: Class[_]): Set[Class[_]] =
210-
if (beforePhase == phase.getClass)
209+
def propagateRunsBefore(beforePhase: String): Set[String] =
210+
if (beforePhase == phase.phaseName)
211211
throw new Exception(constraintConflict(phase))
212212
else if (isInserted(beforePhase))
213213
Set(beforePhase)
@@ -216,8 +216,8 @@ object Plugins {
216216
runsBefore.flatMap(propagateRunsBefore) + beforePhase
217217
}
218218

219-
def propagateRunsAfter(afterPhase: Class[_]): Set[Class[_]] =
220-
if (afterPhase == phase.getClass)
219+
def propagateRunsAfter(afterPhase: String): Set[String] =
220+
if (afterPhase == phase.phaseName)
221221
throw new Exception(constraintConflict(phase))
222222
else if (isInserted(afterPhase))
223223
Set(afterPhase)
@@ -226,7 +226,7 @@ object Plugins {
226226
runsAfter.flatMap(propagateRunsAfter) + afterPhase
227227
}
228228

229-
var (runsAfter, runsBefore) = orderRequirements(phase.getClass)
229+
var (runsAfter, runsBefore) = orderRequirements(phase.phaseName)
230230

231231
runsAfter = runsAfter.flatMap(propagateRunsAfter)
232232
runsBefore = runsBefore.flatMap(propagateRunsBefore)
@@ -249,25 +249,25 @@ object Plugins {
249249

250250
// runsBefore met after the split
251251
val (before, after) = updatedPlan.span { ps =>
252-
val classes = ps.map(_.getClass)
252+
val phases = ps.map(_.phaseName)
253253
val runsAfterSat = runsAfter.isEmpty
254-
runsAfter = runsAfter -- classes
254+
runsAfter = runsAfter -- phases
255255
// Prefer the point immediately before the first runsBefore.
256256
// If runsBefore not specified, insert at the point immediately
257257
// after the last afterPhases.
258-
!classes.exists(runsBefore.contains) &&
258+
!phases.exists(runsBefore.contains) &&
259259
!(runsBefore.isEmpty && runsAfterSat)
260260
}
261261

262262
// check runsAfter
263263
// error can occur if: a < b, b < c, c < a
264264
after.foreach { ps =>
265-
val classes = ps.map(_.getClass)
266-
if (classes.exists(runsAfter)) // afterReq satisfied
265+
val phases = ps.map(_.phaseName)
266+
if (phases.exists(runsAfter)) // afterReq satisfied
267267
throw new Exception(s"Ordering conflict for phase ${phase.phaseName}")
268268
}
269269

270-
insertedPhase = insertedPhase + phase.getClass
270+
insertedPhase = insertedPhase + phase.phaseName
271271
updatedPlan = before ++ (List(phase) :: after)
272272
}
273273

compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class ExtractAPI extends Phase {
3838
// after `PostTyper` (unlike `ExtractDependencies`, the simplication to trees
3939
// done by `PostTyper` do not affect this phase because it only cares about
4040
// definitions, and `PostTyper` does not change definitions).
41-
override def runsAfter = Set(classOf[transform.PostTyper])
41+
override def runsAfter = Set(transform.PostTyper.name)
4242

4343
override def run(implicit ctx: Context): Unit = {
4444
val unit = ctx.compilationUnit

compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ import NameOps._
1717
import NameKinds.{ExpandedName, TraitSetterName}
1818
import ast.Trees._
1919

20+
object AugmentScala2Traits {
21+
val name = "augmentScala2Traits"
22+
}
23+
2024
/** This phase augments Scala2 traits with implementation classes and with additional members
2125
* needed for mixin composition.
2226
* These symbols would have been added between Unpickling and Mixin in the Scala2 pipeline.
@@ -33,7 +37,7 @@ class AugmentScala2Traits extends MiniPhase with IdentityDenotTransformer with F
3337

3438
override def changesMembers = true
3539

36-
override def phaseName: String = "augmentScala2Traits"
40+
override def phaseName: String = AugmentScala2Traits.name
3741

3842
override def rewiredTarget(referenced: Symbol, derived: Symbol)(implicit ctx: Context) = NoSymbol
3943

compiler/src/dotty/tools/dotc/transform/ByNameClosures.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,15 @@ import core.StdNames.nme
2626
class ByNameClosures extends TransformByNameApply with IdentityDenotTransformer { thisPhase =>
2727
import ast.tpd._
2828

29-
override def phaseName: String = "byNameClosures"
29+
override def phaseName: String = ByNameClosures.name
3030

3131
override def mkByNameClosure(arg: Tree, argType: Type)(implicit ctx: Context): Tree = {
3232
val meth = ctx.newSymbol(
3333
ctx.owner, nme.ANON_FUN, Synthetic | Method, MethodType(Nil, Nil, argType))
3434
Closure(meth, _ => arg.changeOwnerAfter(ctx.owner, meth, thisPhase))
3535
}
3636
}
37+
38+
object ByNameClosures {
39+
val name = "byNameClosures"
40+
}

compiler/src/dotty/tools/dotc/transform/Constructors.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ import util.Positions._
2020
import Constants.Constant
2121
import collection.mutable
2222

23+
object Constructors {
24+
val name = "constructors"
25+
}
26+
2327
/** This transform
2428
* - moves initializers from body to constructor.
2529
* - makes all supercalls explicit
@@ -29,9 +33,9 @@ import collection.mutable
2933
class Constructors extends MiniPhase with IdentityDenotTransformer { thisPhase =>
3034
import tpd._
3135

32-
override def phaseName: String = "constructors"
33-
override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[HoistSuperArgs])
34-
override def runsAfterGroupsOf: Set[Class[_ <: Phase]] = Set(classOf[Memoize])
36+
override def phaseName: String = Constructors.name
37+
override def runsAfter = Set(HoistSuperArgs.name)
38+
override def runsAfterGroupsOf = Set(Memoize.name)
3539
// Memoized needs to be finished because we depend on the ownerchain after Memoize
3640
// when checking whether an ident is an access in a constructor or outside it.
3741
// This test is done in the right-hand side of a value definition. If Memoize

compiler/src/dotty/tools/dotc/transform/DropEmptyCompanions.scala.disabled

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import dotty.tools.dotc.transform.MegaPhase.TransformerInfo
3131
class DropEmptyCompanions extends MiniPhase { thisTransform =>
3232
import ast.tpd._
3333
override def phaseName = "dropEmptyCompanions"
34-
override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[Flatten])
34+
override def runsAfter = Set(Flatten.name)
3535

3636
override def transformPackageDef(pdef: PackageDef)(implicit ctx: Context) = {
3737

compiler/src/dotty/tools/dotc/transform/ElimByName.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ import ast.Trees._
4040
class ElimByName extends TransformByNameApply with InfoTransformer {
4141
import ast.tpd._
4242

43-
override def phaseName: String = "elimByName"
43+
override def phaseName: String = ElimByName.name
4444

45-
override def runsAfterGroupsOf = Set(classOf[Splitter])
45+
override def runsAfterGroupsOf = Set(Splitter.name)
4646
// I got errors running this phase in an earlier group, but I did not track them down.
4747

4848
/** Map `tree` to `tree.apply()` is `ftree` was of ExprType and becomes now a function */
@@ -79,3 +79,7 @@ class ElimByName extends TransformByNameApply with InfoTransformer {
7979

8080
override def mayChange(sym: Symbol)(implicit ctx: Context): Boolean = sym.isTerm
8181
}
82+
83+
object ElimByName {
84+
val name = "elimByName"
85+
}

compiler/src/dotty/tools/dotc/transform/ElimErasedValueType.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import Types._, Contexts._, Constants._, Names._, NameOps._, Flags._, DenotTrans
88
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, Scopes._, Denotations._
99
import TypeErasure.ErasedValueType, ValueClasses._
1010

11+
object ElimErasedValueType {
12+
val name = "elimErasedValueType"
13+
}
14+
1115
/** This phase erases ErasedValueType to their underlying type.
1216
* It also removes the synthetic cast methods u2evt$ and evt2u$ which are
1317
* no longer needed afterwards.
@@ -19,9 +23,9 @@ class ElimErasedValueType extends MiniPhase with InfoTransformer {
1923

2024
import tpd._
2125

22-
override def phaseName: String = "elimErasedValueType"
26+
override def phaseName: String = ElimErasedValueType.name
2327

24-
override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[Erasure])
28+
override def runsAfter = Set(Erasure.name)
2529

2630
def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type = sym match {
2731
case sym: ClassSymbol if sym is ModuleClass =>

compiler/src/dotty/tools/dotc/transform/ElimOuterSelect.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class ElimOuterSelect extends MiniPhase {
1717

1818
override def phaseName: String = "elimOuterSelect"
1919

20-
override def runsAfterGroupsOf = Set(classOf[ExplicitOuter])
20+
override def runsAfterGroupsOf = Set(ExplicitOuter.name)
2121
// ExplicitOuter needs to have run to completion before so that all classes
2222
// that need an outer accessor have one.
2323

compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,17 @@ import Names.Name
2222
import NameOps._
2323
import TypeUtils._
2424

25+
object ElimRepeated {
26+
val name = "elimRepeated"
27+
}
28+
2529
/** A transformer that removes repeated parameters (T*) from all types, replacing
2630
* them with Seq types.
2731
*/
2832
class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
2933
import ast.tpd._
3034

31-
override def phaseName = "elimRepeated"
35+
override def phaseName = ElimRepeated.name
3236

3337
override def changesMembers = true // the phase adds vararg bridges
3438

compiler/src/dotty/tools/dotc/transform/Erasure.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,13 @@ import ExplicitOuter._
3030
import core.Mode
3131
import reporting.trace
3232

33+
3334
class Erasure extends Phase with DenotTransformer {
3435

35-
override def phaseName: String = "erasure"
36+
override def phaseName: String = Erasure.name
3637

3738
/** List of names of phases that should precede this phase */
38-
override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[InterceptedMethods], classOf[Splitter], classOf[ElimRepeated])
39+
override def runsAfter = Set(InterceptedMethods.name, Splitter.name, ElimRepeated.name)
3940

4041
override def changesMembers: Boolean = true // the phase adds bridges
4142
override def changesParents: Boolean = true // the phase drops Any
@@ -146,6 +147,8 @@ object Erasure {
146147
import tpd._
147148
import TypeTestsCasts._
148149

150+
val name = "erasure"
151+
149152
object Boxing {
150153

151154
def isUnbox(sym: Symbol)(implicit ctx: Context) =

compiler/src/dotty/tools/dotc/transform/ExpandPrivate.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class ExpandPrivate extends MiniPhase with IdentityDenotTransformer { thisPhase
4141
override def phaseName: String = "expandPrivate"
4242

4343
// This phase moves methods around (in infotransform) so it may need to make other methods public
44-
override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[MoveStatics])
44+
override def runsAfter = Set(MoveStatics.name)
4545

4646
override def changesMembers = true // the phase introduces new members with mangled names
4747

0 commit comments

Comments
 (0)