1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 456101 - class template is refering to itself in code completion

a CPPASTQualifiedName that represents some template instance can never
refer to a template of the same type

Change-Id: Iaf9a452e4797fc0e797e5ed5ccaadfb00ff4fb8f
Signed-off-by: Michi <woskimi@yahoo.de>
Reviewed-on: https://git.eclipse.org/r/38730
Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
Michi 2014-12-23 17:40:33 +01:00 committed by Sergey Prigogin
parent cc7bf7b392
commit 690fc119bb
2 changed files with 42 additions and 9 deletions

View file

@ -42,6 +42,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.model.IEnumeration;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
@ -378,19 +379,21 @@ public class CPPASTQualifiedName extends CPPASTNameBase
return false;
}
private List<IBinding> filterClassScopeBindings(ICPPClassType classType,
IBinding[] bindings, final boolean isDeclaration) {
private List<IBinding> filterClassScopeBindings(ICPPClassType classType, IBinding[] bindings,
final boolean isDeclaration) {
List<IBinding> filtered = new ArrayList<IBinding>();
final boolean canBeFieldAccess= canBeFieldAccess(classType);
final boolean canBeFieldAccess = canBeFieldAccess(classType);
final IBinding templateDefinition = (classType instanceof ICPPTemplateInstance)
? ((ICPPTemplateInstance) classType).getTemplateDefinition() : null;
for (final IBinding binding : bindings) {
if (binding instanceof IField) {
IField field = (IField) binding;
if (!canBeFieldAccess && !field.isStatic())
if (!canBeFieldAccess && !field.isStatic())
continue;
} else if (binding instanceof ICPPMethod) {
ICPPMethod method = (ICPPMethod) binding;
if (method.isImplicit())
if (method.isImplicit())
continue;
if (!isDeclaration) {
if (method.isDestructor() || method instanceof ICPPConstructor
@ -400,14 +403,17 @@ public class CPPASTQualifiedName extends CPPASTNameBase
} else if (binding instanceof IEnumerator || binding instanceof IEnumeration) {
if (isDeclaration)
continue;
} else if (templateDefinition == binding) {
// This solves bug 456101 (template instance refering to itself).
// A<T>:: should not get a binding to its own template definition.
continue;
} else if (binding instanceof IType) {
IType type = (IType) binding;
if (type.isSameType(classType))
if (classType.isSameType((IType) binding))
continue;
}
}
filtered.add(binding);
}
return filtered;
}

View file

@ -154,6 +154,7 @@ public class CompletionTests extends AbstractContentAssistTest {
// T add(T tOther) {
// return fTField + tOther;
// }
// class NestedClass{};
// };
// // bug 109480
// class Printer
@ -1442,6 +1443,32 @@ public class CompletionTests extends AbstractContentAssistTest {
assertContentAssistResults(fCursorOffset, expected, true, DISPLAY);
}
// template<typename T,typename U>
// struct TestTemplate {
// class NestedClass {};
// };
// template<typename T>
// struct TestTemplate<T,int> {
// class NestedClass {};
// };
// template<>
// struct TestTemplate<int,int> {
// class NestedClass {};
// };
// template<typename T,typename U>
// class TestTemplateSelfReference : TestTemplate<T,U>::/*cursor*/
public void testTemplateSelfReference_bug456101() throws Exception {
final String[] expected = { "NestedClass" };
assertContentAssistResults(fCursorOffset, expected, true, DISPLAY);
}
// template<typename T>
// class TestTemplateSelfReference : TClass<T>::/*cursor*/
public void testTemplateSelfReferencePDOM_bug456101() throws Exception {
final String[] expected = { "NestedClass" };
assertContentAssistResults(fCursorOffset, expected, true, DISPLAY);
}
// namespace N {
// void foo(int);
// }