summaryrefslogtreecommitdiff
path: root/sources/scalac/ast/TreeCopier.java
diff options
context:
space:
mode:
Diffstat (limited to 'sources/scalac/ast/TreeCopier.java')
-rw-r--r--sources/scalac/ast/TreeCopier.java91
1 files changed, 91 insertions, 0 deletions
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;
+ }
+}