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