1) make rcrpointer now crashes at processNode in Pointer.java starting at line 439. The switch statement encounters a FlatLiteralNode and doesn't know what to do with it.
2) We fail to parse Hashtable.java in the gnu labrary when using the -jni option. The line of code it fails at is "Hashtable.this.clear();". I can't seem to find any resources telling me what having a "this" midline means, so I can't fix it myself.
return processFlatCall(bblock, index, (FlatCall) node, delta, newgraph);
default:
- throw new Error("Unrecognized node:"+node);
+ throw new Error("Unrecognized node:"+node + " of kind " + node.kind());
}
}
SymbolTable flags;
SymbolTable methods;
- Hashtable singleImports;
+ Hashtable mandatoryImports;
+ Hashtable multiImports;
int numstaticblocks = 0;
int numstaticfields = 0;
this.sourceFileName=sourceFileName;
}
- public void setImports(Hashtable singleImports) {
- this.singleImports = singleImports;
+ public void setImports(Hashtable singleImports, Hashtable multiImports) {
+ this.mandatoryImports = singleImports;
+ this.multiImports = multiImports;
}
public String getSourceFileName() {
}
public Hashtable getSingleImportMappings() {
- return this.singleImports;
+ return this.mandatoryImports;
+ }
+
+ public Hashtable getMultiImportMappings() {
+ return this.multiImports;
+ }
+
+ //Returns the full name/path of another class referenced from this class via imports.
+ public String getCannonicalImportMapName(String otherClassname) {
+ if(mandatoryImports.containsKey(otherClassname)) {
+ return (String) mandatoryImports.get(otherClassname);
+ } else if(multiImports.containsKey(otherClassname)) {
+ //Test for error
+ Object o = multiImports.get(otherClassname);
+ if(o instanceof Error) {
+ throw new Error("Class " + otherClassname + " is ambiguous. Cause: more than 1 package import contain the same class.");
+ } else {
+ //At this point, if we found a unique class
+ //we can treat it as a single, mandatory import.
+ mandatoryImports.put(otherClassname, o);
+ return (String) o;
+ }
+ } else {
+ return otherClassname;
+ }
}
-
}
private ClassDescriptor parseEnumDecl(ClassDescriptor cn, ParseNode pn) {
ClassDescriptor ecd=new ClassDescriptor(pn.getChild("name").getTerminal(), false);
- ecd.setImports(mandatoryImports);
+ ecd.setImports(mandatoryImports, multiimports);
ecd.setAsEnum();
if(cn != null) {
ecd.setSurroundingClass(cn.getSymbol());
private ClassDescriptor parseAnnotationTypeDecl(ParseNode pn) {
ClassDescriptor cn=new ClassDescriptor(pn.getChild("name").getTerminal(), true);
- cn.setImports(mandatoryImports);
+ cn.setImports(mandatoryImports, multiimports);
ParseNode modifiers=pn.getChild("modifiers");
if(modifiers!=null) {
cn.setModifiers(parseModifiersList(modifiers));
cn= new ClassDescriptor(packageName, newClassname, true);
}
- cn.setImports(mandatoryImports);
+ cn.setImports(mandatoryImports, multiimports);
//cn.setAsInterface();
if (!isEmpty(pn.getChild("superIF").getTerminal())) {
/* parse inherited interface name */
String newClassname = packageName + "." + pn.getChild("name").getTerminal();
cn= new ClassDescriptor(packageName, newClassname, false);
}
- cn.setImports(mandatoryImports);
+ cn.setImports(mandatoryImports, multiimports);
if (!isEmpty(pn.getChild("super").getTerminal())) {
/* parse superclass name */
ParseNode snn=pn.getChild("super").getChild("type").getChild("class").getChild("name");
private ClassDescriptor parseInnerClassDecl(ClassDescriptor cn, ParseNode pn) {
ClassDescriptor icn=new ClassDescriptor(pn.getChild("name").getTerminal(), false);
- icn.setImports(mandatoryImports);
+ icn.setImports(mandatoryImports, multiimports);
icn.setAsInnerClass();
icn.setSurroundingClass(cn.getSymbol());
icn.setSurrounding(cn);
//This will get the mapping of a terminal class name
//to a canonical classname (with imports/package locations in them)
private String resolveName(String terminal) {
+
if(mandatoryImports.containsKey(terminal)) {
return (String) mandatoryImports.get(terminal);
} else {
TypeDescriptor td=parseTypeDescriptor(pn);
innerCount++;
ClassDescriptor cnnew=new ClassDescriptor(td.getSymbol()+"$"+innerCount, false);
- cnnew.setImports(mandatoryImports);
+ cnnew.setImports(mandatoryImports, multiimports);
cnnew.setSuper(td.getSymbol());
parseClassBody(cnnew, pn.getChild("decl").getChild("classbody"));
Vector args=parseArgumentList(pn);
HashSet toanalyze;
HashMap<ClassDescriptor, Integer> completed;
- //This is the class mappings for a particular file based
- //on the import names. Maps class to canonical class name.
- static Hashtable singleImportMap;
public static final int NOCHECK=0;
public static final int REFERENCE=1;
public static final int INIT=2;
public ClassDescriptor getClass(ClassDescriptor context, String classname) {
return getClass(context, classname, INIT);
}
- public ClassDescriptor getClass(ClassDescriptor context, String classname, int fullcheck) {
+ public ClassDescriptor getClass(ClassDescriptor context, String classnameIn, int fullcheck) {
+ String classname = classnameIn;
if (context!=null) {
// System.out.println(context.getSymbol() + " is looking for " + classname);
- Hashtable remaptable=context.getSingleImportMappings();
- classname=remaptable.containsKey(classname)?((String)remaptable.get(classname)):classname;
+ classname = context.getCannonicalImportMapName(classnameIn);
}
ClassDescriptor cd=typeutil.getClass(classname, toanalyze);
checkClass(cd, fullcheck);
} else {
ClassDescriptor cd = (ClassDescriptor) obj;
toanalyze.remove(cd);
- //set the class mappings based on imports.
- singleImportMap = cd.getSingleImportMappings();
// need to initialize typeutil object here...only place we can
// get class descriptors without first calling getclass
for (int i = 0; i < state.classpath.size(); i++) {
String path = (String) state.classpath.get(i);
File f = new File(path, cl.replace('.', '/') + ".java");
+// System.out.println("Looking in " + f.getAbsolutePath());
if (f.exists()) {
try {
ParseNode pn = Main.readSourceFile(state, f.getCanonicalPath());