Skip to content

Commit ee91879

Browse files
authored
Merge pull request swiftlang#38831 from rintaro/ide-srcinfo-diag
[CodeCompletion] Explain why results aren't recommended
2 parents 9afb877 + 0dd596a commit ee91879

31 files changed

+1016
-108
lines changed

include/swift/AST/Attr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,6 +2088,10 @@ class DeclAttributes {
20882088
/// a declaration is deprecated on all deployment targets, or null otherwise.
20892089
const AvailableAttr *getDeprecated(const ASTContext &ctx) const;
20902090

2091+
/// Returns the first @available attribute that indicates
2092+
/// a declaration will be deprecated in the future, or null otherwise.
2093+
const AvailableAttr *getSoftDeprecated(const ASTContext &ctx) const;
2094+
20912095
SWIFT_DEBUG_DUMPER(dump(const Decl *D = nullptr));
20922096
void print(ASTPrinter &Printer, const PrintOptions &Options,
20932097
const Decl *D = nullptr) const;

include/swift/AST/DiagnosticEngine.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,8 @@ namespace swift {
11161116
void emitTentativeDiagnostics();
11171117

11181118
public:
1119+
DiagnosticKind declaredDiagnosticKindFor(const DiagID id);
1120+
11191121
llvm::StringRef diagnosticStringFor(const DiagID id,
11201122
bool printDiagnosticNames);
11211123

@@ -1313,6 +1315,26 @@ namespace swift {
13131315
builder();
13141316
}
13151317

1318+
/// Temporary on-stack storage and unescaping for encoded diagnostic
1319+
/// messages.
1320+
class EncodedDiagnosticMessage {
1321+
llvm::SmallString<128> Buf;
1322+
1323+
public:
1324+
/// \param S A string with an encoded message
1325+
EncodedDiagnosticMessage(StringRef S);
1326+
1327+
/// The unescaped message to display to the user.
1328+
const StringRef Message;
1329+
};
1330+
1331+
/// Returns a value that can be used to select between accessor kinds in
1332+
/// diagnostics.
1333+
///
1334+
/// This is correlated with diag::availability_deprecated and others.
1335+
std::pair<unsigned, DeclName>
1336+
getAccessorKindAndNameForDiagnostics(const ValueDecl *D);
1337+
13161338
} // end namespace swift
13171339

13181340
#endif

include/swift/AST/DiagnosticsAll.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define DIAG_NO_UNDEF
2121

2222
#include "DiagnosticsCommon.def"
23+
#include "DiagnosticsIDE.def"
2324
#include "DiagnosticsParse.def"
2425
#include "DiagnosticsSema.def"
2526
#include "DiagnosticsClangImporter.def"

include/swift/AST/DiagnosticsIDE.def

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//===--- DiagnosticsIDE.def - Diagnostics Text ------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#define DEFINE_DIAGNOSTIC_MACROS
14+
#include "DefineDiagnosticMacros.h"
15+
16+
//===----------------------------------------------------------------------===//
17+
18+
ERROR(ide_async_in_nonasync_context, none,
19+
"async %0 used in a context that does not support concurrency",
20+
(DeclName))
21+
22+
// NOTE: This is WARNING because this is emitted for cross actor references with
23+
// non-'Sendable' types. That is optionally ('-warn-concurrency') warning in
24+
// Swift 5.5.
25+
WARNING(ide_cross_actor_reference_swift5, none,
26+
"actor-isolated %0 should only be referenced from inside the actor",
27+
(DeclName))
28+
29+
WARNING(ide_redundant_import, none,
30+
"module %0 is already imported", (DeclName))
31+
32+
// FIXME: Inform which other 'import' this module came from.
33+
NOTE(ide_redundant_import_indirect, none,
34+
"module %0 is already imported via another module import", (DeclName))
35+
36+
WARNING(ide_availability_softdeprecated, Deprecation,
37+
"%select{getter for |setter for |}0%1 will be deprecated"
38+
" in %select{a future version|%select{a future version of %3|%3 %5}4}2"
39+
"%select{|: %6}6",
40+
(unsigned, DeclName, bool, StringRef, bool, llvm::VersionTuple,
41+
StringRef))
42+
43+
WARNING(ide_availability_softdeprecated_rename, Deprecation,
44+
"%select{getter for |setter for |}0%1 will be deprecated"
45+
" in %select{a future version|%select{a future version of %3|%3 %5}4}2"
46+
": renamed to '%6'",
47+
(unsigned, DeclName, bool, StringRef, bool, llvm::VersionTuple, StringRef))
48+
49+
//===----------------------------------------------------------------------===//
50+
51+
#define UNDEFINE_DIAGNOSTIC_MACROS
52+
#include "DefineDiagnosticMacros.h"

include/swift/AST/DiagnosticsIDE.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===--- DiagnosticsIDE.h - Diagnostic Definitions --------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
/// \file
14+
/// This file defines diagnostics used only in IDE.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef SWIFT_DIAGNOSTICSIDE_H
19+
#define SWIFT_DIAGNOSTICSIDE_H
20+
21+
#include "swift/AST/DiagnosticsCommon.h"
22+
23+
namespace swift {
24+
namespace diag {
25+
// Declare common diagnostics objects with their appropriate types.
26+
#define DIAG(KIND,ID,Options,Text,Signature) \
27+
extern detail::DiagWithArguments<void Signature>::type ID;
28+
#include "DiagnosticsIDE.def"
29+
}
30+
}
31+
32+
#endif

include/swift/IDE/CodeCompletion.h

Lines changed: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,14 @@ enum class CompletionKind {
568568
TypeAttrBeginning,
569569
};
570570

571+
enum class CodeCompletionDiagnosticSeverity: uint8_t {
572+
None,
573+
Error,
574+
Warning,
575+
Remark,
576+
Note,
577+
};
578+
571579
/// A single code completion result.
572580
class CodeCompletionResult {
573581
friend class CodeCompletionResultBuilder;
@@ -607,7 +615,9 @@ class CodeCompletionResult {
607615
enum class NotRecommendedReason {
608616
None = 0,
609617
RedundantImport,
618+
RedundantImportIndirect,
610619
Deprecated,
620+
SoftDeprecated,
611621
InvalidAsyncContext,
612622
CrossActorReference,
613623
VariableUsedInOwnDefinition,
@@ -633,10 +643,13 @@ class CodeCompletionResult {
633643
private:
634644
CodeCompletionString *CompletionString;
635645
StringRef ModuleName;
646+
StringRef SourceFilePath;
636647
StringRef BriefDocComment;
637648
ArrayRef<StringRef> AssociatedUSRs;
638649
ArrayRef<std::pair<StringRef, StringRef>> DocWords;
639650
unsigned TypeDistance : 3;
651+
unsigned DiagnosticSeverity: 3;
652+
StringRef DiagnosticMessage;
640653

641654
public:
642655
/// Constructs a \c Pattern, \c Keyword or \c BuiltinOperator result.
@@ -663,6 +676,7 @@ class CodeCompletionResult {
663676
getOperatorKind() != CodeCompletionOperatorKind::None);
664677
AssociatedKind = 0;
665678
IsSystem = 0;
679+
DiagnosticSeverity = 0;
666680
}
667681

668682
/// Constructs a \c Keyword result.
@@ -683,6 +697,7 @@ class CodeCompletionResult {
683697
assert(CompletionString);
684698
AssociatedKind = static_cast<unsigned>(Kind);
685699
IsSystem = 0;
700+
DiagnosticSeverity = 0;
686701
}
687702

688703
/// Constructs a \c Literal result.
@@ -700,6 +715,7 @@ class CodeCompletionResult {
700715
TypeDistance(TypeDistance) {
701716
AssociatedKind = static_cast<unsigned>(LiteralKind);
702717
IsSystem = 0;
718+
DiagnosticSeverity = 0;
703719
assert(CompletionString);
704720
}
705721

@@ -727,6 +743,7 @@ class CodeCompletionResult {
727743
assert(AssociatedDecl && "should have a decl");
728744
AssociatedKind = unsigned(getCodeCompletionDeclKind(AssociatedDecl));
729745
IsSystem = getDeclIsSystem(AssociatedDecl);
746+
DiagnosticSeverity = 0;
730747
assert(CompletionString);
731748
if (isOperator())
732749
KnownOperatorKind =
@@ -740,9 +757,10 @@ class CodeCompletionResult {
740757
CodeCompletionFlair Flair, unsigned NumBytesToErase,
741758
CodeCompletionString *CompletionString,
742759
CodeCompletionDeclKind DeclKind, bool IsSystem,
743-
StringRef ModuleName,
760+
StringRef ModuleName, StringRef SourceFilePath,
744761
CodeCompletionResult::NotRecommendedReason NotRecReason,
745-
StringRef BriefDocComment,
762+
CodeCompletionDiagnosticSeverity diagSeverity,
763+
StringRef DiagnosticMessage, StringRef BriefDocComment,
746764
ArrayRef<StringRef> AssociatedUSRs,
747765
ArrayRef<std::pair<StringRef, StringRef>> DocWords,
748766
ExpectedTypeRelation TypeDistance,
@@ -752,9 +770,11 @@ class CodeCompletionResult {
752770
SemanticContext(unsigned(SemanticContext)), Flair(unsigned(Flair.toRaw())),
753771
NotRecommended(unsigned(NotRecReason)), IsSystem(IsSystem),
754772
NumBytesToErase(NumBytesToErase), CompletionString(CompletionString),
755-
ModuleName(ModuleName), BriefDocComment(BriefDocComment),
756-
AssociatedUSRs(AssociatedUSRs), DocWords(DocWords),
757-
TypeDistance(TypeDistance) {
773+
ModuleName(ModuleName), SourceFilePath(SourceFilePath),
774+
BriefDocComment(BriefDocComment), AssociatedUSRs(AssociatedUSRs),
775+
DocWords(DocWords), TypeDistance(TypeDistance),
776+
DiagnosticSeverity(unsigned(diagSeverity)),
777+
DiagnosticMessage(DiagnosticMessage) {
758778
AssociatedKind = static_cast<unsigned>(DeclKind);
759779
assert(CompletionString);
760780
assert(!isOperator() ||
@@ -853,6 +873,29 @@ class CodeCompletionResult {
853873
return DocWords;
854874
}
855875

876+
void setSourceFilePath(StringRef value) {
877+
SourceFilePath = value;
878+
}
879+
880+
void setDiagnostics(CodeCompletionDiagnosticSeverity severity, StringRef message) {
881+
DiagnosticSeverity = static_cast<unsigned>(severity);
882+
DiagnosticMessage = message;
883+
}
884+
885+
CodeCompletionDiagnosticSeverity getDiagnosticSeverity() const {
886+
return static_cast<CodeCompletionDiagnosticSeverity>(DiagnosticSeverity);
887+
}
888+
889+
StringRef getDiagnosticMessage() const {
890+
return DiagnosticMessage;
891+
}
892+
893+
/// Returns the source file path where the associated decl was declared.
894+
/// Returns an empty string if the information is not available.
895+
StringRef getSourceFilePath() const {
896+
return SourceFilePath;
897+
}
898+
856899
/// Print a debug representation of the code completion result to \p OS.
857900
void printPrefix(raw_ostream &OS) const;
858901
SWIFT_DEBUG_DUMP;
@@ -865,6 +908,15 @@ class CodeCompletionResult {
865908
static bool getDeclIsSystem(const Decl *D);
866909
};
867910

911+
/// A pair of a file path and its up-to-date-ness.
912+
struct SourceFileAndUpToDate {
913+
StringRef FilePath;
914+
bool IsUpToDate;
915+
916+
SourceFileAndUpToDate(StringRef FilePath, bool IsUpToDate)
917+
: FilePath(FilePath), IsUpToDate(IsUpToDate) {}
918+
};
919+
868920
struct CodeCompletionResultSink {
869921
using AllocatorPtr = std::shared_ptr<llvm::BumpPtrAllocator>;
870922

@@ -877,11 +929,13 @@ struct CodeCompletionResultSink {
877929

878930
/// Whether to annotate the results with XML.
879931
bool annotateResult = false;
932+
bool requiresSourceFileInfo = false;
880933

881934
/// Whether to emit object literals if desired.
882935
bool includeObjectLiterals = true;
883936

884937
std::vector<CodeCompletionResult *> Results;
938+
std::vector<SourceFileAndUpToDate> SourceFiles;
885939

886940
/// A single-element cache for module names stored in Allocator, keyed by a
887941
/// clang::Module * or swift::ModuleDecl *.
@@ -950,7 +1004,10 @@ class CodeCompletionContext {
9501004
: Cache(Cache) {}
9511005

9521006
void setAnnotateResult(bool flag) { CurrentResults.annotateResult = flag; }
953-
bool getAnnotateResult() { return CurrentResults.annotateResult; }
1007+
bool getAnnotateResult() const { return CurrentResults.annotateResult; }
1008+
1009+
void setRequiresSourceFileInfo(bool flag) { CurrentResults.requiresSourceFileInfo = flag; }
1010+
bool requiresSourceFileInfo() const { return CurrentResults.requiresSourceFileInfo; }
9541011

9551012
void setIncludeObjectLiterals(bool flag) {
9561013
CurrentResults.includeObjectLiterals = flag;
@@ -995,8 +1052,7 @@ struct SimpleCachingCodeCompletionConsumer : public CodeCompletionConsumer {
9951052
DeclContext *DCForModules) override;
9961053

9971054
/// Clients should override this method to receive \p Results.
998-
virtual void handleResults(
999-
MutableArrayRef<CodeCompletionResult *> Results) = 0;
1055+
virtual void handleResults(CodeCompletionContext &context) = 0;
10001056
};
10011057

10021058
/// A code completion result consumer that prints the results to a
@@ -1007,6 +1063,7 @@ class PrintingCodeCompletionConsumer
10071063
bool IncludeKeywords;
10081064
bool IncludeComments;
10091065
bool PrintAnnotatedDescription;
1066+
bool RequiresSourceFileInfo = false;
10101067

10111068
public:
10121069
PrintingCodeCompletionConsumer(llvm::raw_ostream &OS,
@@ -1018,7 +1075,8 @@ class PrintingCodeCompletionConsumer
10181075
IncludeComments(IncludeComments),
10191076
PrintAnnotatedDescription(PrintAnnotatedDescription) {}
10201077

1021-
void handleResults(MutableArrayRef<CodeCompletionResult *> Results) override;
1078+
void handleResults(CodeCompletionContext &context) override;
1079+
void handleResults(MutableArrayRef<CodeCompletionResult *> Results);
10221080
};
10231081

10241082
/// Create a factory for code completion callbacks.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//===--- ModuleSourceFileInfo.h ---------------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_IDE_MODULESOURCEFILEINFO_H
14+
#define SWIFT_IDE_MODULESOURCEFILEINFO_H
15+
16+
#include "swift/AST/RawComment.h"
17+
#include "swift/Basic/BasicSourceInfo.h"
18+
#include "swift/Basic/LLVM.h"
19+
20+
namespace swift {
21+
class ASTContext;
22+
class Decl;
23+
namespace ide {
24+
25+
/// Get the source file path where \p D is declared. Returns an empty string
26+
/// if the information is not available.
27+
StringRef getSourceFilePathForDecl(const Decl *D);
28+
29+
/// Check if the source file of \p info is up-to-date.
30+
/// * \c true if the mtime and the size are the same.
31+
/// * \c true if the interface has hasn't changed.
32+
/// * \c false otherwise.
33+
bool isSourceFileUpToDate(const BasicSourceFileInfo &info, ASTContext &Ctx);
34+
35+
36+
} // namespace ide
37+
} // namespace swift
38+
39+
#endif // SWIFT_IDE_MODULESOURCEFILEINFO_H

include/swift/Parse/Lexer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ class Lexer {
448448
/// the byte content.
449449
///
450450
/// If a copy needs to be made, it will be allocated out of the provided
451-
/// \p Buffer.
451+
/// \p Buffer. If \p IndentToStrip is '~0U', the indent is auto-detected.
452452
static StringRef getEncodedStringSegment(StringRef Str,
453453
SmallVectorImpl<char> &Buffer,
454454
bool IsFirstSegment = false,

0 commit comments

Comments
 (0)