// Transmogrify License // // Copyright (c) 2001, ThoughtWorks, Inc. // All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // - Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // - Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // Neither the name of the ThoughtWorks, Inc. nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.puppycrawl.tools.checkstyle.checks.usage.transmogrify; import java.io.File; import java.util.Hashtable; import java.util.Stack; /** * this class contains all of the definitions, references, and scopes * created by the system. * * Other stuff this class does: * <ul> * <li> holds the "base" scope containing primitive definitions * <li> holds the java.lang package * <li> holds the definition of java.lang.Object, which is the base class * of all class hierarchies * <li> kicks off the resolve step * <li> does some of the work of constructing object definitions * </ul> */ public class SymbolTable { private Hashtable packages = new Hashtable(); private Stack scopes = new Stack(); private ScopeIndex index = new ScopeIndex(); private File currentFile; private BaseScope baseScope; private SymTabAST root; // private boolean outOfDate; /** * constructor takes <code>SymTabAST</code> * @param aRoot root of the <code>SymTabAST</code> tree */ public SymbolTable(SymTabAST aRoot) { scopes = new Stack(); this.root = aRoot; baseScope = new BaseScope( this ); pushScope(baseScope); } /** * gets the root node * @return <code>SymTabAST</code> */ public SymTabAST getTree() { return root; } // /** // * sets the <code>outOfDate</code> data member to <code>true</code> // * @return <code>void</code> // */ // public void expire() { // outOfDate = true; // } // // /** // * sets <code>outOfDate</code> member to <code>false</code> // * @param lastUpdated // * @return <code>void</code> // */ // public void update(long lastUpdated) { // outOfDate = false; // } /** * returns the "base" scope * * @return Scope the base scope */ // REDTAG -- this should eventually be replaced by a call // to the lookup method that traverses scopes public BaseScope getBaseScope() { return baseScope; } /** * returns the current scope. Scopes are nested in a stack (FIFO queue) * and pushed/popped based on the structure of the AST * @return <code>Scope</code> */ public Scope getCurrentScope() { return (Scope)scopes.peek(); } /** * pushes a new scope onto the stack * * @param scope the <code>Scope</code> to push * @return <code>void</code> */ public void pushScope(Scope scope) { scopes.push(scope); } /** * pops a scope from the stack. * * @return <code>Scope</code> * */ public Scope popScope() { Scope scope = (Scope)(scopes.pop()); return scope; } /** * gets all packages stored in this symbol table * @return <code>Hashtable</code> */ public Hashtable getPackages() { // REDTAG -- think about making this available as something simpler, // perhaps an enumeration return packages; } /** * gets package by its name * @param name * @return <code>PackageDef</code> */ public PackageDef getPackage( String name ) { return (PackageDef)(packages.get( name )); } /** * adds <code>PackageDef</code> to its parent scope and stores the * <code>PackageDef</code> in <code>packages</code> * @param pkg * @param parent * @return <code>void</code> */ public void definePackage( PackageDef pkg, Scope parent ) { parent.addDefinition(pkg); packages.put(pkg.getQualifiedName(), pkg); } /** * defines a class in the symbol table. * * @param def the class to define * @return <code>void</code> * @see #indexScope(Scope) * @see #getCurrentScope() */ public void defineClass(ClassDef def) { indexScope(def); getCurrentScope().addDefinition(def); } /** * defines a method in the symbol table * * @param method the method to be defined * @return <code>void</code> * @see #indexScope(Scope) * @see #getCurrentScope() */ public void defineMethod(MethodDef method) { indexScope(method); ((ClassDef)getCurrentScope()).addDefinition(method); } /** * defines a variable in the symbol table * * @param v the variable to define * @return <code>void</code> * @see #getCurrentScope() */ public void defineVariable(VariableDef v) { getCurrentScope().addDefinition(v); } /** * defines a block within the symbol table * * @param blockDef the block to define * @return <code>void</code> * @see #indexScope(Scope) * @see #getCurrentScope() */ public void defineBlock(BlockDef blockDef) { indexScope(blockDef); getCurrentScope().addDefinition(blockDef); } /** * defines a label within the symbol table * * @param labelDef the label to define * @return <code>void</code> * @see #getCurrentScope() */ // REDTAG -- label does not define a new scope public void defineLabel(LabelDef labelDef) { getCurrentScope().addDefinition(labelDef); } /** * places a scope in the symbol table's index * * @param scope the scope to index * @return <code>void</code> */ public void indexScope(Scope scope) { index.addScope(scope); } /** * gets the symbol table's scope index * * @return ScopeIndex */ public ScopeIndex getScopeIndex() { return index; } /** * sets the current file that the symbol table is processing * * @param file the <code>File</code> to use * @return <code>void</code> */ public void setCurrentFile(File file) { currentFile = file; } /** * gets the file that the symbol table is currently processing * * @return <code>File</code> */ public File getCurrentFile() { return currentFile; } }