package code.symbols;

/**
 * Abstracts a Symbol in the term rewrite system.
 *
 * @author jimeng
 * @since October 22, 2002
 */
public abstract class Symbol {
    /**
     * Constant for Public Visibility of a symbol.
     */

    public static final int Public = 0;
    /**
     * Constant for Private Visibility of a symbol.
     */

    public static final int Private = Public + 1;

    /**
     * Constant for DefaultVisibility Visibility of a symbol.
     * TODO: This constant should go away eventually.
     * it is used in exactly 2 places right now.
     * one of them is (table) slated to be removed shortly.
     */
    public static final int DefaultVisibility = Private + 1;

    /**
     * Symbols's Name
     */
    public final String symbolName;

    /**
     * The name of the module file that contains this symbol.
     */
    public final String moduleName;

    /**
     * Specifies the Visibility of this symbol.
     * The valid values are defined by the static data members of this class
     * Public, Private and DefaultVisibility
     */
    public final int visibility;
    //later visibility should be one byte

    /**
     * Constructor for the Symbol object
     *
     * @param moduleName Symbol's ModuleName.
     * @param symbolName Symbol's Name
     * @param visibility Symbol's Visibility
     */
    public Symbol(String moduleName, String symbolName, int visibility) {
        this.moduleName = moduleName;
        this.symbolName = symbolName;
        this.visibility = visibility;
    }

    /**
     * Description of the Method
     * 
     * @param v Description of the Parameter
     * @param o Description of the Parameter
     * @return Description of the Return Value
     */
    public abstract Object accept(SymbolVisitor v, Object o);


    /**
     * This method compares whether a given object is equal to this
     * Symbol object. This is true if it is a Symbol object and both
     * its symbolName and moduleName fields are equal to this object's
     * value for those fields. Otherwise, false is returned,
     *
     * @param anObject The object to compare this Symbol against.
     * @return True if the two Symbols are equal, false otherwise.
     */
    public boolean equals(Object anObject) {
        if (anObject instanceof Symbol) {
            Symbol aSymbol = (Symbol) anObject;
            if (symbolName.equals(aSymbol.symbolName)) {
                return true;
            }
        }
        return false; // true test must have fell through to here.
    }

}

