diff --git a/pdex/Todo, GSoC 2013.txt b/pdex/Todo, GSoC 2013.txt index d2e577745..c7020fcc0 100644 --- a/pdex/Todo, GSoC 2013.txt +++ b/pdex/Todo, GSoC 2013.txt @@ -4,7 +4,7 @@ This would also be a break down of my thought process and ideas as I tackle vari Manindra Moharana (me@mkmoharana.com) -* : Todo, x : Done, ? : Undecided Todo, ! : Critical, + : Minor Todo +[ ]: Todo, [x] : Done, ? : Undecided Todo, ! : Critical, + : Minor Todo Code Completion =============== @@ -16,122 +16,122 @@ The big stuff: - Many of the cases seem to have been covered, and I'm achieving more and more code unification as I'm working through the problem step by step - Looks almost complete now, nearly all cases covered(July 13th) x After popup appears, the popup location is fixed for the current line. So if editor window is moved while staying in the same line, popup appears at the prev location. Need to ensure editor is still at last know location. Fixed. -* Keyboard Shortcut for completion popup - Ctrl + Space -* Scope handling? Static/non static scope? -* Disable completions on comment line -* Trie implementation would be lower priority, "premature optimisation is pure evil". Get all features of CC working good enough and then plan this. +[ ]Keyboard Shortcut for completion popup - Ctrl + Space +[ ]Scope handling? Static/non static scope? +[ ]Disable completions on comment line +[ ]Trie implementation would be lower priority, "premature optimisation is pure evil". Get all features of CC working good enough and then plan this. -x Ensure that a compilation unit is created at startup! +[x]Ensure that a compilation unit is created at startup! x! Code competition for local code is working with recursive look up. -x Completion doesn't seem to show up for fields of a type defined locally. But works for methods with return type defined locally. Take ideas. Some case missing most probably. Fixed -x Discovered another major issue due to offset differences -> While looking for predictions, if the parsed string contains pde enhancements, predictions FAIL! Zomg. +[x]Completion doesn't seem to show up for fields of a type defined locally. But works for methods with return type defined locally. Take ideas. Some case missing most probably. Fixed +[x]Discovered another major issue due to offset differences -> While looking for predictions, if the parsed string contains pde enhancements, predictions FAIL! Zomg. Ex - "s.substring(int(13.4))." fails. Thinking to just do the substitutions before sending it to updatePredictions(), coz offsets aren't really a concern here, right? Yup, fixed it! x! Code completion with library code, non-nested seems to be broken, fix it. Fixed. -x Completion for external classes - ArrayList, HashMap, etc. +[x]Completion for external classes - ArrayList, HashMap, etc. x! Recursive lookup for compiled(library) code! x! Library CC for nested would be tricky. Need to jump from local->compiled code while searching recursively. Recursive find's current implementation is based on ASTNode return type. Afaik, no way to instantiate orphaned ASTNode objects(or did I miss it?). ASTNode objects have to be created only from the main ast instance. But I need to find a way to switch to compiled instances from local class instance. x! Should I implement wrapper for ASTNode? - possibly needed for code completion with compiled and non-compiled code. Done. -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. -x Parameterized type support is broken. -x Array types, all all other types support broken. :\ -x Completion for array access, strings[0]. +[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. +[x]Parameterized type support is broken. +[x]Array types, all all other types support broken. :\ +[x]Completion for array access, strings[0]. Finer details -* findDeclarations should support 3rd party classes too. It's about time. ;) -* printStuff(int,float,String) - completion endings have to be appropriate. Right now it's just printStuff(,,). Cursor positioning also needs to be taken care of(done). Argument list as tooltip if possible? +[ ]findDeclarations should support 3rd party classes too. It's about time. ;) +[ ]printStuff(int,float,String) - completion endings have to be appropriate. Right now it's just printStuff(,,). Cursor positioning also needs to be taken care of(done). Argument list as tooltip if possible? *! 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. +[ ]Diamond operator isn't supported for now. Bummer. -x Completion popup height is now dynamic, decreases to fit. -* Completion width can be dynamic, if really needed.. -x Icons for completions? Or overkill right now? -x 'Show Usage' menu item added -x Show declaring class for completions +[x]Completion popup height is now dynamic, decreases to fit. +[ ]Completion width can be dynamic, if really needed.. +[x]Icons for completions? Or overkill right now? +[x]'Show Usage' menu item added +[x]Show declaring class for completions x! Ignore String case while finding completion candidates -x Multiple 3rd party classes found in various packages. Not a chance no more. -x Obj a1; a1.-> completion doesn't work before it is instantiated. Look into that. Began working again by itself. Yay! -x Cursor positioning should be after the first ( if arguments present, else after () -x Display the type of Completion(method return type, variable type) in the popup. +[x]Multiple 3rd party classes found in various packages. Not a chance no more. +[x]Obj a1; a1.-> completion doesn't work before it is instantiated. Look into that. Began working again by itself. Yay! +[x]Cursor positioning should be after the first ( if arguments present, else after () +[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. -x Reflection API - getMethods vs getDeclaredMethods. declared. -x Need to add offset correction to ASTGenerator and its lookup methods. Or leave it for later? All set to implement -x Completion List should get hidden on hitting esc key +[x]Sorted list of completion candidates - fields, then methods. It's unsorted presently. +[x]Reflection API - getMethods vs getDeclaredMethods. declared. +[x]Need to add offset correction to ASTGenerator and its lookup methods. Or leave it for later? All set to implement +[x]Completion List should get hidden on hitting esc key Offset Mapping ============== First major hurdle is offset mapping *! pde<->java code offset : precise conversion needed -* W.r.t PDE specific enhancements, things are almost working. There are some offset issues when multiple pde statements are in the same line, but I guess it's good enough for now to proceed ahead. Will keep a close watch for potential bugs. -x for the above, I've decide to first implement a sketch outline like feature, which would highlight an AST element precisely in the pde code. This would ensure I've got the mapping working properly. And may lead to a future feature. -x This is precise upto a certain line. Once on a line, pde stuff have to be taken into consideration. -x Edge case - multiple statements in a single line -x PDE specific enhancements will also have to be tackled like int(), # literals. The length of the node returned needs to be modified to make up for extra chars added like PApplet.parseFloat, etc. Also the 2nd or futher pde enhancements in the same line means even the beginning offset would need adjustment. Meh. +[ ]W.r.t PDE specific enhancements, things are almost working. There are some offset issues when multiple pde statements are in the same line, but I guess it's good enough for now to proceed ahead. Will keep a close watch for potential bugs. +[x]for the above, I've decide to first implement a sketch outline like feature, which would highlight an AST element precisely in the pde code. This would ensure I've got the mapping working properly. And may lead to a future feature. +[x]This is precise upto a certain line. Once on a line, pde stuff have to be taken into consideration. +[x]Edge case - multiple statements in a single line +[x]PDE specific enhancements will also have to be tackled like int(), # literals. The length of the node returned needs to be modified to make up for extra chars added like PApplet.parseFloat, etc. Also the 2nd or futher pde enhancements in the same line means even the beginning offset would need adjustment. Meh. Refactoring =========== -* Undo misbehaves here, handle carefully. -* Fails to rename the first defined global variable, if a javadoc comment precedes it. But owrds for single/multiline comments. Wth! -x New Name is validated. -x Ordered list in 'Show Usage' window -x Add support for word select on right click and rename, mouse co-ordinates need to obtained carefully +[ ]Undo misbehaves here, handle carefully. +[ ]Fails to rename the first defined global variable, if a javadoc comment precedes it. But owrds for single/multiline comments. Wth! +[x]New Name is validated. +[x]Ordered list in 'Show Usage' window +[x]Add support for word select on right click and rename, mouse co-ordinates need to obtained carefully Refactoring would work only when code is compiler error free. I plan to do a find replace type op on the compile ready code. 1. First identify the declaration of the variable in the AST. We'll then make a list of all its occurrences. 2. DFS through the AST, for each (SimpleName)instance of the word in code, find if the matched word is the same one whose declaration we found. -x Edge Case: For renaming a TypeDeclaration, the declaration of SimpleName instance of the TD and it's constructor(s) aren't added to the list generated by DFS. So for renaming TD, will have to manually add the TD SimpleName and it's constructors' SimpleNames to the a list of declaration nodes that can be positively matched against. -x Renaming any constructor is equivalent to renaming the TD +[x]Edge Case: For renaming a TypeDeclaration, the declaration of SimpleName instance of the TD and it's constructor(s) aren't added to the list generated by DFS. So for renaming TD, will have to manually add the TD SimpleName and it's constructors' SimpleNames to the a list of declaration nodes that can be positively matched against. +[x]Renaming any constructor is equivalent to renaming the TD 3. Find corresponding PDE offsets of the SimpleNames, rename in each line. -x Edge Case: Need to take displaced offsets on a line, due to pde enhancements, into consideration. +[x]Edge Case: Need to take displaced offsets on a line, due to pde enhancements, into consideration. 4. All the changes in code would be made in a separate copy of the code(?). After all the renaming is done, allow it only if the new code compiles. Basically an undo should be possible in case of conflicts. -x Refactoring ui -x For now, user needs to highlight the name of the var, and then right-click -> Rename.. -x Handle saving. If sketch closed after renaming w/o saving find bugs. Done, marking the sketch as modified after renaming. +[x]Refactoring ui +[x]For now, user needs to highlight the name of the var, and then right-click -> Rename.. +[x]Handle saving. If sketch closed after renaming w/o saving find bugs. Done, marking the sketch as modified after renaming. Quick Navigation ================ *+ 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. -x On OS X, Ctrl + Click is right mouse click, so implement Cmd + Click instead. isMetaDown()? -x Ctrl + Click on an element to scroll to its definition in code -x Local Vars -x Local Methods -x Local Classes -x Recursive lookup, a.b().c() -x Now highlihgting the declaration name, rather than the whole declaration. +[x]On OS X, Ctrl + Click is right mouse click, so implement Cmd + Click instead. isMetaDown()? +[x]Ctrl + Click on an element to scroll to its definition in code +[x]Local Vars +[x]Local Methods +[x]Local Classes +[x]Recursive lookup, a.b().c() +[x]Now highlihgting the declaration name, rather than the whole declaration. Sketch Outline ============== -x Show Sketch Outline Tree -x Filter stuff in text field -x Add icons - custom cell renderer +[x]Show Sketch Outline Tree +[x]Filter stuff in text field +[x]Add icons - custom cell renderer Suggestion for missing imports ============================== -* Find a more subtle way to suggest for imports. The current method is too troublesome. Randomly pops up offering suggestions. May intimidate beginners. +[ ]Find a more subtle way to suggest for imports. The current method is too troublesome. Randomly pops up offering suggestions. May intimidate beginners. 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. -x Barebones functionality done. -x Add imports only to beginning of first tab. -x Search within contributed libraries folder -x Hide suggestion list before showing import suggestions -x Search within code folder of sketch +[x]Barebones functionality done. +[x]Add imports only to beginning of first tab. +[x]Search within contributed libraries folder +[x]Hide suggestion list before showing import suggestions +[x]Search within code folder of sketch Labels for Java elements ======================== -x Working for local code -* Need to modify getASTNodeAt to also fetch the type for predefined classes. -* Labels for predefined class objects -* Chaining support for labels +[x]Working for local code +[ ]Need to modify getASTNodeAt to also fetch the type for predefined classes. +[ ]Labels for predefined class objects +[ ]Chaining support for labels Synchronization =============== @@ -140,31 +140,31 @@ Gotta do it carefully between main thread, ECS Thread, and SwingWorker threads Fields that are concurrently accessed: ECS members: -x ArrayList problems - updated in ECS, accessed by ErrorBar.update() -x ArrayList classpathJars - updated in ECS, accessed by ASTGenerator.loadJars() -x hasErrors, syntaxErrors - Atomic Boolean -x boolean warningsEnabled - made it volatile -* CompilationUnit cu - updated in ECS, accessed a zillion times in ASTGenerator :'( +[x]ArrayList problems - updated in ECS, accessed by ErrorBar.update() +[x]ArrayList classpathJars - updated in ECS, accessed by ASTGenerator.loadJars() +[x]hasErrors, syntaxErrors - Atomic Boolean +[x]boolean warningsEnabled - made it volatile +[ ]CompilationUnit cu - updated in ECS, accessed a zillion times in ASTGenerator :'( General Stuff ============= -* [Critical] PermGen out of memory bug. Manually triggering GC after making the classloader null ensures permgen memory is reclaimed on editor exit. Max open window still limited by max permgen size. Also, added a classloadcounter in ECS to trigger GC periodically. +[ ][Critical] PermGen out of memory bug. Manually triggering GC after making the classloader null ensures permgen memory is reclaimed on editor exit. Max open window still limited by max permgen size. Also, added a classloadcounter in ECS to trigger GC periodically. https://github.com/processing/processing-experimental/issues/1 See: http://stackoverflow.com/questions/2095974/how-to-unload-a-already-loaded-class-in-java I'm making the classLoader null, but what about the classes loaded by ASTGen? Investigate. -x Disabling Error Checking disables predictions as well! Fixed. -x Added doc listener for text area updates -x Consult Ben on where to save preferences - main preferences.txt or custom one. - Main prefs file -x Save preferences to main preference.txt -x Hide breakpoint markers when Debugger isn't active -x Ensure gutter mouse handler is taken care of when hiding Debugger breakpoint bar. -x Ensure all editor windows are closed when editor is closed. -x Add a red marker near Errors label in console toggle, to indicate errors present in sketch. -x Add option for toggling debug output -x On Run/Debug Console is visible(ProblemsList hidden) -* Update wiki for Ctrl + H instead of Ctrl + J shortcuts -x update build.xml to produce dists -x Make this a contributed mode - mode.txt, github releases feature, version numbering, git tags, etc -x Add GitHub link to PDE X Menu +[x]Disabling Error Checking disables predictions as well! Fixed. +[x]Added doc listener for text area updates +[x]Consult Ben on where to save preferences - main preferences.txt or custom one. - Main prefs file +[x]Save preferences to main preference.txt +[x]Hide breakpoint markers when Debugger isn't active +[x]Ensure gutter mouse handler is taken care of when hiding Debugger breakpoint bar. +[x]Ensure all editor windows are closed when editor is closed. +[x]Add a red marker near Errors label in console toggle, to indicate errors present in sketch. +[x]Add option for toggling debug output +[x]On Run/Debug Console is visible(ProblemsList hidden) +[ ]Update wiki for Ctrl + H instead of Ctrl + J shortcuts +[x]update build.xml to produce dists +[x]Make this a contributed mode - mode.txt, github releases feature, version numbering, git tags, etc +[x]Add GitHub link to PDE X Menu diff --git a/pdex/src/processing/mode/experimental/ASTGenerator.java b/pdex/src/processing/mode/experimental/ASTGenerator.java index ebda1f9ea..3e9d60806 100644 --- a/pdex/src/processing/mode/experimental/ASTGenerator.java +++ b/pdex/src/processing/mode/experimental/ASTGenerator.java @@ -794,6 +794,13 @@ public class ASTGenerator { private AtomicBoolean predictionOngoing; + /** + * The main function that calculates possible code completion candidates + * + * @param word + * @param line + * @param lineStartNonWSOffset + */ public void preparePredictions(final String word, final int line, final int lineStartNonWSOffset) { if(predictionOngoing.get()) return; @@ -890,11 +897,14 @@ public class ASTGenerator { MethodInvocation mi = (MethodInvocation)testnode; System.out.println(mi.getName() + "," + mi.getExpression() + "," + mi.typeArguments().size()); } - nearestNode = findClosestNode(lineNumber, (ASTNode) compilationUnit.types() + + // find nearest ASTNode + nearestNode = findClosestNode(lineNumber, (ASTNode) errorCheckerService.getLastCorrectCU().types() .get(0)); - if (nearestNode == null) - //Make sure nearestNode is not NULL if couldn't find a closeset node - nearestNode = (ASTNode) compilationUnit.types().get(0); + if (nearestNode == null) { + // Make sure nearestNode is not NULL if couldn't find a closeset node + nearestNode = (ASTNode) errorCheckerService.getLastCorrectCU().types().get(0); + } logE(lineNumber + " Nearest ASTNode to PRED " + getNodeAsString(nearestNode)); @@ -1671,8 +1681,13 @@ public class ASTGenerator { logE("DECLA: " + decl.getClass().getName()); nodeLabel = getLabelIfType(new ASTNodeWrapper(decl), (SimpleName) simpName); //retLabelString = getNodeAsString(decl); - } else + } else { logE("null"); + if(scrollOnly) { + editor.statusMessage(simpName + " is not defined in this sketch", + DebugEditor.STATUS_ERR); + } + } log(getNodeAsString(decl)); @@ -2017,19 +2032,22 @@ public class ASTGenerator { public void handleShowUsage(){ log("Last clicked word:" + lastClickedWord); if(lastClickedWord == null && editor.ta.getSelectedText() == null){ - editor.statusError("Highlight the class/function/variable name first"); + editor.statusMessage("Highlight the class/function/variable name first" + , DebugEditor.STATUS_INFO); return; } if(errorCheckerService.hasSyntaxErrors()){ - editor.statusError("Can't perform action until syntax errors are fixed :("); + editor.statusMessage("Can't perform action until syntax errors are " + + "fixed :(", DebugEditor.STATUS_WARNING); return; } DefaultMutableTreeNode defCU = findAllOccurrences(); String selText = lastClickedWord == null ? editor.ta.getSelectedText() : lastClickedWord; if(defCU == null){ - editor.statusError("Can't locate definition of " + selText); + editor.statusMessage("Can't locate definition of " + selText, + DebugEditor.STATUS_ERR); return; } if(defCU.getChildCount() == 0) @@ -2281,12 +2299,24 @@ public class ASTGenerator { public void handleRefactor(){ log("Last clicked word:" + lastClickedWord); if(lastClickedWord == null && editor.ta.getSelectedText() == null){ - editor.statusError("Highlight the class/function/variable name first"); + editor.statusMessage("Highlight the class/function/variable name first", + DebugEditor.STATUS_INFO); return; } if(errorCheckerService.hasSyntaxErrors()){ - editor.statusError("Can't perform action until syntax errors are fixed :("); + editor + .statusMessage("Can't perform action until syntax errors are fixed :(", + DebugEditor.STATUS_WARNING); + return; + } + + DefaultMutableTreeNode defCU = findAllOccurrences(); + String selText = lastClickedWord == null ? editor.ta.getSelectedText() + : lastClickedWord; + if(defCU == null){ + editor.statusMessage(selText + " isn't defined in this sketch, so it can't" + + " be renamed", DebugEditor.STATUS_ERR); return; } if (!frmRename.isVisible()){ diff --git a/pdex/src/processing/mode/experimental/ASTNodeWrapper.java b/pdex/src/processing/mode/experimental/ASTNodeWrapper.java index 2823cc9e7..734da04d9 100644 --- a/pdex/src/processing/mode/experimental/ASTNodeWrapper.java +++ b/pdex/src/processing/mode/experimental/ASTNodeWrapper.java @@ -575,6 +575,20 @@ public class ASTNodeWrapper { return false; } + OffsetMatcher ofm = new OffsetMatcher(pdeLine, javaLine); + int highlightStart = ofm.getPdeOffForJavaOff(nodeName.getStartPosition() + - lineElement.getStartOffset(), + nodeName.getLength()); + if (highlightStart == -1) { + logE("Logical error in highLightNode() during offset matching. " + + "Please file a bug report."); + return false; + } + int lso = astGenerator.editor.ta.getLineStartOffset(pdeOffs[1]); + highlightStart += lso; + astGenerator.editor.setSelection(highlightStart, highlightStart + + nodeName.getLength()); + /* // First find the name in the java line, and marks its index Pattern toFind = Pattern.compile("\\b" + nodeName.toString() + "\\b"); Matcher matcher = toFind.matcher(javaLine); @@ -603,6 +617,7 @@ public class ASTNodeWrapper { int lso = astGenerator.editor.ta.getLineStartOffset(pdeOffs[1]); astGenerator.editor.setSelection(lso + index - lookingFor.length(), lso + index); + */ return true; } catch (BadLocationException e) { logE("BLE in highLightNode() for " + nodeName); diff --git a/pdex/src/processing/mode/experimental/CompletionPanel.java b/pdex/src/processing/mode/experimental/CompletionPanel.java index cadc007e3..00ee4e105 100644 --- a/pdex/src/processing/mode/experimental/CompletionPanel.java +++ b/pdex/src/processing/mode/experimental/CompletionPanel.java @@ -22,16 +22,12 @@ import static processing.mode.experimental.ExperimentalMode.log2; import static processing.mode.experimental.ExperimentalMode.logE; import java.awt.BorderLayout; -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; -import javax.swing.BorderFactory; import javax.swing.DefaultListModel; import javax.swing.JLabel; import javax.swing.JList; @@ -210,17 +206,29 @@ public class CompletionPanel { public boolean insertSelection() { if (completionList.getSelectedValue() != null) { try { + // If user types 'abc.', subword becomes '.' and null is returned String currentSubword = fetchCurrentSubword(); + int currentSubwordLen = currentSubword == null ? 0 : currentSubword + .length(); + //logE(currentSubword + " <= subword,len => " + currentSubword.length()); String selectedSuggestion = ((CompletionCandidate) completionList - .getSelectedValue()).getCompletionString().substring(currentSubword - .length()); - logE(subWord + " <= subword,Inserting suggestion=> " + .getSelectedValue()).getCompletionString(); + + if (currentSubword != null) { + selectedSuggestion = selectedSuggestion.substring(currentSubwordLen); + } else { + currentSubword = ""; + } + + logE(subWord + " <= subword, Inserting suggestion=> " + selectedSuggestion + " Current sub: " + currentSubword); - textarea.getDocument().remove(insertionPosition - - currentSubword.length(), - currentSubword.length()); + if (currentSubword.length() > 0) { + textarea.getDocument().remove(insertionPosition - currentSubwordLen, + currentSubwordLen); + } + textarea.getDocument() - .insertString(insertionPosition - currentSubword.length(), + .insertString(insertionPosition - currentSubwordLen, ((CompletionCandidate) completionList .getSelectedValue()).getCompletionString(), null); if (selectedSuggestion.endsWith(")")) { @@ -240,12 +248,16 @@ public class CompletionPanel { } catch (BadLocationException e1) { e1.printStackTrace(); } + catch (Exception e) { + e.printStackTrace(); + } hide(); } return false; } private String fetchCurrentSubword() { + //log("Entering fetchCurrentSubword"); TextArea ta = editor.ta; int off = ta.getCaretPosition(); //log2("off " + off); @@ -256,35 +268,32 @@ public class CompletionPanel { 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; + int x = ta.getCaretPosition() - ta.getLineStartOffset(line) - 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)); + 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 = "" + // + (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; + //log("fetchCurrentSubword 1 " + word); + if(word.equals(".")) return null; // If user types 'abc.', subword becomes '.' + // 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++; @@ -307,13 +316,13 @@ public class CompletionPanel { } } // if (keyChar != KeyEvent.CHAR_UNDEFINED) - + //log("fetchCurrentSubword 2 " + word); if (Character.isDigit(word.charAt(0))) return null; word = word.trim(); if (word.endsWith(".")) word = word.substring(0, word.length() - 1); - + //log("fetchCurrentSubword 3 " + word); //showSuggestionLater(); return word; //} diff --git a/pdex/src/processing/mode/experimental/DebugEditor.java b/pdex/src/processing/mode/experimental/DebugEditor.java index 640589460..62c6db78e 100755 --- a/pdex/src/processing/mode/experimental/DebugEditor.java +++ b/pdex/src/processing/mode/experimental/DebugEditor.java @@ -39,6 +39,8 @@ import java.io.IOException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; +import java.util.Timer; +import java.util.TimerTask; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; @@ -933,7 +935,7 @@ public class DebugEditor extends JavaEditor implements ActionListener { vi.setTitle(getSketch().getName()); } // if file location has changed, update autosaver - autosaver.reloadAutosaveDir(); +// autosaver.reloadAutosaveDir(); return saved; } @@ -1515,6 +1517,54 @@ public class DebugEditor extends JavaEditor implements ActionListener { statusNotice("Debugger halted."); } + public static final int STATUS_EMPTY = 100, STATUS_COMPILER_ERR = 200, + STATUS_WARNING = 300, STATUS_INFO = 400, STATUS_ERR = 500; + public int statusMessageType = STATUS_EMPTY; + public String statusMessage; + public void statusMessage(final String what, int type){ + // Don't re-display the old message again + if(type != STATUS_EMPTY) { + if(what.equals(statusMessage) && type == statusMessageType) { + return; + } + } + statusMessage = new String(what); + statusMessageType = type; + switch (type) { + case STATUS_COMPILER_ERR: + case STATUS_ERR: + super.statusError(what); + break; + case STATUS_INFO: + case STATUS_WARNING: + statusNotice(what); + break; + } + // Don't need to clear compiler error messages + if(type == STATUS_COMPILER_ERR) return; + + // Clear the message after a delay + SwingWorker s = new SwingWorker() { + @Override + protected Void doInBackground() throws Exception { + try { + Thread.sleep(2 * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + statusEmpty(); + return null; + } + }; + s.execute(); + } + + public void statusEmpty(){ + statusMessage = null; + statusMessageType = STATUS_EMPTY; + super.statusEmpty(); + } + ErrorCheckerService errorCheckerService; /** diff --git a/pdex/src/processing/mode/experimental/ErrorCheckerService.java b/pdex/src/processing/mode/experimental/ErrorCheckerService.java index 92948c09a..d6fabf90b 100644 --- a/pdex/src/processing/mode/experimental/ErrorCheckerService.java +++ b/pdex/src/processing/mode/experimental/ErrorCheckerService.java @@ -36,11 +36,9 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.swing.JCheckBoxMenuItem; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.table.DefaultTableModel; -import javax.swing.text.AbstractDocument; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.compiler.IProblem; @@ -137,7 +135,17 @@ public class ErrorCheckerService implements Runnable{ /** * Compilation Unit for current sketch */ - protected CompilationUnit cu; + protected CompilationUnit cu; + + /** + * The Compilation Unit generated during compile check + */ + protected CompilationUnit compileCheckCU; + + /** + * This Compilation Unit points to the last error free CU + */ + protected CompilationUnit lastCorrectCU; /** * If true, compilation checker will be reloaded with updated classpath @@ -433,6 +441,9 @@ public class ErrorCheckerService implements Runnable{ // No syntax errors, proceed for compilation check, Stage 2. //if(hasSyntaxErrors()) astGenerator.buildAST(null); + if (!hasSyntaxErrors()) { + + } if (problems.length == 0 && editor.compilationCheckEnabled) { //mainClassOffset++; // just a hack. @@ -537,6 +548,10 @@ public class ErrorCheckerService implements Runnable{ if (problems.length == 0) { syntaxErrors.set(false); containsErrors.set(false); + parser.setSource(sourceCode.toCharArray()); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + parser.setCompilerOptions(options); + lastCorrectCU = (CompilationUnit) parser.createAST(null); } else { syntaxErrors.set(true); containsErrors.set(true); @@ -548,7 +563,8 @@ public class ErrorCheckerService implements Runnable{ protected void compileCheck() { - // CU needs to be updated coz before compileCheck xqpreprocessor is run on the source code which makes some further changes + // CU needs to be updated coz before compileCheck xqpreprocessor is run on + // the source code which makes some further changes //TODO Check if this breaks things parser.setSource(sourceCode.toCharArray()); @@ -561,13 +577,17 @@ public class ErrorCheckerService implements Runnable{ options.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED); parser.setCompilerOptions(options); - if (cu == null) - cu = (CompilationUnit) parser.createAST(null); + if (compileCheckCU == null) + compileCheckCU = (CompilationUnit) parser.createAST(null); else { - synchronized (cu) { - cu = (CompilationUnit) parser.createAST(null); + synchronized (compileCheckCU) { + compileCheckCU = (CompilationUnit) parser.createAST(null); } } + if(!hasSyntaxErrors()) + lastCorrectCU = compileCheckCU; + cu = compileCheckCU; + compilationUnitState = 2; // Currently (Sept, 2012) I'm using Java's reflection api to load the // CompilationChecker class(from CompilationChecker.jar) that houses the @@ -719,6 +739,14 @@ public class ErrorCheckerService implements Runnable{ // log("Compilecheck, Done."); } + public CompilationUnit getLastCorrectCU(){ + return lastCorrectCU; + } + + public CompilationUnit getLatestCU(){ + return compileCheckCU; + } + private int loadClassCounter = 0; public URLClassLoader getSketchClassLoader() { loadClassCounter++; @@ -977,12 +1005,14 @@ public class ErrorCheckerService implements Runnable{ if (emarker.getProblem().getLineNumber() == editor.getTextArea() .getCaretLine() + 1) { if (emarker.getType() == ErrorMarker.Warning) { - editor.statusNotice(emarker.getProblem().getMessage()); + editor.statusMessage(emarker.getProblem().getMessage(), + DebugEditor.STATUS_INFO); //+ " : " + errorMsgSimplifier.getIDName(emarker.problem.getIProblem().getID())); //TODO: this is temporary } else { - editor.statusError(emarker.getProblem().getMessage()); + editor.statusMessage(emarker.getProblem().getMessage(), + DebugEditor.STATUS_COMPILER_ERR); //+ " : " + errorMsgSimplifier.getIDName(emarker.problem.getIProblem().getID())); } return; @@ -991,8 +1021,7 @@ public class ErrorCheckerService implements Runnable{ } // This line isn't an error line anymore, so probably just clear it - if (editor.getStatusMode() == EditorStatus.ERR - || editor.getStatusMode() == EditorStatus.NOTICE) { + if (editor.statusMessageType == DebugEditor.STATUS_COMPILER_ERR) { editor.statusEmpty(); return; } diff --git a/pdex/src/processing/mode/experimental/OffsetMatcher.java b/pdex/src/processing/mode/experimental/OffsetMatcher.java new file mode 100644 index 000000000..d5aff521b --- /dev/null +++ b/pdex/src/processing/mode/experimental/OffsetMatcher.java @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2012-14 Manindra Moharana + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +package processing.mode.experimental; + +import java.util.ArrayList; +import static processing.mode.experimental.ExperimentalMode.log; + +/** + * Performs offset matching between PDE and Java code (one line of code only) + * + * @author Manindra Moharana + * + */ + +public class OffsetMatcher { + + public ArrayList offsetMatch; + + String word1, word2; + + boolean matchingNeeded = false; + + public OffsetMatcher(String pdeCode, String javaCode) { + this.word1 = pdeCode; + this.word2 = javaCode; + if(word1.trim().equals(word2.trim())){ //TODO: trim() needed here? + matchingNeeded = false; + offsetMatch = new ArrayList(); + log("Offset Matching not needed"); + } + else + { + matchingNeeded = true; + minDistance(); + } + +// log("PDE <-> Java"); + for (int i = 0; i < offsetMatch.size(); i++) { +// log(offsetMatch.get(i).pdeOffset + " <-> " +// + offsetMatch.get(i).javaOffset + +// ", " + word1.charAt(offsetMatch.get(i).pdeOffset) +// + " <-> " + word2.charAt(offsetMatch.get(i).javaOffset)); + } +// log("Length " + offsetMatch.size()); + } + + public int getPdeOffForJavaOff(int start, int length) { + if(!matchingNeeded) return start; + int ans = getPdeOffForJavaOff(start), end = getPdeOffForJavaOff(start + length - 1); + log(start + " java start off, pde start off " + + ans); + log((start + length - 1) + " java end off, pde end off " + + end); + log("J: " + word2.substring(start, start + length) + "\nP: " + + word1.substring(ans, end + 1)); + return ans; + } + + public int getJavaOffForPdeOff(int start, int length) { + if(!matchingNeeded) return start; + int ans = getJavaOffForPdeOff(start); + log(start + " pde start off, java start off " + + getJavaOffForPdeOff(start)); + log((start + length - 1) + " pde end off, java end off " + + getJavaOffForPdeOff(start + length - 1)); + return ans; + } + + public int getPdeOffForJavaOff(int javaOff) { + if(!matchingNeeded) return javaOff; + for (int i = offsetMatch.size() - 1; i >= 0; i--) { + if (offsetMatch.get(i).javaOffset < javaOff) { + continue; + } else if (offsetMatch.get(i).javaOffset == javaOff) { +// int j = i; + while (offsetMatch.get(--i).javaOffset == javaOff) { + log("MP " + offsetMatch.get(i).javaOffset + " " + + offsetMatch.get(i).pdeOffset); + } + int pdeOff = offsetMatch.get(++i).pdeOffset; + while (offsetMatch.get(--i).pdeOffset == pdeOff) + ; + int j = i + 1; + if (j > -1 && j < offsetMatch.size()) + return offsetMatch.get(j).pdeOffset; + } + + } + return -1; + } + + public int getJavaOffForPdeOff(int pdeOff) { + if(!matchingNeeded) return pdeOff; + for (int i = offsetMatch.size() - 1; i >= 0; i--) { + if (offsetMatch.get(i).pdeOffset < pdeOff) { + continue; + } else if (offsetMatch.get(i).pdeOffset == pdeOff) { +// int j = i; + while (offsetMatch.get(--i).pdeOffset == pdeOff) { +// log("MP " + offsetMatch.get(i).javaOffset + " " +// + offsetMatch.get(i).pdeOffset); + } + int javaOff = offsetMatch.get(++i).javaOffset; + while (offsetMatch.get(--i).javaOffset == javaOff) + ; + int j = i + 1; + if (j > -1 && j < offsetMatch.size()) + return offsetMatch.get(j).javaOffset; + } + + } + return -1; + } + + /** + * Finds 'distance' between two Strings. + * See Edit Distance Problem + * https://secweb.cs.odu.edu/~zeil/cs361/web/website/Lectures/styles/pages/editdistance.html + * http://www.stanford.edu/class/cs124/lec/med.pdf + * + */ + private int minDistance() { + +// word1 = reverse(word1); +// word2 = reverse(word2); + int len1 = word1.length(); + int len2 = word2.length(); + log(word1 + " len: " + len1); + log(word2 + " len: " + len2); + // len1+1, len2+1, because finally return dp[len1][len2] + int[][] dp = new int[len1 + 1][len2 + 1]; + + for (int i = 0; i <= len1; i++) { + dp[i][0] = i; + } + + for (int j = 0; j <= len2; j++) { + dp[0][j] = j; + } + + //iterate though, and check last char + for (int i = 0; i < len1; i++) { + char c1 = word1.charAt(i); + for (int j = 0; j < len2; j++) { + char c2 = word2.charAt(j); + //System.out.print(c1 + "<->" + c2); + //if last two chars equal + if (c1 == c2) { + //update dp value for +1 length + dp[i + 1][j + 1] = dp[i][j]; +// log(); + } else { + int replace = dp[i][j] + 1; + int insert = dp[i][j + 1] + 1; + int delete = dp[i + 1][j] + 1; +// if (replace < delete) { +// log(" --- D"); +// } else +// log(" --- R"); + int min = replace > insert ? insert : replace; + min = delete > min ? min : delete; + dp[i + 1][j + 1] = min; + } + } + } + + ArrayList alist = new ArrayList(); + offsetMatch = alist; + minDistInGrid(dp, len1, len2, 0, 0, word1.toCharArray(), + word2.toCharArray(), alist); + return dp[len1][len2]; + } + + private void minDistInGrid(int g[][], int i, int j, int fi, int fj, + char s1[], char s2[], ArrayList set) { +// if(i < s1.length)System.out.print(s1[i] + " <->"); +// if(j < s2.length)System.out.print(s2[j]); + if (i < s1.length && j < s2.length) { +// pdeCodeMap[k] = i; +// javaCodeMap[k] = j; + //System.out.print(s1[i] + " " + i + " <-> " + j + " " + s2[j]); + set.add(new OffsetPair(i, j)); +// if (s1[i] != s2[j]) +// System.out.println("--"); + } + //System.out.println(); + if (i == fi && j == fj) { + //System.out.println("Reached end."); + } else { + int a = Integer.MAX_VALUE, b = a, c = a; + if (i > 0) + a = g[i - 1][j]; + if (j > 0) + b = g[i][j - 1]; + if (i > 0 && j > 0) + c = g[i - 1][j - 1]; + int mini = Math.min(a, Math.min(b, c)); + if (mini == a) { + //System.out.println(s1[i + 1] + " " + s2[j]); + minDistInGrid(g, i - 1, j, fi, fj, s1, s2, set); + } else if (mini == b) { + //System.out.println(s1[i] + " " + s2[j + 1]); + minDistInGrid(g, i, j - 1, fi, fj, s1, s2, set); + } else if (mini == c) { + //System.out.println(s1[i + 1] + " " + s2[j + 1]); + minDistInGrid(g, i - 1, j - 1, fi, fj, s1, s2, set); + } + } + } + + private class OffsetPair { + public final int pdeOffset, javaOffset; + + public OffsetPair(int pde, int java) { + pdeOffset = pde; + javaOffset = java; + } + } + + public static void main(String[] args) { +// minDistance("c = #qwerty;", "c = 0xffqwerty;"); + OffsetMatcher a; + + a = new OffsetMatcher("int a = int(can); int ball;", + "int a = PApplet.parseInt(can); int ball;"); + a.getPdeOffForJavaOff(25, 3); + a.getJavaOffForPdeOff(12, 3); +// minDistance("static void main(){;", "public static void main(){;"); +// minDistance("#bb00aa", "0xffbb00aa"); + //a.minDistance("color g = #qwerty;", "int g = 0xffqwerty;"); + log("--"); + a = new OffsetMatcher("color abc = #qwerty;", "int abc = 0xffqwerty;"); + a.getPdeOffForJavaOff(4, 3); + a.getJavaOffForPdeOff(6, 3); +// distance("c = #bb00aa;", "c = 0xffbb00aa;"); + } +} diff --git a/pdex/src/processing/mode/experimental/Utils.java b/pdex/src/processing/mode/experimental/Utils.java index 09007ab8d..7992676dc 100644 --- a/pdex/src/processing/mode/experimental/Utils.java +++ b/pdex/src/processing/mode/experimental/Utils.java @@ -19,7 +19,6 @@ package processing.mode.experimental; import java.util.ArrayList; -import java.util.HashMap; /** * A class containing multiple utility methods @@ -30,6 +29,8 @@ import java.util.HashMap; public class Utils { + public ArrayList offsetMatch; + String word1, word2; public static String reverse(String s) { char w[] = s.toCharArray(); for (int i = 0; i < w.length / 2; i++) { @@ -39,8 +40,84 @@ public class Utils { } return new String(w); } + + public void getPdeOffForJavaOff(int start, int length){ + System.out.println("PDE <-> Java" ); + for (int i = 0; i < offsetMatch.size(); i++) { + System.out.print(offsetMatch.get(i).pdeOffset + " <-> " + offsetMatch.get(i).javaOffset); + System.out.println(", " + word1.charAt(offsetMatch.get(i).pdeOffset) + " <-> " + + word2.charAt(offsetMatch.get(i).javaOffset)); + } + System.out.println("Length " + offsetMatch.size()); + System.out.println(start + " java start off, pde start off " + + getPdeOffForJavaOff(start)); + System.out.println((start + length - 1) + " java end off, pde end off " + + getPdeOffForJavaOff(start + length - 1)); + } + + public void getJavaOffForPdeOff(int start, int length){ +// System.out.println("PDE <-> Java" ); +// for (int i = 0; i < offsetMatch.size(); i++) { +// System.out.print(offsetMatch.get(i).pdeOffset + " <-> " + offsetMatch.get(i).javaOffset); +// System.out.println(", " + word1.charAt(offsetMatch.get(i).pdeOffset) + " <-> " +// + word2.charAt(offsetMatch.get(i).javaOffset)); +// } +// System.out.println("Length " + offsetMatch.size()); + System.out.println(start + " pde start off, java start off " + + getJavaOffForPdeOff(start)); + System.out.println((start + length - 1) + " pde end off, java end off " + + getJavaOffForPdeOff(start + length - 1)); + } + + public int getPdeOffForJavaOff(int javaOff){ + for (int i = offsetMatch.size() - 1; i >= 0;i--) { + if(offsetMatch.get(i).javaOffset < javaOff){ + continue; + } + else + if(offsetMatch.get(i).javaOffset == javaOff){ +// int j = i; + while(offsetMatch.get(--i).javaOffset == javaOff){ + System.out.println("MP " + offsetMatch.get(i).javaOffset + " " + + offsetMatch.get(i).pdeOffset); + } + int pdeOff = offsetMatch.get(++i).pdeOffset; + while(offsetMatch.get(--i).pdeOffset == pdeOff); + int j = i + 1; + if (j > -1 && j < offsetMatch.size()) + return offsetMatch.get(j).pdeOffset; + } + + } + return -1; + } + + public int getJavaOffForPdeOff(int pdeOff){ + for (int i = offsetMatch.size() - 1; i >= 0;i--) { + if(offsetMatch.get(i).pdeOffset < pdeOff){ + continue; + } + else + if(offsetMatch.get(i).pdeOffset == pdeOff){ +// int j = i; + while(offsetMatch.get(--i).pdeOffset == pdeOff){ +// System.out.println("MP " + offsetMatch.get(i).javaOffset + " " +// + offsetMatch.get(i).pdeOffset); + } + int javaOff = offsetMatch.get(++i).javaOffset; + while(offsetMatch.get(--i).javaOffset == javaOff); + int j = i + 1; + if (j > -1 && j < offsetMatch.size()) + return offsetMatch.get(j).javaOffset; + } + + } + return -1; + } public int minDistance(String word1, String word2) { + this.word1 = word1; + this.word2 = word2; // word1 = reverse(word1); // word2 = reverse(word2); int len1 = word1.length(); @@ -93,21 +170,22 @@ public class Utils { // int maxLen = Math.max(len1, len2)+2; // int pdeCodeMap[] = new int[maxLen], javaCodeMap[] = new int[maxLen]; // System.out.println("Edit distance1: " + dp[len1][len2]); - ArrayList alist = new ArrayList(); + ArrayList alist = new ArrayList(); + offsetMatch = alist; minDistInGrid(dp, len1, len2, 0, 0, word1.toCharArray(), word2.toCharArray(), alist); - System.out.println("PDE-to-Java"); +// System.out.println("PDE-to-Java"); // for (int i = 0; i < maxLen; i++) { // System.out.print(pdeCodeMap[i] + " <-> " + javaCodeMap[i]); // System.out.println(", " + word1.charAt(pdeCodeMap[i]) + " <-> " // + word2.charAt(javaCodeMap[i])); // } - for (int i = 0; i < alist.size(); i++) { - System.out.print(alist.get(i).pdeOffset + " <-> " + alist.get(i).javaOffset); - System.out.println(", " + word1.charAt(alist.get(i).pdeOffset) + " <-> " - + word2.charAt(alist.get(i).javaOffset)); - } - System.out.println("Length " + alist.size()); +// for (int i = 0; i < alist.size(); i++) { +// System.out.print(alist.get(i).pdeOffset + " <-> " + alist.get(i).javaOffset); +// System.out.println(", " + word1.charAt(alist.get(i).pdeOffset) + " <-> " +// + word2.charAt(alist.get(i).javaOffset)); +// } +// System.out.println("Length " + alist.size()); return dp[len1][len2]; } @@ -141,14 +219,14 @@ public class Utils { if (i < s1.length && j < s2.length) { // pdeCodeMap[k] = i; // javaCodeMap[k] = j; - System.out.print(s1[i] + " " + i + " <-> " + j + " " + s2[j]); - set.add(new OfsSet(i, j)); + //System.out.print(s1[i] + " " + i + " <-> " + j + " " + s2[j]); + set.add(new OfsSetTemp(i, j)); // if (s1[i] != s2[j]) // System.out.println("--"); } - System.out.println(); + //System.out.println(); if (i == fi && j == fj) { - System.out.println("Reached end."); + //System.out.println("Reached end."); } else { int a = Integer.MAX_VALUE, b = a, c = a; if (i > 0) @@ -171,20 +249,37 @@ public class Utils { } } - public class OfsSet { + public class OfsSetTemp { public final int pdeOffset, javaOffset; - public OfsSet(int pde, int java){ + public OfsSetTemp(int pde, int java){ pdeOffset = pde; javaOffset = java; } } + +// public class OffsetMatch{ +// public final ArrayList pdeOffset, javaOffset; +// +// public OffsetMatch(){ +// pdeOffset = new ArrayList(); +// javaOffset = new ArrayList(); +// } +// } public static void main(String[] args) { // minDistance("c = #qwerty;", "c = 0xffqwerty;"); - new Utils().minDistance("color g = #qwerty;", "int g = 0xffqwerty;"); -// minDistance("int a = int(4.5);", "int a = PApplet.parseInt(4.5f);"); + Utils a = new Utils(); + + a.minDistance("int a = int(can); int ball;", "int a = PApplet.parseInt(can); int ball;"); + a.getPdeOffForJavaOff(25, 3); + a.getJavaOffForPdeOff(12,3); // minDistance("static void main(){;", "public static void main(){;"); // minDistance("#bb00aa", "0xffbb00aa"); + //a.minDistance("color g = #qwerty;", "int g = 0xffqwerty;"); + System.out.println("--"); + a.minDistance("color abc = #qwerty;", "int abc = 0xffqwerty;"); + a.getPdeOffForJavaOff(4, 3); + a.getJavaOffForPdeOff(6,3); // distance("c = #bb00aa;", "c = 0xffbb00aa;"); } } diff --git a/pdex/todo.txt b/pdex/todo.txt new file mode 100644 index 000000000..a56bb9bcb --- /dev/null +++ b/pdex/todo.txt @@ -0,0 +1,39 @@ +TODO List for PDE X +=================== + +This would also be a break down of my thought process and ideas as I tackle +various tasks. Previously, a different todo file was used for GSoC 2013. + +Manindra Moharana (me@mkmoharana.com) + +[ ]: Todo, [x] : Done, ? : Undecided Todo, ! : Critical, + : Minor Todo + + +Critical Bugs +------------- + +[ ] Better memory management. #1 + +[ ] Breakpoints in classes. #47 + + +Normal Bugs +----------- +[ ] Sketch NOC 6_09: steer PVector, doesn't show completion. #68 + +[x] Sketch NOC 6_09: Classname in Template, doesn't scroll to decl. This is +happening due certain post processing offsets not being accounted for - "public void" + +Enhancements/New Features +------------------------- + +[ ] When viewing Outline View, instead of showing the beginning of the list, +it should select the current node element within which the cursor is presently positioned. + +[ ] Begin work on code snippets. + +[ ] JUnit Testing? + +[ ] Preferences panel + +[ ] Line Numbers