summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-10-11 20:28:06 +0000
committerMartin Odersky <odersky@gmail.com>2005-10-11 20:28:06 +0000
commit76993fa93bc39bab65e61b4fa9a3887befd48372 (patch)
tree71186c566ccdb15b5264f6e649a67212cc246feb
parent899e2bf1b2aac960ba459cc1e1667ac05cf5b2cc (diff)
downloadscala-76993fa93bc39bab65e61b4fa9a3887befd48372.tar.gz
scala-76993fa93bc39bab65e61b4fa9a3887befd48372.tar.bz2
scala-76993fa93bc39bab65e61b4fa9a3887befd48372.zip
*** empty log message ***
-rwxr-xr-xsources/scala/reflect/Symbol.scala4
-rwxr-xr-xsources/scala/reflect/Type.scala3
-rwxr-xr-xsources/scala/tools/nsc/ast/parser/Parsers.scala10
-rwxr-xr-xsources/scala/tools/nsc/ast/parser/Scanners.scala1
-rw-r--r--sources/scala/tools/nsc/ast/parser/Tokens.scala1
-rwxr-xr-xsources/scala/tools/nsc/symtab/StdNames.scala1
-rwxr-xr-xsources/scala/tools/nsc/symtab/Symbols.scala5
-rwxr-xr-xsources/scala/tools/nsc/transform/Erasure.scala18
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Codification.scala125
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala17
-rwxr-xr-xtest-nsc/files/pos/code.scala3
-rwxr-xr-xtest-nsc/files/run/bug457.scala36
12 files changed, 161 insertions, 63 deletions
diff --git a/sources/scala/reflect/Symbol.scala b/sources/scala/reflect/Symbol.scala
index d0368edd72..14be8e9317 100755
--- a/sources/scala/reflect/Symbol.scala
+++ b/sources/scala/reflect/Symbol.scala
@@ -25,7 +25,7 @@ abstract class GlobalSymbol(val fullname: String) extends Symbol {
abstract class LocalSymbol extends Symbol {}
case class Class(override val fullname: String) extends GlobalSymbol(fullname) {
- val tpe = TypeIdent(ThisType(owner), this);
+ val tpe = NamedType(fullname);
}
case class Method(override val fullname: String, tpe: Type) extends GlobalSymbol(fullname);
@@ -47,5 +47,5 @@ case object NoSymbol extends Symbol {
case object RootSymbol extends Symbol {
val owner = NoSymbol;
val name = "<root>";
- val tpe = TypeIdent(NoPrefix, this)
+ val tpe = NoPrefix
}
diff --git a/sources/scala/reflect/Type.scala b/sources/scala/reflect/Type.scala
index 9b4c4d2e1b..76f1ffd227 100755
--- a/sources/scala/reflect/Type.scala
+++ b/sources/scala/reflect/Type.scala
@@ -13,7 +13,8 @@ abstract class Type;
case object NoPrefix extends Type;
case object NoType extends Type;
-case class TypeIdent(pre: Type, sym: Symbol) extends Type;
+case class NamedType(fullname: String) extends Type;
+case class PrefixedType(pre: Type, sym: Symbol) extends Type;
case class SingleType(pre: Type, sym: Symbol) extends Type;
case class ThisType(clazz: Symbol) extends Type;
case class AppliedType(tpe: Type, args: List[Type]) extends Type;
diff --git a/sources/scala/tools/nsc/ast/parser/Parsers.scala b/sources/scala/tools/nsc/ast/parser/Parsers.scala
index 59eaa4eb47..d8a4f9e49d 100755
--- a/sources/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/sources/scala/tools/nsc/ast/parser/Parsers.scala
@@ -436,10 +436,10 @@ import Tokens._;
if (in.token == COLON) { in.nextToken(); typ() }
else TypeTree();
- /** SimpleTypedOpt ::= [`:' SimpleType]
+ /** RequiresTypedOpt ::= [`:' SimpleType | requires SimpleType]
*/
- def simpleTypedOpt(): Tree =
- if (in.token == COLON) { in.nextToken(); simpleType() }
+ def requiresTypeOpt(): Tree =
+ if (in.token == COLON | in.token == REQUIRES) { in.nextToken(); simpleType() }
else TypeTree();
/** Types ::= Type {`,' Type}
@@ -1484,7 +1484,7 @@ import Tokens._;
EmptyTree
}
- /** ClassDef ::= ClassSig [`:' SimpleType] ClassTemplate
+ /** ClassDef ::= ClassSig RequiresTypeOpt ClassTemplate
* ClassSig ::= Id [TypeParamClause] {ClassParamClause}
*/
def classDef(mods: int): Tree =
@@ -1494,7 +1494,7 @@ import Tokens._;
val tparams = typeParamClauseOpt(name, implicitViews);
if ((mods & Flags.CASE) != 0 && in.token != LPAREN) accept(LPAREN);
val vparamss = paramClauses(name, implicitViews.toList, (mods & Flags.CASE) != 0);
- val thistpe = simpleTypedOpt();
+ val thistpe = requiresTypeOpt();
val template = classTemplate(mods, name, vparamss);
ClassDef(mods, name, tparams, thistpe, template)
}
diff --git a/sources/scala/tools/nsc/ast/parser/Scanners.scala b/sources/scala/tools/nsc/ast/parser/Scanners.scala
index 31508fc1e5..bf55b2ebe9 100755
--- a/sources/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/sources/scala/tools/nsc/ast/parser/Scanners.scala
@@ -745,6 +745,7 @@ import scala.tools.nsc.util.CharArrayReader;
enterKeyword(nme.IMPLICITkw, IMPLICIT);
enterKeyword(nme.IMPORTkw, IMPORT);
enterKeyword(nme.MATCHkw, MATCH);
+ enterKeyword(nme.REQUIRESkw, REQUIRES);
enterKeyword(nme.NEWkw, NEW);
enterKeyword(nme.NULLkw, NULL);
enterKeyword(nme.OBJECTkw, OBJECT);
diff --git a/sources/scala/tools/nsc/ast/parser/Tokens.scala b/sources/scala/tools/nsc/ast/parser/Tokens.scala
index 67c7572aac..85340fa84b 100644
--- a/sources/scala/tools/nsc/ast/parser/Tokens.scala
+++ b/sources/scala/tools/nsc/ast/parser/Tokens.scala
@@ -66,6 +66,7 @@ object Tokens {
final val WHILE = 56;
final val RETURN = 57;
final val MATCH = 58;
+ final val REQUIRES = 59;
/** special symbols */
final val COMMA = 61;
diff --git a/sources/scala/tools/nsc/symtab/StdNames.scala b/sources/scala/tools/nsc/symtab/StdNames.scala
index 78d4da8403..022d4ec357 100755
--- a/sources/scala/tools/nsc/symtab/StdNames.scala
+++ b/sources/scala/tools/nsc/symtab/StdNames.scala
@@ -37,6 +37,7 @@ import scala.tools.nsc.util.NameTransformer;
val PRIVATEkw = newTermName("private");
val PROTECTEDkw = newTermName("protected");
val RETURNkw = newTermName("return");
+ val REQUIRESkw = newTermName("requires");
val SEALEDkw = newTermName("sealed");
val SUPERkw = newTermName("super");
val THISkw = newTermName("this");
diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala
index 0bf2c14ec5..2fef116ccd 100755
--- a/sources/scala/tools/nsc/symtab/Symbols.scala
+++ b/sources/scala/tools/nsc/symtab/Symbols.scala
@@ -840,6 +840,11 @@ import Flags._;
override def setInfo(tp: Type): this.type = {
tpePhase = null;
tyconCache = null;
+ tp match { //debug
+ case TypeRef(_, sym, _) =>
+ assert(sym != this, this);
+ case _ =>
+ }
super.setInfo(tp);
this
}
diff --git a/sources/scala/tools/nsc/transform/Erasure.scala b/sources/scala/tools/nsc/transform/Erasure.scala
index ac2413c678..b14b939e70 100755
--- a/sources/scala/tools/nsc/transform/Erasure.scala
+++ b/sources/scala/tools/nsc/transform/Erasure.scala
@@ -278,7 +278,23 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
/** A replacement for the standard typer's `typed1' method */
override protected def typed1(tree: Tree, mode: int, pt: Type): Tree = {
- super.typed1(adaptMember(tree), mode, pt)
+ val tree1 = super.typed1(adaptMember(tree), mode, pt);
+ tree1 match {
+ case If(cond, thenp, elsep) =>
+ val thenp1 = adaptToType(thenp, tree1.tpe);
+ val elsep1 = if (elsep.isEmpty) elsep else adaptToType(elsep, tree1.tpe);
+ copy.If(tree1, cond, thenp1, elsep1);
+ case Match(selector, cases) =>
+ val cases1 = cases map {
+ case cdef @ CaseDef(pat, guard, body) =>
+ val body1 = adaptToType(body, tree1.tpe);
+ copy.CaseDef(cdef, pat, guard, body1) setType body1.tpe
+ }
+ copy.Match(tree1, selector, cases1)
+ // todo: do same for try
+ case _ =>
+ tree1
+ }
}
}
diff --git a/sources/scala/tools/nsc/typechecker/Codification.scala b/sources/scala/tools/nsc/typechecker/Codification.scala
index 9070b001b3..3c1b53b952 100755
--- a/sources/scala/tools/nsc/typechecker/Codification.scala
+++ b/sources/scala/tools/nsc/typechecker/Codification.scala
@@ -13,10 +13,6 @@ import scala.tools.nsc.util.{ListBuffer, FreshNameCreator};
import global._;
- def codify(tree: Tree): Tree =
- New(TypeTree(appliedType(definitions.TypedCodeClass.typeConstructor, List(tree.tpe))),
- List(List(inject(reify(tree)))));
-
case class FreeValue(tree: Tree) extends reflect.Code;
type ReifyEnvironment = ListMap[Symbol, reflect.Symbol];
@@ -51,19 +47,25 @@ import scala.tools.nsc.util.{ListBuffer, FreshNameCreator};
throw new TypeError("cannot reify tree: " + tree)
}
+ private def mkGlobalSymbol(fullname: String, sym: Symbol): reflect.Symbol =
+ if (sym.isClass) reflect.Class(fullname)
+ else if (sym.isType) reflect.TypeField(fullname, reify(sym.info))
+ else if (sym.isMethod) reflect.Method(fullname, reify(sym.info))
+ else reflect.Field(fullname, reify(sym.info));
+
def reify(sym: Symbol): reflect.Symbol = env.get(sym) match {
case Some(rsym) =>
rsym
case None =>
- reify(sym.owner) match {
+ if (sym.isRoot || sym.isRootPackage || sym.isEmptyPackageClass || sym.isEmptyPackage)
+ reflect.RootSymbol
+ else reify(sym.owner) match {
case reflect.NoSymbol =>
reflect.NoSymbol;
- case reflect.Class(ownername) =>
- val fullname = ownername + "." + sym.name;
- if (sym.isClass) reflect.Class(fullname)
- else if (sym.isType) reflect.TypeField(fullname, reify(sym.info))
- else if (sym.isMethod) reflect.Method(fullname, reify(sym.info))
- else reflect.Field(fullname, reify(sym.info))
+ case reflect.RootSymbol =>
+ mkGlobalSymbol(sym.name.toString(), sym)
+ case reflect.Class(ownername) =>
+ mkGlobalSymbol(ownername + "." + sym.name, sym)
case _ =>
reflect.NoSymbol
}
@@ -75,8 +77,9 @@ import scala.tools.nsc.util.{ListBuffer, FreshNameCreator};
case NoType =>
reflect.NoType
case TypeRef(pre, sym, args) =>
- val tp = reflect.TypeIdent(reify(pre), reify(sym));
- if (args.isEmpty) tp else reflect.AppliedType(tp, args map reify)
+ val tp = if (sym.owner.isPackageClass) reflect.NamedType(sym.fullNameString);
+ else reflect.PrefixedType(reify(pre), reify(sym));
+ if (args.isEmpty) tp else reflect.AppliedType(tp, args map reify)
case SingleType(pre, sym) =>
reflect.SingleType(reify(pre), reify(sym))
case ThisType(clazz) =>
@@ -99,35 +102,38 @@ import scala.tools.nsc.util.{ListBuffer, FreshNameCreator};
// todo replace className by caseName in CaseClass once we have switched to nsc.
def className(value: CaseClass): String = value match {
- case reflect.Ident(_) => "Ident"
- case reflect.Select(_, _) => "Select"
- case reflect.Literal(_) => "Literal"
- case reflect.Apply(_, _) => "Apply"
- case reflect.TypeApply(_, _) => "TypeApply"
- case reflect.Function(_, _) => "Function"
- case reflect.Class(_) => "Class"
- case reflect.Method(_, _) => "Method"
- case reflect.Field(_, _) => "Field"
- case reflect.TypeIdent(_, _) => "TypeIdent"
- case reflect.SingleType(_, _) => "SingleType"
- case reflect.ThisType(_) => "ThisType"
- case reflect.AppliedType(_, _) => "AppliedType"
- case reflect.TypeBounds(_, _) => "TypeBounds"
+ case _ :: _ => "scala.$colon$colon"
+ case reflect.Ident(_) => "scala.reflect.Ident"
+ case reflect.Select(_, _) => "scala.reflect.Select"
+ case reflect.Literal(_) => "scala.reflect.Literal"
+ case reflect.Apply(_, _) => "scala.reflect.Apply"
+ case reflect.TypeApply(_, _) => "scala.reflect.TypeApply"
+ case reflect.Function(_, _) => "scala.reflect.Function"
+ case reflect.Class(_) => "scala.reflect.Class"
+ case reflect.Method(_, _) => "scala.reflect.Method"
+ case reflect.Field(_, _) => "scala.reflect.Field"
+ case reflect.NamedType(_) => "scala.reflect.NamedType"
+ case reflect.PrefixedType(_, _) => "scala.reflect.PrefixedType"
+ case reflect.SingleType(_, _) => "scala.reflect.SingleType"
+ case reflect.ThisType(_) => "scala.reflect.ThisType"
+ case reflect.AppliedType(_, _) => "scala.reflect.AppliedType"
+ case reflect.TypeBounds(_, _) => "scala.reflect.TypeBounds"
case reflect.MethodType(_, _) =>
- if (value.isInstanceOf[reflect.ImplicitMethodType]) "ImplicitMethodType" else "MethodType"
+ if (value.isInstanceOf[reflect.ImplicitMethodType]) "scala.reflect.ImplicitMethodType" else "scala.reflect.MethodType"
case _ =>
""
}
def objectName(value: Any): String = value match {
- case reflect.NoSymbol => "NoSymbol"
- case reflect.RootSymbol => "RootSymbol"
- case reflect.NoPrefix => "NoPrefix"
- case reflect.NoType => "NoType"
+ case Nil => "scala.Nil"
+ case reflect.NoSymbol => "scala.reflect.NoSymbol"
+ case reflect.RootSymbol => "scala.reflect.RootSymbol"
+ case reflect.NoPrefix => "scala.reflect.NoPrefix"
+ case reflect.NoType => "scala.reflect.NoType"
case _ => ""
}
- def injectType(name: String): Tree = TypeTree(definitions.getClass("scala.reflect." + name).tpe);
+ def injectType(name: String): Tree = TypeTree(definitions.getClass(name).initialize.tpe);
def inject(value: Any): Tree = value match {
case FreeValue(tree) =>
@@ -137,26 +143,34 @@ import scala.tools.nsc.util.{ListBuffer, FreshNameCreator};
val vdefs = for (val param <- params) yield {
val lname = newTermName(fresh.newName());
env1 = env1.update(param, lname);
- ValDef(0, lname, injectType("LocalValue"),
- New(injectType("LocalValue"),
+ ValDef(0, lname, injectType("scala.reflect.LocalValue"),
+ New(injectType("scala.reflect.LocalValue"),
List(List(inject(param.owner), inject(param.name), inject(param.tpe)))))
}
Block(vdefs, new Injector(env1, fresh).inject(body))
case rsym: reflect.LocalSymbol =>
Ident(env(rsym))
- case s: String =>
- Literal(Constant(s))
+ case x: String => Literal(Constant(x))
+ case x: Boolean => Literal(Constant(x))
+ case x: Byte => Literal(Constant(x))
+ case x: Short => Literal(Constant(x))
+ case x: Char => Literal(Constant(x))
+ case x: Int => Literal(Constant(x))
+ case x: Long => Literal(Constant(x))
+ case x: Float => Literal(Constant(x))
+ case x: Double => Literal(Constant(x))
case c: CaseClass =>
- val name = className(c);
- if (name.length == 0) throw new Error("don't know how to inject " + value);
- val injectedArgs = new ListBuffer[Tree];
- for (val i <- Iterator.range(0, c.caseArity))
- injectedArgs += inject(c.caseElement(i));
- New(injectType(name), List(injectedArgs.toList))
- case _ =>
- val name = objectName(value);
- if (name.length == 0) throw new Error("don't know how to inject " + value);
- gen.mkRef(definitions.getModule("scala.reflect." + name))
+ val name = objectName(c);
+ if (name.length() != 0) gen.mkRef(definitions.getModule(name))
+ else {
+ val name = className(c);
+ if (name.length() == 0) throw new Error("don't know how to inject " + value);
+ val injectedArgs = new ListBuffer[Tree];
+ for (val i <- Iterator.range(0, c.caseArity))
+ injectedArgs += inject(c.caseElement(i));
+ New(Ident(definitions.getClass(name)), List(injectedArgs.toList))
+ }
+ case _ => throw new Error("don't know how to inject " + value);
}
}
@@ -165,4 +179,21 @@ import scala.tools.nsc.util.{ListBuffer, FreshNameCreator};
def inject(code: reflect.Code): Tree =
new Injector(ListMap.Empty, new FreshNameCreator).inject(code);
+
+ /** returns
+ * < new TypedCode[T](tree1) >
+ * where T = tree.tpe
+ * tree1 = inject(reify(tree))
+ */
+ def codify(tree: Tree): Tree = {
+ val reified = reify(tree);
+ System.out.println("reified = " + reified);
+ val injected = inject(reified);
+ System.out.println("injected = " + injected);
+ New(TypeTree(appliedType(definitions.TypedCodeClass.typeConstructor, List(tree.tpe))),
+ List(List(injected)));
+
+ }
}
+
+
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
index 83ec152b06..0356cd7bd6 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -40,7 +40,8 @@ import collection.mutable.HashMap;
val infer = new Inferencer(context0) {
override def isCoercible(tp: Type, pt: Type): boolean =
- context0.reportGeneralErrors && // this condition prevents chains of views
+ tp.isError || pt.isError ||
+ context0.reportGeneralErrors && // this condition prevents chains of views
inferView(Position.NOPOS, tp, pt, false) != EmptyTree
}
@@ -373,7 +374,8 @@ import collection.mutable.HashMap;
return typed(atPos(tree.pos)(Block(List(tree), Literal(()))), mode, pt)
case _ =>
}
- if (context.reportGeneralErrors) { // (13); the condition prevents chains of views
+ if (context.reportGeneralErrors && !tree.tpe.isError && !pt.isError) {
+ // (13); the condition prevents chains of views
val coercion = inferView(tree.pos, tree.tpe, pt, true);
if (coercion != EmptyTree) {
if (settings.debug.value) log("inferred view from " + tree.tpe + " to " + pt + " = " + coercion + ":" + coercion.tpe);
@@ -711,7 +713,7 @@ import collection.mutable.HashMap;
}
def typedFunction(fun: Function, mode: int, pt: Type): Tree = {
- def decompose(tp: Type): Triple[Symbol, List[Type], Type] =
+ def decompose(pt: Type): Triple[Symbol, List[Type], Type] =
if (isFunctionType(pt)
||
pt.symbol == PartialFunctionClass &&
@@ -882,7 +884,8 @@ import collection.mutable.HashMap;
} else {
qual.tpe.member(name)
}
- if (sym == NoSymbol && qual.isTerm && (qual.symbol == null || qual.symbol.isValue) && !phase.erasedTypes) {
+ if (sym == NoSymbol && qual.isTerm && (qual.symbol == null || qual.symbol.isValue) &&
+ !phase.erasedTypes && !qual.tpe.widen.isError) {
val coercion = inferView(qual.pos, qual.tpe, name, true);
if (coercion != EmptyTree)
return typed(
@@ -890,7 +893,7 @@ import collection.mutable.HashMap;
}
if (sym.info == NoType) {
if (settings.debug.value) log("qual = " + qual + ":" + qual.tpe + "\nSymbol=" + qual.tpe.symbol + "\nsymbol-info = " + qual.tpe.symbol.info + "\nscope-id = " + qual.tpe.symbol.info.decls.hashCode() + "\nmembers = " + qual.tpe.members + "\nfound = " + sym);
- if (!qual.tpe.isError)
+ if (!qual.tpe.widen.isError)
error(tree.pos,
decode(name) + " is not a member of " + qual.tpe.widen +
(if (Position.line(tree.pos) > Position.line(qual.pos))
@@ -1295,9 +1298,9 @@ import collection.mutable.HashMap;
//System.out.println("typing " + tree);//DEBUG
}
val tree1 = if (tree.tpe != null) tree else typed1(tree, mode, pt);
- //System.out.println("typed " + tree1 + ":" + tree1.tpe);//DEBUG
+ //System.out.println("typed " + tree1 + ":" + tree1.tpe);//debug
val result = if (tree1.isEmpty) tree1 else adapt(tree1, mode, pt);
- //System.out.println("adpated " + tree1 + ":" + tree1.tpe + " to " + pt);//DEBUG
+ //System.out.println("adapted " + tree1 + ":" + tree1.tpe + " to " + pt);//debug
result
} catch {
case ex: TypeError =>
diff --git a/test-nsc/files/pos/code.scala b/test-nsc/files/pos/code.scala
new file mode 100755
index 0000000000..05c6e4a779
--- /dev/null
+++ b/test-nsc/files/pos/code.scala
@@ -0,0 +1,3 @@
+class Test {
+ val fun: reflect.TypedCode[int => int] = x => x + 1;
+}
diff --git a/test-nsc/files/run/bug457.scala b/test-nsc/files/run/bug457.scala
new file mode 100755
index 0000000000..5b1462f7e2
--- /dev/null
+++ b/test-nsc/files/run/bug457.scala
@@ -0,0 +1,36 @@
+object Foo {
+
+// def method= {
+// val x = "Hello, world";
+// val y = 100;
+
+// y match {
+// case _: Int
+// if (x match { case t => t.trim().length() == 0 }) =>
+// false;
+// // case _ => true;
+// }
+// }
+
+ def method2(): scala.Boolean = {
+ val x: java.lang.String = "Hello, world";
+ val y: scala.Int = 100;
+ {
+ var temp1: scala.Int = y;
+ var result: scala.Boolean = false;
+ if (
+ {
+ var result1: scala.Boolean = false;
+ if (y == 100)
+ result1
+ else
+ scala.MatchError.fail("crazybox.scala", 11)
+ } && (y == 90)
+ )
+ result
+ else
+ scala.MatchError.fail("crazybox.scala", 9);
+ }
+ }
+
+}