Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Automatic-Module-Name: org.eclipse.ltk.core.refactoring
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.ltk.core.refactoring; singleton:=true
Bundle-Version: 3.15.200.qualifier
Bundle-Version: 3.15.300.qualifier
Bundle-Activator: org.eclipse.ltk.internal.core.refactoring.RefactoringCorePlugin
Bundle-ActivationPolicy: lazy
Bundle-Vendor: %providerName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,22 @@
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubMonitor;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory;

import org.eclipse.core.filebuffers.FileBuffers;
Expand Down Expand Up @@ -120,12 +124,30 @@ public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws Core

@Override
public RefactoringStatus checkFinalConditions(IProgressMonitor pm, CheckConditionsContext context) throws CoreException, OperationCanceledException {
pm.beginTask("", 1); //$NON-NLS-1$
SubMonitor subMonitor= SubMonitor.convert(pm, fResources.length);
try {
RefactoringStatus result= new RefactoringStatus();

boolean lightweightAutoRefresh= Platform.getPreferencesService().getBoolean(ResourcesPlugin.PI_RESOURCES,
ResourcesPlugin.PREF_LIGHTWEIGHT_AUTO_REFRESH, false, null);

List<IResource> remainingResources= new ArrayList<>(fResources.length);
for (IResource resource : fResources) {
if (!isSynchronizedExcludingLinkedResources(resource)) {
boolean inSync= isSynchronizedExcludingLinkedResources(resource);
if (!inSync && lightweightAutoRefresh && resource.isAccessible()) {
try {
resource.refreshLocal(IResource.DEPTH_INFINITE, subMonitor.split(1));
} catch (CoreException e) {
// refresh failed; the out-of-sync warning below covers it
}
if (!resource.exists()) {
// deleted externally; the refresh already removed it from the workspace
continue;
}
inSync= isSynchronizedExcludingLinkedResources(resource);
}
remainingResources.add(resource);
if (!inSync) {
String pathLabel= BasicElementLabels.getPathLabel(resource.getFullPath(), false);

String locationLabel= null;
Expand Down Expand Up @@ -156,6 +178,9 @@ public RefactoringStatus checkFinalConditions(IProgressMonitor pm, CheckConditio
result.addWarning(warning);
}
}
if (remainingResources.size() != fResources.length) {
fResources= remainingResources.toArray(IResource[]::new);
}

checkDirtyResources(result);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -29,6 +31,8 @@

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.preferences.InstanceScope;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
Expand Down Expand Up @@ -66,6 +70,7 @@ public void setUp() throws Exception {

@AfterEach
public void tearDown() throws Exception {
InstanceScope.INSTANCE.getNode(ResourcesPlugin.PI_RESOURCES).remove(ResourcesPlugin.PREF_LIGHTWEIGHT_AUTO_REFRESH);
fProject.delete();
}

Expand Down Expand Up @@ -392,6 +397,65 @@ public void testDeleteRefactoring3_bug343584() throws Exception {
}
}

@Test
public void testDeleteRefactoringOutOfSync_noAutoRefresh() throws Exception {
setLightweightAutoRefresh(false);
IFolder testFolder= fProject.createFolder("test");
IFile file= fProject.createFile(testFolder, "myFile.txt", "hello");
modifyExternally(file);

RefactoringContext context= createDeleteRefactoringContext(file);
try {
RefactoringStatus status= context.getRefactoring().checkAllConditions(new NullProgressMonitor());
assertTrue(status.hasWarning(), "expected an out-of-sync warning");
} finally {
context.dispose();
}
}

@Test
public void testDeleteRefactoringOutOfSync_autoRefresh() throws Exception {
setLightweightAutoRefresh(true);
IFolder testFolder= fProject.createFolder("test");
IFile file= fProject.createFile(testFolder, "myFile.txt", "hello");
File localFile= modifyExternally(file);

RefactoringContext context= createDeleteRefactoringContext(file);
try {
Refactoring refactoring= context.getRefactoring();
RefactoringStatus status= refactoring.checkAllConditions(new NullProgressMonitor());
assertTrue(status.isOK(), () -> "expected no warning but was: " + status);

perform(refactoring.createChange(new NullProgressMonitor()));

assertFalse(file.exists());
assertFalse(localFile.exists());
} finally {
context.dispose();
}
}

@Test
public void testDeleteRefactoringDeletedExternally_autoRefresh() throws Exception {
setLightweightAutoRefresh(true);
IFolder testFolder= fProject.createFolder("test");
IFile file= fProject.createFile(testFolder, "myFile.txt", "hello");
Files.delete(file.getLocation().toFile().toPath());

RefactoringContext context= createDeleteRefactoringContext(file);
try {
Refactoring refactoring= context.getRefactoring();
RefactoringStatus status= refactoring.checkAllConditions(new NullProgressMonitor());
assertTrue(status.isOK(), () -> "expected no warning but was: " + status);

perform(refactoring.createChange(new NullProgressMonitor()));

assertFalse(file.exists());
} finally {
context.dispose();
}
}

@Test
public void testCopyProjectRefactoring() throws Exception {
String content1= "hello";
Expand Down Expand Up @@ -419,6 +483,32 @@ public void testCopyProjectRefactoring() throws Exception {
assertFalse(targetProject.exists());
}

private void setLightweightAutoRefresh(boolean enabled) {
InstanceScope.INSTANCE.getNode(ResourcesPlugin.PI_RESOURCES).putBoolean(ResourcesPlugin.PREF_LIGHTWEIGHT_AUTO_REFRESH, enabled);
}

/**
* Modifies the file in the local file system without notifying the workspace, so the file is
* out of sync afterwards.
*/
private File modifyExternally(IFile file) throws IOException {
File localFile= file.getLocation().toFile();
Files.writeString(localFile.toPath(), "external change");
assertTrue(localFile.setLastModified(localFile.lastModified() + 5000));
assertFalse(file.isSynchronized(IResource.DEPTH_ZERO));
return localFile;
}

private RefactoringContext createDeleteRefactoringContext(IResource... resources) throws CoreException {
RefactoringContribution contribution= RefactoringCore.getRefactoringContribution(DeleteResourcesDescriptor.ID);
DeleteResourcesDescriptor descriptor= (DeleteResourcesDescriptor) contribution.createDescriptor();
descriptor.setResources(resources);
RefactoringStatus status= new RefactoringStatus();
RefactoringContext context= descriptor.createRefactoringContext(status);
assertTrue(status.isOK());
return context;
}

private Change perform(Change change) throws CoreException {
PerformChangeOperation op= new PerformChangeOperation(change);
op.run(null);
Expand Down
Loading