1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-01 13:25:45 +02:00

Bug 304479: Disambiguation of types and objects from index.

This commit is contained in:
Markus Schorn 2010-03-04 08:22:17 +00:00
parent 6a8a4ece8f
commit 96c2033d9f
2 changed files with 102 additions and 16 deletions

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * 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();
}
}
} }

View file

@ -1766,39 +1766,44 @@ public class CPPSemantics {
return composite; return composite;
} }
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 (data.typesOnly) {
if (type != null) {
if (obj instanceof ICPPNamespace && compareByRelevance(data, type, obj) < 0) {
return obj;
}
return type;
}
if (obj instanceof ICPPNamespace) if (obj instanceof ICPPNamespace)
return obj; return obj;
return null; return type;
} }
if (fns.size() > 0) { if (fns.size() > 0) {
final IFunction[] fnArray = fns.keyArray(IFunction.class); final IFunction[] fnArray = fns.keyArray(IFunction.class);
if (type != null && overrulesByRelevance(data, type, fnArray)) {
return type;
}
if (obj != null) { if (obj != null) {
int cmp= compareByRelevance(data, obj, fnArray); int cmp= compareByRelevance(data, obj, fnArray);
if (cmp == 0) { if (cmp == 0) {
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
data.getFoundBindings()); data.getFoundBindings());
} }
if (cmp > 0) if (cmp > 0) {
return obj; return obj;
} }
}
return resolveFunction(data, fnArray, true); return resolveFunction(data, fnArray, true);
} }
if (obj != null) { if (obj != null) {
if (type != null && obj instanceof ICPPNamespace) {
if (compareByRelevance(data, type, obj) >= 0) {
return type;
}
}
return obj; return obj;
} }
return type; return type;
@ -1834,6 +1839,47 @@ public class CPPSemantics {
return 0; 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 * 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, * considered more relevant than index ones since the index may be out of date,