1. Recently introduced ScriptableObject.default(Prototype|ParentScope)() methods had problems with serialization and are removed now. XML code explicitly sets parent/prototype. To simplify that ScriptableObject now contains a special constructor taking scope and prototype arguments.

2. xml/XMLObject do not define lib() method and instead defines few abstract methods to create "with" proxies and perform addition.

3. XMLLib implementation is stored in the scope using ScriptableObject.associateValue() and does not depend on presence of proper XML object.
This commit is contained in:
igor%mir2.org 2004-08-04 12:54:03 +00:00
Родитель 3d37dd81d3
Коммит 4a8da93dda
18 изменённых файлов: 329 добавлений и 317 удалений

Просмотреть файл

@ -56,6 +56,15 @@ public class BaseFunction extends IdScriptableObject implements Function
obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
}
public BaseFunction()
{
}
public BaseFunction(Scriptable scope, Scriptable prototype)
{
super(scope, prototype);
}
public String getClassName() {
return "Function";
}

Просмотреть файл

@ -1099,69 +1099,9 @@ public class Context
public ScriptableObject initStandardObjects(ScriptableObject scope,
boolean sealed)
{
if (scope == null) {
scope = new NativeObject();
}
(new ClassCache()).associate(scope);
BaseFunction.init(this, scope, sealed);
NativeObject.init(this, scope, sealed);
Scriptable objectProto = ScriptableObject.getObjectPrototype(scope);
// Function.prototype.__proto__ should be Object.prototype
Scriptable functionProto = ScriptableObject.getFunctionPrototype(scope);
functionProto.setPrototype(objectProto);
// Set the prototype of the object passed in if need be
if (scope.getPrototype() == null)
scope.setPrototype(objectProto);
// must precede NativeGlobal since it's needed therein
NativeError.init(this, scope, sealed);
NativeGlobal.init(this, scope, sealed);
NativeArray.init(this, scope, sealed);
NativeString.init(this, scope, sealed);
NativeBoolean.init(this, scope, sealed);
NativeNumber.init(this, scope, sealed);
NativeDate.init(this, scope, sealed);
NativeMath.init(this, scope, sealed);
NativeWith.init(this, scope, sealed);
NativeCall.init(this, scope, sealed);
NativeScript.init(this, scope, sealed);
boolean withXml = hasFeature(FEATURE_E4X);
for (int i = 0; i != lazilyNames.length; i += 2) {
String topProperty = lazilyNames[i];
String className = lazilyNames[i + 1];
if (!withXml && className == XML_INIT_CLASS) {
continue;
}
new LazilyLoadedCtor(scope, topProperty, className, sealed);
}
return scope;
return ScriptRuntime.initStandardObjects(this, scope, sealed);
}
private static final String
XML_INIT_CLASS = "org.mozilla.javascript.xmlimpl.XMLLibImpl";
private static final String[] lazilyNames = {
"RegExp", "org.mozilla.javascript.regexp.NativeRegExp",
"Packages", "org.mozilla.javascript.NativeJavaTopPackage",
"java", "org.mozilla.javascript.NativeJavaTopPackage",
"getClass", "org.mozilla.javascript.NativeJavaTopPackage",
"JavaAdapter", "org.mozilla.javascript.JavaAdapter",
"JavaImporter", "org.mozilla.javascript.ImporterTopLevel",
"XML", XML_INIT_CLASS,
"XMLList", XML_INIT_CLASS,
"Namespace", XML_INIT_CLASS,
"QName", XML_INIT_CLASS,
};
/**
* Get the singleton object that represents the JavaScript Undefined value.
*/

Просмотреть файл

@ -41,6 +41,9 @@ public class IdFunctionObject extends BaseFunction
{
public IdFunctionObject(IdFunctionCall idcall, Object tag, int id, int arity)
{
if (arity < 0)
throw new IllegalArgumentException();
this.idcall = idcall;
this.tag = tag;
this.methodId = id;
@ -49,10 +52,20 @@ public class IdFunctionObject extends BaseFunction
}
public IdFunctionObject(IdFunctionCall idcall, Object tag, int id,
String name, int arity, Scriptable scope)
String name, int arity, Scriptable scope)
{
this(idcall, tag, id, arity);
initFunction(name, scope);
super(scope, null);
if (arity < 0)
throw new IllegalArgumentException();
if (name == null)
throw new IllegalArgumentException();
this.idcall = idcall;
this.tag = tag;
this.methodId = id;
this.arity = arity;
this.functionName = name;
}
public void initFunction(String name, Scriptable scope)

Просмотреть файл

@ -323,6 +323,11 @@ public abstract class IdScriptableObject extends ScriptableObject
{
}
public IdScriptableObject(Scriptable scope, Scriptable prototype)
{
super(scope, prototype);
}
public boolean has(String name, Scriptable start)
{
if (maxInstanceId != 0) {

Просмотреть файл

@ -45,8 +45,6 @@ import java.io.*;
import org.mozilla.javascript.debug.*;
import org.mozilla.javascript.xml.XMLObject;
public class Interpreter
{
@ -3202,19 +3200,15 @@ switch (op) {
if (lhs == DBL_MRK) {
sDbl[stackTop] += rDbl;
} else {
do_add(lhs, rDbl, stack, sDbl, stackTop, true);
do_add(lhs, rDbl, stack, sDbl, stackTop, true, cx);
}
} else if (lhs == DBL_MRK) {
do_add(rhs, sDbl[stackTop], stack, sDbl, stackTop, false);
do_add(rhs, sDbl[stackTop], stack, sDbl, stackTop, false, cx);
} else {
if (lhs instanceof XMLObject || rhs instanceof XMLObject) {
if (lhs instanceof Scriptable || rhs instanceof Scriptable) {
stack[stackTop] = ScriptRuntime.add(lhs, rhs, cx);
return stackTop;
}
if (lhs instanceof Scriptable)
lhs = ((Scriptable) lhs).getDefaultValue(null);
if (rhs instanceof Scriptable)
rhs = ((Scriptable) rhs).getDefaultValue(null);
if (lhs instanceof String) {
String lstr = (String)lhs;
String rstr = ScriptRuntime.toString(rhs);
@ -3239,14 +3233,17 @@ switch (op) {
private static void do_add
(Object lhs, double rDbl,
Object[] stack, double[] stackDbl, int stackTop,
boolean left_right_order)
boolean left_right_order, Context cx)
{
if (lhs instanceof Scriptable) {
if (lhs == Undefined.instance) {
lhs = ScriptRuntime.NaNobj;
} else {
lhs = ((Scriptable)lhs).getDefaultValue(null);
Object rhs = doubleWrap(rDbl);
if (!left_right_order) {
Object tmp = lhs;
lhs = rhs;
rhs = tmp;
}
stack[stackTop] = ScriptRuntime.add(lhs, rhs, cx);
return;
}
if (lhs instanceof String) {
String lstr = (String)lhs;

Просмотреть файл

@ -357,9 +357,9 @@ class JavaMembers
ht.put(name, field);
} else if (member instanceof NativeJavaMethod) {
NativeJavaMethod method = (NativeJavaMethod) member;
FieldAndMethods fam = new FieldAndMethods(method.methods,
FieldAndMethods fam = new FieldAndMethods(scope,
method.methods,
field);
fam.setPrototype(ScriptableObject.getFunctionPrototype(scope));
getFieldAndMethodsTable(isStatic).put(name, fam);
ht.put(name, fam);
} else if (member instanceof Field) {
@ -583,7 +583,7 @@ class JavaMembers
Enumeration e = ht.elements();
while (len-- > 0) {
FieldAndMethods fam = (FieldAndMethods) e.nextElement();
FieldAndMethods famNew = new FieldAndMethods(fam.methods,
FieldAndMethods famNew = new FieldAndMethods(scope, fam.methods,
fam.field);
famNew.javaObject = javaObject;
result.put(fam.field.getName(), famNew);
@ -664,10 +664,12 @@ class BeanProperty
class FieldAndMethods extends NativeJavaMethod
{
FieldAndMethods(MemberBox[] methods, Field field)
FieldAndMethods(Scriptable scope, MemberBox[] methods, Field field)
{
super(methods);
this.field = field;
setParentScope(scope);
setPrototype(ScriptableObject.getFunctionPrototype(scope));
}
public Object getDefaultValue(Class hint)

Просмотреть файл

@ -150,7 +150,7 @@ public class NativeWith implements Scriptable, IdFunctionCall {
/**
* Must return null to continue looping or the final collection result.
*/
public Object updateDotQuery(boolean value)
protected Object updateDotQuery(boolean value)
{
// NativeWith itself does not support it
throw new IllegalStateException();

Просмотреть файл

@ -97,6 +97,92 @@ public class ScriptRuntime {
ScriptableObjectClass = Kit.classOrNull("org.mozilla.javascript.ScriptableObject"),
UndefinedClass = Kit.classOrNull("org.mozilla.javascript.Undefined");
private static final String
XML_INIT_CLASS = "org.mozilla.javascript.xmlimpl.XMLLibImpl";
private static final String[] lazilyNames = {
"RegExp", "org.mozilla.javascript.regexp.NativeRegExp",
"Packages", "org.mozilla.javascript.NativeJavaTopPackage",
"java", "org.mozilla.javascript.NativeJavaTopPackage",
"getClass", "org.mozilla.javascript.NativeJavaTopPackage",
"JavaAdapter", "org.mozilla.javascript.JavaAdapter",
"JavaImporter", "org.mozilla.javascript.ImporterTopLevel",
"XML", XML_INIT_CLASS,
"XMLList", XML_INIT_CLASS,
"Namespace", XML_INIT_CLASS,
"QName", XML_INIT_CLASS,
};
private static final Object LIBRARY_SCOPE_KEY = new Object();
public static ScriptableObject initStandardObjects(Context cx,
ScriptableObject scope,
boolean sealed)
{
if (scope == null) {
scope = new NativeObject();
}
scope.associateValue(LIBRARY_SCOPE_KEY, LIBRARY_SCOPE_KEY);
(new ClassCache()).associate(scope);
BaseFunction.init(cx, scope, sealed);
NativeObject.init(cx, scope, sealed);
Scriptable objectProto = ScriptableObject.getObjectPrototype(scope);
// Function.prototype.__proto__ should be Object.prototype
Scriptable functionProto = ScriptableObject.getFunctionPrototype(scope);
functionProto.setPrototype(objectProto);
// Set the prototype of the object passed in if need be
if (scope.getPrototype() == null)
scope.setPrototype(objectProto);
// must precede NativeGlobal since it's needed therein
NativeError.init(cx, scope, sealed);
NativeGlobal.init(cx, scope, sealed);
NativeArray.init(cx, scope, sealed);
NativeString.init(cx, scope, sealed);
NativeBoolean.init(cx, scope, sealed);
NativeNumber.init(cx, scope, sealed);
NativeDate.init(cx, scope, sealed);
NativeMath.init(cx, scope, sealed);
NativeWith.init(cx, scope, sealed);
NativeCall.init(cx, scope, sealed);
NativeScript.init(cx, scope, sealed);
boolean withXml = cx.hasFeature(Context.FEATURE_E4X);
for (int i = 0; i != lazilyNames.length; i += 2) {
String topProperty = lazilyNames[i];
String className = lazilyNames[i + 1];
if (!withXml && className == XML_INIT_CLASS) {
continue;
}
new LazilyLoadedCtor(scope, topProperty, className, sealed);
}
return scope;
}
public static ScriptableObject getLibraryScope(Scriptable scope)
{
scope = ScriptableObject.getTopLevelScope(scope);
do {
if (scope instanceof ScriptableObject) {
ScriptableObject so = (ScriptableObject)scope;
if (null != so.getAssociatedValue(LIBRARY_SCOPE_KEY)) {
return so;
}
}
scope = scope.getPrototype();
} while (scope != null);
throw new IllegalStateException("Failed to find library scope");
}
public static Boolean wrapBoolean(boolean b)
{
return b ? Boolean.TRUE : Boolean.FALSE;
@ -2171,20 +2257,18 @@ public class ScriptRuntime {
return new Double(((Number)val1).doubleValue() +
((Number)val2).doubleValue());
}
if (val1 instanceof XMLObject && val2 instanceof XMLObject) {
XMLObject xml1 = (XMLObject)val1;
XMLObject xml2 = (XMLObject)val2;
XMLLib xmlLib = xml1.lib();
return xmlLib.addXMLObjects(cx, xml1, xml2);
} else if (val1 == Undefined.instance && val2 instanceof XMLObject) {
// Undefined added to any XML or XMLList the undefined needs
// to be "".
val1 = "";
} else if (val2 == Undefined.instance && val1 instanceof XMLObject) {
val2 = "";
if (val1 instanceof XMLObject) {
Object test = ((XMLObject)val1).addValues(cx, true, val2);
if (test != Scriptable.NOT_FOUND) {
return test;
}
}
if (val2 instanceof XMLObject) {
Object test = ((XMLObject)val2).addValues(cx, false, val1);
if (test != Scriptable.NOT_FOUND) {
return test;
}
}
if (val1 instanceof Scriptable)
val1 = ((Scriptable) val1).getDefaultValue(null);
if (val2 instanceof Scriptable)
@ -2792,8 +2876,7 @@ public class ScriptRuntime {
public static Scriptable enterWith(Object value, Scriptable scope) {
if (value instanceof XMLObject) {
XMLObject object = (XMLObject)value;
XMLLib xmlLib = object.lib();
return xmlLib.enterXMLWith(object, scope);
return object.enterWith(scope);
}
return new NativeWith(scope, toObject(scope, value));
}
@ -2812,8 +2895,7 @@ public class ScriptRuntime {
ScriptRuntime.toString(value));
}
XMLObject object = (XMLObject)value;
XMLLib xmlLib = object.lib();
return xmlLib.enterDotQuery(object, scope);
return object.enterDotQuery(scope);
}
public static Object updateDotQuery(boolean value, Scriptable scope)

Просмотреть файл

@ -111,6 +111,19 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
}
}
public ScriptableObject()
{
}
public ScriptableObject(Scriptable scope, Scriptable prototype)
{
if (scope == null)
throw new IllegalArgumentException();
parentScopeObject = scope;
prototypeObject = prototype;
}
/**
* Return the name of the class.
*
@ -434,25 +447,12 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
slot.attributes = (short) attributes;
}
/**
* Returns the default value for prototype of the object.
*/
protected Scriptable defaultPrototype()
{
return null;
}
/**
* Returns the prototype of the object.
*/
public Scriptable getPrototype()
{
Scriptable x = prototypeObject;
if (x == UNSET_SCRIPTABLE_FIELD) {
x = defaultPrototype();
prototypeObject = x;
}
return x;
return prototypeObject;
}
/**
@ -463,26 +463,12 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
prototypeObject = m;
}
/**
* Returns the default value for prototype of the object.
*/
protected Scriptable defaultParentScope()
{
return null;
}
/**
* Returns the parent (enclosing) scope of the object.
*/
public Scriptable getParentScope()
{
Scriptable x = parentScopeObject;
if (x == UNSET_SCRIPTABLE_FIELD) {
x = defaultParentScope();
parentScopeObject = x;
}
return x;
return parentScopeObject;
}
/**
@ -648,7 +634,7 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
* if <tt>this == value</tt> or null otherwise to indicate no custom
* equality is available unless <tt>value</tt> is <tt>this</tt>.
*/
public Boolean equivalentValues(Object value)
protected Boolean equivalentValues(Object value)
{
return (this == value) ? Boolean.TRUE : null;
}
@ -1921,17 +1907,15 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
}
}
private static final Scriptable UNSET_SCRIPTABLE_FIELD = new NativeObject();
/**
* The prototype of this object.
*/
private Scriptable prototypeObject = UNSET_SCRIPTABLE_FIELD;
private Scriptable prototypeObject;
/**
* The parent scope of this object.
*/
private Scriptable parentScopeObject = UNSET_SCRIPTABLE_FIELD;
private Scriptable parentScopeObject;
private static final Object HAS_STATIC_ACCESSORS = Void.TYPE;
private static final Slot REMOVED = new Slot();

Просмотреть файл

@ -39,14 +39,17 @@ import org.mozilla.javascript.*;
public abstract class XMLLib
{
private static final Object XML_LIB_KEY = new Object();
public static XMLLib extractFromScopeOrNull(Scriptable scope)
{
scope = ScriptableObject.getTopLevelScope(scope);
Object testXML = ScriptableObject.getClassPrototype(scope, "XML");
if (testXML instanceof XMLObject) {
return ((XMLObject)testXML).lib();
}
return null;
ScriptableObject so = ScriptRuntime.getLibraryScope(scope);
// Ensure lazily initialization of real XML library instance
// which is done on first access to XML property
ScriptableObject.getProperty(so, "XML");
return (XMLLib)so.getAssociatedValue(XML_LIB_KEY);
}
public static XMLLib extractFromScope(Scriptable scope)
@ -59,6 +62,12 @@ public abstract class XMLLib
throw Context.reportRuntimeError(msg);
}
protected final XMLLib bindToScope(Scriptable scope)
{
ScriptableObject so = ScriptRuntime.getLibraryScope(scope);
return (XMLLib)so.associateValue(XML_LIB_KEY, this);
}
public abstract boolean isXMLName(Context cx, Object name);
public abstract Object toQualifiedName(String namespace,
@ -72,12 +81,6 @@ public abstract class XMLLib
public abstract Reference xmlPrimaryReference(Object nameObject,
Scriptable scope);
public abstract Scriptable enterXMLWith(XMLObject object,
Scriptable scope);
public abstract Scriptable enterDotQuery(XMLObject object,
Scriptable scope);
/**
* Escapes the reserved characters in a value of an attribute
*
@ -95,13 +98,6 @@ public abstract class XMLLib
public abstract String escapeTextValue(Object value);
/**
* Must calculate obj1 + obj2
*/
public abstract Object addXMLObjects(Context cx,
XMLObject obj1,
XMLObject obj2);
/**
* Construct namespace for default xml statement.
*/

Просмотреть файл

@ -48,7 +48,14 @@ import org.mozilla.javascript.xml.*;
*/
public abstract class XMLObject extends IdScriptableObject
{
public abstract XMLLib lib();
public XMLObject()
{
}
public XMLObject(Scriptable scope, Scriptable prototype)
{
super(scope, prototype);
}
/**
* Implementation of ECMAScript [[Has]].
@ -69,4 +76,34 @@ public abstract class XMLObject extends IdScriptableObject
* Implementation of ECMAScript [[Delete]].
*/
public abstract boolean ecmaDelete(Context cx, Object id);
/**
* Wrap this object into NativeWith to implement the with statement.
*/
public abstract NativeWith enterWith(Scriptable scope);
/**
* Wrap this object into NativeWith to implement the .() query.
*/
public abstract NativeWith enterDotQuery(Scriptable scope);
/**
* Custom <tt>+</tt> operator.
* Should return {@link Scriptable#NOT_FOUND} if this object does not have
* custom addition operator for the given value,
* or the result of the addition operation.
* <p>
* The default implementation returns {@link Scriptable#NOT_FOUND}
* to indicate no custom addition operation.
*
* @param cx the Context object associated with the current thread.
* @param thisIsLeft if true, the object should calculate this + value
* if false, the object should calculate value + this.
* @param value the second argument for addition operation.
*/
public Object addValues(Context cx, boolean thisIsLeft, Object value)
{
return Scriptable.NOT_FOUND;
}
}

Просмотреть файл

@ -53,6 +53,8 @@ class Namespace extends IdScriptableObject
public Namespace(XMLLibImpl lib, String uri)
{
super(lib.globalScope(), lib.namespacePrototype);
if (uri == null)
throw new IllegalArgumentException();
@ -64,6 +66,8 @@ class Namespace extends IdScriptableObject
public Namespace(XMLLibImpl lib, String prefix, String uri)
{
super(lib.globalScope(), lib.namespacePrototype);
if (uri == null)
throw new IllegalArgumentException();
if (uri.length() == 0) {
@ -152,20 +156,6 @@ class Namespace extends IdScriptableObject
return uri();
}
protected Scriptable defaultPrototype()
{
Scriptable result = lib.namespacePrototype;
if (result == this) {
result = null;
}
return result;
}
protected Scriptable defaultParentScope()
{
return lib.globalScope();
}
// #string_id_map#
private static final int
Id_prefix = 1,

Просмотреть файл

@ -52,15 +52,9 @@ final class QName extends IdScriptableObject
private String localName;
private String uri;
static void init(XMLLibImpl lib, boolean sealed)
{
QName obj = new QName(lib, "", "", "");
lib.qnamePrototype = obj;
obj.exportAsJSClass(MAX_PROTOTYPE_ID, lib.globalScope(), sealed);
}
public QName(XMLLibImpl lib, String uri, String localName, String prefix)
{
super(lib.globalScope(), lib.qnamePrototype);
if (localName == null) throw new IllegalArgumentException();
this.lib = lib;
this.uri = uri;
@ -153,20 +147,6 @@ final class QName extends IdScriptableObject
return toString();
}
protected Scriptable defaultPrototype()
{
Scriptable result = lib.qnamePrototype;
if (result == this) {
result = null;
}
return result;
}
protected Scriptable defaultParentScope()
{
return lib.globalScope();
}
// #string_id_map#
private static final int
Id_localName = 1,

Просмотреть файл

@ -177,7 +177,7 @@ class XML extends XMLObjectImpl
*/
XML(XMLLibImpl lib)
{
super(lib);
super(lib, lib.xmlPrototype);
XmlObject xo = XmlObject.Factory.newInstance();
XmlCursor curs = xo.newCursor();
@ -198,7 +198,7 @@ class XML extends XMLObjectImpl
*/
private XML(XMLLibImpl lib, XScriptAnnotation anno)
{
super(lib);
super(lib, lib.xmlPrototype);
_anno = anno;
_anno._xScriptXML = this;
}
@ -209,7 +209,7 @@ class XML extends XMLObjectImpl
*/
XML(XMLLibImpl lib, Object inputObject)
{
super(lib);
super(lib, lib.xmlPrototype);
XmlObject xo;
boolean isText = false;
String frag;
@ -377,7 +377,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
*/
private XML(XMLLibImpl lib, XmlCursor cursor)
{
super(lib);
super(lib, lib.xmlPrototype);
if(cursor == null || !cursor.isAttr())
{
// Make default empty XML
@ -1148,15 +1148,6 @@ todo need to handle namespace prefix not found in XML look for namespace type in
return "XML";
}
protected Scriptable defaultPrototype()
{
Scriptable result = lib.xmlPrototype;
if (result == this) {
result = null;
}
return result;
}
//
//
// methods overriding IdScriptableObject

Просмотреть файл

@ -72,7 +72,10 @@ public final class XMLLibImpl extends XMLLib
public static void init(Context cx, Scriptable scope, boolean sealed)
{
XMLLibImpl lib = new XMLLibImpl(scope);
lib.exportToScope(sealed);
XMLLib bound = lib.bindToScope(scope);
if (bound == lib) {
lib.exportToScope(sealed);
}
}
private void exportToScope(boolean sealed)
@ -527,6 +530,36 @@ public final class XMLLibImpl extends XMLLib
return new QName(this, uri, localName, prefix);
}
Object addXMLObjects(Context cx, XMLObject obj1, XMLObject obj2)
{
XMLList listToAdd = new XMLList(this);
if (obj1 instanceof XMLList) {
XMLList list1 = (XMLList)obj1;
if (list1.length() == 1) {
listToAdd.addToList(list1.item(0));
} else {
// Might be xmlFragment + xmlFragment + xmlFragment + ...;
// then the result will be an XMLList which we want to be an
// rValue and allow it to be assigned to an lvalue.
listToAdd = new XMLList(this, obj1);
}
} else {
listToAdd.addToList(((XML)obj1));
}
if (obj2 instanceof XMLList) {
XMLList list2 = (XMLList)obj2;
for (int i = 0; i < list2.length(); i++) {
listToAdd.addToList(list2.item(i));
}
} else if (obj2 instanceof XML) {
listToAdd.addToList(((XML)obj2));
}
return listToAdd;
}
//
//
// Overriding XMLLib methods
@ -608,37 +641,6 @@ public final class XMLLibImpl extends XMLLib
return new XMLReference(xmlObj, xmlName);
}
public Scriptable enterXMLWith(XMLObject object, Scriptable scope)
{
return new XMLWithScope(this, scope, object);
}
public Scriptable enterDotQuery(XMLObject object, Scriptable scope)
{
XMLWithScope xws = new XMLWithScope(this, scope, object);
// XMLWithScope also handles the .(xxx) DotQuery for XML
// basically DotQuery is a for/in/with statement and in
// the following 3 statements we setup to signal it's
// DotQuery,
// the index and the object being looped over. The
// xws.setPrototype is the scope of the object which is
// is a element of the lhs (XMLList).
xws.setCurrIndex(0);
xws.setDQPrototype(object);
if (object instanceof XMLList) {
XMLList xl = (XMLList)object;
if (xl.length() > 0) {
xws.setPrototype((Scriptable)(xl.get(0, null)));
}
}
// Always return the outer-most type of XML lValue of
// XML to left of dotQuery.
xws.setXMLList(new XMLList(this));
return xws;
}
/**
* Escapes the reserved characters in a value of an attribute
*
@ -695,36 +697,6 @@ public final class XMLLibImpl extends XMLLib
return (begin < end) ? elementText.substring(begin, end) : "";
}
public Object addXMLObjects(Context cx, XMLObject obj1, XMLObject obj2)
{
XMLList listToAdd = new XMLList(this);
if (obj1 instanceof XMLList) {
XMLList list1 = (XMLList)obj1;
if (list1.length() == 1) {
listToAdd.addToList(list1.item(0));
} else {
// Might be xmlFragment + xmlFragment + xmlFragment + ...;
// then the result will be an XMLList which we want to be an
// rValue and allow it to be assigned to an lvalue.
listToAdd = new XMLList(this, obj1);
}
} else {
listToAdd.addToList(((XML)obj1));
}
if (obj2 instanceof XMLList) {
XMLList list2 = (XMLList)obj2;
for (int i = 0; i < list2.length(); i++) {
listToAdd.addToList(list2.item(i));
}
} else if (obj2 instanceof XML) {
listToAdd.addToList(((XML)obj2));
}
return listToAdd;
}
public Object toDefaultXmlNamespace(Context cx, Object uriValue)
{
return constructNamespace(cx, uriValue);
@ -765,6 +737,4 @@ public final class XMLLibImpl extends XMLLib
return Undefined.instance;
}
}

Просмотреть файл

@ -102,7 +102,7 @@ class XMLList extends XMLObjectImpl implements Function
*/
XMLList(XMLLibImpl lib)
{
super(lib);
super(lib, lib.xmlListPrototype);
_annos = new AnnotationList();
}
@ -112,7 +112,7 @@ class XMLList extends XMLObjectImpl implements Function
*/
XMLList(XMLLibImpl lib, Object inputObject)
{
super(lib);
super(lib, lib.xmlListPrototype);
String frag;
if (inputObject == null || inputObject instanceof Undefined)
@ -291,15 +291,6 @@ class XMLList extends XMLObjectImpl implements Function
return "XMLList";
}
protected Scriptable defaultPrototype()
{
Scriptable result = lib.xmlListPrototype;
if (result == this) {
result = null;
}
return result;
}
//
//
// methods overriding IdScriptableObject

Просмотреть файл

@ -53,8 +53,9 @@ abstract class XMLObjectImpl extends XMLObject
protected final XMLLibImpl lib;
protected boolean prototypeFlag;
protected XMLObjectImpl(XMLLibImpl lib)
protected XMLObjectImpl(XMLLibImpl lib, XMLObject prototype)
{
super(lib.globalScope(), prototype);
this.lib = lib;
}
@ -149,11 +150,6 @@ abstract class XMLObjectImpl extends XMLObject
return toString();
}
protected final Scriptable defaultParentScope()
{
return lib.globalScope();
}
public void delete(String name)
{
throw new IllegalArgumentException("String: [" + name + "]");
@ -164,7 +160,7 @@ abstract class XMLObjectImpl extends XMLObject
* never returns null for them but rather calls equivalentXml(value)
* and box the result as Boolean.
*/
public final Boolean equivalentValues(Object value)
protected final Boolean equivalentValues(Object value)
{
boolean result = equivalentXml(value);
@ -249,6 +245,40 @@ abstract class XMLObjectImpl extends XMLObject
return true;
}
public NativeWith enterWith(Scriptable scope)
{
return new XMLWithScope(lib, scope, this);
}
public NativeWith enterDotQuery(Scriptable scope)
{
XMLWithScope xws = new XMLWithScope(lib, scope, this);
xws.initAsDotQuery();
return xws;
}
public final Object addValues(Context cx, boolean thisIsLeft,
Object value)
{
if (value instanceof XMLObject) {
XMLObject v1, v2;
if (thisIsLeft) {
v1 = this;
v2 = (XMLObject)value;
} else {
v1 = (XMLObject)value;
v2 = this;
}
return lib.addXMLObjects(cx, v1, v2);
}
if (value == Undefined.instance) {
// both "xml + undefined" and "undefined + xml" gives String(xml)
return ScriptRuntime.toString(this);
}
return super.addValues(cx, thisIsLeft, value);
}
//
//
// IdScriptableObject machinery

Просмотреть файл

@ -43,50 +43,45 @@ import org.mozilla.javascript.xml.*;
final class XMLWithScope extends NativeWith
{
private XMLLib lib;
private XMLLibImpl lib;
private int _currIndex;
private XMLList _xmlList = null;
private Scriptable _dqPrototype;
private XMLList _xmlList;
private XMLObject _dqPrototype;
XMLWithScope(XMLLib lib, Scriptable parent, XMLObject prototype)
XMLWithScope(XMLLibImpl lib, Scriptable parent, XMLObject prototype)
{
super(parent, prototype);
this.lib = lib;
}
public XMLLib lib()
void initAsDotQuery()
{
return lib;
XMLObject prototype = (XMLObject)getPrototype();
// XMLWithScope also handles the .(xxx) DotQuery for XML
// basically DotQuery is a for/in/with statement and in
// the following 3 statements we setup to signal it's
// DotQuery,
// the index and the object being looped over. The
// xws.setPrototype is the scope of the object which is
// is a element of the lhs (XMLList).
_currIndex = 0;
_dqPrototype = prototype;
if (prototype instanceof XMLList) {
XMLList xl = (XMLList)prototype;
if (xl.length() > 0) {
setPrototype((Scriptable)(xl.get(0, null)));
}
}
// Always return the outer-most type of XML lValue of
// XML to left of dotQuery.
_xmlList = new XMLList(lib);
}
public void setCurrIndex (int idx)
{
_currIndex = idx;
}
public int getCurrIndex ()
{
return _currIndex;
}
public void setXMLList (XMLList l)
{
_xmlList = l;
}
public Scriptable getDQPrototype() {
return _dqPrototype;
}
public void setDQPrototype(Scriptable dqPrototype) {
_dqPrototype = dqPrototype;
}
public Object updateDotQuery(boolean value)
protected Object updateDotQuery(boolean value)
{
// Return null to continue looping
Scriptable seed = getDQPrototype();
XMLObject seed = _dqPrototype;
XMLList xmlL = _xmlList;
Object result;
@ -96,7 +91,7 @@ final class XMLWithScope extends NativeWith
// to our result list. If false, we try the next element.
XMLList orgXmlL = (XMLList)seed;
int idx = getCurrIndex();
int idx = _currIndex;
if (value) {
xmlL.addToList(orgXmlL.get(idx, null));
@ -107,7 +102,7 @@ final class XMLWithScope extends NativeWith
// Yes, set our new index, get the next element and
// reset the expression to run with this object as
// the WITH selector.
setCurrIndex(idx);
_currIndex = idx;
setPrototype((Scriptable)(orgXmlL.get(idx, null)));
// continue looping