Skip to content

Commit

Permalink
feat: Workspace symbols for JAX-RS endpoints
Browse files Browse the repository at this point in the history
Fixes #1363

Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Aug 7, 2024
1 parent f55035d commit 83be5fc
Show file tree
Hide file tree
Showing 20 changed files with 484 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.Optional;

import javax.ws.rs.GET;
import javax.ws.rs.PATCH;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
Expand Down Expand Up @@ -40,4 +41,9 @@ public String hello2() {
public String hello3() {
return message + " 4 " + name.orElse("world") + suffix;
}

@PATCH
@Path("hello5")
public String hello5() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.util.Computable;
Expand All @@ -27,21 +28,15 @@
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.java.completion.JavaCompletionContext;
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.java.definition.IJavaDefinitionParticipant;
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.java.definition.JavaDefinitionContext;
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.java.symbols.IJavaWorkspaceSymbolsParticipant;
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.IPsiUtils;
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.java.diagnostics.IJavaDiagnosticsParticipant;
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.java.diagnostics.JavaDiagnosticsContext;
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.java.hover.IJavaHoverParticipant;
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.java.hover.JavaHoverContext;
import com.redhat.devtools.intellij.lsp4mp4ij.psi.internal.core.java.codeaction.CodeActionHandler;
import org.eclipse.lsp4j.CodeAction;
import org.eclipse.lsp4j.CodeLens;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionList;
import org.eclipse.lsp4j.*;
import org.eclipse.lsp4mp.commons.*;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.Hover;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.PublishDiagnosticsParams;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
Expand Down Expand Up @@ -637,4 +632,43 @@ public CodeAction resolveCodeAction(CodeAction unresolved, IPsiUtils utils) {
return codeActionHandler.resolveCodeAction(unresolved, utils);
}

/**
* Returns the workspace symbols for the given java project.
*
* @param projectUri the uri of the java project
* @param utils the JDT utils
* @param monitor the progress monitor
* @return the workspace symbols for the given java project
*/
public List<SymbolInformation> workspaceSymbols(String projectUri, IPsiUtils utils, ProgressIndicator monitor) {
List<SymbolInformation> symbols = new ArrayList<>();
Module module = getModule(projectUri, utils);
if (module != null) {
collectWorkspaceSymbols(module, utils, symbols, monitor);
}
return symbols;
}

private static @Nullable Module getModule(String uri, IPsiUtils utils) {
Module[] modules = ModuleManager.getInstance(utils.getProject()).getModules();
for (Module module : modules) {
if (uri.equals(module.getName())) {
return module;
}
}
return null;
}

private void collectWorkspaceSymbols(Module project, IPsiUtils utils, List<SymbolInformation> symbols,
ProgressIndicator monitor) {
if (monitor.isCanceled()) {
return;
}

List<IJavaWorkspaceSymbolsParticipant> definitions = IJavaWorkspaceSymbolsParticipant.EP_NAME.getExtensionList();
if (definitions.isEmpty()) {
return;
}
definitions.forEach(definition -> definition.collectSymbols(project, utils, symbols, monitor));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
*
*/
public interface IJavaCodeLensParticipant {
public static final ExtensionPointName<IJavaCodeLensParticipant> EP_NAME = ExtensionPointName.create("com.redhat.devtools.intellij.quarkus.javaCodeLensParticipant");

ExtensionPointName<IJavaCodeLensParticipant> EP_NAME = ExtensionPointName.create("com.redhat.devtools.intellij.quarkus.javaCodeLensParticipant");


/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
* @author datho7561
*/
public interface IJavaCompletionParticipant {
public static final ExtensionPointName<IJavaCompletionParticipant> EP_NAME = ExtensionPointName.create("com.redhat.devtools.intellij.quarkus.javaCompletionParticipant");

ExtensionPointName<IJavaCompletionParticipant> EP_NAME = ExtensionPointName.create("com.redhat.devtools.intellij.quarkus.javaCompletionParticipant");

/**
* Returns true if this completion feature should be active in this context, and false otherwise
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
*
*/
public interface IJavaDefinitionParticipant {
public static final ExtensionPointName<IJavaDefinitionParticipant> EP_NAME = ExtensionPointName.create("com.redhat.devtools.intellij.quarkus.javaDefinitionParticipant");

ExtensionPointName<IJavaDefinitionParticipant> EP_NAME = ExtensionPointName.create("com.redhat.devtools.intellij.quarkus.javaDefinitionParticipant");

/**
* Returns true if definition must be collected for the given context and false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
*/
public interface IJavaDiagnosticsParticipant {

public static final ExtensionPointName<IJavaDiagnosticsParticipant> EP_NAME = ExtensionPointName.create("com.redhat.devtools.intellij.quarkus.javaDiagnosticsParticipant");
ExtensionPointName<IJavaDiagnosticsParticipant> EP_NAME = ExtensionPointName.create("com.redhat.devtools.intellij.quarkus.javaDiagnosticsParticipant");

/**
* Returns true if diagnostics must be collected for the given context and false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*/
public interface IJavaHoverParticipant {

public static final ExtensionPointName<IJavaHoverParticipant> EP_NAME = ExtensionPointName.create("com.redhat.devtools.intellij.quarkus.javaHoverParticipant");
ExtensionPointName<IJavaHoverParticipant> EP_NAME = ExtensionPointName.create("com.redhat.devtools.intellij.quarkus.javaHoverParticipant");

/**
* Returns true if hover must be collected for the given context and false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright (c) 2023 Red Hat Inc. and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package com.redhat.devtools.intellij.lsp4mp4ij.psi.core.java.symbols;

import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProgressIndicator;
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.IPsiUtils;
import org.eclipse.lsp4j.SymbolInformation;

import java.util.List;

/**
* Represents an object that can collect workspace symbols for java projects.
*/
public interface IJavaWorkspaceSymbolsParticipant {

ExtensionPointName<IJavaWorkspaceSymbolsParticipant> EP_NAME = ExtensionPointName.create("com.redhat.devtools.intellij.quarkus.javaWorkspaceSymbolsParticipant");

/**
* Fill in <code>symbols</code> with workspace symbols of the given project.
*
* @param project the project to collect workspace symbols from
* @param utils the JDT utils
* @param symbols the list of symbols to add to
* @param monitor the progress monitor
*/
void collectSymbols(Module project, IPsiUtils utils, List<SymbolInformation> symbols,
ProgressIndicator monitor);

}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public interface IJaxRsInfoProvider {
* @param monitor the progress monitor
* @return a non-null set of all the classes in the given project that this provider can provide JAX-RS method information for
*/
@NotNull Set<PsiClass> getAllJaxRsClasses(@NotNull Module javaProject, @NotNull ProgressIndicator monitor);
@NotNull Set<PsiClass> getAllJaxRsClasses(@NotNull Module javaProject, @NotNull IPsiUtils utils, @NotNull ProgressIndicator monitor);

/**
* Returns a list of all the JAX-RS methods in the given type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,19 @@
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.psi.*;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.AnnotatedElementsSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.MergeQuery;
import com.intellij.util.Query;
import com.redhat.devtools.lsp4ij.LSPIJUtils;
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.jaxrs.*;
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.IPsiUtils;
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.PsiTypeUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.concurrent.CancellationException;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand All @@ -55,8 +56,49 @@ public boolean canProvideJaxRsMethodInfoForClass(PsiFile typeRoot, Module javaPr
}

@Override
public Set<PsiClass> getAllJaxRsClasses(Module javaProject, ProgressIndicator monitor) {
// TODO: implement when LSP4IJ will support workspace symbols
public Set<PsiClass> getAllJaxRsClasses(Module javaProject, IPsiUtils utils, ProgressIndicator monitor) {
if (monitor.isCanceled()) {
return Collections.emptySet();
}

try {
SearchScope scope = javaProject.getModuleScope(false);

Query<PsiModifierListOwner> query = null;
for (var httpAnnotation : JaxRsConstants.HTTP_METHOD_ANNOTATIONS) {
PsiClass annotationClass = utils.findClass(javaProject, httpAnnotation);
if (annotationClass != null) {
Query<PsiModifierListOwner> annotationQuery = AnnotatedElementsSearch.searchElements(annotationClass, scope, PsiModifierListOwner.class);
if (query == null) {
query = annotationQuery;
} else {
query = new MergeQuery<>(query, annotationQuery);
}
}
}
if (query == null) {
return Collections.emptySet();
}

Set<PsiClass> jaxRsClasses = new HashSet<>();
query.forEach((Consumer<? super PsiModifierListOwner>) item -> {
if (item instanceof PsiMember) {
PsiClass cl = ((PsiMember) item).getContainingClass();
if (cl != null) {
jaxRsClasses.add(cl);
}
}
});
if (monitor.isCanceled()) {
return Collections.emptySet();
}
return jaxRsClasses;

} catch (IndexNotReadyException | ProcessCanceledException | CancellationException e) {
throw e;
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "While collecting JAX-RS method information for project " + javaProject.getName(), e);
}
return Collections.emptySet();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public static JaxRsInfoProviderRegistry getInstance() {
return null;
}

private List<IJaxRsInfoProvider> getProviders() {
public List<IJaxRsInfoProvider> getProviders() {
if (!initialized) {
providers = loadProviders();
return providers;
Expand Down
Loading

0 comments on commit 83be5fc

Please sign in to comment.