mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-09-10 12:03:16 +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);
|
IName[] decls= ast.getDeclarations(var);
|
||||||
assertEquals(2, decls.length);
|
assertEquals(2, decls.length);
|
||||||
int check= 0;
|
int check= 0;
|
||||||
for (int i = 0; i < decls.length; i++) {
|
for (IName name : decls) {
|
||||||
IName name = decls[i];
|
|
||||||
assert name instanceof IIndexName;
|
assert name instanceof IIndexName;
|
||||||
IIndexName iName= (IIndexName) name;
|
IIndexName iName= (IIndexName) name;
|
||||||
if (iName.getFileLocation().getFileName().endsWith("a.h")) {
|
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
|
// // header.h
|
||||||
// template<class T>
|
// template<class T>
|
||||||
// struct A {
|
// struct A {
|
||||||
|
|
|
@ -1928,17 +1928,24 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data.forUsingDeclaration()) {
|
if (data.forUsingDeclaration()) {
|
||||||
IBinding[] bindings = null;
|
int cmp= -1;
|
||||||
if (obj != null) {
|
if (obj != null) {
|
||||||
|
cmp= 1;
|
||||||
if (fns.size() > 0) {
|
if (fns.size() > 0) {
|
||||||
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
|
IFunction[] fnArray= fns.keyArray(IFunction.class);
|
||||||
data.getFoundBindings());
|
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, obj);
|
||||||
bindings = (IBinding[]) ArrayUtil.append(IBinding.class, bindings, type);
|
bindings = (IBinding[]) ArrayUtil.append(IBinding.class, bindings, type);
|
||||||
} else {
|
} else {
|
||||||
// if (fns == null) return type;
|
|
||||||
bindings = (IBinding[]) ArrayUtil.append(IBinding.class, bindings, type);
|
bindings = (IBinding[]) ArrayUtil.append(IBinding.class, bindings, type);
|
||||||
bindings = (IBinding[]) ArrayUtil.addAll(IBinding.class, bindings, fns.keyArray());
|
bindings = (IBinding[]) ArrayUtil.addAll(IBinding.class, bindings, fns.keyArray());
|
||||||
}
|
}
|
||||||
|
@ -1955,13 +1962,18 @@ public class CPPSemantics {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int numFns = fns.size();
|
if (fns.size() > 0) {
|
||||||
if (numFns > 0) {
|
final IFunction[] fnArray = fns.keyArray(IFunction.class);
|
||||||
if (obj != null) {
|
if (obj != null) {
|
||||||
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
|
int cmp= compareByRelevance(data, obj, fnArray);
|
||||||
data.getFoundBindings());
|
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) {
|
if (obj != null) {
|
||||||
|
@ -2000,6 +2012,44 @@ public class CPPSemantics {
|
||||||
return 0;
|
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) {
|
private static boolean isFromIndex(IBinding binding) {
|
||||||
if (binding instanceof IIndexBinding) {
|
if (binding instanceof IIndexBinding) {
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Add table
Reference in a new issue