From a61eb893701f4d6d34ee7156e8fa8b52375ace07 Mon Sep 17 00:00:00 2001 From: paltherr Date: Wed, 12 Nov 2003 19:12:52 +0000 Subject: - Fixed some bugs in AddAccessors - Moved all code into AddAccessorsPhase --- sources/scalac/transformer/AddAccessors.java | 146 ---------------------- sources/scalac/transformer/AddAccessorsPhase.java | 104 +++++++++++++-- 2 files changed, 93 insertions(+), 157 deletions(-) delete mode 100644 sources/scalac/transformer/AddAccessors.java (limited to 'sources/scalac') diff --git a/sources/scalac/transformer/AddAccessors.java b/sources/scalac/transformer/AddAccessors.java deleted file mode 100644 index 9b91677a83..0000000000 --- a/sources/scalac/transformer/AddAccessors.java +++ /dev/null @@ -1,146 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -\* */ - -// $OldId: AddAccessors.java,v 1.2 2002/11/21 14:14:31 schinz Exp $ -// $Id$ - -package scalac.transformer; - -import scalac.*; -import scalac.ast.*; -import scalac.typechecker.*; -import scalac.symtab.*; -import scalac.util.*; - -import java.util.*; - -/** - * Add private accessor functions for all class constructor arguments - * which are accessed from within the class' methods, or nested - * classes. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class AddAccessors extends Transformer { - public AddAccessors(Global global) { - super(global); - } - - protected Name valName(Symbol sym) { - return Name.fromString(sym.name.toString() + "$"); - } - - protected final HashMap/**/ accessorMap = new HashMap(); - protected boolean inClassContext; - protected Symbol clasz; - - protected Symbol accessor(Symbol sym) { - Symbol accessor = (Symbol)accessorMap.get(sym); - if (accessor == null) { - accessor = new TermSymbol(sym.pos, - sym.name, - sym.classOwner(), - Modifiers.STABLE - | Modifiers.ACCESSOR - | Modifiers.PRIVATE); - accessor.setType(Type.MethodType(Symbol.EMPTY_ARRAY, sym.type())); - accessorMap.put(sym, accessor); - } - return accessor; - } - - public Tree transform(Tree tree) { - switch (tree) { - case ClassDef(_, // : - _, - Tree.AbsTypeDef[] tparams, - Tree.ValDef[][] vparams, - Tree tpe, - Tree.Template impl): { - Symbol backup = clasz; - Symbol clsSym = clasz = tree.symbol(); - assert vparams.length == 1; - Tree.ValDef[] params = vparams[0]; - - // Recursively transform body - Tree[] body = impl.body; - LinkedList/**/ newBody = new LinkedList(); - for (int i = 0; i < body.length; ++i) { - Tree mem = body[i]; - Symbol sym = mem.symbol(); - inClassContext = - mem.definesSymbol() && (sym.isClass() || sym.isMethod()); - newBody.add(transform(mem)); - } - - // Add value definitions and accessors for all constructor - // arguments which were found in the body of the class. - Scope newMembers = new Scope(clsSym.members()); - for (int i = 0; i < params.length; ++i) { - Symbol paramSym = params[i].symbol(); - if (accessorMap.containsKey(paramSym)) { - int pos = paramSym.pos; - Symbol accessorSym = (Symbol)accessorMap.get(paramSym); - - Symbol valSym = new TermSymbol(pos, - valName(paramSym), - clsSym, - Modifiers.PRIVATE); - valSym.setType(paramSym.type()); - - newBody.addFirst(gen.DefDef(accessorSym, gen.Ident(pos, valSym))); - newMembers.enter(accessorSym); - - newBody.addFirst(gen.ValDef(valSym, gen.Ident(pos, paramSym))); - newMembers.enter(valSym); - } - } - - // Update class type with new values/accessors. - clsSym.updateInfo(Type.compoundType(clsSym.parents(), - newMembers, - clsSym)); - - inClassContext = false; - Tree[] newParents = transform(impl.parents); - - Tree[] newBodyA = (Tree[])newBody.toArray(new Tree[newBody.size()]); - - clasz = backup; - return copy.ClassDef(tree, - clsSym, - transform(tparams), - transform(vparams), - transform(tpe), - copy.Template(impl, newParents, newBodyA)); - } - - case Select(Tree qualifier, _): { - Symbol sym = tree.symbol(); - assert sym.kind != Kinds.NONE : tree; - if (sym.owner().isPrimaryConstructor()) - return gen.Apply(gen.Select(tree.pos, transform(qualifier), accessor(sym))); - else - return copy.Select(tree, sym, transform(qualifier)); - } - - case Ident(_): { - Symbol sym = tree.symbol(); - if (inClassContext - && sym.name.isTermName() - && sym.owner().isPrimaryConstructor()) - return gen.Apply(gen.Select(gen.This(tree.pos, clasz), accessor(sym))); - else - return copy.Ident(tree, sym); - } - - default: - return super.transform(tree); - } - } -} diff --git a/sources/scalac/transformer/AddAccessorsPhase.java b/sources/scalac/transformer/AddAccessorsPhase.java index 59497a0972..e93011cdd3 100644 --- a/sources/scalac/transformer/AddAccessorsPhase.java +++ b/sources/scalac/transformer/AddAccessorsPhase.java @@ -9,12 +9,30 @@ package scalac.transformer; +import java.util.Map; +import java.util.HashMap; + import scalac.Global; import scalac.Phase; import scalac.PhaseDescriptor; import scalac.Unit; -import scalac.checkers.*; +import scalac.ast.Transformer; +import scalac.ast.Tree; +import scalac.ast.Tree.Template; +import scalac.ast.TreeList; +import scalac.symtab.Modifiers; +import scalac.symtab.Symbol; +import scalac.symtab.TermSymbol; +import scalac.symtab.Type; +import scalac.util.Name; +import scalac.util.Debug; + +/** + * This phase adds private accessor fields and methods for all class + * constructor arguments which are accessed from within the class' + * methods, or nested classes. + */ public class AddAccessorsPhase extends Phase { //######################################################################## @@ -30,18 +48,82 @@ public class AddAccessorsPhase extends Phase { /** Applies this phase to the given compilation units. */ public void apply(Unit[] units) { - for (int i = 0; i < units.length; i++) - new AddAccessors(global).apply(units[i]); + treeTransformer.apply(units); } - public Checker[] postCheckers(Global global) { - return new Checker[] { - new CheckSymbols(global), - new CheckTypes(global), - new CheckOwners(global), - new CheckNames(global) - }; - } + //######################################################################## + // Private Class - Tree transformer + + /** The tree transformer */ + private final Transformer treeTransformer = new Transformer(global) { + + /** The parameter to accessor method map */ + private final Map/**/ methods = new HashMap(); + + /** Creates an accessor field symbol for given parameter. */ + private Symbol createAccessorField(Symbol param) { + int flags = Modifiers.PRIVATE | Modifiers.STABLE; + Name name = Name.fromString(param.name + "$"); + Symbol owner = param.owner().constructorClass(); + Symbol field = new TermSymbol(param.pos, name, owner, flags); + field.setType(param.type()); + owner.members().enterOrOverload(field); + return field; + } + + /** Creates an accessor method symbol for given parameter. */ + private Symbol createAccessorMethod(Symbol param) { + int flags = Modifiers.PRIVATE | Modifiers.STABLE | Modifiers.ACCESSOR; + Name name = param.name; + Symbol owner = param.owner().constructorClass(); + Symbol method = new TermSymbol(param.pos, name, owner, flags); + method.setType(Type.MethodType(Symbol.EMPTY_ARRAY, param.type())); + owner.members().enterOrOverload(method); + methods.put(param, method); + return method; + } + + /** Transforms the given tree. */ + public Tree transform(Tree tree) { + switch (tree) { + case ClassDef(_, _, _, _, _, Template impl): { + Symbol clasz = tree.symbol(); + // transform parents and body + Tree[] parents = transform(impl.parents); + Tree[] body = transform(impl.body); + // create accessor field & method trees + TreeList accessors = new TreeList(); + Symbol[] params = clasz.valueParams(); + for (int i = 0; i < params.length; ++i) { + Symbol param = params[i]; + Symbol method = (Symbol)methods.remove(param); + if (method == null) continue; + Symbol field = createAccessorField(param); + accessors.append( + gen.ValDef( + field, + gen.Ident(param.pos, param))); + accessors.append( + gen.DefDef( + method, + gen.Select(gen.This(param.pos, clasz), field))); + } + body = Tree.concat(accessors.toArray(), body); + impl = gen.Template(clasz.pos, impl.symbol(), parents, body); + return gen.ClassDef(clasz, impl); + } + case Select(Tree qualifier, _): + if (!tree.symbol().owner().isPrimaryConstructor()) break; + qualifier = transform(qualifier); + Symbol method = (Symbol)methods.get(tree.symbol()); + if (method == null) + method = createAccessorMethod(tree.symbol()); + return gen.Apply(gen.Select(tree.pos, qualifier, method)); + } + return super.transform(tree); + } + + }; //######################################################################## } -- cgit v1.2.3