FilterParentPathpublic final class FilterParentPath extends Expression
Fields Summary |
---|
private Expression | _filterExpr | private Expression | _path | private boolean | _hasDescendantAxis |
Constructors Summary |
---|
public FilterParentPath(Expression filterExpr, Expression path)
(_path = path).setParent(this);
(_filterExpr = filterExpr).setParent(this);
|
Methods Summary |
---|
public void | setDescendantAxis()
_hasDescendantAxis = true;
| public void | setParser(com.sun.org.apache.xalan.internal.xsltc.compiler.Parser parser)
super.setParser(parser);
_filterExpr.setParser(parser);
_path.setParser(parser);
| public java.lang.String | toString()
return "FilterParentPath(" + _filterExpr + ", " + _path + ')";
| public void | translate(com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator classGen, com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator methodGen)
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
// Create new StepIterator
final int initSI = cpg.addMethodref(STEP_ITERATOR_CLASS,
"<init>",
"("
+NODE_ITERATOR_SIG
+NODE_ITERATOR_SIG
+")V");
il.append(new NEW(cpg.addClass(STEP_ITERATOR_CLASS)));
il.append(DUP);
// Recursively compile 2 iterators
_filterExpr.translate(classGen, methodGen);
_path.translate(classGen, methodGen);
// Initialize StepIterator with iterators from the stack
il.append(new INVOKESPECIAL(initSI));
// This is a special case for the //* path with or without predicates
if (_hasDescendantAxis) {
final int incl = cpg.addMethodref(NODE_ITERATOR_BASE,
"includeSelf",
"()" + NODE_ITERATOR_SIG);
il.append(new INVOKEVIRTUAL(incl));
}
if (!(getParent() instanceof RelativeLocationPath) &&
!(getParent() instanceof FilterParentPath)) {
final int order = cpg.addInterfaceMethodref(DOM_INTF,
ORDER_ITERATOR,
ORDER_ITERATOR_SIG);
il.append(methodGen.loadDOM());
il.append(SWAP);
il.append(methodGen.loadContextNode());
il.append(new INVOKEINTERFACE(order, 3));
}
| public com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type | typeCheck(com.sun.org.apache.xalan.internal.xsltc.compiler.SymbolTable stable)Type check a FilterParentPath. If the filter is not a node-set add a
cast to node-set only if it is of reference type. This type coercion is
needed for expressions like $x/LINE where $x is a parameter reference.
final Type ftype = _filterExpr.typeCheck(stable);
if (ftype instanceof NodeSetType == false) {
if (ftype instanceof ReferenceType) {
_filterExpr = new CastExpr(_filterExpr, Type.NodeSet);
}
/*
else if (ftype instanceof ResultTreeType) {
_filterExpr = new CastExpr(_filterExpr, Type.NodeSet);
}
*/
else if (ftype instanceof NodeType) {
_filterExpr = new CastExpr(_filterExpr, Type.NodeSet);
}
else {
throw new TypeCheckError(this);
}
}
// Wrap single node path in a node set
final Type ptype = _path.typeCheck(stable);
if (!(ptype instanceof NodeSetType)) {
_path = new CastExpr(_path, Type.NodeSet);
}
return _type = Type.NodeSet;
|
|