1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-05 23:35:48 +02:00

Improve tracking of lookup points

ASTCache now sets the AST as the initial lookup point when invoking
an ASTRunnable.

In addition, OpenDeclarationsJob sets the selected node as a more precise
lookup point.

Change-Id: I9b32fccd80bc1b13e6da49a80a896b595784b868
This commit is contained in:
Nathan Ridge 2017-10-10 01:57:08 -04:00
parent 45101e2a64
commit 1054a38b44
2 changed files with 74 additions and 71 deletions

View file

@ -18,6 +18,7 @@ import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit; import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.ISafeRunnable;
@ -216,8 +217,10 @@ public class ASTCache {
return astRunnable.runOnAST(lang, ast); return astRunnable.runOnAST(lang, ast);
} }
try { try {
CPPSemantics.pushLookupPoint(ast);
return astRunnable.runOnAST(lang, ast); return astRunnable.runOnAST(lang, ast);
} finally { } finally {
CPPSemantics.popLookupPoint();
releaseSharedAST(ast); releaseSharedAST(ast);
} }
} catch (CoreException e) { } catch (CoreException e) {

View file

@ -252,92 +252,92 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
if (navigateViaCElements(fTranslationUnit.getCProject(), fIndex, implicitTargets)) if (navigateViaCElements(fTranslationUnit.getCProject(), fIndex, implicitTargets))
return Status.OK_STATUS; return Status.OK_STATUS;
} else { } else {
boolean found= false; CPPSemantics.pushLookupPoint(sourceName);
final IASTNode parent = sourceName.getParent(); try {
if (parent instanceof IASTPreprocessorIncludeStatement) { boolean found= false;
openInclude(((IASTPreprocessorIncludeStatement) parent)); final IASTNode parent = sourceName.getParent();
return Status.OK_STATUS; if (parent instanceof IASTPreprocessorIncludeStatement) {
} else if (parent instanceof ICPPASTTemplateId) { openInclude(((IASTPreprocessorIncludeStatement) parent));
sourceName = (IASTName) parent; return Status.OK_STATUS;
} } else if (parent instanceof ICPPASTTemplateId) {
NameKind kind = getNameKind(sourceName); sourceName = (IASTName) parent;
IBinding b = sourceName.resolveBinding();
IBinding[] bindings = new IBinding[] { b };
if (b instanceof IProblemBinding) {
IBinding[] candidateBindings = ((IProblemBinding) b).getCandidateBindings();
if (candidateBindings.length != 0) {
bindings = candidateBindings;
} }
} else if (kind == NameKind.DEFINITION && b instanceof IType && !(b instanceof ICPPClassTemplate)) { NameKind kind = getNameKind(sourceName);
// Don't navigate away from a type definition. IBinding b = sourceName.resolveBinding();
// Select the name at the current location instead. IBinding[] bindings = new IBinding[] { b };
// However, for a class template, it's useful to navigate to if (b instanceof IProblemBinding) {
// a forward declaration, as it may contain definitions of IBinding[] candidateBindings = ((IProblemBinding) b).getCandidateBindings();
// default arguments, while the definition may not. if (candidateBindings.length != 0) {
navigateToName(sourceName); bindings = candidateBindings;
return Status.OK_STATUS; }
} } else if (kind == NameKind.DEFINITION && b instanceof IType && !(b instanceof ICPPClassTemplate)) {
IName[] targets = IName.EMPTY_ARRAY; // Don't navigate away from a type definition.
String filename = ast.getFilePath(); // Select the name at the current location instead.
for (int i = 0; i < bindings.length; ++i) { // However, for a class template, it's useful to navigate to
IBinding binding = bindings[i]; // a forward declaration, as it may contain definitions of
if (binding instanceof ICPPUnknownBinding) { // default arguments, while the definition may not.
// We're not going to find declarations for an unknown binding. navigateToName(sourceName);
// To try to do something useful anyways, we try to heuristically return Status.OK_STATUS;
// resolve the unknown binding to one or more concrete bindings, }
// and use those instead. IName[] targets = IName.EMPTY_ARRAY;
try { String filename = ast.getFilePath();
CPPSemantics.pushLookupPoint(sourceName); for (int i = 0; i < bindings.length; ++i) {
IBinding binding = bindings[i];
if (binding instanceof ICPPUnknownBinding) {
// We're not going to find declarations for an unknown binding.
// To try to do something useful anyways, we try to heuristically
// resolve the unknown binding to one or more concrete bindings,
// and use those instead.
IBinding[] resolved = HeuristicResolver.resolveUnknownBinding( IBinding[] resolved = HeuristicResolver.resolveUnknownBinding(
(ICPPUnknownBinding) binding); (ICPPUnknownBinding) binding);
if (resolved.length > 0) { if (resolved.length > 0) {
bindings = ArrayUtil.addAll(bindings, resolved); bindings = ArrayUtil.addAll(bindings, resolved);
continue; continue;
} }
} finally {
CPPSemantics.popLookupPoint();
} }
} if (binding instanceof ICPPUsingDeclaration) {
if (binding instanceof ICPPUsingDeclaration) { // Skip using-declaration bindings. Their delegates will be among the implicit targets.
// Skip using-declaration bindings. Their delegates will be among the implicit targets. continue;
continue; }
} if (binding != null && !(binding instanceof IProblemBinding)) {
if (binding != null && !(binding instanceof IProblemBinding)) { IName[] names = findDeclNames(ast, kind, binding);
IName[] names = findDeclNames(ast, kind, binding); for (final IName name : names) {
for (final IName name : names) { if (name != null) {
if (name != null) { if (name instanceof IIndexName &&
if (name instanceof IIndexName && filename.equals(((IIndexName) name).getFileLocation().getFileName())) {
filename.equals(((IIndexName) name).getFileLocation().getFileName())) { // Exclude index names from the current file.
// Exclude index names from the current file. } else if (areOverlappingNames(name, sourceName)) {
} else if (areOverlappingNames(name, sourceName)) { // Exclude the current location.
// Exclude the current location. } else if (binding instanceof IParameter) {
} else if (binding instanceof IParameter) { if (isInSameFunction(sourceName, name)) {
if (isInSameFunction(sourceName, name)) { targets = ArrayUtil.append(targets, name);
}
} else if (binding instanceof ICPPTemplateParameter) {
if (isInSameTemplate(sourceName, name)) {
targets = ArrayUtil.append(targets, name);
}
} else {
targets = ArrayUtil.append(targets, name); targets = ArrayUtil.append(targets, name);
} }
} else if (binding instanceof ICPPTemplateParameter) {
if (isInSameTemplate(sourceName, name)) {
targets = ArrayUtil.append(targets, name);
}
} else {
targets = ArrayUtil.append(targets, name);
} }
} }
} }
} }
targets = ArrayUtil.trim(ArrayUtil.addAll(targets, implicitTargets));
if (navigateViaCElements(fTranslationUnit.getCProject(), fIndex, targets)) {
found= true;
} else {
// Leave old method as fallback for local variables, parameters and
// everything else not covered by ICElementHandle.
found = navigateOneLocation(ast, targets);
}
if (!found && !navigationFallBack(ast, sourceName, kind)) {
fAction.reportSymbolLookupFailure(new String(sourceName.toCharArray()));
}
return Status.OK_STATUS;
} finally {
CPPSemantics.popLookupPoint();
} }
targets = ArrayUtil.trim(ArrayUtil.addAll(targets, implicitTargets));
if (navigateViaCElements(fTranslationUnit.getCProject(), fIndex, targets)) {
found= true;
} else {
// Leave old method as fallback for local variables, parameters and
// everything else not covered by ICElementHandle.
found = navigateOneLocation(ast, targets);
}
if (!found && !navigationFallBack(ast, sourceName, kind)) {
fAction.reportSymbolLookupFailure(new String(sourceName.toCharArray()));
}
return Status.OK_STATUS;
} }
// No enclosing name, check if we're in an include statement // No enclosing name, check if we're in an include statement