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:
parent
45101e2a64
commit
1054a38b44
2 changed files with 74 additions and 71 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue