blob: c47d315a3da978e67e27531778907beb6e41ea3d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation and others.
*
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.core.tests.model;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.*;
import junit.framework.AssertionFailedError;
abstract public class CopyMoveTests extends ModifyingResourceTests {
public CopyMoveTests(String name) {
super(name);
}
/**
* Attempts to copy the element with optional
* forcing. The operation should fail with the failure code.
*/
public void copyNegative(IJavaElement element, IJavaElement destination, IJavaElement sibling, String rename, boolean force, int failureCode) {
try {
((ISourceManipulation)element).copy(destination, sibling, rename, force, null);
} catch (JavaModelException jme) {
assertTrue("Code not correct for JavaModelException: " + jme, jme.getStatus().getCode() == failureCode);
return;
}
assertTrue("The copy should have failed for: " + element, false);
return;
}
/**
* Attempts to copy the elements with optional
* forcing. The operation should fail with the failure code.
*/
public void copyNegative(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] renames, boolean force, int failureCode) {
try {
getJavaModel().copy(elements, destinations, siblings, renames, force, null);
} catch (JavaModelException jme) {
assertTrue("Code not correct for JavaModelException: " + jme, jme.getStatus().getCode() == failureCode);
return;
}
assertTrue("The move should have failed for for multiple elements: ", false);
return;
}
/**
* Copies the element to the container with optional rename
* and forcing. The operation should succeed, so any exceptions
* encountered are thrown.
*/
public IJavaElement copyPositive(IJavaElement element, IJavaElement container, IJavaElement sibling, String rename, boolean force) throws JavaModelException {
// if forcing, ensure that a name collision exists
if (force) {
IJavaElement collision = generateHandle(element, rename, container);
assertTrue("Collision does not exist", collision.exists());
}
DeltaListener listener = new DeltaListener();
IJavaElement copy;
try {
startDeltas(listener);
// copy
((ISourceManipulation) element).copy(container, sibling, rename, force, null);
// ensure the original element still exists
assertTrue("The original element must still exist", element.exists());
waitForAutoBuild();
// generate the new element handle
copy = generateHandle(element, rename, container);
assertTrue("Copy should exist", copy.exists());
//ensure correct position
if (element.getElementType() > IJavaElement.COMPILATION_UNIT) {
ensureCorrectPositioning((IParent) container, sibling, copy);
if (copy.getElementType() != IJavaElement.IMPORT_DECLARATION) {
ensureChildExists((IParent) container, copy);
}
} else {
if (container.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT) {
} else {
// ensure package name is correct
if (container.getElementName().equals("")) {
// default package - should be no package decl
IJavaElement[] children = ((ICompilationUnit) copy).getChildren();
boolean found = false;
for (int i = 0; i < children.length; i++) {
if (children[i] instanceof IPackageDeclaration) {
found = true;
break;
}
}
assertTrue("Should not find package decl", !found);
} else {
IJavaElement[] children = ((ICompilationUnit) copy).getChildren();
boolean found = false;
for (int i = 0; i < children.length; i++) {
if (children[i] instanceof IPackageDeclaration) {
assertTrue("package declaration incorrect", ((IPackageDeclaration) children[i]).getElementName().equals(container.getElementName()));
found = true;
}
}
assertTrue("Did not find package decl", found);
}
}
}
if (copy.getElementType() == IJavaElement.IMPORT_DECLARATION)
container = ((ICompilationUnit) container).getImportContainer();
IJavaElementDelta destDelta = listener.getDeltaFor(container, true);
if(destDelta == null) {
fail("No delta found for " + container + ", all deltas: " + listener.getAllDeltas());
}
assertTrue("Destination container not changed", destDelta.getKind() == IJavaElementDelta.CHANGED);
IJavaElementDelta[] deltas = destDelta.getAddedChildren();
assertTrue("Added children not correct for element copy", deltas[0].getElement().equals(copy));
} catch (AssertionFailedError afe) {
System.err.println(listener.stackTraces());
throw afe;
} finally {
stopDeltas(listener);
}
return copy;
}
/**
* Generates a new handle to the original element in
* its new container.
*/
public IJavaElement generateHandle(IJavaElement original, String rename, IJavaElement container) {
String name = original.getElementName();
if (rename != null) {
name = rename;
}
switch (container.getElementType()) {
case IJavaElement.PACKAGE_FRAGMENT_ROOT :
switch (original.getElementType()) {
case IJavaElement.PACKAGE_FRAGMENT :
return ((IPackageFragmentRoot) container).getPackageFragment(name);
default :
assertTrue("illegal child type", false);
break;
}
break;
case IJavaElement.PACKAGE_FRAGMENT :
switch (original.getElementType()) {
case IJavaElement.COMPILATION_UNIT :
return ((IPackageFragment) container).getCompilationUnit(name);
default :
assertTrue("illegal child type", false);
break;
}
break;
case IJavaElement.COMPILATION_UNIT :
switch (original.getElementType()) {
case IJavaElement.IMPORT_DECLARATION :
return ((ICompilationUnit) container).getImport(name);
case IJavaElement.PACKAGE_DECLARATION :
return ((ICompilationUnit) container).getPackageDeclaration(name);
case IJavaElement.TYPE :
if (isMainType(original, container)) {
//the cu has been renamed as well
container = ((IPackageFragment) container.getParent()).getCompilationUnit(name + ".java");
}
return ((ICompilationUnit) container).getType(name);
default :
assertTrue("illegal child type", false);
break;
}
break;
case IJavaElement.TYPE :
switch (original.getElementType()) {
case IJavaElement.METHOD :
if (name.equals(original.getParent().getElementName())) {
//method is a constructor
return ((IType) container).getMethod(container.getElementName(), ((IMethod) original).getParameterTypes());
}
return ((IType) container).getMethod(name, ((IMethod) original).getParameterTypes());
case IJavaElement.FIELD :
return ((IType) container).getField(name);
case IJavaElement.TYPE :
return ((IType) container).getType(name);
case IJavaElement.INITIALIZER :
//hack to return the first initializer
return ((IType) container).getInitializer(1);
default :
assertTrue("illegal child type", false);
break;
}
break;
default :
assertTrue("unsupported container type", false);
break;
}
assertTrue("should not get here", false);
return null;
}
/**
* Returns true if this element is the main type of its compilation unit.
*/
protected boolean isMainType(IJavaElement element, IJavaElement parent) {
if (parent instanceof ICompilationUnit) {
if (element instanceof IType) {
ICompilationUnit cu= (ICompilationUnit)parent;
String typeName = cu.getElementName();
typeName = typeName.substring(0, typeName.length() - 5);
return element.getElementName().equals(typeName) && element.getParent().equals(cu);
}
}
return false;
}
/**
* Attempts to move the element with optional
* forcing. The operation should fail with the failure code.
*/
public void moveNegative(IJavaElement element, IJavaElement destination, IJavaElement sibling, String rename, boolean force, int failureCode) {
try {
((ISourceManipulation)element).move(destination, sibling, rename, force, null);
} catch (JavaModelException jme) {
assertTrue("Code not correct for JavaModelException: " + jme, jme.getStatus().getCode() == failureCode);
return;
}
assertTrue("The move should have failed for: " + element, false);
return;
}
/**
* Attempts to move the element with optional
* forcing. The operation should fail with the failure code.
*/
public void moveNegative(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] renames, boolean force, int failureCode) {
try {
getJavaModel().move(elements, destinations, siblings, renames, force, null);
} catch (JavaModelException jme) {
assertTrue("Code not correct for JavaModelException: " + jme, jme.getStatus().getCode() == failureCode);
return;
}
assertTrue("The move should have failed for for multiple elements: ", false);
return;
}
/**
* Moves the element to the container with optional rename
* and forcing. The operation should succeed, so any exceptions
* encountered are thrown.
*/
public void movePositive(IJavaElement element, IJavaElement container, IJavaElement sibling, String rename, boolean force) throws JavaModelException {
IJavaElement[] siblings = new IJavaElement[] {sibling};
String[] renamings = new String[] {rename};
if (sibling == null) {
siblings = null;
}
if (rename == null) {
renamings = null;
}
movePositive(new IJavaElement[] {element}, new IJavaElement[] {container}, siblings, renamings, force);
}
/**
* Moves the elements to the containers with optional renaming
* and forcing. The operation should succeed, so any exceptions
* encountered are thrown.
*/
public void movePositive(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] names, boolean force) throws JavaModelException {
movePositive(elements, destinations, siblings, names, force, null);
}
public void movePositive(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] names, boolean force, IProgressMonitor monitor) throws JavaModelException {
movePositive(elements, destinations, siblings, names, force, true, null);
}
/**
* Moves the elements to the containers with optional renaming
* and forcing. The operation should succeed, so any exceptions
* encountered are thrown.
*/
public void movePositive(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] names, boolean force, boolean checkDelta, IProgressMonitor monitor) throws JavaModelException {
// if forcing, ensure that a name collision exists
int i;
if (force) {
for (i = 0; i < elements.length; i++) {
IJavaElement e = elements[i];
IJavaElement collision = null;
if (names == null) {
collision = generateHandle(e, null, destinations[i]);
} else {
collision = generateHandle(e, names[i], destinations[i]);
}
assertTrue("Collision does not exist", collision.exists());
}
}
DeltaListener listener = new DeltaListener();
try {
if(checkDelta) startDeltas(listener);
// move
getJavaModel().move(elements, destinations, siblings, names, force, monitor);
for (i = 0; i < elements.length; i++) {
IJavaElement element = elements[i];
IJavaElement moved = null;
if (names == null) {
moved = generateHandle(element, null, destinations[i]);
} else {
moved = generateHandle(element, names[i], destinations[i]);
}
// ensure the original element no longer exists, unless moving within the same container
if (!destinations[i].equals(element.getParent())) {
if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
//moving a package fragment does not necessary mean that it no longer exists
//it could have members that are not part of the Java Model
try {
IResource[] members = ((IContainer) element.getUnderlyingResource()).members();
if (members.length == 0) {
assertTrue("The original element must not exist", !element.exists());
}
} catch (CoreException ce) {
throw new JavaModelException(ce);
}
} else {
assertTrue("The original element must not exist", !element.exists());
}
}
assertTrue("Moved element should exist", moved.exists());
//ensure correct position
if (element.getElementType() > IJavaElement.COMPILATION_UNIT) {
if (siblings != null && siblings.length > 0) {
ensureCorrectPositioning((IParent) moved.getParent(), siblings[i], moved);
}
} else {
IJavaElement container = destinations[i];
if (container.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT) {
} else { // ensure package name is correct
if (container.getElementName().equals("")) {
// default package - should be no package decl
IJavaElement[] children = ((ICompilationUnit) moved).getChildren();
boolean found = false;
for (int j = 0; j < children.length; j++) {
if (children[j] instanceof IPackageDeclaration) {
found = true;
break;
}
}
assertTrue("Should not find package decl", !found);
} else {
IJavaElement[] children = ((ICompilationUnit) moved).getChildren();
boolean found = false;
for (int j = 0; j < children.length; j++) {
if (children[j] instanceof IPackageDeclaration) {
assertTrue("package declaration incorrect", ((IPackageDeclaration) children[j]).getElementName().equals(container.getElementName()));
found = true;
break;
}
}
assertTrue("Did not find package decl", found);
}
}
}
if(checkDelta) {
IJavaElementDelta destDelta = null;
if (isMainType(element, destinations[i]) && names != null && names[i] != null) { //moved/renamed main type to same cu
destDelta = listener.getDeltaFor(moved.getParent());
if(destDelta == null) {
fail("No delta found for " + moved.getParent() + ", all deltas: " + listener.getAllDeltas());
}
assertTrue("Renamed compilation unit as result of main type not added", destDelta.getKind() == IJavaElementDelta.ADDED);
assertTrue("flag should be F_MOVED_FROM", (destDelta.getFlags() & IJavaElementDelta.F_MOVED_FROM) > 0);
assertTrue("moved from handle should be original", destDelta.getMovedFromElement().equals(element.getParent()));
} else {
destDelta = listener.getDeltaFor(destinations[i], true);
assertTrue("Destination container not changed", destDelta != null && destDelta.getKind() == IJavaElementDelta.CHANGED);
IJavaElementDelta[] deltas = destDelta.getAddedChildren();
assertTrue("Added children not correct for element copy", deltas[i].getElement().equals(moved));
assertTrue("should be K_ADDED", deltas[i].getKind() == IJavaElementDelta.ADDED);
IJavaElementDelta sourceDelta= listener.getDeltaFor(element, false);
assertTrue("should be K_REMOVED", sourceDelta.getKind() == IJavaElementDelta.REMOVED);
}
}
}
} catch (AssertionFailedError afe) {
System.err.println(listener.stackTraces());
throw afe;
} finally {
if(checkDelta) stopDeltas(listener);
}
}
}