mirror of
https://github.com/processing/processing4.git
synced 2026-02-04 06:09:17 +01:00
ECS: remove ASTNodeWrapper and old offset mapping
This commit is contained in:
@@ -436,6 +436,7 @@ public class ASTGenerator {
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case ASTNode.QUALIFIED_NAME:
|
||||
QualifiedName qn = (QualifiedName) astNode;
|
||||
ASTNode temp2 = findDeclaration2(qn.getName(), nearestNode);
|
||||
@@ -752,7 +753,7 @@ public class ASTGenerator {
|
||||
|
||||
log("Looking in the classloader for " + className);
|
||||
// TODO: get this from last code check result
|
||||
List<ImportStatement> imports = Collections.emptyList(); //errorCheckerService.getProgramImports();
|
||||
List<ImportStatement> imports = errorCheckerService.latestResult.programImports;
|
||||
|
||||
for (ImportStatement impS : imports) {
|
||||
String temp = impS.getPackageName();
|
||||
@@ -776,7 +777,7 @@ public class ASTGenerator {
|
||||
}
|
||||
|
||||
// TODO: get this from last code check result
|
||||
List<ImportStatement> codeFolderImports = Collections.emptyList();
|
||||
List<ImportStatement> codeFolderImports = errorCheckerService.latestResult.codeFolderImports;
|
||||
for (ImportStatement impS : codeFolderImports) {
|
||||
String temp = impS.getPackageName();
|
||||
if (impS.isStarredImport()) { // case of starred import: pkg.foo.*
|
||||
@@ -798,26 +799,28 @@ public class ASTGenerator {
|
||||
//log("Doesn't exist in (code folder) imp package: " + impS.getImportName());
|
||||
}
|
||||
|
||||
// PdePreprocessor p = new PdePreprocessor(null);
|
||||
PdePreprocessor p = editor.createPreprocessor(null);
|
||||
for (String impS : p.getCoreImports()) {
|
||||
tehClass = loadClass(impS.substring(0,impS.length()-1) + className);
|
||||
// TODO: get this from last code check result
|
||||
List<ImportStatement> coreAndDefaultImports =
|
||||
errorCheckerService.latestResult.coreAndDefaultImports;
|
||||
for (ImportStatement impS : coreAndDefaultImports) {
|
||||
String temp = impS.getPackageName();
|
||||
if (impS.isStarredImport()) { // case of starred import: pkg.foo.*
|
||||
if (className.indexOf('.') == -1) {
|
||||
temp = impS.getPackageName() + "." + className;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else { // case of class import: pkg.foo.MyClass
|
||||
if (!impS.getClassName().equals(className)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
tehClass = loadClass(temp);
|
||||
if (tehClass != null) {
|
||||
log(tehClass.getName() + " located.");
|
||||
return tehClass;
|
||||
}
|
||||
//log("Doesn't exist in package: " + impS);
|
||||
}
|
||||
|
||||
for (String impS : p.getDefaultImports()) {
|
||||
if(className.equals(impS) || impS.endsWith(className)){
|
||||
tehClass = loadClass(impS);
|
||||
if (tehClass != null) {
|
||||
log(tehClass.getName() + " located.");
|
||||
return tehClass;
|
||||
}
|
||||
// log("Doesn't exist in package: " + impS);
|
||||
}
|
||||
//log("Doesn't exist in (code folder) imp package: " + impS.getImportName());
|
||||
}
|
||||
|
||||
// And finally, the daddy
|
||||
@@ -837,9 +840,8 @@ public class ASTGenerator {
|
||||
if (className != null) {
|
||||
try {
|
||||
// TODO: get the class loader from the last code check result
|
||||
/*tehClass = Class.forName(className, false,
|
||||
errorCheckerService.getSketchClassLoader());*/
|
||||
tehClass = Class.forName(className);
|
||||
tehClass = Class.forName(className, false,
|
||||
errorCheckerService.latestResult.classLoader);
|
||||
} catch (ClassNotFoundException e) {
|
||||
//log("Doesn't exist in package: ");
|
||||
}
|
||||
@@ -982,17 +984,12 @@ public class ASTGenerator {
|
||||
}
|
||||
|
||||
|
||||
public String getLabelForASTNode(int lineNumber, String name, int offset) {
|
||||
return getASTNodeAt(lineNumber, name, offset, false).getLabel();
|
||||
//return "";
|
||||
}
|
||||
|
||||
protected String getLabelIfType(ASTNodeWrapper node, SimpleName sn){
|
||||
ASTNode current = node.getNode().getParent();
|
||||
protected String getLabelIfType(ASTNode node){
|
||||
ASTNode current = node.getParent();
|
||||
String type = "";
|
||||
StringBuilder fullName = new StringBuilder();
|
||||
Stack<String> parents = new Stack<>();
|
||||
String simpleName = (sn == null) ? node.getNode().toString() : sn.toString();
|
||||
String simpleName = node.toString();
|
||||
switch (node.getNodeType()) {
|
||||
case ASTNode.TYPE_DECLARATION:
|
||||
case ASTNode.METHOD_DECLARATION:
|
||||
@@ -1007,8 +1004,8 @@ public class ASTGenerator {
|
||||
fullName.append(parents.pop()).append(".");
|
||||
}
|
||||
fullName.append(simpleName);
|
||||
if (node.getNode() instanceof MethodDeclaration) {
|
||||
MethodDeclaration md = (MethodDeclaration) node.getNode();
|
||||
if (node instanceof MethodDeclaration) {
|
||||
MethodDeclaration md = (MethodDeclaration) node;
|
||||
if (!md.isConstructor())
|
||||
type = md.getReturnType2().toString();
|
||||
fullName.append('(');
|
||||
@@ -1025,22 +1022,22 @@ public class ASTGenerator {
|
||||
fullName.deleteCharAt(fullName.length() - 1);
|
||||
fullName.append(')');
|
||||
}
|
||||
else if(node.getNode() instanceof FieldDeclaration){
|
||||
type = ((FieldDeclaration) node.getNode()).getType().toString();
|
||||
else if(node instanceof FieldDeclaration){
|
||||
type = ((FieldDeclaration) node).getType().toString();
|
||||
}
|
||||
int x = fullName.indexOf(".");
|
||||
fullName.delete(0, x + 1);
|
||||
return type + " " + fullName;
|
||||
|
||||
case ASTNode.SINGLE_VARIABLE_DECLARATION:
|
||||
SingleVariableDeclaration svd = (SingleVariableDeclaration)node.getNode();
|
||||
SingleVariableDeclaration svd = (SingleVariableDeclaration)node;
|
||||
return svd.getType() + " " + svd.getName();
|
||||
|
||||
case ASTNode.VARIABLE_DECLARATION_STATEMENT:
|
||||
return ((VariableDeclarationStatement) node.getNode()).getType() + " "
|
||||
return ((VariableDeclarationStatement) node).getType() + " "
|
||||
+ simpleName;
|
||||
case ASTNode.VARIABLE_DECLARATION_EXPRESSION:
|
||||
return ((VariableDeclarationExpression) node.getNode()).getType() + " "
|
||||
return ((VariableDeclarationExpression) node).getType() + " "
|
||||
+ simpleName;
|
||||
default:
|
||||
break;
|
||||
@@ -1059,7 +1056,8 @@ public class ASTGenerator {
|
||||
* @param scrollOnly
|
||||
* @return
|
||||
*/
|
||||
public ASTNodeWrapper getASTNodeAt(int lineNumber, String name, int offset,
|
||||
// TODO: nuke this in favor of NodeFinder
|
||||
public ASTNode getASTNodeAt(int lineNumber, String name, int offset,
|
||||
boolean scrollOnly) {
|
||||
|
||||
// Convert tab based pde line number to actual line number
|
||||
@@ -1087,8 +1085,9 @@ public class ASTGenerator {
|
||||
|
||||
// Obtain correspondin java code at that line, match offsets
|
||||
if (lineNode != null) {
|
||||
String pdeCodeLine = errorCheckerService.getPdeCodeAtLine(editor
|
||||
.getSketch().getCurrentCodeIndex(), lineNumber);
|
||||
// TODO
|
||||
String pdeCodeLine = ""; //errorCheckerService.getPdeCodeAtLine(editor
|
||||
// .getSketch().getCurrentCodeIndex(), lineNumber);
|
||||
String javaCodeLine = getJavaSourceCodeLine(pdeLineNumber);
|
||||
|
||||
// log(lineNumber + " Original Line num.\nPDE :" + pdeCodeLine);
|
||||
@@ -1115,8 +1114,7 @@ public class ASTGenerator {
|
||||
case ASTNode.FIELD_DECLARATION:
|
||||
|
||||
case ASTNode.VARIABLE_DECLARATION_FRAGMENT:
|
||||
decl = lineNode.getParent();
|
||||
return new ASTNodeWrapper(decl, "");
|
||||
return lineNode.getParent();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1129,8 +1127,7 @@ public class ASTGenerator {
|
||||
decl = findDeclaration((SimpleName) simpName);
|
||||
if (decl != null) {
|
||||
// Base.loge("DECLA: " + decl.getClass().getName());
|
||||
nodeLabel = getLabelIfType(new ASTNodeWrapper(decl),
|
||||
(SimpleName) simpName);
|
||||
nodeLabel = getLabelIfType(decl);
|
||||
//retLabelString = getNodeAsString(decl);
|
||||
} else {
|
||||
if (scrollOnly) {
|
||||
@@ -1166,18 +1163,11 @@ public class ASTGenerator {
|
||||
* since it contains all the properties.
|
||||
*/
|
||||
ASTNode simpName2 = getNodeName(decl, nameOfNode);
|
||||
// Base.loge("FINAL String decl: " + getNodeAsString(decl));
|
||||
// Base.loge("FINAL String label: " + getNodeAsString(simpName2));
|
||||
//errorCheckerService.highlightNode(simpName2);
|
||||
ASTNodeWrapper declWrap = new ASTNodeWrapper(simpName2, nodeLabel);
|
||||
//errorCheckerService.highlightNode(declWrap);
|
||||
if (!declWrap.highlightNode(editor)) {
|
||||
Messages.loge("Highlighting failed.");
|
||||
}
|
||||
// TODO: highlight ASTNode (should not be here though)
|
||||
}
|
||||
|
||||
// Return the declaration wrapped as ASTNodeWrapper
|
||||
return new ASTNodeWrapper(decl, nodeLabel);
|
||||
return decl;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1234,52 +1224,7 @@ public class ASTGenerator {
|
||||
return ((CompilationUnit) node.getRoot()).getLineNumber(pos);
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// traversal2();
|
||||
// }
|
||||
//
|
||||
// public static void traversal2() {
|
||||
// ASTParser parser = ASTParser.newParser(AST.JLS4);
|
||||
// String source = readFile("/media/quarkninja/Work/TestStuff/low.java");
|
||||
//// String source = "package decl; \npublic class ABC{\n int ret(){\n}\n}";
|
||||
// parser.setSource(source.toCharArray());
|
||||
// parser.setKind(ASTParser.K_COMPILATION_UNIT);
|
||||
//
|
||||
// Map<String, String> options = JavaCore.getOptions();
|
||||
//
|
||||
// JavaCore.setComplianceOptions(JavaCore.VERSION_1_6, options);
|
||||
// options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6);
|
||||
// parser.setCompilerOptions(options);
|
||||
//
|
||||
// CompilationUnit cu = (CompilationUnit) parser.createAST(null);
|
||||
// log(CompilationUnit.propertyDescriptors(AST.JLS4).size());
|
||||
//
|
||||
// DefaultMutableTreeNode astTree = new DefaultMutableTreeNode("CompilationUnit");
|
||||
// Base.loge("Errors: " + cu.getProblems().length);
|
||||
// visitRecur(cu, astTree);
|
||||
// Base.log("" + astTree.getChildCount());
|
||||
//
|
||||
// try {
|
||||
// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
// JFrame frame2 = new JFrame();
|
||||
// JTree jtree = new JTree(astTree);
|
||||
// frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
// frame2.setBounds(new Rectangle(100, 100, 460, 620));
|
||||
// JScrollPane sp = new JScrollPane();
|
||||
// sp.setViewportView(jtree);
|
||||
// frame2.add(sp);
|
||||
// frame2.setVisible(true);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// ASTNode found = NodeFinder.perform(cu, 468, 5);
|
||||
// if (found != null) {
|
||||
// Base.log(found.toString());
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// TODO: nuke and reimplement
|
||||
protected void refactorIt(String newName){
|
||||
String selText = lastClickedWord == null ? getSelectedText()
|
||||
: lastClickedWord;
|
||||
@@ -1316,22 +1261,22 @@ public class ASTGenerator {
|
||||
//int offsetsMap[][][] = new int[defCU.getChildCount()][2][];
|
||||
int pdeOffsets[][] = new int[defCU.getChildCount()][3];
|
||||
for (int i = 0; i < defCU.getChildCount(); i++) {
|
||||
ASTNodeWrapper awrap = (ASTNodeWrapper) ((DefaultMutableTreeNode) (defCU
|
||||
ASTNode awrap = (ASTNode) ((DefaultMutableTreeNode) (defCU
|
||||
.getChildAt(i))).getUserObject();
|
||||
int ans[] = errorCheckerService.calculateTabIndexAndLineNumber(awrap
|
||||
/*int ans[] = errorCheckerService.calculateTabIndexAndLineNumber(awrap
|
||||
.getLineNumber());
|
||||
pdeOffsets[i][0] = ans[0];
|
||||
pdeOffsets[i][1] = ans[1];
|
||||
pdeOffsets[i][2] = awrap.getPDECodeOffsetForSN(this);
|
||||
pdeOffsets[i][2] = awrap.getPDECodeOffsetForSN(this);*/
|
||||
}
|
||||
|
||||
editor.startCompoundEdit();
|
||||
for (int i = 0; i < defCU.getChildCount(); i++) {
|
||||
ASTNodeWrapper awrap = (ASTNodeWrapper) ((DefaultMutableTreeNode) (defCU
|
||||
ASTNode awrap = (ASTNode) ((DefaultMutableTreeNode) (defCU
|
||||
.getChildAt(i))).getUserObject();
|
||||
// correction for pde enhancements related displacement on a line
|
||||
int off = 0;
|
||||
if (lineOffsetDisplacement.get(awrap.getLineNumber()) != null) {
|
||||
/*if (lineOffsetDisplacement.get(awrap.getLineNumber()) != null) {
|
||||
off = lineOffsetDisplacement.get(awrap.getLineNumber());
|
||||
|
||||
lineOffsetDisplacement.put(awrap.getLineNumber(),
|
||||
@@ -1339,7 +1284,7 @@ public class ASTGenerator {
|
||||
} else {
|
||||
lineOffsetDisplacement.put(awrap.getLineNumber(),
|
||||
lineOffsetDisplacementConst);
|
||||
}
|
||||
}*/
|
||||
// Base.loge(getNodeAsString(awrap.getNode()) + ", T:" + pdeOffsets[i][0]
|
||||
// + ", L:" + pdeOffsets[i][1] + ", O:" + pdeOffsets[i][2]);
|
||||
// TODO: fix this line after fixing offsets in node wrapper
|
||||
@@ -1393,7 +1338,7 @@ public class ASTGenerator {
|
||||
}
|
||||
|
||||
protected String lastClickedWord = null;
|
||||
protected ASTNodeWrapper lastClickedWordNode = null;
|
||||
protected ASTNode lastClickedWordNode = null;
|
||||
|
||||
public String getLastClickedWord() {
|
||||
return lastClickedWord;
|
||||
@@ -1421,22 +1366,22 @@ public class ASTGenerator {
|
||||
+ ", "
|
||||
+ (ta.getSelectionStop() - ta.getLineStartOffset(line)));
|
||||
int offwhitespace = ta.getLineStartNonWhiteSpaceOffset(line);
|
||||
ASTNodeWrapper wnode;
|
||||
if (lastClickedWord == null || lastClickedWordNode.getNode() == null) {
|
||||
ASTNode wnode;
|
||||
if (lastClickedWord == null || lastClickedWordNode == null) {
|
||||
wnode = getASTNodeAt(line + errorCheckerService.mainClassOffset, selText,
|
||||
ta.getSelectionStart() - offwhitespace, false);
|
||||
}
|
||||
else{
|
||||
wnode = lastClickedWordNode;
|
||||
}
|
||||
if(wnode.getNode() == null){
|
||||
if(wnode == null){
|
||||
return null;
|
||||
}
|
||||
Messages.loge("Gonna find all occurrences of " + getNodeAsString(wnode.getNode()));
|
||||
Messages.loge("Gonna find all occurrences of " + getNodeAsString(wnode));
|
||||
|
||||
//If wnode is a constructor, find the TD instead.
|
||||
if (wnode.getNodeType() == ASTNode.METHOD_DECLARATION) {
|
||||
MethodDeclaration md = (MethodDeclaration) wnode.getNode();
|
||||
MethodDeclaration md = (MethodDeclaration) wnode;
|
||||
ASTNode node = md.getParent();
|
||||
while (node != null) {
|
||||
if (node instanceof TypeDeclaration) {
|
||||
@@ -1449,14 +1394,14 @@ public class ASTGenerator {
|
||||
TypeDeclaration td = (TypeDeclaration) node;
|
||||
if(td.getName().toString().equals(md.getName().toString())){
|
||||
Messages.loge("Renaming constructor of " + getNodeAsString(td));
|
||||
wnode = new ASTNodeWrapper(td);
|
||||
wnode = td;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DefaultMutableTreeNode defCU =
|
||||
new DefaultMutableTreeNode(new ASTNodeWrapper(wnode.getNode(), selText));
|
||||
dfsNameOnly(defCU, wnode.getNode(), selText);
|
||||
new DefaultMutableTreeNode(wnode);
|
||||
dfsNameOnly(defCU, wnode, selText);
|
||||
|
||||
// Reverse the list obtained via dfs
|
||||
Stack<Object> tempS = new Stack<>();
|
||||
@@ -1493,9 +1438,7 @@ public class ASTGenerator {
|
||||
if (node.getStructuralProperty(prop) instanceof ASTNode) {
|
||||
ASTNode cnode = (ASTNode) node.getStructuralProperty(prop);
|
||||
if (isAddableASTNode(cnode)) {
|
||||
ctnode = new DefaultMutableTreeNode(
|
||||
new ASTNodeWrapper((ASTNode) node
|
||||
.getStructuralProperty(prop)));
|
||||
ctnode = new DefaultMutableTreeNode(node.getStructuralProperty(prop));
|
||||
tnode.add(ctnode);
|
||||
visitRecur(cnode, ctnode);
|
||||
}
|
||||
@@ -1509,7 +1452,7 @@ public class ASTGenerator {
|
||||
node.getStructuralProperty(prop);
|
||||
for (ASTNode cnode : nodelist) {
|
||||
if (isAddableASTNode(cnode)) {
|
||||
ctnode = new DefaultMutableTreeNode(new ASTNodeWrapper(cnode));
|
||||
ctnode = new DefaultMutableTreeNode(cnode);
|
||||
tnode.add(ctnode);
|
||||
visitRecur(cnode, ctnode);
|
||||
} else {
|
||||
@@ -1531,16 +1474,12 @@ public class ASTGenerator {
|
||||
temp.push((DefaultMutableTreeNode) cnode.getChildAt(i));
|
||||
}
|
||||
|
||||
if(!(cnode.getUserObject() instanceof ASTNodeWrapper))
|
||||
if(!(cnode.getUserObject() instanceof ASTNode))
|
||||
continue;
|
||||
ASTNodeWrapper awnode = (ASTNodeWrapper) cnode.getUserObject();
|
||||
ASTNode awnode = (ASTNode) cnode.getUserObject();
|
||||
// log("Visiting: " + getNodeAsString(awnode.getNode()));
|
||||
if(isInstanceOfType(awnode.getNode(), decl, name)){
|
||||
int val[] = errorCheckerService
|
||||
.JavaToPdeOffsets(awnode.getLineNumber(), 0);
|
||||
tnode.add(new DefaultMutableTreeNode(new ASTNodeWrapper(awnode
|
||||
.getNode(), "Line " + (val[1] + 1) + " | Tab: "
|
||||
+ editor.getSketch().getCode(val[0]).getPrettyName())));
|
||||
if(isInstanceOfType(awnode, decl, name)){
|
||||
tnode.add(new DefaultMutableTreeNode(awnode));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1757,67 +1696,6 @@ public class ASTGenerator {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param node
|
||||
* @param offset
|
||||
* - from textarea painter
|
||||
* @param lineStartOffset
|
||||
* - obtained from findLineOfNode
|
||||
* @param name
|
||||
* @param root
|
||||
* @return
|
||||
*/
|
||||
public static ASTNode pinpointOnLine(ASTNode node, int offset,
|
||||
int lineStartOffset, String name) {
|
||||
//log("pinpointOnLine node class: " + node.getClass().getSimpleName());
|
||||
if (node instanceof SimpleName) {
|
||||
SimpleName sn = (SimpleName) node;
|
||||
//log(offset+ "off,pol " + getNodeAsString(sn));
|
||||
if ((lineStartOffset + offset) >= sn.getStartPosition()
|
||||
&& (lineStartOffset + offset) <= sn.getStartPosition()
|
||||
+ sn.getLength()) {
|
||||
if (sn.toString().equals(name)) {
|
||||
return sn;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
for (Object oprop : node.structuralPropertiesForType()) {
|
||||
StructuralPropertyDescriptor prop = (StructuralPropertyDescriptor) oprop;
|
||||
if (prop.isChildProperty() || prop.isSimpleProperty()) {
|
||||
if (node.getStructuralProperty(prop) != null) {
|
||||
if (node.getStructuralProperty(prop) instanceof ASTNode) {
|
||||
ASTNode retNode = pinpointOnLine((ASTNode) node
|
||||
.getStructuralProperty(prop),
|
||||
offset, lineStartOffset, name);
|
||||
if (retNode != null) {
|
||||
// Base.loge(11 + getNodeAsString(retNode));
|
||||
return retNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (prop.isChildListProperty()) {
|
||||
List<ASTNode> nodelist = (List<ASTNode>) node
|
||||
.getStructuralProperty(prop);
|
||||
for (ASTNode retNode : nodelist) {
|
||||
|
||||
ASTNode rr = pinpointOnLine(retNode, offset, lineStartOffset, name);
|
||||
if (rr != null) {
|
||||
// Base.loge(12 + getNodeAsString(rr));
|
||||
return rr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Base.loge("-1");
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Give this thing a {@link Name} instance - a {@link SimpleName} from the
|
||||
* ASTNode for ex, and it tries its level best to locate its declaration in
|
||||
@@ -2487,45 +2365,6 @@ public class ASTGenerator {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For any line or expression, finds the line start offset(java code).
|
||||
* @param node
|
||||
* @return
|
||||
*/
|
||||
public int getASTNodeLineStartOffset(ASTNode node){
|
||||
int nodeLineNo = getLineNumber(node);
|
||||
while(node.getParent() != null){
|
||||
if (getLineNumber(node.getParent()) == nodeLineNo) {
|
||||
node = node.getParent();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return node.getStartPosition();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For any node, finds various offsets (java code).
|
||||
*
|
||||
* @param node
|
||||
* @return int[]{line number, line number start offset, node start offset,
|
||||
* node length}
|
||||
*/
|
||||
public int[] getASTNodeAllOffsets(ASTNode node){
|
||||
int nodeLineNo = getLineNumber(node), nodeOffset = node.getStartPosition(), nodeLength = node
|
||||
.getLength();
|
||||
while(node.getParent() != null){
|
||||
if (getLineNumber(node.getParent()) == nodeLineNo) {
|
||||
node = node.getParent();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new int[]{nodeLineNo, node.getStartPosition(), nodeOffset,nodeLength};
|
||||
}
|
||||
|
||||
|
||||
static protected String getNodeAsString(ASTNode node) {
|
||||
if (node == null)
|
||||
return "NULL";
|
||||
@@ -2696,7 +2535,13 @@ public class ASTGenerator {
|
||||
ASTNode astRootNode = (ASTNode) errorCheckerService.getLatestCU().types().get(0);
|
||||
|
||||
// If the parsed code contains pde enhancements, take 'em out.
|
||||
String phrase = ASTNodeWrapper.getJavaCode(pdePhrase);
|
||||
// TODO: test this
|
||||
SourceMapping mapping = new SourceMapping();
|
||||
mapping.addAll(SourceUtils.replaceTypeConstructors(pdePhrase));
|
||||
mapping.addAll(SourceUtils.replaceHexLiterals(pdePhrase));
|
||||
mapping.addAll(SourceUtils.replaceColorRegex(pdePhrase));
|
||||
mapping.addAll(SourceUtils.fixFloatsRegex(pdePhrase));
|
||||
String phrase = mapping.apply(pdePhrase);
|
||||
|
||||
//After typing 'arg.' all members of arg type are to be listed. This one is a flag for it
|
||||
boolean noCompare = phrase.endsWith(".");
|
||||
@@ -3056,8 +2901,7 @@ public class ASTGenerator {
|
||||
}
|
||||
|
||||
ASTNode type0 = (ASTNode) cu.types().get(0);
|
||||
ASTNodeWrapper w = new ASTNodeWrapper(type0);
|
||||
DefaultMutableTreeNode codeTree = new DefaultMutableTreeNode(w);
|
||||
DefaultMutableTreeNode codeTree = new DefaultMutableTreeNode(type0);
|
||||
visitRecur(type0, codeTree);
|
||||
return codeTree;
|
||||
}
|
||||
@@ -3107,67 +2951,6 @@ public class ASTGenerator {
|
||||
}
|
||||
|
||||
|
||||
private void hideSuggestion() {
|
||||
((JavaTextArea) editor.getTextArea()).hideSuggestion();
|
||||
}
|
||||
|
||||
|
||||
public int javaCodeOffsetToLineStartOffset(int line, int jOffset){
|
||||
// Find the first node with this line number, return its offset - jOffset
|
||||
line = pdeLineNumToJavaLineNum(line);
|
||||
log("Looking for line: " + line + ", jOff " + jOffset);
|
||||
Stack<DefaultMutableTreeNode> temp = new Stack<>();
|
||||
temp.push(codeTree);
|
||||
|
||||
while (!temp.isEmpty()) {
|
||||
DefaultMutableTreeNode cnode = temp.pop();
|
||||
for (int i = 0; i < cnode.getChildCount(); i++) {
|
||||
temp.push((DefaultMutableTreeNode) cnode.getChildAt(i));
|
||||
}
|
||||
|
||||
if (!(cnode.getUserObject() instanceof ASTNodeWrapper))
|
||||
continue;
|
||||
ASTNodeWrapper awnode = (ASTNodeWrapper) cnode.getUserObject();
|
||||
// log("Visiting: " + getNodeAsString(awnode.getNode()));
|
||||
if (awnode.getLineNumber() == line) {
|
||||
log("First element with this line no is: " + awnode
|
||||
+ "LSO: " + (jOffset - awnode.getNode().getStartPosition()));
|
||||
return (jOffset - awnode.getNode().getStartPosition());
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts pde line number to java line number
|
||||
* @param pdeLineNum - pde line number
|
||||
* @return
|
||||
*/
|
||||
protected int pdeLineNumToJavaLineNum(int pdeLineNum){
|
||||
int javaLineNumber = pdeLineNum + errorCheckerService.getPdeImportsCount();
|
||||
// Adjust line number for tabbed sketches
|
||||
int codeIndex = editor.getSketch().getCodeIndex(editor.getCurrentTab());
|
||||
if (codeIndex > 0)
|
||||
for (int i = 0; i < codeIndex; i++) {
|
||||
SketchCode sc = editor.getSketch().getCode(i);
|
||||
int len = Util.countLines(sc.getProgram()) + 1;
|
||||
javaLineNumber += len;
|
||||
}
|
||||
return javaLineNumber;
|
||||
}
|
||||
|
||||
|
||||
public String getPDESourceCodeLine(int javaLineNumber) {
|
||||
Messages.log("* getPDESourceCodeLine");
|
||||
int res[] = errorCheckerService
|
||||
.calculateTabIndexAndLineNumber(javaLineNumber);
|
||||
if (res != null) {
|
||||
return errorCheckerService.getPdeCodeAtLine(res[0], res[1]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the java source code line at the given line number
|
||||
* @param javaLineNumber
|
||||
@@ -3195,35 +2978,6 @@ public class ASTGenerator {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the java source code line Element at the given line number.
|
||||
* The Element object stores the offset data, but not the actual line
|
||||
* of code.
|
||||
* @param javaLineNumber
|
||||
* @return
|
||||
*/
|
||||
public Element getJavaSourceCodeElement(int javaLineNumber) {
|
||||
Messages.log("* getJavaSourceCodeElement");
|
||||
try {
|
||||
PlainDocument javaSource = new PlainDocument();
|
||||
javaSource.insertString(0, errorCheckerService.latestResult.preprocessedCode, null);
|
||||
Element lineElement = javaSource.getDefaultRootElement()
|
||||
.getElement(javaLineNumber - 1);
|
||||
if (lineElement == null) {
|
||||
log("Couldn't fetch jlinenum " + javaLineNumber);
|
||||
return null;
|
||||
}
|
||||
// String javaLine = javaSource.getText(lineElement.getStartOffset(),
|
||||
// lineElement.getEndOffset()
|
||||
// - lineElement.getStartOffset());
|
||||
return lineElement;
|
||||
} catch (BadLocationException e) {
|
||||
Messages.loge(e + " in getJavaSourceCodeline() for jinenum: " + javaLineNumber);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// GUI ----------------------------------------------------------------------
|
||||
|
||||
@@ -3357,10 +3111,8 @@ public class ASTGenerator {
|
||||
DefaultMutableTreeNode tnode = (DefaultMutableTreeNode) showUsageTree
|
||||
.getLastSelectedPathComponent();
|
||||
|
||||
if (tnode.getUserObject() instanceof ASTNodeWrapper) {
|
||||
ASTNodeWrapper awrap = (ASTNodeWrapper) tnode.getUserObject();
|
||||
//errorCheckerService.highlightNode(awrap);
|
||||
awrap.highlightNode(editor);
|
||||
if (tnode.getUserObject() instanceof ASTNode) {
|
||||
// TODO: highlight ASTNode
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -3466,38 +3218,8 @@ public class ASTGenerator {
|
||||
}
|
||||
DefaultMutableTreeNode tnode =
|
||||
(DefaultMutableTreeNode) debugTree.getLastSelectedPathComponent();
|
||||
if (tnode.getUserObject() instanceof ASTNodeWrapper) {
|
||||
ASTNodeWrapper awrap = (ASTNodeWrapper) tnode.getUserObject();
|
||||
awrap.highlightNode(editor);
|
||||
// errorCheckerService.highlightNode(awrap);
|
||||
|
||||
//--
|
||||
try {
|
||||
int javaLineNumber = getLineNumber(awrap.getNode());
|
||||
int pdeOffs[] = editor.getErrorChecker()
|
||||
.calculateTabIndexAndLineNumber(javaLineNumber);
|
||||
PlainDocument javaSource = new PlainDocument();
|
||||
javaSource.insertString(0, editor.getErrorChecker()
|
||||
.latestResult.preprocessedCode, null);
|
||||
Element lineElement = javaSource.getDefaultRootElement()
|
||||
.getElement(javaLineNumber - 1);
|
||||
if (lineElement == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String javaLine = javaSource.getText(lineElement.getStartOffset(),
|
||||
lineElement.getEndOffset()
|
||||
- lineElement.getStartOffset());
|
||||
editor.getSketch().setCurrentCode(pdeOffs[0]);
|
||||
String pdeLine = editor.getLineText(pdeOffs[1]);
|
||||
//String lookingFor = nodeName.toString();
|
||||
//log(lookingFor + ", " + nodeName.getStartPosition());
|
||||
log("JL " + javaLine + " LSO " + lineElement.getStartOffset() + ","
|
||||
+ lineElement.getEndOffset());
|
||||
log("PL " + pdeLine);
|
||||
} catch (BadLocationException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
if (tnode.getUserObject() instanceof ASTNode) {
|
||||
// TODO: highlight ASTNode, print some info maybe
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,827 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
Copyright (c) 2012-15 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package processing.mode.java.pdex;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.Element;
|
||||
import javax.swing.text.PlainDocument;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.ExpressionStatement;
|
||||
import org.eclipse.jdt.core.dom.FieldDeclaration;
|
||||
import org.eclipse.jdt.core.dom.Javadoc;
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
import org.eclipse.jdt.core.dom.QualifiedName;
|
||||
import org.eclipse.jdt.core.dom.SimpleName;
|
||||
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
|
||||
import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
|
||||
import org.eclipse.jdt.core.dom.Type;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
|
||||
import processing.app.Base;
|
||||
import processing.app.Messages;
|
||||
import processing.mode.java.JavaEditor;
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper class for ASTNode objects
|
||||
* @author Manindra Moharana <me@mkmoharana.com>
|
||||
*
|
||||
*/
|
||||
public class ASTNodeWrapper {
|
||||
private ASTNode node;
|
||||
private String label;
|
||||
private int lineNumber;
|
||||
|
||||
|
||||
/*
|
||||
* TODO: Every ASTNode object in ASTGenerator.codetree is stored as a
|
||||
* ASTNodeWrapper instance. So how resource heavy would it be to store a
|
||||
* pointer to ECS in every instance of ASTNodeWrapper? Currently I will rather
|
||||
* pass an ECS pointer in the argument when I need to access a method which
|
||||
* requires a method defined in ECS, i.e, only on demand.
|
||||
* Bad design choice for ECS methods? IDK, yet.
|
||||
*/
|
||||
|
||||
public ASTNodeWrapper(ASTNode node) {
|
||||
if (node == null){
|
||||
return;
|
||||
}
|
||||
this.node = node;
|
||||
label = getNodeAsString(node);
|
||||
if (label == null)
|
||||
label = node.toString();
|
||||
lineNumber = getLineNumber(node);
|
||||
label += " | Line " + lineNumber;
|
||||
//apiLevel = 0;
|
||||
}
|
||||
|
||||
public ASTNodeWrapper(ASTNode node, String label){
|
||||
if (node == null){
|
||||
return;
|
||||
}
|
||||
this.node = node;
|
||||
if(label != null)
|
||||
this.label = label;
|
||||
else{
|
||||
label = getNodeAsString(node);
|
||||
if (label == null)
|
||||
label = node.toString();
|
||||
|
||||
label += " | Line " + lineNumber;
|
||||
}
|
||||
lineNumber = getLineNumber(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* For this node, finds various offsets (java code).
|
||||
* Note that line start offset for this node is int[2] - int[1]
|
||||
* @return int[]{line number, line number start offset, node start offset,
|
||||
* node length}
|
||||
*/
|
||||
public int[] getJavaCodeOffsets(ErrorCheckerService ecs) {
|
||||
int nodeOffset = node.getStartPosition(), nodeLength = node
|
||||
.getLength();
|
||||
Messages.log("0.nodeOffset " + nodeOffset);
|
||||
ASTNode thisNode = node;
|
||||
while (thisNode.getParent() != null) {
|
||||
if (getLineNumber(thisNode.getParent()) == lineNumber) {
|
||||
thisNode = thisNode.getParent();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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
|
||||
* the first node with this line number.
|
||||
*
|
||||
* Using linear search for now. P.S: Eclipse AST iterators are messy.
|
||||
* TODO: binary search might improve speed by 0.001%?
|
||||
*/
|
||||
|
||||
int altStartPos = thisNode.getStartPosition();
|
||||
Messages.log("1.Altspos " + altStartPos);
|
||||
thisNode = thisNode.getParent();
|
||||
Javadoc jd = null;
|
||||
|
||||
/*
|
||||
* There's another case that needs to be handled. If a TD, MD or FD
|
||||
* contains javadoc comments(multi or single line) the starting position
|
||||
* of the javadoc is treated as the beginning of the declaration by the AST parser.
|
||||
* But that's clearly not what we need. The true decl begins after the javadoc ends.
|
||||
* So this offset needs to be found carefully and stored in altStartPos
|
||||
*
|
||||
*/
|
||||
if (thisNode instanceof TypeDeclaration) {
|
||||
jd = ((TypeDeclaration) thisNode).getJavadoc();
|
||||
altStartPos = getJavadocOffset((TypeDeclaration) thisNode);
|
||||
Messages.log("Has t jdoc " + ((TypeDeclaration) thisNode).getJavadoc());
|
||||
} else if (thisNode instanceof MethodDeclaration) {
|
||||
altStartPos = getJavadocOffset((MethodDeclaration) thisNode);
|
||||
jd = ((MethodDeclaration) thisNode).getJavadoc();
|
||||
Messages.log("Has m jdoc " + jd);
|
||||
} else if (thisNode instanceof FieldDeclaration) {
|
||||
FieldDeclaration fd = ((FieldDeclaration) thisNode);
|
||||
jd = fd.getJavadoc();
|
||||
Messages.log("Has f jdoc " + fd.getJavadoc());
|
||||
altStartPos = getJavadocOffset(fd);
|
||||
//nodeOffset = ((VariableDeclarationFragment)(fd.fragments().get(0))).getName().getStartPosition();
|
||||
}
|
||||
|
||||
if (jd == null) {
|
||||
Messages.log("Visiting children of node " + getNodeAsString(thisNode));
|
||||
@SuppressWarnings("unchecked")
|
||||
Iterator<StructuralPropertyDescriptor> it =
|
||||
thisNode.structuralPropertiesForType().iterator();
|
||||
boolean flag = true;
|
||||
while (it.hasNext()) {
|
||||
StructuralPropertyDescriptor prop = it.next();
|
||||
if (prop.isChildListProperty()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<ASTNode> nodelist = (List<ASTNode>)
|
||||
thisNode.getStructuralProperty(prop);
|
||||
Messages.log("prop " + prop);
|
||||
for (ASTNode cnode : nodelist) {
|
||||
Messages.log("Visiting node " + getNodeAsString(cnode));
|
||||
if (getLineNumber(cnode) == lineNumber) {
|
||||
if (flag) {
|
||||
altStartPos = cnode.getStartPosition();
|
||||
// log("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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Messages.log("Altspos " + altStartPos);
|
||||
}
|
||||
|
||||
int pdeoffsets[] = getPDECodeOffsets(ecs);
|
||||
String pdeCode = ecs.getPdeCodeAtLine(pdeoffsets[0],pdeoffsets[1] - 1).trim();
|
||||
int vals[] = createOffsetMapping(ecs, pdeCode,nodeOffset - altStartPos,nodeLength);
|
||||
if (vals != null)
|
||||
return new int[] {
|
||||
lineNumber, nodeOffset + vals[0] - altStartPos, vals[1] };
|
||||
else {// no offset mapping needed
|
||||
Messages.log("joff[1] = " + (nodeOffset - altStartPos));
|
||||
return new int[] { lineNumber, nodeOffset - altStartPos, nodeLength };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When FD has javadoc attached, the beginning of FD is marked as the
|
||||
* start of the javadoc. This kind of screws things when trying to locate
|
||||
* the exact name of the FD. So, offset compensations...
|
||||
*
|
||||
* @param fd
|
||||
* @return
|
||||
*/
|
||||
private int getJavadocOffset(FieldDeclaration fd){
|
||||
@SuppressWarnings("unchecked")
|
||||
List<ASTNode> list = fd.modifiers();
|
||||
SimpleName sn = (SimpleName) getNode();
|
||||
|
||||
Type tp = fd.getType();
|
||||
int lineNum = getLineNumber(sn);
|
||||
Messages.log("SN "+sn + ", " + lineNum);
|
||||
for (ASTNode astNode : list) {
|
||||
if(getLineNumber(astNode) == lineNum) {
|
||||
Messages.log("first node in that line " + astNode);
|
||||
Messages.log("diff " + (sn.getStartPosition() - astNode.getStartPosition()));
|
||||
return (astNode.getStartPosition());
|
||||
}
|
||||
}
|
||||
if(getLineNumber(fd.getType()) == lineNum) {
|
||||
Messages.log("first node in that line " + tp);
|
||||
Messages.log("diff " + (sn.getStartPosition() - tp.getStartPosition()));
|
||||
return (tp.getStartPosition());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* When MD has javadoc attached, the beginning of FD is marked as the
|
||||
* start of the javadoc. This kind of screws things when trying to locate
|
||||
* the exact name of the MD. So, offset compensations...
|
||||
*
|
||||
* @param md
|
||||
* @return
|
||||
*/
|
||||
private int getJavadocOffset(MethodDeclaration md) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<ASTNode> list = md.modifiers();
|
||||
SimpleName sn = (SimpleName) getNode();
|
||||
int lineNum = getLineNumber(sn);
|
||||
Messages.log("SN " + sn + ", " + lineNum);
|
||||
|
||||
for (ASTNode astNode : list) {
|
||||
if (getLineNumber(astNode) == lineNum) {
|
||||
Messages.log("first node in that line " + astNode);
|
||||
Messages.log("diff " + (sn.getStartPosition() - astNode.getStartPosition()));
|
||||
return (astNode.getStartPosition());
|
||||
}
|
||||
}
|
||||
|
||||
if (!md.isConstructor()) {
|
||||
Type tp = md.getReturnType2();
|
||||
if (getLineNumber(tp) == lineNum) {
|
||||
Messages.log("first node in that line " + tp);
|
||||
Messages.log("diff " + (sn.getStartPosition() - tp.getStartPosition()));
|
||||
return (tp.getStartPosition());
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* When TD has javadoc attached, the beginning of FD is marked as the
|
||||
* start of the javadoc. This kind of screws things when trying to locate
|
||||
* the exact name of the TD. So, offset compensations...
|
||||
*
|
||||
* @param td
|
||||
* @return
|
||||
*/
|
||||
private int getJavadocOffset(TypeDeclaration td){
|
||||
// TODO: This isn't perfect yet. Class \n \n \n className still breaks it.. :'(
|
||||
@SuppressWarnings("unchecked")
|
||||
List<ASTNode> list = td.modifiers();
|
||||
SimpleName sn = (SimpleName) getNode();
|
||||
|
||||
int lineNum = getLineNumber(sn);
|
||||
Messages.log("SN "+sn + ", " + lineNum);
|
||||
for (ASTNode astNode : list) {
|
||||
if (getLineNumber(astNode) == lineNum) {
|
||||
Messages.log("first node in that line " + astNode);
|
||||
Messages.log("diff " + (sn.getStartPosition() - astNode.getStartPosition()));
|
||||
return (astNode.getStartPosition());
|
||||
}
|
||||
}
|
||||
|
||||
if (td.getJavadoc() != null){
|
||||
Messages.log("diff "
|
||||
+ (td.getJavadoc().getStartPosition() + td.getJavadoc().getLength() + 1));
|
||||
return (td.getJavadoc().getStartPosition() + td.getJavadoc().getLength() + 1);
|
||||
}
|
||||
Messages.log("getJavadocOffset(TypeDeclaration td) "+sn + ", found nothing. Meh.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the difference in pde and java code offsets
|
||||
* @param source
|
||||
* @param inpOffset
|
||||
* @param nodeLen
|
||||
* @return int[0] - difference in start offset, int[1] - node length
|
||||
*/
|
||||
private int[] createOffsetMapping(ErrorCheckerService ecs, String source, int inpOffset, int nodeLen) {
|
||||
|
||||
int ret[][] = getOffsetMapping(ecs, source);
|
||||
if(ret == null){
|
||||
// no offset mapping needed
|
||||
return null;
|
||||
}
|
||||
int javaCodeMap[] = ret[0];
|
||||
int pdeCodeMap[] = ret[1];
|
||||
int pi = 1, pj = 1;
|
||||
pj = 0;
|
||||
pi = 0;
|
||||
int count = 1;
|
||||
// first find the java code index
|
||||
pj = inpOffset;
|
||||
|
||||
int startIndex = javaCodeMap[pj];
|
||||
|
||||
// find beginning
|
||||
while (pdeCodeMap[pi] != startIndex && pi < pdeCodeMap.length)
|
||||
pi++;
|
||||
int startoffDif = pi - pj;
|
||||
int stopindex = javaCodeMap[pj + nodeLen - 1];
|
||||
Messages.log(startIndex + "SI,St" + stopindex + "sod " + startoffDif);
|
||||
|
||||
// count till stopindex
|
||||
while (pdeCodeMap[pi] < stopindex && pi < pdeCodeMap.length) {
|
||||
pi++;
|
||||
count++;
|
||||
}
|
||||
|
||||
// log("PDE maps from " + pdeeCodeMap[pi]);
|
||||
|
||||
Messages.log("pde len " + count);
|
||||
return new int[] { startoffDif, count };
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates offset mapping between java and pde code
|
||||
*
|
||||
* @param source
|
||||
* @return int[0] - java code offsets, int[1] = pde code offsets
|
||||
*/
|
||||
public int[][] getOffsetMapping(ErrorCheckerService ecs, String source) {
|
||||
|
||||
/*
|
||||
* This is some tricky shiz. So detailed explanation follows:
|
||||
*
|
||||
* The main issue here is that pde enhancements like color vars, # literals
|
||||
* and int() type casting deviate from standard java. But I need to exact
|
||||
* index matching for pde and java versions of snippets.For ex:
|
||||
* "color col = #ffaadd;" <-PDE version
|
||||
* "int col = 0xffffaadd;" <-Converted to Java
|
||||
*
|
||||
* For exact index mapping, I need to know at which indices either is
|
||||
* deviating from the other and by what amount. Turns out, it isn't quite
|
||||
* easy.(1) First I take the pde version of the code as an argument(pde
|
||||
* version fetched from the editor directly). I then find all instances
|
||||
* which need to be converted to pure java, marking those indices and the
|
||||
* index correction needed. (2) Now all java conversions are applied after
|
||||
* marking the offsets. This ensures that the index order isn't disturbed by
|
||||
* one at a time conversions as done in preprocessCode() in ECS. Took me
|
||||
* sometime to figure out this was a bug. (3) Next I create a table(two
|
||||
* separate arrays) which allows me to look it up for matching any index
|
||||
* between pde or java version of the snippet. This also lets me find out
|
||||
* any difference in length between both versions.
|
||||
*
|
||||
* Keep in mind though, dark magic was involved in creating the final lookup
|
||||
* table.
|
||||
*
|
||||
* TODO: This is a work in progress. There may be more bugs here in hiding.
|
||||
*/
|
||||
|
||||
Messages.log("Src:" + source);
|
||||
// Instead of converting pde into java, how can I simply extract the same source
|
||||
// from the java code? Think. TODO
|
||||
String sourceAlt = new String(source);
|
||||
String sourceJava;
|
||||
synchronized (ecs.astGenerator) {
|
||||
sourceJava = ecs.astGenerator.getJavaSourceCodeLine(lineNumber);
|
||||
}
|
||||
TreeMap<Integer, Integer> offsetmap = new TreeMap<Integer, Integer>();
|
||||
|
||||
if(sourceJava.trim().startsWith("public") && !source.startsWith("public")){
|
||||
offsetmap.put(0,6);
|
||||
//TODO: This is a temp fix. You GOTTA rewrite offset matching
|
||||
}
|
||||
// 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()) {
|
||||
// log("Found at: " + webMatcher.start());
|
||||
// log("-> " + found);
|
||||
offsetmap.put(webMatcher.end() - 1, 3);
|
||||
}
|
||||
|
||||
// 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());
|
||||
// log(" End index: " + colorMatcher.end() + " ");
|
||||
// log("-->" + colorMatcher.group() + "<--");
|
||||
offsetmap.put(colorMatcher.end() - 1, -2);
|
||||
}
|
||||
|
||||
// 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());
|
||||
// log(" End index: " + matcher.end() + " ");
|
||||
// log("-->" + matcher.group() + "<--");
|
||||
offsetmap.put(matcher.end() - 1, ("PApplet.parse").length());
|
||||
}
|
||||
matcher.reset();
|
||||
sourceAlt = matcher.replaceAll("PApplet.parse"
|
||||
+ Character.toUpperCase(dataType.charAt(0)) + dataType.substring(1)
|
||||
+ "(");
|
||||
|
||||
}
|
||||
if(offsetmap.isEmpty()){
|
||||
Messages.log("No offset matching needed.");
|
||||
return null;
|
||||
}
|
||||
// replace with 0xff[webcolor] and others
|
||||
webMatcher = webPattern.matcher(sourceAlt);
|
||||
while (webMatcher.find()) {
|
||||
// log("Found at: " + webMatcher.start());
|
||||
String found = sourceAlt.substring(webMatcher.start(), webMatcher.end());
|
||||
// log("-> " + found);
|
||||
sourceAlt = webMatcher.replaceFirst("0xff" + found.substring(1));
|
||||
webMatcher = webPattern.matcher(sourceAlt);
|
||||
}
|
||||
|
||||
colorMatcher = colorPattern.matcher(sourceAlt);
|
||||
sourceAlt = colorMatcher.replaceAll("int");
|
||||
|
||||
Messages.log("From direct source: ");
|
||||
// sourceAlt = sourceJava;
|
||||
Messages.log(sourceAlt);
|
||||
|
||||
|
||||
// Create code map. Beware! Dark magic ahead.
|
||||
int javaCodeMap[] = new int[source.length() * 2];
|
||||
int pdeCodeMap[] = new int[source.length() * 2];
|
||||
int pi = 1, pj = 1;
|
||||
int keySum = 0;
|
||||
for (Integer key : offsetmap.keySet()) {
|
||||
for (; pi < key +keySum; pi++) {
|
||||
javaCodeMap[pi] = javaCodeMap[pi - 1] + 1;
|
||||
}
|
||||
for (; pj < key; pj++) {
|
||||
pdeCodeMap[pj] = pdeCodeMap[pj - 1] + 1;
|
||||
}
|
||||
|
||||
Messages.log(key + ":" + offsetmap.get(key));
|
||||
|
||||
int kval = offsetmap.get(key);
|
||||
if (kval > 0) {
|
||||
// repeat java offsets
|
||||
pi--;
|
||||
pj--;
|
||||
for (int i = 0; i < kval; i++, pi++, pj++) {
|
||||
if (pi > 1 && pj > 1) {
|
||||
javaCodeMap[pi] = javaCodeMap[pi - 1];
|
||||
pdeCodeMap[pj] = pdeCodeMap[pj - 1] + 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// repeat pde offsets
|
||||
pi--;
|
||||
pj--;
|
||||
for (int i = 0; i < -kval; i++, pi++, pj++) {
|
||||
if (pi > 1 && pj > 1) {
|
||||
javaCodeMap[pi] = javaCodeMap[pi - 1] + 1;
|
||||
pdeCodeMap[pj] = pdeCodeMap[pj - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// after each adjustment, the key values need to keep
|
||||
// up with changed offset
|
||||
keySum += kval;
|
||||
}
|
||||
|
||||
javaCodeMap[pi] = javaCodeMap[pi - 1] + 1;
|
||||
pdeCodeMap[pj] = pdeCodeMap[pj - 1] + 1;
|
||||
|
||||
while (pi < sourceAlt.length()) {
|
||||
javaCodeMap[pi] = javaCodeMap[pi - 1] + 1;
|
||||
pi++;
|
||||
}
|
||||
while (pj < source.length()) {
|
||||
pdeCodeMap[pj] = pdeCodeMap[pj - 1] + 1;
|
||||
pj++;
|
||||
}
|
||||
|
||||
if (Base.DEBUG) {
|
||||
// debug o/p
|
||||
for (int i = 0; i < pdeCodeMap.length; i++) {
|
||||
if (pdeCodeMap[i] > 0 || javaCodeMap[i] > 0 || i == 0) {
|
||||
if (i < source.length())
|
||||
System.out.print(source.charAt(i));
|
||||
System.out.print(pdeCodeMap[i] + " - " + javaCodeMap[i]);
|
||||
if (i < sourceAlt.length())
|
||||
System.out.print(sourceAlt.charAt(i));
|
||||
System.out.print(" <-[" + i + "]");
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
return new int[][] { javaCodeMap, pdeCodeMap };
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Highlight the ASTNode in the editor, if it's of type
|
||||
* SimpleName
|
||||
* @param editor
|
||||
* @return - true if highlighting was successful
|
||||
*/
|
||||
public boolean highlightNode(JavaEditor editor){
|
||||
if (!(node instanceof SimpleName)) {
|
||||
return false;
|
||||
}
|
||||
SimpleName nodeName = (SimpleName) node;
|
||||
try {
|
||||
//TODO: Redundant code. See ASTGenerator.getJavaSourceCodeline()
|
||||
int javaLineNumber = getLineNumber(nodeName);
|
||||
int pdeOffs[] = editor.getErrorChecker().calculateTabIndexAndLineNumber(javaLineNumber);
|
||||
PlainDocument javaSource = new PlainDocument();
|
||||
javaSource.insertString(0, editor.getErrorChecker().latestResult.preprocessedCode, null);
|
||||
Element lineElement = javaSource.getDefaultRootElement()
|
||||
.getElement(javaLineNumber-1);
|
||||
if(lineElement == null) {
|
||||
Messages.log(lineNumber + " line element null while highlighting " + nodeName);
|
||||
return false;
|
||||
}
|
||||
|
||||
String javaLine = javaSource.getText(lineElement.getStartOffset(),
|
||||
lineElement.getEndOffset()
|
||||
- lineElement.getStartOffset());
|
||||
editor.getSketch().setCurrentCode(pdeOffs[0]);
|
||||
String pdeLine = editor.getLineText(pdeOffs[1]);
|
||||
String lookingFor = nodeName.toString();
|
||||
Messages.log(lookingFor + ", " + nodeName.getStartPosition());
|
||||
Messages.log(javaLineNumber +" JL " + javaLine + " LSO " + lineElement.getStartOffset() + ","
|
||||
+ lineElement.getEndOffset());
|
||||
Messages.log(pdeOffs[1] + " PL " + pdeLine);
|
||||
if (!javaLine.contains(lookingFor) || !pdeLine.contains(lookingFor)) {
|
||||
Messages.loge("Logical error in highLightNode(). Please file a bug report.");
|
||||
return false;
|
||||
}
|
||||
|
||||
OffsetMatcher ofm = new OffsetMatcher(pdeLine, javaLine);
|
||||
int highlightStart = ofm.getPdeOffForJavaOff(nodeName.getStartPosition()
|
||||
- lineElement.getStartOffset(),
|
||||
nodeName.getLength());
|
||||
if (highlightStart == -1) {
|
||||
Messages.loge("Logical error in highLightNode() during offset matching. " +
|
||||
"Please file a bug report.");
|
||||
return false;
|
||||
}
|
||||
int lso = editor.getTextArea().getLineStartOffset(pdeOffs[1]);
|
||||
highlightStart += lso;
|
||||
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);
|
||||
int count = 0, index = 0;
|
||||
int lsto = lineElement.getStartOffset();
|
||||
while(matcher.find()){
|
||||
count++;
|
||||
//log(matcher.start() + lsto);
|
||||
if(lsto + matcher.start() == nodeName.getStartPosition())
|
||||
break;
|
||||
}
|
||||
log("count=" + count);
|
||||
index = 0;
|
||||
// find the same name in the pde line by its index and get its offsets
|
||||
matcher = toFind.matcher(pdeLine);
|
||||
while(matcher.find()){
|
||||
count--;
|
||||
if(count == 0){
|
||||
log("Found on pde line lso: " + matcher.start());
|
||||
index = matcher.end();
|
||||
break;
|
||||
}
|
||||
}
|
||||
log("pde lso " + (index - lookingFor.length()));
|
||||
|
||||
int lso = astGenerator.editor.ta.getLineStartOffset(pdeOffs[1]);
|
||||
astGenerator.editor.setSelection(lso + index - lookingFor.length(), lso
|
||||
+ index);
|
||||
*/
|
||||
return true;
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
Messages.loge("BLE in highLightNode() for " + nodeName);
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets offset mapping between java and pde code
|
||||
* int[0][x] stores the java code offset and
|
||||
* int[1][x] is the corresponding offset in pde code
|
||||
* @param ecs
|
||||
* @return int[0] - java code offset, int[1] - pde code offset
|
||||
*/
|
||||
public int[][] getOffsetMapping(ErrorCheckerService ecs){
|
||||
int pdeoffsets[] = getPDECodeOffsets(ecs);
|
||||
String pdeCode = ecs.getPdeCodeAtLine(pdeoffsets[0],pdeoffsets[1] - 1).trim();
|
||||
return getOffsetMapping(ecs, pdeCode);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ecs
|
||||
* - ErrorCheckerService instance
|
||||
* @return int[0] - tab number, int[1] - line number in the int[0] tab, int[2]
|
||||
* - line start offset, int[3] - offset from line start int[2] and
|
||||
* int[3] are on TODO
|
||||
*/
|
||||
public int[] getPDECodeOffsets(ErrorCheckerService ecs) {
|
||||
return ecs.JavaToPdeOffsets(lineNumber + 1, node.getStartPosition());
|
||||
}
|
||||
|
||||
public int getPDECodeOffsetForSN(ASTGenerator astGen){
|
||||
if (node instanceof SimpleName) {
|
||||
Element lineElement = astGen.getJavaSourceCodeElement(lineNumber);
|
||||
Messages.log("Line element off " + lineElement.getStartOffset());
|
||||
OffsetMatcher ofm = new OffsetMatcher(astGen.getPDESourceCodeLine(lineNumber),
|
||||
astGen.getJavaSourceCodeLine(lineNumber));
|
||||
//log("");
|
||||
int pdeOffset = ofm.getPdeOffForJavaOff(node.getStartPosition()
|
||||
- lineElement.getStartOffset(), node.toString().length());
|
||||
return pdeOffset;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public ASTNode getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public int getNodeType() {
|
||||
return node.getNodeType();
|
||||
}
|
||||
|
||||
public int getLineNumber() {
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies pde enhancements to code.
|
||||
* TODO: Code reuse happening here. :\
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public static String getJavaCode(String source){
|
||||
Messages.log("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()) {
|
||||
// log("Found at: " + webMatcher.start());
|
||||
// log("-> " + 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());
|
||||
// log(" End index: " + colorMatcher.end() + " ");
|
||||
// log("-->" + 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());
|
||||
// log(" End index: " + matcher.end() + " ");
|
||||
// log("-->" + 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()) {
|
||||
// log("Found at: " + webMatcher.start());
|
||||
String found = sourceAlt.substring(webMatcher.start(), webMatcher.end());
|
||||
// log("-> " + found);
|
||||
sourceAlt = webMatcher.replaceFirst("0xff" + found.substring(1));
|
||||
webMatcher = webPattern.matcher(sourceAlt);
|
||||
}
|
||||
|
||||
colorMatcher = colorPattern.matcher(sourceAlt);
|
||||
sourceAlt = colorMatcher.replaceAll("int");
|
||||
|
||||
Messages.log("Converted:"+sourceAlt);
|
||||
return sourceAlt;
|
||||
}
|
||||
|
||||
private static int getLineNumber(ASTNode node) {
|
||||
return ((CompilationUnit) node.getRoot()).getLineNumber(node
|
||||
.getStartPosition());
|
||||
}
|
||||
|
||||
/*private static int getLineNumber2(ASTNode thisNode) {
|
||||
int jdocOffset = 0; Javadoc jd = null;
|
||||
if(thisNode instanceof TypeDeclaration){
|
||||
jd = ((TypeDeclaration)thisNode).getJavadoc();
|
||||
log("Has t jdoc " + ((TypeDeclaration)thisNode).getJavadoc());
|
||||
} else if(thisNode instanceof MethodDeclaration){
|
||||
jd = ((MethodDeclaration)thisNode).getJavadoc();
|
||||
log("Has m jdoc " + jd);
|
||||
} else if(thisNode instanceof FieldDeclaration){
|
||||
jd = ((FieldDeclaration)thisNode).getJavadoc();
|
||||
log("Has f jdoc " + ((FieldDeclaration)thisNode).getJavadoc());
|
||||
}
|
||||
if(jd != null){
|
||||
jdocOffset = 1+jd.getLength();
|
||||
}
|
||||
log("ln 2 = " + ((CompilationUnit) thisNode.getRoot()).getLineNumber(thisNode
|
||||
.getStartPosition() + jdocOffset));
|
||||
return ((CompilationUnit) thisNode.getRoot()).getLineNumber(thisNode
|
||||
.getStartPosition() + jdocOffset);
|
||||
}*/
|
||||
|
||||
static private String getNodeAsString(ASTNode node) {
|
||||
if (node == null)
|
||||
return "NULL";
|
||||
String className = node.getClass().getName();
|
||||
int index = className.lastIndexOf(".");
|
||||
if (index > 0)
|
||||
className = className.substring(index + 1);
|
||||
|
||||
// if(node instanceof BodyDeclaration)
|
||||
// return className;
|
||||
|
||||
String value = className;
|
||||
|
||||
if (node instanceof TypeDeclaration)
|
||||
value = ((TypeDeclaration) node).getName().toString() + " | " + className;
|
||||
else if (node instanceof MethodDeclaration)
|
||||
value = ((MethodDeclaration) node).getName().toString() + " | "
|
||||
+ className;
|
||||
else if (node instanceof MethodInvocation)
|
||||
value = ((MethodInvocation) node).getName().toString() + " | "
|
||||
+ className;
|
||||
else if (node instanceof FieldDeclaration)
|
||||
value = ((FieldDeclaration) node).toString() + " FldDecl| ";
|
||||
else if (node instanceof SingleVariableDeclaration)
|
||||
value = ((SingleVariableDeclaration) node).getName() + " - "
|
||||
+ ((SingleVariableDeclaration) node).getType() + " | SVD ";
|
||||
else if (node instanceof ExpressionStatement)
|
||||
value = node.toString() + className;
|
||||
else if (node instanceof SimpleName)
|
||||
value = ((SimpleName) node).getFullyQualifiedName() + " | " + className;
|
||||
else if (node instanceof QualifiedName)
|
||||
value = node.toString() + " | " + className;
|
||||
else if (className.startsWith("Variable"))
|
||||
value = node.toString() + " | " + className;
|
||||
else if (className.endsWith("Type"))
|
||||
value = node.toString() + " |" + className;
|
||||
value += " [" + node.getStartPosition() + ","
|
||||
+ (node.getStartPosition() + node.getLength()) + "]";
|
||||
value += " Line: "
|
||||
+ ((CompilationUnit) node.getRoot()).getLineNumber(node
|
||||
.getStartPosition());
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -36,10 +36,12 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Executors;
|
||||
@@ -48,6 +50,7 @@ import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
@@ -956,19 +959,7 @@ public class ErrorCheckerService {
|
||||
sketch.getCode(p.getTabIndex()).getPrettyName(),
|
||||
Integer.toString(p.getLineNumber() + 1));
|
||||
// Added +1 because lineNumbers internally are 0-indexed
|
||||
|
||||
// //TODO: This is temporary
|
||||
// if (tempErrorLog.size() < 200) {
|
||||
// tempErrorLog.put(p.getMessage(), p.getIProblem());
|
||||
// }
|
||||
|
||||
}
|
||||
// table.updateColumns();
|
||||
|
||||
// DefaultTableModel tm =
|
||||
// new DefaultTableModel(errorData, XQErrorTable.columnNames);
|
||||
// editor.updateTable(tm);
|
||||
|
||||
} catch (Exception e) {
|
||||
Messages.loge("Exception at updateErrorTable()", e);
|
||||
e.printStackTrace();
|
||||
@@ -1014,215 +1005,45 @@ public class ErrorCheckerService {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Maps offset from java code to pde code. Returns a bunch of offsets as array
|
||||
*
|
||||
* @param line
|
||||
* - line number in java code
|
||||
* @param offset
|
||||
* - offset from the start of the 'line'
|
||||
* @return int[0] - tab number, int[1] - line number in the int[0] tab, int[2]
|
||||
* - line start offset, int[3] - offset from line start. int[2] and
|
||||
* int[3] are on TODO
|
||||
*/
|
||||
protected int[] JavaToPdeOffsets(int line, int offset) {
|
||||
|
||||
return new int[] { 0, 0 }; // TODO
|
||||
|
||||
/*
|
||||
int codeIndex = 0;
|
||||
|
||||
int x = line - mainClassOffset;
|
||||
if (x < 0) {
|
||||
// log("Negative line number "
|
||||
// + problem.getSourceLineNumber() + " , offset "
|
||||
// + mainClassOffset);
|
||||
x = line - 2; // Another -1 for 0 index
|
||||
if (x < programImports.size() && x >= 0) {
|
||||
ImportStatement is = programImports.get(x);
|
||||
// log(is.importName + ", " + is.tab + ", "
|
||||
// + is.lineNumber);
|
||||
return new int[] { 0, 0 }; // TODO
|
||||
} else {
|
||||
|
||||
// Some seriously ugly stray error, just can't find the source
|
||||
// line! Simply return first line for first tab.
|
||||
return new int[] { 0, 1 };
|
||||
}
|
||||
|
||||
protected static int mapJavaToTab(PreprocessedSketch sketch, int offset) {
|
||||
int tab = Arrays.binarySearch(sketch.tabStarts, offset);
|
||||
if (tab < 0) {
|
||||
tab = -(tab + 1) - 1;
|
||||
}
|
||||
|
||||
try {
|
||||
for (SketchCode sc : editor.getSketch().getCode()) {
|
||||
if (sc.isExtension("pde")) {
|
||||
int len;
|
||||
if (editor.getSketch().getCurrentCode().equals(sc)) {
|
||||
len = Util.countLines(sc.getDocumentText()) + 1;
|
||||
} else {
|
||||
len = Util.countLines(sc.getProgram()) + 1;
|
||||
}
|
||||
|
||||
// log("x,len, CI: " + x + "," + len + ","
|
||||
// + codeIndex);
|
||||
|
||||
if (x >= len) {
|
||||
|
||||
// We're in the last tab and the line count is greater
|
||||
// than the no.
|
||||
// of lines in the tab,
|
||||
if (codeIndex >= editor.getSketch().getCodeCount() - 1) {
|
||||
// log("Exceeds lc " + x + "," + len
|
||||
// + problem.toString());
|
||||
// x = len
|
||||
x = editor.getSketch().getCode(codeIndex)
|
||||
.getLineCount();
|
||||
// TODO: Obtain line having last non-white space
|
||||
// character in the code.
|
||||
break;
|
||||
} else {
|
||||
x -= len;
|
||||
codeIndex++;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (codeIndex >= editor.getSketch().getCodeCount()) {
|
||||
codeIndex = editor.getSketch().getCodeCount() - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error inside ErrorCheckerService.JavaToPdeOffset()");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new int[] { codeIndex, x };
|
||||
*/
|
||||
return sketch.tabStarts[tab];
|
||||
}
|
||||
|
||||
|
||||
protected String getPdeCodeAtLine(int tab, int linenumber){
|
||||
if(linenumber < 0) return null;
|
||||
editor.getSketch().setCurrentCode(tab);
|
||||
return editor.getTextArea().getLineText(linenumber);
|
||||
protected static int mapJavaToProcessing(PreprocessedSketch sketch, int offset) {
|
||||
SourceMapping syntaxMapping = sketch.syntaxMapping;
|
||||
SourceMapping compilationMapping = sketch.compilationMapping;
|
||||
|
||||
if (compilationMapping != null) {
|
||||
offset = compilationMapping.getInputOffset(offset);
|
||||
}
|
||||
|
||||
if (syntaxMapping != null) {
|
||||
offset = syntaxMapping.getInputOffset(offset);
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the tab number and line number of the error in that particular
|
||||
* tab. Provides mapping between pure java and pde code.
|
||||
*
|
||||
* @param javalineNumber
|
||||
* - int
|
||||
* @return int[0] - tab number, int[1] - line number
|
||||
*/
|
||||
protected int[] calculateTabIndexAndLineNumber(int javalineNumber) {
|
||||
|
||||
return new int[] { 0, 0 }; // TODO
|
||||
|
||||
/*
|
||||
|
||||
// String[] lines = {};// = PApplet.split(sourceString, '\n');
|
||||
int codeIndex = 0;
|
||||
|
||||
int x = javalineNumber - mainClassOffset;
|
||||
if (x < 0) {
|
||||
// log("Negative line number "
|
||||
// + problem.getSourceLineNumber() + " , offset "
|
||||
// + mainClassOffset);
|
||||
x = javalineNumber - 2; // Another -1 for 0 index
|
||||
if (x < programImports.size() && x >= 0) {
|
||||
ImportStatement is = programImports.get(x);
|
||||
// log(is.importName + ", " + is.tab + ", "
|
||||
// + is.lineNumber);
|
||||
return new int[] { 0, 0 }; // TODO
|
||||
} else {
|
||||
|
||||
// Some seriously ugly stray error, just can't find the source
|
||||
// line! Simply return first line for first tab.
|
||||
return new int[] { 0, 1 };
|
||||
}
|
||||
protected static int mapProcessingToJava(PreprocessedSketch sketch, int offset) {
|
||||
SourceMapping syntaxMapping = sketch.syntaxMapping;
|
||||
SourceMapping compilationMapping = sketch.compilationMapping;
|
||||
|
||||
if (syntaxMapping != null) {
|
||||
offset = syntaxMapping.getOutputOffset(offset);
|
||||
}
|
||||
|
||||
try {
|
||||
for (SketchCode sc : editor.getSketch().getCode()) {
|
||||
if (sc.isExtension("pde")) {
|
||||
int len;
|
||||
if (editor.getSketch().getCurrentCode().equals(sc)) {
|
||||
len = Util.countLines(sc.getDocumentText()) + 1;
|
||||
} else {
|
||||
len = Util.countLines(sc.getProgram()) + 1;
|
||||
}
|
||||
|
||||
// log("x,len, CI: " + x + "," + len + ","
|
||||
// + codeIndex);
|
||||
|
||||
if (x >= len) {
|
||||
|
||||
// We're in the last tab and the line count is greater
|
||||
// than the no.
|
||||
// of lines in the tab,
|
||||
if (codeIndex >= editor.getSketch().getCodeCount() - 1) {
|
||||
// log("Exceeds lc " + x + "," + len
|
||||
// + problem.toString());
|
||||
// x = len
|
||||
x = editor.getSketch().getCode(codeIndex)
|
||||
.getLineCount();
|
||||
// TODO: Obtain line having last non-white space
|
||||
// character in the code.
|
||||
break;
|
||||
} else {
|
||||
x -= len;
|
||||
codeIndex++;
|
||||
}
|
||||
} else {
|
||||
if (codeIndex >= editor.getSketch().getCodeCount()) {
|
||||
codeIndex = editor.getSketch().getCodeCount() - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("Things got messed up in ErrorCheckerService.calculateTabIndexAndLineNumber()");
|
||||
if (compilationMapping != null) {
|
||||
offset = compilationMapping.getOutputOffset(offset);
|
||||
}
|
||||
return new int[] { codeIndex, x };
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Now defunct.
|
||||
* The super method that highlights any ASTNode in the pde editor =D
|
||||
* @param awrap
|
||||
* @return true - if highlighting happened correctly.
|
||||
*/
|
||||
private boolean highlightNode(ASTNodeWrapper awrap){
|
||||
Messages.log("Highlighting: " + awrap);
|
||||
try {
|
||||
int pdeoffsets[] = awrap.getPDECodeOffsets(this);
|
||||
int javaoffsets[] = awrap.getJavaCodeOffsets(this);
|
||||
Messages.log("offsets: " +pdeoffsets[0] + "," +
|
||||
pdeoffsets[1]+ "," +javaoffsets[1]+ "," +
|
||||
javaoffsets[2]);
|
||||
scrollToErrorLine(editor, pdeoffsets[0],
|
||||
pdeoffsets[1],javaoffsets[1],
|
||||
javaoffsets[2]);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Messages.loge("Scrolling failed for " + awrap);
|
||||
// e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public boolean highlightNode(ASTNode node){
|
||||
ASTNodeWrapper awrap = new ASTNodeWrapper(node);
|
||||
return highlightNode(awrap);
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
@@ -1250,42 +1071,6 @@ public class ErrorCheckerService {
|
||||
editor.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method for scroll to a particular line in the PDE. Also highlights
|
||||
* the length of the text. Requires the editor instance as arguement.
|
||||
*
|
||||
* @param edt
|
||||
* @param tabIndex
|
||||
* @param lineNoInTab
|
||||
* - line number in the corresponding tab
|
||||
* @param lineStartOffset
|
||||
* - selection start offset(from line start non-whitespace offset)
|
||||
* @param length
|
||||
* - length of selection
|
||||
* @return - true, if scroll was successful
|
||||
*/
|
||||
protected static boolean scrollToErrorLine(Editor edt, int tabIndex, int lineNoInTab, int lineStartOffset, int length) {
|
||||
if (edt == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
edt.toFront();
|
||||
edt.getSketch().setCurrentCode(tabIndex);
|
||||
int lsno = edt.getTextArea()
|
||||
.getLineStartNonWhiteSpaceOffset(lineNoInTab - 1) + lineStartOffset;
|
||||
edt.setSelection(lsno, lsno + length);
|
||||
edt.getTextArea().scrollTo(lineNoInTab - 1, 0);
|
||||
edt.repaint();
|
||||
Messages.log(lineStartOffset + " LSO,len " + length);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println(e
|
||||
+ " : Error while selecting text in static scrollToErrorLine()");
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if import statements in the sketch have changed. If they have,
|
||||
|
||||
@@ -154,10 +154,9 @@ public class SketchOutline {
|
||||
if (soTree.getLastSelectedPathComponent() != null) {
|
||||
DefaultMutableTreeNode tnode = (DefaultMutableTreeNode) soTree
|
||||
.getLastSelectedPathComponent();
|
||||
if (tnode.getUserObject() instanceof ASTNodeWrapper) {
|
||||
ASTNodeWrapper awrap = (ASTNodeWrapper) tnode.getUserObject();
|
||||
awrap.highlightNode(editor);
|
||||
//errorCheckerService.highlightNode(awrap);
|
||||
if (tnode.getUserObject() instanceof ASTNode) {
|
||||
ASTNode awrap = (ASTNode) tnode.getUserObject();
|
||||
// TODO: highlight ASTNode
|
||||
close();
|
||||
}
|
||||
}
|
||||
@@ -274,11 +273,9 @@ public class SketchOutline {
|
||||
}
|
||||
DefaultMutableTreeNode tnode = (DefaultMutableTreeNode) soTree
|
||||
.getLastSelectedPathComponent();
|
||||
if (tnode.getUserObject() instanceof ASTNodeWrapper) {
|
||||
ASTNodeWrapper awrap = (ASTNodeWrapper) tnode.getUserObject();
|
||||
awrap.highlightNode(editor);
|
||||
// log(awrap);
|
||||
//errorCheckerService.highlightNode(awrap);
|
||||
if (tnode.getUserObject() instanceof ASTNode) {
|
||||
ASTNode awrap = (ASTNode) tnode.getUserObject();
|
||||
// TODO: highlight ASTNode
|
||||
close();
|
||||
}
|
||||
|
||||
@@ -313,27 +310,19 @@ public class SketchOutline {
|
||||
if (codetree == null)
|
||||
return;
|
||||
//log("Visi " + codetree + codetree.getUserObject().getClass().getSimpleName());
|
||||
if (!(codetree.getUserObject() instanceof ASTNodeWrapper))
|
||||
if (!(codetree.getUserObject() instanceof ASTNode))
|
||||
return;
|
||||
ASTNodeWrapper awnode = (ASTNodeWrapper) codetree.getUserObject(), aw2 = null;
|
||||
ASTNode awnode = (ASTNode) codetree.getUserObject(), aw2 = null;
|
||||
|
||||
if (awnode.getNode() instanceof TypeDeclaration) {
|
||||
aw2 = new ASTNodeWrapper( ((TypeDeclaration) awnode.getNode()).getName(),
|
||||
((TypeDeclaration) awnode.getNode()).getName()
|
||||
.toString());
|
||||
} else if (awnode.getNode() instanceof MethodDeclaration) {
|
||||
aw2 = new ASTNodeWrapper(
|
||||
((MethodDeclaration) awnode.getNode()).getName(),
|
||||
new CompletionCandidate(
|
||||
((MethodDeclaration) awnode
|
||||
.getNode()))
|
||||
.toString());
|
||||
} else if (awnode.getNode() instanceof FieldDeclaration) {
|
||||
FieldDeclaration fd = (FieldDeclaration) awnode.getNode();
|
||||
if (awnode instanceof TypeDeclaration) {
|
||||
aw2 = ((TypeDeclaration) awnode).getName();
|
||||
} else if (awnode instanceof MethodDeclaration) {
|
||||
aw2 = ((MethodDeclaration) awnode).getName();
|
||||
} else if (awnode instanceof FieldDeclaration) {
|
||||
FieldDeclaration fd = (FieldDeclaration) awnode;
|
||||
for (VariableDeclarationFragment vdf : (List<VariableDeclarationFragment>) fd.fragments()) {
|
||||
final String text = new CompletionCandidate(vdf).toString();
|
||||
DefaultMutableTreeNode newNode =
|
||||
new DefaultMutableTreeNode(new ASTNodeWrapper(vdf.getName(), text));
|
||||
new DefaultMutableTreeNode(vdf.getName());
|
||||
node.add(newNode);
|
||||
}
|
||||
return;
|
||||
@@ -380,11 +369,11 @@ public class SketchOutline {
|
||||
}
|
||||
|
||||
public Icon getTreeIcon(Object o) {
|
||||
if (((DefaultMutableTreeNode) o).getUserObject() instanceof ASTNodeWrapper) {
|
||||
ASTNodeWrapper awrap = (ASTNodeWrapper)
|
||||
if (((DefaultMutableTreeNode) o).getUserObject() instanceof ASTNode) {
|
||||
ASTNode awrap = (ASTNode)
|
||||
((DefaultMutableTreeNode) o).getUserObject();
|
||||
|
||||
int type = awrap.getNode().getParent().getNodeType();
|
||||
int type = awrap.getParent().getNodeType();
|
||||
if (type == ASTNode.METHOD_DECLARATION) {
|
||||
return methodIcon;
|
||||
} else if (type == ASTNode.TYPE_DECLARATION) {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package processing.mode.java.pdex;
|
||||
|
||||
import org.eclipse.jdt.core.dom.AST;
|
||||
import org.eclipse.jdt.core.dom.ASTParser;
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
@@ -180,52 +178,44 @@ public class SourceUtils {
|
||||
return edits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces non-ascii characters with their unicode escape sequences and
|
||||
* stuff. Used as it is from
|
||||
* processing.src.processing.mode.java.preproc.PdePreprocessor
|
||||
*
|
||||
* @param program
|
||||
* - Input String containing non ascii characters
|
||||
* @return String - Converted String
|
||||
*/
|
||||
public static String substituteUnicode(String program) {
|
||||
StringBuilder sb = new StringBuilder(program);
|
||||
substituteUnicode(sb);
|
||||
return sb.toString();
|
||||
|
||||
public static final Pattern COLOR_TYPE_REGEX =
|
||||
Pattern.compile("(?:^|^\\p{javaJavaIdentifierPart})(color)\\s(?!\\s*\\()",
|
||||
Pattern.MULTILINE | Pattern.UNICODE_CHARACTER_CLASS);
|
||||
|
||||
public static List<Edit> replaceColorRegex(CharSequence source) {
|
||||
final List<Edit> edits = new ArrayList<>();
|
||||
|
||||
Matcher matcher = COLOR_TYPE_REGEX.matcher(source);
|
||||
while (matcher.find()) {
|
||||
int offset = matcher.start(1);
|
||||
edits.add(Edit.replace(offset, 5, "int"));
|
||||
}
|
||||
|
||||
return edits;
|
||||
}
|
||||
|
||||
public static void substituteUnicode(StringBuilder p) {
|
||||
// check for non-ascii chars (these will be/must be in unicode format)
|
||||
int unicodeCount = 0;
|
||||
for (int i = 0; i < p.length(); i++) {
|
||||
if (p.charAt(i) > 127) {
|
||||
unicodeCount++;
|
||||
}
|
||||
}
|
||||
if (unicodeCount == 0) {
|
||||
return;
|
||||
}
|
||||
public static final Pattern NUMBER_LITERAL_REGEX =
|
||||
Pattern.compile("[-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?");
|
||||
|
||||
StringBuilder p2 = new StringBuilder(p.length() + 4 * unicodeCount);
|
||||
public static List<Edit> fixFloatsRegex(CharSequence source) {
|
||||
final List<Edit> edits = new ArrayList<>();
|
||||
|
||||
// if non-ascii chars are in there, convert to unicode escapes
|
||||
// add unicodeCount * 5.. replacing each unicode char
|
||||
// with six digit uXXXX sequence (xxxx is in hex)
|
||||
// (except for nbsp chars which will be a replaced with a space)
|
||||
for (int i = 0; i < p.length(); i++) {
|
||||
int c = p.charAt(i);
|
||||
if (c < 128) {
|
||||
p2.append(c);
|
||||
} else if (c == 160) { // unicode for non-breaking space
|
||||
p2.append(' ');
|
||||
} else if (c >= 128){
|
||||
p2.append("\\u").append(String.format("%04X", c));
|
||||
Matcher matcher = NUMBER_LITERAL_REGEX.matcher(source);
|
||||
while (matcher.find()) {
|
||||
int offset = matcher.start();
|
||||
int end = matcher.end();
|
||||
String group = matcher.group().toLowerCase();
|
||||
boolean isFloatingPoint = group.contains(".") || group.contains("e");
|
||||
boolean hasSuffix = end < source.length() &&
|
||||
Character.toLowerCase(source.charAt(end)) != 'f' &&
|
||||
Character.toLowerCase(source.charAt(end)) != 'd';
|
||||
if (isFloatingPoint && !hasSuffix) {
|
||||
edits.add(Edit.insert(offset, "f"));
|
||||
}
|
||||
}
|
||||
|
||||
p.setLength(0);
|
||||
p.append(p2);
|
||||
return edits;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user