forked from qt-creator/qt-creator
CppEditor: Clean up cppvirtualfunctionassistprovider.cpp
- Moves the findMatchingClassDeclaration() call from FollowSymbolUnderCursor::findLink into VirtualFunctionsAssistProcessor since we already have a SymbolFinder there - Make canLookupVirtualFunctionOverrides a class member because we plan to add some methods - Better parameter names/order for FunctionHelper::overrides() Change-Id: I0a93ff5445352d47e808adad45485e520f06946e Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
@@ -55,22 +55,60 @@ typedef BaseTextEditorWidget::Link Link;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool lookupVirtualFunctionOverrides(TypeOfExpression &typeOfExpression,
|
class VirtualFunctionHelper {
|
||||||
const Document::Ptr &document,
|
public:
|
||||||
const Function *function,
|
VirtualFunctionHelper(const TypeOfExpression &typeOfExpression,
|
||||||
Scope *scope,
|
Scope *scope,
|
||||||
const Snapshot &snapshot)
|
const Document::Ptr &document,
|
||||||
{
|
const Snapshot &snapshot);
|
||||||
if (!document || !function || !scope || scope->isClass() || snapshot.isEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ExpressionAST *expressionAST = typeOfExpression.expressionAST();
|
bool canLookupVirtualFunctionOverrides(const Function *function) const;
|
||||||
if (!expressionAST)
|
|
||||||
|
private:
|
||||||
|
VirtualFunctionHelper();
|
||||||
|
Q_DISABLE_COPY(VirtualFunctionHelper)
|
||||||
|
|
||||||
|
ExpressionAST *getBaseExpressionAST() const
|
||||||
|
{
|
||||||
|
if (!m_expressionAST)
|
||||||
|
return 0;
|
||||||
|
CallAST *callAST = m_expressionAST->asCall();
|
||||||
|
if (!callAST)
|
||||||
|
return 0;
|
||||||
|
if (ExpressionAST *baseExpressionAST = callAST->base_expression)
|
||||||
|
return baseExpressionAST;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const QSharedPointer<TypeOfExpression> m_typeOfExpression;
|
||||||
|
ExpressionAST *m_expressionAST;
|
||||||
|
const Document::Ptr m_expressionDocument;
|
||||||
|
Scope *m_scope;
|
||||||
|
const Document::Ptr &m_document;
|
||||||
|
const Snapshot &m_snapshot;
|
||||||
|
};
|
||||||
|
|
||||||
|
VirtualFunctionHelper::VirtualFunctionHelper(const TypeOfExpression &typeOfExpression,
|
||||||
|
Scope *scope,
|
||||||
|
const Document::Ptr &document,
|
||||||
|
const Snapshot &snapshot)
|
||||||
|
: m_expressionAST(typeOfExpression.expressionAST())
|
||||||
|
, m_expressionDocument(typeOfExpression.context().expressionDocument())
|
||||||
|
, m_scope(scope)
|
||||||
|
, m_document(document)
|
||||||
|
, m_snapshot(snapshot)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualFunctionHelper::canLookupVirtualFunctionOverrides(const Function *function) const
|
||||||
|
{
|
||||||
|
if (!m_expressionDocument || !m_document || !function || !m_scope || m_scope->isClass()
|
||||||
|
|| m_snapshot.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
CallAST *callAST = expressionAST->asCall();
|
}
|
||||||
if (!callAST)
|
|
||||||
return false;
|
ExpressionAST *baseExpressionAST = getBaseExpressionAST();
|
||||||
ExpressionAST *baseExpressionAST = callAST->base_expression;
|
|
||||||
if (!baseExpressionAST)
|
if (!baseExpressionAST)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -79,23 +117,23 @@ bool lookupVirtualFunctionOverrides(TypeOfExpression &typeOfExpression,
|
|||||||
if (IdExpressionAST *idExpressionAST = baseExpressionAST->asIdExpression()) {
|
if (IdExpressionAST *idExpressionAST = baseExpressionAST->asIdExpression()) {
|
||||||
NameAST *name = idExpressionAST->name;
|
NameAST *name = idExpressionAST->name;
|
||||||
const bool nameIsQualified = name && name->asQualifiedName();
|
const bool nameIsQualified = name && name->asQualifiedName();
|
||||||
result = !nameIsQualified && FunctionHelper::isVirtualFunction(function, snapshot);
|
result = !nameIsQualified && FunctionHelper::isVirtualFunction(function, m_snapshot);
|
||||||
} else if (MemberAccessAST *memberAccessAST = baseExpressionAST->asMemberAccess()) {
|
} else if (MemberAccessAST *memberAccessAST = baseExpressionAST->asMemberAccess()) {
|
||||||
NameAST *name = memberAccessAST->member_name;
|
NameAST *name = memberAccessAST->member_name;
|
||||||
const bool nameIsQualified = name && name->asQualifiedName();
|
const bool nameIsQualified = name && name->asQualifiedName();
|
||||||
if (!nameIsQualified && FunctionHelper::isVirtualFunction(function, snapshot)) {
|
if (!nameIsQualified && FunctionHelper::isVirtualFunction(function, m_snapshot)) {
|
||||||
const Document::Ptr expressionDocument
|
TranslationUnit *unit = m_expressionDocument->translationUnit();
|
||||||
= typeOfExpression.context().expressionDocument();
|
|
||||||
QTC_ASSERT(expressionDocument, return false);
|
|
||||||
TranslationUnit *unit = expressionDocument->translationUnit();
|
|
||||||
QTC_ASSERT(unit, return false);
|
QTC_ASSERT(unit, return false);
|
||||||
const int accessTokenKind = unit->tokenKind(memberAccessAST->access_token);
|
const int accessTokenKind = unit->tokenKind(memberAccessAST->access_token);
|
||||||
|
|
||||||
if (accessTokenKind == T_ARROW) {
|
if (accessTokenKind == T_ARROW) {
|
||||||
result = true;
|
result = true;
|
||||||
} else if (accessTokenKind == T_DOT) {
|
} else if (accessTokenKind == T_DOT) {
|
||||||
|
TypeOfExpression typeOfExpression;
|
||||||
|
typeOfExpression.init(m_document, m_snapshot);
|
||||||
|
typeOfExpression.setExpandTemplates(true);
|
||||||
const QList<LookupItem> items = typeOfExpression.reference(
|
const QList<LookupItem> items = typeOfExpression.reference(
|
||||||
memberAccessAST->base_expression, document, scope);
|
memberAccessAST->base_expression, m_document, m_scope);
|
||||||
if (!items.isEmpty()) {
|
if (!items.isEmpty()) {
|
||||||
const LookupItem item = items.first();
|
const LookupItem item = items.first();
|
||||||
if (Symbol *declaration = item.declaration())
|
if (Symbol *declaration = item.declaration())
|
||||||
@@ -552,13 +590,10 @@ BaseTextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor &
|
|||||||
|
|
||||||
// Consider to show a pop-up displaying overrides for the function
|
// Consider to show a pop-up displaying overrides for the function
|
||||||
Function *function = symbol->type()->asFunctionType();
|
Function *function = symbol->type()->asFunctionType();
|
||||||
|
VirtualFunctionHelper helper(*typeOfExpression, scope, doc, snapshot);
|
||||||
|
|
||||||
if (lookupVirtualFunctionOverrides(*typeOfExpression, doc, function, scope, snapshot)) {
|
if (helper.canLookupVirtualFunctionOverrides(function)) {
|
||||||
Class *klass = symbolFinder->findMatchingClassDeclaration(function, snapshot);
|
|
||||||
QTC_CHECK(klass);
|
|
||||||
|
|
||||||
VirtualFunctionAssistProvider::Parameters params;
|
VirtualFunctionAssistProvider::Parameters params;
|
||||||
params.startClass = klass;
|
|
||||||
params.function = function;
|
params.function = function;
|
||||||
params.typeOfExpression = typeOfExpression;
|
params.typeOfExpression = typeOfExpression;
|
||||||
params.snapshot = snapshot;
|
params.snapshot = snapshot;
|
||||||
|
|||||||
@@ -132,12 +132,16 @@ public:
|
|||||||
|
|
||||||
IAssistProposal *perform(const IAssistInterface *)
|
IAssistProposal *perform(const IAssistInterface *)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_params.startClass, return 0);
|
|
||||||
QTC_ASSERT(m_params.function, return 0);
|
QTC_ASSERT(m_params.function, return 0);
|
||||||
QTC_ASSERT(!m_params.snapshot.isEmpty(), return 0);
|
QTC_ASSERT(!m_params.snapshot.isEmpty(), return 0);
|
||||||
|
|
||||||
|
Class *functionsClass = m_finder.findMatchingClassDeclaration(m_params.function,
|
||||||
|
m_params.snapshot);
|
||||||
|
if (!functionsClass)
|
||||||
|
return 0;
|
||||||
|
|
||||||
const QList<Symbol *> overrides
|
const QList<Symbol *> overrides
|
||||||
= FunctionHelper::overrides(m_params.startClass, m_params.function, m_params.snapshot);
|
= FunctionHelper::overrides(m_params.function, functionsClass, m_params.snapshot);
|
||||||
if (overrides.isEmpty())
|
if (overrides.isEmpty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -250,19 +254,19 @@ bool FunctionHelper::isPureVirtualFunction(const Function *function, const Snaps
|
|||||||
return isVirtualFunction_helper(function, snapshot, PureVirtual);
|
return isVirtualFunction_helper(function, snapshot, PureVirtual);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Symbol *> FunctionHelper::overrides(Class *startClass, Function *function,
|
QList<Symbol *> FunctionHelper::overrides(Function *function, Class *functionsClass,
|
||||||
const Snapshot &snapshot)
|
const Snapshot &snapshot)
|
||||||
{
|
{
|
||||||
QList<Symbol *> result;
|
QList<Symbol *> result;
|
||||||
QTC_ASSERT(startClass && function, return result);
|
QTC_ASSERT(function && functionsClass, return result);
|
||||||
|
|
||||||
FullySpecifiedType referenceType = function->type();
|
FullySpecifiedType referenceType = function->type();
|
||||||
const Name *referenceName = function->name();
|
const Name *referenceName = function->name();
|
||||||
QTC_ASSERT(referenceName && referenceType.isValid(), return result);
|
QTC_ASSERT(referenceName && referenceType.isValid(), return result);
|
||||||
|
|
||||||
// Find overrides
|
// Find overrides
|
||||||
CppEditor::Internal::CppClass cppClass = CppClass(startClass);
|
CppEditor::Internal::CppClass cppClass = CppClass(functionsClass);
|
||||||
cppClass.lookupDerived(startClass, snapshot);
|
cppClass.lookupDerived(functionsClass, snapshot);
|
||||||
|
|
||||||
QList<CppClass> l;
|
QList<CppClass> l;
|
||||||
l << cppClass;
|
l << cppClass;
|
||||||
|
|||||||
@@ -48,9 +48,8 @@ public:
|
|||||||
VirtualFunctionAssistProvider();
|
VirtualFunctionAssistProvider();
|
||||||
|
|
||||||
struct Parameters {
|
struct Parameters {
|
||||||
Parameters() : startClass(0), function(0), cursorPosition(-1), openInNextSplit(false) {}
|
Parameters() : function(0), cursorPosition(-1), openInNextSplit(false) {}
|
||||||
|
|
||||||
CPlusPlus::Class *startClass;
|
|
||||||
CPlusPlus::Function *function;
|
CPlusPlus::Function *function;
|
||||||
QSharedPointer<CPlusPlus::TypeOfExpression> typeOfExpression; // Keeps instantiated symbols.
|
QSharedPointer<CPlusPlus::TypeOfExpression> typeOfExpression; // Keeps instantiated symbols.
|
||||||
CPlusPlus::Snapshot snapshot;
|
CPlusPlus::Snapshot snapshot;
|
||||||
@@ -79,8 +78,8 @@ public:
|
|||||||
static bool isPureVirtualFunction(const CPlusPlus::Function *function,
|
static bool isPureVirtualFunction(const CPlusPlus::Function *function,
|
||||||
const CPlusPlus::Snapshot &snapshot);
|
const CPlusPlus::Snapshot &snapshot);
|
||||||
|
|
||||||
static QList<CPlusPlus::Symbol *> overrides(CPlusPlus::Class *startClass,
|
static QList<CPlusPlus::Symbol *> overrides(CPlusPlus::Function *function,
|
||||||
CPlusPlus::Function *function,
|
CPlusPlus::Class *functionsClass,
|
||||||
const CPlusPlus::Snapshot &snapshot);
|
const CPlusPlus::Snapshot &snapshot);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user