@@ -12,13 +12,17 @@ import SymDenotations.SymDenotation
12
12
import config .Printers .inlining
13
13
import ErrorReporting .errorTree
14
14
import 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
15
18
import parsing .Parsers .Parser
16
19
import transform .{PostTyper , Inlining , CrossVersionChecks }
17
20
import staging .StagingLevel
18
21
19
22
import collection .mutable
20
23
import reporting .{NotConstant , trace }
21
24
import util .Spans .Span
25
+ import dotty .tools .dotc .core .Periods .PhaseId
22
26
23
27
/** Support for querying inlineable methods and for inlining calls to such methods */
24
28
object Inlines :
@@ -342,10 +346,48 @@ object Inlines:
342
346
if Inlines .isInlineable(codeArg1.symbol) then stripTyped(Inlines .inlineCall(codeArg1))
343
347
else codeArg1
344
348
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
+
345
355
ConstFold (underlyingCodeArg).tpe.widenTermRefExpr match {
346
356
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)
348
359
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
+
349
391
val tree2 = new Parser (source2).block()
350
392
if ctx.reporter.allErrors.nonEmpty then
351
393
ctx.reporter.allErrors.map((ErrorKind .Parser , _))
@@ -354,10 +396,27 @@ object Inlines:
354
396
ctx.base.postTyperPhase match
355
397
case postTyper : PostTyper if ctx.reporter.allErrors.isEmpty =>
356
398
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 _ =>
361
420
case _ =>
362
421
ctx.reporter.allErrors.map((ErrorKind .Typer , _))
363
422
}
0 commit comments