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:
parent
ca169204ad
commit
8e855d931c
2 changed files with 95 additions and 12 deletions
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue