import java.io.*; import java.io.PrintWriter; import java.io.File; import java.io.IOException; import java.util.*; import java.util.Scanner; import java.util.regex.Pattern; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.filechooser.*; import javax.swing.JProgressBar; class JavaPRP{ public static void main(String[] args){ new MasterGUI(); } } class MasterGUI extends JPanel implements ActionListener{ JFileChooser fc; JTextArea log; JButton chooseButton; JButton compileButton; JButton runButton; JButton killButton; JButton clearLogButton; JTextField arg; JPanel argPanel; JPanel progPanel; JPanel arg_progPanel; JProgressBar progBar; File currentFile = null; Execute executeThread; boolean threadFinish = true; FileHandler fh = new FileHandler(); public MasterGUI(){ JFrame f = new JFrame("JavaPRP"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(new BorderLayout()); log = new JTextArea(30,50); log.setMargin(new Insets(5,5,5,5)); log.setEditable(false); JScrollPane logScrollPane = new JScrollPane(log); //create filechooser File self = new File("JavaPRP.java"); fc = new JFileChooser(self); //argument textfield JLabel lab = new JLabel("Parameter(s): "); arg = new JTextField(40); arg.setBackground(null); arg.setEnabled(false); argPanel = new JPanel(); argPanel.add(lab); argPanel.add(arg); //progressbar progPanel = new JPanel(); progBar = new JProgressBar(); progPanel.add(progBar); arg_progPanel = new JPanel(); arg_progPanel.setLayout(new BorderLayout()); arg_progPanel.add(argPanel,BorderLayout.SOUTH); arg_progPanel.add(progPanel,BorderLayout.NORTH); //create a button chooseButton = new JButton("Choose a file"); compileButton = new JButton("Compile"); runButton = new JButton("Execute"); killButton = new JButton("Terminate"); clearLogButton = new JButton("Clear Log"); chooseButton.addActionListener(this); compileButton.addActionListener(this); runButton.addActionListener(this); killButton.addActionListener(this); clearLogButton.addActionListener(this); JPanel buttonPanel = new JPanel(); buttonPanel.add(chooseButton); buttonPanel.add(compileButton); buttonPanel.add(runButton); buttonPanel.add(killButton); buttonPanel.add(clearLogButton); add(buttonPanel, BorderLayout.NORTH); add(arg_progPanel, BorderLayout.CENTER); add(logScrollPane, BorderLayout.SOUTH); compileButton.setEnabled(false); runButton.setEnabled(false); killButton.setEnabled(false); f.add(this); f.pack(); f.setVisible(true); } public void actionPerformed(ActionEvent e){ //Handle open button action. if (e.getSource() == chooseButton) { int returnVal = fc.showOpenDialog(MasterGUI.this); if (returnVal == JFileChooser.APPROVE_OPTION) { currentFile = fc.getSelectedFile(); log.append("Opening: " + currentFile.getName() + "\n"); //send fila til filehandler i JavaPRP fh.setFile(currentFile.getName()); try{ currentFile = fh.readFile(); }catch(FileNotFoundException fnfe){} String name = currentFile.getName().replaceFirst("[.][^.]+$", ""); log.append("Created: " + currentFile.getName() + "\n"); compileButton.setEnabled(true); runButton.setEnabled(false); arg.setEnabled(false); arg.setBackground(null); } else { log.append("Open command cancelled by user.\n"); } log.setCaretPosition(log.getDocument().getLength()); }else if (e.getSource() == compileButton) { boolean correct = compileFile(currentFile.getName()); if(correct){ runButton.setEnabled(true); arg.setBackground(Color.WHITE); arg.setEnabled(true); } }else if (e.getSource() == runButton) { executeFile(currentFile.getName()); threadFinish = false; arg.setText(""); chooseButton.setEnabled(false); compileButton.setEnabled(false); runButton.setEnabled(false); clearLogButton.setEnabled(false); killButton.setEnabled(true); progBar.setIndeterminate(true); }else if (e.getSource() == killButton) { executeThread.destroyProc(); killButton.setEnabled(false); }else if (e.getSource() == clearLogButton) { log.setText(""); } } public boolean compileFile(String filename){ boolean ret = false; try{ Process p = Runtime.getRuntime().exec("javac " + filename); log.append("javac " + filename + "\n"); BufferedReader in = new BufferedReader( new InputStreamReader(p.getErrorStream())); String line = null; int counter = 0; while((line = in.readLine()) != null){ counter++; log.append(line + "\n"); } if(counter == 0){ ret = true; } }catch(IOException e){ e.printStackTrace(); } return ret; } public void executeFile(String filename){ String name = filename.replace(".java",""); String[] arguments = arg.getText().split(" "); String command = "java " + name; for(int i = 0; i < arguments.length; i++){ command += " " + arguments[i]; } Execute exe = new Execute(command,this); executeThread = exe; executeThread.start(); } public void logWriter(String line, boolean exe){ log.append(line + "\n"); } public void threadInfo(){ chooseButton.setEnabled(true); compileButton.setEnabled(true); runButton.setEnabled(true); clearLogButton.setEnabled(true); killButton.setEnabled(false); progBar.setIndeterminate(false); } } class Execute extends Thread{ String command; MasterGUI gui; Process p = null; public Execute(String command, MasterGUI gui){ this.command = command; this.gui = gui; } public void run(){ try{ long start = System.nanoTime(); p = Runtime.getRuntime().exec(command); gui.logWriter(command,true); BufferedReader in = new BufferedReader( new InputStreamReader(p.getInputStream())); String line = null; while((line = in.readLine()) != null){ gui.logWriter(line,true); } long timeTakenNS = System.nanoTime() - start; BufferedReader in2 = new BufferedReader( new InputStreamReader(p.getErrorStream())); String line2 = null; boolean errorOccured = false; while((line2 = in2.readLine()) != null){ errorOccured = true; gui.logWriter(line2,true); } if(!errorOccured){ double timeTakenMS = timeTakenNS * Math.pow(10,-6); timeTakenMS = Math.floor(timeTakenMS * 100) / 100; gui.logWriter("program execution time: " + timeTakenMS + " ms",true); } gui.threadInfo(); }catch(IOException e){ e.printStackTrace(); } } public void destroyProc(){ p.destroy(); } } /************ *FILEHANDLER* ************/ class FileHandler{ String in_name; String out_name; ProgramState ps; void setFile(String name){ in_name = name; } File writeFile(String output) throws java.io.FileNotFoundException{ String noEnding = in_name.replace(".java",""); out_name = noEnding + "Para.java"; File f = new File(out_name); PrintWriter out = new PrintWriter(f); try{ out.println(output); }finally{ out.close(); } return f; } public File readFile() throws java.io.FileNotFoundException{ Scanner in = new Scanner(new File(in_name)); String input; File f = null; try{ input = in.nextLine(); while(in.hasNext()){ input = input + "\n" + in.nextLine(); } //generate worker code ps = new ProgramState(input,in_name); String output = ps.getParallelCode(); //write file f = writeFile(output); }finally{ in.close(); } return f; } } /** *Find the state of the program. *- is it phasedivided or just one * recursive function? ************/ class ProgramState{ boolean PHASE; String code; String newCode; String progName; InitialGenerator ig; AdminGenerator ag; AdminPhaseGenerator apg; WorkerGenerator wg; public ProgramState(String code, String progName){ this.code = code; newCode = ""; this.progName = progName; PHASE = adminMethodExist(); CreateParallelProgram(); } void CreateParallelProgram(){ ig = new InitialGenerator(code,progName); if(PHASE){ apg = new AdminPhaseGenerator(code); newCode = ig.AssembleInitCode() + apg.AssembleAdminPhaseCode(); }else{ ag = new AdminGenerator(code); newCode = ig.AssembleInitCode() + ag.AssembleAdminCode(); } } boolean adminMethodExist(){ String[] codeSplit = code.split("\n"); String admin = "ADMIN"; for(int i = 0; i < codeSplit.length; i++){ if(codeSplit[i].contains(admin)){ return true; } } return false; } public String getParallelCode(){ return newCode; } } /***************** - INIT GENERATOR - *****************/ class InitialGenerator{ //imports and main class //0 = imports, 1 = main class String[] initCode = new String[2]; String code; String fileName; public InitialGenerator(String c, String fn){ code = c; fileName = fn; createImports(); createMainClass(); } public String AssembleInitCode(){ String ret = ""; for(int i = 0; i < initCode.length; i++){ ret += initCode[i]; } return ret; } void printInitCode(){ for(int i = 0; i < initCode.length; i++){ System.out.println(initCode[i]); } } void createImports(){ String[] fileSplit = code.split("class"); String importStat = fileSplit[0].substring(0,fileSplit[0].length()-1); String paraImports = "import java.util.*;\n" + "import java.util.Stack;\n" + "import java.util.NoSuchElementException;\n" + "import java.util.concurrent.*;\n\n"; initCode[0] = importStat + paraImports; } void createMainClass(){ String className = fileName.replace(".java","Para"); String mc = "class " + className + "{\n" + "\tpublic static void main(String[] args){\n" + "\t\tnew Admin(args);\n" + "\t}\n}\n\n"; initCode[1] = mc; } } /************************ - ADMIN PHASE GENERATOR - ************************/ class AdminPhaseGenerator{ //0 = main setup //1 = admin function //2 = rest of class //3 = rest of program 4 = worker class code //5 = recInit code String[] apCode = new String[10]; String code; String admin_code; String admin_code_name; ArrayList funcNames = new ArrayList(); String className = ""; String[] classNames = null; String[] worker_classCode_OLD = null; String[] worker_classCode_NEW = null; String classCode = ""; String original_mainCode = ""; ArrayList original_recCode = new ArrayList(); ArrayList new_recCode = new ArrayList(); public AdminPhaseGenerator(String code){ this.code = code; admin_code = getAdminCode(); setAllFuncNames(); createAdminFunc(); createInitial(); getRestOfClass(); getRestOfProgram(); // AssembleAdminPhaseCode(); } String AssembleAdminPhaseCode(){ return apCode[0] + apCode[1] + apCode[5] + apCode[2] + apCode[4] + apCode[3]; } String getAdminCode(){ String[] codeSplit = code.split("\n"); String admin = "ADMIN"; String next_code = ""; boolean start = false; for(int i = 0; i < codeSplit.length; i++){ if(start){ next_code += codeSplit[i] + "\n"; }else if(codeSplit[i].contains(admin)){ className = TextHelper.getMyClass(i,code); admin_code_name = TextHelper.getFuncNameFromCall(codeSplit[i+1]); start = true; } } start = false; String afterClass = ""; //classCode for(int i = 0; i < codeSplit.length; i++){ if(start){ afterClass += codeSplit[i] + "\n"; }else if(codeSplit[i].contains(className)){ afterClass += codeSplit[i] + "\n"; start = true; } } classCode = TextHelper.codeByParanthese(afterClass); return TextHelper.codeByParanthese(next_code); } void setAllFuncNames(){ String[] codeSplit = code.split("\n"); int counter = 1; String func = "FUNC "; for(int i = 0; i < codeSplit.length; i++){ if(codeSplit[i].contains(func)){ //the number is always a position 8. If more than //10 phases, this will fail seeing as then the number //is at 8 and 9. char numChar = codeSplit[i].charAt(8); int number = Character.getNumericValue(numChar); String call = TextHelper.getFuncNameFromCall(codeSplit[i+1]); funcNames.add(number-1,call); } } } void createInitial(){ String init = "class Admin{\n" + "\n\tpublic Admin(String[] args){\n" + "\t\tinitiateParallel(args);\n" + "\t}\n\n" + "\tvoid initiateParallel(String[] args){\n"; String[] fileSplit = code.split("public static void main"); String mainCode = TextHelper.codeByParanthese(fileSplit[1]); original_mainCode = "public static void main" + mainCode; String[] fileSplit2 = fileSplit[1].split("\n"); String firstLine = fileSplit2[0] + "\n"; mainCode = mainCode.replace(firstLine,""); mainCode = mainCode.replace(className,"Admin"); mainCode = fixCallToAdmin(mainCode); apCode[0] = init + mainCode + "\n\n"; } String fixCallToAdmin(String mainCode){ String[] fileSplit = mainCode.split("\n"); String correct = ""; String remove = ""; int call_index = -1; //find the lines with class x = new class() for the classes //that we remove for(int i = 0; i < fileSplit.length; i++){ boolean contain = false; for(int j = 0; j < classNames.length; j++){ if(fileSplit[i].contains(classNames[j]) && !fileSplit[i].contains("Admin")){ contain = true; } if(fileSplit[i].contains("Admin")){ call_index = i; } } if(!contain){ correct += fileSplit[i] + "\n"; }else{ remove += fileSplit[i] + "\n"; } } //find the removing variable names, so we can remove them //from Admin call parameters String[] removeSplit = remove.split("\n"); String[] vars = new String[removeSplit.length]; for(int i = 0; i < removeSplit.length; i++){ vars[i] = TextHelper.getVarName(removeSplit[i]); } //remove from admin call String param = TextHelper.getParamFromCall(fileSplit[call_index]); param = param.substring(1,param.length()-1); String[] paramSplit = param.split(","); String new_param = ""; for(int i = 0; i < paramSplit.length; i++){ boolean contain = false; for(int j = 0; j < vars.length; j++){ if(paramSplit[i].contains(vars[j])){ contain = true; } } if(!contain){ new_param += paramSplit[i] + ","; } } new_param = new_param.substring(0,new_param.length()-1); String temp = fileSplit[call_index].replace(param,new_param); String new_mainCode = correct.replace(fileSplit[call_index],temp); //new_mainCode = new_mainCode.replace("new Admin().",""); String[] codeSplit = new_mainCode.split("\n"); //find call to outside of static main String mainClassVar = "NONEXISTANT!"; for(int i = 0; i < codeSplit.length; i++){ if(codeSplit[i].contains("new Admin(")){ String newLine = TextHelper.removeDirectPointer(codeSplit[i]); if(newLine.equals("")) mainClassVar = TextHelper.getVarName(codeSplit[i]); new_mainCode = new_mainCode.replace(codeSplit[i],newLine); } } new_mainCode = new_mainCode.replace(mainClassVar + ".",""); return new_mainCode; } void createAdminFunc(){ String[] fileSplit = admin_code.split("\n"); apCode[1] = "\n" + createdataStructure() + "\n\n"; classNames = new String[funcNames.size()]; worker_classCode_OLD = new String[funcNames.size()]; worker_classCode_NEW = new String[funcNames.size()]; int lastIndex = -1; for(int i = 0; i < funcNames.size(); i++){ lastIndex = i; String paraPhase = fileSplit[1 + i*2]; String callName = TextHelper.getFuncNameFromCall(paraPhase); String paraPhase_param = TextHelper.getParamFromCall(paraPhase); String answer = TextHelper.getBeforeEqual(paraPhase); String var = TextHelper.getVarName(paraPhase); String synchPhase = fileSplit[2 + i*2]; WorkerPhaseGenerator wpg = new WorkerPhaseGenerator(code,funcNames.get(i), i); String retVal = wpg.retVal; classNames[i] = wpg.className; worker_classCode_OLD[i] = wpg.classCode; worker_classCode_NEW[i] = wpg.AssembleAdminPhaseCode(); if(!callName.equals(funcNames.get(i))){ String call_param = paraPhase_param.substring(0,paraPhase_param.length()-1) + ",es,b,coreCount)"; String newCall = TextHelper.getBeforeEqual(paraPhase) + " = " + classNames[i] + "_initRec" + call_param + ";"; initialRecCall(callName,i,retVal); apCode[1] += "\n\n\t\t/*new parallel phase: "+ funcNames.get(i) + "*/\n" + "\t\t/********************************************/\n" + newCall + "\n" + synchPhase; }else{ apCode[1] += "\n\n\t\t/*new parallel phase: "+ funcNames.get(i) + "*/\n" + "\t\t/********************************************/\n" + "\t\tLinkedList<" + classNames[i] + "_worker> " + classNames[i] + "_allWorkers = new LinkedList<" + classNames[i] + "_worker>();\n" + "\t\tStack<" + classNames[i] + "_worker> " + classNames[i] + "_waitingWorkers = new Stack<" + classNames[i] + "_worker>();\n" + createStartup(classNames[i],paraPhase_param) + "\n\n" + createWorkers(classNames[i]) + "\n\n" + createWorkerExecution(classNames[i]) + "\n\n" + createWaitingUntilDone() + "\n\n" + createGathering(classNames[i],retVal,answer,var) + "\n\n" + "\t\t}else{\n" + "\t\t\t" + var + " = " + classNames[i] + "_root.run_seq();\n" + "\t\t}\n" + synchPhase; } } String ret = ""; for(int i = 0; i < fileSplit.length; i++){ if(fileSplit[i].contains("return")){ ret += fileSplit[i]; break; } } String def_param = TextHelper.getParamFromCall(fileSplit[0]); String[] paramSplit = def_param.split(","); String new_param = "("; String remove = ""; for(int i = 0; i < paramSplit.length; i++){ boolean contain = false; for(int j = 0; j < classNames.length; j++){ if(paramSplit[i].contains(classNames[j])){ contain = true; } } if(!contain){ new_param += paramSplit[i].trim() + ", "; }else{ remove += paramSplit[i].trim() + "\n"; } } String[] removeParam = remove.split("\n"); for(int i = 0; i < removeParam.length; i++){ String[] removeSplit = removeParam[i].split(" "); removeParam[i] = removeSplit[1]; } for(int i = 0; i < removeParam.length; i++){ apCode[1] = apCode[1].replace(removeParam[i] + ",",""); apCode[1] = apCode[1].replace(removeParam[i],""); } new_param = new_param.substring(0,new_param.length()-2); String new_def = fileSplit[0].replace(def_param,new_param); apCode[1] += "\n\t\tes.shutdown();\n"; apCode[1] += ret + "\n"; apCode[1] += "\n\t}\n"; apCode[1] = new_def + apCode[1]; apCode[4] = ""; for(int i = 0; i < worker_classCode_NEW.length; i++){ apCode[4] += worker_classCode_NEW[i]; } fixInitRecCodes(); } void initialRecCall(String call, int index, String retVal){ //1. get the method isolated String[] fileSplit = code.split("\n"); boolean started = false; String recInitCode = ""; for(int i = 0; i < fileSplit.length; i++){ if(started){ recInitCode += fileSplit[i] + "\n"; }else if(fileSplit[i].contains(call) && !fileSplit[i].contains("=")){ recInitCode += fileSplit[i] + "\n"; started = true; } } recInitCode = TextHelper.codeByParanthese(recInitCode); original_recCode.add(recInitCode); //2. divide into 3 parts: before recursive calls, recursive calls and after String[] codeSplit = recInitCode.split("\n"); String introCode = ""; boolean intro_over = false; String recCalls = ""; boolean recCalls_over = true; int rec_counter = 0; String rest = ""; boolean rest_start = false; int calls = 0; for(int i = 0; i < codeSplit.length; i++){ if(codeSplit[i].contains("REC")){ intro_over = true; recCalls_over = false; recCalls += codeSplit[i] + "\n"; rec_counter = 0; calls++; }else if(!intro_over){ introCode += codeSplit[i] + "\n"; }else if(rec_counter > 1 && !recCalls_over){ recCalls_over = true; rest_start = true; rest += "\t" + codeSplit[i] + "\n"; }else if(!recCalls_over){ recCalls += codeSplit[i] + "\n"; rec_counter++; }else if(rest_start){ rest += "\t" + codeSplit[i] + "\n"; } } //3. create initial datastructures and workers String initial = "\n\n\t\t/*new parallel phase: "+ funcNames.get(index) + "*/\n" + "\t\t/********************************************/\n" + "\t\tLinkedList<" + classNames[index] + "_worker> " + classNames[index] + "_allWorkers = new LinkedList<" + classNames[index] + "_worker>();\n" + "\t\tStack<" + classNames[index] + "_worker> " + classNames[index] + "_waitingWorkers = new Stack<" + classNames[index] + "_worker>();\n"; String[] recSplit = recCalls.split("\n"); String worker_init = ""; int counter = 0; for(int i = 0; i < recSplit.length; i++){ if(!recSplit[i].contains("REC")){ String param = TextHelper.getParamFromCall(recSplit[i]); param = param.substring(0,param.length()-1) + ",b)"; worker_init += "\t\t" + classNames[index] + "_worker " + classNames[index] + "_root" + counter + " = new " + classNames[index] + "_worker" + param + ";\n" + "\t\t" + classNames[index] + "_allWorkers.add(" + classNames[index] + "_root" + counter++ + ");\n"; } } //4. create workers String createW = createWorkers(classNames[index]); //5. initate workers String initW = createWorkerExecution(classNames[index]); //6. wait block String wait_block = createWaitingUntilDone(); //7. gather restults from all but the last ones. number of not popping equals that which is called upon here String res ="\t\t\t" + classNames[index] + "_worker " + classNames[index] + "_current;\n" + "\t\t\twhile(" + classNames[index] + "_waitingWorkers.size() > " + calls + "){\n" + "\t\t\t\t" + classNames[index] + "_current = " + classNames[index] + "_waitingWorkers.pop();\n" + "\t\t\t\t" + classNames[index] + "_current.gatherResultInit();\n" + "\t\t\t}\n"; //8. pop the roots String[] recSplit2 = recCalls.split("\n"); String result = ""; for(int i = recSplit2.length-1; i >= 0; i--){ if(!recSplit2[i].contains("REC")){ String var = TextHelper.getBeforeEqual(recSplit2[i]); result += "\t\t\t" + classNames[index] + "_current = " + classNames[index] + "_waitingWorkers.pop();\n" + "\t\t\t" + classNames[index] + "_current.gatherResultInit();\n" + "\t" + var + " = " + classNames[index] + "_current.sol;\n"; } } String rest_temp = rest.substring(0,rest.length()-1); result += rest_temp + "else{\n"; //9. fix method declaration String name = TextHelper.getFuncNameFromCall(codeSplit[0]); introCode = introCode.replace(name,classNames[index] + "_initRec"); //10.add else for not sequential String result2 = ""; int c = 0; for(int i = 0; i < recSplit2.length; i++){ if(recSplit2[i].contains("REC")){ i++; String var = TextHelper.getBeforeEqual(recSplit2[i]); String param = TextHelper.getParamFromCall(recSplit[i]); result2 += "\t" + var + " = " + classNames[index] + "_root" + (c++) + ".mySolution" + param + ";\n"; } } result2 += rest + "\n\t}\n\n"; String total = introCode + initial + worker_init + createW + initW + wait_block + res + result + /*rest +*/ result2; new_recCode.add(total); } void fixInitRecCodes(){ apCode[5] = "\n"; //go through all the new init recursive methods for(int i = 0; i < new_recCode.size(); i++){ String recCode_old = new_recCode.get(i); String[] codeSplit = recCode_old.split("\n"); //all the lines in the method for(int j = 0; j < codeSplit.length; j++){ if(codeSplit[j].contains("_initRec")){ String param_old = TextHelper.getParamFromCall(codeSplit[j]); param_old = param_old.substring(1,param_old.length()-1); String[] paramSplit = param_old.split(","); String param_new = ""; //go through the parameters for(int k = 0; k < paramSplit.length; k++){ for(int l = 0; l < classNames.length; l++){ if(paramSplit[k].contains(classNames[l])){ if(k == paramSplit.length-1) param_new = param_old.replace(paramSplit[k],""); else param_new = param_old.replace(paramSplit[k] + ",",""); } } } String recCode_new = recCode_old.replace(param_old,param_new + ", ExecutorService es, CyclicBarrier b, int coreCount"); apCode[5] += recCode_new; } } } } String createdataStructure(){ return "\t\tint coreCount = Runtime.getRuntime().availableProcessors();\n" + "\t\tCyclicBarrier b = new CyclicBarrier(coreCount);\n" + "\t\tExecutorService es = Executors.newFixedThreadPool(coreCount);\n"; } String createStartup(String name,String param){ param = param.substring(0,param.length()-1) + ",b)"; return "\t\t" + name + "_worker " + name + "_root = new " + name + "_worker" + param + ";\n" + "\t\t" + name + "_allWorkers.add(" + name + "_root);\n\n"; } String createWorkers(String name){ return "\t\tboolean " + name + "_parallel = true;\n" + "\t\ttry{\n" + "\t\twhile(" + name + "_allWorkers.size() < coreCount){\n" + "\t\t\t" + name + "_worker " + name + "_w = " + name + "_allWorkers.remove();\n" + "\t\t\t" + name + "_allWorkers.addAll(" + name + "_w.makeChildren());\n" + "\t\t\t" + name + "_waitingWorkers.push(" + name + "_w);\n" + "\t\t}\n" + "\t\t}catch(NoSuchElementException e){\n" + "\t\t\t" + name + "_parallel = false;\n" + "\t\t}\n\n" + "\t\tif(" + name + "_parallel){\n"; } String createWorkerExecution(String name){ return "\t\tint threadProgress = 0;\n" + "\t\twhile(" + name + "_allWorkers.size()-1 > 0 && threadProgress < coreCount){\n" + "\t\t\t" + name + "_worker " + name + "_w = " + name + "_allWorkers.remove();\n" + "\t\t\tes.execute(" + name + "_w);\n" + "\t\t\tthreadProgress++;\n" + "\t\t}\n\n" + "\t\twhile(" + name + "_allWorkers.size()-1 > 0){\n" + "\t\t\t" + name + "_worker " + name + "_w = " + name + "_allWorkers.remove();\n" + "\t\t\t" + name + "_w.run_seq();\n" + "\t\t}\n\n" + "\t\tif(" + name + "_allWorkers.size() == 1){\n" + "\t\t\t" + name + "_worker " + name + "_w = " + name + "_allWorkers.remove();\n" + "\t\t\t" + name + "_w.run_seq();\n" + "\t\t}\n\n"; } String createWaitingUntilDone(){ return "\t\t\ttry{\n" + "\t\t\t\tb.await();\n" + "\t\t\t\t}catch(InterruptedException ex){\n" + "\t\t\t\t} catch (BrokenBarrierException ex){\n" + "\t\t\t}\n\n"; } String createGathering(String name, String retVal, String answer, String var){ return "\t\t\t" + name + "_worker " + name + "_current = " + name + "_waitingWorkers.pop();\n" + "\t\t\t" + name + "_current.gatherResultInit();\n" + "\t\t\t" + answer + " = " + name + "_current.sol;\n" + "\t\t\twhile(!" + name + "_waitingWorkers.empty()){\n" + "\t\t\t\t" + name + "_current = " + name + "_waitingWorkers.pop();\n" + "\t\t\t\t" + name + "_current.gatherResultInit();\n" + "\t\t\t\t" + var + " = " + name + "_current.sol;\n\t" + "\t\t}\n"; } void getRestOfClass(){ String newClassCode = classCode.replace(original_mainCode,""); newClassCode = newClassCode.replace(admin_code,""); String[] fileSplit = newClassCode.split("\n"); String firstLine = fileSplit[0]; int index = newClassCode.lastIndexOf('}'); newClassCode = newClassCode.replace(firstLine,""); for(int i = 0; i < original_recCode.size(); i++){ newClassCode = newClassCode.replace(original_recCode.get(i),""); } apCode[2] = newClassCode + "\n\n"; } void getRestOfProgram(){ String rest = code.replace(classCode,""); for(int i = 0; i < worker_classCode_OLD.length; i++){ rest = rest.replace(worker_classCode_OLD[i],""); } String[] fileSplit = rest.split("\n"); for(int i = 0; i < fileSplit.length; i++){ if(fileSplit[i].contains("import")){ rest = rest.replace(fileSplit[i] + "\n", ""); } } apCode[3] = rest; } } /************************* - WORKER PHASE GENERATOR - *************************/ class WorkerPhaseGenerator{ //0 = init(class,vars,constr,run()) 1 = makechildren 2 = mySolution() //3 = gatherResults String[] wpCode = new String[10]; String code; String original_recName; String original_constructor = ""; int phase; String classCode = ""; String className = ""; String recCode = ""; String retVal = ""; String classInit = ""; String param = ""; String[] paramSplit = null; int recCalls = 0; public WorkerPhaseGenerator(String code, String name, int phase){ this.code = code; original_recName = name; this.phase = phase; getClassCode(); getRecCode(); getParameters(); createInit(); createMakeChildren(); createMySolution(); createGatherResult(); createRestOfClass(); // AssembleAdminPhaseCode(); } String AssembleAdminPhaseCode(){ String ret = ""; for(int i = 0; i < 5; i++){ ret += wpCode[i]; } return ret; } void createInit(){ String temp_init = ""; for(int i = 0; i < paramSplit.length; i++){ temp_init += "\t" + paramSplit[i] + ";\n"; } temp_init += "\tCyclicBarrier barrier;\n"; String class_init = "class " + className + "_worker implements Runnable{\n" + temp_init + ""; String variables = "\t" + retVal + " sol;\n" + "\t" + "LinkedList<" + className + "_worker> children = new LinkedList<" + className + "_worker>();\n" + "\n"; String temp_const = ""; for(int i = 0; i < paramSplit.length; i++){ String[] varSplit = paramSplit[i].split(" "); temp_const += "\t\tthis." + varSplit[1] + " = " + varSplit[1] + ";\n"; } temp_const += "\t\tthis.barrier = barrier;\n"; String const_param = param + ", CyclicBarrier barrier"; String constructor = "\tpublic " + className + "_worker(" + const_param + "){\n" + temp_const + "\t}\n\n"; String threadStart = "\tpublic void run(){\n" + "\t\tsol = mySolution" + getParamAsCall(param) + ";\n" + "\t\ttry{\n" + "\t\t\tbarrier.await();\n" + "\t\t}catch(InterruptedException ex){\n" + "\t\t}catch(BrokenBarrierException ex){\n" + "\t\t}\n" + "\t}\n\n"; String seqStart = "\tpublic " + retVal + " run_seq(){\n" + "\t\tsol = mySolution" + getParamAsCall(param) + ";\n" + "\t\treturn sol;\n" + "\t}\n\n"; wpCode[0] = class_init + variables + constructor + threadStart + seqStart; } String getParamAsCall(String param){ String[] paramSplit = param.split(","); String param_new = "("; for(int i = 0; i < paramSplit.length; i++){ String[] varSplit = paramSplit[i].trim().split(" "); if(varSplit.length < 2) return "ERROR - param already a call"; if(i == paramSplit.length-1) param_new += varSplit[1] + ")"; else param_new += varSplit[1] + ","; } return param_new; } void getClassCode(){ String[] fileSplit = code.split("\n"); for(int i = 0; i < fileSplit.length; i++){ if(fileSplit[i].contains(original_recName) && !fileSplit[i].contains("=") && fileSplit[i].contains("{")){ className = TextHelper.getMyClass(i,code); retVal = TextHelper.extractRetVal(fileSplit[i], original_recName).trim(); break; } } boolean start = false; String tempCode = ""; for(int i = 0; i < fileSplit.length; i++){ if(start){ tempCode += fileSplit[i] + "\n"; }else if(fileSplit[i].contains("class " + className)){ tempCode += fileSplit[i] + "\n"; start = true; } } classCode = TextHelper.codeByParanthese(tempCode); } void getRecCode(){ String[] fileSplit = classCode.split("\n"); boolean start = false; String tempCode = ""; for(int i = 0; i < fileSplit.length; i++){ if(start){ tempCode += fileSplit[i] + "\n"; }else if(fileSplit[i].contains(original_recName)){ start = true; tempCode += fileSplit[i] + "\n"; } } recCode = TextHelper.codeByParanthese(tempCode); } void getParameters(){ String[] fileSplit = recCode.split("\n"); param = TextHelper.getParamFromCall(fileSplit[0]); param = param.substring(1, param.length()-1); paramSplit = param.split(","); for(int i = 0; i < paramSplit.length; i++){ paramSplit[i] = paramSplit[i].trim(); } } void createMakeChildren(){ String[] fileSplit = recCode.split("\n"); String mc_code = ""; boolean rec_started = false; boolean correct_return = false; int count = 0; wpCode[1] = "\tpublic LinkedList<" + className + "_worker> makeChildren(){\n"; for(int i = 1; i < fileSplit.length; i++){ if(!fileSplit[i].contains("REC") && rec_started){ // int jumpDown = TextHelper.jumpToReturn(recCode,i); fileSplit[i] = "\t\treturn children;\n"; int jumpDown = TextHelper.jumpToCloseBracket(recCode,i); for(int j = i+1; j < jumpDown; j++){ fileSplit[j] = ""; } i = jumpDown-1; rec_started = false; correct_return =true; if(i >= fileSplit.length) break; }else if(fileSplit[i].contains("return")){ if(rec_started){ correct_return = true; rec_started = false; } if(!correct_return){ fileSplit[i] += "return children\n"; } //get the right amount of tab spaces int index = fileSplit[i].indexOf("return"); fileSplit[i] = fileSplit[i].substring(0,index) + "return children;\n"; }else if(fileSplit[i].contains("REC")){ rec_started = true; i++; String param = TextHelper.getParamFromCall(fileSplit[i]); param = param.substring(0,param.length()-1) + ",barrier)"; fileSplit[i] = "\n\t\t" + className + "_worker w" + count + " = new " + className + "_worker" + param + ";\n" + "\t\tchildren.add(w" + count++ + ");\n"; }else{ fileSplit[i] += "\n"; } } for(int i = 1; i < fileSplit.length; i++){ wpCode[1] += fileSplit[i]; } } void createMySolution(){ String tempCode = recCode.replaceAll(original_recName,"mySolution"); wpCode[2] = "\n\n" + tempCode; } void createGatherResult(){ String[] fileSplit = recCode.split("\n"); String mc_code = ""; boolean rec_started = false; boolean correct_return = false; int count = 0; wpCode[3] = "\n\n\tpublic void gatherResultInit(){\n" + "\t\tsol = gatherResult();\n" + "\t}\n\n" + "\t" + retVal + " gatherResult(){\n"; for(int i = 1; i < fileSplit.length; i++){ if(fileSplit[i].contains("REC")){ rec_started = true; i++; int index = fileSplit[i].indexOf("=")+1; String sub = fileSplit[i].substring(0,index); fileSplit[i] = "\n" + sub + " children.get(" + count++ + ").sol;\n"; }else{ fileSplit[i] += "\n"; } } for(int i = 1; i < fileSplit.length; i++){ wpCode[3] += fileSplit[i]; } } void createRestOfClass(){ String newClassCode = classCode.replace(recCode,""); String[] fileSplit = newClassCode.split("\n"); fileSplit[0] = ""; wpCode[4] = ""; String constructor = ""; boolean const_start = false; for(int i = 0; i < fileSplit.length; i++){ if(fileSplit[i].contains("public " + className + "(")){ constructor += fileSplit[i] + "\n"; const_start = true; }else if(const_start){ constructor += fileSplit[i] + "\n"; } wpCode[4] += fileSplit[i] + "\n"; } original_constructor = TextHelper.codeByParanthese(constructor); wpCode[4] = wpCode[4].replace(original_constructor,"") + "\n\n"; String[] fileSplit2 = wpCode[4].split("\n"); String total = ""; boolean cont = false; for(int i = 0; i < fileSplit2.length; i++){ boolean setF = false; boolean setT = false; int comment = TextHelper.lineIsComment(fileSplit2[i]); if(comment == 1){ setF = true; }else if(comment == 2){ setT = true; }else if(comment == 3){ }else if(comment == 4){ setF = true; }else if(comment == 0){ if(!cont){ total += fileSplit2[i] + "\n"; } } if(setF)cont = false; if(setT)cont = true; } wpCode[4] = total; } } /****************** - ADMIN GENERATOR - ******************/ class AdminGenerator{ //0 = init, 1 = datastructures, 2 = startUp, 3 = workers, //4 = workerExecution, 5 = wait until done, 6 = gather results //7 = ending brackets String[] adminCode = new String[4]; String code; String fileName; String initParam; String param_call; String funcName; String className = ""; String classCode = ""; String retVal = ""; String original_mainCode = ""; String funcCode = ""; String worker_code_old = ""; String worker_code_new = ""; String restClasses = ""; String rootParams = ""; public AdminGenerator(String c){ code = c; findFuncName(); setClassNameAndCode(); findInitParam(); createInit(); getRestOfClass(); WorkerGenerator wg = new WorkerGenerator(c,funcName,funcCode,original_mainCode); worker_code_new = wg.worker_code; worker_code_old = wg.classCode; adminCode[2] = worker_code_new; restOfProgram(); } /**Finds the name of the *recursive function **/ void findFuncName(){ String[] fileSplit = code.split("\n"); boolean start = false; String temp = ""; for(int i = 0; i < fileSplit.length; i++){ if(fileSplit[i].contains("FUNC")){ funcName = TextHelper.getFuncNameFromCall(fileSplit[i+1]); retVal = TextHelper.extractRetVal(fileSplit[i+1],funcName); start = true; }else if(start){ temp += fileSplit[i] + "\n"; } } funcCode = TextHelper.codeByParanthese(temp); } public String AssembleAdminCode(){ String ret = ""; for(int i = 0; i < adminCode.length; i++){ ret += adminCode[i]; } return ret; } void printAdminCode(){ for(int i = 0; i < adminCode.length; i++){ System.out.println(adminCode[i] + " " + i); } } void setClassNameAndCode(){ String[] fileSplit = code.split("\n"); String temp = ""; for(int i = 0; i < fileSplit.length; i++){ temp += fileSplit[i] + "\n"; if(fileSplit[i].contains("main")){ temp += fileSplit[i] + "\n"; className = TextHelper.getMyClass(i, temp); break; } } temp = ""; boolean start = false; for(int i = 0; i < fileSplit.length; i++){ if(fileSplit[i].contains("class " + className)){ temp += fileSplit[i] + "\n"; start = true; }else if(start){ temp += fileSplit[i] + "\n"; } } classCode = TextHelper.codeByParanthese(temp); } /** Creates the setup part of the program. * for instance, if u create some variables and such * before the recursive method **/ void createInit(){ String init = "class Admin{\n" + "\n\tpublic Admin(String[] args){\n" + "\t\tinitiateParallel(args);\n" + "\t}\n\n" + "\tvoid initiateParallel(String[] args){\n"; String[] fileSplit = code.split("public static void main"); String mainCode = TextHelper.codeByParanthese(fileSplit[1]); original_mainCode = "public static void main" + mainCode; String[] fileSplit2 = fileSplit[1].split("\n"); String firstLine = fileSplit2[0] + "\n"; mainCode = mainCode.replace(firstLine,""); mainCode = mainCode.replace(className,"Admin"); String[] codeSplit = mainCode.split("\n"); String var = ""; String param = ""; String threadStart = ""; //find call to outside of static main String mainClassVar = "NONEXISTANT!"; for(int i = 0; i < codeSplit.length; i++){ if(codeSplit[i].contains("new Admin(")){ String newLine = TextHelper.removeDirectPointer(codeSplit[i]); if(newLine.equals("")) mainClassVar = TextHelper.getVarName(codeSplit[i]); mainCode = mainCode.replace(codeSplit[i],newLine); } } mainCode = mainCode.replace(mainClassVar + ".",""); for(int i = 0; i < codeSplit.length; i++){ if(codeSplit[i].contains(funcName)){ var += TextHelper.getBeforeEqual(codeSplit[i]); param += TextHelper.getParamFromCall(codeSplit[i]); param_call = param; mainCode = mainCode.replace(codeSplit[i],var + " = startThreads" + param + ";"); break; } } threadStart = createThreadStarter(); adminCode[0] = init + mainCode + "\n\n" + threadStart; } String createThreadStarter(){ String init = "\t" + retVal + " startThreads" + initParam + "{\n"; init += createDataStructure() + createStartup() + createWorkers() + createWorkerExecution() + createWaitingUntilDone() + createGathering(); init += "\t\treturn answer;\n"; init += "\t}\n\n"; return init; } /** Finds the initial parameters to the recursive method **/ void findInitParam(){ String[] lines = code.split("\n"); boolean functionNext = false; for(int i = 0; i < lines.length; i++){ if(lines[i].contains("FUNC")){ initParam = TextHelper.getParamFromCall(lines[i+1]); } } } String createDataStructure(){ return "\n\t\tint coreCount = Runtime.getRuntime().availableProcessors();\n"+ "\t\tLinkedList allWorkers = new LinkedList();\n"+ "\t\tStack waitingWorkers = new Stack();\n" + "\t\tCyclicBarrier b = new CyclicBarrier(coreCount);\n\n"; } String createStartup(){ String param = initParam.substring(0,initParam.length()-1); String[] paramSplit = param.split(","); String temp = ""; for(int i = 0; i < paramSplit.length; i++){ String[] paramSplit2 = paramSplit[i].trim().split(" "); temp += paramSplit2[1] + ","; } rootParams = temp.substring(0,temp.length()-1); return "\t\tWorker root = new Worker(" + temp + "b);\n" + "\t\tallWorkers.add(root);\n\n"; } String createWorkers(){ return "\t\tboolean sequential = false;\n" + "\t\ttry{\n" + "\t\t\twhile(allWorkers.size() < coreCount){\n" + "\t\t\t\tWorker w = allWorkers.remove();\n" + "\t\t\t\tallWorkers.addAll(w.makeChildren());\n" + "\t\t\t\twaitingWorkers.push(w);\n" + "\t\t}\n" + "\t\t}catch(NoSuchElementException e){\n" + "\t\t\tsequential = true;\n" + "\t\t}\n\n" + "\t\tif(sequential){\n" + "\t\t\treturn root.runMySolution();\n" + "\t\t}\n\n"; } String createWorkerExecution(){ return "\t\tExecutorService es = Executors.newFixedThreadPool(coreCount);\n" + "\t\twhile(allWorkers.size()-1 > 0){\n" + "\t\t\tWorker w = allWorkers.remove();\n" + "\t\t\tes.execute(w);\n" + "\t\t}\n\n" + "\t\tif(allWorkers.size() == 1){\n" + "\t\t\tWorker w = allWorkers.remove();\n" + "\t\t\tw.runMySolution();\n" + "\t\t}\n\n"; } String createWaitingUntilDone(){ return "\t\ttry{\n" + "\t\t\tb.await();\n" + "\t\t\t}catch(InterruptedException ex){\n" + "\t\t\t} catch (BrokenBarrierException ex){\n" + "\t\t}\n\n"; } String createGathering(){ return "\t\tWorker current = waitingWorkers.pop();\n" + "\t\tcurrent.gatherResultInit();\n" + "\t\t"+ retVal + " answer = current.sol;\n" + "\t\twhile(!waitingWorkers.empty()){\n" + "\t\t\tcurrent = waitingWorkers.pop();\n" + "\t\t\tcurrent.gatherResultInit();\n" + "\t\t\tanswer = current.sol;\n\t" + "\t}\n" + "\t\tes.shutdown();\n"; } void getRestOfClass(){ String newClassCode = classCode.replace(original_mainCode,""); String[] fileSplit = newClassCode.split("\n"); String firstLine = fileSplit[0]; int index = newClassCode.lastIndexOf('}'); newClassCode = newClassCode.replace(firstLine,""); newClassCode = newClassCode.replace(funcCode,""); adminCode[1] = newClassCode; } void restOfProgram(){ String programText = code.replace(classCode,""); programText = programText.replace(worker_code_old,""); String[] codeSplit = programText.split("\n"); for(int i = 0; i < codeSplit.length; i++){ if(codeSplit[i].contains("import")){ programText = programText.replace(codeSplit[i] + "\n",""); } } adminCode[3] = programText; } } /******************* - WORKER GENERATOR - *******************/ class WorkerGenerator{ //0 = intro, 1 = makeChildren, 2 = gatherResults(), 3 = mySolution(...) //4 = ekstra metoder String[] workerCode = new String[5]; String program; String code; String retVal; String methodName; String mainCode = ""; String classCode = ""; String className = ""; String original_recName = ""; String worker_code = ""; String recCode = ""; String param = ""; String[] paramSplit = null; String original_constructor = ""; public WorkerGenerator(String c, String name, String recCode, String mainCode){ code = c; original_recName = name; this.recCode = recCode; this.mainCode = mainCode; getClassCode(); getParameters(); createInit(); createMakeChildren(); createMySolution(); createGatherResult(); createRestOfClass(); worker_code = AssembleWorkerCode(); } public String AssembleWorkerCode(){ String ret = ""; for(int i = 0; i < workerCode.length; i++){ ret += workerCode[i]; } return ret; } void printWorkerCode(){ for(int i = 0; i < workerCode.length; i++){ System.out.println(workerCode[i]); } } void createInit(){ String temp_init = ""; for(int i = 0; i < paramSplit.length; i++){ temp_init += "\t" + paramSplit[i] + ";\n"; } temp_init += "\tCyclicBarrier barrier;\n" + "\t" + retVal + " sol;\n" + "\t" + "LinkedList children = new LinkedList();\n" + "\n"; String init = "\n\nclass Worker implements Runnable{\n"; String temp_const = ""; for(int i = 0; i < paramSplit.length; i++){ String[] varSplit = paramSplit[i].split(" "); temp_const += "\t\tthis." + varSplit[1] + " = " + varSplit[1] + ";\n"; } temp_const += "\t\tthis.barrier = barrier;\n"; String const_param = param + ", CyclicBarrier barrier"; String constructor = "\tpublic Worker(" + const_param + "){\n" + temp_const + "\t}\n\n"; String threadStart = "\tpublic void run(){\n" + "\t\tsol = mySolution" + getParamAsCall(param) + ";\n" + "\t\ttry{\n" + "\t\t\tbarrier.await();\n" + "\t\t}catch(InterruptedException ex){\n" + "\t\t}catch(BrokenBarrierException ex){\n" + "\t\t}\n" + "\t}\n\n"; workerCode[0] = init + temp_init + constructor + threadStart; } String getParamAsCall(String param){ //String alter_param = param.substring(1,param.length()-1); String[] paramSplit = param.split(","); String param_new = "("; for(int i = 0; i < paramSplit.length; i++){ String[] varSplit = paramSplit[i].trim().split(" "); if(varSplit.length < 2) return "ERROR - param already a call"; if(i == paramSplit.length-1) param_new += varSplit[1] + ")"; else param_new += varSplit[1] + ","; } return param_new; } void createMakeChildren(){ String[] fileSplit = recCode.split("\n"); String mc_code = ""; boolean rec_started = false; boolean correct_return = false; int count = 0; workerCode[1] = "\tpublic LinkedList makeChildren(){\n"; for(int i = 1; i < fileSplit.length; i++){ if(!fileSplit[i].contains("REC") && rec_started){ fileSplit[i] = "\t\treturn children;\n"; int jumpDown = TextHelper.jumpToCloseBracket(recCode,++i); for(int j = i; j < jumpDown; j++){ fileSplit[j] = ""; } i = jumpDown-1; rec_started = false; correct_return =true; if(i >= fileSplit.length) break; }else if(fileSplit[i].contains("return")){ if(rec_started){ correct_return = true; rec_started = false; } if(!correct_return){ fileSplit[i] += "return children\n"; } //get the right amount of tab spaces int index = fileSplit[i].indexOf("return"); fileSplit[i] = fileSplit[i].substring(0,index) + "return children;\n"; }else if(fileSplit[i].contains("REC")){ rec_started = true; i++; String param = TextHelper.getParamFromCall(fileSplit[i]); param = param.substring(0,param.length()-1) + ",barrier)"; fileSplit[i] = "\n\t\tWorker w" + count + " = new Worker" + param + ";\n" + "\t\tchildren.add(w" + count++ + ");\n"; }else{ fileSplit[i] += "\n"; } } for(int i = 1; i < fileSplit.length; i++){ workerCode[1] += fileSplit[i]; } } String removeTypes(String param){ String ret = ""; String[] paramSplit = param.split(","); for(int i = 0; i < paramSplit.length; i++){ String[] paramSplit2 = paramSplit[i].trim().split(" "); ret += paramSplit2[1].trim(); if(i != paramSplit.length-1) ret += ","; } return ret; } void createGatherResult(){ String[] fileSplit = recCode.split("\n"); String mc_code = ""; boolean rec_started = false; boolean correct_return = false; int count = 0; workerCode[2] = "\n\n\tpublic void gatherResultInit(){\n" + "\t\tsol = gatherResult();\n" + "\t}\n\n" + "\t" + retVal + " gatherResult(){\n"; for(int i = 1; i < fileSplit.length; i++){ if(fileSplit[i].contains("REC")){ rec_started = true; i++; int index = fileSplit[i].indexOf("=")+1; String sub = fileSplit[i].substring(0,index); fileSplit[i] = "\n" + sub + " children.get(" + count++ + ").sol;\n"; }else{ fileSplit[i] += "\n"; } } for(int i = 1; i < fileSplit.length; i++){ workerCode[2] += fileSplit[i]; } } void createMySolution(){ String param = ""; for(int i = 0; i < paramSplit.length; i++){ String[] varSplit = paramSplit[i].split(" "); param += varSplit[1]; if(i != paramSplit.length-1){ param += ","; } } String noParamCall = "\n\t" + retVal + " runMySolution(){\n" + "\t\tsol = mySolution(" + param + ");\n" + "\t\treturn sol;\n" + "\t}\n"; String tempCode = recCode.replaceAll(original_recName,"mySolution"); workerCode[3] = noParamCall + "\n" + tempCode; } void getClassCode(){ String[] fileSplit = code.split("\n"); for(int i = 0; i < fileSplit.length; i++){ if(fileSplit[i].contains(original_recName) && !fileSplit[i].contains("=") && fileSplit[i].contains("{")){ className = TextHelper.getMyClass(i,code); retVal = TextHelper.extractRetVal(fileSplit[i], original_recName).trim(); break; } } boolean start = false; String tempCode = ""; for(int i = 0; i < fileSplit.length; i++){ if(start){ tempCode += fileSplit[i] + "\n"; }else if(fileSplit[i].contains("class " + className)){ tempCode += fileSplit[i] + "\n"; start = true; } } classCode = TextHelper.codeByParanthese(tempCode); } void getParameters(){ String[] fileSplit = recCode.split("\n"); param = TextHelper.getParamFromCall(fileSplit[0]); param = param.substring(1, param.length()-1); paramSplit = param.split(","); for(int i = 0; i < paramSplit.length; i++){ paramSplit[i] = paramSplit[i].trim(); } } void createRestOfClass(){ String newClassCode = classCode.replace(recCode,""); String[] fileSplit = newClassCode.split("\n"); fileSplit[0] = ""; workerCode[4] = ""; String constructor = ""; String mainBlock = ""; boolean const_start = false; boolean main_start = false; for(int i = 0; i < fileSplit.length; i++){ if(fileSplit[i].contains("public " + className + "(")){ constructor += fileSplit[i] + "\n"; const_start = true; }else if(const_start){ constructor += fileSplit[i] + "\n"; } if(fileSplit[i].contains("public static void main(String[] args)")){ mainBlock += fileSplit[i] + "\n"; main_start = true; }else if(main_start){ mainBlock += fileSplit[i] + "\n"; } workerCode[4] += fileSplit[i] + "\n"; } original_constructor = TextHelper.codeByParanthese(constructor); mainBlock = TextHelper.codeByParanthese(mainBlock); workerCode[4] = workerCode[4].replace(mainBlock,""); workerCode[4] = workerCode[4].replace(original_constructor,"") + "\n\n"; String[] fileSplit2 = workerCode[4].split("\n"); String total = ""; boolean cont = false; for(int i = 0; i < fileSplit2.length; i++){ boolean setF = false; boolean setT = false; int comment = TextHelper.lineIsComment(fileSplit2[i]); if(comment == 1){ setF = true; }else if(comment == 2){ setT = true; }else if(comment == 3){ }else if(comment == 4){ setF = true; }else if(comment == 0){ if(!cont){ total += fileSplit2[i] + "\n"; } } if(setF)cont = false; if(setT)cont = true; } workerCode[4] = total; } } class TextHelper{ public static int lineIsComment(String input){ input = input.trim(); int len = input.length(); if(input.equals("")){ return 0; }else if((input.charAt(0) == '/' && input.charAt(1) == '*') && (input.charAt(len-2) == '*' && input.charAt(len-1) == '/')){ return 1; }else if(input.charAt(0) == '/' && input.charAt(1) == '*'){ return 2; }else if(input.charAt(0) == '/' && input.charAt(1) == '/'){ return 3; }else if(input.contains("*/")){ return 4; } return 0; } /** finds the recursive method by using its * name and counting parantheses *@param in the program in text *@return the recursive function in text **/ public static String codeByParanthese(String in){ int paranCount = 0; String container = ""; char[] inChar = in.toCharArray(); boolean initial = true; for(int i = 0; i < inChar.length; i++){ container += inChar[i]; if(inChar[i] == '}'){ paranCount--; initial = false; } if(inChar[i] == '{'){ paranCount++; initial = false; } if(paranCount == 0 && !initial) break; } return container; } public static String getMyClass(int lineIndex, String code){ String[] fileSplit = code.split("\n"); for(int i = lineIndex; i >= 0; i--){ if(fileSplit[i].contains("class")){ String[] fileSplit2 = fileSplit[i].split(" "); for(int j = 0; j < fileSplit2.length; j++){ if(fileSplit2[j].equals("class")){ String name = fileSplit2[j+1]; name = name.replace("{",""); return name; } } } } return "Java PRP ERROR: no class found above this line"; } public static String getFuncNameFromCall(String in){ //should initially check if there is even a call at all here int paramIndex = -1; //1. find the start of parameters (...) int count = 1; //in.length-3 because of the last ");" for(int i = in.length()-3; i >= 0; i--){ if(in.charAt(i) == ')')count++; if(in.charAt(i) == '(')count--; if(count == 0){ paramIndex = i; break; } } if(paramIndex == -1) return "NO CALL"; //2 find the call String call = ""; for(int i = paramIndex-1; i >= 0; i--){ //its either a local call (" ") or via a reference (".") if(in.charAt(i) == ' ' || in.charAt(i) == '.'){ break; } call = in.charAt(i) + call; } return call; } public static String getParamFromCall(String in){ //should initially check if there is even a call at all here int paramIndex = -1; int count = 1; String param = ")"; //in.length-2 because of the last ");" for(int i = in.length()-3; i >= 0; i--){ param = in.charAt(i) + param; if(in.charAt(i) == ')')count++; if(in.charAt(i) == '(')count--; if(count == 0){ break; } } return param; } //0 gir like antall paranteser, negativ gir flere }, positiv gir flere { //(skal ikke gi negativ) public static int parantheseCount(String in){ int left = 0; //} int right = 0; //{ char[] inChar = in.toCharArray(); for(int i = 0; i < inChar.length; i++){ if(inChar[i] == '}') left++; if(inChar[i] == '{') right++; } return (right - left); } public static ArrayList unusedVarInMethod(String code){ String[] fileSplit = code.split("\n"); ArrayList vars = new ArrayList(); //first we find all variables for(int i = 0; i < fileSplit.length; i++){ //a variable is defined by the '=' if(fileSplit[i].contains("=")){ String[] fileSplit2 = fileSplit[i].split(" "); //the '=' should be at pos 2, because we need to //strings before (type var), or its a renaming of var if(fileSplit2[2].equals("=")){ vars.add(fileSplit2[1]); } } } //now we check if they're in use more than once in the code ArrayList unused = new ArrayList(); for(String v : vars){ int used = 0; for(int i = 0; i < fileSplit.length; i++){ if(fileSplit[i].contains(v)){ used++; } } if(used < 2){ unused.add(v); } } return unused; } public static String removeUnusedVarsInMethod(String code, ArrayList unused){ String[] fileSplit = code.split("\n"); String newCode = ""; for(int i = 0; i < fileSplit.length; i++){ boolean remove = false; for(String v : unused){ if(fileSplit[i].contains(v)){ remove = true; } } if(!remove){ newCode += fileSplit[i] + "\n"; } } return newCode; } public static String extractRetVal(String line, String name){ String[] fileSplit = line.split(" "); for(int i = 0; i < fileSplit.length; i++){ if(fileSplit[i].contains(name)){ return fileSplit[i-1]; } } return ""; } public static int jumpToCloseBracket(String code, int index){ String[] fileSplit = code.split("\n"); int counter = 0; int brack_counter = 0; for(int i = index; i < fileSplit.length; i++){ if(fileSplit[i].contains("}") && !fileSplit[i].contains("{")){ if(brack_counter == 0){ return index + counter; }else{ brack_counter--; } }else if(fileSplit[i].contains("{") && !fileSplit[i].contains("}")){ brack_counter++; } counter++; } return -1; } //index of the closest return statement public static int jumpToReturn(String code, int index){ String[] fileSplit = code.split("\n"); int counter = 0; for(int i = index; i < fileSplit.length; i++){ if(fileSplit[i].contains("return")){ return index + counter; }else{ counter++; } } return -1; } //what index is the former bracket '{' for our block public static int jumpToUpperBlockBracket(String code, int index){ String[] fileSplit = code.split("\n"); int block_counter = 0; int counter = 0; for(int i = index; i >= 0; i--){ if(fileSplit[i].contains("{")){ if(block_counter == 0){ return index - counter; }else{ block_counter--; } }else if(fileSplit[i].contains("{")){ block_counter++; }else{ counter++; } } return -1; } public static String getVarName(String code){ String[] fileSplit = code.split("="); String[] varSplit = fileSplit[0].split(" "); if(varSplit.length == 1) return varSplit[0].trim(); return varSplit[1].trim(); } public static String getBeforeEqual(String code){ String[] fileSplit = code.split("="); return fileSplit[0]; } public static String removeDirectPointer(String line){ String temp = line.trim(); if(line.contains("=")){ String[] lineSplit = line.split("="); temp = lineSplit[1].trim(); } boolean started = false; int counter = 0; char[] inChar = temp.toCharArray(); int len = 0; for(int i = 0; i < inChar.length; i++){ if(inChar[i] == '('){ started = true; counter++; }else if(inChar[i] == ')'){ counter--; }else if(started && counter == 0){ if(inChar[i] == ';'){ return ""; } len = i; break; } } String temp2 = temp.substring(0,len+1); line = line.replace(temp2,""); return line; } }