blob: 092f7960c23d4cbce037dc167bdfa90cf0d3919b (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
/* ____ ____ ____ ____ ______ *\
** / __// __ \/ __// __ \/ ____/ 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, TreeFactory make) {
super(global, 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;
}
}
|