From 6f0195534f97934648c3bdb707956730c6abccc8 Mon Sep 17 00:00:00 2001 From: Manindra Moharana Date: Sun, 2 Feb 2014 00:36:33 +0530 Subject: [PATCH] beginning work on race condition bug --- .../mode/experimental/ASTGenerator.java | 16 ++- .../mode/experimental/CompletionPanel.java | 121 +++++++++++++++++- .../mode/experimental/TextArea.java | 5 +- 3 files changed, 136 insertions(+), 6 deletions(-) diff --git a/pdex/src/processing/mode/experimental/ASTGenerator.java b/pdex/src/processing/mode/experimental/ASTGenerator.java index 03343de33..4d7602eaa 100644 --- a/pdex/src/processing/mode/experimental/ASTGenerator.java +++ b/pdex/src/processing/mode/experimental/ASTGenerator.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.Map; import java.util.Stack; import java.util.TreeMap; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Pattern; import javax.swing.BorderFactory; @@ -150,6 +151,7 @@ public class ASTGenerator { //addCompletionPopupListner(); addListeners(); //loadJavaDoc(); + predictionOngoing = new AtomicBoolean(false); } protected void setupGUI(){ @@ -784,15 +786,24 @@ public class ASTGenerator { //protected AtomicBoolean predictionsEnabled; protected int predictionMinLength = 2; + + private AtomicBoolean predictionOngoing; + public void preparePredictions(final String word, final int line, final int lineStartNonWSOffset) { + if(predictionOngoing.get()) return; + if(!ExperimentalMode.codeCompletionsEnabled) return; - if(word.length() < predictionMinLength) return; + if(word.length() < predictionMinLength) return; + + predictionOngoing.set(true); // This method is called from TextArea.fetchPhrase, which is called via a SwingWorker instance // in TextArea.processKeyEvent if(caretWithinLineComment()){ log("No predictions."); + predictionOngoing.set(false); return; } + // SwingWorker worker = new SwingWorker() { // // @Override @@ -826,6 +837,7 @@ public class ASTGenerator { } showPredictions(word); lastPredictedWord = word2; + predictionOngoing.set(false); return; } } @@ -1006,7 +1018,7 @@ public class ASTGenerator { } showPredictions(word); - + predictionOngoing.set(false); // } // }; // diff --git a/pdex/src/processing/mode/experimental/CompletionPanel.java b/pdex/src/processing/mode/experimental/CompletionPanel.java index ab32e4b7d..610be8c3e 100644 --- a/pdex/src/processing/mode/experimental/CompletionPanel.java +++ b/pdex/src/processing/mode/experimental/CompletionPanel.java @@ -18,6 +18,7 @@ package processing.mode.experimental; import static processing.mode.experimental.ExperimentalMode.log; +import static processing.mode.experimental.ExperimentalMode.log2; import static processing.mode.experimental.ExperimentalMode.logE; import java.awt.BorderLayout; @@ -25,6 +26,7 @@ import java.awt.Color; import java.awt.Component; import java.awt.FontMetrics; import java.awt.Point; +import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Iterator; @@ -108,7 +110,7 @@ public class CompletionPanel { textarea.requestFocusInWindow(); popupMenu.show(textarea, location.x, textarea.getBaseline(0, 0) + location.y); - //log("Suggestion constructed" + System.nanoTime()); + log("Suggestion shown: " + System.currentTimeMillis()); } public boolean isVisible() { @@ -205,7 +207,7 @@ public class CompletionPanel { try { String selectedSuggestion = ((CompletionCandidate) completionList .getSelectedValue()).getCompletionString().substring(subWord.length()); - logE(subWord+" <= subword,Inserting suggestion=> " + selectedSuggestion); + logE(subWord+" <= subword,Inserting suggestion=> " + selectedSuggestion + " Current sub: " + fetchPhrase()); textarea.getDocument().remove(insertionPosition-subWord.length(), subWord.length()); textarea.getDocument().insertString(insertionPosition-subWord.length(), ((CompletionCandidate) completionList @@ -223,6 +225,7 @@ public class CompletionPanel { else { textarea.setCaretPosition(insertionPosition + selectedSuggestion.length()); } + log("Suggestion inserted: " + System.currentTimeMillis()); return true; } catch (BadLocationException e1) { e1.printStackTrace(); @@ -231,6 +234,120 @@ public class CompletionPanel { } return false; } + + private String fetchPhrase() { + TextArea ta = editor.ta; + int off = ta.getCaretPosition(); + log2("off " + off); + if (off < 0) + return null; + int line = ta.getCaretLine(); + if (line < 0) + return null; + String s = ta.getLineText(line); + log2("lin " + line); + /* + * if (s == null) return null; else if (s.length() == 0) return null; + */ +// else { + //log2(s + " len " + s.length()); + + int x = ta.getCaretPosition() - ta.getLineStartOffset(line) - 1, x2 = x + 1, x1 = x - 1; + if(x >= s.length() || x < 0) + return null; //TODO: Does this check cause problems? Verify. + log2(" x char: " + s.charAt(x)); + //int xLS = off - getLineStartNonWhiteSpaceOffset(line); + + String word = (x < s.length() ? s.charAt(x) : "") + ""; + if (s.trim().length() == 1) { +// word = "" +// + (keyChar == KeyEvent.CHAR_UNDEFINED ? s.charAt(x - 1) : keyChar); + //word = (x < s.length()?s.charAt(x):"") + ""; + word = word.trim(); + if (word.endsWith(".")) + word = word.substring(0, word.length() - 1); + + return word; + } +// if (keyChar == KeyEvent.VK_BACK_SPACE || keyChar == KeyEvent.VK_DELETE) +// ; // accepted these keys +// else if (!(Character.isLetterOrDigit(keyChar) || keyChar == '_' || keyChar == '$')) +// return null; + int i = 0; + int closeB = 0; + + while (true) { + i++; + //TODO: currently works on single line only. "a. b()" won't be detected + if (x1 >= 0) { +// if (s.charAt(x1) != ';' && s.charAt(x1) != ',' && s.charAt(x1) != '(') + if (Character.isLetterOrDigit(s.charAt(x1)) || s.charAt(x1) == '_' + || s.charAt(x1) == '.' || s.charAt(x1) == ')' || s.charAt(x1) == ']') { + + if (s.charAt(x1) == ')') { + word = s.charAt(x1--) + word; + closeB++; + while (x1 >= 0 && closeB > 0) { + word = s.charAt(x1) + word; + if (s.charAt(x1) == '(') + closeB--; + if (s.charAt(x1) == ')') + closeB++; + x1--; + } + } + else if (s.charAt(x1) == ']') { + word = s.charAt(x1--) + word; + closeB++; + while (x1 >= 0 && closeB > 0) { + word = s.charAt(x1) + word; + if (s.charAt(x1) == '[') + closeB--; + if (s.charAt(x1) == ']') + closeB++; + x1--; + } + } + else { + word = s.charAt(x1--) + word; + } + } else { + break; + } + } else { + break; + } + + // if (x2 >= 0 && x2 < s.length()) { + // if (Character.isLetterOrDigit(s.charAt(x2)) || s.charAt(x2) == '_' + // || s.charAt(x2) == '$') + // word = word + s.charAt(x2++); + // else + // x2 = -1; + // } else + // x2 = -1; + + // if (x1 < 0 )//&& x2 < 0 + // break; + if (i > 200) { + // time out! + break; + } + } + // if (keyChar != KeyEvent.CHAR_UNDEFINED) + + if (Character.isDigit(word.charAt(0))) + return null; + word = word.trim(); + // if (word.endsWith(".")) + // word = word.substring(0, word.length() - 1); + if(word.length() > 1) + + //showSuggestionLater(); + return word; + else return ""; + //} + } /** * Hide the suggestion list diff --git a/pdex/src/processing/mode/experimental/TextArea.java b/pdex/src/processing/mode/experimental/TextArea.java index b74d484c4..6657353ff 100644 --- a/pdex/src/processing/mode/experimental/TextArea.java +++ b/pdex/src/processing/mode/experimental/TextArea.java @@ -205,11 +205,12 @@ public class TextArea extends JEditTextArea { final KeyEvent evt2 = evt; SwingWorker worker = new SwingWorker() { protected Object doInBackground() throws Exception { + log("[KeyEvent]" + evt2.getKeyChar() + " |Prediction started: " + System.currentTimeMillis()); errorCheckerService.runManualErrorCheck(); // Provide completions only if it's enabled if(ExperimentalMode.codeCompletionsEnabled) - log(" Typing: " + fetchPhrase(evt2) + " " - + (evt2.getKeyChar() == KeyEvent.VK_ENTER)); + log("Typing: " + fetchPhrase(evt2) + " " + + (evt2.getKeyChar() == KeyEvent.VK_ENTER) + " T: " + System.currentTimeMillis()); return null; } };