Apply edit via LSP. Fix maven changes
This commit is contained in:
@@ -161,17 +161,10 @@ public class ORDocUtils {
|
||||
WorkspaceEdit we = new WorkspaceEdit();
|
||||
we.setDocumentChanges(new ArrayList<>());
|
||||
for (Result result : results) {
|
||||
if (result.getBefore() == null) {
|
||||
String docUri = result.getAfter().getSourcePath().toUri().toASCIIString();
|
||||
createNewFileEdit(docUri, result.getAfter().printAll(), changeAnnotationId, we);
|
||||
} else if (result.getAfter() == null) {
|
||||
String docUri = result.getBefore().getSourcePath().toUri().toASCIIString();
|
||||
createDeleteFileEdit(docUri, we);
|
||||
} else {
|
||||
String docUri = result.getBefore().getSourcePath().toUri().toASCIIString();
|
||||
createUpdateFileEdit(documents, docUri, result.getBefore().printAll(), result.getAfter().printAll(), changeAnnotationId, we);
|
||||
}
|
||||
|
||||
String docUri = result.getBefore() == null ? result.getAfter().getSourcePath().toUri().toASCIIString() : result.getBefore().getSourcePath().toUri().toASCIIString();
|
||||
String oldContent = result.getBefore() == null ? null : result.getBefore().printAll();
|
||||
String newContent = result.getAfter() == null ? null : result.getAfter().printAll();
|
||||
createWorkspaceEdit(documents, docUri, oldContent, newContent, changeAnnotationId, we);
|
||||
}
|
||||
return Optional.of(we);
|
||||
}
|
||||
@@ -180,7 +173,7 @@ public class ORDocUtils {
|
||||
if(oldContent == null) {
|
||||
createNewFileEdit(docUri, newContent, changeAnnotationId, we);
|
||||
} else if (newContent == null) {
|
||||
createDeleteFileEdit(docUri, we);
|
||||
createDeleteFileEdit(docUri, changeAnnotationId, we);
|
||||
} else {
|
||||
createUpdateFileEdit(documents, docUri, oldContent, newContent, changeAnnotationId, we);
|
||||
}
|
||||
@@ -190,6 +183,7 @@ public class ORDocUtils {
|
||||
WorkspaceEdit we) {
|
||||
CreateFile ro = new CreateFile();
|
||||
ro.setUri(docUri);
|
||||
ro.setAnnotationId(changeAnnotationId);
|
||||
we.getDocumentChanges().add(Either.forRight(ro));
|
||||
|
||||
TextDocumentEdit te = new TextDocumentEdit();
|
||||
@@ -199,8 +193,10 @@ public class ORDocUtils {
|
||||
we.getDocumentChanges().add(Either.forLeft(te));
|
||||
}
|
||||
|
||||
private static void createDeleteFileEdit(String docUri, WorkspaceEdit we) {
|
||||
we.getDocumentChanges().add(Either.forRight(new DeleteFile(docUri)));
|
||||
private static void createDeleteFileEdit(String docUri, String changeAnnotationId, WorkspaceEdit we) {
|
||||
DeleteFile ro = new DeleteFile(docUri);
|
||||
ro.setAnnotationId(changeAnnotationId);
|
||||
we.getDocumentChanges().add(Either.forRight(ro));
|
||||
}
|
||||
|
||||
private static void createUpdateFileEdit(SimpleTextDocumentService documents, String docUri, String oldContent,
|
||||
|
||||
@@ -1,10 +1,23 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2024 Broadcom, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Broadcom, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.copilot;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
|
||||
import org.eclipse.lsp4j.ApplyWorkspaceEditParams;
|
||||
import org.eclipse.lsp4j.ExecuteCommandParams;
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import org.eclipse.lsp4j.WorkspaceEdit;
|
||||
@@ -12,6 +25,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.copilot.util.ResponseModifier;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.IndefiniteProgressTask;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
|
||||
@@ -41,15 +55,27 @@ public class CopilotAgentCommandHandler {
|
||||
server.onCommand(CMD_COPILOT_AGENT_ENHANCERESPONSE, (params) -> {
|
||||
return enhanceResponseHandler(params);
|
||||
});
|
||||
log.info("Registered command handler: {}", CMD_COPILOT_AGENT_ENHANCERESPONSE);
|
||||
|
||||
server.onCommand(CMD_COPILOT_AGENT_LSPEDITS, params -> {
|
||||
try {
|
||||
return createLspEdits(params);
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
return null;
|
||||
final IndefiniteProgressTask progressTask = server.getProgressService().createIndefiniteProgressTask(UUID.randomUUID().toString(), "Applying GenAI Response", "Computing changes...");
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
return createLspEdits(params);
|
||||
} catch (IOException e) {
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
}).thenCompose(we -> {
|
||||
if (progressTask != null) {
|
||||
progressTask.progressEvent("Applying document changes...");
|
||||
}
|
||||
return server.getClient().applyEdit(new ApplyWorkspaceEditParams(we, "Apply GenAI Response")).thenCompose(res -> {
|
||||
if (res.isApplied()) {
|
||||
return CompletableFuture.completedFuture("success");
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
});
|
||||
}).whenComplete((o,t) -> progressTask.done());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -60,7 +86,7 @@ public class CopilotAgentCommandHandler {
|
||||
return CompletableFuture.completedFuture(modifiedResp);
|
||||
}
|
||||
|
||||
private CompletableFuture<WorkspaceEdit> createLspEdits(ExecuteCommandParams params) throws IOException {
|
||||
private WorkspaceEdit createLspEdits(ExecuteCommandParams params) throws IOException {
|
||||
log.info("Command Handler for lsp edits: ");
|
||||
String docURI = ((JsonElement) params.getArguments().get(0)).getAsString();
|
||||
String content = ((JsonElement) params.getArguments().get(1)).getAsString();
|
||||
@@ -69,8 +95,7 @@ public class CopilotAgentCommandHandler {
|
||||
List<ProjectArtifact> projectArtifacts = computeProjectArtifacts(content);
|
||||
ProjectArtifactEditGenerator editGenerator = new ProjectArtifactEditGenerator(server.getTextDocumentService(),
|
||||
projectArtifacts, Paths.get(project.getLocationUri()), docURI);
|
||||
WorkspaceEdit we = editGenerator.process().getResult();
|
||||
return CompletableFuture.completedFuture(we);
|
||||
return editGenerator.process().getResult();
|
||||
}
|
||||
|
||||
List<ProjectArtifact> computeProjectArtifacts(String response) {
|
||||
|
||||
@@ -77,8 +77,7 @@ public class InjectMavenActionHandler extends AbstractInjectMavenActionHandler {
|
||||
for (InjectMavenBuildPlugin p : buildPlugins) {
|
||||
List<Xml.Document> xmlDocuments = parseToXml(p.getText());
|
||||
for (Xml.Document xmlDocument : xmlDocuments) {
|
||||
MavenPluginMetadata pm = findMavenPluginTags(xmlDocument);
|
||||
if (pm != null) {
|
||||
for (MavenPluginMetadata pm : findMavenPluginTags(xmlDocument)) {
|
||||
AddPlugin addPlugin = new AddPlugin(pm.groupId(), pm.artifactId(), pm.version(), pm.configuration(),
|
||||
pm.dependencies(), pm.executions(), pm.filePattern());
|
||||
aggregateRecipe.getRecipeList().add(addPlugin);
|
||||
@@ -88,8 +87,7 @@ public class InjectMavenActionHandler extends AbstractInjectMavenActionHandler {
|
||||
for (InjectMavenRepository r : repositories) {
|
||||
List<Xml.Document> xmlDocuments = parseToXml(r.getText());
|
||||
for (Xml.Document xmlDocument : xmlDocuments) {
|
||||
MavenRepositoryMetadata rm = findRepositoryTags(xmlDocument);
|
||||
if (rm != null) {
|
||||
for (MavenRepositoryMetadata rm : findRepositoryTags(xmlDocument)) {
|
||||
AddRepository addRepository = new AddRepository(rm.id(), rm.url(), rm.repoName(), null,
|
||||
rm.snapshotsEnabled(), null, null, rm.releasesEnabled(), null, null, null);
|
||||
aggregateRecipe.getRecipeList().add(addRepository);
|
||||
@@ -99,8 +97,7 @@ public class InjectMavenActionHandler extends AbstractInjectMavenActionHandler {
|
||||
for (InjectMavenDependencyManagement dm : dependencyManagements) {
|
||||
List<Xml.Document> xmlDocuments = parseToXml(dm.getText());
|
||||
for (Xml.Document xmlDocument : xmlDocuments) {
|
||||
MavenDependencyMetadata mdm = findMavenDependencyTags(xmlDocument);
|
||||
if (mdm != null) {
|
||||
for (MavenDependencyMetadata mdm : findMavenDependencyTags(xmlDocument)) {
|
||||
AddManagedDependency addManagedDependency = new AddManagedDependency(mdm.groupId(), mdm.artifactId(),
|
||||
mdm.version(), mdm.scope(), null, mdm.classifier(), null, null, null, null);
|
||||
aggregateRecipe.getRecipeList().add(addManagedDependency);
|
||||
@@ -118,8 +115,9 @@ public class InjectMavenActionHandler extends AbstractInjectMavenActionHandler {
|
||||
return xmlDocuments;
|
||||
}
|
||||
|
||||
public MavenDependencyMetadata findMavenDependencyTags(Xml.Document xmlDocument) {
|
||||
public List<MavenDependencyMetadata> findMavenDependencyTags(Xml.Document xmlDocument) {
|
||||
Set<Tag> dependencyTags = FindTags.find(xmlDocument, "//dependency");
|
||||
List<MavenDependencyMetadata> deps = new ArrayList<>(dependencyTags.size());
|
||||
for (Tag dependencyTag : dependencyTags) {
|
||||
String groupId = dependencyTag.getChildValue("groupId").orElse(null);
|
||||
String artifactId = dependencyTag.getChildValue("artifactId").orElse(null);
|
||||
@@ -127,16 +125,16 @@ public class InjectMavenActionHandler extends AbstractInjectMavenActionHandler {
|
||||
String scope = dependencyTag.getChildValue("scope").orElse(null);
|
||||
String type = dependencyTag.getChildValue("type").orElse(null);
|
||||
String classifier = dependencyTag.getChildValue("classifier").orElse(null);
|
||||
if (groupId != null && artifactId != null && version != null)
|
||||
return new MavenDependencyMetadata(groupId, artifactId, version, scope, type, classifier);
|
||||
|
||||
if (groupId != null && artifactId != null && version != null) {
|
||||
deps.add(new MavenDependencyMetadata(groupId, artifactId, version, scope, type, classifier));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return deps;
|
||||
}
|
||||
|
||||
public MavenPluginMetadata findMavenPluginTags(Xml.Document xmlDocument) {
|
||||
public List<MavenPluginMetadata> findMavenPluginTags(Xml.Document xmlDocument) {
|
||||
Set<Tag> pluginTags = FindTags.find(xmlDocument, "//plugin");
|
||||
|
||||
List<MavenPluginMetadata> plugins = new ArrayList<>(pluginTags.size());
|
||||
for (Tag pluginTag : pluginTags) {
|
||||
String groupId = pluginTag.getChildValue("groupId").orElse(null);
|
||||
String artifactId = pluginTag.getChildValue("artifactId").orElse(null);
|
||||
@@ -146,16 +144,17 @@ public class InjectMavenActionHandler extends AbstractInjectMavenActionHandler {
|
||||
String executions = pluginTag.getChildValue("executions").orElse(null);
|
||||
String filePattern = pluginTag.getChildValue("filePattern").orElse(null);
|
||||
|
||||
if (groupId != null && artifactId != null && version != null)
|
||||
return new MavenPluginMetadata(groupId, artifactId, version, configuration, dependencies, executions,
|
||||
filePattern);
|
||||
if (groupId != null && artifactId != null && version != null) {
|
||||
plugins.add(new MavenPluginMetadata(groupId, artifactId, version, configuration, dependencies, executions,
|
||||
filePattern));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return plugins;
|
||||
}
|
||||
|
||||
private MavenRepositoryMetadata findRepositoryTags(Document xmlDocument) {
|
||||
private List<MavenRepositoryMetadata> findRepositoryTags(Document xmlDocument) {
|
||||
Set<Tag> repoTags = FindTags.find(xmlDocument, "//plugin");
|
||||
|
||||
List<MavenRepositoryMetadata> repos = new ArrayList<>(repoTags.size());
|
||||
for (Tag repoTag : repoTags) {
|
||||
String id = repoTag.getChildValue("id").orElse(null);
|
||||
String url = repoTag.getChildValue("url").orElse(null);
|
||||
@@ -163,10 +162,11 @@ public class InjectMavenActionHandler extends AbstractInjectMavenActionHandler {
|
||||
boolean snapshotsEnabled = Boolean.parseBoolean(repoTag.getChildValue("snapshotsEnabled").orElse(null));
|
||||
boolean releasesEnabled = Boolean.parseBoolean(repoTag.getChildValue("releasesEnabled").orElse(null));
|
||||
|
||||
if (id != null && url != null)
|
||||
return new MavenRepositoryMetadata(id, url, repoName, snapshotsEnabled, releasesEnabled);
|
||||
if (id != null && url != null) {
|
||||
repos.add(new MavenRepositoryMetadata(id, url, repoName, snapshotsEnabled, releasesEnabled));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return repos;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -135,8 +135,9 @@ public class ProjectArtifactEditGenerator {
|
||||
// Move the parsing to injectMavenActionHandler
|
||||
List<Xml.Document> xmlDocuments = injectMavenActionHandler.parseToXml(projectArtifact.getText());
|
||||
for (Xml.Document xmlDocument : xmlDocuments) {
|
||||
MavenDependencyMetadata dep = injectMavenActionHandler.findMavenDependencyTags(xmlDocument);
|
||||
injectMavenActionHandler.injectDependency(dep);
|
||||
for (MavenDependencyMetadata dep : injectMavenActionHandler.findMavenDependencyTags(xmlDocument)) {
|
||||
injectMavenActionHandler.injectDependency(dep);
|
||||
}
|
||||
}
|
||||
|
||||
List<Result> res = injectMavenActionHandler.run().getChangeset().getAllResults();
|
||||
|
||||
@@ -1,45 +1,10 @@
|
||||
import { Uri, workspace, window, commands, ProgressLocation } from "vscode";
|
||||
import { Uri, commands } from "vscode";
|
||||
import { getTargetGuideMardown, readResponseFromFile } from "./util";
|
||||
import { createConverter } from "vscode-languageclient/lib/common/protocolConverter";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
|
||||
const CONVERTER = createConverter(undefined, true, true);
|
||||
const CANCELLED = "Cancelled";
|
||||
|
||||
export async function applyLspEdit(uri: Uri) {
|
||||
try {
|
||||
if (!uri) {
|
||||
uri = await getTargetGuideMardown();
|
||||
}
|
||||
|
||||
window.withProgress({
|
||||
location: ProgressLocation.Window,
|
||||
title: "Copilot agent",
|
||||
cancellable: true
|
||||
}, async (progress, cancellation) => {
|
||||
progress.report({ message: "applying edits..." });
|
||||
const fileContent = (await readResponseFromFile(uri)).toString();
|
||||
const lspEdit = await commands.executeCommand("sts/copilot/agent/lspEdits", uri.toString(), fileContent);
|
||||
const workspaceEdit = await CONVERTER.asWorkspaceEdit(lspEdit);
|
||||
|
||||
|
||||
await Promise.all(workspaceEdit.entries().map(async ([uri, edits]) => {
|
||||
console.log(edits);
|
||||
if (fs.existsSync(uri.fsPath)) {
|
||||
const doc = await workspace.openTextDocument(uri.fsPath);
|
||||
await window.showTextDocument(doc);
|
||||
}
|
||||
}));
|
||||
|
||||
return await workspace.applyEdit(workspaceEdit, {
|
||||
isRefactoring: true
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
if (error !== CANCELLED) {
|
||||
window.showErrorMessage(error);
|
||||
}
|
||||
if (!uri) {
|
||||
uri = await getTargetGuideMardown();
|
||||
}
|
||||
const fileContent = (await readResponseFromFile(uri)).toString();
|
||||
await commands.executeCommand("sts/copilot/agent/lspEdits", uri.toString(), fileContent);
|
||||
}
|
||||
Reference in New Issue
Block a user