1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * @LastModified: Oct 2017
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.xalan.internal.xsltc.compiler;
  23 
  24 import com.sun.org.apache.bcel.internal.generic.CHECKCAST;
  25 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
  26 import com.sun.org.apache.bcel.internal.generic.InstructionList;
  27 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
  28 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
  29 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
  30 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ObjectType;
  31 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
  32 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
  33 import java.util.List;
  34 
  35 /**
  36  * @author Santiago Pericas-Geertsen
  37  */
  38 final class CastCall extends FunctionCall {
  39 
  40     /**
  41      * Name of the class that is the target of the cast. Must be a
  42      * fully-qualified Java class Name.
  43      */
  44     private String _className;
  45 
  46     /**
  47      * A reference to the expression being casted.
  48      */
  49     private Expression _right;
  50 
  51     /**
  52      * Constructor.
  53      */
  54     public CastCall(QName fname, List<Expression> arguments) {
  55         super(fname, arguments);
  56     }
  57 
  58     /**
  59      * Type check the two parameters for this function
  60      */
  61     public Type typeCheck(SymbolTable stable) throws TypeCheckError {
  62         // Check that the function was passed exactly two arguments
  63         if (argumentCount() != 2) {
  64             throw new TypeCheckError(new ErrorMsg(ErrorMsg.ILLEGAL_ARG_ERR,
  65                                                   getName(), this));
  66         }
  67 
  68         // The first argument must be a literal String
  69         Expression exp = argument(0);
  70         if (exp instanceof LiteralExpr) {
  71             _className = ((LiteralExpr) exp).getValue();
  72             _type = Type.newObjectType(_className);
  73         }
  74         else {
  75             throw new TypeCheckError(new ErrorMsg(ErrorMsg.NEED_LITERAL_ERR,
  76                                                   getName(), this));
  77         }
  78 
  79          // Second argument must be of type reference or object
  80         _right = argument(1);
  81         Type tright = _right.typeCheck(stable);
  82         if (tright != Type.Reference &&
  83             tright instanceof ObjectType == false)
  84         {
  85             throw new TypeCheckError(new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
  86                                                   tright, _type, this));
  87         }
  88 
  89         return _type;
  90     }
  91 
  92     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  93         final ConstantPoolGen cpg = classGen.getConstantPool();
  94         final InstructionList il = methodGen.getInstructionList();
  95 
  96         _right.translate(classGen, methodGen);
  97         il.append(new CHECKCAST(cpg.addClass(_className)));
  98     }
  99 }