blob: 70b1b236c393e6a5d8affdfab0df83c715da32ae (
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
/* ____ ____ ____ ____ ______ *\
** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
** /_____/\____/\___/\____/____/ **
\* */
// $Id$
package scalac.ast;
import java.util.Map;
import java.util.HashMap;
import scalac.symtab.Symbol;
import scalac.symtab.SymbolCloner;
import scalac.util.Name;
import scalac.util.Debug;
/**
* This class implements a tree traverser that clones specified
* symbols it encounters.
*/
public class TreeSymbolCloner extends Traverser {
//########################################################################
// Private Fields
// !!! replace Idents in patterns by ValDefs and remove this field
/** Indicates whether we are in a pattern */
private boolean inPattern = false;
//########################################################################
// Public Fields
/** The symbol cloner used to clone symbols */
public final SymbolCloner cloner;
//########################################################################
// Public Constructors
/** Initializes a new instance. */
public TreeSymbolCloner(SymbolCloner cloner) {
this.cloner = cloner;
}
//########################################################################
// Public Methods
/**
* Returns true iff the symbol of the given tree symbol must be
* cloned. The default implementation returns true iff the tree
* defines a symbol and that symbol hasn't been cloned yet.
*/
public boolean mustCloneSymbolOf(Tree tree) {
// !!! replace Idents in patterns by ValDefs and remove this switch
switch (tree) {
case Ident(Name name):
if (!inPattern || !name.isVariable()) return false; else break;
default:
if (!tree.definesSymbol()) return false; else break;
}
return !cloner.clones.containsKey(tree.symbol());
}
/**
* Clones the given symbol. The default implementation invokes
* getOwnerOfCloneOf to obtain the owner of the cloned symbol and
* then invokes the symbol cloner to clone the symbol.
*/
public Symbol cloneSymbol(Symbol symbol) {
return cloner.cloneSymbol(symbol);
}
/**
* Traverses the tree and clones symbols. The default
* implemenation invokes cloneSymbol with the symbol of every tree
* nodes for which mustCloneSymbolOf returns true.
*/
public void traverse(Tree tree) {
if (mustCloneSymbolOf(tree)) cloneSymbol(tree.symbol());
// !!!replace Idents in patterns by ValDefs and remove this switch
switch (tree) {
case PatDef(_, Tree pat, Tree rhs):
inPattern = true;
traverse(pat);
inPattern = false;
traverse(rhs);
return;
case CaseDef(Tree pat, Tree guard, Tree body):
inPattern = true;
traverse(pat);
inPattern = false;
traverse(guard);
traverse(body);
return;
default:
super.traverse(tree);
return;
}
}
//########################################################################
}
|