@@ -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 :
@@ -342,10 +346,48 @@ object Inlines:
342346 if Inlines .isInlineable(codeArg1.symbol) then stripTyped(Inlines .inlineCall(codeArg1))
343347 else codeArg1
344348
349+ class MegaPhaseWithCustomPhaseId (miniPhases : Array [MiniPhase ], startId : PhaseId , endId : PhaseId )
350+ extends MegaPhase (miniPhases) {
351+ override def start : Int = startId
352+ override def end : Int = endId
353+ }
354+
345355 ConstFold (underlyingCodeArg).tpe.widenTermRefExpr match {
346356 case ConstantType (Constant (code : String )) =>
347- val source2 = SourceFile .virtual(" tasty-reflect" , code)
357+ val unitName = " tasty-reflect"
358+ val source2 = SourceFile .virtual(unitName, code)
348359 inContext(ctx.fresh.setNewTyperState().setTyper(new Typer (ctx.nestingLevel + 1 )).setSource(source2)) {
360+
361+ // Let's reconstruct necessary transform MegaPhases, without anything
362+ // that could cause problems here (like `CrossVersionChecks`).
363+ // The individiual lists here should line up with Compiler.scala, i.e
364+ // separate chunks there should also be kept separate here.
365+ // For now we create a single MegaPhase, since there does not seem to
366+ // be any important checks later (e.g. ForwardDepChecks could be applicable here,
367+ // but the equivalent is also not run in the scala 2's `ctx.typechecks`,
368+ // so let's leave it out for now).
369+ val transformPhases : List [List [(Class [? ], () => MiniPhase )]] = List (
370+ List (
371+ (classOf [InlineVals ], () => new InlineVals ),
372+ (classOf [ElimRepeated ], () => new ElimRepeated ),
373+ (classOf [RefChecks ], () => new RefChecks ),
374+ ),
375+ )
376+
377+ val mergedTransformPhases =
378+ transformPhases.flatMap( (megaPhaseList : List [(Class [? ], () => MiniPhase )]) =>
379+ val (newMegaPhasePhases, phaseIds) =
380+ megaPhaseList
381+ .flatMap { filteredPhase =>
382+ ctx.base.phases.find(phase => filteredPhase._1.isInstance(phase)).map { a =>
383+ (filteredPhase._2(), a.id)
384+ }
385+ }
386+ .unzip
387+ if newMegaPhasePhases.isEmpty then None
388+ else Some (MegaPhaseWithCustomPhaseId (newMegaPhasePhases.toArray, phaseIds.head, phaseIds.last))
389+ )
390+
349391 val tree2 = new Parser (source2).block()
350392 if ctx.reporter.allErrors.nonEmpty then
351393 ctx.reporter.allErrors.map((ErrorKind .Parser , _))
@@ -354,10 +396,27 @@ object Inlines:
354396 ctx.base.postTyperPhase match
355397 case postTyper : PostTyper if ctx.reporter.allErrors.isEmpty =>
356398 val tree4 = atPhase(postTyper) { postTyper.newTransformer.transform(tree3) }
357- ctx.base.inliningPhase match
358- case inlining : Inlining if ctx.reporter.allErrors.isEmpty =>
359- atPhase(inlining) { inlining.newTransformer.transform(tree4) }
360- case _ =>
399+ ctx.base.setRootTreePhase match
400+ case setRootTree =>
401+ val tree5 =
402+ val compilationUnit = CompilationUnit (unitName, code)
403+ compilationUnit.tpdTree = tree4
404+ compilationUnit.untpdTree = tree2
405+ var units = List (compilationUnit)
406+ atPhase(setRootTree)(setRootTree.runOn(units).head.tpdTree)
407+
408+ ctx.base.inliningPhase match
409+ case inlining : Inlining if ctx.reporter.allErrors.isEmpty =>
410+ val tree6 = atPhase(inlining) { inlining.newTransformer.transform(tree5) }
411+ if mergedTransformPhases.nonEmpty then
412+ var transformTree = tree6
413+ for (phase <- mergedTransformPhases if ctx.reporter.allErrors.isEmpty) {
414+ // We use different set of phases than those defined in ctx.base, so calls to
415+ // atPhase(phase)(...) may actually set a NoPhase with outdated SymbolDenotations.
416+ // Same thing may happen in underlying miniphases
417+ transformTree = atPhase(phase.end + 1 )(phase.transformUnit(transformTree))
418+ }
419+ case _ =>
361420 case _ =>
362421 ctx.reporter.allErrors.map((ErrorKind .Typer , _))
363422 }
0 commit comments