Was in a poetic mood and all, but this lame bug had to ruin it all. Nevertheless, fixed

This commit is contained in:
Manindra Moharana
2013-07-08 22:37:10 +05:30
parent 27a5eb7327
commit 6217be0227
4 changed files with 109 additions and 89 deletions

View File

@@ -11,11 +11,14 @@ Code Completion
The big stuff:
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.
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.
*! Recursive lookup for compiled(library) code!
*! 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.
*! May be I should just implement recursive find for compiled code first, see how it goes and hopefully it would give me some ideas about how to integrating the two.
*! May be I should just implement recursive find for compiled code first, see how it goes and hopefully it would give me some ideas about how to integrating the two.
- Making very good progress here. The elegance of recurion - Hats off!
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.

View File

@@ -669,11 +669,29 @@ public class ASTGenerator {
return ((FieldAccess) expression).getName();
} else if (expression instanceof QualifiedName) {
return ((QualifiedName) expression).getName();
}else if (expression instanceof MethodInvocation) {
return ((MethodInvocation) expression).getName();
}
System.out.println(" resolveChildExpression returning NULL for "
+ getNodeAsString(expression));
return null;
}
public static ASTNode resolveParentExpression(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();
}
System.out.println("resolveParentExpression returning NULL for "
+ getNodeAsString(expression));
return null;
}
public static TypeDeclaration getDefiningNode(ASTNode node) {
ASTNode parent = node.getParent();
@@ -685,7 +703,7 @@ public class ASTGenerator {
return (TypeDeclaration) parent;
}
public void updatePredictions(final String word, final int line) {
public void updatePredictions(final String word, final int line, final int lineStartNonWSOffset) {
SwingWorker worker = new SwingWorker() {
@Override
@@ -695,16 +713,16 @@ public class ASTGenerator {
protected void done() {
String word2 = word;
String word2 = ASTNodeWrapper.getJavaCode(word);
//After typing 'arg.' all members of arg type are to be listed. This one is a flag for it
boolean noCompare = false;
if (word2.endsWith(".")) {
// return all matches
word2 = word2.substring(0, word.length() - 1);
word2 = word2.substring(0, word2.length() - 1);
noCompare = true;
}
int lineNumber = line;
// Adjust line number for tabbed sketches
if (errorCheckerService != null) {
@@ -726,7 +744,7 @@ public class ASTGenerator {
parser.setKind(ASTParser.K_EXPRESSION);
parser.setSource(word2.toCharArray());
ASTNode testnode = parser.createAST(null);
//System.err.println("PREDICTION PARSER PROBLEMS: " + parser);
// Find closest ASTNode of the document to this word
System.err.print("Typed: " + word2 + "|");
nearestNode = findClosestNode(lineNumber, (ASTNode) compilationUnit.types()
@@ -912,10 +930,17 @@ public class ASTGenerator {
}
if(candidates.size() == 0){
System.out.println("candidates empty");
ClassMember expr = resolveExpression3rdParty(nearestNode, testnode, true);
String childExpr = resolveChildExpression(testnode)
.toString();
System.out.println("Child expression : " + childExpr);
if(!noCompare){
System.out.println("Original testnode " + getNodeAsString(testnode));
testnode = resolveParentExpression(testnode);
System.out.println("Corrected testnode " + getNodeAsString(testnode));
}
ClassMember expr = resolveExpression3rdParty(nearestNode, testnode, noCompare);
candidates = getMembersForType(expr,
resolveChildExpression(testnode)
.toString(), true, false);
childExpr, noCompare, false);
}
}
@@ -1201,7 +1226,7 @@ public class ASTGenerator {
private static ASTNode findClosestParentNode(int lineNumber, ASTNode node) {
Iterator<StructuralPropertyDescriptor> it = node
.structuralPropertiesForType().iterator();
//System.err.println("Props of " + node.getClass().getName());
System.err.println("Props of " + node.getClass().getName());
while (it.hasNext()) {
StructuralPropertyDescriptor prop = (StructuralPropertyDescriptor) it
.next();
@@ -1212,7 +1237,7 @@ public class ASTGenerator {
// .println(node.getStructuralProperty(prop) + " -> " + (prop));
if (node.getStructuralProperty(prop) instanceof ASTNode) {
ASTNode cnode = (ASTNode) node.getStructuralProperty(prop);
// System.out.println("Looking at " + getNodeAsString(cnode));
// System.out.println("Looking at " + getNodeAsString(cnode)+ " for line num " + lineNumber);
int cLineNum = ((CompilationUnit) cnode.getRoot())
.getLineNumber(cnode.getStartPosition() + cnode.getLength());
if (getLineNumber(cnode) <= lineNumber && lineNumber <= cLineNum) {
@@ -1228,7 +1253,7 @@ public class ASTGenerator {
for (ASTNode cnode : nodelist) {
int cLineNum = ((CompilationUnit) cnode.getRoot())
.getLineNumber(cnode.getStartPosition() + cnode.getLength());
// System.out.println("Looking at " + getNodeAsString(cnode));
// System.out.println("Looking at " + getNodeAsString(cnode)+ " for line num " + lineNumber);
if (getLineNumber(cnode) <= lineNumber && lineNumber <= cLineNum) {
return findClosestParentNode(lineNumber, cnode);
}
@@ -1272,81 +1297,6 @@ public class ASTGenerator {
return null;
}
// static DefaultMutableTreeNode findNodeBS(DefaultMutableTreeNode tree,
// int lineNumber, String name,
// int elementOffset) {
// if (tree.getUserObject() == null)
// return null;
//
// ASTNodeWrapper node = ((ASTNodeWrapper) tree.getUserObject());
//
// if (node.getLineNumber() == lineNumber) {
// System.out.println("Located line " + lineNumber + " , " + tree);
// if (name == null)
// return tree;
// else
// return findOnLine(tree, lineNumber, name, elementOffset, node.getNode()
// .getStartPosition());
// }
//
// int low = 0, high = tree.getChildCount() - 1, mid = (high + low) / 2;
// DefaultMutableTreeNode tnode = null;
// while (low <= high) {
// mid = (high + low) / 2;
// tnode = (DefaultMutableTreeNode) tree.getChildAt(mid);
// node = ((ASTNodeWrapper) tnode.getUserObject());
// if (node.getLineNumber() == lineNumber) {
// System.out.println("Located line " + lineNumber + " , " + tnode);
// if (name == null)
// return tnode;
// else
// return findOnLine(tnode, lineNumber, name, elementOffset, node
// .getNode().getStartPosition());
// } else if (lineNumber < node.getLineNumber()) {
// high = mid - 1;
// } else {
// if (high - mid <= 1) {
// if (lineNumber > ((ASTNodeWrapper) ((DefaultMutableTreeNode) tree
// .getChildAt(high)).getUserObject()).getLineNumber()) //high l no.
// low = mid + 1;
// else
//
// high = mid - 1;
// }
// low = mid + 1;
// }
//
// }
//
// if (!tnode.isLeaf())
// return findNodeBS(tnode, lineNumber, name, elementOffset);
// else
// return tnode;
//
// //System.out.println("visiting: " + getNodeAsString(node.getNode()) + " on line "+node.getLineNumber());
// if (node.getLineNumber() == lineNumber) {
// System.err.println("Located line: " + node.toString());
// if (name == null) // name ==null, finds any node equal to line
// // number
// {
// System.out.println("Closest node at line: " + lineNumber);
// return tree;
// } else
// return findOnLine(tree, lineNumber, name, elementOffset, node.getNode()
// .getStartPosition());
//
// } else if (!tree.isLeaf()) {
// for (int i = 0; i < tree.getChildCount(); i++) {
// .getChildAt(i),
// lineNumber, name, elementOffset);
// if (node2 != null)
// return node2;
// }
// }
//
// return null;
// }
public DefaultMutableTreeNode getAST() {
return codeTree;
}

View File

@@ -373,6 +373,72 @@ public class ASTNodeWrapper {
public int getLineNumber() {
return lineNumber;
}
/**
* Applies pde enhancements to code.
* TODO: Code reuse happening here. :\
* @param source
* @return
*/
public static String getJavaCode(String source){
System.out.println("Src:" + source);
String sourceAlt = new String(source);
// Find all #[web color]
// Should be 6 digits only.
final String webColorRegexp = "#{1}[A-F|a-f|0-9]{6}\\W";
Pattern webPattern = Pattern.compile(webColorRegexp);
Matcher webMatcher = webPattern.matcher(sourceAlt);
while (webMatcher.find()) {
// System.out.println("Found at: " + webMatcher.start());
// System.out.println("-> " + found);
}
// Find all color data types
final String colorTypeRegex = "color(?![a-zA-Z0-9_])(?=\\[*)(?!(\\s*\\())";
Pattern colorPattern = Pattern.compile(colorTypeRegex);
Matcher colorMatcher = colorPattern.matcher(sourceAlt);
while (colorMatcher.find()) {
// System.out.print("Start index: " + colorMatcher.start());
// System.out.println(" End index: " + colorMatcher.end() + " ");
// System.out.println("-->" + colorMatcher.group() + "<--");
}
// Find all int(), char()
String dataTypeFunc[] = { "int", "char", "float", "boolean", "byte" };
for (String dataType : dataTypeFunc) {
String dataTypeRegexp = "\\b" + dataType + "\\s*\\(";
Pattern pattern = Pattern.compile(dataTypeRegexp);
Matcher matcher = pattern.matcher(sourceAlt);
while (matcher.find()) {
// System.out.print("Start index: " + matcher.start());
// System.out.println(" End index: " + matcher.end() + " ");
// System.out.println("-->" + matcher.group() + "<--");
}
matcher.reset();
sourceAlt = matcher.replaceAll("PApplet.parse"
+ Character.toUpperCase(dataType.charAt(0)) + dataType.substring(1)
+ "(");
}
// replace with 0xff[webcolor] and others
webMatcher = webPattern.matcher(sourceAlt);
while (webMatcher.find()) {
// System.out.println("Found at: " + webMatcher.start());
String found = sourceAlt.substring(webMatcher.start(), webMatcher.end());
// System.out.println("-> " + found);
sourceAlt = webMatcher.replaceFirst("0xff" + found.substring(1));
webMatcher = webPattern.matcher(sourceAlt);
}
colorMatcher = colorPattern.matcher(sourceAlt);
sourceAlt = colorMatcher.replaceAll("int");
System.out.println("Converted:"+sourceAlt);
return sourceAlt;
}
private static int getLineNumber(ASTNode node) {
return ((CompilationUnit) node.getRoot()).getLineNumber(node

View File

@@ -290,7 +290,7 @@ public class TextArea extends JEditTextArea {
if (word.endsWith("."))
word = word.substring(0, word.length() - 1);
errorCheckerService.astGenerator.updatePredictions(word, line
+ errorCheckerService.mainClassOffset);
+ errorCheckerService.mainClassOffset,0);
return word;
}
// if (keyChar == KeyEvent.VK_BACK_SPACE || keyChar == KeyEvent.VK_DELETE)
@@ -353,8 +353,9 @@ public class TextArea extends JEditTextArea {
word = word.trim();
// if (word.endsWith("."))
// word = word.substring(0, word.length() - 1);
int lineStartNonWSOffset = 0;
errorCheckerService.astGenerator.updatePredictions(word, line
+ errorCheckerService.mainClassOffset);
+ errorCheckerService.mainClassOffset,lineStartNonWSOffset);
//showSuggestionLater();
return word;