diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownTypeScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownTypeScope.java index b4e8f00daa7..cac4422bea0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownTypeScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownTypeScope.java @@ -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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index be938c1e1b4..e777ba1c0aa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -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; - } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/HeuristicResolver.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/HeuristicResolver.java new file mode 100644 index 00000000000..6a0a3c013f6 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/HeuristicResolver.java @@ -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; + } +}