mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 09:46:02 +02:00
bug 520470 - [codeassist] HeuristicResolver & qualifiedType resolution
Change-Id: I9569d776981dbf87a075aebcd0c07ce9f1470f47 Signed-off-by: Michi <woskimi@yahoo.de>
This commit is contained in:
parent
18831f4407
commit
b0ce8bc3fb
2 changed files with 72 additions and 15 deletions
|
@ -22,6 +22,7 @@ import org.eclipse.cdt.core.dom.ast.IEnumerator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IField;
|
import org.eclipse.cdt.core.dom.ast.IField;
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IQualifierType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
|
@ -108,7 +109,7 @@ public class HeuristicResolver {
|
||||||
*/
|
*/
|
||||||
public static IScope findConcreteScopeForType(IType type, IASTNode point) {
|
public static IScope findConcreteScopeForType(IType type, IASTNode point) {
|
||||||
if (type instanceof ICPPUnknownType) {
|
if (type instanceof ICPPUnknownType) {
|
||||||
type = resolveUnknownType((ICPPUnknownType) type, point, SemanticUtil.TDEF | SemanticUtil.REF);
|
type = resolveUnknownType((ICPPUnknownType) type, point, SemanticUtil.TDEF | SemanticUtil.REF | SemanticUtil.CVTYPE);
|
||||||
}
|
}
|
||||||
type = SemanticUtil.getNestedType(type, SemanticUtil.PTR);
|
type = SemanticUtil.getNestedType(type, SemanticUtil.PTR);
|
||||||
if (type instanceof ICompositeType) {
|
if (type instanceof ICompositeType) {
|
||||||
|
@ -266,6 +267,10 @@ public class HeuristicResolver {
|
||||||
isPointerDeref = false;
|
isPointerDeref = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ownerType instanceof IQualifierType) {
|
||||||
|
ownerType = ((IQualifierType) ownerType).getType();
|
||||||
|
}
|
||||||
|
|
||||||
IType lookupType = ownerType;
|
IType lookupType = ownerType;
|
||||||
ICPPClassSpecialization specializationContext = null;
|
ICPPClassSpecialization specializationContext = null;
|
||||||
if (lookupType instanceof ICPPUnknownType) {
|
if (lookupType instanceof ICPPUnknownType) {
|
||||||
|
@ -283,9 +288,25 @@ public class HeuristicResolver {
|
||||||
lookupType = specializationContext.getSpecializedBinding();
|
lookupType = specializationContext.getSpecializedBinding();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
IType resolvedType = resolveUnknownTypeOnce((ICPPUnknownType) lookupType, lookupSet,
|
IType resolvedType = resolveUnknownTypeOnce((ICPPUnknownType) lookupType, lookupSet, point);
|
||||||
point);
|
resolvedType = SemanticUtil.getNestedType(resolvedType,
|
||||||
resolvedType = SemanticUtil.getNestedType(resolvedType, SemanticUtil.TDEF | SemanticUtil.REF);
|
SemanticUtil.TDEF | SemanticUtil.REF | SemanticUtil.CVTYPE);
|
||||||
|
|
||||||
|
// If this is a pointer dereference, and the pointer type wasn't
|
||||||
|
// outside the
|
||||||
|
// dependent type, it might be inside the dependent type.
|
||||||
|
if (isPointerDeref) {
|
||||||
|
if (resolvedType instanceof IPointerType) {
|
||||||
|
isPointerDeref = false;
|
||||||
|
resolvedType = ((IPointerType) resolvedType).getType();
|
||||||
|
} else {
|
||||||
|
resolvedType = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resolvedType = SemanticUtil.getNestedType(resolvedType,
|
||||||
|
SemanticUtil.CVTYPE | SemanticUtil.TDEF);
|
||||||
|
|
||||||
if (resolvedType == lookupType || !(resolvedType instanceof ICPPUnknownType)) {
|
if (resolvedType == lookupType || !(resolvedType instanceof ICPPUnknownType)) {
|
||||||
lookupType = resolvedType;
|
lookupType = resolvedType;
|
||||||
break;
|
break;
|
||||||
|
@ -295,15 +316,6 @@ public class HeuristicResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a pointer dereference, and the pointer type wasn't outside the
|
|
||||||
// dependent type, it might be inside the dependent type.
|
|
||||||
if (isPointerDeref) {
|
|
||||||
if (lookupType instanceof IPointerType) {
|
|
||||||
lookupType = ((IPointerType) lookupType).getType();
|
|
||||||
} else {
|
|
||||||
lookupType = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IScope lookupScope = null;
|
IScope lookupScope = null;
|
||||||
|
@ -365,7 +377,7 @@ public class HeuristicResolver {
|
||||||
* @param point the point of instantiation for lookups
|
* @param point the point of instantiation for lookups
|
||||||
*/
|
*/
|
||||||
public static IType resolveUnknownType(ICPPUnknownType type, IASTNode point) {
|
public static IType resolveUnknownType(ICPPUnknownType type, IASTNode point) {
|
||||||
return resolveUnknownType(type, point, SemanticUtil.TDEF);
|
return resolveUnknownType(type, point, SemanticUtil.TDEF | SemanticUtil.CVTYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -378,6 +390,7 @@ public class HeuristicResolver {
|
||||||
Set<HeuristicLookup> lookupSet = new HashSet<>();
|
Set<HeuristicLookup> lookupSet = new HashSet<>();
|
||||||
IType resolvedType = resolveUnknownTypeOnce(type, lookupSet, point);
|
IType resolvedType = resolveUnknownTypeOnce(type, lookupSet, point);
|
||||||
resolvedType = SemanticUtil.getNestedType(resolvedType, unwrapOptions);
|
resolvedType = SemanticUtil.getNestedType(resolvedType, unwrapOptions);
|
||||||
|
|
||||||
if (resolvedType != type && resolvedType instanceof ICPPUnknownType) {
|
if (resolvedType != type && resolvedType instanceof ICPPUnknownType) {
|
||||||
type = (ICPPUnknownType) resolvedType;
|
type = (ICPPUnknownType) resolvedType;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1127,6 +1127,50 @@ public class CompletionTests extends CompletionTestBase {
|
||||||
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 {
|
||||||
|
|
Loading…
Add table
Reference in a new issue