Skip to content

Commit ec88978

Browse files
committed
Don't re-trigger Java validation for all opened Java files when a Java
file is saved. Signed-off-by: azerr <azerr@redhat.com>
1 parent 9aa027b commit ec88978

2 files changed

Lines changed: 64 additions & 7 deletions

File tree

microprofile.jdt/org.eclipse.lsp4mp.jdt.core/src/main/java/org/eclipse/lsp4mp/jdt/internal/core/MicroProfilePropertiesListenerManager.java

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,23 @@
2020
import java.util.logging.Logger;
2121

2222
import org.eclipse.core.resources.IFile;
23+
import org.eclipse.core.resources.IProject;
2324
import org.eclipse.core.resources.IResource;
2425
import org.eclipse.core.resources.IResourceChangeEvent;
2526
import org.eclipse.core.resources.IResourceChangeListener;
2627
import org.eclipse.core.resources.IResourceDelta;
2728
import org.eclipse.core.resources.IResourceDeltaVisitor;
2829
import org.eclipse.core.resources.ResourcesPlugin;
2930
import org.eclipse.core.runtime.CoreException;
31+
import org.eclipse.core.runtime.IPath;
3032
import org.eclipse.jdt.core.ElementChangedEvent;
3133
import org.eclipse.jdt.core.IElementChangedListener;
3234
import org.eclipse.jdt.core.IJavaElement;
3335
import org.eclipse.jdt.core.IJavaElementDelta;
3436
import org.eclipse.jdt.core.IJavaProject;
37+
import org.eclipse.jdt.core.IPackageFragmentRoot;
3538
import org.eclipse.jdt.core.JavaCore;
39+
import org.eclipse.jdt.core.JavaModelException;
3640
import org.eclipse.lsp4mp.commons.MicroProfilePropertiesChangeEvent;
3741
import org.eclipse.lsp4mp.commons.MicroProfilePropertiesScope;
3842
import org.eclipse.lsp4mp.jdt.core.IMicroProfilePropertiesChangedListener;
@@ -146,11 +150,17 @@ public boolean visit(IResourceDelta delta) throws CoreException {
146150
if (resource == null) {
147151
return false;
148152
}
153+
154+
// Step 5: Process folders, files, and projects as needed
149155
switch (resource.getType()) {
150156
case IResource.ROOT:
157+
return true;
151158
case IResource.PROJECT:
159+
IProject project = (IProject) resource;
160+
return project.isAccessible() && project.hasNature(JavaCore.NATURE_ID);
152161
case IResource.FOLDER:
153-
return resource.isAccessible();
162+
// Ignore folder which belongs to Java output file location (ex: target/classes)
163+
return resource.isAccessible() && !isInOutput(resource);
154164
case IResource.FILE:
155165
IFile file = (IFile) resource;
156166
if (isJavaFile(file) && isFileContentChanged(delta)) {
@@ -171,6 +181,43 @@ public boolean visit(IResourceDelta delta) throws CoreException {
171181
return false;
172182
}
173183

184+
/**
185+
* Returns true if the given (folder) resource is in the Java output location
186+
* (ex : /target/classes) and false otherwise (ex: src/main/java).
187+
*
188+
* @param resource the folder resource.
189+
* @return true if the given (folder) resource is in the Java output location
190+
* (ex : /target/classes) and false otherwise (ex: src/main/java).
191+
* @throws JavaModelException
192+
*/
193+
private static boolean isInOutput(IResource resource) throws JavaModelException {
194+
195+
IJavaProject javaProject = JavaCore.create(resource.getProject());
196+
IPath resourcePath = resource.getFullPath();
197+
198+
// Exclude resources in the main output location (e.g.,/ProjectName/bin)
199+
IPath outputLocation = javaProject.getOutputLocation();
200+
IPath outputFullPath = ResourcesPlugin.getWorkspace().getRoot().getFolder(outputLocation).getFullPath();
201+
if (outputFullPath.isPrefixOf(resourcePath)) {
202+
return true;
203+
}
204+
205+
// Exclude resources in custom output locations (if any)
206+
for (IPackageFragmentRoot root : javaProject.getPackageFragmentRoots()) {
207+
if (root.getKind() == IPackageFragmentRoot.K_SOURCE) {
208+
IPath customOutput = root.getRawClasspathEntry().getOutputLocation();
209+
if (customOutput != null) {
210+
IPath customFullPath = ResourcesPlugin.getWorkspace().getRoot().getFolder(customOutput)
211+
.getFullPath();
212+
if (customFullPath.isPrefixOf(resourcePath)) {
213+
return true;
214+
}
215+
}
216+
}
217+
}
218+
return false;
219+
}
220+
174221
private void fireAsyncEvent(MicroProfilePropertiesChangeEvent event) {
175222
// IMPORTANT: The LSP notification 'microprofile/propertiesChanged' must be
176223
// executed

microprofile.ls/org.eclipse.lsp4mp.ls/src/main/java/org/eclipse/lsp4mp/ls/java/JavaFileTextDocumentService.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@
6464
import org.eclipse.lsp4mp.ls.commons.TextDocument;
6565
import org.eclipse.lsp4mp.ls.commons.ValidatorDelayer;
6666
import org.eclipse.lsp4mp.ls.commons.client.CommandKind;
67-
import org.eclipse.lsp4mp.ls.commons.client.ExtendedCompletionCapabilities;
6867
import org.eclipse.lsp4mp.ls.java.JavaTextDocuments.JavaTextDocument;
6968
import org.eclipse.lsp4mp.ls.properties.IPropertiesModelProvider;
7069
import org.eclipse.lsp4mp.model.Node;
@@ -93,7 +92,8 @@ public class JavaFileTextDocumentService extends AbstractTextDocumentService {
9392
private ValidatorDelayer<JavaTextDocument> validatorDelayer;
9493

9594
public JavaFileTextDocumentService(MicroProfileLanguageServer microprofileLanguageServer,
96-
IPropertiesModelProvider propertiesModelProvider, SharedSettings sharedSettings, JavaTextDocuments javaTextDocuments) {
95+
IPropertiesModelProvider propertiesModelProvider, SharedSettings sharedSettings,
96+
JavaTextDocuments javaTextDocuments) {
9797
super(microprofileLanguageServer, sharedSettings);
9898
this.propertiesModelProvider = propertiesModelProvider;
9999
this.documents = javaTextDocuments;
@@ -125,8 +125,17 @@ public void didClose(DidCloseTextDocumentParams params) {
125125

126126
@Override
127127
public void didSave(DidSaveTextDocumentParams params) {
128+
// Do nothing..
129+
130+
// Since the beginning of the MP LS project,
131+
// saving a Java file triggers validation for all open Java files,
132+
// which can negatively impact performance.
133+
// As there's no comment explaining the reason for this behavior,
134+
// we are disabling this feature.
135+
128136
// validate all opened java files which belong to a MicroProfile project
129-
triggerValidationForAll(null);
137+
// triggerValidationForAll(null);
138+
130139
}
131140

132141
// ------------------------------ Completion ------------------------------
@@ -167,8 +176,9 @@ public CompletableFuture<Either<List<CompletionItem>, CompletionList>> completio
167176
JavaCursorContextResult cursorContext = completionResult.getCursorContext();
168177

169178
// calculate the snippet completion items based on the context
170-
List<CompletionItem> snippetCompletionItems = documents.getSnippetRegistry().getCompletionItems(document, finalizedCompletionOffset,
171-
canSupportMarkdown, snippetsSupported, (context, model) -> {
179+
List<CompletionItem> snippetCompletionItems = documents.getSnippetRegistry().getCompletionItems(
180+
document, finalizedCompletionOffset, canSupportMarkdown, snippetsSupported,
181+
(context, model) -> {
172182
if (context != null && context instanceof SnippetContextForJava) {
173183
return ((SnippetContextForJava) context)
174184
.isMatch(new JavaSnippetCompletionContext(projectInfo, cursorContext));
@@ -339,7 +349,7 @@ private void validate(JavaTextDocument javaTextDocument, boolean delay) {
339349
/**
340350
* Validate the given opened Java file.
341351
*
342-
* @param document the opened Java file.
352+
* @param document the opened Java file.
343353
*/
344354
private void triggerValidationFor(JavaTextDocument document) {
345355
document.executeIfInMicroProfileProject((projectinfo, cancelChecker) -> {

0 commit comments

Comments
 (0)