Adjustments to AOT data query navigation, CodeLens
This commit is contained in:
@@ -631,6 +631,14 @@ public class Editor {
|
||||
.map(cl -> "'%s'".formatted(cl.getCommand().getTitle())).collect(Collectors.joining(", ")), codeLensText));
|
||||
}
|
||||
}
|
||||
|
||||
public List<CodeLens> getCodeLenses(String over, int occurrence) throws Exception {
|
||||
int offset = getHoverPosition(over, occurrence);
|
||||
return harness.getCodeLenses(doc).stream()
|
||||
.filter(cl -> doc.toOffset(cl.getRange().getStart()) <= offset
|
||||
&& doc.toOffset(cl.getRange().getEnd()) >= offset)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void assertLiveCodeLensContains(String codeLensOver, int occurrence, String snippet) throws Exception {
|
||||
int cmPosition = getHoverPosition(codeLensOver, occurrence);
|
||||
|
||||
@@ -420,7 +420,7 @@ public class BootLanguageServerBootApp {
|
||||
new NamedDefinitionProvider(springIndex),
|
||||
new DataQueryParameterDefinitionProvider(server.getTextDocumentService(), qurySemanticTokens),
|
||||
new SpelDefinitionProvider(springIndex, cuCache),
|
||||
new GenAotQueryMethodDefinitionProvider(cuCache, server.getTextDocumentService())));
|
||||
new GenAotQueryMethodDefinitionProvider(server, cuCache, projectFinder)));
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -64,6 +64,8 @@ import com.google.gson.JsonElement;
|
||||
@Component
|
||||
public class BootLanguageServerInitializer implements InitializingBean {
|
||||
|
||||
public static final String CMD_SHOW_DOC = "sts/show/document";
|
||||
|
||||
@Autowired SimpleLanguageServer server;
|
||||
@Autowired BootLanguageServerParams params;
|
||||
@Autowired SourceLinks sourceLinks;
|
||||
@@ -165,7 +167,7 @@ public class BootLanguageServerInitializer implements InitializingBean {
|
||||
|
||||
startListening();
|
||||
|
||||
server.onCommand("sts/show/document", p -> {
|
||||
server.onCommand(CMD_SHOW_DOC, p -> {
|
||||
ShowDocumentParams showDocParams = new Gson().fromJson((JsonElement)p.getArguments().get(0), ShowDocumentParams.class);
|
||||
return server.getClient().showDocument(showDocParams).thenApply(r -> {
|
||||
if (!r.isSuccess()) {
|
||||
|
||||
@@ -20,17 +20,17 @@ import java.util.stream.Collectors;
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.IAnnotationBinding;
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
import org.eclipse.lsp4j.CodeLens;
|
||||
import org.eclipse.lsp4j.Command;
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchies;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.CodeLensProvider;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.RewriteRefactorings;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
@@ -46,7 +46,7 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
*/
|
||||
public class DataRepositoryAotMetadataCodeLensProvider implements CodeLensProvider {
|
||||
|
||||
private static final String COVERT_TO_QUERY_LABEL = "Add @Query";
|
||||
private static final String COVERT_TO_QUERY_LABEL = "Turn into @Query";
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(DataRepositoryAotMetadataCodeLensProvider.class);
|
||||
|
||||
@@ -71,23 +71,12 @@ public class DataRepositoryAotMetadataCodeLensProvider implements CodeLensProvid
|
||||
});
|
||||
}
|
||||
|
||||
static boolean isDataQuaryNonAnnotatedMethodCandidate(IMethodBinding methodBinding) {
|
||||
static boolean isValidMethodBinding(IMethodBinding methodBinding) {
|
||||
if (methodBinding == null || methodBinding.getDeclaringClass() == null
|
||||
|| methodBinding.getMethodDeclaration() == null
|
||||
|| methodBinding.getDeclaringClass().getBinaryName() == null
|
||||
|| methodBinding.getMethodDeclaration().toString() == null) {
|
||||
|| methodBinding.getDeclaringClass().getBinaryName() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't show CodeLens if annotated with `@Query` or `@NativeQuery`
|
||||
for (IAnnotationBinding a : methodBinding.getAnnotations()) {
|
||||
ITypeBinding t = a.getAnnotationType();
|
||||
if (t != null
|
||||
&& (Annotations.DATA_JPA_QUERY.equals(t.getQualifiedName()) || Annotations.DATA_JPA_NATIVE_QUERY.equals(t.getQualifiedName()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -115,7 +104,7 @@ public class DataRepositoryAotMetadataCodeLensProvider implements CodeLensProvid
|
||||
|
||||
IMethodBinding methodBinding = node.resolveBinding();
|
||||
|
||||
if (isDataQuaryNonAnnotatedMethodCandidate(methodBinding)) {
|
||||
if (isValidMethodBinding(methodBinding)) {
|
||||
cancelToken.checkCanceled();
|
||||
getDataQuery(repositoryMetadataService, project, methodBinding)
|
||||
.map(queryStatement -> createCodeLenses(node, document, queryStatement))
|
||||
@@ -127,12 +116,30 @@ public class DataRepositoryAotMetadataCodeLensProvider implements CodeLensProvid
|
||||
List<CodeLens> codeLenses = new ArrayList<>(2);
|
||||
try {
|
||||
IMethodBinding mb = node.resolveBinding();
|
||||
Range range = document.toRange(node.getName().getStartPosition(), node.getName().getLength());
|
||||
Command queryTitle = new Command();
|
||||
queryTitle.setTitle(queryStatement);
|
||||
codeLenses.add(new CodeLens(range, queryTitle, null));
|
||||
if (mb != null) {
|
||||
codeLenses.add(new CodeLens(range, refactorings.createFixCommand(COVERT_TO_QUERY_LABEL, createFixDescriptor(mb, document.getUri(), queryStatement)), null));
|
||||
Position startPos = document.toPosition(node.getStartPosition());
|
||||
Position endPos = document.toPosition(node.getName().getStartPosition() + node.getName().getLength());
|
||||
Range range = new Range(startPos, endPos);
|
||||
AnnotationHierarchies hierarchyAnnot = AnnotationHierarchies.get(node);
|
||||
if (mb != null && hierarchyAnnot != null) {
|
||||
boolean isQueryAnnotated = hierarchyAnnot.isAnnotatedWith(mb, Annotations.DATA_JPA_QUERY);
|
||||
if (!isQueryAnnotated) {
|
||||
codeLenses.add(new CodeLens(range, refactorings.createFixCommand(COVERT_TO_QUERY_LABEL, createFixDescriptor(mb, document.getUri(), queryStatement)), null));
|
||||
}
|
||||
|
||||
Command impl = new Command("Implementation", GenAotQueryMethodDefinitionProvider.CMD_NAVIGATE_TO_IMPL, List.of(new GenAotQueryMethodDefinitionProvider.GoToImplParams(
|
||||
document.getId(),
|
||||
mb.getDeclaringClass().getQualifiedName(),
|
||||
mb.getName(),
|
||||
Arrays.stream(mb.getParameterTypes()).map(p -> p.getQualifiedName()).toArray(String[]::new),
|
||||
null
|
||||
)));
|
||||
codeLenses.add(new CodeLens(range, impl, null));
|
||||
|
||||
if (!isQueryAnnotated) {
|
||||
Command queryTitle = new Command();
|
||||
queryTitle.setTitle(queryStatement);
|
||||
codeLenses.add(new CodeLens(range, queryTitle, null));
|
||||
}
|
||||
}
|
||||
} catch (BadLocationException e) {
|
||||
log.error("bad location while calculating code lens for data repository query method", e);
|
||||
|
||||
@@ -22,7 +22,9 @@ import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -35,6 +37,7 @@ import org.eclipse.jdt.core.dom.SimpleName;
|
||||
import org.eclipse.lsp4j.LocationLink;
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.eclipse.lsp4j.ShowDocumentParams;
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
|
||||
import org.slf4j.Logger;
|
||||
@@ -46,19 +49,29 @@ import org.springframework.ide.vscode.commons.Version;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.SpringProjectUtil;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
public class GenAotQueryMethodDefinitionProvider implements IJavaDefinitionProvider {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(GenAotQueryMethodDefinitionProvider.class);
|
||||
|
||||
public static final String CMD_NAVIGATE_TO_IMPL = "sts/boot/open-data-query-method-aot-definition";
|
||||
|
||||
private final CompilationUnitCache cuCache;
|
||||
private final SimpleTextDocumentService docService;
|
||||
private final JavaProjectFinder projectFinder;
|
||||
|
||||
public GenAotQueryMethodDefinitionProvider(CompilationUnitCache cuCache, SimpleTextDocumentService docService) {
|
||||
public GenAotQueryMethodDefinitionProvider(SimpleLanguageServer server, CompilationUnitCache cuCache, JavaProjectFinder projectFinder) {
|
||||
this.cuCache = cuCache;
|
||||
this.docService = docService;
|
||||
this.docService = server.getTextDocumentService();
|
||||
this.projectFinder = projectFinder;
|
||||
registerCommands(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,17 +86,29 @@ public class GenAotQueryMethodDefinitionProvider implements IJavaDefinitionProvi
|
||||
&& methodBinding.getDeclaringClass() != null
|
||||
&& ASTUtils.isAnyTypeInHierarchy(methodBinding.getDeclaringClass(),
|
||||
List.of(Constants.REPOSITORY_TYPE))) {
|
||||
String genRepoFqn = methodBinding.getDeclaringClass().getQualifiedName() + "Impl__Aot";
|
||||
Path relativeGenSourcePath = Paths.get("%s.java".formatted(genRepoFqn.replace('.', '/')));
|
||||
List<LocationLink> defs = findInSourceFolder(project, relativeGenSourcePath, docId, md, methodBinding, genRepoFqn);
|
||||
return defs.isEmpty() ? findInBuildFolder(project, relativeGenSourcePath, docId, md, methodBinding, genRepoFqn) : defs;
|
||||
|
||||
try {
|
||||
Range originRange = docService.getLatestSnapshot(docId.getUri()).toRange(md.getName().getStartPosition(), md.getName().getLength());
|
||||
GoToImplParams params = new GoToImplParams(docId, methodBinding.getDeclaringClass().getQualifiedName(), methodBinding.getName(), Arrays.stream(methodBinding.getParameterTypes()).map(b -> b.getQualifiedName()).toArray(String[]::new), originRange);
|
||||
return findDefinitions(project, params);
|
||||
} catch (BadLocationException e) {
|
||||
log.error("", e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
private List<LocationLink> getLocationInGenFile(IJavaProject project, TextDocumentIdentifier docId, MethodDeclaration md, IMethodBinding methodBinding, Path genRepoSourcePath, String genRepoFqn) {
|
||||
private List<LocationLink> findDefinitions(IJavaProject project, GoToImplParams implParams) {
|
||||
String genRepoFqn = implParams.repoFqName() + "Impl__Aot";
|
||||
Path relativeGenSourcePath = Paths.get("%s.java".formatted(genRepoFqn.replace('.', '/')));
|
||||
List<LocationLink> defs = findInSourceFolder(project, relativeGenSourcePath, genRepoFqn, implParams);
|
||||
return defs.isEmpty() ? findInBuildFolder(project, relativeGenSourcePath, genRepoFqn, implParams) : defs;
|
||||
}
|
||||
|
||||
private List<LocationLink> getLocationInGenFile(IJavaProject project, Path genRepoSourcePath, String genRepoFqn, GoToImplParams params) {
|
||||
if (Files.exists(genRepoSourcePath)) {
|
||||
URI genUri = genRepoSourcePath.toUri();
|
||||
return cuCache.withCompilationUnit(project, genUri, genCu -> {
|
||||
@@ -94,21 +119,18 @@ public class GenAotQueryMethodDefinitionProvider implements IJavaDefinitionProvi
|
||||
public boolean visit(MethodDeclaration node) {
|
||||
IMethodBinding genBinding = node.resolveBinding();
|
||||
if (genBinding != null
|
||||
&& genBinding.getName().equals(methodBinding.getName())
|
||||
&& Arrays.equals(Arrays.stream(genBinding.getParameterTypes()).map(b -> b.getQualifiedName()).toArray(), Arrays.stream(methodBinding.getParameterTypes()).map(b -> b.getQualifiedName()).toArray() )
|
||||
&& genBinding.getName().equals(params.queryMethodName())
|
||||
&& Arrays.equals(Arrays.stream(genBinding.getParameterTypes()).map(b -> b.getQualifiedName()).toArray(), params.paramTypes)
|
||||
&& genRepoFqn.equals(genBinding.getDeclaringClass().getQualifiedName())) {
|
||||
LocationLink ll = new LocationLink();
|
||||
ll.setTargetUri(genUri.toASCIIString());
|
||||
try {
|
||||
ll.setOriginSelectionRange(docService.getLatestSnapshot(docId.getUri()).toRange(md.getName().getStartPosition(), md.getName().getLength()));
|
||||
} catch (BadLocationException e) {
|
||||
log.error("", e);
|
||||
}
|
||||
ll.setOriginSelectionRange(params.originSelection());
|
||||
SimpleName genName = node.getName();
|
||||
int startLine = genCu.getLineNumber(genName.getStartPosition());
|
||||
Position targetStartPosition = new Position(startLine, genName.getStartPosition() - genCu.getPosition(startLine, 0));
|
||||
// LSP line are 0-based hence -1 from line number when building LSP Range/Position
|
||||
Position targetStartPosition = new Position(startLine - 1, genName.getStartPosition() - genCu.getPosition(startLine, 0));
|
||||
int endLine = genCu.getLineNumber(genName.getStartPosition() + genName.getLength());
|
||||
Position targetEndPosition = new Position(endLine, genName.getStartPosition() + genName.getLength() - genCu.getPosition(endLine, 0));
|
||||
Position targetEndPosition = new Position(endLine - 1, genName.getStartPosition() + genName.getLength() - genCu.getPosition(endLine, 0));
|
||||
Range targetRange = new Range(targetStartPosition, targetEndPosition);
|
||||
ll.setTargetRange(targetRange);
|
||||
ll.setTargetSelectionRange(targetRange);
|
||||
@@ -124,15 +146,15 @@ public class GenAotQueryMethodDefinitionProvider implements IJavaDefinitionProvi
|
||||
return List.of();
|
||||
}
|
||||
|
||||
private List<LocationLink> findInSourceFolder(IJavaProject project, Path relativeGenSourcePath, TextDocumentIdentifier docId, MethodDeclaration md, IMethodBinding methodBinding, String genRepoFqn) {
|
||||
private List<LocationLink> findInSourceFolder(IJavaProject project, Path relativeGenSourcePath, String genRepoFqn, GoToImplParams params) {
|
||||
for (File f : IClasspathUtil.getSourceFolders(project.getClasspath()).collect(Collectors.toSet())) {
|
||||
Path genRepoSourcePath = f.toPath().resolve(relativeGenSourcePath);
|
||||
return getLocationInGenFile(project, docId, md, methodBinding, genRepoSourcePath, genRepoFqn);
|
||||
return getLocationInGenFile(project, genRepoSourcePath, genRepoFqn, params);
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
private List<LocationLink> findInBuildFolder(IJavaProject project, Path relativeGenSourcePath, TextDocumentIdentifier docId, MethodDeclaration md, IMethodBinding methodBinding, String genRepoFqn) {
|
||||
private List<LocationLink> findInBuildFolder(IJavaProject project, Path relativeGenSourcePath, String genRepoFqn, GoToImplParams params) {
|
||||
Path buildDirRelativePath = null;
|
||||
Path projectPath = Paths.get(project.getLocationUri());
|
||||
Set<Path> outputFolders = IClasspathUtil.getOutputFolders(project.getClasspath()).map(f -> f.toPath()).collect(Collectors.toSet());
|
||||
@@ -182,7 +204,30 @@ public class GenAotQueryMethodDefinitionProvider implements IJavaDefinitionProvi
|
||||
} catch (IOException e) {
|
||||
log.error("", e);
|
||||
}
|
||||
return genSourceFilePathRef.get() == null ? List.of() : getLocationInGenFile(project, docId, md, methodBinding, genSourceFilePathRef.get(), genRepoFqn);
|
||||
return genSourceFilePathRef.get() == null ? List.of() : getLocationInGenFile(project, genSourceFilePathRef.get(), genRepoFqn, params);
|
||||
}
|
||||
|
||||
private void registerCommands(SimpleLanguageServer server) {
|
||||
server.onCommand(CMD_NAVIGATE_TO_IMPL, params -> {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
GoToImplParams implParams = new Gson().fromJson((JsonElement) params.getArguments().get(0), GoToImplParams.class);
|
||||
Optional<IJavaProject> project = projectFinder.find(implParams.docId());
|
||||
if (project.isEmpty()) {
|
||||
return List.<LocationLink>of();
|
||||
}
|
||||
return findDefinitions(project.get(), implParams);
|
||||
}).thenCompose(links -> {
|
||||
if (links.isEmpty()) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
} else {
|
||||
ShowDocumentParams showDocParams = new ShowDocumentParams(links.get(0).getTargetUri());
|
||||
showDocParams.setSelection(links.get(0).getTargetRange());
|
||||
return server.getClient().showDocument(showDocParams);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public record GoToImplParams(TextDocumentIdentifier docId, String repoFqName, String queryMethodName, String[] paramTypes, Range originSelection) {}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,8 @@ import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
import org.eclipse.lsp4j.CodeAction;
|
||||
import org.eclipse.lsp4j.CodeActionKind;
|
||||
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchies;
|
||||
import org.springframework.ide.vscode.boot.java.codeaction.JdtAstCodeActionProvider;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.RewriteRefactorings;
|
||||
import org.springframework.ide.vscode.commons.Version;
|
||||
@@ -30,7 +32,7 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
public class QueryMethodCodeActionProvider implements JdtAstCodeActionProvider {
|
||||
|
||||
private static final String TITLE = "Convert into `@Query`";
|
||||
private static final String TITLE = "Add `@Query`";
|
||||
|
||||
private final DataRepositoryAotMetadataService repositoryMetadataService;
|
||||
private final RewriteRefactorings refactorings;
|
||||
@@ -55,11 +57,12 @@ public class QueryMethodCodeActionProvider implements JdtAstCodeActionProvider {
|
||||
public boolean visit(MethodDeclaration node) {
|
||||
cancelToken.checkCanceled();
|
||||
if (node.getStartPosition() <= region.getStart() && node.getStartPosition() + node.getLength() >= region.getEnd()) {
|
||||
int offset = node.getName().getStartPosition();
|
||||
int length = node.getName().getLength();
|
||||
if (offset <= region.getStart() && offset + length >= region.getEnd()) {
|
||||
int start = node.getStartPosition();
|
||||
int end = node.getName().getStartPosition() + node.getName().getLength();
|
||||
if (start <= region.getStart() && end >= region.getEnd()) {
|
||||
IMethodBinding binding = node.resolveBinding();
|
||||
if (DataRepositoryAotMetadataCodeLensProvider.isDataQuaryNonAnnotatedMethodCandidate(binding)) {
|
||||
AnnotationHierarchies hierarchyAnnot = AnnotationHierarchies.get(node);
|
||||
if (hierarchyAnnot != null && !hierarchyAnnot.isAnnotatedWith(binding, Annotations.DATA_JPA_QUERY)) {
|
||||
DataRepositoryAotMetadataCodeLensProvider.getDataQuery(repositoryMetadataService, project, binding)
|
||||
.map(query -> createCodeAction(binding, docURI, query)).ifPresent(collector::accept);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.eclipse.lsp4j.Command;
|
||||
import org.eclipse.lsp4j.Diagnostic;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.eclipse.lsp4j.ShowDocumentParams;
|
||||
import org.springframework.ide.vscode.boot.app.BootLanguageServerInitializer;
|
||||
import org.springframework.ide.vscode.boot.validation.generations.json.Generation;
|
||||
import org.springframework.ide.vscode.boot.validation.generations.json.ResolvedSpringProject;
|
||||
import org.springframework.ide.vscode.boot.validation.generations.preferences.VersionValidationProblemType;
|
||||
@@ -148,7 +149,7 @@ public class GenerationsValidator extends AbstractDiagnosticValidator {
|
||||
showDocumentParams.setExternal(true);
|
||||
showDocumentParams.setTakeFocus(true);
|
||||
showDocumentParams.setSelection(new Range());
|
||||
commercialSupportLink.setCommand(new Command("Get commercial Spring Boot support via Tanzu Spring Runtime", "sts/show/document",
|
||||
commercialSupportLink.setCommand(new Command("Get commercial Spring Boot support via Tanzu Spring Runtime", BootLanguageServerInitializer.CMD_SHOW_DOC,
|
||||
ImmutableList.of(showDocumentParams)));
|
||||
return commercialSupportLink;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.eclipse.lsp4j.Command;
|
||||
import org.eclipse.lsp4j.Diagnostic;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.eclipse.lsp4j.ShowDocumentParams;
|
||||
import org.springframework.ide.vscode.boot.app.BootLanguageServerInitializer;
|
||||
import org.springframework.ide.vscode.boot.java.rewrite.SpringBootUpgrade;
|
||||
import org.springframework.ide.vscode.boot.validation.generations.preferences.VersionValidationProblemType;
|
||||
import org.springframework.ide.vscode.commons.Version;
|
||||
@@ -157,7 +158,7 @@ public class UpdateBootVersion extends AbstractDiagnosticValidator {
|
||||
showDocumentParams.setExternal(true);
|
||||
showDocumentParams.setTakeFocus(true);
|
||||
showDocumentParams.setSelection(new Range());
|
||||
releaseNoteLink.setCommand(new Command("Release Notes for Spring Boot " + version.toString(), "sts/show/document",
|
||||
releaseNoteLink.setCommand(new Command("Release Notes for Spring Boot " + version.toString(), BootLanguageServerInitializer.CMD_SHOW_DOC,
|
||||
ImmutableList.of(showDocumentParams)));
|
||||
return releaseNoteLink;
|
||||
}
|
||||
|
||||
@@ -10,13 +10,17 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.data.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.lsp4j.CodeLens;
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -64,8 +68,10 @@ public class DataRepositoryAotMetadataCodeLensProviderTest {
|
||||
.resolve("src/main/java/example/springdata/aot/UserRepository.java");
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA, new String(Files.readAllBytes(filePath), StandardCharsets.UTF_8), filePath.toUri().toASCIIString());
|
||||
|
||||
editor.assertCodeLens("findUserByUsername", 1, "SELECT u FROM example.springdata.aot.User u WHERE u.username = :username");
|
||||
editor.assertCodeLens("findUserByUsername", 1, "Add @Query");
|
||||
List<CodeLens> cls = editor.getCodeLenses("findUserByUsername", 1);
|
||||
assertEquals("Turn into @Query", cls.get(0).getCommand().getTitle());
|
||||
assertEquals("Implementation", cls.get(1).getCommand().getTitle());
|
||||
assertEquals("SELECT u FROM example.springdata.aot.User u WHERE u.username = :username", cls.get(2).getCommand().getTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -74,6 +80,9 @@ public class DataRepositoryAotMetadataCodeLensProviderTest {
|
||||
.resolve("src/main/java/example/springdata/aot/UserRepository.java");
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA, new String(Files.readAllBytes(filePath), StandardCharsets.UTF_8), filePath.toUri().toASCIIString());
|
||||
|
||||
editor.assertCodeLens("usersWithUsernamesStartingWith", 1, null);
|
||||
List<CodeLens> cls = editor.getCodeLenses("usersWithUsernamesStartingWith", 1);
|
||||
assertEquals(1, cls.size());
|
||||
assertEquals("Implementation", cls.get(0).getCommand().getTitle());
|
||||
assertEquals(1, cls.get(0).getCommand().getArguments().size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,8 +73,8 @@ public class GenAotQueryMethodDefinitionProviderTest {
|
||||
.resolve("target/spring-aot/main/sources/example/springdata/aot/UserRepositoryImpl__Aot.java").toUri()
|
||||
.toASCIIString());
|
||||
ll.setOriginSelectionRange(new Range(new Position(43, 15), new Position(43, 61)));
|
||||
ll.setTargetRange(new Range(new Position(145, 20), new Position(145, 66)));
|
||||
ll.setTargetSelectionRange(new Range(new Position(145, 20), new Position(145, 66)));
|
||||
ll.setTargetRange(new Range(new Position(144, 20), new Position(144, 66)));
|
||||
ll.setTargetSelectionRange(new Range(new Position(144, 20), new Position(144, 66)));
|
||||
editor.assertLinkTargets("findUserByLastnameStartingWith", List.of(ll));
|
||||
}
|
||||
|
||||
@@ -89,8 +89,8 @@ public class GenAotQueryMethodDefinitionProviderTest {
|
||||
.resolve("target/spring-aot/main/sources/example/springdata/aot/UserRepositoryImpl__Aot.java").toUri()
|
||||
.toASCIIString());
|
||||
ll.setOriginSelectionRange(new Range(new Position(54, 15), new Position(54, 45)));
|
||||
ll.setTargetRange(new Range(new Position(191, 20), new Position(191, 50)));
|
||||
ll.setTargetSelectionRange(new Range(new Position(191, 20), new Position(191, 50)));
|
||||
ll.setTargetRange(new Range(new Position(190, 20), new Position(190, 50)));
|
||||
ll.setTargetSelectionRange(new Range(new Position(190, 20), new Position(190, 50)));
|
||||
editor.assertLinkTargets("usersWithUsernamesStartingWith", List.of(ll));
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ public class QueryMethodCodeActionProviderTest {
|
||||
List<CodeAction> codeActions = editor.getCodeActions("findUserByLastnameStartingWith", 1);
|
||||
assertEquals(1, codeActions.size());
|
||||
CodeAction ca = codeActions.get(0);
|
||||
assertEquals("Convert into `@Query`", ca.getLabel());
|
||||
assertEquals("Add `@Query`", ca.getLabel());
|
||||
Command cmd = ca.getCommand();
|
||||
assertEquals(RewriteRefactorings.REWRITE_RECIPE_QUICKFIX, cmd.getArguments().get(0));
|
||||
WorkspaceEdit edit = refactorings.createEdit((JsonElement) cmd.getArguments().get(1)).get(5, TimeUnit.SECONDS);
|
||||
|
||||
Reference in New Issue
Block a user