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

Fix for 195641: CStructureCreator should be migrated to DOM parser

This commit is contained in:
Anton Leherbauer 2007-10-11 09:41:48 +00:00
parent 8c172d53d7
commit 35a31af9c6
10 changed files with 1092 additions and 148 deletions

View file

@ -73,7 +73,6 @@ import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.IContributedModelBuilder; import org.eclipse.cdt.core.model.IContributedModelBuilder;
import org.eclipse.cdt.core.model.IParent;
import org.eclipse.cdt.core.model.IProblemRequestor; import org.eclipse.cdt.core.model.IProblemRequestor;
import org.eclipse.cdt.core.model.IStructure; import org.eclipse.cdt.core.model.IStructure;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
@ -515,18 +514,6 @@ public class CModelBuilder2 implements IContributedModelBuilder {
elements= new CElement[1]; elements= new CElement[1];
final CElement element= createSimpleDeclaration(parent, declSpecifier, null, isTemplate); final CElement element= createSimpleDeclaration(parent, declSpecifier, null, isTemplate);
elements[0]= element; elements[0]= element;
} else if (declarators.length == 1 && isCompositeType) {
elements= new CElement[declarators.length];
final IASTDeclarator declarator= declarators[0];
CElement element= createTypedefOrFunctionOrVariable(parent, declSpecifier, declarator, isTemplate);
if (element instanceof IParent) {
parent= (Parent)element;
if (!isTemplate) {
setBodyPosition((SourceManipulation)element, declSpecifier.getParent());
}
}
elements[0]= element;
createSimpleDeclaration(parent, declSpecifier, null, isTemplate);
} else { } else {
if (isCompositeType) { if (isCompositeType) {
createSimpleDeclaration(parent, declSpecifier, null, isTemplate); createSimpleDeclaration(parent, declSpecifier, null, isTemplate);
@ -535,7 +522,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
for (int i= 0; i < declarators.length; i++) { for (int i= 0; i < declarators.length; i++) {
final IASTDeclarator declarator= declarators[i]; final IASTDeclarator declarator= declarators[i];
final CElement element= createSimpleDeclaration(parent, declSpecifier, declarator, isTemplate); final CElement element= createSimpleDeclaration(parent, declSpecifier, declarator, isTemplate);
if (!isTemplate && element instanceof SourceManipulation) { if (!isTemplate && element instanceof SourceManipulation && declarators.length > 1) {
setBodyPosition((SourceManipulation)element, declarator); setBodyPosition((SourceManipulation)element, declarator);
} }
elements[i]= element; elements[i]= element;
@ -800,17 +787,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
} else { } else {
final IASTFileLocation classLocation= getMinFileLocation(compositeTypeSpecifier.getNodeLocations()); final IASTFileLocation classLocation= getMinFileLocation(compositeTypeSpecifier.getNodeLocations());
if (classLocation != null) { if (classLocation != null) {
if (compositeTypeSpecifier.getStorageClass() == IASTDeclSpecifier.sc_typedef) { element.setIdPos(classLocation.getNodeOffset(), type.length());
// fix positions for typedef struct (heuristically)
final int delta= Keywords.TYPEDEF.length() + 1;
element.setIdPos(classLocation.getNodeOffset() + delta, type.length());
if(!isTemplate){
final SourceManipulationInfo info= element.getSourceManipulationInfo();
info.setPos(info.getStartPos() + delta, info.getLength() - delta);
}
} else {
element.setIdPos(classLocation.getNodeOffset(), type.length());
}
} }
} }
// add members // add members
@ -1146,7 +1123,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
// hook up the offsets // hook up the offsets
setIdentifierPosition(info, name); setIdentifierPosition(info, name);
if (!isTemplate) { if (!isTemplate) {
setBodyPosition(info, declarator); setBodyPosition(info, declarator.getParent());
} }
return element; return element;
} }

View file

@ -0,0 +1,155 @@
// include
#include "included.h"
// macro
#define PRINT(string,msg) printf(string, msg)
//namespace
namespace MyPackage
{
// check class
// class
class Hello
{
// protected visibility
protected:
// field
int x;
// method
inline void setX(int X)
{
x = X;
};
// check nested pachage
// nested namespace
namespace MyNestedPackage {
// check parent nested class
// nested class
class Y
{ // public visibility
public:
// constructor
Y();
// virtual destructor
virtual ~Y();
};
// check derived nested class
// derived class
class X : public Y {
// private visibility
private:
// private field
B b;
public:
// constructor chain
X(int x) : Y(x) {
cout << "In consturctor\n";
}
// method declaration
int doNothing();
};
}
};
// check enums
// enum without name
enum {
first = 1,
second,
third
}
;
// enum with name
enum MyEnum {
f,
s,
t };
// check variables
// variable
int v;
// unsigned long variable
unsigned long vuLong;
// unsigned short variable
unsigned short vuShort;
// check variable declarations
// variable declaration
extern int evar;
// function pointer
static void * (*orig_malloc_hook)(const char *file, int line, size_t size);
// check functions
// simple function declaration
void foo();
// function declaration with parameters
char* foo(int& x,
char**y);
// simple function definition
void boo(){
int g = 0;
};
// check Structs
// struct
struct MyStruct{
int sint;
};
// typedef and elaborated types
typedef struct MyStruct myStruct;
// typedef
typedef struct{
int ss;
} myTypedef;
// unions
union U{
int U1;
};
// check templates
// template function declaration
template<class A, typename B=C>
A aTemplatedFunction( B bInstance );
// template function definition
template<class A, typename B=C>
A aTemplatedFunction( B bInstance ) {
A a;
return a;
}
// template method
class enclosing {
// public visibility
public:
template<class A, typename B=C>
A aTemplatedMethod( B bInstance );
};
// template class
template<class T, typename Tibor = junk>
class myarray { /* */ };
// template struct
template<class T, typename Tibor = junk>
struct mystruct { /* */ };
// template variable
template <bool __threads, int __inst>
char* default_alloc_template<__threads, __inst>::_S_start_free = 0;
};
// check arrays
// arrays
int myArray [5][];
int main(int argc, char * argv[])
{
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=180815
struct bug180815 {
int i,j;
} bug180815_var0, bug180815_var1;
// using
using Mypackage;
// linkage spec
extern "C" {
void cfunction() {}
}

View file

@ -0,0 +1,267 @@
/*******************************************************************************
* Copyright (c) 2007 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.ui.tests.text;
import junit.framework.TestSuite;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.ResourceNode;
import org.eclipse.compare.structuremergeviewer.DocumentRangeNode;
import org.eclipse.compare.structuremergeviewer.IStructureComparator;
import org.eclipse.core.resources.IFile;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IParent;
import org.eclipse.cdt.core.model.ISourceRange;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.ui.tests.BaseUITestCase;
import org.eclipse.cdt.internal.ui.compare.CStructureCreator;
/**
* Tests for the CStructureCreator.
*
* @since 5.0
*/
public class CStructureCreatorTest extends BaseUITestCase {
public static TestSuite suite() {
return suite(CStructureCreatorTest.class, "_");
}
private ICProject fCProject;
protected void setUp() throws Exception {
super.setUp();
fCProject= EditorTestHelper.createCProject("CStructureCreatorTest", "resources/compare", false);
}
protected void tearDown() throws Exception {
if (fCProject != null) {
CProjectHelper.delete(fCProject);
}
super.tearDown();
}
public void testStructureCreatorNodeTypes() throws Exception {
IFile file= ResourceTestHelper.findFile("/CStructureCreatorTest/src/CompareTest.cpp");
assertNotNull(file);
CStructureCreator creator= new CStructureCreator();
IStructureComparator node= creator.getStructure(new ResourceNode(file));
assertNotNull(node);
Object[] children= node.getChildren();
// one node below root == translation unit
assertEquals(1, children.length);
DocumentRangeNode tuNode= (DocumentRangeNode)children[0];
// tu children
children= tuNode.getChildren();
assertEquals(10, children.length);
DocumentRangeNode child= (DocumentRangeNode)children[0];
assertEquals(ICElement.C_INCLUDE, child.getTypeCode());
child= (DocumentRangeNode)children[1];
assertEquals(ICElement.C_MACRO, child.getTypeCode());
DocumentRangeNode namespace= (DocumentRangeNode)children[2];
assertEquals(ICElement.C_NAMESPACE, namespace.getTypeCode());
child= (DocumentRangeNode)children[3];
assertEquals(ICElement.C_VARIABLE, child.getTypeCode());
child= (DocumentRangeNode)children[4];
assertEquals(ICElement.C_FUNCTION, child.getTypeCode());
DocumentRangeNode struct= (DocumentRangeNode)children[5];
assertEquals(ICElement.C_STRUCT, struct.getTypeCode());
child= (DocumentRangeNode)children[6];
assertEquals(ICElement.C_VARIABLE, child.getTypeCode());
child= (DocumentRangeNode)children[7];
assertEquals(ICElement.C_VARIABLE, child.getTypeCode());
child= (DocumentRangeNode)children[8];
assertEquals(ICElement.C_USING, child.getTypeCode());
DocumentRangeNode linkageSpec= (DocumentRangeNode)children[9];
assertEquals(ICElement.C_STORAGE_EXTERN, linkageSpec.getTypeCode());
// namespace children
children= namespace.getChildren();
assertEquals(22, children.length);
DocumentRangeNode clazz= (DocumentRangeNode)children[0];
assertEquals(ICElement.C_CLASS, clazz.getTypeCode());
DocumentRangeNode enum1= (DocumentRangeNode)children[1];
assertEquals(ICElement.C_ENUMERATION, enum1.getTypeCode());
child= (DocumentRangeNode)children[2];
assertEquals(ICElement.C_ENUMERATION, child.getTypeCode());
child= (DocumentRangeNode)children[3];
assertEquals(ICElement.C_VARIABLE, child.getTypeCode());
child= (DocumentRangeNode)children[4];
assertEquals(ICElement.C_VARIABLE, child.getTypeCode());
child= (DocumentRangeNode)children[5];
assertEquals(ICElement.C_VARIABLE, child.getTypeCode());
child= (DocumentRangeNode)children[6];
assertEquals(ICElement.C_VARIABLE_DECLARATION, child.getTypeCode());
child= (DocumentRangeNode)children[7];
assertEquals(ICElement.C_VARIABLE, child.getTypeCode());
child= (DocumentRangeNode)children[8];
assertEquals(ICElement.C_FUNCTION_DECLARATION, child.getTypeCode());
child= (DocumentRangeNode)children[9];
assertEquals(ICElement.C_FUNCTION_DECLARATION, child.getTypeCode());
child= (DocumentRangeNode)children[10];
assertEquals(ICElement.C_FUNCTION, child.getTypeCode());
child= (DocumentRangeNode)children[11];
assertEquals(ICElement.C_STRUCT, child.getTypeCode());
child= (DocumentRangeNode)children[12];
assertEquals(ICElement.C_TYPEDEF, child.getTypeCode());
child= (DocumentRangeNode)children[13];
assertEquals(ICElement.C_STRUCT, child.getTypeCode());
child= (DocumentRangeNode)children[14];
assertEquals(ICElement.C_TYPEDEF, child.getTypeCode());
DocumentRangeNode union= (DocumentRangeNode)children[15];
assertEquals(ICElement.C_UNION, union.getTypeCode());
child= (DocumentRangeNode)children[16];
assertEquals(ICElement.C_TEMPLATE_FUNCTION_DECLARATION, child.getTypeCode());
child= (DocumentRangeNode)children[17];
assertEquals(ICElement.C_TEMPLATE_FUNCTION, child.getTypeCode());
DocumentRangeNode clazz2= (DocumentRangeNode)children[18];
assertEquals(ICElement.C_CLASS, clazz2.getTypeCode());
child= (DocumentRangeNode)children[19];
assertEquals(ICElement.C_TEMPLATE_CLASS, child.getTypeCode());
child= (DocumentRangeNode)children[20];
assertEquals(ICElement.C_TEMPLATE_STRUCT, child.getTypeCode());
child= (DocumentRangeNode)children[21];
assertEquals(ICElement.C_TEMPLATE_VARIABLE, child.getTypeCode());
// class children
children= clazz.getChildren();
assertEquals(3, children.length);
child= (DocumentRangeNode)children[0];
assertEquals(ICElement.C_FIELD, child.getTypeCode());
child= (DocumentRangeNode)children[1];
assertEquals(ICElement.C_METHOD, child.getTypeCode());
namespace= (DocumentRangeNode)children[2];
assertEquals(ICElement.C_NAMESPACE, namespace.getTypeCode());
// enum children
children= enum1.getChildren();
assertEquals(3, children.length);
child= (DocumentRangeNode)children[0];
assertEquals(ICElement.C_ENUMERATOR, child.getTypeCode());
child= (DocumentRangeNode)children[1];
assertEquals(ICElement.C_ENUMERATOR, child.getTypeCode());
child= (DocumentRangeNode)children[2];
assertEquals(ICElement.C_ENUMERATOR, child.getTypeCode());
// union children
children= union.getChildren();
assertEquals(1, children.length);
child= (DocumentRangeNode)children[0];
assertEquals(ICElement.C_FIELD, child.getTypeCode());
// enclosing class children
children= clazz2.getChildren();
assertEquals(1, children.length);
child= (DocumentRangeNode)children[0];
assertEquals(ICElement.C_TEMPLATE_METHOD_DECLARATION, child.getTypeCode());
// nested namespace children
children= namespace.getChildren();
assertEquals(2, children.length);
child= (DocumentRangeNode)children[0];
assertEquals(ICElement.C_CLASS, child.getTypeCode());
clazz= (DocumentRangeNode)children[1];
assertEquals(ICElement.C_CLASS, child.getTypeCode());
// nested class children
children= clazz.getChildren();
assertEquals(3, children.length);
child= (DocumentRangeNode)children[0];
assertEquals(ICElement.C_FIELD, child.getTypeCode());
child= (DocumentRangeNode)children[1];
assertEquals(ICElement.C_METHOD, child.getTypeCode());
child= (DocumentRangeNode)children[2];
assertEquals(ICElement.C_METHOD_DECLARATION, child.getTypeCode());
// extern "C" children
children= linkageSpec.getChildren();
assertEquals(1, children.length);
child= (DocumentRangeNode)children[0];
assertEquals(ICElement.C_FUNCTION, child.getTypeCode());
}
public void testStructureCreatorNodeSizes() throws Exception {
IFile file= ResourceTestHelper.findFile("/CStructureCreatorTest/src/CompareTest.cpp");
assertNotNull(file);
CStructureCreator creator= new CStructureCreator();
IStructureComparator node= creator.getStructure(new ResourceNode(file));
assertNotNull(node);
Object[] children= node.getChildren();
// one node below root == translation unit
assertEquals(1, children.length);
DocumentRangeNode tuNode= (DocumentRangeNode)children[0];
IDocument document= tuNode.getDocument();
Position range= tuNode.getRange();
assertEqualPositions(new Position(0, document.getLength()), range);
verifyStructure(tuNode, CoreModel.getDefault().create(file));
}
private void assertEqualPositions(Position expected, Position actual) {
assertEquals(expected.getOffset(), actual.getOffset());
assertEquals(expected.getLength(), actual.getLength());
}
private void verifyStructure(DocumentRangeNode cNode, ICElement cElement) throws CModelException, BadLocationException {
// verify same type
assertEquals(cElement.getElementType(), cNode.getTypeCode());
if (cNode.getTypeCode() != ICElement.C_UNIT && cNode instanceof ITypedElement) {
Position nodeRange= cNode.getRange();
IDocument doc= cNode.getDocument();
ISourceReference sourceRef= (ISourceReference)cElement;
ISourceRange sourceRange= sourceRef.getSourceRange();
// verify start and endline of elements match
assertEquals(sourceRange.getStartLine(), doc.getLineOfOffset(nodeRange.getOffset()) + 1);
assertEquals(sourceRange.getEndLine(), doc.getLineOfOffset(nodeRange.getOffset() + nodeRange.getLength() - 1) + 1);
assertEqualPositions(new Position(sourceRange.getStartPos(), sourceRange.getLength()), nodeRange);
if (cElement.getElementName().length() > 0) {
assertEquals(cElement.getElementName(), ((ITypedElement)cNode).getName());
}
}
Object[] nodeChildren= cNode.getChildren();
// merge in extern "C" children to match cmodel hierarchy
for (int i = 0; i < nodeChildren.length; i++) {
DocumentRangeNode childNode= (DocumentRangeNode)nodeChildren[i];
if (childNode.getTypeCode() == ICElement.C_STORAGE_EXTERN) {
Object[] linkageSpecChildren= childNode.getChildren();
Object[] newArray= new Object[nodeChildren.length - 1 + linkageSpecChildren.length];
System.arraycopy(nodeChildren, 0, newArray, 0, i);
System.arraycopy(linkageSpecChildren, 0, newArray, i, linkageSpecChildren.length);
System.arraycopy(nodeChildren, i+1, newArray, i + linkageSpecChildren.length, nodeChildren.length - i - 1);
nodeChildren= newArray;
}
}
ICElement[] cElementChildren;
if (cElement instanceof IParent) {
cElementChildren= ((IParent)cElement).getChildren();
} else {
cElementChildren= new ICElement[0];
}
// verify same number of children
assertEquals(cElementChildren.length, nodeChildren.length);
for (int i = 0; i < cElementChildren.length; i++) {
verifyStructure((DocumentRangeNode)nodeChildren[i], cElementChildren[i]);
}
}
}

View file

@ -57,5 +57,8 @@ public class TextTestSuite extends TestSuite {
// word detection // word detection
addTest(CWordFinderTest.suite()); addTest(CWordFinderTest.suite());
// compare tests
addTest(CStructureCreatorTest.suite());
} }
} }

View file

@ -60,25 +60,6 @@ AbstractErrorParserBlock.label.errorParsers=Error Parsers
ICElementPropertyConstants.catagory=Binary Info ICElementPropertyConstants.catagory=Binary Info
IndexerOptions.enableIndexing = Enable C/C++ &Indexing
IndexerOptions.problemReporting = C/C++ Index problem reporting
IndexerOptions.enablePreprocessor = Report &preprocessor problems
IndexerOptions.enableSemantic = Report &semantic problems
IndexerOptions.enableSyntactic = Report s&yntactic problems
IndexerOptiosn.task.savingAttributes = Saving Attributes
CTagsIndexerBlock.blockName=CTags File
CTagsIndexerBlock.radioButtonInternal=Use internal CTags file (default)
CTagsIndexerBlock.radioButtonExternal=Import existing CTags file
CTagsIndexerBlock.browseButton=Browse...
CTagsIndexerBlock.fileBrowser=Select CTags File
CTagsIndexerBlock.radioButtonCTagsDefault=Use the CTags on the path (default)
CTagsIndexerBlock.radioButtonCTagsSpecified=Use the specified CTags
CTagsIndexerBlock.ctagsLocation=CTags Location
CTagsIndexerBlock.includeGroup=Include Files
CTagsIndexerBlock.indexIncludes=Index include paths
StatusBarUpdater.num_elements_selected={0} items selected StatusBarUpdater.num_elements_selected={0} items selected
CHelpConfigurationPropertyPage.buttonLabels.CheckAll=Check All CHelpConfigurationPropertyPage.buttonLabels.CheckAll=Check All
@ -93,3 +74,4 @@ TextEditorDropAdapter.unreadableFile=Unreadable file: ''{0}''
TextEditorDropAdapter.noFile=Not a file: ''{0}'' TextEditorDropAdapter.noFile=Not a file: ''{0}''
OptionalMessageDialog_dontShowAgain= Do not show this &message again OptionalMessageDialog_dontShowAgain= Do not show this &message again
CStructureCreatorVisitor.translationUnitName=Translation Unit

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2006 IBM Corporation and others. * Copyright (c) 2005, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * IBM Corporation - initial API and implementation
* QNX Software System * QNX Software System
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.compare; package org.eclipse.cdt.internal.ui.compare;
@ -18,20 +19,20 @@ import org.eclipse.compare.structuremergeviewer.DocumentRangeNode;
import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Image;
/** /**
* *
*/ */
class CNode extends DocumentRangeNode implements ITypedElement { class CNode extends DocumentRangeNode implements ITypedElement {
public CNode(CNode parent, int type, String id, IDocument doc, int start, int length) { public CNode(DocumentRangeNode parent, int type, String id, IDocument doc, int start, int length) {
super(type, id, doc, start, length); super(parent, type, id, doc, start, length);
if (parent != null) { if (parent != null) {
parent.addChild(this); parent.addChild(this);
} }
} }
public CNode(CNode parent, int type, String id, int start, int length) { public CNode(DocumentRangeNode parent, int type, String id, int start, int length) {
this(parent, type, id, parent.getDocument(), start, length); this(parent, type, id, parent.getDocument(), start, length);
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005 IBM Corporation and others. * Copyright (c) 2005, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * IBM Corporation - initial API and implementation
* QNX Software System * QNX Software System
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.compare; package org.eclipse.cdt.internal.ui.compare;
@ -36,7 +37,7 @@ import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocument;
/** /**
* * @deprecated As of CDT 5.0. This class is not used anymore. Kept for reference only.
*/ */
public class CParseTreeBuilder extends SourceElementRequestorAdapter { public class CParseTreeBuilder extends SourceElementRequestorAdapter {
@ -295,7 +296,7 @@ public class CParseTreeBuilder extends SourceElementRequestorAdapter {
} }
/** /**
* Adds a new JavaNode with the given type and name to the current container. * Adds a new CNode with the given type and name to the current container.
*/ */
private void push(int type, String name, int declarationStart) { private void push(int type, String name, int declarationStart) {
fStack.push(new CNode(getCurrentContainer(), type, name, declarationStart, 0)); fStack.push(new CNode(getCurrentContainer(), type, name, declarationStart, 0));
@ -307,12 +308,8 @@ public class CParseTreeBuilder extends SourceElementRequestorAdapter {
*/ */
private void pop(int declarationEnd) { private void pop(int declarationEnd) {
CNode current = getCurrentContainer(); CNode current = getCurrentContainer();
if (current.getTypeCode() == ICElement.C_UNIT) { current.setAppendPosition(declarationEnd);
current.setAppendPosition(declarationEnd + 1); current.setLength(declarationEnd - current.getRange().getOffset());
} else {
current.setAppendPosition(declarationEnd);
}
current.setLength(declarationEnd - current.getRange().getOffset() + 1);
fStack.pop(); fStack.pop();
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2006 IBM Corporation and others. * Copyright (c) 2005, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -17,37 +17,43 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import org.eclipse.compare.CompareUI;
import org.eclipse.compare.IEditableContent;
import org.eclipse.compare.IEncodedStreamContentAccessor; import org.eclipse.compare.IEncodedStreamContentAccessor;
import org.eclipse.compare.ISharedDocumentAdapter;
import org.eclipse.compare.IStreamContentAccessor; import org.eclipse.compare.IStreamContentAccessor;
import org.eclipse.compare.structuremergeviewer.Differencer; import org.eclipse.compare.ResourceNode;
import org.eclipse.compare.structuremergeviewer.IDiffContainer; import org.eclipse.compare.contentmergeviewer.IDocumentRange;
import org.eclipse.compare.structuremergeviewer.DocumentRangeNode;
import org.eclipse.compare.structuremergeviewer.IStructureComparator; import org.eclipse.compare.structuremergeviewer.IStructureComparator;
import org.eclipse.compare.structuremergeviewer.IStructureCreator; import org.eclipse.compare.structuremergeviewer.StructureCreator;
import org.eclipse.compare.structuremergeviewer.StructureRootNode;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.Document; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.Position;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.dom.ICodeReaderFactory;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.IParser; import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.ISourceElementRequestor;
import org.eclipse.cdt.core.parser.NullLogService;
import org.eclipse.cdt.core.parser.ParserFactory;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.core.parser.ParserUtil;
import org.eclipse.cdt.core.parser.ScannerInfo; import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.text.ICPartitions;
import org.eclipse.cdt.internal.core.dom.NullCodeReaderFactory;
import org.eclipse.cdt.internal.ui.editor.CDocumentSetupParticipant;
/** /**
* * A structure creator for C/C++ translation units.
*/ */
public class CStructureCreator implements IStructureCreator { public class CStructureCreator extends StructureCreator {
private static final String NAME = "CStructureCreator.name"; //$NON-NLS-1$ private static final String NAME = "CStructureCreator.name"; //$NON-NLS-1$
@ -58,78 +64,18 @@ public class CStructureCreator implements IStructureCreator {
return CUIPlugin.getResourceString(NAME); return CUIPlugin.getResourceString(NAME);
} }
public IStructureComparator getStructure(Object input) { /*
IDocument doc= CompareUI.getDocument(input);
if (doc == null) {
if (input instanceof IStreamContentAccessor) {
String s = null;
try {
s = readString((IStreamContentAccessor) input);
} catch (CoreException ex) {
}
if (s != null) {
doc = new Document(s);
new CDocumentSetupParticipant().setup(doc);
}
}
}
if (doc == null) {
return null;
}
CNode root = new CNode(null, ICElement.C_UNIT, "root", doc, 0, 0); //$NON-NLS-1$
ISourceElementRequestor builder = new CParseTreeBuilder(root, doc);
try {
//Using the CPP parser (was implicit before, now its explicit). If there
//are bugs while parsing C files, we might want to create a separate Structure
//compare for c files, but we'll never be completely right about .h files
IScanner scanner =
ParserFactory.createScanner(new CodeReader(doc.get().toCharArray()), new ScannerInfo(), ParserMode.QUICK_PARSE, ParserLanguage.CPP, builder, new NullLogService(), null);
IParser parser = ParserFactory.createParser(scanner, builder, ParserMode.QUICK_PARSE, ParserLanguage.CPP, ParserUtil.getParserLogService() );
parser.parse();
} catch (Exception e) {
// What to do when error ?
// The CParseTreeBuilder will throw CParseTreeBuilder.ParseError
// for acceptProblem.
//TODO : New : ParserFactoryError gets thrown by ParserFactory primitives
}
return root;
}
public boolean canSave() {
return true;
}
public IStructureComparator locate(Object path, Object source) {
return null;
}
public boolean canRewriteTree() {
return false;
}
public void rewriteTree(Differencer differencer, IDiffContainer root) {
}
/**
* @see IStructureCreator#save
*/
public void save(IStructureComparator structure, Object input) {
if (input instanceof IEditableContent && structure instanceof CNode) {
IDocument doc = ((CNode) structure).getDocument();
IEditableContent bca = (IEditableContent) input;
String c = doc.get();
bca.setContent(c.getBytes());
}
}
/**
* @see IStructureCreator#getContents * @see IStructureCreator#getContents
*/ */
public String getContents(Object node, boolean ignoreWhitespace) { public String getContents(Object node, boolean ignoreWhitespace) {
if (node instanceof IDocumentRange) {
IDocumentRange documentRange= (IDocumentRange)node;
final Position range = documentRange.getRange();
try {
return documentRange.getDocument().get(range.getOffset(), range.getLength());
} catch (BadLocationException exc) {
}
}
if (node instanceof IStreamContentAccessor) { if (node instanceof IStreamContentAccessor) {
IStreamContentAccessor sca = (IStreamContentAccessor) node; IStreamContentAccessor sca = (IStreamContentAccessor) node;
try { try {
@ -140,6 +86,80 @@ public class CStructureCreator implements IStructureCreator {
return null; return null;
} }
/*
* @see org.eclipse.compare.structuremergeviewer.StructureCreator#createStructureComparator(java.lang.Object, org.eclipse.jface.text.IDocument, org.eclipse.compare.ISharedDocumentAdapter, org.eclipse.core.runtime.IProgressMonitor)
*/
protected IStructureComparator createStructureComparator(Object element,
IDocument document, ISharedDocumentAdapter sharedDocumentAdapter,
IProgressMonitor monitor) throws CoreException {
DocumentRangeNode root= new StructureRootNode(document, element, this, sharedDocumentAdapter);
// don't follow inclusions
ICodeReaderFactory codeReaderFactory= NullCodeReaderFactory.getInstance();
// empty scanner info
IScannerInfo scanInfo= new ScannerInfo();
CodeReader reader= new CodeReader(document.get().toCharArray());
// determine the language
ILanguage language= determineLanguage(element);
try {
IASTTranslationUnit ast;
ast= language.getASTTranslationUnit(reader, scanInfo, codeReaderFactory, null, ParserUtil.getParserLogService());
CStructureCreatorVisitor structureCreator= new CStructureCreatorVisitor(root);
// build structure
ast.accept(structureCreator);
} catch (CoreException exc) {
CUIPlugin.getDefault().log(exc);
}
return root;
}
/**
* Try to determine the <code>ILanguage</code> for the given input element.
*
* @param element
* @return a language instance
*/
private ILanguage determineLanguage(Object element) {
ILanguage language= null;
if (element instanceof ResourceNode) {
IResource resource= ((ResourceNode)element).getResource();
if (resource.getType() == IResource.FILE) {
ITranslationUnit tUnit= (ITranslationUnit)CoreModel.getDefault().create(resource);
if (tUnit != null) {
try {
language= tUnit.getLanguage();
} catch (CoreException exc) {
// silently ignored
}
}
}
}
if (language == null) {
language= GPPLanguage.getDefault();
}
return language;
}
/*
* @see org.eclipse.compare.structuremergeviewer.StructureCreator#getDocumentPartitioning()
*/
protected String getDocumentPartitioning() {
return ICPartitions.C_PARTITIONING;
}
/*
* @see org.eclipse.compare.structuremergeviewer.StructureCreator#getDocumentPartitioner()
*/
protected IDocumentPartitioner getDocumentPartitioner() {
return CUIPlugin.getDefault().getTextTools().createDocumentPartitioner();
}
private static String readString(IStreamContentAccessor sa) throws CoreException { private static String readString(IStreamContentAccessor sa) throws CoreException {
InputStream is= sa.getContents(); InputStream is= sa.getContents();
if (is != null) { if (is != null) {

View file

@ -0,0 +1,542 @@
/*******************************************************************************
* Copyright (c) 2007 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.compare;
import java.util.Stack;
import org.eclipse.compare.structuremergeviewer.DocumentRangeNode;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisiblityLabel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.internal.core.model.ASTStringUtil;
import org.eclipse.cdt.internal.core.model.CoreModelMessages;
import org.eclipse.cdt.internal.ui.CUIMessages;
/**
* AST visitor to create compare structure.
*
* @since 5.0
*/
class CStructureCreatorVisitor extends CPPASTVisitor {
private static final String TRANSLATION_UNIT_NAME = CUIMessages.getString("CStructureCreatorVisitor.translationUnitName"); //$NON-NLS-1$
private static final String ANONYMOUS_NAME= CoreModelMessages.getString("CElementLabels.anonymous"); //$NON-NLS-1$
private Stack fStack = new Stack();
private IDocument fDocument;
private String fTranslationUnitFileName;
/**
* Create visitor adding nodes to given root.
*
* @param root
*/
public CStructureCreatorVisitor(DocumentRangeNode root) {
fDocument = root.getDocument();
fStack.clear();
fStack.push(root);
// visitor options
shouldVisitTranslationUnit= true;
shouldVisitDeclarations= true;
shouldVisitEnumerators=true;
shouldVisitNamespaces=true;
}
/*
* @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTTranslationUnit)
*/
public int visit(IASTTranslationUnit tu) {
fTranslationUnitFileName= tu.getFilePath();
push(ICElement.C_UNIT, TRANSLATION_UNIT_NAME, 0);
// TODO fix ordering of includes and macros
// includes
final IASTPreprocessorIncludeStatement[] includeDirectives= tu.getIncludeDirectives();
for (int i= 0; i < includeDirectives.length; i++) {
IASTPreprocessorIncludeStatement includeDirective= includeDirectives[i];
if (isLocalToFile(includeDirective)) {
push(ICElement.C_INCLUDE, new String(includeDirective.getName().toCharArray()), getStartOffset(includeDirective));
pop(getEndOffset(includeDirective));
}
}
// macros
final IASTPreprocessorMacroDefinition[] macroDefinitions= tu.getMacroDefinitions();
for (int i= 0; i < macroDefinitions.length; i++) {
IASTPreprocessorMacroDefinition macroDefinition= macroDefinitions[i];
if (isLocalToFile(macroDefinition)) {
push(ICElement.C_MACRO, new String(macroDefinition.getName().toCharArray()), getStartOffset(macroDefinition));
pop(getEndOffset(macroDefinition));
}
}
return super.visit(tu);
}
/**
* Test whether given AST node is local to the source file
* and not part of an inclusion.
*
* @param node
* @return <code>true</code> if the node is part of the source file.
*/
private boolean isLocalToFile(IASTNode node) {
return fTranslationUnitFileName.equals(node.getContainingFilename());
}
/**
* Compute the start offset of given AST node.
*
* @param node
* @return
*/
private int getStartOffset(IASTNode node) {
IASTFileLocation fileLocation= getMinFileLocation(node.getNodeLocations());
if (fileLocation != null) {
return fileLocation.getNodeOffset();
}
DocumentRangeNode container= getCurrentContainer();
Object[] children= container.getChildren();
if (children != null && children.length > 0) {
Position prevRange= ((DocumentRangeNode)children[children.length - 1]).getRange();
return prevRange.getOffset() + prevRange.getLength();
}
// fallback: use container range start
Position containerRange= container.getRange();
return containerRange.getOffset();
}
/**
* Compute the end offset of give AST node.
*
* @param node
* @return
*/
private int getEndOffset(IASTNode node) {
IASTFileLocation fileLocation= getMaxFileLocation(node.getNodeLocations());
if (fileLocation != null) {
return fileLocation.getNodeOffset() + fileLocation.getNodeLength();
}
// fallback: use container range end
DocumentRangeNode container= getCurrentContainer();
Position containerRange= container.getRange();
return containerRange.getOffset() + containerRange.getLength();
}
/*
* @see org.eclipse.cdt.core.dom.ast.ASTVisitor#leave(org.eclipse.cdt.core.dom.ast.IASTTranslationUnit)
*/
public int leave(IASTTranslationUnit tu) {
super.leave(tu);
assert getCurrentContainer().getTypeCode() == ICElement.C_UNIT;
pop(fDocument.getLength());
return PROCESS_SKIP;
}
/*
* @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
*/
public int visit(IASTDeclaration node) {
boolean isTemplateDecl= isTemplateDecl(node);
final int startOffset= isTemplateDecl ? getStartOffset(node.getParent()) : getStartOffset(node);
final int endOffset= getEndOffset(node);
if (node instanceof IASTFunctionDefinition) {
IASTFunctionDefinition functionDef= (IASTFunctionDefinition)node;
final int nodeType;
if (inClassBody()) {
nodeType= isTemplateDecl ? ICElement.C_TEMPLATE_METHOD : ICElement.C_METHOD;
} else {
nodeType= isTemplateDecl ? ICElement.C_TEMPLATE_FUNCTION : ICElement.C_FUNCTION;
}
push(nodeType, getDeclaratorName(functionDef.getDeclarator()), startOffset);
pop(endOffset);
return PROCESS_SKIP;
} else if (node instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration simpleDecl= (IASTSimpleDeclaration)node;
IASTDeclSpecifier declSpec= simpleDecl.getDeclSpecifier();
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
ICPPASTCompositeTypeSpecifier compositeTypeSpec= (ICPPASTCompositeTypeSpecifier)declSpec;
final String nodeName= getTypeName(compositeTypeSpec);
final int nodeType;
switch (compositeTypeSpec.getKey()) {
case IASTCompositeTypeSpecifier.k_struct:
nodeType= isTemplateDecl ? ICElement.C_TEMPLATE_STRUCT : ICElement.C_STRUCT;
break;
case IASTCompositeTypeSpecifier.k_union:
nodeType= isTemplateDecl ? ICElement.C_TEMPLATE_UNION : ICElement.C_UNION;
break;
case ICPPASTCompositeTypeSpecifier.k_class:
nodeType= isTemplateDecl ? ICElement.C_TEMPLATE_CLASS : ICElement.C_CLASS;
break;
default:
assert false : "Unexpected composite type specifier"; //$NON-NLS-1$
return PROCESS_CONTINUE;
}
push(nodeType, nodeName, startOffset);
} else if (declSpec instanceof IASTEnumerationSpecifier) {
IASTEnumerationSpecifier enumSpecifier= (IASTEnumerationSpecifier)declSpec;
push(ICElement.C_ENUMERATION, getEnumerationName(enumSpecifier), startOffset);
} else {
IASTDeclarator[] declarators= simpleDecl.getDeclarators();
for (int i = 0; i < declarators.length; i++) {
IASTDeclarator declarator= declarators[i];
int declStartOffset= declarators.length == 1 ? startOffset : getStartOffset(declarator);
int declEndOffset= declarators.length == 1 ? endOffset : getEndOffset(declarator);
final String nodeName = getDeclaratorName(declarator);
if (declSpec.getStorageClass() == IASTDeclSpecifier.sc_typedef) {
push(ICElement.C_TYPEDEF, nodeName, declStartOffset);
pop(declEndOffset);
} else if (declarator instanceof IASTFunctionDeclarator && !hasNestedPointerOperators(declarator)) {
final int nodeType;
if (inClassBody()) {
nodeType= isTemplateDecl ? ICElement.C_TEMPLATE_METHOD_DECLARATION : ICElement.C_METHOD_DECLARATION;
} else {
nodeType= isTemplateDecl ? ICElement.C_TEMPLATE_FUNCTION_DECLARATION : ICElement.C_FUNCTION_DECLARATION;
}
push(nodeType, nodeName, declStartOffset);
pop(declEndOffset);
} else if (declarator != null) {
final int nodeType;
if (inClassBody()) {
nodeType= ICElement.C_FIELD;
} else {
if (declSpec.getStorageClass() == IASTDeclSpecifier.sc_extern) {
nodeType= ICElement.C_VARIABLE_DECLARATION;
} else {
nodeType= isTemplateDecl ? ICElement.C_TEMPLATE_VARIABLE : ICElement.C_VARIABLE;
}
}
push(nodeType, nodeName, declStartOffset);
pop(declEndOffset);
}
}
}
} else if (node instanceof IASTASMDeclaration) {
// ignored
} else if (node instanceof ICPPASTVisiblityLabel) {
// ignored
} else if (node instanceof ICPPASTNamespaceDefinition) {
// handled below
} else if (node instanceof ICPPASTNamespaceAlias) {
// ignored
} else if (node instanceof ICPPASTUsingDeclaration) {
ICPPASTUsingDeclaration usingDecl= (ICPPASTUsingDeclaration)node;
push(ICElement.C_USING, ASTStringUtil.getQualifiedName(usingDecl.getName()), startOffset);
pop(endOffset);
} else if (node instanceof ICPPASTUsingDirective) {
ICPPASTUsingDirective usingDirective= (ICPPASTUsingDirective)node;
push(ICElement.C_USING, ASTStringUtil.getQualifiedName(usingDirective.getQualifiedName()), startOffset);
pop(endOffset);
} else if (node instanceof ICPPASTLinkageSpecification) {
ICPPASTLinkageSpecification linkageSpec= (ICPPASTLinkageSpecification)node;
push(ICElement.C_STORAGE_EXTERN, "extern \"" + linkageSpec.getLiteral() + '"', startOffset); //$NON-NLS-1$
} else if (node instanceof ICPPASTTemplateDeclaration) {
// handled at child declaration level
} else if (node instanceof ICPPASTTemplateSpecialization) {
// ignored
} else if (node instanceof ICPPASTExplicitTemplateInstantiation) {
// ignored
} else if (node instanceof IASTProblemDeclaration) {
// ignored
}
return super.visit(node);
}
/*
* @see org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor#visit(org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition)
*/
public int visit(ICPPASTNamespaceDefinition namespace) {
push(ICElement.C_NAMESPACE, ASTStringUtil.getQualifiedName(namespace.getName()), getStartOffset(namespace));
return super.visit(namespace);
}
/*
* @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator)
*/
public int visit(IASTEnumerator enumerator) {
push(ICElement.C_ENUMERATOR, ASTStringUtil.getQualifiedName(enumerator.getName()), getStartOffset(enumerator));
pop(getEndOffset(enumerator));
return super.visit(enumerator);
}
/*
* @see org.eclipse.cdt.core.dom.ast.ASTVisitor#leave(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
*/
public int leave(IASTDeclaration node) {
super.leave(node);
boolean isTemplateDecl= isTemplateDecl(node);
final int endOffset= isTemplateDecl ? getEndOffset(node.getParent()) : getEndOffset(node);
if (node instanceof IASTFunctionDefinition) {
final int nodeType;
if (inClassBody()) {
nodeType= isTemplateDecl ? ICElement.C_TEMPLATE_METHOD : ICElement.C_METHOD;
} else {
nodeType= isTemplateDecl ? ICElement.C_TEMPLATE_FUNCTION : ICElement.C_FUNCTION;
}
assert getCurrentContainer().getTypeCode() == nodeType;
pop(endOffset);
} else if (node instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration simpleDecl= (IASTSimpleDeclaration)node;
IASTDeclSpecifier declSpec= simpleDecl.getDeclSpecifier();
boolean isCompositeType= false;
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
isCompositeType= true;
ICPPASTCompositeTypeSpecifier compositeTypeSpec= (ICPPASTCompositeTypeSpecifier)declSpec;
final int nodeType;
switch (compositeTypeSpec.getKey()) {
case IASTCompositeTypeSpecifier.k_struct:
nodeType= isTemplateDecl ? ICElement.C_TEMPLATE_STRUCT : ICElement.C_STRUCT;
break;
case IASTCompositeTypeSpecifier.k_union:
nodeType= isTemplateDecl ? ICElement.C_TEMPLATE_UNION : ICElement.C_UNION;
break;
case ICPPASTCompositeTypeSpecifier.k_class:
nodeType= isTemplateDecl ? ICElement.C_TEMPLATE_CLASS : ICElement.C_CLASS;
break;
default:
assert false : "Unexpected composite type specifier"; //$NON-NLS-1$
return PROCESS_CONTINUE;
}
assert getCurrentContainer().getTypeCode() == nodeType;
pop(isTemplateDecl ? endOffset : getEndOffset(declSpec));
} else if (declSpec instanceof IASTEnumerationSpecifier) {
isCompositeType= true;
assert getCurrentContainer().getTypeCode() == ICElement.C_ENUMERATION;
pop(getEndOffset(declSpec));
}
if (isCompositeType) {
IASTDeclarator[] declarators= simpleDecl.getDeclarators();
for (int i= 0; i < declarators.length; i++) {
IASTDeclarator declarator= declarators[i];
final String nodeName= getDeclaratorName(declarator);
final int declStartOffset= getStartOffset(declarator);
final int declEndOffset= getEndOffset(declarator);
if (declSpec.getStorageClass() == IASTDeclSpecifier.sc_typedef) {
push(ICElement.C_TYPEDEF, nodeName, declStartOffset);
pop(declEndOffset);
} else if (declarator instanceof IASTFunctionDeclarator && !hasNestedPointerOperators(declarator)) {
final int nodeType;
if (inClassBody()) {
nodeType= isTemplateDecl ? ICElement.C_TEMPLATE_METHOD_DECLARATION : ICElement.C_METHOD_DECLARATION;
} else {
nodeType= isTemplateDecl ? ICElement.C_TEMPLATE_FUNCTION_DECLARATION : ICElement.C_FUNCTION_DECLARATION;
}
push(nodeType, nodeName, declStartOffset);
pop(declEndOffset);
} else if (declarator != null) {
final int nodeType;
if (inClassBody()) {
nodeType= ICElement.C_FIELD;
} else {
if (declSpec.getStorageClass() == IASTDeclSpecifier.sc_extern) {
nodeType= ICElement.C_VARIABLE_DECLARATION;
} else {
nodeType= isTemplateDecl ? ICElement.C_TEMPLATE_VARIABLE : ICElement.C_VARIABLE;
}
}
push(nodeType, nodeName, declStartOffset);
pop(declEndOffset);
}
}
}
} else if (node instanceof IASTASMDeclaration) {
// ignored
} else if (node instanceof ICPPASTVisiblityLabel) {
// ignored
} else if (node instanceof ICPPASTNamespaceDefinition) {
// handled below
} else if (node instanceof ICPPASTNamespaceAlias) {
// ignored
} else if (node instanceof ICPPASTUsingDeclaration) {
// handled in visit
} else if (node instanceof ICPPASTUsingDirective) {
// handled in visit
} else if (node instanceof ICPPASTLinkageSpecification) {
assert getCurrentContainer().getTypeCode() == ICElement.C_STORAGE_EXTERN;
pop(endOffset);
} else if (node instanceof ICPPASTTemplateDeclaration) {
// handled at child declaration level
} else if (node instanceof ICPPASTTemplateSpecialization) {
// ignored
} else if (node instanceof ICPPASTExplicitTemplateInstantiation) {
// ignored
} else if (node instanceof IASTProblemDeclaration) {
// ignored
}
return PROCESS_CONTINUE;
}
/*
* @see org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor#leave(org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition)
*/
public int leave(ICPPASTNamespaceDefinition namespace) {
assert getCurrentContainer().getTypeCode() == ICElement.C_NAMESPACE;
pop(getEndOffset(namespace));
return super.leave(namespace);
}
private DocumentRangeNode getCurrentContainer() {
return (DocumentRangeNode) fStack.peek();
}
/**
* Adds a new node with the given type and name to the current container.
*/
private void push(int type, String name, int declarationStart) {
if (name.length() == 0) {
name= ANONYMOUS_NAME;
}
fStack.push(new CNode(getCurrentContainer(), type, name, declarationStart, 0));
}
/**
* Closes the current node by setting its end position
* and pops it off the stack.
*/
private void pop(int declarationEnd) {
DocumentRangeNode current= getCurrentContainer();
current.setAppendPosition(declarationEnd);
current.setLength(declarationEnd - current.getRange().getOffset());
fStack.pop();
}
/**
* @return <code>true</code> if the current container is class-like.
*/
private boolean inClassBody() {
int typeCode= getCurrentContainer().getTypeCode();
return typeCode == ICElement.C_CLASS
|| typeCode == ICElement.C_TEMPLATE_CLASS
|| typeCode == ICElement.C_STRUCT
|| typeCode == ICElement.C_TEMPLATE_STRUCT
|| typeCode == ICElement.C_UNION
|| typeCode == ICElement.C_TEMPLATE_UNION;
}
/**
* Test whether the given declaration is a templated declaration.
*
* @param node
* @return <code>true</code> if the declaration is templated.
*/
private boolean isTemplateDecl(IASTDeclaration node) {
return node.getParent() instanceof ICPPASTTemplateDeclaration;
}
private boolean hasNestedPointerOperators(IASTDeclarator declarator) {
declarator= declarator.getNestedDeclarator();
while (declarator != null) {
if (declarator.getPointerOperators().length > 0) {
return true;
}
declarator= declarator.getNestedDeclarator();
}
return false;
}
private String getEnumerationName(IASTEnumerationSpecifier enumSpecifier) {
String nodeName= ASTStringUtil.getQualifiedName(enumSpecifier.getName());
if (nodeName.length() == 0) {
nodeName= ANONYMOUS_NAME;
}
return nodeName;
}
private String getTypeName(IASTCompositeTypeSpecifier compositeTypeSpec) {
String nodeName= ASTStringUtil.getQualifiedName(compositeTypeSpec.getName());
if (nodeName.length() == 0) {
nodeName= ANONYMOUS_NAME;
}
return nodeName;
}
private String getDeclaratorName(IASTDeclarator node) {
node= getInnermostDeclarator(node);
IASTName name= node.getName();
String nodeName= ASTStringUtil.getQualifiedName(name);
if (nodeName.length() == 0) {
nodeName= ANONYMOUS_NAME;
}
return nodeName;
}
private IASTDeclarator getInnermostDeclarator(IASTDeclarator node) {
IASTDeclarator nested= node.getNestedDeclarator();
while (nested != null) {
node= nested;
nested= node.getNestedDeclarator();
}
return node;
}
private static IASTFileLocation getMaxFileLocation(IASTNodeLocation[] locations) {
if (locations == null || locations.length == 0) {
return null;
}
final IASTNodeLocation nodeLocation= locations[locations.length-1];
if (nodeLocation instanceof IASTFileLocation) {
return (IASTFileLocation)nodeLocation;
} else if (nodeLocation instanceof IASTMacroExpansion) {
IASTNodeLocation[] macroLocations= ((IASTMacroExpansion)nodeLocation).getExpansionLocations();
return getMaxFileLocation(macroLocations);
}
return null;
}
private static IASTFileLocation getMinFileLocation(IASTNodeLocation[] locations) {
if (locations == null || locations.length == 0) {
return null;
}
final IASTNodeLocation nodeLocation= locations[0];
if (nodeLocation instanceof IASTFileLocation) {
return (IASTFileLocation)nodeLocation;
} else if (nodeLocation instanceof IASTMacroExpansion) {
IASTNodeLocation[] macroLocations= ((IASTMacroExpansion)nodeLocation).getExpansionLocations();
return getMinFileLocation(macroLocations);
}
return null;
}
}

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2002, 2006 QNX Software Systems and others. * Copyright (c) 2002, 2007 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -54,7 +54,7 @@ import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.cdt.core.parser.ast.IASTVariableReference; import org.eclipse.cdt.core.parser.ast.IASTVariableReference;
/** /**
* * @deprecated As of CDT 5.0. This class is not used anymore. Kept for reference only.
*/ */
public class SourceElementRequestorAdapter implements ISourceElementRequestor { public class SourceElementRequestorAdapter implements ISourceElementRequestor {
/* (non-Javadoc) /* (non-Javadoc)