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:
parent
453e429d5c
commit
6398b59947
3 changed files with 59 additions and 29 deletions
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue