From 03449ed20a3cca9e8d974c7efeff6b4e01ecb66d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 31 Jul 2003 09:57:59 +0000 Subject: *** empty log message *** --- sources/meta/scalac/ast/MetaTree.java | 4 +- sources/meta/scalac/ast/Tree.java | 2 +- sources/scalac/Global.java | 2 +- sources/scalac/ast/TreeGen.java | 21 +- sources/scalac/ast/parser/Parser.java | 94 ++++----- sources/scalac/ast/parser/Scanner.java | 6 +- sources/scalac/ast/parser/Tokens.java | 2 +- sources/scalac/ast/printer/TextTreePrinter.java | 6 +- sources/scalac/backend/Primitives.java | 8 +- sources/scalac/backend/msil/TypeCreator.java | 2 +- sources/scalac/checkers/CheckNames.java | 6 +- sources/scalac/checkers/CheckOwners.java | 8 +- sources/scalac/symtab/Definitions.java | 6 +- sources/scalac/symtab/EntryTags.java | 76 ++++--- sources/scalac/symtab/Scope.java | 5 +- sources/scalac/symtab/Symbol.java | 222 ++++++++++++------- sources/scalac/symtab/Type.java | 21 +- .../scalac/symtab/classfile/AttributeParser.java | 61 ++---- .../scalac/symtab/classfile/ClassfileParser.java | 36 ++-- sources/scalac/symtab/classfile/PackageParser.java | 12 +- sources/scalac/symtab/classfile/Pickle.java | 78 +++---- sources/scalac/symtab/classfile/UnPickle.java | 106 +++++----- sources/scalac/transformer/AddAccessors.java | 1 - sources/scalac/transformer/AddConstructors.java | 7 +- sources/scalac/transformer/AddInterfaces.java | 8 +- sources/scalac/transformer/AddInterfacesPhase.java | 16 +- sources/scalac/transformer/ExpandMixins.java | 2 +- .../scalac/transformer/ExplicitOuterClasses.java | 2 +- sources/scalac/transformer/LambdaLift.java | 16 +- sources/scalac/transformer/LambdaLiftPhase.java | 5 +- sources/scalac/transformer/OwnerTransformer.java | 6 +- .../transformer/matching/AlgebraicMatcher.java | 4 +- .../transformer/matching/PatternMatcher.java | 4 +- sources/scalac/typechecker/Analyzer.java | 234 ++++++++++++--------- sources/scalac/typechecker/DeSugarize.java | 4 +- sources/scalac/typechecker/ImportList.java | 2 - sources/scalac/typechecker/RefCheck.java | 10 +- sources/scalac/util/FreshNameCreator.java | 1 - sources/scalac/util/Name.java | 27 --- 39 files changed, 593 insertions(+), 540 deletions(-) (limited to 'sources') diff --git a/sources/meta/scalac/ast/MetaTree.java b/sources/meta/scalac/ast/MetaTree.java index 74ddd49657..3ae0c9970d 100644 --- a/sources/meta/scalac/ast/MetaTree.java +++ b/sources/meta/scalac/ast/MetaTree.java @@ -117,10 +117,10 @@ public class MetaTree extends AbstractTreeExpander { writer.indent().print("return "); switch (kind) { case TreeKind.Type: - writer.print("name.isTypeName() || name == Name.ERROR"); + writer.print("name.isTypeName() && (symbol() == null || !symbol().isConstructor()) || name == Name.ERROR"); break; case TreeKind.Term: - writer.print("!name.isTypeName()"); + writer.print("name.isTermName() || (symbol() != null && symbol().isConstructor())"); break; default: throw new Error("unexpected kind " + kind); diff --git a/sources/meta/scalac/ast/Tree.java b/sources/meta/scalac/ast/Tree.java index 10948ef5d1..611054180e 100644 --- a/sources/meta/scalac/ast/Tree.java +++ b/sources/meta/scalac/ast/Tree.java @@ -271,7 +271,7 @@ public class Tree { n_TypeApply. setDescription("Type application"). setRange(Phase.PARSER, Phase.END). - addField(t_TermTree, "fun"). + addField(t_Tree, "fun"). addField(t_TypeTrees, "args"); n_Apply. diff --git a/sources/scalac/Global.java b/sources/scalac/Global.java index b5ef83b8ab..36c25ce503 100644 --- a/sources/scalac/Global.java +++ b/sources/scalac/Global.java @@ -407,7 +407,7 @@ public class Global { make.Apply(0, make.Select(0, make.Ident(0, Names.scala), - Names.Object.toConstrName()), + Names.Object.toTypeName()), new Tree[0])}, unit.body))}; module++; diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java index f890a63a61..051c067b5a 100644 --- a/sources/scalac/ast/TreeGen.java +++ b/sources/scalac/ast/TreeGen.java @@ -188,7 +188,12 @@ public class TreeGen implements Kinds, Modifiers { public Tree mkParentConstr(int pos, Type parentType, Tree[] parentArgs) { switch (parentType) { case TypeRef(Type pre, Symbol sym, Type[] args): - Tree ref = mkRef(pos, pre, sym.constructor()); + Tree ref = mkRef(pos, pre, sym.allConstructors()); + switch (ref.type) { + case OverloadedType(Symbol[] alts, Type[] alttypes): + infer.methodAlternative( + ref, alts, alttypes, Tree.typeOf(parentArgs), Type.AnyType); + } Tree constr = (args.length == 0) ? ref : TypeApply(ref, mkTypes(sym.pos, args)); return Apply(constr, parentArgs); @@ -206,14 +211,14 @@ public class TreeGen implements Kinds, Modifiers { public Tree[] mkParentConstrs(int pos, Type[] parents, Tree[][] parentArgs) { Tree[] constrs = new Tree[parents.length]; for (int i = 0; i < parents.length; ++i) - constrs[i] = (parentArgs == null ? + constrs[i] = (parentArgs.length == 0 ? mkParentConstr(pos, parents[i]) - : mkParentConstr(pos, parents[i], parentArgs[i])); + : mkParentConstr(pos, parents[i], parentArgs[i])); return constrs; } public Tree[] mkParentConstrs(int pos, Type[] parents) { - return mkParentConstrs(pos, parents, null); + return mkParentConstrs(pos, parents, new Tree[][]{}); } /** Build parameter sections corresponding to type. @@ -344,7 +349,7 @@ public class TreeGen implements Kinds, Modifiers { */ public Tree New(int pos, Type pre, Symbol clazz, Type[] targs, Tree[] args) { - Tree constr = mkRef(pos, pre, clazz.constructor()); + Tree constr = mkRef(pos, pre, clazz.primaryConstructor()); if (targs.length != 0) constr = TypeApply(constr, mkTypes(pos, targs)); Tree base = Apply(constr, args); @@ -511,7 +516,7 @@ public class TreeGen implements Kinds, Modifiers { */ public Tree ClassDef(int pos, Symbol clazz, Template template) { Global.instance.nextPhase(); - Type constrtype = clazz.constructor().info(); + Type constrtype = clazz.primaryConstructor().info(); Global.instance.prevPhase(); return make.ClassDef( pos, @@ -615,7 +620,7 @@ public class TreeGen implements Kinds, Modifiers { pos, Names.ANON_CLASS_NAME.toTypeName(), owner, 0); clazz.setInfo(Type.compoundType(new Type[]{definitions.OBJECT_TYPE, ft}, new Scope(), clazz)); - clazz.constructor().setInfo( + clazz.allConstructors().setInfo( Type.MethodType(Symbol.EMPTY_ARRAY, clazz.typeConstructor())); Symbol applyMeth = new TermSymbol(pos, Names.apply, clazz, FINAL) @@ -639,7 +644,7 @@ public class TreeGen implements Kinds, Modifiers { pos, Names.ANON_CLASS_NAME.toTypeName(), owner, 0); clazz.setInfo(Type.compoundType(new Type[]{definitions.OBJECT_TYPE, pft}, new Scope(), clazz)); - clazz.constructor().setInfo( + clazz.allConstructors().setInfo( Type.MethodType(Symbol.EMPTY_ARRAY, clazz.typeConstructor())); Tree classDef = ClassDef(clazz, new Tree[]{ diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java index 3d88b2decf..afb5d8abbe 100644 --- a/sources/scalac/ast/parser/Parser.java +++ b/sources/scalac/ast/parser/Parser.java @@ -130,7 +130,7 @@ public class Parser implements Tokens { boolean isDefIntro() { switch (s.token) { - case VAL: case VAR: case DEF: case CONSTR: case TYPE: + case VAL: case VAR: case DEF: case TYPE: case OBJECT: case CASEOBJECT: case CLASS: case CASECLASS: case TRAIT: return true; default: @@ -140,7 +140,7 @@ public class Parser implements Tokens { boolean isDclIntro() { switch (s.token) { - case VAL: case VAR: case DEF: case CONSTR: case TYPE: + case VAL: case VAR: case DEF: case TYPE: return true; default: return false; @@ -247,7 +247,7 @@ public class Parser implements Tokens { Tree scalaObjectConstr(int pos) { return make.Apply( - pos, scalaDot(pos, Names.Object.toConstrName()), Tree.EMPTY_ARRAY); + pos, scalaDot(pos, Names.Object.toTypeName()), Tree.EMPTY_ARRAY); } /** Create tree for for-comprehension or @@ -403,9 +403,9 @@ public class Parser implements Tokens { Tree convertToConstr(Tree t) { switch (t) { case Ident(Name name): - return make.Ident(t.pos, name.toConstrName()); + return make.Ident(t.pos, name.toTypeName()); case Select(Tree qual, Name name): - return make.Select(t.pos, qual, name.toConstrName()); + return make.Select(t.pos, qual, name.toTypeName()); default: return syntaxError(t.pos, "class constructor expected", false); } @@ -413,12 +413,11 @@ public class Parser implements Tokens { /** Convert this(...) application to constructor invocation */ - Tree convertToSelfConstr(Tree t, Name constrname) { + Tree convertToSelfConstr(Tree t) { switch (t) { case Block(Tree[] stats): if (stats.length > 0) { - stats[stats.length - 1] = convertToSelfConstr( - stats[stats.length - 1], constrname); + stats[stats.length - 1] = convertToSelfConstr(stats[stats.length - 1]); return t; } break; @@ -426,7 +425,7 @@ public class Parser implements Tokens { switch (fn) { case This(TypeNames.EMPTY): return make.Apply( - t.pos, make.Ident(t.pos, constrname), args); + t.pos, make.Ident(t.pos, Names.this_.toTypeName()), args); } } return syntaxError(t.pos, "class constructor expected", false); @@ -928,6 +927,7 @@ public class Parser implements Tokens { * | BlockExpr * | new Template * | SimpleExpr `.' Id + * | Id `#' Id * | SimpleExpr TypeArgs * | SimpleExpr ArgumentExprs */ @@ -989,6 +989,16 @@ public class Parser implements Tokens { case DOT: t = make.Select(s.skipToken(), t, ident()); break; + case HASH: + switch (t) { + case Ident(Name name): + t = make.SelectFromType( + s.skipToken(), convertToTypeId(t), ident()); + break; + default: + return t; + } + break; case LBRACKET: switch (t) { case Ident(_): @@ -1581,7 +1591,6 @@ public class Parser implements Tokens { * Dcl ::= val ValDcl {`,' ValDcl} * | var ValDcl {`,' ValDcl} * | def FunDcl {`,' FunDcl} - * | constr ConstrDcl {`,' ConstrDcl} * | type TypeDcl {`,' TypeDcl} */ Tree[] defOrDcl(int mods) { @@ -1696,41 +1705,31 @@ public class Parser implements Tokens { } /** FunDef ::= Id [FunTypeParamClause] {ParamClauses} [`:' Type] `=' Expr + * | this ParamClause `=' ConstrExpr * FunDcl ::= Id [FunTypeParamClause] {ParamClauses} `:' Type */ Tree funDefOrDcl(int mods) { int pos = s.pos; - Name name = ident(); - TypeDef[] tparams = typeParamClauseOpt(false); - ValDef[][] vparams = paramClauses(); - Tree restype = typedOpt(); - if (s.token == EQUALS || restype == Tree.Empty) - return make.DefDef(pos, mods, name, tparams, vparams, - restype, equalsExpr()); - else - return make.DefDef(pos, mods | Modifiers.DEFERRED, name, - tparams, vparams, restype, Tree.Empty); - } - - /* ConstrDef ::= [ParamClause] `=' ConstrExpr - * ConstrExpr ::= this `(' [Exprs] `)' - * | `{' { BlockStat `;' } ConstrExpr `}' - */ - Tree constrDef(int mods, Name clazzname, TypeDef[] tparams) { - Name constrname = clazzname.toConstrName(); - int pos = s.pos; - 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); + if (s.token == THIS) { + s.nextToken(); + ValDef[][] vparams = new ValDef[][]{paramClause()}; + accept(EQUALS); + return make.DefDef( + pos, mods, Names.this_.toTypeName(), + Tree.TypeDef_EMPTY_ARRAY, vparams, Tree.Empty, + convertToSelfConstr(expr())); + } else { + Name name = ident(); + TypeDef[] tparams = typeParamClauseOpt(false); + ValDef[][] vparams = paramClauses(); + Tree restype = typedOpt(); + if (s.token == EQUALS || restype == Tree.Empty) + return make.DefDef(pos, mods, name, tparams, vparams, + restype, equalsExpr()); + else + return make.DefDef(pos, mods | Modifiers.DEFERRED, name, + tparams, vparams, restype, Tree.Empty); } - return make.DefDef( - pos, mods | Modifiers.FINAL, constrname, - tparams, vparams, restype, convertToSelfConstr(expr(), constrname)); } /** TypeDef ::= Id `=' Type @@ -1754,23 +1753,16 @@ public class Parser implements Tokens { } } - /** ClassDef ::= Id [TypeParamClause] [ParamClause] [`:' SimpleType] - * ClassTemplate { [`;'] constr ConstrDef } + /** ClassDef ::= Id [TypeParamClause] [ParamClause] [`:' SimpleType] ClassTemplate */ - Tree[] classDef(int mods) { + Tree classDef(int mods) { int pos = s.pos; Name clazzname = ident().toTypeName(); TypeDef[] tparams = typeParamClauseOpt(true); ValDef[][] params = paramClauseOpt(); TreeList result = new TreeList(); - result.append( - popComment(make.ClassDef(pos, mods, clazzname, tparams, params, - simpleTypedOpt(), classTemplate()))); - while (s.token == CONSTR) { - s.nextToken(); - result.append(popComment(constrDef(mods, clazzname, tparams))); - } - return result.toArray(); + return popComment(make.ClassDef(pos, mods, clazzname, tparams, params, + simpleTypedOpt(), classTemplate())); } /** ObjectDef ::= Id [`:' SimpleType] ClassTemplate diff --git a/sources/scalac/ast/parser/Scanner.java b/sources/scalac/ast/parser/Scanner.java index c747fc1bcc..4b070006bc 100644 --- a/sources/scalac/ast/parser/Scanner.java +++ b/sources/scalac/ast/parser/Scanner.java @@ -124,7 +124,6 @@ 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: @@ -163,7 +162,7 @@ public class Scanner extends TokenData { } else if (token == SEMI) { prev.copyFrom(this); fetchToken(); - if (token != ELSE || token == CONSTR) { + if (token != ELSE) { next.copyFrom(this); this.copyFrom(prev); } @@ -237,7 +236,7 @@ public class Scanner extends TokenData { break; case '_': nextch(); - getIdentOrOperatorRest(index); + getIdentRest(index); return; case '0': nextch(); @@ -815,7 +814,6 @@ public class Scanner extends TokenData { enterKeyword("case", CASE); enterKeyword("class", CLASS); enterKeyword("catch", CATCH); - enterKeyword("constr", CONSTR); enterKeyword("def", DEF); enterKeyword("do", DO); enterKeyword("else", ELSE); diff --git a/sources/scalac/ast/parser/Tokens.java b/sources/scalac/ast/parser/Tokens.java index 9ec7878918..9da23bc7e3 100644 --- a/sources/scalac/ast/parser/Tokens.java +++ b/sources/scalac/ast/parser/Tokens.java @@ -52,7 +52,7 @@ public interface Tokens { FALSE = 42, OBJECT = 43, CLASS = 44, - CONSTR = 45, + IMPORT = 46, PACKAGE = 47, AS = 48, diff --git a/sources/scalac/ast/printer/TextTreePrinter.java b/sources/scalac/ast/printer/TextTreePrinter.java index 8773c7e72e..664957e79a 100644 --- a/sources/scalac/ast/printer/TextTreePrinter.java +++ b/sources/scalac/ast/printer/TextTreePrinter.java @@ -149,7 +149,6 @@ public class TextTreePrinter implements TreePrinter { protected static final Text KW_ABSTRACT = Text.Keyword("abstract"); protected static final Text KW_CASE = Text.Keyword("case"); protected static final Text KW_CLASS = Text.Keyword("class"); - protected static final Text KW_CONSTR = Text.Keyword("constr"); protected static final Text KW_DEF = Text.Keyword("def"); protected static final Text KW_DO = Text.Keyword("do"); protected static final Text KW_ELSE = Text.Keyword("else"); @@ -322,9 +321,10 @@ public class TextTreePrinter implements TreePrinter { Tree tpe, Tree rhs): printModifiers(mods); - if (name.isConstrName()) print(KW_CONSTR); else print(KW_DEF); + print(KW_DEF); print(Text.Space); - printSymbolDefinition(tree.symbol(), name); + if (name.isTypeName()) print(KW_THIS); + else printSymbolDefinition(tree.symbol(), name); printParams(tparams); printParams(vparams); printOpt(TXT_COLON, tpe, false); diff --git a/sources/scalac/backend/Primitives.java b/sources/scalac/backend/Primitives.java index d7e6ba3a5e..05549c7133 100644 --- a/sources/scalac/backend/Primitives.java +++ b/sources/scalac/backend/Primitives.java @@ -249,7 +249,7 @@ public class Primitives { this.FARRAY_SET = getUniqueTerm(RUNTIME, FARRAY_SET_N); this.DARRAY_SET = getUniqueTerm(RUNTIME, DARRAY_SET_N); this.OARRAY_SET = getUniqueTerm(RUNTIME, OARRAY_SET_N); - Symbol[] boxes = getTerm(RUNTIME, BOX_N).alternatives(); + Symbol[] boxes = getTerm(RUNTIME, BOX_N).alternativeSymbols(); this.BOX_UVALUE = getBoxUnit(boxes); this.BOX_ZVALUE = getBoxValue(boxes, definitions.BOOLEAN_TYPE); this.BOX_BVALUE = getBoxValue(boxes, definitions.BYTE_TYPE); @@ -560,7 +560,7 @@ public class Primitives { Name name = Names.ADD; Symbol symbol = clasz.lookup(name); assert symbol != Symbol.NONE : Debug.show(clasz) + "." + name; - Symbol[] alts = symbol.alternatives(); + Symbol[] alts = symbol.alternativeSymbols(); // !!! assert count + 2 == alts.length : (count + 2) + " != " + alts.length; boolean pos = false; boolean concat = false; @@ -597,7 +597,7 @@ public class Primitives { Name name = Names.SUB; Symbol symbol = clasz.lookup(name); assert symbol != Symbol.NONE : Debug.show(clasz) + "." + name; - Symbol[] alts = symbol.alternatives(); + Symbol[] alts = symbol.alternativeSymbols(); // !!! assert count + 1 == alts.length : (count + 1) + " != " + alts.length; boolean pos = false; for (int i = 0; i < alts.length; i++) { @@ -626,7 +626,7 @@ public class Primitives { private void addAll(Symbol clasz,Name name,Primitive primitive,int count) { Symbol symbol = clasz.lookup(name); assert symbol != Symbol.NONE : Debug.show(clasz) + "." + name; - Symbol[] alts = symbol.alternatives(); + Symbol[] alts = symbol.alternativeSymbols(); assert count == alts.length : count + " != " + alts.length; for (int i = 0; i < alts.length; i++) addPrimitive(alts[i], primitive); } diff --git a/sources/scalac/backend/msil/TypeCreator.java b/sources/scalac/backend/msil/TypeCreator.java index 8d7c4fa1a5..5a4a8e84a5 100644 --- a/sources/scalac/backend/msil/TypeCreator.java +++ b/sources/scalac/backend/msil/TypeCreator.java @@ -175,7 +175,7 @@ public final class TypeCreator scalac.symtab.Type[] paramTypes) { Symbol[] methods = clazz.members(). - lookup(Name.fromString(name)).alternatives(); + lookup(Name.fromString(name)).alternativeSymbols(); search: for (int i = 0; i < methods.length; i++) { switch (methods[i].info()) { diff --git a/sources/scalac/checkers/CheckNames.java b/sources/scalac/checkers/CheckNames.java index a129aa0236..9529a6b088 100644 --- a/sources/scalac/checkers/CheckNames.java +++ b/sources/scalac/checkers/CheckNames.java @@ -35,12 +35,12 @@ public class CheckNames extends Checker { "class " + Debug.show(tree.symbol()) + "should have a type name"); - Symbol constr = tree.symbol().constructor(); + Symbol constr = tree.symbol().primaryConstructor(); verify(tree, - constr.name.isConstrName(), + constr.name.isTypeName(), "name kinds", "the class constructor " + Debug.show(constr) - + " should have a constructor name"); + + " should have a type name"); break; } } diff --git a/sources/scalac/checkers/CheckOwners.java b/sources/scalac/checkers/CheckOwners.java index cabe120708..8ebd0b9f8f 100644 --- a/sources/scalac/checkers/CheckOwners.java +++ b/sources/scalac/checkers/CheckOwners.java @@ -54,7 +54,7 @@ public class CheckOwners extends Checker { protected void traverse(Template templ, Symbol owner) { Symbol prevOwner = currentOwner; if (owner.kind == Kinds.CLASS) - currentOwner = owner.constructor(); + currentOwner = owner.primaryConstructor(); traverse(templ.parents); currentOwner = owner; @@ -103,8 +103,8 @@ public class CheckOwners extends Checker { Tree tpe, Template impl): { check(tree); - traverse(tparams, tree.symbol().constructor()); - traverse(vparams, tree.symbol().constructor()); + traverse(tparams, tree.symbol().primaryConstructor()); + traverse(vparams, tree.symbol().primaryConstructor()); traverse(tpe); traverse(impl, tree.symbol()); } break; @@ -151,7 +151,7 @@ public class CheckOwners extends Checker { if (sym != null && sym != Symbol.NONE) { checkOwner(tree, sym); if (sym.kind == Kinds.CLASS) - checkOwner(tree, sym.constructor()); + checkOwner(tree, sym.primaryConstructor()); } } } diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java index 6760dbaa28..648e253380 100644 --- a/sources/scalac/symtab/Definitions.java +++ b/sources/scalac/symtab/Definitions.java @@ -205,7 +205,7 @@ public class Definitions { SCALA_CLASS.members().enter(ANY_CLASS); ANY_TYPE = ANY_CLASS.typeConstructor(); ANY_CLASS.setInfo(Type.compoundType(Type.EMPTY_ARRAY, new Scope(), ANY_CLASS)); - ANY_CLASS.constructor().setInfo( + ANY_CLASS.primaryConstructor().setInfo( Type.MethodType(Symbol.EMPTY_ARRAY, ANY_TYPE)); // the java.lang.OBJECT class @@ -238,7 +238,7 @@ public class Definitions { SCALA_CLASS.members().enter(ALL_CLASS); ALL_TYPE = ALL_CLASS.typeConstructor(); ALL_CLASS.setInfo(Type.compoundType(new Type[]{ANY_TYPE}, new Scope(), ALL_CLASS)); - ALL_CLASS.constructor().setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, ALL_TYPE)); + ALL_CLASS.primaryConstructor().setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, ALL_TYPE)); // the scala.ALLREF class ALLREF_CLASS = new ClassSymbol( @@ -246,7 +246,7 @@ public class Definitions { SCALA_CLASS.members().enter(ALLREF_CLASS); ALLREF_TYPE = ALLREF_CLASS.typeConstructor(); ALLREF_CLASS.setInfo(Type.compoundType(new Type[]{ANYREF_TYPE}, new Scope(), ALLREF_CLASS)); - ALLREF_CLASS.constructor().setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, ALLREF_TYPE)); + ALLREF_CLASS.primaryConstructor().setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, ALLREF_TYPE)); // the primitive types DOUBLE_CLASS = getClass(Names.scala_Double); diff --git a/sources/scalac/symtab/EntryTags.java b/sources/scalac/symtab/EntryTags.java index b8ae7c2d7a..ed1d089641 100644 --- a/sources/scalac/symtab/EntryTags.java +++ b/sources/scalac/symtab/EntryTags.java @@ -14,24 +14,23 @@ public interface EntryTags { * Symbol table attribute format: * Symtab = nentries_Nat {Entry} * Entry = 1 TERMNAME len_Nat NameInfo - * | 2 CONSTRNAME len_Nat NameInfo - * | 3 TYPENAME len_Nat NameInfo - * | 4 NONEsym len_Nat - * | 5 TYPEsym len_Nat SymbolInfo lobound_Ref - * | 6 ALIASsym len_Nat SymbolInfo - * | 7 CLASSsym len_Nat SymbolInfo thistype_Ref constrsym_Ref - * | 8 VALsym len_Nat SymbolInfo [classsym_Ref] - * | 9 EXTsym len_Nat name_Ref [owner_Ref] - * | 10 EXTMODCLASSsym len_Nat name_Ref [owner_Ref] - * | 11 NOtpe len_Nat - * | 12 THIStpe len_Nat sym_Ref - * | 13 SINGLEtpe len_Nat type_Ref sym_Ref - * | 14 TYPEREFtpe len_Nat type_Ref sym_Ref {targ_Ref} - * | 15 COMPOUNDtpe len_Nat classsym_Ref {tpe_Ref} - * | 16 METHODtpe len_Nat tpe_Ref {tpe_Ref} - * | 17 POLYTtpe len_Nat tpe_Ref {sym_Ref} - * | 18 OVERLOADEDtpe len_Nat {sym_Ref} {tpe_Ref} - * | 21 FLAGGEDtype len_Nat flags_Nat tpe_Ref + * | 2 TYPENAME len_Nat NameInfo + * | 3 NONEsym len_Nat + * | 4 TYPEsym len_Nat SymbolInfo lobound_Ref + * | 5 ALIASsym len_Nat SymbolInfo + * | 6 CLASSsym len_Nat SymbolInfo thistype_Ref constrsym_Ref + * | 7 VALsym len_Nat SymbolInfo [classsym_Ref] + * | 8 TERMref len_Nat name_Ref [owner_Ref] + * | 9 TYPEref len_Nat name_Ref [owner_Ref] + * | 10 NOtpe len_Nat + * | 11 THIStpe len_Nat sym_Ref + * | 12 SINGLEtpe len_Nat type_Ref sym_Ref + * | 13 TYPEREFtpe len_Nat type_Ref sym_Ref {targ_Ref} + * | 14 COMPOUNDtpe len_Nat classsym_Ref {tpe_Ref} + * | 15 METHODtpe len_Nat tpe_Ref {tpe_Ref} + * | 16 POLYTtpe len_Nat tpe_Ref {sym_Ref} + * | 17 OVERLOADEDtpe len_Nat {sym_Ref} {tpe_Ref} + * | 20 FLAGGEDtype len_Nat flags_Nat tpe_Ref * SymbolInfo = name_Ref owner_Ref flags_Nat info_Ref * NameInfo = * Ref = Nat @@ -40,27 +39,26 @@ public interface EntryTags { */ int TERMname = 1, - CONSTRname = 2, - TYPEname = 3, - NONEsym = 4, - TYPEsym = 5, - ALIASsym = 6, - CLASSsym = 7, - VALsym = 8, - EXTsym = 9, - EXTMODCLASSsym = 10, - NOtpe = 11, - THIStpe = 12, - SINGLEtpe = 13, - TYPEREFtpe = 14, - COMPOUNDtpe = 15, - METHODtpe = 16, - POLYtpe = 17, - OVERLOADEDtpe = 18, - UNBOXEDtpe = 19, - UNBOXEDARRAYtpe = 20, - FLAGGEDtpe = 21, - ERRORtpe = 22; + TYPEname = 2, + NONEsym = 3, + TYPEsym = 4, + ALIASsym = 5, + CLASSsym = 6, + VALsym = 7, + TERMref = 8, + TYPEref = 9, + NOtpe = 10, + THIStpe = 11, + SINGLEtpe = 12, + TYPEREFtpe = 13, + COMPOUNDtpe = 14, + METHODtpe = 15, + POLYtpe = 16, + OVERLOADEDtpe = 17, + UNBOXEDtpe = 18, + UNBOXEDARRAYtpe = 19, + FLAGGEDtpe = 20, + ERRORtpe = 21; int firstSymTag = NONEsym, lastSymTag = VALsym; int firstTypeTag = NOtpe, lastTypeTag = FLAGGEDtpe; diff --git a/sources/scalac/symtab/Scope.java b/sources/scalac/symtab/Scope.java index 477144cd3a..c9daf10c5a 100644 --- a/sources/scalac/symtab/Scope.java +++ b/sources/scalac/symtab/Scope.java @@ -79,7 +79,7 @@ public class Scope { */ public final Scope owner; - Entry(Symbol sym, Scope owner) { + public Entry(Symbol sym, Scope owner) { this.sym = sym; this.owner = owner; this.next = owner.elems; @@ -173,7 +173,7 @@ public class Scope { return s; } - private Scope enter(Entry e) { + public Scope enter(Entry e) { elems = e; elemsCache = null; if (hashtable != null) { @@ -189,6 +189,7 @@ public class Scope { /** enter a symbol */ public Scope enter(Symbol sym) { + assert !sym.isConstructor(); return enter(new Entry(sym, this)); } diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index 0044beeb2c..585bc5de95 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -119,7 +119,10 @@ public abstract class Symbol implements Modifiers, Kinds { assert symbol != Symbol.NONE; assert symbol != Symbol.ERROR; if (symbol.isModule()) setOwner(symbol.moduleClass(), owner); - if (symbol.isClass()) setOwner(symbol.constructor(), owner); + if (symbol.isClass()) { + Symbol[] alts = symbol.allConstructors().alternativeSymbols(); + for (int i = 0; i < alts.length; i++) setOwner(alts[i], owner); + } symbol.owner = owner; } @@ -132,19 +135,22 @@ public abstract class Symbol implements Modifiers, Kinds { public Symbol setInfo(Type info, int limit) { assert !isConstructor() || info instanceof Type.LazyType + || info == Type.NoType || info == Type.ErrorType || info instanceof Type.MethodType || info instanceof Type.OverloadedType || info instanceof Type.PolyType && ((Type.PolyType)info).result instanceof Type.MethodType : "illegal type for " + this + ": " + info; - if ((flags & (INITIALIZED | LOCKED)) != (INITIALIZED | LOCKED)) { + //if ((flags & (INITIALIZED | LOCKED)) != (INITIALIZED | LOCKED)) { if (infos == TypeIntervalList.EMPTY) { infos = new TypeIntervalList(TypeIntervalList.EMPTY); } infos.limit = limit; infos.info = info; - } + if (info instanceof Type.LazyType) flags &= ~INITIALIZED; + else flags |= INITIALIZED; + //} return this; } @@ -173,12 +179,14 @@ public abstract class Symbol implements Modifiers, Kinds { throw new ApplicationError("setLoBound inapplicable for " + this); } -// Symbol classification ---------------------------------------------------- - - public final boolean isDefined() { - return !(rawInfoAt(FIRST_ID) instanceof Type.LazyType); + /** Add an auxiliary constructor to class; return created symbol. + */ + public Symbol addConstructor() { + throw new ApplicationError("addConstructor inapplicable for " + this); } +// Symbol classification ---------------------------------------------------- + /** Does this symbol denote a type? */ public final boolean isType() { return kind == TYPE || kind == CLASS || kind == ALIAS; @@ -377,13 +385,13 @@ public abstract class Symbol implements Modifiers, Kinds { } /** Is this symbol a constructor? */ - public final boolean isConstructor() { - return name.isConstrName(); + public boolean isConstructor() { + return false; } /** Is this symbol the primary constructor of a type? */ public final boolean isPrimaryConstructor() { - return isConstructor() && this == primaryConstructorClass().constructor(); + return isConstructor() && this == primaryConstructorClass().primaryConstructor(); } public boolean isGenerated() { @@ -451,8 +459,13 @@ public abstract class Symbol implements Modifiers, Kinds { return EMPTY_ARRAY; } + /** Get all constructors of class */ + public Symbol allConstructors() { + return NONE; + } + /** Get primary constructor of class */ - public Symbol constructor() { + public Symbol primaryConstructor() { return NONE; } @@ -474,7 +487,7 @@ public abstract class Symbol implements Modifiers, Kinds { public Symbol classOwner() { Symbol owner = owner(); Symbol clazz = owner.primaryConstructorClass(); - if (clazz.constructor() == owner) return clazz; + if (clazz.primaryConstructor() == owner) return clazz; else return owner; } @@ -501,6 +514,19 @@ public abstract class Symbol implements Modifiers, Kinds { return this; } + /** Return first alternative if this has a (possibly lazy) + * overloaded type, otherwise symbol itself. + * Needed only in ClassSymbol.primaryConstructor() + */ + Symbol firstAlternative() { + if (infos.info instanceof Type.OverloadedType) + return infos.info.alternativeSymbols()[0]; + else if (infos.info instanceof LazyOverloadedType) + return ((LazyOverloadedType) infos.info).sym1.firstAlternative(); + else + return this; + } + /* If this is a module, return its class. * Otherwise return the symbol itself. */ @@ -508,6 +534,22 @@ public abstract class Symbol implements Modifiers, Kinds { return this; } + /** if type is a (possibly lazy) overloaded type, return its alternatves + * else return array consisting of symbol itself + */ + public Symbol[] alternativeSymbols() { + Symbol[] alts = type().alternativeSymbols(); + if (alts.length == 0) return new Symbol[]{this}; + else return alts; + } + + /** if type is a (possibly lazy) overloaded type, return its alternatves + * else return array consisting of type itself + */ + public Type[] alternativeTypes() { + return type().alternativeTypes(); + } + /** The symbol accessed by this accessor function. */ public Symbol accessed() { @@ -598,7 +640,7 @@ public abstract class Symbol implements Modifiers, Kinds { flags &= ~SNDTIME; } else { assert !(rawInfoAt(id) instanceof Type.LazyType) : this; - flags |= INITIALIZED; + //flags |= INITIALIZED; } //System.out.println("done: " + this.name);//DEBUG } @@ -624,8 +666,8 @@ public abstract class Symbol implements Modifiers, Kinds { /** get info at phase #id, without forcing lazy types. */ public Type rawInfoAt(int id) { - int nextid = infos.limit; assert infos != TypeIntervalList.EMPTY : this; + int nextid = infos.limit; if (nextid < id) { PhaseDescriptor curphase = Global.instance.currentPhase; do { @@ -868,59 +910,43 @@ public abstract class Symbol implements Modifiers, Kinds { /** A lazy type which, when forced computed the overloaded type * of symbols `sym1' and `sym2'. It also checks that this type is well-formed. */ - private static class LazyOverloadedType extends Type.LazyType { + public static class LazyOverloadedType extends Type.LazyType { Symbol sym1; Symbol sym2; LazyOverloadedType(Symbol sym1, Symbol sym2) { this.sym1 = sym1; this.sym2 = sym2; } - private Symbol[] alts(Symbol sym) { - if (sym == null) return Symbol.EMPTY_ARRAY; - switch (sym.type()) { - case OverloadedType(Symbol[] alts, _): return alts; - default: return new Symbol[]{sym}; - } - } - private Type[] alttypes(Symbol sym) { - if (sym == null) return Type.EMPTY_ARRAY; - switch (sym.type()) { - case OverloadedType(_, Type[] alttypes): return alttypes; - default: return new Type[]{sym.type()}; - } - } - public void complete(Symbol overloaded) { - if (sym1 != null) sym1.initialize(); - if (sym2 != null) sym2.initialize(); - Symbol[] alts1 = alts(sym1); - Symbol[] alts2 = alts(sym2); + public Symbol[] alternativeSymbols() { + Symbol[] alts1 = sym1.alternativeSymbols(); + Symbol[] alts2 = sym2.alternativeSymbols(); Symbol[] alts3 = new Symbol[alts1.length + alts2.length]; System.arraycopy(alts1, 0, alts3, 0, alts1.length); System.arraycopy(alts2, 0, alts3, alts1.length, alts2.length); + return alts3; + } + + public Type[] alternativeTypes() { + Type[] alts1 = sym1.alternativeTypes(); + Type[] alts2 = sym2.alternativeTypes(); + Type[] alts3 = new Type[alts1.length + alts2.length]; + System.arraycopy(alts1, 0, alts3, 0, alts1.length); + System.arraycopy(alts2, 0, alts3, alts1.length, alts2.length); + return alts3; + } - Type[] alttypes1 = alttypes(sym1); - Type[] alttypes2 = alttypes(sym2); - Type[] alttypes3 = new Type[alttypes1.length + alttypes2.length]; - System.arraycopy(alttypes1, 0, alttypes3, 0, alttypes1.length); - System.arraycopy(alttypes2, 0, alttypes3, alttypes1.length, alttypes2.length); - overloaded.setInfo(Type.OverloadedType(alts3, alttypes3)); + public void complete(Symbol overloaded) { + overloaded.setInfo( + Type.OverloadedType( + alternativeSymbols(), alternativeTypes())); } + public String toString() { return "LazyOverloadedType(" + sym1 + "," + sym2 + ")"; } } - /** All the alternatives of this symbol if it's overloaded, the - * symbol alone otherwise. - */ - public Symbol[] alternatives() { - switch (type()) { - case OverloadedType(Symbol[] alts, _): return alts; - default: return new Symbol[]{this}; - } - } - /** The symbol which is overridden by this symbol in base class `base' * `base' must be a superclass of this.owner(). */ @@ -985,8 +1011,7 @@ public class TermSymbol extends Symbol { public static TermSymbol newConstructor(Symbol clazz, int flags) { TermSymbol sym = new TermSymbol( - clazz.pos, clazz.name.toConstrName(), clazz.owner(), - flags | FINAL); + clazz.pos, clazz.name, clazz.owner(), flags | FINAL); sym.clazz = clazz; return sym; } @@ -1008,7 +1033,7 @@ public class TermSymbol extends Symbol { int flags) { ClassSymbol clazz = new ClassSymbol( pos, name.toTypeName(), owner, flags | MODUL | FINAL); - clazz.constructor().setInfo( + clazz.primaryConstructor().setInfo( Type.MethodType(Symbol.EMPTY_ARRAY, clazz.typeConstructor())); return newModule(pos, name, owner, flags, clazz); @@ -1044,6 +1069,11 @@ public class TermSymbol extends Symbol { else return super.fullName(); } + /** Is this symbol a constructor? */ + public boolean isConstructor() { + return name.isTypeName(); + } + /** Return a fresh symbol with the same fields as this one. */ public Symbol cloneSymbol(Symbol owner) { @@ -1129,6 +1159,16 @@ public class TypeSymbol extends Symbol { return type().unalias().typeParams(); } + /** Get all constructors of class */ + public Symbol allConstructors() { + return type().unalias().symbol().allConstructors(); + } + + /** Get primary constructor of class */ + public Symbol primaryConstructor() { + return type().unalias().symbol().primaryConstructor(); + } + public Type[] closure() { if (kind == ALIAS) return info().symbol().closure(); int id = currentPhaseId(); @@ -1257,6 +1297,16 @@ public class AbsTypeSymbol extends TypeSymbol { return Symbol.EMPTY_ARRAY; } + /** Get all constructors of class */ + public Symbol allConstructors() { + return Symbol.NONE; + } + + /** Get primary constructor of class */ + public Symbol primaryConstructor() { + return Symbol.NONE; + } + public Type loBound() { initialize(); return lobound == null ? Global.instance.definitions.ALL_TYPE : lobound; @@ -1279,7 +1329,7 @@ public class ClassSymbol extends TypeSymbol { private Type template; /** The primary constructor of this type */ - public final Symbol constructor; + private Symbol constructor; /** The module belonging to the class. This means: * For Java classes, its statics parts. @@ -1328,27 +1378,38 @@ public class ClassSymbol extends TypeSymbol { ClassSymbol other = new ClassSymbol(pos, name, owner, flags); other.module = module; other.setInfo(info()); - other.constructor.setInfo( - fixClonedConstrType( - constructor.info().cloneType(constructor, other.constructor), - other)); + other.primaryConstructor().setInfo( + fixConstrType( + primaryConstructor().info().cloneType( + primaryConstructor(), other.primaryConstructor()), + other)); + Symbol[] alts = allConstructors().alternativeSymbols(); + for (int i = 1; i < alts.length; i++) { + Symbol constr = other.addConstructor(); + constr.setInfo( + fixConstrType( + alts[i].info().cloneType(alts[i], constr), + other)); + } other.mangled = mangled; if (thisSym != this) other.setTypeOfThis(typeOfThis()); return other; } - private Type fixClonedConstrType(Type type, Symbol clone) { + private Type fixConstrType(Type type, Symbol clone) { switch (type) { case MethodType(Symbol[] vparams, Type result): - result = fixClonedConstrType(result, clone); + result = fixConstrType(result, clone); return new Type.MethodType(vparams, result); case PolyType(Symbol[] tparams, Type result): - result = fixClonedConstrType(result, clone); + result = fixConstrType(result, clone); return new Type.PolyType(tparams, result); case TypeRef(Type pre, Symbol sym, Type[] args): assert sym == this : Debug.show(sym) + " != " + Debug.show(this); return new Type.TypeRef(pre, clone, args); + case LazyType(): + return type; default: - throw Debug.abort("unexpected constructor type"); + throw Debug.abort("unexpected constructor type:" + clone + ":" + type); } } @@ -1356,6 +1417,9 @@ public class ClassSymbol extends TypeSymbol { */ public void copyTo(Symbol sym) { super.copyTo(sym); + Symbol symconstr = ((ClassSymbol) sym).constructor; + constructor.copyTo(symconstr); + symconstr.setInfo(fixConstrType(symconstr.rawInfo(), sym)); if (thisSym != this) sym.setTypeOfThis(typeOfThis()); } @@ -1404,21 +1468,11 @@ public class ClassSymbol extends TypeSymbol { /** Get type parameters */ public Symbol[] typeParams() { - // !!! For some Java classes, constructor() returns an - // Overloaded symbol. This is wrong as constructor() should - // return the primary constructor. Once this problem is - // solved, the following switch can be removed. - Type constrtype = constructor.info(); - switch (constrtype) { - case OverloadedType(_, _): - return Symbol.EMPTY_ARRAY; - default: - return constrtype.typeParams(); - } + return primaryConstructor().info().typeParams(); } public Symbol[] valueParams() { - return constructor.info().valueParams(); + return primaryConstructor().info().valueParams(); } /** Get type */ @@ -1453,9 +1507,22 @@ public class ClassSymbol extends TypeSymbol { return this; } + /** add a constructor + */ + public Symbol addConstructor() { + Symbol constr = TermSymbol.newConstructor(this, flags & ~MODUL); + constructor = constructor.overloadWith(constr); + return constr; + } + /** Get primary constructor */ - public Symbol constructor() { - return constructor; + public Symbol primaryConstructor() { + return constructor.firstAlternative(); + } + + /** Get all constructors */ + public Symbol allConstructors() { + return constructor; } /** Return the next enclosing class */ @@ -1479,7 +1546,6 @@ public class ClassSymbol extends TypeSymbol { public void reset(Type completer) { super.reset(completer); - constructor().reset(completer); module().reset(completer); template = null; thisSym = this; @@ -1520,7 +1586,7 @@ public final class ErrorSymbol extends Symbol { } /** Get primary constructor */ - public Symbol constructor() { + public Symbol primaryConstructor() { return TermSymbol.newConstructor(this, 0).setInfo(Type.ErrorType); } diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 7dcf109456..7b27647e22 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -53,6 +53,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { */ public case TypeRef(Type pre, Symbol sym, Type[] args) { assert pre.isLegalPrefix() || pre == ErrorType : pre + "#" + sym; + assert sym.kind == ERROR || sym.isType() : pre + "#" + sym; } /** parts_1 with ... with parts_n { members } @@ -159,7 +160,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { Position.NOPOS, Names.COMPOUND_NAME.toTypeName(), Symbol.NONE, SYNTHETIC | ABSTRACTCLASS); res.tsym.setInfo(res); - res.tsym.constructor().setInfo( + res.tsym.primaryConstructor().setInfo( Type.MethodType(Symbol.EMPTY_ARRAY, Type.NoType)); return res; } @@ -419,7 +420,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { if (sym.kind == ALIAS) return unalias().parents(); else if (sym.kind == CLASS) { - assert sym.typeParams().length == args.length : sym + " " + ArrayApply.toString(args);//debug + assert sym.typeParams().length == args.length : sym + " " + ArrayApply.toString(args) + " " + sym.primaryConstructor().info();//debug return subst(asSeenFrom(sym.info().parents(), pre, sym.owner()), sym.typeParams(), args); } else @@ -508,7 +509,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { /** If this type is overloaded, its alternative types, * otherwise an array consisting of this type itself. */ - public Type[] alternatives() { + public Type[] alternativeTypes() { switch (this) { case OverloadedType(_, Type[] alttypes): return alttypes; @@ -517,6 +518,18 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } } + /** If this type is overloaded, its alternative symbols, + * otherwise an empty array. + */ + public Symbol[] alternativeSymbols() { + switch (this) { + case OverloadedType(Symbol[] alts, _): + return alts; + default: + return Symbol.EMPTY_ARRAY; + } + } + /** If type is a this type of a module class, transform to singletype of * module. */ @@ -2440,7 +2453,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { else return sym.typeConstructor(); } - default: throw new ApplicationError(); + default: throw new ApplicationError(sym + " has wrong kind: " + sym.kind); } case CompoundType(Type[] parents, _): if (parents.length > 0) return parents[0].erasure(); diff --git a/sources/scalac/symtab/classfile/AttributeParser.java b/sources/scalac/symtab/classfile/AttributeParser.java index fe2264f594..4df2529b2d 100644 --- a/sources/scalac/symtab/classfile/AttributeParser.java +++ b/sources/scalac/symtab/classfile/AttributeParser.java @@ -150,7 +150,9 @@ public class AttributeParser implements ClassfileConstants { case META_ATTR: //System.out.println("parsing meta data for " + sym); String meta = pool.readPool(in.nextChar()).toString().trim(); - sym.setInfo(new MetaParser(meta, tvars, sym, type).parse(), parser.phaseId); + sym.setInfo( + new MetaParser(meta, tvars, sym, type).parse(), + Symbol.FIRST_ID); return; } throw new RuntimeException("unknown classfile attribute"); @@ -176,7 +178,7 @@ public class AttributeParser implements ClassfileConstants { } private Symbol getTVar(String name) { - return getTVar(name, parser.c.constructor()); + return getTVar(name, parser.c.primaryConstructor()); } private Symbol getTVar(String name, Symbol owner) { @@ -195,7 +197,7 @@ public class AttributeParser implements ClassfileConstants { Name.fromString(token).toTypeName(), owner, Modifiers.PARAM); - s.setInfo(parser.defs.ANY_TYPE, parser.phaseId); + s.setInfo(parser.defs.ANY_TYPE, Symbol.FIRST_ID); tvars.enter(s); return s; } else @@ -251,7 +253,7 @@ public class AttributeParser implements ClassfileConstants { //System.out.println("new var " + s + ", " + token);//DEBUG if (token.equals("<")) { nextToken(); - s.setInfo(parseType(), parser.phaseId); + s.setInfo(parseType(), Symbol.FIRST_ID); } syms.add(s); } while (token.equals(",")); @@ -259,36 +261,19 @@ public class AttributeParser implements ClassfileConstants { nextToken(); Symbol[] smbls = (Symbol[])syms.toArray(new Symbol[syms.size()]); //System.out.println("*** " + syms);//DEBUG - Type constrtype = Type.appliedType( - parser.ctype, Symbol.type(smbls)); - - if ((parser.c.flags & Modifiers.INTERFACE) != 0) { - parser.c.constructor().setInfo( - Type.PolyType( - smbls, Type.MethodType(Symbol.EMPTY_ARRAY, constrtype)), - parser.phaseId); - //System.out.println("info = " + parser.c.constructor().info());//DEBUG - } - Symbol[] constrs; - switch (parser.c.constructor().rawInfo()) { - case OverloadedType(Symbol[] alts, _): - constrs = alts; - break; - default: - constrs = new Symbol[]{parser.c.constructor()}; - } - for (int i = 0; i < constrs.length; i++) { - //System.out.println("info = " + e.sym.info()); - switch (constrs[i].rawInfo()) { - case MethodType(Symbol[] vparams, _): - constrs[i].setInfo( - Type.PolyType( - smbls, Type.MethodType(vparams, constrtype)), - parser.phaseId); - break; - } - //System.out.println("*** constructor " + e.sym + ": " + e.sym.info());//DEBUG - } + Type clazztype = Type.appliedType( + parser.ctype, Symbol.type(smbls)); + Symbol constr = parser.c.primaryConstructor(); + switch (constr.rawInfo()) { + case MethodType(Symbol[] vparams, _): + constr.setInfo( + Type.PolyType( + smbls, Type.MethodType(vparams, clazztype)), + Symbol.FIRST_ID); + break; + default: + throw new ApplicationError(constr.rawInfo()); + } } catch (NoSuchElementException e) { } } @@ -352,12 +337,12 @@ public class AttributeParser implements ClassfileConstants { Name.fromString(token).toTypeName(), owner, Modifiers.PARAM); - s.setInfo(parser.defs.ANY_TYPE, parser.phaseId); + s.setInfo(parser.defs.ANY_TYPE, Symbol.FIRST_ID); locals.enter(s); nextToken(); if (token.equals("<")) { nextToken(); - s.setInfo(parseType(), parser.phaseId); + s.setInfo(parseType(), Symbol.FIRST_ID); } syms.add(s); } while (token.equals(",")); @@ -381,7 +366,7 @@ public class AttributeParser implements ClassfileConstants { Position.NOPOS, Name.fromString("x" + (i++)), owner, - flags).setInfo(parseType(), parser.phaseId)); + flags).setInfo(parseType(), Symbol.FIRST_ID)); //System.out.println(" + " + token); } while (token.equals(",")); assert ")".equals(token); @@ -434,7 +419,7 @@ public class AttributeParser implements ClassfileConstants { Position.NOPOS, Name.fromString("x" + (i++)), owner, - Modifiers.PARAM).setInfo(parseType(), parser.phaseId)); + Modifiers.PARAM).setInfo(parseType(), Symbol.FIRST_ID)); //System.out.println(" + " + token); } while (token.equals(",")); assert ")".equals(token); diff --git a/sources/scalac/symtab/classfile/ClassfileParser.java b/sources/scalac/symtab/classfile/ClassfileParser.java index 2272b6dc21..098be96b06 100644 --- a/sources/scalac/symtab/classfile/ClassfileParser.java +++ b/sources/scalac/symtab/classfile/ClassfileParser.java @@ -41,7 +41,6 @@ public class ClassfileParser implements ClassfileConstants { protected Type ctype; protected Scope locals; protected Scope statics; - protected Scope constr; protected JavaTypeFactory make; protected Signatures sigs; protected ConstantPool pool; @@ -93,16 +92,16 @@ public class ClassfileParser implements ClassfileConstants { Type[] basetpes = new Type[in.nextChar() + 1]; this.locals = new Scope(); this.statics = new Scope(); - this.constr = new Scope(); // set type of class Type classType = Type.compoundType(basetpes, locals, c); - c.setInfo(classType, phaseId); + c.setInfo(classType, Symbol.FIRST_ID); // set type of statics Symbol staticsClass = c.module().moduleClass(); Type staticsInfo = Type.compoundType(Type.EMPTY_ARRAY, statics, staticsClass); - staticsClass.setInfo(staticsInfo, phaseId); + staticsClass.setInfo(staticsInfo, Symbol.FIRST_ID); c.module().setInfo(Type.TypeRef(staticsClass.owner().thisType(), staticsClass, Type.EMPTY_ARRAY)); + basetpes[0] = supertpe; for (int i = 1; i < basetpes.length; i++) basetpes[i] = readClassType(in.nextChar()); @@ -112,16 +111,14 @@ public class ClassfileParser implements ClassfileConstants { int methodCount = in.nextChar(); for (int i = 0; i < methodCount; i++) parseMethod(); - // set constructor type to the declared type - Symbol[] constrs = constr.elements(); - if (constrs.length != 0) { - assert constrs.length == 1; - c.constructor().setInfo(constrs[0].info(), phaseId); - } else { - Symbol[] cparams = ((c.flags & Modifiers.INTERFACE) != 0) ? Symbol.EMPTY_ARRAY - : new Symbol[]{Symbol.NONE}; - c.constructor().setInfo(Type.MethodType(cparams, ctype), phaseId); - } + + Symbol constr = c.primaryConstructor(); + if (!constr.isInitialized()) { + constr.setInfo( + Type.MethodType(Symbol.EMPTY_ARRAY, ctype), Symbol.FIRST_ID); + if ((c.flags & Modifiers.INTERFACE) == 0) + constr.flags |= Modifiers.PRIVATE; + } attrib.readAttributes(c, classType, CLASS_ATTR); //System.out.println("dynamic class: " + c); //System.out.println("statics class: " + staticsClass); @@ -188,7 +185,7 @@ public class ClassfileParser implements ClassfileConstants { if ((flags & 0x0008) != 0) owner = c.module().moduleClass(); Symbol s = new TermSymbol(Position.NOPOS, name, owner, mods); - s.setInfo(type, phaseId); + s.setInfo(type, Symbol.FIRST_ID); attrib.readAttributes(s, type, FIELD_ATTR); ((flags & 0x0008) != 0 ? statics : locals).enterOrOverload(s); } @@ -215,16 +212,19 @@ public class ClassfileParser implements ClassfileConstants { default: throw new ApplicationError(); } - s.setInfo(type, phaseId); + s.setInfo(type, Symbol.FIRST_ID); attrib.readAttributes(s, type, METH_ATTR); + Symbol constr = c.primaryConstructor(); + if (constr.isInitialized()) constr = c.addConstructor(); + s.copyTo(constr); + //System.out.println(c + " " + c.allConstructors() + ":" + c.allConstructors().info());//debug //System.out.println("-- enter " + s); - constr.enterOrOverload(s); } else { Symbol s = new TermSymbol( Position.NOPOS, name, ((flags & 0x0008) != 0) ? c.module().moduleClass() : c, transFlags(flags)); - s.setInfo(type, phaseId); + s.setInfo(type, Symbol.FIRST_ID); attrib.readAttributes(s, type, METH_ATTR); ((flags & 0x0008) != 0 ? statics : locals).enterOrOverload(s); } diff --git a/sources/scalac/symtab/classfile/PackageParser.java b/sources/scalac/symtab/classfile/PackageParser.java index 80191c79ba..e523bc4dbb 100644 --- a/sources/scalac/symtab/classfile/PackageParser.java +++ b/sources/scalac/symtab/classfile/PackageParser.java @@ -77,11 +77,11 @@ public class PackageParser extends Type.LazyType { .toTypeName(); if (locals.lookup(n) == Symbol.NONE) { ClassSymbol clazz = new ClassSymbol(n, p, classCompletion); - clazz.constructor().setInfo( + // todo: needed? + clazz.allConstructors().setInfo( classCompletion.staticsParser(clazz)); // enter class locals.enter(clazz); - locals.enter(clazz.constructor()); // enter module, except for scala.Object class // todo: why not there also?. if (!(n == Names.Object.toTypeName() && @@ -110,10 +110,10 @@ public class PackageParser extends Type.LazyType { sym.rawInfoAt(Symbol.FIRST_ID) instanceof ClassParser && !(sym.rawInfoAt(Symbol.FIRST_ID) instanceof SymblParser)) { ClassSymbol clazz = new ClassSymbol(n, p, symblCompletion); - clazz.constructor().setInfo(symblCompletion); + //todo: needed + clazz.allConstructors().setInfo(symblCompletion); clazz.module().setInfo(symblCompletion); locals.enter(clazz); - locals.enter(clazz.constructor()); locals.enter(clazz.module()); } } else if (inclClasses && fname.endsWith(".scala")) { @@ -126,11 +126,11 @@ public class PackageParser extends Type.LazyType { SourceCompleter completer = new SourceCompleter(global, dir.getPath() + File.separatorChar + fname); ClassSymbol clazz = new ClassSymbol(n, p, completer); - clazz.constructor().setInfo(completer); + //todo: needed? + clazz.allConstructors().setInfo(completer); clazz.module().setInfo(completer); // enter class locals.enter(clazz); - locals.enter(clazz.constructor()); locals.enter(clazz.module()); } } diff --git a/sources/scalac/symtab/classfile/Pickle.java b/sources/scalac/symtab/classfile/Pickle.java index 83d9851405..ded41362ea 100644 --- a/sources/scalac/symtab/classfile/Pickle.java +++ b/sources/scalac/symtab/classfile/Pickle.java @@ -143,45 +143,38 @@ public class Pickle implements Kinds, Modifiers, EntryTags { * another symbol. */ private void putSymbol(Symbol sym) { - switch (sym.info()) { - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) - putSymbol(alts[i]); - break; - default: - if (putEntry(sym)) { - //System.out.println("put sym " + sym);//DEBUG - if (isLocal(sym)) { - putEntry(sym.name); - putSymbol(sym.owner()); - putType(sym.info()); - switch (sym.kind) { - case TYPE: - putType(sym.loBound()); - break; - case ALIAS: - break; - case CLASS: - putType(sym.typeOfThis()); - putSymbol(sym.constructor()); - for (Scope.SymbolIterator it = sym.members().iterator(); - it.hasNext();) - putSymbol(it.next()); - break; - case VAL: - if (sym.isPrimaryConstructor()) - putSymbol(sym.primaryConstructorClass()); - else if (sym.isModule()) - putSymbol(sym.moduleClass()); - break; - default: - throw new ApplicationError(); - } - } else if (sym.kind != NONE) { - putEntry(sym.name); - if (sym.owner() != Global.instance.definitions.ROOT_CLASS) - putSymbol(sym.owner()); + if (putEntry(sym)) { + //System.out.println("put sym " + sym);//DEBUG + if (isLocal(sym)) { + putEntry(sym.name); + putSymbol(sym.owner()); + putType(sym.info()); + switch (sym.kind) { + case TYPE: + putType(sym.loBound()); + break; + case ALIAS: + break; + case CLASS: + putType(sym.typeOfThis()); + putSymbol(sym.allConstructors()); + for (Scope.SymbolIterator it = sym.members().iterator(); + it.hasNext();) + putSymbol(it.next()); + break; + case VAL: + if (sym.isPrimaryConstructor()) + putSymbol(sym.primaryConstructorClass()); + else if (sym.isModule()) + putSymbol(sym.moduleClass()); + break; + default: + throw new ApplicationError(); } + } else if (sym.kind != NONE) { + putEntry(sym.name); + if (sym.owner() != Global.instance.definitions.ROOT_CLASS) + putSymbol(sym.owner()); } } } @@ -229,7 +222,8 @@ public class Pickle implements Kinds, Modifiers, EntryTags { putSymbols(tparams); break; case OverloadedType(Symbol[] alts, Type[] alttypes): - assert false : tp; + for (int i = 0; i < alts.length; i++) + putSymbol(alts[i]); break; default: throw new ApplicationError(); @@ -308,7 +302,6 @@ public class Pickle implements Kinds, Modifiers, EntryTags { */ private void writeName(Name name) { if (name.isTermName()) writeByte(TERMname); - else if (name.isConstrName()) writeByte(CONSTRname); else writeByte(TYPEname); writeByte(0); // space for length while (bp + name.length() > bytes.length) resizeTo(bytes.length * 2); @@ -350,7 +343,7 @@ public class Pickle implements Kinds, Modifiers, EntryTags { break; case CLASS: writeRef(sym.typeOfThis()); - writeRef(sym.constructor()); + writeRef(sym.allConstructors()); break; case VAL: if (sym.isPrimaryConstructor()) @@ -363,8 +356,7 @@ public class Pickle implements Kinds, Modifiers, EntryTags { writeByte(NONEsym); writeByte(0); // space for length } else { - writeByte(((sym.flags & (MODUL | PACKAGE)) == MODUL) - ? EXTMODCLASSsym : EXTsym); + writeByte((sym.isTerm() || sym.isModuleClass()) ? TERMref : TYPEref); writeByte(0); // space for length writeRef(sym.name); if (sym.owner() != Global.instance.definitions.ROOT_CLASS) diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java index a0cc7eda31..ccc4fcf2fe 100644 --- a/sources/scalac/symtab/classfile/UnPickle.java +++ b/sources/scalac/symtab/classfile/UnPickle.java @@ -49,7 +49,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { if (global.debug) global.log( "unpickle " + root + " " + classroot + " " + moduleroot + " " + - moduleroot.moduleClass() + moduleroot.moduleClass().constructor()); + moduleroot.moduleClass() + moduleroot.moduleClass().primaryConstructor()); this.bytes = data; this.bp = 0; this.sourceName = sourceName; @@ -69,7 +69,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { System.out.print(tag + " "); int len = readNat(); System.out.print(len + " "); - if (tag == TERMname || tag == TYPEname || tag == CONSTRname) + if (tag == TERMname || tag == TYPEname) System.out.print( SourceRepresentation.ascii2string(bytes, bp, len)); else @@ -141,7 +141,6 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { Name name = Name.fromAscii(bytes, bp, len); switch (tag) { case TERMname : entries[n] = name; break; - case CONSTRname: entries[n] = name.toConstrName(); break; case TYPEname : entries[n] = name.toTypeName(); break; default: throw new BadSignature(this); } @@ -156,25 +155,19 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { String decode(Name name) { if (name.isTypeName()) return "type " + NameTransformer.decode(name); - else if (name.isConstrName()) return "constructor " + NameTransformer.decode(name); else return "value " + NameTransformer.decode(name); } - Symbol extRef(Symbol owner, Name name, boolean modclass) { - if (name.length() == 0 && owner == Symbol.NONE) { - return Global.instance.definitions.ROOT_CLASS; - } else if (modclass) { - assert name.isTypeName() : name; - Symbol module = extRef(owner, name.toTermName(), false); - switch (module.type()) { - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) - if (alts[i].isModule()) module = alts[i]; - } - assert module.isModule(); - return module.moduleClass(); + void enterSymbol(Symbol sym) { + Symbol owner = sym.owner(); + Scope scope = owner.info().members(); + Symbol other = scope.lookup(sym.name); + if (other == Symbol.NONE) { + if (global.debug) + global.log("entering " + sym + ":" + sym.type() + " in " + owner);//debug + scope.enter(sym); } else { - return owner.info().lookup(name); + assert sym.rawInfo() instanceof Type.OverloadedType : sym; } } @@ -190,8 +183,8 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { case NONEsym: entries[n] = sym = Symbol.NONE; break; - case EXTsym: - case EXTMODCLASSsym: + case TERMref: + case TYPEref: Name name = readNameRef(); if (bp == end) { owner = Global.instance.definitions.ROOT_CLASS; @@ -199,7 +192,22 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { assert bp < end; owner = readSymbolRef(); } - entries[n] = sym = extRef(owner, name, tag == EXTMODCLASSsym); + if (name.length() == 0 && owner == Symbol.NONE) { + sym = Global.instance.definitions.ROOT_CLASS; + } else if (tag == TERMref && name.isTypeName()) { + Symbol module = owner.info().lookup(name.toTermName()); + switch (module.type()) { + case OverloadedType(Symbol[] alts, _): + for (int i = 0; i < alts.length; i++) + if (alts[i].isModule()) module = alts[i]; + } + assert module.isModule(); + sym = module.moduleClass(); + } else { + assert (tag == TYPEref) == name.isTypeName(); + sym = owner.info().lookup(name); + } + entries[n] = sym; if (sym.kind == NONE) { if (global.debug) global.log(owner.info().members().toString());//debug @@ -243,30 +251,30 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { } sym.setInfo(getType(inforef)); sym.setTypeOfThis(readTypeRef()); - Symbol constructor = readSymbolRef(); //will install itself! + Symbol constr = readSymbolRef(); + constr.copyTo(sym.allConstructors()); + if (sym.isCaseClass()) { + Symbol cf = new TermSymbol( + Position.NOPOS, name.toTermName(), + owner, flags | CASE); + cf.setInfo(setOwner(constr.type(), cf)); + if (name == classroot.name && owner == classroot.owner()) { + if (global.debug) + global.log("overwriting " + moduleroot);//debug + cf.copyTo(moduleroot); + cf = moduleroot; + } else { + enterSymbol(sym); + } + } break; case VALsym: - Symbol cf = Symbol.NONE; if (bp < end) { ClassSymbol clazz = (ClassSymbol) readSymbolRef(); - if (name.isConstrName()) { - entries[n] = sym = clazz.constructor(); - if (global.debug) - global.log("overwriting " + sym);//debug - TermSymbol.newConstructor(clazz, flags).copyTo(sym); - if (clazz.isCaseClass()) { - cf = new TermSymbol( - Position.NOPOS, name.toTermName(), owner, flags | CASE); - if (name.toTypeName() == classroot.name && owner == moduleroot.owner()) { - if (global.debug) - global.log("overwriting " + moduleroot);//debug - cf.copyTo(moduleroot); - cf = moduleroot; - } else { - owner.info().members().enterOrOverload(cf); - } - } + if (name.isTypeName()) { + entries[n] = sym = TermSymbol.newConstructor( + clazz, flags); } else { assert (flags & MODUL) != 0 : name; entries[n] = sym = TermSymbol.newModule( @@ -284,34 +292,20 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { } Type tp = getType(inforef); sym.setInfo(setOwner(tp, sym)); - if (cf.kind != NONE) cf.setInfo(setOwner(tp, cf)); break; default: throw new BadSignature(this); } - if (owner.kind == CLASS && !noEnter(sym)) { - if (global.debug) - global.log("entering " + sym + ":" + sym.type() + " in " + owner);//debug - owner.info().members().enterOrOverload(sym); - } + if (owner.kind == CLASS) + enterSymbol(sym); } } bp = savedBp; } return (Symbol) entries[n]; } - //where - private boolean noEnter(Symbol sym) { - return - sym == classroot || - sym == moduleroot || - sym.isModuleClass() || - sym.isPrimaryConstructor() && noEnter(sym.primaryConstructorClass()); - } - - Symbol readSymbolRef() { return getSymbol(readNat()); diff --git a/sources/scalac/transformer/AddAccessors.java b/sources/scalac/transformer/AddAccessors.java index 5628bdb3fe..3d3c5a9ba8 100644 --- a/sources/scalac/transformer/AddAccessors.java +++ b/sources/scalac/transformer/AddAccessors.java @@ -62,7 +62,6 @@ public class AddAccessors extends Transformer { Tree tpe, Tree.Template impl): { Symbol clsSym = tree.symbol(); - Symbol constrSym = clsSym.constructor(); LinkedList/**/ newBody = new LinkedList(Arrays.asList(transform(impl.body))); diff --git a/sources/scalac/transformer/AddConstructors.java b/sources/scalac/transformer/AddConstructors.java index bf7cd290c5..226b476dc5 100644 --- a/sources/scalac/transformer/AddConstructors.java +++ b/sources/scalac/transformer/AddConstructors.java @@ -122,7 +122,7 @@ public class AddConstructors extends Transformer { ArrayList constrBody2 = new ArrayList(); ArrayList classBody = new ArrayList(); Symbol constrSym = - getConstructor(treeSym.constructor(), paramSyms, treeSym); + getConstructor(treeSym.primaryConstructor(), paramSyms, treeSym); Scope classScope = new Scope(); classScope.enter(constrSym); @@ -216,9 +216,9 @@ public class AddConstructors extends Transformer { classBody.add(gen.DefDef(tree.pos, constrSym, constrTree)); // strip off the class constructor from parameters - switch (treeSym.constructor().info()) { + switch (treeSym.primaryConstructor().info()) { case MethodType(_, Type result): - treeSym.constructor(). + treeSym.primaryConstructor(). updateInfo(Type.MethodType(Symbol.EMPTY_ARRAY, result)); break; default : assert false; @@ -235,6 +235,7 @@ public class AddConstructors extends Transformer { Tree base = baseClasses[0]; switch (base) { case Apply(Tree fun, Tree[] args): + //System.out.println(tree + " new " + fun.symbol());//DEBUG return gen.New(copy.Apply (base, gen.Ident(base.pos, getConstructor(fun.symbol())), diff --git a/sources/scalac/transformer/AddInterfaces.java b/sources/scalac/transformer/AddInterfaces.java index 3d11c5b019..ec18661c8c 100644 --- a/sources/scalac/transformer/AddInterfaces.java +++ b/sources/scalac/transformer/AddInterfaces.java @@ -172,8 +172,8 @@ class AddInterfaces extends Transformer { // constructor, use the class constructor instead. Symbol clsSym = sym.primaryConstructorClass(); if (phase.needInterface(clsSym)) - return gen.Select(transform(qualifier), - phase.getClassSymbol(clsSym).constructor()); + return gen.Select(qualifier, + phase.getClassSymbol(clsSym).primaryConstructor()); else return super.transform(tree); } else { @@ -207,7 +207,7 @@ class AddInterfaces extends Transformer { // constructor, use the class constructor instead. Symbol clsSym = sym.primaryConstructorClass(); if (phase.needInterface(clsSym)) - return gen.Ident(phase.getClassSymbol(clsSym).constructor()); + return gen.Ident(phase.getClassSymbol(clsSym).primaryConstructor()); else return super.transform(tree); } else if (typeSubst != null) { @@ -228,7 +228,7 @@ class AddInterfaces extends Transformer { Map clsMap = new HashMap(); Symbol classSym = phase.getClassSymbol(ifaceSym); clsMap.put(ifaceSym, classSym); - clsMap.put(ifaceSym.constructor(), classSym.constructor()); + clsMap.put(ifaceSym.primaryConstructor(), classSym.primaryConstructor()); SymbolSubstTypeMap clsSubst = new SymbolSubstTypeMap(clsMap, Collections.EMPTY_MAP); diff --git a/sources/scalac/transformer/AddInterfacesPhase.java b/sources/scalac/transformer/AddInterfacesPhase.java index 18df3f4cee..77b9fdb5b2 100644 --- a/sources/scalac/transformer/AddInterfacesPhase.java +++ b/sources/scalac/transformer/AddInterfacesPhase.java @@ -40,8 +40,8 @@ public class AddInterfacesPhase extends PhaseDescriptor { } public Type transformInfo(Symbol sym, Type tp) { - if (sym.isConstructor()) { - Symbol clazz =sym.primaryConstructorClass(); + if (sym.isPrimaryConstructor()) { + Symbol clazz = sym.primaryConstructorClass(); if (clazz.isPackage() || !needInterface(clazz)) return tp; // The symbol is a constructor of a class which needs // an interface. All its value arguments have to be @@ -165,7 +165,6 @@ public class AddInterfacesPhase extends PhaseDescriptor { uniqueName(sym, buf); Name newName = Name.fromString(buf.toString()); if (sym.name.isTypeName()) return newName.toTypeName(); - else if (sym.name.isConstrName()) return newName.toConstrName(); else return newName; } @@ -192,7 +191,6 @@ public class AddInterfacesPhase extends PhaseDescriptor { protected Name className(Name ifaceName) { Name className = Name.fromString(ifaceName.toString() + CLASS_SUFFIX); if (ifaceName.isTypeName()) return className.toTypeName(); - else if (ifaceName.isConstrName()) return className.toConstrName(); else return className; } @@ -206,7 +204,7 @@ public class AddInterfacesPhase extends PhaseDescriptor { protected Symbol getClassSymbol(Symbol ifaceSym) { if (ifaceSym.isPrimaryConstructor()) return getClassSymbol(ifaceSym.primaryConstructorClass()) - .constructor(); + .primaryConstructor(); if (!needInterface(ifaceSym)) return ifaceSym; @@ -217,13 +215,13 @@ public class AddInterfacesPhase extends PhaseDescriptor { classSym.name = className(ifaceSym.name); classSym.flags &= ~Modifiers.INTERFACE; - Symbol ifaceConstrSym = ifaceSym.constructor(); - Symbol classConstrSym = classSym.constructor(); + Symbol ifaceConstrSym = ifaceSym.primaryConstructor(); + Symbol classConstrSym = classSym.primaryConstructor(); classConstrSym.name = className(ifaceConstrSym.name); Scope ifaceOwnerMembers = ifaceSym.owner().members(); ifaceOwnerMembers.enter(classSym); - ifaceOwnerMembers.enter(classConstrSym); + // ifaceOwnerMembers.enter(classConstrSym); Type.SubstThisMap thisTypeMap = new Type.SubstThisMap(ifaceSym, classSym); @@ -278,7 +276,7 @@ public class AddInterfacesPhase extends PhaseDescriptor { classMembersMap.put(ifaceMemberSym, classMemberSym); classMembers.enterOrOverload(classMemberSym); if (classMemberSym.isClass()) - classMembers.enterOrOverload(classMemberSym.constructor()); + classMembers.enterOrOverload(classMemberSym.primaryConstructor()); } // Give correct type to the class symbol by using class diff --git a/sources/scalac/transformer/ExpandMixins.java b/sources/scalac/transformer/ExpandMixins.java index dc4d9a04ef..57ab76a5e9 100644 --- a/sources/scalac/transformer/ExpandMixins.java +++ b/sources/scalac/transformer/ExpandMixins.java @@ -95,7 +95,7 @@ public class ClassExpander { switch (parents[i]) { case TypeRef(Type prefix, Symbol mixin, Type[] args): map.insertSymbol(mixin, clasz); - cloner.owners.put(mixin.constructor(), clasz); + cloner.owners.put(mixin.primaryConstructor(), clasz); inlineMixinTParams(type); Tree.Apply constr = (Tree.Apply)template.parents[i]; inlineMixinVParams(mixin.valueParams(), constr.args); diff --git a/sources/scalac/transformer/ExplicitOuterClasses.java b/sources/scalac/transformer/ExplicitOuterClasses.java index d60507288c..b71a063b5d 100644 --- a/sources/scalac/transformer/ExplicitOuterClasses.java +++ b/sources/scalac/transformer/ExplicitOuterClasses.java @@ -117,7 +117,7 @@ public class ExplicitOuterClasses extends Transformer { } else { // Add the outer parameter to the tree (it is added to // the type by transformInfo). - Symbol constSym = classSym.constructor(); + Symbol constSym = classSym.primaryConstructor(); Symbol outerSym = phase.outerSym(constSym); assert (outerSym.owner() == constSym) : outerSym; outerLinks.addFirst(outerSym); diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java index acfa0f9c49..099b26a46d 100644 --- a/sources/scalac/transformer/LambdaLift.java +++ b/sources/scalac/transformer/LambdaLift.java @@ -58,7 +58,7 @@ public class LambdaLift extends OwnerTransformer * otherwise current symbol itself */ static Symbol asFunction(Symbol sym) { - return sym.kind == CLASS ? sym.constructor() : sym; + return sym.kind == CLASS ? sym.primaryConstructor() : sym; } /** `asFunction' applied to the next enclosing function or class owner. @@ -174,7 +174,7 @@ public class LambdaLift extends OwnerTransformer Name newname = global.freshNameCreator.newName(sym.name); sym.name = newname; if (sym.kind == CLASS) - sym.constructor().name = newname.toConstrName(); + sym.primaryConstructor().name = newname.toTypeName(); } private Type.Map traverseTypeMap = new Type.Map() { @@ -327,9 +327,9 @@ public class LambdaLift extends OwnerTransformer ((ClassDef) tree).mods &= ~LIFTED; Tree tree1 = copy.ClassDef( tree, sym, - addTypeParams(transform(tparams, sym), newtparams(sym.constructor())), + addTypeParams(transform(tparams, sym), newtparams(sym.primaryConstructor())), new ValDef[][]{ - addParams(transform(vparams, sym)[0], newparams(sym.constructor()))}, + addParams(transform(vparams, sym)[0], newparams(sym.primaryConstructor()))}, transform(tpe, sym), transform(impl, sym)); liftedDefs.append(tree1); @@ -488,7 +488,7 @@ public class LambdaLift extends OwnerTransformer ((ClassDef) tree).mods |= LIFTED; Symbol sym = tree.symbol(); assert sym.isLocal() : sym; - liftSymbol(sym, ftvsParams(sym.constructor()), fvsParams(sym.constructor())); + liftSymbol(sym, ftvsParams(sym.primaryConstructor()), fvsParams(sym.primaryConstructor())); break; case DefDef(_, _, _, _, _, _): @@ -502,7 +502,7 @@ public class LambdaLift extends OwnerTransformer void liftSymbol(Symbol sym, Symbol[] newtparams, Symbol[] newparams) { Symbol enclClass = sym.owner().enclClass(); if (!sym.isPrimaryConstructor()) sym.setOwner(enclClass); - enclClass.members().enter(sym); + if (!sym.isConstructor()) enclClass.members().enter(sym); if (sym.isMethod()) { if (newtparams.length != 0 || newparams.length != 0) { sym.updateInfo( @@ -513,7 +513,7 @@ public class LambdaLift extends OwnerTransformer global.log(sym + " has now type " + sym.typeAt(descr.nextPhase)); } } else if (sym.kind == CLASS) { - liftSymbol(sym.constructor(), newtparams, newparams); + liftSymbol(sym.primaryConstructor(), newtparams, newparams); } else { throw new ApplicationError(); } @@ -609,7 +609,7 @@ public class LambdaLift extends OwnerTransformer gen.TypeApply( gen.mkRef( pos, - global.definitions.getClass(Names.scala_COLONCOLON).constructor()), + global.definitions.getClass(Names.scala_COLONCOLON).primaryConstructor()), new Tree[]{gen.mkType(pos, elemtpe)}), new Tree[]{hd, tl})); } diff --git a/sources/scalac/transformer/LambdaLiftPhase.java b/sources/scalac/transformer/LambdaLiftPhase.java index 563710cb51..a61011cfc9 100644 --- a/sources/scalac/transformer/LambdaLiftPhase.java +++ b/sources/scalac/transformer/LambdaLiftPhase.java @@ -85,14 +85,15 @@ public class LambdaLiftPhase extends PhaseDescriptor implements Kinds, Modifiers case TypeRef(Type pre, Symbol sym, Type[] targs): switch (pre) { case ThisType(_): - if (sym.kind == CLASS && sym.constructor().isUpdated(nextPhase)) { + if (sym.kind == CLASS && + sym.primaryConstructor().isUpdated(nextPhase)) { // !!! For some Java classes, // Symbol.constructor() returns an Overloaded // symbol. This is wrong as constructor() // should return the primary constructor. Once // this problem is solved, the following // switch can be removed. - Type constrtype = sym.constructor().infoAt(nextPhase); + Type constrtype = sym.primaryConstructor().infoAt(nextPhase); Symbol[] tparams; switch (constrtype) { case OverloadedType(_, _): diff --git a/sources/scalac/transformer/OwnerTransformer.java b/sources/scalac/transformer/OwnerTransformer.java index 66e68ff45b..587362e345 100644 --- a/sources/scalac/transformer/OwnerTransformer.java +++ b/sources/scalac/transformer/OwnerTransformer.java @@ -62,7 +62,7 @@ public class OwnerTransformer extends Transformer { public Template transform(Template templ, Symbol owner) { Symbol prevOwner = currentOwner; if (owner.kind == Kinds.CLASS) - currentOwner = owner.constructor(); + currentOwner = owner.primaryConstructor(); Tree[] parents1 = transform(templ.parents); currentOwner = owner; Tree[] body1 = transformTemplateStats(templ.body, templ.symbol()); @@ -99,8 +99,8 @@ public class OwnerTransformer extends Transformer { Symbol symbol = tree.symbol(); return copy.ClassDef( tree, symbol, - transform(tparams, symbol.constructor()), - transform(vparams, symbol.constructor()), + transform(tparams, symbol.primaryConstructor()), + transform(vparams, symbol.primaryConstructor()), transform(tpe), transform(impl, symbol)); diff --git a/sources/scalac/transformer/matching/AlgebraicMatcher.java b/sources/scalac/transformer/matching/AlgebraicMatcher.java index 67fc972798..aba3f9d90b 100644 --- a/sources/scalac/transformer/matching/AlgebraicMatcher.java +++ b/sources/scalac/transformer/matching/AlgebraicMatcher.java @@ -441,8 +441,8 @@ public class AlgebraicMatcher extends PatternTool { protected int nCaseComponents(Tree tree) { switch (tree) { case Apply(Tree fn, _): - Type tpe = typeOf(tree.type.symbol().constructor()); - //System.out.println("~~~ " + tree.type() + ", " + tree.type().symbol().constructor()); + Type tpe = typeOf(tree.type.symbol().primaryConstructor()); + //System.out.println("~~~ " + tree.type() + ", " + tree.type().symbol().primaryConstructor()); switch (tpe) { // I'm not sure if this is a good idea, but obviously, currently all case classes // without constructor arguments have type NoType diff --git a/sources/scalac/transformer/matching/PatternMatcher.java b/sources/scalac/transformer/matching/PatternMatcher.java index f3f52d8074..2420e361b3 100644 --- a/sources/scalac/transformer/matching/PatternMatcher.java +++ b/sources/scalac/transformer/matching/PatternMatcher.java @@ -589,8 +589,8 @@ public class PatternMatcher extends PatternTool { protected int nCaseComponents(Tree tree) { switch (tree) { case Apply(Tree fn, _): - Type tpe = typeOf(tree.type.symbol().constructor()); - //System.out.println("~~~ " + tree.type() + ", " + tree.type().symbol().constructor()); + Type tpe = typeOf(tree.type.symbol().primaryConstructor()); + //System.out.println("~~~ " + tree.type() + ", " + tree.type().symbol().primaryConstructor()); switch (tpe) { // I'm not sure if this is a good idea, but obviously, currently all case classes // without constructor arguments have type NoType diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index 5e4684b423..9976f447df 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -12,6 +12,8 @@ // todo: use mangled name or drop. // todo: emit warnings for unchecked. // todo: synchronize on module instantiation. +// todo: type select operator for superclass term access. + package scalac.typechecker; @@ -93,10 +95,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { enterUnit(unit); if (sym.rawInfoAt(Symbol.FIRST_ID) instanceof SourceCompleter) { sym.setInfo(Type.ErrorType); - String kind; - if (sym.name.isTermName()) kind = "object "; - else if (sym.name.isTypeName()) kind = "class "; - else kind = "constructor "; + String kind = (sym.name.isTermName()) ? "object " : "class "; throw new Type.Error("file " + unit.source + " does not define public " + kind + sym.fullName()); } else { @@ -201,30 +200,27 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { error(pos, msg); } - void reportTypeError(int pos, Type.Error ex) { + Tree reportTypeError(int pos, Type.Error ex) { if (ex instanceof CyclicReference) { if (global.debug) ex.printStackTrace(); CyclicReference cyc = (CyclicReference) ex; if (cyc.info instanceof LazyTreeType) { switch (((LazyTreeType) cyc.info).tree) { case ValDef(_, _, Tree.Empty, _): - error(pos, "recursive " + cyc.sym + " needs type"); - return; + return error(pos, "recursive " + cyc.sym + " needs type"); case DefDef(_, _, _, _, Tree.Empty, _): - error(pos, "recursive function " + cyc.sym.name + " needs result type"); - return; + return error(pos, "recursive function " + cyc.sym.name + " needs result type"); } } } //throw ex;//DEBUG - error(pos, ex.msg); + return error(pos, ex.msg); } // Name resolution ----------------------------------------------------------- String decode(Name name) { if (name.isTypeName()) return "type " + NameTransformer.decode(name); - else if (name.isConstrName()) return "constructor " + NameTransformer.decode(name); else return "value " + NameTransformer.decode(name); } @@ -640,23 +636,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { super(tree); } public void complete(Symbol sym) { - Symbol constr = tree.symbol().constructor(); - Type constrtype = constr.type().instanceType(); - constrtype = constrtype.cloneType(constr, sym); - sym.setInfo(constrtype); - } - /* todo: remove - private Type removeMethod(Type tp) { - switch (tp) { - case MethodType(_, Type restp): - return restp; - case PolyType(Symbol[] tparams, Type restp): - return Type.PolyType(tparams, removeMethod(restp)); - default: - return tp; - } + Symbol constr = tree.symbol().primaryConstructor(); + sym.setInfo(constr.type().instanceType().cloneType(constr, sym)); } - */ } /** A lazy type for self types @@ -731,7 +713,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { case ClassDef(int mods, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, _, Tree.Template templ): ClassSymbol clazz = new ClassSymbol(tree.pos, name, owner, mods); if (clazz.isLocalClass()) unit.mangler.setMangledName(clazz); - enterSym(tree, clazz.constructor()); + clazz.primaryConstructor().setInfo(new LazyTreeType(tree)); if ((mods & CASE) != 0) { /* todo: remove if (vparams.length == 0) { @@ -759,7 +741,22 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { return enterSym(tree, new TermSymbol(tree.pos, name, owner, mods)); case DefDef(int mods, Name name, _, _, _, _): - return enterSym(tree, new TermSymbol(tree.pos, name, owner, mods)); + Symbol sym; + if (name == Names.this_.toTypeName()) { + Symbol clazz = context.enclClass.owner; + if (!(context.tree instanceof Template) || + clazz.isModuleClass() || + clazz.isAnonymousClass() || + clazz.isCompoundSym() || + clazz.isPackage()) { + error(tree.pos, "constructor definition not allowed here"); + } + ((DefDef) tree).name = clazz.name; + sym = context.enclClass.owner.addConstructor(); + } else { + sym = new TermSymbol(tree.pos, name, owner, mods); + } + return enterSym(tree, sym); case TypeDef(int mods, Name name, _, _): Symbol tsym = ((mods & (DEFERRED | PARAM)) != 0) @@ -784,13 +781,14 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { private Symbol enterSym(Tree tree, Symbol sym) { //if (global.debug) System.out.println("entering " + sym);//DEBUG sym.setInfo(new LazyTreeType(tree)); - Symbol owner = sym.owner(); - if (sym.kind == VAL && !sym.isConstructor() && - (sym.flags & (PRIVATE | SEALED)) == 0 && - owner != null && owner.kind == CLASS && - (owner.flags & FINAL) != 0) - sym.flags |= FINAL; - sym = enterInScope(sym); + if (!sym.isConstructor()) { + Symbol owner = sym.owner(); + if (sym.kind == VAL && (sym.flags & (PRIVATE | SEALED)) == 0 && + owner != null && owner.kind == CLASS && + (owner.flags & FINAL) != 0) + sym.flags |= FINAL; + sym = enterInScope(sym); + } tree.setSymbol(sym); // set the comment associated with a symbol @@ -823,7 +821,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { if (other.isPreloaded()) { // symbol was preloaded from package; // need to overwrite definition. - overwrite(sym, other); + if (global.debug) global.log(sym + " overwrites " + other); + sym.copyTo(other); + if (sym.isModule()) + sym.moduleClass().copyTo(other.moduleClass()); result = other; } else if (sym.owner().isPackage()) { if (global.compiledNow.get(other) != null) { @@ -857,23 +858,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { return result; } - /** Overwrite symbol `to' from symbol `from' - */ - void overwrite(Symbol from, Symbol to) { - if (Global.instance.debug) System.out.println(from + " overwrites " + to);//debug - from.copyTo(to); - if (from.isModule()) { - from.moduleClass().copyTo( - to.moduleClass()); - from.moduleClass().constructor().copyTo( - to.moduleClass().constructor()); - to.moduleClass().constructor().setInfo( - Type.MethodType( - Symbol.EMPTY_ARRAY, - to.moduleClass().typeConstructor())); - } - } - /** Enter all symbols in statement list */ public void enterSyms(Tree[] stats) { @@ -939,7 +923,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { Type owntype; switch (tree) { case ClassDef(int mods, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree.Template templ): - pushContext(tree, sym.constructor(), new Scope(context.scope)); + pushContext( + tree, sym.primaryConstructor(), new Scope(context.scope)); Symbol[] tparamSyms = enterParams(tparams); Symbol[][] vparamSyms = enterParams(vparams); if (vparamSyms.length == 0) @@ -953,9 +938,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { vparamSyms, Type.TypeRef(sym.owner().thisType(), sym, Symbol.type(tparamSyms))); //System.out.println("set info " + sym.constructor() + " to " + constrtype + " was " + sym.constructor().rawInfo());//DEBUG - sym.constructor().setInfo(constrtype); + sym.primaryConstructor().setInfo(constrtype); // necessary so that we can access tparams - sym.constructor().flags |= INITIALIZED; + sym.primaryConstructor().flags |= INITIALIZED; if (tpe != Tree.Empty) sym.setTypeOfThis(new LazySelfType(tpe)); @@ -1000,18 +985,33 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { break; case DefDef(int mods, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree rhs): - pushContext(tree, sym, new Scope(context.scope)); - Symbol[] tparamSyms = enterParams(tparams); - Symbol[][] vparamSyms = enterParams(vparams); - if (tpe != Tree.Empty) { - ((DefDef) tree).tpe = tpe = transform(tpe, TYPEmode); + Symbol[] tparamSyms; + Symbol[][] vparamSyms; + Type restype; + if (name.isTypeName()) { + Context prevContext = context; + Symbol clazz = context.enclClass.owner; + context = context.enclClass.outer.outer; + pushContext(tree, sym, new Scope(context.scope)); + tparamSyms = enterParams(tparams); + vparamSyms = enterParams(vparams); + restype = clazz.type().subst( + clazz.typeParams(), tparamSyms); + ((DefDef) tree).tpe = tpe = gen.mkType(tree.pos, restype); + context = prevContext; } else { - ((DefDef) tree).rhs = rhs = transform(rhs, EXPRmode); - ((DefDef) tree).tpe = tpe = gen.mkType(tree.pos, rhs.type); + pushContext(tree, sym, new Scope(context.scope)); + tparamSyms = enterParams(tparams); + vparamSyms = enterParams(vparams); + if (tpe != Tree.Empty) { + ((DefDef) tree).tpe = tpe = transform(tpe, TYPEmode); + } else { + ((DefDef) tree).rhs = rhs = transform(rhs, EXPRmode); + ((DefDef) tree).tpe = tpe = gen.mkType(tree.pos, rhs.type); + } + restype = checkNoEscape(tpe.pos, tpe.type); + popContext(); } - Type restype = checkNoEscape(tpe.pos, tpe.type); - popContext(); - //checkNonCyclic(tree.pos, tpe.type); owntype = makeMethodType(tparamSyms, vparamSyms, restype); //System.out.println("methtype " + name + ":" + owntype);//DEBUG break; @@ -1042,8 +1042,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { 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) + tp.lookup(selectors[i].toTypeName()) == Symbol.NONE) error(tree.pos, NameTransformer.decode(selectors[i]) + " is not a member of " + expr + " of type " + expr.type); } break; @@ -1133,7 +1132,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { try { infer.exprAlternative(tree, alts, alttypes, pt); } catch (Type.Error ex) { - error(tree.pos, ex.msg); + reportTypeError(tree.pos, ex); } switch (tree.type) { case OverloadedType(_, _): @@ -1178,7 +1177,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { if (clazz.isCaseClass()) { // set type to instantiated case class constructor - tree.type = clazz.constructor().type(); + tree.type = clazz.primaryConstructor().type(); switch (tree.type) { case PolyType(Symbol[] tparams, Type restp): try { @@ -1260,13 +1259,29 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } //where Type seqConstructorType(Type paramtp, Type resulttp) { - Symbol constr = resulttp.symbol().constructor(); + Symbol constr = resulttp.symbol().primaryConstructor(); Symbol param = new TermSymbol( Position.NOPOS, Names.WILDCARD, constr, PARAM | REPEATED).setInfo( paramtp.baseType(definitions.SEQ_CLASS)); return Type.MethodType(new Symbol[]{param}, resulttp); } + Symbol typeToConstructor(int pos, Symbol sym) { + if (sym.kind == ERROR) + return sym; + else if ((mode & CONSTRmode) != 0) { + assert sym.isType() : sym; + sym.initialize(); + Symbol constr = sym.allConstructors(); + if (constr.kind == NONE) + error(pos, sym + " is abstract type; cannot be instantiated"); + //System.out.println(sym + ":" + constr + ":" + constr.rawInfo() + " --toconstr--> " + constr.info());//DEBUG + return constr; + } else { + return sym; + } + } + /** Attribute an identifier consisting of a simple name or an outer reference. * @param tree The tree representing the identifier. * @param name The name of the identifier. @@ -1276,6 +1291,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { // find applicable definition and assign to `sym' Symbol sym = Symbol.NONE; Type pre; + Tree qual = Tree.Empty; int stopPos = Integer.MIN_VALUE; Context nextcontext = context; @@ -1326,11 +1342,11 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { if (sym.owner().kind == CLASS) { pre = nextcontext.enclClass.owner.thisType(); if (!sym.owner().isPackage()) { - Tree qual = makeStableId(tree.pos, pre); - tree = make.Select(tree.pos, qual, name); + Tree qual1 = makeStableId(tree.pos, pre); + tree = make.Select(tree.pos, qual1, name); if (context.enclClass != nextcontext.enclClass) sym.flags |= SELECTOR; - //System.out.println(name + " :::> " + tree + " " + qual.symbol());//DEBUG + //System.out.println(name + " :::> " + tree + " " + qual1.symbol());//DEBUG } } else { pre = Type.localThisType; @@ -1356,12 +1372,13 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } sym = sym1; sym.flags |= (ACCESSED | SELECTOR); - Tree qual = lastimports.importPrefix().duplicate(); + qual = lastimports.importPrefix().duplicate(); pre = qual.type; //new TextTreePrinter().print(name + " => ").print(lastimports.tree).print("." + name).println().end();//DEBUG tree = make.Select(tree.pos, qual, name); - checkAccessible(tree.pos, sym, qual); } + sym = typeToConstructor(tree.pos, sym); + if (qual != Tree.Empty) checkAccessible(tree.pos, sym, qual); Type symtype = (sym.isType() ? sym.typeConstructor() : sym.type()) .asSeenFrom(pre, sym.owner()); if (symtype == Type.NoType) @@ -1384,7 +1401,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { qual = infer.mkTypeApply(qual, tparams, restype, Symbol.type(tparams)); uninst = tparams; } - Symbol sym = qual.type.lookup(name); + Symbol sym = typeToConstructor(tree.pos, qual.type.lookup(name)); if (sym.kind == NONE) { //System.out.println(qual.type + " has members " + qual.type.members());//DEBUG return error(tree.pos, @@ -1413,7 +1430,18 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { sym.isStable() && qual.type.isStable()) symtype = Type.singleType(qual.type, sym); //System.out.println(qual.type + ".member: " + sym + ":" + symtype);//DEBUG - return copy.Select(tree, sym, qual).setType(symtype); + Tree tree1; + switch (tree) { + case Select(_, _): + tree1 = copy.Select(tree, sym, qual); + break; + case SelectFromType(_, _): + tree1 = copy.Select(tree, sym, qual); + break; + default: + throw new ApplicationError(); + } + return tree1.setType(symtype); } } @@ -1554,11 +1582,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { Type[] argtypes = new Type[args.length]; switch (methtype) { case MethodType(Symbol[] params, Type restp): - if (meth != null && meth.isConstructor() && - params.length == 1 && params[0] == Symbol.NONE) { - error(pos, meth + " is inaccessible"); - return null; - } Type[] formals = infer.formalTypes(params, args.length); if (formals.length != args.length) { error(pos, "wrong number of arguments for " + @@ -1724,7 +1747,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { return tree.setType(Type.ErrorType); case ClassDef(_, _, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree.Template templ): - pushContext(tree, sym.constructor(), new Scope(context.scope)); + pushContext( + tree, sym.primaryConstructor(), new Scope(context.scope)); reenterParams(tparams); Tree.TypeDef[] tparams1 = transform(tparams); reenterParams(vparams); @@ -1757,16 +1781,23 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { return copy.ValDef(tree, sym, tpe, rhs1) .setType(definitions.UNIT_TYPE); - case DefDef(_, _, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree rhs): + case DefDef(_, Name name, Tree.TypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree rhs): + Context prevContext = context; + if (name.isTypeName()) { + Symbol clazz = context.enclClass.owner; + context = context.enclClass.outer.outer; + } pushContext(tree, sym, new Scope(context.scope)); reenterParams(tparams); Tree.TypeDef[] tparams1 = transform(tparams); reenterParams(vparams); Tree.ValDef[][] vparams1 = transform(vparams); Tree rhs1 = rhs; - if (rhs != Tree.Empty) + if (name.isTypeName()) + rhs1 = transform(rhs, CONSTRmode, tpe.type); + else if (rhs != Tree.Empty) rhs1 = transform(rhs, EXPRmode, tpe.type); - popContext(); + context = prevContext; sym.flags |= LOCKED; checkNonCyclic(tree.pos, tpe.type); sym.flags &= ~LOCKED; @@ -1951,10 +1982,13 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { else owntype = checkNoEscape(tree.pos, owntype); - Tree alloc = gen.New( - gen.Apply( - gen.mkRef(tree.pos, - Type.localThisType, clazz.constructor()), + Tree alloc = + gen.New( + gen.Apply( + gen.mkRef( + tree.pos, + Type.localThisType, + clazz.primaryConstructor()), Tree.EMPTY_ARRAY)) .setType(owntype); popContext(); @@ -1982,7 +2016,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { tree.pos, vparams1, body1, restype, context.owner); case TypeApply(Tree fn, Tree[] args): - Tree fn1 = transform(fn, EXPRmode | FUNmode, Type.AnyType); + Tree fn1 = transform( + fn, (mode & (EXPRmode | CONSTRmode)) | FUNmode, Type.AnyType); Tree[] args1 = transform(args, TYPEmode); Type[] argtypes = Tree.typeOf(args1); @@ -1992,7 +2027,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { try { infer.polyAlternative(fn1, alts, alttypes, args.length); } catch (Type.Error ex) { - error(tree.pos, ex.msg); + reportTypeError(tree.pos, ex); } } @@ -2095,7 +2130,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { try { infer.methodAlternative(fn1, alts, alttypes, argtypes, pt); } catch (Type.Error ex) { - error(tree.pos, ex.msg); + reportTypeError(tree.pos, ex); } } @@ -2107,7 +2142,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { fn1 = infer.methodInstance(fn1, tparams, restp, argtypes, pt); //System.out.println(fn1 + ":" + fn1.type);//DEBUG } catch (Type.Error ex) { - error(tree.pos, ex.msg); + reportTypeError(tree.pos, ex); } switch (fn1.type) { case MethodType(Symbol[] params, Type restp1): @@ -2153,13 +2188,16 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { case Select(Tree qual, Name name): int qualmode = EXPRmode | POLYmode | QUALmode; Tree qual1 = transform(qual, qualmode); - if (name.isTypeName() || name.isConstrName()) + if (name.isTypeName()) qual1 = checkStable(qual1); return transformSelect( tree, adapt(qual1, qualmode, Type.AnyType), name); case Ident(Name name): - if (((mode & (PATTERNmode | FUNmode)) == PATTERNmode) && name.isVariable()) { + if (name == Names.this_.toTypeName()) { + return transform(make.Ident(tree.pos, pt.symbol().name)); + } else if (((mode & (PATTERNmode | FUNmode)) == PATTERNmode) && + name.isVariable()) { Symbol vble, vble2 = null; diff --git a/sources/scalac/typechecker/DeSugarize.java b/sources/scalac/typechecker/DeSugarize.java index dc7e01378d..2a82dd0586 100644 --- a/sources/scalac/typechecker/DeSugarize.java +++ b/sources/scalac/typechecker/DeSugarize.java @@ -200,7 +200,7 @@ public class DeSugarize implements Kinds, Modifiers { make.Select( tree.pos, make.Ident(tree.pos, Names.scala), - Names.Object.toConstrName()), + Names.Object.toTypeName()), Tree.EMPTY_ARRAY); Tree constr = make.Apply( tree.pos, @@ -209,7 +209,7 @@ public class DeSugarize implements Kinds, Modifiers { make.Select( tree.pos, make.Ident(tree.pos, Names.scala), - Name.fromString("Function" + length).toConstrName()), + Name.fromString("Function" + length).toTypeName()), argtpes), Tree.EMPTY_ARRAY); diff --git a/sources/scalac/typechecker/ImportList.java b/sources/scalac/typechecker/ImportList.java index 7f3e82c659..f631ade171 100644 --- a/sources/scalac/typechecker/ImportList.java +++ b/sources/scalac/typechecker/ImportList.java @@ -58,8 +58,6 @@ class ImportList { if (i + 1 < selectors.length && name.toTermName() == selectors[i + 1]) { if (name.isTypeName()) return t.lookupNonPrivate(selectors[i].toTypeName()); - else if (name.isConstrName()) - return t.lookupNonPrivate(selectors[i].toConstrName()); else return t.lookupNonPrivate(selectors[i]); } else if (name.toTermName() == selectors[i]) { diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java index 9cd8575c6b..3b5b9f7d78 100644 --- a/sources/scalac/typechecker/RefCheck.java +++ b/sources/scalac/typechecker/RefCheck.java @@ -395,7 +395,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { Symbol sym = null; switch (stat) { case ClassDef(_, _, _, _, _, _): - sym = stat.symbol().constructor(); + sym = stat.symbol().primaryConstructor(); break; case DefDef(_, _, _, _, _, _): case ModuleDef(_, _, _, _): @@ -403,7 +403,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { sym = stat.symbol(); } if (sym != null && sym.isLocal()) { - scopes[level].enter(sym); + scopes[level].enter(new Scope.Entry(sym, scopes[level])); symIndex.put(sym, new Integer(index)); } } @@ -522,7 +522,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { } private Tree[] caseFields(ClassSymbol clazz) { - Symbol[] vparams = clazz.constructor().type().firstParams(); + Symbol[] vparams = clazz.primaryConstructor().type().firstParams(); Tree[] fields = new Tree[vparams.length]; for (int i = 0; i < fields.length; i++) { fields[i] = gen.mkRef( @@ -874,12 +874,14 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { case Apply(Tree fn, Tree[] args): Symbol fsym = TreeInfo.methSymbol(fn); + assert fsym != Symbol.NONE : tree; if (fsym != null && fsym.isMethod() && !fsym.isConstructor() && (fsym.flags & CASE) != 0) { // convert case methods to new's - Symbol constr = fsym.type().resultType().symbol().constructor(); + Symbol constr = fsym.type().resultType().symbol().primaryConstructor(); tree = gen.New(toConstructor(tree, constr)); } + return super.transform(tree); case AppliedType(Tree tpe, Tree[] args): diff --git a/sources/scalac/util/FreshNameCreator.java b/sources/scalac/util/FreshNameCreator.java index fb69ad5c33..3675f359f0 100644 --- a/sources/scalac/util/FreshNameCreator.java +++ b/sources/scalac/util/FreshNameCreator.java @@ -43,7 +43,6 @@ public class FreshNameCreator { public Name newName(Name prefixName, char separator) { Name name = newName(prefixName.toString(), separator); if (prefixName.isTypeName()) return name.toTypeName(); - else if (prefixName.isConstrName()) return name.toConstrName(); else return name; } diff --git a/sources/scalac/util/Name.java b/sources/scalac/util/Name.java index efe35a488b..988d0282b2 100644 --- a/sources/scalac/util/Name.java +++ b/sources/scalac/util/Name.java @@ -39,10 +39,6 @@ public final class Name { */ private static Name[] typeHashtable = new Name[HASH_SIZE]; -/** hashtable for finding constructor names quickly - */ - private static Name[] constrHashtable = new Name[HASH_SIZE]; - /** Constructor */ Name(int index, int len, Name[] table, int hash) { @@ -163,16 +159,6 @@ public final class Name { return n == this; } -/** is this name a type name? - */ - public boolean isConstrName() { - int h = hashValue(names, index, len) & HASH_MASK; - Name n = constrHashtable[h]; - while (n != null && n != this) - n = n.next; - return n == this; - } - /** create a term name corresponding to this name */ public Name toTermName() { @@ -199,19 +185,6 @@ public final class Name { return n; } -/** create a constructor name corresponding to this name - */ - public Name toConstrName() { - int h = hashValue(names, index, len) & HASH_MASK; - Name n = constrHashtable[h]; - while (n != null && n.index != index) - n = n.next; - if (n == null) { - n = new Name(index, len, constrHashtable, h); - } - return n; - } - /** return the string hash value of this name */ public int hashCode() { -- cgit v1.2.3