java-functional-lsp 0.9.15__tar.gz → 0.9.16__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.15 → java_functional_lsp-0.9.16}/PKG-INFO +1 -1
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/editors/intellij/README.md +1 -1
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/pyproject.toml +1 -1
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/src/java_functional_lsp/__init__.py +1 -1
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/src/java_functional_lsp/cli.py +34 -25
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/test_cli.py +27 -1
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/test_server.py +7 -2
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.claude-plugin/plugin.json +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.githooks/pre-commit +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.githooks/pre-push +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.github/CODEOWNERS +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.github/ISSUE_TEMPLATE/bug-report.md +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.github/ISSUE_TEMPLATE/feature-request.md +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.github/SECURITY.md +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.github/dependabot.yml +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.github/release-drafter.yml +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.github/workflows/publish.yml +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.github/workflows/release-drafter.yml +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.github/workflows/stale.yml +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.github/workflows/test.yml +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.github/workflows/update-homebrew.yml +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.github/workflows/vscode-ext.yml +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.gitignore +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/CONTRIBUTING.md +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/LICENSE +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/README.md +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/SKILL.md +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/commands/lint-java.md +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/editors/intellij/lsp4ij-template.json +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/editors/vscode/.vscodeignore +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/editors/vscode/README.md +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/editors/vscode/package-lock.json +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/editors/vscode/package.json +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/editors/vscode/src/extension.ts +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/editors/vscode/tsconfig.json +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/hooks/hooks.json +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/hooks/java_linter_reminder.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/scripts/ensure-lsp.sh +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/scripts/generate-formula.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/src/java_functional_lsp/__main__.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/src/java_functional_lsp/analyzers/__init__.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/src/java_functional_lsp/analyzers/base.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/src/java_functional_lsp/analyzers/exception_checker.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/src/java_functional_lsp/analyzers/functional_checker.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/src/java_functional_lsp/analyzers/mutation_checker.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/src/java_functional_lsp/analyzers/null_checker.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/src/java_functional_lsp/analyzers/spring_checker.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/src/java_functional_lsp/fixes.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/src/java_functional_lsp/merkle.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/src/java_functional_lsp/proxy.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/src/java_functional_lsp/server.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/__init__.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/conftest.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/test_base.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/test_config.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/test_e2e.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/test_e2e_jdtls.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/test_exception_checker.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/test_fixes.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/test_functional_checker.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/test_merkle.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/test_merkle_proxy.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/test_mutation_checker.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/test_null_checker.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/test_proxy.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/test_spring_checker.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/tests/test_suppress.py +0 -0
- {java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/uv.lock +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.16
|
|
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
|
|
@@ -84,7 +84,7 @@ The server automatically detects JetBrains IDEs and disables the jdtls proxy —
|
|
|
84
84
|
### No diagnostics appear
|
|
85
85
|
- Ensure the file mapping is set to Language: `Java`, Language ID: `java`
|
|
86
86
|
- Check that `.java-functional-lsp.json` doesn't have rules set to `"off"`
|
|
87
|
-
- Try restarting the language server: **
|
|
87
|
+
- Try restarting the language server: **Language Servers** (search it in intellij Actions [Double Shift on keyboard]) → click on java-functional-lsp → **Restart**
|
|
88
88
|
- If diagnostics worked before but stopped, the jdtls proxy may be interfering. Set `JAVA_FUNCTIONAL_LSP_JDTLS=off` in the server command environment to force-disable jdtls. The server auto-detects JetBrains IDEs and disables jdtls by default (since IntelliJ provides native Java support), but this can be overridden with `JAVA_FUNCTIONAL_LSP_JDTLS=on`.
|
|
89
89
|
|
|
90
90
|
### PATH not found
|
|
@@ -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.16"
|
|
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" }
|
|
@@ -66,14 +66,41 @@ def format_diagnostic(path: Path, d: Diagnostic) -> str:
|
|
|
66
66
|
return f"{path}:{d.line + 1}:{d.col}: [{sym}] {d.code}: {d.message}"
|
|
67
67
|
|
|
68
68
|
|
|
69
|
+
_USAGE = """\
|
|
70
|
+
Usage: java-functional-lsp check <file.java> [file2.java ...]
|
|
71
|
+
java-functional-lsp check --dir <directory>
|
|
72
|
+
java-functional-lsp (start LSP server on stdio)"""
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _collect_files(args: list[str]) -> list[Path]:
|
|
76
|
+
"""Resolve CLI args to a list of .java paths."""
|
|
77
|
+
files: list[Path] = []
|
|
78
|
+
if args and args[0] == "--dir":
|
|
79
|
+
if len(args) < 2:
|
|
80
|
+
print("Error: --dir requires a directory path", file=sys.stderr)
|
|
81
|
+
sys.exit(1)
|
|
82
|
+
directory = Path(args[1])
|
|
83
|
+
if not directory.is_dir():
|
|
84
|
+
print(f"Error: {directory} is not a directory", file=sys.stderr)
|
|
85
|
+
sys.exit(1)
|
|
86
|
+
return sorted(directory.rglob("*.java"))
|
|
87
|
+
for arg in args:
|
|
88
|
+
p = Path(arg)
|
|
89
|
+
if p.is_file():
|
|
90
|
+
files.append(p)
|
|
91
|
+
elif p.is_dir():
|
|
92
|
+
files.extend(sorted(p.rglob("*.java")))
|
|
93
|
+
else:
|
|
94
|
+
print(f"Warning: {arg} not found, skipping", file=sys.stderr)
|
|
95
|
+
return files
|
|
96
|
+
|
|
97
|
+
|
|
69
98
|
def main() -> None:
|
|
70
99
|
"""CLI entry point: java-functional-lsp check <files...>"""
|
|
71
100
|
args = sys.argv[1:]
|
|
72
101
|
|
|
73
102
|
if args and args[0] in ("-h", "--help"):
|
|
74
|
-
print(
|
|
75
|
-
print(" java-functional-lsp check --dir <directory>")
|
|
76
|
-
print(" java-functional-lsp (start LSP server on stdio)")
|
|
103
|
+
print(_USAGE)
|
|
77
104
|
sys.exit(0)
|
|
78
105
|
|
|
79
106
|
if not args or args[0] != "check":
|
|
@@ -85,34 +112,16 @@ def main() -> None:
|
|
|
85
112
|
|
|
86
113
|
args = args[1:] # skip "check"
|
|
87
114
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if len(args) < 2:
|
|
92
|
-
print("Error: --dir requires a directory path", file=sys.stderr)
|
|
93
|
-
sys.exit(1)
|
|
94
|
-
directory = Path(args[1])
|
|
95
|
-
if not directory.is_dir():
|
|
96
|
-
print(f"Error: {directory} is not a directory", file=sys.stderr)
|
|
97
|
-
sys.exit(1)
|
|
98
|
-
files = sorted(directory.rglob("*.java"))
|
|
99
|
-
else:
|
|
100
|
-
for arg in args:
|
|
101
|
-
p = Path(arg)
|
|
102
|
-
if p.is_file():
|
|
103
|
-
files.append(p)
|
|
104
|
-
elif p.is_dir():
|
|
105
|
-
files.extend(sorted(p.rglob("*.java")))
|
|
106
|
-
else:
|
|
107
|
-
print(f"Warning: {arg} not found, skipping", file=sys.stderr)
|
|
115
|
+
if args and args[0] in ("-h", "--help"):
|
|
116
|
+
print(_USAGE)
|
|
117
|
+
sys.exit(0)
|
|
108
118
|
|
|
119
|
+
files = _collect_files(args)
|
|
109
120
|
if not files:
|
|
110
121
|
print("No .java files found", file=sys.stderr)
|
|
111
122
|
sys.exit(1)
|
|
112
123
|
|
|
113
|
-
# Load config from first file's directory
|
|
114
124
|
config = load_config(files[0])
|
|
115
|
-
|
|
116
125
|
total_diags = 0
|
|
117
126
|
excludes: list[str] = config.get("excludes", [])
|
|
118
127
|
for path in files:
|
|
@@ -4,8 +4,11 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
from typing import Any
|
|
7
|
+
from unittest.mock import patch
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
from java_functional_lsp.cli import check_file, format_diagnostic, load_config, main
|
|
9
12
|
|
|
10
13
|
|
|
11
14
|
class TestCheckFile:
|
|
@@ -53,3 +56,26 @@ class TestLoadConfig:
|
|
|
53
56
|
def test_missing_config(self, tmp_path: Path) -> None:
|
|
54
57
|
config = load_config(tmp_path / "Test.java")
|
|
55
58
|
assert config == {}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class TestHelp:
|
|
62
|
+
def test_top_level_help(self, capsys: pytest.CaptureFixture[str]) -> None:
|
|
63
|
+
with patch("sys.argv", ["java-functional-lsp", "--help"]):
|
|
64
|
+
with pytest.raises(SystemExit) as exc:
|
|
65
|
+
main()
|
|
66
|
+
assert exc.value.code == 0
|
|
67
|
+
assert "check" in capsys.readouterr().out
|
|
68
|
+
|
|
69
|
+
def test_check_subcommand_help(self, capsys: pytest.CaptureFixture[str]) -> None:
|
|
70
|
+
with patch("sys.argv", ["java-functional-lsp", "check", "--help"]):
|
|
71
|
+
with pytest.raises(SystemExit) as exc:
|
|
72
|
+
main()
|
|
73
|
+
assert exc.value.code == 0
|
|
74
|
+
assert "check" in capsys.readouterr().out
|
|
75
|
+
|
|
76
|
+
def test_check_short_help(self, capsys: pytest.CaptureFixture[str]) -> None:
|
|
77
|
+
with patch("sys.argv", ["java-functional-lsp", "check", "-h"]):
|
|
78
|
+
with pytest.raises(SystemExit) as exc:
|
|
79
|
+
main()
|
|
80
|
+
assert exc.value.code == 0
|
|
81
|
+
assert "check" in capsys.readouterr().out
|
|
@@ -109,12 +109,17 @@ async def lsp_client(tmp_path: Any) -> LanguageClient: # type: ignore[misc]
|
|
|
109
109
|
try:
|
|
110
110
|
yield client
|
|
111
111
|
finally:
|
|
112
|
+
# Teardown with timeouts: the server subprocess may be mid-jdtls-startup
|
|
113
|
+
# on a slow CI runner, causing shutdown_async or stop to hang indefinitely.
|
|
112
114
|
try:
|
|
113
|
-
await client.shutdown_async(None)
|
|
115
|
+
await asyncio.wait_for(client.shutdown_async(None), timeout=5.0)
|
|
114
116
|
client.exit(None)
|
|
115
117
|
except Exception:
|
|
116
118
|
pass
|
|
117
|
-
|
|
119
|
+
try:
|
|
120
|
+
await asyncio.wait_for(client.stop(), timeout=5.0)
|
|
121
|
+
except Exception:
|
|
122
|
+
pass
|
|
118
123
|
|
|
119
124
|
|
|
120
125
|
async def _open_and_wait_for_diagnostics(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.github/ISSUE_TEMPLATE/bug-report.md
RENAMED
|
File without changes
|
{java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.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.15 → java_functional_lsp-0.9.16}/.github/workflows/release-drafter.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/.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
|
{java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/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.15 → java_functional_lsp-0.9.16}/src/java_functional_lsp/__main__.py
RENAMED
|
File without changes
|
|
File without changes
|
{java_functional_lsp-0.9.15 → java_functional_lsp-0.9.16}/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
|
|
File without changes
|