Skip to content

Commit ed0d5dd

Browse files
authored
Merge pull request #26888 from nathawes/pr-disable-diagnostics-for-code-completion-2
2 parents dcd0893 + feb48a6 commit ed0d5dd

13 files changed

+65
-35
lines changed

include/swift/AST/DiagnosticEngine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ namespace swift {
657657
}
658658

659659
/// Return all \c DiagnosticConsumers.
660-
ArrayRef<DiagnosticConsumer *> getConsumers() {
660+
ArrayRef<DiagnosticConsumer *> getConsumers() const {
661661
return Consumers;
662662
}
663663

include/swift/AST/DiagnosticSuppression.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class DiagnosticSuppression {
3737
public:
3838
explicit DiagnosticSuppression(DiagnosticEngine &diags);
3939
~DiagnosticSuppression();
40+
static bool isEnabled(const DiagnosticEngine &diags);
4041
};
4142

4243
}

include/swift/Basic/SourceManager.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,6 @@ class SourceManager {
103103
rangeContainsTokenLoc(Enclosing, Inner.End);
104104
}
105105

106-
/// Returns true if range \p R contains the code-completion location, if any.
107-
bool rangeContainsCodeCompletionLoc(SourceRange R) const {
108-
return CodeCompletionBufferID
109-
? rangeContainsTokenLoc(R, getCodeCompletionLoc())
110-
: false;
111-
}
112-
113106
/// Returns the buffer ID for the specified *valid* location.
114107
///
115108
/// Because a valid source location always corresponds to a source buffer,

lib/AST/DiagnosticEngine.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,10 @@ DiagnosticSuppression::~DiagnosticSuppression() {
950950
diags.addConsumer(*consumer);
951951
}
952952

953+
bool DiagnosticSuppression::isEnabled(const DiagnosticEngine &diags) {
954+
return diags.getConsumers().empty();
955+
}
956+
953957
BufferIndirectlyCausingDiagnosticRAII::BufferIndirectlyCausingDiagnosticRAII(
954958
const SourceFile &SF)
955959
: Diags(SF.getASTContext().Diags) {

lib/IDE/ExprContextAnalysis.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,11 @@ static bool collectPossibleCalleesForApply(
384384
} else if (auto *UDE = dyn_cast<UnresolvedDotExpr>(fnExpr)) {
385385
collectPossibleCalleesByQualifiedLookup(
386386
DC, UDE->getBase(), UDE->getName().getBaseName(), candidates);
387+
} else if (auto *DSCE = dyn_cast<DotSyntaxCallExpr>(fnExpr)) {
388+
if (auto *DRE = dyn_cast<DeclRefExpr>(DSCE->getFn())) {
389+
collectPossibleCalleesByQualifiedLookup(
390+
DC, DSCE->getArg(), DRE->getDecl()->getBaseName(), candidates);
391+
}
387392
}
388393

389394
if (candidates.empty()) {

lib/Parse/ParseExpr.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,17 +236,19 @@ ParserResult<Expr> Parser::parseExprSequence(Diag<> Message,
236236
// Parse the middle expression of the ternary.
237237
ParserResult<Expr> middle =
238238
parseExprSequence(diag::expected_expr_after_if_question, isExprBasic);
239+
ParserStatus Status = middle;
239240
if (middle.hasCodeCompletion())
240-
return makeParserCodeCompletionResult<Expr>();
241+
HasCodeCompletion = true;
241242
if (middle.isNull())
242243
return nullptr;
243244

244245
// Make sure there's a matching ':' after the middle expr.
245246
if (!Tok.is(tok::colon)) {
246247
diagnose(questionLoc, diag::expected_colon_after_if_question);
247248

248-
return makeParserErrorResult(new (Context) ErrorExpr(
249-
{startLoc, middle.get()->getSourceRange().End}));
249+
Status.setIsParseError();
250+
return makeParserResult(Status, new (Context) ErrorExpr(
251+
{startLoc, middle.get()->getSourceRange().End}));
250252
}
251253

252254
SourceLoc colonLoc = consumeToken();

lib/Sema/BuilderTransform.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -566,12 +566,6 @@ ConstraintSystem::TypeMatchResult ConstraintSystem::applyFunctionBuilder(
566566
assert(!builderType->hasTypeParameter());
567567
}
568568

569-
// If we are performing code-completion inside the closure body, supress
570-
// diagnostics to workaround typechecking performance problems.
571-
if (getASTContext().SourceMgr.rangeContainsCodeCompletionLoc(
572-
closure->getSourceRange()))
573-
Options |= ConstraintSystemFlags::SuppressDiagnostics;
574-
575569
BuilderClosureVisitor visitor(getASTContext(), this,
576570
/*wantExpr=*/true, builderType);
577571
Expr *singleExpr = visitor.visit(closure->getBody());

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "swift/AST/ASTVisitor.h"
2525
#include "swift/AST/ASTWalker.h"
2626
#include "swift/AST/DiagnosticsParse.h"
27+
#include "swift/AST/DiagnosticSuppression.h"
2728
#include "swift/AST/ExistentialLayout.h"
2829
#include "swift/AST/Initializer.h"
2930
#include "swift/AST/NameLookup.h"
@@ -2141,7 +2142,7 @@ class FallbackDiagnosticListener : public ExprTypeCheckListener {
21412142

21422143
void maybeProduceFallbackDiagnostic(Expr *expr) const {
21432144
if (Options.contains(TypeCheckExprFlags::SubExpressionDiagnostics) ||
2144-
Options.contains(TypeCheckExprFlags::SuppressDiagnostics))
2145+
DiagnosticSuppression::isEnabled(TC.Diags))
21452146
return;
21462147

21472148
// Before producing fatal error here, let's check if there are any "error"
@@ -2183,7 +2184,7 @@ Type TypeChecker::typeCheckExpressionImpl(Expr *&expr, DeclContext *dc,
21832184
// Construct a constraint system from this expression.
21842185
ConstraintSystemOptions csOptions = ConstraintSystemFlags::AllowFixes;
21852186

2186-
if (options.contains(TypeCheckExprFlags::SuppressDiagnostics))
2187+
if (DiagnosticSuppression::isEnabled(Diags))
21872188
csOptions |= ConstraintSystemFlags::SuppressDiagnostics;
21882189

21892190
if (options.contains(TypeCheckExprFlags::AllowUnresolvedTypeVariables))

lib/Sema/TypeCheckStmt.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "swift/AST/ASTWalker.h"
2525
#include "swift/AST/ASTVisitor.h"
2626
#include "swift/AST/DiagnosticsSema.h"
27+
#include "swift/AST/DiagnosticSuppression.h"
2728
#include "swift/AST/Identifier.h"
2829
#include "swift/AST/Initializer.h"
2930
#include "swift/AST/NameLookup.h"
@@ -518,20 +519,18 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
518519
}
519520
}
520521

522+
if (EndTypeCheckLoc.isValid()) {
523+
assert(DiagnosticSuppression::isEnabled(TC.Diags) &&
524+
"Diagnosing and AllowUnresolvedTypeVariables don't seem to mix");
525+
options |= TypeCheckExprFlags::AllowUnresolvedTypeVariables;
526+
}
527+
521528
ContextualTypePurpose ctp = CTP_ReturnStmt;
522529
if (auto func =
523530
dyn_cast_or_null<FuncDecl>(TheFunc->getAbstractFunctionDecl())) {
524531
if (func->hasSingleExpressionBody()) {
525532
ctp = CTP_ReturnSingleExpr;
526533
}
527-
528-
// If we are performing code-completion inside a function builder body,
529-
// suppress diagnostics to workaround typechecking performance problems.
530-
if (func->getFunctionBuilderType() &&
531-
TC.Context.SourceMgr.rangeContainsCodeCompletionLoc(
532-
func->getBody()->getSourceRange())) {
533-
options |= TypeCheckExprFlags::SuppressDiagnostics;
534-
}
535534
}
536535

537536
auto exprTy = TC.typeCheckExpression(E, DC, TypeLoc::withoutLoc(ResultTy),
@@ -1785,6 +1784,12 @@ Stmt *StmtChecker::visitBraceStmt(BraceStmt *BS) {
17851784
if (isDiscarded)
17861785
options |= TypeCheckExprFlags::IsDiscarded;
17871786

1787+
if (EndTypeCheckLoc.isValid()) {
1788+
assert(DiagnosticSuppression::isEnabled(TC.Diags) &&
1789+
"Diagnosing and AllowUnresolvedTypeVariables don't seem to mix");
1790+
options |= TypeCheckExprFlags::AllowUnresolvedTypeVariables;
1791+
}
1792+
17881793
auto resultTy =
17891794
TC.typeCheckExpression(SubExpr, DC, TypeLoc(), CTP_Unused, options);
17901795

@@ -1942,10 +1947,10 @@ static Expr* constructCallToSuperInit(ConstructorDecl *ctor,
19421947
r = new (Context) TryExpr(SourceLoc(), r, Type(), /*implicit=*/true);
19431948

19441949
TypeChecker &tc = *static_cast<TypeChecker *>(Context.getLazyResolver());
1950+
DiagnosticSuppression suppression(tc.Diags);
19451951
auto resultTy =
19461952
tc.typeCheckExpression(r, ctor, TypeLoc(), CTP_Unused,
1947-
TypeCheckExprFlags::IsDiscarded |
1948-
TypeCheckExprFlags::SuppressDiagnostics);
1953+
TypeCheckExprFlags::IsDiscarded);
19491954
if (!resultTy)
19501955
return nullptr;
19511956

lib/Sema/TypeChecker.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -705,8 +705,7 @@ bool swift::typeCheckExpression(DeclContext *DC, Expr *&parsedExpr) {
705705
TypeChecker &TC = createTypeChecker(ctx);
706706

707707
auto resultTy = TC.typeCheckExpression(parsedExpr, DC, TypeLoc(),
708-
ContextualTypePurpose::CTP_Unused,
709-
TypeCheckExprFlags::SuppressDiagnostics);
708+
ContextualTypePurpose::CTP_Unused);
710709
return !resultTy;
711710
}
712711

lib/Sema/TypeChecker.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,6 @@ enum class TypeCheckExprFlags {
235235
/// that we force for style or other reasons.
236236
DisableStructuralChecks = 0x02,
237237

238-
/// Set if the client wants diagnostics suppressed.
239-
SuppressDiagnostics = 0x04,
240-
241238
/// If set, the client wants a best-effort solution to the constraint system,
242239
/// but can tolerate a solution where all of the constraints are solved, but
243240
/// not all type variables have been determined. In this case, the constraint

test/IDE/complete_in_closures.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@
5757
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IN_IIFE_4 | %FileCheck %s -check-prefix=IN_IIFE_1
5858
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ERROR_IN_CLOSURE_IN_INITIALIZER | %FileCheck %s -check-prefix=ERROR_IN_CLOSURE_IN_INITIALIZER
5959
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DECL_IN_CLOSURE_IN_TOPLEVEL_INIT | %FileCheck %s -check-prefix=DECL_IN_CLOSURE_IN_TOPLEVEL_INIT
60+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=SINGLE_EXPR_CLOSURE_CONTEXT | %FileCheck %s -check-prefix=SINGLE_EXPR_CLOSURE_CONTEXT
61+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=SINGLE_TERNARY_EXPR_CLOSURE_CONTEXT | %FileCheck %s -check-prefix=SINGLE_TERNARY_EXPR_CLOSURE_CONTEXT
62+
6063

6164
// ERROR_COMMON: found code completion token
6265
// ERROR_COMMON-NOT: Begin completions
@@ -401,3 +404,30 @@ var foo = {
401404
// DECL_IN_CLOSURE_IN_TOPLEVEL_INIT-DAG: Decl[InstanceMethod]/Super: dropFirst()[#Substring#]; name=dropFirst()
402405
// DECL_IN_CLOSURE_IN_TOPLEVEL_INIT: End completions
403406
}
407+
408+
func testWithMemoryRebound(_ bar: UnsafePointer<UInt64>) {
409+
_ = bar.withMemoryRebound(to: Int64.self, capacity: 3) { ptr in
410+
return ptr #^SINGLE_EXPR_CLOSURE_CONTEXT^#
411+
// SINGLE_EXPR_CLOSURE_CONTEXT: Begin completions
412+
// SINGLE_EXPR_CLOSURE_CONTEXT-DAG: Decl[InstanceMethod]/CurrNominal: .deallocate()[#Void#]; name=deallocate()
413+
// SINGLE_EXPR_CLOSURE_CONTEXT-DAG: Decl[InstanceVar]/CurrNominal: .pointee[#Int64#]; name=pointee
414+
// SINGLE_EXPR_CLOSURE_CONTEXT: End completions
415+
}
416+
}
417+
418+
func testInsideTernaryClosureReturn(test: Bool) -> [String] {
419+
return "hello".map { thing in
420+
test ? String(thing #^SINGLE_TERNARY_EXPR_CLOSURE_CONTEXT^#).uppercased() : String(thing).lowercased()
421+
// SINGLE_TERNARY_EXPR_CLOSURE_CONTEXT: Begin completions
422+
// SINGLE_TERNARY_EXPR_CLOSURE_CONTEXT-DAG: Decl[InstanceVar]/CurrNominal: .utf8[#Character.UTF8View#]; name=utf8
423+
// SINGLE_TERNARY_EXPR_CLOSURE_CONTEXT-DAG: Decl[InstanceVar]/CurrNominal: .description[#String#]; name=description
424+
// SINGLE_TERNARY_EXPR_CLOSURE_CONTEXT-DAG: Decl[InstanceVar]/CurrNominal: .isWhitespace[#Bool#]; name=isWhitespace
425+
// SINGLE_TERNARY_EXPR_CLOSURE_CONTEXT-DAG: Decl[InstanceMethod]/CurrNominal: .uppercased()[#String#]; name=uppercased()
426+
// SINGLE_TERNARY_EXPR_CLOSURE_CONTEXT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']... {#String.Element#}[#ClosedRange<String.Element>#]; name=... String.Element
427+
// SINGLE_TERNARY_EXPR_CLOSURE_CONTEXT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']< {#Character#}[#Bool#]; name=< Character
428+
// SINGLE_TERNARY_EXPR_CLOSURE_CONTEXT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']>= {#String.Element#}[#Bool#]; name=>= String.Element
429+
// SINGLE_TERNARY_EXPR_CLOSURE_CONTEXT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']== {#Character#}[#Bool#]; name=== Character
430+
// SINGLE_TERNARY_EXPR_CLOSURE_CONTEXT-DAG: Keyword[self]/CurrNominal: .self[#String.Element#]; name=self
431+
// SINGLE_TERNARY_EXPR_CLOSURE_CONTEXT: End completions
432+
}
433+
}

test/SourceKit/CodeComplete/injected_vfs_complete_open.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ func foo(
4242
// RUN: == -req=complete.update -pos=9:1 -req-opts=filtertext=StructDefinedInSameTarget %s | %FileCheck --check-prefix=INNER_SAMETARGET %s
4343
// INNER_SAMETARGET: key.name: "StructDefinedInSameTarget"
4444
// INNER_SAMETARGET: key.name: "StructDefinedInSameTarget."
45-
// INNER_SAMETARGET: key.name: "StructDefinedInSameTarget("
4645

4746
// RUN: %sourcekitd-test -req=complete.open -pos=9:1 -req-opts=filtertext=StructDefinedInCModule -vfs-files=/target_file2.swift=@%S/../Inputs/vfs/other_file_in_target.swift,/CModule/module.modulemap=%S/../Inputs/vfs/CModule/module.modulemap,/CModule/CModule.h=%S/../Inputs/vfs/CModule/CModule.h,/SwiftModule/SwiftModule.swiftmodule=%t/SwiftModule.swiftmodule %s -pass-as-sourcetext -- %s /target_file2.swift -I /CModule -I /SwiftModule -target %target-triple | %FileCheck --check-prefix=INNER_CMODULE %s
4847
// RUN: %sourcekitd-test -req=complete.open -pos=9:1 -dont-print-response -vfs-files=/target_file2.swift=@%S/../Inputs/vfs/other_file_in_target.swift,/CModule/module.modulemap=%S/../Inputs/vfs/CModule/module.modulemap,/CModule/CModule.h=%S/../Inputs/vfs/CModule/CModule.h,/SwiftModule/SwiftModule.swiftmodule=%t/SwiftModule.swiftmodule %s -pass-as-sourcetext -- %s /target_file2.swift -I /CModule -I /SwiftModule -target %target-triple \

0 commit comments

Comments
 (0)