new import suggestions

This commit is contained in:
Manindra Moharana
2014-11-15 16:33:06 -07:00
parent f2a10310e9
commit 4ee4e59268
4 changed files with 253 additions and 9 deletions

View File

@@ -980,18 +980,18 @@ public class ASTGenerator {
String[] resources = classPath.findResources("",
regExpResourceFilter);
for (String matchedClass2 : resources) {
matchedClass2 = matchedClass2.replace('/', '.');
matchedClass2 = matchedClass2.replace('/', '.'); //package name
String matchedClass = matchedClass2.substring(0, matchedClass2
.length() - 6);
int d = matchedClass.lastIndexOf('.');
if (ignorableImport(matchedClass2,matchedClass.substring(d + 1)))
continue;
matchedClass = matchedClass.substring(d + 1);
candidates
.add(new CompletionCandidate(matchedClass, matchedClass
+ " : " + matchedClass2.substring(0, d), matchedClass,
CompletionCandidate.PREDEF_CLASS));
matchedClass = matchedClass.substring(d + 1); //class name
candidates.add(new CompletionCandidate(matchedClass, "<html>"
+ matchedClass + " : " + "<font color=#777777>"
+ matchedClass2.substring(0, d) + "</font>", matchedClass
+ "</html>", CompletionCandidate.PREDEF_CLASS)); // display package name in grey
//log("-> " + className);
}
}
@@ -3307,6 +3307,68 @@ public class ASTGenerator {
}
return null;
}
public String[] getSuggestImports(final String className){
if(ignoredImportSuggestions == null) {
ignoredImportSuggestions = new TreeSet<String>();
} else {
if(ignoredImportSuggestions.contains(className)) {
log("Ignoring import suggestions for " + className);
return null;
}
}
log("Looking for class " + className);
RegExpResourceFilter regf = new RegExpResourceFilter(
Pattern.compile(".*"),
Pattern
.compile(className
+ ".class",
Pattern.CASE_INSENSITIVE));
String[] resources = classPath
.findResources("", regf);
ArrayList<String> candidates = new ArrayList<String>();
for (String res : resources) {
candidates.add(res);
}
// log("Couldn't find import for class " + className);
for (Library lib : editor.dmode.contribLibraries) {
ClassPath cp = factory.createFromPath(lib.getClassPath());
resources = cp.findResources("", regf);
for (String res : resources) {
candidates.add(res);
log("Res: " + res);
}
}
if (editor.getSketch().hasCodeFolder()) {
File codeFolder = editor.getSketch().getCodeFolder();
// get a list of .jar files in the "code" folder
// (class files in subfolders should also be picked up)
ClassPath cp = factory.createFromPath(Base
.contentsToClassPath(codeFolder));
resources = cp.findResources("", regf);
for (String res : resources) {
candidates.add(res);
log("Res: " + res);
}
}
resources = new String[candidates.size()];
for (int i = 0; i < resources.length; i++) {
resources[i] = candidates.get(i).replace('/', '.')
.substring(0, candidates.get(i).length() - 6);
}
// ArrayList<String> ans = new ArrayList<String>();
// for (int i = 0; i < resources.length; i++) {
// ans.add(resources[i]);
// }
return resources;
}
protected JFrame frmImportSuggest;
private TreeSet<String> ignoredImportSuggestions;

View File

@@ -404,7 +404,7 @@ public class ErrorCheckerService implements Runnable{
if (args.length > 0) {
String missingClass = args[0];
log("Will suggest for type:" + missingClass);
astGenerator.suggestImports(missingClass);
//astGenerator.suggestImports(missingClass);
}
}
}
@@ -1006,6 +1006,30 @@ public class ErrorCheckerService implements Runnable{
if (tempErrorLog.size() < 200)
tempErrorLog.put(problemsList.get(i).getMessage(), problemsList
.get(i).getIProblem());
if(!ExperimentalMode.importSuggestEnabled) continue;
Problem p = problemsList.get(i);
if(p.getIProblem().getID() == IProblem.UndefinedType) {
String args[] = p.getIProblem().getArguments();
if (args.length > 0) {
String missingClass = args[0];
// log("Will suggest for type:" + missingClass);
//astGenerator.suggestImports(missingClass);
String[] si = astGenerator.getSuggestImports(missingClass);
if(si != null && si.length > 0){
// log("Suggested imps");
// for (int j = 0; j < si.length; j++) {
// log(si[j]);
// }
p.setImportSuggestions(si);
errorData[i][0] = "<html>"
+ problemsList.get(i).getMessage()
+ " (<font color=#0000ff><u>Import Suggestions available</u></font>)</html>";
}
}
}
}
DefaultTableModel tm = new DefaultTableModel(errorData,

View File

@@ -22,6 +22,7 @@
package processing.mode.experimental;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -63,6 +64,11 @@ public class Problem {
* The type of error - WARNING or ERROR.
*/
private int type;
/**
* If the error is a 'cannot find type' contains the list of suggested imports
*/
private String[] importSuggestions;
public static final int ERROR = 1, WARNING = 2;
@@ -147,6 +153,14 @@ public class Problem {
type = WARNING;
else throw new IllegalArgumentException("Illegal Problem type passed to Problem.setType(int)");
}
public String[] getImportSuggestions() {
return importSuggestions;
}
public void setImportSuggestions(String[] a) {
importSuggestions = a;
}
private static Pattern pattern;
private static Matcher matcher;

View File

@@ -22,15 +22,31 @@ package processing.mode.experimental;
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
import javax.swing.ToolTipManager;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableModel;
import javax.swing.text.BadLocationException;
import processing.app.Language;
import static processing.mode.experimental.ExperimentalMode.log;
/**
* Custom JTable implementation for XQMode. Minor tweaks and addtions.
@@ -76,7 +92,7 @@ public class XQErrorTable extends JTable {
this.addMouseListener(new MouseAdapter() {
@Override
synchronized public void mouseReleased(MouseEvent e) {
synchronized public void mouseClicked(MouseEvent e) {
try {
errorCheckerService.scrollToErrorLine(((XQErrorTable) e
.getSource()).getSelectedRow());
@@ -87,7 +103,60 @@ public class XQErrorTable extends JTable {
+ e);
}
}
// public void mouseMoved(MouseEvent evt) {
// log(evt);
//// String tip = null;
//// java.awt.Point p = evt.getPoint();
// int rowIndex = rowAtPoint(evt.getPoint());
// int colIndex = columnAtPoint(evt.getPoint());
// synchronized (errorCheckerService.problemsList) {
// if (rowIndex < errorCheckerService.problemsList.size()) {
// Problem p = errorCheckerService.problemsList.get(rowIndex);
// if (p.getImportSuggestions() != null
// && p.getImportSuggestions().length > 0) {
// log("Import Suggestions available");
// }
// }
// }
//// return super.getToolTipText(evt);
// }
});
final XQErrorTable thisTable = this;
this.addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseMoved(MouseEvent evt) {
// log(evt);
// String tip = null;
// java.awt.Point p = evt.getPoint();
int rowIndex = rowAtPoint(evt.getPoint());
int colIndex = columnAtPoint(evt.getPoint());
synchronized (errorCheckerService.problemsList) {
if (rowIndex < errorCheckerService.problemsList.size()) {
Problem p = errorCheckerService.problemsList.get(rowIndex);
if (p.getImportSuggestions() != null
&& p.getImportSuggestions().length > 0) {
String[] list = p.getImportSuggestions();
String className = list[0].substring(list[0].lastIndexOf('.') + 1);
String[] temp = new String[list.length];
for (int i = 0; i < list.length; i++) {
temp[i] = "<html>Import '" + className + "' <font color=#777777>(" + list[i] + ")</font></html>";
}
showImportSuggestion(temp, evt.getXOnScreen(), evt.getYOnScreen() - 3 * thisTable.getFont().getSize());
}
}
}
}
@Override
public void mouseDragged(MouseEvent e) {
}
});
// Handles the resizing of columns. When mouse press is detected on
// table header, Stop updating the table, store new values of column
@@ -111,8 +180,9 @@ public class XQErrorTable extends JTable {
}
}
});
ToolTipManager.sharedInstance().registerComponent(this);
}
/**
* Updates table contents with new data
@@ -163,5 +233,79 @@ public class XQErrorTable extends JTable {
}
return true;
}
JFrame frmImportSuggest;
private void showImportSuggestion(String list[], int x, int y){
if(frmImportSuggest != null) {
// frmImportSuggest.setVisible(false);
// frmImportSuggest = null;
return;
}
final JList<String> classList = new JList<String>(list);
classList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
frmImportSuggest = new JFrame();
frmImportSuggest.setUndecorated(true);
frmImportSuggest.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBackground(Color.WHITE);
frmImportSuggest.setBackground(Color.WHITE);
panel.add(classList);
JLabel label = new JLabel("<html><div ><font size = \"2\"><br>(Click to insert)</font></div></html>");
label.setBackground(Color.WHITE);
label.setHorizontalTextPosition(SwingConstants.CENTER);
panel.add(label);
panel.validate();
frmImportSuggest.getContentPane().add(panel);
frmImportSuggest.pack();
final DebugEditor editor = errorCheckerService.getEditor();
classList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if (classList.getSelectedValue() != null) {
try {
String t = classList.getSelectedValue().trim();
log(t);
int x = t.indexOf('(');
String impString = "import " + t.substring(x + 1, t.indexOf(')')) + ";\n";
int ct = editor.getSketch().getCurrentCodeIndex();
editor.getSketch().setCurrentCode(0);
editor.textArea().getDocument().insertString(0, impString, null);
editor.getSketch().setCurrentCode(ct);
} catch (BadLocationException ble) {
log("Failed to insert import");
ble.printStackTrace();
}
}
frmImportSuggest.setVisible(false);
frmImportSuggest.dispose();
frmImportSuggest = null;
}
});
frmImportSuggest.addWindowFocusListener(new WindowFocusListener() {
@Override
public void windowLostFocus(WindowEvent e) {
if (frmImportSuggest != null) {
frmImportSuggest.dispose();
frmImportSuggest = null;
}
}
@Override
public void windowGainedFocus(WindowEvent e) {
}
});
frmImportSuggest.setLocation(x, y);
frmImportSuggest.setBounds(x, y, 250, 100);
frmImportSuggest.pack();
frmImportSuggest.setVisible(true);
}
}