summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-06-28 14:36:34 +0000
committerPaul Phillips <paulp@improving.org>2009-06-28 14:36:34 +0000
commit979e774ef861656c40effd3ab973a54529844c78 (patch)
tree897cf033901b0af262d169f2cef5ef387bf1bb27 /src/compiler
parentb3924e660b9644b20714d71673f3ebfb6e0db4af (diff)
downloadscala-979e774ef861656c40effd3ab973a54529844c78.tar.gz
scala-979e774ef861656c40effd3ab973a54529844c78.tar.bz2
scala-979e774ef861656c40effd3ab973a54529844c78.zip
More fleshing out of code generation DSL.
consistent and reasonably aesthetic naming scheme for operators. Making progress on consolidating the several different places where code generation logic has been partially encapsulated.
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
))