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: Type.java 468649 2006-10-28 07:00:55Z minchau $ 020 */ 021 022 package org.apache.xalan.xsltc.compiler.util; 023 024 import org.apache.bcel.generic.BranchInstruction; 025 import org.apache.bcel.generic.Instruction; 026 import org.apache.xalan.xsltc.compiler.Constants; 027 import org.apache.xalan.xsltc.compiler.FlowList; 028 import org.apache.xalan.xsltc.compiler.NodeTest; 029 030 /** 031 * @author Jacek Ambroziak 032 * @author Santiago Pericas-Geertsen 033 * @author Morten Jorgensen 034 */ 035 public abstract class Type implements Constants { 036 public static final Type Int = new IntType(); 037 public static final Type Real = new RealType(); 038 public static final Type Boolean = new BooleanType(); 039 public static final Type NodeSet = new NodeSetType(); 040 public static final Type String = new StringType(); 041 public static final Type ResultTree = new ResultTreeType(); 042 public static final Type Reference = new ReferenceType(); 043 public static final Type Void = new VoidType(); 044 public static final Type Object = new ObjectType(java.lang.Object.class); 045 046 public static final Type Node = new NodeType(NodeTest.ANODE); 047 public static final Type Root = new NodeType(NodeTest.ROOT); 048 public static final Type Element = new NodeType(NodeTest.ELEMENT); 049 public static final Type Attribute = new NodeType(NodeTest.ATTRIBUTE); 050 public static final Type Text = new NodeType(NodeTest.TEXT); 051 public static final Type Comment = new NodeType(NodeTest.COMMENT); 052 public static final Type Processing_Instruction = new NodeType(NodeTest.PI); 053 054 /** 055 * Factory method to instantiate object types. Returns a pre-defined 056 * instance for "java.lang.Object" and "java.lang.String". 057 */ 058 public static Type newObjectType(String javaClassName) { 059 if (javaClassName == "java.lang.Object") { 060 return Type.Object; 061 } 062 else if (javaClassName == "java.lang.String") { 063 return Type.String; 064 } 065 else { 066 return new ObjectType(javaClassName); 067 } 068 } 069 070 /** 071 * Factory method to instantiate object types. Returns a pre-defined 072 * instance for java.lang.Object.class and java.lang.String.class. 073 */ 074 public static Type newObjectType(Class clazz) { 075 if (clazz == java.lang.Object.class) { 076 return Type.Object; 077 } 078 else if (clazz == java.lang.String.class) { 079 return Type.String; 080 } 081 else { 082 return new ObjectType(clazz); 083 } 084 } 085 086 /** 087 * Returns a string representation of this type. 088 */ 089 public abstract String toString(); 090 091 /** 092 * Returns true if this and other are identical types. 093 */ 094 public abstract boolean identicalTo(Type other); 095 096 /** 097 * Returns true if this type is a numeric type. Redefined in NumberType. 098 */ 099 public boolean isNumber() { 100 return false; 101 } 102 103 /** 104 * Returns true if this type has no object representaion. Redefined in 105 * ResultTreeType. 106 */ 107 public boolean implementedAsMethod() { 108 return false; 109 } 110 111 /** 112 * Returns true if this type is a simple type. Redefined in NumberType, 113 * BooleanType and StringType. 114 */ 115 public boolean isSimple() { 116 return false; 117 } 118 119 public abstract org.apache.bcel.generic.Type toJCType(); 120 121 /** 122 * Returns the distance between two types. This measure is used to select 123 * overloaded functions/operators. This method is typically redefined by 124 * the subclasses. 125 */ 126 public int distanceTo(Type type) { 127 return type == this ? 0 : Integer.MAX_VALUE; 128 } 129 130 /** 131 * Returns the signature of an internal type's external representation. 132 */ 133 public abstract String toSignature(); 134 135 /** 136 * Translates an object of this type to an object of type 137 * <code>type</code>. 138 * Expects an object of the former type and pushes an object of the latter. 139 */ 140 public void translateTo(ClassGenerator classGen, MethodGenerator methodGen, 141 Type type) { 142 ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR, 143 toString(), type.toString()); 144 classGen.getParser().reportError(Constants.FATAL, err); 145 } 146 147 /** 148 * Translates object of this type to an object of type <code>type</code>. 149 * Expects an object of the former type and pushes an object of the latter 150 * if not boolean. If type <code>type</code> is boolean then a branchhandle 151 * list (to be appended to the false list) is returned. 152 */ 153 public FlowList translateToDesynthesized(ClassGenerator classGen, 154 MethodGenerator methodGen, 155 Type type) { 156 FlowList fl = null; 157 if (type == Type.Boolean) { 158 fl = translateToDesynthesized(classGen, methodGen, 159 (BooleanType)type); 160 } 161 else { 162 translateTo(classGen, methodGen, type); 163 } 164 return fl; 165 } 166 167 /** 168 * Translates an object of this type to an non-synthesized boolean. It 169 * does not push a 0 or a 1 but instead returns branchhandle list to be 170 * appended to the false list. 171 */ 172 public FlowList translateToDesynthesized(ClassGenerator classGen, 173 MethodGenerator methodGen, 174 BooleanType type) { 175 ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR, 176 toString(), type.toString()); 177 classGen.getParser().reportError(Constants.FATAL, err); 178 return null; 179 } 180 181 /** 182 * Translates an object of this type to the external (Java) type denoted 183 * by <code>clazz</code>. This method is used to translate parameters 184 * when external functions are called. 185 */ 186 public void translateTo(ClassGenerator classGen, MethodGenerator methodGen, 187 Class clazz) { 188 ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR, 189 toString(), clazz.getClass().toString()); 190 classGen.getParser().reportError(Constants.FATAL, err); 191 } 192 193 /** 194 * Translates an external (Java) type denoted by <code>clazz</code> to 195 * an object of this type. This method is used to translate return values 196 * when external functions are called. 197 */ 198 public void translateFrom(ClassGenerator classGen, MethodGenerator methodGen, 199 Class clazz) { 200 ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR, 201 clazz.getClass().toString(), toString()); 202 classGen.getParser().reportError(Constants.FATAL, err); 203 } 204 205 /** 206 * Translates an object of this type to its boxed representation. 207 */ 208 public void translateBox(ClassGenerator classGen, 209 MethodGenerator methodGen) { 210 ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR, 211 toString(), "["+toString()+"]"); 212 classGen.getParser().reportError(Constants.FATAL, err); 213 } 214 215 /** 216 * Translates an object of this type to its unboxed representation. 217 */ 218 public void translateUnBox(ClassGenerator classGen, 219 MethodGenerator methodGen) { 220 ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR, 221 "["+toString()+"]", toString()); 222 classGen.getParser().reportError(Constants.FATAL, err); 223 } 224 225 /** 226 * Returns the class name of an internal type's external representation. 227 */ 228 public String getClassName() { 229 return(EMPTYSTRING); 230 } 231 232 public Instruction ADD() { 233 return null; // should never be called 234 } 235 236 public Instruction SUB() { 237 return null; // should never be called 238 } 239 240 public Instruction MUL() { 241 return null; // should never be called 242 } 243 244 public Instruction DIV() { 245 return null; // should never be called 246 } 247 248 public Instruction REM() { 249 return null; // should never be called 250 } 251 252 public Instruction NEG() { 253 return null; // should never be called 254 } 255 256 public Instruction LOAD(int slot) { 257 return null; // should never be called 258 } 259 260 public Instruction STORE(int slot) { 261 return null; // should never be called 262 } 263 264 public Instruction POP() { 265 return POP; 266 } 267 268 public BranchInstruction GT(boolean tozero) { 269 return null; // should never be called 270 } 271 272 public BranchInstruction GE(boolean tozero) { 273 return null; // should never be called 274 } 275 276 public BranchInstruction LT(boolean tozero) { 277 return null; // should never be called 278 } 279 280 public BranchInstruction LE(boolean tozero) { 281 return null; // should never be called 282 } 283 284 public Instruction CMP(boolean less) { 285 return null; // should never be called 286 } 287 288 public Instruction DUP() { 289 return DUP; // default 290 } 291 }