func()

in internal/langserver/handlers/code_action.go [24:118]


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
}