Permalink
Browse files

added existential types

  • Loading branch information...
1 parent 6ad83da commit 8414ebada9615aac0e8b436e7bdbeee5986ccaa3 @odersky odersky committed Jun 9, 2007
@@ -720,7 +720,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
case rawType => rawType
}
- map + name -> cleanedType.toString
+ map + name -> compiler.atPhase(objRun.typerPhase.next) { cleanedType.toString }
})
}
@@ -185,6 +185,7 @@ abstract class NodePrinters {
traverse(tparams(i), level + 2, i < n-1)
println(" ),")
}
+ println(tpt+",")
traverse(rhs, level + 1, false)
printcln(")")
case EmptyTree =>
@@ -252,6 +252,12 @@ abstract class TreePrinters {
case Throw(expr) =>
print("throw "); print(expr)
+ case Pack(expr) =>
+ print("pack("); print(expr); print(")")
+
+ case Unpack(expr) =>
+ print("unpack("); print(expr); print(")")
+
case New(tpe) =>
print("new "); print(tpe)
@@ -327,6 +333,10 @@ abstract class TreePrinters {
case WildcardTypeTree(lo, hi) =>
print("_ "); printOpt(" >: ", lo); printOpt(" <: ", hi)
+ case ExistentialTypeTree(tpt, whereClauses) =>
+ print(tpt);
+ printColumn(whereClauses, " for_some { ", ";", "}")
+
case tree =>
print("<unknown tree of class "+tree.getClass+">")
}
@@ -11,6 +11,7 @@ import java.io.{PrintWriter, StringWriter}
import scala.tools.nsc.symtab.Flags
import scala.tools.nsc.symtab.Flags._
import scala.tools.nsc.util.{HashSet, Position, NoPosition, SourceFile}
+import scala.collection.mutable.ListBuffer
trait Trees {
@@ -98,6 +99,16 @@ trait Trees {
def isErroneous = (tpe ne null) && tpe.isErroneous
+ /** Apply `f' to each subtree */
+ def foreach(f: Tree => Unit): Unit = new ForeachTraverser(f).traverse(this)
+
+ /** Find all subtrees matching predicate `p' */
+ def filter(f: Tree => Boolean): List[Tree] = {
+ val ft = new FilterTraverser(f)
+ ft.traverse(this)
+ ft.hits.toList
+ }
+
override def toString(): String = {
val buffer = new StringWriter()
val printer = treePrinters.create(new PrintWriter(buffer))
@@ -585,6 +596,14 @@ trait Trees {
case class Throw(expr: Tree)
extends TermTree
+ /** Pack skolemized type, yielding existential */
+ case class Pack(expr: Tree)
+ extends TermTree
+
+ /** Unpack existential, yielding skolemized type */
+ case class Unpack(expr: Tree)
+ extends TermTree
+
/** Object instantiation
* One should always use factory method below to build a user level new.
*
@@ -787,6 +806,10 @@ trait Trees {
// try block catch { catches } finally finalizer where catches: List[CaseDef]
case Throw(expr) =>
// throw expr
+ case Pack(expr) => (eliminated by erasure)
+ // internal: pack existential type
+ case Unpack(expr) => (eliminated by erasure)
+ // internal: unpack existential type
case New(tpt) =>
// new tpt always in the context: new tpt.<init>[targs](args)
case Typed(expr, tpt) => (eliminated by erasure)
@@ -853,6 +876,8 @@ trait Trees {
def Return(tree: Tree, expr: Tree): Return
def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree): Try
def Throw(tree: Tree, expr: Tree): Throw
+ def Pack(tree: Tree, expr: Tree): Pack
+ def Unpack(tree: Tree, expr: Tree): Unpack
def New(tree: Tree, tpt: Tree): New
def Typed(tree: Tree, expr: Tree, tpt: Tree): Typed
def TypeApply(tree: Tree, fun: Tree, args: List[Tree]): TypeApply
@@ -928,6 +953,10 @@ trait Trees {
new Try(block, catches, finalizer).copyAttrs(tree)
def Throw(tree: Tree, expr: Tree) =
new Throw(expr).copyAttrs(tree)
+ def Pack(tree: Tree, expr: Tree) =
+ new Pack(expr).copyAttrs(tree)
+ def Unpack(tree: Tree, expr: Tree) =
+ new Unpack(expr).copyAttrs(tree)
def New(tree: Tree, tpt: Tree) =
new New(tpt).copyAttrs(tree)
def Typed(tree: Tree, expr: Tree, tpt: Tree) =
@@ -1104,6 +1133,16 @@ trait Trees {
if expr0 == expr => t
case _ => copy.Throw(tree, expr)
}
+ def Pack(tree: Tree, expr: Tree) = tree match {
+ case t @ Pack(expr0)
+ if expr0 == expr => t
+ case _ => copy.Pack(tree, expr)
+ }
+ def Unpack(tree: Tree, expr: Tree) = tree match {
+ case t @ Unpack(expr0)
+ if expr0 == expr => t
+ case _ => copy.Unpack(tree, expr)
+ }
def New(tree: Tree, tpt: Tree) = tree match {
case t @ New(tpt0)
if tpt0 == tpt => t
@@ -1275,6 +1314,10 @@ trait Trees {
copy.Try(tree, transform(block), transformCaseDefs(catches), transform(finalizer))
case Throw(expr) =>
copy.Throw(tree, transform(expr))
+ case Pack(expr) =>
+ copy.Pack(tree, transform(expr))
+ case Unpack(expr) =>
+ copy.Unpack(tree, transform(expr))
case New(tpt) =>
copy.New(tree, transform(tpt))
case Typed(expr, tpt) =>
@@ -1423,6 +1466,10 @@ trait Trees {
traverse(block); traverseTrees(catches); traverse(finalizer)
case Throw(expr) =>
traverse(expr)
+ case Pack(expr) =>
+ traverse(expr)
+ case Unpack(expr) =>
+ traverse(expr)
case New(tpt) =>
traverse(tpt)
case Typed(expr, tpt) =>
@@ -1544,6 +1591,15 @@ trait Trees {
}
}
+ class ForeachTraverser(f: Tree => Unit) extends Traverser {
+ override def traverse(t: Tree) = f(t)
+ }
+
+ class FilterTraverser(p: Tree => Boolean) extends Traverser {
+ val hits = new ListBuffer[Tree]
+ override def traverse(t: Tree) = if (p(t)) hits += t
+ }
+
object resetPos extends Traverser {
override def traverse(t: Tree): unit = {
if (t != EmptyTree) t.setPos(NoPosition)
@@ -66,6 +66,7 @@ object Flags extends Enumeration {
// local value has been lifted out to class level
// todo: make LIFTED = latePRIVATE?
final val MIXEDIN = 0x800000000L // term member has been mixed in
+ final val EXISTENTIAL = 0x800000000L // type is an existential parameter or skolem
final val EXPANDEDNAME = 0x1000000000L // name has been expanded with class suffix
final val IMPLCLASS = 0x2000000000L // symbol is an implementation class
@@ -115,9 +115,6 @@ trait Symbols {
}
final def newThisSym(pos: Position) =
newValue(pos, nme.this_).setFlag(SYNTHETIC)
- final def newThisSkolem: Symbol =
- new ThisSkolem(owner, pos, name, this)
- .setFlag(SYNTHETIC | FINAL)
final def newImport(pos: Position) =
newValue(pos, nme.IMPORT)
final def newOverloaded(pre: Type, alternatives: List[Symbol]): Symbol =
@@ -196,14 +193,18 @@ trait Symbols {
final def isStaticModule = isModule && isStatic && !isMethod
final def isPackage = isModule && hasFlag(PACKAGE)
final def isThisSym = isTerm && owner.thisSym == this
- final def isThisSkolem = isTerm && deSkolemize != this
final def isMonomorphicType = isType && hasFlag(MONOMORPHIC)
final def isError = hasFlag(IS_ERROR)
final def isErroneous = isError || isInitialized && tpe.isErroneous
final def isTrait = isClass & hasFlag(TRAIT)
+ final def isSkolem = deSkolemize != this
final def isTypeParameterOrSkolem = isType && hasFlag(PARAM)
- final def isTypeParameter = isTypeParameterOrSkolem && deSkolemize == this
- final def isClassLocalToConstructor = isClass && hasFlag(INCONSTRUCTOR)
+ final def isTypeParameter = isTypeParameterOrSkolem && !isSkolem
+ final def isTypeSkolem = isTypeParameterOrSkolem && isSkolem
+ final def isExistential = isType && hasFlag(EXISTENTIAL)
+ final def isExistentialQuantified = isExistential && !isSkolem
+ final def isExistentialSkolem = isExistential && isSkolem
+ final def isClassLocalToConstructor = isClass && hasFlag(INCONSTRUCTOR)
final def isAnonymousClass = isClass && (originalName startsWith nme.ANON_CLASS_NAME)
// startsWith necessary because name may grow when lifted and also because of anonymous function classes
final def isRefinementClass = isClass && name == nme.REFINE_CLASS_NAME.toTypeName; // no lifting for refinement classes
@@ -1129,17 +1130,6 @@ trait Symbols {
}
}
- /** A class for type parameters viewed from inside their scopes */
- class ThisSkolem(initOwner: Symbol, initPos: Position,
- initName: Name, clazz: Symbol)
- extends TermSymbol(initOwner, initPos, initName) {
- override def deSkolemize = clazz
- override def cloneSymbolImpl(owner: Symbol): Symbol = {
- throw new Error("should not clone a this skolem")
- }
- override def nameString: String = clazz.name.toString() + ".this"
- }
-
/** A class of type symbols. Alias and abstract types are direct instances
* of this class. Classes are instances of a subclass.
*/
@@ -1168,7 +1158,8 @@ trait Symbols {
else unsafeTypeParams map (_.typeConstructor) //@M! use typeConstructor to generate dummy type arguments,
// sym.tpe should not be called on a symbol that's supposed to be a higher-kinded type
// memberType should be used instead, that's why it uses tpeHK and not tpe
- tpeCache = typeRef(if (isTypeParameterOrSkolem) NoPrefix else owner.thisType, this, targs)
+ tpeCache = typeRef(if (hasFlag(PARAM | EXISTENTIAL)) NoPrefix else owner.thisType,
+ this, targs)
}
}
assert(tpeCache ne null/*, "" + this + " " + phase*/)//debug
@@ -1177,7 +1168,8 @@ trait Symbols {
override def typeConstructor: Type = {
if ((tyconCache eq null) || tyconRunId != currentRunId) {
- tyconCache = typeRef(if (isTypeParameter) NoPrefix else owner.thisType, this, List())
+ tyconCache = typeRef(if (hasFlag(PARAM | EXISTENTIAL)) NoPrefix else owner.thisType,
+ this, List())
tyconRunId = currentRunId
}
assert(tyconCache ne null)
Oops, something went wrong.

0 comments on commit 8414eba

Please sign in to comment.