001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 /* 019 * $Id: CastCall.java 468650 2006-10-28 07:03:30Z minchau $ 020 */ 021 022 package org.apache.xalan.xsltc.compiler; 023 024 import java.util.Vector; 025 026 import org.apache.bcel.generic.ConstantPoolGen; 027 import org.apache.bcel.generic.CHECKCAST; 028 import org.apache.bcel.generic.InstructionList; 029 import org.apache.xalan.xsltc.compiler.util.ClassGenerator; 030 import org.apache.xalan.xsltc.compiler.util.MethodGenerator; 031 import org.apache.xalan.xsltc.compiler.util.ErrorMsg; 032 import org.apache.xalan.xsltc.compiler.util.Type; 033 import org.apache.xalan.xsltc.compiler.util.ObjectType; 034 import org.apache.xalan.xsltc.compiler.util.TypeCheckError; 035 036 /** 037 * @author Santiago Pericas-Geertsen 038 */ 039 final class CastCall extends FunctionCall { 040 041 /** 042 * Name of the class that is the target of the cast. Must be a 043 * fully-qualified Java class Name. 044 */ 045 private String _className; 046 047 /** 048 * A reference to the expression being casted. 049 */ 050 private Expression _right; 051 052 /** 053 * Constructor. 054 */ 055 public CastCall(QName fname, Vector arguments) { 056 super(fname, arguments); 057 } 058 059 /** 060 * Type check the two parameters for this function 061 */ 062 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 063 // Check that the function was passed exactly two arguments 064 if (argumentCount() != 2) { 065 throw new TypeCheckError(new ErrorMsg(ErrorMsg.ILLEGAL_ARG_ERR, 066 getName(), this)); 067 } 068 069 // The first argument must be a literal String 070 Expression exp = argument(0); 071 if (exp instanceof LiteralExpr) { 072 _className = ((LiteralExpr) exp).getValue(); 073 _type = Type.newObjectType(_className); 074 } 075 else { 076 throw new TypeCheckError(new ErrorMsg(ErrorMsg.NEED_LITERAL_ERR, 077 getName(), this)); 078 } 079 080 // Second argument must be of type reference or object 081 _right = argument(1); 082 Type tright = _right.typeCheck(stable); 083 if (tright != Type.Reference && 084 tright instanceof ObjectType == false) 085 { 086 throw new TypeCheckError(new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR, 087 tright, _type, this)); 088 } 089 090 return _type; 091 } 092 093 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 094 final ConstantPoolGen cpg = classGen.getConstantPool(); 095 final InstructionList il = methodGen.getInstructionList(); 096 097 _right.translate(classGen, methodGen); 098 il.append(new CHECKCAST(cpg.addClass(_className))); 099 } 100 }