diff options
author | schinz <schinz@epfl.ch> | 2003-02-19 09:55:54 +0000 |
---|---|---|
committer | schinz <schinz@epfl.ch> | 2003-02-19 09:55:54 +0000 |
commit | 8ab0ae13ce49fb8d39a6c9af7873586da4e61c4a (patch) | |
tree | 69bb72f17b10f0f7a6adc553bf5ede8fde279b03 /sources/scalac/ast | |
parent | 6cb8bc84c903322e4c87e545c23a648d7950fe9d (diff) | |
download | scala-8ab0ae13ce49fb8d39a6c9af7873586da4e61c4a.tar.gz scala-8ab0ae13ce49fb8d39a6c9af7873586da4e61c4a.tar.bz2 scala-8ab0ae13ce49fb8d39a6c9af7873586da4e61c4a.zip |
*** empty log message ***
Diffstat (limited to 'sources/scalac/ast')
-rw-r--r-- | sources/scalac/ast/StrictTreeFactory.java | 317 | ||||
-rw-r--r-- | sources/scalac/ast/SubstTransformer.java | 247 | ||||
-rw-r--r-- | sources/scalac/ast/TreeCopier.java | 91 |
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; + } +} |