1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-25 01:45:33 +02:00

Bug 421823 - Move CPPSemantics.heuristicallyFindConcreteScopeForType()

into a new class HeuristicResolver

Change-Id: I4a4948aa101192d4d74b385360bd94129ed71307
Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
This commit is contained in:
Nathan Ridge 2015-07-13 00:12:13 -04:00 committed by Sergey Prigogin
parent 515b275a48
commit 28ed0a3d7a
3 changed files with 71 additions and 47 deletions

View file

@ -31,7 +31,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.HeuristicResolver;
/**
* Models the scope represented by an unknown type (e.g.: typeof(template type parameter)).
@ -156,7 +156,7 @@ public class CPPUnknownTypeScope implements ICPPInternalUnknownScope {
if (lookup.isPrefixLookup()) {
// If name lookup is performed for the purpose of code completion in a dependent context,
// try to give some useful results heuristically.
IScope scope = CPPSemantics.heuristicallyFindConcreteScopeForType(fScopeType,
IScope scope = HeuristicResolver.findConcreteScopeForType(fScopeType,
lookup.getLookupPoint());
if (scope != null) {
return scope.getBindings(lookup);

View file

@ -91,7 +91,6 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IPointerType;
@ -4142,48 +4141,4 @@ public class CPPSemantics {
return binding;
}
/**
* Given a dependent type, heuristically try to find a concrete scope (i.e. not an unknown scope) for it.
* @param point the point of instantiation for name lookups
*/
public static IScope heuristicallyFindConcreteScopeForType(IType type, IASTNode point) {
if (type instanceof ICPPDeferredClassInstance) {
// If this scope is for a deferred-class-instance, use the scope of the primary template.
ICPPDeferredClassInstance instance = (ICPPDeferredClassInstance) type;
return instance.getClassTemplate().getCompositeScope();
} else if (type instanceof TypeOfDependentExpression) {
// If this scope is for the id-expression of a field reference, and the field owner
// is a deferred-class-instance, look up the field in the scope of the primary template,
// and use the scope of the resulting field type.
ICPPEvaluation evaluation = ((TypeOfDependentExpression) type).getEvaluation();
if (evaluation instanceof EvalID) {
EvalID evalId = (EvalID) evaluation;
ICPPEvaluation fieldOwner = evalId.getFieldOwner();
if (fieldOwner != null) {
IType fieldOwnerType = fieldOwner.getTypeOrFunctionSet(point);
if (fieldOwnerType instanceof ICPPDeferredClassInstance) {
ICPPDeferredClassInstance instance = (ICPPDeferredClassInstance) fieldOwnerType;
IScope scope = instance.getClassTemplate().getCompositeScope();
LookupData lookup = new LookupData(evalId.getName(), evalId.getTemplateArgs(), point);
lookup.qualified = evalId.isQualified();
try {
CPPSemantics.lookup(lookup, scope);
} catch (DOMException e) {
return null;
}
IBinding[] bindings = lookup.getFoundBindings();
if (bindings.length == 1 && bindings[0] instanceof IField) {
IType fieldType = ((IField) bindings[0]).getType();
if (fieldType instanceof ICompositeType) {
return ((ICompositeType) fieldType).getCompositeScope();
}
}
}
}
}
}
// TODO(nathanridge): Handle more cases.
return null;
}
}

View file

@ -0,0 +1,69 @@
/*******************************************************************************
* Copyright (c) 2015 Nathan Ridge.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nathan Ridge - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
public class HeuristicResolver {
/**
* Given a dependent type, heuristically tries to find a concrete scope (i.e. not an unknown scope)
* for it.
*
* @param point the point of instantiation for name lookups
*/
public static IScope findConcreteScopeForType(IType type, IASTNode point) {
if (type instanceof ICPPDeferredClassInstance) {
// If this scope is for a deferred-class-instance, use the scope of the primary template.
ICPPDeferredClassInstance instance = (ICPPDeferredClassInstance) type;
return instance.getClassTemplate().getCompositeScope();
} else if (type instanceof TypeOfDependentExpression) {
// If this scope is for the id-expression of a field reference, and the field owner
// is a deferred-class-instance, look up the field in the scope of the primary template,
// and use the scope of the resulting field type.
ICPPEvaluation evaluation = ((TypeOfDependentExpression) type).getEvaluation();
if (evaluation instanceof EvalID) {
EvalID evalId = (EvalID) evaluation;
ICPPEvaluation fieldOwner = evalId.getFieldOwner();
if (fieldOwner != null) {
IType fieldOwnerType = fieldOwner.getTypeOrFunctionSet(point);
if (fieldOwnerType instanceof ICPPDeferredClassInstance) {
ICPPDeferredClassInstance instance = (ICPPDeferredClassInstance) fieldOwnerType;
IScope scope = instance.getClassTemplate().getCompositeScope();
LookupData lookup = new LookupData(evalId.getName(), evalId.getTemplateArgs(), point);
lookup.qualified = evalId.isQualified();
try {
CPPSemantics.lookup(lookup, scope);
} catch (DOMException e) {
return null;
}
IBinding[] bindings = lookup.getFoundBindings();
if (bindings.length == 1 && bindings[0] instanceof IField) {
IType fieldType = ((IField) bindings[0]).getType();
if (fieldType instanceof ICompositeType) {
return ((ICompositeType) fieldType).getCompositeScope();
}
}
}
}
}
}
// TODO(nathanridge): Handle more cases.
return null;
}
}