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

SymbolTable.java

00001 package edu.ksu.cis.bandera.jjjc.symboltable;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 1999, 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 java.io.*;
00036 import java.util.*;
00037 import java.lang.reflect.*;
00038 import edu.ksu.cis.bandera.jjjc.*;
00039 import edu.ksu.cis.bandera.jjjc.node.*;
00040 import edu.ksu.cis.bandera.jjjc.lexer.*;
00041 import ca.mcgill.sable.laleh.java.astfix.*;
00042 import edu.ksu.cis.bandera.jjjc.unicodepreprocessor.*;
00043 import edu.ksu.cis.bandera.jjjc.analysis.*;
00044 import edu.ksu.cis.bandera.jjjc.exception.*;
00045 import edu.ksu.cis.bandera.jjjc.util.*;
00046 
00047 public class SymbolTable {
00048     private Hashtable declaredTypes = new Hashtable();
00049   private Hashtable importedTypesOnDemand = new Hashtable();
00050   private Hashtable importedTypes = new Hashtable();
00051   private static Hashtable primitiveTypes = new Hashtable();
00052 
00053   private Package currentPackage = null;
00054   private ClassOrInterfaceType currentClassOrInterfaceType = null;
00055   private String currentJavaFilePath = null;
00056   private Stack scopes = new Stack();
00057 
00058   static {
00059       initPrimitiveTypes();
00060   }
00061 /**
00062  * 
00063  * @param name edu.ksu.cis.bandera.jjjc.symboltable.Name
00064  */
00065 public SymbolTable(Name name) throws CompilerException {
00066 
00067     ClassOrInterfaceType classOrInterfaceType = Package.getClassOrInterfaceType(name);
00068 
00069     loadFromClassFile(classOrInterfaceType);
00070     
00071     for (Enumeration e = declaredTypes.elements(); e.hasMoreElements();) {
00072         ClassOrInterfaceType type = (ClassOrInterfaceType) e.nextElement();
00073         type.loadReferences();
00074     }
00075 }
00076 /**
00077  * 
00078  * @param path java.lang.String
00079  */
00080 public SymbolTable(String path) throws CompilerException {
00081     loadFromSourceFile(path);
00082 
00083     for (Enumeration e = declaredTypes.elements(); e.hasMoreElements();) {
00084         ClassOrInterfaceType classOrInterfaceType = (ClassOrInterfaceType) e.nextElement();
00085         classOrInterfaceType.loadReferences();
00086     }
00087 }
00088 /**
00089  * 
00090  * @return edu.ksu.cis.bandera.jjjc.symboltable.Type
00091  * @param type java.lang.Class
00092  */
00093 protected Type convertType(Class type) throws InvalidNameException, ClassOrInterfaceTypeNotFoundException {
00094     if (type == Boolean.TYPE) return BooleanType.TYPE;
00095     else if (type == Byte.TYPE) return ByteType.TYPE;
00096     else if (type == Character.TYPE) return CharType.TYPE;
00097     else if (type == Short.TYPE) return ShortType.TYPE;
00098     else if (type == Integer.TYPE) return IntType.TYPE;
00099     else if (type == Long.TYPE) return LongType.TYPE;
00100     else if (type == Float.TYPE) return FloatType.TYPE;
00101     else if (type == Double.TYPE) return DoubleType.TYPE;
00102     else if (type == Void.TYPE) return VoidType.TYPE;
00103     else if (type.isArray()) {
00104         Type componentType = convertType(type.getComponentType());
00105         if (componentType instanceof ArrayType) {
00106             ArrayType arrayType = (ArrayType) componentType;
00107             arrayType.nDimensions++;
00108             return arrayType;
00109         } else
00110             return new ArrayType(componentType, 1);
00111     } else
00112         return Package.getClassOrInterfaceType(new Name(type.getName()));
00113 }
00114 /**
00115  * 
00116  * @param variable edu.ksu.cis.bandera.jjjc.symboltable.Variable
00117  */
00118 public void declareLocalVariable(Variable variable) throws AlreadyDeclaredException {
00119     Name varName = variable.getName();
00120     
00121     for (int i = 0; i < scopes.size(); i++)
00122         if (((Hashtable) scopes.elementAt(i)).get(varName) != null)
00123             throw new AlreadyDeclaredException("Local variable named '" + varName.toString() + "' has already declared");
00124     
00125     Hashtable scope = (Hashtable) scopes.peek();
00126     scope.put(varName, variable);
00127 }
00128 /**
00129  * 
00130  * @return edu.ksu.cis.bandera.jjjc.symboltable.ClassOrInterfaceType
00131  * @param name edu.ksu.cis.bandera.jjjc.symboltable.Name
00132  */
00133 public ClassOrInterfaceType declareType(Name name) throws InvalidNameException {
00134     String msg1 = name.toString() + " in " + currentPackage.getName().toString();
00135     String msg2 = "Could not declare type with name " + msg1;
00136     
00137     if (!(name.isSimpleName()))
00138         throw new InvalidNameException(msg2);
00139 
00140     if (primitiveTypes.get(name) != null)
00141         throw new InvalidNameException(msg2);
00142 
00143     if (importedTypes.get(name) != null)
00144         throw new InvalidNameException(msg2);
00145 
00146   Name className = new Name(currentPackage.getName(), name);
00147 
00148   if (declaredTypes.get(className) != null)
00149         throw new InvalidNameException("Redefinition of type with name " + msg1);
00150 
00151     ClassOrInterfaceType declaredType;
00152     try {
00153         declaredType = Package.getClassOrInterfaceType(className);
00154     } catch (ClassOrInterfaceTypeNotFoundException e) {
00155         declaredType = new ClassOrInterfaceType(currentPackage, name, currentJavaFilePath);
00156         currentPackage.addType(declaredType);
00157     }
00158 
00159     declaredTypes.put(name, declaredType);
00160     
00161     return declaredType;
00162 }
00163 /**
00164  * 
00165  */
00166 public void enterScope() {
00167     scopes.push(new Hashtable());
00168 }
00169 /**
00170  * 
00171  */
00172 public void exitScope() {
00173     scopes.pop();
00174 }
00175 /**
00176  * 
00177  * @return edu.ksu.cis.bandera.jjjc.symboltable.ClassOrInterfaceType
00178  */
00179 public ClassOrInterfaceType getCurrentClassOrInterfaceType() {
00180     return currentClassOrInterfaceType;
00181 }
00182 /**
00183  * 
00184  * @return edu.ksu.cis.bandera.jjjc.symboltable.Package
00185  */
00186 public Package getCurrentPackage() {
00187     return currentPackage;
00188 }
00189 /**
00190  * 
00191  * @return edu.ksu.cis.bandera.jjjc.symboltable.ClassOrInterfaceType
00192  * @param name edu.ksu.cis.bandera.jjjc.symboltable.Name
00193  */
00194 public ClassOrInterfaceType getDeclaredType(Name name) throws NotDeclaredException {
00195     if (declaredTypes.get(name) == null)
00196         throw new NotDeclaredException("Type named '" + name + "' is not declared");
00197     else
00198         return (ClassOrInterfaceType) declaredTypes.get(name);
00199 }
00200 /**
00201  * 
00202  * @return java.util.Enumeration
00203  */
00204 public Enumeration getDeclaredTypes() {
00205     return declaredTypes.elements();
00206 }
00207 /**
00208  * 
00209  * @return java.lang.String
00210  * @param exceptions java.util.Enumeration
00211  */
00212 private String getExceptionMessages(Enumeration exceptions) {
00213     String msg = "{";
00214     for (Enumeration e = exceptions; e.hasMoreElements();) {
00215         msg += (e.nextElement().toString() + ", ");
00216     }
00217     return msg.substring(0, msg.length() - 2) + "}";
00218 }
00219 /**
00220  * 
00221  * @return edu.ksu.cis.bandera.jjjc.symboltable.Variable
00222  * @param name edu.ksu.cis.bandera.jjjc.symboltable.Name
00223  */
00224 public Variable getLocalVariable(Name name) throws NotDeclaredException {
00225     for (int i = 0; i < scopes.size(); i++)
00226         if (((Hashtable) scopes.elementAt(i)).get(name) != null)
00227             return (Variable) ((Hashtable) scopes.elementAt(i)).get(name);
00228     
00229     throw new NotDeclaredException("Local variable named '" + name.toString() + "' is not declared");
00230 }
00231 /**
00232  * 
00233  * @return edu.ksu.cis.bandera.jjjc.symboltable.Method
00234  * @param methods java.util.Vector
00235  */
00236 private Method getMostSpecificMethod(Vector methods) throws AmbiguousMethodException {
00237     Vector result = (Vector) methods.clone();
00238 
00239     for (Enumeration e1 = methods.elements(); e1.hasMoreElements();) {
00240       Method m1 = (Method) e1.nextElement();
00241 
00242       for (Enumeration e2 = methods.elements(); e2.hasMoreElements();) {
00243             Method m2 = (Method) e2.nextElement();
00244             
00245             if ((m1 != m2) && m2.isMoreSpecific(m1)) {
00246               result.removeElement(m1);
00247               break;
00248             }
00249       }
00250     }
00251 
00252     if (result.size() > 1)
00253         try {
00254             Method m = (Method) result.elementAt(0);
00255             throw new AmbiguousMethodException("Cannot determine the most specific method for method named '"
00256                 + m.getName().toString() + "' in class or interface type named '"
00257                 + m.getDeclaringClassOrInterface().getName().toString() + "'");
00258         } catch (NotDeclaredException nde) {
00259             nde.printStackTrace();
00260             System.exit(1);
00261         }
00262         
00263     return (Method) result.elementAt(0);    
00264 }
00265 /**
00266  * 
00267  * @return int
00268  */
00269 public int getNumScopeLevels() {
00270     return scopes.size();
00271 }
00272 /**
00273  * 
00274  * @return java.lang.String
00275  */
00276 public String getPath() {
00277     return currentJavaFilePath;
00278 }
00279 /**
00280  * 
00281  * @return boolean
00282  * @param name edu.ksu.cis.bandera.jjjc.symboltable.Name
00283  */
00284 public boolean hasLocalVariableDeclared(Name name) {
00285     for (int i = 0; i < scopes.size(); i++)
00286         if (((Hashtable) scopes.elementAt(i)).get(name) != null)
00287             return true;
00288             
00289     return false;
00290 }
00291 /**
00292  * 
00293  * @param name edu.ksu.cis.bandera.jjjc.symboltable.Name
00294  */
00295 public void importType(Name name) throws InvalidNameException, ClassOrInterfaceTypeNotFoundException {
00296     String msg1 = "Invalid import type name '" + name + "'";
00297     String msg2 = "Redefinition of type '" + name + "' in import type";
00298     
00299     Name simpleName = new Name(name.getLastIdentifier());
00300 
00301     if (simpleName.equals(""))
00302         throw new InvalidNameException(msg1);
00303 
00304     if (primitiveTypes.get(simpleName) != null)
00305         throw new InvalidNameException(msg1);
00306 
00307     if (declaredTypes.get(simpleName) != null)
00308         throw new InvalidNameException(msg2);
00309 
00310     if (importedTypes.get(simpleName) != null)
00311         throw new InvalidNameException(msg2);
00312 
00313     importedTypes.put(simpleName, Package.getClassOrInterfaceType(name));
00314 }
00315 /**
00316  * 
00317  * @param name edu.ksu.cis.bandera.jjjc.symboltable.Name
00318  */
00319 public void importTypeOnDemand(Name name) throws InvalidNameException {
00320     Package p = Package.getPackage(name);
00321     importedTypesOnDemand.put(p.getName(), p);
00322 }
00323 /**
00324  * 
00325  */
00326 private static void initPrimitiveTypes() {
00327     primitiveTypes.put(BooleanType.TYPE.getName(), BooleanType.TYPE);
00328     primitiveTypes.put(ByteType.TYPE.getName(), ByteType.TYPE);
00329     primitiveTypes.put(CharType.TYPE.getName(), CharType.TYPE);
00330     primitiveTypes.put(ShortType.TYPE.getName(), ShortType.TYPE);
00331     primitiveTypes.put(IntType.TYPE.getName(), IntType.TYPE);
00332     primitiveTypes.put(LongType.TYPE.getName(), LongType.TYPE);
00333     primitiveTypes.put(FloatType.TYPE.getName(), FloatType.TYPE);
00334     primitiveTypes.put(DoubleType.TYPE.getName(), DoubleType.TYPE);
00335 }
00336 /**
00337  * 
00338  * @param classOrInterfaceType edu.ksu.cis.bandera.jjjc.symboltable.ClassOrInterfaceType
00339  */
00340 private void loadFromClassFile(ClassOrInterfaceType classOrInterfaceType) throws InvalidNameException,
00341         AlreadyDeclaredException, ClassOrInterfaceTypeNotFoundException {
00342 
00343     /*
00344     if (analyzedType.get(classOrInterfaceType.toString()) == null)
00345         analyzedType.put(classOrInterfaceType.toString(), classOrInterfaceType);
00346     else
00347         System.out.println("Type '" + classOrInterfaceType.toString() + "' is analyzed again");
00348     */
00349     classOrInterfaceType.setLoadingState();
00350         
00351     Class classOrInterface = null;
00352     
00353     try {
00354         classOrInterface = Class.forName(classOrInterfaceType.getName().toString());
00355     } catch (ClassNotFoundException cnfe) {}
00356 
00357     classOrInterfaceType.setInterface(classOrInterface.isInterface());
00358 
00359     if (classOrInterface.getSuperclass() != null) {
00360         classOrInterfaceType.setSuperClass((ClassOrInterfaceType) convertType(classOrInterface.getSuperclass()));
00361     } else {
00362         if (!"java.lang.Object".equals(classOrInterface.getName().trim())) {
00363             classOrInterfaceType.setSuperClass(Package.getClassOrInterfaceType(new Name("java.lang.Object")));
00364         }
00365     }
00366 
00367     Class[] superInterfaces = classOrInterface.getInterfaces();
00368     for (int i = 0; i < superInterfaces.length; i++) {
00369         classOrInterfaceType.addSuperInterface((ClassOrInterfaceType) convertType(superInterfaces[i]));
00370     }
00371 
00372     if (classOrInterface.getDeclaringClass() != null) {
00373         classOrInterfaceType.setDeclaringClass((ClassOrInterfaceType) convertType(classOrInterface.getDeclaringClass()));
00374     }
00375     
00376     try {
00377         classOrInterfaceType.setModifiers(classOrInterface.getModifiers());
00378     } catch (InvalidModifiersException ime) {}
00379     
00380     java.lang.reflect.Field[] fields = classOrInterface.getDeclaredFields();
00381     java.lang.reflect.Constructor[] constructors = classOrInterface.getDeclaredConstructors();
00382     java.lang.reflect.Method[] methods = classOrInterface.getDeclaredMethods();
00383 
00384     for (int i = 0; i < fields.length; i++) {
00385         java.lang.reflect.Field field = fields[i];
00386         Type fieldType = convertType(field.getType());
00387         Name fieldName = new Name(field.getName());
00388         Field newField = new Field(fieldName, fieldType);
00389         classOrInterfaceType.addField(newField);
00390         
00391         try {
00392             newField.setModifiers(field.getModifiers());
00393         } catch (InvalidModifiersException ime) {}
00394     }
00395 
00396     Name constructorName = new Name((new Name(classOrInterface.getName())).getLastIdentifier());
00397     for (int i = 0; i < constructors.length; i++) {
00398         java.lang.reflect.Constructor constructor = constructors[i];
00399         Method method = new Method(constructorName);
00400 
00401         try {
00402             Class[] parmTypes = constructor.getParameterTypes();
00403             NameGenerator paramName = new NameGenerator("JJJCPARAM$");
00404             for (int j = 0; j < parmTypes.length; j++) {
00405                 try {
00406                     method.addParameterVariable(new Variable(0, convertType(parmTypes[j]),
00407                             new Name(paramName.newName())));
00408                 } catch (InvalidModifiersException ime) {}
00409             }
00410         } catch (AlreadyDeclaredException ade) {}
00411 
00412         Class[] exceptionTypes = constructor.getExceptionTypes();
00413         
00414         for (int j = 0; j < exceptionTypes.length; j++) {
00415             method.addException((ClassOrInterfaceType) convertType(exceptionTypes[j]));
00416         }
00417         
00418         classOrInterfaceType.addConstructor(method);
00419 
00420         try {
00421             method.setModifiers(constructor.getModifiers());
00422         } catch (InvalidModifiersException ime) {}
00423     }
00424     
00425     for (int i = 0; i < methods.length; i++) {
00426         java.lang.reflect.Method method = methods[i];
00427         Method newMethod = new Method(new Name(method.getName()));
00428 
00429         newMethod.setReturnType(convertType(method.getReturnType()));
00430 
00431         try {
00432             Class[] parmTypes = method.getParameterTypes();
00433             NameGenerator paramName = new NameGenerator("JJJCPARAM$");
00434             for (int j = 0; j < parmTypes.length; j++) {
00435                 try {
00436                     newMethod.addParameterVariable(new Variable(0, convertType(parmTypes[j]),
00437                             new Name(paramName.newName())));
00438                 } catch (InvalidModifiersException ime) {}
00439             }
00440         } catch (AlreadyDeclaredException ade) {}
00441 
00442         Class[] exceptionTypes = method.getExceptionTypes();
00443         for (int j = 0; j < exceptionTypes.length; j++) {
00444             newMethod.addException((ClassOrInterfaceType) convertType(exceptionTypes[j]));
00445         }   
00446 
00447         classOrInterfaceType.addMethod(newMethod);
00448 
00449         try {
00450             newMethod.setModifiers(method.getModifiers());
00451         } catch (InvalidModifiersException ime) {}
00452     }
00453 
00454     /*
00455 
00456     Class[] declaredClasses = classOrInterface.getDeclaredClasses();
00457     for (int i = 0; i < declaredClasses.length; i++) {
00458         classOrInterfaceType.addDeclaredType((ClassOrInterfaceType) convertType(declaredClasses[i]));
00459     }
00460 
00461     */
00462     
00463     classOrInterfaceType.setLoadedState();
00464     declaredTypes.put(new Name(classOrInterfaceType.getName().getLastIdentifier()), classOrInterfaceType);
00465 }
00466 /**
00467  * 
00468  * @param classOrInterfaceType edu.ksu.cis.bandera.jjjc.symboltable.ClassOrInterfaceType
00469  */
00470 private void loadFromSourceFile(String path) throws InvalidNameException, AnalysisException {
00471     currentJavaFilePath = path;
00472 
00473     Start ast = null;
00474         
00475     try {
00476         /*
00477         UnicodePreprocessor preprocessor = new UnicodePreprocessor(
00478                 new PushbackReader(new BufferedReader(new FileReader(currentJavaFilePath)), 1024));
00479 
00480         Lexer lexer = new Lexer(new PushbackReader(preprocessor, 1024));
00481         JJCParser parser = new JJCParser(lexer);
00482         ast = parser.parse();
00483         */
00484         ast = CompilationManager.parseFile(currentJavaFilePath);
00485     } catch (Exception e) {
00486         throw new AnalysisException(e.toString());
00487     }
00488 
00489     setCurrentPackage(Package.getPackage(new Name("")));
00490 
00491     Package javaLang = Package.getPackage(new Name("java.lang"));
00492     importedTypesOnDemand.put(javaLang.getName(), javaLang);
00493 
00494     CompilationUnitAnalysis compilationUnitAnalysis = new CompilationUnitAnalysis(this);
00495     ast.apply(compilationUnitAnalysis);
00496     if (compilationUnitAnalysis.getExceptions().hasMoreElements()) {
00497         String msg = getExceptionMessages(compilationUnitAnalysis.getExceptions());
00498         throw new AnalysisException("Compilation unit analysis for " + currentJavaFilePath
00499                 + " failed due to the following exceptions: " + msg);
00500     }
00501 
00502     ClassOrInterfaceAnalysis classOrInterfaceAnalysis = new ClassOrInterfaceAnalysis(this);
00503     ast.apply(classOrInterfaceAnalysis);
00504     if (classOrInterfaceAnalysis.getExceptions().hasMoreElements()) {
00505         String msg = getExceptionMessages(classOrInterfaceAnalysis.getExceptions());
00506         throw new AnalysisException("Class or interface analysis for " + currentJavaFilePath
00507                 + " failed due to the following exceptions: " + msg);
00508     }
00509 
00510     ClassOrInterfaceMembersAnalysis classOrInterfaceMembersAnalysis = new ClassOrInterfaceMembersAnalysis(this);
00511     ast.apply(classOrInterfaceMembersAnalysis);
00512     if (classOrInterfaceMembersAnalysis.getExceptions().hasMoreElements()) {
00513         String msg = getExceptionMessages(classOrInterfaceMembersAnalysis.getExceptions());
00514         throw new AnalysisException("Class or interface members analysis for " + currentJavaFilePath
00515                 + " failed due to the following exceptions: " + msg);
00516     }
00517 
00518     setLoadedState();
00519 }
00520 /**
00521  * 
00522  */
00523 public void resetScope() {
00524     scopes = new Stack();
00525 }
00526 /**
00527  * 
00528  * @return edu.ksu.cis.bandera.jjjc.symboltable.Named
00529  * @param name edu.ksu.cis.bandera.jjjc.symboltable.Name
00530  */
00531 public Named resolveAmbiguousName(Name name) throws MeaninglessNameException {
00532     try {
00533         return resolveExpression(name);
00534     } catch (CompilerException e) {
00535     }
00536     
00537     try {
00538         return resolveType(name);
00539     } catch (CompilerException e) {
00540     }
00541 
00542     try {
00543         return resolvePackage(name);
00544     } catch (CompilerException e) {
00545     }
00546 
00547     throw new MeaninglessNameException("Cannot resolve ambiguous name '" + name + "'");
00548 }
00549 /**
00550  * 
00551  * @return edu.ksu.cis.bandera.jjjc.symboltable.ClassOrInterfaceType
00552  * @param name edu.ksu.cis.bandera.jjjc.symboltable.Name
00553  */
00554 public ClassOrInterfaceType resolveClassOrInterfaceType(Name name) throws InvalidNameException,
00555         ClassOrInterfaceTypeNotFoundException, AmbiguousTypeException, ClassCircularityException, AlreadyDeclaredException,
00556         AmbiguousMethodException, AmbiguousFieldException, NotDeclaredException, AnalysisException {
00557     ClassOrInterfaceType type = null;
00558 
00559     if (name.isSimpleName()) {
00560         if (declaredTypes.get(name) != null)
00561             type = (ClassOrInterfaceType) declaredTypes.get(name);
00562         else if (importedTypes.get(name) != null)
00563             type = (ClassOrInterfaceType) importedTypes.get(name);
00564         else {
00565             int typesFound = 0;
00566 
00567             try {
00568                 type = Package.getClassOrInterfaceType(name);
00569             } catch (Exception e) {
00570             }
00571             if (type != null) return type;
00572                 
00573             for (Enumeration e = importedTypesOnDemand.elements(); e.hasMoreElements();) {
00574                 Package p = (Package) e.nextElement();
00575                 if (p.hasType(name)) {
00576                     if (typesFound == 0)
00577                         type = Package.getClassOrInterfaceType(new Name(p.getName(), name));
00578                     typesFound++;
00579                 }
00580             }
00581 
00582             if (typesFound > 1) {
00583                 throw new AmbiguousTypeException("Ambiguous type named '" + name + "' in import on demand");
00584             } else if (typesFound == 0) {
00585                 type = Package.getClassOrInterfaceType(new Name(currentPackage.getName(), name));
00586             }
00587         }
00588     } else {
00589         type = Package.getClassOrInterfaceType(name);
00590     }
00591 
00592     return type;
00593 }
00594 /**
00595  * 
00596  * @return edu.ksu.cis.bandera.jjjc.symboltable.Method
00597  * @param className edu.ksu.cis.bandera.jjjc.symboltable.Name
00598  * @param argumentTypes java.util.Vector
00599  */
00600 public Method resolveConstructor(Name className, Vector argumentTypes) throws CompilerException {
00601     String msg = "Could not find a constructor for type named '" + className.toString()
00602                 + "' with argument types " + argumentTypes.toString();
00603                 
00604     ClassOrInterfaceType classType = resolveClassOrInterfaceType(className);
00605     classType.loadReferences();
00606     if (classType.isInterface())
00607         throw new NoSuchConstructorException("Cannot have a constructor for an interface named '" +
00608                 className.toString() + "'");
00609 
00610     Vector applicableConstructors = classType.getApplicableConstructors(argumentTypes);
00611     Vector possibleConstructors = new Vector();
00612     for (int i = 0; i < applicableConstructors.size(); i++) {
00613         Method constructor = (Method) applicableConstructors.elementAt(i);
00614         if (constructor.isAccessible(currentClassOrInterfaceType))
00615             possibleConstructors.addElement(constructor);
00616     }
00617 
00618     if (possibleConstructors.size() == 0)
00619         throw new NoSuchConstructorException(msg);
00620 
00621     try {
00622         return getMostSpecificMethod(possibleConstructors);
00623     } catch (CompilerException e) {
00624     }
00625     throw new NoSuchConstructorException(msg);
00626 }
00627 /**
00628  * 
00629  * @return edu.ksu.cis.bandera.jjjc.symboltable.Named
00630  * @param name edu.ksu.cis.bandera.jjjc.symboltable.Name
00631  */
00632 public Named resolveExpression(Name name) throws CompilerException {
00633     if (name.getLastIdentifier().equals("length") && !name.isSimpleName()) {
00634         Typed array = (Typed) resolveFieldOrLocal(name.getSuperName());
00635         
00636         if (array instanceof Variable) {
00637             return ((ArrayType) ((Variable) array).getType()).length;
00638         } else {
00639             return ((ArrayType) ((Field) array).getType()).length;
00640         }
00641     } else {
00642         return resolveFieldOrLocal(name);
00643     }
00644 }
00645 /**
00646  * 
00647  * @return edu.ksu.cis.bandera.jjjc.symboltable.Named
00648  * @param name edu.ksu.cis.bandera.jjjc.symboltable.Name
00649  */
00650 public Named resolveFieldOrLocal(Name name) throws CompilerException {
00651     if (hasLocalVariableDeclared(name)) {
00652         return getLocalVariable(name);
00653     } else {
00654         if (name.isSimpleName()) {
00655             return currentClassOrInterfaceType.getField(name);
00656         } else {
00657             Name fieldName = new Name(name.getLastIdentifier());
00658             Name superName = name.getSuperName();
00659             boolean isTypeName;
00660             try {
00661                 superName = resolveClassOrInterfaceType(superName).getName();
00662                 isTypeName = true;
00663             } catch (Exception e) {
00664                 isTypeName = false;
00665             }
00666             Name className;
00667             if (isTypeName) {
00668                 className = superName;
00669             } else {
00670                 edu.ksu.cis.bandera.jjjc.symboltable.Type superType = ((Typed) resolveFieldOrLocal(superName)).getType();
00671                 if (!(superType instanceof ClassOrInterfaceType))
00672                     throw new ExpressionException("Type '" + superType.getFullyQualifiedName() + "' does not have field named '"
00673                             + fieldName + "'");
00674                 className = superType.getName();
00675             }
00676             ClassOrInterfaceType type = resolveClassOrInterfaceType(className);
00677             type.loadReferences();
00678             Field f = type.getField(fieldName);
00679             if (f.isAccessible(currentClassOrInterfaceType)) {
00680                 if (className.equals(superName)) {
00681                     if (Modifier.isStatic(f.getModifiers()))
00682                         return f;
00683                     else
00684                         throw new ExpressionException("Cannot acccess instance field named '" + fieldName + "' with type named '" +
00685                                 className + "'");
00686                 } else {
00687                     return f;
00688                 }
00689             } else {
00690                 throw new ExpressionException("Field named '" + fieldName + "' of type named '" + className +
00691                         "' is not accessible from '" + currentClassOrInterfaceType.getName() + "'");
00692             }
00693         }
00694     }
00695 }
00696 /**
00697  * 
00698  * @return edu.ksu.cis.bandera.jjjc.symboltable.Method
00699  * @param name edu.ksu.cis.bandera.jjjc.symboltable.Name
00700  */
00701 public Method resolveMethod(Name name) throws CompilerException {
00702     if (name.isSimpleName())
00703         resolveMethod(currentClassOrInterfaceType.getName(), name);
00704     else
00705         resolveMethod(name.getSuperName(), new Name(name.getLastIdentifier()));
00706     return null;
00707 }
00708 /**
00709  * 
00710  * @return edu.ksu.cis.bandera.jjjc.symboltable.Method
00711  * @param typeName edu.ksu.cis.bandera.jjjc.symboltable.Name
00712  * @param methodName edu.ksu.cis.bandera.jjjc.symboltable.Name
00713  */
00714 public Method resolveMethod(Name typeName, Name methodName) throws CompilerException {
00715     ClassOrInterfaceType type = resolveClassOrInterfaceType(typeName);
00716     type.loadReferences();
00717     
00718     Method result = null;
00719     
00720     for (Enumeration e = type.getMethods(methodName); e.hasMoreElements();) {
00721         if (result == null)
00722             result = (Method) e.nextElement();
00723         else
00724             throw new AmbiguousMethodException("Cannot resolve method named '" + methodName + "' in type '" + typeName +
00725                 "' without the argument types");
00726     }
00727     return result;  
00728 }
00729 /**
00730  * 
00731  * @return edu.ksu.cis.bandera.jjjc.symboltable.Method
00732  * @param typeName edu.ksu.cis.bandera.jjjc.symboltable.Name
00733  * @param simpleMethodName edu.ksu.cis.bandera.jjjc.symboltable.Name
00734  * @param argumentTypes java.util.Vector
00735  */
00736 public Method resolveMethod(Name typeName, Name methodName, Vector argumentTypes) throws CompilerException {
00737     String msg = "Could not find a method named '" + methodName.toString() +"' in type named '" + typeName.toString()
00738                 + "' with argument types " + argumentTypes.toString();
00739                 
00740     ClassOrInterfaceType classType = resolveClassOrInterfaceType(typeName);
00741     classType.loadReferences();
00742     Vector applicableMethods = classType.getApplicableMethods(methodName, argumentTypes);
00743     Vector possibleMethods = new Vector();
00744     
00745     for (int i = 0; i < applicableMethods.size(); i++) {
00746         Method method = (Method) applicableMethods.elementAt(i);
00747         if (method.isAccessible(currentClassOrInterfaceType))
00748             possibleMethods.addElement(method);
00749     }
00750 
00751     if (possibleMethods.size() == 0)
00752         throw new edu.ksu.cis.bandera.jjjc.exception.NoSuchMethodException(msg);
00753 
00754     try {
00755         return getMostSpecificMethod(possibleMethods);
00756     } catch (CompilerException e) {
00757     }
00758     throw new edu.ksu.cis.bandera.jjjc.exception.NoSuchMethodException(msg);
00759 }
00760 /**
00761  * 
00762  * @return edu.ksu.cis.bandera.jjjc.symboltable.Method
00763  * @param name edu.ksu.cis.bandera.jjjc.symboltable.Name
00764  * @param argumentTypes java.util.Vector
00765  */
00766 public Method resolveMethod(Name name, Vector argumentTypes) throws CompilerException {
00767     if (name.isSimpleName())
00768         return resolveMethod(currentClassOrInterfaceType.getName(), name, argumentTypes);
00769     else
00770         return resolveMethod(name.getSuperName(), new Name(name.getLastIdentifier()),   argumentTypes);
00771 }
00772 /**
00773  * 
00774  * @return edu.ksu.cis.bandera.jjjc.symboltable.Package
00775  * @param name edu.ksu.cis.bandera.jjjc.symboltable.Name
00776  */
00777 public Package resolvePackage(Name name) throws InvalidNameException {
00778     return Package.getPackage(name);
00779 }
00780 /**
00781  * 
00782  * @return edu.ksu.cis.bandera.jjjc.symboltable.Type
00783  * @param name edu.ksu.cis.bandera.jjjc.symboltable.Name
00784  */
00785 public Type resolveType(Name name) throws CompilerException {
00786     if (primitiveTypes.get(name) != null)
00787         return (Type) primitiveTypes.get(name);
00788     else
00789         return resolveClassOrInterfaceType(name);
00790 }
00791 /**
00792  * 
00793  * @param classOrInterfaceType edu.ksu.cis.bandera.jjjc.symboltable.ClassOrInterfaceType
00794  */
00795 public void setCurrentClassOrInterfaceType(ClassOrInterfaceType classOrInterfaceType) {
00796     currentClassOrInterfaceType = classOrInterfaceType;
00797 }
00798 /**
00799  * 
00800  * @param p edu.ksu.cis.bandera.jjjc.symboltable.Package
00801  */
00802 public void setCurrentPackage(Package p) {
00803     currentPackage = p;
00804 }
00805 /**
00806  * 
00807  */
00808 private void setLoadedState() {
00809     for (Enumeration e = declaredTypes.elements(); e.hasMoreElements();) {
00810         ((ClassOrInterfaceType) e.nextElement()).setLoadedState();
00811     }
00812 }
00813 /**
00814  * 
00815  * @return java.lang.String
00816  */
00817 public String toString() {
00818     return declaredTypes.toString();
00819 }
00820 }

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