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     /***
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 }