summaryrefslogblamecommitdiff
path: root/sources/scalac/symtab/SymbolNameWriter.java
blob: bd4b17c9061fef3dec184c83e1bbd9b037c4eb41 (plain) (tree)














































































                                                                              


                                                              







































































































                                                                              



                                                   



                                                        



                                                              



                                                                



                                                              



                                                                



                                                                         



                                                                        


                                                                              









                                                                     






                                                                    





                                                                    









                                                                  

























                                                                               
                                                   





                                                                      
                                                       




                                                             
                                                  
                         
                           









                                                                              
/*     ____ ____  ____ ____  ______                                     *\
**    / __// __ \/ __// __ \/ ____/    SOcos COmpiles Scala             **
**  __\_ \/ /_/ / /__/ /_/ /\_ \       (c) 2002, LAMP/EPFL              **
** /_____/\____/\___/\____/____/                                        **
\*                                                                      */

// $Id$

package scalac.symtab;

import scalac.Global;
import scalac.util.NameTransformer;

/**
 * This class provides methods to turn symbol names into strings.
 *
 * There are several kinds of owner/symbol relationships:
 *  - root/symbol
 *  - package/symbol
 *  - class/class
 *  - class/member
 *  - owner/parameter
 *  - none/symbol
 *  - error/symbol
 *  - other relationships
 *
 * The separator to use for each of these relationships are specified
 * independently. When a separator is set to '\0' the corresponding
 * owners are dropped from the resulting string. ROOT, NONE and ERROR
 * owners are also dropped. The choice of the separator to use is done
 * by the method "getOwnerSymbolSeparator(Symbol)"
 *
 * Symbol names are usually encoded. There is support to decode these
 * names.
 *
 * Each symbol has an unique identifier. There is support to print
 * these unique identifiers.
 */
public class SymbolNameWriter {

    //########################################################################
    // Private Fields

    /** The string buffer */
    private StringBuffer buffer;

    /** The root/symbol separator */
    private char root;

    /** The package/symbol separator */
    private char peckage;

    /** The class/class separator */
    private char clasz;

    /** The class/member separator */
    private char member;

    /** The owner/parameter separator */
    private char parameter;

    /** The none/symbol separator */
    private char none;

    /** The error/symbol separator */
    private char error;

    /** The other relationships separator */
    private char other;

    /** The name decoding status */
    private boolean decode;

    /** The symbol/unique-identifier separator */
    private char unique;

    /** The number of pending characters */
    private int pending;

    /** The prefix for the current operation (null if none) */
    private String prefix;

    //########################################################################
    // Public Constructors

    /**
     * Initializes this instance with an empty string buffer. This is
     * equivalent to calling "SymbolStringifier(null)".
     */
    public SymbolNameWriter() {
        this(null);
    }

    /**
     * Initializes this instance with given string buffer. All
     * separators are set to '.' excepted the root/symbol separator
     * which is set to '\0'. The symbol name decoding is disabled. The
     * unique identifier printing is disabled.
     */
    public SymbolNameWriter(StringBuffer buffer) {
        setStringBuffer(buffer).setAllSeparators('.').setRootSeparator('\0');
    }

    //########################################################################
    // Public Method - Configuration operations

    /** Sets the string buffer. */
    public SymbolNameWriter setStringBuffer(StringBuffer buffer) {
        this.buffer = buffer;
        return this;
    }

    /** Sets all separators. */
    public SymbolNameWriter setAllSeparators(char separator) {
        setRootSeparator(separator);
        setPackageSeparator(separator);
        setClassSeparator(separator);
        setMemberSeparator(separator);
        setParameterSeparator(separator);
        setNoneSeparator(separator);
        setErrorSeparator(separator);
        setOtherSeparator(separator);
        return this;
    }

    /** Sets the root/symbol separator. */
    public SymbolNameWriter setRootSeparator(char separator) {
        this.root = separator;
        return this;
    }

    /** Sets the package/symbol separator. */
    public SymbolNameWriter setPackageSeparator(char separator) {
        this.peckage = separator;
        return this;
    }

    /** Sets the class/class separator. */
    public SymbolNameWriter setClassSeparator(char separator) {
        this.clasz = separator;
        return this;
    }

    /** Sets the class/member separator. */
    public SymbolNameWriter setMemberSeparator(char separator) {
        this.member = separator;
        return this;
    }

    /** Sets the owner/parameter separator. */
    public SymbolNameWriter setParameterSeparator(char separator) {
        this.parameter = separator;
        return this;
    }

    /** Sets the none/symbol separator. */
    public SymbolNameWriter setNoneSeparator(char separator) {
        this.none = separator;
        return this;
    }

    /** Sets the error/symbol separator. */
    public SymbolNameWriter setErrorSeparator(char separator) {
        this.error = separator;
        return this;
    }

    /** Sets the other relationships separator. */
    public SymbolNameWriter setOtherSeparator(char separator) {
        this.other = separator;
        return this;
    }

    /** Sets the name decoding status. */
    public SymbolNameWriter setNameDecoding(boolean decode) {
        this.decode = decode;
        return this;
    }

    /** Sets the symbol/unique-identifier separator. */
    public SymbolNameWriter setUniqueSeparator(char separator) {
        this.unique = separator;
        return this;
    }

    //########################################################################
    // Public Method - To string operations

    /** Returns the string formed by the symbol. */
    public String toString(Symbol symbol) {
        assert buffer == null;
        String string = appendSymbol(symbol).toString();
        setStringBuffer(null);
        return string;
    }

    /** Returns the string formed by the prefix and symbol. */
    public String toString(String prefix, Symbol symbol) {
        assert buffer == null;
        String string = appendSymbol(prefix, symbol).toString();
        setStringBuffer(null);
        return string;
    }

    /** Returns the string formed by the symbol and suffix. */
    public String toString(Symbol symbol, String suffix) {
        assert buffer == null;
        String string = appendSymbol(symbol, suffix).toString();
        setStringBuffer(null);
        return string;
    }

    /** Returns the string formed by the prefix, symbol and suffix. */
    public String toString(String prefix, Symbol symbol, String suffix) {
        assert buffer == null;
        String string = appendSymbol(prefix, symbol, suffix).toString();
        setStringBuffer(null);
        return string;
    }

    //########################################################################
    // Public Method - Append operations

    /** Appends given symbol. */
    public StringBuffer appendSymbol(Symbol symbol) {
        String name = getSymbolName(symbol);
        this.pending += name.length();
        char separator = getSymbolSeparator(symbol);
        return appendPrefix(symbol.owner(), separator).append(name);;
    }

    /** Appends given prefix and symbol. */
    public StringBuffer appendSymbol(String prefix, Symbol symbol) {
        assert this.prefix == null && prefix != null;
        this.prefix = prefix;
        return appendSymbol(symbol);
    }

    /** Appends given symbol and suffix. */
    public StringBuffer appendSymbol(Symbol symbol, String suffix) {
        this.pending += suffix.length();
        return appendSymbol(symbol).append(suffix);
    }

    /** Appends given prefix, symbol and suffix. */
    public StringBuffer appendSymbol(String prefix, Symbol symbol,
        String suffix)
    {
        assert this.prefix == null && prefix != null;
        this.prefix = prefix;
        this.pending += suffix.length();
        return appendSymbol(symbol).append(suffix);
    }

    /** Appends prefix formed by given owner and separator. */
    public StringBuffer appendPrefix(Symbol owner, char separator) {
        if (separator == 0) return getStringBuffer();
        this.pending += 1;
        return appendSymbol(owner).append(separator);
    }

    //########################################################################
    // Public Method - Query operations

    /** Returns the name to use for given symbol. */
    public String getSymbolName(Symbol symbol) {
        String name = symbol.name.toString();
        if (decode) name = NameTransformer.decode(name);
        if (unique != 0) name =name+unique+Global.instance.uniqueID.id(symbol);
        return name;
    }

    /** Returns the owner/symbol separator to use for given symbol. */
    public char getSymbolSeparator(Symbol symbol) {
        if (symbol.isRoot() || symbol.isNone() || symbol.isError()) return 0;
        if (symbol.isParameter()) return parameter;
        Symbol owner = symbol.owner();
        if (owner.isRoot()) return root;
        if (owner.isNone()) return none;
        if (owner.isError()) return error;
        if (owner.isPackageClass()) return peckage;
        if (owner.isClass()) return symbol.isClass() ? clasz : member;
        return other;
    }

    /** Returns the string buffer. */
    public StringBuffer getStringBuffer() {
        if (prefix != null) pending += prefix.length();
        if (buffer == null) {
            this.buffer = new StringBuffer(pending);
        } else {
            buffer.ensureCapacity(buffer.length() + pending);
        }
        if (prefix != null) buffer.append(prefix);
        this.pending = 0;
        this.prefix = null;
        return buffer;
    }

    /** Returns the content of the string buffer. */
    public String toString() {
        return buffer == null ? "" : buffer.toString();
    }

    //########################################################################
}