1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-04 06:45:43 +02:00

Bug 478121 - HeuristicResolver: add support for EvalID with non-dependent field owner type, and EvalMemberAccess

Also use HeuristicResolver in CContentAssistProcessor to determine more
accurately whether dot-to-arrow replacement should be performed.

Change-Id: If011d6797247acc41c9fdd705dd8f5fbcbce87a4
This commit is contained in:
Nathan Ridge 2016-02-06 02:44:38 -05:00
parent 453e429d5c
commit 6398b59947
3 changed files with 59 additions and 29 deletions

View file

@ -53,6 +53,7 @@ public class HeuristicResolver {
if (type instanceof ICPPUnknownType) {
type = resolveUnknownType((ICPPUnknownType) type, point, SemanticUtil.TDEF | SemanticUtil.REF);
}
type = SemanticUtil.getNestedType(type, SemanticUtil.PTR);
if (type instanceof ICompositeType) {
return ((ICompositeType) type).getCompositeScope();
}
@ -171,30 +172,31 @@ public class HeuristicResolver {
ownerType = ((IPointerType) ownerType).getType();
isPointerDeref = false;
}
if (ownerType instanceof ICPPUnknownType) {
IType lookupType = ownerType;
ICPPClassSpecialization specializationContext = null;
if (lookupType instanceof ICPPUnknownType) {
// Here we have a loop similar to the one in resolveUnknownType(), but we stop when
// we get a result that's an ICPPClassSpecialization or an ICPPDeferredClassInstance,
// so we can use it to specialize the lookup results as appropriate.
IType lookupType;
ICPPClassSpecialization specializationContext = null;
while (true) {
if (ownerType instanceof ICPPClassSpecialization) {
specializationContext = (ICPPClassSpecialization) ownerType;
if (lookupType instanceof ICPPClassSpecialization) {
specializationContext = (ICPPClassSpecialization) lookupType;
lookupType = specializationContext.getSpecializedBinding();
break;
} else if (ownerType instanceof ICPPDeferredClassInstance) {
} else if (lookupType instanceof ICPPDeferredClassInstance) {
specializationContext = new CPPDependentClassInstance(
(ICPPDeferredClassInstance) ownerType);
(ICPPDeferredClassInstance) lookupType);
lookupType = specializationContext.getSpecializedBinding();
break;
}
IType resolvedType = resolveUnknownTypeOnce((ICPPUnknownType) ownerType, point);
IType resolvedType = resolveUnknownTypeOnce((ICPPUnknownType) lookupType, point);
resolvedType = SemanticUtil.getNestedType(resolvedType, SemanticUtil.TDEF | SemanticUtil.REF);
if (resolvedType == ownerType || !(resolvedType instanceof ICPPUnknownType)) {
if (resolvedType == lookupType || !(resolvedType instanceof ICPPUnknownType)) {
lookupType = resolvedType;
break;
} else {
ownerType = resolvedType;
lookupType = resolvedType;
continue;
}
}
@ -208,27 +210,27 @@ public class HeuristicResolver {
lookupType = null;
}
}
}
IScope lookupScope = null;
if (lookupType instanceof ICPPClassType) {
lookupScope = ((ICPPClassType) lookupType).getCompositeScope();
} else if (lookupType instanceof ICPPEnumeration) {
lookupScope = ((ICPPEnumeration) lookupType).asScope();
}
if (lookupScope != null) {
LookupData lookup = new LookupData(name, templateArgs, point);
lookup.fHeuristicBaseLookup = true;
try {
CPPSemantics.lookup(lookup, lookupScope);
IBinding[] foundBindings = lookup.getFoundBindings();
if (foundBindings.length > 0) {
if (specializationContext != null) {
foundBindings = specializeBindings(foundBindings, specializationContext, point);
}
return foundBindings;
IScope lookupScope = null;
if (lookupType instanceof ICPPClassType) {
lookupScope = ((ICPPClassType) lookupType).getCompositeScope();
} else if (lookupType instanceof ICPPEnumeration) {
lookupScope = ((ICPPEnumeration) lookupType).asScope();
}
if (lookupScope != null) {
LookupData lookup = new LookupData(name, templateArgs, point);
lookup.fHeuristicBaseLookup = true;
try {
CPPSemantics.lookup(lookup, lookupScope);
IBinding[] foundBindings = lookup.getFoundBindings();
if (foundBindings.length > 0) {
if (specializationContext != null) {
foundBindings = specializeBindings(foundBindings, specializationContext, point);
}
} catch (DOMException e) {
return foundBindings;
}
} catch (DOMException e) {
}
}
return IBinding.EMPTY_BINDING_ARRAY;
@ -265,7 +267,7 @@ public class HeuristicResolver {
*
* @param point the point of instantiation for lookups
*/
private static IType resolveUnknownType(ICPPUnknownType type, IASTNode point) {
public static IType resolveUnknownType(ICPPUnknownType type, IASTNode point) {
return resolveUnknownType(type, point, SemanticUtil.TDEF);
}
@ -327,6 +329,11 @@ public class HeuristicResolver {
functionType = resolveUnknownType((ICPPUnknownType) functionType, point);
}
return ExpressionTypes.typeFromFunctionCall(functionType);
} else if (evaluation instanceof EvalMemberAccess) {
IBinding member = ((EvalMemberAccess) evaluation).getMember();
// Presumably the type will be unknown. That's fine, it will be
// resolved during subsequent resolution rounds.
return typeForBinding(member);
}
// TODO(nathanridge): Handle more cases.
} else if (type instanceof ICPPUnknownMemberClass) {

View file

@ -1820,4 +1820,21 @@ public class CompletionTests extends AbstractContentAssistTest {
};
assertCompletionResults(fCursorOffset, expected, ID);
}
// template <int k>
// struct D {
// struct C {
// C* c;
// };
// C c;
// void f() {
// c.c->c->c./*cursor*/
// }
// };
public void testDependentMemberChain_bug478121() throws Exception {
setReplaceDotWithArrow(true);
final String[] expected = { "C", "c" };
assertCompletionResults(fCursorOffset, expected, ID);
assertDotReplacedWithArrow();
}
}

View file

@ -44,6 +44,8 @@ import org.eclipse.cdt.ui.text.ICCompletionProposal;
import org.eclipse.cdt.ui.text.contentassist.ContentAssistInvocationContext;
import org.eclipse.cdt.ui.text.contentassist.IProposalFilter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.HeuristicResolver;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.ui.preferences.ProposalFilterPreferencesUtil;
@ -273,6 +275,10 @@ public class CContentAssistProcessor extends ContentAssistProcessor {
IASTFieldReference ref = (IASTFieldReference) names[0].getParent();
IASTExpression ownerExpr = ref.getFieldOwner();
IType ownerExprType = SemanticUtil.getNestedType(ownerExpr.getExpressionType(), SemanticUtil.TDEF);
if (ownerExprType instanceof ICPPUnknownType) {
ownerExprType = HeuristicResolver.resolveUnknownType((ICPPUnknownType) ownerExprType,
names[0]);
}
if (ownerExprType instanceof IPointerType) {
context = replaceDotWithArrow(viewer, offset, isCompletion, context, activationChar);
}