summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala92
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala11
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala3
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala7
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala15
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala2
7 files changed, 103 insertions, 29 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index 734921eac6..cc9c748d88 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -301,6 +301,8 @@ abstract class TreeGen {
def mkForwarder(target: Tree, vparamss: List[List[Symbol]]) =
(target /: vparamss)((fn, vparams) => Apply(fn, vparams map paramToArg))
+ /** Used in situations where you need to access value of an expression several times
+ */
def evalOnce(expr: Tree, owner: Symbol, unit: CompilationUnit)(within: (() => Tree) => Tree): Tree =
if (treeInfo.isPureExpr(expr)) {
within(() => expr);
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index f6c2bfd40f..929f623c2d 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -45,9 +45,14 @@ trait Trees {
// modifiers --------------------------------------------------------
+ /** @param privateWithin the qualifier for a private (a type name)
+ * or nme.EMPTY.toTypeName, if none is given.
+ * @param annotations the annotations for the definition
+ * (i.e things starting with @)
+ */
case class Modifiers(flags: Long, privateWithin: Name, annotations: List[Annotation]) {
- def isCovariant = hasFlag(COVARIANT )
- def isContravariant = hasFlag(CONTRAVARIANT)
+ def isCovariant = hasFlag(COVARIANT ) // marked with `+'
+ def isContravariant = hasFlag(CONTRAVARIANT) // marked with `-'
def isPrivate = hasFlag(PRIVATE )
def isProtected = hasFlag(PROTECTED)
def isVariable = hasFlag(MUTABLE )
@@ -101,7 +106,10 @@ trait Trees {
def pos = rawpos
- var tpe: Type = _
+ private[this] var rawtpe: Type = _
+
+ def tpe = rawtpe
+ def tpe_=(t: Type) = rawtpe = t
def setPos(pos: Position): this.type = { rawpos = pos; this }
def setType(tp: Type): this.type = {
@@ -285,7 +293,9 @@ trait Trees {
/** The empty tree */
case object EmptyTree extends TermTree {
- tpe = NoType
+ super.tpe_=(NoType)
+ override def tpe_=(t: Type) =
+ if (t != NoType) throw new Error("tpe_=("+t+") inapplicable for <empty>")
override def isEmpty = true
}
@@ -327,7 +337,6 @@ trait Trees {
*/
def ClassDef(sym: Symbol, impl: Template): ClassDef =
posAssigner.atPos(sym.pos) {
- var flags = sym.flags
ClassDef(Modifiers(sym.flags),
sym.name,
sym.typeParams map TypeDef,
@@ -500,7 +509,7 @@ trait Trees {
case class Import(expr: Tree, selectors: List[(Name, Name)])
extends SymTree
// The symbol of an Import is an import symbol @see Symbol.newImport
- // It's used primarily as a marker to check thta the import has been typechecked.
+ // It's used primarily as a marker to check that the import has been typechecked.
/** Annotation application (constructor arguments + name-value pairs) */
case class Annotation(constr: Tree, elements: List[Tree])
@@ -537,19 +546,32 @@ trait Trees {
// System.err.println("TEMPLATE: " + parents)
}
- /**
- * @param parents ...
- * @param vparamss ...
- * @param argss ...
- * @param body ...
- * @return ...
+ /** Generates a template with constructor corresponding to
+ *
+ * constrmods (vparams1_) ... (vparams_n) preSuper { presupers }
+ * extends superclass(args_1) ... (args_n) with mixins { self => body }
+ *
+ * This gets translated to
+ *
+ * extends superclass with mixins { self =>
+ * presupers' // presupers without rhs
+ * vparamss // abstract fields corresponding to value parameters
+ * def <init>(vparamss) {
+ * presupers
+ * super.<init>(args)
+ * }
+ * body
+ * }
*/
def Template(parents: List[Tree], self: ValDef, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree]): Template = {
- /** Add constructor to template */
+ /* Add constructor to template */
+
+ // create parameters for <init>
var vparamss1 =
vparamss map (vps => vps.map { vd =>
- val ret = ValDef(Modifiers(vd.mods.flags & IMPLICIT | PARAM) withAnnotations vd.mods.annotations,
- vd.name, vd.tpt.duplicate, EmptyTree).setPos(vd.pos)
+ val ret = ValDef(
+ Modifiers(vd.mods.flags & IMPLICIT | PARAM) withAnnotations vd.mods.annotations,
+ vd.name, vd.tpt.duplicate, EmptyTree).setPos(vd.pos)
if (inIDE && vd.symbol != NoSymbol)
ret.symbol = vd.symbol
ret
@@ -568,6 +590,7 @@ trait Trees {
else List(
DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, List(), List(List()), TypeTree(), Block(lvdefs, Literal(()))))
} else {
+ // convert (implicit ... ) to ()(implicit ... ) if its the only parameter section
if (vparamss1.isEmpty ||
!vparamss1.head.isEmpty && (vparamss1.head.head.mods.flags & IMPLICIT) != 0)
vparamss1 = List() :: vparamss1;
@@ -843,25 +866,39 @@ trait Trees {
case PackageDef(name, stats) =>
// package name { stats }
case ClassDef(mods, name, tparams, impl) =>
- // mods class name[tparams] impl
+ // mods class name [tparams] impl where impl = extends parents { defs }
case ModuleDef(mods, name, impl) => (eliminated by refcheck)
// mods object name impl where impl = extends parents { defs }
case ValDef(mods, name, tpt, rhs) =>
// mods val name: tpt = rhs
+ // note missing type information is expressed by tpt = TypeTree()
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- // mods def name[tparams](vparams): tpt = rhs
+ // mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs
+ // note missing type information is expressed by tpt = TypeTree()
case TypeDef(mods, name, tparams, rhs) => (eliminated by erasure)
// mods type name[tparams] = rhs
+ // mods type name[tparams] >: lo <: hi, where lo, hi are in a TypeBoundsTree,
+ and DEFERRED is set in mods
case LabelDef(name, params, rhs) =>
// used for tailcalls and like
+ // while/do are desugared to label defs as follows:
+ // while (cond) body ==> LabelDef($L, List(), if (cond) { body; L$() } else ())
+ // do body while (cond) ==> LabelDef($L, List(), body; if (cond) L$() else ())
case Import(expr, selectors) => (eliminated by typecheck)
// import expr.{selectors}
+ // Selectors are a list of pairs of names (from, to).
+ // The last (and maybe only name) may be a nme.WILDCARD
+ // for instance
+ // import qual.{x, y => z, _} would be represented as
+ // Import(qual, List(("x", "x"), ("y", "z"), (WILDCARD, null)))
case Annotation(constr, elements) =>
- // @constr(elements) where constr = tp(args), elements = { val x1 = c1, ..., val xn = cn }
+ // @constr(elements) where constr = tp(args), (an instance of Apply)
+ // elements = { val x1 = c1, ..., val xn = cn }
case DocDef(comment, definition) => (eliminated by typecheck)
// /** comment */ definition
case Template(parents, self, body) =>
// extends parents { self => body }
+ // if self is missing it is represented as emptyValDef
case Block(stats, expr) =>
// { stats; expr }
case CaseDef(pat, guard, body) => (eliminated by transmatch/explicitouter)
@@ -878,6 +915,11 @@ trait Trees {
// used for unapply's
case ArrayValue(elemtpt, trees) => (introduced by uncurry)
// used to pass arguments to vararg arguments
+ // for instance, printf("%s%d", foo, 42) is translated to after uncurry to:
+ // Apply(
+ // Ident("printf"),
+ // Literal("%s%d"),
+ // ArrayValue(<Any>, List(Ident("foo"), Literal(42))))
case Function(vparams, body) => (eliminated by lambdaLift)
// vparams => body where vparams:List[ValDef]
case Assign(lhs, rhs) =>
@@ -893,27 +935,30 @@ trait Trees {
case Throw(expr) =>
// throw expr
case New(tpt) =>
- // new tpt always in the context: new tpt.<init>[targs](args)
+ // new tpt always in the context: (new tpt).<init>[targs](args)
case Typed(expr, tpt) => (eliminated by erasure)
// expr: tpt
case TypeApply(fun, args) =>
// fun[args]
case Apply(fun, args) =>
// fun(args)
+ // for instance fun[targs](args) is expressed as Apply(TypeApply(fun, targs), args)
case ApplyDynamic(qual, args) (introduced by erasure, eliminated by cleanup)
// fun(args)
case Super(qual, mix) =>
- // qual.super[mix]
+ // qual.super[mix] if qual and/or mix is empty, ther are nme.EMPTY.toTypeName
case This(qual) =>
// qual.this
case Select(qualifier, selector) =>
// qualifier.selector
case Ident(name) =>
// name
+ // note: type checker converts idents that refer to enclosing fields or methods
+ // to selects; name ==> this.name
case Literal(value) =>
// value
case TypeTree() => (introduced by refcheck)
- // a type that's not written out, but given in the attribute
+ // a type that's not written out, but given in the tpe attribute
case Annotated(annot, arg) => (eliminated by typer)
// arg @annot for types, arg: @annot for exprs
case SingletonTypeTree(ref) => (eliminated by uncurry)
@@ -924,9 +969,10 @@ trait Trees {
// parent1 with ... with parentN { refinement }
case AppliedTypeTree(tpt, args) => (eliminated by uncurry)
// tpt[args]
- case TypeBoundsTree(lo, hi) => (eliminated by uncurry)
+ case TypeBoundsTree(lo, hi) => (eliminated by uncurry)
// >: lo <: hi
- case ExistentialTypeTree(tpt, whereClauses) =>
+ case ExistentialTypeTree(tpt, whereClauses) => (eliminated by uncurry)
+ // tpt forSome { whereClauses }
*/
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 99b8089b8b..1cd4ee8820 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -3414,6 +3414,17 @@ A type's typeSymbol should never be inspected directly.
case _ => tp.normalize
}
+ /*
+ todo: change to:
+ def normalizePlus(tp: Type) = tp match {
+ case TypeRef(pre, sym, List()) =>
+ if (!sym.isInitialized) sym.rawInfo.load(sym)
+ if (sym.hasFlag(JAVA) && !sym.typeParams.isEmpty) rawToExistential(tp)
+ else tp.normalize
+ case _ => tp.normalize
+ }
+ */
+
private def isSameType0(tp1: Type, tp2: Type): Boolean =
((tp1, tp2) match {
case (ErrorType, _) => true
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index c52eda360a..5a74c9087c 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -764,8 +764,7 @@ abstract class ClassfileParser {
val t = pool.getType(index)
val n = pool.getName(in.nextChar)
val s = t.typeSymbol.linkedModuleOfClass.info.decls.lookup(n)
- //assert (s != NoSymbol, "while processing " + in.file + ": " + t + "." + n + ": " + t.decls)
- assert(s != NoSymbol, t) // avoid string concatenation!
+ assert(s != NoSymbol, t)
Constant(s)
case ARRAY_TAG =>
val arr = new ArrayBuffer[Constant]()
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 23203bd848..48a096a78b 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -177,7 +177,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
def classSig: String =
"L"+atPhase(currentRun.icodePhase)(sym.fullNameString).replace('.', '/')
def classSigSuffix: String =
- "."+atPhase(currentRun.icodePhase)(sym.name)
+ "."+sym.name
if (sym == ArrayClass)
ARRAY_TAG.toString+(args map jsig).mkString
else if (sym.isTypeParameterOrSkolem)
@@ -228,7 +228,10 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
jsig(erasure(tp))
}
}
- if (needsJavaSig(sym.info)) Some(jsig2(true, List(), sym.info))
+ if (needsJavaSig(sym.info)) {
+ //println("Java sig of "+sym+" is "+jsig2(true, List(), sym.info))//DEBUG
+ Some(jsig2(true, List(), sym.info))
+ }
else None
}
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 582baba778..bb552de8b9 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -256,7 +256,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
// ------ Transforming anonymous functions and by-name-arguments ----------------
- /** Undo eta expansion for parameterless and nullaray methods */
+ /** Undo eta expansion for parameterless and nullary methods */
def deEta(fun: Function): Tree = fun match {
case Function(List(), Apply(expr, List())) if treeInfo.isPureExpr(expr) =>
if (expr.hasSymbol && expr.symbol.hasFlag(LAZY))
@@ -316,6 +316,16 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
def applyMethodDef(body: Tree) =
DefDef(Modifiers(FINAL), nme.apply, List(), List(fun.vparams), TypeTree(restpe), body)
.setSymbol(applyMethod)
+/*
+ def toStringMethodDefs = fun match {
+ case etaExpansion(_, fn, _) if (fn.hasSymbol) =>
+ List(
+ DefDef(Modifiers(FINAL | OVERRIDE), nme.toString_, List(), List(List()), TypeTree(StringClass.tpe),
+ Literal(fn.symbol.name)))
+ case _ =>
+ List()
+ }
+*/
def mkUnchecked(tree: Tree) = tree match {
case Match(selector, cases) =>
atPos(tree.pos) {
@@ -326,7 +336,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
case _ =>
tree
}
- val members =
+ val members = {
if (fun.tpe.typeSymbol == PartialFunctionClass) {
val isDefinedAtMethod = anonClass.newMethod(fun.pos, nme.isDefinedAt)
.setFlag(FINAL).setInfo(MethodType(formals, BooleanClass.tpe))
@@ -350,6 +360,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
} else {
List(applyMethodDef(fun.body))
}
+ } /* ::: toStringMethodDefs */
localTyper.typed {
atPos(fun.pos) {
Block(
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 860e83666e..7172a0a2d0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -372,6 +372,8 @@ abstract class RefChecks extends InfoTransform {
unit.error(clazz.pos, "illegal inheritance;\n " + clazz +
" inherits different type instances of " + baseClass +
":\n" + tp1 + " and " + tp2);
+ explainTypes(tp1, tp2)
+ explainTypes(tp2, tp1)
}
}
}