summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorschinz <schinz@epfl.ch>2003-02-17 14:00:10 +0000
committerschinz <schinz@epfl.ch>2003-02-17 14:00:10 +0000
commitbd7715e8ddfcb141a24bdb74b4c07bc3a6c7d675 (patch)
tree54020ceb75f39e3449ca867d38513b14a78b2b8a
parentdf427a25f188fa7df88089a32e8625508d2b3d6a (diff)
downloadscala-bd7715e8ddfcb141a24bdb74b4c07bc3a6c7d675.tar.gz
scala-bd7715e8ddfcb141a24bdb74b4c07bc3a6c7d675.tar.bz2
scala-bd7715e8ddfcb141a24bdb74b4c07bc3a6c7d675.zip
*** empty log message ***
-rw-r--r--sources/scalac/transformer/AddAccessors.java140
-rw-r--r--sources/scalac/transformer/AddAccessorsPhase.java42
2 files changed, 182 insertions, 0 deletions
diff --git a/sources/scalac/transformer/AddAccessors.java b/sources/scalac/transformer/AddAccessors.java
new file mode 100644
index 0000000000..2961f0d6e2
--- /dev/null
+++ b/sources/scalac/transformer/AddAccessors.java
@@ -0,0 +1,140 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ 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, PhaseDescriptor descr) {
+ super(global, descr);
+ }
+
+ protected Name valName(Symbol sym) {
+ return Name.fromString(sym.name.toString() + "$");
+ }
+
+ protected final HashMap/*<Symbol,Symbol>*/ accessorMap = new HashMap();
+ protected boolean inClassContext = true;
+
+ 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(int mods, // :
+ Name name,
+ Tree.TypeDef[] tparams,
+ Tree.ValDef[][] vparams,
+ Tree tpe,
+ Tree.Template impl): {
+ Symbol clsSym = tree.symbol();
+ Symbol constrSym = clsSym.constructor();
+
+ LinkedList/*<Tree>*/ newBody =
+ new LinkedList(Arrays.asList(transform(impl.body)));
+
+ // Add value definitions and accessors for all constructor
+ // arguments which were found in the body of the class.
+ assert vparams.length == 1;
+ Tree.ValDef[] params = vparams[0];
+ Scope newMembers = new Scope(clsSym.members());
+ for (int i = 0; i < params.length; ++i) {
+ Symbol paramSym = params[i].symbol();
+ if (accessorMap.containsKey(paramSym)) {
+ Symbol accessorSym = (Symbol)accessorMap.get(paramSym);
+
+ Symbol valSym = new TermSymbol(paramSym.pos,
+ valName(paramSym),
+ clsSym,
+ Modifiers.PRIVATE);
+ valSym.setType(paramSym.type());
+
+ newBody.addFirst(gen.DefDef(accessorSym, gen.Ident(valSym)));
+ newMembers.enter(accessorSym);
+
+ newBody.addFirst(gen.ValDef(valSym, gen.Ident(paramSym)));
+ newMembers.enter(valSym);
+ }
+ }
+
+ // Update class type with new values/accessors.
+ switch (clsSym.info()) {
+ case CompoundType(Type[] basetypes, Scope members):
+ clsSym.updateInfo(Type.compoundType(basetypes, newMembers, clsSym));
+ break;
+ default:
+ Debug.abort("unexpected type", clsSym.info());
+ }
+
+ assert inClassContext;
+ inClassContext = false;
+ Tree[] newParents = transform(impl.parents);
+ inClassContext = true;
+
+ Tree[] newBodyA = (Tree[])newBody.toArray(new Tree[newBody.size()]);
+
+ return copy.ClassDef(tree,
+ mods,
+ name,
+ transform(tparams),
+ transform(vparams),
+ transform(tpe),
+ copy.Template(impl, newParents, newBodyA));
+ }
+
+ case Select(Tree qualifier, Name selector): {
+ Symbol sym = tree.symbol();
+ if (sym.owner().isPrimaryConstructor())
+ return gen.Apply(gen.Select(transform(qualifier), accessor(sym)),
+ Tree.EMPTY_ARRAY);
+ else
+ return copy.Select(tree, transform(qualifier), selector);
+ }
+
+ case Ident(Name name): {
+ Symbol sym = tree.symbol();
+ if (inClassContext && sym.owner().isPrimaryConstructor())
+ return gen.Apply(gen.Ident(accessor(sym)), Tree.EMPTY_ARRAY);
+ else
+ return copy.Ident(tree, name);
+ }
+
+ default:
+ return super.transform(tree);
+ }
+ }
+}
diff --git a/sources/scalac/transformer/AddAccessorsPhase.java b/sources/scalac/transformer/AddAccessorsPhase.java
new file mode 100644
index 0000000000..7a55df17a8
--- /dev/null
+++ b/sources/scalac/transformer/AddAccessorsPhase.java
@@ -0,0 +1,42 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+** **
+\* */
+
+// $OldId: AddAccessorsPhase.java,v 1.1 2002/10/17 12:27:11 schinz Exp $
+// $Id$
+
+package scalac.transformer;
+
+import scalac.*;
+import scalac.checkers.*;
+
+import java.util.*;
+
+public class AddAccessorsPhase extends PhaseDescriptor {
+ public String name () {
+ return "addaccessors";
+ }
+
+ public String description () {
+ return "add accessors for constructor arguments";
+ }
+
+ public String taskDescription() {
+ return "added accessors";
+ }
+
+ public Phase createPhase(Global global) {
+ return new AddAccessors(global, this);
+ }
+
+ public Checker[] postCheckers(Global global) {
+ return new Checker[] {
+ new CheckSymbols(global),
+ new CheckTypes(global),
+ new CheckOwners(global)
+ };
+ }
+}