summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala147
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala20
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolWalker.scala43
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala113
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala191
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala141
7 files changed, 317 insertions, 342 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 67f3f7f8b2..acc9aafa80 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -822,9 +822,38 @@ abstract class GenJVM extends SubComponent {
}
var linearization: List[BasicBlock] = Nil
-
var isModuleInitialized = false
+ private def genConstant(jcode: JExtendedCode, const: Constant) {
+ const.tag match {
+ case UnitTag => ()
+ case BooleanTag => jcode.emitPUSH(const.booleanValue)
+ case ByteTag => jcode.emitPUSH(const.byteValue)
+ case ShortTag => jcode.emitPUSH(const.shortValue)
+ case CharTag => jcode.emitPUSH(const.charValue)
+ case IntTag => jcode.emitPUSH(const.intValue)
+ case LongTag => jcode.emitPUSH(const.longValue)
+ case FloatTag => jcode.emitPUSH(const.floatValue)
+ case DoubleTag => jcode.emitPUSH(const.doubleValue)
+ case StringTag => jcode.emitPUSH(const.stringValue)
+ case NullTag => jcode.emitACONST_NULL()
+ case ClassTag =>
+ val kind = toTypeKind(const.typeValue)
+ val toPush =
+ if (kind.isValueType) classLiteral(kind)
+ else javaType(kind).asInstanceOf[JReferenceType]
+
+ jcode emitPUSH toPush
+
+ case EnumTag =>
+ val sym = const.symbolValue
+ jcode.emitGETSTATIC(javaName(sym.owner),
+ javaName(sym),
+ javaType(sym.tpe.underlying))
+ case _ => abort("Unknown constant value: " + const);
+ }
+ }
+
/**
* @param m ...
*/
@@ -835,7 +864,7 @@ abstract class GenJVM extends SubComponent {
if (settings.debug.value)
log("Making labels for: " + method)
- HashMap(bs map (b => b -> jcode.newLabel) : _*)
+ HashMap(bs map (_ -> jcode.newLabel) : _*)
}
isModuleInitialized = false
@@ -847,12 +876,11 @@ abstract class GenJVM extends SubComponent {
var nextBlock: BasicBlock = linearization.head
- def genBlocks(l: List[BasicBlock]): Unit = l match {
- case Nil => ()
- case x :: Nil => nextBlock = null; genBlock(x)
- case x :: y :: ys => nextBlock = y; genBlock(x); genBlocks(y :: ys)
- }
-
+ def genBlocks(l: List[BasicBlock]): Unit = l match {
+ case Nil => ()
+ case x :: Nil => nextBlock = null; genBlock(x)
+ case x :: y :: ys => nextBlock = y; genBlock(x); genBlocks(y :: ys)
+ }
/** Generate exception handlers for the current method. */
def genExceptionHandlers {
@@ -867,30 +895,28 @@ abstract class GenJVM extends SubComponent {
var start = -1
var end = -1
- linearization foreach ((b) => {
+ linearization foreach { b =>
if (! (covered contains b) ) {
if (start >= 0) { // we're inside a handler range
end = labels(b).getAnchor()
- ranges = (start, end) :: ranges
+ ranges ::= (start, end)
start = -1
}
} else {
- if (start >= 0) { // we're inside a handler range
- end = endPC(b)
- } else {
+ if (start < 0) // we're not inside a handler range
start = labels(b).getAnchor()
- end = endPC(b)
- }
- covered = covered - b
+
+ end = endPC(b)
+ covered -= b
}
- });
+ }
/* Add the last interval. Note that since the intervals are
* open-ended to the right, we have to give a number past the actual
* code!
*/
if (start >= 0) {
- ranges = (start, jcode.getPC()) :: ranges;
+ ranges ::= (start, jcode.getPC())
}
if (!covered.isEmpty)
@@ -900,19 +926,16 @@ abstract class GenJVM extends SubComponent {
ranges
}
- this.method.exh foreach { e =>
- ranges(e).sort({ (p1, p2) => p1._1 < p2._1 })
- .foreach { p =>
- if (p._1 < p._2) {
- if (settings.debug.value)
- log("Adding exception handler " + e + "at block: " + e.startBlock + " for " + method +
- " from: " + p._1 + " to: " + p._2 + " catching: " + e.cls);
- jcode.addExceptionHandler(p._1, p._2,
- labels(e.startBlock).getAnchor(),
- if (e.cls == NoSymbol) null else javaName(e.cls))
- } else
- log("Empty exception range: " + p)
- }
+ for (e <- this.method.exh ; p <- ranges(e).sortBy(_._1)) {
+ if (p._1 < p._2) {
+ if (settings.debug.value)
+ log("Adding exception handler " + e + "at block: " + e.startBlock + " for " + method +
+ " from: " + p._1 + " to: " + p._2 + " catching: " + e.cls);
+ jcode.addExceptionHandler(p._1, p._2,
+ labels(e.startBlock).getAnchor(),
+ if (e.cls == NoSymbol) null else javaName(e.cls))
+ } else
+ log("Empty exception range: " + p)
}
}
@@ -944,31 +967,7 @@ abstract class GenJVM extends SubComponent {
jcode.emitALOAD_0()
case CONSTANT(const) =>
- const.tag match {
- case UnitTag => ();
- case BooleanTag => jcode.emitPUSH(const.booleanValue)
- case ByteTag => jcode.emitPUSH(const.byteValue)
- case ShortTag => jcode.emitPUSH(const.shortValue)
- case CharTag => jcode.emitPUSH(const.charValue)
- case IntTag => jcode.emitPUSH(const.intValue)
- case LongTag => jcode.emitPUSH(const.longValue)
- case FloatTag => jcode.emitPUSH(const.floatValue)
- case DoubleTag => jcode.emitPUSH(const.doubleValue)
- case StringTag => jcode.emitPUSH(const.stringValue)
- case NullTag => jcode.emitACONST_NULL()
- case ClassTag =>
- val kind = toTypeKind(const.typeValue);
- if (kind.isValueType)
- jcode.emitPUSH(classLiteral(kind));
- else
- jcode.emitPUSH(javaType(kind).asInstanceOf[JReferenceType]);
- case EnumTag =>
- val sym = const.symbolValue
- jcode.emitGETSTATIC(javaName(sym.owner),
- javaName(sym),
- javaType(sym.tpe.underlying))
- case _ => abort("Unknown constant value: " + const);
- }
+ genConstant(jcode, const)
case LOAD_ARRAY_ITEM(kind) =>
jcode.emitALOAD(javaType(kind))
@@ -1029,46 +1028,36 @@ abstract class GenJVM extends SubComponent {
genPrimitive(primitive, instr.pos)
case call @ CALL_METHOD(method, style) =>
- val owner: String = javaName(method.owner);
- //reference the type of the receiver instead of the method owner (if not an interface!)
+ val owner: String = javaName(method.owner)
+ // reference the type of the receiver instead of the method owner (if not an interface!)
val dynamicOwner =
if (needsInterfaceCall(call.hostClass)) owner
else javaName(call.hostClass)
+ val jname = javaName(method)
+ val jtype = javaType(method).asInstanceOf[JMethodType]
style match {
case InvokeDynamic =>
- jcode.emitINVOKEINTERFACE("java.dyn.Dynamic",
- javaName(method),
- javaType(method).asInstanceOf[JMethodType])
+ jcode.emitINVOKEINTERFACE("java.dyn.Dynamic", jname, jtype)
case Dynamic =>
if (needsInterfaceCall(method.owner))
- jcode.emitINVOKEINTERFACE(owner,
- javaName(method),
- javaType(method).asInstanceOf[JMethodType])
+ jcode.emitINVOKEINTERFACE(owner, jname, jtype)
else
- jcode.emitINVOKEVIRTUAL(dynamicOwner,
- javaName(method),
- javaType(method).asInstanceOf[JMethodType]);
+ jcode.emitINVOKEVIRTUAL(dynamicOwner, jname, jtype)
case Static(instance) =>
- if (instance) {
- jcode.emitINVOKESPECIAL(owner,
- javaName(method),
- javaType(method).asInstanceOf[JMethodType]);
- } else
- jcode.emitINVOKESTATIC(owner,
- javaName(method),
- javaType(method).asInstanceOf[JMethodType]);
+ if (instance)
+ jcode.emitINVOKESPECIAL(owner, jname, jtype)
+ else
+ jcode.emitINVOKESTATIC(owner, jname, jtype)
case SuperCall(_) =>
- jcode.emitINVOKESPECIAL(owner,
- javaName(method),
- javaType(method).asInstanceOf[JMethodType]);
+ jcode.emitINVOKESPECIAL(owner, jname, jtype)
// we initialize the MODULE$ field immediately after the super ctor
if (isStaticModule(clasz.symbol) && !isModuleInitialized &&
jmethod.getName() == JMethod.INSTANCE_CONSTRUCTOR_NAME &&
- javaName(method) == JMethod.INSTANCE_CONSTRUCTOR_NAME) {
+ jname == JMethod.INSTANCE_CONSTRUCTOR_NAME) {
isModuleInitialized = true;
jcode.emitALOAD_0();
jcode.emitPUTSTATIC(jclass.getName(),
diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
index 39955f7003..194c99f800 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
@@ -23,6 +23,18 @@ abstract class Inliners extends SubComponent {
val phaseName = "inliner"
+ /** Debug - for timing the inliner. */
+ private def timed[T](s: String, body: => T): T = {
+ val t1 = System.currentTimeMillis()
+ val res = body
+ val t2 = System.currentTimeMillis()
+ val ms = (t2 - t1).toInt
+ if (ms >= 2000)
+ println("%s: %d milliseconds".format(s, ms))
+
+ res
+ }
+
/** The maximum size in basic blocks of methods considered for inlining. */
final val MAX_INLINE_SIZE = 16
@@ -269,9 +281,9 @@ abstract class Inliners extends SubComponent {
def analyzeClass(cls: IClass): Unit = if (settings.inline.value) {
if (settings.debug.value)
log("Analyzing " + cls);
- cls.methods.foreach { m => if (!m.symbol.isConstructor) analyzeMethod(m)
- }}
+ cls.methods filterNot (_.symbol.isConstructor) foreach analyzeMethod
+ }
val tfa = new analysis.MethodTFA();
tfa.stat = settings.Ystatistics.value
@@ -281,7 +293,7 @@ abstract class Inliners extends SubComponent {
override def default(k: Symbol) = 0
}
- def analyzeMethod(m: IMethod): Unit = {//try {
+ def analyzeMethod(m: IMethod): Unit = {
var retry = false
var count = 0
fresh.clear
@@ -371,7 +383,7 @@ abstract class Inliners extends SubComponent {
// e.printStackTrace();
// m.dump
// throw e
- }
+ }
def isMonadMethod(method: Symbol): Boolean =
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolWalker.scala b/src/compiler/scala/tools/nsc/symtab/SymbolWalker.scala
index 5f0574b525..f2e16b537a 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolWalker.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolWalker.scala
@@ -20,32 +20,35 @@ trait SymbolWalker {
def apply(pos : Position) : Symbol = map.apply(pos)
}
*/
+ private def validSym(t: Tree) = t.symbol != NoSymbol && t.symbol != null
+ private def validSym(tp: Type) = tp != null && tp.typeSymbol != NoSymbol && tp.typeSymbol != null
+ private def notNull(tp: Type) = tp.typeSymbol != null
+ private def isNoSymbol(t: Tree) = t.symbol eq NoSymbol
+
def walk(tree: Tree, visitor : Visitor)(fid : (util.Position) => Option[String]) : Unit = {
val visited = new LinkedHashSet[Tree]
def f(t : Tree) : Unit = {
if (visited.add(t)) return
- def fs(l : List[Tree]) : Unit = {
- val i = l.iterator
- while (i.hasNext) f(i.next)
- }
- def fss(l : List[List[Tree]]) : Unit = {
- val i = l.iterator
- while (i.hasNext) fs(i.next)
- }
+
+ def fs(l: List[Tree]) = l foreach f
+ def fss(l: List[List[Tree]]) = l foreach fs
+
if (t.isInstanceOf[StubTree]) return
- def asTypeRef = t.tpe.asInstanceOf[TypeRef]
- val sym = (t,t.tpe) match {
- case (Super(_,_),SuperType(_,supertp)) if supertp.typeSymbol != NoSymbol && supertp.typeSymbol != null => supertp.typeSymbol
- case _ if t.symbol != NoSymbol && t.symbol != null => t.symbol
- case (t : TypeTree, tp) if tp != null && tp.typeSymbol != null && tp.typeSymbol != NoSymbol => tp.typeSymbol
- case (t : TypeTree, tp) if tp != null && tp.resultType != null && tp.resultType.typeSymbol != null => tp.resultType.typeSymbol
- case (t, tpe : Type) if tpe != null && (t.symbol eq NoSymbol) && t.isTerm && tpe.termSymbol != null =>
- tpe.termSymbol
- case (t, tpe : Type) if tpe != null && (t.symbol eq NoSymbol) && tpe.typeSymbol != null =>
- if (t.tpe.isInstanceOf[TypeRef]) asTypeRef.sym // XXX: looks like a bug
- else tpe.typeSymbol
- case _ => NoSymbol
+
+ val sym = (t, t.tpe) match {
+ case (Super(_,_),SuperType(_,supertp)) if validSym(supertp) => supertp.typeSymbol
+ case _ if validSym(t) => t.symbol
+ case (t: TypeTree, tp) if validSym(tp) => tp.typeSymbol
+ case (t: TypeTree, tp) if validSym(tp.resultType) => tp.resultType.typeSymbol
+ case (t, tpe: Type) if isNoSymbol(t) && tpe.termSymbol != null =>
+ if (t.isTerm) tpe.termSymbol
+ else t.tpe match {
+ case x: TypeRef => x.sym // XXX: looks like a bug
+ case _ => tpe.typeSymbol
+ }
+ case _ => NoSymbol
}
+
if (sym != null && sym != NoSymbol /* && !sym.hasFlag(SYNTHETIC) */) {
var id = fid(t.pos)
val doAdd = if (id.isDefined) {
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index 3e0681ccdf..694fc9fe91 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -34,8 +34,8 @@ abstract class ICodeReader extends ClassfileParser {
var method: IMethod = _ // the current IMethod
val OBJECT: TypeKind = REFERENCE(definitions.ObjectClass)
- val nothingName = newTermName("scala.runtime.Nothing$")
- val nullName = newTermName("scala.runtime.Null$")
+ val nothingName = newTermName(SCALA_NOTHING)
+ val nullName = newTermName(SCALA_NULL)
var isScalaModule = false
/** Read back bytecode for the given class symbol. It returns
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index e36e8ffb02..bd4bde2511 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -290,52 +290,55 @@ trait Namers { self: Analyzer =>
if (m.isModule && inCurrentScope(m) && currentRun.compiles(m)) m
else enterSyntheticSym(creator)
}
-
- 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)).enterSyms(tparams)
-
- ltype = new PolyTypeCompleter(tparams, ltype, tree, sym, context) //@M
- if (sym.isTerm) skolemize(tparams)
- }
- def copyIsSynthetic() = sym.owner.info.member(nme.copy).hasFlag(SYNTHETIC)
- if (sym.name == nme.copy && sym.hasFlag(SYNTHETIC) ||
- sym.name.startsWith(nme.copy + "$default$") && copyIsSynthetic()){
- // the 'copy' method of case classes needs a special type completer to make bug0054.scala (and others)
- // work. the copy method has to take exactly the same parameter types as the primary constructor.
- setInfo(sym)(mkTypeCompleter(tree)(copySym => {
- val constrType = copySym.owner.primaryConstructor.tpe
- val subst = new SubstSymMap(copySym.owner.typeParams, tparams map (_.symbol))
- for ((params, cparams) <- tree.asInstanceOf[DefDef].vparamss.zip(constrType.paramss);
- (param, cparam) <- params.zip(cparams)) {
- // need to clone the type cparam.tpe??? problem is: we don't have the new owner yet (the new param symbol)
- param.tpt.setType(subst(cparam.tpe))
- () // @LUC TODO workaround for #1996
- }
- ltype.complete(sym)
- }))
- } else setInfo(sym)(ltype)
+ private def enterSymFinishWith(tree: Tree, 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)).enterSyms(tparams)
+
+ ltype = new PolyTypeCompleter(tparams, ltype, tree, sym, context) //@M
+ if (sym.isTerm) skolemize(tparams)
}
- def finish = finishWith(List())
+ def copyIsSynthetic() = sym.owner.info.member(nme.copy).hasFlag(SYNTHETIC)
+ if (sym.name == nme.copy && sym.hasFlag(SYNTHETIC) ||
+ sym.name.startsWith(nme.copy + "$default$") && copyIsSynthetic()){
+ // the 'copy' method of case classes needs a special type completer to make bug0054.scala (and others)
+ // work. the copy method has to take exactly the same parameter types as the primary constructor.
+ setInfo(sym)(mkTypeCompleter(tree)(copySym => {
+ val constrType = copySym.owner.primaryConstructor.tpe
+ val subst = new SubstSymMap(copySym.owner.typeParams, tparams map (_.symbol))
+ for ((params, cparams) <- tree.asInstanceOf[DefDef].vparamss.zip(constrType.paramss);
+ (param, cparam) <- params.zip(cparams)) {
+ // need to clone the type cparam.tpe??? problem is: we don't have the new owner yet (the new param symbol)
+ param.tpt.setType(subst(cparam.tpe))
+ () // @LUC TODO workaround for #1996
+ }
+ ltype.complete(sym)
+ }))
+ } else setInfo(sym)(ltype)
+ }
- if (tree.symbol == NoSymbol) {
+ def enterSym(tree: Tree): Context = {
+ def finishWith(tparams: List[TypeDef]) { enterSymFinishWith(tree, tparams) }
+ def finish = finishWith(Nil)
+ def sym = tree.symbol
+ if (sym != NoSymbol)
+ return this.context
+
+ try {
val owner = context.owner
tree match {
case PackageDef(pid, stats) =>
tree.symbol = enterPackageSymbol(tree.pos, pid,
if (context.owner == EmptyPackageClass) RootClass else context.owner)
- val namer = newNamer(
- context.make(tree, tree.symbol.moduleClass, tree.symbol.info.decls))
- namer.enterSyms(stats)
+ val namer = newNamer(context.make(tree, sym.moduleClass, sym.info.decls))
+ namer enterSyms stats
+
case tree @ ClassDef(mods, name, tparams, impl) =>
tree.symbol = enterClassSymbol(tree)
finishWith(tparams)
@@ -343,21 +346,18 @@ trait Namers { self: Analyzer =>
val m = ensureCompanionObject(tree, caseModuleDef(tree))
caseClassOfModuleClass(m.moduleClass) = tree
}
- val constrs = impl.body filter {
- case DefDef(_, name, _, _, _, _) => name == nme.CONSTRUCTOR
- case _ => false
- }
- val hasDefault = constrs.exists(c => {
- val DefDef(_, _, _, vparamss, _, _) = c
- vparamss.exists(_.exists(_.mods hasFlag DEFAULTPARAM))
- })
+ val hasDefault = impl.body flatMap {
+ case DefDef(_, nme.CONSTRUCTOR, _, vparamss, _, _) => vparamss.flatten
+ case _ => Nil
+ } exists (_.mods hasFlag DEFAULTPARAM)
+
if (hasDefault) {
val m = ensureCompanionObject(tree, companionModuleDef(tree, List(gen.scalaScalaObjectConstr)))
classAndNamerOfModule(m) = (tree, null)
}
case tree @ ModuleDef(mods, name, _) =>
tree.symbol = enterModuleSymbol(tree)
- tree.symbol.moduleClass.setInfo(namerOf(tree.symbol).moduleClassTypeCompleter((tree)))
+ sym.moduleClass setInfo namerOf(sym).moduleClassTypeCompleter(tree)
finish
case vd @ ValDef(mods, name, tp, rhs) =>
@@ -372,14 +372,14 @@ trait Namers { self: Analyzer =>
} else {
// add getter and possibly also setter
val accflags: Long = ACCESSOR |
- (if ((mods.flags & MUTABLE) != 0L) mods.flags & ~MUTABLE & ~PRESUPER
+ (if (mods.isVariable) 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 `_='")
// .isInstanceOf[..]: probably for (old) IDE hook. is this obsolete?
val getter = enterAliasMethod(tree, name, accflags, mods)
setInfo(getter)(namerOf(getter).getterTypeCompleter(vd))
- if ((mods.flags & MUTABLE) != 0L) {
+ if (mods.isVariable) {
val setter = enterAliasMethod(tree, nme.getterToSetter(name),
accflags & ~STABLE & ~CASEACCESSOR,
mods)
@@ -427,17 +427,18 @@ trait Namers { self: Analyzer =>
enterSym(defn)
case imp @ Import(_, _) =>
tree.symbol = NoSymbol.newImport(tree.pos)
- setInfo(tree.symbol)(namerOf(tree.symbol).typeCompleter(tree))
+ setInfo(sym)(namerOf(sym).typeCompleter(tree))
return (context.makeNewImport(imp))
case _ =>
}
}
+ catch {
+ case ex: TypeError =>
+ //Console.println("caught " + ex + " in enterSym")//DEBUG
+ typer.reportTypeError(tree.pos, ex)
+ this.context
+ }
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 = {
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 5001f8b9bf..b80a782e36 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -128,112 +128,107 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
tree
}
- override def transform(tree: Tree): Tree = try { tree match {
- case ClassDef(_, _, _, _) =>
- checkCompanionNameClashes(tree.symbol)
- val decls = tree.symbol.info.decls
- for (sym <- decls.toList) {
- if (sym.privateWithin.isClass && !sym.privateWithin.isModuleClass &&
- !sym.hasFlag(EXPANDEDNAME) && !sym.isConstructor) {
- decls.unlink(sym)
- sym.expandName(sym.privateWithin)
- decls.enter(sym)
- }
- }
- super.transform(tree)
- case ModuleDef(_, _, _) =>
- checkCompanionNameClashes(tree.symbol)
- super.transform(tree)
- case Template(parents, self, body) =>
- val ownAccDefs = new ListBuffer[Tree];
- accDefs = (currentOwner, ownAccDefs) :: accDefs;
-
- // ugly hack... normally, the following line should not be
- // necessary, the 'super' method taking care of that. but because
- // that one is iterating through parents (and we dont want that here)
- // we need to inline it.
- curTree = tree
- val body1 = atOwner(currentOwner) { transformTrees(body) }
- accDefs = accDefs.tail;
- treeCopy.Template(tree, parents, self, ownAccDefs.toList ::: body1);
-
- case TypeApply(sel @ Select(This(_), name), args) =>
- val sym = tree.symbol
- if (needsProtectedAccessor(sym, tree.pos)) {
- if (settings.debug.value) log("Adding protected accessor for " + tree);
- transform(makeAccessor(sel.asInstanceOf[Select], args))
- } else
- tree
+ override def transform(tree: Tree): Tree = {
+ val sym = tree.symbol
- case Select(qual @ This(_), name) =>
- val sym = tree.symbol
- if ((sym hasFlag PARAMACCESSOR) && (sym.alias != NoSymbol)) {
- val result = typed {
- Select(
- Super(qual.symbol, nme.EMPTY.toTypeName/*qual.symbol.info.parents.head.symbol.name*/) setPos qual.pos,
- sym.alias) setPos tree.pos
- }
+ def mayNeedProtectedAccessor(sel: Select, args: List[Tree], goToSuper: Boolean) =
+ if (needsProtectedAccessor(sym, tree.pos)) {
if (settings.debug.value)
- Console.println("alias replacement: " + tree + " ==> " + result);//debug
- transformSuperSelect(result)
- } else {
- if (needsProtectedAccessor(sym, tree.pos)) {
- if (settings.debug.value) log("Adding protected accessor for " + tree);
- transform(makeAccessor(tree.asInstanceOf[Select], List(EmptyTree)))
- } else
- tree
- }
- case Select(sup @ Super(_, mix), name) =>
- val sym = tree.symbol
- if (sym.isValue && !sym.isMethod || sym.hasFlag(ACCESSOR)) {
- unit.error(tree.pos, "super may be not be used on "+
- (if (sym.hasFlag(ACCESSOR)) sym.accessed else sym))
- }
- transformSuperSelect(tree)
+ log("Adding protected accessor for " + tree)
- case TypeApply(sel @ Select(qual, name), args) =>
- val sym = tree.symbol
- if (needsProtectedAccessor(sym, tree.pos)) {
- if (settings.debug.value) log("Adding protected accessor for tree: " + tree);
- transform(makeAccessor(sel.asInstanceOf[Select], args))
- } else
+ transform(makeAccessor(sel, args))
+ }
+ else if (goToSuper) super.transform(tree)
+ else tree
+
+ try tree match {
+ case ClassDef(_, _, _, _) =>
+ checkCompanionNameClashes(sym)
+ val decls = sym.info.decls
+ for (s <- decls.toList) {
+ if (s.privateWithin.isClass && !s.privateWithin.isModuleClass &&
+ !s.hasFlag(EXPANDEDNAME) && !s.isConstructor) {
+ decls.unlink(s)
+ s.expandName(s.privateWithin)
+ decls.enter(s)
+ }
+ }
super.transform(tree)
-
- case Select(qual, name) =>
- val sym = tree.symbol
- if (needsProtectedAccessor(sym, tree.pos)) {
- if (settings.debug.value) log("Adding protected accessor for tree: " + tree);
- transform(makeAccessor(tree.asInstanceOf[Select], List(EmptyTree)))
- } else
+ case ModuleDef(_, _, _) =>
+ checkCompanionNameClashes(sym)
super.transform(tree)
+ case Template(parents, self, body) =>
+ val ownAccDefs = new ListBuffer[Tree];
+ accDefs = (currentOwner, ownAccDefs) :: accDefs;
+
+ // ugly hack... normally, the following line should not be
+ // necessary, the 'super' method taking care of that. but because
+ // that one is iterating through parents (and we dont want that here)
+ // we need to inline it.
+ curTree = tree
+ val body1 = atOwner(currentOwner) { transformTrees(body) }
+ accDefs = accDefs.tail;
+ treeCopy.Template(tree, parents, self, ownAccDefs.toList ::: body1);
+
+ case TypeApply(sel @ Select(This(_), name), args) =>
+ mayNeedProtectedAccessor(sel, args, false)
+
+ case sel @ Select(qual @ This(_), name) =>
+ if ((sym hasFlag PARAMACCESSOR) && (sym.alias != NoSymbol)) {
+ val result = typed {
+ Select(
+ Super(qual.symbol, nme.EMPTY.toTypeName/*qual.symbol.info.parents.head.symbol.name*/) setPos qual.pos,
+ sym.alias) setPos tree.pos
+ }
+ if (settings.debug.value)
+ Console.println("alias replacement: " + tree + " ==> " + result);//debug
+ transformSuperSelect(result)
+ }
+ else mayNeedProtectedAccessor(sel, List(EmptyTree), false)
- case Assign(lhs @ Select(qual, name), rhs) =>
- if (lhs.symbol.isVariable &&
- lhs.symbol.hasFlag(JAVA) &&
- needsProtectedAccessor(lhs.symbol, tree.pos)) {
- if (settings.debug.value) log("Adding protected setter for " + tree)
- val setter = makeSetter(lhs);
- if (settings.debug.value)
- log("Replaced " + tree + " with " + setter);
- transform(typed(Apply(setter, List(qual, rhs))))
- } else
+ case Select(sup @ Super(_, mix), name) =>
+ if (sym.isValue && !sym.isMethod || sym.hasFlag(ACCESSOR)) {
+ unit.error(tree.pos, "super may be not be used on "+
+ (if (sym.hasFlag(ACCESSOR)) sym.accessed else sym))
+ }
+ transformSuperSelect(tree)
+
+ case TypeApply(sel @ Select(qual, name), args) =>
+ mayNeedProtectedAccessor(sel, args, true)
+
+ case sel @ Select(qual, name) =>
+ mayNeedProtectedAccessor(sel, List(EmptyTree), true)
+
+ case Assign(lhs @ Select(qual, name), rhs) =>
+ if (lhs.symbol.isVariable &&
+ lhs.symbol.hasFlag(JAVA) &&
+ needsProtectedAccessor(lhs.symbol, tree.pos)) {
+ if (settings.debug.value) log("Adding protected setter for " + tree)
+ val setter = makeSetter(lhs);
+ if (settings.debug.value)
+ log("Replaced " + tree + " with " + setter);
+ transform(typed(Apply(setter, List(qual, rhs))))
+ } else
+ super.transform(tree)
+
+ case Apply(fn, args) =>
+ assert(fn.tpe != null, tree)
+ treeCopy.Apply(tree, transform(fn), transformArgs(args, fn.tpe.paramTypes))
+ case Function(vparams, body) =>
+ withInvalidOwner {
+ treeCopy.Function(tree, vparams, transform(body))
+ }
+ case _ =>
super.transform(tree)
+ }
+ catch {
+ case ex : AssertionError =>
+ if (sym != null && sym != NoSymbol)
+ Console.println("TRANSFORM: " + tree.symbol.sourceFile)
- case Apply(fn, args) =>
- assert(fn.tpe != null, tree)
- treeCopy.Apply(tree, transform(fn), transformArgs(args, fn.tpe.paramTypes))
- case Function(vparams, body) =>
- withInvalidOwner {
- treeCopy.Function(tree, vparams, transform(body))
- }
- case _ =>
- super.transform(tree)
- }} catch {
- case ex : AssertionError =>
- if (tree.symbol != null && tree.symbol != NoSymbol)
- Console.println("TRANSFORM: " + tree.symbol.sourceFile)
- Console.println("TREE: " + tree)
- throw ex
+ Console.println("TREE: " + tree)
+ throw ex
+ }
}
override def atOwner[A](owner: Symbol)(trans: => A): A = {
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index 3e8e803c13..9eb89e26bb 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -42,7 +42,6 @@ abstract class TreeCheckers extends Analyzer {
override def newTyper(context: Context): Typer = new TreeChecker(context)
class TreeChecker(context0: Context) extends Typer(context0) {
-
import infer._
override def typed(tree: Tree, mode: Int, pt: Type): Tree = {
@@ -50,104 +49,80 @@ abstract class TreeCheckers extends Analyzer {
case EmptyTree | TypeTree() =>
;
case _ =>
- try {
- if (!tpeOfTree.contains(tree)) {
- tpeOfTree.update(tree, tree.tpe)
- tree.tpe = null
- }
- val newtree = super.typed(tree, mode, pt);
- if ((newtree ne tree) && !newtree.isInstanceOf[Literal])
- error(tree.pos, "trees differ\n old: " + tree + " [" + tree.getClass() +
- "]\n new: " + newtree + " [" + newtree.getClass() + "]")
- } catch {
- case ex: Throwable =>
- Console.println("exception while typing "+tree)
- throw ex
+ if (!tpeOfTree.contains(tree)) {
+ tpeOfTree.update(tree, tree.tpe)
+ tree.tpe = null
}
+ val newtree = super.typed(tree, mode, pt);
+ if ((newtree ne tree) && !newtree.isInstanceOf[Literal])
+ error(tree.pos, "trees differ\n old: " + tree + " [" + tree.getClass() +
+ "]\n new: " + newtree + " [" + newtree.getClass() + "]")
}
tree
}
object precheck extends Traverser {
override def traverse(tree: Tree) {
- try {
- tree match {
- case DefDef(_, _, _, _, _, _) =>
- if (tree.symbol.hasFlag(ACCESSOR) &&
- !tree.symbol.isDeferred &&
- !tree.symbol.tpe.resultType.isInstanceOf[ConstantType]) {
- assert(tree.symbol.accessed != NoSymbol, tree.symbol)
- assert(tree.symbol.accessed.getter(tree.symbol.owner) == tree.symbol ||
- tree.symbol.accessed.setter(tree.symbol.owner) == tree.symbol)
- }
- case ValDef(_, _, _, _) =>
- if (tree.symbol.hasGetter) {
- assert(tree.symbol.getter(tree.symbol.owner) != NoSymbol, tree.symbol)
- }
- case Apply(_, args) =>
- assert(args forall (EmptyTree !=))
- case Select(_, _) =>
- assert(tree.symbol != NoSymbol, tree)
- case This(_) =>
- if (!(tree.symbol.isStatic && (tree.symbol hasFlag MODULE))) {
- var o = currentOwner
- while (o != tree.symbol) {
- o = o.owner
- if (o == NoSymbol) {
- error(tree.pos, "tree symbol "+tree.symbol+" does not point to enclosing class; tree = "+tree)
- return
- }
- }
+ tree match {
+ case DefDef(_, _, _, _, _, _) =>
+ if (tree.symbol.hasFlag(ACCESSOR) &&
+ !tree.symbol.isDeferred &&
+ !tree.symbol.tpe.resultType.isInstanceOf[ConstantType]) {
+ assert(tree.symbol.accessed != NoSymbol, tree.symbol)
+ assert(tree.symbol.accessed.getter(tree.symbol.owner) == tree.symbol ||
+ tree.symbol.accessed.setter(tree.symbol.owner) == tree.symbol)
+ }
+ case ValDef(_, _, _, _) =>
+ if (tree.symbol.hasGetter) {
+ assert(tree.symbol.getter(tree.symbol.owner) != NoSymbol, tree.symbol)
+ }
+ case Apply(_, args) =>
+ assert(args forall (EmptyTree !=))
+ case Select(_, _) =>
+ assert(tree.symbol != NoSymbol, tree)
+ case This(_) =>
+ if (!(tree.symbol.isStatic && (tree.symbol hasFlag MODULE))) {
+ if (currentOwner.ownerChain takeWhile (_ != tree.symbol) exists (_ == NoSymbol)) {
+ error(tree.pos, "tree symbol "+tree.symbol+" does not point to enclosing class; tree = "+tree)
+ return
}
- case _ =>
- }
- if (tree.pos == NoPosition && tree != EmptyTree) {
- error(tree.pos, "tree without position: " + tree)
- } else if ((tree.tpe eq null) && phase.id >= currentRun.typerPhase.id) {
- error(tree.pos, "tree without type: " + tree)
- } else if (tree.isDef && tree.symbol.owner != currentOwner) {
- var owner = currentOwner
- while (owner.isTerm && !owner.isMethod && tree.symbol.owner != owner)
- owner = owner.owner;
- if (tree.symbol.owner != owner) {
- error(tree.pos, "" + tree.symbol + " has wrong owner: " + tree.symbol.owner +
- tree.symbol.owner.locationString + ", should be: " +
- currentOwner + currentOwner.locationString)
}
- } else {
- super.traverse(tree)
+ case _ =>
+ }
+ if (tree.pos == NoPosition && tree != EmptyTree) {
+ error(tree.pos, "tree without position: " + tree)
+ } else if ((tree.tpe eq null) && phase.id >= currentRun.typerPhase.id) {
+ error(tree.pos, "tree without type: " + tree)
+ } else if (tree.isDef && tree.symbol.owner != currentOwner) {
+ var owner = currentOwner
+ while (owner.isTerm && !owner.isMethod && tree.symbol.owner != owner)
+ owner = owner.owner;
+ if (tree.symbol.owner != owner) {
+ error(tree.pos, "" + tree.symbol + " has wrong owner: " + tree.symbol.owner +
+ tree.symbol.owner.locationString + ", should be: " +
+ currentOwner + currentOwner.locationString)
}
- } catch {
- case ex: Throwable =>
- if (settings.debug.value)
- Console.println("exception when traversing " + tree);
- throw(ex)
+ } else {
+ super.traverse(tree)
}
}
}
object postcheck extends Traverser {
override def traverse(tree: Tree) {
- try {
- tree match {
- case EmptyTree | TypeTree() =>
- ;
- case _ =>
- tpeOfTree.get(tree) match {
- case Some(oldtpe) =>
- if (!(oldtpe =:= tree.tpe))
- error(tree.pos, "types differ\n old: " + oldtpe +
- "\n new: " + tree.tpe + "\n tree: " + tree)
- tree.tpe = oldtpe
- super.traverse(tree)
- case None =>
- }
- }
- } catch {
- case ex: Throwable =>
- if (settings.debug.value)
- Console.println("exception when traversing " + tree);
- throw(ex)
+ tree match {
+ case EmptyTree | TypeTree() =>
+ ;
+ case _ =>
+ tpeOfTree.get(tree) match {
+ case Some(oldtpe) =>
+ if (!(oldtpe =:= tree.tpe))
+ error(tree.pos, "types differ\n old: " + oldtpe +
+ "\n new: " + tree.tpe + "\n tree: " + tree)
+ tree.tpe = oldtpe
+ super.traverse(tree)
+ case None =>
+ }
}
}
}