Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#1207] cache IResource in EnablementTester #1208

Merged
merged 9 commits into from
Feb 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion org.eclipse.lsp4e/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Language Server Protocol client for Eclipse IDE (Incubation)
Bundle-SymbolicName: org.eclipse.lsp4e;singleton:=true
Bundle-Version: 0.18.17.qualifier
Bundle-Version: 0.18.18.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-17
Require-Bundle: org.eclipse.core.runtime;bundle-version="3.12.0",
org.eclipse.equinox.common;bundle-version="3.8.0",
Expand Down
2 changes: 1 addition & 1 deletion org.eclipse.lsp4e/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</parent>
<artifactId>org.eclipse.lsp4e</artifactId>
<packaging>eclipse-plugin</packaging>
<version>0.18.17-SNAPSHOT</version>
<version>0.18.18-SNAPSHOT</version>

<build>
<plugins>
Expand Down
20 changes: 2 additions & 18 deletions org.eclipse.lsp4e/src/org/eclipse/lsp4e/LSPEclipseUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.lsp4e.internal.ArrayUtil;
import org.eclipse.lsp4e.internal.DocumentInputStream;
import org.eclipse.lsp4e.internal.ResourceForUriCache;
import org.eclipse.lsp4e.refactoring.CreateFileChange;
import org.eclipse.lsp4e.refactoring.DeleteExternalFile;
import org.eclipse.lsp4e.refactoring.LSPTextChange;
Expand Down Expand Up @@ -458,24 +459,7 @@ public static IResource findResourceFor(@Nullable String uri) {

@Nullable
public static IResource findResourceFor(@Nullable URI uri) {
if (uri == null) {
return null;
}
if (FILE_SCHEME.equals(uri.getScheme())) {
IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();

IFile[] files = wsRoot.findFilesForLocationURI(uri);
if (files.length > 0) {
IFile file = findMostNested(files);
if(file!=null) {
return file;
}
}

return ArrayUtil.findFirst(wsRoot.findContainersForLocationURI(uri));
} else {
return Adapters.adapt(uri, IResource.class, true);
}
return ResourceForUriCache.get(uri);
}

public static @Nullable IFile findMostNested(IFile[] files) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*******************************************************************************
* Copyright (c) 2025 Contributors to the Eclipse Foundation.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* See git history
*******************************************************************************/

package org.eclipse.lsp4e.internal;

import java.net.URI;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.lsp4e.LSPEclipseUtils;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

/**
* <p>NOTE: In case a resource has been moved or deleted the entry will not be removed automatically.
* It's up to the caller to check if the resource is accessible.
*
* <p>The cache is limited to 100 resource elements. It uses least-recently-used eviction if limit exceeds.
* The cache will try to evict entries that haven't been used recently.
* Therefore entries can be removed before the limit exceeds.
*/
public final class ResourceForUriCache {
private static final String FILE_SCHEME = "file"; //$NON-NLS-1$
private static final Cache<URI, IResource> cache = CacheBuilder.newBuilder().maximumSize(100).build();

private ResourceForUriCache() {
// this class shouldn't be instantiated
}

/**
* <p>Returns the cached IResource for the given URI. Tries to determine the IResource
* if it's not already in the cache. Returns NULL if the IResource could not be determined,
* e.g. the URI points to a file outside the workspace.
*
* <p>NOTE: In case a resource has been moved or deleted the entry will not be removed automatically.
* It's up to the caller to check if the resource is accessible.
* @param uri
* @return IResource or NULL
*/
@Nullable
public static IResource get(@Nullable URI uri) {
// Note: The load method in CacheLoader/LoadingCache cannot be applied here because
// the load method has to return a non-null value.
// But it cannot be guaranteed that there can be a IResource fetched for the given URI.
URI localURI = uri;
IResource resource = null;
if (localURI != null) {
resource = cache.getIfPresent(localURI);
if (resource != null) {
return resource;
}
resource = findResourceFor(localURI);
if (resource != null) {
cache.put(localURI, resource);
}
}
return resource;
}

@Nullable
private static IResource findResourceFor(URI uri) {
if (FILE_SCHEME.equals(uri.getScheme())) {
IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();

IFile[] files = wsRoot.findFilesForLocationURI(uri);
if (files.length > 0) {
IFile file = LSPEclipseUtils.findMostNested(files);
if(file!=null) {
return file;
}
}

return ArrayUtil.findFirst(wsRoot.findContainersForLocationURI(uri));
} else {
return Adapters.adapt(uri, IResource.class, true);
}
}

}


Loading