diff --git a/launch/jdt.ls.remote.server.launch b/launch/jdt.ls.remote.server.launch index 9586b46c02..f700048017 100644 --- a/launch/jdt.ls.remote.server.launch +++ b/launch/jdt.ls.remote.server.launch @@ -128,6 +128,7 @@ + diff --git a/launch/jdt.ls.socket-stream.launch b/launch/jdt.ls.socket-stream.launch index c1b56e00a0..f94788b9aa 100644 --- a/launch/jdt.ls.socket-stream.launch +++ b/launch/jdt.ls.socket-stream.launch @@ -130,6 +130,7 @@ + diff --git a/launch/jdt.ls.socket-stream.syntaxserver.launch b/launch/jdt.ls.socket-stream.syntaxserver.launch index 98b11414b8..8ab41dc8dd 100644 --- a/launch/jdt.ls.socket-stream.syntaxserver.launch +++ b/launch/jdt.ls.socket-stream.syntaxserver.launch @@ -110,6 +110,7 @@ + diff --git a/org.eclipse.jdt.ls.compiler.batch.fragment/.project b/org.eclipse.jdt.ls.compiler.batch.fragment/.project new file mode 100644 index 0000000000..95478f7020 --- /dev/null +++ b/org.eclipse.jdt.ls.compiler.batch.fragment/.project @@ -0,0 +1,28 @@ + + + org.eclipse.jdt.ls.compiler.batch.fragment + + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + org.eclipse.pde.PluginNature + + diff --git a/org.eclipse.jdt.ls.compiler.batch.fragment/META-INF/MANIFEST.MF b/org.eclipse.jdt.ls.compiler.batch.fragment/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..f1a3c3b001 --- /dev/null +++ b/org.eclipse.jdt.ls.compiler.batch.fragment/META-INF/MANIFEST.MF @@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %Bundle-Name +Bundle-SymbolicName: org.eclipse.jdt.ls.compiler.batch.fragment;singleton:=true +Bundle-Version: 1.61.0.qualifier +Fragment-Host: org.eclipse.jdt.core.compiler.batch +Automatic-Module-Name: org.eclipse.jdt.ls.compiler.batch.fragment +Bundle-RequiredExecutionEnvironment: JavaSE-21 +Import-Package: org.eclipse.core.resources, + org.eclipse.core.runtime +Bundle-Vendor: %Bundle-Vendor diff --git a/org.eclipse.jdt.ls.compiler.batch.fragment/about.html b/org.eclipse.jdt.ls.compiler.batch.fragment/about.html new file mode 100644 index 0000000000..b313486523 --- /dev/null +++ b/org.eclipse.jdt.ls.compiler.batch.fragment/about.html @@ -0,0 +1,38 @@ + + + + + + About + + + +

About This Content

+ +

November 30, 2017

+

License

+ +

+ The Eclipse Foundation makes available all content in this plug-in + ("Content"). Unless otherwise indicated below, the Content + is provided to you under the terms and conditions of the Eclipse + Public License Version 2.0 ("EPL"). A copy of the EPL is + available at https://www.eclipse.org/legal/epl-2.0. + For purposes of the EPL, "Program" will mean the Content. +

+ +

+ If you did not receive this Content directly from the Eclipse + Foundation, the Content is being redistributed by another party + ("Redistributor") and different terms and conditions may + apply to your use of any object code in the Content. Check the + Redistributor's license that was provided with the Content. If no such + license exists, contact the Redistributor. Unless otherwise indicated + below, the terms and conditions of the EPL still apply to any source + code in the Content and such source code may be obtained at https://www.eclipse.org. +

+ + + + \ No newline at end of file diff --git a/org.eclipse.jdt.ls.compiler.batch.fragment/build.properties b/org.eclipse.jdt.ls.compiler.batch.fragment/build.properties new file mode 100644 index 0000000000..fed5a8e264 --- /dev/null +++ b/org.eclipse.jdt.ls.compiler.batch.fragment/build.properties @@ -0,0 +1,4 @@ +bin.includes = META-INF/,\ + plugin.properties,\ + about.html +src.includes = about.html diff --git a/org.eclipse.jdt.ls.compiler.batch.fragment/plugin.properties b/org.eclipse.jdt.ls.compiler.batch.fragment/plugin.properties new file mode 100644 index 0000000000..6391472ff5 --- /dev/null +++ b/org.eclipse.jdt.ls.compiler.batch.fragment/plugin.properties @@ -0,0 +1,14 @@ +############################################################################### +# Copyright (c) 2026 Microsoft Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License 2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# +# Contributors: +# Microsoft Corporation - initial API and implementation +############################################################################### +Bundle-Vendor = Eclipse.org +Bundle-Name = JDT Language Server - Batch Compiler Fragment diff --git a/org.eclipse.jdt.ls.compiler.batch.fragment/pom.xml b/org.eclipse.jdt.ls.compiler.batch.fragment/pom.xml new file mode 100644 index 0000000000..2c5f80f3be --- /dev/null +++ b/org.eclipse.jdt.ls.compiler.batch.fragment/pom.xml @@ -0,0 +1,15 @@ + + + 4.0.0 + + org.eclipse.jdt.ls + parent + 1.61.0-SNAPSHOT + + org.eclipse.jdt.ls.compiler.batch.fragment + ${base.name} :: Java LS Batch Compiler Fragment + eclipse-plugin + + diff --git a/org.eclipse.jdt.ls.product/languageServer.product b/org.eclipse.jdt.ls.product/languageServer.product index 6367ac4657..d2ea600abd 100644 --- a/org.eclipse.jdt.ls.product/languageServer.product +++ b/org.eclipse.jdt.ls.product/languageServer.product @@ -52,6 +52,7 @@ + diff --git a/org.eclipse.jdt.ls.product/syntaxServer.product b/org.eclipse.jdt.ls.product/syntaxServer.product index 2a44226bf8..87722d67f3 100644 --- a/org.eclipse.jdt.ls.product/syntaxServer.product +++ b/org.eclipse.jdt.ls.product/syntaxServer.product @@ -45,6 +45,7 @@ + diff --git a/org.eclipse.jdt.ls.repository/category.xml b/org.eclipse.jdt.ls.repository/category.xml index 00e4fb9c67..1ed163450a 100644 --- a/org.eclipse.jdt.ls.repository/category.xml +++ b/org.eclipse.jdt.ls.repository/category.xml @@ -9,6 +9,9 @@ + + + diff --git a/org.eclipse.jdt.ls.tests/pom.xml b/org.eclipse.jdt.ls.tests/pom.xml index 642ad0ecb5..933c53a6a1 100644 --- a/org.eclipse.jdt.ls.tests/pom.xml +++ b/org.eclipse.jdt.ls.tests/pom.xml @@ -13,6 +13,27 @@ eclipse-test-plugin + + + org.eclipse.tycho + target-platform-configuration + ${tycho-version} + + + + + + eclipse-plugin + org.eclipse.jdt.ls.compiler.batch.fragment + 0.0.0 + + + + + + diff --git a/org.eclipse.jdt.ls.tests/projects/maven/mavenlombokconfig/lombok.config b/org.eclipse.jdt.ls.tests/projects/maven/mavenlombokconfig/lombok.config new file mode 100644 index 0000000000..2209211bf9 --- /dev/null +++ b/org.eclipse.jdt.ls.tests/projects/maven/mavenlombokconfig/lombok.config @@ -0,0 +1,2 @@ +config.stopBubbling = true +lombok.accessors.chain = true diff --git a/org.eclipse.jdt.ls.tests/projects/maven/mavenlombokconfig/pom.xml b/org.eclipse.jdt.ls.tests/projects/maven/mavenlombokconfig/pom.xml new file mode 100644 index 0000000000..c1ec116bf1 --- /dev/null +++ b/org.eclipse.jdt.ls.tests/projects/maven/mavenlombokconfig/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + org.sample + mavenlombokconfig + jar + 1.0-SNAPSHOT + + + + org.projectlombok + lombok + 1.18.32 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 11 + 11 + + + + + diff --git a/org.eclipse.jdt.ls.tests/projects/maven/mavenlombokconfig/src/main/java/org/sample/Chained.java b/org.eclipse.jdt.ls.tests/projects/maven/mavenlombokconfig/src/main/java/org/sample/Chained.java new file mode 100644 index 0000000000..81be037d88 --- /dev/null +++ b/org.eclipse.jdt.ls.tests/projects/maven/mavenlombokconfig/src/main/java/org/sample/Chained.java @@ -0,0 +1,13 @@ +package org.sample; + +import lombok.Data; + +/** + * The setters generated for this class only return {@code Chained} instead of + * {@code void} when the {@code lombok.config} sitting in the project root is + * picked up by Lombok. + */ +@Data +public class Chained { + private String name; +} diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/LombokConfigurationTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/LombokConfigurationTest.java new file mode 100644 index 0000000000..2f1e27bf38 --- /dev/null +++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/LombokConfigurationTest.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2026 Microsoft Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Microsoft Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.ls.core.internal; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.stream.Stream; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.Signature; +import org.eclipse.jdt.ls.core.internal.managers.AbstractProjectsManagerBasedTest; +import org.junit.jupiter.api.Test; + +/** + * Lombok resolves the {@code lombok.config} that applies to a source file by turning the + * workspace relative file name reported by ECJ into an absolute file system location, which + * requires {@code org.eclipse.core.resources} and {@code org.eclipse.core.runtime} to be + * visible from the class loader of the bundle hosting ECJ + * ({@code org.eclipse.jdt.core.compiler.batch}). When they are not, Lombok silently falls back + * to a bogus location and no {@code lombok.config} is ever read. + * + * @see vscode-java#4461 + */ +public class LombokConfigurationTest extends AbstractProjectsManagerBasedTest { + + // this test needs the Lombok agent (-javaagent:) to be meaningful + @Test + public void testLombokConfigIsApplied() throws Exception { + if (Boolean.getBoolean("jdt.ls.lombok.disabled")) { + return; + } + importProjects("maven/mavenlombokconfig"); + IProject project = WorkspaceHelper.getProject("mavenlombokconfig"); + IFile file = project.getFile("src/main/java/org/sample/Chained.java"); + assertTrue(file.exists()); + ICompilationUnit cu = JavaCore.createCompilationUnitFrom(file); + IType type = cu.getType("Chained"); + IMethod setter = Stream.of(type.getMethods()).filter(m -> "setName".equals(m.getElementName())).findFirst().orElse(null); + if (setter == null) { + // the Lombok agent isn't installed in this JVM, nothing to check + return; + } + assertEquals("Chained", Signature.getSignatureSimpleName(setter.getReturnType()), + "'lombok.accessors.chain=true' from the project's lombok.config was not applied"); + } +} diff --git a/pom.xml b/pom.xml index 86d3b9add8..8331ff5102 100644 --- a/pom.xml +++ b/pom.xml @@ -37,6 +37,7 @@ org.eclipse.jdt.ls.target org.eclipse.jdt.ls.core org.eclipse.jdt.ls.filesystem + org.eclipse.jdt.ls.compiler.batch.fragment org.eclipse.jdt.ls.tests org.eclipse.jdt.ls.logback.appender org.eclipse.jdt.ls.tests.syntaxserver