From 7cac0a0d0dff85948c820a9d4525e81fb005fa99 Mon Sep 17 00:00:00 2001 From: Manindra Moharana Date: Thu, 20 Jun 2013 21:35:43 +0530 Subject: [PATCH] Forst shot at pde specific offset mapping. Not there yet. --- pdex/Todo, GSoC 2013.txt | 5 +- .../mode/experimental/ASTNodeWrapper.java | 93 ++++++++++++++++--- .../experimental/ErrorCheckerService.java | 2 +- 3 files changed, 84 insertions(+), 16 deletions(-) diff --git a/pdex/Todo, GSoC 2013.txt b/pdex/Todo, GSoC 2013.txt index 14526ce18..a690e2dec 100644 --- a/pdex/Todo, GSoC 2013.txt +++ b/pdex/Todo, GSoC 2013.txt @@ -16,7 +16,7 @@ x Completion for external classes - ArrayList, HashMap, etc. *! 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. -*! Should I implement wrapper for ASTNode? - possibly needed for code completion with compiled and non-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. *+ Differentiating between multiple statements on the same line. How to? @@ -34,7 +34,8 @@ First major hurdle is offset mapping 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. * This is precise upto a certain line. Once on a line, pde stuff have to be taken into consideration. x Edge case - multiple staetments in a single line -* PDE specific enhancements will also have to be tackled like int(), # literals. Although after being able to precisely locate ast nodes in a single line(with multiple statements per line), it seems this problem might not occur at all! Need to examine test cases further. +* 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 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. diff --git a/pdex/src/processing/mode/experimental/ASTNodeWrapper.java b/pdex/src/processing/mode/experimental/ASTNodeWrapper.java index 620d2ca78..b8ad65c16 100644 --- a/pdex/src/processing/mode/experimental/ASTNodeWrapper.java +++ b/pdex/src/processing/mode/experimental/ASTNodeWrapper.java @@ -2,6 +2,8 @@ package processing.mode.experimental; import java.util.Iterator; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.CompilationUnit; @@ -16,7 +18,7 @@ import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; import org.eclipse.jdt.core.dom.TypeDeclaration; public class ASTNodeWrapper { - private ASTNode node; + private ASTNode Node; private String label; @@ -36,7 +38,7 @@ public class ASTNodeWrapper { public ASTNodeWrapper(ASTNode node) { if (node == null) return; - this.node = node; + this.Node = node; label = getNodeAsString(node); if (label == null) label = node.toString(); @@ -52,9 +54,9 @@ public class ASTNodeWrapper { * node length} */ public int[] getJavaCodeOffsets() { - int nodeOffset = node.getStartPosition(), nodeLength = node + int nodeOffset = Node.getStartPosition(), nodeLength = Node .getLength(); - ASTNode thisNode = node; + ASTNode thisNode = Node; while (thisNode.getParent() != null) { if (getLineNumber(thisNode.getParent()) == lineNumber) { thisNode = thisNode.getParent(); @@ -63,7 +65,7 @@ public class ASTNodeWrapper { } } /* - * There's an edge case here - multiple staetments in a single line. + * There's an edge case here - multiple statements in a single line. * After identifying the statement with the line number, I'll have to * look at previous tree nodes in the same level for same line number. * The correct line start offset would be the line start offset of @@ -78,7 +80,7 @@ public class ASTNodeWrapper { Iterator it = thisNode .structuralPropertiesForType().iterator(); - + boolean flag = true; while (it.hasNext()) { StructuralPropertyDescriptor prop = (StructuralPropertyDescriptor) it .next(); @@ -87,15 +89,80 @@ public class ASTNodeWrapper { .getStructuralProperty(prop); for (ASTNode cnode : nodelist) { if (getLineNumber(cnode) == lineNumber) { - altStartPos = cnode.getStartPosition(); - // System.out.println("multi..."); - break; + if (flag) { + altStartPos = cnode.getStartPosition(); + // System.out.println("multi..."); + + flag = false; + } else { + if(cnode == Node){ + // loop only till the current node. + break; + } + // We've located the first node in the line. + // Now normalize offsets till Node + //altStartPos += normalizeOffsets(cnode); + + } + } } } } // System.out.println("Altspos " + altStartPos); - return new int[] { lineNumber,altStartPos , nodeOffset, nodeLength }; + return new int[] { lineNumber,altStartPos , nodeOffset, nodeLength + normalizeOffsets(Node) }; + } + + /** + * Returns the difference in offsets between pde and java versions of the ast + * node + * + * @param anode + * @return offset adjustment + */ + private int normalizeOffsets(ASTNode anode){ + String source = anode.toString().trim(); + System.out.println("Src: " + source); + int offset = 0; + String dataTypeFunc[] = { "Int", "Char", "Float", "Boolean", "Byte" }; + + for (String dataType : dataTypeFunc) { + String dataTypeRegexp = "\\bPApplet.parse" + dataType + "\\s*\\("; + Pattern pattern = Pattern.compile(dataTypeRegexp); + Matcher matcher = pattern.matcher(source); + + while (matcher.find()) { + System.out.print("Start index: " + matcher.start()); + System.out.println(" End index: " + matcher.end() + " "); + System.out.println("-->" + matcher.group() + "<--"); + offset = offset - ("PApplet.parse(").length(); + } + + + } + + // Find all #[web color] and replace with 0xff[webcolor] + // 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(source); + while (webMatcher.find()) { + // System.out.println("Found at: " + webMatcher.start()); + String found = source.substring(webMatcher.start(), webMatcher.end()); + // System.out.println("-> " + found); + source = webMatcher.replaceFirst("0xff" + found.substring(1)); + webMatcher = webPattern.matcher(source); + offset += 3; + } + + // Replace all color data types with int + // Regex, Y U SO powerful? + final String colorTypeRegex = "color(?![a-zA-Z0-9_])(?=\\[*)(?!(\\s*\\())"; + Pattern colorPattern = Pattern.compile(colorTypeRegex); + Matcher colorMatcher = colorPattern.matcher(source); + source = colorMatcher.replaceAll("int"); + System.out.println(source + "-Norm offset " + offset); + return offset; } /** @@ -107,7 +174,7 @@ public class ASTNodeWrapper { * int[3] are on TODO */ public int[] getPDECodeOffsets(ErrorCheckerService ecs) { - return ecs.JavaToPdeOffsets(lineNumber + 1, node.getStartPosition()); + return ecs.JavaToPdeOffsets(lineNumber + 1, Node.getStartPosition()); } public String toString() { @@ -115,7 +182,7 @@ public class ASTNodeWrapper { } public ASTNode getNode() { - return node; + return Node; } public String getLabel() { @@ -123,7 +190,7 @@ public class ASTNodeWrapper { } public int getNodeType() { - return node.getNodeType(); + return Node.getNodeType(); } public int getLineNumber() { diff --git a/pdex/src/processing/mode/experimental/ErrorCheckerService.java b/pdex/src/processing/mode/experimental/ErrorCheckerService.java index 0f97281a1..0a84df988 100644 --- a/pdex/src/processing/mode/experimental/ErrorCheckerService.java +++ b/pdex/src/processing/mode/experimental/ErrorCheckerService.java @@ -897,7 +897,7 @@ public class ErrorCheckerService implements Runnable{ * java source. And there's a difference between parsable and compilable. * XQPrerocessor.java makes this code compilable.
* Handles:
  • Removal of import statements
  • Conversion of int(), - * char(), etc to (int)(), (char)(), etc.
  • Replacing '#' with 0xff for + * char(), etc to PApplet.parseInt(), etc.
  • Replacing '#' with 0xff for * color representation
  • Converts all 'color' datatypes to int * (experimental)
  • Appends class declaration statement after determining * the mode the sketch is in - ACTIVE or STATIC