summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2006-12-04 17:41:36 +0000
committerMartin Odersky <odersky@gmail.com>2006-12-04 17:41:36 +0000
commit67dfced37f9b5d7a2b7f80f4da7fb5716f557350 (patch)
treec62c6fafcd14d847d45baa8b6155d9c52b76cbfc /src/compiler
parent525018c3cab1aaeb6644e9dacae2ab36ffa28d13 (diff)
downloadscala-67dfced37f9b5d7a2b7f80f4da7fb5716f557350.tar.gz
scala-67dfced37f9b5d7a2b7f80f4da7fb5716f557350.tar.bz2
scala-67dfced37f9b5d7a2b7f80f4da7fb5716f557350.zip
added infix type constructors
added &: infix constructor for pairs optimization to remove redudant outer pointers
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala9
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala5
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala20
5 files changed, 37 insertions, 17 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 844d74cea5..23ba5df865 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -1,4 +1,4 @@
-/* NSC -- new Scala compiler
+ /* NSC -- new Scala compiler
* Copyright 2005-2006 LAMP/EPFL
* @author Martin Odersky
*/
@@ -49,6 +49,7 @@ trait Types requires SymbolTable {
private var checkMalformedSwitch = true
private var globalVariance = 1
private final val healTypes = false
+ private final val LubGlbMargin = 0
val emptyTypeArray = new Array[Type](0)
@@ -717,7 +718,7 @@ trait Types requires SymbolTable {
case RefinedType(parents, decls) =>
assert(decls.isEmpty)
//Console.println("compute closure of "+this+" => glb("+parents+")")
- closureCache(j) = mergePrefixAndArgs(parents, -1, maxClosureDepth(parents)) match {
+ closureCache(j) = mergePrefixAndArgs(parents, -1, maxClosureDepth(parents) + LubGlbMargin) match {
case Some(tp0) => tp0
case None => throw new MalformedClosure(parents)
}
@@ -2168,7 +2169,7 @@ trait Types requires SymbolTable {
if (rest exists (t1 => t <:< t1)) rest else t :: rest
}
- def lub(ts: List[Type]): Type = lub(ts, maxClosureDepth(ts))
+ def lub(ts: List[Type]): Type = lub(ts, maxClosureDepth(ts) + LubGlbMargin)
/** The least upper bound wrt &lt;:&lt; of a list of types */
def lub(ts: List[Type], depth: int): Type = {
@@ -2250,7 +2251,7 @@ trait Types requires SymbolTable {
res
}
- def glb(ts: List[Type]): Type = glb(ts, maxClosureDepth(ts))
+ def glb(ts: List[Type]): Type = glb(ts, maxClosureDepth(ts) + LubGlbMargin)
/** The greatest lower bound wrt &lt;:&lt; of a list of types */
private def glb(ts: List[Type], depth: int): Type = {
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 9849af6dcf..54ea55dde8 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -74,7 +74,7 @@ abstract class Constructors extends Transform {
}
else if (tree.symbol.outerSource == clazz && !clazz.isImplClass) {
thisRefSeen = false
- gen.mkAttributedIdent(parameterNamed(nme.OUTER))
+ gen.mkAttributedIdent(parameterNamed(nme.OUTER)) setPos tree.pos
}
else
super.transform(tree)
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 9df54f371a..17b3798e34 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -227,8 +227,9 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
gen.mkRuntimeCall(nme.arrayValue, List(tree1, Literal(pt.typeArgs.head)))
}
else {
- Apply(gen.mkAttributedRef(unboxMethod(pt.symbol)), List(tree)).
- setPos(tree.pos) setType pt
+ atPos(tree.pos) {
+ Apply(gen.mkAttributedRef(unboxMethod(pt.symbol)), List(tree)) setType pt
+ }
}
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 2080baff5c..70996371b8 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -37,6 +37,17 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter
private def isInner(clazz: Symbol) =
!clazz.isPackageClass && !clazz.outerClass.isStaticOwner
+ /** Does given <code>clazz</code> define an outer field? */
+ def hasOuterField(clazz: Symbol) = {
+ def hasSameOuter(parent: Type) =
+ parent.symbol.isClass &&
+ clazz.owner.isClass &&
+ clazz.owner == parent.symbol.owner &&
+ parent.prefix =:= clazz.owner.thisType
+ isInner(clazz) && !clazz.isTrait &&
+ (clazz.info.parents.isEmpty || !hasSameOuter(clazz.info.parents.head))
+ }
+
private def outerField(clazz: Symbol): Symbol = {
val result = clazz.info.member(nme.getterToLocal(nme.OUTER))
if (result == NoSymbol)
@@ -184,12 +195,12 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter
outerAcc.expandName(clazz)
val restpe = if (clazz.isTrait) clazz.outerClass.tpe else clazz.outerClass.thisType
decls1 enter clazz.newOuterAccessor(clazz.pos).setInfo(MethodType(List(), restpe))
- if (!clazz.isTrait) // 2
- //todo: avoid outer field if superclass has same outer value?
+ if (hasOuterField(clazz)) { //2
decls1 enter (
clazz.newValue(clazz.pos, nme.getterToLocal(nme.OUTER))
setFlag (SYNTHETIC | PROTECTED | PARAMACCESSOR)
setInfo clazz.outerClass.thisType)
+ }
}
if (!clazz.isTrait && !parents.isEmpty) {
for (val mc <- clazz.mixinClasses) {
@@ -513,7 +524,8 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter
atOwner(tree, currentOwner) {
if (!(currentClass hasFlag INTERFACE) || (currentClass hasFlag lateINTERFACE)) {
if (isInner(currentClass)) {
- if (!currentClass.isTrait) newDefs += outerFieldDef // (1a)
+ if (hasOuterField(currentClass))
+ newDefs += outerFieldDef // (1a)
newDefs += outerAccessorDef // (1)
}
if (!currentClass.isTrait)
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index 5871edbf10..2cceae8059 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -48,14 +48,20 @@ abstract class TreeCheckers extends Analyzer {
case EmptyTree | TypeTree() =>
;
case _ =>
- if (!tpeOfTree.contains(tree)) {
- tpeOfTree.update(tree, tree.tpe)
- tree.tpe = null
+ 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
}
- 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
}