FileDocCategorySizeDatePackage
FilterParentPath.javaAPI DocJava SE 5 API4729Fri Aug 26 14:55:34 BST 2005com.sun.org.apache.xalan.internal.xsltc.compiler

FilterParentPath

public final class FilterParentPath extends Expression
author
Jacek Ambroziak
author
Santiago Pericas-Geertsen

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 voidsetDescendantAxis()

	_hasDescendantAxis = true;
    
public voidsetParser(com.sun.org.apache.xalan.internal.xsltc.compiler.Parser parser)

	super.setParser(parser);
	_filterExpr.setParser(parser);
	_path.setParser(parser);
    
public java.lang.StringtoString()

	return "FilterParentPath(" + _filterExpr + ", " + _path + ')";
    
public voidtranslate(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.TypetypeCheck(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;