Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

TypeChecker.java

00001 package edu.ksu.cis.bandera.specification.assertion.ast;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 2000   Robby (robby@cis.ksu.edu)                    *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * This work was done as a project in the SAnToS Laboratory,         *
00009  * Department of Computing and Information Sciences, Kansas State    *
00010  * University, USA (http://www.cis.ksu.edu/santos).                  *
00011  * It is understood that any modification not identified as such is  *
00012  * not covered by the preceding statement.                           *
00013  *                                                                   *
00014  * This work is free software; you can redistribute it and/or        *
00015  * modify it under the terms of the GNU Library General Public       *
00016  * License as published by the Free Software Foundation; either      *
00017  * version 2 of the License, or (at your option) any later version.  *
00018  *                                                                   *
00019  * This work is distributed in the hope that it will be useful,      *
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00022  * Library General Public License for more details.                  *
00023  *                                                                   *
00024  * You should have received a copy of the GNU Library General Public *
00025  * License along with this toolkit; if not, write to the             *
00026  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00027  * Boston, MA  02111-1307, USA.                                      *
00028  *                                                                   *
00029  * Java is a trademark of Sun Microsystems, Inc.                     *
00030  *                                                                   *
00031  * To submit a bug report, send a comment, or get the latest news on *
00032  * this project and other SAnToS projects, please visit the web-site *
00033  *                http://www.cis.ksu.edu/santos                      *
00034  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00035 import ca.mcgill.sable.soot.jimple.*;
00036 import edu.ksu.cis.bandera.annotation.*;
00037 import edu.ksu.cis.bandera.specification.assertion.datastructure.*;
00038 import edu.ksu.cis.bandera.specification.assertion.exception.*;
00039 import edu.ksu.cis.bandera.jjjc.*;
00040 import edu.ksu.cis.bandera.jjjc.analysis.*;
00041 import edu.ksu.cis.bandera.jjjc.util.*;
00042 import edu.ksu.cis.bandera.jjjc.node.*;
00043 import edu.ksu.cis.bandera.jjjc.symboltable.Package;
00044 import edu.ksu.cis.bandera.jjjc.symboltable.*;
00045 import java.util.*;
00046 public class TypeChecker extends DepthFirstAdapter {
00047     private SymbolTable symbolTable;
00048     private Vector usedTypeNames = new Vector();
00049     private Vector exceptions = new Vector();
00050     private ClassOrInterfaceType type;
00051     private Type currentType;
00052     private LabeledStmtAnnotation currentAnnotation;
00053     private Annotation annotation;
00054     boolean isStatic;
00055 /**
00056  * 
00057  * @param node edu.ksu.cis.bandera.predicate.node.AWeakArrayNavigation
00058 public void caseAWeakArrayNavigation(AWeakArrayNavigation node) {
00059     if (currentType instanceof ArrayType) {
00060         currentType = new ArrayType(((ArrayType) currentType).baseType,
00061                 ((ArrayType) currentType).nDimensions - 1);
00062     } else {
00063         int line = node.getLWeakArrayReference().getLine();
00064         int pos = node.getLWeakArrayReference().getPos();
00065         exceptions.add(new TypeException("[" + line + ", " + pos + "] not an array in array navigation"));
00066         currentType = VoidType.TYPE;
00067     }
00068     expTable.put(node, currentType);
00069 }
00070  */
00071 /**
00072  * 
00073  * @param node edu.ksu.cis.bandera.predicate.node.AWeakCastExp
00074 public void caseAWeakCastExp(AWeakCastExp node) {
00075     currentType = VoidType.TYPE;
00076     Type cast;
00077     try {
00078         cast = symbolTable.resolveType(new Name(node.getType().toString()));
00079     } catch (Exception e) {
00080         int line = node.getLWeakCastParen().getLine();
00081         int pos = node.getLWeakCastParen().getPos();
00082         exceptions.add(new TypeException("[" + line + ", " + pos + "] invalid casting type"));
00083         expTable.put(node, currentType);
00084         return;
00085     }
00086     int i;
00087     if ((i = node.getDim().toArray().length) > 0) {
00088         cast = new ArrayType(cast, i);
00089     }
00090     node.getExp().apply(this);
00091     if (!currentType.isValidCastingConversion(cast)) {
00092         int line = node.getLWeakCastParen().getLine();
00093         int pos = node.getLWeakCastParen().getPos();
00094         exceptions.add(new TypeException("[" + line + ", " + pos + "] invalid casting type"));
00095     }
00096     currentType = cast;
00097     expTable.put(node, currentType);
00098 }
00099  */
00100 /**
00101  * 
00102  * @param node edu.ksu.cis.bandera.predicate.node.AWeakObjectNavigation
00103 public void caseAWeakObjectNavigation(AWeakObjectNavigation node) {
00104     String id = node.getId().toString().trim();
00105     if ("length".equals(id) && (currentType instanceof ArrayType)) {
00106         currentType = IntType.TYPE;
00107     } else if (currentType instanceof ClassOrInterfaceType) {
00108         try {
00109             currentType = ((ClassOrInterfaceType) currentType).getField(new Name(id)).getType();
00110         } catch (Exception e) {
00111             int line = node.getWeakObjectReference().getLine();
00112             int pos = node.getWeakObjectReference().getPos();
00113             exceptions.add(new TypeException("[" + line + ", " + pos + "] field undefined"));
00114             currentType = VoidType.TYPE;
00115         }
00116     } else {
00117         int line = node.getWeakObjectReference().getLine();
00118         int pos = node.getWeakObjectReference().getPos();
00119         exceptions.add(new TypeException("[" + line + ", " + pos + "] not an object in object navigation"));
00120         currentType = VoidType.TYPE;
00121     }
00122     expTable.put(node, currentType);
00123 }
00124  */
00125 /**
00126  * 
00127  * @param symbolTable edu.ksu.cis.bandera.jjjc.symboltable.SymbolTable
00128  * @param type edu.ksu.cis.bandera.jjjc.symboltable.ClassOrInterfaceType
00129  * @param annotation edu.ksu.cis.bandera.annotation.Annotation
00130  * @param isStatic boolean
00131  */
00132 public TypeChecker(SymbolTable symbolTable, ClassOrInterfaceType type, Annotation annotation, boolean isStatic) {
00133     this.symbolTable = symbolTable;
00134     this.type = type;
00135     if (annotation instanceof LabeledStmtAnnotation) {
00136         currentAnnotation = (LabeledStmtAnnotation) annotation;
00137         this.annotation = CompilationManager.getAnnotationManager().getMethodAnnotationContainingAnnotation(annotation);
00138     } else {
00139         this.annotation = annotation;
00140     }
00141 }
00142 /**
00143  * 
00144  * @return edu.ksu.cis.bandera.predicate.node.PExp
00145  * @param name edu.ksu.cis.bandera.predicate.node.AQualifiedName
00146  */
00147 private PExp buildFieldAccess(AQualifiedName name) {
00148     PExp exp;
00149     if (name.getName() instanceof AQualifiedName) {
00150         exp = buildFieldAccess((AQualifiedName) name.getName());
00151     } else {
00152         exp = buildFieldAccess((ASimpleName) name.getName());
00153     }
00154     
00155     return new AFieldAccessExp(new APrimaryFieldAccess(exp, new TDot(), name.getId()));
00156 }
00157 /**
00158  * 
00159  * @return edu.ksu.cis.bandera.predicate.node.PExp
00160  * @param name edu.ksu.cis.bandera.predicate.node.ASimpleName
00161  */
00162 private PExp buildFieldAccess(ASimpleName name) {
00163     return new ANameExp(name);
00164 }
00165 /**
00166  * 
00167  * @return edu.ksu.cis.bandera.predicate.node.PExp
00168  * @param typeExp edu.ksu.cis.bandera.predicate.node.PExp
00169  * @param name java.lang.String
00170  */
00171 private PExp buildFieldAccess(PExp typeExp, String name) {
00172     if ("".equals(name.trim())) return typeExp;
00173     for (StringTokenizer tokenizer = new StringTokenizer(name, "."); tokenizer.hasMoreTokens();) {
00174         String token = (String) tokenizer.nextToken();
00175         if (currentType instanceof ClassOrInterfaceType) {
00176             ClassOrInterfaceType type = (ClassOrInterfaceType) currentType;
00177             try {
00178                 currentType = type.getField(new Name(token)).getType();
00179             } catch (Exception e) {
00180                 exceptions.add(e);
00181                 currentType = VoidType.TYPE;
00182             }
00183         }
00184         typeExp = new AFieldAccessExp(new APrimaryFieldAccess(typeExp, new TDot(), new TId(token)));
00185     }
00186     return typeExp;
00187 }
00188 /**
00189  * 
00190  * @param node edu.ksu.cis.bandera.jjjc.node.AArrayInitializer
00191  */
00192 public void caseAArrayInitializer(AArrayInitializer node) {
00193     try {
00194         ArrayType at = (ArrayType) currentType;
00195         currentType = new ArrayType(at.baseType, at.nDimensions - 1);
00196     
00197         Object temp[] = node.getVariableInitializer().toArray();
00198         for (int i = 0; i < temp.length; i++) {
00199             ((PVariableInitializer) temp[i]).apply(this);
00200         }
00201     } catch (Exception e) {
00202         exceptions.add(new TypeException("Type mismatch in array initializer"));
00203     }
00204 }
00205 /**
00206  * 
00207  * @param node edu.ksu.cis.bandera.jjjc.node.AAssignmentExp
00208  */
00209 public void caseAAssignmentExp(AAssignmentExp node) {
00210     String op = node.getAssignmentOperator().toString().trim();
00211     if ("=".equals(op)) {
00212         node.getLeftHandSide().apply(this);
00213         Type lhsType = currentType;
00214         node.getExp().apply(this);
00215         if (!(currentType.isValidIdentityConversion(lhsType) || currentType.isValidWideningConversion(lhsType))) {
00216             exceptions.add(new TypeException("Type mismatch in assignment operation"));
00217         }
00218         currentType = lhsType;
00219     } else {
00220         node.getLeftHandSide().apply(this);
00221         String s = currentType.toString();
00222         PName name = null;
00223         if ("java.lang.String".equals(s)) {
00224             name = new AQualifiedName(new AQualifiedName(new ASimpleName(new TId("java")), new TDot(), new TId("lang")), new TDot(), new TId("lang"));
00225         } else if ("boolean".equals(s)) {
00226             name = new ASimpleName(new TId("boolean"));
00227         } else if ("byte".equals(s)) {
00228             name = new ASimpleName(new TId("byte"));
00229         } else if ("short".equals(s)) {
00230             name = new ASimpleName(new TId("short"));
00231         } else if ("char".equals(s)) {
00232             name = new ASimpleName(new TId("char"));
00233         } else if ("int".equals(s)) {
00234             name = new ASimpleName(new TId("int"));
00235         } else if ("long".equals(s)) {
00236             name = new ASimpleName(new TId("long"));
00237         } else if ("float".equals(s)) {
00238             name = new ASimpleName(new TId("float"));
00239         } else if ("double".equals(s)) {
00240             name = new ASimpleName(new TId("double"));
00241         } else {
00242             currentType = VoidType.TYPE;
00243             exceptions.add(new TypeException("Type mismatch for assignment operator " + op));
00244             return;
00245         }
00246         PBinaryOperator binop;
00247         if ("+=".equals(op)) {
00248             binop = new APlusBinaryOperator();
00249         } else if ("-=".equals(op)) {
00250             binop = new AMinusBinaryOperator();
00251         } else if ("*=".equals(op)) {
00252             binop = new AStarBinaryOperator();
00253         } else if ("/=".equals(op)) {
00254             binop = new ADivBinaryOperator();
00255         } else if ("%=".equals(op)) {
00256             binop = new AModBinaryOperator();
00257         } else if ("<<=".equals(op)) {
00258             binop = new AShiftLeftBinaryOperator();
00259         } else if (">>=".equals(op)) {
00260             binop = new ASignedShiftRightBinaryOperator();
00261         } else if ("<<<=".equals(op)) {
00262             binop = new AUnsignedShiftRightBinaryOperator();
00263         } else if ("&=".equals(op)) {
00264             binop = new ABitAndBinaryOperator();
00265         } else if ("|=".equals(op)) {
00266             binop = new ABitOrBinaryOperator();
00267         } else if ("^=".equals(op)) {
00268             binop = new ABitXorBinaryOperator();
00269         } else {
00270             currentType = VoidType.TYPE;
00271             exceptions.add(new TypeException("Unknown operator " + op));
00272             return;
00273         }
00274 
00275         PExp exp1;
00276 
00277         if (node.getLeftHandSide() instanceof AFieldAccessLeftHandSide) {
00278             exp1 = new AFieldAccessExp((PFieldAccess) ((AFieldAccessLeftHandSide) node.getLeftHandSide()).getFieldAccess().clone());
00279         } else if (node.getLeftHandSide() instanceof AArrayAccessLeftHandSide) {
00280             exp1 = new AArrayAccessExp((PArrayAccess) ((AArrayAccessLeftHandSide) node.getLeftHandSide()).getArrayAccess().clone());
00281         } else {
00282             exp1 = new ANameExp((PName) ((ANameLeftHandSide) node.getLeftHandSide()).getName().clone());
00283         }
00284 
00285         new AAssignmentExp((PLeftHandSide) node.getLeftHandSide().clone(), new AAssignAssignmentOperator(new TAssign()),
00286                 new AExpCastExp(new TLPar(), new ANameExp(name), new TRPar(), new ABinaryExp(exp1, binop, (PExp) node.getExp().clone()))).apply(this);
00287     }
00288 }
00289 /**
00290  * 
00291  * @param node edu.ksu.cis.bandera.jjjc.node.ABinaryExp
00292  */
00293 public void caseABinaryExp(ABinaryExp node) {
00294     node.getFirst().apply(this);
00295     Type leftType = currentType;
00296     node.getSecond().apply(this);
00297     Type rightType = currentType;
00298 
00299     PBinaryOperator binOp = node.getBinaryOperator();
00300     if ((binOp instanceof AAndBinaryOperator) || (binOp instanceof AOrBinaryOperator)) {
00301         // && ||
00302         currentType = BooleanType.TYPE;
00303         if ((leftType != BooleanType.TYPE) || (rightType != BooleanType.TYPE)) {
00304             exceptions.add(new TypeException("Expecting boolean expression"));
00305         }
00306     } else if ((binOp instanceof ABitAndBinaryOperator) || (binOp instanceof ABitOrBinaryOperator)
00307              || (binOp instanceof ABitXorBinaryOperator)) {
00308         // & | ^
00309         currentType = IntType.TYPE;
00310         if ((leftType == BooleanType.TYPE) && (rightType == BooleanType.TYPE)) {
00311             currentType = BooleanType.TYPE;
00312         } else if (getIntegralType(leftType, rightType) != null) {
00313             currentType = getIntegralType(leftType, rightType);
00314         } else {
00315             exceptions.add(new TypeException("Type mismatch for binary operator " + binOp.toString().trim()));
00316         }
00317     } else if ((binOp instanceof APlusBinaryOperator) || (binOp instanceof AMinusBinaryOperator)
00318              || (binOp instanceof AStarBinaryOperator) || (binOp instanceof ADivBinaryOperator)
00319              || (binOp instanceof AModBinaryOperator)) {
00320         // + - * / % /| %% 
00321         currentType = IntType.TYPE;
00322         if (getNumericType(leftType, rightType) != null) {
00323             currentType = getNumericType(leftType, rightType);
00324         } else {
00325             exceptions.add(new TypeException("Type mismatch for binary operator " + binOp.toString().trim()));
00326         }
00327     } else if ((binOp instanceof AShiftLeftBinaryOperator) || (binOp instanceof ASignedShiftRightBinaryOperator)
00328             || (binOp instanceof AUnsignedShiftRightBinaryOperator)) {
00329         // << >> >>>
00330         currentType = IntType.TYPE;
00331         if (getIntegralType(leftType, rightType) != null) {
00332             currentType = getIntegralType(leftType, rightType);
00333         } else {
00334             exceptions.add(new TypeException("Type mismatch for binary operator " + binOp.toString().trim()));
00335         }
00336     } else if ((binOp instanceof ALtBinaryOperator) || (binOp instanceof ALteqBinaryOperator)
00337              || (binOp instanceof AGtBinaryOperator) || (binOp instanceof AGteqBinaryOperator)) {
00338         // < <= > >=
00339         currentType = BooleanType.TYPE;
00340         if (getNumericType(leftType, rightType) == null) {
00341             exceptions.add(new TypeException("Type mismatch for binary operator " + binOp.toString().trim()));
00342         }
00343     } else if ((binOp instanceof AEqBinaryOperator) || (binOp instanceof ANeqBinaryOperator)) {
00344         // == !=
00345         currentType = BooleanType.TYPE;
00346         if ((leftType == BooleanType.TYPE) && (rightType == BooleanType.TYPE)) {
00347         } else if ((leftType instanceof ReferenceType) && (rightType instanceof ReferenceType)) {
00348         } else if (getNumericType(leftType, rightType) == null) {
00349             exceptions.add(new TypeException("Type mismatch for binary operator " + binOp.toString().trim()));
00350         }
00351     }
00352 }
00353 /**
00354  * 
00355  * @param node edu.ksu.cis.bandera.jjjc.node.ABooleanPrimitiveType
00356  */
00357 public void caseABooleanPrimitiveType(ABooleanPrimitiveType node) {
00358     currentType = BooleanType.TYPE;
00359 }
00360 /**
00361  * 
00362  * @param node edu.ksu.cis.bandera.jjjc.node.ABytePrimitiveType
00363  */
00364 public void caseABytePrimitiveType(ABytePrimitiveType node) {
00365     currentType = ByteType.TYPE;
00366 }
00367 /**
00368  * 
00369  * @param node edu.ksu.cis.bandera.jjjc.node.ACharacterLiteralLiteral
00370  */
00371 public void caseACharacterLiteralLiteral(ACharacterLiteralLiteral node) {
00372     currentType = CharType.TYPE;
00373 }
00374 /**
00375  * 
00376  * @param node edu.ksu.cis.bandera.jjjc.node.ACharPrimitiveType
00377  */
00378 public void caseACharPrimitiveType(ACharPrimitiveType node) {
00379     currentType = CharType.TYPE;
00380 }
00381 /**
00382  * 
00383  * @param node edu.ksu.cis.bandera.jjjc.node.AClassOrInterfaceTypeExp
00384  */
00385 public void caseAClassOrInterfaceTypeExp(AClassOrInterfaceTypeExp node) {
00386     for (ca.mcgill.sable.util.Iterator i = node.getDimExp().iterator(); i.hasNext();) {
00387         ((PDimExp) i.next()).apply(this);
00388         if (!(currentType instanceof IntegralType)) {
00389             exceptions.add(new TypeException("Expecting integral expression in dim exp"));
00390         }
00391     }
00392 
00393     try {
00394         currentType = symbolTable.resolveType(new Name(node.getClassOrInterfaceType().toString()));
00395         int dimensions = node.getDimExp().size() + node.getDim().size();
00396         currentType = new ArrayType(currentType, dimensions);
00397     } catch (Exception e) {
00398         exceptions.add(e);
00399         currentType = VoidType.TYPE;
00400     }
00401 }
00402 /**
00403  * 
00404  * @param node edu.ksu.cis.bandera.jjjc.node.ADecimalIntegerLiteral
00405  */
00406 public void caseADecimalIntegerLiteral(ADecimalIntegerLiteral node) {
00407     String literal = node.toString().trim();
00408     if (literal.endsWith("L") || literal.endsWith("l")) {
00409         currentType = LongType.TYPE;
00410     } else {
00411         currentType = IntType.TYPE;
00412     }
00413 }
00414 /**
00415  * 
00416  * @param node edu.ksu.cis.bandera.jjjc.node.ADoublePrimitiveType
00417  */
00418 public void caseADoublePrimitiveType(ADoublePrimitiveType node) {
00419     currentType = DoubleType.TYPE;
00420 }
00421 /**
00422  * 
00423  * @param node edu.ksu.cis.bandera.jjjc.node.AExpCastExp
00424  */
00425 public void caseAExpCastExp(AExpCastExp node) {
00426     currentType = VoidType.TYPE;
00427     Type destType;
00428     try {
00429         destType = symbolTable.resolveType(new Name(node.getFirst().toString()));
00430     } catch (Exception e) {
00431         exceptions.add(new TypeException("Invalid casting type " + node.getFirst()));
00432         return;
00433     }
00434     node.getSecond().apply(this);
00435     if (!currentType.isValidCastingConversion(destType)) {
00436         exceptions.add(new TypeException("Invalid casting type"));
00437     }
00438     currentType = destType;
00439 }
00440 /**
00441  * 
00442  * @param node edu.ksu.cis.bandera.jjjc.node.AExpVariableInitializer
00443  */
00444 public void caseAExpVariableInitializer(AExpVariableInitializer node) {
00445     Type destType = currentType;
00446     node.getExp().apply(this);
00447     if (!(currentType.isValidIdentityConversion(destType) || currentType.isValidWideningConversion(destType))) {
00448         exceptions.add(new TypeException("Type mismatch in array initializer"));
00449     }
00450     currentType = destType;
00451 }
00452 /**
00453  * 
00454  * @param node edu.ksu.cis.bandera.jjjc.node.AFalseBooleanLiteral
00455  */
00456 public void caseAFalseBooleanLiteral(AFalseBooleanLiteral node) {
00457     currentType = BooleanType.TYPE;
00458 }
00459 /**
00460  * 
00461  * @param node edu.ksu.cis.bandera.jjjc.node.AFloatingPointLiteralLiteral
00462  */
00463 public void caseAFloatingPointLiteralLiteral(AFloatingPointLiteralLiteral node) {
00464     String literal = node.toString().trim();
00465     if (literal.endsWith("F") || literal.endsWith("f"))
00466         currentType = FloatType.TYPE;
00467     else
00468         currentType = DoubleType.TYPE;
00469 }
00470 /**
00471  * 
00472  * @param node edu.ksu.cis.bandera.jjjc.node.AFloatPrimitiveType
00473  */
00474 public void caseAFloatPrimitiveType(AFloatPrimitiveType node) {
00475     currentType = FloatType.TYPE;
00476 }
00477 /**
00478  * 
00479  * @param node edu.ksu.cis.bandera.jjjc.node.AHexIntegerLiteral
00480  */
00481 public void caseAHexIntegerLiteral(AHexIntegerLiteral node) {
00482     String literal = node.toString().substring(2).trim();
00483     if (literal.endsWith("L") || literal.endsWith("l")) {
00484         currentType = LongType.TYPE;
00485     } else {
00486         currentType = IntType.TYPE;
00487     }
00488 }
00489 /**
00490  * 
00491  * @param node edu.ksu.cis.bandera.jjjc.node.AInitClassInterfaceExp
00492  */
00493 public void caseAInitClassInterfaceExp(AInitClassInterfaceExp node) {
00494     try {
00495         currentType = symbolTable.resolveType(new Name(node.getClassOrInterfaceType().toString()));
00496         Type resultType = currentType = new ArrayType(currentType, node.getDim().size());
00497         node.getArrayInitializer().apply(this);
00498         currentType = resultType;
00499     } catch (Exception e) {
00500         exceptions.add(e);
00501         currentType = VoidType.TYPE;
00502     }
00503 }
00504 /**
00505  * 
00506  * @param node edu.ksu.cis.bandera.jjjc.node.AInitPrimitiveExp
00507  */
00508 public void caseAInitPrimitiveExp(AInitPrimitiveExp node) {
00509     node.getPrimitiveType().apply(this);
00510     Type resultType = currentType = new ArrayType(currentType, node.getDim().size());
00511     node.getArrayInitializer().apply(this);
00512     currentType = resultType;
00513 }
00514 /**
00515  * 
00516  * @param node edu.ksu.cis.bandera.jjjc.node.AInstanceofExp
00517  */
00518 public void caseAInstanceofExp(AInstanceofExp node) {
00519     node.getExp().apply(this);
00520     boolean flag = false;
00521     try {
00522         Type type = symbolTable.resolveClassOrInterfaceType(new Name(node.getReferenceType().toString()));
00523         if ((type instanceof ReferenceType) && (currentType instanceof ReferenceType))
00524             flag = true;
00525     } catch (Exception e) {
00526         exceptions.add(e);
00527     }
00528     if (!flag) {
00529         exceptions.add(new TypeException("Invalid type in instanceof expression"));
00530         currentType = BooleanType.TYPE;
00531     }
00532 }
00533 /**
00534  * 
00535  * @param node edu.ksu.cis.bandera.jjjc.node.AIntPrimitiveType
00536  */
00537 public void caseAIntPrimitiveType(AIntPrimitiveType node) {
00538     currentType = IntType.TYPE;
00539 }
00540 /**
00541  * 
00542  * @param node edu.ksu.cis.bandera.jjjc.node.ALongPrimitiveType
00543  */
00544 public void caseALongPrimitiveType(ALongPrimitiveType node) {
00545     currentType = LongType.TYPE;
00546 }
00547 /**
00548  * 
00549  * @param node edu.ksu.cis.bandera.jjjc.node.ANameArrayAccess
00550  */
00551 public void caseANameArrayAccess(ANameArrayAccess node) {
00552     new ANameExp((PName) node.getName().clone()).apply(this);
00553     if (!(currentType instanceof ArrayType)) {
00554         exceptions.add(new TypeException("Not an array type in array access"));
00555         currentType = VoidType.TYPE;
00556         return;
00557     }
00558     ArrayType arrayType = (ArrayType) currentType;
00559     node.getExp().apply(this);
00560     if (!(currentType instanceof IntegralType)) {
00561         exceptions.add(new TypeException("Expecting integral expression in array access"));
00562     }
00563     if (arrayType.nDimensions > 1) {
00564         currentType = new ArrayType(arrayType.baseType , arrayType.nDimensions - 1);
00565     } else {
00566         currentType = arrayType.baseType;
00567     }
00568 }
00569 /**
00570  * 
00571  * @param node edu.ksu.cis.bandera.jjjc.node.ANameCastExp
00572  */
00573 public void caseANameCastExp(ANameCastExp node) {
00574     currentType = VoidType.TYPE;
00575     Type destType;
00576     try {
00577         destType = symbolTable.resolveType(new Name(node.getName().toString()));
00578     } catch (Exception e) {
00579         exceptions.add(new TypeException("Invalid casting type " + node.getName()));
00580         return;
00581     }
00582     int dimension = node.getDim().size();
00583     if (dimension > 0) {
00584         destType = new ArrayType(destType, dimension);
00585     }
00586     node.getExp().apply(this);
00587     if (!currentType.isValidCastingConversion(destType)) {
00588         exceptions.add(new TypeException("Invalid casting type"));
00589     }
00590     currentType = destType;
00591 }
00592 /**
00593  * 
00594  * @param node edu.ksu.cis.bandera.jjjc.node.ANamedTypeExp
00595  */
00596 public void caseANamedTypeExp(ANamedTypeExp node) {
00597     currentType = VoidType.TYPE;
00598     exceptions.add(new TypeException("unsupported expression " + node));
00599 }
00600 /**
00601  * 
00602  * @param node edu.ksu.cis.bandera.jjjc.node.ANameExp
00603  */
00604 public void caseANameExp(ANameExp node) {
00605     if ("$ret".equals(node.toString().trim())) {
00606         if (annotation instanceof MethodDeclarationAnnotation) {
00607             currentType = ((MethodDeclarationAnnotation) annotation).getMethod().getReturnType();
00608         } else {
00609             currentType = VoidType.TYPE;
00610         }
00611         return;
00612     }
00613     if (node.getName() instanceof ASimpleName) {
00614         Hashtable visibleLocals = getDeclaredLocals();
00615         String local = node.getName().toString().trim();
00616         Name localOrFieldName = new Name(local);
00617         if (visibleLocals.get(local) != null) {
00618             try {
00619                 currentType = Util.convertType(((Local) visibleLocals.get(local)).getType(), symbolTable);
00620             } catch (Exception e) {
00621                 exceptions.add(e);
00622             }
00623         } else {
00624             try {
00625                 Field f = type.getField(localOrFieldName);
00626                 currentType = f.getType();
00627                 if (isStatic && !java.lang.reflect.Modifier.isStatic(f.getModifiers())) {
00628                     TId id = ((ASimpleName) node.getName()).getId();
00629                     exceptions.add(new TypeException("Cannot refer to instance field '"
00630                             + id.toString().trim() + "' in a static predicate"));
00631                 }
00632             } catch (Exception e) {
00633                 try {
00634                     currentType = symbolTable.resolveType(new Name(node.getName().toString()));
00635                 } catch (Exception e2) {
00636                     currentType = VoidType.TYPE;
00637                     exceptions.add(new TypeException("Unresolved name expression '" + localOrFieldName.toString()
00638                             + "' in " + type.getFullyQualifiedName()));
00639                 }
00640             }
00641         }
00642     } else {
00643         Name name = new Name(node.getName().toString()).getSuperName();
00644         ClassOrInterfaceType type = null;
00645         PName typeName = ((AQualifiedName) node.getName()).getName();
00646         while (!name.isSimpleName()) {
00647             try {
00648                 type = (ClassOrInterfaceType) symbolTable.resolveType(name);
00649                 break;
00650             } catch (Exception e) {
00651                 name = name.getSuperName();
00652                 typeName = ((AQualifiedName) typeName).getName();
00653             }
00654         }
00655         
00656         if (type == null) {
00657             try {
00658                 type = (ClassOrInterfaceType) symbolTable.resolveType(name);
00659             } catch (Exception e) {
00660                 try {
00661                     currentType = (ClassOrInterfaceType) symbolTable.resolveType(new Name(node.getName().toString()));
00662                     usedTypeNames.add(node);
00663                     return;
00664                 } catch (Exception e2) {
00665                     PExp exp = buildFieldAccess((AQualifiedName) node.getName().clone());
00666                     node.replaceBy(exp);
00667                     exp.apply(this);
00668                     return;
00669                 }
00670             }
00671         }
00672 
00673         String nameExp = new Name(node.getName().toString()).toString();
00674         Name n = new Name(nameExp.substring(type.getFullyQualifiedName().length() + 1));
00675         nameExp = n.getSubName().toString();
00676         PName newName = (PName) typeName.parent().clone();
00677         try {
00678             currentType = type.getField(new Name(n.getFirstIdentifier())).getType();
00679         } catch (Exception e) {
00680             exceptions.add(e);
00681             currentType = VoidType.TYPE;
00682         }
00683         PExp exp = buildFieldAccess(new ANameExp(newName), nameExp);
00684         node.replaceBy(exp);
00685     }
00686 }
00687 /**
00688  * 
00689  * @param node edu.ksu.cis.bandera.jjjc.node.ANameMethodInvocationExp
00690  */
00691 public void caseANameMethodInvocationExp(ANameMethodInvocationExp node) {
00692     Vector types = new Vector();
00693     {
00694         Object temp[] = node.getArgumentList().toArray();
00695         for (int i = 0; i < temp.length; i++) {
00696             ((PExp) temp[i]).apply(this);
00697             types.add(currentType);
00698         }
00699     }
00700 
00701     Name methodName;
00702     if (node.getName() instanceof AQualifiedName) {
00703         new ANameExp((PName) ((AQualifiedName) node.getName()).getName().clone()).apply(this);
00704         methodName = new Name(((AQualifiedName) node.getName()).getId().toString());
00705     } else {
00706         currentType = type;
00707         methodName = new Name(((ASimpleName) node.getName()).getId().toString());
00708     }
00709 
00710     try {
00711         Method m = symbolTable.resolveMethod(currentType.getName(), methodName, types);
00712         currentType = m.getReturnType();
00713     } catch (Exception e) {
00714         exceptions.add(e);
00715         currentType = VoidType.TYPE;
00716     }
00717 }
00718 /**
00719  * 
00720  * @param node edu.ksu.cis.bandera.jjjc.node.ANullLiteral
00721  */
00722 public void caseANullLiteral(ANullLiteral node) {
00723     currentType = NullType.TYPE;
00724 }
00725 /**
00726  * 
00727  * @param node edu.ksu.cis.bandera.jjjc.node.AOctalIntegerLiteral
00728  */
00729 public void caseAOctalIntegerLiteral(AOctalIntegerLiteral node) {
00730     String literal = node.toString().substring(1).trim();
00731     if (literal.endsWith("L") || literal.endsWith("l")) {
00732         currentType = LongType.TYPE;
00733     } else {
00734         currentType = IntType.TYPE;
00735     }
00736 }
00737 /**
00738  * 
00739  * @param node edu.ksu.cis.bandera.jjjc.node.APostDecrementExp
00740  */
00741 public void caseAPostDecrementExp(APostDecrementExp node) {
00742     node.getExp().apply(this);
00743     if (!(currentType instanceof IntegralType)) {
00744         currentType = IntType.TYPE;
00745         exceptions.add(new TypeException("Expecting an integral expression for unary operator --"));
00746     } 
00747 }
00748 /**
00749  * 
00750  * @param node edu.ksu.cis.bandera.jjjc.node.APostIncrementExp
00751  */
00752 public void caseAPostIncrementExp(APostIncrementExp node) {
00753     node.getExp().apply(this);
00754     if (!(currentType instanceof IntegralType)) {
00755         currentType = IntType.TYPE;
00756         exceptions.add(new TypeException("Expecting an integral expression for unary operator ++"));
00757     } 
00758 }
00759 /**
00760  * 
00761  * @param node edu.ksu.cis.bandera.jjjc.node.APrimaryFieldAccess
00762  */
00763 public void caseAPrimaryFieldAccess(APrimaryFieldAccess node) {
00764     node.getExp().apply(this);
00765     if ((currentType instanceof ArrayType) && ("length".equals(node.getId().toString().trim()))) {
00766         currentType = IntType.TYPE;
00767     } else if (currentType instanceof ClassOrInterfaceType) {
00768         try {
00769             currentType = ((ClassOrInterfaceType) currentType).getField(new Name(node.getId().toString())).getType();
00770         } catch (Exception e) {
00771             exceptions.add(new TypeException("unresolved field name " + node.getId()));
00772             currentType = VoidType.TYPE;
00773         }
00774     } else {
00775         exceptions.add(new TypeException("Invalid type in field access"));
00776         currentType = VoidType.TYPE;
00777     }
00778 }
00779 /**
00780  * 
00781  * @param node edu.ksu.cis.bandera.jjjc.node.APrimaryMethodInvocationExp
00782  */
00783 public void caseAPrimaryMethodInvocationExp(APrimaryMethodInvocationExp node) {
00784     Vector types = new Vector();
00785     {
00786         Object temp[] = node.getArgumentList().toArray();
00787         for (int i = 0; i < temp.length; i++) {
00788             ((PExp) temp[i]).apply(this);
00789             types.add(currentType);
00790         }
00791     }
00792 
00793     Name methodName = methodName = new Name(node.getId().toString());
00794     node.getExp().apply(this);
00795     try {
00796         Method m = symbolTable.resolveMethod(currentType.getName(), methodName, types);
00797         currentType = m.getReturnType();
00798     } catch (Exception e) {
00799         exceptions.add(e);
00800         currentType = VoidType.TYPE;
00801     }
00802 }
00803 /**
00804  * 
00805  * @param node edu.ksu.cis.bandera.jjjc.node.APrimaryNoNewArrayArrayAccess
00806  */
00807 public void caseAPrimaryNoNewArrayArrayAccess(APrimaryNoNewArrayArrayAccess node) {
00808     node.getFirst().apply(this);
00809     if (!(currentType instanceof ArrayType)) {
00810         exceptions.add(new TypeException("Not an array type in array access"));
00811         currentType = VoidType.TYPE;
00812         return;
00813     }
00814     ArrayType arrayType = (ArrayType) currentType;
00815     node.getSecond().apply(this);
00816     if (!(currentType instanceof IntegralType)) {
00817         exceptions.add(new TypeException("Expecting integral expression in array access"));
00818     }
00819     if (arrayType.nDimensions > 1) {
00820         currentType = new ArrayType(arrayType.baseType , arrayType.nDimensions - 1);
00821     } else {
00822         currentType = arrayType.baseType;
00823     }
00824 }
00825 /**
00826  * 
00827  * @param node edu.ksu.cis.bandera.jjjc.node.APrimitiveTypeArrayExp
00828  */
00829 public void caseAPrimitiveTypeArrayExp(APrimitiveTypeArrayExp node) {
00830     for (ca.mcgill.sable.util.Iterator i = node.getDimExp().iterator(); i.hasNext();) {
00831         ((PDimExp) i.next()).apply(this);
00832         if (!(currentType instanceof IntegralType)) {
00833             exceptions.add(new TypeException("Expecting integral expression in dim exp"));
00834         }
00835     }
00836 
00837     node.getPrimitiveType().apply(this);
00838     int dimensions = node.getDimExp().size() + node.getDim().size();
00839     currentType = new ArrayType(currentType, dimensions);
00840 }
00841 /**
00842  * 
00843  * @param node edu.ksu.cis.bandera.jjjc.node.APrimitiveTypeCastExp
00844  */
00845 public void caseAPrimitiveTypeCastExp(APrimitiveTypeCastExp node) {
00846     node.getPrimitiveType().apply(this);
00847     Type destType = currentType;
00848     int dimension = node.getDim().size();
00849     if (dimension > 0) {
00850         destType = new ArrayType(destType, dimension);
00851     }
00852     node.getExp().apply(this);
00853     
00854     if (!currentType.isValidCastingConversion(destType)) {
00855         exceptions.add(new TypeException("Invalid casting type"));
00856     }
00857     currentType = destType;
00858 }
00859 /**
00860  * 
00861  * @param node edu.ksu.cis.bandera.jjjc.node.APrimitiveTypePrimaryExp
00862  */
00863 public void caseAPrimitiveTypePrimaryExp(APrimitiveTypePrimaryExp node) {
00864     currentType = VoidType.TYPE;
00865     exceptions.add(new TypeException("unsupported expression " + node));
00866 }
00867 /**
00868  * 
00869  * @param node edu.ksu.cis.bandera.jjjc.node.AQualifiedClassInstanceCreationExp
00870  */
00871 public void caseAQualifiedClassInstanceCreationExp(AQualifiedClassInstanceCreationExp node) {
00872     currentType = VoidType.TYPE;
00873     exceptions.add(new TypeException("unsupported expression " + node));
00874 }
00875 /**
00876  * 
00877  * @param node edu.ksu.cis.bandera.jjjc.node.AQualifiedThisExp
00878  */
00879 public void caseAQualifiedThisExp(AQualifiedThisExp node) {
00880     currentType = VoidType.TYPE;
00881     exceptions.add(new TypeException("unsupported expression " + node));
00882 }
00883 /**
00884  * 
00885  * @param node edu.ksu.cis.bandera.jjjc.node.AQuestionExp
00886  */
00887 public void caseAQuestionExp(AQuestionExp node) {
00888     node.getFirst().apply(this);
00889     if (currentType != BooleanType.TYPE) {
00890         exceptions.add(new TypeException("Expecting a boolean expression for ?: first expression"));
00891     }
00892     node.getSecond().apply(this);
00893     Type trueType = currentType;
00894     node.getThird().apply(this);
00895     Type falseType = currentType;
00896 
00897     boolean flag = true;
00898     if (trueType == falseType) {
00899         currentType = trueType;
00900     } else if (trueType instanceof NumericType) {
00901         if (((trueType == ByteType.TYPE) && (falseType == ShortType.TYPE))
00902                 || ((trueType == ShortType.TYPE) && (falseType == ByteType.TYPE))) {
00903             currentType = ShortType.TYPE;
00904         } else if (((trueType == ByteType.TYPE) || (trueType == ShortType.TYPE)
00905                 || (trueType == CharType.TYPE)) && (falseType == IntType.TYPE)
00906                 && (node.getThird() instanceof ALiteralExp)) {
00907             currentType = trueType;
00908         } else if (((falseType == ByteType.TYPE) || (falseType == ShortType.TYPE)
00909                 || (falseType == CharType.TYPE)) && (trueType == IntType.TYPE)
00910                 && (node.getSecond() instanceof ALiteralExp)) {
00911             currentType = falseType;
00912         } else {
00913             currentType = getNumericType(trueType, falseType);
00914         }
00915     } else if ((trueType == NullType.TYPE) && (falseType instanceof ReferenceType)) {
00916         currentType = trueType;
00917     } else if ((trueType instanceof ReferenceType) && (falseType == NullType.TYPE)) {
00918         currentType = falseType;
00919     } else if ((trueType instanceof ReferenceType) && (falseType instanceof ReferenceType)) {
00920         if (trueType.isValidIdentityConversion(falseType)
00921                 && trueType.isValidWideningConversion(falseType)) {
00922             currentType = falseType;
00923         } else if (falseType.isValidIdentityConversion(trueType)
00924                 && falseType.isValidWideningConversion(trueType)) {
00925             currentType = trueType;
00926         } else flag = false;
00927     } else {
00928         flag = false;
00929     }
00930 
00931     if (!flag) {
00932         currentType = VoidType.TYPE;
00933         exceptions.add(new TypeException("Type mismatch in question expression"));
00934     }
00935 }
00936 /**
00937  * 
00938  * @param node edu.ksu.cis.bandera.jjjc.node.AShortPrimitiveType
00939  */
00940 public void caseAShortPrimitiveType(AShortPrimitiveType node) {
00941     currentType = ShortType.TYPE;
00942 }
00943 /**
00944  * 
00945  * @param node edu.ksu.cis.bandera.jjjc.node.ASimpleClassInstanceCreationExp
00946  */
00947 public void caseASimpleClassInstanceCreationExp(ASimpleClassInstanceCreationExp node) {
00948     currentType = VoidType.TYPE;
00949     exceptions.add(new TypeException("unsupported expression " + node));
00950 }
00951 /**
00952  * 
00953  * @param node edu.ksu.cis.bandera.jjjc.node.AStringLiteralLiteral
00954  */
00955 public void caseAStringLiteralLiteral(AStringLiteralLiteral node) {
00956     try {
00957         currentType = symbolTable.resolveType(new Name("java.lang.String"));
00958     } catch (Exception e) {
00959         exceptions.add(e);
00960         currentType = VoidType.TYPE;
00961     }
00962 }
00963 /**
00964  * 
00965  * @param node edu.ksu.cis.bandera.jjjc.node.ASuperFieldAccess
00966  */
00967 public void caseASuperFieldAccess(ASuperFieldAccess node) {
00968     try {
00969         currentType = type.getDirectSuperClass().getField(new Name(node.getId().toString())).getType();
00970     } catch (Exception e) {
00971         exceptions.add(new TypeException("Invalid field in super field access"));
00972         currentType = VoidType.TYPE;
00973     }
00974 }
00975 /**
00976  * 
00977  * @param node edu.ksu.cis.bandera.jjjc.node.ASuperMethodInvocationExp
00978  */
00979 public void caseASuperMethodInvocationExp(ASuperMethodInvocationExp node) {
00980     Vector types = new Vector();
00981     {
00982         Object temp[] = node.getArgumentList().toArray();
00983         for (int i = 0; i < temp.length; i++) {
00984             ((PExp) temp[i]).apply(this);
00985             types.add(currentType);
00986         }
00987     }
00988 
00989     Name methodName = methodName = new Name(node.getId().toString());
00990     currentType = type.getDirectSuperClass();
00991     try {
00992         Method m = symbolTable.resolveMethod(currentType.getName(), methodName, types);
00993         currentType = m.getReturnType();
00994     } catch (Exception e) {
00995         exceptions.add(e);
00996         currentType = VoidType.TYPE;
00997     }
00998 }
00999 /**
01000  * 
01001  * @param node edu.ksu.cis.bandera.jjjc.node.AThisExp
01002  */
01003 public void caseAThisExp(AThisExp node) {
01004     currentType = type;
01005 }
01006 /**
01007  * 
01008  * @param node edu.ksu.cis.bandera.jjjc.node.ATrueBooleanLiteral
01009  */
01010 public void caseATrueBooleanLiteral(ATrueBooleanLiteral node) {
01011     currentType = BooleanType.TYPE;
01012 }
01013 /**
01014  * 
01015  * @param node edu.ksu.cis.bandera.jjjc.node.AUnaryExp
01016  */
01017 public void caseAUnaryExp(AUnaryExp node) {
01018     PUnaryOperator op = node.getUnaryOperator();
01019     node.getExp().apply(this);
01020     if (op instanceof AIncrementUnaryOperator) {
01021         if (!(currentType instanceof IntegralType)) {
01022             currentType = IntType.TYPE;
01023             exceptions.add(new TypeException("Expecting an integral expression for unary operator ++"));
01024         } 
01025     } else if (op instanceof ADecrementUnaryOperator) {
01026         if (!(currentType instanceof IntegralType)) {
01027             currentType = IntType.TYPE;
01028             exceptions.add(new TypeException("Expecting an integral expression for unary operator --"));
01029         } 
01030     } else if (op instanceof APlusUnaryOperator) {
01031         if (!(currentType instanceof NumericType)) {
01032             currentType = IntType.TYPE;
01033             exceptions.add(new TypeException("Expecting a numeric expression for unary operator +"));
01034         }
01035     } else if (op instanceof AMinusUnaryOperator) {
01036         if (!(currentType instanceof NumericType)) {
01037             currentType = IntType.TYPE;
01038             exceptions.add(new TypeException("Expecting a numeric expression for unary operator -"));
01039         }
01040     } else if (op instanceof ABitComplementUnaryOperator) {
01041         if (!(currentType instanceof IntegralType)) {
01042             currentType = IntType.TYPE;
01043             exceptions.add(new TypeException("Expecting an integral expression for unary operator ~"));
01044         }
01045         if (!(currentType instanceof LongType)) {
01046             currentType = IntType.TYPE;
01047         }
01048     } else if (op instanceof AComplementUnaryOperator) {
01049         if (currentType != BooleanType.TYPE) {
01050             currentType = BooleanType.TYPE;
01051             exceptions.add(new TypeException("Expecting a boolean expression for unary operator !"));
01052         }
01053     }
01054 }
01055 /**
01056  * 
01057  * @param node edu.ksu.cis.bandera.jjjc.node.AVoidExp
01058  */
01059 public void caseAVoidExp(AVoidExp node) {
01060     currentType = VoidType.TYPE;
01061     exceptions.add(new TypeException("unsupported expression " + node));
01062 }
01063 /**
01064  * 
01065  * @return java.lang.Vector
01066  * @param node edu.ksu.cis.bandera.jjjc.node.Node
01067  */
01068 public Vector check(Node node) {
01069     node.apply(this);
01070 
01071     if (currentType != BooleanType.TYPE) {
01072         exceptions.add(new TypeException("Assertion expression should be boolean type"));
01073     }
01074     
01075     return exceptions;
01076 }
01077 /**
01078  * 
01079  * @return java.util.Hashtable
01080  */
01081 private Hashtable getDeclaredLocals() {
01082     if (currentAnnotation != null) {
01083         Hashtable visibleLocals;
01084         if (annotation instanceof MethodDeclarationAnnotation) {
01085             visibleLocals = ((MethodDeclarationAnnotation) annotation).getParameterLocals();
01086         } else {
01087             visibleLocals = ((ConstructorDeclarationAnnotation) annotation).getParameterLocals();
01088         }
01089         for (Enumeration e = currentAnnotation.getDeclaredLocalVariables().elements();
01090                 e.hasMoreElements();) {
01091             Local l = (Local) e.nextElement();
01092             visibleLocals.put(l.getName().trim(), l);
01093         }
01094         return visibleLocals;
01095     } else {
01096         if (annotation instanceof MethodDeclarationAnnotation) {
01097             return ((MethodDeclarationAnnotation) annotation).getParameterLocals();
01098         } else {
01099             return ((ConstructorDeclarationAnnotation) annotation).getParameterLocals();
01100         }
01101     }
01102 }
01103 /**
01104  * 
01105  * @return java.util.Vector
01106  */
01107 public Vector getExceptions() {
01108     return exceptions;
01109 }
01110 /**
01111  * 
01112  * @return edu.ksu.cis.bandera.jjjc.symboltable.Type
01113  * @param leftType edu.ksu.cis.bandera.jjjc.symboltable.Type
01114  * @param rightType edu.ksu.cis.bandera.jjjc.symboltable.Type
01115  */
01116 private Type getIntegralType(Type leftType, Type rightType) {
01117     if (!(leftType instanceof IntegralType) || !(rightType instanceof IntegralType))
01118         return null;
01119     if ((leftType == LongType.TYPE) || (rightType == LongType.TYPE))
01120         return LongType.TYPE;
01121     else if ((leftType instanceof IntegralType) || (rightType instanceof IntegralType))
01122         return IntType.TYPE;
01123     else return null;
01124 }
01125 /**
01126  * 
01127  * @return edu.ksu.cis.bandera.jjjc.symboltable.Type
01128  * @param leftType edu.ksu.cis.bandera.jjjc.symboltable.Type
01129  * @param rightType edu.ksu.cis.bandera.jjjc.symboltable.Type
01130  */
01131 private Type getNumericType(Type leftType, Type rightType) {
01132     if (!(leftType instanceof NumericType) || !(rightType instanceof NumericType))
01133         return null;
01134     if ((leftType == LongType.TYPE) || (rightType == LongType.TYPE))
01135         return LongType.TYPE;
01136     else if ((leftType == FloatType.TYPE) || (rightType == FloatType.TYPE))
01137         return FloatType.TYPE;
01138     else if ((leftType == DoubleType.TYPE) || (rightType == DoubleType.TYPE))
01139         return DoubleType.TYPE;
01140     else if ((leftType instanceof IntegralType) || (rightType instanceof IntegralType))
01141         return IntType.TYPE;
01142     else return null;
01143 }
01144 }

Generated at Thu Feb 7 06:58:40 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001