1
/*******************************************************************************
2
* Copyright (c) 2000, 2008 IBM Corporation and others.
3
* All rights reserved. This program and the accompanying materials
4
* are made available under the terms of the Eclipse Public License v1.0
5
* which accompanies this distribution, and is available at
6
* http://www.eclipse.org/legal/epl-v10.html
9
* IBM Corporation - initial API and implementation
10
* Markus Schorn (Wind River Systems)
11
*******************************************************************************/
12
package org.eclipse.cdt.internal.core.parser.util;
14
import java.util.ArrayList;
15
import java.util.List;
17
import junit.framework.Assert;
19
import org.eclipse.cdt.core.CCorePlugin;
20
import org.eclipse.cdt.core.dom.IName;
21
import org.eclipse.cdt.core.dom.ast.DOMException;
22
import org.eclipse.cdt.core.dom.ast.IASTName;
23
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
24
import org.eclipse.cdt.core.dom.ast.IBinding;
25
import org.eclipse.cdt.core.dom.ast.c.CASTVisitor;
26
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
27
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
28
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
29
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
30
import org.eclipse.cdt.core.index.IIndexBinding;
31
import org.eclipse.cdt.core.parser.ParserLanguage;
32
import org.eclipse.cdt.core.parser.util.ArrayUtil;
33
import org.eclipse.core.resources.IFile;
34
import org.eclipse.core.resources.IProject;
35
import org.eclipse.core.runtime.IPath;
36
import org.eclipse.core.runtime.content.IContentType;
39
* Utility class to have commonly used algorithms in one place for searching with the DOM.
43
public class DOMSearchUtil {
44
private static final IASTName[] BLANK_NAME_ARRAY = new IASTName[0];
45
// private static final IASTName[] EMPTY_NAME_LIST = BLANK_NAME_ARRAY;
47
public static final int DECLARATIONS = 1;
48
public static final int DEFINITIONS = 2;
49
public static final int DECLARATIONS_DEFINITIONS = 3;
50
public static final int REFERENCES = 4;
51
public static final int ALL_OCCURRENCES = 5;
53
* This retrieves the ParserLanguage from an IFile.
58
public static ParserLanguage getLanguageFromFile(IFile file) {
59
IProject project = file.getProject();
60
IContentType contentType = CCorePlugin.getContentType(project, file.getFullPath().lastSegment());
61
if (contentType != null) {
62
String lid = contentType.getId();
63
if (CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(lid) ||
64
CCorePlugin.CONTENT_TYPE_CXXHEADER.equals(lid)) {
65
return ParserLanguage.CPP;
68
return ParserLanguage.C;
72
* The CPPNameCollector used to get IASTNames from an IASTNode.
76
static public class CPPNameCollector extends CPPASTVisitor {
78
shouldVisitNames = true;
80
public List nameList = new ArrayList();
81
public int visit( IASTName name ){
83
return PROCESS_CONTINUE;
85
public IASTName getName( int idx ){
86
if( idx < 0 || idx >= nameList.size() )
88
return (IASTName) nameList.get( idx );
90
public int size() { return nameList.size(); }
94
* The CNameCollector used to get IASTNames from an IASTNode.
98
static public class CNameCollector extends CASTVisitor {
100
shouldVisitNames = true;
102
public List nameList = new ArrayList();
103
public int visit( IASTName name ){
104
nameList.add( name );
105
return PROCESS_CONTINUE;
107
public IASTName getName( int idx ){
108
if( idx < 0 || idx >= nameList.size() )
110
return (IASTName) nameList.get( idx );
112
public int size() { return nameList.size(); }
116
* Returns the ParserLanguage corresponding to the IPath and IProject. Returns ParserLanguage.CPP if the file type is a header.
122
public static ParserLanguage getLanguage( IPath path, IProject project )
124
//FIXME: ALAIN, for headers should we assume CPP ??
125
// The problem is that it really depends on how the header was included.
127
IContentType contentType = CCorePlugin.getContentType(project, path.lastSegment());
128
if (contentType != null) {
129
id = contentType.getId();
132
if (CCorePlugin.CONTENT_TYPE_CXXHEADER.equals(id)) {
133
return ParserLanguage.CPP;
134
} else if (CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(id)) {
135
return ParserLanguage.CPP;
136
} else if (CCorePlugin.CONTENT_TYPE_CHEADER.equals(id)) {
137
return ParserLanguage.C;
138
} else if (CCorePlugin.CONTENT_TYPE_CSOURCE.equals(id)) {
139
return ParserLanguage.C;
140
} else if (CCorePlugin.CONTENT_TYPE_ASMSOURCE.equals(id)) {
142
// What do we do here ?
145
return ParserLanguage.CPP;
149
* This is used to get the names from the TU that the IASTName searchName belongs to.
151
* @param searchName the IASTName whose references/delcarations are to be retrieved
152
* @param limitTo used to specify whether to get declarations, references, or both, one of:
153
* ( CSearchPattern.DECLARATION | CSearchPattern.REFERENCES | CSearchPattern.ALL_OCCURRENCES )
154
* @return IASTName[] declarations, references, or both depending on limitTo that correspond to the IASTName searchName searched for
156
public static IName[] getNamesFromDOM(IASTName searchName, int limitTo) {
157
IName[] names = null;
158
IASTTranslationUnit tu = searchName.getTranslationUnit();
161
return BLANK_NAME_ARRAY;
164
IBinding binding = searchName.resolveBinding();
165
if (binding instanceof IIndexBinding) {
166
Assert.fail("Not implemented");
168
// ArrayList pdomNames = new ArrayList();
169
// IPDOMResolver pdom= ((PDOMBinding) binding).getPDOM();
171
// names= pdom.getDeclarations(binding);
172
// pdomNames.addAll(Arrays.asList(names));
174
// names= pdom.getDefinitions(binding);
175
// pdomNames.addAll(Arrays.asList(names));
176
// names = (IName[])pdomNames.toArray(new IName[pdomNames.size()]);
177
// } catch (CoreException e) {
178
// CCorePlugin.log(e);
181
names = getNames(tu, binding, limitTo);
183
if (names == null || names.length == 0) { // try alternate strategies
185
// fix for 86829, 95224
186
if ((binding instanceof ICPPConstructor || (binding instanceof ICPPMethod && ((ICPPMethod)binding).isDestructor()))
187
&& binding.getScope() instanceof ICPPClassScope) {
188
binding = ((ICPPClassScope)binding.getScope()).getClassType();
189
names = getNames(tu, binding, limitTo);
191
} catch (DOMException e) {}
198
private static IASTName[] getNames(IASTTranslationUnit tu, IBinding binding, int limitTo) {
199
IASTName[] names = null;
200
if (limitTo == DECLARATIONS ||
201
limitTo == DECLARATIONS_DEFINITIONS) {
202
names = tu.getDeclarationsInAST(binding);
203
} else if (limitTo == REFERENCES) {
204
names = tu.getReferences(binding);
205
} else if (limitTo == DEFINITIONS) {
206
names = tu.getDefinitionsInAST(binding);
207
} else if (limitTo == ALL_OCCURRENCES){
208
names = tu.getDeclarationsInAST(binding);
209
names = (IASTName[])ArrayUtil.addAll(IASTName.class, names, tu.getReferences(binding));
210
} else { // assume ALL
211
names = tu.getDeclarationsInAST(binding);
212
names = (IASTName[])ArrayUtil.addAll(IASTName.class, names, tu.getReferences(binding));