1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 08:55:25 +02:00

Bug 520783 - wrong AccessContext for heuristically resolved

CPPUnknownMemberClass

Change-Id: I5a24c7df1dc3b4c270c60b93327190c0461c4cd0
Signed-off-by: Michi <woskimi@yahoo.de>
This commit is contained in:
Michi 2017-08-09 11:18:27 +02:00 committed by Michael Woski
parent b0ce8bc3fb
commit e252398ee1
3 changed files with 33 additions and 47 deletions

View file

@ -36,6 +36,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClosureType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownMemberClass;
/**
* The context that determines access to private and protected class members.
@ -82,13 +83,19 @@ public class AccessContext {
* A class through which the bindings are accessed (11.2.4).
*/
private boolean isUnqualifiedLookup;
private boolean isPrefixLookup;
private ICPPClassType namingClass; // Depends on the binding for which we check the access.
// The first candidate is independent of the binding for which we do the access-check.
private ICPPClassType firstCandidateForNamingClass;
private DOMException initializationException;
public AccessContext(IASTName name) {
this(name, false);
}
public AccessContext(IASTName name, boolean prefixLookup) {
this.name = name;
this.isPrefixLookup = prefixLookup;
}
/**
@ -296,6 +303,13 @@ public class AccessContext {
if (scopeType instanceof ICPPDeferredClassInstance) {
return ((ICPPDeferredClassInstance) scopeType).getClassTemplate();
}
if (scopeType instanceof ICPPUnknownMemberClass && isPrefixLookup) {
scopeType = HeuristicResolver.resolveUnknownType((ICPPUnknownMemberClass) scopeType,
name.getParent());
if (scopeType instanceof ICPPClassType) {
return (ICPPClassType) scopeType;
}
}
}
scope = CPPSemantics.getParentScope(scope, data.getTranslationUnit());

View file

@ -590,6 +590,22 @@ public class CompletionTests extends CompletionTestBase {
assertCompletionResults(fCursorOffset, expected, ID);
}
// template <typename TPA>
// struct A {
// struct AA {
// static int i;
// };
// };
//
// template <typename TPB>
// void test()
// {
// A<TPB>::AA::/*cursor*/
// }
public void testUnknownMemberClassAccessContext_520783() throws Exception {
assertCompletionResults(new String[] { "i" });
}
// template <typename T>
// struct A {
// template <typename U>
@ -1126,51 +1142,7 @@ public class CompletionTests extends CompletionTestBase {
final String[] expected= { "add(tOther)" };
assertCompletionResults(fCursorOffset, expected, REPLACEMENT);
}
// template <typename TPA>
// struct A {
// struct {
// int i;
// } test;
// };
//
// template <typename TPB>
// struct B {
//
// A<TPB> const* a;
//
// void
// test()
// {
// a->test./*cursor*/
// }
// };
public void testHeuristicTypeResolution1_520470() throws Exception {
assertCompletionResults(new String[] { "i" });
}
// template <typename TPA>
// struct A {
// struct {
// int i;
// } test;
// };
//
// template <typename TPB>
// struct B {
//
// A<TPB> const* a();
//
// void
// test()
// {
// a()->t/*cursor*/
// }
// };
public void testHeuristicTypeResolution2_520470() throws Exception {
assertCompletionResults(new String[] { "test" });
}
//namespace ns {
// template<class T>
// class Base {

View file

@ -183,7 +183,7 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
IBinding[] bindings = astContext.findBindings(name, !context.isContextInformationStyle());
if (bindings != null) {
AccessContext accessibilityContext = new AccessContext(name);
AccessContext accessibilityContext = new AccessContext(name, true);
for (IBinding binding : bindings) {
if (accessibilityContext.isAccessible(binding))
handleBinding(binding, context, prefix, astContext, proposals);
@ -844,7 +844,7 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
});
Map<String, IBinding> elementsMap = new HashMap<>();
AccessContext accessibilityContext = new AccessContext(name);
AccessContext accessibilityContext = new AccessContext(name, true);
for (IBinding binding : bindings) {
// Consider only fields and variables that are declared in the current translation unit.
if (binding instanceof IVariable