git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@5722 5e8d7ff9-d8ef-0310-90f0-a4852d11357a

This commit is contained in:
odersky 2006-02-09 16:25:11 +00:00
parent ed47b10b5e
commit 9c2316fd39
9 changed files with 60 additions and 145 deletions

View File

@ -223,9 +223,9 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
val global: Global.this.type = Global.this;
}
object checkDefined extends CheckDefined {
val global: Global.this.type = Global.this;
}
// object checkDefined extends CheckDefined {
// val global: Global.this.type = Global.this;
// }
object explicitOuter extends ExplicitOuter {
val global: Global.this.type = Global.this;
@ -285,7 +285,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
uncurry,
tailCalls,
transMatcher,
checkDefined,
// checkDefined,
explicitOuter,
erasure,
lambdaLift,

View File

@ -73,7 +73,7 @@ mixin class Definitions requires SymbolTable {
var ArrayClass: Symbol = _;
var TypeClass: Symbol = _;
var SerializableClass: Symbol = _;
var NonNullClass: Symbol = _;
//var NonNullClass: Symbol = _;
var PredefModule: Symbol = _;
var ConsoleModule: Symbol = _;
var MatchErrorClass: Symbol = _;
@ -349,7 +349,7 @@ mixin class Definitions requires SymbolTable {
ArrayClass = getClass("scala.Array");
//TypeClass = getClass("scala.Type");
SerializableClass = getClass("java.io.Serializable");
NonNullClass = getClass("scala.NonNull");
//NonNullClass = getClass("scala.NonNull");
PredefModule = getModule("scala.Predef");
ConsoleModule = getModule("scala.Console");
MatchErrorClass = getClass("scala.MatchError");

View File

@ -49,8 +49,6 @@ mixin class Types requires SymbolTable {
val emptyTypeArray = new Array[Type](0);
final val X = true;
/** The base class for all types */
abstract class Type {
@ -128,7 +126,10 @@ mixin class Types requires SymbolTable {
def isStable: boolean = false;
/** Does this type denote a reference type which can be null? */
def isNullable: boolean = false;
// def isNullable: boolean = false;
/** Is this type guaranteed to be non-null? */
// def isNonNull: boolean = false;
/** For a classtype or refined type, its defined or declared members;
* inherited by subtypes and typerefs.
@ -433,6 +434,7 @@ mixin class Types requires SymbolTable {
override def baseType(clazz: Symbol): Type = supertype.baseType(clazz);
override def closure: Array[Type] = supertype.closure;
override def baseClasses: List[Symbol] = supertype.baseClasses;
// override def isNonNull = supertype.isNonNull;
}
/** A base class for types that represent a single value
@ -466,20 +468,20 @@ mixin class Types requires SymbolTable {
override def baseType(clazz: Symbol): Type = this;
override def toString(): String = "<error>";
override def narrow: Type = this;
override def isNullable: boolean = true;
// override def isNullable: boolean = true;
}
/** An object representing an unknown type */
case object WildcardType extends Type {
override def toString(): String = "?"
override def isNullable: boolean = true;
// override def isNullable: boolean = true;
}
/** An object representing a non-existing type */
case object NoType extends Type {
override def isTrivial: boolean = true;
override def toString(): String = "<notype>"
override def isNullable: boolean = true;
// override def isNullable: boolean = true;
}
/** An object representing a non-existing prefix */
@ -488,7 +490,7 @@ mixin class Types requires SymbolTable {
override def isStable: boolean = true;
override def prefixString = "";
override def toString(): String = "<noprefix>";
override def isNullable: boolean = true;
// override def isNullable: boolean = true;
}
/** A class for this-types of the form <sym>.this.type
@ -496,6 +498,7 @@ mixin class Types requires SymbolTable {
abstract case class ThisType(sym: Symbol) extends SingletonType {
//assert(sym.isClass && !sym.isModuleClass || sym.isRoot, sym);
override def isTrivial: boolean = sym.isPackageClass;
// override def isNonNull = true;
override def symbol = sym;
override def singleDeref: Type = sym.typeOfThis;
override def prefixString =
@ -513,6 +516,8 @@ mixin class Types requires SymbolTable {
*/
abstract case class SingleType(pre: Type, sym: Symbol) extends SingletonType {
override val isTrivial: boolean = pre.isTrivial;
// override def isNullable = supertype.isNullable;
// override def isNonNull = supertype.isNonNull;
private var singleDerefCache: Type = _;
private var singleDerefPhase: Phase = null;
override def singleDeref: Type = {
@ -534,6 +539,7 @@ mixin class Types requires SymbolTable {
abstract case class SuperType(thistpe: Type, supertp: Type) extends SingletonType {
override val isTrivial: boolean = thistpe.isTrivial && supertp.isTrivial;
// override def isNonNull = true;
override def symbol = thistpe.symbol;
override def singleDeref = supertp;
override def prefix: Type = supertp.prefix;
@ -551,14 +557,13 @@ mixin class Types requires SymbolTable {
def supertype: Type = hi;
override def bounds: TypeBounds = this;
def containsType(that: Type) = that <:< this || lo <:< that && that <:< hi;
override def isNullable: boolean = AllRefClass.tpe <:< lo;
// override def isNullable: boolean = AllRefClass.tpe <:< lo;
override def toString() = ">: " + lo + " <: " + hi;
}
/** A common base class for intersection types and class types
*/
abstract class CompoundType extends Type {
assert(!parents.exists (.isInstanceOf[TypeBounds]), this);//debug
private var closureCache: Array[Type] = _;
private var closurePhase: Phase = null;
@ -692,8 +697,10 @@ mixin class Types requires SymbolTable {
override def narrow: Type = symbol.thisType;
override def isNullable: boolean =
parents forall (p => p.isNullable && !p.symbol.isAbstractType);
// override def isNonNull: boolean = parents forall (.isNonNull);
// override def isNullable: boolean =
// parents forall (p => p.isNullable && !p.symbol.isAbstractType);
override def toString(): String = (
parents.mkString("", " with ", "") +
@ -717,10 +724,11 @@ mixin class Types requires SymbolTable {
override val decls: Scope,
override val symbol: Symbol) extends CompoundType {
override def isNullable: boolean =
symbol == AnyClass ||
symbol != AllClass && (symbol isSubClass ObjectClass) && !(symbol isSubClass NonNullClass);
// override def isNullable: boolean =
// symbol == AnyClass ||
// symbol != AllClass && (symbol isSubClass ObjectClass) && !(symbol isSubClass NonNullClass);
// override def isNonNull: boolean = symbol == NonNullClass || super.isNonNull;
}
class PackageClassInfoType(decls: Scope, clazz: Symbol) extends ClassInfoType(List(), decls, clazz);
@ -733,7 +741,8 @@ mixin class Types requires SymbolTable {
override def singleDeref: Type = value.tpe;
override def deconst: Type = value.tpe;
override def toString(): String = value.tpe.toString() + "(" + value.stringValue + ")";
override def isNullable: boolean = value.value == null
// override def isNullable: boolean = value.value == null
// override def isNonNull: boolean = value.value != null
}
/** A class for named types of the form <prefix>.<sym.name>[args]
@ -820,7 +829,7 @@ mixin class Types requires SymbolTable {
override def baseClasses: List[Symbol] = sym.info.baseClasses;
override def isNullable: boolean = sym.info.isNullable
// override def isNullable: boolean = sym.info.isNullable
override def toString(): String = {
if (!settings.debug.value) {
@ -883,7 +892,7 @@ mixin class Types requires SymbolTable {
override def baseType(clazz: Symbol): Type = resultType.baseType(clazz);
override def narrow: Type = resultType.narrow;
override def isNullable: boolean = resultType.isNullable;
// override def isNullable: boolean = resultType.isNullable;
override def toString(): String =
(if (typeParams.isEmpty) "=> "
@ -1550,14 +1559,15 @@ mixin class Types requires SymbolTable {
||
sym2.isAbstractType && !(tp2 =:= tp2.bounds.lo) && (tp1 <:< tp2.bounds.lo)
||
// sym2 == NonNullClass && tp1.isNonNull
// ||
sym2.isClass &&
({ val base = tp1 baseType sym2; !(base eq tp1) && (base <:< tp2) })
||
sym1 == AllClass
||
sym1 == AllRefClass &&
(if (X) tp2.isNullable
else sym2 != AllClass && tp2 <:< AnyRefClass.tpe))
// System.out.println("last chance " + sym1 + " " + sym2 + " " + sym2.isClass + " " (sym2 isSubClass ObjectClass))
sym1 == AllRefClass && sym2.isClass && (sym2 isSubClass ObjectClass))
case Pair(MethodType(pts1, res1), MethodType(pts2, res2)) =>
(pts1.length == pts2.length &&
matchingParams(pts1, pts2, tp2.isInstanceOf[JavaMethodType]) &&
@ -1592,9 +1602,12 @@ mixin class Types requires SymbolTable {
case Pair(TypeRef(pre1, sym1, args1), _) =>
(sym1 == AllClass && tp2 <:< AnyClass.tpe
||
sym1 == AllRefClass && (
sym1 == AllRefClass && tp2.isInstanceOf[SingletonType] && (tp1 <:< tp2.widen))
/* ||
sym1 == AllRefClass && tp2.symbol != AllClass &&
tp2 <:< AnyRefClass.tpe))
if (X) tp2.isNullable
else tp2.symbol != AllClass && tp2 <:< AnyRefClass.tpe))
else tp2.symbol != AllClass && tp2 <:< AnyRefClass.tpe))*/
case _ =>
false
}
@ -1934,7 +1947,7 @@ mixin class Types requires SymbolTable {
}
} catch {
case _: MalformedClosure =>
if (ts forall (t => if (X) t.isNullable else t <:< AnyRefClass.tpe)) AllRefClass.tpe
if (ts forall (t => AllRefClass.tpe <:< t)) AllRefClass.tpe
else AllClass.tpe
}
}

View File

@ -1,83 +0,0 @@
/* NSC -- new scala compiler
* Copyright 2005 LAMP/EPFL
* @author
*/
// $Id: ExplicitOuter.scala 5642 2006-01-26 13:00:58Z odersky $
package scala.tools.nsc.transform;
import symtab._;
import Flags._;
abstract class CheckDefined extends Transform {
import global._;
import definitions._;
import posAssigner.atPos;
/** the following two members override abstract members in Transform */
val phaseName: String = "checkdefined";
protected def newTransformer(unit: CompilationUnit): Transformer =
new CheckDefinedTransformer(unit);
class CheckDefinedTransformer(unit: CompilationUnit) extends Transformer {
var qualNode: Tree = EmptyTree;
private def isAlwaysInitialized(tp: Type): boolean = tp match {
case ConstantType(_) => true
case ThisType(_) => true
case SuperType(_, _) => true
case SingleType(_, sym) => sym.isModule || isAlwaysInitialized(tp.singleDeref)
case TypeRef(_, sym, _) => sym.isModuleClass
case _ => false
}
def checkDefined(tree: Tree): Tree = {
/*
System.out.println("check def? " + tree + " " +
(tree ne qualNode) + " " +
(tree.symbol hasFlag ACCESSOR) + " " +
!(tree.symbol hasFlag PARAMACCESSOR) + " " +
(tree.tpe <:< AnyClass.tpe) + " " +
(tree.tpe.symbol != AllClass) + " " +
!tree.tpe.isNullable + " " +
!(tree.tpe <:< AnyValClass.tpe) + " " +
!isAlwaysInitialized(tree.tpe));
*/
if ((tree ne qualNode) &&
(tree.symbol hasFlag ACCESSOR) &&
!(tree.symbol hasFlag PARAMACCESSOR) &&
(tree.tpe <:< AnyClass.tpe) &&
!(tree.tpe <:< AnyValClass.tpe) &&
(tree.tpe.symbol != AllClass) &&
!tree.tpe.isNullable &&
!isAlwaysInitialized(tree.tpe)) {
if (settings.debug.value) log("check def " + tree + ":" + tree.tpe + " in " + unit.source.file);
atPos(tree.pos) {
Apply(
TypeApply(
gen.mkRef(checkDefinedMethod),
List(TypeTree(tree.tpe))
) setType MethodType(List(tree.tpe), tree.tpe),
List(tree)
) setType tree.tpe
}
} else tree;
}
override def transform(tree: Tree): Tree = {
tree match {
case Select(qual, name) =>
val savedQualNode = qualNode;
qualNode = qual;
val tree1 = super.transform(tree);
qualNode = savedQualNode;
checkDefined(tree1)
case Apply(fn, List()) =>
checkDefined(super.transform(tree))
case _ =>
super.transform(tree)
}
}
}
}

View File

@ -540,9 +540,9 @@ mixin class Infer requires Analyzer {
System.out.println("new bounds of " + tparam + " = " + tparam.info);//debug
}
}
} else { System.out.println("no instance: "); instError }
} else { System.out.println("not a subtype " + restpe.subst(undetparams, tvars) + " of " + ptWithWildcards); instError }
} else { System.out.println("not fuly defined: " + pt); instError }
} else { if (settings.debug.value) System.out.println("no instance: "); instError }
} else { if (settings.debug.value) System.out.println("not a subtype " + restpe.subst(undetparams, tvars) + " of " + ptWithWildcards); instError }
} else { if (settings.debug.value) System.out.println("not fuly defined: " + pt); instError }
}
/* -- Overload Resolution ----------------------------------------------------------- */

View File

@ -834,9 +834,19 @@ mixin class Typers requires Analyzer {
copy.CaseDef(cdef, pat1, guard1, body1) setType body1.tpe
}
def typedCases(tree: Tree, cases: List[CaseDef], pattp: Type, pt: Type): List[CaseDef] = {
List.mapConserve(cases)(cdef =>
newTyper(context.makeNewScope(cdef, context.owner)).typedCase(cdef, pattp, pt))
def typedCases(tree: Tree, cases: List[CaseDef], pattp0: Type, pt: Type): List[CaseDef] = {
var pattp = pattp0
List.mapConserve(cases) ( cdef =>
newTyper(context.makeNewScope(cdef, context.owner)).typedCase(cdef, pattp, pt))
/* not yet!
cdef.pat match {
case Literal(Constant(null)) =>
if (!(pattp <:< NonNullClass.tpe))
pattp = intersectionType(List(pattp, NonNullClass.tpe), context.owner)
case _ =>
}
result
*/
}
def typedFunction(fun: Function, mode: int, pt: Type): Tree = {

View File

@ -1,13 +0,0 @@
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2002-2005, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
// $Id: ScalaObject.scala 5390 2005-12-19 13:49:03Z dubochet $
package scala;
trait NonNull;

View File

@ -1,12 +0,0 @@
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2002, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
** **
** $Id: MatchError.scala 5390 2005-12-19 13:49:03Z dubochet $
\* */
package scala;
final class UndefinedException extends RuntimeException;

View File

@ -88,8 +88,8 @@ object ScalaRunTime {
false
}
def checkDefined[T >: AllRef](x: T): T =
if (x == null) throw new UndefinedException else x
//def checkDefined[T >: AllRef](x: T): T =
// if (x == null) throw new UndefinedException else x
def Seq[a](xs: a*): Seq[a] = null; // interpreted specially by new backend.