summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpaltherr <paltherr@epfl.ch>2003-11-12 19:12:52 +0000
committerpaltherr <paltherr@epfl.ch>2003-11-12 19:12:52 +0000
commita61eb893701f4d6d34ee7156e8fa8b52375ace07 (patch)
tree15fc7e22f70cd653cc68fc2eef78e3f05f8c6f25
parentf5437e9a8bb543cf57b295739dd3abdebb7be651 (diff)
downloadscala-a61eb893701f4d6d34ee7156e8fa8b52375ace07.tar.gz
scala-a61eb893701f4d6d34ee7156e8fa8b52375ace07.tar.bz2
scala-a61eb893701f4d6d34ee7156e8fa8b52375ace07.zip
- Fixed some bugs in AddAccessors
- Moved all code into AddAccessorsPhase
-rw-r--r--config/list/compiler.lst1
-rw-r--r--sources/scalac/transformer/AddAccessors.java146
-rw-r--r--sources/scalac/transformer/AddAccessorsPhase.java104
3 files changed, 93 insertions, 158 deletions
diff --git a/config/list/compiler.lst b/config/list/compiler.lst
index 8bbd83e0d3..4582983ab5 100644
--- a/config/list/compiler.lst
+++ b/config/list/compiler.lst
@@ -102,7 +102,6 @@ symtab/SymbolTablePrinter.java
symtab/Type.java
symtab/TypeTags.java
-transformer/AddAccessors.java
transformer/AddAccessorsPhase.java
transformer/AddConstructors.java
transformer/AddConstructorsPhase.java
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/*<Symbol,Symbol>*/ 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/*<Tree>*/ 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/*<Symbol,Symbol>*/ 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);
+ }
+
+ };
//########################################################################
}