зеркало из https://github.com/mozilla/pjs.git
1. Reference cleanup:
Signatures in Reference are changed to include Context and reference-related methods in ScriptRuntime accept/return explicit Reference type instead of generic Object as code generation ensure proper type. 2. x..y use explicit reference instead of special descendants mark XMLName: In this way less code is necessary to support x..y operations and support for .. in non-xml objects is possible.
This commit is contained in:
Родитель
615bf892fa
Коммит
ee94cb397f
|
@ -948,7 +948,7 @@ final class IRFactory
|
|||
} else if (childType == Token.GET_REF) {
|
||||
Node ref = child.getFirstChild();
|
||||
child.removeChild(ref);
|
||||
n = new Node(Token.DELPROP, ref);
|
||||
n = new Node(Token.DEL_REF, ref);
|
||||
} else {
|
||||
n = new Node(Token.TRUE);
|
||||
}
|
||||
|
@ -1080,12 +1080,14 @@ final class IRFactory
|
|||
break;
|
||||
|
||||
case Token.DOTDOT:
|
||||
if (right.getType() == Token.NAME) {
|
||||
right.setType(Token.STRING);
|
||||
{
|
||||
Node ref;
|
||||
if (right.getType() == Token.NAME) {
|
||||
right.setType(Token.STRING);
|
||||
}
|
||||
ref = new Node(Token.DESC_REF, left, right);
|
||||
return new Node(Token.GET_REF, ref);
|
||||
}
|
||||
right = new Node(Token.DESCENDANTS, right);
|
||||
nodeType = Token.GETELEM;
|
||||
break;
|
||||
|
||||
case Token.LB:
|
||||
// OPT: could optimize to GETPROP iff string can't be a number
|
||||
|
|
|
@ -990,19 +990,13 @@ public class Interpreter
|
|||
addStringOp(Token.GETPROP, child.getString());
|
||||
break;
|
||||
|
||||
case Token.GETELEM:
|
||||
visitExpression(child, 0);
|
||||
child = child.getNext();
|
||||
visitExpression(child, 0);
|
||||
addToken(Token.GETELEM);
|
||||
stackChange(-1);
|
||||
break;
|
||||
|
||||
case Token.GET_REF:
|
||||
visitExpression(child, 0);
|
||||
addToken(Token.GET_REF);
|
||||
break;
|
||||
|
||||
case Token.GETELEM:
|
||||
case Token.DESC_REF:
|
||||
case Token.DELPROP:
|
||||
case Token.BITAND:
|
||||
case Token.BITOR:
|
||||
|
@ -1267,7 +1261,6 @@ public class Interpreter
|
|||
case Token.ESCXMLATTR :
|
||||
case Token.ESCXMLTEXT :
|
||||
case Token.TOATTRNAME :
|
||||
case Token.DESCENDANTS :
|
||||
visitExpression(child, 0);
|
||||
addToken(type);
|
||||
break;
|
||||
|
@ -2810,30 +2803,27 @@ switch (op) {
|
|||
continue Loop;
|
||||
}
|
||||
case Token.GET_REF : {
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
|
||||
stack[stackTop] = ScriptRuntime.getReference(lhs);
|
||||
Reference ref = (Reference)stack[stackTop];
|
||||
stack[stackTop] = ScriptRuntime.getReference(ref, cx);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.SET_REF : {
|
||||
Object rhs = stack[stackTop];
|
||||
if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
|
||||
Object value = stack[stackTop];
|
||||
if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]);
|
||||
--stackTop;
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
|
||||
stack[stackTop] = ScriptRuntime.setReference(lhs, rhs);
|
||||
Reference ref = (Reference)stack[stackTop];
|
||||
stack[stackTop] = ScriptRuntime.setReference(ref, value, cx);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.DEL_REF : {
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
|
||||
stack[stackTop] = ScriptRuntime.deleteReference(lhs);
|
||||
Reference ref = (Reference)stack[stackTop];
|
||||
stack[stackTop] = ScriptRuntime.deleteReference(ref, cx);
|
||||
continue Loop;
|
||||
}
|
||||
case Icode_REF_INC_DEC : {
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
|
||||
stack[stackTop] = ScriptRuntime.referenceIncrDecr(lhs, iCode[frame.pc]);
|
||||
Reference ref = (Reference)stack[stackTop];
|
||||
stack[stackTop] = ScriptRuntime.referenceIncrDecr(ref, cx,
|
||||
iCode[frame.pc]);
|
||||
++frame.pc;
|
||||
continue Loop;
|
||||
}
|
||||
|
@ -3247,6 +3237,16 @@ switch (op) {
|
|||
cx, frame.scope);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.DESC_REF : {
|
||||
Object rhs = stack[stackTop];
|
||||
if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
|
||||
--stackTop;
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
|
||||
stack[stackTop] = ScriptRuntime.getDescendantsRef(lhs, rhs,
|
||||
cx, frame.scope);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.XML_REF : {
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
|
||||
|
@ -3355,12 +3355,6 @@ switch (op) {
|
|||
stack[stackTop] = ScriptRuntime.toAttributeName(value, cx);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.DESCENDANTS : {
|
||||
Object value = stack[stackTop];
|
||||
if(value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]);
|
||||
stack[stackTop] = ScriptRuntime.toDescendantsName(value, cx);
|
||||
continue Loop;
|
||||
}
|
||||
case Token.COLONCOLON : {
|
||||
Object value = stack[stackTop];
|
||||
if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]);
|
||||
|
|
|
@ -44,16 +44,16 @@ package org.mozilla.javascript;
|
|||
*/
|
||||
public abstract class Reference
|
||||
{
|
||||
public boolean has()
|
||||
public boolean has(Context cx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract Object get();
|
||||
public abstract Object get(Context cx);
|
||||
|
||||
public abstract Object set(Object value);
|
||||
public abstract Object set(Context cx, Object value);
|
||||
|
||||
public void delete()
|
||||
public void delete(Context cx)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1518,23 +1518,20 @@ public class ScriptRuntime {
|
|||
return value;
|
||||
}
|
||||
|
||||
public static Object getReference(Object obj)
|
||||
public static Object getReference(Reference ref, Context cx)
|
||||
{
|
||||
Reference ref = (Reference)obj;
|
||||
return ref.get();
|
||||
return ref.get(cx);
|
||||
}
|
||||
|
||||
public static Object setReference(Object obj, Object value)
|
||||
public static Object setReference(Reference ref, Object value, Context cx)
|
||||
{
|
||||
Reference ref = (Reference)obj;
|
||||
return ref.set(value);
|
||||
return ref.set(cx, value);
|
||||
}
|
||||
|
||||
public static Object deleteReference(Object obj)
|
||||
public static Object deleteReference(Reference ref, Context cx)
|
||||
{
|
||||
Reference ref = (Reference)obj;
|
||||
ref.delete();
|
||||
return wrapBoolean(!ref.has());
|
||||
ref.delete(cx);
|
||||
return wrapBoolean(!ref.has(cx));
|
||||
}
|
||||
|
||||
static boolean isSpecialProperty(String s)
|
||||
|
@ -1542,10 +1539,10 @@ public class ScriptRuntime {
|
|||
return s.equals("__proto__") || s.equals("__parent__");
|
||||
}
|
||||
|
||||
public static Object specialReference(final Object obj,
|
||||
final String specialProperty,
|
||||
final Context cx,
|
||||
final Scriptable scope)
|
||||
public static Reference specialReference(final Object obj,
|
||||
final String specialProperty,
|
||||
Context cx,
|
||||
final Scriptable scope)
|
||||
{
|
||||
final int PROTO = 0;
|
||||
final int PARENT = 1;
|
||||
|
@ -1562,10 +1559,10 @@ public class ScriptRuntime {
|
|||
|
||||
final Scriptable sobj = toObject(scope, obj);
|
||||
return new Reference() {
|
||||
public Object get()
|
||||
public Object get(Context cx2)
|
||||
{
|
||||
if (!specials) {
|
||||
return getObjectProp(sobj, specialProperty, cx);
|
||||
return getObjectProp(sobj, specialProperty, cx2);
|
||||
}
|
||||
if (id == PROTO) {
|
||||
return getProto(sobj, scope);
|
||||
|
@ -1574,10 +1571,10 @@ public class ScriptRuntime {
|
|||
}
|
||||
}
|
||||
|
||||
public Object set(Object value)
|
||||
public Object set(Context cx2, Object value)
|
||||
{
|
||||
if (!specials) {
|
||||
return setObjectProp(sobj, specialProperty, value, cx);
|
||||
return setObjectProp(sobj, specialProperty, value, cx2);
|
||||
}
|
||||
Scriptable result;
|
||||
if (value == null) {
|
||||
|
@ -2464,9 +2461,10 @@ public class ScriptRuntime {
|
|||
}
|
||||
}
|
||||
|
||||
public static Object referenceIncrDecr(Object obj, int incrDecrMask)
|
||||
public static Object referenceIncrDecr(Reference ref, Context cx,
|
||||
int incrDecrMask)
|
||||
{
|
||||
Object value = getReference(obj);
|
||||
Object value = ref.get(cx);
|
||||
boolean post = ((incrDecrMask & Node.POST_FLAG) != 0);
|
||||
double number;
|
||||
if (value instanceof Number) {
|
||||
|
@ -2484,7 +2482,7 @@ public class ScriptRuntime {
|
|||
--number;
|
||||
}
|
||||
Number result = wrapNumber(number);
|
||||
setReference(obj, result);
|
||||
ref.set(cx, result);
|
||||
if (post) {
|
||||
return value;
|
||||
} else {
|
||||
|
@ -3059,10 +3057,8 @@ public class ScriptRuntime {
|
|||
|
||||
public static Scriptable enterDotQuery(Object value, Scriptable scope)
|
||||
{
|
||||
if (!(value instanceof XMLObject))
|
||||
{
|
||||
throw ScriptRuntime.typeError1("msg.isnt.xml.object",
|
||||
ScriptRuntime.toString(value));
|
||||
if (!(value instanceof XMLObject)) {
|
||||
throw notXmlError(value);
|
||||
}
|
||||
XMLObject object = (XMLObject)value;
|
||||
return object.enterDotQuery(scope);
|
||||
|
@ -3378,6 +3374,11 @@ public class ScriptRuntime {
|
|||
return typeError1("msg.isnt.function", msg);
|
||||
}
|
||||
|
||||
private static RuntimeException notXmlError(Object value)
|
||||
{
|
||||
throw typeError1("msg.isnt.xml.object", ScriptRuntime.toString(value));
|
||||
}
|
||||
|
||||
private static void warnAboutNonJSObject(Object nonJSObject)
|
||||
{
|
||||
String message =
|
||||
|
@ -3449,10 +3450,14 @@ public class ScriptRuntime {
|
|||
return xmlLib.toAttributeName(cx, name);
|
||||
}
|
||||
|
||||
public static Object toDescendantsName(Object name, Context cx)
|
||||
public static Reference getDescendantsRef(Object obj, Object elem,
|
||||
Context cx, Scriptable scope)
|
||||
{
|
||||
XMLLib xmlLib = currentXMLLib(cx);
|
||||
return xmlLib.toDescendantsName(cx, name);
|
||||
if (!(obj instanceof XMLObject)) {
|
||||
throw notXmlError(obj);
|
||||
}
|
||||
XMLObject xmlObject = (XMLObject)obj;
|
||||
return xmlObject.getDescendantsRef(cx, elem);
|
||||
}
|
||||
|
||||
public static Object toQualifiedName(String namespace,
|
||||
|
@ -3463,9 +3468,9 @@ public class ScriptRuntime {
|
|||
return xmlLib.toQualifiedName(namespace, name, scope);
|
||||
}
|
||||
|
||||
public static Object xmlReference(Object xmlName,
|
||||
Context cx,
|
||||
Scriptable scope)
|
||||
public static Reference xmlReference(Object xmlName,
|
||||
Context cx,
|
||||
Scriptable scope)
|
||||
{
|
||||
XMLLib xmlLib = currentXMLLib(cx);
|
||||
return xmlLib.xmlPrimaryReference(cx, xmlName, scope);
|
||||
|
|
|
@ -149,7 +149,7 @@ public class Token
|
|||
ESCXMLATTR = 72,
|
||||
ESCXMLTEXT = 73,
|
||||
TOATTRNAME = 74,
|
||||
DESCENDANTS = 75,
|
||||
DESC_REF = 75, // Descendants reference to implement x..y
|
||||
XML_REF = 76;
|
||||
|
||||
// End of interpreter bytecodes
|
||||
|
@ -328,7 +328,7 @@ public class Token
|
|||
case ESCXMLTEXT: return "ESCXMLTEXT";
|
||||
case ESCXMLATTR: return "ESCXMLATTR";
|
||||
case TOATTRNAME: return "TOATTRNAME";
|
||||
case DESCENDANTS: return "DESCENDANTS";
|
||||
case DESC_REF: return "DESC_REF";
|
||||
case XML_REF: return "XML_REF";
|
||||
case TRY: return "TRY";
|
||||
case SEMI: return "SEMI";
|
||||
|
|
|
@ -2022,9 +2022,11 @@ class BodyCodegen
|
|||
|
||||
case Token.GET_REF:
|
||||
generateExpression(child, node); // reference
|
||||
cfw.addALoad(contextLocal);
|
||||
addScriptRuntimeInvoke(
|
||||
"getReference",
|
||||
"(Ljava/lang/Object;"
|
||||
"(Lorg/mozilla/javascript/Reference;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+")Ljava/lang/Object;");
|
||||
break;
|
||||
|
||||
|
@ -2057,24 +2059,30 @@ class BodyCodegen
|
|||
child = child.getNext();
|
||||
if (type == Token.SET_REF_OP) {
|
||||
cfw.add(ByteCode.DUP);
|
||||
cfw.addALoad(contextLocal);
|
||||
addScriptRuntimeInvoke(
|
||||
"getReference",
|
||||
"(Ljava/lang/Object;"
|
||||
"(Lorg/mozilla/javascript/Reference;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+")Ljava/lang/Object;");
|
||||
}
|
||||
generateExpression(child, node);
|
||||
cfw.addALoad(contextLocal);
|
||||
addScriptRuntimeInvoke(
|
||||
"setReference",
|
||||
"(Ljava/lang/Object;"
|
||||
"(Lorg/mozilla/javascript/Reference;"
|
||||
+"Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+")Ljava/lang/Object;");
|
||||
}
|
||||
break;
|
||||
|
||||
case Token.DEL_REF:
|
||||
generateExpression(child, node);
|
||||
cfw.addALoad(contextLocal);
|
||||
addScriptRuntimeInvoke("deleteReference",
|
||||
"(Ljava/lang/Object;"
|
||||
"(Lorg/mozilla/javascript/Reference;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+")Ljava/lang/Object;");
|
||||
break;
|
||||
|
||||
|
@ -2128,7 +2136,7 @@ class BodyCodegen
|
|||
+"Ljava/lang/String;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Ljava/lang/Object;");
|
||||
+")Lorg/mozilla/javascript/Reference;");
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2141,7 +2149,7 @@ class BodyCodegen
|
|||
"(Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Ljava/lang/Object;");
|
||||
+")Lorg/mozilla/javascript/Reference;");
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2184,13 +2192,17 @@ class BodyCodegen
|
|||
+")Ljava/lang/Object;");
|
||||
break;
|
||||
|
||||
case Token.DESCENDANTS:
|
||||
case Token.DESC_REF:
|
||||
generateExpression(child, node);
|
||||
generateExpression(child.getNext(), node);
|
||||
cfw.addALoad(contextLocal);
|
||||
addScriptRuntimeInvoke("toDescendantsName",
|
||||
cfw.addALoad(variableObjectLocal);
|
||||
addScriptRuntimeInvoke("getDescendantsRef",
|
||||
"(Ljava/lang/Object;"
|
||||
+"Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+")Ljava/lang/Object;");
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Lorg/mozilla/javascript/Reference;");
|
||||
break;
|
||||
|
||||
case Token.COLONCOLON : {
|
||||
|
@ -3156,9 +3168,13 @@ Else pass the JS object in the aReg and 0.0 in the dReg.
|
|||
case Token.GET_REF: {
|
||||
Node refChild = child.getFirstChild();
|
||||
generateExpression(refChild, node);
|
||||
cfw.addALoad(contextLocal);
|
||||
cfw.addPush(incrDecrMask);
|
||||
addScriptRuntimeInvoke(
|
||||
"referenceIncrDecr", "(Ljava/lang/Object;I)Ljava/lang/Object;");
|
||||
"referenceIncrDecr",
|
||||
"(Lorg/mozilla/javascript/Reference;"
|
||||
+"Lorg/mozilla/javascript/Context;"
|
||||
+"I)Ljava/lang/Object;");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -84,8 +84,6 @@ public abstract class XMLLib
|
|||
|
||||
public abstract Object toAttributeName(Context cx, Object nameValue);
|
||||
|
||||
public abstract Object toDescendantsName(Context cx, Object name);
|
||||
|
||||
public abstract Reference xmlPrimaryReference(Context cx,
|
||||
Object nameObject,
|
||||
Scriptable scope);
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
package org.mozilla.javascript.xml;
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
import org.mozilla.javascript.xml.*;
|
||||
|
||||
/**
|
||||
* This Interface describes what all XML objects (XML, XMLList) should have in common.
|
||||
|
@ -77,6 +76,11 @@ public abstract class XMLObject extends IdScriptableObject
|
|||
*/
|
||||
public abstract boolean ecmaDelete(Context cx, Object id);
|
||||
|
||||
/**
|
||||
* To implement ECMAScript [[Descendants]].
|
||||
*/
|
||||
public abstract Reference getDescendantsRef(Context cx, Object id);
|
||||
|
||||
/**
|
||||
* Wrap this object into NativeWith to implement the with statement.
|
||||
*/
|
||||
|
|
|
@ -1151,7 +1151,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
|
|||
* @param start
|
||||
* @return
|
||||
*/
|
||||
boolean hasXMLProperty(XMLName xmlName)
|
||||
boolean hasXMLProperty(XMLName xmlName, boolean descendants)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
|
@ -1169,7 +1169,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
|
|||
// Has now should return true if the property would have results > 0 or
|
||||
// if it's a method name
|
||||
String name = xmlName.localName();
|
||||
if ((getPropertyList(xmlName).length() > 0) ||
|
||||
if ((getPropertyList(xmlName, descendants).length() > 0) ||
|
||||
(getMethod(name) != NOT_FOUND))
|
||||
{
|
||||
result = true;
|
||||
|
@ -1229,7 +1229,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
|
|||
* @param start
|
||||
* @return
|
||||
*/
|
||||
Object getXMLProperty(XMLName xmlName)
|
||||
Object getXMLProperty(XMLName xmlName, boolean descendants)
|
||||
{
|
||||
Object result = NOT_FOUND;
|
||||
|
||||
|
@ -1241,7 +1241,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
|
|||
}
|
||||
else
|
||||
{
|
||||
result = getPropertyList(xmlName);
|
||||
result = getPropertyList(xmlName, descendants);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1277,10 +1277,6 @@ todo need to handle namespace prefix not found in XML look for namespace type in
|
|||
{
|
||||
setAttribute(xmlName, value);
|
||||
}
|
||||
else if (xmlName.isDescendants())
|
||||
{
|
||||
throw ScriptRuntime.typeError("Assignment to descendants (\"..\") not supported");
|
||||
}
|
||||
else if (xmlName.uri() == null &&
|
||||
xmlName.localName().equals("*"))
|
||||
{
|
||||
|
@ -1322,7 +1318,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
|
|||
xmlValue = makeXmlFromString(lib, xmlName, ScriptRuntime.toString(value));
|
||||
}
|
||||
|
||||
XMLList matches = (XMLList)getPropertyList(xmlName);
|
||||
XMLList matches = (XMLList)getPropertyList(xmlName, false);
|
||||
|
||||
if (matches.length() == 0)
|
||||
{
|
||||
|
@ -1361,9 +1357,9 @@ todo need to handle namespace prefix not found in XML look for namespace type in
|
|||
*
|
||||
* @param name
|
||||
*/
|
||||
void deleteXMLProperty(XMLName name)
|
||||
void deleteXMLProperty(XMLName name, boolean descendants)
|
||||
{
|
||||
if (!name.isDescendants() && name.isAttributeName())
|
||||
if (!descendants && name.isAttributeName())
|
||||
{
|
||||
XmlCursor curs = newCursor();
|
||||
|
||||
|
@ -1391,7 +1387,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
|
|||
}
|
||||
else
|
||||
{
|
||||
XMLList matches = (XMLList)getPropertyList(name);
|
||||
XMLList matches = (XMLList)getPropertyList(name, descendants);
|
||||
|
||||
matches.remove();
|
||||
}
|
||||
|
@ -2233,7 +2229,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
|
|||
}
|
||||
else
|
||||
{
|
||||
hasProperty = (getPropertyList(xmlName).length() > 0);
|
||||
hasProperty = (getPropertyList(xmlName, false).length() > 0);
|
||||
}
|
||||
|
||||
return hasProperty;
|
||||
|
@ -2592,7 +2588,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
|
|||
*/
|
||||
boolean propertyIsEnumerable(XMLName xmlName)
|
||||
{
|
||||
return (getPropertyList(xmlName).length() > 0);
|
||||
return (getPropertyList(xmlName, false).length() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2738,7 +2734,7 @@ todo need to handle namespace prefix not found in XML look for namespace type in
|
|||
{
|
||||
// remove all children
|
||||
XMLName xmlName = XMLName.formStar();
|
||||
XMLList matches = (XMLList)getPropertyList(xmlName);
|
||||
XMLList matches = (XMLList)getPropertyList(xmlName, false);
|
||||
matches.remove();
|
||||
|
||||
// append new children
|
||||
|
@ -3018,12 +3014,12 @@ todo need to handle namespace prefix not found in XML look for namespace type in
|
|||
* @param start
|
||||
* @return
|
||||
*/
|
||||
XMLList getPropertyList(XMLName name)
|
||||
XMLList getPropertyList(XMLName name, boolean descendants)
|
||||
{
|
||||
XMLList result;
|
||||
|
||||
// Get the named property
|
||||
if (name.isDescendants())
|
||||
if (descendants)
|
||||
{
|
||||
result = descendants(name);
|
||||
}
|
||||
|
|
|
@ -125,51 +125,6 @@ public final class XMLLibImpl extends XMLLib
|
|||
return prettyIndent;
|
||||
}
|
||||
|
||||
private XMLName resolveName(Context cx, Object id)
|
||||
{
|
||||
if(id instanceof XMLName) return (XMLName)id;
|
||||
if (id instanceof QName) {
|
||||
QName qname = (QName)id;
|
||||
return XMLName.formProperty(qname.uri(), qname.localName());
|
||||
}
|
||||
|
||||
String name = ScriptRuntime.toString(id);
|
||||
boolean isAttributeName = false;
|
||||
if (name.length() != 0 && name.charAt(0) == '@') {
|
||||
name = name.substring(1);
|
||||
isAttributeName = true;
|
||||
}
|
||||
|
||||
String uri = null;
|
||||
if(!name.equals("*")) {
|
||||
if (isAttributeName) {
|
||||
uri = "";
|
||||
} else {
|
||||
uri = "";
|
||||
if (cx == null) {
|
||||
cx = Context.getCurrentContext();
|
||||
}
|
||||
if (cx != null) {
|
||||
Object defaultNS = ScriptRuntime.searchDefaultNamespace(cx);
|
||||
if (defaultNS != null) {
|
||||
if (defaultNS instanceof Namespace) {
|
||||
uri = ((Namespace)defaultNS).uri();
|
||||
} else {
|
||||
// Should not happen but for now it could
|
||||
// due to bad searchDefaultNamespace implementation.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XMLName xmlName = XMLName.formProperty(uri, name);
|
||||
if (isAttributeName) {
|
||||
xmlName.setAttributeName();
|
||||
}
|
||||
return xmlName;
|
||||
}
|
||||
|
||||
private Namespace resolveNamespace(String prefix, Scriptable scope)
|
||||
{
|
||||
Namespace ns = null;
|
||||
|
@ -604,13 +559,6 @@ public final class XMLLibImpl extends XMLLib
|
|||
return toAttributeNameImpl(cx, nameValue);
|
||||
}
|
||||
|
||||
public Object toDescendantsName(Context cx, Object name)
|
||||
{
|
||||
XMLName xmlName = resolveName(cx, name);
|
||||
xmlName.setDescendants();
|
||||
return xmlName;
|
||||
}
|
||||
|
||||
/**
|
||||
* See E4X 11.1 PrimaryExpression : PropertyIdentifier production
|
||||
*/
|
||||
|
@ -629,7 +577,7 @@ public final class XMLLibImpl extends XMLLib
|
|||
// of XMLWithScope
|
||||
if (scope instanceof XMLWithScope) {
|
||||
xmlObj = (XMLObjectImpl)scope.getPrototype();
|
||||
if (xmlObj.hasXMLProperty(xmlName)) {
|
||||
if (xmlObj.hasXMLProperty(xmlName, false)) {
|
||||
break;
|
||||
}
|
||||
if (firstXmlObject == null) {
|
||||
|
@ -644,7 +592,7 @@ public final class XMLLibImpl extends XMLLib
|
|||
}
|
||||
|
||||
// xmlName == null corresponds to undefined
|
||||
return new XMLReference(xmlObj, xmlName);
|
||||
return new XMLReference(false, xmlObj, xmlName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -323,14 +323,14 @@ class XMLList extends XMLObjectImpl implements Function
|
|||
* @param start
|
||||
* @return
|
||||
*/
|
||||
boolean hasXMLProperty(XMLName xmlName)
|
||||
boolean hasXMLProperty(XMLName xmlName, boolean descendants)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
// Has now should return true if the property would have results > 0 or
|
||||
// if it's a method name
|
||||
String name = xmlName.localName();
|
||||
if ((getPropertyList(xmlName).length() > 0) ||
|
||||
if ((getPropertyList(xmlName, descendants).length() > 0) ||
|
||||
(getMethod(name) != NOT_FOUND))
|
||||
{
|
||||
result = true;
|
||||
|
@ -427,9 +427,9 @@ class XMLList extends XMLObjectImpl implements Function
|
|||
* @param name
|
||||
* @return
|
||||
*/
|
||||
Object getXMLProperty(XMLName name)
|
||||
Object getXMLProperty(XMLName name, boolean descendants)
|
||||
{
|
||||
return getPropertyList(name);
|
||||
return getPropertyList(name, descendants);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -563,7 +563,7 @@ class XMLList extends XMLObjectImpl implements Function
|
|||
*
|
||||
* @param name
|
||||
*/
|
||||
void deleteXMLProperty(XMLName name)
|
||||
void deleteXMLProperty(XMLName name, boolean descendants)
|
||||
{
|
||||
for (int i = 0; i < length(); i++)
|
||||
{
|
||||
|
@ -571,7 +571,7 @@ class XMLList extends XMLObjectImpl implements Function
|
|||
|
||||
if (xml.tokenType() == XmlCursor.TokenType.START)
|
||||
{
|
||||
xml.deleteXMLProperty(name);
|
||||
xml.deleteXMLProperty(name, descendants);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -993,7 +993,7 @@ class XMLList extends XMLObjectImpl implements Function
|
|||
}
|
||||
else
|
||||
{
|
||||
hasProperty = (getPropertyList(xmlName).length() > 0);
|
||||
hasProperty = (getPropertyList(xmlName, false).length() > 0);
|
||||
}
|
||||
|
||||
return hasProperty;
|
||||
|
@ -1256,7 +1256,7 @@ class XMLList extends XMLObjectImpl implements Function
|
|||
*/
|
||||
boolean propertyIsEnumerable(XMLName xmlName)
|
||||
{
|
||||
return hasXMLProperty(xmlName);
|
||||
return hasXMLProperty(xmlName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1495,12 +1495,12 @@ class XMLList extends XMLObjectImpl implements Function
|
|||
* @param start
|
||||
* @return
|
||||
*/
|
||||
private XMLList getPropertyList(XMLName name)
|
||||
private XMLList getPropertyList(XMLName name, boolean descendants)
|
||||
{
|
||||
XMLList propertyList = new XMLList(lib);
|
||||
javax.xml.namespace.QName qname = null;
|
||||
|
||||
if (!name.isDescendants() && !name.isAttributeName())
|
||||
if (!descendants && !name.isAttributeName())
|
||||
{
|
||||
// Only set the targetProperty if this is a regular child get
|
||||
// and not a descendant or attribute get
|
||||
|
@ -1511,7 +1511,8 @@ class XMLList extends XMLObjectImpl implements Function
|
|||
|
||||
for (int i = 0; i < length(); i++)
|
||||
{
|
||||
propertyList.addToList(getXmlFromAnnotation(i).getPropertyList(name));
|
||||
propertyList.addToList(getXmlFromAnnotation(i).
|
||||
getPropertyList(name, descendants));
|
||||
}
|
||||
|
||||
return propertyList;
|
||||
|
|
|
@ -41,7 +41,6 @@ class XMLName
|
|||
private String uri;
|
||||
private String localName;
|
||||
private boolean isAttributeName;
|
||||
private boolean isDescendants;
|
||||
|
||||
private XMLName(String uri, String localName)
|
||||
{
|
||||
|
@ -71,23 +70,10 @@ class XMLName
|
|||
isAttributeName = true;
|
||||
}
|
||||
|
||||
boolean isDescendants()
|
||||
{
|
||||
return isDescendants;
|
||||
}
|
||||
|
||||
void setDescendants()
|
||||
{
|
||||
if (isDescendants)
|
||||
throw new IllegalStateException();
|
||||
isDescendants = true;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
//return qname.localName();
|
||||
StringBuffer buff = new StringBuffer();
|
||||
if(isDescendants()) buff.append("..");
|
||||
if(isAttributeName()) buff.append('@');
|
||||
if(uri() == null)
|
||||
{
|
||||
|
|
|
@ -63,13 +63,13 @@ abstract class XMLObjectImpl extends XMLObject
|
|||
* ecmaHas(cx, id) calls this after resolving when id to XMLName
|
||||
* and checking it is not Uint32 index.
|
||||
*/
|
||||
abstract boolean hasXMLProperty(XMLName name);
|
||||
abstract boolean hasXMLProperty(XMLName name, boolean descendants);
|
||||
|
||||
/**
|
||||
* ecmaGet(cx, id) calls this after resolving when id to XMLName
|
||||
* and checking it is not Uint32 index.
|
||||
*/
|
||||
abstract Object getXMLProperty(XMLName name);
|
||||
abstract Object getXMLProperty(XMLName name, boolean descendants);
|
||||
|
||||
/**
|
||||
* ecmaPut(cx, id, value) calls this after resolving when id to XMLName
|
||||
|
@ -81,7 +81,7 @@ abstract class XMLObjectImpl extends XMLObject
|
|||
* ecmaDelete(cx, id) calls this after resolving when id to XMLName
|
||||
* and checking it is not Uint32 index.
|
||||
*/
|
||||
abstract void deleteXMLProperty(XMLName name);
|
||||
abstract void deleteXMLProperty(XMLName name, boolean descendants);
|
||||
|
||||
/**
|
||||
* Test XML equality with target the target.
|
||||
|
@ -190,7 +190,7 @@ abstract class XMLObjectImpl extends XMLObject
|
|||
// XXX Fix this cast
|
||||
return has((int)index, this);
|
||||
}
|
||||
return hasXMLProperty(xmlName);
|
||||
return hasXMLProperty(xmlName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -209,7 +209,7 @@ abstract class XMLObjectImpl extends XMLObject
|
|||
}
|
||||
return result;
|
||||
}
|
||||
return getXMLProperty(xmlName);
|
||||
return getXMLProperty(xmlName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -229,7 +229,7 @@ abstract class XMLObjectImpl extends XMLObject
|
|||
}
|
||||
|
||||
/**
|
||||
* Implementation of ECMAScript [[Delete]]
|
||||
* Implementation of ECMAScript [[Delete]].
|
||||
*/
|
||||
public final boolean ecmaDelete(Context cx, Object id)
|
||||
{
|
||||
|
@ -241,10 +241,16 @@ abstract class XMLObjectImpl extends XMLObject
|
|||
delete((int)index);
|
||||
return true;
|
||||
}
|
||||
deleteXMLProperty(xmlName);
|
||||
deleteXMLProperty(xmlName, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
public Reference getDescendantsRef(Context cx, Object id)
|
||||
{
|
||||
XMLName xmlName = lib.toXMLName(cx, id);
|
||||
return new XMLReference(true, this, xmlName);
|
||||
}
|
||||
|
||||
public NativeWith enterWith(Scriptable scope)
|
||||
{
|
||||
return new XMLWithScope(lib, scope, this);
|
||||
|
|
|
@ -43,57 +43,65 @@ import org.mozilla.javascript.xml.*;
|
|||
|
||||
class XMLReference extends Reference
|
||||
{
|
||||
private boolean descendants;
|
||||
private XMLObjectImpl xmlObject;
|
||||
private XMLName xmlName;
|
||||
|
||||
/**
|
||||
* When xmlObject == null, it corresponds to undefined in JS, not null
|
||||
*/
|
||||
XMLReference(XMLObjectImpl xmlObject, XMLName xmlName)
|
||||
XMLReference(boolean descendants, XMLObjectImpl xmlObject, XMLName xmlName)
|
||||
{
|
||||
if (xmlName == null)
|
||||
throw new IllegalArgumentException();
|
||||
if (descendants && xmlObject == null)
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.descendants = descendants;
|
||||
this.xmlObject = xmlObject;
|
||||
this.xmlName = xmlName;
|
||||
}
|
||||
|
||||
public boolean has()
|
||||
public boolean has(Context cx)
|
||||
{
|
||||
if (xmlObject == null) {
|
||||
return false;
|
||||
}
|
||||
return xmlObject.hasXMLProperty(xmlName);
|
||||
return xmlObject.hasXMLProperty(xmlName, descendants);
|
||||
}
|
||||
|
||||
/**
|
||||
* See E4X 11.1 PrimaryExpression : PropertyIdentifier production
|
||||
*/
|
||||
public Object get()
|
||||
public Object get(Context cx)
|
||||
{
|
||||
if (xmlObject == null) {
|
||||
throw ScriptRuntime.undefReadError(Undefined.instance,
|
||||
xmlName.toString());
|
||||
}
|
||||
return xmlObject.getXMLProperty(xmlName);
|
||||
return xmlObject.getXMLProperty(xmlName, descendants);
|
||||
}
|
||||
|
||||
public Object set(Object value)
|
||||
public Object set(Context cx, Object value)
|
||||
{
|
||||
if (xmlObject == null) {
|
||||
throw ScriptRuntime.undefWriteError(Undefined.instance,
|
||||
xmlName.toString(),
|
||||
value);
|
||||
}
|
||||
// Assignment to descendants causes parse error on bad reference
|
||||
// and this should not be called
|
||||
if (descendants) throw Kit.codeBug();
|
||||
xmlObject.putXMLProperty(xmlName, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
public void delete()
|
||||
public void delete(Context cx)
|
||||
{
|
||||
if (xmlObject == null) {
|
||||
return;
|
||||
}
|
||||
xmlObject.deleteXMLProperty(xmlName);
|
||||
xmlObject.deleteXMLProperty(xmlName, descendants);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче