|
|
/* ____ ____ ____ ____ ______ *\
** / __// __ \/ __// __ \/ ____/ 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 + symbol.id;
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();
}
//########################################################################
}
|