summaryrefslogtreecommitdiff
path: root/sources/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-06-09 18:45:48 +0000
committerMartin Odersky <odersky@gmail.com>2005-06-09 18:45:48 +0000
commit4ae459ef755dccc8230a884bf6f462c4dadc96b8 (patch)
tree3d27d19a37680d452c4b52b84e809174a86fba5f /sources/scala/tools/nsc/typechecker/Typers.scala
parentd7499538cc0da7beb331a4550b7a6e85cd132876 (diff)
downloadscala-4ae459ef755dccc8230a884bf6f462c4dadc96b8.tar.gz
scala-4ae459ef755dccc8230a884bf6f462c4dadc96b8.tar.bz2
scala-4ae459ef755dccc8230a884bf6f462c4dadc96b8.zip
Repository : /home/cvslamp/repositories/scala
Module : scala Working dir: ~/scala/ In directory .: Unknown META-INF Unknown Test.symbl Unknown VERSION-1.1.0-b1 Unknown collection Unknown expr.exe.stackdump Unknown importing Unknown iq.symbl Unknown java.io.Writer Unknown make Unknown rm Unknown scalac.symtab.Symbol Unknown testcast Unknown x Unknown xmake Unknown y Unknown z In directory bin: Unknown bin/dtd2scala.lnk Unknown bin/scala-debug.lnk Unknown bin/scala-info.lnk Unknown bin/scala.lnkMa Unknown bin/scalac-debug.lnk Unknown bin/scalac.lnk Unknown bin/scaladoc-debug.lnk Unknown bin/scaladoc.lnk Unknown bin/scalaint-debug.lnk Unknown bin/scalaint.lnk Unknown bin/scalap.lnk Unknown bin/scalarun-debug.lnk Unknown bin/scalarun.lnk Unknown bin/scalatest.lnk In directory config: In directory config/list: Modified config/list/nsc.lst In directory doc: Unknown doc/announcement.txt In directory doc/papers: Message: cvs update: cannot open directory /home/cvslamp/repositories/scala/scala/doc/papers: No such file or directory Message: cvs update: skipping directory doc/papers In directory doc/reference: Unknown doc/reference/R1.tex Unknown doc/reference/ScalaReference.tex.1 Unknown doc/reference/ScalaReference.tex.new Unknown doc/reference/ScalaVersion.tex Unknown doc/reference/lecture.tex Unknown doc/reference/math.sty Unknown doc/reference/modefs.sty Unknown doc/reference/prooftree.sty Unknown doc/reference/sbe-talk.tex Unknown doc/reference/scaladefs.sty Unknown doc/reference/scaladefs.tex Unknown doc/reference/scaladoc.sty Unknown doc/reference/tweaklist.sty Unknown doc/reference/vquote.sty Unknown doc/reference/x In directory doc/reports: Message: cvs update: cannot open directory /home/cvslamp/repositories/scala/scala/doc/reports: No such file or directory Message: cvs update: skipping directory doc/reports In directory doc/talks: Message: cvs update: cannot open directory /home/cvslamp/repositories/scala/scala/doc/talks: No such file or directory Message: cvs update: skipping directory doc/talks In directory sources: Unknown sources/new Unknown sources/scala.zip Unknown sources/scalac.own Unknown sources/ziDeLBjS In directory sources/examples: Unknown sources/examples/BibTree.scala Unknown sources/examples/BibTree1.scala Unknown sources/examples/BinTree.scala Unknown sources/examples/concurrent Unknown sources/examples/epl Unknown sources/examples/epl.zip Unknown sources/examples/examples Unknown sources/examples/fs Unknown sources/examples/graphs.scala Unknown sources/examples/implicit Unknown sources/examples/interpreters.scala Unknown sources/examples/parsers2a.scala Unknown sources/examples/parsers3.scala Unknown sources/examples/pubsub.scala Unknown sources/examples/pubsub.scala.notyet Unknown sources/examples/pubsub1.scala Unknown sources/examples/shapes.scala Unknown sources/examples/stacks.scala Unknown sources/examples/teletrans.scala Unknown sources/examples/teletrans1.scala Unknown sources/examples/xpath.scala Unknown sources/examples/xpath1.scala In directory sources/examples/expressions: Unknown sources/examples/expressions/abstract-data-1.scala Unknown sources/examples/expressions/abstract-data-2.scala Unknown sources/examples/expressions/abstract-data-mixin-1.scala Unknown sources/examples/expressions/abstract-data-mixin-bad.scala Unknown sources/examples/expressions/abstract-data-mixin-neg.scala Unknown sources/examples/expressions/abstract-data-mixin.scala Unknown sources/examples/expressions/abstract-data.scala Unknown sources/examples/expressions/abstract-operation-1.scala Unknown sources/examples/expressions/abstract-operation-2.scala Unknown sources/examples/expressions/abstract-operation-mixin.scala Unknown sources/examples/expressions/abstract-operation.scala Unknown sources/examples/expressions/expressions-constr-abstypes.scala Unknown sources/examples/expressions/expressions-oo.scala Unknown sources/examples/expressions/expressions-visitors.scala Unknown sources/examples/expressions/expressions-visitos.scala Unknown sources/examples/expressions/generic-data.scala Unknown sources/examples/expressions/generic-operation-factory.scala Unknown sources/examples/expressions/generic-operation-simple.scala Unknown sources/examples/expressions/generic-operation.scala Unknown sources/examples/expressions/scala Unknown sources/examples/expressions/test Unknown sources/examples/expressions/x In directory sources/scala: Unknown sources/scala/$colon$colon.scala.disabled Unknown sources/scala/.latest-compiler Unknown sources/scala/Array.java.notyet Unknown sources/scala/ArrayIterator.java.notyet Modified sources/scala/CaseClass.scala Modified sources/scala/List.scala Unknown sources/scala/NoValue Unknown sources/scala/ScalaObject.scala Unknown sources/scala/bootclasses Unknown sources/scala/cls Unknown sources/scala/new Unknown sources/scala/newclasses Unknown sources/scala/nsc-build Unknown sources/scala/nsc-build.bat Unknown sources/scala/nscnew Unknown sources/scala/nscnew.bat Unknown sources/scala/nx Unknown sources/scala/old Unknown sources/scala/ox Unknown sources/scala/predef Unknown sources/scala/scala.Ordered![a!])scala.Ordered![scala.List![a!]] Unknown sources/scala/test.scala Unknown sources/scala/x In directory sources/scala/runtime: Unknown sources/scala/runtime/CaseOps.scala In directory sources/scala/tools: Unknown sources/scala/tools/nsc.zip Unknown sources/scala/tools/nsc1 Unknown sources/scala/tools/nscnew In directory sources/scala/tools/nsc: Modified sources/scala/tools/nsc/Global.scala Modified sources/scala/tools/nsc/Phase.scala Added sources/scala/tools/nsc/SubComponent.scala Unknown sources/scala/tools/nsc/typechecker.new In directory sources/scala/tools/nsc/ast: Modified sources/scala/tools/nsc/ast/TreeGen.scala Modified sources/scala/tools/nsc/ast/Trees.scala In directory sources/scala/tools/nsc/ast/parser: Modified sources/scala/tools/nsc/ast/parser/Parsers.scala Modified sources/scala/tools/nsc/ast/parser/Scanners.scala Added sources/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala Modified sources/scala/tools/nsc/ast/parser/Tokens.scala Modified sources/scala/tools/nsc/ast/parser/TreeBuilder.scala In directory sources/scala/tools/nsc/matching: Modified sources/scala/tools/nsc/matching/PatternUtil.scala In directory sources/scala/tools/nsc/symtab: Modified sources/scala/tools/nsc/symtab/Definitions.scala Modified sources/scala/tools/nsc/symtab/Flags.scala Modified sources/scala/tools/nsc/symtab/Names.scala Modified sources/scala/tools/nsc/symtab/Scopes.scala Modified sources/scala/tools/nsc/symtab/StdNames.scala Modified sources/scala/tools/nsc/symtab/SymbolTable.scala Modified sources/scala/tools/nsc/symtab/Symbols.scala Modified sources/scala/tools/nsc/symtab/Types.scala In directory sources/scala/tools/nsc/symtab/classfile: Modified sources/scala/tools/nsc/symtab/classfile/ClassfileConstants.scala Modified sources/scala/tools/nsc/symtab/classfile/PickleFormat.scala Modified sources/scala/tools/nsc/symtab/classfile/Pickler.scala In directory sources/scala/tools/nsc/transform: Modified sources/scala/tools/nsc/transform/SampleTransform.scala Modified sources/scala/tools/nsc/transform/Transform.scala Removed sources/scala/tools/nsc/transform/TypesAsValues.scala In directory sources/scala/tools/nsc/typechecker: Modified sources/scala/tools/nsc/typechecker/Analyzer.scala Modified sources/scala/tools/nsc/typechecker/Contexts.scala Modified sources/scala/tools/nsc/typechecker/Infer.scala Modified sources/scala/tools/nsc/typechecker/Namers.scala Added sources/scala/tools/nsc/typechecker/RefChecks.scala Modified sources/scala/tools/nsc/typechecker/TreeCheckers.scala Modified sources/scala/tools/nsc/typechecker/Typers.scala In directory sources/scala/xml: In directory sources/scala/xml/parsing: Modified sources/scala/xml/parsing/MarkupHandler.scala Modified sources/scala/xml/parsing/MarkupParser.scala In directory sources/scalac: In directory sources/scalac/symtab: In directory sources/scalac/symtab/classfile: Unknown sources/scalac/symtab/classfile/PackageParser.java.1 In directory test: Unknown test/absobs.scala Unknown test/attr.scala Unknown test/bug363.scala Unknown test/mixin.scala Unknown test/nsc Unknown test/nsc.scala Unknown test/nsc1.scala Unknown test/nsc2.scala Unknown test/sabin.scala Unknown test/sabin2.scala Unknown test/selftypes.scala Unknown test/single.scala Unknown test/testmatch.scala In directory test/files: Unknown test/files/bug320.scala In directory test/files/neg: Unknown test/files/neg/bug356.check Unknown test/files/neg/bug356.scala Unknown test/files/neg/bug363.check Unknown test/files/neg/bug363.scala Unknown test/files/neg/bug369.check Unknown test/files/neg/bug369.scala Unknown test/files/neg/bug370.check Unknown test/files/neg/bug370.scala Unknown test/files/neg/bug373.check Unknown test/files/neg/bug373.scala Unknown test/files/neg/bug375.check Unknown test/files/neg/bug375.scala Unknown test/files/neg/escapes.scala Unknown test/files/neg/test In directory test/files/pos: Unknown test/files/pos/A.symbl Unknown test/files/pos/B.symbl Unknown test/files/pos/C.symbl Unknown test/files/pos/D.symbl Unknown test/files/pos/O.symbl Unknown test/files/pos/S.symbl Unknown test/files/pos/T.symbl Unknown test/files/pos/arrays2.symbl Unknown test/files/pos/bug348plus.scala Unknown test/files/pos/lists.symbl Unknown test/files/pos/main.symbl Unknown test/files/pos/test.symbl In directory test/new: Message: cvs update: cannot open directory /home/cvslamp/repositories/scala/scala/test/new: No such file or directory Message: cvs update: skipping directory test/new In directory test/pos: Unknown test/pos/valparams.scala Unknown test/pos/vincent.scala In directory website: Message: cvs update: cannot open directory /home/cvslamp/repositories/scala/scala/website: No such file or directory Message: cvs update: skipping directory website --------------------- End --------------------- -- last cmd: cvs -f update -d -P --
Diffstat (limited to 'sources/scala/tools/nsc/typechecker/Typers.scala')
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala113
1 files changed, 89 insertions, 24 deletions
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
index 075eeb7e60..027956badc 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -198,9 +198,9 @@ abstract class Typers: Analyzer {
else if ((mode & (EXPRmode | QUALmode)) == EXPRmode && !sym.isValue) // (2)
errorTree(tree, sym.toString() + " is not a value");
else if (sym.isStable && pre.isStable && tree.tpe.symbol != ByNameParamClass &&
- (pt.isStable || (mode & QUALmode) != 0 || sym.isModule)) // (3)
+ (pt.isStable || (mode & QUALmode) != 0 && !sym.isConstant || sym.isModule)) { // (3)
tree.setType(singleType(pre, sym))
- else tree
+ } else tree
}
/** Perform the following adaptations of expression, pattern or type `tree' wrt to
@@ -234,7 +234,7 @@ abstract class Typers: Analyzer {
*/
// def adapt(tree: Tree, mode: int, pt: Type): Tree = {
private def adapt(tree: Tree, mode: int, pt: Type): Tree = tree.tpe match {
- case ct @ ConstantType(base, value) if ((mode & TYPEmode) == 0 && (ct <:< pt)) => // (0)
+ case ct @ ConstantType(value) if ((mode & TYPEmode) == 0 && (ct <:< pt)) => // (0)
copy.Literal(tree, value)
case OverloadedType(pre, alts) if ((mode & FUNmode) == 0) => // (1)
inferExprAlternative(tree, pt);
@@ -447,8 +447,7 @@ abstract class Typers: Analyzer {
val getter = sym.owner.info.decls.lookup(name).suchThat(.hasFlag(ACCESSOR));
val result = atPos(vdef.pos)(
DefDef(getter, vparamss =>
- if ((mods & DEFERRED) != 0) EmptyTree
- else stabilize(gen.mkRef(sym), sym.owner.thisType, EXPRmode, sym.tpe)));
+ if ((mods & DEFERRED) != 0) EmptyTree else typed(gen.mkRef(sym), EXPRmode, sym.tpe)));
checkNoEscaping.privates(result.symbol, result.tpt);
result
}
@@ -570,30 +569,94 @@ abstract class Typers: Analyzer {
copy.CaseDef(cdef, pat1, guard1, body1) setType body1.tpe
}
- def typedFunction(fun: Function, mode: int, pt: Type): Function = {
+ /* Transform a function node (x_1,...,x_n) => body of type FunctionN[T_1, .., T_N, R] to
+ *
+ * class $anon() extends Object() with FunctionN[T_1, .., T_N, R] with ScalaObject {
+ * def apply(x_1: T_1, ..., x_N: T_n): R = body
+ * }
+ * new $anon()
+ *
+ * transform a function node (x => body) of type PartialFunction[T, R] where
+ * body = x match { case P_i if G_i => E_i }_i=1..n
+ * to:
+ *
+ * class $anon() extends Object() with PartialFunction[T, R] with ScalaObject {
+ * def apply(x: T): R = body;
+ * def isDefinedAt(x: T): boolean = x match {
+ * case P_1 if G_1 => true
+ * ...
+ * case P_n if G_n => true
+ * case _ => false
+ * }
+ * }
+ * new $anon()
+ *
+ * However, if one of the patterns P_i if G_i is a default pattern, generate instead
+ *
+ * def isDefinedAt(x: T): boolean = true
+ */
+ def typedFunction(fun: Function, mode: int, pt: Type): Tree = {
val Triple(clazz, argpts, respt) =
- if (isFunctionType(pt)
- ||
+ if (isFunctionType(pt)
+ ||
pt.symbol == PartialFunctionClass &&
fun.vparams.length == 1 && fun.body.isInstanceOf[Match])
Triple(pt.symbol, pt.typeArgs.init, pt.typeArgs.last)
else
Triple(FunctionClass(fun.vparams.length), fun.vparams map (x => NoType), WildcardType);
val vparamSyms = List.map2(fun.vparams, argpts) { (vparam, argpt) =>
- vparam match {
- case ValDef(_, _, tpt, _) =>
- if (tpt.isEmpty)
- tpt.tpe =
- if (argpt == NoType) { error(vparam.pos, "missing parameter type"); ErrorType }
- else argpt
- }
+ if (vparam.tpt.isEmpty)
+ vparam.tpt.tpe =
+ if (argpt == NoType) { error(vparam.pos, "missing parameter type"); ErrorType }
+ else argpt;
namer.enterSym(vparam);
vparam.symbol
}
- val vparams1 = List.mapConserve(fun.vparams)(typedValDef);
- val body1 = typed(fun.body, respt);
- copy.Function(fun, vparams1, body1)
- setType typeRef(clazz.tpe.prefix, clazz, (vparamSyms map (.tpe)) ::: List(body1.tpe))
+ val vparams = List.mapConserve(fun.vparams)(typedValDef);
+ val body = typed(fun.body, respt);
+ val formals = vparamSyms map (.tpe);
+ val funtpe = typeRef(clazz.tpe.prefix, clazz, formals ::: List(body.tpe));
+ val anonClass = context.owner.newAnonymousFunctionClass(fun.pos) setFlag (FINAL | SYNTHETIC);
+ anonClass setInfo ClassInfoType(
+ List(ObjectClass.tpe, funtpe, ScalaObjectClass.tpe), new Scope(), anonClass);
+ val applyMethod = anonClass.newMethod(fun.pos, nme.apply)
+ setFlag FINAL setInfo MethodType(formals, body.tpe);
+ anonClass.info.decls enter applyMethod;
+ for (val vparam <- vparamSyms) vparam.owner = applyMethod;
+ var members = List(
+ DefDef(FINAL, nme.apply, List(), List(vparams), TypeTree(body.tpe), body)
+ setSymbol applyMethod);
+ if (pt.symbol == PartialFunctionClass) {
+ val isDefinedAtMethod = anonClass.newMethod(fun.pos, nme.isDefinedAt)
+ setFlag FINAL setInfo MethodType(formals, BooleanClass.tpe);
+ anonClass.info.decls enter isDefinedAtMethod;
+ def idbody(idparam: Symbol) = body match {
+ case Match(_, cases) =>
+ val substParam = new TreeSymSubstituter(List(vparams.head.symbol), List(idparam));
+ def transformCase(cdef: CaseDef): CaseDef =
+ CaseDef(substParam(cdef.pat.duplicate),
+ substParam(cdef.guard.duplicate),
+ Literal(true));
+ def isDefaultCase(cdef: CaseDef) = cdef match {
+ case CaseDef(Ident(nme.WILDCARD), EmptyTree, _) => true
+ case CaseDef(Bind(_, Ident(nme.WILDCARD)), EmptyTree, _) => true
+ case _ => false
+ }
+ if (cases exists isDefaultCase) Literal(true)
+ else Match(
+ Ident(idparam),
+ (cases map transformCase) :::
+ List(CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(false))))
+ }
+ members = DefDef(isDefinedAtMethod, vparamss => idbody(vparamss.head.head)) :: members;
+ }
+ typed(
+ atPos(fun.pos)(
+ Block(
+ List(ClassDef(anonClass, List(List()), List(List()), members)),
+ Typed(
+ New(TypeTree(anonClass.tpe), List(List())),
+ TypeTree(funtpe)))))
}
def typedRefinement(stats: List[Tree]): List[Tree] = {
@@ -916,8 +979,7 @@ abstract class Typers: Analyzer {
copy.Bind(tree, name, body1) setSymbol vble setType pt
case fun @ Function(_, _) =>
- newTyper(context.makeNewScope(tree, context.owner))
- .typedFunction(fun, mode, pt)
+ newTyper(context.makeNewScope(tree, context.owner)).typedFunction(fun, mode, pt)
case Assign(lhs, rhs) =>
def isGetter(sym: Symbol) = sym.info match {
@@ -1074,9 +1136,9 @@ abstract class Typers: Analyzer {
else
typedIdent(name);
+ // todo: try with case Literal(Constant(()))
case Literal(value) =>
- tree setType
- (if (value == ()) UnitClass.tpe else ConstantType(constfold.literalType(value), value))
+ tree setType (if (value.tag == UnitTag) UnitClass.tpe else ConstantType(value))
case SingletonTypeTree(ref) =>
val ref1 = checkStable(typed(ref, EXPRmode | QUALmode, AnyRefClass.tpe));
@@ -1119,7 +1181,10 @@ abstract class Typers: Analyzer {
//System.out.println("typing " + tree);//debug
}
val tree1 = if (tree.tpe != null) tree else typed1(tree, mode, pt);
- if (tree1.isEmpty) tree1 else adapt(tree1, mode, pt)
+ //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
+ result
} catch {
case ex: TypeError =>
reportTypeError(tree.pos, ex);