summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@epfl.ch>2009-04-28 13:33:47 +0000
committerLukas Rytz <lukas.rytz@epfl.ch>2009-04-28 13:33:47 +0000
commitbdc8c11581b0fc67cf895ba349e43b2081e29c59 (patch)
treec7964a41b187a464ae02e1b1debc0b79326fa26c /src
parent03429aee94c9eb4b1d2a4aa7fd8fadfea6e17bf1 (diff)
downloadscala-bdc8c11581b0fc67cf895ba349e43b2081e29c59.tar.gz
scala-bdc8c11581b0fc67cf895ba349e43b2081e29c59.tar.bz2
scala-bdc8c11581b0fc67cf895ba349e43b2081e29c59.zip
removed Namers.scala.1 / .2
Diffstat (limited to 'src')
-rwxr-xr-xsrc/compiler/scala/tools/nsc/typechecker/Namers.scala.11047
-rwxr-xr-xsrc/compiler/scala/tools/nsc/typechecker/Namers.scala.21046
2 files changed, 0 insertions, 2093 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala.1 b/src/compiler/scala/tools/nsc/typechecker/Namers.scala.1
deleted file mode 100755
index 910418ba65..0000000000
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala.1
+++ /dev/null
@@ -1,1047 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2009 LAMP/EPFL
- * @author Martin Odersky
- */
-// $Id: Namers.scala 17117 2009-02-16 14:56:54Z odersky $
-
-package scala.tools.nsc.typechecker
-
-import scala.collection.mutable.HashMap
-import scala.tools.nsc.util.Position
-import symtab.Flags
-import symtab.Flags._
-
-/** This trait declares methods to create symbols and to enter them into scopes.
- *
- * @author Martin Odersky
- * @version 1.0
- */
-trait Namers { self: Analyzer =>
- import global._
- import definitions._
- import posAssigner.atPos
-
- /** Convert to corresponding type parameters all skolems of method parameters
- * which appear in `tparams`.
- */
- class DeSkolemizeMap(tparams: List[Symbol]) extends TypeMap {
- def apply(tp: Type): Type = tp match {
- case TypeRef(pre, sym, args)
- if (sym.isTypeSkolem && (tparams contains sym.deSkolemize)) =>
-// println("DESKOLEMIZING "+sym+" in "+sym.owner)
- mapOver(rawTypeRef(NoPrefix, sym.deSkolemize, args))
-/*
- case PolyType(tparams1, restpe) =>
- new DeSkolemizeMap(tparams1 ::: tparams).mapOver(tp)
- case ClassInfoType(parents, decls, clazz) =>
- val parents1 = List.mapConserve(parents)(this)
- if (parents1 eq parents) tp else ClassInfoType(parents1, decls, clazz)
-*/
- case _ =>
- mapOver(tp)
- }
- }
-
- private class NormalNamer(context : Context) extends Namer(context)
- def newNamer(context : Context) : Namer = new NormalNamer(context)
-
- private[typechecker] val caseClassOfModuleClass = new HashMap[Symbol, ClassDef]
-
- def resetNamer() {
- caseClassOfModuleClass.clear
- }
-
- abstract class Namer(val context: Context) {
-
- val typer = newTyper(context)
-
- def setPrivateWithin[Sym <: Symbol](tree: Tree, sym: Sym, mods: Modifiers): Sym = {
- if (!mods.privateWithin.isEmpty)
- sym.privateWithin = typer.qualifyingClassContext(tree, mods.privateWithin, true).owner
- sym
- }
-
- def inConstructorFlag: Long =
- if (context.owner.isConstructor && !context.inConstructorSuffix || context.owner.isEarly) INCONSTRUCTOR
- else 0l
-
- def moduleClassFlags(moduleFlags: Long) =
- (moduleFlags & ModuleToClassFlags) | FINAL | inConstructorFlag
-
- def updatePosFlags(sym: Symbol, pos: Position, flags: Long): Symbol = {
- if (settings.debug.value) log("overwriting " + sym)
- val lockedFlag = sym.flags & LOCKED
- sym.reset(NoType)
- sym setPos pos
- sym.flags = flags | lockedFlag
- if (sym.isModule && sym.moduleClass != NoSymbol)
- updatePosFlags(sym.moduleClass, pos, moduleClassFlags(flags))
- if (sym.owner.isPackageClass &&
- (sym.linkedSym.rawInfo.isInstanceOf[loaders.SymbolLoader] ||
- sym.linkedSym.rawInfo.isComplete && runId(sym.validTo) != currentRunId))
- // pre-set linked symbol to NoType, in case it is not loaded together with this symbol.
- sym.linkedSym.setInfo(NoType)
- sym
- }
-
- private def isTemplateContext(context: Context): Boolean = context.tree match {
- case Template(_, _, _) => true
- case Import(_, _) => isTemplateContext(context.outer)
- case _ => false
- }
-
- private var innerNamerCache: Namer = null
- protected def makeConstructorScope(classContext : Context) : Context = {
- val outerContext = classContext.outer.outer
- outerContext.makeNewScope(outerContext.tree, outerContext.owner)(Constructor1ScopeKind)
- }
-
- def namerOf(sym: Symbol): Namer = {
-
- def innerNamer: Namer = {
- if (innerNamerCache eq null)
- innerNamerCache =
- if (!isTemplateContext(context)) this
- else newNamer(context.make(context.tree, context.owner, scopeFor(context.tree, InnerScopeKind)))
- innerNamerCache
- }
-
- def primaryConstructorParamNamer: Namer = { //todo: can we merge this with SCCmode?
- val classContext = context.enclClass
- val paramContext = makeConstructorScope(classContext)
- val unsafeTypeParams = context.owner.unsafeTypeParams
- unsafeTypeParams foreach(sym => paramContext.scope.enter(sym))
- newNamer(paramContext)
- }
- if (sym.isTerm) {
- if (sym.hasFlag(PARAM) && sym.owner.isPrimaryConstructor)
- primaryConstructorParamNamer
- else if (sym.hasFlag(PARAMACCESSOR) && !inIDE)
- primaryConstructorParamNamer
- else innerNamer
- } else innerNamer
- }
-
- protected def conflict(newS : Symbol, oldS : Symbol) : Boolean = {
- (!oldS.isSourceMethod ||
- nme.isSetterName(newS.name) ||
- newS.owner.isPackageClass) &&
- !((newS.owner.isTypeParameter || newS.owner.isAbstractType) &&
- newS.name.length==1 && newS.name(0)=='_') //@M: allow repeated use of `_' for higher-order type params
- }
-
- // IDE hook
- protected def setInfo[Sym <: Symbol](sym : Sym)(tpe : LazyType) : Sym = sym.setInfo(tpe)
-
- private def doubleDefError(pos: Position, sym: Symbol) {
- context.error(pos,
- sym.name.toString() + " is already defined as " +
- (if (sym.hasFlag(SYNTHETIC))
- "(compiler-generated) "+ (if (sym.isModule) "case class companion " else "")
- else "") +
- (if (sym.hasFlag(CASE)) "case class " + sym.name else sym.toString()))
- }
-
- private def inCurrentScope(m: Symbol): Boolean = {
- if (context.owner.isClass) context.owner == m.owner
- else m.owner.isClass && context.scope == m.owner.info.decls
- }
-
- def enterInScope(sym: Symbol): Symbol = enterInScope(sym, context.scope)
-
- def enterInScope(sym: Symbol, scope: Scope): Symbol = {
- // allow for overloaded methods
- if (!(sym.isSourceMethod && sym.owner.isClass && !sym.owner.isPackageClass)) {
- var prev = scope.lookupEntryWithContext(sym.name)(context.owner);
- if ((prev ne null) && inIDE) {
- var guess = prev
- while ((guess ne null) && (guess.sym ne sym)) guess = scope.lookupNextEntry(guess)
- if (guess != null) prev = guess
- while (prev != null && (!prev.sym.hasRawInfo || !prev.sym.rawInfo.isComplete ||
- (prev.sym.sourceFile == null && sym.getClass == prev.sym.getClass))) {
- if (!prev.sym.hasRawInfo || prev.sym.rawInfo.isComplete) {
- Console.println("DITCHING: " + prev.sym)
- }
- scope unlink prev.sym
- prev = scope.lookupNextEntry(prev)
- }
- val sym0 = scope enter sym
- if (sym0 ne sym) {
- Console.println("WEIRD: " + sym0 + " vs. " + sym + " " + sym0.id + " " + sym.id + " " + sym.sourceFile + " " + sym0.sourceFile)
- }
- if (prev != null && (sym0 ne prev.sym) && conflict(sym0,prev.sym)) {
- doubleDefError(sym0.pos, prev.sym)
- }
- sym0
- } else if ((prev ne null) && prev.owner == scope && conflict(sym, prev.sym)) {
- doubleDefError(sym.pos, prev.sym)
- sym setInfo ErrorType // don't do this in IDE for stability
- scope unlink prev.sym // let them co-exist...
- scope enter sym
- } else scope enter sym
- } else scope enter sym
- }
-
- def enterPackageSymbol(pos: Position, name: Name): Symbol = {
- val (cscope, cowner) =
- if (context.owner == EmptyPackageClass) (RootClass.info.decls, RootClass)
- else (context.scope, context.owner)
- val p: Symbol = cscope.lookupWithContext(name)(context.owner)
- if (p.isPackage && cscope == p.owner.info.decls) {
- p
- } else {
- val pkg = cowner.newPackage(pos, name)
- // IDE: newScope should be ok because packages are never destroyed.
- if (inIDE) assert(!pkg.moduleClass.hasRawInfo || !pkg.moduleClass.rawInfo.isComplete)
- pkg.moduleClass.setInfo(new PackageClassInfoType(newScope, pkg.moduleClass, null))
- pkg.setInfo(pkg.moduleClass.tpe)
- enterInScope(pkg, cscope)
- }
- }
-
- def enterClassSymbol(tree : ClassDef): Symbol = {
- var c: Symbol = context.scope.lookupWithContext(tree.name)(context.owner);
- if (!inIDE && c.isType && c.owner.isPackageClass && context.scope == c.owner.info.decls && !currentRun.compiles(c)) {
- updatePosFlags(c, tree.pos, tree.mods.flags)
- setPrivateWithin(tree, c, tree.mods)
- } else {
- var sym = context.owner.newClass(tree.pos, tree.name)
- sym = sym.setFlag(tree.mods.flags | inConstructorFlag)
- sym = setPrivateWithin(tree, sym, tree.mods)
- c = enterInScope(sym)
- }
- if (c.owner.isPackageClass) {
- val file = context.unit.source.file
- val clazz = c.asInstanceOf[ClassSymbol]
- if (settings.debug.value && (clazz.sourceFile ne null) && !clazz.sourceFile.equals(file)) {
- Console.err.println("SOURCE MISMATCH: " + clazz.sourceFile + " vs. " + file + " SYM=" + c);
- }
- clazz.sourceFile = file
- if (clazz.sourceFile ne null) {
- assert(inIDE || !currentRun.compiles(clazz) || clazz.sourceFile == currentRun.symSource(c));
- currentRun.symSource(c) = clazz.sourceFile
- }
- }
- assert(c.name.toString.indexOf('(') == -1)
- c
- }
-
- /** Enter a module symbol. The tree parameter can be either a module definition
- * or a class definition */
- def enterModuleSymbol(tree : ModuleDef): Symbol = {
- // .pos, mods.flags | MODULE | FINAL, name
- var m: Symbol = context.scope.lookupWithContext(tree.name)(context.owner)
- val moduleFlags = tree.mods.flags | MODULE | FINAL
- if (m.isModule && !m.isPackage && inCurrentScope(m) &&
- ((!inIDE && !currentRun.compiles(m)) || (m hasFlag SYNTHETIC))) {
- updatePosFlags(m, tree.pos, moduleFlags)
- setPrivateWithin(tree, m, tree.mods)
- context.unit.synthetics -= m
- } else {
- m = context.owner.newModule(tree.pos, tree.name)
- m.setFlag(moduleFlags)
- m = setPrivateWithin(tree, m, tree.mods)
- m = enterInScope(m)
-
- m.moduleClass.setFlag(moduleClassFlags(moduleFlags))
- setPrivateWithin(tree, m.moduleClass, tree.mods)
- }
- if (m.owner.isPackageClass) {
- m.moduleClass.sourceFile = context.unit.source.file
- currentRun.symSource(m) = m.moduleClass.sourceFile
- }
- m
- }
-
- def enterSyms(trees: List[Tree]): Namer = {
- var namer : Namer = this
- for (tree <- trees) {
- val txt = namer.enterSym(tree)
- if (!(txt eq namer.context)) namer = newNamer(txt)
- }
- namer
- }
-
- def newTypeSkolems(tparams: List[Symbol]): List[Symbol] = {
- val tskolems = tparams map (_.newTypeSkolem)
- val ltp = new LazyType {
- override def complete(sym: Symbol) {
- sym setInfo sym.deSkolemize.info.substSym(tparams, tskolems) //@M the info of a skolem is the skolemized info of the actual type parameter of the skolem
- }
- }
- tskolems foreach (_.setInfo(ltp))
- tskolems
- }
-
- /** Replace type parameters with their TypeSkolems, which can later be deskolemized to the original type param
- * (a skolem is a representation of a bound variable when viewed inside its scope)
- */
- def skolemize(tparams: List[TypeDef]) {
- val tskolems = newTypeSkolems(tparams map (_.symbol))
- for ((tparam, tskolem) <- tparams zip tskolems) tparam.symbol = tskolem
- }
-
- def applicableTypeParams(owner: Symbol): List[Symbol] =
- if (inIDE && (owner eq NoSymbol)) List()
- else if (owner.isTerm || owner.isPackageClass) List()
- else applicableTypeParams(owner.owner) ::: owner.typeParams
-
- def enterSym(tree: Tree): Context = try {
-
- def finishWith(tparams: List[TypeDef]) {
- val sym = tree.symbol
- if (settings.debug.value) log("entered " + sym + " in " + context.owner + ", scope-id = " + context.scope.hashCode());
- var ltype = namerOf(sym).typeCompleter(tree)
- if (!tparams.isEmpty) {
- //@M! TypeDef's type params are handled differently
- //@M e.g., in [A[x <: B], B], A and B are entered first as both are in scope in the definition of x
- //@M x is only in scope in `A[x <: B]'
- if(!sym.isAbstractType) //@M TODO: change to isTypeMember ?
- newNamer(context.makeNewScope(tree, sym)(FinishWithScopeKind)).enterSyms(tparams)
- ltype = new PolyTypeCompleter(tparams, ltype, tree, sym, context) //@M
- if (sym.isTerm) skolemize(tparams)
- }
- setInfo(sym)(ltype)
- }
- def finish = finishWith(List())
-
- if (tree.symbol == NoSymbol) {
- val owner = context.owner
- tree match {
- case PackageDef(name, stats) =>
- tree.symbol = enterPackageSymbol(tree.pos, name)
- val namer = newNamer(
- context.make(tree, tree.symbol.moduleClass, tree.symbol.info.decls))
- namer.enterSyms(stats)
- case tree @ ClassDef(mods, name, tparams, impl) =>
- tree.symbol = enterClassSymbol(tree)
- finishWith(tparams)
- if ((mods.flags & CASE) != 0) {
- var m: Symbol = context.scope.lookupWithContext(tree.name.toTermName)(context.owner).filter(! _.isSourceMethod)
- if (!(m.isModule && inCurrentScope(m) && (inIDE || currentRun.compiles(m)))) {
- m = enterSyntheticSym(caseModuleDef(tree))
- }
- caseClassOfModuleClass(m.moduleClass) = tree
- }
- case tree @ ModuleDef(mods, name, _) =>
- tree.symbol = enterModuleSymbol(tree)
- tree.symbol.moduleClass.setInfo(namerOf(tree.symbol).moduleClassTypeCompleter((tree)))
- finish
-
- case ValDef(mods, name, tp, rhs) =>
- if ((!context.owner.isClass ||
- (mods.flags & (PRIVATE | LOCAL)) == (PRIVATE | LOCAL) ||
- name.endsWith(nme.OUTER, nme.OUTER.length) ||
- context.unit.isJava) &&
- (mods.flags & LAZY) == 0) {
- tree.symbol = enterInScope(owner.newValue(tree.pos, name)
- .setFlag(mods.flags))
- finish
- } else {
- // add getter and possibly also setter
- val accflags: Long = ACCESSOR |
- (if ((mods.flags & MUTABLE) != 0) mods.flags & ~MUTABLE & ~PRESUPER
- else mods.flags & ~PRESUPER | STABLE)
- if (nme.isSetterName(name))
- context.error(tree.pos, "Names of vals or vars may not end in `_='")
- var getter = owner.newMethod(tree.pos, name).setFlag(accflags)
- setPrivateWithin(tree, getter, mods)
- getter = enterInScope(getter).asInstanceOf[TermSymbol]
- setInfo(getter)(namerOf(getter).getterTypeCompleter(tree))
- if ((mods.flags & MUTABLE) != 0) {
- var setter = owner.newMethod(tree.pos, nme.getterToSetter(name))
- .setFlag(accflags & ~STABLE & ~CASEACCESSOR)
- setPrivateWithin(tree, setter, mods)
- setter = enterInScope(setter).asInstanceOf[TermSymbol]
- setInfo(setter)(namerOf(setter).setterTypeCompleter(tree))
- }
- tree.symbol =
- if ((mods.flags & DEFERRED) == 0) {
- 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
- }
- 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
- } catch {
- case ex: TypeError =>
- //Console.println("caught " + ex + " in enterSym")//DEBUG
- typer.reportTypeError(tree.pos, ex)
- 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)+sym.locationString)
- 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 =>
- val moduleSymbol = tree.symbol
- assert(moduleSymbol.moduleClass == sym)
- if (inIDE && moduleSymbol.rawInfo.isComplete) {
- // reset!
- }
- moduleSymbol.info // sets moduleClass info as a side effect.
- //assert(sym.rawInfo.isComplete)
- }
- }
-
- 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
- }
- }
- var templateNamer = newNamer(context.make(templ, clazz, decls))
- templateNamer = templateNamer.enterSyms(template.body filter treeInfo.isEarlyType)
- var parents = typer.parentTypes(templ) map checkParent
- enterSelf(templ.self)
- val decls = newClassScope(clazz)
- templateNamer = templateNamer.enterSyms(templ.body)
-
- /* add overridden virtuals to parents
- val overridden = clazz.overriddenVirtuals
- if (!overridden.isEmpty)
- parents = parents ::: ( overridden map (
- sym => TypeRef(clazz.owner.thisType, sym, clazz.typeParams map (_.tpe))))
- println("Parents of "+clazz+":"+parents)
-
- // check that virtual classses are only defined as members of templates
- if (clazz.isVirtualClass && !clazz.owner.isClass)
- context.error(
- clazz.pos,
- "virtual traits and their subclasses must be defined as members of some other class")
-
- // make subclasses of virtual classes virtual as well; check that
- // they are defined in same scope.
- val virtualParents = parents map (_.typeSymbol) filter (_.isVirtualClass)
- virtualParents find {
- vp => !(clazz.owner.isClass && (clazz.owner isSubClass vp.owner))
- } match {
- case Some(vp) =>
- context.error(
- clazz.pos,
- "subclass of virtual "+vp+
- " needs to be defined at same level,\nas member of "+vp.owner)
- case None =>
- if (!virtualParents.isEmpty) clazz setFlag DEFERRED // make it virtual
- }
- */
-
- // add apply and unapply methods to companion objects of case classes,
- // unless they exist already
- Namers.this.caseClassOfModuleClass get clazz match {
- case Some(cdef) =>
- val go = if (inIDE) { // garbage collect in the presentaiton compiler.
- assert(cdef.symbol != null && cdef.symbol != NoSymbol)
- if (!cdef.symbol.isClass || !cdef.symbol.hasFlag(CASE) || cdef.symbol.rawInfo == NoType) false
- else true
- } else true
- if (go)
- addApplyUnapply(cdef, templateNamer)
- if (!go || !inIDE) caseClassOfModuleClass -= clazz
- if (!go) {
- val rem = clazz.linkedModuleOfClass
- assert(rem != NoSymbol)
- }
- 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....
-
- enterValueParams(meth.owner.owner, vparamss)
- } else {
- enterValueParams(meth, vparamss)
- }
- if (tpt.isEmpty && meth.name == nme.CONSTRUCTOR) {
- tpt.tpe = context.enclClass.owner.tpe
- tpt setPos meth.pos
- }
-
- if (onlyPresentation && methodArgumentNames != null)
- 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 (vparam =>
- if (meth hasFlag JAVA) objToAny(vparam.tpe) else vparam.tpe)
- val restpe1 = convertToDeBruijn(vparams, 1)(restpe)
- if (!vparams.isEmpty && vparams.head.hasFlag(IMPLICIT))
- ImplicitMethodType(formals, restpe1)
- else if (meth hasFlag JAVA) JavaMethodType(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.tpt setPos vparam.pos
- 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
- }
-
- thisMethodType(
- if (tpt.isEmpty) {
- val pt = resultPt.substSym(tparamSyms, tparams map (_.symbol))
- tpt.tpe = widenIfNotFinal(meth, typer.computeType(rhs, pt), pt)
- tpt setPos meth.pos
- tpt.tpe
- } else typer.typedType(tpt).tpe)
- }
-
- //@M! an abstract type definition (abstract type member/type parameter) may take type parameters, which are in scope in its bounds
- private def typeDefSig(tpsym: Symbol, tparams: List[TypeDef], rhs: Tree) = {
- val tparamSyms = typer.reenterTypeParams(tparams) //@M make tparams available in scope (just for this abstypedef)
- val tp = typer.typedType(rhs).tpe match {
- case TypeBounds(lt, rt) if (lt.isError || rt.isError) =>
- TypeBounds(NothingClass.tpe, AnyClass.tpe)
- case tp @ TypeBounds(lt, rt) if (tpsym hasFlag JAVA) =>
- TypeBounds(lt, objToAny(rt))
- case tp =>
- tp
- }
-
- def verifyOverriding(other: Symbol): Boolean = {
- if(other.unsafeTypeParams.length != tparamSyms.length) {
- context.error(tpsym.pos,
- "The kind of "+tpsym.keyString+" "+tpsym.varianceString + tpsym.nameString+
- " does not conform to the expected kind of " + other.defString + other.locationString + ".")
- false
- } else true
- }
-
- // @M: make sure overriding in refinements respects rudimentary kinding
- // have to do this early, as otherwise we might get crashes: (see neg/bug1275.scala)
- // suppose some parameterized type member is overridden by a type member w/o params,
- // then appliedType will be called on a type that does not expect type args --> crash
- if (tpsym.owner.isRefinementClass && // only needed in refinements
- !tpsym.allOverriddenSymbols.forall{verifyOverriding(_)})
- ErrorType
- else polyType(tparamSyms, tp)
- }
-
- /** Given a case class
- *
- * case class C[Ts] (ps: Us)
- *
- * Add the following methods to toScope:
- *
- * 1. if case class is not abstract, add
- *
- * <synthetic> <case> def apply[Ts](ps: Us): C[Ts] = new C[Ts](ps)
- *
- * 2. add a method
- *
- * <synthetic> <case> def unapply[Ts](x: C[Ts]) = <ret-val>
- *
- * where <ret-val> is the caseClassUnapplyReturnValue of class C (see UnApplies.scala)
- */
- def addApplyUnapply(cdef: ClassDef, namer: Namer) {
- if (!(cdef.symbol hasFlag ABSTRACT))
- namer.enterSyntheticSym(caseModuleApplyMeth(cdef))
- namer.enterSyntheticSym(caseModuleUnapplyMeth(cdef))
- }
-
- def typeSig(tree: Tree): Type = {
- val sym: Symbol = tree.symbol
- tree match {
- case defn: MemberDef =>
- val ainfos = for {
- annot <- defn.mods.annotations
- val ainfo = typer.typedAnnotation(annot, tree.symbol)
- if !ainfo.atp.isError && annot != null
- } yield ainfo
- if (!ainfos.isEmpty) {
- val annotated = if (sym.isModule) sym.moduleClass else sym
- annotated.attributes = ainfos
- }
- case _ =>
- }
- implicit val scopeKind = TypeSigScopeKind
- val result =
- try {
- tree match {
- case ClassDef(_, _, tparams, impl) =>
- newNamer(context.makeNewScope(tree, sym)).classSig(tparams, impl)
-
- case ModuleDef(_, _, impl) =>
- val clazz = sym.moduleClass
- clazz.setInfo(newNamer(context.makeNewScope(tree, clazz)).templateSig(impl))
- //clazz.typeOfThis = singleType(sym.owner.thisType, sym);
- clazz.tpe
-
- case DefDef(_, _, tparams, vparamss, tpt, rhs) =>
- //val result =
- newNamer(context.makeNewScope(tree, sym)).methodSig(tparams, vparamss, tpt, rhs)
-
- case vdef @ ValDef(mods, _, tpt, rhs) =>
- val typer1 = typer.constrTyperIf(sym.hasFlag(PARAM | PRESUPER) && sym.owner.isConstructor)
- if (tpt.isEmpty) {
- if (rhs.isEmpty) {
- context.error(tpt.pos, "missing parameter type");
- ErrorType
- } else {
- tpt.tpe = widenIfNotFinal(
- sym,
- newTyper(typer1.context.make(vdef, sym)).computeType(rhs, WildcardType),
- WildcardType)
- tpt setPos vdef.pos
- tpt.tpe
- }
- } else typer1.typedType(tpt).tpe
-
- case TypeDef(_, _, tparams, rhs) =>
- newNamer(context.makeNewScope(tree, sym)).typeDefSig(sym, tparams, rhs) //@M!
-
- case Import(expr, selectors) =>
- val expr1 = typer.typedQualifier(expr)
- val base = expr1.tpe
- typer.checkStable(expr1)
- if (expr1.symbol.isRootPackage) context.error(tree.pos, "_root_ cannot be imported")
- def checkNotRedundant(pos: Position, from: Name, to: Name): Boolean = {
- if (!tree.symbol.hasFlag(SYNTHETIC) &&
- !((expr1.symbol ne null) && expr1.symbol.isInterpreterWrapper) &&
- base.member(from) != NoSymbol) {
- val e = context.scope.lookupEntryWithContext(to)(context.owner)
- def warnRedundant(sym: Symbol) =
- context.unit.warning(pos, "imported `"+to+
- "' is permanently hidden by definition of "+sym+
- sym.locationString)
- if ((e ne null) && e.owner == context.scope) {
- warnRedundant(e.sym); return false
- } else if (context eq context.enclClass) {
- val defSym = context.prefix.member(to) filter (
- sym => sym.exists && context.isAccessible(sym, context.prefix, false))
- if (defSym != NoSymbol) { warnRedundant(defSym); return false }
- }
- }
- true
- }
- def checkSelectors(selectors: List[(Name, Name)]): Unit = selectors match {
- case (from, to) :: rest =>
- if (from != nme.WILDCARD && base != ErrorType) {
- if (base.member(from) == NoSymbol && base.member(from.toTypeName) == NoSymbol)
- context.error(tree.pos, from.decode + " is not a member of " + expr);
- if (checkNotRedundant(tree.pos, from, to))
- checkNotRedundant(tree.pos, from.toTypeName, to.toTypeName)
- }
- if (from != nme.WILDCARD && (rest.exists (sel => sel._1 == from)))
- context.error(tree.pos, from.decode + " is renamed twice");
- if ((to ne null) && to != nme.WILDCARD && (rest exists (sel => sel._2 == to)))
- context.error(tree.pos, to.decode + " appears twice as a target of a renaming");
- checkSelectors(rest)
- case Nil =>
- }
- checkSelectors(selectors)
- ImportType(expr1)
- }
- } catch {
- case ex: TypeError =>
- //Console.println("caught " + ex + " in typeSig")//DEBUG
- typer.reportTypeError(tree.pos, ex)
- ErrorType
- }
- result match {
- case PolyType(tparams, restpe)
- if (!tparams.isEmpty && tparams.head.owner.isTerm ||
- // Adriaan: The added conditon below is quite a hack. It seems that HK type parameters is relying
- // on a pass that forces all infos in the type to get everything right.
- // The problem is that the same pass causes cyclic reference errors in
- // test pos/cyclics.scala. It turned out that deSkolemize is run way more often than necessary,
- // ruinning it only when needed fixes the cuclic reference errors.
- // But correcting deSkolemize broke HK types, because we don't do the traversal anymore.
- // For the moment I made a special hack to do the traversal if we have HK type parameters.
- // Maybe it's not a hack, then we need to document it better. But ideally, we should find
- // a way to deal with HK types that's not dependent on accidental side
- // effects like this.
- tparams.exists(!_.typeParams.isEmpty)) =>
- new DeSkolemizeMap(tparams) mapOver result
- case _ =>
-// println("not skolemizing "+result+" in "+context.owner)
-// new DeSkolemizeMap(List()) mapOver result
- result
- }
- }
-
- /** Check that symbol's definition is well-formed. This means:
- * - no conflicting modifiers
- * - `abstract' modifier only for classes
- * - `override' modifier never for classes
- * - `def' modifier never for parameters of case classes
- * - declarations only in mixins or abstract classes (when not @native)
- */
- def validate(sym: Symbol) {
- def checkNoConflict(flag1: Int, flag2: Int) {
- if (sym.hasFlag(flag1) && sym.hasFlag(flag2))
- context.error(sym.pos,
- if (flag1 == DEFERRED)
- "abstract member may not have " + Flags.flagsToString(flag2) + " modifier";
- else
- "illegal combination of modifiers: " +
- Flags.flagsToString(flag1) + " and " + Flags.flagsToString(flag2) +
- " for: " + sym + Flags.flagsToString(sym.rawflags));
- }
-
- if (sym.hasFlag(IMPLICIT) && !sym.isTerm)
- context.error(sym.pos, "`implicit' modifier can be used only for values, variables and methods")
- if (sym.hasFlag(IMPLICIT) && sym.owner.isPackageClass && !inIDE)
- context.error(sym.pos, "`implicit' modifier cannot be used for top-level objects")
- if (sym.hasFlag(ABSTRACT) && !sym.isClass)
- context.error(sym.pos, "`abstract' modifier can be used only for classes; " +
- "\nit should be omitted for abstract members")
- if (sym.hasFlag(OVERRIDE | ABSOVERRIDE) && !sym.hasFlag(TRAIT) && sym.isClass)
- context.error(sym.pos, "`override' modifier not allowed for classes")
- if (sym.hasFlag(OVERRIDE | ABSOVERRIDE) && sym.isConstructor)
- context.error(sym.pos, "`override' modifier not allowed for constructors")
- if (sym.hasFlag(ABSOVERRIDE) && !sym.owner.isTrait)
- context.error(sym.pos, "`abstract override' modifier only allowed for members of traits")
- if (sym.hasFlag(LAZY) && sym.hasFlag(PRESUPER))
- context.error(sym.pos, "`lazy' definitions may not be initialized early")
- if (sym.info.typeSymbol == FunctionClass(0) &&
- sym.isValueParameter && sym.owner.isClass && sym.owner.hasFlag(CASE))
- context.error(sym.pos, "pass-by-name arguments not allowed for case class parameters");
- if (sym hasFlag DEFERRED) { // virtual classes count, too
- if (sym.hasAttribute(definitions.NativeAttr))
- sym.resetFlag(DEFERRED)
- else if (!sym.isValueParameter && !sym.isTypeParameterOrSkolem &&
- !context.tree.isInstanceOf[ExistentialTypeTree] &&
- (!sym.owner.isClass || sym.owner.isModuleClass || sym.owner.isAnonymousClass)) {
- context.error(sym.pos,
- "only classes can have declared but undefined members" + varNotice(sym))
- sym.resetFlag(DEFERRED)
- }
- }
-
- checkNoConflict(DEFERRED, PRIVATE)
- checkNoConflict(FINAL, SEALED)
- checkNoConflict(PRIVATE, PROTECTED)
- checkNoConflict(PRIVATE, OVERRIDE)
- /* checkNoConflict(PRIVATE, FINAL) // can't do this because FINAL also means compile-time constant */
- checkNoConflict(DEFERRED, FINAL)
- }
- }
-
- abstract class TypeCompleter extends LazyType {
- val tree: Tree
- }
-
- def mkTypeCompleter(t: Tree)(c: Symbol => Unit) = new TypeCompleter {
- val tree = t
- override def complete(sym: Symbol) = c(sym)
- }
-
- /** A class representing a lazy type with known type parameters.
- */
- class PolyTypeCompleter(tparams: List[Tree], restp: TypeCompleter, owner: Tree, ownerSym: Symbol, ctx: Context) extends TypeCompleter {
- override val typeParams: List[Symbol]= tparams map (_.symbol) //@M
- override val tree = restp.tree
- override def complete(sym: Symbol) {
- if(ownerSym.isAbstractType) //@M an abstract type's type parameters are entered -- TODO: change to isTypeMember ?
- newNamer(ctx.makeNewScope(owner, ownerSym)(PolyTypeCompleterScopeKind)).enterSyms(tparams) //@M
- restp.complete(sym)
- }
- }
-
- /** The symbol that which this accessor represents (possibly in part).
- * This is used for error messages, where we want to speak in terms
- * of the actual declaration or definition, not in terms of the generated setters
- * and getters */
- def underlying(member: Symbol): Symbol =
- if (member hasFlag ACCESSOR) {
- if (member.isDeferred) {
- val getter = if (member.isSetter) member.getter(member.owner) else member
- if (inIDE && getter == NoSymbol) return NoSymbol;
- val result = getter.owner.newValue(getter.pos, getter.name)
- .setInfo(getter.tpe.resultType)
- .setFlag(DEFERRED)
- if (getter.setter(member.owner) != NoSymbol) result.setFlag(MUTABLE)
- result
- } else member.accessed
- } else member
-
- /** An explanatory note to be added to error messages
- * when there's a problem with abstract var defs */
- def varNotice(sym: Symbol): String =
- if (underlying(sym).isVariable)
- "\n(Note that variables need to be initialized to be defined)"
- else ""
-}
-
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala.2 b/src/compiler/scala/tools/nsc/typechecker/Namers.scala.2
deleted file mode 100755
index bffde363c0..0000000000
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala.2
+++ /dev/null
@@ -1,1046 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2009 LAMP/EPFL
- * @author Martin Odersky
- */
-// $Id: Namers.scala 17114 2009-02-15 16:43:36Z odersky $
-
-package scala.tools.nsc.typechecker
-
-import scala.collection.mutable.HashMap
-import scala.tools.nsc.util.Position
-import symtab.Flags
-import symtab.Flags._
-
-/** This trait declares methods to create symbols and to enter them into scopes.
- *
- * @author Martin Odersky
- * @version 1.0
- */
-trait Namers { self: Analyzer =>
- import global._
- import definitions._
- import posAssigner.atPos
-
- /** Convert to corresponding type parameters all skolems of method parameters
- * which appear in `tparams`.
- */
- class DeSkolemizeMap(tparams: List[Symbol]) extends TypeMap {
- def apply(tp: Type): Type = tp match {
- case TypeRef(pre, sym, args)
- if (sym.isTypeSkolem && (tparams contains sym.deSkolemize)) =>
-// println("DESKOLEMIZING "+sym+" in "+sym.owner)
- mapOver(rawTypeRef(NoPrefix, sym.deSkolemize, args))
-/*
- case PolyType(tparams1, restpe) =>
- new DeSkolemizeMap(tparams1 ::: tparams).mapOver(tp)
- case ClassInfoType(parents, decls, clazz) =>
- val parents1 = List.mapConserve(parents)(this)
- if (parents1 eq parents) tp else ClassInfoType(parents1, decls, clazz)
-*/
- case _ =>
- mapOver(tp)
- }
- }
-
- private class NormalNamer(context : Context) extends Namer(context)
- def newNamer(context : Context) : Namer = new NormalNamer(context)
-
- private[typechecker] val caseClassOfModuleClass = new HashMap[Symbol, ClassDef]
-
- def resetNamer() {
- caseClassOfModuleClass.clear
- }
-
- abstract class Namer(val context: Context) {
-
- val typer = newTyper(context)
-
- def setPrivateWithin[Sym <: Symbol](tree: Tree, sym: Sym, mods: Modifiers): Sym = {
- if (!mods.privateWithin.isEmpty)
- sym.privateWithin = typer.qualifyingClassContext(tree, mods.privateWithin, true).owner
- sym
- }
-
- def inConstructorFlag: Long =
- if (context.owner.isConstructor && !context.inConstructorSuffix || context.owner.isEarly) INCONSTRUCTOR
- else 0l
-
- def moduleClassFlags(moduleFlags: Long) =
- (moduleFlags & ModuleToClassFlags) | FINAL | inConstructorFlag
-
- def updatePosFlags(sym: Symbol, pos: Position, flags: Long): Symbol = {
- if (settings.debug.value) log("overwriting " + sym)
- val lockedFlag = sym.flags & LOCKED
- sym.reset(NoType)
- sym setPos pos
- sym.flags = flags | lockedFlag
- if (sym.isModule && sym.moduleClass != NoSymbol)
- updatePosFlags(sym.moduleClass, pos, moduleClassFlags(flags))
- if (sym.owner.isPackageClass &&
- (sym.linkedSym.rawInfo.isInstanceOf[loaders.SymbolLoader] ||
- sym.linkedSym.rawInfo.isComplete && runId(sym.validTo) != currentRunId))
- // pre-set linked symbol to NoType, in case it is not loaded together with this symbol.
- sym.linkedSym.setInfo(NoType)
- sym
- }
-
- private def isTemplateContext(context: Context): Boolean = context.tree match {
- case Template(_, _, _) => true
- case Import(_, _) => isTemplateContext(context.outer)
- case _ => false
- }
-
- private var innerNamerCache: Namer = null
- protected def makeConstructorScope(classContext : Context) : Context = {
- val outerContext = classContext.outer.outer
- outerContext.makeNewScope(outerContext.tree, outerContext.owner)(Constructor1ScopeKind)
- }
-
- def namerOf(sym: Symbol): Namer = {
-
- def innerNamer: Namer = {
- if (innerNamerCache eq null)
- innerNamerCache =
- if (!isTemplateContext(context)) this
- else newNamer(context.make(context.tree, context.owner, scopeFor(context.tree, InnerScopeKind)))
- innerNamerCache
- }
-
- def primaryConstructorParamNamer: Namer = { //todo: can we merge this with SCCmode?
- val classContext = context.enclClass
- val paramContext = makeConstructorScope(classContext)
- val unsafeTypeParams = context.owner.unsafeTypeParams
- unsafeTypeParams foreach(sym => paramContext.scope.enter(sym))
- newNamer(paramContext)
- }
- if (sym.isTerm) {
- if (sym.hasFlag(PARAM) && sym.owner.isPrimaryConstructor)
- primaryConstructorParamNamer
- else if (sym.hasFlag(PARAMACCESSOR) && !inIDE)
- primaryConstructorParamNamer
- else innerNamer
- } else innerNamer
- }
-
- protected def conflict(newS : Symbol, oldS : Symbol) : Boolean = {
- (!oldS.isSourceMethod ||
- nme.isSetterName(newS.name) ||
- newS.owner.isPackageClass) &&
- !((newS.owner.isTypeParameter || newS.owner.isAbstractType) &&
- newS.name.length==1 && newS.name(0)=='_') //@M: allow repeated use of `_' for higher-order type params
- }
-
- // IDE hook
- protected def setInfo[Sym <: Symbol](sym : Sym)(tpe : LazyType) : Sym = sym.setInfo(tpe)
-
- private def doubleDefError(pos: Position, sym: Symbol) {
- context.error(pos,
- sym.name.toString() + " is already defined as " +
- (if (sym.hasFlag(SYNTHETIC))
- "(compiler-generated) "+ (if (sym.isModule) "case class companion " else "")
- else "") +
- (if (sym.hasFlag(CASE)) "case class " + sym.name else sym.toString()))
- }
-
- private def inCurrentScope(m: Symbol): Boolean = {
- if (context.owner.isClass) context.owner == m.owner
- else m.owner.isClass && context.scope == m.owner.info.decls
- }
-
- def enterInScope(sym: Symbol): Symbol = enterInScope(sym, context.scope)
-
- def enterInScope(sym: Symbol, scope: Scope): Symbol = {
- // allow for overloaded methods
- if (!(sym.isSourceMethod && sym.owner.isClass && !sym.owner.isPackageClass)) {
- var prev = scope.lookupEntryWithContext(sym.name)(context.owner);
- if ((prev ne null) && inIDE) {
- var guess = prev
- while ((guess ne null) && (guess.sym ne sym)) guess = scope.lookupNextEntry(guess)
- if (guess != null) prev = guess
- while (prev != null && (!prev.sym.hasRawInfo || !prev.sym.rawInfo.isComplete ||
- (prev.sym.sourceFile == null && sym.getClass == prev.sym.getClass))) {
- if (!prev.sym.hasRawInfo || prev.sym.rawInfo.isComplete) {
- Console.println("DITCHING: " + prev.sym)
- }
- scope unlink prev.sym
- prev = scope.lookupNextEntry(prev)
- }
- val sym0 = scope enter sym
- if (sym0 ne sym) {
- Console.println("WEIRD: " + sym0 + " vs. " + sym + " " + sym0.id + " " + sym.id + " " + sym.sourceFile + " " + sym0.sourceFile)
- }
- if (prev != null && (sym0 ne prev.sym) && conflict(sym0,prev.sym)) {
- doubleDefError(sym0.pos, prev.sym)
- }
- sym0
- } else if ((prev ne null) && prev.owner == scope && conflict(sym, prev.sym)) {
- doubleDefError(sym.pos, prev.sym)
- sym setInfo ErrorType // don't do this in IDE for stability
- scope unlink prev.sym // let them co-exist...
- scope enter sym
- } else scope enter sym
- } else scope enter sym
- }
-
- def enterPackageSymbol(pos: Position, name: Name): Symbol = {
- val (cscope, cowner) =
- if (context.owner == EmptyPackageClass) (RootClass.info.decls, RootClass)
- else (context.scope, context.owner)
- val p: Symbol = cscope.lookupWithContext(name)(context.owner)
- if (p.isPackage && cscope == p.owner.info.decls) {
- p
- } else {
- val pkg = cowner.newPackage(pos, name)
- // IDE: newScope should be ok because packages are never destroyed.
- if (inIDE) assert(!pkg.moduleClass.hasRawInfo || !pkg.moduleClass.rawInfo.isComplete)
- pkg.moduleClass.setInfo(new PackageClassInfoType(newScope, pkg.moduleClass, null))
- pkg.setInfo(pkg.moduleClass.tpe)
- enterInScope(pkg, cscope)
- }
- }
-
- def enterClassSymbol(tree : ClassDef): Symbol = {
- var c: Symbol = context.scope.lookupWithContext(tree.name)(context.owner);
- if (!inIDE && c.isType && c.owner.isPackageClass && context.scope == c.owner.info.decls && !currentRun.compiles(c)) {
- updatePosFlags(c, tree.pos, tree.mods.flags)
- setPrivateWithin(tree, c, tree.mods)
- } else {
- var sym = context.owner.newClass(tree.pos, tree.name)
- sym = sym.setFlag(tree.mods.flags | inConstructorFlag)
- sym = setPrivateWithin(tree, sym, tree.mods)
- c = enterInScope(sym)
- }
- if (c.owner.isPackageClass) {
- val file = context.unit.source.file
- val clazz = c.asInstanceOf[ClassSymbol]
- if (settings.debug.value && (clazz.sourceFile ne null) && !clazz.sourceFile.equals(file)) {
- Console.err.println("SOURCE MISMATCH: " + clazz.sourceFile + " vs. " + file + " SYM=" + c);
- }
- clazz.sourceFile = file
- if (clazz.sourceFile ne null) {
- assert(inIDE || !currentRun.compiles(clazz) || clazz.sourceFile == currentRun.symSource(c));
- currentRun.symSource(c) = clazz.sourceFile
- }
- }
- assert(c.name.toString.indexOf('(') == -1)
- c
- }
-
- /** Enter a module symbol. The tree parameter can be either a module definition
- * or a class definition */
- def enterModuleSymbol(tree : ModuleDef): Symbol = {
- // .pos, mods.flags | MODULE | FINAL, name
- var m: Symbol = context.scope.lookupWithContext(tree.name)(context.owner)
- val moduleFlags = tree.mods.flags | MODULE | FINAL
- if (m.isModule && !m.isPackage && inCurrentScope(m) &&
- ((!inIDE && !currentRun.compiles(m)) || (m hasFlag SYNTHETIC))) {
- updatePosFlags(m, tree.pos, moduleFlags)
- setPrivateWithin(tree, m, tree.mods)
- context.unit.synthetics -= m
- } else {
- m = context.owner.newModule(tree.pos, tree.name)
- m.setFlag(moduleFlags)
- m = setPrivateWithin(tree, m, tree.mods)
- m = enterInScope(m)
-
- m.moduleClass.setFlag(moduleClassFlags(moduleFlags))
- setPrivateWithin(tree, m.moduleClass, tree.mods)
- }
- if (m.owner.isPackageClass) {
- m.moduleClass.sourceFile = context.unit.source.file
- currentRun.symSource(m) = m.moduleClass.sourceFile
- }
- m
- }
-
- def enterSyms(trees: List[Tree]): Namer = {
- var namer : Namer = this
- for (tree <- trees) {
- val txt = namer.enterSym(tree)
- if (!(txt eq namer.context)) namer = newNamer(txt)
- }
- namer
- }
-
- def newTypeSkolems(tparams: List[Symbol]): List[Symbol] = {
- val tskolems = tparams map (_.newTypeSkolem)
- val ltp = new LazyType {
- override def complete(sym: Symbol) {
- sym setInfo sym.deSkolemize.info.substSym(tparams, tskolems) //@M the info of a skolem is the skolemized info of the actual type parameter of the skolem
- }
- }
- tskolems foreach (_.setInfo(ltp))
- tskolems
- }
-
- /** Replace type parameters with their TypeSkolems, which can later be deskolemized to the original type param
- * (a skolem is a representation of a bound variable when viewed inside its scope)
- */
- def skolemize(tparams: List[TypeDef]) {
- val tskolems = newTypeSkolems(tparams map (_.symbol))
- for ((tparam, tskolem) <- tparams zip tskolems) tparam.symbol = tskolem
- }
-
- def applicableTypeParams(owner: Symbol): List[Symbol] =
- if (inIDE && (owner eq NoSymbol)) List()
- else if (owner.isTerm || owner.isPackageClass) List()
- else applicableTypeParams(owner.owner) ::: owner.typeParams
-
- def enterSym(tree: Tree): Context = try {
-
- def finishWith(tparams: List[TypeDef]) {
- val sym = tree.symbol
- if (settings.debug.value) log("entered " + sym + " in " + context.owner + ", scope-id = " + context.scope.hashCode());
- var ltype = namerOf(sym).typeCompleter(tree)
- if (!tparams.isEmpty) {
- //@M! TypeDef's type params are handled differently
- //@M e.g., in [A[x <: B], B], A and B are entered first as both are in scope in the definition of x
- //@M x is only in scope in `A[x <: B]'
- if(!sym.isAbstractType) //@M TODO: change to isTypeMember ?
- newNamer(context.makeNewScope(tree, sym)(FinishWithScopeKind)).enterSyms(tparams)
- ltype = new PolyTypeCompleter(tparams, ltype, tree, sym, context) //@M
- if (sym.isTerm) skolemize(tparams)
- }
- setInfo(sym)(ltype)
- }
- def finish = finishWith(List())
-
- if (tree.symbol == NoSymbol) {
- val owner = context.owner
- tree match {
- case PackageDef(name, stats) =>
- tree.symbol = enterPackageSymbol(tree.pos, name)
- val namer = newNamer(
- context.make(tree, tree.symbol.moduleClass, tree.symbol.info.decls))
- namer.enterSyms(stats)
- case tree @ ClassDef(mods, name, tparams, impl) =>
- tree.symbol = enterClassSymbol(tree)
- finishWith(tparams)
- if ((mods.flags & CASE) != 0) {
- var m: Symbol = context.scope.lookupWithContext(tree.name.toTermName)(context.owner).filter(! _.isSourceMethod)
- if (!(m.isModule && inCurrentScope(m) && (inIDE || currentRun.compiles(m)))) {
- m = enterSyntheticSym(caseModuleDef(tree))
- }
- caseClassOfModuleClass(m.moduleClass) = tree
- }
- case tree @ ModuleDef(mods, name, _) =>
- tree.symbol = enterModuleSymbol(tree)
- tree.symbol.moduleClass.setInfo(namerOf(tree.symbol).moduleClassTypeCompleter((tree)))
- finish
-
- case ValDef(mods, name, tp, rhs) =>
- if ((!context.owner.isClass ||
- (mods.flags & (PRIVATE | LOCAL)) == (PRIVATE | LOCAL) ||
- name.endsWith(nme.OUTER, nme.OUTER.length) ||
- context.unit.isJava) &&
- (mods.flags & LAZY) == 0) {
- tree.symbol = enterInScope(owner.newValue(tree.pos, name)
- .setFlag(mods.flags))
- finish
- } else {
- // add getter and possibly also setter
- val accflags: Long = ACCESSOR |
- (if ((mods.flags & MUTABLE) != 0) mods.flags & ~MUTABLE & ~PRESUPER
- else mods.flags & ~PRESUPER | STABLE)
- if (nme.isSetterName(name))
- context.error(tree.pos, "Names of vals or vars may not end in `_='")
- var getter = owner.newMethod(tree.pos, name).setFlag(accflags)
- setPrivateWithin(tree, getter, mods)
- getter = enterInScope(getter).asInstanceOf[TermSymbol]
- setInfo(getter)(namerOf(getter).getterTypeCompleter(tree))
- if ((mods.flags & MUTABLE) != 0) {
- var setter = owner.newMethod(tree.pos, nme.getterToSetter(name))
- .setFlag(accflags & ~STABLE & ~CASEACCESSOR)
- setPrivateWithin(tree, setter, mods)
- setter = enterInScope(setter).asInstanceOf[TermSymbol]
- setInfo(setter)(namerOf(setter).setterTypeCompleter(tree))
- }
- tree.symbol =
- if ((mods.flags & DEFERRED) == 0) {
- 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
- }
- 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
- } catch {
- case ex: TypeError =>
- //Console.println("caught " + ex + " in enterSym")//DEBUG
- typer.reportTypeError(tree.pos, ex)
- 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)+sym.locationString)
- 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 =>
- val moduleSymbol = tree.symbol
- assert(moduleSymbol.moduleClass == sym)
- if (inIDE && moduleSymbol.rawInfo.isComplete) {
- // reset!
- }
- moduleSymbol.info // sets moduleClass info as a side effect.
- //assert(sym.rawInfo.isComplete)
- }
- }
-
- 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
- }
- }
- var parents = typer.parentTypes(templ) map checkParent
- enterSelf(templ.self)
- val decls = newClassScope(clazz)
- val templateNamer = newNamer(context.make(templ, clazz, decls))
- .enterSyms(templ.body)
-
- /* add overridden virtuals to parents
- val overridden = clazz.overriddenVirtuals
- if (!overridden.isEmpty)
- parents = parents ::: ( overridden map (
- sym => TypeRef(clazz.owner.thisType, sym, clazz.typeParams map (_.tpe))))
- println("Parents of "+clazz+":"+parents)
-
- // check that virtual classses are only defined as members of templates
- if (clazz.isVirtualClass && !clazz.owner.isClass)
- context.error(
- clazz.pos,
- "virtual traits and their subclasses must be defined as members of some other class")
-
- // make subclasses of virtual classes virtual as well; check that
- // they are defined in same scope.
- val virtualParents = parents map (_.typeSymbol) filter (_.isVirtualClass)
- virtualParents find {
- vp => !(clazz.owner.isClass && (clazz.owner isSubClass vp.owner))
- } match {
- case Some(vp) =>
- context.error(
- clazz.pos,
- "subclass of virtual "+vp+
- " needs to be defined at same level,\nas member of "+vp.owner)
- case None =>
- if (!virtualParents.isEmpty) clazz setFlag DEFERRED // make it virtual
- }
- */
-
- // add apply and unapply methods to companion objects of case classes,
- // unless they exist already
- Namers.this.caseClassOfModuleClass get clazz match {
- case Some(cdef) =>
- val go = if (inIDE) { // garbage collect in the presentaiton compiler.
- assert(cdef.symbol != null && cdef.symbol != NoSymbol)
- if (!cdef.symbol.isClass || !cdef.symbol.hasFlag(CASE) || cdef.symbol.rawInfo == NoType) false
- else true
- } else true
- if (go)
- addApplyUnapply(cdef, templateNamer)
- if (!go || !inIDE) caseClassOfModuleClass -= clazz
- if (!go) {
- val rem = clazz.linkedModuleOfClass
- assert(rem != NoSymbol)
- }
- 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....
-
- enterValueParams(meth.owner.owner, vparamss)
- } else {
- enterValueParams(meth, vparamss)
- }
- if (tpt.isEmpty && meth.name == nme.CONSTRUCTOR) {
- tpt.tpe = context.enclClass.owner.tpe
- tpt setPos meth.pos
- }
-
- if (onlyPresentation && methodArgumentNames != null)
- 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 (vparam =>
- if (meth hasFlag JAVA) objToAny(vparam.tpe) else vparam.tpe)
- val restpe1 = convertToDeBruijn(vparams, 1)(restpe)
- if (!vparams.isEmpty && vparams.head.hasFlag(IMPLICIT))
- ImplicitMethodType(formals, restpe1)
- else if (meth hasFlag JAVA) JavaMethodType(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.tpt setPos vparam.pos
- 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
- }
-
- thisMethodType(
- if (tpt.isEmpty) {
- val pt = resultPt.substSym(tparamSyms, tparams map (_.symbol))
- tpt.tpe = widenIfNotFinal(meth, typer.computeType(rhs, pt), pt)
- tpt setPos meth.pos
- tpt.tpe
- } else typer.typedType(tpt).tpe)
- }
-
- //@M! an abstract type definition (abstract type member/type parameter) may take type parameters, which are in scope in its bounds
- private def typeDefSig(tpsym: Symbol, tparams: List[TypeDef], rhs: Tree) = {
- val tparamSyms = typer.reenterTypeParams(tparams) //@M make tparams available in scope (just for this abstypedef)
- val tp = typer.typedType(rhs).tpe match {
- case TypeBounds(lt, rt) if (lt.isError || rt.isError) =>
- TypeBounds(NothingClass.tpe, AnyClass.tpe)
- case tp @ TypeBounds(lt, rt) if (tpsym hasFlag JAVA) =>
- TypeBounds(lt, objToAny(rt))
- case tp =>
- tp
- }
-
- def verifyOverriding(other: Symbol): Boolean = {
- if(other.unsafeTypeParams.length != tparamSyms.length) {
- context.error(tpsym.pos,
- "The kind of "+tpsym.keyString+" "+tpsym.varianceString + tpsym.nameString+
- " does not conform to the expected kind of " + other.defString + other.locationString + ".")
- false
- } else true
- }
-
- // @M: make sure overriding in refinements respects rudimentary kinding
- // have to do this early, as otherwise we might get crashes: (see neg/bug1275.scala)
- // suppose some parameterized type member is overridden by a type member w/o params,
- // then appliedType will be called on a type that does not expect type args --> crash
- if (tpsym.owner.isRefinementClass && // only needed in refinements
- !tpsym.allOverriddenSymbols.forall{verifyOverriding(_)})
- ErrorType
- else polyType(tparamSyms, tp)
- }
-
- /** Given a case class
- *
- * case class C[Ts] (ps: Us)
- *
- * Add the following methods to toScope:
- *
- * 1. if case class is not abstract, add
- *
- * <synthetic> <case> def apply[Ts](ps: Us): C[Ts] = new C[Ts](ps)
- *
- * 2. add a method
- *
- * <synthetic> <case> def unapply[Ts](x: C[Ts]) = <ret-val>
- *
- * where <ret-val> is the caseClassUnapplyReturnValue of class C (see UnApplies.scala)
- */
- def addApplyUnapply(cdef: ClassDef, namer: Namer) {
- if (!(cdef.symbol hasFlag ABSTRACT))
- namer.enterSyntheticSym(caseModuleApplyMeth(cdef))
- namer.enterSyntheticSym(caseModuleUnapplyMeth(cdef))
- }
-
- def typeSig(tree: Tree): Type = {
- val sym: Symbol = tree.symbol
- tree match {
- case defn: MemberDef =>
- val ainfos = for {
- annot <- defn.mods.annotations
- val ainfo = typer.typedAnnotation(annot, tree.symbol)
- if !ainfo.atp.isError && annot != null
- } yield ainfo
- if (!ainfos.isEmpty) {
- val annotated = if (sym.isModule) sym.moduleClass else sym
- annotated.attributes = ainfos
- }
- case _ =>
- }
- implicit val scopeKind = TypeSigScopeKind
- val result =
- try {
- tree match {
- case ClassDef(_, _, tparams, impl) =>
- newNamer(context.makeNewScope(tree, sym)).classSig(tparams, impl)
-
- case ModuleDef(_, _, impl) =>
- val clazz = sym.moduleClass
- clazz.setInfo(newNamer(context.makeNewScope(tree, clazz)).templateSig(impl))
- //clazz.typeOfThis = singleType(sym.owner.thisType, sym);
- clazz.tpe
-
- case DefDef(_, _, tparams, vparamss, tpt, rhs) =>
- //val result =
- newNamer(context.makeNewScope(tree, sym)).methodSig(tparams, vparamss, tpt, rhs)
-
- case vdef @ ValDef(mods, _, tpt, rhs) =>
- val typer1 = typer.constrTyperIf(sym.hasFlag(PARAM | PRESUPER) && sym.owner.isConstructor)
- if (tpt.isEmpty) {
- if (rhs.isEmpty) {
- context.error(tpt.pos, "missing parameter type");
- ErrorType
- } else {
- tpt.tpe = widenIfNotFinal(
- sym,
- newTyper(typer1.context.make(vdef, sym)).computeType(rhs, WildcardType),
- WildcardType)
- tpt setPos vdef.pos
- tpt.tpe
- }
- } else typer1.typedType(tpt).tpe
-
- case TypeDef(_, _, tparams, rhs) =>
- newNamer(context.makeNewScope(tree, sym)).typeDefSig(sym, tparams, rhs) //@M!
-
- case Import(expr, selectors) =>
- val expr1 = typer.typedQualifier(expr)
- val base = expr1.tpe
- typer.checkStable(expr1)
- if (expr1.symbol.isRootPackage) context.error(tree.pos, "_root_ cannot be imported")
- def checkNotRedundant(pos: Position, from: Name, to: Name): Boolean = {
- if (!tree.symbol.hasFlag(SYNTHETIC) &&
- !((expr1.symbol ne null) && expr1.symbol.isInterpreterWrapper) &&
- base.member(from) != NoSymbol) {
- val e = context.scope.lookupEntryWithContext(to)(context.owner)
- def warnRedundant(sym: Symbol) =
- context.unit.warning(pos, "imported `"+to+
- "' is permanently hidden by definition of "+sym+
- sym.locationString)
- if ((e ne null) && e.owner == context.scope) {
- warnRedundant(e.sym); return false
- } else if (context eq context.enclClass) {
- val defSym = context.prefix.member(to) filter (
- sym => sym.exists && context.isAccessible(sym, context.prefix, false))
- if (defSym != NoSymbol) { warnRedundant(defSym); return false }
- }
- }
- true
- }
- def checkSelectors(selectors: List[(Name, Name)]): Unit = selectors match {
- case (from, to) :: rest =>
- if (from != nme.WILDCARD && base != ErrorType) {
- if (base.member(from) == NoSymbol && base.member(from.toTypeName) == NoSymbol)
- context.error(tree.pos, from.decode + " is not a member of " + expr);
- if (checkNotRedundant(tree.pos, from, to))
- checkNotRedundant(tree.pos, from.toTypeName, to.toTypeName)
- }
- if (from != nme.WILDCARD && (rest.exists (sel => sel._1 == from)))
- context.error(tree.pos, from.decode + " is renamed twice");
- if ((to ne null) && to != nme.WILDCARD && (rest exists (sel => sel._2 == to)))
- context.error(tree.pos, to.decode + " appears twice as a target of a renaming");
- checkSelectors(rest)
- case Nil =>
- }
- checkSelectors(selectors)
- ImportType(expr1)
- }
- } catch {
- case ex: TypeError =>
- //Console.println("caught " + ex + " in typeSig")//DEBUG
- typer.reportTypeError(tree.pos, ex)
- ErrorType
- }
- result match {
- case PolyType(tparams, restpe)
- if (!tparams.isEmpty && tparams.head.owner.isTerm ||
- // Adriaan: The added conditon below is quite a hack. It seems that HK type parameters is relying
- // on a pass that forces all infos in the type to get everything right.
- // The problem is that the same pass causes cyclic reference errors in
- // test pos/cyclics.scala. It turned out that deSkolemize is run way more often than necessary,
- // ruinning it only when needed fixes the cuclic reference errors.
- // But correcting deSkolemize broke HK types, because we don't do the traversal anymore.
- // For the moment I made a special hack to do the traversal if we have HK type parameters.
- // Maybe it's not a hack, then we need to document it better. But ideally, we should find
- // a way to deal with HK types that's not dependent on accidental side
- // effects like this.
- tparams.exists(!_.typeParams.isEmpty)) =>
- new DeSkolemizeMap(tparams) mapOver result
- case _ =>
-// println("not skolemizing "+result+" in "+context.owner)
-// new DeSkolemizeMap(List()) mapOver result
- result
- }
- }
-
- /** Check that symbol's definition is well-formed. This means:
- * - no conflicting modifiers
- * - `abstract' modifier only for classes
- * - `override' modifier never for classes
- * - `def' modifier never for parameters of case classes
- * - declarations only in mixins or abstract classes (when not @native)
- */
- def validate(sym: Symbol) {
- def checkNoConflict(flag1: Int, flag2: Int) {
- if (sym.hasFlag(flag1) && sym.hasFlag(flag2))
- context.error(sym.pos,
- if (flag1 == DEFERRED)
- "abstract member may not have " + Flags.flagsToString(flag2) + " modifier";
- else
- "illegal combination of modifiers: " +
- Flags.flagsToString(flag1) + " and " + Flags.flagsToString(flag2) +
- " for: " + sym + Flags.flagsToString(sym.rawflags));
- }
-
- if (sym.hasFlag(IMPLICIT) && !sym.isTerm)
- context.error(sym.pos, "`implicit' modifier can be used only for values, variables and methods")
- if (sym.hasFlag(IMPLICIT) && sym.owner.isPackageClass && !inIDE)
- context.error(sym.pos, "`implicit' modifier cannot be used for top-level objects")
- if (sym.hasFlag(ABSTRACT) && !sym.isClass)
- context.error(sym.pos, "`abstract' modifier can be used only for classes; " +
- "\nit should be omitted for abstract members")
- if (sym.hasFlag(OVERRIDE | ABSOVERRIDE) && !sym.hasFlag(TRAIT) && sym.isClass)
- context.error(sym.pos, "`override' modifier not allowed for classes")
- if (sym.hasFlag(OVERRIDE | ABSOVERRIDE) && sym.isConstructor)
- context.error(sym.pos, "`override' modifier not allowed for constructors")
- if (sym.hasFlag(ABSOVERRIDE) && !sym.owner.isTrait)
- context.error(sym.pos, "`abstract override' modifier only allowed for members of traits")
- if (sym.hasFlag(LAZY) && sym.hasFlag(PRESUPER))
- context.error(sym.pos, "`lazy' definitions may not be initialized early")
- if (sym.info.typeSymbol == FunctionClass(0) &&
- sym.isValueParameter && sym.owner.isClass && sym.owner.hasFlag(CASE))
- context.error(sym.pos, "pass-by-name arguments not allowed for case class parameters");
- if (sym hasFlag DEFERRED) { // virtual classes count, too
- if (sym.hasAttribute(definitions.NativeAttr))
- sym.resetFlag(DEFERRED)
- else if (!sym.isValueParameter && !sym.isTypeParameterOrSkolem &&
- !context.tree.isInstanceOf[ExistentialTypeTree] &&
- (!sym.owner.isClass || sym.owner.isModuleClass || sym.owner.isAnonymousClass)) {
- context.error(sym.pos,
- "only classes can have declared but undefined members" + varNotice(sym))
- sym.resetFlag(DEFERRED)
- }
- }
-
- checkNoConflict(DEFERRED, PRIVATE)
- checkNoConflict(FINAL, SEALED)
- checkNoConflict(PRIVATE, PROTECTED)
- checkNoConflict(PRIVATE, OVERRIDE)
- /* checkNoConflict(PRIVATE, FINAL) // can't do this because FINAL also means compile-time constant */
- checkNoConflict(DEFERRED, FINAL)
- }
- }
-
- abstract class TypeCompleter extends LazyType {
- val tree: Tree
- }
-
- def mkTypeCompleter(t: Tree)(c: Symbol => Unit) = new TypeCompleter {
- val tree = t
- override def complete(sym: Symbol) = c(sym)
- }
-
- /** A class representing a lazy type with known type parameters.
- */
- class PolyTypeCompleter(tparams: List[Tree], restp: TypeCompleter, owner: Tree, ownerSym: Symbol, ctx: Context) extends TypeCompleter {
- override val typeParams: List[Symbol]= tparams map (_.symbol) //@M
- override val tree = restp.tree
- override def complete(sym: Symbol) {
- if(ownerSym.isAbstractType) //@M an abstract type's type parameters are entered -- TODO: change to isTypeMember ?
- newNamer(ctx.makeNewScope(owner, ownerSym)(PolyTypeCompleterScopeKind)).enterSyms(tparams) //@M
- restp.complete(sym)
- }
- }
-
- /** The symbol that which this accessor represents (possibly in part).
- * This is used for error messages, where we want to speak in terms
- * of the actual declaration or definition, not in terms of the generated setters
- * and getters */
- def underlying(member: Symbol): Symbol =
- if (member hasFlag ACCESSOR) {
- if (member.isDeferred) {
- val getter = if (member.isSetter) member.getter(member.owner) else member
- if (inIDE && getter == NoSymbol) return NoSymbol;
- val result = getter.owner.newValue(getter.pos, getter.name)
- .setInfo(getter.tpe.resultType)
- .setFlag(DEFERRED)
- if (getter.setter(member.owner) != NoSymbol) result.setFlag(MUTABLE)
- result
- } else member.accessed
- } else member
-
- /** An explanatory note to be added to error messages
- * when there's a problem with abstract var defs */
- def varNotice(sym: Symbol): String =
- if (underlying(sym).isVariable)
- "\n(Note that variables need to be initialized to be defined)"
- else ""
-}
-