summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBurak Emir <emir@epfl.ch>2006-11-29 18:05:14 +0000
committerBurak Emir <emir@epfl.ch>2006-11-29 18:05:14 +0000
commit10213bc9e7c1743f90b677b7f1bf45920f95fcf3 (patch)
tree0f640c9198627505d57b1c044d634fd4990b438b
parent6337248afe55a90280b6136ef83865f76598ff0f (diff)
downloadscala-10213bc9e7c1743f90b677b7f1bf45920f95fcf3.tar.gz
scala-10213bc9e7c1743f90b677b7f1bf45920f95fcf3.tar.bz2
scala-10213bc9e7c1743f90b677b7f1bf45920f95fcf3.zip
added -Xkilloption, unfinished
-rw-r--r--src/compiler/scala/tools/nsc/Settings.scala1
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternMatchers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala6
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala75
5 files changed, 83 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala
index 6d50522c13..90978e58b6 100644
--- a/src/compiler/scala/tools/nsc/Settings.scala
+++ b/src/compiler/scala/tools/nsc/Settings.scala
@@ -130,6 +130,7 @@ class Settings(error: String => unit) {
val Xexperimental = BooleanSetting("-Xexperimental", "enable experimental extensions")
val Xunapply = BooleanSetting("-Xunapply", "enable unapply pattern matching")
val Xplugtypes = BooleanSetting("-Xplugtypes", "parse but ignore annotations in more locations")
+ val Xkilloption = BooleanSetting("-Xkilloption", "optimizes option types")
/** A list of all settings */
def allSettings: List[Setting] = allsettings.reverse
diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
index 1bcb67c52d..d9957c87d0 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
@@ -1184,7 +1184,7 @@ print()
Or(squeezedBlock(
List(ValDef(v,Apply(fn1,List(selector)))),
And(Not(Select(Ident(v), nme.isEmpty)),
- squeezedBlock(List(ValDef(casted, typed(Select(Ident(v),"get")))),toTree(node.and)))),
+ squeezedBlock(List(ValDef(casted, typed(Select(Ident(v),nme.get)))),toTree(node.and)))),
toTree(node.or, selector.duplicate))
case ConstrPat(casted) =>
def outerAlwaysEqual(left: Type, right: Type) = Pair(left,right) match {
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index fe7c4d5cf5..752644d1e5 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -133,6 +133,7 @@ trait Definitions requires SymbolTable {
var OptionClass: Symbol = _
def SomeClass: Symbol = getClass("scala.Some")
+ def NoneClass: Symbol = getModule("scala.None")
def isOptionType(tp: Type) = tp match {
case TypeRef(_, sym, List(_)) if sym == OptionClass => true
@@ -148,6 +149,11 @@ trait Definitions requires SymbolTable {
def someType(tp: Type) =
typeRef(SomeClass.typeConstructor.prefix, SomeClass, List(tp))
+ def isNoneType(tp: Type) = tp match {
+ case TypeRef(_, sym, List(_)) if sym == NoneClass => true
+ case _ => false
+ }
+
def optionOfProductElems(tp: Type): List[Type] = {
assert(tp.symbol == OptionClass)
val prod = tp.typeArgs.head
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index 70047ddafc..c688824a11 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -256,6 +256,7 @@ trait StdNames requires SymbolTable {
val flatMap = newTermName("flatMap")
val forName = newTermName("forName")
val foreach = newTermName("foreach")
+ val get = newTermName("get")
val getClass_ = newTermName("getClass")
val hasAsInstance = newTermName("hasAsInstance")
val hashCode_ = newTermName("hashCode")
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 083887dd69..0538942fd0 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -93,13 +93,16 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter
* </ol>
*/
def transformInfo(sym: Symbol, tp: Type): Type = tp match {
- case MethodType(formals, restpe) =>
+ case MethodType(formals, restpe1) =>
+ val restpe = transformInfo(sym, restpe1) // removeOption
if (sym.owner.isTrait && ((sym hasFlag SUPERACCESSOR) || sym.isModule)) { // 5
sym.makeNotPrivate(sym.owner)
}
if (sym.owner.isTrait && (sym hasFlag PROTECTED)) sym setFlag notPROTECTED // 6
if (sym.isClassConstructor && isInner(sym.owner)) // 1
MethodType(sym.owner.outerClass.thisType :: formals, restpe)
+ else if (restpe ne restpe1)
+ MethodType(formals, restpe) // removeOption
else tp
case ClassInfoType(parents, decls, clazz) =>
var decls1 = decls
@@ -132,6 +135,15 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter
case PolyType(tparams, restp) =>
val restp1 = transformInfo(sym, restp)
if (restp eq restp1) tp else PolyType(tparams, restp1)
+
+ // <removeOption>
+ case TypeRef(_, sym, List(tpe))
+ if settings.Xkilloption.value
+ && (sym == definitions.OptionClass || sym == definitions.SomeClass)
+ && isSubType(tpe, definitions.AnyRefClass.tpe) =>
+ tpe
+ // </removeOption>
+
case _ =>
tp
}
@@ -308,12 +320,67 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter
/** The main transformation method */
override def transform(tree: Tree): Tree = {
+
+ def wasNone(tpe:Type) = atPhase(phase.prev){tpe}.symbol == definitions.NoneClass
+ def wasOption(tpe:Type) = {
+ def ntpe = if(tpe.isInstanceOf[SingleType]) tpe.widen else tpe
+ definitions.isOptionType(atPhase(phase.prev){ntpe})
+ }
+ def wasOptionRef(tpe:Type) = {
+ def ntpe = if(tpe.isInstanceOf[SingleType]) tpe.widen else tpe
+ val otpe = atPhase(phase.prev){ntpe}
+ definitions.isOptionType(otpe) && isSubType(otpe.typeArgs(0), definitions.AnyRefClass.tpe)
+ }
+
val sym = tree.symbol
if ((sym ne null) && sym.isType) {//(9)
if (sym hasFlag PRIVATE) sym setFlag notPRIVATE
if (sym hasFlag PROTECTED) sym setFlag notPROTECTED
}
tree match {
+
+ // <removeOption>
+
+ case sm @ Apply(fn, List(vlue)) // scala.Some(x:T) -> x if T <: AnyRef
+ if settings.Xkilloption.value
+ && definitions.isSomeType(sm.tpe)
+ && fn.symbol.isClassConstructor
+ && isSubType(sm.tpe.typeArgs(0), definitions.AnyRefClass.tpe) =>
+ vlue
+
+
+ case nne: Select // scala.None -> null
+ if settings.Xkilloption.value && wasNone(nne.tpe) =>
+ atPos(tree.pos) { typer.typed { Literal(Constant(null)) }}
+
+ case Apply(Select(t, nme.isEmpty),List()) // t.isEmpty -> t ne null
+ if settings.Xkilloption.value && wasOption(t.tpe) =>
+ NotNull(t)
+
+ case Apply(Select(t, nme.get),List()) // t.get -> t if T <: Option[AnyRef]
+ if settings.Xkilloption.value && wasOptionRef(t.tpe) =>
+ t
+
+ case Select(t, n)
+ if settings.Xkilloption.value && {Console.println(t.tpe); wasOption(t.tpe)} && n != nme.get =>
+ def ntpe = if(t.tpe.isInstanceOf[SingleType]) t.tpe.widen else t.tpe
+ val otpe = atPhase(phase.prev){ntpe}
+ val nt = atPos(tree.pos) { typer.typed {
+ Select(If(NotNull(t),
+ Apply(Select(New(TypeTree( definitions.someType(otpe.typeArgs(0)))), nme.CONSTRUCTOR), List(t)),
+ gen.mkAttributedRef(definitions.NoneClass)),
+ n)
+ }}
+ Console.println("nt == "+nt)
+ nt
+ case _ // e.g. this.blabla().x -> t
+ if settings.Xkilloption.value
+ && wasOptionRef(tree.tpe) =>
+ Console.println("cuckoo" + tree)
+ super.transform(tree.setType(atPhase(phase.prev){tree.tpe}.typeArgs(0)))
+
+ // </removeOption>
+
case Template(parents, decls) =>
val newDefs = new ListBuffer[Tree]
atOwner(tree, currentOwner) {
@@ -351,6 +418,12 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter
} else { //todo: see whether we can move this to transformInfo
if (sym.owner.isTrait && (sym hasFlag (ACCESSOR | SUPERACCESSOR)))
sym.makeNotPrivate(sym.owner); //(2)
+ if(settings.Xkilloption.value
+ && definitions.isOptionType(tpt.tpe)
+ && isSubType(tpt.tpe.typeArgs(0), definitions.AnyRefClass.tpe)) {
+
+ return super.transform(copy.DefDef(tree,mods,name,tparams,vparamss, TypeTree(tpt.tpe.typeArgs(0)), rhs))
+ }
super.transform(tree)
}