mirror of
https://github.com/processing/processing4.git
synced 2026-02-04 06:09:17 +01:00
in search of the prediction prep deadlock on OS X (might be related to #3741)
This commit is contained in:
@@ -22,6 +22,7 @@ package processing.mode.java.pdex;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
@@ -753,7 +754,7 @@ public class ASTGenerator {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void trimCandidates(String newWord){
|
||||
protected void trimCandidates(String newWord) {
|
||||
ArrayList<CompletionCandidate> newCandidate = new ArrayList<CompletionCandidate>();
|
||||
newWord = newWord.toLowerCase();
|
||||
for (CompletionCandidate comp : candidates) {
|
||||
@@ -764,12 +765,8 @@ public class ASTGenerator {
|
||||
candidates = newCandidate;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of CompletionCandidates
|
||||
*/
|
||||
protected ArrayList<CompletionCandidate> candidates;
|
||||
protected List<CompletionCandidate> candidates;
|
||||
protected String lastPredictedWord = " ";
|
||||
//protected AtomicBoolean predictionsEnabled;
|
||||
protected int predictionMinLength = 2;
|
||||
|
||||
|
||||
@@ -784,6 +781,17 @@ public class ASTGenerator {
|
||||
*/
|
||||
public void preparePredictions(final String word, final int line,
|
||||
final int lineStartNonWSOffset) {
|
||||
// EventQueue.invokeLater(new Runnable() {
|
||||
// public void run() {
|
||||
// preparePredictions2(word, line, lineStartNonWSOffset);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// public void preparePredictions2(final String word, final int line,
|
||||
// final int lineStartNonWSOffset) {
|
||||
// System.out.println(EventQueue.isDispatchThread() + " " + predictionOngoing.get() + " " + (!JavaMode.codeCompletionsEnabled) + " " + (word.length() < predictionMinLength));
|
||||
// new Exception("preparing predictions " + EventQueue.isDispatchThread() + " " + predictionOngoing.get() + " " + (!JavaMode.codeCompletionsEnabled) + " " + (word.length() < predictionMinLength)).printStackTrace(System.out);
|
||||
if (predictionOngoing.get()) return;
|
||||
if (!JavaMode.codeCompletionsEnabled) return;
|
||||
if (word.length() < predictionMinLength) return;
|
||||
@@ -797,6 +805,7 @@ public class ASTGenerator {
|
||||
return;
|
||||
}
|
||||
|
||||
// presumably this was removed because the caller is running from a SwingWorker [fry]
|
||||
// SwingWorker worker = new SwingWorker() {
|
||||
//
|
||||
// @Override
|
||||
@@ -806,48 +815,48 @@ public class ASTGenerator {
|
||||
//
|
||||
// protected void done() {
|
||||
|
||||
// If the parsed code contains pde enhancements, take 'em out.
|
||||
String word2 = ASTNodeWrapper.getJavaCode(word);
|
||||
// If the parsed code contains pde enhancements, take 'em out.
|
||||
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, word2.length() - 1);
|
||||
noCompare = true;
|
||||
//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, word2.length() - 1);
|
||||
noCompare = true;
|
||||
}
|
||||
|
||||
if (word2.length() >= predictionMinLength && !noCompare
|
||||
&& word2.length() > lastPredictedWord.length()) {
|
||||
if (word2.startsWith(lastPredictedWord)) {
|
||||
log(word + " starts with " + lastPredictedWord);
|
||||
log("Don't recalc");
|
||||
if (word2.contains(".")) {
|
||||
int x = word2.lastIndexOf('.');
|
||||
trimCandidates(word2.substring(x + 1));
|
||||
} else {
|
||||
trimCandidates(word2);
|
||||
}
|
||||
showPredictions(word);
|
||||
lastPredictedWord = word2;
|
||||
predictionOngoing.set(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (word2.length() >= predictionMinLength && !noCompare
|
||||
&& word2.length() > lastPredictedWord.length()) {
|
||||
if (word2.startsWith(lastPredictedWord)) {
|
||||
log(word + " starts with " + lastPredictedWord);
|
||||
log("Don't recalc");
|
||||
if (word2.contains(".")) {
|
||||
int x = word2.lastIndexOf('.');
|
||||
trimCandidates(word2.substring(x + 1));
|
||||
} else {
|
||||
trimCandidates(word2);
|
||||
}
|
||||
showPredictions(word);
|
||||
lastPredictedWord = word2;
|
||||
predictionOngoing.set(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int lineNumber = line;
|
||||
// Adjust line number for tabbed sketches
|
||||
if (errorCheckerService != null) {
|
||||
editor = errorCheckerService.getEditor();
|
||||
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;
|
||||
lineNumber += len;
|
||||
}
|
||||
|
||||
int lineNumber = line;
|
||||
// Adjust line number for tabbed sketches
|
||||
if (errorCheckerService != null) {
|
||||
editor = errorCheckerService.getEditor();
|
||||
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;
|
||||
lineNumber += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that we're not inside a comment. TODO: Binary search
|
||||
|
||||
@@ -864,157 +873,150 @@ public class ASTGenerator {
|
||||
}
|
||||
}*/
|
||||
|
||||
// Now parse the expression into an ASTNode object
|
||||
ASTNode nearestNode = null;
|
||||
ASTParser parser = ASTParser.newParser(AST.JLS4);
|
||||
parser.setKind(ASTParser.K_EXPRESSION);
|
||||
parser.setSource(word2.toCharArray());
|
||||
ASTNode testnode = parser.createAST(null);
|
||||
//Base.loge("PREDICTION PARSER PROBLEMS: " + parser);
|
||||
// Find closest ASTNode of the document to this word
|
||||
Messages.loge("Typed: " + word2 + "|" + " temp Node type: " + testnode.getClass().getSimpleName());
|
||||
if(testnode instanceof MethodInvocation){
|
||||
MethodInvocation mi = (MethodInvocation)testnode;
|
||||
log(mi.getName() + "," + mi.getExpression() + "," + mi.typeArguments().size());
|
||||
}
|
||||
// Now parse the expression into an ASTNode object
|
||||
ASTNode nearestNode = null;
|
||||
ASTParser parser = ASTParser.newParser(AST.JLS4);
|
||||
parser.setKind(ASTParser.K_EXPRESSION);
|
||||
parser.setSource(word2.toCharArray());
|
||||
ASTNode testnode = parser.createAST(null);
|
||||
//Base.loge("PREDICTION PARSER PROBLEMS: " + parser);
|
||||
// Find closest ASTNode of the document to this word
|
||||
Messages.loge("Typed: " + word2 + "|" + " temp Node type: " + testnode.getClass().getSimpleName());
|
||||
if(testnode instanceof MethodInvocation){
|
||||
MethodInvocation mi = (MethodInvocation)testnode;
|
||||
log(mi.getName() + "," + mi.getExpression() + "," + mi.typeArguments().size());
|
||||
}
|
||||
|
||||
// find nearest ASTNode
|
||||
nearestNode = findClosestNode(lineNumber, (ASTNode) errorCheckerService.getLastCorrectCU().types()
|
||||
.get(0));
|
||||
if (nearestNode == null) {
|
||||
// Make sure nearestNode is not NULL if couldn't find a closeset node
|
||||
nearestNode = (ASTNode) errorCheckerService.getLastCorrectCU().types().get(0);
|
||||
}
|
||||
Messages.loge(lineNumber + " Nearest ASTNode to PRED "
|
||||
+ getNodeAsString(nearestNode));
|
||||
// find nearest ASTNode
|
||||
nearestNode = findClosestNode(lineNumber, (ASTNode) errorCheckerService.getLastCorrectCU().types()
|
||||
.get(0));
|
||||
if (nearestNode == null) {
|
||||
// Make sure nearestNode is not NULL if couldn't find a closeset node
|
||||
nearestNode = (ASTNode) errorCheckerService.getLastCorrectCU().types().get(0);
|
||||
}
|
||||
Messages.loge(lineNumber + " Nearest ASTNode to PRED "
|
||||
+ getNodeAsString(nearestNode));
|
||||
|
||||
candidates = new ArrayList<CompletionCandidate>();
|
||||
lastPredictedWord = word2;
|
||||
// Determine the expression typed
|
||||
candidates = new ArrayList<CompletionCandidate>();
|
||||
lastPredictedWord = word2;
|
||||
// Determine the expression typed
|
||||
|
||||
if (testnode instanceof SimpleName && !noCompare) {
|
||||
Messages.loge("One word expression " + getNodeAsString(testnode));
|
||||
//==> Simple one word exprssion - so is just an identifier
|
||||
if (testnode instanceof SimpleName && !noCompare) {
|
||||
Messages.loge("One word expression " + getNodeAsString(testnode));
|
||||
//==> Simple one word exprssion - so is just an identifier
|
||||
|
||||
// Bottom up traversal of the AST to look for possible definitions at
|
||||
// higher levels.
|
||||
//nearestNode = nearestNode.getParent();
|
||||
while (nearestNode != null) {
|
||||
// If the current class has a super class, look inside it for
|
||||
// definitions.
|
||||
if (nearestNode instanceof TypeDeclaration) {
|
||||
TypeDeclaration td = (TypeDeclaration) nearestNode;
|
||||
if (td.getStructuralProperty(TypeDeclaration.SUPERCLASS_TYPE_PROPERTY) != null) {
|
||||
SimpleType st = (SimpleType) td.getStructuralProperty(TypeDeclaration.SUPERCLASS_TYPE_PROPERTY);
|
||||
log("Superclass " + st.getName());
|
||||
ArrayList<CompletionCandidate> tempCandidates =
|
||||
getMembersForType(st.getName().toString(), word2, noCompare, false);
|
||||
for (CompletionCandidate can : tempCandidates) {
|
||||
candidates.add(can);
|
||||
}
|
||||
//findDeclaration(st.getName())
|
||||
}
|
||||
// Bottom up traversal of the AST to look for possible definitions at
|
||||
// higher levels.
|
||||
//nearestNode = nearestNode.getParent();
|
||||
while (nearestNode != null) {
|
||||
// If the current class has a super class, look inside it for
|
||||
// definitions.
|
||||
if (nearestNode instanceof TypeDeclaration) {
|
||||
TypeDeclaration td = (TypeDeclaration) nearestNode;
|
||||
if (td.getStructuralProperty(TypeDeclaration.SUPERCLASS_TYPE_PROPERTY) != null) {
|
||||
SimpleType st = (SimpleType) td.getStructuralProperty(TypeDeclaration.SUPERCLASS_TYPE_PROPERTY);
|
||||
log("Superclass " + st.getName());
|
||||
ArrayList<CompletionCandidate> tempCandidates =
|
||||
getMembersForType(st.getName().toString(), word2, noCompare, false);
|
||||
for (CompletionCandidate can : tempCandidates) {
|
||||
candidates.add(can);
|
||||
}
|
||||
List<StructuralPropertyDescriptor> sprops =
|
||||
nearestNode.structuralPropertiesForType();
|
||||
for (StructuralPropertyDescriptor sprop : sprops) {
|
||||
ASTNode cnode = null;
|
||||
if (!sprop.isChildListProperty()) {
|
||||
if (nearestNode.getStructuralProperty(sprop) instanceof ASTNode) {
|
||||
cnode = (ASTNode) nearestNode.getStructuralProperty(sprop);
|
||||
CompletionCandidate[] types = checkForTypes(cnode);
|
||||
if (types != null) {
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
if (types[i].getElementName().toLowerCase().startsWith(word2.toLowerCase()))
|
||||
candidates.add(types[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Childlist prop
|
||||
List<ASTNode> nodelist = (List<ASTNode>)
|
||||
nearestNode.getStructuralProperty(sprop);
|
||||
for (ASTNode clnode : nodelist) {
|
||||
CompletionCandidate[] types = checkForTypes(clnode);
|
||||
if (types != null) {
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
if (types[i].getElementName().toLowerCase().startsWith(word2.toLowerCase()))
|
||||
candidates.add(types[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nearestNode = nearestNode.getParent();
|
||||
//findDeclaration(st.getName())
|
||||
}
|
||||
// We're seeing a simple name that's not defined locally or in
|
||||
// the parent class. So most probably a pre-defined type.
|
||||
log("Empty can. " + word2);
|
||||
if (classPath != null) {
|
||||
RegExpResourceFilter regExpResourceFilter;
|
||||
regExpResourceFilter = new RegExpResourceFilter(Pattern.compile(".*"),
|
||||
Pattern.compile(word2 + "[a-zA-Z_0-9]*.class",
|
||||
Pattern.CASE_INSENSITIVE));
|
||||
String[] resources = classPath.findResources("", regExpResourceFilter);
|
||||
|
||||
for (String matchedClass2 : resources) {
|
||||
matchedClass2 = matchedClass2.replace('/', '.'); //package name
|
||||
String matchedClass = matchedClass2.substring(0, matchedClass2.length() - 6);
|
||||
int d = matchedClass.lastIndexOf('.');
|
||||
if (ignorableImport(matchedClass,matchedClass.substring(d + 1))) {
|
||||
continue;
|
||||
}
|
||||
List<StructuralPropertyDescriptor> sprops =
|
||||
nearestNode.structuralPropertiesForType();
|
||||
for (StructuralPropertyDescriptor sprop : sprops) {
|
||||
ASTNode cnode = null;
|
||||
if (!sprop.isChildListProperty()) {
|
||||
if (nearestNode.getStructuralProperty(sprop) instanceof ASTNode) {
|
||||
cnode = (ASTNode) nearestNode.getStructuralProperty(sprop);
|
||||
CompletionCandidate[] types = checkForTypes(cnode);
|
||||
if (types != null) {
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
if (types[i].getElementName().toLowerCase().startsWith(word2.toLowerCase()))
|
||||
candidates.add(types[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Childlist prop
|
||||
List<ASTNode> nodelist =
|
||||
(List<ASTNode>) nearestNode.getStructuralProperty(sprop);
|
||||
for (ASTNode clnode : nodelist) {
|
||||
CompletionCandidate[] types = checkForTypes(clnode);
|
||||
if (types != null) {
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
if (types[i].getElementName().toLowerCase().startsWith(word2.toLowerCase()))
|
||||
candidates.add(types[i]);
|
||||
}
|
||||
}
|
||||
matchedClass = matchedClass.substring(d + 1); //class name
|
||||
candidates
|
||||
.add(new CompletionCandidate(matchedClass, "<html>"
|
||||
+ matchedClass + " : <font color=#777777>"
|
||||
+ matchedClass2.substring(0, d) + "</font></html>",
|
||||
matchedClass,
|
||||
CompletionCandidate.PREDEF_CLASS)); // display package name in grey
|
||||
//log("-> " + className);
|
||||
}
|
||||
}
|
||||
}
|
||||
nearestNode = nearestNode.getParent();
|
||||
}
|
||||
// We're seeing a simple name that's not defined locally or in
|
||||
// the parent class. So most probably a pre-defined type.
|
||||
log("Empty can. " + word2);
|
||||
if (classPath != null) {
|
||||
RegExpResourceFilter regExpResourceFilter =
|
||||
new RegExpResourceFilter(Pattern.compile(".*"),
|
||||
Pattern.compile(word2 + "[a-zA-Z_0-9]*.class",
|
||||
Pattern.CASE_INSENSITIVE));
|
||||
String[] resources = classPath.findResources("", regExpResourceFilter);
|
||||
|
||||
for (String matchedClass2 : resources) {
|
||||
matchedClass2 = matchedClass2.replace('/', '.'); //package name
|
||||
String matchedClass = matchedClass2.substring(0, matchedClass2.length() - 6);
|
||||
int d = matchedClass.lastIndexOf('.');
|
||||
if (!ignorableImport(matchedClass,matchedClass.substring(d + 1))) {
|
||||
matchedClass = matchedClass.substring(d + 1); //class name
|
||||
// display package name in grey
|
||||
String html = "<html>" + matchedClass + " : <font color=#777777>" +
|
||||
matchedClass2.substring(0, d) + "</font></html>";
|
||||
candidates.add(new CompletionCandidate(matchedClass, html,
|
||||
matchedClass,
|
||||
CompletionCandidate.PREDEF_CLASS));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// ==> Complex expression of type blah.blah2().doIt,etc
|
||||
// Have to resolve it by carefully traversing AST of testNode
|
||||
Messages.loge("Complex expression " + getNodeAsString(testnode));
|
||||
log("candidates empty");
|
||||
ASTNode childExpr = getChildExpression(testnode);
|
||||
log("Parent expression : " + getParentExpression(testnode));
|
||||
log("Child expression : " + childExpr);
|
||||
if (childExpr != null) {
|
||||
if (!noCompare) {
|
||||
log("Original testnode " + getNodeAsString(testnode));
|
||||
testnode = getParentExpression(testnode);
|
||||
log("Corrected testnode " + getNodeAsString(testnode));
|
||||
}
|
||||
ClassMember expr =
|
||||
resolveExpression3rdParty(nearestNode, testnode, noCompare);
|
||||
if (expr == null) {
|
||||
log("Expr is null");
|
||||
} else {
|
||||
|
||||
// ==> Complex expression of type blah.blah2().doIt,etc
|
||||
// Have to resolve it by carefully traversing AST of testNode
|
||||
Messages.loge("Complex expression " + getNodeAsString(testnode));
|
||||
log("candidates empty");
|
||||
ASTNode childExpr = getChildExpression(testnode);
|
||||
log("Parent expression : " + getParentExpression(testnode));
|
||||
log("Child expression : " + childExpr);
|
||||
if (childExpr != null) {
|
||||
if (!noCompare) {
|
||||
log("Original testnode "
|
||||
+ getNodeAsString(testnode));
|
||||
testnode = getParentExpression(testnode);
|
||||
log("Corrected testnode "
|
||||
+ getNodeAsString(testnode));
|
||||
}
|
||||
ClassMember expr = resolveExpression3rdParty(nearestNode, testnode,
|
||||
noCompare);
|
||||
if (expr == null) {
|
||||
log("Expr is null");
|
||||
} else {
|
||||
log("Expr is " + expr.toString());
|
||||
candidates = getMembersForType(expr, childExpr.toString(),
|
||||
noCompare, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log("ChildExpr is null");
|
||||
}
|
||||
log("Expr is " + expr.toString());
|
||||
candidates = getMembersForType(expr, childExpr.toString(),
|
||||
noCompare, false);
|
||||
}
|
||||
|
||||
showPredictions(word);
|
||||
predictionOngoing.set(false);
|
||||
} else {
|
||||
log("ChildExpr is null");
|
||||
}
|
||||
}
|
||||
showPredictions(word);
|
||||
predictionOngoing.set(false);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// worker.execute();
|
||||
}
|
||||
|
||||
|
||||
protected void showPredictions(final String word) {
|
||||
if (sketchOutline != null && sketchOutline.isVisible()) {
|
||||
// don't show completions when the outline is visible
|
||||
@@ -3364,7 +3366,7 @@ public class ASTGenerator {
|
||||
private TreeSet<String> ignoredImportSuggestions;
|
||||
|
||||
public void suggestImports(final String className){
|
||||
if(ignoredImportSuggestions == null) {
|
||||
if (ignoredImportSuggestions == null) {
|
||||
ignoredImportSuggestions = new TreeSet<String>();
|
||||
} else {
|
||||
if(ignoredImportSuggestions.contains(className)) {
|
||||
@@ -3372,18 +3374,17 @@ public class ASTGenerator {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(frmImportSuggest != null)
|
||||
if(frmImportSuggest.isVisible())
|
||||
return;
|
||||
if (frmImportSuggest != null) {
|
||||
if (frmImportSuggest.isVisible()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
log("Looking for class " + className);
|
||||
RegExpResourceFilter regf = new RegExpResourceFilter(
|
||||
Pattern.compile(".*"),
|
||||
Pattern
|
||||
.compile(className
|
||||
+ ".class",
|
||||
Pattern.CASE_INSENSITIVE));
|
||||
String[] resources = classPath
|
||||
.findResources("", regf);
|
||||
RegExpResourceFilter regf =
|
||||
new RegExpResourceFilter(Pattern.compile(".*"),
|
||||
Pattern.compile(className + ".class",
|
||||
Pattern.CASE_INSENSITIVE));
|
||||
String[] resources = classPath.findResources("", regf);
|
||||
ArrayList<String> candidates = new ArrayList<String>();
|
||||
for (String res : resources) {
|
||||
candidates.add(res);
|
||||
@@ -3504,14 +3505,15 @@ public class ASTGenerator {
|
||||
classList.setSelectedIndex(0);
|
||||
frmImportSuggest.setVisible(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void disposeAllWindows() {
|
||||
disposeWindow(frmASTView, frameAutoComp, frmImportSuggest,
|
||||
frmOccurenceList, frmRename);
|
||||
}
|
||||
|
||||
|
||||
public static void disposeWindow(JFrame... f) {
|
||||
for (JFrame jFrame : f) {
|
||||
if(jFrame != null)
|
||||
@@ -3519,6 +3521,7 @@ public class ASTGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected boolean ignorableImport(String impName, String fullClassName) {
|
||||
for (ImportStatement impS : errorCheckerService.getProgramImports()) {
|
||||
if (impName.toLowerCase().startsWith(impS.getPackageName().toLowerCase())) {
|
||||
@@ -3555,6 +3558,7 @@ public class ASTGenerator {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isAddableASTNode(ASTNode node) {
|
||||
switch (node.getNodeType()) {
|
||||
// case ASTNode.STRING_LITERAL:
|
||||
@@ -3567,6 +3571,7 @@ public class ASTGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For any line or expression, finds the line start offset(java code).
|
||||
* @param node
|
||||
@@ -3584,6 +3589,7 @@ public class ASTGenerator {
|
||||
return node.getStartPosition();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For any node, finds various offsets (java code).
|
||||
*
|
||||
@@ -3605,7 +3611,6 @@ public class ASTGenerator {
|
||||
}
|
||||
|
||||
|
||||
|
||||
static protected String getNodeAsString(ASTNode node) {
|
||||
if (node == null)
|
||||
return "NULL";
|
||||
|
||||
Reference in New Issue
Block a user