@@ -12,13 +12,17 @@ import SymDenotations.SymDenotation
1212import config .Printers .inlining
1313import ErrorReporting .errorTree
1414import dotty .tools .dotc .util .{SourceFile , SourcePosition , SrcPos }
15+ import dotty .tools .dotc .transform .*
16+ import dotty .tools .dotc .transform .MegaPhase
17+ import dotty .tools .dotc .transform .MegaPhase .MiniPhase
1518import parsing .Parsers .Parser
1619import transform .{PostTyper , Inlining , CrossVersionChecks }
1720import staging .StagingLevel
1821
1922import collection .mutable
2023import reporting .{NotConstant , trace }
2124import util .Spans .Span
25+ import dotty .tools .dotc .core .Periods .PhaseId
2226
2327/** Support for querying inlineable methods and for inlining calls to such methods */
2428object Inlines :
@@ -345,10 +349,58 @@ object Inlines:
345349 // We should not be rewriting tested strings
346350 val noRewriteSettings = ctx.settings.rewrite.updateIn(ctx.settingsState.reinitializedCopy(), None )
347351
352+ class MegaPhaseWithCustomPhaseId (miniPhases : Array [MiniPhase ], startId : PhaseId , endId : PhaseId )
353+ extends MegaPhase (miniPhases) {
354+ override def start : Int = startId
355+ override def end : Int = endId
356+ }
357+
358+ // Let's reconstruct necessary transform MegaPhases, without anything
359+ // that could cause problems here (like `CrossVersionChecks`).
360+ // The individiual lists here should line up with Compiler.scala, i.e
361+ // separate chunks there should also be kept separate here.
362+ // For now we create a single MegaPhase, since there does not seem to
363+ // be any important checks later (e.g. ForwardDepChecks could be applicable here,
364+ // but the equivalent is also not run in the scala 2's `ctx.typechecks`,
365+ // so let's leave it out for now).
366+ lazy val reconstructedTransformPhases =
367+ val transformPhases : List [List [(Class [? ], () => MiniPhase )]] = List (
368+ List (
369+ (classOf [InlineVals ], () => new InlineVals ),
370+ (classOf [ElimRepeated ], () => new ElimRepeated ),
371+ (classOf [RefChecks ], () => new RefChecks ),
372+ ),
373+ )
374+
375+ transformPhases.flatMap( (megaPhaseList : List [(Class [? ], () => MiniPhase )]) =>
376+ val (newMegaPhasePhases, phaseIds) =
377+ megaPhaseList.flatMap {
378+ case (filteredPhaseClass, miniphaseConstructor) =>
379+ ctx.base.phases
380+ .find(phase => filteredPhaseClass.isInstance(phase))
381+ .map(phase => (miniphaseConstructor(), phase.id))
382+ }
383+ .unzip
384+ if newMegaPhasePhases.isEmpty then None
385+ else Some (MegaPhaseWithCustomPhaseId (newMegaPhasePhases.toArray, phaseIds.head, phaseIds.last))
386+ )
387+
348388 ConstFold (underlyingCodeArg).tpe.widenTermRefExpr match {
349389 case ConstantType (Constant (code : String )) =>
350- val source2 = SourceFile .virtual(" tasty-reflect" , code)
351- inContext(ctx.fresh.setSettings(noRewriteSettings).setNewTyperState().setTyper(new Typer (ctx.nestingLevel + 1 )).setSource(source2)) {
390+ val unitName = " tasty-reflect"
391+ val source2 = SourceFile .virtual(unitName, code)
392+ // We need a dummy owner, as the actual one does not have a computed denotation yet,
393+ // but might be inspected in a transform phase, leading to cyclic errors
394+ val dummyOwner = newSymbol(ctx.owner, " $dummySymbol$" .toTermName, Private , defn.AnyType , NoSymbol )
395+ val newContext =
396+ ctx.fresh
397+ .setSettings(noRewriteSettings)
398+ .setNewTyperState()
399+ .setTyper(new Typer (ctx.nestingLevel + 1 ))
400+ .setSource(source2)
401+ .withOwner(dummyOwner)
402+
403+ inContext(newContext) {
352404 val tree2 = new Parser (source2).block()
353405 if ctx.reporter.allErrors.nonEmpty then
354406 ctx.reporter.allErrors.map((ErrorKind .Parser , _))
@@ -357,10 +409,23 @@ object Inlines:
357409 ctx.base.postTyperPhase match
358410 case postTyper : PostTyper if ctx.reporter.allErrors.isEmpty =>
359411 val tree4 = atPhase(postTyper) { postTyper.newTransformer.transform(tree3) }
360- ctx.base.inliningPhase match
361- case inlining : Inlining if ctx.reporter.allErrors.isEmpty =>
362- atPhase(inlining) { inlining.newTransformer.transform(tree4) }
363- case _ =>
412+ ctx.base.setRootTreePhase match
413+ case setRootTree =>
414+ val tree5 =
415+ val compilationUnit = CompilationUnit (unitName, code)
416+ compilationUnit.tpdTree = tree4
417+ compilationUnit.untpdTree = tree2
418+ var units = List (compilationUnit)
419+ atPhase(setRootTree)(setRootTree.runOn(units).head.tpdTree)
420+ ctx.base.inliningPhase match
421+ case inlining : Inlining if ctx.reporter.allErrors.isEmpty =>
422+ val tree6 = atPhase(inlining) { inlining.newTransformer.transform(tree5) }
423+ if ctx.reporter.allErrors.isEmpty && reconstructedTransformPhases.nonEmpty then
424+ var transformTree = tree6
425+ for phase <- reconstructedTransformPhases do
426+ if ctx.reporter.allErrors.isEmpty then
427+ transformTree = atPhase(phase.end + 1 )(phase.transformUnit(transformTree))
428+ case _ =>
364429 case _ =>
365430 ctx.reporter.allErrors.map((ErrorKind .Typer , _))
366431 }
0 commit comments