Skip to content

Commit 055a9ec

Browse files
committed
AST: Return a SemanticAvailableAttr from Decl::getDeprecatedAttr().
1 parent 2bc0427 commit 055a9ec

File tree

6 files changed

+59
-41
lines changed

6 files changed

+59
-41
lines changed

include/swift/AST/Attr.h

+10
Original file line numberDiff line numberDiff line change
@@ -3215,6 +3215,16 @@ class SemanticAvailableAttr final {
32153215
/// `PlatformKind::none` if the attribute is not platform specific.
32163216
PlatformKind getPlatform() const { return getDomain().getPlatformKind(); }
32173217

3218+
/// Whether this is attribute indicates unavailability in all versions.
3219+
bool isUnconditionallyUnavailable() const {
3220+
return attr->isUnconditionallyUnavailable();
3221+
}
3222+
3223+
/// Whether this is attribute indicates deprecation in all versions.
3224+
bool isUnconditionallyDeprecated() const {
3225+
return attr->isUnconditionallyDeprecated();
3226+
}
3227+
32183228
/// Whether this is a `noasync` attribute.
32193229
bool isNoAsync() const { return attr->isNoAsync(); }
32203230

include/swift/AST/Decl.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -1416,15 +1416,15 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl>, public Swi
14161416

14171417
/// Returns true if the declaration is deprecated at the current deployment
14181418
/// target.
1419-
bool isDeprecated() const { return getDeprecatedAttr() != nullptr; }
1419+
bool isDeprecated() const { return getDeprecatedAttr().has_value(); }
14201420

14211421
/// Returns the first `@available` attribute that indicates that this decl
14221422
/// is deprecated on current deployment target, or `nullptr` otherwise.
1423-
const AvailableAttr *getDeprecatedAttr() const;
1423+
std::optional<SemanticAvailableAttr> getDeprecatedAttr() const;
14241424

14251425
/// Returns the first `@available` attribute that indicates that this decl
14261426
/// will be deprecated in the future, or `nullptr` otherwise.
1427-
const AvailableAttr *getSoftDeprecatedAttr() const;
1427+
std::optional<SemanticAvailableAttr> getSoftDeprecatedAttr() const;
14281428

14291429
/// Returns the first @available attribute that indicates this decl is
14301430
/// unavailable from asynchronous contexts, or `nullptr` otherwise.

lib/AST/Availability.cpp

+18-22
Original file line numberDiff line numberDiff line change
@@ -511,64 +511,60 @@ Decl::getActiveAvailableAttrForCurrentPlatform(bool ignoreAppExtensions) const {
511511
return bestAttr;
512512
}
513513

514-
const AvailableAttr *Decl::getDeprecatedAttr() const {
514+
std::optional<SemanticAvailableAttr> Decl::getDeprecatedAttr() const {
515515
auto &ctx = getASTContext();
516-
const AvailableAttr *result = nullptr;
516+
std::optional<SemanticAvailableAttr> result;
517517
auto bestActive = getActiveAvailableAttrForCurrentPlatform();
518518

519-
for (auto semanticAttr :
520-
getSemanticAvailableAttrs(/*includingInactive=*/false)) {
521-
auto attr = semanticAttr.getParsedAttr();
522-
523-
if (attr->hasPlatform() && (!bestActive || semanticAttr != bestActive))
519+
for (auto attr : getSemanticAvailableAttrs(/*includingInactive=*/false)) {
520+
if (attr.isPlatformSpecific() && (!bestActive || attr != bestActive))
524521
continue;
525522

526523
// Unconditional deprecated.
527-
if (attr->isUnconditionallyDeprecated())
524+
if (attr.isUnconditionallyDeprecated())
528525
return attr;
529526

530-
std::optional<llvm::VersionTuple> deprecatedVersion = attr->Deprecated;
527+
auto deprecatedVersion = attr.getDeprecated();
531528

532529
StringRef deprecatedPlatform;
533530
llvm::VersionTuple remappedDeprecatedVersion;
534531
if (AvailabilityInference::updateDeprecatedPlatformForFallback(
535-
attr, ctx, deprecatedPlatform, remappedDeprecatedVersion))
532+
attr.getParsedAttr(), ctx, deprecatedPlatform,
533+
remappedDeprecatedVersion))
536534
deprecatedVersion = remappedDeprecatedVersion;
537535

538536
if (!deprecatedVersion.has_value())
539537
continue;
540538

541-
llvm::VersionTuple minVersion = semanticAttr.getActiveVersion(ctx);
539+
llvm::VersionTuple minVersion = attr.getActiveVersion(ctx);
542540

543541
// We treat the declaration as deprecated if it is deprecated on
544542
// all deployment targets.
545543
if (deprecatedVersion.value() <= minVersion) {
546-
result = attr;
544+
result.emplace(attr);
547545
}
548546
}
549547
return result;
550548
}
551549

552-
const AvailableAttr *Decl::getSoftDeprecatedAttr() const {
550+
std::optional<SemanticAvailableAttr> Decl::getSoftDeprecatedAttr() const {
553551
auto &ctx = getASTContext();
554-
const AvailableAttr *result = nullptr;
552+
std::optional<SemanticAvailableAttr> result;
555553
auto bestActive = getActiveAvailableAttrForCurrentPlatform();
556554

557-
for (auto semanticAttr :
558-
getSemanticAvailableAttrs(/*includingInactive=*/false)) {
559-
auto attr = semanticAttr.getParsedAttr();
560-
561-
if (attr->hasPlatform() && (!bestActive || semanticAttr != bestActive))
555+
for (auto attr : getSemanticAvailableAttrs(/*includingInactive=*/false)) {
556+
if (attr.isPlatformSpecific() && (!bestActive || attr != bestActive))
562557
continue;
563558

564-
std::optional<llvm::VersionTuple> deprecatedVersion = attr->Deprecated;
559+
// FIXME: This needs to do a version remap.
560+
auto deprecatedVersion = attr.getDeprecated();
565561
if (!deprecatedVersion.has_value())
566562
continue;
567563

568-
llvm::VersionTuple activeVersion = semanticAttr.getActiveVersion(ctx);
564+
llvm::VersionTuple activeVersion = attr.getActiveVersion(ctx);
569565

570566
if (deprecatedVersion.value() > activeVersion)
571-
result = attr;
567+
result.emplace(attr);
572568
}
573569
return result;
574570
}

lib/IDE/CodeCompletionDiagnostics.cpp

+22-10
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ class CodeCompletionDiagnostics {
5555
llvm::raw_ostream &Out, Diag<ArgTypes...> ID,
5656
typename swift::detail::PassArgument<ArgTypes>::type... VArgs);
5757

58+
bool getDiagnosticForDeprecated(const ValueDecl *D, const AvailableAttr *Attr,
59+
bool isSoftDeprecated,
60+
CodeCompletionDiagnosticSeverity &severity,
61+
llvm::raw_ostream &Out);
62+
5863
bool getDiagnosticForDeprecated(const ValueDecl *D,
5964
CodeCompletionDiagnosticSeverity &severity,
6065
llvm::raw_ostream &Out);
@@ -75,16 +80,9 @@ bool CodeCompletionDiagnostics::getDiagnostics(
7580
}
7681

7782
bool CodeCompletionDiagnostics::getDiagnosticForDeprecated(
78-
const ValueDecl *D, CodeCompletionDiagnosticSeverity &severity,
79-
llvm::raw_ostream &Out) {
80-
bool isSoftDeprecated = false;
81-
const AvailableAttr *Attr = D->getDeprecatedAttr();
82-
if (!Attr) {
83-
Attr = D->getSoftDeprecatedAttr();
84-
isSoftDeprecated = true;
85-
}
86-
if (!Attr)
87-
return true;
83+
const ValueDecl *D, const AvailableAttr *Attr, bool isSoftDeprecated,
84+
CodeCompletionDiagnosticSeverity &severity, llvm::raw_ostream &Out) {
85+
assert(Attr);
8886

8987
// FIXME: Code completion doesn't offer accessors. It only emits 'VarDecl's.
9088
// So getter/setter specific availability doesn't work in code completion.
@@ -144,6 +142,20 @@ bool CodeCompletionDiagnostics::getDiagnosticForDeprecated(
144142
return false;;
145143
}
146144

145+
bool CodeCompletionDiagnostics::getDiagnosticForDeprecated(
146+
const ValueDecl *D, CodeCompletionDiagnosticSeverity &severity,
147+
llvm::raw_ostream &Out) {
148+
if (auto attr = D->getDeprecatedAttr())
149+
return getDiagnosticForDeprecated(D, attr->getParsedAttr(), false, severity,
150+
Out);
151+
152+
if (auto attr = D->getSoftDeprecatedAttr())
153+
return getDiagnosticForDeprecated(D, attr->getParsedAttr(), true, severity,
154+
Out);
155+
156+
return true;
157+
}
158+
147159
} // namespace
148160

149161
bool swift::ide::getContextFreeCompletionDiagnostics(

lib/Sema/TypeCheckAvailability.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -2373,14 +2373,14 @@ diagnosePotentialUnavailability(const RootProtocolConformance *rootConf,
23732373
/// declaration is deprecated or null otherwise.
23742374
static const AvailableAttr *getDeprecated(const Decl *D) {
23752375
auto &Ctx = D->getASTContext();
2376-
if (auto *Attr = D->getDeprecatedAttr())
2377-
return Attr;
2376+
if (auto Attr = D->getDeprecatedAttr())
2377+
return Attr->getParsedAttr();
23782378

23792379
if (Ctx.LangOpts.WarnSoftDeprecated) {
23802380
// When -warn-soft-deprecated is specified, treat any declaration that is
23812381
// deprecated in the future as deprecated.
2382-
if (auto *Attr = D->getSoftDeprecatedAttr())
2383-
return Attr;
2382+
if (auto Attr = D->getSoftDeprecatedAttr())
2383+
return Attr->getParsedAttr();
23842384
}
23852385

23862386
// Treat extensions methods as deprecated if their extension

lib/Sema/TypeCheckProtocol.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -4452,8 +4452,8 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
44524452
auto &ctx = witness->getASTContext();
44534453
auto &diags = ctx.Diags;
44544454
SourceLoc diagLoc = getLocForDiagnosingWitness(conformance, witness);
4455-
auto *attr = witness->getDeprecatedAttr();
4456-
EncodedDiagnosticMessage EncodedMessage(attr->Message);
4455+
auto attr = witness->getDeprecatedAttr();
4456+
EncodedDiagnosticMessage EncodedMessage(attr->getMessage());
44574457
diags.diagnose(diagLoc, diag::witness_deprecated,
44584458
witness, conformance->getProtocol()->getName(),
44594459
EncodedMessage.Message);

0 commit comments

Comments
 (0)