Skip to content

Commit

Permalink
Improve diagnostic location for "virtual" nodes
Browse files Browse the repository at this point in the history
Javac sometimes add virtual nodes to the tree (usually with endPos ==
-1). Ignore then when computing diagnostic position.
  • Loading branch information
mickaelistria committed Sep 20, 2024
1 parent 297f670 commit 1cac8cc
Showing 1 changed file with 12 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import com.sun.tools.javac.parser.ScannerFactory;
import com.sun.tools.javac.parser.Tokens.Token;
import com.sun.tools.javac.parser.Tokens.TokenKind;
import com.sun.tools.javac.tree.EndPosTable;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCAssign;
Expand Down Expand Up @@ -219,6 +220,7 @@ private org.eclipse.jface.text.Position getDiagnosticPosition(Diagnostic<? exten
}
}
TreePath diagnosticPath = getTreePath(jcDiagnostic);
EndPosTable endPos = units.get(diagnostic.getSource()).endPositions;
if (diagnosticPath != null) {
if (problemId == IProblem.ParameterMismatch) {
// Javac points to the arg, which JDT expects the method name
Expand All @@ -237,7 +239,7 @@ private org.eclipse.jface.text.Position getDiagnosticPosition(Diagnostic<? exten
}
if (selectExpr instanceof JCFieldAccess methodFieldAccess) {
int start = methodFieldAccess.getPreferredPosition() + 1; // after dot
int end = methodFieldAccess.getEndPosition(this.units.get(jcDiagnostic.getSource()).endPositions);
int end = methodFieldAccess.getEndPosition(endPos);
return new org.eclipse.jface.text.Position(start, end - start);
}
}
Expand Down Expand Up @@ -265,7 +267,7 @@ private org.eclipse.jface.text.Position getDiagnosticPosition(Diagnostic<? exten
}
} else if (problemId == IProblem.TypeMismatch && diagnosticPath.getLeaf() instanceof JCFieldAccess fieldAccess) {
int start = fieldAccess.getStartPosition();
int end = fieldAccess.getEndPosition(this.units.get(jcDiagnostic.getSource()).endPositions);
int end = fieldAccess.getEndPosition(endPos);
return new org.eclipse.jface.text.Position(start, end - start);
} else if (problemId == IProblem.MethodMustOverrideOrImplement) {
Tree tree = diagnosticPath.getParentPath() == null ? null
Expand Down Expand Up @@ -306,7 +308,12 @@ private org.eclipse.jface.text.Position getDiagnosticPosition(Diagnostic<? exten
}
}

Tree element = diagnosticPath != null ? diagnosticPath.getLeaf() :
TreePath current = diagnosticPath;
while (current != null && current.getLeaf() instanceof JCTree tree &&
TreeInfo.getEndPos(tree, endPos) == Position.NOPOS) {
current = current.getParentPath();
}
Tree element = current != null ? current.getLeaf() :
jcDiagnostic.getDiagnosticPosition() instanceof Tree tree ? tree :
null;
if (problemId == IProblem.NoMessageSendOnArrayType
Expand Down Expand Up @@ -676,7 +683,7 @@ public int toProblemId(Diagnostic<? extends JavaFileObject> diagnostic) {
treePath = treePath.getParentPath();
}
if (treePath == null || !(treePath.getLeaf() instanceof JCMethodDecl methodDecl)) {
ILog.get().error("Could not convert diagnostic (" + diagnostic.getCode() + ")\n" + diagnostic + ". Expected the constructor invocation to be in a constructor.");
// potential case of enum values without explicit call to constructor
yield IProblem.UndefinedConstructor;
}
boolean isDefault = (methodDecl.sym.flags() & Flags.GENERATEDCONSTR) != 0;
Expand All @@ -695,7 +702,7 @@ yield switch (rootCauseCode) {
};
}
case METHOD -> IProblem.ParameterMismatch;
default -> 0;
default -> IProblem.ParameterMismatch;
};
case "compiler.err.premature.eof" -> IProblem.ParsingErrorUnexpectedEOF; // syntax error
case "compiler.err.report.access" -> convertNotVisibleAccess(diagnostic);
Expand Down

0 comments on commit 1cac8cc

Please sign in to comment.