forked from qt-creator/qt-creator
CppEditor: Fix Follow Symbol on trailing return type
For the function
auto foo() -> @Foo {}
whereas '@' denotes the cursor position, we detected the expression
under cursor as "foo() -> Foo" and tried to resolve the member "Foo"
within the type of "foo()".
ExpressionUnderCursor can't detect whether we are on a trailing return
type since it only looks at the tokens. Thus, check also the AST.
Task-number: QTCREATORBUG-13096
Change-Id: Ifc14e402fb70e722940e5fa13f1eaaa9973362e4
Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
This commit is contained in:
@@ -395,11 +395,11 @@ Symbol *findDefinition(Symbol *symbol, const Snapshot &snapshot, SymbolFinder *s
|
||||
return symbolFinder->findMatchingDefinition(symbol, snapshot);
|
||||
}
|
||||
|
||||
void maybeAppendArgumentOrParameterList(QString *expression, const QTextCursor &textCursor)
|
||||
bool maybeAppendArgumentOrParameterList(QString *expression, const QTextCursor &textCursor)
|
||||
{
|
||||
QTC_ASSERT(expression, return);
|
||||
QTC_ASSERT(expression, return false);
|
||||
QTextDocument *textDocument = textCursor.document();
|
||||
QTC_ASSERT(textDocument, return);
|
||||
QTC_ASSERT(textDocument, return false);
|
||||
|
||||
// Skip white space
|
||||
QTextCursor cursor(textCursor);
|
||||
@@ -407,20 +407,62 @@ void maybeAppendArgumentOrParameterList(QString *expression, const QTextCursor &
|
||||
&& cursor.movePosition(QTextCursor::NextCharacter)) {
|
||||
}
|
||||
|
||||
// Find/Include (...)
|
||||
// Find/Include "(arg1, arg2, ...)"
|
||||
if (textDocument->characterAt(cursor.position()) == QLatin1Char('(')) {
|
||||
if (TextBlockUserData::findNextClosingParenthesis(&cursor, true))
|
||||
if (TextBlockUserData::findNextClosingParenthesis(&cursor, true)) {
|
||||
expression->append(cursor.selectedText());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isCursorOnTrailingReturnType(const QList<AST *> &astPath)
|
||||
{
|
||||
for (auto it = astPath.cend() - 1, begin = astPath.cbegin(); it >= begin; --it) {
|
||||
const auto nextIt = it + 1;
|
||||
const auto nextNextIt = nextIt + 1;
|
||||
if (nextNextIt != astPath.cend() && (*it)->asTrailingReturnType()) {
|
||||
return (*nextIt)->asNamedTypeSpecifier()
|
||||
&& ((*nextNextIt)->asSimpleName()
|
||||
|| (*nextNextIt)->asQualifiedName()
|
||||
|| (*nextNextIt)->asTemplateId());
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void maybeFixExpressionInTrailingReturnType(QString *expression,
|
||||
const QTextCursor &textCursor,
|
||||
const Document::Ptr documentFromSemanticInfo)
|
||||
{
|
||||
QTC_ASSERT(expression, return);
|
||||
|
||||
if (!documentFromSemanticInfo)
|
||||
return;
|
||||
|
||||
const QString arrow = QLatin1String("->");
|
||||
const int arrowPosition = expression->lastIndexOf(arrow);
|
||||
if (arrowPosition != -1) {
|
||||
ASTPath astPathFinder(documentFromSemanticInfo);
|
||||
const QList<AST *> astPath = astPathFinder(textCursor);
|
||||
|
||||
if (isCursorOnTrailingReturnType(astPath))
|
||||
*expression = expression->mid(arrowPosition + arrow.size()).trimmed();
|
||||
}
|
||||
}
|
||||
|
||||
QString expressionUnderCursorAsString(const QTextCursor &textCursor,
|
||||
const Document::Ptr documentFromSemanticInfo,
|
||||
const LanguageFeatures &features)
|
||||
{
|
||||
ExpressionUnderCursor expressionUnderCursor(features);
|
||||
QString expression = expressionUnderCursor(textCursor);
|
||||
|
||||
maybeAppendArgumentOrParameterList(&expression, textCursor);
|
||||
if (!maybeAppendArgumentOrParameterList(&expression, textCursor))
|
||||
maybeFixExpressionInTrailingReturnType(&expression, textCursor, documentFromSemanticInfo);
|
||||
|
||||
return expression;
|
||||
}
|
||||
@@ -644,7 +686,8 @@ TextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor &curs
|
||||
|
||||
// Evaluate the type of the expression under the cursor
|
||||
QTC_CHECK(document == tc.document());
|
||||
const QString expression = expressionUnderCursorAsString(tc, features);
|
||||
const QString expression = expressionUnderCursorAsString(tc, documentFromSemanticInfo,
|
||||
features);
|
||||
const QSharedPointer<TypeOfExpression> typeOfExpression(new TypeOfExpression);
|
||||
typeOfExpression->init(doc, snapshot);
|
||||
// make possible to instantiate templates
|
||||
|
||||
Reference in New Issue
Block a user