Repository: neovim
Issue: LSP: data properties will be removed if null
Labels: bug,lsp

### Problem

Neovim provides `dataSupprt` for codeActions and publishDiagnostics

```
	/**
	 * Whether code action supports the `data` property which is
	 * preserved between a `textDocument/codeAction` and a
	 * `codeAction/resolve` request.
	 *
	 * @since 3.16.0
	 */
	dataSupport?: boolean;
```

```
/**
	 * A data entry field that is preserved on a code action between
	 * a `textDocument/codeAction` and a `codeAction/resolve` request.
	 *
	 * @since 3.16.0
	 */
	data?: [LSPAny](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#lspAny);
}
```


In the example notice that `REALLY_IMPORTANT_PARAM` is missing from the resolve request.

Because we serialise converting null to lua nils, when we decode and re-encode we lose properties in the data object


### Steps to reproduce using "nvim -u minimal_init.lua"

```lua
local requests = {
  ['initialize'] = function(_)
    return {
      --- @type lsp.ServerCapabilities
      capabilities = {
        codeActionProvider = {
          resolveProvider = true,
          codeActionKinds = { 'source' },
        },
      },
    }
  end,
  ['shutdown'] = function(_) end,
  ['textDocument/codeAction'] = function(_)
    ---@type lsp.CodeAction[]
    local action = {
      {
        title = 'Example Action',
        kind = 'source',
        data = {
          something = 'this',
          REALLY_IMPORTANT_PARAM = vim.NIL,
          something_else = 'that',
        },
      },
    }
    --- NOTE: Force serde as in memory lsp doesnt go through rpc
    local encoded = vim.json.encode(action)
    local decoded = vim.json.decode(encoded, { luanil = { object = true } })
    return decoded
  end,
  ['codeAction/resolve'] = function(params)
    print(vim.inspect(params))
	return {}
retu
  end,
}

local noops = {
  ['initialized'] = true,
}

local function server()
  local srv = {}
  local closing = false

  function srv.request(method, params, handler)
    coroutine.wrap(function()
      if requests[method] then
        local response = requests[method](params)
        handler(nil, response)
      elseif method == 'exit' then
        closing = true
      else
        vim.notify('Unhandled request: ' .. method)
      end
    end)()
  end

  function srv.notify(method, _params)
    coroutine.wrap(function()
      if method == 'exit' then
        closing = true
      elseif not noops[method] then
        vim.notify('Unhandled notification: ' .. method)
      end
    end)()
  end

  function srv.is_closing()
    return closing
  end

  function srv.terminate()
    closing = true
  end

  return srv
end

vim.lsp.start({
  name = 'serde_nil',
  cmd = server,
})
```

Perform a code action and see that the param is missing

### Expected behavior

Data properties to be preserved as null is a valid LSPAny value

```
/**
 * The LSP any type
 *
 * @since 3.17.0
 */
export type LSPAny = LSPObject | LSPArray | string | integer | uinteger |
	decimal | boolean | null;

```

### Nvim version (nvim -v)

0.11

### Language server name/version

Any

### Operating system/version

N/A

### Log file

_No response_