namers.scala

来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 1,028 行 · 第 1/3 页

SCALA
1,028
字号
              tree.symbol =                 if ((mods.flags & DEFERRED) == 0) { // not deferred                  var vsym =                     if (!context.owner.isClass) {                      assert((mods.flags & LAZY) != 0) // if not a field, it has to be a lazy val                      owner.newValue(tree.pos, name + "$lzy" ).setFlag(mods.flags | MUTABLE)                    } else {                      owner.newValue(tree.pos, nme.getterToLocal(name))                        .setFlag(mods.flags & FieldFlags | PRIVATE | LOCAL | (if ((mods.flags & LAZY) != 0) MUTABLE else 0))                    }                  vsym = enterInScope(vsym).asInstanceOf[TermSymbol]                  setInfo(vsym)(namerOf(vsym).typeCompleter(tree))                  if ((mods.flags & LAZY) != 0)                    vsym.setLazyAccessor(getter)                  vsym                } else getter;            } else {              tree.symbol = enterInScope(owner.newValue(tree.pos, name)                .setFlag(mods.flags))              finish            }          case DefDef(mods, nme.CONSTRUCTOR, tparams, _, _, _) =>            var sym = owner.newConstructor(tree.pos).setFlag(mods.flags | owner.getFlag(ConstrFlags))            setPrivateWithin(tree, sym, mods)            tree.symbol = enterInScope(sym)            finishWith(tparams)          case DefDef(mods, name, tparams, _, _, _) =>            var sym = (owner.newMethod(tree.pos, name)).setFlag(mods.flags)            setPrivateWithin(tree, sym, mods)            tree.symbol = enterInScope(sym)             finishWith(tparams)          case TypeDef(mods, name, tparams, _) =>            var flags: Long = mods.flags            if ((flags & PARAM) != 0) flags |= DEFERRED            var sym =new TypeSymbol(owner, tree.pos, name).setFlag(flags)            setPrivateWithin(tree, sym, mods)            tree.symbol = enterInScope(sym)            finishWith(tparams)           case DocDef(_, defn) =>            enterSym(defn)           case imp @ Import(_, _) =>            tree.symbol = NoSymbol.newImport(tree.pos)            setInfo(tree.symbol)(namerOf(tree.symbol).typeCompleter(tree))            return (context.makeNewImport(imp))          case _ =>        }      }      this.context    }    def enterSyntheticSym(tree: Tree): Symbol = {      enterSym(tree)      context.unit.synthetics(tree.symbol) = tree      tree.symbol    }// --- Lazy Type Assignment --------------------------------------------------    def typeCompleter(tree: Tree) = mkTypeCompleter(tree) { sym =>      if (settings.debug.value) log("defining " + sym + Flags.flagsToString(sym.flags));      val tp = typeSig(tree)      tp match {        case TypeBounds(lo, hi) =>          // check that lower bound is not an F-bound          for (val t <- lo) {            t match {              case TypeRef(_, sym, _) => sym.initialize              case _ =>            }          }        case _ =>      }      sym.setInfo(tp)      if ((sym.isAliasType || sym.isAbstractType) && !(sym hasFlag PARAM) &&           !typer.checkNonCyclic(tree.pos, tp))        sym.setInfo(ErrorType) // this early test is there to avoid infinite baseTypes when                               // adding setters and getters --> bug798      if (settings.debug.value) log("defined " + sym);      validate(sym)    }    def moduleClassTypeCompleter(tree: Tree) = mkTypeCompleter(tree) { sym =>      tree.symbol.info // sets moduleClass info as a side effect.    }    def getterTypeCompleter(tree: Tree) = mkTypeCompleter(tree) { sym =>      if (settings.debug.value) log("defining " + sym)      sym.setInfo(PolyType(List(), typeSig(tree)))      if (settings.debug.value) log("defined " + sym)      validate(sym)    }    def setterTypeCompleter(tree: Tree) = mkTypeCompleter(tree) { sym =>      if (settings.debug.value) log("defining " + sym);      sym.setInfo(MethodType(List(typeSig(tree)), UnitClass.tpe))      if (settings.debug.value) log("defined " + sym);      validate(sym)    }    def selfTypeCompleter(tree: Tree) = mkTypeCompleter(tree) { sym =>      var selftpe = typer.typedType(tree).tpe      if (!(selftpe.typeSymbol isNonBottomSubClass sym.owner))        selftpe = intersectionType(List(sym.owner.tpe, selftpe))//    println("completing self of "+sym.owner+": "+selftpe)      sym.setInfo(selftpe)    }    private def widenIfNotFinal(sym: Symbol, tpe: Type, pt: Type): Type = {      val getter =         if (sym.isValue && sym.owner.isClass && (sym hasFlag PRIVATE))          sym.getter(sym.owner)         else sym      def isHidden(tp: Type): Boolean = tp match {        case SingleType(pre, sym) =>          (sym isLessAccessibleThan getter) || isHidden(pre)        case ThisType(sym) =>          sym isLessAccessibleThan getter        case p: SimpleTypeProxy =>           isHidden(p.underlying)        case _ =>          false      }      val tpe1 = tpe.deconst      val tpe2 = tpe1.widen      if ((sym.isVariable || sym.isMethod && !(sym hasFlag ACCESSOR)))         if (tpe2 <:< pt) tpe2 else tpe1      else if (isHidden(tpe)) tpe2      else if (!(sym hasFlag FINAL)) tpe1      else tpe    }    def enterValueParams(owner: Symbol, vparamss: List[List[ValDef]]): List[List[Symbol]] = {      def enterValueParam(param: ValDef): Symbol = {        if (inIDE) param.symbol = {          var sym = owner.newValueParameter(param.pos, param.name).            setFlag(param.mods.flags & (BYNAMEPARAM | IMPLICIT))          setPrivateWithin(param, sym, param.mods)          sym = enterInScope(sym).asInstanceOf[TermSymbol]          if (!sym.hasRawInfo || sym.rawInfo.isComplete)            setInfo(sym)(typeCompleter(param))            sym          } else param.symbol = setInfo(          enterInScope{            val sym = owner.newValueParameter(param.pos, param.name).              setFlag(param.mods.flags & (BYNAMEPARAM | IMPLICIT))            setPrivateWithin(param, sym, param.mods)          })(typeCompleter(param))        param.symbol      }       vparamss.map(_.map(enterValueParam))    }    private def templateSig(templ: Template): Type = {      val clazz = context.owner      def checkParent(tpt: Tree): Type = {        val tp = tpt.tpe        if (tp.typeSymbol == context.owner) {           context.error(tpt.pos, ""+tp.typeSymbol+" inherits itself")          AnyRefClass.tpe         } else if (tp.isError) {          AnyRefClass.tpe        } else {          tp        }      }                def enterSelf(self: ValDef) {        if (!self.tpt.isEmpty) {          clazz.typeOfThis = selfTypeCompleter(self.tpt)          self.symbol = clazz.thisSym.setPos(self.pos)        } else {          self.tpt.tpe = NoType          if (self.name != nme.WILDCARD) {            clazz.typeOfThis = clazz.tpe            self.symbol = clazz.thisSym          } else if (self ne emptyValDef) {            self.symbol = clazz.newThisSym(self.pos) setInfo clazz.tpe          }        }        if (self.name != nme.WILDCARD) {          self.symbol.name = self.name          self.symbol = context.scope enter self.symbol        }      }      val parents = typer.parentTypes(templ) map checkParent      enterSelf(templ.self)      val decls = newClassScope(clazz)      val templateNamer = newNamer(context.make(templ, clazz, decls))        .enterSyms(templ.body)      caseClassOfModuleClass get clazz match {        case Some(cdef) =>          addApplyUnapply(cdef, templateNamer)          caseClassOfModuleClass -= clazz        case None =>      }      ClassInfoType(parents, decls, clazz)        }    private def classSig(tparams: List[TypeDef], impl: Template): Type =       polyType(typer.reenterTypeParams(tparams), templateSig(impl))        private def methodSig(tparams: List[TypeDef], vparamss: List[List[ValDef]],                          tpt: Tree, rhs: Tree): Type = {      val meth = context.owner       val tparamSyms = typer.reenterTypeParams(tparams)      var vparamSymss =         if (inIDE && meth.isPrimaryConstructor) {          // @S: because they have already been entered this way....          assert(true)          enterValueParams(meth.owner.owner, vparamss)        } else {          enterValueParams(meth, vparamss)        }      if (tpt.isEmpty && meth.name == nme.CONSTRUCTOR) tpt.tpe = context.enclClass.owner.tpe      if (onlyPresentation)         methodArgumentNames(meth) = vparamss.map(_.map(_.symbol));      def convertToDeBruijn(vparams: List[Symbol], level: Int): TypeMap = new TypeMap {	def debruijnFor(param: Symbol) = 	  DeBruijnIndex(level, vparams indexOf param)        def apply(tp: Type) = {          tp match {            case SingleType(_, sym) =>              if (settings.Xexperimental.value && sym.owner == meth && (vparams contains sym)) {/*                if (sym hasFlag IMPLICIT) {                  context.error(sym.pos, "illegal type dependence on implicit parameter")                  ErrorType                } else */		debruijnFor(sym)              } else tp            case MethodType(formals, restpe) =>              val formals1 = List.mapConserve(formals)(this)               val restpe1 = convertToDeBruijn(vparams, level + 1)(restpe)              if ((formals1 eq formals) && (restpe1 eq restpe)) tp              else copyMethodType(tp, formals1, restpe1)            case _ =>              mapOver(tp)          }        }	object treeTrans extends TypeMapTransformer {	  override def transform(tree: Tree): Tree =	    tree match {	      case Ident(name) if (vparams contains tree.symbol) =>	        val dtpe = debruijnFor(tree.symbol)	        val dsym = 		    newLocalDummy(context.owner, tree.symbol.pos)		      .newValue(tree.symbol.pos, name)	        dsym.setFlag(PARAM)	        dsym.setInfo(dtpe)		Ident(name).setSymbol(dsym).copyAttrs(tree).setType(dtpe)	      case tree => super.transform(tree)	    }	}	override def mapOver(arg: Tree) = Some(treeTrans.transform(arg))      }      val checkDependencies: TypeTraverser = new TypeTraverser {        def traverse(tp: Type) = {          tp match {            case SingleType(_, sym) =>              if (sym.owner == meth && (vparamSymss exists (_ contains sym)))                context.error(                  sym.pos,                   "illegal dependent method type"+                  (if (settings.Xexperimental.value)                      ": parameter appears in the type of another parameter in the same section or an earlier one"                   else ""))            case _ =>              mapOver(tp)          }          this        }      }            def makeMethodType(vparams: List[Symbol], restpe: Type) = {        val formals = vparams map (_.tpe)        val restpe1 = convertToDeBruijn(vparams, 1)(restpe)        if (!vparams.isEmpty && vparams.head.hasFlag(IMPLICIT))           ImplicitMethodType(formals, restpe1)        else MethodType(formals, restpe1)      }      def thisMethodType(restpe: Type) =         polyType(          tparamSyms,           if (vparamSymss.isEmpty) PolyType(List(), restpe)          else checkDependencies((vparamSymss :\ restpe) (makeMethodType)))      var resultPt = if (tpt.isEmpty) WildcardType else typer.typedType(tpt).tpe      val site = meth.owner.thisType      def overriddenSymbol = intersectionType(meth.owner.info.parents).member(meth.name).filter(sym =>          sym != NoSymbol && (site.memberType(sym) matches thisMethodType(resultPt)))      // fill in result type and parameter types from overridden symbol if there is a unique one.      if (meth.owner.isClass && (tpt.isEmpty || vparamss.exists(_.exists(_.tpt.isEmpty)))) {        // try to complete from matching definition in base type        for (vparams <- vparamss; vparam <- vparams)          if (vparam.tpt.isEmpty) vparam.symbol setInfo WildcardType        val overridden = overriddenSymbol        if (overridden != NoSymbol && !(overridden hasFlag OVERLOADED)) {          resultPt = site.memberType(overridden) match {            case PolyType(tparams, rt) => rt.substSym(tparams, tparamSyms)            case mt => mt          }          for (vparams <- vparamss) {            var pfs = resultPt.paramTypes            for (vparam <- vparams) {              if (vparam.tpt.isEmpty) {                vparam.tpt.tpe = pfs.head                vparam.symbol setInfo pfs.head              }              pfs = pfs.tail            }            resultPt = resultPt.resultType          }          resultPt match {            case PolyType(List(), rtpe) => resultPt = rtpe            case MethodType(List(), rtpe) => resultPt = rtpe            case _ =>           }          if (tpt.isEmpty) {            // provisionally assign `meth' a method type with inherited result type            // that way, we can leave out the result type even if method is recursive.            meth setInfo thisMethodType(resultPt)          }        }      }       // Add a () parameter section if this overrides dome method with () parameters.      if (meth.owner.isClass && vparamss.isEmpty && overriddenSymbol.alternatives.exists(        _.info.isInstanceOf[MethodType])) {        vparamSymss = List(List())      }      for (vparams <- vparamss; vparam <- vparams if vparam.tpt.isEmpty) {        context.error(vparam.pos, "missing parameter type")        vparam.tpt.tpe = ErrorType

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?