1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-28 19:35:36 +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.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; 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.ICPPInternalUnknownScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownMemberClass;
/** /**
* The context that determines access to private and protected class members. * 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). * A class through which the bindings are accessed (11.2.4).
*/ */
private boolean isUnqualifiedLookup; private boolean isUnqualifiedLookup;
private boolean isPrefixLookup;
private ICPPClassType namingClass; // Depends on the binding for which we check the access. 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. // The first candidate is independent of the binding for which we do the access-check.
private ICPPClassType firstCandidateForNamingClass; private ICPPClassType firstCandidateForNamingClass;
private DOMException initializationException; private DOMException initializationException;
public AccessContext(IASTName name) { public AccessContext(IASTName name) {
this(name, false);
}
public AccessContext(IASTName name, boolean prefixLookup) {
this.name = name; this.name = name;
this.isPrefixLookup = prefixLookup;
} }
/** /**
@ -296,6 +303,13 @@ public class AccessContext {
if (scopeType instanceof ICPPDeferredClassInstance) { if (scopeType instanceof ICPPDeferredClassInstance) {
return ((ICPPDeferredClassInstance) scopeType).getClassTemplate(); 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()); scope = CPPSemantics.getParentScope(scope, data.getTranslationUnit());

View file

@ -590,6 +590,22 @@ public class CompletionTests extends CompletionTestBase {
assertCompletionResults(fCursorOffset, expected, ID); 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> // template <typename T>
// struct A { // struct A {
// template <typename U> // template <typename U>
@ -1126,51 +1142,7 @@ public class CompletionTests extends CompletionTestBase {
final String[] expected= { "add(tOther)" }; final String[] expected= { "add(tOther)" };
assertCompletionResults(fCursorOffset, expected, REPLACEMENT); 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 { //namespace ns {
// template<class T> // template<class T>
// class Base { // class Base {

View file

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