internal/langserver/handlers/code_action.go (102 lines of code) (raw):

package handlers import ( "context" "encoding/json" "strings" lsctx "github.com/Azure/azapi-lsp/internal/context" ilsp "github.com/Azure/azapi-lsp/internal/lsp" lsp "github.com/Azure/azapi-lsp/internal/protocol" "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclsyntax" ) func (h *logHandler) TextDocumentCodeAction(ctx context.Context, params lsp.CodeActionParams) []lsp.CodeAction { ca, err := h.textDocumentCodeAction(ctx, params) if err != nil { h.logger.Printf("code action failed: %s", err) } return ca } func (h *logHandler) textDocumentCodeAction(ctx context.Context, params lsp.CodeActionParams) ([]lsp.CodeAction, error) { var list []lsp.CodeAction fs, err := lsctx.DocumentStorage(ctx) if err != nil { return list, err } doc, err := fs.GetDocument(ilsp.FileHandlerFromDocumentURI(params.TextDocument.URI)) if err != nil { return list, err } startDocPos := lsp.TextDocumentPositionParams{ TextDocument: params.TextDocument, Position: params.Range.Start, } startPos, err := ilsp.FilePositionFromDocumentPosition(startDocPos, doc) if err != nil { return list, err } endDocPos := lsp.TextDocumentPositionParams{ TextDocument: params.TextDocument, Position: params.Range.End, } endPos, err := ilsp.FilePositionFromDocumentPosition(endDocPos, doc) if err != nil { return list, err } data, err := doc.Text() if err != nil { return list, err } hclDoc, _ := hclsyntax.ParseConfig(data, "", hcl.InitialPos) body, isHcl := hclDoc.Body.(*hclsyntax.Body) if !isHcl { h.logger.Printf("file is not hcl") return list, nil } hasAzapiResources := false hasAzurermResources := false for _, block := range body.Blocks { if startPos.Position().Byte <= block.Range().Start.Byte && block.Range().End.Byte <= endPos.Position().Byte { if block.Type != "resource" { continue } address := strings.Join(block.Labels, ".") if strings.HasPrefix(address, "azapi_resource.") { hasAzapiResources = true } if strings.HasPrefix(address, "azurerm") { hasAzurermResources = true } } } // If the file has both azapi and azurerm resources or neither, we can't migrate if hasAzapiResources == hasAzurermResources { return list, nil } title := "" if hasAzapiResources { title = "Migrate to AzureRM Provider" } else { title = "Migrate to AzAPI Provider" } argument, _ := json.Marshal(params) list = append(list, lsp.CodeAction{ Title: title, Kind: "refactor.rewrite", Diagnostics: nil, IsPreferred: false, Disabled: nil, Edit: lsp.WorkspaceEdit{ Changes: nil, DocumentChanges: nil, ChangeAnnotations: nil, }, Command: &lsp.Command{ Title: title, Command: CommandAztfMigrate, Arguments: []json.RawMessage{ argument, }, }, Data: nil, }) return list, nil }