From a09eaa034f9e28ef14e959c98ef431984d44823c Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Sun, 23 Jan 2005 04:44:37 +0000 Subject: [PATCH] 2005-01-22 Alain Magloire PR 38958 Part implementation of the CreateXXXOperation classes. * model/org/eclipse/cdt/core/model/ICElement.java * model/org/eclipse/cdt/core/model/IStructure.java * model/org/eclipse/cdt/core/model/IStructureDeclaration.java * model/org/eclipse/cdt/internal/core/model/CModelBuiilder.java * model/org/eclipse/cdt/internal/core/model/CModelOperation.java * model/org/eclipse/cdt/internal/core/model/CopyElementOperation.java * model/org/eclipse/cdt/internal/core/model/CreateElementIntTUOperation.java * model/org/eclipse/cdt/internal/core/model/CreateFieldOperation.java * model/org/eclipse/cdt/internal/core/model/CreateIncludeOperation.java * model/org/eclipse/cdt/internal/core/model/CreateMethodOperation.java * model/org/eclipse/cdt/internal/core/model/CreateSourceReferenceOperation.java * model/org/eclipse/cdt/internal/core/model/FuntionInfo.java * model/org/eclipse/cdt/internal/core/model/FuntionDeclaration.java * model/org/eclipse/cdt/internal/core/model/Structure.java * model/org/eclipse/cdt/internal/core/model/StructureDeclaratin.java * model/org/eclipse/cdt/internal/core/model/StructureInfo.java * model/org/eclipse/cdt/internal/core/model/MethodInfo.java * model/org/eclipse/cdt/internal/core/model/util.java * model/org/eclipse/cdt/internal/core/model/SurceManipulationInfo.java --- core/org.eclipse.cdt.core/ChangeLog | 23 ++ .../org/eclipse/cdt/core/model/ICElement.java | 18 ++ .../eclipse/cdt/core/model/IStructure.java | 23 +- .../cdt/core/model/IStructureDeclaration.java | 45 ++++ .../internal/core/model/CModelBuilder.java | 51 +++- .../internal/core/model/CModelOperation.java | 12 +- .../core/model/CopyElementsOperation.java | 74 ++++-- .../model/CreateElementInTUOperation.java | 135 +---------- .../core/model/CreateFieldOperation.java | 30 ++- .../CreateFunctionDeclarationOperation.java | 96 -------- .../core/model/CreateIncludeOperation.java | 55 ++++- .../core/model/CreateMemberOperation.java | 36 +-- .../core/model/CreateMethodOperation.java | 61 ++++- .../model/CreateSourceReferenceOperation.java | 83 +++++++ .../core/model/FunctionDeclaration.java | 8 +- .../cdt/internal/core/model/FunctionInfo.java | 1 + .../internal/core/model/FunctionTemplate.java | 3 +- .../cdt/internal/core/model/MethodInfo.java | 10 - .../core/model/SourceManipulation.java | 5 + .../core/model/SourceManipulationInfo.java | 53 +++-- .../cdt/internal/core/model/Structure.java | 54 +---- .../core/model/StructureDeclaration.java | 81 +++++++ .../internal/core/model/StructureInfo.java | 79 +++++- .../eclipse/cdt/internal/core/model/Util.java | 117 +++++++++ .../internal/core/util/CharArrayBuffer.java | 225 ++++++++++++++++++ .../org/eclipse/cdt/core/CConventions.java | 31 ++- 26 files changed, 992 insertions(+), 417 deletions(-) create mode 100644 core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IStructureDeclaration.java delete mode 100644 core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateFunctionDeclarationOperation.java create mode 100644 core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateSourceReferenceOperation.java create mode 100644 core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/StructureDeclaration.java create mode 100644 core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/util/CharArrayBuffer.java diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog index 1f9e314c2b6..4186f1b748c 100644 --- a/core/org.eclipse.cdt.core/ChangeLog +++ b/core/org.eclipse.cdt.core/ChangeLog @@ -1,3 +1,26 @@ +2005-01-22 Alain Magloire + PR 38958 + Part implementation of the CreateXXXOperation classes. + * model/org/eclipse/cdt/core/model/ICElement.java + * model/org/eclipse/cdt/core/model/IStructure.java + * model/org/eclipse/cdt/core/model/IStructureDeclaration.java + * model/org/eclipse/cdt/internal/core/model/CModelBuiilder.java + * model/org/eclipse/cdt/internal/core/model/CModelOperation.java + * model/org/eclipse/cdt/internal/core/model/CopyElementOperation.java + * model/org/eclipse/cdt/internal/core/model/CreateElementIntTUOperation.java + * model/org/eclipse/cdt/internal/core/model/CreateFieldOperation.java + * model/org/eclipse/cdt/internal/core/model/CreateIncludeOperation.java + * model/org/eclipse/cdt/internal/core/model/CreateMethodOperation.java + * model/org/eclipse/cdt/internal/core/model/CreateSourceReferenceOperation.java + * model/org/eclipse/cdt/internal/core/model/FuntionInfo.java + * model/org/eclipse/cdt/internal/core/model/FuntionDeclaration.java + * model/org/eclipse/cdt/internal/core/model/Structure.java + * model/org/eclipse/cdt/internal/core/model/StructureDeclaratin.java + * model/org/eclipse/cdt/internal/core/model/StructureInfo.java + * model/org/eclipse/cdt/internal/core/model/MethodInfo.java + * model/org/eclipse/cdt/internal/core/model/util.java + * model/org/eclipse/cdt/internal/core/model/SurceManipulationInfo.java + 2005-01-19 Alain Magloire PR 83224 * model/org/eclipse/cdt/internal/core/model/DeltaProcessor.java diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ICElement.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ICElement.java index 96c8f4d01ad..b000a4602a6 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ICElement.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ICElement.java @@ -176,6 +176,24 @@ public interface ICElement extends IAdaptable { */ static final int C_TEMPLATE_VARIABLE = 84; + /** + * Declaration of a structure without the definition. + * struct C; + */ + static final int C_STRUCT_DECLARATION = 85; + + /** + * Declaration of a class without the definition. + * class C; + */ + static final int C_CLASS_DECLARATION = 86; + + /** + * Declaration of a union without the definition. + * struct C; + */ + static final int C_UNION_DECLARATION = 87; + /** * Modifier indicating a class constructor */ diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IStructure.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IStructure.java index af967c70e0d..f85806addf7 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IStructure.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IStructure.java @@ -14,7 +14,7 @@ package org.eclipse.cdt.core.model; /** * Represent struct(ure), class or union. */ -public interface IStructure extends IInheritance, IParent, IVariableDeclaration { +public interface IStructure extends IInheritance, IParent, IStructureDeclaration { public IField getField(String name); /** @@ -39,27 +39,6 @@ public interface IStructure extends IInheritance, IParent, IVariableDeclaration */ public IMethodDeclaration [] getMethods() throws CModelException; - /** - * Checks if the structure is a Union - * @return boolean - * @throws CModelException - */ - public boolean isUnion() throws CModelException; - - /** - * Checks if the structure is a class - * @return boolean - * @throws CModelException - */ - public boolean isClass() throws CModelException; - - /** - * Checks if the structure is a struct - * @return boolean - * @throws CModelException - */ - public boolean isStruct() throws CModelException; - /** * Checks if the structure is abstract * @return boolean diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IStructureDeclaration.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IStructureDeclaration.java new file mode 100644 index 00000000000..72033e888c9 --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IStructureDeclaration.java @@ -0,0 +1,45 @@ +/********************************************************************** + * 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.core.model; + +/** + * IStructureDeclaration + */ +public interface IStructureDeclaration extends IDeclaration { + + /** + * Checks if the structure is a Union + * @return boolean + * @throws CModelException + */ + public boolean isUnion() throws CModelException; + + /** + * Checks if the structure is a class + * @return boolean + * @throws CModelException + */ + public boolean isClass() throws CModelException; + + /** + * Checks if the structure is a struct + * @return boolean + * @throws CModelException + */ + public boolean isStruct() throws CModelException; + + /** + * Return "class", "struct", "union" + * @deprecated use isUnion(), isClass(), isStruct() + */ + String getTypeName() throws CModelException; +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder.java index a31d6e65ff4..db01b25ecec 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder.java @@ -71,7 +71,8 @@ public class CModelBuilder { private org.eclipse.cdt.internal.core.model.TranslationUnit translationUnit; private Map newElements; - private IQuickParseCallback quickParseCallback; + private IQuickParseCallback quickParseCallback; + private static char[] EMPTY_CHAR_ARRAY = {}; // indicator if the unit has parse errors private boolean hasNoErrors = false; @@ -103,7 +104,7 @@ public class CModelBuilder { { IProject currentProject = null; boolean hasCppNature = true; - String code = ""; //$NON-NLS-1$ + char[] code = EMPTY_CHAR_ARRAY; //$NON-NLS-1$ // get the current project if (translationUnit != null && translationUnit.getCProject() != null) { @@ -116,7 +117,7 @@ public class CModelBuilder { } // get the code to parse try{ - code = translationUnit.getBuffer().getContents(); + code = translationUnit.getBuffer().getCharacters(); } catch (CModelException e) { } @@ -165,8 +166,8 @@ public class CModelBuilder { CodeReader reader = translationUnit.getUnderlyingResource() != null - ? new CodeReader(translationUnit.getUnderlyingResource().getLocation().toOSString(), code.toCharArray()) - : new CodeReader(code.toCharArray()); + ? new CodeReader(translationUnit.getUnderlyingResource().getLocation().toOSString(), code) + : new CodeReader(code); parser = ParserFactory.createParser( ParserFactory.createScanner( reader, @@ -309,7 +310,7 @@ public class CModelBuilder { private void generateModelElements (Parent parent, IASTAbstractTypeSpecifierDeclaration abstractDeclaration) throws CModelException, ASTNotImplementedException { // IASTAbstractTypeSpecifierDeclaration - CElement element = createAbstractElement(parent, abstractDeclaration, false); + CElement element = createAbstractElement(parent, abstractDeclaration, false, true); } private void generateModelElements (Parent parent, IASTTemplateDeclaration templateDeclaration) throws CModelException, ASTNotImplementedException @@ -318,7 +319,7 @@ public class CModelBuilder { IASTDeclaration declaration = templateDeclaration.getOwnedDeclaration(); if(declaration instanceof IASTAbstractTypeSpecifierDeclaration){ IASTAbstractTypeSpecifierDeclaration abstractDeclaration = (IASTAbstractTypeSpecifierDeclaration)declaration ; - CElement element = createAbstractElement(parent, abstractDeclaration , true); + CElement element = createAbstractElement(parent, abstractDeclaration , true, true); if(element != null){ // set the element position element.setPos(templateDeclaration.getStartingOffset(), templateDeclaration.getEndingOffset() - templateDeclaration.getStartingOffset()); @@ -360,7 +361,7 @@ public class CModelBuilder { { TypeDef typeDef = createTypeDef(parent, declaration); IASTAbstractDeclaration abstractDeclaration = declaration.getAbstractDeclarator(); - CElement element = createAbstractElement(parent, abstractDeclaration, false); + CElement element = createAbstractElement(parent, abstractDeclaration, false, true); } private CElement createClassSpecifierElement(Parent parent, IASTClassSpecifier classSpecifier, boolean isTemplate)throws ASTNotImplementedException, CModelException{ @@ -377,7 +378,7 @@ public class CModelBuilder { return element; } - private CElement createAbstractElement(Parent parent, IASTTypeSpecifierOwner abstractDeclaration, boolean isTemplate)throws ASTNotImplementedException, CModelException{ + private CElement createAbstractElement(Parent parent, IASTTypeSpecifierOwner abstractDeclaration, boolean isTemplate, boolean isDeclaration)throws ASTNotImplementedException, CModelException{ CElement element = null; if(abstractDeclaration != null){ IASTTypeSpecifier typeSpec = abstractDeclaration.getTypeSpecifier(); @@ -391,9 +392,11 @@ public class CModelBuilder { else if (typeSpec instanceof IASTClassSpecifier){ IASTClassSpecifier classSpecifier = (IASTClassSpecifier) typeSpec; element = createClassSpecifierElement (parent, classSpecifier, isTemplate); - } else if (typeSpec instanceof IASTElaboratedTypeSpecifier){ + } else if (isDeclaration && typeSpec instanceof IASTElaboratedTypeSpecifier) { // This is not a model element, so we don't create anything here. // However, do we need to do anything else? + IASTElaboratedTypeSpecifier elabSpecifier = (IASTElaboratedTypeSpecifier) typeSpec; + element = createElaboratedTypeSpecifier(parent, elabSpecifier); } } return element; @@ -414,6 +417,32 @@ public class CModelBuilder { return element; } + private StructureDeclaration createElaboratedTypeSpecifier(Parent parent, IASTElaboratedTypeSpecifier typeSpec) throws CModelException{ + // create element + ASTClassKind classkind = typeSpec.getClassKind(); + int kind = -1; + if (classkind == ASTClassKind.CLASS) { + kind = ICElement.C_CLASS_DECLARATION; + } else if (classkind == ASTClassKind.STRUCT) { + kind = ICElement.C_STRUCT_DECLARATION; + } else if (classkind == ASTClassKind.UNION) { + kind = ICElement.C_UNION_DECLARATION; + } + String className = (typeSpec.getName() == null) + ? "" //$NON-NLS-1$ + : typeSpec.getName().toString(); + StructureDeclaration element = new StructureDeclaration(parent, className, kind); + + // add to parent + parent.addChild(element); + // set position + element.setIdPos(typeSpec.getNameOffset(), typeSpec.getNameEndOffset() - typeSpec.getNameOffset()); + element.setPos(typeSpec.getStartingOffset(), typeSpec.getEndingOffset() - typeSpec.getStartingOffset()); + element.setLines(typeSpec.getStartingLine(), typeSpec.getEndingLine()); + this.newElements.put(element, element.getElementInfo()); + return element; + } + private Include createInclusion(Parent parent, IASTInclusion inclusion) throws CModelException{ // create element Include element = new Include(parent, inclusion.getName(), !inclusion.isLocal()); @@ -600,7 +629,7 @@ public class CModelBuilder { } IASTAbstractDeclaration abstractDeclaration = varDeclaration.getAbstractDeclaration(); - CElement abstractElement = createAbstractElement (parent, abstractDeclaration , isTemplate); + CElement abstractElement = createAbstractElement (parent, abstractDeclaration , isTemplate, false); VariableDeclaration element = null; if(varDeclaration instanceof IASTField){ diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelOperation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelOperation.java index e719378b8a7..ee76bb06209 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelOperation.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelOperation.java @@ -48,7 +48,7 @@ public abstract class CModelOperation implements IWorkspaceRunnable, IProgressMo * or null if this operation * does not operate with specific parent elements. */ - protected ICElement[] fParentElements; + protected ICElement[] parentElements; /** * An empty collection of ICElements - the common @@ -107,7 +107,7 @@ public abstract class CModelOperation implements IWorkspaceRunnable, IProgressMo */ protected CModelOperation(ICElement[] elementsToProcess, ICElement[] parentElements) { fElementsToProcess = elementsToProcess; - fParentElements= parentElements; + this.parentElements= parentElements; } /** @@ -115,7 +115,7 @@ public abstract class CModelOperation implements IWorkspaceRunnable, IProgressMo */ protected CModelOperation(ICElement[] elementsToProcess, ICElement[] parentElements, boolean force) { fElementsToProcess = elementsToProcess; - fParentElements= parentElements; + this.parentElements= parentElements; fForce= force; } @@ -387,10 +387,10 @@ public abstract class CModelOperation implements IWorkspaceRunnable, IProgressMo * or null if not applicable. */ protected ICElement getParentElement() { - if (fParentElements == null || fParentElements.length == 0) { + if (parentElements == null || parentElements.length == 0) { return null; } - return fParentElements[0]; + return parentElements[0]; } /** @@ -398,7 +398,7 @@ public abstract class CModelOperation implements IWorkspaceRunnable, IProgressMo * or null if not applicable. */ protected ICElement[] getParentElements() { - return fParentElements; + return parentElements; } /** diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CopyElementsOperation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CopyElementsOperation.java index b5d214fcc4d..14f6634da19 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CopyElementsOperation.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CopyElementsOperation.java @@ -9,6 +9,8 @@ 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.IParent; +import org.eclipse.cdt.core.model.ISourceReference; +import org.eclipse.cdt.core.model.ITranslationUnit; /** * This operation copies/moves a collection of elements from their current @@ -77,27 +79,53 @@ public class CopyElementsOperation extends MultiOperation { * Returns the nested operation to use for processing this element */ protected CModelOperation getNestedOperation(ICElement element) { - //ICElement dest = getDestinationParent(element); - switch (element.getElementType()) { - //case ICElement.C_INCLUDE: - // return new CreateIncludeOperation(element, dest); - //case ICElement.C_FUNCTION_DECLARATION : - // return new CreateFunctionDeclarationOperation(element, dest); - //case ICElement.C_FUNCTION : - // return new CreateFunctionOperation(element, dest); - //case ICElement.C_STRUCTURE : - // return new CreateStructureOperation(element, dest, fForce); - //case ICElement.C_METHOD : - // return new CreateMethodOperation(element, dest, fForce); - //case ICElement.C_FIELD : - // return new CreateFieldOperation(element, dest, fForce); - //case ICElement.C_VARIABLE: - // return new CreateVariableOperation(element, dest); - default : - return null; - } + ICElement dest = getDestinationParent(element); + ITranslationUnit unit = (ITranslationUnit)dest.getAncestor(ICElement.C_UNIT); + 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; +// } } + /** + * Returns the cached source for this element or compute it if not already cached. + */ + private String getSourceFor(ICElement element) { + if (element instanceof ISourceReference) { + ISourceReference source = (ISourceReference)element; + try { + return source.getSource(); + } catch (CModelException e) { + // + } + } + return ""; //$NON-NLS-1$ + } /** * Copy/move the element from the source to destination, renaming * the elements as specified, honoring the collision policy. @@ -129,10 +157,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); +// } } /** diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateElementInTUOperation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateElementInTUOperation.java index 94a6e581a91..dc61c89babb 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateElementInTUOperation.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateElementInTUOperation.java @@ -5,22 +5,14 @@ package org.eclipse.cdt.internal.core.model; * All Rights Reserved. */ -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -import org.eclipse.cdt.core.model.*; 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.ICModelStatus; import org.eclipse.cdt.core.model.ICModelStatusConstants; import org.eclipse.cdt.core.model.ISourceRange; import org.eclipse.cdt.core.model.ISourceReference; import org.eclipse.cdt.core.model.ITranslationUnit; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.CoreException; /** *

This abstract class implements behavior common to CreateElementInCUOperations. @@ -62,7 +54,7 @@ public abstract class CreateElementInTUOperation extends CModelOperation { /** * The element that is being created. */ - protected ISourceReference fCreatedElement = null; + protected String fCreatedElement = null; /** * The element that the newly created element is @@ -129,6 +121,8 @@ public abstract class CreateElementInTUOperation extends CModelOperation { setRelativePosition(sibling, INSERT_BEFORE); } + protected abstract String generateElement(ITranslationUnit unit) throws CModelException; + /** * Execute the operation - generate new source for the compilation unit * and save the results. @@ -139,7 +133,7 @@ public abstract class CreateElementInTUOperation extends CModelOperation { beginTask(getMainTaskName(), getMainAmountOfWork()); CElementDelta delta = newCElementDelta(); ITranslationUnit unit = getTranslationUnit(); - // generateNewTranslationUnitDOM(unit); + fCreatedElement = generateElement(unit); insertElement(); if (fCreationOccurred) { //a change has really occurred @@ -147,29 +141,23 @@ public abstract class CreateElementInTUOperation extends CModelOperation { if (buffer == null) return; char[] bufferContents = buffer.getCharacters(); if (bufferContents == null) return; - //char[] elementContents = normalizeCRS(..); - char[] elementContents = fCreatedElement.getSource().toCharArray(); - //IFile file = (IFile)((ICResource)unit).getResource(); - //StringBuffer buffer = getContent(file); + char[] elementContents = Util.normalizeCRs(getCreatedElementCharacters(), bufferContents); switch (fReplacementLength) { case -1 : // element is append at the end - //buffer.append(fCreatedElement.getSource()); buffer.append(elementContents); break; case 0 : // element is inserted - //buffer.insert(fInsertionPosition, fCreatedElement.getSource()); buffer.replace(fInsertionPosition, 0, elementContents); break; default : // element is replacing the previous one - buffer.replace(fInsertionPosition, fReplacementLength, fCreatedElement.getSource()); + buffer.replace(fInsertionPosition, fReplacementLength, elementContents); } unit.save(null, false); - //save(buffer, file); boolean isWorkingCopy = unit.isWorkingCopy(); //if (isWorkingCopy) { // this.setAttributes(...); @@ -189,6 +177,10 @@ public abstract class CreateElementInTUOperation extends CModelOperation { done(); } + private char[] getCreatedElementCharacters() { + return fCreatedElement.toCharArray(); + } + /** * Creates and returns the handle for the element this operation created. */ @@ -314,9 +306,6 @@ public abstract class CreateElementInTUOperation extends CModelOperation { } if (fAnchorElement != null) { ICElement domPresentParent = fAnchorElement.getParent(); - //if (domPresentParent.getElementType() == ICElement.IMPORT_CONTAINER) { - // domPresentParent = domPresentParent.getParent(); - //} if (!domPresentParent.equals(getParentElement())) { return new CModelStatus(ICModelStatusConstants.INVALID_SIBLING, fAnchorElement); } @@ -324,106 +313,4 @@ public abstract class CreateElementInTUOperation extends CModelOperation { return CModelStatus.VERIFIED_OK; } - - StringBuffer getContent(IFile file) throws CModelException { - InputStream stream = null; - try { - stream = new BufferedInputStream(file.getContents(true)); - } catch (CoreException e) { - throw new CModelException(e); - } - try { - char [] b = getInputStreamAsCharArray(stream, -1, null); - return new StringBuffer(b.length).append(b); - } catch (IOException e) { - throw new CModelException(e, ICModelStatusConstants.IO_EXCEPTION); - } finally { - try { - if (stream != null) - stream.close(); - } catch (IOException e) { - } - } - } - - /** - * Returns the given input stream's contents as a character array. - * If a length is specified (ie. if length != -1), only length chars - * are returned. Otherwise all chars in the stream are returned. - * Note this doesn't close the stream. - * @throws IOException if a problem occured reading the stream. - */ - public static char[] getInputStreamAsCharArray(InputStream stream, int length, String encoding) - throws IOException { - InputStreamReader reader = null; - reader = encoding == null - ? new InputStreamReader(stream) - : new InputStreamReader(stream, encoding); - char[] contents; - if (length == -1) { - contents = new char[0]; - int contentsLength = 0; - int charsRead = -1; - do { - int available = stream.available(); - - // resize contents if needed - if (contentsLength + available > contents.length) { - System.arraycopy( - contents, - 0, - contents = new char[contentsLength + available], - 0, - contentsLength); - } - - // read as many chars as possible - charsRead = reader.read(contents, contentsLength, available); - - if (charsRead > 0) { - // remember length of contents - contentsLength += charsRead; - } - } while (charsRead > 0); - - // resize contents if necessary - if (contentsLength < contents.length) { - System.arraycopy( - contents, - 0, - contents = new char[contentsLength], - 0, - contentsLength); - } - } else { - contents = new char[length]; - int len = 0; - int readSize = 0; - while ((readSize != -1) && (len != length)) { - // See PR 1FMS89U - // We record first the read size. In this case len is the actual read size. - len += readSize; - readSize = reader.read(contents, len, length - len); - } - // See PR 1FMS89U - // Now we need to resize in case the default encoding used more than one byte for each - // character - if (len != length) - System.arraycopy(contents, 0, (contents = new char[len]), 0, len); - } - - return contents; - } - - void save (StringBuffer buffer, IFile file) throws CModelException { - byte[] bytes = buffer.toString().getBytes(); - ByteArrayInputStream stream = new ByteArrayInputStream(bytes); - // use a platform operation to update the resource contents - try { - boolean force = true; - file.setContents(stream, force, true, null); // record history - } catch (CoreException e) { - throw new CModelException(e); - } - } } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateFieldOperation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateFieldOperation.java index 0ebe1dc4554..26d6189d087 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateFieldOperation.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateFieldOperation.java @@ -9,6 +9,7 @@ import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.IStructure; import org.eclipse.cdt.core.model.ICModelStatus; +import org.eclipse.cdt.core.model.ITranslationUnit; /** *

This operation creates a field declaration in a type. * @@ -19,6 +20,11 @@ import org.eclipse.cdt.core.model.ICModelStatus; * */ public class CreateFieldOperation extends CreateMemberOperation { + /** + * Initializer for Element + */ + String fInitializer; + /** * When executed, this operation will create a field with the given name * in the given type with the specified source. @@ -27,8 +33,9 @@ public class CreateFieldOperation extends CreateMemberOperation { * declaration, or as the first member in the type if there are no * field declarations. */ - public CreateFieldOperation(IStructure parentElement, String source, boolean force) { - super(parentElement, source, force); + public CreateFieldOperation(IStructure parentElement, String name, String returnType, String initializer, boolean force) { + super(parentElement, name, returnType, force); + fInitializer = initializer; } /** @@ -63,13 +70,28 @@ public class CreateFieldOperation extends CreateMemberOperation { * @see CreateElementInCUOperation#generateResultHandle */ protected ICElement generateResultHandle() { - return getStructure().getField(fSource); + return getStructure().getField(fName); } /** * @see CreateTypeMemberOperation#verifyNameCollision */ protected ICModelStatus verifyNameCollision() { - return CModelStatus.VERIFIED_OK; + return super.verifyNameCollision(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.model.CreateElementInTUOperation#generateElement(org.eclipse.cdt.core.model.ITranslationUnit) + */ + protected String generateElement(ITranslationUnit unit) throws CModelException { + StringBuffer sb = new StringBuffer(); + sb.append(fReturnType).append(' '); + sb.append(fName); + if (fInitializer != null && fInitializer.length() > 0) { + sb.append(' ').append('=').append(' '); + sb.append(fInitializer); + } + sb.append(';'); + return sb.toString(); } } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateFunctionDeclarationOperation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateFunctionDeclarationOperation.java deleted file mode 100644 index d00f25c0167..00000000000 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateFunctionDeclarationOperation.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.eclipse.cdt.internal.core.model; - -/* - * (c) Copyright IBM Corp. 2000, 2001. - * All Rights Reserved. - */ - -import org.eclipse.cdt.core.model.ICElement; -import org.eclipse.cdt.core.model.IInclude; -import org.eclipse.cdt.core.model.ITranslationUnit; -import org.eclipse.cdt.core.model.ICModelStatus; -import org.eclipse.cdt.core.model.CModelException; - -/** - *

This operation adds an include declaration to an existing translation unit. - * If the translation unit already includes the specified include declaration, - * the include is not generated (it does not generate duplicates). - * - *

Required Attributes:

- */ -public class CreateFunctionDeclarationOperation extends CreateElementInTUOperation { - - /** - * The name of the include to be created. - */ - protected String fFunction; - - /** - * When executed, this operation will add an include to the given translation unit. - */ - public CreateFunctionDeclarationOperation(String function, ITranslationUnit parentElement) { - super(parentElement); - fFunction = function; - } - - /** - * @see CreateElementInCUOperation#generateResultHandle - */ - protected ICElement generateResultHandle() { - try { - return getTranslationUnit().getElement(fFunction); - } catch (CModelException e) { - } - return null; - } - - /** - * @see CreateElementInCUOperation#getMainTaskName - */ - public String getMainTaskName(){ - return "operation.createIncludeProgress"; //$NON-NLS-1$ - } - - /** - * Sets the correct position for the new include: */ public class CreateMethodOperation extends CreateMemberOperation { + /** + * Parameter types of the element. + */ protected String[] fParameterTypes; + /** + * The source code for the new member. + */ + protected String fSource; + + /** * When executed, this operation will create a method * in the given type with the specified source. */ - public CreateMethodOperation(IStructure parentElement, String source, boolean force) { - super(parentElement, source, force); + public CreateMethodOperation(IStructure parentElement, String name, String returnType, String source, String[] parameters, boolean force) { + super(parentElement, name, returnType, force); + fParameterTypes = parameters; + fSource = source; } /** * @see CreateElementInCUOperation#generateResultHandle */ protected ICElement generateResultHandle() { - return getStructure().getMethod(fSource); + //TODO: what about collisions, we need the signature here. + return getStructure().getMethod(fName); } /** @@ -47,6 +62,46 @@ public class CreateMethodOperation extends CreateMemberOperation { * @see CreateTypeMemberOperation#verifyNameCollision */ protected ICModelStatus verifyNameCollision() { + ICModelStatus status = super.verify(); + if (!status.isOK()) { + return status; + } + if (fSource == null) { + return new CModelStatus(ICModelStatusConstants.INVALID_CONTENTS); + } + if (!fForce) { + //check for name collisions + //if (node == null) { + // return new CModelStatus(ICModelStatusConstants.INVALID_CONTENTS); + // } + //} catch (CModelException cme) { + //} + } + return CModelStatus.VERIFIED_OK; } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.model.CreateElementInTUOperation#generateElement(org.eclipse.cdt.core.model.ITranslationUnit) + */ + protected String generateElement(ITranslationUnit unit) throws CModelException { + StringBuffer sb = new StringBuffer(); + sb.append(fReturnType); + sb.append(' '); + sb.append(fName); + sb.append('('); + if (fParameterTypes != null) { + for (int i = 0; i < fParameterTypes.length; ++i) { + if (i != 0) { + sb.append(',').append(' '); + } + sb.append(fParameterTypes[i]); + } + } + sb.append(')').append(' ').append('{').append(Util.LINE_SEPARATOR); + sb.append(fSource); + sb.append(Util.LINE_SEPARATOR).append('}').append(Util.LINE_SEPARATOR); + return sb.toString(); + } + } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateSourceReferenceOperation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateSourceReferenceOperation.java new file mode 100644 index 00000000000..9f2e21cb87f --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateSourceReferenceOperation.java @@ -0,0 +1,83 @@ +/********************************************************************** + * 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.ITranslationUnit; + +/** + * CreateSourceReferenceOperation + */ +public class CreateSourceReferenceOperation extends CreateElementInTUOperation { + + /** + * Element Name + */ + String fName; + + /** + * Element Type + */ + int fElementType; + + /** + * Source Reference element to copy to parent + */ + String fSource; + + /** + * @param parentElement + */ + public CreateSourceReferenceOperation(ICElement parentElement, String name, int elementType, String source) { + super(parentElement); + fName = name; + fElementType = elementType; + fSource = source; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.model.CreateElementInTUOperation#generateElement(org.eclipse.cdt.core.model.ITranslationUnit) + */ + protected String generateElement(ITranslationUnit unit) throws CModelException { + return fSource; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.model.CreateElementInTUOperation#generateResultHandle() + */ + protected ICElement generateResultHandle() { + ITranslationUnit unit = getTranslationUnit(); + try { + ICElement[] celements = unit.getChildren(); + for (int i = 0; i < celements.length; ++i) { + if (celements[i].getElementType() == fElementType) { + String name = celements[i].getElementName(); + if (name.equals(fName)) { + return celements[i]; + } + } + } + } catch (CModelException e) { + // + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.model.CreateElementInTUOperation#getMainTaskName() + */ + protected String getMainTaskName() { + return "operation.createsourceReference"; //$NON-NLS-1$ + } + +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/FunctionDeclaration.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/FunctionDeclaration.java index 8185ed078c6..22c44c06fa6 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/FunctionDeclaration.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/FunctionDeclaration.java @@ -10,21 +10,17 @@ import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.IFunctionDeclaration; public class FunctionDeclaration extends SourceManipulation implements IFunctionDeclaration { - /** - * An empty list of Strings - */ - protected static final String[] fgEmptyList= new String[] {}; protected String[] fParameterTypes; protected String returnType; public FunctionDeclaration(ICElement parent, String name) { super(parent, name, ICElement.C_FUNCTION_DECLARATION); - fParameterTypes= fgEmptyList; + fParameterTypes= fgEmptyStrings; } public FunctionDeclaration(ICElement parent, String name, int type) { super(parent, name, type); - fParameterTypes= fgEmptyList; + fParameterTypes= fgEmptyStrings; } public String getReturnType(){ diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/FunctionInfo.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/FunctionInfo.java index 0d74c45793b..8f08d734c30 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/FunctionInfo.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/FunctionInfo.java @@ -55,6 +55,7 @@ class FunctionInfo extends SourceManipulationInfo { return (super.hasSameContentsAs(otherInfo) && (this.isStatic() == ((FunctionInfo)otherInfo).isStatic()) && (this.isVolatile() == ((FunctionInfo)otherInfo).isVolatile()) + && (this.isConst() == ((FunctionInfo)otherInfo).isConst()) ); } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/FunctionTemplate.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/FunctionTemplate.java index 17da161474d..cf72a900a86 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/FunctionTemplate.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/FunctionTemplate.java @@ -17,12 +17,11 @@ import org.eclipse.cdt.core.model.ITemplate; public class FunctionTemplate extends FunctionDeclaration implements ITemplate{ - protected static final String[] fgEmptyList= new String[] {}; protected String[] templateParameterTypes; public FunctionTemplate(ICElement parent, String name) { super(parent, name, ICElement.C_TEMPLATE_FUNCTION); - templateParameterTypes= fgEmptyList; + templateParameterTypes= fgEmptyStrings; } /** diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/MethodInfo.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/MethodInfo.java index bf3f5efadd4..19bfcaa10c6 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/MethodInfo.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/MethodInfo.java @@ -19,7 +19,6 @@ public class MethodInfo extends FunctionInfo { boolean isInline = false; boolean isVirtual = false; boolean isFriend = false; - boolean isConst = false; ASTAccessVisibility visibility = null; MethodInfo(CElement element) { @@ -58,14 +57,6 @@ public class MethodInfo extends FunctionInfo { public void setFriend(boolean isFriend){ this.isFriend = isFriend; } - - public boolean isConst(){ - return isConst; - } - - public void setConst(boolean isConst){ - this.isConst = isConst; - } /** * Returns the visibility. @@ -88,7 +79,6 @@ public class MethodInfo extends FunctionInfo { */ public boolean hasSameContentsAs(SourceManipulationInfo otherInfo) { return (super.hasSameContentsAs(otherInfo) - && (isConst == ((MethodInfo)otherInfo).isConst()) && (isPureVirtual == ((MethodInfo)otherInfo).isPureVirtual()) && (isInline == ((MethodInfo)otherInfo).isInline()) && (isVirtual == ((MethodInfo)otherInfo).isVirtual()) diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/SourceManipulation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/SourceManipulation.java index bd96ed0d40e..ec708c0ef10 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/SourceManipulation.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/SourceManipulation.java @@ -23,6 +23,11 @@ import org.eclipse.core.runtime.IProgressMonitor; public class SourceManipulation extends Parent implements ISourceManipulation, ISourceReference { + /** + * An empty list of Strings + */ + protected static final String[] fgEmptyStrings = {}; + public SourceManipulation(ICElement parent, String name, int type) { super(parent, name, type); } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/SourceManipulationInfo.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/SourceManipulationInfo.java index fd561a58881..9c5232e1960 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/SourceManipulationInfo.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/SourceManipulationInfo.java @@ -5,15 +5,12 @@ package org.eclipse.cdt.internal.core.model; * All Rights Reserved. */ -import java.io.IOException; 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.ISourceRange; import org.eclipse.cdt.core.model.ITranslationUnit; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IProgressMonitor; /** @@ -43,23 +40,39 @@ class SourceManipulationInfo extends CElementInfo { * @see ISourceReference */ public String getSource() throws CModelException { - ITranslationUnit tu = getTranslationUnit(); - if (tu != null) { - try { - IResource res = tu.getResource(); - if (res != null && res instanceof IFile) { - StringBuffer buffer = Util.getContent((IFile)res); - return buffer.substring(getElement().getStartPos(), - getElement().getStartPos() + getElement().getLength()); - } - } catch (IOException e) { - throw new CModelException(e, ICModelStatusConstants.IO_EXCEPTION); - } catch (StringIndexOutOfBoundsException bound) { - // This is not good we screwed up the offset some how - throw new CModelException(bound, ICModelStatusConstants.INDEX_OUT_OF_BOUNDS); - } + ITranslationUnit unit = getTranslationUnit(); + IBuffer buffer = unit.getBuffer(); + if (buffer == null) { + return null; } - return ""; //$NON-NLS-1$ + int offset = getElement().getStartPos(); + int length = getElement().getLength(); + if (offset == -1 || length == 0 ) { + return null; + } + try { + return buffer.getText(offset, length); + } catch(RuntimeException e) { + return null; + } + +// ITranslationUnit tu = getTranslationUnit(); +// if (tu != null) { +// try { +// IResource res = tu.getResource(); +// if (res != null && res instanceof IFile) { +// StringBuffer buffer = Util.getContent((IFile)res); +// return buffer.substring(getElement().getStartPos(), +// getElement().getStartPos() + getElement().getLength()); +// } +// } catch (IOException e) { +// throw new CModelException(e, ICModelStatusConstants.IO_EXCEPTION); +// } catch (StringIndexOutOfBoundsException bound) { +// // This is not good we screwed up the offset some how +// throw new CModelException(bound, ICModelStatusConstants.INDEX_OUT_OF_BOUNDS); +// } +// } +// return ""; //$NON-NLS-1$ } /** diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Structure.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Structure.java index d08f79cf701..dd7614d38ae 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Structure.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Structure.java @@ -17,7 +17,7 @@ import org.eclipse.cdt.core.model.IMethodDeclaration; import org.eclipse.cdt.core.model.IStructure; import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; -public class Structure extends SourceManipulation implements IStructure { +public class Structure extends StructureDeclaration implements IStructure { Map superClassesNames = new TreeMap(); @@ -66,18 +66,6 @@ public class Structure extends SourceManipulation implements IStructure { return null; } - public boolean isUnion() throws CModelException { - return getStructureInfo().isUnion(); - } - - public boolean isClass() throws CModelException { - return getStructureInfo().isClass(); - } - - public boolean isStruct() throws CModelException { - return getStructureInfo().isStruct(); - } - public boolean isAbstract() throws CModelException { IMethodDeclaration[] methods = getMethods(); for(int i=0; i= 0) { + line = new char[lineLength]; + System.arraycopy(text, lineStart, line, 0, lineLength); + result.append(line); + result.append(lineSeparator); + if (nextChar == '\n') { + nextChar = ' '; + lineStart = i+2; + } else { + // when line separator are mixed in the same file + // \r might not be followed by a \n. If not, we should increment + // lineStart by one and not by two. + lineStart = i+1; + } + } else { + // when line separator are mixed in the same file + // we need to prevent NegativeArraySizeException + lineStart = i+1; + } + break; + } + } + char[] lastLine; + if (lineStart > 0) { + int lastLineLength = length-lineStart; + if (lastLineLength > 0) { + lastLine = new char[lastLineLength]; + System.arraycopy(text, lineStart, lastLine, 0, lastLineLength); + result.append(lastLine); + } + return result.getContents(); + } + return text; + } + + /** + * Normalizes the cariage returns in the given text. + * They are all changed to use given buffer's line sepatator. + */ + public static String normalizeCRs(String text, String buffer) { + return new String(normalizeCRs(text.toCharArray(), buffer.toCharArray())); + } + + /** + * Returns the line separator used by the given buffer. + * Uses the given text if none found. + * + * @return "\n" or "\r" or "\r\n" + */ + private static String getLineSeparator(char[] text, char[] buffer) { + // search in this buffer's contents first + String lineSeparator = findLineSeparator(buffer); + if (lineSeparator == null) { + // search in the given text + lineSeparator = findLineSeparator(text); + if (lineSeparator == null) { + // default to system line separator + return LINE_SEPARATOR; + } + } + return lineSeparator; + } + + /** + * Finds the first line separator used by the given text. + * + * @return "\n" or "\r" or "\r\n", + * or null if none found + */ + public static String findLineSeparator(char[] text) { + // find the first line separator + int length = text.length; + if (length > 0) { + char nextChar = text[0]; + for (int i = 0; i < length; i++) { + char currentChar = nextChar; + nextChar = i < length-1 ? text[i+1] : ' '; + switch (currentChar) { + case '\n': return "\n"; //$NON-NLS-1$ + case '\r': return nextChar == '\n' ? "\r\n" : "\r"; //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } + // not found + return null; + } + + } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/util/CharArrayBuffer.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/util/CharArrayBuffer.java new file mode 100644 index 00000000000..e4713dd1375 --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/util/CharArrayBuffer.java @@ -0,0 +1,225 @@ +/********************************************************************** + * 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.util; + +/** + * The CharArrayBuffer is intended as a lightweight partial + * implementation of the StringBuffer class, but using char[]'s + * instead of Strings. + * + *

+ * The CharArrayBuffer maintains a list of char[]'s + * which don't get appended until the user asks for them. The following code + * illustrates how to use the class. + * + * + * CharArrayBuffer buffer = new CharArrayBuffer(myCharArray); + * buffer.append(moreBytes, 0, someLength); + * myCharArray = buffer.getContents(); + * + * + *

+ * NOTE: This class is not Thread safe! + */ +public class CharArrayBuffer { + /** + * This is the buffer of char arrays which must be appended together during + * the getContents method. + */ + protected char[][] fBuffer; + + /** + * The default buffer size. + */ + public static final int DEFAULT_BUFFER_SIZE = 10; + + /** + * The end of the buffer + */ + protected int fEnd; + + /** + * The current size of the buffer. + */ + protected int fSize; + + /** + * A buffer of ranges which is maintained along with the buffer. Ranges are + * of the form {start, length}. Enables append(char[] array, int start, int + * end). + */ + protected int[][] fRanges; + + /** + * Creates a CharArrayBuffer with the default buffer size + * (10). + */ + public CharArrayBuffer() { + this(null, DEFAULT_BUFFER_SIZE); + } + + /** + * Creates a CharArrayBuffer with the default buffer size, + * and sets the first element in the buffer to be the given char[]. + * + * @param first - + * the first element to be placed in the buffer, ignored if null + */ + public CharArrayBuffer(char[] first) { + this(first, DEFAULT_BUFFER_SIZE); + } + + /** + * Creates a CharArrayBuffer with the given buffer size, and + * sets the first element in the buffer to be the given char array. + * + * @param first - + * the first element of the buffer, ignored if null. + * @param size - + * the buffer size, if less than 1, set to the + * DEFAULT_BUFFER_SIZE. + */ + public CharArrayBuffer(char[] first, int size) { + fSize = (size > 0) ? size : DEFAULT_BUFFER_SIZE; + fBuffer = new char[fSize][]; + fRanges = new int[fSize][]; + fEnd = 0; + if (first != null) + append(first, 0, first.length); + } + + /** + * Creates a CharArrayBuffer with the given buffer size. + * + * @param size - + * the size of the buffer. + */ + public CharArrayBuffer(int size) { + this(null, size); + } + + /** + * Appends the entire given char array. Given for convenience. + * + * @param src - + * a char array which is appended to the end of the buffer. + */ + public CharArrayBuffer append(char[] src) { + if (src != null) + append(src, 0, src.length); + return this; + } + + /** + * Appends a sub array of the given array to the buffer. + * + * @param src - + * the next array of characters to be appended to the buffer, + * ignored if null + * @param start - + * the start index in the src array. + * @param length - + * the number of characters from start to be appended + * + * @throws ArrayIndexOutOfBoundsException - + * if arguments specify an array index out of bounds. + */ + public CharArrayBuffer append(char[] src, int start, int length) { + if (start < 0) + throw new ArrayIndexOutOfBoundsException(); + if (length < 0) + throw new ArrayIndexOutOfBoundsException(); + if (src != null) { + int srcLength = src.length; + if (start > srcLength) + throw new ArrayIndexOutOfBoundsException(); + if (length + start > srcLength) + throw new ArrayIndexOutOfBoundsException(); + /** do length check here to allow exceptions to be thrown */ + if (length > 0) { + if (fEnd == fSize) { + int size2 = fSize * 2; + System.arraycopy(fBuffer, 0, (fBuffer = new char[size2][]), + 0, fSize); + System.arraycopy(fRanges, 0, (fRanges = new int[size2][]), + 0, fSize); + fSize *= 2; + } + fBuffer[fEnd] = src; + fRanges[fEnd] = new int[] { start, length }; + fEnd++; + } + } + return this; + } + + /** + * Appends the given char. Given for convenience. + * + * @param c - + * a char which is appended to the end of the buffer. + */ + public CharArrayBuffer append(char c) { + append(new char[] { c }, 0, 1); + return this; + } + + /** + * Appends the given String to the buffer. Given for convenience, use + * #append(char[]) if possible + * + * @param src - + * a char array which is appended to the end of the buffer. + */ + public CharArrayBuffer append(String src) { + if (src != null) + append(src.toCharArray(), 0, src.length()); + return this; + } + + /** + * Returns the entire contents of the buffer as one char[] or null if + * nothing has been put in the buffer. + */ + public char[] getContents() { + if (fEnd == 0) + return null; + + // determine the size of the array + int size = 0; + for (int i = 0; i < fEnd; i++) + size += fRanges[i][1]; + + if (size > 0) { + char[] result = new char[size]; + int current = 0; + // copy the results + for (int i = 0; i < fEnd; i++) { + int[] range = fRanges[i]; + int length = range[1]; + System.arraycopy(fBuffer[i], range[0], result, current, length); + current += length; + } + return result; + } + return null; + } + + /** + * Returns the contents of the buffer as a String, or null if + * the buffer is empty. + */ + public String toString() { + char[] contents = getContents(); + return (contents != null) ? new String(contents) : null; + } +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CConventions.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CConventions.java index e622cfe0ae1..fa15650b936 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CConventions.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CConventions.java @@ -26,6 +26,7 @@ import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.model.CModelStatus; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; /** @@ -35,7 +36,7 @@ public class CConventions { private final static String scopeResolutionOperator= "::"; //$NON-NLS-1$ private final static char fgDot= '.'; - private final static String ILLEGAL_FILE_CHARS = "/\\:<>?*|\""; + private final static String ILLEGAL_FILE_CHARS = "/\\:<>?*|\""; //$NON-NLS-1$ private static boolean isLegalIdentifier(String name) { if (name == null) { @@ -290,6 +291,34 @@ public class CConventions { return validateIdentifier(name); } + /** + * Validate the given include name. + *

+ * The name of an include without the surroounding double quotes or brakets + * For example, stdio.h or iostream. + * + * @param name the include declaration + * @return a status object with code IStatus.OK if + * the given name is valid as an include name, otherwise a status + * object indicating what is wrong with the name + */ + + public static IStatus validateIncludeName(IProject project, String name) { + String[] segments = new Path(name).segments(); + for (int i = 0; i < segments.length; ++i) { + IStatus status; + if (i == (segments.length - 1)) { + status = validateHeaderFileName(project, segments[i]); + } else { + status = validateFileName(segments[i]); + } + if (!status.isOK()) { + return status; + } + } + return CModelStatus.VERIFIED_OK; + } + public static boolean isValidIdentifier(String name){ // create a scanner and get the type of the token // assuming that you are given a valid identifier