ClangCodeModel: Implement declaration/definition switch via clangd

Change-Id: I522a415d76fbc5332e5cc1fdfd2d7ab19cb9ed64
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2021-05-31 15:57:44 +02:00
parent de6c7696d2
commit 41dafc8132
11 changed files with 392 additions and 80 deletions

View File

@@ -796,6 +796,83 @@ void FollowSymbolUnderCursor::findLink(
processLinkCallback(Link());
}
void FollowSymbolUnderCursor::switchDeclDef(
const CursorInEditor &data,
Utils::ProcessLinkCallback &&processLinkCallback,
const CPlusPlus::Snapshot &snapshot,
const CPlusPlus::Document::Ptr &documentFromSemanticInfo,
SymbolFinder *symbolFinder)
{
if (!documentFromSemanticInfo) {
processLinkCallback({});
return;
}
// Find function declaration or definition under cursor
Function *functionDefinitionSymbol = nullptr;
Symbol *functionDeclarationSymbol = nullptr;
Symbol *declarationSymbol = nullptr;
ASTPath astPathFinder(documentFromSemanticInfo);
const QList<AST *> astPath = astPathFinder(data.cursor());
for (AST *ast : astPath) {
if (FunctionDefinitionAST *functionDefinitionAST = ast->asFunctionDefinition()) {
if ((functionDefinitionSymbol = functionDefinitionAST->symbol))
break; // Function definition found!
} else if (SimpleDeclarationAST *simpleDeclaration = ast->asSimpleDeclaration()) {
if (List<Symbol *> *symbols = simpleDeclaration->symbols) {
if (Symbol *symbol = symbols->value) {
if (symbol->isDeclaration()) {
declarationSymbol = symbol;
if (symbol->type()->isFunctionType()) {
functionDeclarationSymbol = symbol;
break; // Function declaration found!
}
}
}
}
}
}
// Link to function definition/declaration
Utils::Link symbolLink;
if (functionDeclarationSymbol) {
Symbol *symbol = symbolFinder->findMatchingDefinition(functionDeclarationSymbol, snapshot);
if (symbol)
symbolLink = symbol->toLink();
} else if (declarationSymbol) {
Symbol *symbol = symbolFinder->findMatchingVarDefinition(declarationSymbol, snapshot);
if (symbol)
symbolLink = symbol->toLink();
} else if (functionDefinitionSymbol) {
LookupContext context(documentFromSemanticInfo, snapshot);
ClassOrNamespace *binding = context.lookupType(functionDefinitionSymbol);
const QList<LookupItem> declarations
= context.lookup(functionDefinitionSymbol->name(),
functionDefinitionSymbol->enclosingScope());
QList<Symbol *> best;
foreach (const LookupItem &r, declarations) {
if (Symbol *decl = r.declaration()) {
if (Function *funTy = decl->type()->asFunctionType()) {
if (funTy->match(functionDefinitionSymbol)) {
if (decl != functionDefinitionSymbol && binding == r.binding())
best.prepend(decl);
else
best.append(decl);
}
}
}
}
if (best.isEmpty())
return;
symbolLink = best.first()->toLink();
}
processLinkCallback(symbolLink);
}
QSharedPointer<VirtualFunctionAssistProvider> FollowSymbolUnderCursor::virtualFunctionAssistProvider()
{
return m_virtualFunctionAssistProvider;

View File

@@ -44,6 +44,12 @@ public:
CppTools::SymbolFinder *symbolFinder,
bool inNextSplit) override;
void switchDeclDef(const CursorInEditor &data,
Utils::ProcessLinkCallback &&processLinkCallback,
const CPlusPlus::Snapshot &snapshot,
const CPlusPlus::Document::Ptr &documentFromSemanticInfo,
SymbolFinder *symbolFinder) override;
QSharedPointer<VirtualFunctionAssistProvider> virtualFunctionAssistProvider();
void setVirtualFunctionAssistProvider(
const QSharedPointer<VirtualFunctionAssistProvider> &provider);

View File

@@ -472,6 +472,11 @@ RefactoringEngineInterface *CppModelManager::builtinRefactoringEngine()
return instance()->d->m_refactoringEngines.value(RefactoringEngineType::BuiltIn);
}
FollowSymbolInterface &CppModelManager::builtinFollowSymbol()
{
return instance()->d->m_builtinModelManagerSupport->followSymbolInterface();
}
template<class FilterClass>
static void setFilter(std::unique_ptr<FilterClass> &filter,
std::unique_ptr<FilterClass> &&newFilter)

View File

@@ -218,6 +218,7 @@ public:
RefactoringEngineInterface *refactoringEngine);
static void removeRefactoringEngine(RefactoringEngineType type);
static RefactoringEngineInterface *builtinRefactoringEngine();
static FollowSymbolInterface &builtinFollowSymbol();
void setLocatorFilter(std::unique_ptr<Core::ILocatorFilter> &&filter);
void setClassesFilter(std::unique_ptr<Core::ILocatorFilter> &&filter);

View File

@@ -49,6 +49,11 @@ public:
const CPlusPlus::Document::Ptr &documentFromSemanticInfo,
SymbolFinder *symbolFinder,
bool inNextSplit) = 0;
virtual void switchDeclDef(const CursorInEditor &data,
Utils::ProcessLinkCallback &&processLinkCallback,
const CPlusPlus::Snapshot &snapshot,
const CPlusPlus::Document::Ptr &documentFromSemanticInfo,
SymbolFinder *symbolFinder) = 0;
};
} // namespace CppTools