mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-13 12:15:10 +00:00
feat(jdtls): surface Lombok-generated methods in document symbols, bump jdtls version (#1434)
* feat(jdtls): surface Lombok-generated methods in document symbols JDTLS' DocumentSymbolHandler filtered out every SourceMethod where JDTUtils.isGenerated() was true, so Lombok-synthesised methods (getX/setX, builder(), equals/hashCode/toString, withX, fluent accessors, ...) never reached the LSP client. As a result Serena's symbol-aware tools — find_symbol, get_symbols_overview, replace_symbol_body, insert_before_symbol, insert_after_symbol — could not see, address or edit any Lombok-generated member; only search_for_pattern / replace_content (text-based) worked. Upstream introduced an opt-in preference java.symbols.includeGeneratedCode in eclipse-jdtls/eclipse.jdt.ls#3706 (merged 2026-02-24) and surfaced it through redhat-developer/vscode-java#4335. First vscode-java release with the new JDTLS build is v1.53.0 (2026-02-26). Serena was pinned to v1.42.0-561, well before the fix existed. Changes: - New ls_specific_settings.java.lombok_show_generated setting (default true); forwarded to JDTLS as java.symbols.includeGeneratedCode in initialize params. Older servers ignore the unknown preference key silently. - Bump bundled vscode-java DEFAULT 1.42.0-561 -> 1.54.0-923 (brings JRE 21.0.10, Lombok 1.18.39 and Equinox launcher 1.7.100). INITIAL stays at 1.42.0-561, so per the per-version install-dir convention from #1438 the new build lands in vscode-java-1.54.0-923/ while legacy vscode-java/ caches and any explicit vscode_java_version: '1.42.0-561' override keep working. - New VsixResourcePaths dataclass + INITIAL/DEFAULT_VSCODE_JAVA_PATHS pin the JRE / Lombok / launcher filenames *inside* the VSIX. Without this, bumping the archive would break users on legacy 1.42.0-561 because resource paths inside the archive change between releases. Resolution mirrors SHA pinning: known versions get their pinned paths; any other version raises SolidLSPException with a pointer to upstream-jdtls mode (which derives paths dynamically and needs no pinning). - Drop dead 'static/vscode-java/...' placeholder in initialize params; the real runtimes[] is overwritten below from runtime_dependency_paths .jre_home_path, which is correct in both default-VSIX and upstream-jdtls modes. - Test fixtures: Lombok provided dep in test_repo/pom.xml plus LombokModel / FluentLombokModel / DefaultGreeter covering @Data, @Builder (toBuilder=true), @With, @Delegate, @AllArgsConstructor, @NoArgsConstructor and @Accessors(fluent=true). Regression test in test_java_basic.py asserts every generated-method shape lands in document symbols. Closes #1432
This commit is contained in:
1 parent
3122384822
commit
ba6170bab1
8 files changed
+229
-35
No files matched your search
@@ -28,6 +28,7 @@ Status of the `main` branch. Changes prior to the next official version change w
|
||||
* Language Servers:
|
||||
- Elixir (`elixir-tools/next-ls`): Fix deadlock in monorepo projects where `mix.exs` lives in a subdirectory. The server now searches immediate subdirectories when no `mix.exs` is found at the repository root. #1444
|
||||
- Java (`eclipse.jdt.ls`): Add upstream JDTLS mode for offline / restricted-network use. Setting both `jdtls_path` and `lombok_path` in `ls_specific_settings.java` makes Serena use an existing upstream JDTLS installation (e.g. `brew install jdtls`) and the system JDK 21+, skipping the ~500 MB vscode-java VSIX, Gradle, and IntelliCode downloads. New related setting `java_home` lets the user override the JDK used to launch JDTLS. Default behavior unchanged — the JDTLS workspace hash is preserved bit-for-bit for users on the default route, so existing project caches are reused without a one-time reindex; the launcher path is mixed into the hash only when `jdtls_path` is set, isolating upstream installations from the default workspace. #1415
|
||||
- Java (eclipse.jdt.ls): Lombok-generated methods (getters/setters, builder(), equals/hashCode/toString, etc.) are now included in symbol-based tools (find_symbol, get_symbols_overview, edits). Added lombok_show_generated setting (default: on) to toggle this. Updated bundled vscode-java to 1.54.0-923. Issue #1432.
|
||||
- Add **Angular** (experimental) via a dual-server architecture: `@angular/language-server` (ngserver) handles standalone `.html` template files, while a companion `typescript-language-server` with `@angular/language-service` loaded as a tsserver plugin handles all `.ts` operations including inline templates. Provides type-aware navigation between templates and component classes. Requires Node.js, npm, and `@angular/core` installed in the project (`npm install` in the project root). Subsumes `typescript`+`html` for `.ts`/`.html` files when active; SCSS is not subsumed.
|
||||
- Add **HTML** (experimental) using `vscode-html-language-server` from the `vscode-langservers-extracted` npm package. Provides in-file element/id symbols via documentSymbol; cross-file references are not meaningful for HTML. Also used as a companion server by the Angular LS for plain HTML documentSymbol support.
|
||||
- Add **SCSS / Sass / CSS** (experimental) using [some-sass-language-server](https://github.com/wkillerud/some-sass). Handles `.scss`, `.sass`, and `.css` through one server, with full `@use`/`@forward` workspace-wide go-to-definition and find-references for variables, mixins, and functions across Sass files. The `.css` path uses the same `vscode-css-languageservice` engine that powers the standalone CSS LS; CSS feature toggles default off upstream and are flipped on at startup so symbols, hover, completion, and syntax-level diagnostics work for plain CSS as well.
|
||||
|
||||
@@ -589,8 +589,9 @@ The following settings are supported for the Java language server:
|
||||
| `gradle_java_home` | `null` | Path to the JDK used by Gradle. When unset, Gradle uses the bundled JRE. |
|
||||
| `use_system_java_home` | `false` | Use the system's `JAVA_HOME` environment variable for JDTLS itself. Enable this if your project requires a specific JDK vendor or version for Gradle's JDK checks. |
|
||||
| `gradle_version` | `8.14.2` | (vscode-java mode only) Override the Gradle distribution version Serena downloads by default. |
|
||||
| `vscode_java_version` | `1.42.0-561` | (vscode-java mode only) Override the bundled `vscode-java` runtime bundle version Serena downloads by default. |
|
||||
| `vscode_java_version` | `1.54.0-923` | (vscode-java mode only) Override the bundled `vscode-java` runtime bundle version Serena downloads by default. |
|
||||
| `intellicode_version` | `1.2.30` | (vscode-java mode only) Override the IntelliCode VSIX version Serena downloads by default. |
|
||||
| `lombok_show_generated` | `true` | Show Lombok-generated methods (`getX/setX`, `builder()`, `equals/hashCode/toString`, `withX`, fluent accessors) in `find_symbol`, `get_symbols_overview` and the symbol-edit tools. Set to `false` to restore the previous JDTLS default and hide the synthetic methods (e.g. when `@Data` classes pollute the outline with too many getters/setters). Requires JDTLS commit `b2d8952` / `vscode-java >= 1.53.0`; the bundled default already meets this. |
|
||||
| `jdtls_xmx` | `3G` | Maximum heap size for the JDTLS server JVM. |
|
||||
| `jdtls_xms` | `100m` | Initial heap size for the JDTLS server JVM. |
|
||||
| `intellicode_xmx` | `1G` | (vscode-java mode only) Maximum heap size for the IntelliCode embedded JVM. |
|
||||
@@ -613,7 +614,7 @@ Example: upstream-jdtls mode (offline / corporate network):
|
||||
ls_specific_settings:
|
||||
java:
|
||||
jdtls_path: "/opt/homebrew/Cellar/jdtls/1.50.0/libexec"
|
||||
lombok_path: "/Users/me/.m2/repository/org/projectlombok/lombok/1.18.36/lombok-1.18.36.jar"
|
||||
lombok_path: "/Users/me/.m2/repository/org/projectlombok/lombok/1.18.38/lombok-1.18.38.jar"
|
||||
# java_home: "/opt/homebrew/opt/openjdk@21" # optional
|
||||
```
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ INTELLICODE_ALLOWED_HOSTS = (
|
||||
"download.visualstudio.microsoft.com",
|
||||
)
|
||||
|
||||
|
||||
# Version pinning convention (read this before bumping anything below):
|
||||
#
|
||||
# INITIAL_* — the very first version we shipped runtime-dependency support for, paired with
|
||||
@@ -62,6 +63,22 @@ INTELLICODE_ALLOWED_HOSTS = (
|
||||
# custom_settings and the matching cached subdir is picked up without re-downloading.
|
||||
# - INITIAL_* and DEFAULT_* hold identical literals when first introduced; they diverge on
|
||||
# the first DEFAULT_* bump and stay independent thereafter.
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class VsixResourcePaths:
|
||||
"""
|
||||
Paths to resources inside the vscode-java VSIX archive. These vary between vscode-java
|
||||
releases (JRE bundle, Lombok jar, Equinox launcher all have versioned filenames inside
|
||||
the VSIX), so we pin them per-version alongside SHA256 — bumping the VSIX version means
|
||||
bumping these too. Without this, a user requesting a non-DEFAULT pinned version would
|
||||
extract the right archive but then crash on FileNotFoundError trying to find the wrong
|
||||
JRE / Lombok / launcher inside it.
|
||||
"""
|
||||
|
||||
jre_version: str # e.g. "21.0.7"; expanded to extension/jre/{jre_version}-{platform-suffix}
|
||||
lombok_jar_basename: str # e.g. "lombok-1.18.36.jar"
|
||||
equinox_launcher_basename: str # e.g. "org.eclipse.equinox.launcher_1.7.0.v20250424-1814.jar"
|
||||
|
||||
|
||||
INITIAL_VSCODE_JAVA_VERSION = "1.42.0-561"
|
||||
INITIAL_VSCODE_JAVA_SHA256_BY_PLATFORM = {
|
||||
"osx-arm64": "bc00c2699d4b8d478eb9a1621db9d6d3a12ea0dcc247a9cd8040e8ac19c03933",
|
||||
@@ -70,14 +87,26 @@ INITIAL_VSCODE_JAVA_SHA256_BY_PLATFORM = {
|
||||
"linux-x64": "7660b7b527be6fda46a917966b34d828e7416d5cc84287b29b88e7b99c1737f9",
|
||||
"win-x64": "ef195b45bd260976ad2e84618f4044b5d7248deed41d647573f0ee22c4233df3",
|
||||
}
|
||||
DEFAULT_VSCODE_JAVA_VERSION = "1.42.0-561"
|
||||
INITIAL_VSCODE_JAVA_PATHS = VsixResourcePaths(
|
||||
jre_version="21.0.7",
|
||||
lombok_jar_basename="lombok-1.18.36.jar",
|
||||
equinox_launcher_basename="org.eclipse.equinox.launcher_1.7.0.v20250424-1814.jar",
|
||||
)
|
||||
# Bumped from 1.42.0-561 to surface Lombok-generated methods (#1432); brings JDTLS commit b2d8952
|
||||
# (java.symbols.includeGeneratedCode), JRE 21.0.10, Lombok 1.18.39 and Equinox launcher 1.7.100.
|
||||
DEFAULT_VSCODE_JAVA_VERSION = "1.54.0-923"
|
||||
DEFAULT_VSCODE_JAVA_SHA256_BY_PLATFORM = {
|
||||
"osx-arm64": "bc00c2699d4b8d478eb9a1621db9d6d3a12ea0dcc247a9cd8040e8ac19c03933",
|
||||
"osx-x64": "03ae1db1a22c15561a620f1b722d6797d35d4faaa7c4666dbe6ca2715089852f",
|
||||
"linux-arm64": "e15bc9b2a665d3453203402621b5441062aa41b0ec2d140661f439326fd248c1",
|
||||
"linux-x64": "7660b7b527be6fda46a917966b34d828e7416d5cc84287b29b88e7b99c1737f9",
|
||||
"win-x64": "ef195b45bd260976ad2e84618f4044b5d7248deed41d647573f0ee22c4233df3",
|
||||
"osx-arm64": "c54c45cb0d2579d8e0a4ddeb24d4a9dd0b460d07d9366adea2b38a1da22a463c",
|
||||
"osx-x64": "dfc98abc4e54165a78372e280242a039671729b1b03420608df3b10c6b629fb6",
|
||||
"linux-arm64": "e2bb22c427d90da8dbb1afff72ff1e2dce38d50b76deb02d7bc313a330a1330c",
|
||||
"linux-x64": "9d4b15da54e25a0192f9bac073f086c015397d3676623b68dbf83a5dbaf5132b",
|
||||
"win-x64": "66f3914987edeccfee8a2558470e0fde4f8c4154232ff4baa5d73373ebc819d4",
|
||||
}
|
||||
DEFAULT_VSCODE_JAVA_PATHS = VsixResourcePaths(
|
||||
jre_version="21.0.10",
|
||||
lombok_jar_basename="lombok-1.18.39-4050.jar",
|
||||
equinox_launcher_basename="org.eclipse.equinox.launcher_1.7.100.v20251111-0406.jar",
|
||||
)
|
||||
|
||||
INITIAL_INTELLICODE_VERSION = "1.2.30"
|
||||
INITIAL_INTELLICODE_SHA256 = "7f61a7f96d101cdf230f96821be3fddd8f890ebfefb3695d18beee43004ae251"
|
||||
@@ -156,8 +185,16 @@ class EclipseJDTLS(SolidLanguageServer):
|
||||
- jdtls_xms: Initial heap size for the JDTLS server JVM (default: "100m")
|
||||
- intellicode_xmx: Maximum heap size for the IntelliCode embedded JVM (default: "1G")
|
||||
- intellicode_xms: Initial heap size for the IntelliCode embedded JVM (default: "100m")
|
||||
- lombok_show_generated: Show Lombok-generated methods (getX/setX/builder()/...) in document
|
||||
symbols by sending java.symbols.includeGeneratedCode=true to JDTLS (default: true).
|
||||
Set to false for @Data-heavy projects where the extra getters/setters are noise.
|
||||
Requires JDTLS commit b2d8952+ (vscode-java >= 1.53.0); older servers ignore the
|
||||
key silently. See eclipse-jdtls/eclipse.jdt.ls#3706 and serena #1432.
|
||||
- gradle_version: Override the pinned Gradle distribution version downloaded by Serena
|
||||
- vscode_java_version: Override the pinned vscode-java runtime bundle version downloaded by Serena
|
||||
- vscode_java_version: Override the pinned vscode-java runtime bundle version downloaded by Serena.
|
||||
Pinned versions: "1.54.0-923" (default) and "1.42.0-561" (legacy / initial). Other versions
|
||||
are not supported in default VSIX mode (the resource paths inside the archive change between
|
||||
releases); use upstream-jdtls mode for arbitrary versions.
|
||||
- intellicode_version: Override the pinned IntelliCode VSIX version downloaded by Serena
|
||||
|
||||
Example configuration for upstream JDTLS mode (no downloads, suitable for offline/corporate):
|
||||
@@ -184,8 +221,9 @@ class EclipseJDTLS(SolidLanguageServer):
|
||||
jdtls_xms: "100m" # initial heap size for the JDTLS server JVM
|
||||
intellicode_xmx: "1G" # maximum heap size for the IntelliCode embedded JVM
|
||||
intellicode_xms: "100m" # initial heap size for the IntelliCode embedded JVM
|
||||
lombok_show_generated: true # show Lombok-generated methods in document symbols (default true)
|
||||
gradle_version: "8.14.2"
|
||||
vscode_java_version: "1.42.0-561"
|
||||
vscode_java_version: "1.54.0-923" # also accepts pinned legacy "1.42.0-561"
|
||||
intellicode_version: "1.2.30"
|
||||
```
|
||||
"""
|
||||
@@ -305,6 +343,23 @@ class EclipseJDTLS(SolidLanguageServer):
|
||||
return DEFAULT_INTELLICODE_SHA256
|
||||
return None
|
||||
|
||||
# Resolve internal VSIX paths (JRE / Lombok / launcher filenames). For pinned versions
|
||||
# these are known; for any other user-supplied version we bail out — guessing would
|
||||
# silently produce broken paths at JDTLS launch time, which is a worse UX than failing
|
||||
# fast here with a pointer to upstream-JDTLS mode (which doesn't need pinned paths).
|
||||
if vscode_java_version == INITIAL_VSCODE_JAVA_VERSION:
|
||||
vsix_paths = INITIAL_VSCODE_JAVA_PATHS
|
||||
elif vscode_java_version == DEFAULT_VSCODE_JAVA_VERSION:
|
||||
vsix_paths = DEFAULT_VSCODE_JAVA_PATHS
|
||||
else:
|
||||
raise SolidLSPException(
|
||||
f"Resource paths inside the vscode-java {vscode_java_version} VSIX are not pinned in serena "
|
||||
f"(known: {INITIAL_VSCODE_JAVA_VERSION}, {DEFAULT_VSCODE_JAVA_VERSION}). "
|
||||
f"Either remove the 'vscode_java_version' override (defaults to {DEFAULT_VSCODE_JAVA_VERSION}), "
|
||||
f"or use upstream JDTLS mode by setting both 'jdtls_path' and 'lombok_path' in "
|
||||
f"ls_specific_settings.java (no pinning required)."
|
||||
)
|
||||
|
||||
runtime_dependencies: dict[str, dict[str, dict[str, object]]] = {
|
||||
"gradle": {
|
||||
"platform-agnostic": {
|
||||
@@ -329,10 +384,10 @@ class EclipseJDTLS(SolidLanguageServer):
|
||||
"relative_extraction_path": vscode_java_dirname,
|
||||
"sha256": vscode_java_sha("osx-arm64"),
|
||||
"allowed_hosts": VSCODE_JAVA_ALLOWED_HOSTS,
|
||||
"jre_home_path": "extension/jre/21.0.7-macosx-aarch64",
|
||||
"jre_path": "extension/jre/21.0.7-macosx-aarch64/bin/java",
|
||||
"lombok_jar_path": "extension/lombok/lombok-1.18.36.jar",
|
||||
"jdtls_launcher_jar_path": "extension/server/plugins/org.eclipse.equinox.launcher_1.7.0.v20250424-1814.jar",
|
||||
"jre_home_path": f"extension/jre/{vsix_paths.jre_version}-macosx-aarch64",
|
||||
"jre_path": f"extension/jre/{vsix_paths.jre_version}-macosx-aarch64/bin/java",
|
||||
"lombok_jar_path": f"extension/lombok/{vsix_paths.lombok_jar_basename}",
|
||||
"jdtls_launcher_jar_path": f"extension/server/plugins/{vsix_paths.equinox_launcher_basename}",
|
||||
"jdtls_readonly_config_path": "extension/server/config_mac_arm",
|
||||
},
|
||||
"osx-x64": {
|
||||
@@ -341,10 +396,10 @@ class EclipseJDTLS(SolidLanguageServer):
|
||||
"relative_extraction_path": vscode_java_dirname,
|
||||
"sha256": vscode_java_sha("osx-x64"),
|
||||
"allowed_hosts": VSCODE_JAVA_ALLOWED_HOSTS,
|
||||
"jre_home_path": "extension/jre/21.0.7-macosx-x86_64",
|
||||
"jre_path": "extension/jre/21.0.7-macosx-x86_64/bin/java",
|
||||
"lombok_jar_path": "extension/lombok/lombok-1.18.36.jar",
|
||||
"jdtls_launcher_jar_path": "extension/server/plugins/org.eclipse.equinox.launcher_1.7.0.v20250424-1814.jar",
|
||||
"jre_home_path": f"extension/jre/{vsix_paths.jre_version}-macosx-x86_64",
|
||||
"jre_path": f"extension/jre/{vsix_paths.jre_version}-macosx-x86_64/bin/java",
|
||||
"lombok_jar_path": f"extension/lombok/{vsix_paths.lombok_jar_basename}",
|
||||
"jdtls_launcher_jar_path": f"extension/server/plugins/{vsix_paths.equinox_launcher_basename}",
|
||||
"jdtls_readonly_config_path": "extension/server/config_mac",
|
||||
},
|
||||
"linux-arm64": {
|
||||
@@ -353,10 +408,10 @@ class EclipseJDTLS(SolidLanguageServer):
|
||||
"relative_extraction_path": vscode_java_dirname,
|
||||
"sha256": vscode_java_sha("linux-arm64"),
|
||||
"allowed_hosts": VSCODE_JAVA_ALLOWED_HOSTS,
|
||||
"jre_home_path": "extension/jre/21.0.7-linux-aarch64",
|
||||
"jre_path": "extension/jre/21.0.7-linux-aarch64/bin/java",
|
||||
"lombok_jar_path": "extension/lombok/lombok-1.18.36.jar",
|
||||
"jdtls_launcher_jar_path": "extension/server/plugins/org.eclipse.equinox.launcher_1.7.0.v20250424-1814.jar",
|
||||
"jre_home_path": f"extension/jre/{vsix_paths.jre_version}-linux-aarch64",
|
||||
"jre_path": f"extension/jre/{vsix_paths.jre_version}-linux-aarch64/bin/java",
|
||||
"lombok_jar_path": f"extension/lombok/{vsix_paths.lombok_jar_basename}",
|
||||
"jdtls_launcher_jar_path": f"extension/server/plugins/{vsix_paths.equinox_launcher_basename}",
|
||||
"jdtls_readonly_config_path": "extension/server/config_linux_arm",
|
||||
},
|
||||
"linux-x64": {
|
||||
@@ -365,10 +420,10 @@ class EclipseJDTLS(SolidLanguageServer):
|
||||
"relative_extraction_path": vscode_java_dirname,
|
||||
"sha256": vscode_java_sha("linux-x64"),
|
||||
"allowed_hosts": VSCODE_JAVA_ALLOWED_HOSTS,
|
||||
"jre_home_path": "extension/jre/21.0.7-linux-x86_64",
|
||||
"jre_path": "extension/jre/21.0.7-linux-x86_64/bin/java",
|
||||
"lombok_jar_path": "extension/lombok/lombok-1.18.36.jar",
|
||||
"jdtls_launcher_jar_path": "extension/server/plugins/org.eclipse.equinox.launcher_1.7.0.v20250424-1814.jar",
|
||||
"jre_home_path": f"extension/jre/{vsix_paths.jre_version}-linux-x86_64",
|
||||
"jre_path": f"extension/jre/{vsix_paths.jre_version}-linux-x86_64/bin/java",
|
||||
"lombok_jar_path": f"extension/lombok/{vsix_paths.lombok_jar_basename}",
|
||||
"jdtls_launcher_jar_path": f"extension/server/plugins/{vsix_paths.equinox_launcher_basename}",
|
||||
"jdtls_readonly_config_path": "extension/server/config_linux",
|
||||
},
|
||||
"win-x64": {
|
||||
@@ -377,10 +432,10 @@ class EclipseJDTLS(SolidLanguageServer):
|
||||
"relative_extraction_path": vscode_java_dirname,
|
||||
"sha256": vscode_java_sha("win-x64"),
|
||||
"allowed_hosts": VSCODE_JAVA_ALLOWED_HOSTS,
|
||||
"jre_home_path": "extension/jre/21.0.7-win32-x86_64",
|
||||
"jre_path": "extension/jre/21.0.7-win32-x86_64/bin/java.exe",
|
||||
"lombok_jar_path": "extension/lombok/lombok-1.18.36.jar",
|
||||
"jdtls_launcher_jar_path": "extension/server/plugins/org.eclipse.equinox.launcher_1.7.0.v20250424-1814.jar",
|
||||
"jre_home_path": f"extension/jre/{vsix_paths.jre_version}-win32-x86_64",
|
||||
"jre_path": f"extension/jre/{vsix_paths.jre_version}-win32-x86_64/bin/java.exe",
|
||||
"lombok_jar_path": f"extension/lombok/{vsix_paths.lombok_jar_basename}",
|
||||
"jdtls_launcher_jar_path": f"extension/server/plugins/{vsix_paths.equinox_launcher_basename}",
|
||||
"jdtls_readonly_config_path": "extension/server/config_win",
|
||||
},
|
||||
},
|
||||
@@ -883,6 +938,15 @@ class EclipseJDTLS(SolidLanguageServer):
|
||||
intellicode_xmx = self._custom_settings.get("intellicode_xmx", "1G")
|
||||
intellicode_xms = self._custom_settings.get("intellicode_xms", "100m")
|
||||
|
||||
# Lombok-generated symbols (getX/setX/builder()/equals/hashCode/toString/...): JDTLS filters
|
||||
# these out of documentSymbol results by default. Without them, find_symbol/get_symbols_overview
|
||||
# return only user-written sources, which breaks navigation around @Data/@Builder/@Getter/@Setter
|
||||
# classes. Default to True so agentic workflows can find_symbol -> replace_symbol_body on generated
|
||||
# members. Requires JDTLS commit b2d8952 or newer (vscode-java >= 1.53.0, or upstream JDTLS
|
||||
# snapshot after 2026-02-24); older servers ignore the unknown preference key silently.
|
||||
# See eclipse-jdtls/eclipse.jdt.ls#3706.
|
||||
lombok_show_generated = self._custom_settings.get("lombok_show_generated", True)
|
||||
|
||||
# Gradle wrapper: default to False to preserve existing behaviour
|
||||
gradle_wrapper_enabled = self._custom_settings.get("gradle_wrapper_enabled", False)
|
||||
log.info(
|
||||
@@ -1096,9 +1160,10 @@ class EclipseJDTLS(SolidLanguageServer):
|
||||
"defaultMojoExecutionAction": "ignore",
|
||||
},
|
||||
"workspaceCacheLimit": 90,
|
||||
"runtimes": [
|
||||
{"name": "JavaSE-21", "path": "static/vscode-java/extension/jre/21.0.7-linux-x86_64", "default": True}
|
||||
],
|
||||
# Placeholder; the real `runtimes` array is overwritten below from
|
||||
# self.runtime_dependency_paths.jre_home_path (works for both default
|
||||
# VSIX mode and upstream-jdtls mode, which uses the system JDK).
|
||||
"runtimes": [],
|
||||
},
|
||||
"trace": {"server": "verbose"},
|
||||
"import": {
|
||||
@@ -1162,7 +1227,11 @@ class EclipseJDTLS(SolidLanguageServer):
|
||||
"references": {"includeAccessors": True, "includeDecompiledSources": True},
|
||||
"typeHierarchy": {"lazyLoad": False},
|
||||
"settings": {"url": None},
|
||||
"symbols": {"includeSourceMethodDeclarations": False},
|
||||
"symbols": {
|
||||
"includeSourceMethodDeclarations": False,
|
||||
# Surface Lombok-generated methods in document symbols (#1432).
|
||||
"includeGeneratedCode": lombok_show_generated,
|
||||
},
|
||||
"inlayHints": {"parameterNames": {"enabled": "literals", "exclusions": []}},
|
||||
"codeAction": {"sortMembers": {"avoidVolatileChanges": True}},
|
||||
"compile": {
|
||||
|
||||
@@ -11,8 +11,18 @@
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<maven.compiler.plugin.version>3.13.0</maven.compiler.plugin.version>
|
||||
<lombok.version>1.18.38</lombok.version>
|
||||
</properties>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
@@ -22,6 +32,13 @@
|
||||
<configuration>
|
||||
<source>21</source>
|
||||
<target>21</target>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package test_repo;
|
||||
|
||||
class DefaultGreeter implements LombokModel.Greeter {
|
||||
@Override
|
||||
public String greet() {
|
||||
return "hi";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String farewell() {
|
||||
return "bye";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package test_repo;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/** Verifies prefix-stripped fluent accessors generated by @Accessors(fluent=true). */
|
||||
@Getter
|
||||
@Setter
|
||||
@Accessors(fluent = true)
|
||||
public class FluentLombokModel {
|
||||
private String host;
|
||||
private String tag;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package test_repo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.With;
|
||||
import lombok.experimental.Delegate;
|
||||
|
||||
@Data
|
||||
@Builder(toBuilder = true)
|
||||
@With
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class LombokModel {
|
||||
private String name;
|
||||
private int age;
|
||||
|
||||
/** Lombok @Delegate forwards every method of Greeter to delegate.* (covers @Delegate generation). */
|
||||
public interface Greeter {
|
||||
String greet();
|
||||
String farewell();
|
||||
}
|
||||
|
||||
@Delegate
|
||||
private final Greeter delegate = new DefaultGreeter();
|
||||
}
|
||||
@@ -96,3 +96,55 @@ class TestJavaLanguageServer:
|
||||
f"Found malformed symbols: {[format_symbol_for_assert(sym) for sym in malformed_symbols]}",
|
||||
pytrace=False,
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.JAVA], indirect=True)
|
||||
def test_lombok_generated_methods_visible_by_default(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Generated Lombok methods must appear in document symbols across the common annotations.
|
||||
|
||||
Default `lombok_show_generated=True` sends `java.symbols.includeGeneratedCode=true` to JDTLS,
|
||||
which disables the SourceMethod-isGenerated filter in DocumentSymbolHandler. Without it,
|
||||
find_symbol/get_symbols_overview cannot reach Lombok-synthesised methods at all (#1432).
|
||||
Covers @Data, @Builder(toBuilder=true), @With, @AllArgsConstructor, @NoArgsConstructor,
|
||||
@Delegate and @Accessors(fluent=true) — every method-generating annotation listed in the
|
||||
issue plus fluent prefix-stripped accessors and @Delegate forwarders.
|
||||
"""
|
||||
|
||||
def _names_by_kind(doc, kind: int) -> set[str]:
|
||||
return {sym.get("name") for sym in doc.get_all_symbols_and_roots()[0] if sym.get("kind") == kind}
|
||||
|
||||
SYMBOL_KIND_CLASS = 5
|
||||
SYMBOL_KIND_METHOD = 6
|
||||
SYMBOL_KIND_CONSTRUCTOR = 9
|
||||
|
||||
# ---- LombokModel: @Data + @Builder(toBuilder=true) + @With + ctors + @Delegate -------
|
||||
lombok_path = os.path.join("src", "main", "java", "test_repo", "LombokModel.java")
|
||||
lombok_doc = language_server.request_document_symbols(lombok_path)
|
||||
|
||||
lombok_methods = _names_by_kind(lombok_doc, SYMBOL_KIND_METHOD)
|
||||
# @Data getters/setters (prefixed) + canonical Object overrides
|
||||
for expected in ("getName", "getAge", "setName", "setAge", "equals", "hashCode", "toString"):
|
||||
assert expected in lombok_methods, f"@Data did not surface {expected!r}; got: {sorted(lombok_methods)}"
|
||||
# @Builder(toBuilder=true): static factory + instance toBuilder + inner build()
|
||||
for expected in ("builder", "toBuilder", "build"):
|
||||
assert expected in lombok_methods, f"@Builder did not surface {expected!r}; got: {sorted(lombok_methods)}"
|
||||
# @With: copy-with methods
|
||||
for expected in ("withName", "withAge"):
|
||||
assert expected in lombok_methods, f"@With did not surface {expected!r}; got: {sorted(lombok_methods)}"
|
||||
# @Delegate: forwarder methods for every method of the delegate target
|
||||
for expected in ("greet", "farewell"):
|
||||
assert expected in lombok_methods, f"@Delegate did not surface forwarder {expected!r}; got: {sorted(lombok_methods)}"
|
||||
|
||||
# @Builder generates an inner builder class
|
||||
lombok_classes = _names_by_kind(lombok_doc, SYMBOL_KIND_CLASS)
|
||||
assert "LombokModelBuilder" in lombok_classes, f"@Builder inner class missing; got: {sorted(lombok_classes)}"
|
||||
|
||||
# @AllArgsConstructor + @NoArgsConstructor surface as ctor symbols (kind=9)
|
||||
lombok_ctors = _names_by_kind(lombok_doc, SYMBOL_KIND_CONSTRUCTOR)
|
||||
assert "LombokModel" in lombok_ctors, f"Lombok ctors missing; got ctors {sorted(lombok_ctors)}"
|
||||
|
||||
# ---- FluentLombokModel: @Accessors(fluent=true) - prefix-stripped accessors ---------
|
||||
fluent_path = os.path.join("src", "main", "java", "test_repo", "FluentLombokModel.java")
|
||||
fluent_doc = language_server.request_document_symbols(fluent_path)
|
||||
fluent_methods = _names_by_kind(fluent_doc, SYMBOL_KIND_METHOD)
|
||||
for expected in ("host", "tag"):
|
||||
assert expected in fluent_methods, f"@Accessors(fluent=true) did not surface {expected!r}; got: {sorted(fluent_methods)}"
|
||||
Reference in new issue
Block a user