diff options
author | Martin Odersky <odersky@gmail.com> | 2003-07-04 14:06:34 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2003-07-04 14:06:34 +0000 |
commit | 00abd39f96ee40da727ccc735d25ca3d96ce01ce (patch) | |
tree | 6d7314cd14761335c0dd99d149d8934ef45d4115 /sources | |
parent | bf8fd4c5b3e1df5b249f7fa2d765913cf662fd51 (diff) | |
download | scala-00abd39f96ee40da727ccc735d25ca3d96ce01ce.tar.gz scala-00abd39f96ee40da727ccc735d25ca3d96ce01ce.tar.bz2 scala-00abd39f96ee40da727ccc735d25ca3d96ce01ce.zip |
*** empty log message ***
Diffstat (limited to 'sources')
-rw-r--r-- | sources/scalac/ast/parser/Parser.java | 16 | ||||
-rw-r--r-- | sources/scalac/ast/parser/Scanner.java | 1 | ||||
-rw-r--r-- | sources/scalac/ast/parser/Tokens.java | 1 | ||||
-rw-r--r-- | sources/scalac/ast/printer/TextTreePrinter.java | 9 | ||||
-rw-r--r-- | sources/scalac/symtab/Modifiers.java | 10 | ||||
-rw-r--r-- | sources/scalac/symtab/Symbol.java | 18 | ||||
-rw-r--r-- | sources/scalac/symtab/Type.java | 6 | ||||
-rw-r--r-- | sources/scalac/typechecker/Analyzer.java | 69 | ||||
-rw-r--r-- | sources/scalac/util/Names.java | 1 |
9 files changed, 92 insertions, 39 deletions
diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java index 0ec6de68b0..51d926afdf 100644 --- a/sources/scalac/ast/parser/Parser.java +++ b/sources/scalac/ast/parser/Parser.java @@ -115,15 +115,16 @@ public class Parser implements Tokens { boolean isModifier() { return (s.token == ABSTRACT) || (s.token == FINAL) + || (s.token == SEALED) || (s.token == PRIVATE) || (s.token == PROTECTED) -// || (s.token == QUALIFIED) || (s.token == OVERRIDE); } boolean isLocalModifier() { return (s.token == ABSTRACT) - || (s.token == FINAL); + || (s.token == FINAL) + || (s.token == SEALED); } boolean isDefIntro() { @@ -921,6 +922,9 @@ public class Parser implements Tokens { convertToConstr(stats[stats.length - 1])); else syntaxError(res.pos, "class constructor expected", false); + break; + default: + res = applyConstr(convertToConstr(res)); } accept(RBRACE); return res; @@ -1190,6 +1194,9 @@ public class Parser implements Tokens { case FINAL: mod = Modifiers.FINAL; break; + case SEALED: + mod = Modifiers.SEALED; + break; case PRIVATE: mod = Modifiers.PRIVATE; break; @@ -1224,6 +1231,9 @@ public class Parser implements Tokens { case FINAL: mod = Modifiers.FINAL; break; + case SEALED: + mod = Modifiers.SEALED; + break; default: return mods; } @@ -1386,9 +1396,11 @@ public class Parser implements Tokens { t = make.Select(pos, t, name); pos = accept(DOT); } else { + /* if (name == Names.ASTERISK) s.unit.warning( pos, "this imports only the identifier `*';\nuse `import xyz._' to import all members of `xyz'."); + */ return make.Import(startpos, t, new Name[]{name, name}); } } diff --git a/sources/scalac/ast/parser/Scanner.java b/sources/scalac/ast/parser/Scanner.java index 82b41f6e3a..5573ce3e05 100644 --- a/sources/scalac/ast/parser/Scanner.java +++ b/sources/scalac/ast/parser/Scanner.java @@ -816,6 +816,7 @@ public class Scanner extends TokenData { enterKeyword("package", PACKAGE); enterKeyword("private", PRIVATE); enterKeyword("protected", PROTECTED); + enterKeyword("sealed", SEALED); enterKeyword("super", SUPER); enterKeyword("this", THIS); enterKeyword("trait", TRAIT); diff --git a/sources/scalac/ast/parser/Tokens.java b/sources/scalac/ast/parser/Tokens.java index cad7a2da8b..f2e3bc39ad 100644 --- a/sources/scalac/ast/parser/Tokens.java +++ b/sources/scalac/ast/parser/Tokens.java @@ -60,6 +60,7 @@ public interface Tokens { YIELD = 50, DO = 51, TRAIT = 52, + SEALED = 53, /* special symbols */ COMMA = 61, diff --git a/sources/scalac/ast/printer/TextTreePrinter.java b/sources/scalac/ast/printer/TextTreePrinter.java index 39e8f1edcf..a56fb1a656 100644 --- a/sources/scalac/ast/printer/TextTreePrinter.java +++ b/sources/scalac/ast/printer/TextTreePrinter.java @@ -154,6 +154,7 @@ public class TextTreePrinter implements TreePrinter { protected static final Text KW_ELSE = Text.Keyword("else"); protected static final Text KW_EXTENDS = Text.Keyword("extends"); protected static final Text KW_FINAL = Text.Keyword("final"); + protected static final Text KW_SEALED = Text.Keyword("sealed"); protected static final Text KW_FOR = Text.Keyword("for"); protected static final Text KW_IF = Text.Keyword("if"); protected static final Text KW_IMPORT = Text.Keyword("import"); @@ -643,6 +644,10 @@ public class TextTreePrinter implements TreePrinter { print(KW_FINAL); print(Text.Space); } + if ((flags & Modifiers.SEALED) != 0) { + print(KW_SEALED); + print(Text.Space); + } if ((flags & Modifiers.PRIVATE) != 0) { print(KW_PRIVATE); print(Text.Space); @@ -651,10 +656,6 @@ public class TextTreePrinter implements TreePrinter { print(KW_PROTECTED); print(Text.Space); } - if ((flags & Modifiers.QUALIFIED) != 0) { - print(KW_QUALIFIED); - print(Text.Space); - } if ((flags & Modifiers.OVERRIDE) != 0) { print(KW_OVERRIDE); print(Text.Space); diff --git a/sources/scalac/symtab/Modifiers.java b/sources/scalac/symtab/Modifiers.java index 9c6f12c115..00509ad16b 100644 --- a/sources/scalac/symtab/Modifiers.java +++ b/sources/scalac/symtab/Modifiers.java @@ -16,7 +16,7 @@ public interface Modifiers { int PRIVATE = 0x00000004; int PROTECTED = 0x00000008; - int QUALIFIED = 0x00000010; + int SEALED = 0x00000010; int OVERRIDE = 0x00000020; int CASE = 0x00000040; int ABSTRACTCLASS = 0x00000080; // abstract class @@ -36,7 +36,7 @@ public interface Modifiers { int ACCESSED = 0x00040000; // symbol was accessed at least once int SELECTOR = 0x00080000; // symbol was used as selector in Select - int PACKAGE = 0x00100000; // symbol is a java packages. + int PACKAGE = 0x00100000; // symbol is a java package. int LABEL = 0x00200000; // symbol is a label symbol int STATIC = 0x00400000; // "static" inner classes (i.e. after class norm.) int STABLE = 0x00800000; // functions that are assumed to be stable @@ -79,8 +79,8 @@ public interface Modifiers { return (flags & PROTECTED) != 0; } - public static boolean isQualified(int flags) { - return (flags & QUALIFIED) != 0; + public static boolean isSealed(int flags) { + return (flags & SEALED) != 0; } public static boolean isOverride(int flags) { @@ -132,7 +132,7 @@ public interface Modifiers { if (isProtected(flags)) buffer.append("protected "); if (isAbstract(flags)) buffer.append("abstract "); if (isFinal(flags)) buffer.append("final "); - if (isQualified(flags)) buffer.append("qualified "); + if (isSealed(flags)) buffer.append("qualified "); if (isInterface(flags)) buffer.append("interface "); if (isCase(flags)) buffer.append("case "); if (isDef(flags)) buffer.append("def "); diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index 23b062800f..5e4e7e2801 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -211,6 +211,13 @@ public abstract class Symbol implements Modifiers, Kinds { return isInitializedMethod(); } + /* + public final boolean caseClassOfFactory() { + if (isMethod() && !isConstructor() && (flags & CASE) != 0) + return owner.info().lookup(name.toTypeName()).constructor(); + } + */ + public final boolean isAbstractClass() { return (flags & ABSTRACTCLASS) != 0 && this != Global.instance.definitions.ARRAY_CLASS; @@ -542,7 +549,7 @@ public abstract class Symbol implements Modifiers, Kinds { throw new CyclicReference(this, info); } flags |= LOCKED; - //System.out.println("completing " + this);//DEBUG + //System.out.println("completing " + this.name);//DEBUG info.complete(this); flags = flags & ~LOCKED; if (info instanceof SourceCompleter && (flags & SNDTIME) == 0) { @@ -553,7 +560,7 @@ public abstract class Symbol implements Modifiers, Kinds { assert !(rawInfoAt(id) instanceof Type.LazyType) : this; flags |= INITIALIZED; } - //System.out.println("done: " + this);//DEBUG + //System.out.println("done: " + this.name);//DEBUG } return rawInfoAt(id); } @@ -741,6 +748,7 @@ public abstract class Symbol implements Modifiers, Kinds { closurePos(c) >= 0 || this == Global.instance.definitions.ALL_CLASS || (this == Global.instance.definitions.ALLREF_CLASS && + c != Global.instance.definitions.ALL_CLASS && c.isSubClass(Global.instance.definitions.ANYREF_CLASS)); } @@ -914,8 +922,10 @@ public abstract class Symbol implements Modifiers, Kinds { owner.thisType().memberType(that)); } + /** Reset symbol to initial state + */ public void reset(Type completer) { - this.flags &= (FINAL | MODUL); + this.flags &= SOURCEFLAGS; this.pos = 0; this.infos = TypeIntervalList.EMPTY; this.setInfo(completer); @@ -942,7 +952,7 @@ public class TermSymbol extends Symbol { } public static TermSymbol newJavaConstructor(Symbol clazz) { - return newConstructor(clazz, clazz.flags & (ACCESSFLAGS | QUALIFIED | JAVA)); + return newConstructor(clazz, clazz.flags & (ACCESSFLAGS | JAVA)); } public static TermSymbol newModule(int pos, Name name, Symbol owner, int flags) { diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 471c206b9c..33d509c55c 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -305,6 +305,7 @@ public class Type implements Modifiers, Kinds, TypeTags { lb = pre.memberLoBound(sym); } if (lb.symbol() == Global.instance.definitions.ALL_CLASS && + this.symbol() != Global.instance.definitions.ALL_CLASS && this.isSubType(Global.instance.definitions.ANYREF_TYPE)) { lb = Global.instance.definitions.ALLREF_TYPE; } @@ -1389,8 +1390,9 @@ public class Type implements Modifiers, Kinds, TypeTags { return that.isSubType(Global.instance.definitions.ANY_TYPE); else if (sym == Global.instance.definitions.ALLREF_CLASS) return - that.isSameAs(Global.instance.definitions.ANY_TYPE) || - that.isSubType(Global.instance.definitions.ANYREF_TYPE); + that.symbol() == Global.instance.definitions.ANY_CLASS || + (that.symbol() != Global.instance.definitions.ALL_CLASS && + that.isSubType(Global.instance.definitions.ANYREF_TYPE)); break; case OverloadedType(Symbol[] alts, Type[] alttypes): diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index 03377ef78c..abb6b7067f 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -9,12 +9,11 @@ // todo: (0) propagate target type in cast. // todo: eliminate Typed nodes. // todo: use SELECTOR flag to avoid access methods for privates -// todo: drop requirement that only abstract classes can have abstract -// type members. // 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 package scalac.typechecker; @@ -259,6 +258,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { void validate(Symbol sym) { checkNoConflict(sym, DEFERRED, PRIVATE); checkNoConflict(sym, FINAL, PRIVATE); + checkNoConflict(sym, FINAL, SEALED); checkNoConflict(sym, PRIVATE, PROTECTED); checkNoConflict(sym, PRIVATE, OVERRIDE); checkNoConflict(sym, DEFERRED, FINAL); @@ -331,6 +331,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { " does not conform to " + parents[i] + "'s supertype"); } if ((bsym.flags & FINAL) != 0) { + error(constrs[i].pos, "illegal inheritance from final class"); + } else if ((bsym.flags & SEALED) != 0) { // are we in same scope as base type definition? Scope.Entry e = context.scope.lookupEntry(bsym.name); if (e.sym != bsym || e.owner != context.scope) { @@ -339,7 +341,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { while (c != Context.NONE && c.owner != bsym) c = c.outer; if (c == Context.NONE) { - error(constrs[i].pos, "illegal inheritance from final class"); + error(constrs[i].pos, "illegal inheritance from sealed class"); } } } @@ -880,6 +882,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { this.mode = EXPRmode; Type savedPt = this.pt; this.pt = Type.AnyType; + int savedId = global.currentPhase.id; + global.currentPhase.id = descr.id; try { Symbol sym = tree.symbol(); @@ -942,8 +946,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } popContext(); } + //checkNonCyclic(tree.pos, tpe.type); owntype = tpe.type; - checkNonCyclic(tree.pos, owntype); break; case DefDef(int mods, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree rhs): @@ -959,7 +963,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } Type restype = checkNoEscape(tpe.pos, tpe.type); popContext(); - checkNonCyclic(tree.pos, restype); + //checkNonCyclic(tree.pos, tpe.type); owntype = makeMethodType(tparamSyms, vparamSyms, restype); //System.out.println("methtype " + name + ":" + owntype);//DEBUG break; @@ -978,13 +982,21 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { owntype = rhs.type; popContext(); } - checkNonCyclic(tree.pos, owntype); + //checkNonCyclic(tree.pos, owntype); break; case Import(Tree expr, Name[] selectors): ((Import) tree).expr = expr = transform(expr, EXPRmode | QUALmode); checkStable(expr); owntype = expr.type; + Type tp = owntype.widen(); + for (int i = 0; i < selectors.length; i = i + 2) { + if (selectors[i] != Names.WILDCARD && + 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); + } break; default: @@ -1003,6 +1015,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { this.context = savedContext; this.mode = savedMode; this.pt = savedPt; + global.currentPhase.id = savedId; } /** Definition phase for a template. This enters all symbols in template @@ -1660,6 +1673,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { rhs1 = transform(rhs, EXPRmode, tpe.type); popContext(); } + sym.flags |= LOCKED; + checkNonCyclic(tree.pos, tpe.type); + sym.flags &= ~LOCKED; return copy.ValDef(tree, sym, tpe, rhs1) .setType(definitions.UNIT_TYPE); @@ -1673,10 +1689,14 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { if (rhs != Tree.Empty) rhs1 = transform(rhs, EXPRmode, tpe.type); popContext(); + sym.flags |= LOCKED; + checkNonCyclic(tree.pos, tpe.type); + sym.flags &= ~LOCKED; return copy.DefDef(tree, sym, tparams1, vparams1, tpe, rhs1) .setType(definitions.UNIT_TYPE); case TypeDef(_, _, _, _): + checkNonCyclic(tree.pos, sym.type()); return tree .setType(definitions.UNIT_TYPE); @@ -2073,23 +2093,30 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { infer.applyErrorMsg( "", fn1, " cannot be applied to ", argtypes, pt)); - case Super(Tree tpe): - Symbol enclClazz = context.enclClass.owner; - if (enclClazz != null) { - // we are in a class or module - Tree tpe1 = transform(tpe, TYPEmode); // ignored for now. - switch (enclClazz.info()) { - case CompoundType(Type[] parents, _): - return copy.Super(tree, tpe1) - .setType(Type.compoundType(parents, Scope.EMPTY).symbol().thisType()); - case ErrorType: - return tree.setType(Type.ErrorType); - default: - throw new ApplicationError(); + case Super(Tree qual): + Symbol clazz; + Tree qual1; + if (qual == Tree.Empty) { + clazz = context.enclClass.owner; + if (clazz != null) { + qual1 = gen.Ident(tree.pos, clazz); + } else { + return error( + tree.pos, + "super can be used only in a class, object, or template"); } } else { - return error(tree.pos, - "super can be used only in a class, object, or template"); + qual1 = transform(qual, TYPEmode | FUNmode); + clazz = qual1.symbol(); + } + switch (clazz.info()) { + case CompoundType(Type[] parents, _): + return copy.Super(tree, qual1) + .setType(Type.compoundType(parents, Scope.EMPTY).symbol().thisType()); + case ErrorType: + return tree.setType(Type.ErrorType); + default: + return error(qual.pos, "class identifier expected"); } case This(Tree qual): diff --git a/sources/scalac/util/Names.java b/sources/scalac/util/Names.java index 0b224b9758..9e338d9d4d 100644 --- a/sources/scalac/util/Names.java +++ b/sources/scalac/util/Names.java @@ -21,7 +21,6 @@ public class Names { public static final Name _EQ = encode("_="); public static final Name MINUS = encode("-"); public static final Name PLUS = encode("+"); - public static final Name ASTERISK = encode("*"); public static final Name TILDE = encode("~"); public static final Name EQEQ = encode("=="); public static final Name BANG = encode("!"); |