From da4122e437b215478608e7edf430ee8ae6a2a872 Mon Sep 17 00:00:00 2001 From: stephey Date: Sun, 24 Apr 2011 07:23:33 +0000 Subject: [PATCH] Refactored the multiimport code so that it looks nicer and added java.lang as a default multiimport as well. Now Brian's test file crashes at parsing Hashmap (invalid character). Still no support for importing a class within a class though --- Robust/src/IR/Tree/BuildIR.java | 117 ++++++++++++-------------- Robust/src/IR/Tree/SemanticCheck.java | 2 +- 2 files changed, 55 insertions(+), 64 deletions(-) diff --git a/Robust/src/IR/Tree/BuildIR.java b/Robust/src/IR/Tree/BuildIR.java index 478bccdb..4deb4d03 100644 --- a/Robust/src/IR/Tree/BuildIR.java +++ b/Robust/src/IR/Tree/BuildIR.java @@ -42,38 +42,8 @@ public class BuildIR { mandatoryImports = new Hashtable(); multiimports = new Hashtable(); - ParseNode ppn=pn.getChild("packages").getChild("package"); - String packageName = null; - if (ppn!=null) { - NameDescriptor nd = parseClassName(ppn.getChild("name")); - packageName = nd.getPathFromRootToHere(); - - //Trick -> import the package directory as a multi-import and it'll - //automatically recognize files in the same directory. - for (int i = 0; i < state.classpath.size(); i++) { - String path = (String) state.classpath.get(i); - File folder = new File(path, nd.getPathFromRootToHere().replace('.', '/')); - if(folder.exists()) { - for (String file : folder.list()) { - // if the file is of type *.java add to multiImport list. - if (file.lastIndexOf('.') != -1 - && file.substring(file.lastIndexOf('.')).equalsIgnoreCase(".java")) { - String classname = file.substring(0, file.length() - 5); - // single imports have precedence over multi-imports - if (!mandatoryImports.containsKey(classname)) { - if (multiimports.containsKey(classname)) { - // put error in for later, in case we try to import. - multiimports.put(classname, new Error("Error: class " + nd.getIdentifier() - + " is defined more than once in a multi-import in " + sourcefile)); - } else { - multiimports.put(classname, nd.getPathFromRootToHere() + "." + classname); - } - } - } - } - } - } - } + //add java.lang as our default multi-import + this.addMultiImport(sourcefile, "java.lang", false); ParseNode ipn = pn.getChild("imports").getChild("import_decls_list"); if (ipn != null) { @@ -81,7 +51,7 @@ public class BuildIR { for (int i = 0; i < pnv.size(); i++) { ParseNode pnimport = pnv.elementAt(i); NameDescriptor nd = parseName(pnimport.getChild("name")); - if (isNode(pnimport, "import_single")) + if (isNode(pnimport, "import_single")) { if (!mandatoryImports.containsKey(nd.getIdentifier())) { // map name to full name (includes package/directory mandatoryImports.put(nd.getIdentifier(), nd.getPathFromRootToHere()); @@ -90,41 +60,24 @@ public class BuildIR { ((String)mandatoryImports.get(nd.getIdentifier())) + " and " + nd.getPathFromRootToHere()); } + } else { - // This kind of breaks away from tradition a little bit by doing the file checks here - // instead of in Semantic check, but doing it here is easier because we have a mapping early on - // if I wait until semantic check, I have to change ALL the type descriptors to match the new - // mapping and that's both ugly and tedious. - for (int j = 0; j < state.classpath.size(); j++) { - String path = (String) state.classpath.get(j); - File folder = new File(path, nd.getPathFromRootToHere().replace('.', '/')); - if (folder.exists()) { - for (String file : folder.list()) { - // if the file is of type *.java add to multiImport list. - if (file.lastIndexOf('.') != -1 - && file.substring(file.lastIndexOf('.')).equalsIgnoreCase(".java")) { - String classname = file.substring(0, file.length() - 5); - // single imports have precedence over multi-imports - if (!mandatoryImports.containsKey(classname)) { - if (multiimports.containsKey(classname)) { - // put error in for later, in case we try to import. - multiimports.put(classname, new Error("Error: class " + nd.getIdentifier() - + " is defined more than once in a multi-import in " + sourcefile)); - } else { - multiimports.put(classname, nd.getPathFromRootToHere() + "." + classname); - } - } - } - } - } else { - throw new Error("Import package " + folder.getAbsolutePath() + " in " + sourcefile - + " cannot be resolved."); - } - } + addMultiImport(sourcefile, nd.getPathFromRootToHere(), false); } } } + ParseNode ppn=pn.getChild("packages").getChild("package"); + String packageName = null; + if (ppn!=null) { + NameDescriptor nd = parseClassName(ppn.getChild("name")); + packageName = nd.getPathFromRootToHere(); + + //Trick -> import the package directory as a multi-import and it'll + //automatically recognize files in the same directory. + addMultiImport(sourcefile, packageName, true); + } + ParseNode tpn=pn.getChild("type_declaration_list"); if (tpn != null) { ParseNodeVector pnv = tpn.getChildren(); @@ -217,6 +170,44 @@ public class BuildIR { } } } + + //This kind of breaks away from tradition a little bit by doing the file checks here + // instead of in Semantic check, but doing it here is easier because we have a mapping early on + // if I wait until semantic check, I have to change ALL the type descriptors to match the new + // mapping and that's both ugly and tedious. + private void addMultiImport(String currentSource, String importPath, boolean isPackageDirectory) { + boolean found = false; + for (int j = 0; j < state.classpath.size(); j++) { + String path = (String) state.classpath.get(j); + File folder = new File(path, importPath.replace('.', '/')); + System.out.println("Trying " + folder.getAbsolutePath()); + if (folder.exists()) { + found = true; + for (String file : folder.list()) { + // if the file is of type *.java add to multiImport list. + if (file.lastIndexOf('.') != -1 && file.substring(file.lastIndexOf('.')).equalsIgnoreCase(".java")) { + String classname = file.substring(0, file.length() - 5); + // single imports have precedence over multi-imports + if (!mandatoryImports.containsKey(classname)) { + //package files have precedence over multi-imports. + if (multiimports.containsKey(classname) && !isPackageDirectory) { + // put error in for later, in case we try to import + multiimports.put(classname, new Error("Error: class " + classname + " is defined more than once in a multi-import in " + currentSource)); + } else { + multiimports.put(classname, importPath + "." + classname); + } + } + } + } + } + } + + + if(!found) { + throw new Error("Import package " + importPath + " in " + currentSource + + " cannot be resolved."); + } + } public void parseInitializers(ClassDescriptor cn){ Vector fv=cn.getFieldVec(); diff --git a/Robust/src/IR/Tree/SemanticCheck.java b/Robust/src/IR/Tree/SemanticCheck.java index 2dd2306b..8b14222e 100644 --- a/Robust/src/IR/Tree/SemanticCheck.java +++ b/Robust/src/IR/Tree/SemanticCheck.java @@ -42,7 +42,7 @@ public class SemanticCheck { } public ClassDescriptor getClass(ClassDescriptor context, String classname, int fullcheck) { if (context!=null) { - System.out.println(context.getSymbol() + " is looking for " + classname); +// System.out.println(context.getSymbol() + " is looking for " + classname); Hashtable remaptable=context.getSingleImportMappings(); classname=remaptable.containsKey(classname)?((String)remaptable.get(classname)):classname; } -- 2.34.1