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:
igor%mir2.org 2004-09-29 20:58:16 +00:00
Родитель 615bf892fa
Коммит ee94cb397f
14 изменённых файлов: 160 добавлений и 196 удалений

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

@ -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);
}
}