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:
parent
515b275a48
commit
28ed0a3d7a
3 changed files with 71 additions and 47 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue