From 8a2a64bf6c363dbe6769468e624731cada122d0c Mon Sep 17 00:00:00 2001 From: Manindra Moharana Date: Sat, 20 Jul 2013 00:45:06 +0530 Subject: [PATCH] completion caching for efficiency --- pdex/Todo, GSoC 2013.txt | 3 + .../mode/experimental/ASTGenerator.java | 113 ++++++++++++------ .../experimental/CompletionCandidate.java | 6 +- .../mode/experimental/TextArea.java | 4 +- 4 files changed, 83 insertions(+), 43 deletions(-) diff --git a/pdex/Todo, GSoC 2013.txt b/pdex/Todo, GSoC 2013.txt index dc1461ecd..aff776f5e 100644 --- a/pdex/Todo, GSoC 2013.txt +++ b/pdex/Todo, GSoC 2013.txt @@ -25,6 +25,8 @@ x! Library CC for nested would be tricky. Need to jump from local->compiled code x! Should I implement wrapper for ASTNode? - possibly needed for code completion with compiled and non-compiled code. Done. * Trie implementation would be lower priority, "premature optimisation is pure evil". Get all features of CC working good enough and then plan this. x Differentiating between multiple statements on the same line. How to? Done with offset handling. +x - Cache predictions if current 'word' is increasing in length. If already showing predictions beginning with 's', for 'sa', remove extra completions, rather than recalculating predictions. Performance increase. +* - Disable completions on comment line * - Add a static debug field, disable debugging info on console. * - update build.xml to produce dists * - Make this a contributed mode - mode.txt, github releases feature, version numbering, git tags, etc @@ -42,6 +44,7 @@ x Cursor positioning should be after the first ( if arguments present, else afte x Display the type of Completion(method return type, variable type) in the popup. - facing some issues for local types. Fixed. x Sorted list of completion candidates - fields, then methods. It's unsorted presently. +* - Show declaring class for completions *! p5 enhanced stuff in java, how does it fit in with everything else, and edge cases. Possibly add support for them. Offset handling improvements should help here. * - Diamond operator isn't supported for now. Bummer. x Reflection API - getMethods vs getDeclaredMethods. declared. diff --git a/pdex/src/processing/mode/experimental/ASTGenerator.java b/pdex/src/processing/mode/experimental/ASTGenerator.java index 90de29374..b271bf074 100644 --- a/pdex/src/processing/mode/experimental/ASTGenerator.java +++ b/pdex/src/processing/mode/experimental/ASTGenerator.java @@ -720,23 +720,41 @@ public class ASTGenerator { public static ASTNode getParentExpression(ASTNode expression) { // ASTNode anode = null; - if (expression instanceof SimpleName) { - return expression; - } else if (expression instanceof FieldAccess) { - return ((FieldAccess) expression).getExpression(); - } else if (expression instanceof QualifiedName) { - return ((QualifiedName) expression).getQualifier(); - } else if (expression instanceof MethodInvocation) { - return ((MethodInvocation) expression).getExpression(); - }else if(expression instanceof ArrayAccess){ - return ((ArrayAccess)expression).getArray(); + if (expression instanceof SimpleName) { + return expression; + } else if (expression instanceof FieldAccess) { + return ((FieldAccess) expression).getExpression(); + } else if (expression instanceof QualifiedName) { + return ((QualifiedName) expression).getQualifier(); + } else if (expression instanceof MethodInvocation) { + return ((MethodInvocation) expression).getExpression(); + } else if (expression instanceof ArrayAccess) { + return ((ArrayAccess) expression).getArray(); + } + System.out.println("getParentExpression returning NULL for " + + getNodeAsString(expression)); + return null; } - System.out.println("getParentExpression returning NULL for " - + getNodeAsString(expression)); - return null; -} - public void updatePredictions(final String word, final int line, final int lineStartNonWSOffset) { + private void trimCandidates(String newWord){ + ArrayList newCandidate = new ArrayList(); + newWord = newWord.toLowerCase(); + for (CompletionCandidate comp : candidates) { + if(comp.toString().toLowerCase().startsWith(newWord)){ + System.out.println("Adding " + comp); + newCandidate.add(comp); + } + } + candidates = newCandidate; + } + + /** + * List of CompletionCandidates + */ + private ArrayList candidates; + private String lastPredictedWord = " "; + + public void preparePredictions(final String word, final int line, final int lineStartNonWSOffset) { SwingWorker worker = new SwingWorker() { @Override @@ -756,6 +774,23 @@ public class ASTGenerator { noCompare = true; } + if (word2.length() > 2 && !noCompare + && word2.length() > lastPredictedWord.length()) { + if (word2.startsWith(lastPredictedWord)) { + System.out.println(word + " starts with " + lastPredictedWord); + System.out.println("Don't recalc"); + if (word2.contains(".")) { + int x = word2.lastIndexOf('.'); + trimCandidates(word2.substring(x + 1)); + } else { + trimCandidates(word2); + } + updatePredictions(word); + lastPredictedWord = word2; + return; + } + } + int lineNumber = line; // Adjust line number for tabbed sketches if (errorCheckerService != null) { @@ -788,8 +823,8 @@ public class ASTGenerator { System.err.println(lineNumber + " Nearest ASTNode to PRED " + getNodeAsString(nearestNode)); - ArrayList candidates = new ArrayList(); - + candidates = new ArrayList(); + lastPredictedWord = word2; // Determine the expression typed if (testnode instanceof SimpleName && !noCompare) { @@ -1019,35 +1054,35 @@ public class ASTGenerator { }*/ } + updatePredictions(word); - - Collections.sort(candidates); - CompletionCandidate[][] candi = new CompletionCandidate[candidates - .size()][1]; - - DefaultListModel defListModel = new DefaultListModel(); - - for (int i = 0; i < candi.length; i++) { - candi[i][0] = candidates.get(i); - defListModel.addElement(candidates.get(i)); - } - System.out.println("K = " + candidates.size()); - DefaultTableModel tm = new DefaultTableModel( - candi, - new String[] { "Suggestions" }); - if(tableAuto.isVisible()){ - tableAuto.setModel(tm); - tableAuto.validate(); - tableAuto.repaint(); - } - errorCheckerService.getEditor().textArea() - .showSuggestion(defListModel,word); } }; worker.execute(); } + + private void updatePredictions(final String word) { + Collections.sort(candidates); + CompletionCandidate[][] candi = new CompletionCandidate[candidates.size()][1]; + DefaultListModel defListModel = new DefaultListModel(); + + for (int i = 0; i < candi.length; i++) { + candi[i][0] = candidates.get(i); + defListModel.addElement(candidates.get(i)); + } + System.out.println("Total preds = " + candidates.size()); + DefaultTableModel tm = new DefaultTableModel(candi, + new String[] { "Suggestions" }); + if (tableAuto.isVisible()) { + tableAuto.setModel(tm); + tableAuto.validate(); + tableAuto.repaint(); + } + errorCheckerService.getEditor().textArea() + .showSuggestion(defListModel, word); + } /** * Loads classes from .jar files in sketch classpath diff --git a/pdex/src/processing/mode/experimental/CompletionCandidate.java b/pdex/src/processing/mode/experimental/CompletionCandidate.java index f6bf99633..b8c69aa3c 100644 --- a/pdex/src/processing/mode/experimental/CompletionCandidate.java +++ b/pdex/src/processing/mode/experimental/CompletionCandidate.java @@ -41,7 +41,8 @@ public class CompletionCandidate implements Comparable{ cstr.append(' '); } label.append(")"); - label.append(" : "+method.getReturnType().getSimpleName()); + label.append(" : " + method.getReturnType().getSimpleName() + " - " + + method.getDeclaringClass().getSimpleName()); cstr.append(")"); this.label = label.toString(); this.completionString = cstr.toString(); @@ -98,7 +99,8 @@ public class CompletionCandidate implements Comparable{ f.getDeclaringClass().getName(); elementName = f.getName(); type = PREDEF_FIELD; - label = f.getName() + " : " + f.getType().getSimpleName(); + label = f.getName() + " : " + f.getType().getSimpleName() + + f.getDeclaringClass().getSimpleName(); completionString = elementName; } diff --git a/pdex/src/processing/mode/experimental/TextArea.java b/pdex/src/processing/mode/experimental/TextArea.java index 58ebf5311..bbacebc1d 100644 --- a/pdex/src/processing/mode/experimental/TextArea.java +++ b/pdex/src/processing/mode/experimental/TextArea.java @@ -289,7 +289,7 @@ public class TextArea extends JEditTextArea { word = word.trim(); if (word.endsWith(".")) word = word.substring(0, word.length() - 1); - errorCheckerService.astGenerator.updatePredictions(word, line + errorCheckerService.astGenerator.preparePredictions(word, line + errorCheckerService.mainClassOffset,0); return word; } @@ -367,7 +367,7 @@ public class TextArea extends JEditTextArea { // if (word.endsWith(".")) // word = word.substring(0, word.length() - 1); int lineStartNonWSOffset = 0; - errorCheckerService.astGenerator.updatePredictions(word, line + errorCheckerService.astGenerator.preparePredictions(word, line + errorCheckerService.mainClassOffset,lineStartNonWSOffset); //showSuggestionLater(); return word;