Skip to content

Commit

Permalink
Support Diagnostic Tag (#1161)
Browse files Browse the repository at this point in the history
Signed-off-by: Rome Li <[email protected]>
  • Loading branch information
akaroml authored and fbricon committed Sep 25, 2019
1 parent 1041bea commit bff2b30
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

Expand All @@ -28,6 +29,7 @@
import org.eclipse.jdt.ls.core.internal.ResourceUtils;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DiagnosticSeverity;
import org.eclipse.lsp4j.DiagnosticTag;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.PublishDiagnosticsParams;
import org.eclipse.lsp4j.Range;
Expand Down Expand Up @@ -116,7 +118,8 @@ public void beginReporting() {
@Override
public void endReporting() {
JavaLanguageServerPlugin.logInfo(problems.size() + " problems reported for " + this.uri.substring(this.uri.lastIndexOf('/')));
PublishDiagnosticsParams $ = new PublishDiagnosticsParams(ResourceUtils.toClientUri(uri), toDiagnosticsArray(this.cu, problems));
boolean isDiagnosticTagSupported = JavaLanguageServerPlugin.getPreferencesManager().getClientPreferences().isDiagnosticTagSupported();
PublishDiagnosticsParams $ = new PublishDiagnosticsParams(ResourceUtils.toClientUri(uri), toDiagnosticsArray(this.cu, problems, isDiagnosticTagSupported));
this.connection.publishDiagnostics($);
}

Expand All @@ -125,7 +128,12 @@ public boolean isActive() {
return true;
}

@Deprecated
public static List<Diagnostic> toDiagnosticsArray(IOpenable openable, List<IProblem> problems) {
return toDiagnosticsArray(openable, problems, false);
}

public static List<Diagnostic> toDiagnosticsArray(IOpenable openable, List<IProblem> problems, boolean isDiagnosticTagSupported) {
List<Diagnostic> array = new ArrayList<>(problems.size());
for (IProblem problem : problems) {
Diagnostic diag = new Diagnostic();
Expand All @@ -134,11 +142,59 @@ public static List<Diagnostic> toDiagnosticsArray(IOpenable openable, List<IProb
diag.setCode(Integer.toString(problem.getID()));
diag.setSeverity(convertSeverity(problem));
diag.setRange(convertRange(openable, problem));
if (isDiagnosticTagSupported) {
diag.setTags(getDiagnosticTag(problem.getID()));
}
array.add(diag);
}
return array;
}

public static List<DiagnosticTag> getDiagnosticTag(int id) {
switch (id) {
case IProblem.UsingDeprecatedType:
case IProblem.UsingDeprecatedField:
case IProblem.UsingDeprecatedMethod:
case IProblem.UsingDeprecatedConstructor:
case IProblem.OverridingDeprecatedMethod:
case IProblem.JavadocUsingDeprecatedField:
case IProblem.JavadocUsingDeprecatedConstructor:
case IProblem.JavadocUsingDeprecatedMethod:
case IProblem.JavadocUsingDeprecatedType:
case IProblem.UsingTerminallyDeprecatedType:
case IProblem.UsingTerminallyDeprecatedMethod:
case IProblem.UsingTerminallyDeprecatedConstructor:
case IProblem.UsingTerminallyDeprecatedField:
case IProblem.OverridingTerminallyDeprecatedMethod:
case IProblem.UsingDeprecatedSinceVersionType:
case IProblem.UsingDeprecatedSinceVersionMethod:
case IProblem.UsingDeprecatedSinceVersionConstructor:
case IProblem.UsingDeprecatedSinceVersionField:
case IProblem.OverridingDeprecatedSinceVersionMethod:
case IProblem.UsingTerminallyDeprecatedSinceVersionType:
case IProblem.UsingTerminallyDeprecatedSinceVersionMethod:
case IProblem.UsingTerminallyDeprecatedSinceVersionConstructor:
case IProblem.UsingTerminallyDeprecatedSinceVersionField:
case IProblem.OverridingTerminallyDeprecatedSinceVersionMethod:
case IProblem.UsingDeprecatedPackage:
case IProblem.UsingDeprecatedSinceVersionPackage:
case IProblem.UsingTerminallyDeprecatedPackage:
case IProblem.UsingTerminallyDeprecatedSinceVersionPackage:
case IProblem.UsingDeprecatedModule:
case IProblem.UsingDeprecatedSinceVersionModule:
case IProblem.UsingTerminallyDeprecatedModule:
case IProblem.UsingTerminallyDeprecatedSinceVersionModule:
return Arrays.asList(DiagnosticTag.Deprecated);
case IProblem.UnnecessaryCast:
case IProblem.UnnecessaryInstanceof:
case IProblem.UnnecessaryElse:
case IProblem.UnnecessaryNLSTag:
return Arrays.asList(DiagnosticTag.Unnecessary);
}

return null;
}

private static DiagnosticSeverity convertSeverity(IProblem problem) {
if(problem.isError()) {
return DiagnosticSeverity.Error;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,14 +254,15 @@ public void initialized(InitializedParams params) {
// we do not have the user setting initialized yet at this point but we should
// still call to enable defaults in case client does not support configuration changes
syncCapabilitiesToSettings();

Job initializeWorkspace = new Job("Initialize workspace") {

@Override
public IStatus run(IProgressMonitor monitor) {
try {
JobHelpers.waitForBuildJobs(60 * 60 * 1000); // 1 hour
logInfo(">> build jobs finished");
workspaceDiagnosticsHandler = new WorkspaceDiagnosticsHandler(JDTLanguageServer.this.client, pm);
workspaceDiagnosticsHandler = new WorkspaceDiagnosticsHandler(JDTLanguageServer.this.client, pm, preferenceManager.getClientPreferences());
workspaceDiagnosticsHandler.publishDiagnostics(monitor);
workspaceDiagnosticsHandler.addResourceChangeListener();
pm.registerWatchers();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
import org.eclipse.jdt.ls.core.internal.ResourceUtils;
import org.eclipse.jdt.ls.core.internal.managers.ProjectsManager;
import org.eclipse.jdt.ls.core.internal.preferences.ClientPreferences;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.lsp4j.Diagnostic;
Expand All @@ -64,10 +65,17 @@ public final class WorkspaceDiagnosticsHandler implements IResourceChangeListene
public static final String PROJECT_CONFIGURATION_IS_NOT_UP_TO_DATE_WITH_POM_XML = "Project configuration is not up-to-date with pom.xml, requires an update.";
private final JavaClientConnection connection;
private final ProjectsManager projectsManager;
private final boolean isDiagnosticTagSupported;

@Deprecated
public WorkspaceDiagnosticsHandler(JavaClientConnection connection, ProjectsManager projectsManager) {
this(connection, projectsManager, null);
}

public WorkspaceDiagnosticsHandler(JavaClientConnection connection, ProjectsManager projectsManager, ClientPreferences prefs) {
this.connection = connection;
this.projectsManager = projectsManager;
this.isDiagnosticTagSupported = prefs != null ? prefs.isDiagnosticTagSupported() : false;
}

public void addResourceChangeListener() {
Expand Down Expand Up @@ -150,7 +158,7 @@ else if (projectsManager.isBuildFile(file)) {
}
if (document != null) {
String uri = JDTUtils.getFileURI(resource);
this.connection.publishDiagnostics(new PublishDiagnosticsParams(ResourceUtils.toClientUri(uri), toDiagnosticsArray(document, markers)));
this.connection.publishDiagnostics(new PublishDiagnosticsParams(ResourceUtils.toClientUri(uri), toDiagnosticsArray(document, markers, isDiagnosticTagSupported)));
}
return false;
}
Expand All @@ -173,13 +181,13 @@ private void publishMarkers(IProject project, IMarker[] markers) throws CoreExce
projectMarkers.add(marker);
}
}
List<Diagnostic> diagnostics = toDiagnosticArray(range, projectMarkers);
List<Diagnostic> diagnostics = toDiagnosticArray(range, projectMarkers, isDiagnosticTagSupported);
String clientUri = ResourceUtils.toClientUri(uri);
connection.publishDiagnostics(new PublishDiagnosticsParams(clientUri, diagnostics));
if (pom.exists()) {
IDocument document = JsonRpcHelpers.toDocument(pom);
diagnostics = toDiagnosticsArray(document, pom.findMarkers(null, true, IResource.DEPTH_ZERO));
List<Diagnostic> diagnosicts2 = toDiagnosticArray(range, pomMarkers);
diagnostics = toDiagnosticsArray(document, pom.findMarkers(null, true, IResource.DEPTH_ZERO), isDiagnosticTagSupported);
List<Diagnostic> diagnosicts2 = toDiagnosticArray(range, pomMarkers, isDiagnosticTagSupported);
diagnostics.addAll(diagnosicts2);
connection.publishDiagnostics(new PublishDiagnosticsParams(ResourceUtils.toClientUri(clientUri + "/pom.xml"), diagnostics));
}
Expand Down Expand Up @@ -252,13 +260,16 @@ private void publishDiagnostics(List<IMarker> markers) {
document = JsonRpcHelpers.toDocument(file);
}
if (document != null) {
List<Diagnostic> diagnostics = WorkspaceDiagnosticsHandler.toDiagnosticsArray(document, entry.getValue().toArray(new IMarker[0]));
List<Diagnostic> diagnostics = WorkspaceDiagnosticsHandler.toDiagnosticsArray(document, entry.getValue().toArray(new IMarker[0]), isDiagnosticTagSupported);
connection.publishDiagnostics(new PublishDiagnosticsParams(ResourceUtils.toClientUri(uri), diagnostics));
}
}
}


@Deprecated
public static List<Diagnostic> toDiagnosticArray(Range range, Collection<IMarker> markers) {
return toDiagnosticArray(range, markers, false);
}

/**
* Transforms {@link IMarker}s into a list of {@link Diagnostic}s
Expand All @@ -267,12 +278,12 @@ private void publishDiagnostics(List<IMarker> markers) {
* @param markers
* @return a list of {@link Diagnostic}s
*/
public static List<Diagnostic> toDiagnosticArray(Range range, Collection<IMarker> markers) {
List<Diagnostic> diagnostics = markers.stream().map(m -> toDiagnostic(range, m)).filter(d -> d != null).collect(Collectors.toList());
public static List<Diagnostic> toDiagnosticArray(Range range, Collection<IMarker> markers, boolean isDiagnosticTagSupported) {
List<Diagnostic> diagnostics = markers.stream().map(m -> toDiagnostic(range, m, isDiagnosticTagSupported)).filter(d -> d != null).collect(Collectors.toList());
return diagnostics;
}

private static Diagnostic toDiagnostic(Range range, IMarker marker) {
private static Diagnostic toDiagnostic(Range range, IMarker marker, boolean isDiagnosticTagSupported) {
if (marker == null || !marker.exists()) {
return null;
}
Expand All @@ -284,11 +295,20 @@ private static Diagnostic toDiagnostic(Range range, IMarker marker) {
}
d.setMessage(message);
d.setSeverity(convertSeverity(marker.getAttribute(IMarker.SEVERITY, -1)));
d.setCode(String.valueOf(marker.getAttribute(IJavaModelMarker.ID, 0)));
int problemId = marker.getAttribute(IJavaModelMarker.ID, 0);
d.setCode(String.valueOf(problemId));
if (isDiagnosticTagSupported) {
d.setTags(DiagnosticsHandler.getDiagnosticTag(problemId));
}
d.setRange(range);
return d;
}

@Deprecated
public static List<Diagnostic> toDiagnosticsArray(IDocument document, IMarker[] markers) {
return toDiagnosticsArray(document, markers, false);
}

/**
* Transforms {@link IMarker}s of a {@link IDocument} into a list of
* {@link Diagnostic}s.
Expand All @@ -297,24 +317,28 @@ private static Diagnostic toDiagnostic(Range range, IMarker marker) {
* @param markers
* @return a list of {@link Diagnostic}s
*/
public static List<Diagnostic> toDiagnosticsArray(IDocument document, IMarker[] markers) {
public static List<Diagnostic> toDiagnosticsArray(IDocument document, IMarker[] markers, boolean isDiagnosticTagSupported) {
List<Diagnostic> diagnostics = Stream.of(markers)
.map(m -> toDiagnostic(document, m))
.map(m -> toDiagnostic(document, m, isDiagnosticTagSupported))
.filter(d -> d != null)
.collect(Collectors.toList());
return diagnostics;
}

private static Diagnostic toDiagnostic(IDocument document, IMarker marker) {
private static Diagnostic toDiagnostic(IDocument document, IMarker marker, boolean isDiagnosticTagSupported) {
if (marker == null || !marker.exists()) {
return null;
}
Diagnostic d = new Diagnostic();
d.setSource(JavaLanguageServerPlugin.SERVER_SOURCE_ID);
d.setMessage(marker.getAttribute(IMarker.MESSAGE, ""));
d.setCode(String.valueOf(marker.getAttribute(IJavaModelMarker.ID, 0)));
int problemId = marker.getAttribute(IJavaModelMarker.ID, 0);
d.setCode(String.valueOf(problemId));
d.setSeverity(convertSeverity(marker.getAttribute(IMarker.SEVERITY, -1)));
d.setRange(convertRange(document, marker));
if (isDiagnosticTagSupported) {
d.setTags(DiagnosticsHandler.getDiagnosticTag(problemId));
}
return d;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,4 +274,17 @@ public boolean isSupportedCodeActionKind(String kind) {
.stream().filter(k -> kind.startsWith(k)).findAny().isPresent();
//@formatter:on
}

/**
* {@code true} if the client has explicitly set the
* {@code textDocument.publishDiagnostics.tagSupport} to
* {@code true} when initializing the LS. Otherwise, {@code false}.
*/
public boolean isDiagnosticTagSupported() {
//@formatter:off
return v3supported && capabilities.getTextDocument().getPublishDiagnostics() != null
&& capabilities.getTextDocument().getPublishDiagnostics().getTagSupport() != null
&& capabilities.getTextDocument().getPublishDiagnostics().getTagSupport().booleanValue();
//@formatter:on
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ protected List<Either<Command, CodeAction>> evaluateCodeActions(ICompilationUnit
parms.setTextDocument(textDocument);
parms.setRange(range);
CodeActionContext context = new CodeActionContext();
context.setDiagnostics(DiagnosticsHandler.toDiagnosticsArray(cu, Arrays.asList(problems)));
context.setDiagnostics(DiagnosticsHandler.toDiagnosticsArray(cu, Arrays.asList(problems), true));
context.setOnly(onlyKinds);
parms.setContext(context);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.eclipse.jdt.ls.core.internal.managers.AbstractProjectsManagerBasedTest;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DiagnosticSeverity;
import org.eclipse.lsp4j.DiagnosticTag;
import org.eclipse.lsp4j.Range;
import org.junit.Before;
import org.junit.Test;
Expand Down Expand Up @@ -73,7 +74,7 @@ public void testMultipleLineRange() throws Exception {

CompilationUnit astRoot = CoreASTProvider.getInstance().getAST(cu, CoreASTProvider.WAIT_YES, monitor);
IProblem[] problems = astRoot.getProblems();
List<Diagnostic> diagnostics = DiagnosticsHandler.toDiagnosticsArray(cu, Arrays.asList(problems));
List<Diagnostic> diagnostics = DiagnosticsHandler.toDiagnosticsArray(cu, Arrays.asList(problems), true);
assertEquals(1, diagnostics.size());
Range range = diagnostics.get(0).getRange();
assertNotEquals(range.getStart().getLine(), range.getEnd().getLine());
Expand Down Expand Up @@ -122,7 +123,7 @@ public IProblemRequestor getProblemRequestor(ICompilationUnit workingCopy) {
cu.reconcile(ICompilationUnit.NO_AST, true, wcOwner, null);
List<IProblem> problems = handler.getProblems();
assertEquals(problems.size(), 1);
List<Diagnostic> diagnostics = DiagnosticsHandler.toDiagnosticsArray(cu, problems);
List<Diagnostic> diagnostics = DiagnosticsHandler.toDiagnosticsArray(cu, problems, true);
assertEquals(diagnostics.size(), 1);
DiagnosticSeverity severity = diagnostics.get(0).getSeverity();
assertEquals(severity, DiagnosticSeverity.Information);
Expand Down Expand Up @@ -174,7 +175,7 @@ public IProblemRequestor getProblemRequestor(ICompilationUnit workingCopy) {
cu.reconcile(ICompilationUnit.NO_AST, true, wcOwner, null);
List<IProblem> problems = handler.getProblems();
assertEquals(problems.size(), 1);
List<Diagnostic> diagnostics = DiagnosticsHandler.toDiagnosticsArray(cu, problems);
List<Diagnostic> diagnostics = DiagnosticsHandler.toDiagnosticsArray(cu, problems, true);
assertEquals(diagnostics.size(), 1);
DiagnosticSeverity severity = diagnostics.get(0).getSeverity();
assertEquals(severity, DiagnosticSeverity.Warning);
Expand All @@ -183,4 +184,24 @@ public IProblemRequestor getProblemRequestor(ICompilationUnit workingCopy) {
}
}

@Test
public void testDeprecated() throws Exception {
IJavaProject javaProject = newEmptyProject();
IPackageFragmentRoot sourceFolder = javaProject.getPackageFragmentRoot(javaProject.getProject().getFolder("src"));
IPackageFragment pack1 = sourceFolder.createPackageFragment("test1", false, null);

StringBuilder buf = new StringBuilder();
buf.append("package test1;\n");
buf.append("import java.security.Certificate;\n");
ICompilationUnit cu = pack1.createCompilationUnit("E.java", buf.toString(), false, null);

CompilationUnit astRoot = CoreASTProvider.getInstance().getAST(cu, CoreASTProvider.WAIT_YES, monitor);
IProblem[] problems = astRoot.getProblems();
List<Diagnostic> diagnostics = DiagnosticsHandler.toDiagnosticsArray(cu, Arrays.asList(problems), true);
assertEquals(2, diagnostics.size());
List<DiagnosticTag> tags = diagnostics.get(0).getTags();
assertEquals(1, tags.size());
assertEquals(DiagnosticTag.Deprecated, tags.get(0));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ protected List<Either<Command, CodeAction>> getCodeActions(ICompilationUnit cu)
parms.setTextDocument(textDocument);
parms.setRange(range);
CodeActionContext context = new CodeActionContext();
context.setDiagnostics(DiagnosticsHandler.toDiagnosticsArray(cu, Arrays.asList(problems)));
context.setDiagnostics(DiagnosticsHandler.toDiagnosticsArray(cu, Arrays.asList(problems), true));
context.setOnly(Arrays.asList(CodeActionKind.QuickFix));
parms.setContext(context);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.eclipse.jdt.ls.core.internal.JavaClientConnection;
import org.eclipse.jdt.ls.core.internal.ResourceUtils;
import org.eclipse.jdt.ls.core.internal.managers.AbstractProjectsManagerBasedTest;
import org.eclipse.jdt.ls.core.internal.preferences.ClientPreferences;
import org.eclipse.jdt.ls.tests.Unstable;
import org.eclipse.jface.text.IDocument;
import org.eclipse.lsp4j.Diagnostic;
Expand Down Expand Up @@ -66,7 +67,7 @@ public class WorkspaceDiagnosticsHandlerTest extends AbstractProjectsManagerBase

@Before
public void setup() throws Exception {
handler = new WorkspaceDiagnosticsHandler(connection, projectsManager);
handler = new WorkspaceDiagnosticsHandler(connection, projectsManager, preferenceManager.getClientPreferences());
handler.addResourceChangeListener();
}

Expand Down

0 comments on commit bff2b30

Please sign in to comment.