From: stephey Date: Sat, 23 Apr 2011 15:55:30 +0000 (+0000) Subject: Fixes. Almost everything works (but still no importing subclass support). X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=364b4dd6f345d975eab4c0c587753eb7dc1e3367;p=IRC.git Fixes. Almost everything works (but still no importing subclass support). JNI compilation on Brian's test file still fails, HOWEVER I believe it's because /classpath/java/lang/ should be added into our state.classpaths vector. This should be true because Java automatically imports java.lang.* in every file, so it's essentially like having it as a class path. I've left 1 System.out.println statement in extra to help trace which files are trying to find which files. When I look at the one I'm currently crashing on, I see that there is indeed no Class.java file in its package and it doesn't import it anywhere. --- diff --git a/Robust/src/IR/Tree/BuildIR.java b/Robust/src/IR/Tree/BuildIR.java index 8aaf398f..478bccdb 100644 --- a/Robust/src/IR/Tree/BuildIR.java +++ b/Robust/src/IR/Tree/BuildIR.java @@ -41,12 +41,46 @@ public class BuildIR { public void parseFile(ParseNode pn, Set toanalyze, String sourcefile) { 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); + } + } + } + } + } + } + } + ParseNode ipn = pn.getChild("imports").getChild("import_decls_list"); if (ipn != null) { ParseNodeVector pnv = ipn.getChildren(); for (int i = 0; i < pnv.size(); i++) { ParseNode pnimport = pnv.elementAt(i); - NameDescriptor nd = parseNameRaw(pnimport.getChild("name")); + NameDescriptor nd = parseName(pnimport.getChild("name")); if (isNode(pnimport, "import_single")) if (!mandatoryImports.containsKey(nd.getIdentifier())) { // map name to full name (includes package/directory @@ -61,40 +95,36 @@ public class BuildIR { // 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. - File folder = new File(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.getIdentifier() + "." + classname); + 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."); } - } else { - throw new Error("Import package " + folder.getAbsolutePath() + " in " + sourcefile - + " cannot be resolved."); } } } } - ParseNode ppn=pn.getChild("packages").getChild("package"); - String packageName = null; - if (ppn!=null) { - NameDescriptor nd = parseName(ppn.getChild("name")); - packageName = nd.getPathFromRootToHere(); - } - ParseNode tpn=pn.getChild("type_declaration_list"); if (tpn != null) { ParseNodeVector pnv = tpn.getChildren(); @@ -158,7 +188,7 @@ public class BuildIR { state.addTask(td); } else if (isNode(type_pn, "interface_declaration")) { // TODO add version for normal Java later - ClassDescriptor cn = parseInterfaceDecl(type_pn); + ClassDescriptor cn = parseInterfaceDecl(type_pn, packageName); if (toanalyze != null) toanalyze.add(cn); cn.setSourceFileName(sourcefile); @@ -244,8 +274,15 @@ public class BuildIR { cn.addEnumConstant(pn.getChild("name").getTerminal()); } - public ClassDescriptor parseInterfaceDecl(ParseNode pn) { - ClassDescriptor cn=new ClassDescriptor(pn.getChild("name").getTerminal(), true); + public ClassDescriptor parseInterfaceDecl(ParseNode pn, String packageName) { + ClassDescriptor cn; + if(packageName == null) { + cn=new ClassDescriptor(pn.getChild("name").getTerminal(), true); + } else { + String newClassname = packageName + "." + pn.getChild("name").getTerminal(); + cn= new ClassDescriptor(packageName, newClassname, true); + } + cn.setImports(mandatoryImports); //cn.setAsInterface(); if (!isEmpty(pn.getChild("superIF").getTerminal())) { @@ -255,7 +292,7 @@ public class BuildIR { for(int i=0; i