1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Implementation of the CreateXXXOperation classes

This commit is contained in:
Alain Magloire 2005-01-24 05:42:39 +00:00
parent 0988982be3
commit abd661fca1
10 changed files with 553 additions and 44 deletions

View file

@ -0,0 +1,70 @@
/**********************************************************************
* Copyright (c) 2002,2003,2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* QNX Software Systems
***********************************************************************/
package org.eclipse.cdt.core.model;
/**
* A C model region describes a hierarchical set of elements.
* Regions are often used to describe a set of elements to be considered
* when performing operations; for example, the set of elements to be
* considered during a search. A region may include elements from different
* projects.
* <p>
* When an element is included in a region, all of its children
* are considered to be included. Children of an included element
* <b>cannot</b> be selectively excluded.
* </p>
* <p>
* This interface is not intended to be implemented by clients.
* Instances can be created via the <code>CoreModel.newRegion</code>.
* </p>
*
* @see CoreModel#newRegion()
*/
public interface IRegion {
/**
* Adds the given element and all of its descendents to this region.
* If the specified element is already included, or one of its
* ancestors is already included, this has no effect. If the element
* being added is an ancestor of an element already contained in this
* region, the ancestor subsumes the descendent.
*
* @param element the given element
*/
void add(ICElement element);
/**
* Returns whether the given element is contained in this region.
*
* @param element the given element
* @return true if the given element is contained in this region, false otherwise
*/
boolean contains(ICElement element);
/**
* Returns the top level elements in this region.
* All descendents of these elements are also included in this region.
*
* @return the top level elements in this region
*/
ICElement[] getElements();
/**
* Removes the specified element from the region and returns
* <code>true</code> if successful, <code>false</code> if the remove
* fails. If an ancestor of the given element is included, the
* remove fails (in other words, it is not possible to selectively
* exclude descendants of included ancestors).
*
* @param element the given element
* @return <code>true</code> if successful, <code>false</code> if the remove fails
*/
boolean remove(ICElement element);
}

View file

@ -109,8 +109,7 @@ public class CModel extends Openable implements ICModel {
if (elements != null && elements[0] != null && elements[0].getElementType() <= ICElement.C_UNIT ) {
runOperation(new CopyResourceElementsOperation(elements, containers, replace), elements, siblings, renamings, monitor);
} else {
throw new CModelException (new CModelStatus());
//runOperation(new CopyElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
runOperation(new CopyElementsOperation(elements, containers, replace), elements, siblings, renamings, monitor);
}
}
@ -119,8 +118,7 @@ public class CModel extends Openable implements ICModel {
if (elements != null && elements[0] != null && elements[0].getElementType() <= ICElement.C_UNIT) {
runOperation(new DeleteResourceElementsOperation(elements, force), monitor);
} else {
throw new CModelException (new CModelStatus());
//runOperation(new DeleteElementsOperation(elements, force), monitor);
runOperation(new DeleteElementsOperation(elements, force), monitor);
}
}
@ -129,8 +127,7 @@ public class CModel extends Openable implements ICModel {
if (elements != null && elements[0] != null && elements[0].getElementType() <= ICElement.C_UNIT) {
runOperation(new MoveResourceElementsOperation(elements, containers, replace), elements, siblings, renamings, monitor);
} else {
throw new CModelException (new CModelStatus());
//runOperation(new MoveElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
runOperation(new MoveElementsOperation(elements, containers, replace), elements, siblings, renamings, monitor);
}
}
@ -140,8 +137,7 @@ public class CModel extends Openable implements ICModel {
runOperation(new RenameResourceElementsOperation(elements, destinations,
renamings, force), monitor);
} else {
throw new CModelException (new CModelStatus());
//runOperation(new RenameElementsOperation(elements, containers, renamings, force), monitor);
runOperation(new RenameElementsOperation(elements, destinations, renamings, force), monitor);
}
}

View file

@ -15,6 +15,8 @@ import org.eclipse.cdt.core.model.ICModel;
import org.eclipse.cdt.core.model.ICModelStatus;
import org.eclipse.cdt.core.model.ICModelStatusConstants;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
@ -222,6 +224,21 @@ public abstract class CModelOperation implements IWorkspaceRunnable, IProgressMo
return CModelStatus.VERIFIED_OK;
}
/**
* Returns the translation unit the given element is contained in,
* or the element itself (if it is a compilation unit),
* otherwise <code>null</code>.
*/
protected ITranslationUnit getTranslationUnitFor(ICElement element) {
if (element instanceof ITranslationUnit) {
return (ITranslationUnit)element;
} else if (element instanceof ISourceReference) {
ISourceReference ref = (ISourceReference)element;
return ref.getTranslationUnit();
}
return null;
}
/**
* Convenience method to copy resources
*/

View file

@ -47,8 +47,6 @@ import org.eclipse.cdt.core.model.ITranslationUnit;
*/
public class CopyElementsOperation extends MultiOperation {
//private Map fSources = new HashMap();
/**
* When executed, this operation will copy the given elements to the
* given containers. The elements and destination containers must be in
@ -84,32 +82,6 @@ public class CopyElementsOperation extends MultiOperation {
String name = element.getElementName();
int type = element.getElementType();
return new CreateSourceReferenceOperation(unit, name, type, getSourceFor(element));
// switch (element.getElementType()) {
// case ICElement.C_INCLUDE: {
// IInclude include = (IInclude)element;
// return new CreateIncludeOperation(include.getIncludeName(), include.isStandard(), unit);
// }
// case ICElement.C_FUNCTION_DECLARATION : {
// IFunctionDeclaration declaration = (IFunctionDeclaration)element;
// return new CreateFunctionDeclarationOperation(declaration.getElementName(), unit);
// }
// case ICElement.C_FUNCTION : {
// IFunction function = (IFunction)element;
// return new CreateFunctionOperation(function, unit);
// }
// case ICElement.C_STRUCTURE :
// return new CreateStructureOperation(element, dest, fForce);
// case ICElement.C_METHOD : {
// IMethod method = (IMethod)element;
// return new CreateMethodOperation(method, unit, fForce);
// }
// case ICElement.C_FIELD :
// return new CreateFieldOperation(element, dest, fForce);
// case ICElement.C_VARIABLE:
// return new CreateVariableOperation(element, dest);
// default :
// return null;
// }
}
/**
@ -119,7 +91,12 @@ public class CopyElementsOperation extends MultiOperation {
if (element instanceof ISourceReference) {
ISourceReference source = (ISourceReference)element;
try {
return source.getSource();
String contents = source.getSource();
// TODO: remove this hack when we have ASTRewrite and doit properly
if (! contents.endsWith(Util.LINE_SEPARATOR)) {
contents += Util.LINE_SEPARATOR;
}
return contents;
} catch (CModelException e) {
//
}
@ -157,10 +134,10 @@ public class CopyElementsOperation extends MultiOperation {
}
executeNestedOperation(op, 1);
// if (isInTUOperation && isMove()) {
// DeleteElementsOperation deleteOp = new DeleteElementsOperation(new ICElement[] { element }, fForce);
// executeNestedOperation(deleteOp, 1);
// }
if (isInTUOperation && isMove()) {
DeleteElementsOperation deleteOp = new DeleteElementsOperation(new ICElement[] { element }, fForce);
executeNestedOperation(deleteOp, 1);
}
}
/**

View file

@ -252,11 +252,11 @@ public abstract class CreateElementInTUOperation extends CModelOperation {
case INSERT_BEFORE:
fReplacementLength = 0;
fInsertionPosition = range.getStartPos();
break;
default:
fReplacementLength = range.getStartPos() + range.getLength();
fInsertionPosition = range.getStartPos();
break;
}
return;
}

View file

@ -0,0 +1,151 @@
/**********************************************************************
* Copyright (c) 2002,2003,2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.model;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.IBuffer;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICModelStatusConstants;
import org.eclipse.cdt.core.model.IRegion;
import org.eclipse.cdt.core.model.ISourceRange;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.CharOperation;
/**
* DeleteElementsOperation
*/
public class DeleteElementsOperation extends MultiOperation {
/**
* The elements this operation processes grouped by compilation unit
* @see processElements(). Keys are compilation units,
* values are <code>IRegion</code>s of elements to be processed in each
* compilation unit.
*/
protected Map fChildrenToRemove;
/**
* When executed, this operation will delete the given elements. The elements
* to delete cannot be <code>null</code> or empty, and must be contained within a
* compilation unit.
*/
public DeleteElementsOperation(ICElement[] elementsToDelete, boolean force) {
super(elementsToDelete, force);
}
/**
* @see MultiOperation
*/
protected String getMainTaskName() {
return "operation.deleteElementProgress"; //$NON-NLS-1$
}
/**
* Groups the elements to be processed by their compilation unit.
* If parent/child combinations are present, children are
* discarded (only the parents are processed). Removes any
* duplicates specified in elements to be processed.
*/
protected void groupElements() throws CModelException {
fChildrenToRemove = new HashMap(1);
int uniqueTUs = 0;
for (int i = 0, length = fElementsToProcess.length; i < length; i++) {
ICElement e = fElementsToProcess[i];
ITranslationUnit tu = getTranslationUnitFor(e);
if (tu == null) {
throw new CModelException(new CModelStatus(ICModelStatusConstants.READ_ONLY, e));
}
IRegion region = (IRegion) fChildrenToRemove.get(tu);
if (region == null) {
region = new Region();
fChildrenToRemove.put(tu, region);
uniqueTUs++;
}
region.add(e);
}
fElementsToProcess = new ICElement[uniqueTUs];
Iterator iter = fChildrenToRemove.keySet().iterator();
int i = 0;
while (iter.hasNext()) {
fElementsToProcess[i++] = (ICElement) iter.next();
}
}
/**
* Deletes this element from its compilation unit.
* @see MultiOperation
*/
protected void processElement(ICElement element) throws CModelException {
ITranslationUnit tu = (ITranslationUnit) element;
IBuffer buffer = tu.getBuffer();
if (buffer == null) return;
CElementDelta delta = new CElementDelta(tu);
ICElement[] cuElements = ((IRegion) fChildrenToRemove.get(tu)).getElements();
for (int i = 0, length = cuElements.length; i < length; i++) {
ICElement e = cuElements[i];
if (e.exists()) {
char[] contents = buffer.getCharacters();
if (contents == null) continue;
String tuName = tu.getElementName();
replaceElementInBuffer(buffer, e, tuName);
delta.removed(e);
}
}
if (delta.getAffectedChildren().length > 0) {
tu.save(getSubProgressMonitor(1), fForce);
if (!tu.isWorkingCopy()) { // if unit is working copy, then save will have already fired the delta
addDelta(delta);
// this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
}
}
}
/**
* @deprecated marked deprecated to suppress JDOM-related deprecation warnings
*/
private void replaceElementInBuffer(IBuffer buffer, ICElement elementToRemove, String cuName) throws CModelException {
if (elementToRemove instanceof ISourceReference) {
ISourceRange range = ((ISourceReference)elementToRemove).getSourceRange();
int startPosition = range.getStartPos();
int length = range.getLength();
buffer.replace(startPosition, length, CharOperation.NO_CHAR);
}
}
/**
* @see MultiOperation
* This method first group the elements by <code>ICompilationUnit</code>,
* and then processes the <code>ICompilationUnit</code>.
*/
protected void processElements() throws CModelException {
groupElements();
super.processElements();
}
/**
* @see MultiOperation
*/
protected void verify(ICElement element) throws CModelException {
ICElement[] children = ((IRegion) fChildrenToRemove.get(element)).getElements();
for (int i = 0; i < children.length; i++) {
ICElement child = children[i];
if (child.getResource() != null)
error(ICModelStatusConstants.INVALID_ELEMENT_TYPES, child);
if (child.isReadOnly())
error(ICModelStatusConstants.READ_ONLY, child);
}
}
}

View file

@ -0,0 +1,40 @@
/**********************************************************************
* Copyright (c) 2002,2003,2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.model;
import org.eclipse.cdt.core.model.ICElement;
/**
* MoveElementsOperation
*/
public class MoveElementsOperation extends CopyElementsOperation {
/**
* When executed, this operation will move the given elements to the given containers.
*/
public MoveElementsOperation(ICElement[] elementsToMove, ICElement[] destContainers, boolean force) {
super(elementsToMove, destContainers, force);
}
/**
* Returns the <code>String</code> to use as the main task name
* for progress monitoring.
*/
protected String getMainTaskName() {
return "operation.moveElementProgress"; //$NON-NLS-1$
}
/**
* @see CopyElementsOperation#isMove()
*/
protected boolean isMove() {
return true;
}
}

View file

@ -13,6 +13,9 @@ import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ICModelStatus;
import org.eclipse.cdt.core.model.ICModelStatusConstants;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
/**
* This class is used to perform operations on multiple <code>ICElement</code>.
@ -260,9 +263,19 @@ public abstract class MultiOperation extends CModelOperation {
* <code>element</code> and <code>destination</code>.
*/
protected void verifyDestination(ICElement element, ICElement destination) throws CModelException {
if (destination == null || !destination.exists())
if (destination == null || !destination.exists()) {
error(ICModelStatusConstants.ELEMENT_DOES_NOT_EXIST, destination);
}
if (element.getElementType() == ICElement.C_UNIT) {
IResource res = destination.getResource();
if (!(res instanceof IContainer)) {
error(ICModelStatusConstants.INVALID_DESTINATION, element);
}
ITranslationUnit tu = (ITranslationUnit)element;
if (isMove() && tu.isWorkingCopy() /*&& !cu.isPrimary() */) {
error(ICModelStatusConstants.INVALID_ELEMENT_TYPES, element);
}
}
}
/**

View file

@ -0,0 +1,161 @@
/**********************************************************************
* Copyright (c) 2002,2003,2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* QNX Software Systems
***********************************************************************/
package org.eclipse.cdt.internal.core.model;
import java.util.ArrayList;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.IParent;
import org.eclipse.cdt.core.model.IRegion;
/**
* @see IRegion
*/
public class Region implements IRegion {
/**
* A collection of the top level elements that have been added to the region
*/
protected ArrayList fRootElements;
/**
* Creates an empty region.
*
* @see IRegion
*/
public Region() {
fRootElements = new ArrayList(1);
}
/**
* @see IRegion#add(ICElement)
*/
public void add(ICElement element) {
if (!contains(element)) {
// "new" element added to region
removeAllChildren(element);
fRootElements.add(element);
fRootElements.trimToSize();
}
}
/**
* @see IRegion
*/
public boolean contains(ICElement element) {
int size = fRootElements.size();
ArrayList parents = getAncestors(element);
for (int i = 0; i < size; i++) {
ICElement aTop = (ICElement) fRootElements.get(i);
if (aTop.equals(element)) {
return true;
}
for (int j = 0, pSize = parents.size(); j < pSize; j++) {
if (aTop.equals(parents.get(j))) {
// an ancestor is already included
return true;
}
}
}
return false;
}
/**
* Returns a collection of all the parents of this element in bottom-up
* order.
*
*/
private ArrayList getAncestors(ICElement element) {
ArrayList parents = new ArrayList();
ICElement parent = element.getParent();
while (parent != null) {
parents.add(parent);
parent = parent.getParent();
}
parents.trimToSize();
return parents;
}
/**
* @see IRegion
*/
public ICElement[] getElements() {
int size = fRootElements.size();
ICElement[] roots = new ICElement[size];
for (int i = 0; i < size; i++) {
roots[i] = (ICElement) fRootElements.get(i);
}
return roots;
}
/**
* @see IRegion#remove(ICElement)
*/
public boolean remove(ICElement element) {
removeAllChildren(element);
return fRootElements.remove(element);
}
/**
* Removes any children of this element that are contained within this
* region as this parent is about to be added to the region.
*
* <p>
* Children are all children, not just direct children.
*/
private void removeAllChildren(ICElement element) {
if (element instanceof IParent) {
ArrayList newRootElements = new ArrayList();
for (int i = 0, size = fRootElements.size(); i < size; i++) {
ICElement currentRoot = (ICElement) fRootElements.get(i);
// walk the current root hierarchy
ICElement parent = currentRoot.getParent();
boolean isChild = false;
while (parent != null) {
if (parent.equals(element)) {
isChild = true;
break;
}
parent = parent.getParent();
}
if (!isChild) {
newRootElements.add(currentRoot);
}
}
fRootElements = newRootElements;
}
}
/**
* Returns a printable representation of this region.
*/
public String toString() {
StringBuffer buffer = new StringBuffer();
ICElement[] roots = getElements();
buffer.append('[');
for (int i = 0; i < roots.length; i++) {
buffer.append(roots[i].getElementName());
if (i < (roots.length - 1)) {
buffer.append(", "); //$NON-NLS-1$
}
}
buffer.append(']');
return buffer.toString();
}
}

View file

@ -0,0 +1,84 @@
/**********************************************************************
* Copyright (c) 2002,2003,2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.model;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICModelStatus;
import org.eclipse.cdt.core.model.ICModelStatusConstants;
import org.eclipse.cdt.core.model.ISourceReference;
/**
* RenameElementsOperation
*/
public class RenameElementsOperation extends MoveElementsOperation {
/**
* When executed, this operation will rename the specified elements with the given names in the
* corresponding destinations.
*/
public RenameElementsOperation(ICElement[] elements, ICElement[] destinations, String[] newNames, boolean force) {
//a rename is a move to the same parent with a new name specified
//these elements are from different parents
super(elements, destinations, force);
setRenamings(newNames);
}
/**
* @see MultiOperation
*/
protected String getMainTaskName() {
return "operation.renameElementProgress"; //$NON-NLS-1$
}
/**
* @see CopyElementsOperation#isRename()
*/
protected boolean isRename() {
return true;
}
/**
* @see MultiOperation
*/
protected ICModelStatus verify() {
ICModelStatus status = super.verify();
if (! status.isOK())
return status;
if (this.fRenamingsList == null || this.fRenamingsList.length == 0)
return new CModelStatus(ICModelStatusConstants.NULL_NAME);
return CModelStatus.VERIFIED_OK;
}
/**
* @see MultiOperation
*/
protected void verify(ICElement element) throws CModelException {
int elementType = element.getElementType();
if (element == null || !element.exists())
error(ICModelStatusConstants.ELEMENT_DOES_NOT_EXIST, element);
if (element.isReadOnly())
error(ICModelStatusConstants.READ_ONLY, element);
if (!(element instanceof ISourceReference))
error(ICModelStatusConstants.INVALID_ELEMENT_TYPES, element);
if (elementType < ICElement.C_UNIT /*|| elementType == ICElement.INITIALIZER*/)
error(ICModelStatusConstants.INVALID_ELEMENT_TYPES, element);
// Member localContext;
// if (element instanceof Member && (localContext = ((Member)element).getOuterMostLocalContext()) != null && localContext != element) {
// // JDOM doesn't support source manipulation in local/anonymous types
// error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
// }
verifyRenaming(element);
}
}