mirror of
https://github.com/processing/processing4.git
synced 2026-02-11 17:40:48 +01:00
Was in a poetic mood and all, but this lame bug had to ruin it all. Nevertheless, fixed
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user