Skip to content

Commit 4529083

Browse files
authored
Merge pull request swiftlang#21110 from aciidb0mb3r/swiftpm-manifest-version
Extend @available to support PackageDescription
2 parents eed4996 + 92d09f4 commit 4529083

23 files changed

+370
-93
lines changed

include/swift/AST/Attr.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,10 @@ enum class PlatformAgnosticAvailabilityKind {
616616
/// The declaration is available in some but not all versions
617617
/// of Swift, as specified by the VersionTuple members.
618618
SwiftVersionSpecific,
619+
/// The declaration is available in some but not all versions
620+
/// of SwiftPM's PackageDescription library, as specified by
621+
/// the VersionTuple members.
622+
PackageDescriptionVersionSpecific,
619623
/// The declaration is unavailable for other reasons.
620624
Unavailable,
621625
};
@@ -686,6 +690,9 @@ class AvailableAttr : public DeclAttribute {
686690
/// Whether this is a language-version-specific entity.
687691
bool isLanguageVersionSpecific() const;
688692

693+
/// Whether this is a PackageDescription version specific entity.
694+
bool isPackageDescriptionVersionSpecific() const;
695+
689696
/// Whether this is an unconditionally unavailable entity.
690697
bool isUnconditionallyUnavailable() const;
691698

@@ -722,6 +729,12 @@ class AvailableAttr : public DeclAttribute {
722729
/// Returns true if this attribute is active given the current platform.
723730
bool isActivePlatform(const ASTContext &ctx) const;
724731

732+
/// Returns the active version from the AST context corresponding to
733+
/// the available kind. For example, this will return the effective language
734+
/// version for swift version-specific availability kind, PackageDescription
735+
/// version for PackageDescription version-specific availability.
736+
llvm::VersionTuple getActiveVersion(const ASTContext &ctx) const;
737+
725738
/// Compare this attribute's version information against the platform or
726739
/// language version (assuming the this attribute pertains to the active
727740
/// platform).

include/swift/AST/AvailabilitySpec.h

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ enum class AvailabilitySpecKind {
3737

3838
/// A language-version constraint of the form "swift X.Y.Z"
3939
LanguageVersionConstraint,
40+
41+
/// A PackageDescription version constraint of the form "_PackageDescription X.Y.Z"
42+
PackageDescriptionVersionConstraint,
4043
};
4144

4245
/// The root class for specifications of API availability in availability
@@ -101,38 +104,48 @@ class PlatformVersionConstraintAvailabilitySpec : public AvailabilitySpec {
101104
};
102105

103106
/// An availability specification that guards execution based on the
104-
/// compile-time language version, e.g., swift >= 3.0.1.
105-
class LanguageVersionConstraintAvailabilitySpec : public AvailabilitySpec {
106-
SourceLoc SwiftLoc;
107+
/// compile-time platform agnostic version, e.g., swift >= 3.0.1,
108+
/// package-description >= 4.0.
109+
class PlatformAgnosticVersionConstraintAvailabilitySpec : public AvailabilitySpec {
110+
SourceLoc PlatformAgnosticNameLoc;
107111

108112
llvm::VersionTuple Version;
109113
SourceRange VersionSrcRange;
110114

111115
public:
112-
LanguageVersionConstraintAvailabilitySpec(SourceLoc SwiftLoc,
113-
llvm::VersionTuple Version,
114-
SourceRange VersionSrcRange)
115-
: AvailabilitySpec(AvailabilitySpecKind::LanguageVersionConstraint),
116-
SwiftLoc(SwiftLoc), Version(Version),
117-
VersionSrcRange(VersionSrcRange) {}
116+
PlatformAgnosticVersionConstraintAvailabilitySpec(
117+
AvailabilitySpecKind AvailabilitySpecKind,
118+
SourceLoc PlatformAgnosticNameLoc, llvm::VersionTuple Version,
119+
SourceRange VersionSrcRange)
120+
: AvailabilitySpec(AvailabilitySpecKind),
121+
PlatformAgnosticNameLoc(PlatformAgnosticNameLoc), Version(Version),
122+
VersionSrcRange(VersionSrcRange) {
123+
assert(AvailabilitySpecKind == AvailabilitySpecKind::LanguageVersionConstraint ||
124+
AvailabilitySpecKind == AvailabilitySpecKind::PackageDescriptionVersionConstraint);
125+
}
118126

119-
SourceLoc getSwiftLoc() const { return SwiftLoc; }
127+
SourceLoc getPlatformAgnosticNameLoc() const { return PlatformAgnosticNameLoc; }
120128

121129
// The platform version to compare against.
122130
llvm::VersionTuple getVersion() const { return Version; }
123131
SourceRange getVersionSrcRange() const { return VersionSrcRange; }
124132

125133
SourceRange getSourceRange() const;
126134

135+
bool isLanguageVersionSpecific() const {
136+
return getKind() == AvailabilitySpecKind::LanguageVersionConstraint;
137+
}
138+
127139
void print(raw_ostream &OS, unsigned Indent) const;
128140

129141
static bool classof(const AvailabilitySpec *Spec) {
130-
return Spec->getKind() == AvailabilitySpecKind::LanguageVersionConstraint;
142+
return Spec->getKind() == AvailabilitySpecKind::LanguageVersionConstraint ||
143+
Spec->getKind() == AvailabilitySpecKind::PackageDescriptionVersionConstraint;
131144
}
132145

133146
void *
134147
operator new(size_t Bytes, ASTContext &C,
135-
unsigned Alignment = alignof(LanguageVersionConstraintAvailabilitySpec)){
148+
unsigned Alignment = alignof(PlatformAgnosticVersionConstraintAvailabilitySpec)){
136149
return AvailabilitySpec::operator new(Bytes, C, Alignment);
137150
}
138151
};

include/swift/AST/DiagnosticsParse.def

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,15 +1363,15 @@ ERROR(attr_availability_expected_equal,none,
13631363
ERROR(attr_availability_expected_version,none,
13641364
"expected version number in '%0' attribute", (StringRef))
13651365

1366-
WARNING(attr_availability_swift_expected_option,none,
1366+
WARNING(attr_availability_platform_agnostic_expected_option,none,
13671367
"expected 'introduced', 'deprecated', or 'obsoleted' in '%0' attribute "
1368-
"for platform 'swift'", (StringRef))
1369-
WARNING(attr_availability_swift_expected_deprecated_version,none,
1368+
"for platform '%1'", (StringRef, StringRef))
1369+
WARNING(attr_availability_platform_agnostic_expected_deprecated_version,none,
13701370
"expected version number with 'deprecated' in '%0' attribute for "
1371-
"platform 'swift'", (StringRef))
1372-
WARNING(attr_availability_swift_infeasible_option,none,
1373-
"'%0' cannot be used in '%1' attribute for platform 'swift'",
1374-
(StringRef, StringRef))
1371+
"platform '%1'", (StringRef, StringRef))
1372+
WARNING(attr_availability_platform_agnostic_infeasible_option,none,
1373+
"'%0' cannot be used in '%1' attribute for platform '%2'",
1374+
(StringRef, StringRef, StringRef))
13751375

13761376
WARNING(attr_availability_nonspecific_platform_unexpected_version,none,
13771377
"unexpected version number in '%0' attribute for non-specific platform "
@@ -1606,12 +1606,15 @@ ERROR(avail_query_version_comparison_not_needed,
16061606
ERROR(availability_query_wildcard_required, none,
16071607
"must handle potential future platforms with '*'", ())
16081608

1609-
ERROR(availability_swift_must_occur_alone, none,
1610-
"'swift' version-availability must be specified alone", ())
1609+
ERROR(availability_must_occur_alone, none,
1610+
"'%0' version-availability must be specified alone", (StringRef))
16111611

16121612
ERROR(pound_available_swift_not_allowed, none,
16131613
"Swift language version checks not allowed in #available(...)", ())
16141614

1615+
ERROR(pound_available_package_description_not_allowed, none,
1616+
"PackageDescription version checks not allowed in #available(...)", ())
1617+
16151618
ERROR(availability_query_repeated_platform, none,
16161619
"version for '%0' already specified", (StringRef))
16171620

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3936,9 +3936,9 @@ NOTE(availability_marked_unavailable, none,
39363936
"%select{getter for |setter for |}0%1 has been explicitly marked "
39373937
"unavailable here", (unsigned, DeclName))
39383938

3939-
NOTE(availability_introduced_in_swift, none,
3940-
"%select{getter for |setter for |}0%1 was introduced in Swift %2",
3941-
(unsigned, DeclName, llvm::VersionTuple))
3939+
NOTE(availability_introduced_in_version, none,
3940+
"%select{getter for |setter for |}0%1 was introduced in %2 %3",
3941+
(unsigned, DeclName, StringRef, llvm::VersionTuple))
39423942

39433943
NOTE(availability_obsoleted, none,
39443944
"%select{getter for |setter for |}0%1 was obsoleted in %2 %3",

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ namespace swift {
8282
/// User-overridable language version to compile for.
8383
version::Version EffectiveLanguageVersion = version::Version::getCurrentLanguageVersion();
8484

85+
/// PackageDescription version to compile for.
86+
version::Version PackageDescriptionVersion;
87+
8588
/// Disable API availability checking.
8689
bool DisableAvailabilityChecking = false;
8790

include/swift/Option/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ def swift_version : Separate<["-"], "swift-version">, Flags<[FrontendOption, Par
172172
HelpText<"Interpret input according to a specific Swift language version number">,
173173
MetaVarName<"<vers>">;
174174

175+
def package_description_version: Separate<["-"], "package-description-version">,
176+
Flags<[FrontendOption, HelpHidden, ParseableInterfaceOption]>,
177+
HelpText<"The version number to be applied on the input for the PackageDescription availability kind">,
178+
MetaVarName<"<vers>">;
179+
175180
def tools_directory : Separate<["-"], "tools-directory">,
176181
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild,
177182
ArgumentIsPath]>,

include/swift/Parse/Parser.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,8 +1413,8 @@ class Parser {
14131413
ParserResult<AvailabilitySpec> parseAvailabilitySpec();
14141414
ParserResult<PlatformVersionConstraintAvailabilitySpec>
14151415
parsePlatformVersionConstraintSpec();
1416-
ParserResult<LanguageVersionConstraintAvailabilitySpec>
1417-
parseLanguageVersionConstraintSpec();
1416+
ParserResult<PlatformAgnosticVersionConstraintAvailabilitySpec>
1417+
parsePlatformAgnosticVersionConstraintSpec();
14181418

14191419
bool canDelayMemberDeclParsing();
14201420
};

include/swift/Serialization/ModuleFormat.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5252
/// describe what change you made. The content of this comment isn't important;
5353
/// it just ensures a conflict if two people change the module format.
5454
/// Don't worry about adhering to the 80-column limit for this line.
55-
const uint16_t SWIFTMODULE_VERSION_MINOR = 470; // Last change: Remove @trivial
55+
const uint16_t SWIFTMODULE_VERSION_MINOR = 471; // Last change: Add @available(_PackageDescription..)
5656

5757
using DeclIDField = BCFixed<31>;
5858

@@ -1547,6 +1547,7 @@ namespace decls_block {
15471547
BCFixed<1>, // implicit flag
15481548
BCFixed<1>, // is unconditionally unavailable?
15491549
BCFixed<1>, // is unconditionally deprecated?
1550+
BCFixed<1>, // is this PackageDescription version-specific kind?
15501551
BC_AVAIL_TUPLE, // Introduced
15511552
BC_AVAIL_TUPLE, // Deprecated
15521553
BC_AVAIL_TUPLE, // Obsoleted

lib/AST/ASTDumper.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1436,7 +1436,8 @@ class PrintStmt : public StmtVisitor<PrintStmt> {
14361436
cast<PlatformVersionConstraintAvailabilitySpec>(Query)->print(OS, Indent + 2);
14371437
break;
14381438
case AvailabilitySpecKind::LanguageVersionConstraint:
1439-
cast<LanguageVersionConstraintAvailabilitySpec>(Query)->print(OS, Indent + 2);
1439+
case AvailabilitySpecKind::PackageDescriptionVersionConstraint:
1440+
cast<PlatformVersionConstraintAvailabilitySpec>(Query)->print(OS, Indent + 2);
14401441
break;
14411442
case AvailabilitySpecKind::OtherPlatform:
14421443
cast<OtherPlatformAvailabilitySpec>(Query)->print(OS, Indent + 2);

lib/AST/Attr.cpp

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ const AvailableAttr *DeclAttributes::getUnavailable(
142142

143143
// If this attribute doesn't apply to the active platform, we're done.
144144
if (!AvAttr->isActivePlatform(ctx) &&
145-
!AvAttr->isLanguageVersionSpecific())
145+
!AvAttr->isLanguageVersionSpecific() &&
146+
!AvAttr->isPackageDescriptionVersionSpecific())
146147
continue;
147148

148149
// Unconditional unavailable.
@@ -172,7 +173,8 @@ DeclAttributes::getDeprecated(const ASTContext &ctx) const {
172173
continue;
173174

174175
if (!AvAttr->isActivePlatform(ctx) &&
175-
!AvAttr->isLanguageVersionSpecific())
176+
!AvAttr->isLanguageVersionSpecific() &&
177+
!AvAttr->isPackageDescriptionVersionSpecific())
176178
continue;
177179

178180
// Unconditional deprecated.
@@ -183,10 +185,7 @@ DeclAttributes::getDeprecated(const ASTContext &ctx) const {
183185
if (!DeprecatedVersion.hasValue())
184186
continue;
185187

186-
llvm::VersionTuple MinVersion =
187-
AvAttr->isLanguageVersionSpecific() ?
188-
ctx.LangOpts.EffectiveLanguageVersion :
189-
ctx.LangOpts.getMinPlatformVersion();
188+
llvm::VersionTuple MinVersion = AvAttr->getActiveVersion(ctx);
190189

191190
// We treat the declaration as deprecated if it is deprecated on
192191
// all deployment targets.
@@ -240,6 +239,7 @@ static bool isShortAvailable(const DeclAttribute *DA) {
240239
return false;
241240
case PlatformAgnosticAvailabilityKind::None:
242241
case PlatformAgnosticAvailabilityKind::SwiftVersionSpecific:
242+
case PlatformAgnosticAvailabilityKind::PackageDescriptionVersionSpecific:
243243
return true;
244244
}
245245

@@ -261,10 +261,16 @@ static void printShortFormAvailable(ArrayRef<const DeclAttribute *> Attrs,
261261
Printer << "@available(";
262262
auto FirstAvail = cast<AvailableAttr>(Attrs.front());
263263
if (Attrs.size() == 1 &&
264-
FirstAvail->isLanguageVersionSpecific()) {
264+
FirstAvail->getPlatformAgnosticAvailability() !=
265+
PlatformAgnosticAvailabilityKind::None) {
265266
assert(FirstAvail->Introduced.hasValue());
266-
Printer << "swift "
267-
<< FirstAvail->Introduced.getValue().getAsString()
267+
if (FirstAvail->isLanguageVersionSpecific()) {
268+
Printer << "swift ";
269+
} else {
270+
assert(FirstAvail->isPackageDescriptionVersionSpecific());
271+
Printer << "_PackageDescription ";
272+
}
273+
Printer << FirstAvail->Introduced.getValue().getAsString()
268274
<< ")";
269275
} else {
270276
for (auto *DA : Attrs) {
@@ -290,6 +296,7 @@ void DeclAttributes::print(ASTPrinter &Printer, const PrintOptions &Options,
290296
// Process attributes in passes.
291297
AttributeVector shortAvailableAttributes;
292298
const DeclAttribute *swiftVersionAvailableAttribute = nullptr;
299+
const DeclAttribute *packageDescriptionVersionAvailableAttribute = nullptr;
293300
AttributeVector longAttributes;
294301
AttributeVector attributes;
295302
AttributeVector modifiers;
@@ -311,6 +318,11 @@ void DeclAttributes::print(ASTPrinter &Printer, const PrintOptions &Options,
311318
swiftVersionAvailableAttribute = availableAttr;
312319
continue;
313320
}
321+
if (availableAttr->isPackageDescriptionVersionSpecific() &&
322+
isShortAvailable(availableAttr)) {
323+
packageDescriptionVersionAvailableAttribute = availableAttr;
324+
continue;
325+
}
314326
}
315327

316328
AttributeVector &which = DA->isDeclModifier() ? modifiers :
@@ -322,6 +334,8 @@ void DeclAttributes::print(ASTPrinter &Printer, const PrintOptions &Options,
322334

323335
if (swiftVersionAvailableAttribute)
324336
printShortFormAvailable(swiftVersionAvailableAttribute, Printer, Options);
337+
if (packageDescriptionVersionAvailableAttribute)
338+
printShortFormAvailable(packageDescriptionVersionAvailableAttribute, Printer, Options);
325339
if (!shortAvailableAttributes.empty())
326340
printShortFormAvailable(shortAvailableAttributes, Printer, Options);
327341

@@ -424,6 +438,8 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
424438
auto Attr = cast<AvailableAttr>(this);
425439
if (Attr->isLanguageVersionSpecific())
426440
Printer << "swift";
441+
else if (Attr->isPackageDescriptionVersionSpecific())
442+
Printer << "_PackageDescription";
427443
else
428444
Printer << Attr->platformString();
429445

@@ -890,11 +906,25 @@ bool AvailableAttr::isLanguageVersionSpecific() const {
890906
return false;
891907
}
892908

909+
bool AvailableAttr::isPackageDescriptionVersionSpecific() const {
910+
if (PlatformAgnostic ==
911+
PlatformAgnosticAvailabilityKind::PackageDescriptionVersionSpecific)
912+
{
913+
assert(Platform == PlatformKind::none &&
914+
(Introduced.hasValue() ||
915+
Deprecated.hasValue() ||
916+
Obsoleted.hasValue()));
917+
return true;
918+
}
919+
return false;
920+
}
921+
893922
bool AvailableAttr::isUnconditionallyUnavailable() const {
894923
switch (PlatformAgnostic) {
895924
case PlatformAgnosticAvailabilityKind::None:
896925
case PlatformAgnosticAvailabilityKind::Deprecated:
897926
case PlatformAgnosticAvailabilityKind::SwiftVersionSpecific:
927+
case PlatformAgnosticAvailabilityKind::PackageDescriptionVersionSpecific:
898928
return false;
899929

900930
case PlatformAgnosticAvailabilityKind::Unavailable:
@@ -911,6 +941,7 @@ bool AvailableAttr::isUnconditionallyDeprecated() const {
911941
case PlatformAgnosticAvailabilityKind::Unavailable:
912942
case PlatformAgnosticAvailabilityKind::UnavailableInSwift:
913943
case PlatformAgnosticAvailabilityKind::SwiftVersionSpecific:
944+
case PlatformAgnosticAvailabilityKind::PackageDescriptionVersionSpecific:
914945
return false;
915946

916947
case PlatformAgnosticAvailabilityKind::Deprecated:
@@ -920,17 +951,24 @@ bool AvailableAttr::isUnconditionallyDeprecated() const {
920951
llvm_unreachable("Unhandled PlatformAgnosticAvailabilityKind in switch.");
921952
}
922953

954+
llvm::VersionTuple AvailableAttr::getActiveVersion(const ASTContext &ctx) const {
955+
if (isLanguageVersionSpecific()) {
956+
return ctx.LangOpts.EffectiveLanguageVersion;
957+
} else if (isPackageDescriptionVersionSpecific()) {
958+
return ctx.LangOpts.PackageDescriptionVersion;
959+
} else {
960+
return ctx.LangOpts.getMinPlatformVersion();
961+
}
962+
}
963+
923964
AvailableVersionComparison AvailableAttr::getVersionAvailability(
924965
const ASTContext &ctx) const {
925966

926967
// Unconditional unavailability.
927968
if (isUnconditionallyUnavailable())
928969
return AvailableVersionComparison::Unavailable;
929970

930-
llvm::VersionTuple queryVersion =
931-
isLanguageVersionSpecific() ?
932-
ctx.LangOpts.EffectiveLanguageVersion :
933-
ctx.LangOpts.getMinPlatformVersion();
971+
llvm::VersionTuple queryVersion = getActiveVersion(ctx);
934972

935973
// If this entity was obsoleted before or at the query platform version,
936974
// consider it obsolete.
@@ -943,7 +981,7 @@ AvailableVersionComparison AvailableAttr::getVersionAvailability(
943981
// static requirement, so we treat "introduced later" as just plain
944982
// unavailable.
945983
if (Introduced && *Introduced > queryVersion) {
946-
if (isLanguageVersionSpecific())
984+
if (isLanguageVersionSpecific() || isPackageDescriptionVersionSpecific())
947985
return AvailableVersionComparison::Unavailable;
948986
else
949987
return AvailableVersionComparison::PotentiallyUnavailable;

0 commit comments

Comments
 (0)