forked from qt-creator/qt-creator
ClangCodeModel: Implement declaration/definition switch via clangd
Change-Id: I522a415d76fbc5332e5cc1fdfd2d7ab19cb9ed64 Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user