From a8f9240799ff6cb13a7de66e9e626ebc3321cc83 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 31 Mar 2003 17:16:36 +0000 Subject: *** empty log message *** --- sources/scalac/ast/TreeList.java | 6 +- sources/scalac/symtab/Definitions.java | 2 +- sources/scalac/typechecker/RefCheck.java | 125 ++++++++++++++++++++----------- 3 files changed, 86 insertions(+), 47 deletions(-) (limited to 'sources/scalac') diff --git a/sources/scalac/ast/TreeList.java b/sources/scalac/ast/TreeList.java index d35627c686..35c203aae2 100644 --- a/sources/scalac/ast/TreeList.java +++ b/sources/scalac/ast/TreeList.java @@ -65,7 +65,11 @@ public final class TreeList { } public Tree[] copyTo(Tree[] ts) { - System.arraycopy(trees, 0, ts, 0, len); + return copyTo(ts, 0); + } + + public Tree[] copyTo(Tree[] ts, int from) { + System.arraycopy(trees, 0, ts, from, len); return ts; } } diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java index 3fe8cc7dee..f0734f4654 100644 --- a/sources/scalac/symtab/Definitions.java +++ b/sources/scalac/symtab/Definitions.java @@ -309,7 +309,7 @@ public class Definitions { ANY_CLASS.members().enter(EQEQ); BANGEQ = new TermSymbol( - Position.NOPOS, Names.BANGEQ, ANY_CLASS, 0); + Position.NOPOS, Names.BANGEQ, ANY_CLASDeS, 0); BANGEQ.setInfo(Type.MethodType(new Symbol[]{newParameter(BANGEQ, ANY_TYPE)}, BOOLEAN_TYPE)); ANY_CLASS.members().enter(BANGEQ); diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java index 74ab754ae0..8122055e76 100644 --- a/sources/scalac/typechecker/RefCheck.java +++ b/sources/scalac/typechecker/RefCheck.java @@ -128,56 +128,89 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { (sym.owner().isPackage() || isGlobalModule(sym.owner().module())); } + private Tree[] transformModule(Tree tree) { + Symbol sym = tree.symbol(); + Tree cdef = make.ClassDef( + tree.pos, + mods | FINAL | MODUL, + name.toTypeName(), + Tree.ExtTypeDef.EMPTY_ARRAY, + Tree.ExtValDef.EMPTY_ARRAY_ARRAY, + Tree.Empty, + templ) + .setSymbol(sym.moduleClass()).setType(tree.type); + Tree alloc = gen.New( + tree.pos, + sym.type().prefix(), + sym.moduleClass(), + Tree.EMPTY_ARRAY); + if (isGlobalModule(sym)) { + Tree vdef = gen.ValDef(sym, alloc); + return new Tree[]{cdef, vdef}; + } else { + // var m$: T = null[T]; + Name varname = Name.fromString(name + "$"); + Symbol mvar = new TermSymbol( + tree.pos, varname, sym.owner(), PRIVATE | MUTABLE | SYNTHETIC) + .setInfo(sym.type()); + Tree vdef = gen.ValDef(mvar, nullTree(tree.pos, sym.type())); + + // { if (m$ == null[T]) m$ = new m$class; m$ } + Tree body = gen.Block(new Tree[]{ + gen.If( + gen.Apply( + gen.Select(gen.mkRef(tree.pos, mvar), global.definitions.EQEQ), + new Tree[]{nullTree(tree.pos, sym.type())}), + gen.Assign(gen.mkRef(tree.pos, mvar), alloc), + gen.Block(tree.pos, Tree.EMPTY_ARRAY)), + gen.mkRef(tree.pos, mvar)}); + + // def m: T = { if (m$ == null[T]) m$ = new m$class; m$ } + sym.updateInfo(Type.PolyType(Symbol.EMPTY_ARRAY, sym.type())); + sym.flags |= STABLE; + Tree ddef = gen.DefDef(sym, body); + return new Tree[]{cdef, vdef, ddef}; + } + } + + private boolean hasImplementation(Symbol clazz, Name name) { + Symbol sym = clazz.lookupNonPrivate(name); + return sym.kind == VAL && + sym.owner() != Definitions.ANY_CLASS && + (sym.flags & DEFERRED) == 0; + } + + private Tree toStringMethod(Symbol clazz) { + + + + private Tree[] addCaseMethods(Tree[] stats, Symbol clazz) { + if ((clazz.flags & CASE) != 0) { + TreeList ts = new TreeList(); + if (!hasImplementation(clazz, Names.toString)) + ts.append(toStringMethod(clazz)) + if (!hasImplementation(clazz, Names.EQEQ)) + ts.append(equalsMethod(clazz)); + if (!hasImplementation(clazz, Names.hashCode)) + ts.append(hashCodeMethod(clazz)); + if (ts.length() > 0) { + Tree[] stats1 = new Tree[stats.length + ts.length()); + System.arraycopy(stats, 0, stats1, 0, stats.length); + ts.copyTo(stats1, stats.length); + return stats1; + } + } + return stats; + } + + /** The main checking functions */ public Tree[] transformStat(Tree tree, int index) { Tree resultTree; switch (tree) { case ModuleDef(int mods, Name name, Tree tpe, Tree.Template templ): - Symbol sym = tree.symbol(); - Tree cdef = make.ClassDef( - tree.pos, - mods | FINAL | MODUL, - name.toTypeName(), - Tree.ExtTypeDef.EMPTY_ARRAY, - Tree.ExtValDef.EMPTY_ARRAY_ARRAY, - Tree.Empty, - templ) - .setSymbol(sym.moduleClass()).setType(tree.type); - Tree alloc = gen.New( - tree.pos, - sym.type().prefix(), - sym.moduleClass(), - Tree.EMPTY_ARRAY); - Tree[] result; - if (isGlobalModule(sym)) { - Tree vdef = gen.ValDef(sym, alloc); - result = new Tree[]{cdef, vdef}; - } else { - // var m$: T = null[T]; - Name varname = Name.fromString(name + "$"); - Symbol mvar = new TermSymbol( - tree.pos, varname, sym.owner(), PRIVATE | MUTABLE | SYNTHETIC) - .setInfo(sym.type()); - Tree vdef = gen.ValDef(mvar, nullTree(tree.pos, sym.type())); - - // { if (m$ == null[T]) m$ = new m$class; m$ } - Tree body = gen.Block(new Tree[]{ - gen.If( - gen.Apply( - gen.Select(gen.mkRef(tree.pos, mvar), global.definitions.EQEQ), - new Tree[]{nullTree(tree.pos, sym.type())}), - gen.Assign(gen.mkRef(tree.pos, mvar), alloc), - gen.Block(tree.pos, Tree.EMPTY_ARRAY)), - gen.mkRef(tree.pos, mvar)}); - - // def m: T = { if (m$ == null[T]) m$ = new m$class; m$ } - sym.updateInfo(Type.PolyType(Symbol.EMPTY_ARRAY, sym.type())); - sym.flags |= STABLE; - Tree ddef = gen.DefDef(sym, body); - result = new Tree[]{cdef, vdef, ddef}; - } - return transform(result); + return transform(transformModule(tree)); case ValDef(int mods, Name name, Tree tpe, Tree rhs): Symbol sym = tree.symbol(); @@ -192,6 +225,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { normalize(name)); } break; + default: resultTree = transform(tree); } @@ -203,7 +237,8 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { switch (tree) { case Template(Tree[] bases, Tree[] body): Tree[] bases1 = transform(bases); - Tree[] body1 = transformStats(body); + Tree[] body1 = addCaseMethods( + transformStats(body), tree.symbol().owner()); return copy.Template(tree, bases1, body1); case Block(Tree[] stats): Tree[] stats1 = transformStats(stats); -- cgit v1.2.3