FilterExprpublic class FilterExpr extends Expression
Fields Summary |
---|
private Expression | _primaryPrimary expression of this filter. I.e., 'e' in '(e)[p1]...[pn]'. | private final Vector | _predicatesArray of predicates in '(e)[p1]...[pn]'. |
Constructors Summary |
---|
public FilterExpr(Expression primary, Vector predicates)
_primary = primary;
_predicates = predicates;
primary.setParent(this);
|
Methods Summary |
---|
protected com.sun.org.apache.xalan.internal.xsltc.compiler.Expression | getExpr()
if (_primary instanceof CastExpr)
return ((CastExpr)_primary).getExpr();
else
return _primary;
| public void | setParser(com.sun.org.apache.xalan.internal.xsltc.compiler.Parser parser)
super.setParser(parser);
_primary.setParser(parser);
if (_predicates != null) {
final int n = _predicates.size();
for (int i = 0; i < n; i++) {
final Expression exp = (Expression)_predicates.elementAt(i);
exp.setParser(parser);
exp.setParent(this);
}
}
| public java.lang.String | toString()
return "filter-expr(" + _primary + ", " + _predicates + ")";
| 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)Translate a filter expression by pushing the appropriate iterator
onto the stack.
if (_predicates.size() > 0) {
translatePredicates(classGen, methodGen);
}
else {
_primary.translate(classGen, methodGen);
}
| public void | translatePredicates(com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator classGen, com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator methodGen)Translate a sequence of predicates. Each predicate is translated
by constructing an instance of CurrentNodeListIterator
which is initialized from another iterator (recursive call), a
filter and a closure (call to translate on the predicate) and "this".
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
// If not predicates left, translate primary expression
if (_predicates.size() == 0) {
translate(classGen, methodGen);
}
else {
// Translate predicates from right to left
final int initCNLI = cpg.addMethodref(CURRENT_NODE_LIST_ITERATOR,
"<init>",
"("+NODE_ITERATOR_SIG+"Z"+
CURRENT_NODE_LIST_FILTER_SIG +
NODE_SIG+TRANSLET_SIG+")V");
// Backwards branches are prohibited if an uninitialized object is
// on the stack by section 4.9.4 of the JVM Specification, 2nd Ed.
// We don't know whether this code might contain backwards branches,
// so we mustn't create the new object until after we've created
// the suspect arguments to its constructor. Instead we calculate
// the values of the arguments to the constructor first, store them
// in temporary variables, create the object and reload the
// arguments from the temporaries to avoid the problem.
// Remove the next predicate to be translated
Predicate predicate = (Predicate)_predicates.lastElement();
_predicates.remove(predicate);
// Translate the rest of the predicates from right to left
translatePredicates(classGen, methodGen);
LocalVariableGen nodeIteratorTemp =
methodGen.addLocalVariable("filter_expr_tmp1",
Util.getJCRefType(NODE_ITERATOR_SIG),
il.getEnd(), null);
il.append(new ASTORE(nodeIteratorTemp.getIndex()));
predicate.translate(classGen, methodGen);
LocalVariableGen filterTemp =
methodGen.addLocalVariable("filter_expr_tmp2",
Util.getJCRefType(CURRENT_NODE_LIST_FILTER_SIG),
il.getEnd(), null);
il.append(new ASTORE(filterTemp.getIndex()));
// Create a CurrentNodeListIterator
il.append(new NEW(cpg.addClass(CURRENT_NODE_LIST_ITERATOR)));
il.append(DUP);
// Initialize CurrentNodeListIterator
il.append(new ALOAD(nodeIteratorTemp.getIndex()));
il.append(ICONST_1);
il.append(new ALOAD(filterTemp.getIndex()));
il.append(methodGen.loadCurrentNode());
il.append(classGen.loadTranslet());
il.append(new INVOKESPECIAL(initCNLI));
}
| 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 where $x is a parameter reference.
All optimizations are turned off before type checking underlying
predicates.
Type ptype = _primary.typeCheck(stable);
if (ptype instanceof NodeSetType == false) {
if (ptype instanceof ReferenceType) {
_primary = new CastExpr(_primary, Type.NodeSet);
}
else {
throw new TypeCheckError(this);
}
}
// Type check predicates and turn all optimizations off
int n = _predicates.size();
for (int i = 0; i < n; i++) {
Predicate pred = (Predicate) _predicates.elementAt(i);
pred.dontOptimize();
pred.typeCheck(stable);
}
return _type = Type.NodeSet;
|
|