00001 package edu.ksu.cis.bandera.jjjc.symboltable;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
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
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
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
00091
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
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
00131
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
00178
00179 public ClassOrInterfaceType getCurrentClassOrInterfaceType() {
00180 return currentClassOrInterfaceType;
00181 }
00182
00183
00184
00185
00186 public Package getCurrentPackage() {
00187 return currentPackage;
00188 }
00189
00190
00191
00192
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
00203
00204 public Enumeration getDeclaredTypes() {
00205 return declaredTypes.elements();
00206 }
00207
00208
00209
00210
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
00222
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
00234
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
00268
00269 public int getNumScopeLevels() {
00270 return scopes.size();
00271 }
00272
00273
00274
00275
00276 public String getPath() {
00277 return currentJavaFilePath;
00278 }
00279
00280
00281
00282
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
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
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
00339
00340 private void loadFromClassFile(ClassOrInterfaceType classOrInterfaceType) throws InvalidNameException,
00341 AlreadyDeclaredException, ClassOrInterfaceTypeNotFoundException {
00342
00343
00344
00345
00346
00347
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
00457
00458
00459
00460
00461
00462
00463 classOrInterfaceType.setLoadedState();
00464 declaredTypes.put(new Name(classOrInterfaceType.getName().getLastIdentifier()), classOrInterfaceType);
00465 }
00466
00467
00468
00469
00470 private void loadFromSourceFile(String path) throws InvalidNameException, AnalysisException {
00471 currentJavaFilePath = path;
00472
00473 Start ast = null;
00474
00475 try {
00476
00477
00478
00479
00480
00481
00482
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
00529
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
00552
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
00597
00598
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
00630
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
00648
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
00699
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
00711
00712
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
00732
00733
00734
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
00763
00764
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
00775
00776
00777 public Package resolvePackage(Name name) throws InvalidNameException {
00778 return Package.getPackage(name);
00779 }
00780
00781
00782
00783
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
00794
00795 public void setCurrentClassOrInterfaceType(ClassOrInterfaceType classOrInterfaceType) {
00796 currentClassOrInterfaceType = classOrInterfaceType;
00797 }
00798
00799
00800
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
00816
00817 public String toString() {
00818 return declaredTypes.toString();
00819 }
00820 }