mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 08:55:25 +02:00
Bug 304479: Disambiguation of types and objects from index.
This commit is contained in:
parent
6a8a4ece8f
commit
96c2033d9f
2 changed files with 102 additions and 16 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2009 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2006, 2010 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
|
||||
|
@ -2169,4 +2169,44 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
// // a.h
|
||||
// struct Error{};
|
||||
|
||||
// // b.h
|
||||
// void Error(int errCode) {}
|
||||
|
||||
// // source1.cpp
|
||||
// #include "a.h"
|
||||
// Error d;
|
||||
|
||||
// // source2.cpp
|
||||
// Error d; // Problem, without inclusion we need to prefer the function.
|
||||
public void testDisambiguateObjectVsType_304479() throws Exception {
|
||||
waitForIndexer();
|
||||
String[] testData = getContentsForTest(4);
|
||||
TestSourceReader.createFile(fCProject.getProject(), "a.h", testData[0]);
|
||||
TestSourceReader.createFile(fCProject.getProject(), "b.h", testData[1]);
|
||||
IFile s1= TestSourceReader.createFile(fCProject.getProject(), "s1.cpp", testData[2]);
|
||||
IFile s2= TestSourceReader.createFile(fCProject.getProject(), "s2.cpp", testData[3]);
|
||||
final IIndexManager indexManager = CCorePlugin.getIndexManager();
|
||||
indexManager.reindex(fCProject);
|
||||
waitForIndexer();
|
||||
IIndex index= indexManager.getIndex(fCProject);
|
||||
index.acquireReadLock();
|
||||
try {
|
||||
IASTTranslationUnit tu = TestSourceReader.createIndexBasedAST(index, fCProject, s1);
|
||||
IASTSimpleDeclaration sdecl= (IASTSimpleDeclaration) tu.getDeclarations()[0];
|
||||
IVariable var= (IVariable) sdecl.getDeclarators()[0].getName().resolveBinding();
|
||||
assertFalse(var.getType() instanceof IProblemBinding);
|
||||
assertTrue(var.getType() instanceof ICPPClassType);
|
||||
|
||||
tu = TestSourceReader.createIndexBasedAST(index, fCProject, s2);
|
||||
sdecl= (IASTSimpleDeclaration) tu.getDeclarations()[0];
|
||||
var= (IVariable) sdecl.getDeclarators()[0].getName().resolveBinding();
|
||||
assertTrue(var.getType() instanceof IProblemBinding);
|
||||
} finally {
|
||||
index.releaseReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1765,40 +1765,45 @@ public class CPPSemantics {
|
|||
ICPPUsingDeclaration composite = new CPPUsingDeclaration(data.astName, bindings);
|
||||
return composite;
|
||||
}
|
||||
|
||||
if (data.typesOnly) {
|
||||
if (type != null) {
|
||||
if (obj instanceof ICPPNamespace && compareByRelevance(data, type, obj) < 0) {
|
||||
return obj;
|
||||
}
|
||||
return type;
|
||||
|
||||
if (obj != null && type != null) {
|
||||
if (obj instanceof ICPPNamespace) {
|
||||
if (compareByRelevance(data, type, obj) >= 0) {
|
||||
obj= null;
|
||||
}
|
||||
} else if (!data.typesOnly && overrulesByRelevance(data, type, obj)) {
|
||||
obj= null;
|
||||
}
|
||||
}
|
||||
|
||||
if (data.typesOnly) {
|
||||
if (obj instanceof ICPPNamespace)
|
||||
return obj;
|
||||
|
||||
return null;
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
if (fns.size() > 0) {
|
||||
final IFunction[] fnArray = fns.keyArray(IFunction.class);
|
||||
if (type != null && overrulesByRelevance(data, type, fnArray)) {
|
||||
return type;
|
||||
}
|
||||
|
||||
if (obj != null) {
|
||||
int cmp= compareByRelevance(data, obj, fnArray);
|
||||
if (cmp == 0) {
|
||||
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
|
||||
data.getFoundBindings());
|
||||
}
|
||||
if (cmp > 0)
|
||||
if (cmp > 0) {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return resolveFunction(data, fnArray, true);
|
||||
}
|
||||
|
||||
if (obj != null) {
|
||||
if (type != null && obj instanceof ICPPNamespace) {
|
||||
if (compareByRelevance(data, type, obj) >= 0) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
return type;
|
||||
|
@ -1834,6 +1839,47 @@ public class CPPSemantics {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two bindings for relevance in the context of an AST. Type bindings are
|
||||
* considered to overrule object bindings when the former is reachable but the
|
||||
* latter is not.
|
||||
*/
|
||||
static boolean overrulesByRelevance(LookupData data, IBinding type, IBinding b2) {
|
||||
if (data != null && data.tu != null) {
|
||||
return !isReachableFromAst(data.tu, b2) && isReachableFromAst(data.tu, type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares a binding with a list of function candidates for relevance in the
|
||||
* context of an AST. Types are considered to overrule object bindings when
|
||||
* the former is reachable but none of the functions are.
|
||||
*/
|
||||
static boolean overrulesByRelevance(LookupData data, IBinding type, IFunction[] fns) {
|
||||
if (data == null || data.tu == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < fns.length; i++) {
|
||||
if (!isFromIndex(fns[i])) {
|
||||
return false; // function from ast
|
||||
}
|
||||
}
|
||||
|
||||
if (!isReachableFromAst(data.tu, type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (IFunction fn : fns) {
|
||||
if (isReachableFromAst(data.tu, fn)) {
|
||||
return false; // function from ast
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compares two bindings 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,
|
||||
|
@ -1901,7 +1947,7 @@ public class CPPSemantics {
|
|||
}
|
||||
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