1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

Further disambiguation of bindings from index, bug 268704.

This commit is contained in:
Markus Schorn 2009-07-20 09:48:58 +00:00
parent ca169204ad
commit 8e855d931c
2 changed files with 95 additions and 12 deletions

View file

@ -1866,8 +1866,7 @@ public class IndexBugsTests extends BaseTestCase {
IName[] decls= ast.getDeclarations(var);
assertEquals(2, decls.length);
int check= 0;
for (int i = 0; i < decls.length; i++) {
IName name = decls[i];
for (IName name : decls) {
assert name instanceof IIndexName;
IIndexName iName= (IIndexName) name;
if (iName.getFileLocation().getFileName().endsWith("a.h")) {
@ -1976,6 +1975,40 @@ public class IndexBugsTests extends BaseTestCase {
}
}
// // a.h
// int xx;
// #include "a.h"
// int yy= xx;
// // b.h
// int xx();
// #include "b.h"
// void test() {
// xx();
// }
public void testDisambiguationByReachability_268704_3() throws Exception {
String[] testData = getContentsForTest(4);
TestSourceReader.createFile(fCProject.getProject(), "a.h", testData[0]);
IFile a = TestSourceReader.createFile(fCProject.getProject(), "a.cpp", testData[1]);
TestSourceReader.createFile(fCProject.getProject(), "b.h", testData[2]);
IFile b = TestSourceReader.createFile(fCProject.getProject(), "b.cpp", testData[3]);
final IIndexManager indexManager = CCorePlugin.getIndexManager();
indexManager.reindex(fCProject);
waitForIndexer();
IIndex index= indexManager.getIndex(fCProject);
index.acquireReadLock();
try {
BindingAssertionHelper aHelper = new BindingAssertionHelper(a, testData[1], index);
IVariable b1 = aHelper.assertNonProblem("xx;", 2, IVariable.class);
BindingAssertionHelper bHelper = new BindingAssertionHelper(b, testData[3], index);
IFunction f = bHelper.assertNonProblem("xx();", 2, IFunction.class);
} finally {
index.releaseReadLock();
}
}
// // header.h
// template<class T>
// struct A {

View file

@ -1928,17 +1928,24 @@ public class CPPSemantics {
}
}
if (data.forUsingDeclaration()) {
IBinding[] bindings = null;
int cmp= -1;
if (obj != null) {
cmp= 1;
if (fns.size() > 0) {
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
data.getFoundBindings());
IFunction[] fnArray= fns.keyArray(IFunction.class);
cmp= compareByRelevance(data, obj, fnArray);
if (cmp == 0) {
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
data.getFoundBindings());
}
}
// if (type == null) return obj;
}
IBinding[] bindings = null;
if (cmp > 0) {
bindings = (IBinding[]) ArrayUtil.append(IBinding.class, bindings, obj);
bindings = (IBinding[]) ArrayUtil.append(IBinding.class, bindings, type);
} else {
// if (fns == null) return type;
bindings = (IBinding[]) ArrayUtil.append(IBinding.class, bindings, type);
bindings = (IBinding[]) ArrayUtil.addAll(IBinding.class, bindings, fns.keyArray());
}
@ -1955,13 +1962,18 @@ public class CPPSemantics {
return null;
}
int numFns = fns.size();
if (numFns > 0) {
if (fns.size() > 0) {
final IFunction[] fnArray = fns.keyArray(IFunction.class);
if (obj != null) {
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
data.getFoundBindings());
int cmp= compareByRelevance(data, obj, fnArray);
if (cmp == 0) {
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
data.getFoundBindings());
}
if (cmp > 0)
return obj;
}
return resolveFunction(data, fns.keyArray(IFunction.class), true);
return resolveFunction(data, fnArray, true);
}
if (obj != null) {
@ -2000,6 +2012,44 @@ public class CPPSemantics {
return 0;
}
/**
* Compares a binding with a list of function candidates for relevance in the context of an AST. AST bindings are
* considered more relevant than index ones since the index may be out of date,
* built for a different configuration, etc. Index bindings reachable through includes
* are more relevant than unreachable ones.
* @return 1 if binding <code>obj</code> is more relevant than the function candidates; 0 if
* the they have the same relevance; -1 if <code>obj</code> is less relevant than
* the function candidates.
*/
static int compareByRelevance(LookupData data, IBinding obj, IFunction[] fns) {
if (isFromIndex(obj)) {
for (int i = 0; i < fns.length; i++) {
if (!isFromIndex(fns[i])) {
return -1; // function from ast
}
}
// everything is from the index
if (!isReachableFromAst(data.tu, obj)) {
return -1; // obj not reachable
}
for (IFunction fn : fns) {
if (isReachableFromAst(data.tu, fn)) {
return 0; // obj reachable, 1 function reachable
}
}
return 1; // no function is reachable
}
// obj is not from the index
for (int i = 0; i < fns.length; i++) {
if (!isFromIndex(fns[i])) {
return 0; // obj and function from ast
}
}
return 1; // only obj is from ast.
}
private static boolean isFromIndex(IBinding binding) {
if (binding instanceof IIndexBinding) {
return true;