public final class SymbolGenerator extends java.lang.Object
The generated name follows the patter __$$_<name>_<counter>
.
The default name is symbol
.
The generator maintains a stack of scope names, to generate hierarchical names.
SymbolGenerator sym = new SymbolGenerator("closure");
sym.current(); // __$$_closure_0
sym.next(); // __$$_closure_1
sym.current(); // __$$_closure_1
sym.enter("scope");
sym.next(); // __$$_closure_scope_2
sym.enter("subscope");
sym.next(); // __$$_closure_scope_subscope_3
sym.exit().exit();
sym.next(); // __$$_closure_4
Since the counter maintains uniqueness, the name and scopes only purpose is to give somewhat readable names to help debugging.
Be warned that the uniqueness is only preserved in the context of a single generator. Two independent generators with the same name (and scope) can produce identical names.
A counter is used instead of e.g. the generation timestamp or a random number to guarantee stability across compilations to ease debugging.
If a true uniqueness is require, or if the somewhat predictability of the symbol is a concern, one can use
getFor(String)
or even next(String)
in conjunction with System.nanoTime()
or
Random.nextLong()
(for instance sym.next(String.valueOf(System.nanoTime()))
Modifier and Type | Field and Description |
---|---|
static java.lang.String |
DEFAULT_NAME |
static java.lang.String |
ESCAPE_MANGLE |
static java.lang.String |
JOIN |
static java.lang.String |
PREFIX |
Constructor and Description |
---|
SymbolGenerator() |
SymbolGenerator(java.lang.String name) |
Modifier and Type | Method and Description |
---|---|
java.lang.String |
current()
Generate the name for the current context.
|
java.lang.String |
current(java.lang.String name)
Generate the name for the current context and given simple name.
|
SymbolGenerator |
enter(java.lang.String scopeName)
Enter a hierarchical scope.
|
SymbolGenerator |
exit()
Exit from a scope.
|
java.lang.String |
getFor(java.lang.String localName)
Mangles the given name without using the counter.
|
java.lang.String |
next()
Generates the next name for the current context.
|
java.lang.String |
next(java.lang.String name)
Generates the next name for the current context and given simple name.
|
public static final java.lang.String PREFIX
public static final java.lang.String DEFAULT_NAME
public static final java.lang.String ESCAPE_MANGLE
public static final java.lang.String JOIN
public SymbolGenerator(java.lang.String name)
public SymbolGenerator()
public java.lang.String next()
Increments the counter and returns the name generated by the current scope and counter.
public java.lang.String next(java.lang.String name)
Increments the counter and returns the name generated by the given name and the current scope and counter, and increment it.
Warning: no check is made that the given name will produce a valid language symbol.
name
- the simple name to derive the unique name frompublic java.lang.String getFor(java.lang.String localName)
This can be used in macros to provide hygiene by mangling the local variable names. Mangling is escaped for
names beginning by ESCAPE_MANGLE
.
For instance:
let symb = SymbolGenerator("foo")
symb: getFor("bar") # __$$_foo_bar
symb: getFor("$bar") # bar
Warning: no check is made that the given name will produce a valid language symbol.
public java.lang.String current(java.lang.String name)
Returns the name generated by the given name and the current scope and counter, without incrementing it.
Warning: no check is made that the given name will produce a valid language symbol.
name
- the simple name to derive the unique name frompublic java.lang.String current()
Returns the name generated by the current scope and counter, without incrementing it.
public SymbolGenerator exit()
public SymbolGenerator enter(java.lang.String scopeName)
Warning: no check is made that the given name will produce a valid language symbol.
scopeName
- the name of the scope.