typers.scala

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

SCALA
1,553
字号
                      alias = NoSymbol                    if (alias != NoSymbol) {                      var ownAcc = clazz.info.decl(name).suchThat(_.hasFlag(PARAMACCESSOR))                      if ((ownAcc hasFlag ACCESSOR) && !ownAcc.isDeferred)                        ownAcc = ownAcc.accessed                      if (!ownAcc.isVariable && !alias.accessed.isVariable) {                        if (settings.debug.value)                          log("" + ownAcc + " has alias "+alias + alias.locationString);//debug                        ownAcc.asInstanceOf[TermSymbol].setAlias(alias)                      }                    }                  }                case _ =>              }              ()            }          } else if (inIDE) { // XXX: maybe add later            Console.println("" + superClazz + ":" +              superClazz.info.decls.toList.filter(_.hasFlag(PARAMACCESSOR)))            error(rhs.pos, "mismatch: " + superParamAccessors +              ";" + rhs + ";" + superClazz.info.decls)//debug            return                                    }        }      }    }    private def checkStructuralCondition(refinement: Symbol, vparam: ValDef) {      val tp = vparam.symbol.tpe      if (tp.typeSymbol.isAbstractType && !(tp.typeSymbol.hasTransOwner(refinement)))        error(vparam.tpt.pos,"Parameter type in structural refinement may not refer to abstract type defined outside that same refinement")    }    /**     *  @param ddef ...     *  @return     ...     */    def typedDefDef(ddef: DefDef): DefDef = {      val meth = ddef.symbol      if (inIDE && meth == NoSymbol) throw new TypeError("bad signature")      reenterTypeParams(ddef.tparams)      reenterValueParams(ddef.vparamss)      val tparams1 = List.mapConserve(ddef.tparams)(typedTypeDef)      val vparamss1 = List.mapConserve(ddef.vparamss)(vparams1 =>        List.mapConserve(vparams1)(typedValDef))      for (vparams1 <- vparamss1; if !vparams1.isEmpty; vparam1 <- vparams1.init) {        if (vparam1.symbol.tpe.typeSymbol == RepeatedParamClass)          error(vparam1.pos, "*-parameter must come last")      }      var tpt1 = checkNoEscaping.privates(meth, typedType(ddef.tpt))                 if (!settings.Xexperimental.value) {        for (vparams <- vparamss1; vparam <- vparams) {          checkNoEscaping.locals(context.scope, WildcardType, vparam.tpt); ()        }        checkNoEscaping.locals(context.scope, WildcardType, tpt1)      }      checkNonCyclic(ddef, tpt1)      ddef.tpt.setType(tpt1.tpe)      val typedMods = typedModifiers(ddef.mods)      var rhs1 =         if (ddef.name == nme.CONSTRUCTOR) {          if (!meth.isPrimaryConstructor &&              (!meth.owner.isClass ||               meth.owner.isModuleClass ||               meth.owner.isAnonymousClass ||               meth.owner.isRefinementClass))            error(ddef.pos, "constructor definition not allowed here")          typed(ddef.rhs)        } else {          if (inIDE && ddef.rhs == EmptyTree) EmptyTree          else transformedOrTyped(ddef.rhs, tpt1.tpe)        }      if (meth.isPrimaryConstructor && meth.isClassConstructor &&           phase.id <= currentRun.typerPhase.id && !reporter.hasErrors)        computeParamAliases(meth.owner, vparamss1, rhs1)      if (tpt1.tpe.typeSymbol != AllClass && !context.returnsSeen) rhs1 = checkDead(rhs1)            if (meth.owner.isRefinementClass && meth.allOverriddenSymbols.isEmpty)        for (vparams <- ddef.vparamss; vparam <- vparams)           checkStructuralCondition(meth.owner, vparam)      copy.DefDef(ddef, typedMods, ddef.name, tparams1, vparamss1, tpt1, rhs1) setType NoType    }    def typedTypeDef(tdef: TypeDef): TypeDef = {      reenterTypeParams(tdef.tparams) // @M!      val tparams1 = List.mapConserve(tdef.tparams)(typedTypeDef) // @M!      val typedMods = typedModifiers(tdef.mods)      val rhs1 = checkNoEscaping.privates(tdef.symbol, typedType(tdef.rhs))      checkNonCyclic(tdef.symbol)      rhs1.tpe match {        case TypeBounds(lo1, hi1) =>          if (!(lo1 <:< hi1))            error(tdef.pos, "lower bound "+lo1+" does not conform to upper bound "+hi1)        case _ =>      }      copy.TypeDef(tdef, typedMods, tdef.name, tparams1, rhs1) setType NoType    }    private def enterLabelDef(stat: Tree) {      stat match {        case ldef @ LabelDef(_, _, _) =>          if (ldef.symbol == NoSymbol)            ldef.symbol = namer.enterInScope(              context.owner.newLabel(ldef.pos, ldef.name) setInfo MethodType(List(), UnitClass.tpe))        case _ =>      }    }    def typedLabelDef(ldef: LabelDef): LabelDef = {      val restpe = ldef.symbol.tpe.resultType      val rhs1 = typed(ldef.rhs, restpe)      ldef.params foreach (param => param.tpe = param.symbol.tpe)      copy.LabelDef(ldef, ldef.name, ldef.params, rhs1) setType restpe    }    protected def typedFunctionIDE(fun : Function, txt : Context) = {}        /**     *  @param block ...     *  @param mode  ...     *  @param pt    ...     *  @return      ...     */    def typedBlock(block: Block, mode: Int, pt: Type): Block = {      if (context.retyping) {        for (stat <- block.stats) {          if (stat.isDef) context.scope.enter(stat.symbol)        }      }      namer.enterSyms(block.stats)      block.stats foreach enterLabelDef      val stats1 = typedStats(block.stats, context.owner)      val expr1 = typed(block.expr, mode & ~(FUNmode | QUALmode), pt)      val block1 = copy.Block(block, stats1, expr1)        .setType(if (treeInfo.isPureExpr(block)) expr1.tpe else expr1.tpe.deconst)      //checkNoEscaping.locals(context.scope, pt, block1)      block1    }    /**     *  @param cdef   ...     *  @param pattpe ...     *  @param pt     ...     *  @return       ...     */    def typedCase(cdef: CaseDef, pattpe: Type, pt: Type): CaseDef = {      val pat1: Tree = typedPattern(cdef.pat, pattpe)      val guard1: Tree = if (cdef.guard == EmptyTree) EmptyTree                         else typed(cdef.guard, BooleanClass.tpe)      var body1: Tree = typed(cdef.body, pt)      if (!context.savedTypeBounds.isEmpty) {        body1.tpe = context.restoreTypeBounds(body1.tpe)        if (isFullyDefined(pt) && !(body1.tpe <:< pt)) {          body1 =            typed {              atPos(body1.pos) {                TypeApply(Select(body1, Any_asInstanceOf), List(TypeTree(pt))) // @M no need for pt.normalize here, is done in erasure              }            }        }      }//    body1 = checkNoEscaping.locals(context.scope, pt, body1)      copy.CaseDef(cdef, pat1, guard1, body1) setType body1.tpe    }    def typedCases(tree: Tree, cases: List[CaseDef], pattp0: Type, pt: Type): List[CaseDef] = {      var pattp = pattp0      List.mapConserve(cases) ( cdef =>           newTyper(context.makeNewScope(cdef, context.owner)(TypedCasesScopeKind)).typedCase(cdef, pattp, pt))/* not yet!        cdef.pat match {          case Literal(Constant(null)) =>             if (!(pattp <:< NonNullClass.tpe))              pattp = intersectionType(List(pattp, NonNullClass.tpe), context.owner)          case _ =>        }        result*/    }    /**     *  @param fun  ...     *  @param mode ...     *  @param pt   ...     *  @return     ...     */    def typedFunction(fun: Function, mode: Int, pt: Type): Tree = {      val codeExpected = !forCLDC && !forMSIL && (pt.typeSymbol isNonBottomSubClass CodeClass)      def decompose(pt: Type): (Symbol, List[Type], Type) =        if ((isFunctionType(pt)             ||              pt.typeSymbol == PartialFunctionClass &&              fun.vparams.length == 1 && fun.body.isInstanceOf[Match])              && // see bug901 for a reason why next conditions are neeed            (pt.normalize.typeArgs.length - 1 == fun.vparams.length              ||              fun.vparams.exists(_.tpt.isEmpty)))          (pt.typeSymbol, pt.normalize.typeArgs.init, pt.normalize.typeArgs.last)        else          (FunctionClass(fun.vparams.length), fun.vparams map (x => NoType), WildcardType)      val (clazz, argpts, respt) = decompose(if (codeExpected) pt.normalize.typeArgs.head else pt)      if (fun.vparams.length != argpts.length)        errorTree(fun, "wrong number of parameters; expected = " + argpts.length)      else {        val vparamSyms = List.map2(fun.vparams, argpts) { (vparam, argpt) =>          if (vparam.tpt.isEmpty) {            vparam.tpt.tpe =               if (isFullyDefined(argpt)) argpt              else {                fun match {                  case etaExpansion(vparams, fn, args) if !codeExpected =>                    println("typing eta "+fn)                    silent(_.typed(fn, funMode(mode), pt)) match {                      case fn1: Tree =>                        val ftpe = normalize(fn1.tpe) baseType FunctionClass(fun.vparams.length)                        if (isFunctionType(ftpe) && isFullyDefined(ftpe))                          return typedFunction(fun, mode, ftpe)                      case _ =>                    }                  case _ =>                }                error(                  vparam.pos,                   "missing parameter type"+                  (if (vparam.mods.hasFlag(SYNTHETIC)) " for expanded function "+fun                   else ""))                ErrorType               }          }          enterSym(context, vparam)          if (context.retyping) context.scope enter vparam.symbol          vparam.symbol        }        val vparams = List.mapConserve(fun.vparams)(typedValDef)//        for (vparam <- vparams) {//          checkNoEscaping.locals(context.scope, WildcardType, vparam.tpt); ()//        }        var body = typed(fun.body, respt)        val formals = vparamSyms map (_.tpe)        val restpe = packedType(body, fun.symbol).deconst        val funtpe = typeRef(clazz.tpe.prefix, clazz, formals ::: List(restpe))//        body = checkNoEscaping.locals(context.scope, restpe, body)        val fun1 = copy.Function(fun, vparams, body).setType(funtpe)        if (codeExpected) {          val liftPoint = Apply(Select(Ident(CodeModule), nme.lift_), List(fun1))          typed(atPos(fun.pos)(liftPoint))        } else fun1      }    }    def typedRefinement(stats: List[Tree]): List[Tree] = {      namer.enterSyms(stats)      val stats1 = typedStats(stats, NoSymbol)      for (stat <- stats1 if stat.isDef) {        val member = stat.symbol        if (!(context.owner.info.baseClasses.tail forall            (bc => member.matchingSymbol(bc, context.owner.thisType) == NoSymbol))) {          member setFlag OVERRIDE        }      }      stats1    }    def typedImport(imp : Import) : Import = imp;    def typedStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = {      val inBlock = exprOwner == context.owner      def typedStat(stat: Tree): Tree = {        if (context.owner.isRefinementClass && !treeInfo.isDeclaration(stat))          errorTree(stat, "only declarations allowed here")        stat match {          case imp @ Import(_, _) =>            val imp0 = typedImport(imp)            if (imp0 ne null) {              context = context.makeNewImport(imp0)              imp0.symbol.initialize            }            if ((imp0 ne null) && inIDE) {              imp0.symbol.info match {              case ImportType(exr) =>                 imp0.expr.tpe = exr.tpe              case _ =>              }              imp0            } else EmptyTree          case _ =>            val localTyper = if (inBlock || (stat.isDef && !stat.isInstanceOf[LabelDef])) this                             else newTyper(context.make(stat, exprOwner))            val result = checkDead(localTyper.typed(stat))            if (treeInfo.isSelfOrSuperConstrCall(result)) {              context.inConstructorSuffix = true              if (!inIDE && treeInfo.isSelfConstrCall(result) && result.symbol.pos.offset.getOrElse(0) >= exprOwner.enclMethod.pos.offset.getOrElse(0))                error(stat.pos, "called constructor's definition must precede calling constructor's definition")            }            result        }      }      def accesses(accessor: Symbol, accessed: Symbol) =         (accessed hasFlag LOCAL) && (accessed hasFlag PARAMACCESSOR) ||        (accessor hasFlag ACCESSOR) &&      

⌨️ 快捷键说明

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