00001 package edu.ksu.cis.bandera.jjjc.analysis;
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.util.*;
00036 import java.lang.reflect.Modifier;
00037 import edu.ksu.cis.bandera.jjjc.node.*;
00038 import edu.ksu.cis.bandera.jjjc.analysis.*;
00039 import edu.ksu.cis.bandera.jjjc.exception.*;
00040 import edu.ksu.cis.bandera.jjjc.symboltable.*;
00041 import edu.ksu.cis.bandera.jjjc.util.*;
00042
00043 public class ClassOrInterfaceMembersAnalysis extends DepthFirstAdapter {
00044 private SymbolTable symbolTable;
00045 private Vector exceptions = new Vector();
00046 private ClassOrInterfaceType currentClassOrInterfaceType = null;
00047 private ClassOrInterfaceType declaringClassOrInterfaceType = null;
00048 private Method currentMethod = null;
00049 private Type currentType = null;
00050
00051
00052
00053
00054 public ClassOrInterfaceMembersAnalysis(SymbolTable symbolTable) {
00055 this.symbolTable = symbolTable;
00056 }
00057
00058
00059
00060
00061 public void caseABlockClassBodyDeclaration(ABlockClassBodyDeclaration node) {
00062 }
00063
00064
00065
00066
00067 public void caseAClassClassBodyDeclaration(AClassClassBodyDeclaration node) {
00068 }
00069
00070
00071
00072
00073 public void caseAClassDeclaration(AClassDeclaration node) {
00074 try {
00075 currentClassOrInterfaceType = symbolTable.getDeclaredType(new Name(node.getId().toString()));
00076
00077 if (currentClassOrInterfaceType.isLoaded()) return;
00078
00079 symbolTable.setCurrentClassOrInterfaceType(currentClassOrInterfaceType);
00080
00081 Name className = currentClassOrInterfaceType.getName();
00082
00083 if (currentClassOrInterfaceType.isLoaded()) return;
00084
00085 if (node.getClassBody() != null) {
00086 node.getClassBody().apply(this);
00087 }
00088
00089 if (!currentClassOrInterfaceType.getConstructors().hasMoreElements()) {
00090 Method constructor = new Method(new Name(currentClassOrInterfaceType.getName().getLastIdentifier()));
00091 currentClassOrInterfaceType.addConstructor(constructor);
00092 constructor.setModifiers(Modifier.PUBLIC);
00093 }
00094 } catch (CompilerException e) {
00095 exceptions.addElement(e);
00096 }
00097 symbolTable.setCurrentClassOrInterfaceType(null);
00098 currentClassOrInterfaceType = null;
00099 }
00100
00101
00102
00103
00104 public void caseAClassDeclarationBlockedStmt(AClassDeclarationBlockedStmt node) {
00105 }
00106
00107
00108
00109
00110 public void caseAClassDeclarationInterfaceMemberDeclaration(AClassDeclarationInterfaceMemberDeclaration node) {
00111 }
00112
00113
00114
00115
00116 public void caseAConstructorDeclaration(AConstructorDeclaration node) {
00117 try {
00118 int modifiers = Util.convertModifiers(node.getModifier().toString());
00119
00120 if (node.getConstructorDeclarator() != null) {
00121 node.getConstructorDeclarator().apply(this);
00122 }
00123
00124 if (node.getThrows() != null) {
00125 node.getThrows().apply(this);
00126 }
00127
00128 currentClassOrInterfaceType.addConstructor(currentMethod);
00129 currentMethod.setModifiers(modifiers);
00130 } catch (CompilerException e) {
00131 exceptions.addElement(e);
00132 }
00133 currentMethod = null;
00134 }
00135
00136
00137
00138
00139 public void caseAConstructorDeclarator(AConstructorDeclarator node) {
00140 try {
00141 Name name = new Name(node.getSimpleName().toString());
00142
00143 if (!name.equals(new Name(currentClassOrInterfaceType.getName().getLastIdentifier())))
00144 throw new AnalysisException("Constructor declaration '" + name + "' should have name '"
00145 + currentClassOrInterfaceType.getName().getLastIdentifier() + "'");
00146
00147 currentMethod = new Method(name);
00148
00149 if (node.getFormalParameter() != null) {
00150 Object[] formalParameters = node.getFormalParameter().toArray();
00151
00152 for (int i = 0; i < formalParameters.length; i++) {
00153 ((PFormalParameter) formalParameters[i]).apply(this);
00154 }
00155 }
00156 } catch (CompilerException e) {
00157 exceptions.addElement(e);
00158 }
00159 }
00160
00161
00162
00163
00164 public void caseAFieldDeclaration(AFieldDeclaration node) {
00165 try {
00166 int modifiers = 0;
00167 if (node.getModifier() != null)
00168 modifiers = Util.convertModifiers(node.getModifier().toString());
00169
00170 Type type = symbolTable.resolveType(new Name(node.getType().toString()));
00171
00172 int dims = Util.countArrayDimensions(node.getType().toString());
00173
00174 Object[] variableDeclarators = node.getVariableDeclarator().toArray();
00175
00176 for (int i = 0; i < variableDeclarators.length; i++) {
00177 AVariableDeclaratorId variableDeclaratorId;
00178
00179 if (variableDeclarators[i] instanceof AIdVariableDeclarator)
00180 variableDeclaratorId = (AVariableDeclaratorId)
00181 ((AIdVariableDeclarator) variableDeclarators[i]).getVariableDeclaratorId();
00182 else
00183 variableDeclaratorId = (AVariableDeclaratorId)
00184 ((AAssignedVariableDeclarator) variableDeclarators[i]).getVariableDeclaratorId();
00185
00186 int dimensions = variableDeclaratorId.getDim().size() + dims;
00187 Type fieldType;
00188 if (dimensions > 0)
00189 fieldType = new ArrayType(type, dimensions);
00190 else
00191 fieldType = type;
00192
00193 Field f = new Field(new Name(variableDeclaratorId.getId().toString()), fieldType);
00194 currentClassOrInterfaceType.addField(f);
00195 f.setModifiers(modifiers);
00196 }
00197 } catch (CompilerException e) {
00198 exceptions.addElement(e);
00199 }
00200 }
00201
00202
00203
00204
00205 public void caseAFormalParameter(AFormalParameter node) {
00206 try {
00207 int modifiers = 0;
00208
00209 if (node.getModifier() != null)
00210 modifiers = Util.convertModifiers(node.getModifier().toString());
00211
00212 Type type = symbolTable.resolveType(new Name(node.getType().toString()));
00213
00214 AVariableDeclaratorId variableDeclaratorId = (AVariableDeclaratorId) node.getVariableDeclaratorId();
00215
00216 int dimensions = variableDeclaratorId.getDim().size() + Util.countArrayDimensions(node.getType().toString());
00217
00218 if (dimensions > 0)
00219 type = new ArrayType(type, dimensions);
00220
00221 Name name = new Name(variableDeclaratorId.getId().toString());
00222
00223 currentMethod.addParameterVariable(new Variable(modifiers, type, name));
00224 } catch (CompilerException e) {
00225 exceptions.addElement(e);
00226 }
00227 }
00228
00229
00230
00231
00232 public void caseAInterfaceDeclaration(AInterfaceDeclaration node) {
00233 try {
00234 currentClassOrInterfaceType = symbolTable.getDeclaredType(new Name(node.getId().toString()));
00235 if (currentClassOrInterfaceType.isLoaded()) return;
00236 symbolTable.setCurrentClassOrInterfaceType(currentClassOrInterfaceType);
00237
00238 if (currentClassOrInterfaceType.isLoaded()) return;
00239
00240 } catch (CompilerException e) {
00241 exceptions.addElement(e);
00242 }
00243
00244 if(node.getInterfaceBody() != null) {
00245 node.getInterfaceBody().apply(this);
00246 }
00247
00248 symbolTable.setCurrentClassOrInterfaceType(null);
00249 currentClassOrInterfaceType = null;
00250 }
00251
00252
00253
00254
00255 public void caseAInterfaceDeclarationClassMemberDeclaration(AInterfaceDeclarationClassMemberDeclaration node) {
00256 }
00257
00258
00259
00260
00261 public void caseAInterfaceDeclarationInterfaceMemberDeclaration(AInterfaceDeclarationInterfaceMemberDeclaration node) {
00262 }
00263
00264
00265
00266
00267 public void caseAMethodDeclaration(AMethodDeclaration node) {
00268 node.getMethodHeader().apply(this);
00269 }
00270
00271
00272
00273
00274 public void caseAMethodDeclarator(AMethodDeclarator node) {
00275 try {
00276 if (node.getDim() != null) {
00277 int dimensions = node.getDim().size();
00278
00279 if (dimensions > 0) {
00280 if (currentType instanceof VoidType)
00281 throw new TypeException("Cannot have a type of array of void as return type for method");
00282
00283 if (currentType instanceof ArrayType)
00284 currentType = new ArrayType(((ArrayType) currentType).baseType,
00285 ((ArrayType) currentType).nDimensions + dimensions);
00286 else
00287 currentType = new ArrayType(currentType, dimensions);
00288 }
00289 }
00290
00291 currentMethod = new Method(new Name(node.getId().toString()));
00292 currentMethod.setReturnType(currentType);
00293 currentType = null;
00294
00295 if (node.getFormalParameter() != null) {
00296 Object[] formalParameters = node.getFormalParameter().toArray();
00297 for (int i = 0; i < formalParameters.length; i++) {
00298 ((PFormalParameter) formalParameters[i]).apply(this);
00299 }
00300 }
00301 } catch (CompilerException e) {
00302 exceptions.addElement(e);
00303 }
00304 }
00305
00306
00307
00308
00309 public void caseAStaticInitializerClassBodyDeclaration(AStaticInitializerClassBodyDeclaration node) {
00310 }
00311
00312
00313
00314
00315 public void caseAThrows(AThrows node) {
00316 try {
00317 Object[] exceptionTypes = node.getName().toArray();
00318 for (int i = 0; i < exceptionTypes.length; i++) {
00319 ClassOrInterfaceType exceptionType = symbolTable.resolveClassOrInterfaceType(new Name(exceptionTypes[i].toString()));
00320 currentMethod.addException(exceptionType);
00321 }
00322 } catch (CompilerException e) {
00323 exceptions.addElement(e);
00324 }
00325 }
00326
00327
00328
00329
00330 public void caseATypedMethodHeader(ATypedMethodHeader node) {
00331 try {
00332 int modifiers = 0;
00333 if (node.getModifier() != null) {
00334 modifiers = Util.convertModifiers(node.getModifier().toString());
00335 }
00336
00337 String type = node.getType().toString();
00338 currentType = symbolTable.resolveType(new Name(type));
00339 int dimensions = Util.countArrayDimensions(type);
00340
00341 if (dimensions > 0)
00342 currentType = new ArrayType(currentType, dimensions);
00343
00344 if (node.getMethodDeclarator() != null) {
00345 node.getMethodDeclarator().apply(this);
00346 }
00347
00348 if (node.getThrows() != null) {
00349 node.getThrows().apply(this);
00350 }
00351
00352 currentClassOrInterfaceType.addMethod(currentMethod);
00353 currentMethod.setModifiers(modifiers);
00354 } catch (CompilerException e) {
00355 exceptions.addElement(e);
00356 }
00357
00358 currentMethod = null;
00359 }
00360
00361
00362
00363
00364 public void caseAVoidMethodHeader(AVoidMethodHeader node) {
00365 try {
00366 int modifiers = 0;
00367 if (node.getModifier() != null) {
00368 modifiers = Util.convertModifiers(node.getModifier().toString());
00369 }
00370
00371 currentType = VoidType.TYPE;
00372
00373 if (node.getMethodDeclarator() != null) {
00374 node.getMethodDeclarator().apply(this);
00375 }
00376
00377 if (node.getThrows() != null) {
00378 node.getThrows().apply(this);
00379 }
00380
00381 currentClassOrInterfaceType.addMethod(currentMethod);
00382 currentMethod.setModifiers(modifiers);
00383 } catch (CompilerException e) {
00384 exceptions.addElement(e);
00385 }
00386
00387 currentMethod = null;
00388 }
00389
00390
00391
00392
00393 public Enumeration getExceptions() {
00394 return exceptions.elements();
00395 }
00396 }