aboutsummaryrefslogblamecommitdiff
path: root/src/dotty/tools/dotc/typer/Typer.scala
blob: ee221f9f2e66fe7d212b5bb5251ba25aeefef798 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16















                                                                                                  






























































                                                                                                                
                    


















                                                                                               
 
package dotty.tools
package dotc
package typer

import core._
import ast._
import Trees._, Constants._, StdNames._, Scopes._
import Contexts._, Symbols._, Types._, SymDenotations._, Names._, NameOps._, Flags._, Decorators._
import util.Positions._
import util.SourcePosition
import collection.mutable
import language.implicitConversions

trait TyperContextOps { ctx: Context => }


class Typer extends Namer {

  import tpd._

  def typed(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = ???
  def typedExpr(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = ???
  def typedType(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = ???

  type DefTyper[UT <: untpd.NameTree, T <: tpd.Tree] = (UT, NamedType) => Context => T

  def lateDef[UT <: untpd.NameTree, T <: tpd.Tree](defn: UT, op: DefTyper[UT, T])(implicit ctx: Context): T = {
    val sym = symOfUntypedTree(defn)
    sym.ensureCompleted()
    untypedTreeOfSym -= sym
    typedTreeOfSym remove sym match {
      case Some(tree) => tree.asInstanceOf[T]
      case None => op(defn, sym.symRef)(ctx)
    }
  }

  def aheadDef[UT <: untpd.NameTree, T <: tpd.Tree](defn: UT, op: DefTyper[UT, T])(implicit ctx: Context): T = {
    val sym = symOfUntypedTree(defn)
    val tree1 = op(defn, sym.symRef)(ctx)
    typedTreeOfSym(sym) = tree1
    tree1
  }

  def noDefTyper: DefTyper[untpd.NameTree, Nothing] = { (tdef, pt) => implicit ctx => ??? }

  val completeTypeDef: DefTyper[untpd.TypeDef, TypeDef] = { (tdef, pt) => implicit ctx =>
    val Trees.TypeDef(mods, name, tparams, rhs) = tdef
    val mods1 = typedModifiers(mods)
    val tparams1 = reEnterParams(tparams)
    val rhs1 = typedType(rhs)
    tdef.withType(pt).derivedTypeDef(mods1, name, tparams1, rhs1)
  }

  def typedTypedDef(tdef: untpd.TypeDef)(implicit ctx: Context): TypeDef =
    lateDef(tdef, completeTypeDef)

  def typedTptRhs(tpt: untpd.Tree, rhs: untpd.Tree)(implicit ctx: Context): (Tree, Tree) = {
    var tpt1: Tree = EmptyTree
    var rhs1: Tree = EmptyTree
    if (tpt.isEmpty) {
      rhs1 = typedExpr(rhs)
      tpt1 = tpt.withType(rhs1.tpe)
    } else {
      tpt1 = typedType(tpt)
      rhs1 = typedExpr(rhs, tpt1.tpe)
    }
    (tpt1, rhs1)
  }

  val completeValDef: DefTyper[untpd.ValDef, ValDef] = { (vdef, pt) => implicit ctx: Context =>
    val Trees.ValDef(mods, name, tpt, rhs) = vdef
    val mods1 = typedModifiers(mods)
    val (tpt1, rhs1) = typedTptRhs(tpt, rhs)
    vdef.withType(tpt1.tpe).derivedValDef(mods1, name, tpt1, rhs1)
  }

  def reEnterParams[UT <: untpd.NameTree, T <: tpd.Tree](params: List[UT])(implicit ctx: Context): List[T] = {
    for (param <- params) yield {
      val sym = symOfUntypedTree(param)
      ctx.enter(sym)
      lateDef(param, noDefTyper)
    }
  }

  val completeDefDef: DefTyper[untpd.DefDef, DefDef] = { (ddef, pt) => implicit ctx: Context =>
    val Trees.DefDef(mods, name, tparams, vparamss, tpt, rhs) = ddef
    val mods1 = typedModifiers(mods)
    val tparams1: List[TypeDef] = reEnterParams(tparams)
    val vparamss1: List[List[ValDef]] = vparamss.mapconserve(reEnterParams)
    val (tpt1, rhs1) = typedTptRhs(tpt, rhs)
    ddef.withType(tpt1.tpe).derivedDefDef(mods1, name, tparams1, vparamss1, tpt1, rhs1)
  }

  def typedImport(imp: untpd.Import, pt: Type)(implicit ctx: Context): Import = {
    val expr1 = typed(imp.expr)
    imp.withType(pt).derivedImport(expr1, imp.selectors)
  }

  def typedModifiers(mods: untpd.Modifiers): Modifiers = ???
}