summaryrefslogtreecommitdiff
path: root/sources/scalac
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-07-16 10:49:15 +0000
committerMartin Odersky <odersky@gmail.com>2003-07-16 10:49:15 +0000
commit0a0595a1c73b956f8582879d518c75970b910c23 (patch)
tree5bffa1f28df8a5cb2b7451c18fc3a9acf85c3722 /sources/scalac
parent9aaa79cdba130a6e22e9b761d5a1f78720a2a180 (diff)
downloadscala-0a0595a1c73b956f8582879d518c75970b910c23.tar.gz
scala-0a0595a1c73b956f8582879d518c75970b910c23.tar.bz2
scala-0a0595a1c73b956f8582879d518c75970b910c23.zip
*** empty log message ***
Diffstat (limited to 'sources/scalac')
-rw-r--r--sources/scalac/ast/TreeInfo.java4
-rw-r--r--sources/scalac/ast/parser/Parser.java119
-rw-r--r--sources/scalac/ast/parser/Scanner.java3
-rw-r--r--sources/scalac/symtab/SourceCompleter.java2
-rw-r--r--sources/scalac/symtab/Symbol.java17
-rw-r--r--sources/scalac/typechecker/Analyzer.java42
-rw-r--r--sources/scalac/typechecker/DeSugarize.java16
-rw-r--r--sources/scalac/typechecker/RefCheck.java7
8 files changed, 121 insertions, 89 deletions
diff --git a/sources/scalac/ast/TreeInfo.java b/sources/scalac/ast/TreeInfo.java
index f79a5765a5..9721afb447 100644
--- a/sources/scalac/ast/TreeInfo.java
+++ b/sources/scalac/ast/TreeInfo.java
@@ -112,10 +112,8 @@ public class TreeInfo {
public static boolean isPureConstr(Tree tree) {
switch (tree) {
case Ident(_):
+ case Select(_, _):
return tree.symbol() != null && tree.symbol().isPrimaryConstructor();
- case Select(Tree qual, _):
- return isPureExpr(qual) &&
- tree.symbol() != null && tree.symbol().isPrimaryConstructor();
case TypeApply(Tree constr, _):
return isPureConstr(constr);
case Apply(Tree fn, Tree[] args):
diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java
index 6c5356ebbb..b5aa598f23 100644
--- a/sources/scalac/ast/parser/Parser.java
+++ b/sources/scalac/ast/parser/Parser.java
@@ -369,10 +369,6 @@ public class Parser implements Tokens {
*/
Tree convertToConstr(Tree t) {
switch (t) {
- case Apply(Tree fn, Tree[] args):
- return make.Apply(t.pos, convertToConstr(fn), args);
- case TypeApply(Tree fn, Tree[] args):
- return make.TypeApply(t.pos, convertToConstr(fn), args);
case Ident(Name name):
return make.Ident(t.pos, name.toConstrName());
case Select(Tree qual, Name name):
@@ -382,6 +378,27 @@ public class Parser implements Tokens {
}
}
+ /** Convert this(...) application to constructor invocation
+ */
+ Tree convertToSelfConstr(Tree t, Name constrname) {
+ switch (t) {
+ case Block(Tree[] stats):
+ if (stats.length > 0) {
+ stats[stats.length - 1] = convertToSelfConstr(
+ stats[stats.length - 1], constrname);
+ return t;
+ }
+ break;
+ case Apply(Tree fn, Tree[] args):
+ switch (fn) {
+ case This(Tree.Empty):
+ return make.Apply(
+ t.pos, make.Ident(t.pos, constrname), args);
+ }
+ }
+ return syntaxError(t.pos, "class constructor expected", false);
+ }
+
/** Complete unapplied constructor with `()' arguments
*/
Tree applyConstr(Tree t) {
@@ -994,31 +1011,6 @@ public class Parser implements Tokens {
return res;
}
- /** ConstrExpr ::= Constr
- * | `{' {BlockStat `;'} Constr `}'
- */
- Tree constrExpr() {
- if (s.token == LBRACE) {
- int pos = s.skipToken();
- Tree res = block(pos);
- switch (res) {
- case Block(Tree[] stats):
- if (stats.length > 0)
- stats[stats.length - 1] = applyConstr(
- convertToConstr(stats[stats.length - 1]));
- else
- syntaxError(res.pos, "class constructor expected", false);
- break;
- default:
- res = applyConstr(convertToConstr(res));
- }
- accept(RBRACE);
- return res;
- } else {
- return constr();
- }
- }
-
/** Block ::= BlockStatSeq
*/
Tree block(int pos) {
@@ -1177,7 +1169,7 @@ public class Parser implements Tokens {
make.Sequence(s.pos, Tree.EMPTY_ARRAY)}));
}
}
- while ((s.token == IDENTIFIER)&&( s.name != BAR )) {
+ while ((s.token == IDENTIFIER) && (s.name != BAR)) {
top = reduceStack(
false, base, top, s.name.precedence(), s.name.isLeftAssoc());
push(top, s.pos, s.name);
@@ -1341,6 +1333,13 @@ public class Parser implements Tokens {
return (ValDef[][])ts.toArray(new ValDef[ts.size()][]);
}
+ /** ParamClauseOpt ::= [ParamClause]
+ */
+ ValDef[][] paramClauseOpt() {
+ return (s.token == LPAREN) ? new ValDef[][]{paramClause()}
+ : Tree.ValDef_EMPTY_ARRAY_ARRAY;
+ }
+
/** ParamClause ::= `(' [Param {`,' Param}] `)'
*/
ValDef[] paramClause() {
@@ -1535,7 +1534,6 @@ public class Parser implements Tokens {
/** Def ::= val PatDef {`,' PatDef}
* | var VarDef {`,' VarDef}
* | def FunDef {`,' FunDef}
- * | constr ConstrDef {`,' ConstrDef}
* | type TypeDef {`,' TypeDef}
* | ClsDef
* Dcl ::= val ValDcl {`,' ValDcl}
@@ -1565,12 +1563,6 @@ public class Parser implements Tokens {
ts.append(funDefOrDcl(mods));
} while (s.token == COMMA);
return ts.toArray();
- case CONSTR:
- do {
- s.nextToken();
- ts.append(constrDefOrDcl(mods));
- } while (s.token == COMMA);
- return ts.toArray();
case TYPE:
do {
s.nextToken();
@@ -1678,23 +1670,25 @@ public class Parser implements Tokens {
tparams, vparams, restype, Tree.Empty);
}
- /* ConstrDef ::= Id [FunTypeParamClause] [ParamClause] [`:' Type] `=' ConstrExpr
+ /* ConstrDef ::= [ParamClause] `=' ConstrExpr
+ * ConstrExpr ::= this `(' [Exprs] `)'
+ * | `{' { BlockStat `;' } ConstrExpr `}'
*/
- Tree constrDefOrDcl(int mods) {
+ Tree constrDef(int mods, Name clazzname, TypeDef[] tparams) {
+ Name constrname = clazzname.toConstrName();
int pos = s.pos;
- Name name = ident().toConstrName();
- TypeDef[] tparams = typeParamClauseOpt(false);
- ValDef[][] vparams = new ValDef[][]{paramClause()};
- Tree restype = typedOpt();
- if (s.token == EQUALS || restype == Tree.Empty) {
- accept(EQUALS);
- return make.DefDef(
- pos, mods | Modifiers.FINAL, name,
- tparams, vparams, restype, constrExpr());
- } else
- return make.DefDef(
- pos, mods | Modifiers.FINAL | Modifiers.DEFERRED, name,
- tparams, vparams, restype, Tree.Empty);
+ ValDef[][] vparams = paramClauseOpt();
+ accept(EQUALS);
+ Tree restype = make.Ident(pos, clazzname.toTypeName());
+ if (tparams.length != 0) {
+ Tree[] targs = new Tree[tparams.length];
+ for (int i = 0; i < tparams.length; i++)
+ targs[i] = make.Ident(pos, ((TypeDef) tparams[i]).name);
+ restype = make.AppliedType(pos, restype, targs);
+ }
+ return make.DefDef(
+ pos, mods | Modifiers.FINAL, constrname,
+ tparams, vparams, restype, convertToSelfConstr(expr(), constrname));
}
/** TypeDef ::= Id `=' Type
@@ -1718,16 +1712,23 @@ public class Parser implements Tokens {
}
}
- /** ClassDef ::= Id [TypeParamClause] [ParamClause] [`:' SimpleType] ClassTemplate
+ /** ClassDef ::= Id [TypeParamClause] [ParamClause] [`:' SimpleType]
+ * ClassTemplate { [`;'] constr ConstrDef }
*/
- Tree classDef(int mods) {
+ Tree[] classDef(int mods) {
int pos = s.pos;
- Name name = ident();
+ Name clazzname = ident().toTypeName();
TypeDef[] tparams = typeParamClauseOpt(true);
- ValDef[][] params = (s.token == LPAREN) ? new ValDef[][]{paramClause()}
- : Tree.ValDef_EMPTY_ARRAY_ARRAY;
- return make.ClassDef(pos, mods, name.toTypeName(), tparams, params,
- simpleTypedOpt(), classTemplate());
+ ValDef[][] params = paramClauseOpt();
+ TreeList result = new TreeList();
+ result.append(
+ make.ClassDef(pos, mods, clazzname, tparams, params,
+ simpleTypedOpt(), classTemplate()));
+ while (s.token == CONSTR) {
+ s.nextToken();
+ result.append(constrDef(mods, clazzname, tparams));
+ }
+ return result.toArray();
}
/** ObjectDef ::= Id [`:' SimpleType] ClassTemplate
diff --git a/sources/scalac/ast/parser/Scanner.java b/sources/scalac/ast/parser/Scanner.java
index da022bd953..bc153c869f 100644
--- a/sources/scalac/ast/parser/Scanner.java
+++ b/sources/scalac/ast/parser/Scanner.java
@@ -114,6 +114,7 @@ public class Scanner extends TokenData {
int prevpos = pos;
fetchToken();
switch (token) {
+ case CONSTR:
case ELSE: case EXTENDS: case WITH:
case YIELD: case CATCH: case FINALLY:
case COMMA: case SEMI: case DOT:
@@ -152,7 +153,7 @@ public class Scanner extends TokenData {
} else if (token == SEMI) {
prev.copyFrom(this);
fetchToken();
- if (token != ELSE) {
+ if (token != ELSE || token == CONSTR) {
next.copyFrom(this);
this.copyFrom(prev);
}
diff --git a/sources/scalac/symtab/SourceCompleter.java b/sources/scalac/symtab/SourceCompleter.java
index 9475e79ffe..1fe722abac 100644
--- a/sources/scalac/symtab/SourceCompleter.java
+++ b/sources/scalac/symtab/SourceCompleter.java
@@ -33,7 +33,7 @@ public class SourceCompleter extends Type.LazyType {
*/
public void complete(Symbol c) {
if (completed) {
- c.setInfo(Type.ErrorType);
+ c.setInfo(Type.NoType);
} else if (filename != null) {
try {
String fname = filename;
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index a67669075a..f6466931d7 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -187,8 +187,7 @@ public abstract class Symbol implements Modifiers, Kinds {
public final boolean isStable() {
return kind == VAL &&
((flags & STABLE) != 0 ||
- (flags & MUTABLE) == 0 && type().isObjectType()) &&
- !owner.isPrimaryConstructor();
+ (flags & MUTABLE) == 0 && type().isObjectType());
}
/** Does this symbol denote a variable? */
@@ -560,13 +559,13 @@ public abstract class Symbol implements Modifiers, Kinds {
info.complete(this);
flags = flags & ~LOCKED;
if (info instanceof SourceCompleter && (flags & SNDTIME) == 0) {
- flags |= SNDTIME;
- Type tp = info();
- flags &= ~SNDTIME;
- } else {
- assert !(rawInfoAt(id) instanceof Type.LazyType) : this;
- flags |= INITIALIZED;
- }
+ flags |= SNDTIME;
+ Type tp = info();
+ flags &= ~SNDTIME;
+ } else {
+ assert !(rawInfoAt(id) instanceof Type.LazyType) : this;
+ flags |= INITIALIZED;
+ }
//System.out.println("done: " + this.name);//DEBUG
}
return rawInfoAt(id);
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index fb903640aa..5ddd9b9d5a 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -11,9 +11,7 @@
// todo: use SELECTOR flag to avoid access methods for privates
// todo: use mangled name or drop.
// todo: emit warnings for unchecked.
-// todo: qualified super.
-// todo: pattern definitions with 0 or 1 bound variable.
-// todo: phase sync
+// todo: synchronize on module instantiation.
package scalac.typechecker;
@@ -417,6 +415,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
error(pos, "cyclic aliasing or subtyping involving " + sym);
} else if (sym.kind == ALIAS || sym.kind == TYPE) {
sym.flags |= LOCKED;
+ //System.out.println("checking " + sym);//DEBUG
checkNonCyclic(
pos, pre.memberInfo(sym).subst(sym.typeParams(), args));
if (sym.kind == TYPE)
@@ -444,7 +443,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
try {
return checkNoEscapeMap.apply(tp);
} catch (Type.Error ex) {
- if (infer.isFullyDefined(pt)) return pt;
+ if ((mode & EXPRmode) != 0 && infer.isFullyDefined(pt)) return pt;
error(pos, ex.msg + " as part of " + tp.unalias());
return Type.ErrorType;
}
@@ -612,14 +611,17 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
Symbol constr = tree.symbol().constructor();
Type constrtype = constr.type().instanceType();
constrtype = constrtype.cloneType(constr, sym);
+ /* todo: remove
switch (tree) {
case ClassDef(_, _, _, ValDef[][] vparams, _, _):
if (vparams.length == 0) {
constrtype = removeMethod(constrtype);
}
}
+ */
sym.setInfo(constrtype);
}
+ /* todo: remove
private Type removeMethod(Type tp) {
switch (tp) {
case MethodType(_, Type restp):
@@ -630,6 +632,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
return tp;
}
}
+ */
}
/** A lazy type for self types
@@ -707,9 +710,12 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
enterSym(tree, clazz.constructor());
if ((mods & CASE) != 0) {
+ /* todo: remove
if (vparams.length == 0) {
error(tree.pos, "case class needs () parameter section");
- } else if ((mods & ABSTRACTCLASS) == 0) {
+ }
+ else */
+ if ((mods & ABSTRACTCLASS) == 0) {
// enter case constructor method.
enterInScope(
new TermSymbol(
@@ -964,8 +970,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if (tpe != Tree.Empty) {
((DefDef) tree).tpe = tpe = transform(tpe, TYPEmode);
} else {
- int rhsmode = name.isConstrName() ? CONSTRmode : EXPRmode;
- ((DefDef) tree).rhs = rhs = transform(rhs, rhsmode);
+ ((DefDef) tree).rhs = rhs = transform(rhs, EXPRmode);
((DefDef) tree).tpe = tpe = gen.mkType(tree.pos, rhs.type);
}
Type restype = checkNoEscape(tpe.pos, tpe.type);
@@ -1002,7 +1007,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
tp.lookup(selectors[i]) == Symbol.NONE &&
tp.lookup(selectors[i].toTypeName()) == Symbol.NONE &&
tp.lookup(selectors[i].toConstrName()) == Symbol.NONE)
- error(tree.pos, selectors[i] + " is not a member of " + expr);
+ error(tree.pos, NameTransformer.decode(selectors[i]) + " is not a member of " + expr);
}
break;
@@ -1317,6 +1322,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
checkAccessible(tree.pos, sym, qual);
}
symtype = pre.memberType(sym);
+ if (symtype == Type.NoType)
+ return error(tree.pos, "not found: " + decode(name));
if ((pt != null && pt.isStable() || (mode & QUALmode) != 0) && sym.isStable()) {
//System.out.println("making single " + sym + ":" + symtype);//DEBUG
symtype = Type.singleType(pre, sym);
@@ -1346,6 +1353,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
if (!TreeInfo.isSelf(qual, context.enclClass.owner))
sym.flags |= SELECTOR;
Type symtype = qual.type.memberType(sym);
+ if (symtype == Type.NoType)
+ return error(tree.pos, "not found: " + decode(name));
//System.out.println(sym.name + ":" + symtype);//DEBUG
if (uninst.length != 0) {
switch (symtype) {
@@ -1370,7 +1379,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
* results.
*/
Tree transformVisitor(Tree tree, Type pattpe, Type pt) {
- //System.out.println("trans visitor with " + pt);//DEBUG
+ //System.out.println("trans visitor with " + pattpe + "," + pt);//DEBUG
switch (tree) {
case Visitor(Tree.CaseDef[] cases):
Tree.CaseDef[] cases1 = cases;
@@ -1569,6 +1578,13 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
return transformArgs(pos, meth, tparams2, restp, argMode, args, pt);
+ case Type.ErrorType:
+ for (int i = 0; i < args.length; i++) {
+ args[i] = transform(args[i], argMode, Type.ErrorType);
+ argtypes[i] = args[i].type;
+ }
+ return argtypes;
+
default:
for (int i = 0; i < args.length; i++) {
args[i] = transform(args[i], argMode, Type.AnyType);
@@ -1590,6 +1606,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
this.pt = pt;
Tree tree1 = adapt(transform(tree), mode, pt);
+ assert tree.type != Type.AnyType : tree;//debug
+
//new TextTreePrinter().print(tree1).print(": " + tree1.type).println().end();//DEBUG
this.mode = savedMode;
@@ -1670,6 +1688,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
Tree.ValDef[][] vparams1 = transform(vparams);
Tree tpe1 = transform(tpe);
Tree.Template templ1 = transformTemplate(templ, sym);
+ checkNoEscape(tree.pos, sym.info());
popContext();
return copy.ClassDef(tree, sym, tparams1, vparams1, tpe1, templ1)
.setType(definitions.UNIT_TYPE);
@@ -1683,7 +1702,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
Tree rhs1 = rhs;
if (rhs != Tree.Empty) {
pushContext(tree, sym, context.scope);
- rhs1 = transform(rhs, EXPRmode, tpe.type);
+ if ((sym.flags & CASEACCESSOR) != 0)
+ rhs1.type = rhs1.symbol().type();
+ else
+ rhs1 = transform(rhs, EXPRmode, tpe.type);
popContext();
}
sym.flags |= LOCKED;
diff --git a/sources/scalac/typechecker/DeSugarize.java b/sources/scalac/typechecker/DeSugarize.java
index 58b40ec390..defc49f470 100644
--- a/sources/scalac/typechecker/DeSugarize.java
+++ b/sources/scalac/typechecker/DeSugarize.java
@@ -96,6 +96,10 @@ public class DeSugarize implements Kinds, Modifiers {
for (int i = 0; i < args.length; i++)
getVariables(args[i], vars);
break;
+ case Sequence(Tree[] elems):
+ for (int i = 0; i < elems.length; i++)
+ getVariables(elems[i], vars);
+ break;
default:
throw new ApplicationError ("illegal pattern", tree);
}
@@ -474,11 +478,13 @@ public class DeSugarize implements Kinds, Modifiers {
if (vars.length == 0) {
// e.match (case p => ())
+ print(pat, "patdef", match);
return new Tree[]{match};
} else if (vars.length == 1) {
// val x_1 = e.match (case p => x_1)
- return new Tree[]{
- make.ValDef(pos, mods, vars[0], Tree.Empty, match)};
+ Tree valdef = make.ValDef(pos, mods, vars[0], Tree.Empty, match);
+ print(pat, "patdef", valdef);
+ return new Tree[]{valdef};
} else {
// t$
Name var = getvar();
@@ -493,7 +499,7 @@ public class DeSugarize implements Kinds, Modifiers {
pos, mods, vars[i], Tree.Empty,
make.Select(pos, make.Ident(pos, var), tupleSelectorName(i + 1)));
}
- print(pat, " -> ", new Block(res));//debug
+ print(pat, "patdef", new Block(res));//debug
return res;
}
default:
@@ -684,12 +690,12 @@ public class DeSugarize implements Kinds, Modifiers {
/** Build value element definition name for case parameter.
*/
void addCaseElement(TreeList ts, ValDef vparam) {
- vparam.symbol().initialize();
+ //vparam.symbol().initialize();
ts.append(
make.ValDef(
vparam.pos, CASEACCESSOR, vparam.name, vparam.tpe,
make.Ident(vparam.pos, vparam.name)
- .setSymbol(vparam.symbol()).setType(vparam.symbol().type())));
+ .setSymbol(vparam.symbol())));
}
/** add case constructor, value defintiions and access functions.
diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java
index 79a3e1a015..8c8f899abd 100644
--- a/sources/scalac/typechecker/RefCheck.java
+++ b/sources/scalac/typechecker/RefCheck.java
@@ -27,7 +27,7 @@ import Tree.*;
*
* It preforms the following transformations.
*
- * - Local modules are replaces by variables and classes
+ * - Local modules are replaced by variables and classes
* - toString, equals, and hashCode methods are added to case classes, unless
* they are defined in the class or a baseclass different from java.lang.Object
* - Calls to case factory methods are replaced by new's.
@@ -903,7 +903,12 @@ public class RefCheck extends Transformer implements Modifiers, Kinds {
//System.out.println("name: "+name);
Scope.Entry e = scopes[level].lookupEntry(name);
+<<<<<<< RefCheck.java
+ //System.out.println("sym: "+sym);
+ if (sym == null) unit.error(tree.pos, "sym is null");
+=======
//System.out.println("sym: "+sym);
+>>>>>>> 1.27
if (sym.isLocal() && sym == e.sym) {
int i = level;
while (scopes[i] != e.owner) i--;