[Compile Time Constant Extraction] Extract listed Availability Attributes for buildLimitedAvailability in Result Builders

This commit is contained in:
Venkatesh Sriram
2024-09-26 14:11:35 -07:00
parent 352fb004b3
commit f04486db3e
3 changed files with 64 additions and 2 deletions

View File

@@ -15,6 +15,7 @@
#include "swift/AST/Attr.h"
#include "swift/AST/Type.h"
#include "swift/AST/TypeCheckRequests.h"
#include <memory>
#include <string>
#include <vector>
@@ -197,6 +198,15 @@ public:
///
class ConditionalMember : public BuilderMember {
public:
ConditionalMember(MemberKind MemberKind,
std::vector<PlatformVersionConstraintAvailabilitySpec>
AvailabilityAttributes,
std::vector<std::shared_ptr<BuilderMember>> IfElements,
std::vector<std::shared_ptr<BuilderMember>> ElseElements)
: BuilderMember(MemberKind),
AvailabilityAttributes(AvailabilityAttributes),
IfElements(IfElements), ElseElements(ElseElements) {}
ConditionalMember(MemberKind MemberKind,
std::vector<std::shared_ptr<BuilderMember>> IfElements,
std::vector<std::shared_ptr<BuilderMember>> ElseElements)
@@ -210,6 +220,10 @@ public:
(Kind == MemberKind::Optional);
}
std::optional<std::vector<PlatformVersionConstraintAvailabilitySpec>>
getAvailabilityAttributes() const {
return AvailabilityAttributes;
}
std::vector<std::shared_ptr<BuilderMember>> getIfElements() const {
return IfElements;
}
@@ -218,6 +232,8 @@ public:
}
private:
std::optional<std::vector<PlatformVersionConstraintAvailabilitySpec>>
AvailabilityAttributes;
std::vector<std::shared_ptr<BuilderMember>> IfElements;
std::vector<std::shared_ptr<BuilderMember>> ElseElements;
};

View File

@@ -945,6 +945,7 @@ getResultBuilderElementFromASTNode(const ASTNode node) {
BuilderValue::ConditionalMember
getConditionalMemberFromIfStmt(const IfStmt *ifStmt) {
std::vector<PlatformVersionConstraintAvailabilitySpec> AvailabilityAttributes;
std::vector<std::shared_ptr<BuilderValue::BuilderMember>> IfElements;
std::vector<std::shared_ptr<BuilderValue::BuilderMember>> ElseElements;
if (auto thenBraceStmt = ifStmt->getThenStmt()) {
@@ -976,12 +977,24 @@ getConditionalMemberFromIfStmt(const IfStmt *ifStmt) {
}
for (auto elt : ifStmt->getCond()) {
if (elt.getKind() == StmtConditionElement::CK_Availability) {
for (auto *Q : elt.getAvailability()->getQueries()) {
if (auto *availability =
dyn_cast<PlatformVersionConstraintAvailabilitySpec>(Q)) {
AvailabilityAttributes.push_back(*availability);
}
}
memberKind = BuilderValue::LimitedAvailability;
break;
}
}
return BuilderValue::ConditionalMember(memberKind, IfElements, ElseElements);
if (AvailabilityAttributes.empty()) {
return BuilderValue::ConditionalMember(memberKind, IfElements,
ElseElements);
}
return BuilderValue::ConditionalMember(memberKind, AvailabilityAttributes,
IfElements, ElseElements);
}
BuilderValue::ArrayMember
@@ -1094,6 +1107,17 @@ void writeBuilderMember(
default: {
auto member = cast<BuilderValue::ConditionalMember>(Member);
if (auto availabilityAttributes = member->getAvailabilityAttributes()) {
JSON.attributeArray("availabilityAttributes", [&] {
for (auto elem : *availabilityAttributes) {
JSON.object([&] {
JSON.attribute("platform",
platformString(elem.getPlatform()).str());
JSON.attribute("minVersion", elem.getVersion().getAsString());
});
}
});
}
JSON.attributeArray("ifElements", [&] {
for (auto elem : member->getIfElements()) {
JSON.object([&] { writeBuilderMember(JSON, elem); });

View File

@@ -108,7 +108,7 @@ public struct MyFooProviderInferred: FooProvider {
Foo(name: "MyFooProviderInferred.foos.Optional")
}
if #available(macOS 99, *) {
if #available(iOS 18.0, macOS 15.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) {
Foo(name: "MyFooProviderInferred.foos.limitedAvailability.1")
Foo(name: "MyFooProviderInferred.foos.limitedAvailability.2")
} else {
@@ -430,6 +430,28 @@ public struct MyFooProviderInferred: FooProvider {
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "kind": "buildLimitedAvailability",
// CHECK-NEXT: "availabilityAttributes": [
// CHECK-NEXT: {
// CHECK-NEXT: "platform": "iOS",
// CHECK-NEXT: "minVersion": "18.0"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "platform": "macOS",
// CHECK-NEXT: "minVersion": "15.0"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "platform": "watchOS",
// CHECK-NEXT: "minVersion": "11.0"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "platform": "tvOS",
// CHECK-NEXT: "minVersion": "18.0"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "platform": "visionOS",
// CHECK-NEXT: "minVersion": "2.0"
// CHECK-NEXT: }
// CHECK-NEXT: ],
// CHECK-NEXT: "ifElements": [
// CHECK-NEXT: {
// CHECK-NEXT: "element": {