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

CastExpr

public final class CastExpr extends Expression
author
Jacek Ambroziak
author
Santiago Pericas-Geertsen
author
Morten Jorgensen
author
Erwin Bolwidt

Fields Summary
private final Expression
_left
private static MultiHashtable
InternalTypeMap
Legal conversions between internal types.
private boolean
_typeTest
Constructors Summary
public CastExpr(Expression left, Type type)
Construct a cast expression and check that the conversion is valid by calling typeCheck().


                        
           
	_left = left;
	_type = type;		// use inherited field

	if ((_left instanceof Step) && (_type == Type.Boolean)) {
	    Step step = (Step)_left;
	    if ((step.getAxis() == Axis.SELF) && (step.getNodeType() != -1)) 
		_typeTest = true;
	}
	
	// check if conversion is valid
	setParser(left.getParser());
	setParent(left.getParent());
	left.setParent(this);
	typeCheck(left.getParser().getSymbolTable());
    
Methods Summary
public com.sun.org.apache.xalan.internal.xsltc.compiler.ExpressiongetExpr()

	return _left;
    
public booleanhasLastCall()

	return(_left.hasLastCall());
    
public booleanhasPositionCall()
Returns true if this expressions contains a call to position(). This is needed for context changes in node steps containing multiple predicates.

	return(_left.hasPositionCall());
    
public java.lang.StringtoString()

	return "cast(" + _left + ", " + _type + ")";
    
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 Type ltype = _left.getType();
	_left.translate(classGen, methodGen);
	if (_type.identicalTo(ltype) == false) {
	    _left.startIterator(classGen, methodGen);
	    ltype.translateTo(classGen, methodGen, _type);
	}
    
public voidtranslateDesynthesized(com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator classGen, com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator methodGen)

	FlowList fl;
	final Type ltype = _left.getType();

	// This is a special case for the self:: axis. Instead of letting
	// the Step object create and iterator that we cast back to a single
	// node, we simply ask the DOM for the node type.
	if (_typeTest) {
	    final ConstantPoolGen cpg = classGen.getConstantPool();
	    final InstructionList il = methodGen.getInstructionList();

	    final int idx = cpg.addInterfaceMethodref(DOM_INTF,
						      "getExpandedTypeID",
                                                      "(I)I");
	    il.append(new SIPUSH((short)((Step)_left).getNodeType()));
	    il.append(methodGen.loadDOM());
	    il.append(methodGen.loadContextNode());
	    il.append(new INVOKEINTERFACE(idx, 2));
	    _falseList.add(il.append(new IF_ICMPNE(null)));
	}
	else {

	    _left.translate(classGen, methodGen);
	    if (_type != ltype) {
		_left.startIterator(classGen, methodGen);
		if (_type instanceof BooleanType) {
		    fl = ltype.translateToDesynthesized(classGen, methodGen,
							_type);
		    if (fl != null) {
			_falseList.append(fl);
		    }
		}
		else {
		    ltype.translateTo(classGen, methodGen, _type);	
		}
	    }
	}
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypetypeCheck(com.sun.org.apache.xalan.internal.xsltc.compiler.SymbolTable stable)
Type checking a cast expression amounts to verifying that the type conversion is legal. Cast expressions are created during type checking, but typeCheck() is usually not called on them. As a result, this method is called from the constructor.

	Type tleft = _left.getType();
	if (tleft == null) {
	    tleft = _left.typeCheck(stable);
	}
	if (tleft instanceof NodeType) {
	    tleft = Type.Node;	// multiple instances
	}
	else if (tleft instanceof ResultTreeType) {
	    tleft = Type.ResultTree; // multiple instances
	}
	if (InternalTypeMap.maps(tleft, _type) != null) {
	    return _type;
	}
	// throw new TypeCheckError(this);	
	throw new TypeCheckError(new ErrorMsg(
	    ErrorMsg.DATA_CONVERSION_ERR, tleft.toString(), _type.toString()));