From 8a646553f0ba771039992ff8420686593ec8b24c Mon Sep 17 00:00:00 2001 From: aboyko Date: Wed, 17 May 2023 22:47:23 -0400 Subject: [PATCH] Update classpath on output folders content changes --- .../classpath/ClasspathListenerManager.java | 44 ++++++++++++++++++- .../vscode/boot/jdt/ls/JdtLsProjectCache.java | 4 -- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathListenerManager.java b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathListenerManager.java index d40c95f01..4a6d7cb44 100644 --- a/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathListenerManager.java +++ b/headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathListenerManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2020 Pivotal, Inc. + * Copyright (c) 2019, 2023 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,22 +10,29 @@ *******************************************************************************/ package org.springframework.tooling.jdt.ls.commons.classpath; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; import java.util.Queue; +import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jdt.core.ElementChangedEvent; +import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IElementChangedListener; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaElementDelta; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; import org.springframework.tooling.jdt.ls.commons.Logger; /** @@ -79,7 +86,8 @@ public class ClasspathListenerManager { // Classpath unchanged but maven/gradle repo cache has JAR's removed or downloaded // See individual method comments for more details || isClasspathManifestFileChanged(jp, delta) - || areClasspathJarsChanged(delta)) { + || areClasspathJarsChanged(delta) + || areOutputFoldersContentChanged(jp, delta)) { listener.classpathChanged(jp); } break; @@ -106,6 +114,38 @@ public class ClasspathListenerManager { } return false; } + + private boolean areOutputFoldersContentChanged(IJavaProject jp, IJavaElementDelta delta) { + Collection outputFolders = getOutputFolders(jp); + if (delta.getResourceDeltas() != null && (delta.getFlags() & (IJavaElementDelta.F_CONTENT | IJavaElementDelta.F_CHILDREN)) != 0) { + for (IResourceDelta resourceDelta : delta.getResourceDeltas()) { + if (outputFolders.contains(resourceDelta.getResource().getFullPath())) { + return true; + } else if (outputFolders.stream().anyMatch(of -> resourceDelta.getFullPath().isPrefixOf(of))) { + for (IResourceDelta rd : resourceDelta.getAffectedChildren()) { + if (outputFolders.contains(rd.getResource().getFullPath())) { + return true; + } + } + } + } + } + return false; + } + + private Collection getOutputFolders(IJavaProject jp) { + try { + Set outputFolders = new HashSet<>();; + for (IClasspathEntry cpe : jp.getRawClasspath()) { + if (cpe.getEntryKind() == IClasspathEntry.CPE_SOURCE && cpe.getOutputLocation() != null) { + outputFolders.add(cpe.getOutputLocation()); + } + } + return outputFolders; + } catch (JavaModelException e) { + return Collections.emptyList(); + } + } /** * When Maven project update is completed .classpath file content changed is one diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/jdt/ls/JdtLsProjectCache.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/jdt/ls/JdtLsProjectCache.java index a550dae7e..8f7501b6a 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/jdt/ls/JdtLsProjectCache.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/jdt/ls/JdtLsProjectCache.java @@ -360,10 +360,6 @@ public class JdtLsProjectCache implements InitializableJavaProjectsService, Serv URI projectUri = new URI(uri); ClasspathData classpath = new ClasspathData(event.name, event.classpath.getEntries()); IJavaProject oldProject = table.get(uri); - if (oldProject != null && classpath.equals(oldProject.getClasspath())) { - // nothing has changed - return; - } IProjectBuild projectBuild = from(event.projectBuild); IJavaProject newProject = IS_JANDEX_INDEX ? new JavaProject(getFileObserver(), projectUri, classpath,