Skip to content

Commit 486c7b8

Browse files
committed
[Diagnostics][NFC] Add support for using the %select format specifier with StringRef args
Get rid of some redundant availability diagnostics as a result.
1 parent b8de310 commit 486c7b8

File tree

5 files changed

+39
-67
lines changed

5 files changed

+39
-67
lines changed

docs/Diagnostics.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Most diagnostics have no reason to change behavior under editor mode. An example
9797

9898
- `%0`, `%1`, etc - Formats the specified diagnostic argument based on its type.
9999

100-
- `%select{a|b|c}0` - Chooses from a list of alternatives, separated by vertical bars, based on the value of the given argument. In this example, a value of 2 in diagnostic argument 0 would result in "c" being output.
100+
- `%select{a|b|c}0` - Chooses from a list of alternatives, separated by vertical bars, based on the value of the given argument. In this example, a value of 2 in diagnostic argument 0 would result in "c" being output. The argument to the %select may be an integer, enum, or StringRef. If it's a StringRef, the specifier acts as an emptiness check.
101101

102102
- `%s0` - Produces an "s" if the given argument is anything other than 1, as meant for an English plural. This isn't particularly localizable without a more general `%plural` form, but most diagnostics try to avoid cases where a plural/singular distinction would be necessary in the first place.
103103

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2223,10 +2223,8 @@ ERROR(multiple_override,none,
22232223
NOTE(multiple_override_prev,none,
22242224
"%0 previously overridden here", (DeclName))
22252225

2226-
ERROR(override_unavailable,none,
2227-
"cannot override %0 which has been marked unavailable", (DeclBaseName))
2228-
ERROR(override_unavailable_msg, none,
2229-
"cannot override %0 which has been marked unavailable: %1",
2226+
ERROR(override_unavailable, none,
2227+
"cannot override %0 which has been marked unavailable%select{|: %1}1",
22302228
(DeclBaseName, StringRef))
22312229

22322230
ERROR(override_less_available,none,
@@ -4118,27 +4116,16 @@ ERROR(dynamic_replacement_replaced_constructor_is_not_convenience, none,
41184116

41194117
ERROR(availability_decl_unavailable, none,
41204118
"%select{getter for |setter for |}0%1 is unavailable"
4121-
"%select{ in %3|}2",
4122-
(unsigned, DeclName, bool, StringRef))
4119+
"%select{ in %3|}2%select{|: %4}4",
4120+
(unsigned, DeclName, bool, StringRef, StringRef))
41234121

41244122
#define REPLACEMENT_DECL_KIND_SELECT "select{| instance method| property}"
41254123
ERROR(availability_decl_unavailable_rename, none,
41264124
"%select{getter for |setter for |}0%1 has been "
41274125
"%select{renamed to|replaced by}2%" REPLACEMENT_DECL_KIND_SELECT "3 "
4128-
"'%4'",
4129-
(unsigned, DeclName, bool, unsigned, StringRef))
4130-
4131-
ERROR(availability_decl_unavailable_rename_msg, none,
4132-
"%select{getter for |setter for |}0%1 has been "
4133-
"%select{renamed to|replaced by}2%" REPLACEMENT_DECL_KIND_SELECT "3 "
4134-
"'%4': %5",
4126+
"'%4'%select{|: %5}5",
41354127
(unsigned, DeclName, bool, unsigned, StringRef, StringRef))
41364128

4137-
ERROR(availability_decl_unavailable_msg, none,
4138-
"%select{getter for |setter for |}0%1 is unavailable"
4139-
"%select{ in %3|}2: %4",
4140-
(unsigned, DeclName, bool, StringRef, StringRef))
4141-
41424129
NOTE(availability_marked_unavailable, none,
41434130
"%select{getter for |setter for |}0%1 has been explicitly marked "
41444131
"unavailable here", (unsigned, DeclName))
@@ -4153,12 +4140,7 @@ NOTE(availability_obsoleted, none,
41534140

41544141
WARNING(availability_deprecated, none,
41554142
"%select{getter for |setter for |}0%1 %select{is|%select{is|was}4}2 "
4156-
"deprecated%select{| in %3%select{| %5}4}2",
4157-
(unsigned, DeclName, bool, StringRef, bool, llvm::VersionTuple))
4158-
4159-
WARNING(availability_deprecated_msg, none,
4160-
"%select{getter for |setter for |}0%1 %select{is|%select{is|was}4}2 "
4161-
"deprecated%select{| in %3%select{| %5}4}2: %6",
4143+
"deprecated%select{| in %3%select{| %5}4}2%select{|: %6}6",
41624144
(unsigned, DeclName, bool, StringRef, bool, llvm::VersionTuple,
41634145
StringRef))
41644146

lib/AST/DiagnosticEngine.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,14 @@ static void formatDiagnosticArgument(StringRef Modifier,
449449
break;
450450

451451
case DiagnosticArgumentKind::String:
452-
assert(Modifier.empty() && "Improper modifier for string argument");
453-
Out << Arg.getAsString();
452+
if (Modifier == "select") {
453+
formatSelectionArgument(ModifierArguments, Args,
454+
Arg.getAsString().empty() ? 0 : 1, FormatOpts,
455+
Out);
456+
} else {
457+
assert(Modifier.empty() && "Improper modifier for string argument");
458+
Out << Arg.getAsString();
459+
}
454460
break;
455461

456462
case DiagnosticArgumentKind::Identifier:

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1955,8 +1955,9 @@ void TypeChecker::diagnoseIfDeprecated(SourceRange ReferenceRange,
19551955
if (Attr->Message.empty() && Attr->Rename.empty()) {
19561956
diagnose(ReferenceRange.Start, diag::availability_deprecated,
19571957
RawAccessorKind, Name, Attr->hasPlatform(), Platform,
1958-
Attr->Deprecated.hasValue(), DeprecatedVersion)
1959-
.highlight(Attr->getRange());
1958+
Attr->Deprecated.hasValue(), DeprecatedVersion,
1959+
/*message*/ StringRef())
1960+
.highlight(Attr->getRange());
19601961
return;
19611962
}
19621963

@@ -1967,11 +1968,11 @@ void TypeChecker::diagnoseIfDeprecated(SourceRange ReferenceRange,
19671968

19681969
if (!Attr->Message.empty()) {
19691970
EncodedDiagnosticMessage EncodedMessage(Attr->Message);
1970-
diagnose(ReferenceRange.Start, diag::availability_deprecated_msg,
1971+
diagnose(ReferenceRange.Start, diag::availability_deprecated,
19711972
RawAccessorKind, Name, Attr->hasPlatform(), Platform,
19721973
Attr->Deprecated.hasValue(), DeprecatedVersion,
19731974
EncodedMessage.Message)
1974-
.highlight(Attr->getRange());
1975+
.highlight(Attr->getRange());
19751976
} else {
19761977
unsigned rawReplaceKind = static_cast<unsigned>(
19771978
replacementDeclKind.getValueOr(ReplacementDeclKind::None));
@@ -1998,12 +1999,9 @@ void swift::diagnoseUnavailableOverride(ValueDecl *override,
19981999
ASTContext &ctx = override->getASTContext();
19992000
auto &diags = ctx.Diags;
20002001
if (attr->Rename.empty()) {
2001-
if (attr->Message.empty())
2002-
diags.diagnose(override, diag::override_unavailable,
2003-
override->getBaseName());
2004-
else
2005-
diags.diagnose(override, diag::override_unavailable_msg,
2006-
override->getBaseName(), attr->Message);
2002+
EncodedDiagnosticMessage EncodedMessage(attr->Message);
2003+
diags.diagnose(override, diag::override_unavailable,
2004+
override->getBaseName(), EncodedMessage.Message);
20072005

20082006
DeclName name;
20092007
unsigned rawAccessorKind;
@@ -2185,22 +2183,12 @@ bool swift::diagnoseExplicitUnavailability(
21852183
unsigned rawReplaceKind = static_cast<unsigned>(
21862184
replaceKind.getValueOr(ReplacementDeclKind::None));
21872185
StringRef newName = replaceKind ? newNameBuf.str() : Attr->Rename;
2188-
2189-
if (Attr->Message.empty()) {
2190-
auto diag = diags.diagnose(Loc,
2191-
diag::availability_decl_unavailable_rename,
2192-
RawAccessorKind, Name,
2193-
replaceKind.hasValue(),
2194-
rawReplaceKind, newName);
2195-
attachRenameFixIts(diag);
2196-
} else {
21972186
EncodedDiagnosticMessage EncodedMessage(Attr->Message);
21982187
auto diag =
2199-
diags.diagnose(Loc, diag::availability_decl_unavailable_rename_msg,
2200-
RawAccessorKind, Name, replaceKind.hasValue(),
2201-
rawReplaceKind, newName, EncodedMessage.Message);
2188+
diags.diagnose(Loc, diag::availability_decl_unavailable_rename,
2189+
RawAccessorKind, Name, replaceKind.hasValue(),
2190+
rawReplaceKind, newName, EncodedMessage.Message);
22022191
attachRenameFixIts(diag);
2203-
}
22042192
} else if (isSubscriptReturningString(D, ctx)) {
22052193
diags.diagnose(Loc, diag::availabilty_string_subscript_migration)
22062194
.highlight(R)
@@ -2209,16 +2197,12 @@ bool swift::diagnoseExplicitUnavailability(
22092197

22102198
// Skip the note emitted below.
22112199
return true;
2212-
} else if (Attr->Message.empty()) {
2213-
diags.diagnose(Loc, diag::availability_decl_unavailable,
2214-
RawAccessorKind, Name, platform.empty(), platform)
2215-
.highlight(R);
22162200
} else {
22172201
EncodedDiagnosticMessage EncodedMessage(Attr->Message);
2218-
diags.diagnose(Loc, diag::availability_decl_unavailable_msg,
2219-
RawAccessorKind, Name, platform.empty(), platform,
2220-
EncodedMessage.Message)
2221-
.highlight(R);
2202+
diags
2203+
.diagnose(Loc, diag::availability_decl_unavailable, RawAccessorKind,
2204+
Name, platform.empty(), platform, EncodedMessage.Message)
2205+
.highlight(R);
22222206
}
22232207

22242208
switch (Attr->getVersionAvailability(ctx)) {
@@ -2695,7 +2679,7 @@ AvailabilityWalker::diagnoseIncDecRemoval(const ValueDecl *D, SourceRange R,
26952679
std::tie(RawAccessorKind, Name) = getAccessorKindAndNameForDiagnostics(D);
26962680

26972681
// If we emit a deprecation diagnostic, produce a fixit hint as well.
2698-
auto diag = TC.diagnose(R.Start, diag::availability_decl_unavailable_msg,
2682+
auto diag = TC.diagnose(R.Start, diag::availability_decl_unavailable,
26992683
RawAccessorKind, Name, true, "",
27002684
"it has been removed in Swift 3");
27012685
if (isa<PrefixUnaryExpr>(call)) {
@@ -2746,9 +2730,9 @@ AvailabilityWalker::diagnoseMemoryLayoutMigration(const ValueDecl *D,
27462730
std::tie(RawAccessorKind, Name) = getAccessorKindAndNameForDiagnostics(D);
27472731

27482732
EncodedDiagnosticMessage EncodedMessage(Attr->Message);
2749-
auto diag = TC.diagnose(R.Start, diag::availability_decl_unavailable_msg,
2750-
RawAccessorKind, Name, true, "",
2751-
EncodedMessage.Message);
2733+
auto diag =
2734+
TC.diagnose(R.Start, diag::availability_decl_unavailable, RawAccessorKind,
2735+
Name, true, "", EncodedMessage.Message);
27522736
diag.highlight(R);
27532737

27542738
auto subject = args->getSubExpr();

lib/Sema/TypeCheckPattern.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,11 +1414,11 @@ bool TypeChecker::coercePatternToType(Pattern *&P, TypeResolution resolution,
14141414
EEP->getName().str() == "Some") {
14151415
SmallString<4> Rename;
14161416
camel_case::toLowercaseWord(EEP->getName().str(), Rename);
1417-
diagnose(EEP->getLoc(),
1418-
diag::availability_decl_unavailable_rename,
1419-
/*"getter" prefix*/2, EEP->getName(), /*replaced*/false,
1420-
/*special kind*/0, Rename.str())
1421-
.fixItReplace(EEP->getLoc(), Rename.str());
1417+
diagnose(
1418+
EEP->getLoc(), diag::availability_decl_unavailable_rename,
1419+
/*"getter" prefix*/ 2, EEP->getName(), /*replaced*/ false,
1420+
/*special kind*/ 0, Rename.str(), /*message*/ StringRef())
1421+
.fixItReplace(EEP->getLoc(), Rename.str());
14221422

14231423
return true;
14241424
}

0 commit comments

Comments
 (0)