Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve DiagnosticEngine's handling of ValueDecl arguments #67075

Merged
merged 14 commits into from
Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion docs/Diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,26 @@ If you run into any issues or have questions while following the steps above, fe

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

- `%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.
- `%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, StringRef, Identifier, or Decl. If it's a StringRef or Identifier, the specifier acts as an emptiness check; if it's a Decl, it acts as a null check.

- `%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.

- `%error` - Represents a branch in a `%select` that should never be taken. In debug builds of the compiler this produces an assertion failure.

- `%%` - Emits a literal percent sign.

There are several format specifiers that are specific to `Decl` parameters:

- `%kind0` - Prefixes the declaration's name with its descriptive decl kind (e.g. `instance method 'foo(x:)'`).

- `%kindonly0` - Inserts only the descriptive decl kind (e.g. `instance method`).

- `%base0` - Inserts only the base name, removing any argument labels (e.g. `'foo'`).

- `%kindbase0` - Combines `kind` and `base` (e.g. `instance method 'foo'`).

Note: If your diagnostic could apply to accessors, be careful how you format the declaration's name; accessors have an empty name, so you need to display their accessor kind and the name of their storage decl instead. Inserting the name with a `Decl *` parameter will handle these complications automatically; if you want to use `DeclName` or `Identifier` instead, you'll probably need a separate version of the diagnostic for accessors.

### Diagnostic Verifier ###

(This section is specific to the Swift compiler's diagnostic engine.)
Expand Down
24 changes: 10 additions & 14 deletions include/swift/AST/DiagnosticEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,14 @@ class NamedDecl;
}

namespace swift {
class ConstructorDecl;
class Decl;
class DeclAttribute;
class DiagnosticEngine;
class FuncDecl;
class GeneratedSourceInfo;
class SourceManager;
class TypeAliasDecl;
class ValueDecl;
class SourceFile;

Expand Down Expand Up @@ -109,7 +112,7 @@ namespace swift {
Unsigned,
Identifier,
ObjCSelector,
ValueDecl,
Decl,
Type,
TypeRepr,
FullyQualifiedType,
Expand Down Expand Up @@ -143,7 +146,7 @@ namespace swift {
StringRef StringVal;
DeclNameRef IdentifierVal;
ObjCSelector ObjCSelectorVal;
const ValueDecl *TheValueDecl;
const Decl *TheDecl;
Type TypeVal;
TypeRepr *TyR;
FullyQualified<Type> FullyQualifiedTypeVal;
Expand Down Expand Up @@ -194,8 +197,8 @@ namespace swift {
: Kind(DiagnosticArgumentKind::ObjCSelector), ObjCSelectorVal(S) {
}

DiagnosticArgument(const ValueDecl *VD)
: Kind(DiagnosticArgumentKind::ValueDecl), TheValueDecl(VD) {
DiagnosticArgument(const Decl *VD)
: Kind(DiagnosticArgumentKind::Decl), TheDecl(VD) {
}

DiagnosticArgument(Type T)
Expand Down Expand Up @@ -305,9 +308,9 @@ namespace swift {
return ObjCSelectorVal;
}

const ValueDecl *getAsValueDecl() const {
assert(Kind == DiagnosticArgumentKind::ValueDecl);
return TheValueDecl;
const Decl *getAsDecl() const {
assert(Kind == DiagnosticArgumentKind::Decl);
return TheDecl;
}

Type getAsType() const {
Expand Down Expand Up @@ -1497,13 +1500,6 @@ namespace swift {
const StringRef Message;
};

/// Returns a value that can be used to select between accessor kinds in
/// diagnostics.
///
/// This is correlated with diag::availability_deprecated and others.
std::pair<unsigned, DeclName>
getAccessorKindAndNameForDiagnostics(const ValueDecl *D);

/// Retrieve the macro name for a generated source info that represents
/// a macro expansion.
DeclName getGeneratedSourceInfoMacroName(const GeneratedSourceInfo &info);
Expand Down
16 changes: 8 additions & 8 deletions include/swift/AST/DiagnosticsIDE.def
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ NOTE(ide_redundant_import_indirect, none,
"module %0 is already imported via another module import", (StringRef))

WARNING(ide_availability_softdeprecated, Deprecation,
"%select{getter for |setter for |}0%1 will be deprecated"
" in %select{a future version|%select{a future version of %3|%3 %5}4}2"
"%select{|: %6}6",
(unsigned, DeclName, bool, StringRef, bool, llvm::VersionTuple,
"%0 will be deprecated"
" in %select{a future version|%select{a future version of %2|%2 %4}3}1"
"%select{|: %5}5",
(const ValueDecl *, bool, StringRef, bool, llvm::VersionTuple,
StringRef))

WARNING(ide_availability_softdeprecated_rename, Deprecation,
"%select{getter for |setter for |}0%1 will be deprecated"
" in %select{a future version|%select{a future version of %3|%3 %5}4}2"
": renamed to '%6'",
(unsigned, DeclName, bool, StringRef, bool, llvm::VersionTuple, StringRef))
"%0 will be deprecated"
" in %select{a future version|%select{a future version of %2|%2 %4}3}1"
": renamed to '%5'",
(const ValueDecl *, bool, StringRef, bool, llvm::VersionTuple, StringRef))

WARNING(ide_recursive_accessor_reference,none,
"attempting to %select{access|modify}1 %0 within its own "
Expand Down
Loading