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:
parent
8c172d53d7
commit
35a31af9c6
10 changed files with 1092 additions and 148 deletions
|
@ -73,7 +73,6 @@ import org.eclipse.cdt.core.index.IIndexManager;
|
|||
import org.eclipse.cdt.core.model.CModelException;
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
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.IStructure;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
|
@ -515,18 +514,6 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
|||
elements= new CElement[1];
|
||||
final CElement element= createSimpleDeclaration(parent, declSpecifier, null, isTemplate);
|
||||
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 {
|
||||
if (isCompositeType) {
|
||||
createSimpleDeclaration(parent, declSpecifier, null, isTemplate);
|
||||
|
@ -535,7 +522,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
|||
for (int i= 0; i < declarators.length; i++) {
|
||||
final IASTDeclarator declarator= declarators[i];
|
||||
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);
|
||||
}
|
||||
elements[i]= element;
|
||||
|
@ -800,17 +787,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
|||
} else {
|
||||
final IASTFileLocation classLocation= getMinFileLocation(compositeTypeSpecifier.getNodeLocations());
|
||||
if (classLocation != null) {
|
||||
if (compositeTypeSpecifier.getStorageClass() == IASTDeclSpecifier.sc_typedef) {
|
||||
// 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());
|
||||
}
|
||||
element.setIdPos(classLocation.getNodeOffset(), type.length());
|
||||
}
|
||||
}
|
||||
// add members
|
||||
|
@ -1146,7 +1123,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
|||
// hook up the offsets
|
||||
setIdentifierPosition(info, name);
|
||||
if (!isTemplate) {
|
||||
setBodyPosition(info, declarator);
|
||||
setBodyPosition(info, declarator.getParent());
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
|
155
core/org.eclipse.cdt.ui.tests/resources/compare/CompareTest.cpp
Normal file
155
core/org.eclipse.cdt.ui.tests/resources/compare/CompareTest.cpp
Normal 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() {}
|
||||
}
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,5 +57,8 @@ public class TextTestSuite extends TestSuite {
|
|||
|
||||
// word detection
|
||||
addTest(CWordFinderTest.suite());
|
||||
|
||||
// compare tests
|
||||
addTest(CStructureCreatorTest.suite());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,25 +60,6 @@ AbstractErrorParserBlock.label.errorParsers=Error Parsers
|
|||
|
||||
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
|
||||
|
||||
CHelpConfigurationPropertyPage.buttonLabels.CheckAll=Check All
|
||||
|
@ -93,3 +74,4 @@ TextEditorDropAdapter.unreadableFile=Unreadable file: ''{0}''
|
|||
TextEditorDropAdapter.noFile=Not a file: ''{0}''
|
||||
|
||||
OptionalMessageDialog_dontShowAgain= Do not show this &message again
|
||||
CStructureCreatorVisitor.translationUnitName=Translation Unit
|
||||
|
|
|
@ -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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* QNX Software System
|
||||
* Anton Leherbauer (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
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.text.IDocument;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
class CNode extends DocumentRangeNode implements ITypedElement {
|
||||
|
||||
public CNode(CNode parent, int type, String id, IDocument doc, int start, int length) {
|
||||
super(type, id, doc, start, length);
|
||||
public CNode(DocumentRangeNode parent, int type, String id, IDocument doc, int start, int length) {
|
||||
super(parent, type, id, doc, start, length);
|
||||
if (parent != null) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* QNX Software System
|
||||
* Anton Leherbauer (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @deprecated As of CDT 5.0. This class is not used anymore. Kept for reference only.
|
||||
*/
|
||||
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) {
|
||||
fStack.push(new CNode(getCurrentContainer(), type, name, declarationStart, 0));
|
||||
|
@ -307,12 +308,8 @@ public class CParseTreeBuilder extends SourceElementRequestorAdapter {
|
|||
*/
|
||||
private void pop(int declarationEnd) {
|
||||
CNode current = getCurrentContainer();
|
||||
if (current.getTypeCode() == ICElement.C_UNIT) {
|
||||
current.setAppendPosition(declarationEnd + 1);
|
||||
} else {
|
||||
current.setAppendPosition(declarationEnd);
|
||||
}
|
||||
current.setLength(declarationEnd - current.getRange().getOffset() + 1);
|
||||
current.setAppendPosition(declarationEnd);
|
||||
current.setLength(declarationEnd - current.getRange().getOffset());
|
||||
fStack.pop();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -17,37 +17,43 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import org.eclipse.compare.CompareUI;
|
||||
import org.eclipse.compare.IEditableContent;
|
||||
import org.eclipse.compare.IEncodedStreamContentAccessor;
|
||||
import org.eclipse.compare.ISharedDocumentAdapter;
|
||||
import org.eclipse.compare.IStreamContentAccessor;
|
||||
import org.eclipse.compare.structuremergeviewer.Differencer;
|
||||
import org.eclipse.compare.structuremergeviewer.IDiffContainer;
|
||||
import org.eclipse.compare.ResourceNode;
|
||||
import org.eclipse.compare.contentmergeviewer.IDocumentRange;
|
||||
import org.eclipse.compare.structuremergeviewer.DocumentRangeNode;
|
||||
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.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.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.IParser;
|
||||
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.IScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.ParserUtil;
|
||||
import org.eclipse.cdt.core.parser.ScannerInfo;
|
||||
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$
|
||||
|
||||
|
@ -58,78 +64,18 @@ public class CStructureCreator implements IStructureCreator {
|
|||
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
|
||||
*/
|
||||
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) {
|
||||
IStreamContentAccessor sca = (IStreamContentAccessor) node;
|
||||
try {
|
||||
|
@ -140,6 +86,80 @@ public class CStructureCreator implements IStructureCreator {
|
|||
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 {
|
||||
InputStream is= sa.getContents();
|
||||
if (is != null) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @deprecated As of CDT 5.0. This class is not used anymore. Kept for reference only.
|
||||
*/
|
||||
public class SourceElementRequestorAdapter implements ISourceElementRequestor {
|
||||
/* (non-Javadoc)
|
||||
|
|
Loading…
Add table
Reference in a new issue