summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeDSL.scala68
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala102
-rw-r--r--src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala9
-rw-r--r--src/compiler/scala/tools/nsc/matching/CodeFactory.scala37
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala37
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala9
-rw-r--r--src/compiler/scala/tools/nsc/transform/LazyVals.scala12
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala118
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala6
12 files changed, 196 insertions, 218 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
index 1ef0a1bc69..884e54a21d 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
@@ -18,7 +18,9 @@ trait TreeDSL {
import definitions._
object CODE {
- def LIT(x: Any) = Literal(Constant(x))
+ def LIT(x: Any) = Literal(Constant(x))
+ def ID(sym: Symbol) = Ident(sym) setType sym.tpe
+
def TRUE = LIT(true)
def FALSE = LIT(false)
def NULL = LIT(null)
@@ -26,13 +28,10 @@ trait TreeDSL {
def ZERO = LIT(0)
def WILD = Ident(nme.WILDCARD)
- case class ExpectApply(target: Tree) {
- def apply(args: Tree*) = Apply(target, args.toList)
- }
+ def fn(lhs: Tree, op: Name, args: Tree*) = Apply(Select(lhs, op), args.toList)
+ def fn(lhs: Tree, op: Symbol, args: Tree*) = Apply(Select(lhs, op), args.toList)
class TreeMethods(target: Tree) {
- private def binop(lhs: Tree, op: Name, rhs: Tree) = Apply(Select(lhs, op), List(rhs))
- private def binop(lhs: Tree, op: Symbol, rhs: Tree) = Apply(Select(lhs, op), List(rhs))
private def toAnyRef(x: Tree) = x setType AnyRefClass.tpe
/** logical/comparison ops **/
@@ -46,19 +45,27 @@ trait TreeDSL {
else if (other == EmptyTree) target
else gen.mkAnd(target, other)
- def BIT_AND(other: Tree) = binop(target, Int_And, other)
- def EQREF(other: Tree) = binop(target, nme.eq, toAnyRef(other))
- def NE_REF(other: Tree) = binop(target, nme.ne, other)
- def EQEQ(other: Tree) = binop(target, nme.EQ, other)
- def EQINT(other: Tree) = binop(target, Int_==, other)
- def EQANY(other: Tree) = binop(target, Any_==, other)
- def NOT_==(other: Tree) = binop(target, Object_ne, other)
+ def NE_REF(other: Tree) = fn(target, nme.ne, other)
+ def EQEQ(other: Tree) = fn(target, nme.EQ, other)
+
+ def ANY_EQ (other: Tree) = fn(target, nme.eq, toAnyRef(other))
+ def ANY_== (other: Tree) = fn(target, Any_==, other)
+ def OBJ_!= (other: Tree) = fn(target, Object_ne, other)
+
+ def INT_| (other: Tree) = fn(target, getMember(IntClass, nme.OR), other)
+ def INT_& (other: Tree) = fn(target, getMember(IntClass, nme.AND), other)
+ def INT_== (other: Tree) = fn(target, getMember(IntClass, nme.EQ), other)
+ def INT_!= (other: Tree) = fn(target, getMember(IntClass, nme.NE), other)
+
+ def BOOL_&& (other: Tree) = fn(target, getMember(BooleanClass, nme.ZAND), other)
+ def BOOL_|| (other: Tree) = fn(target, getMember(BooleanClass, nme.ZOR), other)
/** Apply, Select, Match **/
+ def APPLY(params: Tree*) = Apply(target, params.toList)
def APPLY(params: List[Tree]) = Apply(target, params)
def MATCH(cases: CaseDef*) = Match(target, cases.toList)
- def DOT(member: Name) = ExpectApply(Select(target, member))
- def DOT(sym: Symbol) = ExpectApply(Select(target, sym))
+ def DOT(member: Name) = SelectStart(Select(target, member))
+ def DOT(sym: Symbol) = SelectStart(Select(target, sym))
/** Assignment */
def ===(rhs: Tree) = Assign(target, rhs)
@@ -67,13 +74,18 @@ trait TreeDSL {
* what differs between the different forms of IS and AS.
*/
def AS(tpe: Type) = TypeApply(Select(target, Any_asInstanceOf), List(TypeTree(tpe)))
+ def AS_ANY(tpe: Type) = gen.mkAsInstanceOf(target, tpe)
def AS_ATTR(tpe: Type) = gen.mkAttributedCast(target, tpe)
def IS(tpe: Type) = gen.mkIsInstanceOf(target, tpe, true)
def IS_OBJ(tpe: Type) = gen.mkIsInstanceOf(target, tpe, false)
- def TOSTRING() = Apply(Select(target, nme.toString_), Nil)
- def GETCLASS() = Apply(Select(target, Object_getClass), Nil)
+ def TOSTRING() = fn(target, nme.toString_)
+ def GETCLASS() = fn(target, Object_getClass)
+ }
+
+ case class SelectStart(tree: Select) {
+ def apply(args: Tree*) = Apply(tree, args.toList)
}
class CaseStart(pat: Tree, guard: Tree) {
@@ -110,7 +122,11 @@ trait TreeDSL {
class SymbolMethods(target: Symbol) {
def BIND(body: Tree) = Bind(target, body)
- // def DOT(member: Symbol) = new TreeMethods(Ident(target)) DOT member
+
+ // Option
+ def IS_DEFINED() =
+ if (target.tpe.typeSymbol == SomeClass) TRUE // is Some[_]
+ else NOT(ID(target) DOT nme.isEmpty) // is Option[_]
// name of nth indexed argument to a method (first parameter list), defaults to 1st
def ARG(idx: Int = 0) = Ident(target.paramss.head(idx))
@@ -135,6 +151,14 @@ trait TreeDSL {
def TRY(tree: Tree) = new TryStart(tree, Nil, EmptyTree)
def REF(sym: Symbol) = gen.mkAttributedRef(sym)
def BLOCK(xs: Tree*) = Block(xs.init.toList, xs.last)
+ def NOT(tree: Tree) = Select(tree, getMember(BooleanClass, nme.UNARY_!))
+
+ //
+ // Unused, from the pattern matcher:
+ // def SEQELEM(tpe: Type): Type = (tpe.widen baseType SeqClass) match {
+ // case NoType => Predef.error("arg " + tpe + " not subtype of Seq[A]")
+ // case t => t typeArgs 0
+ // }
/** Implicits - some of these should probably disappear **/
implicit def mkTreeMethods(target: Tree): TreeMethods = new TreeMethods(target)
@@ -146,5 +170,13 @@ trait TreeDSL {
implicit def mkNameMethodsFromString(target: String): NameMethods = new NameMethods(target)
implicit def mkSymbolMethodsFromSymbol(target: Symbol): SymbolMethods = new SymbolMethods(target)
+
+ /** (foo DOT bar) might be simply a Select, but more likely it is to be immediately
+ * followed by an Apply. We don't want to add an actual apply method to arbitrary
+ * trees, so SelectStart is created with an apply - and if apply is not the next
+ * thing called, the implicit from SelectStart -> Tree will provide the tree.
+ */
+ implicit def mkTreeFromSelectStart(ss: SelectStart): Select = ss.tree
+ implicit def mkTreeMethodsFromSelectStart(ss: SelectStart): TreeMethods = mkTreeMethods(ss.tree)
}
} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index dcdb284af2..ed3c842201 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -10,6 +10,9 @@ import scala.collection.mutable.ListBuffer
import symtab.Flags._
import symtab.SymbolTable
+/** XXX to resolve: TreeGen only assumes global is a SymbolTable, but
+ * TreeDSL at the moment expects a Global. Can we get by with SymbolTable?
+ */
abstract class TreeGen {
val global: SymbolTable
@@ -102,9 +105,9 @@ abstract class TreeGen {
def mkAttributedRef(pre: Type, sym: Symbol): Tree = {
val qual = mkAttributedQualifier(pre)
qual match {
- case EmptyTree => mkAttributedIdent(sym)
+ case EmptyTree => mkAttributedIdent(sym)
case This(clazz) if (qual.symbol.isRoot || qual.symbol.isEmptyPackageClass) => mkAttributedIdent(sym)
- case _ => mkAttributedSelect(qual, sym)
+ case _ => mkAttributedSelect(qual, sym)
}
}
@@ -119,8 +122,7 @@ abstract class TreeGen {
if (tree.symbol.isStable) tree.setType(singleType(tree.symbol.owner.thisType, tree.symbol))
else tree
case Select(qual, _) =>
- assert(tree.symbol ne null)
- assert(qual.tpe ne null)
+ assert((tree.symbol ne null) && (qual.tpe ne null))
if (tree.symbol.isStable && qual.tpe.isStable)
tree.setType(singleType(qual.tpe, tree.symbol))
else tree
@@ -135,9 +137,7 @@ abstract class TreeGen {
assert(!pt.typeSymbol.isPackageClass)
assert(!pt.typeSymbol.isPackageObjectClass)
assert(pt eq pt.normalize) //@MAT only called during erasure, which already takes care of that
- atPos(tree.pos) {
- Apply(TypeApply(mkAttributedSelect(tree, Object_asInstanceOf), List(TypeTree(pt))), List())
- }
+ atPos(tree.pos)(mkAsInstanceOf(tree, pt, false))
}
/** Builds a reference with stable type to given symbol */
@@ -150,59 +150,60 @@ abstract class TreeGen {
def mkAttributedThis(sym: Symbol): Tree =
This(sym.name) setSymbol sym setType sym.thisType
- def mkAttributedIdent(sym: Symbol): Tree = {
+ def mkAttributedIdent(sym: Symbol): Tree =
Ident(sym.name) setSymbol sym setType sym.tpe
- }
- def mkAttributedSelect(qual: Tree, sym: Symbol): Tree =
- if ((qual.symbol ne null) &&
- (qual.symbol.name.toTermName == nme.ROOT ||
- qual.symbol.name.toTermName == nme.EMPTY_PACKAGE_NAME)) {
- mkAttributedIdent(sym)
- } else {
- val qual1 =
- if ((qual.tpe ne null) &&
- sym.owner.isPackageObjectClass &&
- sym.owner.owner == qual.tpe.typeSymbol) {
- //println("insert package for "+qual+"/"+sym)
- val pkgobj = sym.owner.sourceModule
- Select(qual, nme.PACKAGEkw) setSymbol pkgobj setType singleType(qual.tpe, pkgobj)
- } else qual
- val result = Select(qual1, sym.name) setSymbol sym
- if (qual1.tpe ne null) result setType qual.tpe.memberType(sym)
- result
+ /** XXX this method needs a close analysis to identify its essential logical
+ * units - this attempt at modularization verges on the arbitrary.
+ */
+ def mkAttributedSelect(qual: Tree, sym: Symbol): Tree = {
+ def tpe = qual.tpe
+ def isUnqualified(s: Symbol) =
+ s != null && (List(nme.ROOT, nme.EMPTY_PACKAGE_NAME) contains s.name.toTermName)
+ def isInPkgObject(s: Symbol) =
+ tpe != null && s.owner.isPackageObjectClass && s.owner.owner == tpe.typeSymbol
+ def getQualifier() =
+ if (!isInPkgObject(sym)) qual
+ else {
+ val pkgobj = sym.owner.sourceModule
+ Select(qual, nme.PACKAGEkw) setSymbol pkgobj setType singleType(tpe, pkgobj)
+ }
+
+ if (isUnqualified(qual.symbol)) mkAttributedIdent(sym)
+ else {
+ val newQualifier = getQualifier()
+ def verifyType(tree: Tree) =
+ if (newQualifier.tpe == null) tree
+ else tree setType (tpe memberType sym)
+
+ verifyType( Select(newQualifier, sym.name) setSymbol sym )
}
+ }
- /** Builds an instance test with given value and type. */
- def mkIsInstanceOf(value: Tree, tpe: Type, any: Boolean = true): Tree = {
- val sym = if (any) Any_isInstanceOf else Object_isInstanceOf
+ private def mkTypeApply(value: Tree, tpe: Type, what: Symbol) =
Apply(
TypeApply(
- mkAttributedSelect(value, sym),
+ mkAttributedSelect(value, what),
List(TypeTree(tpe.normalize))
),
Nil
)
- }
+ /** Builds an instance test with given value and type. */
+ def mkIsInstanceOf(value: Tree, tpe: Type, any: Boolean = true): Tree =
+ mkTypeApply(value, tpe, (if (any) Any_isInstanceOf else Object_isInstanceOf))
/** Builds a cast with given value and type. */
- def mkAsInstanceOf(value: Tree, tpe: Type, any: Boolean = true): Tree = {
- val sym = if (any) Any_asInstanceOf else Object_asInstanceOf
- Apply(
- TypeApply(
- mkAttributedSelect(value, sym),
- List(TypeTree(tpe.normalize))
- ),
- Nil
- )
- }
+ def mkAsInstanceOf(value: Tree, tpe: Type, any: Boolean = true): Tree =
+ mkTypeApply(value, tpe, (if (any) Any_asInstanceOf else Object_asInstanceOf))
def mkClassOf(tp: Type): Tree =
Literal(Constant(tp)) setType Predef_classOfType(tp)
def mkCheckInit(tree: Tree): Tree = {
- var tpe = tree.tpe
- if (tpe == null && tree.hasSymbol) tpe = tree.symbol.tpe
+ val tpe =
+ if (tree.tpe != null || !tree.hasSymbol) tree.tpe
+ else tree.symbol.tpe
+
if (!global.phase.erasedTypes && settings.Xchecknull.value &&
tpe <:< NotNullClass.tpe && !tpe.isNotNull)
mkRuntimeCall(nme.checkInitialized, List(tree))
@@ -212,23 +213,24 @@ abstract class TreeGen {
/** Builds a list with given head and tail. */
def mkNewCons(head: Tree, tail: Tree): Tree =
- New(Apply(mkAttributedRef(definitions.ConsClass), List(head, tail)))
+ New(Apply(mkAttributedRef(ConsClass), List(head, tail)))
/** Builds a list with given head and tail. */
- def mkNil: Tree =
- mkAttributedRef(definitions.NilModule)
+ def mkNil: Tree = mkAttributedRef(NilModule)
/** Builds a tuple */
def mkTuple(elems: List[Tree]): Tree =
if (elems.isEmpty) Literal(())
else Apply(
- Select(mkAttributedRef(definitions.TupleClass(elems.length).caseModule), nme.apply),
+ Select(mkAttributedRef(TupleClass(elems.length).caseModule), nme.apply),
elems)
- def mkAnd(tree1: Tree, tree2: Tree) =
+ // tree1 AND tree2
+ def mkAnd(tree1: Tree, tree2: Tree): Tree =
Apply(Select(tree1, Boolean_and), List(tree2))
- def mkOr(tree1: Tree, tree2: Tree) =
+ // tree1 OR tree2
+ def mkOr(tree1: Tree, tree2: Tree): Tree =
Apply(Select(tree1, Boolean_or), List(tree2))
def mkCached(cvar: Symbol, expr: Tree): Tree = {
@@ -278,7 +280,7 @@ abstract class TreeGen {
/** Make a synchronized block on 'monitor'. */
def mkSynchronized(monitor: Tree, body: Tree): Tree =
- Apply(Select(monitor, definitions.Object_synchronized), List(body))
+ Apply(Select(monitor, Object_synchronized), List(body))
def wildcardStar(tree: Tree) =
atPos(tree.pos) { Typed(tree, Ident(nme.WILDCARD_STAR.toTypeName)) }
diff --git a/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala b/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala
index fdaa1ad42c..3f53b2e77c 100644
--- a/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala
+++ b/src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala
@@ -235,15 +235,12 @@ abstract class ScalaPrimitives {
// scala.Boolean
addPrimitives(BooleanClass, nme.EQ, EQ)
addPrimitives(BooleanClass, nme.NE, NE)
- addPrimitive(Boolean_not, ZNOT)
- addPrimitive(Boolean_or, ZOR)
- addPrimitive(Boolean_and, ZAND)
+ addPrimitives(BooleanClass, nme.UNARY_!, ZNOT)
+ addPrimitives(BooleanClass, nme.ZOR, ZOR)
+ addPrimitives(BooleanClass, nme.ZAND, ZAND)
addPrimitives(BooleanClass, nme.OR, OR)
addPrimitives(BooleanClass, nme.AND, AND)
addPrimitives(BooleanClass, nme.XOR, XOR)
-// addPrimitives(BooleanClass, nme.ADD, CONCAT)
- // unary !
-// addPrimitives(BooleanClass, nme.UNARY_!, ZNOT)
// scala.Byte
addPrimitives(ByteClass, nme.EQ, EQ)
diff --git a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
index ece4518703..f62c5a0c7a 100644
--- a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
+++ b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
@@ -12,29 +12,21 @@ import scala.tools.nsc.util.Position
*
* @author Burak Emir
*/
-trait CodeFactory {
+trait CodeFactory extends ast.TreeDSL
+{
self: transform.ExplicitOuter with PatternNodes =>
import global.{typer => _, _}
- import analyzer.Typer;
+ import analyzer.Typer
- import definitions._ // standard classes and methods
+ import definitions._
import Code._
+ import CODE._
/** Methods to simplify code generation
*/
object Code {
- // function application
- def fn(lhs: Tree, op: Name, args: Tree*) = Apply(Select(lhs, op), args.toList)
- def fn(lhs: Tree, op: Symbol, args: Tree*) = Apply(Select(lhs, op), args.toList)
-
- val AND = definitions.Boolean_and
- val NOT = definitions.Boolean_not
- val SEQ = definitions.SeqClass
- val SOME = definitions.SomeClass
- val TRUE = Const(true)
- val FALSE = Const(false)
- val NULL = Const(null)
+ // val SOME = definitions.SomeClass
object Const {
def apply(x: Any) = Literal(Constant(x))
@@ -57,21 +49,6 @@ trait CodeFactory {
final def mkIdent(sym: Symbol) = Ident(sym) setType sym.tpe
final def mk_(tpe: Type) = Ident(nme.WILDCARD) setType tpe
- /** returns A for T <: Sequence[ A ]
- */
- final def getElemType_Sequence(tpe: Type): Type = {
- val tpe1 = tpe.widen.baseType(SEQ)
- if (tpe1 == NoType)
- Predef.error("arg " + tpe + " not subtype of Seq[A]")
-
- tpe1.typeArgs(0)
- }
-
- // Option fullness check
- final def nonEmptinessCheck(vsym: Symbol) =
- if (vsym.tpe.typeSymbol == SOME) TRUE // is Some[_]
- else Not(Select(mkIdent(vsym), nme.isEmpty)) // is Option[_]
-
/** for tree of sequence type, returns tree that drops first i elements */
final def seqDrop(sel:Tree, ix: Int)(implicit typer : Typer) =
if (ix == 0) sel else
@@ -95,8 +72,6 @@ trait CodeFactory {
final def Equals (left: Tree, right: Tree): Tree = fn(left, nme.EQ, right)
final def Eq (left: Tree, right: Tree): Tree = fn(left, nme.eq, right)
final def GTE (left: Tree, right: Tree): Tree = fn(left, nme.GE, right) // >=
- final def And (terms: Tree*): Tree = terms.reduceLeft((left, right) => fn(left, AND, right))
- final def Not (arg: Tree): Tree = Select(arg, NOT)
final def ThrowMatchError(pos: Position, obj: Tree) = atPos(pos) {
Throw( New(TypeTree(MatchErrorClass.tpe), List(List(obj))) )
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index d821bc4956..b497dcf185 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -30,14 +30,15 @@ import MatchUtil._
*
* @author Burak Emir
*/
-trait ParallelMatching {
+trait ParallelMatching extends ast.TreeDSL {
self: transform.ExplicitOuter with PatternNodes with CodeFactory =>
import global.{typer => _, _}
import analyzer.Typer;
import symtab.Flags
import Types._
- import Code.{ fn, Const }
+ import Code.Const
+ import CODE._
/**
* Encapsulates a symbol being matched on.
@@ -56,7 +57,7 @@ trait ParallelMatching {
def mkList(prefix: List[Symbol], suffix: List[Symbol]) = prefix ::: sym :: suffix
def isDefined = sym ne NoSymbol
def accessors = sym.caseFieldAccessors
- def id = mkIdent(sym)
+ def id = ID(sym)
def tpe = sym.tpe
def pos = sym.pos
def isChar = tpe.widen.isChar
@@ -292,10 +293,11 @@ trait ParallelMatching {
val (branches, defaultV, defaultRep) = this.getTransition // tag body pairs
val cases = for ((tag, r) <- branches) yield {
val r2 = rep.make(r.temp, r.row.map(x => x.rebind(bindVars(tag, x.subst))))
- CaseDef(Literal(tag), EmptyTree, r2.toTree)
+
+ CASE(Literal(tag)) ==> r2.toTree
}
- lazy val ndefault = defaultRep.map(_.toTree) getOrElse failTree
- lazy val casesWithDefault = cases ::: List(CaseDef(mk_(definitions.IntClass.tpe), EmptyTree, ndefault))
+ lazy val ndefault = defaultRep.map(_.toTree) getOrElse failTree
+ lazy val casesWithDefault = cases ::: List(CASE(mk_(definitions.IntClass.tpe)) ==> ndefault)
cases match {
case CaseDef(lit,_,body) :: Nil => If(Equals(scrut.id, lit), body, ndefault)
@@ -354,19 +356,19 @@ trait ParallelMatching {
val vtpe = app.tpe.typeArgs(0)
val vsym = newVarCapture(ua.pos, vtpe)
val nrows = mkNewRows((xs) => List(xs.head), 1)
- val vdef = typedValDef(vsym, Get(mkIdent(ures)))
+ val vdef = typedValDef(vsym, Get(ID(ures)))
mkTransition(List(vdef), List(vsym), nrows)
case _ => // app.tpe is Option[? <: ProductN[T1,...,Tn]]
val uresGet = newVarCapture(ua.pos, app.tpe.typeArgs(0))
- val vdefHead = typedValDef(uresGet, Get(mkIdent(ures)))
+ val vdefHead = typedValDef(uresGet, Get(ID(ures)))
val ts = definitions.getProductArgs(uresGet.tpe).get
val nrows = mkNewRows(identity, ts.size)
val (vdefs: List[Tree], vsyms: List[Symbol]) = List.unzip(
for ((vtpe, i) <- ts.zip((1 to ts.size).toList)) yield {
val vchild = newVarCapture(ua.pos, vtpe)
val accSym = definitions.productProj(uresGet, i)
- val rhs = typer.typed(Code.fn(mkIdent(uresGet), accSym))
+ val rhs = typer.typed(fn(ID(uresGet), accSym))
(typedValDef(vchild, rhs), vchild)
})
@@ -379,8 +381,8 @@ trait ParallelMatching {
val succ = srep.toTree
val fail = frep.map(_.toTree) getOrElse failTree
val cond =
- if (uacall.symbol.tpe.isBoolean) typer.typed(mkIdent(uacall.symbol))
- else nonEmptinessCheck(uacall.symbol)
+ if (uacall.symbol.tpe.isBoolean) typer.typed(ID(uacall.symbol))
+ else uacall.symbol IS_DEFINED
typer.typed( squeezedBlock(List(rep.handleOuter(uacall)), If(cond,squeezedBlock(vdefs,succ),fail)) )
}
@@ -609,7 +611,7 @@ trait ParallelMatching {
val caseTemps = srep.temp match { case x :: xs if x == casted.sym => xs ; case x => x }
var vdefs = for ((tmp, accessorMethod) <- caseTemps.zip(cfa)) yield {
- val untypedAccess = Code.fn(casted.id, accessorMethod)
+ val untypedAccess = fn(casted.id, accessorMethod)
val typedAccess = typer.typed(untypedAccess)
typedValDef(tmp, typedAccess)
}
@@ -701,10 +703,9 @@ trait ParallelMatching {
case If(cond, Const(true), Const(false)) =>
super.transform(cond)
case If(cond1, If(cond2, thenp, elsep1), elsep2) if (elsep1 equalsStructure elsep2) =>
- super.transform(If(And(cond1,cond2), thenp, elsep1))
+ super.transform( IF (cond1 AND cond2) THEN thenp ELSE elsep1 )
case If(cond1, If(cond2, thenp, Apply(jmp,List())), ld:LabelDef) if (jmp.symbol eq ld.symbol) =>
- super.transform(If(And(cond1,cond2), thenp, ld))
-
+ super.transform( IF (cond1 AND cond2) THEN thenp ELSE ld )
case t => super.transform(t)
}
}
@@ -731,7 +732,7 @@ trait ParallelMatching {
final def requestBody(bx: Int, subst: Bindings)(implicit theOwner: Symbol): Tree = {
if (bx < 0) { // is shortcut
val jlabel = shortCuts(-bx-1)
- return Apply(mkIdent(jlabel), Nil)
+ return Apply(ID(jlabel), Nil)
}
if (!isReached(bx)) { // first time this bx is requested
// might be bound elsewhere ( see `x @ unapply' ) <-- this comment refers to null check
@@ -777,7 +778,7 @@ trait ParallelMatching {
val vdefs = for (v <- vss(bx) ; substv <- subst(v)) yield typedValDef(v, substv)
squeezedBlock(vdefs, body.duplicate setType resultType)
case _ =>
- Apply(mkIdent(label),args)
+ Apply(ID(label), args)
}
}
@@ -1015,7 +1016,7 @@ trait ParallelMatching {
outerAccessor(tpe2test.typeSymbol) match {
case NoSymbol => if (settings.debug.value) cunit.warning(scrut.pos, "no outer acc for "+tpe2test.typeSymbol) ; cond
- case outerAcc => And(cond, Eq(Code.fn(gen.mkAsInstanceOf(scrut, tpe2test), outerAcc), theRef))
+ case outerAcc => cond AND (((scrut AS_ANY tpe2test) DOT outerAcc)() ANY_EQ theRef)
}
}
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 56c19e8fc7..4254ec4800 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -86,14 +86,10 @@ trait Definitions {
lazy val FloatClass = newValueClass(nme.Float, 'F')
lazy val DoubleClass = newValueClass(nme.Double, 'D')
- // some value class conveniences
- def Boolean_not = getMember(BooleanClass, nme.UNARY_!)
+ // XXX the class-specific member symbols need to be grouped somewhere
+ // associated with that class.
def Boolean_and = getMember(BooleanClass, nme.ZAND)
def Boolean_or = getMember(BooleanClass, nme.ZOR)
- def Int_Or = getMember(IntClass, nme.OR)
- def Int_And = getMember(IntClass, nme.AND)
- def Int_== = getMember(IntClass, nme.EQ)
- def Int_!= = getMember(IntClass, nme.NE)
// the scala reference classes
lazy val ScalaObjectClass: Symbol = getClass("scala.ScalaObject")
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index f1c6641dd0..4313ec5f8e 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -267,7 +267,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
BLOCK(
VAL(methodSym) === ((REF(reflPolyCacheSym) DOT methodCache_find)(REF(forReceiverSym))) ,
- IF (REF(methodSym) NOT_== NULL) .
+ IF (REF(methodSym) OBJ_!= NULL) .
THEN (Return(REF(methodSym)))
ELSE {
def methodSymRHS = ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), REF(reflParamsCacheSym)))
@@ -366,7 +366,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
val sym = currentOwner.newValue(ad.pos, mkTerm()) setInfo ObjectClass.tpe
BLOCK(
VAL(sym) === tree,
- IF (NULL EQANY REF(sym)) THEN NULL ELSE gen.mkRuntimeCall(nme.boxArray, List(REF(sym)))
+ IF (NULL ANY_== REF(sym)) THEN NULL ELSE gen.mkRuntimeCall(nme.boxArray, List(REF(sym)))
)
}
resType.typeSymbol match {
@@ -394,7 +394,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
BLOCK(
VAL(sym) === param,
- IF (NULL EQANY REF(sym)) .
+ IF (NULL ANY_== REF(sym)) .
THEN (NULL) .
ELSE (
IF (REF(sym) IS_OBJ BoxedArrayClass.tpe) .
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 2d3edf3a0e..0331766b80 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -136,7 +136,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
result =
atPos(to.pos) {
localTyper.typed {
- IF (from EQREF NULL) THEN THROW(NullPointerExceptionClass) ELSE result
+ IF (from ANY_EQ NULL) THEN THROW(NullPointerExceptionClass) ELSE result
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 6cdadc758a..1a8c52c118 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -16,7 +16,14 @@ import matching.{TransMatcher, PatternNodes, CodeFactory, ParallelMatching}
* @author Martin Odersky
* @version 1.0
*/
-abstract class ExplicitOuter extends InfoTransform with TransMatcher with PatternNodes with CodeFactory with ParallelMatching with TypingTransformers {
+abstract class ExplicitOuter extends InfoTransform
+ with TransMatcher
+ with PatternNodes
+ with CodeFactory
+ with ParallelMatching
+ with TypingTransformers
+ with ast.TreeDSL
+{
import global._
import definitions._
diff --git a/src/compiler/scala/tools/nsc/transform/LazyVals.scala b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
index 9707baf392..21370c3176 100644
--- a/src/compiler/scala/tools/nsc/transform/LazyVals.scala
+++ b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
@@ -28,8 +28,6 @@ abstract class LazyVals extends Transform with ast.TreeDSL {
* Transform local lazy accessors to check for the initialized bit.
*/
class LazyValues(unit: CompilationUnit) extends Transformer {
-
- import definitions.{Int_And, Int_Or, Int_==}
/** map from method symbols to the number of lazy values it defines. */
private val lazyVals = new HashMap[Symbol, Int] {
override def default(meth: Symbol) = 0
@@ -106,6 +104,8 @@ abstract class LazyVals extends Transform with ast.TreeDSL {
}
}
+ import CODE._
+
/** return a 'lazified' version of rhs. Rhs should conform to the
* following schema:
* {
@@ -146,18 +146,14 @@ abstract class LazyVals extends Transform with ast.TreeDSL {
(Block(List(rhs, mkSetFlag(bitmapSym, mask)), Literal(Constant(()))), Literal(()))
}
- import CODE._
-
val result = atPos(tree.pos) {
- IF ((Ident(bitmapSym) BIT_AND mask) EQINT ZERO) THEN block ENDIF
+ IF ((Ident(bitmapSym) INT_& mask) INT_== ZERO) THEN block ENDIF
}
typed(Block(List(result), res))
}
private def mkSetFlag(bmp: Symbol, mask: Tree): Tree =
- Assign(Ident(bmp),
- Apply(Select(Ident(bmp), Int_Or), List(mask)))
-
+ Ident(bmp) === (Ident(bmp) INT_| mask)
final val FLAGS_PER_WORD = 32
val bitmaps = new HashMap[Symbol, List[Symbol]] {
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 3dc9588208..56bcd34cd2 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -12,9 +12,10 @@ import scala.collection.mutable.ListBuffer
import scala.tools.nsc.util.{Position,NoPosition}
import scala.collection.mutable.HashMap
-abstract class Mixin extends InfoTransform {
+abstract class Mixin extends InfoTransform with ast.TreeDSL {
import global._
import definitions._
+ import CODE._
/** The name of the phase: */
val phaseName: String = "mixin"
@@ -381,6 +382,7 @@ abstract class Mixin extends InfoTransform {
/** The typer */
private var localTyper: erasure.Typer = _
+ private def typedPos(pos: Position)(tree: Tree) = localTyper typed { atPos(pos)(tree) }
import scala.collection._
@@ -489,7 +491,7 @@ abstract class Mixin extends InfoTransform {
/** Attribute given tree and anchor at given position */
def attributedDef(pos: Position, tree: Tree): Tree = {
if (settings.debug.value) log("add new def to " + clazz + ": " + tree)
- localTyper.typed { atPos(pos) { tree } }
+ typedPos(pos)(tree)
}
/** The position of given symbol, or, if this is undefined,
@@ -576,19 +578,20 @@ abstract class Mixin extends InfoTransform {
/** Return an (untyped) tree of the form 'Clazz.this.bmp = Clazz.this.bmp | mask'. */
def mkSetFlag(clazz: Symbol, offset: Int): Tree = {
val bmp = bitmapFor(clazz, offset)
- val mask = Literal(Constant(1 << (offset % FLAGS_PER_WORD)))
+ val mask = LIT(1 << (offset % FLAGS_PER_WORD))
+ def x = This(clazz) DOT bmp
- Assign(Select(This(clazz), bmp),
- Apply(Select(Select(This(clazz), bmp), Int_Or), List(mask)))
+ x === (x INT_| mask)
}
/** Return an (untyped) tree of the form 'clazz.this.bitmapSym & mask (==|!=) 0', the
* precise comparison operator depending on the value of 'equalToZero'.
*/
- def mkTest(clazz: Symbol, mask: Tree, bitmapSym: Symbol, equalToZero: Boolean): Tree =
- Apply(Select(Apply(Select(Select(This(clazz), bitmapSym), Int_And), List(mask)),
- if (equalToZero) Int_== else Int_!=),
- List(Literal(Constant(0))))
+ def mkTest(clazz: Symbol, mask: Tree, bitmapSym: Symbol, equalToZero: Boolean): Tree = {
+ def lhs = (This(clazz) DOT bitmapSym) INT_& mask
+ if (equalToZero) lhs INT_== ZERO
+ else lhs INT_!= ZERO
+ }
/** return a 'lazified' version of rhs.
* @param clazz The class symbol
@@ -612,31 +615,30 @@ abstract class Mixin extends InfoTransform {
* the 'n' is (offset / 32), the MASK is (1 << (offset % 32)).
*/
def mkLazyDef(clazz: Symbol, init: List[Tree], retVal: Tree, offset: Int): Tree = {
-
val bitmapSym = bitmapFor(clazz, offset)
+ val mask = LIT(1 << (offset % FLAGS_PER_WORD))
+ def cond = mkTest(clazz, mask, bitmapSym, true)
+ def syncBody = init ::: List(mkSetFlag(clazz, offset), UNIT)
+
+ val result =
+ IF (cond) THEN gen.mkSynchronized(
+ gen mkAttributedThis clazz,
+ IF (cond) THEN BLOCK(syncBody: _*) ENDIF
+ ) ENDIF
- val mask = Literal(Constant(1 << (offset % FLAGS_PER_WORD)))
- val result =
- If(mkTest(clazz, mask, bitmapSym, true),
- gen.mkSynchronized(gen.mkAttributedThis(clazz),
- If(mkTest(clazz, mask, bitmapSym, true),
- Block(init :::
- List(mkSetFlag(clazz, offset)),
- Literal(Constant(()))),
- EmptyTree)),
- EmptyTree)
- localTyper.typed(atPos(init.head.pos)(Block(List(result), retVal)))
+ typedPos(init.head.pos)(BLOCK(result, retVal))
}
def mkCheckedAccessor(clazz: Symbol, retVal: Tree, offset: Int, pos: Position): Tree = {
val bitmapSym = bitmapFor(clazz, offset)
- val mask = Literal(Constant(1 << (offset % FLAGS_PER_WORD)))
- val msg = "Uninitialized field: " + unit.source + ": " + pos.line.get
- val result =
- If(mkTest(clazz, mask, bitmapSym, false),
- retVal,
- Throw(New(TypeTree(definitions.UninitializedErrorClass.tpe), List(List(Literal(Constant(msg)))))))
- localTyper.typed(atPos(pos)(Block(List(result), retVal)))
+ val mask = LIT(1 << (offset % FLAGS_PER_WORD))
+ val msg = "Uninitialized field: " + unit.source + ": " + pos.line.get
+ val result =
+ IF (mkTest(clazz, mask, bitmapSym, false)) .
+ THEN (retVal) .
+ ELSE (THROW(UninitializedErrorClass, LIT(msg)))
+
+ typedPos(pos)(BLOCK(result, retVal))
}
/** Complete lazy field accessors. Applies only to classes, for it's own (non inherited) lazy fields.
@@ -911,11 +913,8 @@ abstract class Mixin extends InfoTransform {
def staticCall(target: Symbol) = {
if (target == NoSymbol)
assert(false, "" + sym + ":" + sym.tpe + " " + sym.owner + " " + implClass(sym.owner) + " " + implClass(sym.owner).info.member(sym.name) + " " + atPhase(phase.prev)(implClass(sym.owner).info.member(sym.name).tpe) + " " + phase);//debug
- localTyper.typed {
- atPos(tree.pos) {
- Apply(staticRef(target), transformSuper(qual) :: args)
- }
- }
+
+ typedPos(tree.pos)(Apply(staticRef(target), transformSuper(qual) :: args))
}
if (isStaticOnly(sym)) {
// change calls to methods which are defined only in implementation
@@ -934,12 +933,9 @@ abstract class Mixin extends InfoTransform {
if (sym.hasFlag(ACCESSOR)) {
assert(args.isEmpty)
val sym1 = sym.overridingSymbol(currentOwner.enclClass)
- localTyper.typed {
- atPos(tree.pos) {
- Apply(Select(transformSuper(qual), sym1), List())
- }
- }
- } else {
+ typedPos(tree.pos)((transformSuper(qual) DOT sym1)())
+ }
+ else {
staticCall(atPhase(phase.prev)(sym.overridingSymbol(implClass(sym.owner))))
}
} else {
@@ -959,49 +955,25 @@ abstract class Mixin extends InfoTransform {
tree
case Select(qual, name) if sym.owner.isImplClass && !isStaticOnly(sym) =>
+ assert(!sym.isMethod, "no method allowed here: %s%s %s".format(sym, sym.isImplOnly, flagsToString(sym.flags)))
+
// refer to fields in some implementation class via an abstract
// getter in the interface.
-
- if (sym.isMethod)
- assert(false, "no method allowed here: " + sym + sym.isImplOnly +
- " " + flagsToString(sym.flags))
val iface = toInterface(sym.owner.tpe).typeSymbol
val getter = sym.getter(iface)
assert(getter != NoSymbol)
- localTyper.typed {
- atPos(tree.pos) {
- Apply(Select(qual, getter), List())
- }
- }
+ typedPos(tree.pos)((qual DOT getter)())
case Assign(Apply(lhs @ Select(qual, _), List()), rhs) =>
// assign to fields in some implementation class via an abstract
// setter in the interface.
- localTyper.typed {
-/*
- println(lhs.symbol)
- println(lhs.symbol.owner.info.decls)
- println(needsExpandedSetterName(lhs.symbol))
- println(toInterface(lhs.symbol.owner.tpe).typeSymbol)
- println(toInterface(lhs.symbol.owner.tpe).typeSymbol.info.decls)
- util.trace("generating tree: ") {
-*/
- atPos(tree.pos) {
- Apply(
- Select(
- qual,
- lhs.symbol.setter(
- toInterface(lhs.symbol.owner.tpe).typeSymbol,
- needsExpandedSetterName(lhs.symbol))) setPos lhs.pos,
- List(rhs))
- }
-// }
- }
-/* //DEBUG
- case Ident(name) if (name.toString == "xxx") =>
- println(tree+":"+tree.tpe+"/"+tree.tpe.baseClasses)
- tree
-*/
+ def setter = lhs.symbol.setter(
+ toInterface(lhs.symbol.owner.tpe).typeSymbol,
+ needsExpandedSetterName(lhs.symbol)
+ ) setPos lhs.pos
+
+ typedPos(tree.pos) { (qual DOT setter)(rhs) }
+
case _ =>
tree
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 5809b56f30..010171effe 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -116,7 +116,7 @@ trait SyntheticMethods extends ast.TreeDSL {
name, 0, makeTypeConstructor(paramtypes, target.tpe.resultType)
)
- typer.typed {
+ typer typed {
DEF(method) === {
Apply(gen.mkAttributedRef(target), This(clazz) :: (method ARGNAMES))
}
@@ -171,11 +171,11 @@ trait SyntheticMethods extends ast.TreeDSL {
val (guards, params) = List.map2(clazz.caseFieldAccessors, constrParamTypes)(makeTrees) unzip
// Pattern is classname applied to parameters, and guards are all logical and-ed
- val (guard, pat) = (AND(guards : _*), clazz.name.toTermName APPLY params)
+ val (guard, pat) = (AND(guards: _*), clazz.name.toTermName APPLY params)
localTyper typed {
DEF(method) === {
- (This(clazz) EQREF that) OR (that MATCH(
+ (This(clazz) ANY_EQ that) OR (that MATCH(
(CASE(pat) IF guard) ==> TRUE ,
DEFAULT ==> FALSE
))