summaryrefslogtreecommitdiff
path: root/sources/scalac/ast
diff options
context:
space:
mode:
Diffstat (limited to 'sources/scalac/ast')
-rw-r--r--sources/scalac/ast/StrictTreeFactory.java317
-rw-r--r--sources/scalac/ast/SubstTransformer.java247
-rw-r--r--sources/scalac/ast/TreeCopier.java91
3 files changed, 655 insertions, 0 deletions
diff --git a/sources/scalac/ast/StrictTreeFactory.java b/sources/scalac/ast/StrictTreeFactory.java
new file mode 100644
index 0000000000..c68453424e
--- /dev/null
+++ b/sources/scalac/ast/StrictTreeFactory.java
@@ -0,0 +1,317 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+** **
+\* */
+
+// $OldId: StrictTreeFactory.java,v 1.6 2002/04/19 10:57:23 gamboni Exp $
+// $Id$
+
+package scalac.ast;
+
+import scalac.util.Name;
+import Tree.*;
+
+public class StrictTreeFactory extends AbstractTreeCopyFactory {
+ protected final TreeFactory make;
+
+ public StrictTreeFactory(TreeFactory make) {
+ this.make = make;
+ }
+
+ public Tree Bad(Tree tree) {
+ return tree;
+ }
+
+ public Tree ClassDef(Tree tree,
+ int mods,
+ Name name,
+ TypeDef[] tparams,
+ ValDef[][] vparams,
+ Tree tpe,
+ Template impl) {
+ ClassDef t = (ClassDef)tree;
+ tree = make.ClassDef(t.pos, mods, name, tparams, vparams, tpe, impl);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree PackageDef(Tree tree,
+ Tree packaged,
+ Template impl) {
+ PackageDef t = (PackageDef)tree;
+ tree = make.PackageDef(t.pos, packaged, impl);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree ModuleDef(Tree tree,
+ int mods,
+ Name name,
+ Tree tpe,
+ Template impl) {
+ ModuleDef t = (ModuleDef)tree;
+ tree = make.ModuleDef(t.pos, mods, name, tpe, impl);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree ValDef(Tree tree,
+ int mods,
+ Name name,
+ Tree tpe,
+ Tree rhs) {
+ ValDef t = (ValDef)tree;
+ tree = make.ValDef(t.pos, mods, name, tpe, rhs);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree PatDef(Tree tree,
+ int mods,
+ Tree pat,
+ Tree rhs) {
+ PatDef t = (PatDef)tree;
+ tree = make.PatDef(t.pos, mods, pat, rhs);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree DefDef(Tree tree,
+ int mods,
+ Name name,
+ TypeDef[] tparams,
+ ValDef[][] vparams,
+ Tree tpe,
+ Tree rhs) {
+ DefDef t = (DefDef)tree;
+ tree = make.DefDef(t.pos, mods, name, tparams, vparams, tpe, rhs);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree TypeDef(Tree tree,
+ int mods,
+ Name name,
+ TypeDef[] tparams,
+ Tree rhs) {
+ TypeDef t = (TypeDef)tree;
+ tree = make.TypeDef(t.pos, mods, name, tparams, rhs);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree Import(Tree tree,
+ Tree expr,
+ Name[] selectors) {
+ Import t = (Import)tree;
+ tree = make.Import(t.pos, expr, selectors);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree CaseDef(Tree tree,
+ Tree pat,
+ Tree guard,
+ Tree body) {
+ CaseDef t = (CaseDef)tree;
+ tree = make.CaseDef(t.pos, pat, guard, body);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Template Template(Tree tree,
+ Tree[] baseClasses,
+ Tree[] body) {
+ Template t = (Template)tree;
+ Template newTree = make.Template(t.pos, baseClasses, body);
+ attribute(newTree, t);
+ return newTree;
+ }
+
+ public Tree LabelDef(Tree tree,
+ Tree[] params,
+ Tree rhs) {
+ LabelDef t = (LabelDef)tree;
+ tree = make.LabelDef(t.pos,params,rhs);
+ attribute(tree,t);
+ return tree;
+ }
+
+ public Tree Block(Tree tree,
+ Tree[] stats) {
+ Block t = (Block)tree;
+ tree = make.Block(t.pos, stats);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree Tuple(Tree tree,
+ Tree[] trees) {
+ Tuple t = (Tuple)tree;
+ tree = make.Tuple(t.pos, trees);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree Visitor(Tree tree,
+ CaseDef[] cases) {
+ Visitor t = (Visitor)tree;
+ tree = make.Visitor(t.pos, cases);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree Function(Tree tree,
+ ValDef[] vparams,
+ Tree body) {
+ Function t = (Function)tree;
+ tree = make.Function(t.pos, vparams, body);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree Assign(Tree tree,
+ Tree lhs,
+ Tree rhs) {
+ Assign t = (Assign)tree;
+ tree = make.Assign(t.pos, lhs, rhs);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree If(Tree tree,
+ Tree cond,
+ Tree thenp,
+ Tree elsep) {
+ If t = (If)tree;
+ tree = make.If(t.pos, cond, thenp, elsep);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree New(Tree tree,
+ Template templ) {
+ New t = (New)tree;
+ tree = make.New(t.pos, templ);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree Typed(Tree tree,
+ Tree expr,
+ Tree tpe) {
+ Typed t = (Typed)tree;
+ tree = make.Typed(t.pos, expr, tpe);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree TypeApply(Tree tree,
+ Tree fun,
+ Tree[] args) {
+ TypeApply t = (TypeApply)tree;
+ tree = make.TypeApply(t.pos, fun, args);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree Apply(Tree tree,
+ Tree fun,
+ Tree[] args) {
+ Apply t = (Apply)tree;
+ tree = make.Apply(t.pos, fun, args);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree This(Tree tree, Tree qualifier) {
+ This t = (This)tree;
+ tree = make.This(t.pos, qualifier);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree Super(Tree tree,
+ Tree tpe) {
+ Super t = (Super)tree;
+ tree = make.Super(t.pos, tpe);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree Select(Tree tree,
+ Tree qualifier,
+ Name selector) {
+ Select t = (Select)tree;
+ tree = make.Select(t.pos, qualifier, selector);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree Ident(Tree tree,
+ Name name) {
+ Ident t = (Ident)tree;
+ tree = make.Ident(t.pos, name);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree Literal(Tree tree,
+ Object value) {
+ Literal t = (Literal)tree;
+ tree = make.Literal(t.pos, value);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree SingletonType(Tree tree, Tree ref) {
+ SingletonType t = (SingletonType)tree;
+ tree = make.SingletonType(t.pos, ref);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree SelectFromType(Tree tree, Tree qualifier, Name selector) {
+ SelectFromType t = (SelectFromType)tree;
+ tree = make.SelectFromType(t.pos, qualifier, selector);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree FunType(Tree tree,
+ Tree[] argtpe,
+ Tree restpe) {
+ FunType t = (FunType)tree;
+ tree = make.FunType(t.pos, argtpe, restpe);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree CompoundType(Tree tree,
+ Tree[] baseTypes,
+ Tree[] refinements) {
+ CompoundType t = (CompoundType)tree;
+ tree = make.CompoundType(t.pos, baseTypes, refinements);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree CovariantType(Tree tree,
+ Tree clazz) {
+ CovariantType t = (CovariantType)tree;
+ tree = make.CovariantType(t.pos, clazz);
+ attribute(tree, t);
+ return tree;
+ }
+
+ public Tree AppliedType(Tree tree,
+ Tree tpe,
+ Tree[] args) {
+ AppliedType t = (AppliedType)tree;
+ tree = make.AppliedType(t.pos, tpe, args);
+ attribute(tree, t);
+ return tree;
+ }
+}
diff --git a/sources/scalac/ast/SubstTransformer.java b/sources/scalac/ast/SubstTransformer.java
new file mode 100644
index 0000000000..c7802d20d7
--- /dev/null
+++ b/sources/scalac/ast/SubstTransformer.java
@@ -0,0 +1,247 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+** **
+\* */
+
+// $OldId: SubstTransformer.java,v 1.3 2002/04/19 10:55:15 schinz Exp $
+// $Id$
+
+package scalac.ast;
+
+import scalac.*;
+import scalac.ast.*;
+import scalac.symtab.*;
+import scalac.util.*;
+import scalac.typechecker.*;
+import Tree.*;
+
+import java.util.*;
+
+/**
+ * A transformer which performs symbol or type substitutions.
+ *
+ * @author Michel Schinz
+ * @version 1.0
+ */
+
+public class SubstTransformer extends Transformer {
+ protected Map/*<Symbol,Symbol>*/ symbolMap = new HashMap();
+ protected SymbolMapApplier smApplier = new SymbolMapApplier(symbolMap);
+ protected LinkedList/*<Map<Symbol,Symbol>>*/ ssStack = new LinkedList();
+
+ protected Symbol[] typeMapFormals = Symbol.EMPTY_ARRAY;
+ protected Type[] typeMapActuals = Type.EMPTY_ARRAY;
+ protected LinkedList/*<Symbol[]>*/ tmfStack = new LinkedList();
+ protected LinkedList/*<Symbol[]>*/ tmaStack = new LinkedList();
+
+ final protected Type.Map typeMap =
+ new Type.Map() {
+ public Type apply(Type t) {
+ return t.subst(typeMapFormals, typeMapActuals);
+ }
+ };
+
+ protected final TreeCopyFactory simpleCopy;
+
+ public SubstTransformer(Global global,
+ PhaseDescriptor descr,
+ TreeFactory make) {
+ super(global, descr, make, new TCF(make));
+ this.simpleCopy = new StrictTreeFactory(make);
+
+ ((TCF)copy).setTransformer(this);
+ }
+
+ public boolean mustSubstituteSymbol(Tree tree) {
+ return true;
+ }
+
+ protected void updateSymbolSubst() {
+ symbolMap.clear();
+ Iterator ssIt = ssStack.iterator();
+ while (ssIt.hasNext()) {
+ Map/*<Symbol,Symbol>*/ map = (Map)ssIt.next();
+ symbolMap.putAll(map);
+ }
+ }
+
+ public void pushSymbolSubst(Map map) {
+ ssStack.addLast(map);
+ updateSymbolSubst();
+ }
+
+ public void popSymbolSubst() {
+ ssStack.removeLast();
+ updateSymbolSubst();
+ }
+
+ public void clearSymbolSubst() {
+ ssStack.clear();
+ updateSymbolSubst();
+ }
+
+ protected void updateTypeSubst() {
+ assert tmfStack.size() == tmaStack.size();
+
+ Map/*<Symbol,Type>*/ map = new HashMap();
+ Iterator tmfIt = tmfStack.iterator();
+ Iterator tmaIt = tmaStack.iterator();
+ while (tmfIt.hasNext()) {
+ assert tmaIt.hasNext();
+ Symbol[] formals = (Symbol[]) tmfIt.next();
+ Type[] actuals = (Type[]) tmaIt.next();
+ assert formals.length == actuals.length;
+ for (int i = 0; i < formals.length; ++i)
+ map.put(formals[i], actuals[i]);
+ }
+
+ typeMapFormals = new Symbol[map.size()];
+ typeMapActuals = new Type[map.size()];
+
+ Set/*<Map.Entry<Symbol,Type>>*/ entries = map.entrySet();
+ Iterator entriesIt = entries.iterator();
+ int i = 0;
+ while (entriesIt.hasNext()) {
+ Map.Entry entry = (Map.Entry)entriesIt.next();
+ typeMapFormals[i] = (Symbol)entry.getKey();
+ typeMapActuals[i] = (Type)entry.getValue();
+ ++i;
+ }
+ }
+
+ public void pushTypeSubst(Symbol[] from, Type[] to) {
+ assert from.length == to.length;
+ tmfStack.addLast(from);
+ tmaStack.addLast(to);
+ updateTypeSubst();
+ }
+
+ public void popTypeSubst() {
+ tmfStack.removeLast();
+ tmaStack.removeLast();
+ updateTypeSubst();
+ }
+
+ public void clearTypeSubst() {
+ tmfStack.clear();
+ tmaStack.clear();
+ updateTypeSubst();
+ }
+
+ public Tree transform(Tree tree) {
+ Tree newTree = super.transform(tree);
+ return syncTree(newTree);
+ }
+
+ // Update the tree so that:
+ // 1. names reflect the ones in symbols,
+ // 2. types reflect the ones in symbols.
+ // 3. modifiers reflect the ones in symbols.
+ public Tree syncTree(Tree tree) {
+ Name newName = null;
+ Type newType = null;
+ int newMods = -1;
+
+ if (tree.hasSymbol()) {
+ Symbol sym = tree.symbol();
+
+ newName = sym.name;
+ newType = smApplier.apply(typeMap.apply(sym.nextInfo()));
+ newMods = sym.flags;
+ }
+
+ switch (tree) {
+ case ClassDef(_, // fix Emacs :
+ _,
+ Tree.TypeDef[] tparams,
+ Tree.ValDef[][] vparams,
+ Tree tpe,
+ Tree.Template impl) :
+ return simpleCopy
+ .ClassDef(tree, newMods, newName, tparams, vparams, tpe, impl);
+
+ case ModuleDef(_, _, Tree tpe, Template impl):
+ return simpleCopy.ModuleDef(tree,
+ newMods,
+ newName,
+ gen.mkType(tpe.pos, newType),
+ impl);
+
+ case ValDef(int mods, Name name, Tree tpe, Tree rhs):
+ return simpleCopy.ValDef(tree,
+ newMods,
+ newName,
+ gen.mkType(tpe.pos, newType),
+ rhs);
+
+ case DefDef(_, // fix for Emacs :
+ Name name,
+ Tree.TypeDef[] tparams,
+ Tree.ValDef[][] vparams,
+ Tree tpe,
+ Tree rhs):
+ return simpleCopy.DefDef(tree,
+ newMods,
+ newName,
+ tparams,
+ vparams,
+ gen.mkType(tpe.pos, newType.resultType()),
+ rhs);
+
+ case Select(Tree qualifier, _):
+ return simpleCopy.Select(tree, qualifier, newName);
+
+ case Ident(_):
+ return simpleCopy.Ident(tree, newName);
+
+ // TODO add a case for TypeDef?
+
+ case Typed(Tree expr, Tree tpe): {
+ Type newType2 =
+ smApplier.apply(((Tree.Typed)tree).tpe.type);
+ return simpleCopy.Typed(tree,
+ expr,
+ gen.mkType(tpe.pos, newType2));
+ }
+
+ default:
+ return tree;
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ public static class TCF extends StrictTreeFactory {
+ protected SubstTransformer transformer;
+ protected Map/*<Symbol,Symbol>*/ symbolMap;
+ protected SymbolMapApplier smApplier;
+ protected Type.Map typeMap;
+
+ public TCF(TreeFactory make) {
+ super(make);
+ }
+
+ public void setTransformer(SubstTransformer transformer) {
+ this.transformer = transformer;
+ this.symbolMap = transformer.symbolMap;
+ this.smApplier = transformer.smApplier;
+ this.typeMap = transformer.typeMap;
+ }
+
+ public void attribute(Tree newTree, Tree oldTree) {
+ if (oldTree.hasSymbol()) {
+ Symbol oldSym = oldTree.symbol();
+
+ if (transformer.mustSubstituteSymbol(oldTree)
+ && symbolMap.containsKey(oldSym)) {
+ newTree.setSymbol((Symbol)symbolMap.get(oldSym));
+ } else
+ newTree.setSymbol(oldTree.symbol());
+ }
+
+ newTree.type = smApplier.apply(typeMap.apply(oldTree.type));
+ }
+ }
+}
diff --git a/sources/scalac/ast/TreeCopier.java b/sources/scalac/ast/TreeCopier.java
new file mode 100644
index 0000000000..ad03cd6632
--- /dev/null
+++ b/sources/scalac/ast/TreeCopier.java
@@ -0,0 +1,91 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $OldId: TreeCopier.java,v 1.17 2002/06/13 12:04:12 schinz Exp $
+// $Id$
+
+package scalac.ast;
+
+import scalac.*;
+import scalac.util.Name;
+import scalac.symtab.*;
+import java.util.*;
+
+/**
+ * Superclass for tree copiers. Takes care of duplicating symbols and
+ * types when needed.
+ *
+ * @author Michel Schinz
+ * @version 1.0
+ */
+
+public class TreeCopier extends SubstTransformer {
+ public TreeCopier(Global global,
+ PhaseDescriptor descr,
+ TreeFactory make) {
+ super(global, descr, make);
+ }
+
+ private boolean inPattern = false;
+
+ // Return true iff tree's symbol must be copied. By default,
+ // symbols which are defined are copied.
+ public boolean mustCopySymbol(Tree tree) {
+ switch (tree) {
+ case Ident(Name name):
+ return (inPattern && name.isVariable()) || tree.definesSymbol();
+ default:
+ return tree.definesSymbol();
+ }
+ }
+
+ public Tree copy(Tree tree) {
+ // Copy all symbols that have to be copied.
+ Traverser symCopier = new Traverser() {
+ public void traverse(Tree tree) {
+ if (tree.hasSymbol()) {
+ Symbol sym = tree.symbol();
+
+ if (sym != Symbol.NONE
+ && mustCopySymbol(tree)
+ && !symbolMap.containsKey(sym)) {
+ Symbol newSym = sym.cloneSymbol();
+
+ if (symbolMap.containsKey(newSym.owner()))
+ newSym.setOwner((Symbol)symbolMap.get(newSym.owner()));
+
+ symbolMap.put(sym, newSym);
+ }
+ }
+ switch (tree) {
+ case CaseDef(Tree pat, Tree guard, Tree body):
+ inPattern = true; traverse(pat); inPattern = false;
+ traverse(guard);
+ traverse(body);
+ break;
+ default:
+ super.traverse(tree);
+ }
+ }
+ };
+ symCopier.traverse(tree);
+
+ // Copy tree
+ Tree newTree = transform(tree);
+
+ // Update symbols
+ Iterator symbolsIt = symbolMap.entrySet().iterator();
+ while (symbolsIt.hasNext()) {
+ Map.Entry symPair = (Map.Entry)symbolsIt.next();
+ Symbol oldSym = (Symbol)symPair.getKey();
+ Symbol newSym = (Symbol)symPair.getValue();
+
+ newSym.setInfo(smApplier.apply(typeMap.apply(oldSym.info())));
+ }
+
+ return newTree;
+ }
+}