1 package net.sourceforge.pmd.cpd.cppast;
2
3 import java.util.Hashtable;
4
5 /***
6 * Manages the symbol table and scopes within a given compilation unit.
7 */
8 public class SymtabManager
9 {
10 /***
11 * Global symbol table indexed by the name of the scope (class/function).
12 */
13 static Hashtable scopeTable = new Hashtable();
14
15 /***
16 * Stack of scopes. Currently max. nesting allowed is 100.
17 */
18 static Scope[] scopeStack = new Scope[100];
19
20 /***
21 * Current depth of scope nesting.
22 */
23 static int depth = 0;
24
25 /***
26 * Dummy at the bottom of the stack so that no need to check for null.
27 */
28 static
29 {
30 scopeStack[depth] = new Scope(null);
31 }
32
33 /***
34 * Opens a new scope (with optional name and type flag).
35 */
36 public static Scope OpenScope(String scopeName, boolean isType)
37 {
38 Scope newScope;
39
40 if (scopeName != null)
41 {
42 if (isType)
43 {
44 newScope = new ClassScope(scopeName, scopeStack[depth]);
45 scopeStack[depth].PutTypeName(scopeName, newScope);
46 }
47 else
48 {
49 newScope = new Scope(scopeName, isType, scopeStack[depth]);
50 }
51
52 scopeTable.put(scopeName, newScope);
53 }
54 else
55 newScope = new Scope(scopeStack[depth]);
56
57 scopeStack[++depth] = newScope;
58 return newScope;
59 }
60
61 public static void OpenScope(Scope sc)
62 {
63 scopeStack[++depth] = sc;
64 }
65
66 public static void PutTypeName(String name)
67 {
68 scopeStack[depth].PutTypeName(name);
69 }
70
71 public static boolean IsFullyScopedTypeName(String name)
72 {
73 if (name == null)
74 return false;
75
76 if (name.indexOf("::") == -1)
77 return IsTypeName(name);
78
79 Scope sc = GetScopeOfFullyScopedName(name);
80
81 if (sc != null)
82 return sc.IsTypeName(name.substring(name.lastIndexOf("::") + 2,
83 name.length()));
84
85 return false;
86 }
87
88 public static boolean IsTypeName(String name)
89 {
90 int i = depth;
91
92 while (i >= 0)
93 {
94 if (scopeStack[i--].IsTypeName(name))
95 return true;
96 }
97
98 return false;
99 }
100
101 public static void CloseScope()
102 {
103 depth--;
104 }
105
106 /***
107 * For now, we just say if it is a class name, it is OK to call it a
108 * constructor.
109 */
110 public static boolean IsCtor(String name)
111 {
112 if (name == null)
113 return false;
114
115 if (name.indexOf("::") == -1)
116 return GetScope(name) != null;
117
118 Scope sc = GetScopeOfFullyScopedName(name);
119
120 if (sc != null && sc.parent != null)
121 return sc.parent.GetScope(name.substring(name.lastIndexOf("::") + 2,
122 name.length())) == sc;
123
124 return false;
125 }
126
127 public static Scope GetCurScope()
128 {
129 return scopeStack[depth];
130 }
131
132 public static Scope GetScope(String name)
133 {
134 int i = depth;
135 Scope sc = null;
136
137 while (i >= 0)
138 if ((sc = scopeStack[i--].GetScope(name)) != null)
139 return sc;
140
141 return null;
142 }
143
144 /***
145 * Returns the Scope of B in A::B::C.
146 */
147 public static Scope GetScopeOfFullyScopedName(String name)
148 {
149 Scope sc;
150 int i = 0, j = 0;
151
152 if (name.indexOf("::") == -1)
153 return GetScope(name);
154
155 if (name.indexOf("::") == 0)
156 {
157 sc = scopeStack[1];
158 j = 2;
159 }
160 else
161 sc = GetCurScope();
162
163 String tmp = name.substring(j, name.lastIndexOf("::"));
164
165 while ((j = tmp.indexOf("::", i)) != -1)
166 {
167 sc = sc.GetScope(tmp.substring(i, j));
168 i = j + 2;
169
170 if (sc == null)
171 return null;
172 }
173
174 if (sc == GetCurScope())
175 return GetScope(tmp.substring(i, tmp.length()));
176
177 return sc.GetScope(tmp.substring(i, tmp.length()));
178 }
179
180 public static boolean IsGlobalScope()
181 {
182 return depth == 1 || depth == 2;
183 }
184 }
This page was automatically generated by Maven