From 0a0595a1c73b956f8582879d518c75970b910c23 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 16 Jul 2003 10:49:15 +0000 Subject: *** empty log message *** --- sources/scalac/ast/TreeInfo.java | 4 +- sources/scalac/ast/parser/Parser.java | 119 +++++++++++++++-------------- sources/scalac/ast/parser/Scanner.java | 3 +- sources/scalac/symtab/SourceCompleter.java | 2 +- sources/scalac/symtab/Symbol.java | 17 ++--- sources/scalac/typechecker/Analyzer.java | 42 +++++++--- sources/scalac/typechecker/DeSugarize.java | 16 ++-- sources/scalac/typechecker/RefCheck.java | 7 +- 8 files changed, 121 insertions(+), 89 deletions(-) (limited to 'sources/scalac') 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--; -- cgit v1.2.3