import java.io.*;
import java.util.*;
-/** A JavaScript Scope */
+/** Implementation of a JavaScript Scope */
class ScopeImpl extends JS.Obj {
private JS.Scope parentScope;
- private static Object NULL = new Object();
- public ScopeImpl(JS.Scope parentScope) { this(parentScope, false); }
+ private static final Object NULL_PLACEHOLDER = new Object();
public ScopeImpl(JS.Scope parentScope, boolean sealed) {
super(sealed);
if (parentScope == this) throw new Error("can't make a scope its own parent!");
this.parentScope = parentScope;
}
- public JS.Scope getParentScope() { return parentScope; }
-
- // transparent scopes are not returned by THIS
- public boolean isTransparent() { return false; }
-
+ public Object[] keys() { throw new Error("you can't enumerate the properties of a Scope"); }
public boolean has(Object key) { return super.get(key) != null; }
- public Object get(Object key) {
- if (!has(key)) return parentScope == null ? null : getParentScope().get(key);
- Object ret = super.get(key); return ret == NULL ? null : ret;
- }
- public void put(Object key, Object val) {
- if (!has(key) && parentScope != null) getParentScope().put(key, val);
- else super.put(key, val == null ? NULL : val);
+ // we use _get instead of get solely to work around a GCJ bug
+ public Object _get(Object key) {
+ Object o = super.get(key);
+ if (o != null) return o == NULL_PLACEHOLDER ? null : o;
+ else return parentScope == null ? null : parentScope.get(key);
}
- public Object[] keys() { throw new Error("you can't enumerate the properties of a Scope"); }
- public void declare(String s) {
- if (isTransparent()) getParentScope().declare(s);
- else super.put(s, NULL);
+ // we use _put instead of put solely to work around a GCJ bug
+ public void _put(Object key, Object val) {
+ if (parentScope != null && !has(key)) parentScope.put(key, val);
+ else super.put(key, val == null ? NULL_PLACEHOLDER : val);
}
-}
+ public boolean isTransparent() { return false; }
+ public void declare(String s) { super.put(s, NULL_PLACEHOLDER); }
+ public Scope getParentScope() { return parentScope; }
+}
+