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.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;
|
||||||
}
|
}
|
||||||
|
|
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
|
// word detection
|
||||||
addTest(CWordFinderTest.suite());
|
addTest(CWordFinderTest.suite());
|
||||||
|
|
||||||
|
// compare tests
|
||||||
|
addTest(CStructureCreatorTest.suite());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
* 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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue