Skip to content

Commit b27f3e0

Browse files
committed
[Sema] Extract per decl check for -require-explicit-availability
1 parent 51db014 commit b27f3e0

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2828,6 +2828,23 @@ bool swift::diagnoseDeclAvailability(const ValueDecl *Decl,
28282828
return AW.diagAvailability(const_cast<ValueDecl *>(Decl), R, nullptr, Flags);
28292829
}
28302830

2831+
/// Should we warn that \p valueDecl needs an explicit availability annotation
2832+
/// in -require-explicit-availaiblity mode?
2833+
static bool declNeedsExplicitAvailability(const ValueDecl *valueDecl) {
2834+
AccessScope scope =
2835+
valueDecl->getFormalAccessScope(/*useDC*/nullptr,
2836+
/*treatUsableFromInlineAsPublic*/true);
2837+
if (!scope.isPublic() ||
2838+
valueDecl->getAttrs().hasAttribute<AlwaysEmitIntoClientAttr>())
2839+
return false;
2840+
2841+
// Warn on decls without an introduction version.
2842+
auto &ctx = valueDecl->getASTContext();
2843+
auto safeRangeUnderApprox = AvailabilityInference::availableRange(valueDecl, ctx);
2844+
return !safeRangeUnderApprox.getOSVersion().hasLowerEndpoint() &&
2845+
!valueDecl->getAttrs().isUnavailable(ctx);
2846+
}
2847+
28312848
void swift::checkExplicitAvailability(Decl *decl) {
28322849
// Check only if the command line option was set.
28332850
if (!decl->getASTContext().LangOpts.RequireExplicitAvailability)
@@ -2840,27 +2857,14 @@ void swift::checkExplicitAvailability(Decl *decl) {
28402857

28412858
ValueDecl *valueDecl = dyn_cast<ValueDecl>(decl);
28422859
if (valueDecl == nullptr) {
2843-
// decl should be either a ValueDecl or an ExtensionDecl
2860+
// decl should be either a ValueDecl or an ExtensionDecl.
28442861
auto extension = cast<ExtensionDecl>(decl);
28452862
valueDecl = extension->getExtendedNominal();
28462863
if (!valueDecl)
28472864
return;
28482865
}
28492866

2850-
// Skip decls that are not public and not usable from inline.
2851-
AccessScope scope =
2852-
valueDecl->getFormalAccessScope(/*useDC*/nullptr,
2853-
/*treatUsableFromInlineAsPublic*/true);
2854-
if (!scope.isPublic() ||
2855-
decl->getAttrs().hasAttribute<AlwaysEmitIntoClientAttr>())
2856-
return;
2857-
2858-
// Warn on decls without an introduction version.
2859-
auto &ctx = decl->getASTContext();
2860-
auto safeRangeUnderApprox = AvailabilityInference::availableRange(decl, ctx);
2861-
if (!safeRangeUnderApprox.getOSVersion().hasLowerEndpoint() &&
2862-
!decl->getAttrs().isUnavailable(ctx)) {
2863-
2867+
if (declNeedsExplicitAvailability(valueDecl)) {
28642868
auto diag = decl->diagnose(diag::public_decl_needs_availability);
28652869

28662870
auto suggestPlatform = decl->getASTContext().LangOpts.RequireExplicitAvailabilityTarget;
@@ -2876,6 +2880,7 @@ void swift::checkExplicitAvailability(Decl *decl) {
28762880
{
28772881
llvm::raw_string_ostream Out(AttrText);
28782882

2883+
auto &ctx = valueDecl->getASTContext();
28792884
StringRef OriginalIndent = Lexer::getIndentationForLine(
28802885
ctx.SourceMgr, InsertLoc);
28812886
Out << "@available(" << suggestPlatform << ", *)\n"

0 commit comments

Comments
 (0)