View Javadoc

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