HLSL: bump to shader-language-server v1.3.1, remove CRLF workaround

The upstream fix for the CRLF stale-tree crash (antaalt/shader-sense#44)
was merged and released as v1.3.1. This commit:

- Removes the client-side CRLF workaround (open_file override and
  _preload_crlf_content helper) added in #1305, along with the
  now-unused imports.
- Bumps _DEFAULT_VERSION to 1.3.1 and updates SHA-256 checksums for
  all three pre-built platform archives (win-x64, linux-x64, win-arm64).

The regression test (test_include_file_document_symbols_directly) that
exercises the original crash scenario passes against v1.3.1 without the
workaround.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
TheSmallKiwiandClaude Sonnet 4.6 committed 2026-04-12 15:38:48 -04:00
1 parent 34a703ad50
commit e7b51173bc
2 files changed
+5 -96

No files matched your search

+1 -1
View File
@@ -472,7 +472,7 @@ Supported settings:
| Setting | Default | Description |
|---|---|---|
| `ls_path` | managed install or build | Override the `shader-language-server` executable path. |
| `version` | `1.3.0` | Override the bundled version Serena downloads, or builds from source on macOS, when `ls_path` is not set. |
| `version` | `1.3.1` | Override the bundled version Serena downloads, or builds from source on macOS, when `ls_path` is not set. |
#### Haxe
@@ -7,9 +7,6 @@ import logging
import os
import pathlib
import shutil
from collections.abc import Iterator
from contextlib import contextmanager
from pathlib import Path
from typing import Any, cast
import psutil
@@ -18,11 +15,9 @@ from overrides import override
from solidlsp.ls import (
LanguageServerDependencyProvider,
LanguageServerDependencyProviderSinglePath,
LSPFileBuffer,
SolidLanguageServer,
)
from solidlsp.ls_config import LanguageServerConfig
from solidlsp.ls_exceptions import SolidLSPException
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
from solidlsp.settings import SolidLSPSettings
@@ -31,13 +26,13 @@ from .common import RuntimeDependency, RuntimeDependencyCollection
log = logging.getLogger(__name__)
# GitHub release version to download when not installed locally
_DEFAULT_VERSION = "1.3.0"
_DEFAULT_VERSION = "1.3.1"
_GITHUB_RELEASE_BASE = "https://github.com/antaalt/shader-sense/releases/download"
_HLSL_ALLOWED_HOSTS = ("github.com", "release-assets.githubusercontent.com", "objects.githubusercontent.com")
_HLSL_SHA256_BY_ASSET = {
"shader-language-server-x86_64-pc-windows-msvc.zip": "a945b000c296cdeebb9ee2d4452cec2a0f26544dd076bb08bfdcade2278296a6",
"shader-language-server-x86_64-unknown-linux-gnu.zip": "8c0a7b36f51cc58593762db3592ae13e21ca3cb982b2526cfaaf7c82e92ca089",
"shader-language-server-aarch64-pc-windows-msvc.zip": "cdbd7b41e71cf6040d5cdb7e211ba4b76671a404ee0f7add281d72d3ab8dfa65",
"shader-language-server-x86_64-pc-windows-msvc.zip": "49081c5547ddde1b8b3b17295282a80ddacbca1d6f5dcd834e2788c02bafa997",
"shader-language-server-x86_64-unknown-linux-gnu.zip": "61710df7ca17a2d063b598936c57c56c49fbf837707a1aa886f9b0193a35be3c",
"shader-language-server-aarch64-pc-windows-msvc.zip": "a3b3799affe2cad27652e788376b46fe76e1a6c2ce45946a486dcb26c9091412",
}
@@ -277,92 +272,6 @@ class HlslLanguageServer(SolidLanguageServer):
log.debug(f"Error cleaning up shader-language-server process tree: {e}")
super().stop(shutdown_timeout)
@contextmanager
def open_file(self, relative_file_path: str, open_in_ls: bool = True) -> Iterator[LSPFileBuffer]:
"""Open a file for LSP, preserving on-disk CRLF line endings.
Workaround for an upstream bug in shader-language-server
(antaalt/shader-sense) where `watch_main_file` replaces an already-cached
module's content without re-parsing the tree-sitter tree. When a file is
first pulled into the server's cache via an `#include` from another
shader (where it's read via `std::fs::read_to_string`, preserving CRLF),
and then later opened directly via `textDocument/didOpen` with the
client-normalized LF text, the stored tree still references byte offsets
into the longer CRLF content. The next symbol query slices the new
(shorter) content with stale offsets and panics with
`byte index N is out of bounds` in `shader-sense/src/symbols/symbol_parser.rs`.
The root-cause fix belongs upstream (the server should call
`update_module` instead of assigning `content` raw). Until then, we
ensure the text we send in `didOpen` matches byte-for-byte what the
server reads from disk by preloading the file buffer with a
CRLF-preserving read before the LSP notification is sent.
This is the only place in Serena that overrides `open_file`; the fix is
deliberately scoped to the HLSL language server. It mirrors the base
class logic in `SolidLanguageServer.open_file` verbatim except for the
buffer construction branch, where creation is deferred (`open_in_ls=False`)
so the buffer's contents can be preloaded before `ensure_open_in_ls` runs.
"""
if not self.server_started:
log.error("open_file called before Language Server started")
raise SolidLSPException("Language Server not started")
absolute_file_path = Path(self.repository_root_path, relative_file_path)
uri = absolute_file_path.as_uri()
if uri in self.open_file_buffers:
fb = self.open_file_buffers[uri]
assert fb.uri == uri
assert fb.ref_count >= 1
fb.ref_count += 1
if open_in_ls:
fb.ensure_open_in_ls()
yield fb
fb.ref_count -= 1
else:
version = 0
language_id = self._get_language_id_for_file(relative_file_path)
# Defer the didOpen so we can preload CRLF-preserved content first.
fb = LSPFileBuffer(
abs_path=absolute_file_path,
uri=uri,
encoding=self._encoding,
version=version,
language_id=language_id,
ref_count=1,
language_server=self,
open_in_ls=False,
)
self._preload_crlf_content(fb)
self.open_file_buffers[uri] = fb
if open_in_ls:
fb.ensure_open_in_ls()
yield fb
fb.ref_count -= 1
if self.open_file_buffers[uri].ref_count == 0:
self.open_file_buffers[uri].close()
del self.open_file_buffers[uri]
def _preload_crlf_content(self, fb: LSPFileBuffer) -> None:
"""Populate an LSPFileBuffer with a CRLF-preserving read of its backing file.
Python's default text-mode open applies universal-newlines translation
(CRLF -> LF), which would desync the client's `didOpen` text from the
server-side `std::fs::read_to_string` view that parsed the dependency
tree. Passing `newline=""` disables the translation so bytes match.
"""
with open(fb.abs_path, encoding=fb.encoding, newline="") as f:
raw = f.read()
# Set the buffer's cached state directly: the contents, the mtime
# (required by the contents property's staleness check), and clear the
# hash so it's recomputed against the new bytes.
fb._contents = raw
fb._read_file_modified_date = fb.abs_path.stat().st_mtime
fb._content_hash = None
@override
def is_ignored_dirname(self, dirname: str) -> bool:
"""Ignore Unity-specific directories that contain no user-authored shaders."""