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 + -
显示快捷键?