From 10755992a4a387906cbb239a5d941fed33ab2c26 Mon Sep 17 00:00:00 2001 From: Manindra Moharana Date: Sun, 14 Jul 2013 21:37:06 +0530 Subject: [PATCH] added import suggestion --- pdex/Todo, GSoC 2013.txt | 5 ++ .../mode/experimental/ASTGenerator.java | 73 +++++++++++++++++++ .../experimental/ErrorCheckerService.java | 17 ++++- 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/pdex/Todo, GSoC 2013.txt b/pdex/Todo, GSoC 2013.txt index 2159156ae..6b8bb497a 100644 --- a/pdex/Todo, GSoC 2013.txt +++ b/pdex/Todo, GSoC 2013.txt @@ -85,3 +85,8 @@ x Now highlihgting the declaration name, rather than the whole declaration. * On OS X, Ctrl + Click is right mouse click, so implement Cmd + Click instead. isMetaDown()? *+ A silly bug where the name of the first field declaration isn't highlighted correctly. Seems to be happening if there's a javadoc or multiline comment near about the top. +Suggestion for missing imports +============================== +1. In compileCheck() in ECS, check if error message is of the type "__" cannot be resolved to a type. +2. Find the class name via astGen, and suggest import as a popup. + diff --git a/pdex/src/processing/mode/experimental/ASTGenerator.java b/pdex/src/processing/mode/experimental/ASTGenerator.java index 76aa69879..b0d0af25f 100644 --- a/pdex/src/processing/mode/experimental/ASTGenerator.java +++ b/pdex/src/processing/mode/experimental/ASTGenerator.java @@ -34,17 +34,20 @@ import javax.swing.JButton; import javax.swing.JEditorPane; import javax.swing.JFrame; import javax.swing.JLabel; +import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.JTree; +import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import javax.swing.UIManager; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.table.DefaultTableModel; +import javax.swing.text.BadLocationException; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; @@ -2751,6 +2754,76 @@ public class ASTGenerator { } return null; } + JFrame frmImportSuggest; + public void suggestImports(final String className){ + if(frmImportSuggest != null) + return; + System.out.println("Looking for class " + className); + RegExpResourceFilter regf = new RegExpResourceFilter( + Pattern.compile(".*"), + Pattern + .compile(className + + ".class", + Pattern.CASE_INSENSITIVE)); + String[] resources = classPath + .findResources("", regf); + if(resources.length == 0){ + System.out.println("Couldn't find import for class " + className); + return; + } + for (int i = 0; i < resources.length; i++) { + resources[i] = resources[i].replace('/', '.') + .substring(0, resources[i].length() - 6); + } + if(resources.length == 1){ + System.out.println("Found import: " + resources[0]); + String impS = resources[0].substring(0, resources[0] + .length() - 6); + String impString = "import " + impS.replace('/','.') + ";\n"; + try { + editor.textArea().getDocument().insertString(0, impString, null); + } catch (BadLocationException e) { + System.out.println("Failed to insert import for " + className); + e.printStackTrace(); + } + } + else if(resources.length > 1){ + final JList classList = new JList(resources); + classList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + frmImportSuggest = new JFrame(); + frmImportSuggest.setBounds(300, 300, 400, 300); + frmImportSuggest.setLayout(new BoxLayout(frmImportSuggest.getContentPane(), BoxLayout.Y_AXIS)); + JLabel lbl = new JLabel( + "The class \"" + + className + + "\" couldn't be found.
Choose the import you want."); + JScrollPane jsp = new JScrollPane(); + jsp.setViewportView(classList); + JButton btnInsertImport = new JButton("Insert import"); + btnInsertImport.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if(classList.getSelectedValue() != null){ + try { + String impString = "import " + classList.getSelectedValue() + ";\n"; + editor.textArea().getDocument().insertString(0, impString, null); + frmImportSuggest.setVisible(false); + frmImportSuggest = null; + } catch (BadLocationException e) { + System.out.println("Failed to insert import for " + className); + e.printStackTrace(); + } + } + } + }); + + frmImportSuggest.add(lbl); + frmImportSuggest.add(jsp); + frmImportSuggest.add(btnInsertImport); + frmImportSuggest.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frmImportSuggest.setVisible(true); + } + + } public static boolean isAddableASTNode(ASTNode node) { switch (node.getNodeType()) { diff --git a/pdex/src/processing/mode/experimental/ErrorCheckerService.java b/pdex/src/processing/mode/experimental/ErrorCheckerService.java index b1b04576f..3c082d1ca 100644 --- a/pdex/src/processing/mode/experimental/ErrorCheckerService.java +++ b/pdex/src/processing/mode/experimental/ErrorCheckerService.java @@ -250,16 +250,31 @@ public class ErrorCheckerService implements Runnable{ updatePaintedThingys(); updateEditorStatus(); + if (pauseThread) continue; if(textModified.get() == 0) continue; // Check every x seconds checkCode(); - + checkForMissingImports(); } } + private void checkForMissingImports() { + for (Problem p : problemsList) { + if(p.getMessage().endsWith(" cannot be resolved to a type"));{ + int idx = p.getMessage().indexOf(" cannot be resolved to a type"); + if(idx > 1){ + String missingClass = p.getMessage().substring(0, idx); + System.out.println("Will suggest for type:" + missingClass); + astGenerator.suggestImports(missingClass); + runManualErrorCheck(); + } + } + } + } + protected ASTGenerator astGenerator; private AtomicInteger textModified = new AtomicInteger();