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:
parent
cc7bf7b392
commit
690fc119bb
2 changed files with 42 additions and 9 deletions
|
@ -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.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
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.ICPPMethod;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
||||||
import org.eclipse.cdt.core.model.IEnumeration;
|
import org.eclipse.cdt.core.model.IEnumeration;
|
||||||
import org.eclipse.cdt.core.parser.Keywords;
|
import org.eclipse.cdt.core.parser.Keywords;
|
||||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
|
@ -378,19 +379,21 @@ public class CPPASTQualifiedName extends CPPASTNameBase
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<IBinding> filterClassScopeBindings(ICPPClassType classType,
|
private List<IBinding> filterClassScopeBindings(ICPPClassType classType, IBinding[] bindings,
|
||||||
IBinding[] bindings, final boolean isDeclaration) {
|
final boolean isDeclaration) {
|
||||||
List<IBinding> filtered = new ArrayList<IBinding>();
|
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) {
|
for (final IBinding binding : bindings) {
|
||||||
if (binding instanceof IField) {
|
if (binding instanceof IField) {
|
||||||
IField field = (IField) binding;
|
IField field = (IField) binding;
|
||||||
if (!canBeFieldAccess && !field.isStatic())
|
if (!canBeFieldAccess && !field.isStatic())
|
||||||
continue;
|
continue;
|
||||||
} else if (binding instanceof ICPPMethod) {
|
} else if (binding instanceof ICPPMethod) {
|
||||||
ICPPMethod method = (ICPPMethod) binding;
|
ICPPMethod method = (ICPPMethod) binding;
|
||||||
if (method.isImplicit())
|
if (method.isImplicit())
|
||||||
continue;
|
continue;
|
||||||
if (!isDeclaration) {
|
if (!isDeclaration) {
|
||||||
if (method.isDestructor() || method instanceof ICPPConstructor
|
if (method.isDestructor() || method instanceof ICPPConstructor
|
||||||
|
@ -400,14 +403,17 @@ public class CPPASTQualifiedName extends CPPASTNameBase
|
||||||
} else if (binding instanceof IEnumerator || binding instanceof IEnumeration) {
|
} else if (binding instanceof IEnumerator || binding instanceof IEnumeration) {
|
||||||
if (isDeclaration)
|
if (isDeclaration)
|
||||||
continue;
|
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) {
|
} else if (binding instanceof IType) {
|
||||||
IType type = (IType) binding;
|
if (classType.isSameType((IType) binding))
|
||||||
if (type.isSameType(classType))
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
filtered.add(binding);
|
filtered.add(binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
return filtered;
|
return filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,6 +154,7 @@ public class CompletionTests extends AbstractContentAssistTest {
|
||||||
// T add(T tOther) {
|
// T add(T tOther) {
|
||||||
// return fTField + tOther;
|
// return fTField + tOther;
|
||||||
// }
|
// }
|
||||||
|
// class NestedClass{};
|
||||||
// };
|
// };
|
||||||
// // bug 109480
|
// // bug 109480
|
||||||
// class Printer
|
// class Printer
|
||||||
|
@ -1442,6 +1443,32 @@ public class CompletionTests extends AbstractContentAssistTest {
|
||||||
assertContentAssistResults(fCursorOffset, expected, true, DISPLAY);
|
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 {
|
// namespace N {
|
||||||
// void foo(int);
|
// void foo(int);
|
||||||
// }
|
// }
|
||||||
|
|
Loading…
Add table
Reference in a new issue