From 6f471781b8facfb74b935e58b88d0b072d6c2179 Mon Sep 17 00:00:00 2001 From: Manindra Moharana Date: Mon, 24 Jun 2013 14:26:13 +0530 Subject: [PATCH] Starting work on refactoring. --- pdex/Todo, GSoC 2013.txt | 7 +- .../mode/experimental/ASTGenerator.java | 189 +++++++++++++++--- 2 files changed, 170 insertions(+), 26 deletions(-) diff --git a/pdex/Todo, GSoC 2013.txt b/pdex/Todo, GSoC 2013.txt index 4acc4988d..889dfb842 100644 --- a/pdex/Todo, GSoC 2013.txt +++ b/pdex/Todo, GSoC 2013.txt @@ -39,9 +39,10 @@ x PDE specific enhancements will also have to be tackled like int(), # literals. * The above is almost working. There are some offset issues when multiple pde statements are in the same line, but I guess it's good enough for now to proceed ahead. Will keep a close watch for potential bugs. Refactoring would work only when code is compiler error free. I plan to do a find replace type op on the compile ready code. -1. First identify the declaration of the variable in the AST. -2. Now for each instance of the word in code inside the declaration scope(i.e further down the child nodes in the AST), find if the matched word is the same one whose declaration I know of. -3. If it is so, replace it with the new name. +1. First identify the declaration of the variable in the AST. We'll then make a list of all its occurrences. +2. DFS through the AST, for each (SimpleName)instance of the word in code, find if the matched word is the same one whose declaration we found. +x Edge Case: For renaming a TypeDeclaration, the declaration of SimpleName instance of the TD and it's constructor(s) aren't added to the list generated by DFS. So for renaming TD, will have to manually add the TD SimpleName and it's constructors' SimpleNames to the a list of declaration nodes that can be positively matched against. +3. Find corresponding PDE offsets of the SimpleNames, rename in each line taking displaced offsets into consideration. 4. All the changes in code would be made in a separate copy of the code(?). After all the renaming is done, allow it only if the new code compiles. Basically an undo should be possible in case of conflicts. Quick Navigation diff --git a/pdex/src/processing/mode/experimental/ASTGenerator.java b/pdex/src/processing/mode/experimental/ASTGenerator.java index dc62b8e42..a8d3f0818 100644 --- a/pdex/src/processing/mode/experimental/ASTGenerator.java +++ b/pdex/src/processing/mode/experimental/ASTGenerator.java @@ -1,6 +1,10 @@ package processing.mode.experimental; +import java.awt.Dimension; +import java.awt.FlowLayout; import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.BufferedReader; @@ -18,8 +22,10 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Stack; import java.util.TreeMap; +import javax.swing.JButton; import javax.swing.JEditorPane; import javax.swing.JFrame; import javax.swing.JScrollPane; @@ -67,6 +73,7 @@ import com.google.classpath.ClassPath; import com.google.classpath.ClassPathFactory; import com.google.classpath.RegExpResourceFilter; import com.ibm.icu.util.StringTokenizer; +import com.sun.org.apache.bcel.internal.generic.GETSTATIC; public class ASTGenerator { @@ -89,6 +96,11 @@ public class ASTGenerator { * Swing component wrapper for AST, used for internal testing */ private JTree jtree; + + /** + * JTree used for testing refactoring operations + */ + private JTree renameTree; private CompilationUnit compilationUnit; @@ -98,6 +110,8 @@ public class ASTGenerator { private JScrollPane scrollPane; + private JButton renameButton; + public ASTGenerator(ErrorCheckerService ecs) { this.errorCheckerService = ecs; this.editor = ecs.getEditor(); @@ -105,34 +119,50 @@ public class ASTGenerator { jtree = new JTree(); frame2.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - frame2.setBounds(new Rectangle(100, 100, 460, 620)); + frame2.setBounds(new Rectangle(680, 100, 460, 620)); JScrollPane sp = new JScrollPane(); sp.setViewportView(jtree); frame2.add(sp); - frameAutoComp = new JFrame(); - frameAutoComp.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - frameAutoComp.setBounds(new Rectangle(1280, 100, 460, 620)); - tableAuto = new JTable(); + renameButton = new JButton("Rename"); + JFrame frame3 = new JFrame(); + frame3.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame3.setBounds(new Rectangle(680, 50, 100, 50)); + frame3.add(renameButton); + frame3.setVisible(true); + + JFrame frame4 = new JFrame(); + frame4.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame4.setBounds(new Rectangle(1100, 50, 350, 500)); JScrollPane sp2 = new JScrollPane(); - sp2.setViewportView(tableAuto); - frameAutoComp.add(sp2); + renameTree = new JTree(); + sp2.setViewportView(renameTree); + frame4.add(sp2); + frame4.setVisible(true); + +// frameAutoComp = new JFrame(); +// frameAutoComp.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); +// frameAutoComp.setBounds(new Rectangle(1280, 100, 460, 620)); +// tableAuto = new JTable(); +// JScrollPane sp2 = new JScrollPane(); +// sp2.setViewportView(tableAuto); +// frameAutoComp.add(sp2); - jdocWindow = new JFrame(); - jdocWindow.setTitle("P5 InstaHelp"); - //jdocWindow.setUndecorated(true); - jdocWindow.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); - javadocPane = new JEditorPane(); - javadocPane.setContentType("text/html"); - javadocPane.setEditable(false); - scrollPane = new JScrollPane(); - scrollPane.setViewportView(javadocPane); - jdocWindow.add(scrollPane); - jdocMap = new TreeMap(); - //loadJars(); +// jdocWindow = new JFrame(); +// jdocWindow.setTitle("P5 InstaHelp"); +// //jdocWindow.setUndecorated(true); +// jdocWindow.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); +// javadocPane = new JEditorPane(); +// javadocPane.setContentType("text/html"); +// javadocPane.setEditable(false); +// scrollPane = new JScrollPane(); +// scrollPane.setViewportView(javadocPane); +// jdocWindow.add(scrollPane); +// jdocMap = new TreeMap(); +//// loadJars(); //addCompletionPopupListner(); - addTreeListner(); + addListners(); } private DefaultMutableTreeNode buildAST(String source, CompilationUnit cu) { @@ -992,7 +1022,8 @@ public class ASTGenerator { public ASTNodeWrapper getASTNodeAt(int lineNumber, String name, int offset, boolean scrollOnly) { - System.out.println("--------"); + + System.out.println("----getASTNodeAt----"); if (errorCheckerService != null) { editor = errorCheckerService.getEditor(); int codeIndex = editor.getSketch().getCodeIndex(editor.getCurrentTab()); @@ -1094,7 +1125,7 @@ public class ASTGenerator { errorCheckerService.highlightNode(simpName2); } - return null; + return new ASTNodeWrapper(decl); } /** @@ -1193,7 +1224,7 @@ public class ASTGenerator { } } - private void addTreeListner(){ + private void addListners(){ jtree.addTreeSelectionListener(new TreeSelectionListener() { @Override @@ -1226,6 +1257,83 @@ public class ASTGenerator { worker.execute(); } }); + + renameButton.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + SwingWorker worker = new SwingWorker() { + + @Override + protected Object doInBackground() throws Exception { + return null; + } + + protected void done() { + if (editor.ta.getSelectedText() == null) + return; + String selText = editor.ta.getSelectedText(); + int line = editor.ta.getSelectionStartLine(); + System.out.println(editor.ta.getSelectedText() + + "<- offsets " + + (line) + + ", " + + (editor.ta.getSelectionStart() - editor.ta + .getLineStartOffset(line)) + + ", " + + (editor.ta.getSelectionStop() - editor.ta + .getLineStartOffset(line))); + ASTNodeWrapper wnode = getASTNodeAt(line + + errorCheckerService.mainClassOffset, + selText, + editor.ta.getSelectionStart() + - editor.ta + .getLineStartOffset(line), + false); + + DefaultMutableTreeNode defCU = new DefaultMutableTreeNode(wnode); + visitRecurNameOnly(defCU, wnode.getNode(), selText); + System.out.println(wnode); + renameTree.setModel(new DefaultTreeModel(defCU)); + ((DefaultTreeModel) renameTree.getModel()).reload(); + } + }; + worker.execute(); + } + }); + + renameTree.addTreeSelectionListener(new TreeSelectionListener() { + + @Override + public void valueChanged(TreeSelectionEvent e) { + System.out.println(e); + SwingWorker worker = new SwingWorker() { + + @Override + protected Object doInBackground() throws Exception { + return null; + } + + protected void done() { + if(renameTree + .getLastSelectedPathComponent() == null){ + return; + } + DefaultMutableTreeNode tnode = (DefaultMutableTreeNode) renameTree + .getLastSelectedPathComponent(); + if(tnode.getUserObject() == null){ + return; + } + + if (tnode.getUserObject() instanceof ASTNodeWrapper) { + ASTNodeWrapper awrap = (ASTNodeWrapper) tnode.getUserObject(); + errorCheckerService.highlightNode(awrap); + } + } + }; + worker.execute(); + } + }); } @SuppressWarnings({ "unchecked" }) @@ -1277,6 +1385,41 @@ public class ASTGenerator { } } } + + public void visitRecurNameOnly(DefaultMutableTreeNode tnode,ASTNode decl, String name) { + Stack temp = new Stack(); + temp.push(codeTree); + + while(!temp.isEmpty()){ + DefaultMutableTreeNode cnode = (DefaultMutableTreeNode) temp.pop(); + for (int i = 0; i < cnode.getChildCount(); i++) { + temp.push(cnode.getChildAt(i)); + } + + if(!(cnode.getUserObject() instanceof ASTNodeWrapper)) + continue; + ASTNodeWrapper awnode = (ASTNodeWrapper) cnode.getUserObject(); +// System.out.println("Visiting: " + getNodeAsString(awnode.getNode())); + if(isInstanceOfType(awnode.getNode(), decl, name)){ + tnode.add(new DefaultMutableTreeNode(awnode)); + } + + } + } + + private boolean isInstanceOfType(ASTNode node,ASTNode decl, String name){ + if(node instanceof SimpleName){ + SimpleName sn = (SimpleName) node; + System.out.println("Visiting: " + getNodeAsString(node)); + if (sn.toString().equals(name)) { + if (findDeclaration(sn).equals(decl)) + return true; + } + } + return false; + } + + public static void printRecur(ASTNode node) { Iterator it = node