Method from com.sun.tools.javac.code.Scope Detail: |
public void addScopeListener(ScopeListener sl) {
listeners = listeners.prepend(sl);
}
|
public Scope dup() {
return dup(this.owner);
}
Construct a fresh scope within this scope, with same owner,
which shares its table with the outer scope. Used in connection with
method leave if scope access is stack-like in order to avoid allocation
of fresh tables. |
public Scope dup(Symbol newOwner) {
Scope result = new Scope(this, newOwner, this.table, this.nelems);
shared++;
// System.out.println("==== > duping scope " + this.hashCode() + " owned by " + newOwner + " to " + result.hashCode());
// new Error().printStackTrace(System.out);
return result;
}
Construct a fresh scope within this scope, with new owner,
which shares its table with the outer scope. Used in connection with
method leave if scope access is stack-like in order to avoid allocation
of fresh tables. |
public Scope dupUnshared() {
return new Scope(this, this.owner, this.table.clone(), this.nelems);
}
Construct a fresh scope within this scope, with same owner,
with a new hash table, whose contents initially are those of
the table of its outer scope. |
public void enter(Symbol sym) {
Assert.check(shared == 0);
enter(sym, this);
}
Enter symbol sym in this scope. |
public void enter(Symbol sym,
Scope s) {
enter(sym, s, s);
}
|
public void enter(Symbol sym,
Scope s,
Scope origin) {
Assert.check(shared == 0);
if (nelems * 3 >= hashMask * 2)
dble();
int hash = getIndex(sym.name);
Entry old = table[hash];
if (old == null) {
old = sentinel;
nelems++;
}
Entry e = makeEntry(sym, old, elems, s, origin);
table[hash] = e;
elems = e;
//notify listeners
for (List< ScopeListener > l = listeners; l.nonEmpty(); l = l.tail) {
l.head.symbolAdded(sym, this);
}
}
Enter symbol sym in this scope, but mark that it comes from
given scope `s' accessed through `origin'. The last two
arguments are only used in import scopes. |
public void enterIfAbsent(Symbol sym) {
Assert.check(shared == 0);
Entry e = lookup(sym.name);
while (e.scope == this && e.sym.kind != sym.kind) e = e.next();
if (e.scope != this) enter(sym);
}
Enter symbol sym in this scope if not already there. |
public Iterable<Symbol> getElements() {
return getElements(noFilter);
}
|
public Iterable<Symbol> getElements(Filter<Symbol> sf) {
return new Iterable< Symbol >() {
public Iterator< Symbol > iterator() {
return new Iterator< Symbol >() {
private Scope currScope = Scope.this;
private Scope.Entry currEntry = elems;
{
update();
}
public boolean hasNext() {
return currEntry != null;
}
public Symbol next() {
Symbol sym = (currEntry == null ? null : currEntry.sym);
if (currEntry != null) {
currEntry = currEntry.sibling;
}
update();
return sym;
}
public void remove() {
throw new UnsupportedOperationException();
}
private void update() {
skipToNextMatchingEntry();
while (currEntry == null && currScope.next != null) {
currScope = currScope.next;
currEntry = currScope.elems;
skipToNextMatchingEntry();
}
}
void skipToNextMatchingEntry() {
while (currEntry != null && !sf.accepts(currEntry.sym)) {
currEntry = currEntry.sibling;
}
}
};
}
};
}
|
public Iterable<Symbol> getElementsByName(Name name) {
return getElementsByName(name, noFilter);
}
|
public Iterable<Symbol> getElementsByName(Name name,
Filter<Symbol> sf) {
return new Iterable< Symbol >() {
public Iterator< Symbol > iterator() {
return new Iterator< Symbol >() {
Scope.Entry currentEntry = lookup(name, sf);
public boolean hasNext() {
return currentEntry.scope != null;
}
public Symbol next() {
Scope.Entry prevEntry = currentEntry;
currentEntry = currentEntry.next(sf);
return prevEntry.sym;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
|
int getIndex(Name name) {
int h = name.hashCode();
int i = h & hashMask;
// The expression below is always odd, so it is guaranteed
// to be mutually prime with table.length, a power of 2.
int x = hashMask - ((h + (h > > 16)) < < 1);
int d = -1; // Index of a deleted item.
for (;;) {
Entry e = table[i];
if (e == null)
return d >= 0 ? d : i;
if (e == sentinel) {
// We have to keep searching even if we see a deleted item.
// However, remember the index in case we fail to find the name.
if (d < 0)
d = i;
} else if (e.sym.name == name)
return i;
i = (i + x) & hashMask;
}
}
Look for slot in the table.
We use open addressing with double hashing. |
public boolean includes(Symbol c) {
for (Scope.Entry e = lookup(c.name);
e.scope == this;
e = e.next()) {
if (e.sym == c) return true;
}
return false;
}
Given a class, is there already a class with same fully
qualified name in this (import) scope? |
public Scope leave() {
Assert.check(shared == 0);
if (table != next.table) return next;
while (elems != null) {
int hash = getIndex(elems.sym.name);
Entry e = table[hash];
Assert.check(e == elems, elems.sym);
table[hash] = elems.shadowed;
elems = elems.sibling;
}
Assert.check(next.shared > 0);
next.shared--;
next.nelems = nelems;
// System.out.println("==== > leaving scope " + this.hashCode() + " owned by " + this.owner + " to " + next.hashCode());
// new Error().printStackTrace(System.out);
return next;
}
Remove all entries of this scope from its table, if shared
with next. |
public Entry lookup(Name name) {
return lookup(name, noFilter);
}
Return the entry associated with given name, starting in
this scope and proceeding outwards. If no entry was found,
return the sentinel, which is characterized by having a null in
both its scope and sym fields, whereas both fields are non-null
for regular entries. |
public Entry lookup(Name name,
Filter<Symbol> sf) {
Entry e = table[getIndex(name)];
if (e == null || e == sentinel)
return sentinel;
while (e.scope != null && (e.sym.name != name || !sf.accepts(e.sym)))
e = e.shadowed;
return e;
}
|
Entry makeEntry(Symbol sym,
Entry shadowed,
Entry sibling,
Scope scope,
Scope origin) {
return new Entry(sym, shadowed, sibling, scope);
}
|
public void remove(Symbol sym) {
Assert.check(shared == 0);
Entry e = lookup(sym.name);
if (e.scope == null) return;
// remove e from table and shadowed list;
int i = getIndex(sym.name);
Entry te = table[i];
if (te == e)
table[i] = e.shadowed;
else while (true) {
if (te.shadowed == e) {
te.shadowed = e.shadowed;
break;
}
te = te.shadowed;
}
// remove e from elems and sibling list
te = elems;
if (te == e)
elems = e.sibling;
else while (true) {
if (te.sibling == e) {
te.sibling = e.sibling;
break;
}
te = te.sibling;
}
//notify listeners
for (List< ScopeListener > l = listeners; l.nonEmpty(); l = l.tail) {
l.head.symbolRemoved(sym, this);
}
}
Remove symbol from this scope. Used when an inner class
attribute tells us that the class isn't a package member. |
public String toString() {
StringBuilder result = new StringBuilder();
result.append("Scope[");
for (Scope s = this; s != null ; s = s.next) {
if (s != this) result.append(" | ");
for (Entry e = s.elems; e != null; e = e.sibling) {
if (e != s.elems) result.append(", ");
result.append(e.sym);
}
}
result.append("]");
return result.toString();
}
|