aboutsummaryrefslogblamecommitdiff
path: root/src/dotty/tools/dotc/Compiler.scala
blob: ad3249be242790dd949215f743d2202484d9b2ac (plain) (tree)
1
2
3
4
5
6
7
8
9




                   

                
              
               
                                                     
                                            
                   
                  
                            


                                                                
 
                                                                       
 


                                                                              

                

                               
                                                                                    




                                                                                    







                                                                                          

                                 
                                                                                       
                                                                                                           
                                                                                         
                                                                                                        











                                                                                                                             

                                                                 




                                                                                                  
                                                                                                                        




                                                                                                                  

                                                                                                    










                                                                                                                                             
                                                                                                       






                                                                                                                                           
                                                                                               
                                                                     
                                                                              
                                                                                            
                                                                               
                                                                        
                                                            
     
 
               


                     
 







                                                                                        
                                                     
                         
                            

                                    

                                                 

                                                           


                                     
                                                                                                          

                                                                      

                                                                
                                                                           

   
                                              

                       

   
                                            
           
                              
   
 
package dotty.tools
package dotc

import core._
import Contexts._
import Periods._
import Symbols._
import Types._
import Scopes._
import typer.{FrontEnd, Typer, ImportInfo, RefChecks}
import reporting.{Reporter, ConsoleReporter}
import Phases.Phase
import transform._
import util.FreshNameCreator
import transform.TreeTransforms.{TreeTransform, TreeTransformer}
import core.DenotTransformers.DenotTransformer
import core.Denotations.SingleDenotation

import dotty.tools.backend.jvm.{LabelDefs, GenBCode, CollectSuperCalls}

/** The central class of the dotc compiler. The job of a compiler is to create
 *  runs, which process given `phases` in a given `rootContext`.
 */
class Compiler {

  /** Meta-ordering constraint:
   *
   *  DenotTransformers that change the signature of their denotation's info must go
   *  after erasure. The reason is that denotations are permanently referred to by
   *  TermRefs which contain a signature. If the signature of a symbol would change,
   *  all refs to it would become outdated - they could not be dereferenced in the
   *  new phase.
   *
   *  After erasure, signature changing denot-transformers are OK because erasure
   *  will make sure that only term refs with fixed SymDenotations survive beyond it. This
   *  is possible because:
   *
   *   - splitter has run, so every ident or select refers to a unique symbol
   *   - after erasure, asSeenFrom is the identity, so every reference has a
   *     plain SymDenotation, as opposed to a UniqueRefDenotation.
   */
  def phases: List[List[Phase]] =
    List(
      List(new FrontEnd),           // Compiler frontend: scanner, parser, namer, typer
      List(new sbt.ExtractDependencies), // Sends information on classes' dependencies to sbt via callbacks
      List(new PostTyper),          // Additional checks and cleanups after type checking
      List(new sbt.ExtractAPI),     // Sends a representation of the API of classes to sbt via callbacks
      List(new Pickler),            // Generate TASTY info
      List(new FirstTransform,      // Some transformations to put trees into a canonical form
           new CheckReentrant),     // Internal use only: Check that compiled program has no data races involving global vars
      List(new RefChecks,           // Various checks mostly related to abstract members and overriding
           new CheckStatic,         // Check restrictions that apply to @static members
           new ElimRepeated,        // Rewrite vararg parameters and arguments
           new NormalizeFlags,      // Rewrite some definition flags
           new ExtensionMethods,    // Expand methods of value classes with extension methods
           new ExpandSAMs,          // Expand single abstract method closures to anonymous classes
           new TailRec,             // Rewrite tail recursion to loops
           new LiftTry,             // Put try expressions that might execute on non-empty stacks into their own methods
           new ClassOf),            // Expand `Predef.classOf` calls.
      List(new TryCatchPatterns,    // Compile cases in try/catch
           new PatternMatcher,      // Compile pattern matches
           new ExplicitOuter,       // Add accessors to outer classes from nested ones.
           new ExplicitSelf,        // Make references to non-trivial self types explicit as casts
           new CrossCastAnd,        // Normalize selections involving intersection types.
           new Splitter),           // Expand selections involving union types into conditionals
      List(new VCInlineMethods,     // Inlines calls to value class methods
           new IsInstanceOfEvaluator, // Issues warnings when unreachable statements are present in match/if expressions
           new SeqLiterals,         // Express vararg arguments as arrays
           new InterceptedMethods,  // Special handling of `==`, `|=`, `getClass` methods
           new Getters,             // Replace non-private vals and vars with getter defs (fields are added later)
           new ElimByName,          // Expand by-name parameters and arguments
           new AugmentScala2Traits, // Expand traits defined in Scala 2.11 to simulate old-style rewritings
           new ResolveSuper,        // Implement super accessors and add forwarders to trait methods
           new ArrayConstructors),  // Intercept creation of (non-generic) arrays and intrinsify.
      List(new Erasure),            // Rewrite types to JVM model, erasing all type parameters, abstract types and refinements.
      List(new ElimErasedValueType, // Expand erased value types to their underlying implmementation types
           new VCElideAllocations,  // Peep-hole optimization to eliminate unnecessary value class allocations
           new Mixin,               // Expand trait fields and trait initializers
           new LazyVals,            // Expand lazy vals
           new Memoize,             // Add private fields to getters and setters
           new LinkScala2ImplClasses, // Forward calls to the implementation classes of traits defined by Scala 2.11
           new NonLocalReturns,     // Expand non-local returns
           new CapturedVars,        // Represent vars captured by closures as heap objects
           new Constructors,        // Collect initialization code in primary constructors
                                       // Note: constructors changes decls in transformTemplate, no InfoTransformers should be added after it
           new FunctionalInterfaces, // Rewrites closures to implement @specialized types of Functions.
           new GetClass),           // Rewrites getClass calls on primitive types.
      List(new LambdaLift,          // Lifts out nested functions to class scope, storing free variables in environments
                                       // Note: in this mini-phase block scopes are incorrect. No phases that rely on scopes should be here
           new ElimStaticThis,      // Replace `this` references to static objects by global identifiers
           new Flatten,             // Lift all inner classes to package scope
           new RestoreScopes),      // Repair scopes rendered invalid by moving definitions in prior phases of the group
      List(new ExpandPrivate,       // Widen private definitions accessed from nested classes
           new SelectStatic,        // get rid of selects that would be compiled into GetStatic
           new CollectEntryPoints,  // Find classes with main methods
           new CollectSuperCalls,   // Find classes that are called with super
           new DropInlined,         // Drop Inlined nodes, since backend has no use for them
           new MoveStatics,         // Move static methods to companion classes
           new LabelDefs),          // Converts calls to labels to jumps
      List(new GenBCode)            // Generate JVM bytecode
    )

  var runId = 1
  def nextRunId = {
    runId += 1; runId
  }

  /** Produces the following contexts, from outermost to innermost
   *
   *    bootStrap:   A context with next available runId and a scope consisting of
   *                 the RootPackage _root_
   *    start        A context with RootClass as owner and the necessary initializations
   *                 for type checking.
   *    imports      For each element of RootImports, an import context
   */
  def rootContext(implicit ctx: Context): Context = {
    ctx.initialize()(ctx)
    ctx.setPhasePlan(phases)
    val rootScope = new MutableScope
    val bootstrap = ctx.fresh
      .setPeriod(Period(nextRunId, FirstPhaseId))
      .setScope(rootScope)
    rootScope.enter(ctx.definitions.RootPackage)(bootstrap)
    val start = bootstrap.fresh
      .setOwner(defn.RootClass)
      .setTyper(new Typer)
      .setMode(Mode.ImplicitsEnabled)
      .setTyperState(new MutableTyperState(ctx.typerState, ctx.typerState.reporter, isCommittable = true))
      .setFreshNames(new FreshNameCreator.Default)
  ctx.initialize()(start) // re-initialize the base context with start
    def addImport(ctx: Context, refFn: () => TermRef) =
      ctx.fresh.setImportInfo(ImportInfo.rootImport(refFn)(ctx))
    (start.setRunInfo(new RunInfo(start)) /: defn.RootImportFns)(addImport)
  }

  def reset()(implicit ctx: Context): Unit = {
    ctx.base.reset()
    ctx.runInfo.clear()
  }

  def newRun(implicit ctx: Context): Run = {
    reset()
    new Run(this)(rootContext)
  }
}