java-functional-lsp 0.9.16__tar.gz → 0.9.18__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/PKG-INFO +1 -1
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/pyproject.toml +1 -1
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/src/java_functional_lsp/__init__.py +1 -1
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/src/java_functional_lsp/cli.py +7 -1
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/src/java_functional_lsp/server.py +42 -2
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/test_cli.py +16 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/uv.lock +1 -1
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.claude-plugin/plugin.json +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.githooks/pre-commit +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.githooks/pre-push +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/CODEOWNERS +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/ISSUE_TEMPLATE/bug-report.md +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/ISSUE_TEMPLATE/feature-request.md +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/SECURITY.md +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/dependabot.yml +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/release-drafter.yml +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/workflows/publish.yml +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/workflows/release-drafter.yml +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/workflows/stale.yml +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/workflows/test.yml +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/workflows/update-homebrew.yml +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/workflows/vscode-ext.yml +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.gitignore +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/CONTRIBUTING.md +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/LICENSE +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/README.md +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/SKILL.md +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/commands/lint-java.md +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/editors/intellij/README.md +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/editors/intellij/lsp4ij-template.json +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/editors/vscode/.vscodeignore +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/editors/vscode/README.md +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/editors/vscode/package-lock.json +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/editors/vscode/package.json +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/editors/vscode/src/extension.ts +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/editors/vscode/tsconfig.json +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/hooks/hooks.json +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/hooks/java_linter_reminder.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/scripts/ensure-lsp.sh +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/scripts/generate-formula.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/src/java_functional_lsp/__main__.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/src/java_functional_lsp/analyzers/__init__.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/src/java_functional_lsp/analyzers/base.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/src/java_functional_lsp/analyzers/exception_checker.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/src/java_functional_lsp/analyzers/functional_checker.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/src/java_functional_lsp/analyzers/mutation_checker.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/src/java_functional_lsp/analyzers/null_checker.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/src/java_functional_lsp/analyzers/spring_checker.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/src/java_functional_lsp/fixes.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/src/java_functional_lsp/merkle.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/src/java_functional_lsp/proxy.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/__init__.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/conftest.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/test_base.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/test_config.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/test_e2e.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/test_e2e_jdtls.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/test_exception_checker.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/test_fixes.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/test_functional_checker.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/test_merkle.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/test_merkle_proxy.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/test_mutation_checker.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/test_null_checker.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/test_proxy.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/test_server.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/test_spring_checker.py +0 -0
- {java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/tests/test_suppress.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: java-functional-lsp
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.18
|
|
4
4
|
Summary: Java LSP server enforcing functional programming best practices — null safety, immutability, no exceptions
|
|
5
5
|
Project-URL: Homepage, https://github.com/aviadshiber/java-functional-lsp
|
|
6
6
|
Project-URL: Repository, https://github.com/aviadshiber/java-functional-lsp
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "java-functional-lsp"
|
|
7
|
-
version = "0.9.
|
|
7
|
+
version = "0.9.18"
|
|
8
8
|
description = "Java LSP server enforcing functional programming best practices — null safety, immutability, no exceptions"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -7,6 +7,7 @@ import sys
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from typing import Any
|
|
9
9
|
|
|
10
|
+
from . import __version__
|
|
10
11
|
from .analyzers.base import Analyzer, Diagnostic, Severity, get_parser, is_excluded
|
|
11
12
|
from .analyzers.exception_checker import ExceptionChecker
|
|
12
13
|
from .analyzers.functional_checker import FunctionalChecker
|
|
@@ -69,7 +70,8 @@ def format_diagnostic(path: Path, d: Diagnostic) -> str:
|
|
|
69
70
|
_USAGE = """\
|
|
70
71
|
Usage: java-functional-lsp check <file.java> [file2.java ...]
|
|
71
72
|
java-functional-lsp check --dir <directory>
|
|
72
|
-
java-functional-lsp (start LSP server on stdio)
|
|
73
|
+
java-functional-lsp (start LSP server on stdio)
|
|
74
|
+
java-functional-lsp --version"""
|
|
73
75
|
|
|
74
76
|
|
|
75
77
|
def _collect_files(args: list[str]) -> list[Path]:
|
|
@@ -103,6 +105,10 @@ def main() -> None:
|
|
|
103
105
|
print(_USAGE)
|
|
104
106
|
sys.exit(0)
|
|
105
107
|
|
|
108
|
+
if args and args[0] in ("-v", "--version"):
|
|
109
|
+
print(f"java-functional-lsp {__version__}")
|
|
110
|
+
sys.exit(0)
|
|
111
|
+
|
|
106
112
|
if not args or args[0] != "check":
|
|
107
113
|
# No args or unknown command — start LSP server on stdio
|
|
108
114
|
from .server import main as lsp_main
|
|
@@ -16,7 +16,11 @@ import time
|
|
|
16
16
|
from collections import OrderedDict
|
|
17
17
|
from collections.abc import Coroutine
|
|
18
18
|
from pathlib import Path
|
|
19
|
-
from
|
|
19
|
+
from threading import Event
|
|
20
|
+
from typing import TYPE_CHECKING, Any
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from typing import BinaryIO
|
|
20
24
|
|
|
21
25
|
from lsprotocol import types as lsp
|
|
22
26
|
from lsprotocol.converters import get_converter
|
|
@@ -1204,10 +1208,46 @@ def on_code_action(params: lsp.CodeActionParams) -> list[lsp.CodeAction] | None:
|
|
|
1204
1208
|
# --- Entry point ---
|
|
1205
1209
|
|
|
1206
1210
|
|
|
1211
|
+
class _EternalStdinBuffer:
|
|
1212
|
+
"""Wraps sys.stdin.buffer so EOF never propagates to the pygls reader.
|
|
1213
|
+
|
|
1214
|
+
Claude Code (ENABLE_LSP_TOOL, versions ≤ 0.2.x) closes the LSP subprocess's
|
|
1215
|
+
stdin pipe immediately after process startup — before sending any LSP messages.
|
|
1216
|
+
pygls sees EOF on the first readline() and shuts down the server.
|
|
1217
|
+
|
|
1218
|
+
This wrapper intercepts that EOF: instead of returning b'' (which pygls's
|
|
1219
|
+
run_async() treats as a signal to break its read loop and shut down), it
|
|
1220
|
+
blocks the calling thread indefinitely via threading.Event.wait().
|
|
1221
|
+
|
|
1222
|
+
pygls uses a ThreadPoolExecutor for stdin reads (run_in_executor), so
|
|
1223
|
+
blocking one thread does not stall the asyncio event loop — all other
|
|
1224
|
+
coroutines (jdtls proxy, diagnostics publishing, etc.) remain responsive.
|
|
1225
|
+
|
|
1226
|
+
When Claude Code is fixed upstream, this class becomes a transparent pass-
|
|
1227
|
+
through: data before EOF is forwarded unchanged; only the EOF itself is swallowed.
|
|
1228
|
+
"""
|
|
1229
|
+
|
|
1230
|
+
def __init__(self, buf: BinaryIO) -> None:
|
|
1231
|
+
self._buf = buf
|
|
1232
|
+
self._eof_gate = Event() # never set — waits block forever
|
|
1233
|
+
|
|
1234
|
+
def readline(self) -> bytes:
|
|
1235
|
+
line = self._buf.readline()
|
|
1236
|
+
if not line:
|
|
1237
|
+
self._eof_gate.wait() # block forever instead of returning b''
|
|
1238
|
+
return line
|
|
1239
|
+
|
|
1240
|
+
def read(self, n: int) -> bytes:
|
|
1241
|
+
data = self._buf.read(n)
|
|
1242
|
+
if not data:
|
|
1243
|
+
self._eof_gate.wait()
|
|
1244
|
+
return data
|
|
1245
|
+
|
|
1246
|
+
|
|
1207
1247
|
def main() -> None:
|
|
1208
1248
|
"""Entry point for the LSP server."""
|
|
1209
1249
|
logging.basicConfig(level=logging.INFO, format="%(name)s %(levelname)s: %(message)s")
|
|
1210
|
-
server.start_io()
|
|
1250
|
+
server.start_io(stdin=_EternalStdinBuffer(sys.stdin.buffer)) # type: ignore[arg-type]
|
|
1211
1251
|
|
|
1212
1252
|
|
|
1213
1253
|
if __name__ == "__main__":
|
|
@@ -79,3 +79,19 @@ class TestHelp:
|
|
|
79
79
|
main()
|
|
80
80
|
assert exc.value.code == 0
|
|
81
81
|
assert "check" in capsys.readouterr().out
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class TestVersion:
|
|
85
|
+
def test_version_flag(self, capsys: pytest.CaptureFixture[str]) -> None:
|
|
86
|
+
with patch("sys.argv", ["java-functional-lsp", "--version"]):
|
|
87
|
+
with pytest.raises(SystemExit) as exc:
|
|
88
|
+
main()
|
|
89
|
+
assert exc.value.code == 0
|
|
90
|
+
assert "java-functional-lsp" in capsys.readouterr().out
|
|
91
|
+
|
|
92
|
+
def test_version_short_flag(self, capsys: pytest.CaptureFixture[str]) -> None:
|
|
93
|
+
with patch("sys.argv", ["java-functional-lsp", "-v"]):
|
|
94
|
+
with pytest.raises(SystemExit) as exc:
|
|
95
|
+
main()
|
|
96
|
+
assert exc.value.code == 0
|
|
97
|
+
assert "java-functional-lsp" in capsys.readouterr().out
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/ISSUE_TEMPLATE/bug-report.md
RENAMED
|
File without changes
|
{java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/ISSUE_TEMPLATE/feature-request.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/workflows/release-drafter.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/.github/workflows/update-homebrew.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/editors/intellij/lsp4ij-template.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/src/java_functional_lsp/__main__.py
RENAMED
|
File without changes
|
|
File without changes
|
{java_functional_lsp-0.9.16 → java_functional_lsp-0.9.18}/src/java_functional_lsp/analyzers/base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|