package LBJ2; import java.io.File; import java.io.FilenameFilter; import java.util.Iterator; import java.util.LinkedList; import LBJ2.IR.AST; import LBJ2.IR.ClassifierName; import LBJ2.IR.CodedClassifier; import LBJ2.IR.CompositeGenerator; import LBJ2.IR.Conjunction; import LBJ2.IR.ConstraintDeclaration; import LBJ2.IR.InferenceDeclaration; import LBJ2.IR.InferenceInvocation; import LBJ2.IR.LearningClassifierExpression; import LBJ2.IR.Name; /** * To be run after <code>SemanticAnalysis</code>, this pass compiles the list * of files created by the LBJ2 compiler and removes them. * * @see LBJ2.SemanticAnalysis * @author Nick Rizzolo **/ public class Clean extends Pass { /** The list of files to be deleted. */ private LinkedList files; /** The path at which a cleanable Java file will be found. */ private String javaPath; /** The path at which a cleanable class file will be found. */ private String classPath; /** * Instantiates a pass that runs on an entire <code>AST</code>. * * @param ast The program to run this pass on. **/ public Clean(AST ast) { super(ast); } /** * Runs this pass on all nodes of the indicated type. * * @param ast The node to process. **/ public void run(AST ast) { files = new LinkedList(); if (Main.generatedSourceDirectory != null) javaPath = Main.generatedSourceDirectory + File.separator; else javaPath = ""; if (Main.classDirectory != null) classPath = Main.classDirectory + File.separator; else classPath = ""; runOnChildren(ast); for (Iterator I = files.iterator(); I.hasNext(); ) { Object o = I.next(); if (o instanceof String) { String name = (String) o; File f = new File(name); if (f.exists() && !f.delete()) reportError(0, "Could not delete '" + name + "'."); } else { String[] names = (String[]) o; for (int i = 0; i < names.length; ++i) { File f = new File(names[i]); if (f.exists() && !f.delete()) reportError(0, "Could not delete '" + names[i] + "'."); } } } } /** * Adds the default files (<code>*.java</code> and <code>*.class</code>) * to the remove list. * * @param n The node to add files with respect to. **/ protected void defaultFiles(CodeGenerator n) { files.add(javaPath + n.getName() + ".java"); files.add(classPath + n.getName() + ".class"); } /** * Adds files generated for anonymous classes associated with a particular * named classifier to the remove list. * * @param name The name of the classifier with which anonymous classes may * be associated. **/ protected void anonymousFiles(Name name) { final String prefix = name + "$"; String directory = javaPath; if (directory.length() == 0) directory = System.getProperty("user.dir"); else directory = directory.substring(0, directory.length() - 1); String[] toAdd = new File(directory).list( new FilenameFilter() { public boolean accept(File directory, String n) { return n.startsWith(prefix); } }); for (int i = 0; i < toAdd.length; ++i) toAdd[i] = directory + File.separator + toAdd[i]; files.add(toAdd); directory = classPath; if (directory.length() == 0) directory = System.getProperty("user.dir"); else directory = directory.substring(0, directory.length() - 1); toAdd = new File(directory).list( new FilenameFilter() { public boolean accept(File directory, String n) { return n.startsWith(prefix); } }); for (int i = 0; i < toAdd.length; ++i) toAdd[i] = directory + File.separator + toAdd[i]; files.add(toAdd); } /** * Runs this pass on all nodes of the indicated type. * * @param cn The node to process. **/ public void run(ClassifierName cn) { if (cn.name == cn.referent) return; defaultFiles(cn); } /** * Runs this pass on all nodes of the indicated type. * * @param cc The node to process. **/ public void run(CodedClassifier cc) { defaultFiles(cc); } /** * Runs this pass on all nodes of the indicated type. * * @param cg The node to process. **/ public void run(CompositeGenerator cg) { defaultFiles(cg); anonymousFiles(cg.name); } /** * Runs this pass on all nodes of the indicated type. * * @param c The node to process. **/ public void run(Conjunction c) { defaultFiles(c); anonymousFiles(c.name); } /** * Runs this pass on all nodes of the indicated type. * * @param i The node to process. **/ public void run(InferenceInvocation i) { defaultFiles(i); } /** * Runs this pass on all nodes of the indicated type. * * @param lce The node to process. **/ public void run(LearningClassifierExpression lce) { defaultFiles(lce); anonymousFiles(lce.name); files.add(classPath + lce.name + ".lc"); files.add(javaPath + lce.name + ".ex"); files.add(javaPath + lce.name + ".lex"); } /** * Runs this pass on all nodes of the indicated type. * * @param c The node to process. **/ public void run(ConstraintDeclaration c) { defaultFiles(c); } /** * Runs this pass on all nodes of the indicated type. * * @param i The node to process. **/ public void run(InferenceDeclaration i) { defaultFiles(i); defaultFiles(i.constraint); } }