[CodeComplete] Tweak completion for else.

If an `if` statement uses braces for its `then` block, suggest braces for the `else` and `else if` completion blocks, Otherwise don't suggest them.

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D82626
This commit is contained in:
Nathan James 2020-06-30 16:48:23 +01:00
parent 2efba0e812
commit 8ba4867c27
No known key found for this signature in database
GPG Key ID: CC007AFCDA90AA5F
4 changed files with 52 additions and 18 deletions

View File

@ -11980,7 +11980,7 @@ public:
void CodeCompleteDesignator(const QualType BaseType,
llvm::ArrayRef<Expr *> InitExprs,
const Designation &D);
void CodeCompleteAfterIf(Scope *S);
void CodeCompleteAfterIf(Scope *S, bool IsBracedThen);
void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext,
bool IsUsingDeclaration, QualType BaseType,

View File

@ -1348,6 +1348,8 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
if (IsConstexpr)
ConstexprCondition = Cond.getKnownValue();
bool IsBracedThen = Tok.is(tok::l_brace);
// C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
// there is no compound stmt. C90 does not have this clause. We only do this
// if the body isn't a compound statement to avoid push/pop in common cases.
@ -1366,7 +1368,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
// would have to notify ParseStatement not to create a new scope. It's
// simpler to let it create a new scope.
//
ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, IsBracedThen);
MisleadingIndentationChecker MIChecker(*this, MSK_if, IfLoc);
@ -1427,7 +1429,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
// Pop the 'else' scope if needed.
InnerScope.Exit();
} else if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteAfterIf(getCurScope());
Actions.CodeCompleteAfterIf(getCurScope(), IsBracedThen);
cutOffParsing();
return StmtError();
} else if (InnerStatementTrailingElseLoc.isValid()) {

View File

@ -5759,7 +5759,7 @@ void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
CodeCompleteExpression(S, Data);
}
void Sema::CodeCompleteAfterIf(Scope *S) {
void Sema::CodeCompleteAfterIf(Scope *S, bool IsBracedThen) {
ResultBuilder Results(*this, CodeCompleter->getAllocator(),
CodeCompleter->getCodeCompletionTUInfo(),
mapCodeCompletionContext(*this, PCC_Statement));
@ -5776,15 +5776,25 @@ void Sema::CodeCompleteAfterIf(Scope *S) {
// "else" block
CodeCompletionBuilder Builder(Results.getAllocator(),
Results.getCodeCompletionTUInfo());
auto AddElseBodyPattern = [&] {
if (IsBracedThen) {
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
Builder.AddPlaceholderChunk("statements");
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
} else {
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
Builder.AddPlaceholderChunk("statement");
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
}
};
Builder.AddTypedTextChunk("else");
if (Results.includeCodePatterns()) {
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
Builder.AddPlaceholderChunk("statements");
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
}
if (Results.includeCodePatterns())
AddElseBodyPattern();
Results.AddResult(Builder.TakeString());
// "else if" block
@ -5797,12 +5807,7 @@ void Sema::CodeCompleteAfterIf(Scope *S) {
Builder.AddPlaceholderChunk("expression");
Builder.AddChunk(CodeCompletionString::CK_RightParen);
if (Results.includeCodePatterns()) {
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
Builder.AddPlaceholderChunk("statements");
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
AddElseBodyPattern();
}
Results.AddResult(Builder.TakeString());

View File

@ -74,3 +74,30 @@ int Cls::*memptr_return() {
// RUN: %clang_cc1 -fsyntax-only -std=c++03 -code-completion-patterns -code-completion-at=%s:37:1 %s -o - | FileCheck -check-prefix=RETURN-PTR-STD03 %s
// RUN: %clang_cc1 -fsyntax-only -std=c++03 -code-completion-patterns -code-completion-at=%s:41:1 %s -o - | FileCheck -check-prefix=RETURN-PTR-STD03 %s
// RETURN-PTR-STD03-NOT: COMPLETION: Pattern : return nullptr;
void something();
void unbraced_if() {
if (true)
something();
// line 83
}
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:83:3 %s -o - | FileCheck -check-prefix=UNBRACED-IF %s
// UNBRACED-IF: COMPLETION: Pattern : else
// UNBRACED-IF-NEXT: <#statement#>;
// UNBRACED-IF: COMPLETION: Pattern : else if (<#condition#>)
// UNBRACED-IF-NEXT: <#statement#>;
void braced_if() {
if (true) {
something();
}
// line 95
}
// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:95:3 %s -o - | FileCheck -check-prefix=BRACED-IF %s
// BRACED-IF: COMPLETION: Pattern : else {
// BRACED-IF-NEXT: <#statements#>
// BRACED-IF-NEXT: }
// BRACED-IF: COMPLETION: Pattern : else if (<#condition#>) {
// BRACED-IF-NEXT: <#statements#>
// BRACED-IF-NEXT: }