forked from qt-creator/qt-creator
C++: Do not auto-insert '}' after class/struct/enum/union
...when typing the opening brace. This restores the initial behavior from version 4.3. Not auto-inserting the closing brace allows the user to press Enter to get "};" completed. Change-Id: I8c62a08433a947e28f0555338a5fb8eeeae11bea Task-number: QTCREATORBUG-18872 Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
@@ -314,6 +314,50 @@ static bool allowAutoClosingBraceByLookahead(const QTextCursor &cursor)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isRecordLikeToken(const Token &token)
|
||||||
|
{
|
||||||
|
return token.is(T_CLASS)
|
||||||
|
|| token.is(T_STRUCT)
|
||||||
|
|| token.is(T_UNION)
|
||||||
|
|| token.is(T_ENUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isRecordLikeToken(const BackwardsScanner &tokens, int index)
|
||||||
|
{
|
||||||
|
if (index < tokens.size() - 1)
|
||||||
|
return isRecordLikeToken(tokens[index]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool recordLikeHasToFollowToken(const Token &token)
|
||||||
|
{
|
||||||
|
return token.is(T_SEMICOLON)
|
||||||
|
|| token.is(T_LBRACE) // e.g. class X {
|
||||||
|
|| token.is(T_RBRACE) // e.g. function definition
|
||||||
|
|| token.is(T_EOF_SYMBOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool recordLikeMightFollowToken(const Token &token)
|
||||||
|
{
|
||||||
|
return token.is(T_IDENTIFIER) // e.g. macro like QT_END_NAMESPACE
|
||||||
|
|| token.is(T_ANGLE_STRING_LITERAL) // e.g. #include directive
|
||||||
|
|| token.is(T_STRING_LITERAL) // e.g. #include directive
|
||||||
|
|| token.isComment();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isAfterRecordLikeDefinition(const BackwardsScanner &tokens, int index)
|
||||||
|
{
|
||||||
|
for (;; --index) {
|
||||||
|
if (recordLikeHasToFollowToken(tokens[index]))
|
||||||
|
return isRecordLikeToken(tokens, index + 1);
|
||||||
|
|
||||||
|
if (recordLikeMightFollowToken(tokens[index]) && isRecordLikeToken(tokens, index + 1))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool allowAutoClosingBrace(const QTextCursor &cursor,
|
static bool allowAutoClosingBrace(const QTextCursor &cursor,
|
||||||
MatchingText::IsNextBlockDeeperIndented isNextIndented)
|
MatchingText::IsNextBlockDeeperIndented isNextIndented)
|
||||||
{
|
{
|
||||||
@@ -329,6 +373,9 @@ static bool allowAutoClosingBrace(const QTextCursor &cursor,
|
|||||||
if (isAfterNamespaceDefinition(tokens, index))
|
if (isAfterNamespaceDefinition(tokens, index))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (isAfterRecordLikeDefinition(tokens, index))
|
||||||
|
return false;
|
||||||
|
|
||||||
const QTextBlock block = cursor.block();
|
const QTextBlock block = cursor.block();
|
||||||
if (isEmptyOrWhitespace(block.text()))
|
if (isEmptyOrWhitespace(block.text()))
|
||||||
return allowAutoClosingBraceAtEmptyLine(cursor.block(), isNextIndented);
|
return allowAutoClosingBraceAtEmptyLine(cursor.block(), isNextIndented);
|
||||||
@@ -555,7 +602,7 @@ QString MatchingText::insertParagraphSeparator(const QTextCursor &cursor)
|
|||||||
if (current.is(T_EOF_SYMBOL))
|
if (current.is(T_EOF_SYMBOL))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (current.is(T_CLASS) || current.is(T_STRUCT) || current.is(T_UNION) || current.is(T_ENUM)) {
|
if (isRecordLikeToken(current)) {
|
||||||
// found a class key.
|
// found a class key.
|
||||||
QString str = QLatin1String("};");
|
QString str = QLatin1String("};");
|
||||||
|
|
||||||
|
@@ -256,6 +256,34 @@ TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotBeforeNestedName
|
|||||||
ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{"));
|
ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotBeforeClass)
|
||||||
|
{
|
||||||
|
const Document document("class X @");
|
||||||
|
|
||||||
|
ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotBeforeStruct)
|
||||||
|
{
|
||||||
|
const Document document("struct X @");
|
||||||
|
|
||||||
|
ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotBeforeEnum)
|
||||||
|
{
|
||||||
|
const Document document("enum X @");
|
||||||
|
|
||||||
|
ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotBeforeUnion)
|
||||||
|
{
|
||||||
|
const Document document("union X @");
|
||||||
|
|
||||||
|
ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{"));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotWithinString)
|
TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotWithinString)
|
||||||
{
|
{
|
||||||
const Document document("\"a@b\"");
|
const Document document("\"a@b\"");
|
||||||
|
Reference in New Issue
Block a user