mirror of
https://github.com/processing/processing4.git
synced 2026-02-04 06:09:17 +01:00
new import suggestions
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user