Skip to content

Commit 774248f

Browse files
committed
ConstExtract: Refactor handling of AvailabilitySpec.
Soon, `AvailabilitySpec` will require that the `AvailabiltyDomain` it contains be queried using a request that takes the `DeclContext` as input in order to resolve the parsed domain name to an instance of `AvailabilityDomain`. The constant extraction pipeline needed a bit of refactoring to thread a `DeclContext` through to the place where it will be needed to execute the query. NFC.
1 parent b1411b3 commit 774248f

File tree

2 files changed

+90
-55
lines changed

2 files changed

+90
-55
lines changed

include/swift/AST/ConstTypeInfo.h

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,24 @@ class BuilderValue : public CompileTimeValue {
217217
///
218218
class ConditionalMember : public BuilderMember {
219219
public:
220+
class AvailabilitySpec {
221+
private:
222+
AvailabilityDomain Domain;
223+
llvm::VersionTuple Version;
224+
225+
public:
226+
AvailabilitySpec(AvailabilityDomain Domain, llvm::VersionTuple Version)
227+
: Domain(Domain), Version(Version) {}
228+
229+
AvailabilityDomain getDomain() const { return Domain; }
230+
llvm::VersionTuple getVersion() const { return Version; }
231+
};
232+
220233
ConditionalMember(MemberKind MemberKind,
221-
std::vector<AvailabilitySpec> AvailabilityAttributes,
234+
std::vector<AvailabilitySpec> AvailabilitySpecs,
222235
std::vector<std::shared_ptr<BuilderMember>> IfElements,
223236
std::vector<std::shared_ptr<BuilderMember>> ElseElements)
224-
: BuilderMember(MemberKind),
225-
AvailabilityAttributes(AvailabilityAttributes),
237+
: BuilderMember(MemberKind), AvailabilitySpecs(AvailabilitySpecs),
226238
IfElements(IfElements), ElseElements(ElseElements) {}
227239

228240
ConditionalMember(MemberKind MemberKind,
@@ -238,9 +250,8 @@ class BuilderValue : public CompileTimeValue {
238250
(Kind == MemberKind::Optional);
239251
}
240252

241-
std::optional<std::vector<AvailabilitySpec>>
242-
getAvailabilityAttributes() const {
243-
return AvailabilityAttributes;
253+
std::optional<std::vector<AvailabilitySpec>> getAvailabilitySpecs() const {
254+
return AvailabilitySpecs;
244255
}
245256
std::vector<std::shared_ptr<BuilderMember>> getIfElements() const {
246257
return IfElements;
@@ -250,7 +261,7 @@ class BuilderValue : public CompileTimeValue {
250261
}
251262

252263
private:
253-
std::optional<std::vector<AvailabilitySpec>> AvailabilityAttributes;
264+
std::optional<std::vector<AvailabilitySpec>> AvailabilitySpecs;
254265
std::vector<std::shared_ptr<BuilderMember>> IfElements;
255266
std::vector<std::shared_ptr<BuilderMember>> ElseElements;
256267
};

lib/ConstExtract/ConstExtract.cpp

Lines changed: 72 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,15 @@ parseProtocolListFromFile(StringRef protocolListFilePath,
168168
}
169169

170170
std::vector<std::shared_ptr<BuilderValue::BuilderMember>>
171-
getResultBuilderMembersFromBraceStmt(BraceStmt *braceStmt);
171+
getResultBuilderMembersFromBraceStmt(BraceStmt *braceStmt,
172+
const DeclContext *declContext);
172173

173-
static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr);
174+
static std::shared_ptr<CompileTimeValue>
175+
extractCompileTimeValue(Expr *expr, const DeclContext *declContext);
174176

175177
static std::vector<FunctionParameter>
176-
extractFunctionArguments(const ArgumentList *args) {
178+
extractFunctionArguments(const ArgumentList *args,
179+
const DeclContext *declContext) {
177180
std::vector<FunctionParameter> parameters;
178181

179182
for (auto arg : *args) {
@@ -188,7 +191,8 @@ extractFunctionArguments(const ArgumentList *args) {
188191
} else if (auto optionalInject = dyn_cast<InjectIntoOptionalExpr>(argExpr)) {
189192
argExpr = optionalInject->getSubExpr();
190193
}
191-
parameters.push_back({label, type, extractCompileTimeValue(argExpr)});
194+
parameters.push_back(
195+
{label, type, extractCompileTimeValue(argExpr, declContext)});
192196
}
193197

194198
return parameters;
@@ -224,7 +228,8 @@ static std::optional<std::string> extractRawLiteral(Expr *expr) {
224228
return std::nullopt;
225229
}
226230

227-
static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
231+
static std::shared_ptr<CompileTimeValue>
232+
extractCompileTimeValue(Expr *expr, const DeclContext *declContext) {
228233
if (expr) {
229234
switch (expr->getKind()) {
230235
case ExprKind::BooleanLiteral:
@@ -247,7 +252,8 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
247252
auto arrayExpr = cast<ArrayExpr>(expr);
248253
std::vector<std::shared_ptr<CompileTimeValue>> elementValues;
249254
for (const auto elementExpr : arrayExpr->getElements()) {
250-
elementValues.push_back(extractCompileTimeValue(elementExpr));
255+
elementValues.push_back(
256+
extractCompileTimeValue(elementExpr, declContext));
251257
}
252258
return std::make_shared<ArrayValue>(elementValues);
253259
}
@@ -256,7 +262,7 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
256262
auto dictionaryExpr = cast<DictionaryExpr>(expr);
257263
std::vector<std::shared_ptr<TupleValue>> tuples;
258264
for (auto elementExpr : dictionaryExpr->getElements()) {
259-
auto elementValue = extractCompileTimeValue(elementExpr);
265+
auto elementValue = extractCompileTimeValue(elementExpr, declContext);
260266
if (isa<TupleValue>(elementValue.get())) {
261267
tuples.push_back(std::static_pointer_cast<TupleValue>(elementValue));
262268
}
@@ -279,13 +285,15 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
279285
? std::nullopt
280286
: std::optional<std::string>(elementName.str().str());
281287

282-
elements.push_back({label, elementExpr->getType(),
283-
extractCompileTimeValue(elementExpr)});
288+
elements.push_back(
289+
{label, elementExpr->getType(),
290+
extractCompileTimeValue(elementExpr, declContext)});
284291
}
285292
} else {
286293
for (auto elementExpr : tupleExpr->getElements()) {
287-
elements.push_back({std::nullopt, elementExpr->getType(),
288-
extractCompileTimeValue(elementExpr)});
294+
elements.push_back(
295+
{std::nullopt, elementExpr->getType(),
296+
extractCompileTimeValue(elementExpr, declContext)});
289297
}
290298
}
291299
return std::make_shared<TupleValue>(elements);
@@ -301,13 +309,13 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
301309
declRefExpr->getDecl()->getName().getBaseIdentifier().str().str();
302310

303311
std::vector<FunctionParameter> parameters =
304-
extractFunctionArguments(callExpr->getArgs());
312+
extractFunctionArguments(callExpr->getArgs(), declContext);
305313
return std::make_shared<FunctionCallValue>(identifier, parameters);
306314
}
307315

308316
if (functionKind == ExprKind::ConstructorRefCall) {
309317
std::vector<FunctionParameter> parameters =
310-
extractFunctionArguments(callExpr->getArgs());
318+
extractFunctionArguments(callExpr->getArgs(), declContext);
311319
return std::make_shared<InitCallValue>(callExpr->getType(), parameters);
312320
}
313321

@@ -320,7 +328,7 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
320328
declRefExpr->getDecl()->getName().getBaseIdentifier().str().str();
321329

322330
std::vector<FunctionParameter> parameters =
323-
extractFunctionArguments(callExpr->getArgs());
331+
extractFunctionArguments(callExpr->getArgs(), declContext);
324332

325333
auto declRef = dotSyntaxCallExpr->getFn()->getReferencedDecl();
326334
switch (declRef.getDecl()->getKind()) {
@@ -364,23 +372,23 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
364372

365373
case ExprKind::Erasure: {
366374
auto erasureExpr = cast<ErasureExpr>(expr);
367-
return extractCompileTimeValue(erasureExpr->getSubExpr());
375+
return extractCompileTimeValue(erasureExpr->getSubExpr(), declContext);
368376
}
369377

370378
case ExprKind::Paren: {
371379
auto parenExpr = cast<ParenExpr>(expr);
372-
return extractCompileTimeValue(parenExpr->getSubExpr());
380+
return extractCompileTimeValue(parenExpr->getSubExpr(), declContext);
373381
}
374382

375383
case ExprKind::PropertyWrapperValuePlaceholder: {
376384
auto placeholderExpr = cast<PropertyWrapperValuePlaceholderExpr>(expr);
377-
return extractCompileTimeValue(
378-
placeholderExpr->getOriginalWrappedValue());
385+
return extractCompileTimeValue(placeholderExpr->getOriginalWrappedValue(),
386+
declContext);
379387
}
380388

381389
case ExprKind::Coerce: {
382390
auto coerceExpr = cast<CoerceExpr>(expr);
383-
return extractCompileTimeValue(coerceExpr->getSubExpr());
391+
return extractCompileTimeValue(coerceExpr->getSubExpr(), declContext);
384392
}
385393

386394
case ExprKind::DotSelf: {
@@ -394,7 +402,8 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
394402

395403
case ExprKind::UnderlyingToOpaque: {
396404
auto underlyingToOpaque = cast<UnderlyingToOpaqueExpr>(expr);
397-
return extractCompileTimeValue(underlyingToOpaque->getSubExpr());
405+
return extractCompileTimeValue(underlyingToOpaque->getSubExpr(),
406+
declContext);
398407
}
399408

400409
case ExprKind::DefaultArgument: {
@@ -445,12 +454,13 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
445454

446455
case ExprKind::InjectIntoOptional: {
447456
auto injectIntoOptionalExpr = cast<InjectIntoOptionalExpr>(expr);
448-
return extractCompileTimeValue(injectIntoOptionalExpr->getSubExpr());
457+
return extractCompileTimeValue(injectIntoOptionalExpr->getSubExpr(),
458+
declContext);
449459
}
450460

451461
case ExprKind::Load: {
452462
auto loadExpr = cast<LoadExpr>(expr);
453-
return extractCompileTimeValue(loadExpr->getSubExpr());
463+
return extractCompileTimeValue(loadExpr->getSubExpr(), declContext);
454464
}
455465

456466
case ExprKind::MemberRef: {
@@ -474,7 +484,7 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
474484
Ctx, [&](bool isInterpolation, CallExpr *segment) -> void {
475485
auto arg = segment->getArgs()->get(0);
476486
auto expr = arg.getExpr();
477-
segments.push_back(extractCompileTimeValue(expr));
487+
segments.push_back(extractCompileTimeValue(expr, declContext));
478488
});
479489

480490
return std::make_shared<InterpolatedStringLiteralValue>(segments);
@@ -483,7 +493,8 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
483493
case ExprKind::Closure: {
484494
auto closureExpr = cast<ClosureExpr>(expr);
485495
auto body = closureExpr->getBody();
486-
auto resultBuilderMembers = getResultBuilderMembersFromBraceStmt(body);
496+
auto resultBuilderMembers =
497+
getResultBuilderMembersFromBraceStmt(body, declContext);
487498

488499
if (!resultBuilderMembers.empty()) {
489500
return std::make_shared<BuilderValue>(resultBuilderMembers);
@@ -493,7 +504,7 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
493504

494505
case ExprKind::DerivedToBase: {
495506
auto derivedExpr = cast<DerivedToBaseExpr>(expr);
496-
return extractCompileTimeValue(derivedExpr->getSubExpr());
507+
return extractCompileTimeValue(derivedExpr->getSubExpr(), declContext);
497508
}
498509
default: {
499510
break;
@@ -504,8 +515,8 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
504515
return std::make_shared<RuntimeValue>();
505516
}
506517

507-
static CustomAttrValue
508-
extractAttributeValue(const CustomAttr *attr) {
518+
static CustomAttrValue extractAttributeValue(const CustomAttr *attr,
519+
const DeclContext *declContext) {
509520
std::vector<FunctionParameter> parameters;
510521
if (const auto *args = attr->getArgs()) {
511522
for (auto arg : *args) {
@@ -518,8 +529,8 @@ extractAttributeValue(const CustomAttr *attr) {
518529
argExpr = decl->getTypeCheckedDefaultExpr();
519530
}
520531
}
521-
parameters.push_back(
522-
{label, argExpr->getType(), extractCompileTimeValue(argExpr)});
532+
parameters.push_back({label, argExpr->getType(),
533+
extractCompileTimeValue(argExpr, declContext)});
523534
}
524535
}
525536
return {attr, parameters};
@@ -529,7 +540,8 @@ static AttrValueVector
529540
extractPropertyWrapperAttrValues(VarDecl *propertyDecl) {
530541
AttrValueVector customAttrValues;
531542
for (auto *propertyWrapper : propertyDecl->getAttachedPropertyWrappers())
532-
customAttrValues.push_back(extractAttributeValue(propertyWrapper));
543+
customAttrValues.push_back(
544+
extractAttributeValue(propertyWrapper, propertyDecl->getDeclContext()));
533545
return customAttrValues;
534546
}
535547

@@ -541,7 +553,9 @@ extractTypePropertyInfo(VarDecl *propertyDecl) {
541553

542554
if (const auto binding = propertyDecl->getParentPatternBinding()) {
543555
if (const auto originalInit = binding->getInit(0)) {
544-
return {propertyDecl, extractCompileTimeValue(originalInit),
556+
return {propertyDecl,
557+
extractCompileTimeValue(originalInit,
558+
propertyDecl->getInnermostDeclContext()),
545559
propertyWrapperValues};
546560
}
547561
}
@@ -551,9 +565,11 @@ extractTypePropertyInfo(VarDecl *propertyDecl) {
551565
auto node = body->getFirstElement();
552566
if (auto *stmt = node.dyn_cast<Stmt *>()) {
553567
if (stmt->getKind() == StmtKind::Return) {
554-
return {propertyDecl,
555-
extractCompileTimeValue(cast<ReturnStmt>(stmt)->getResult()),
556-
propertyWrapperValues};
568+
return {
569+
propertyDecl,
570+
extractCompileTimeValue(cast<ReturnStmt>(stmt)->getResult(),
571+
accessorDecl->getInnermostDeclContext()),
572+
propertyWrapperValues};
557573
}
558574
}
559575
}
@@ -992,16 +1008,19 @@ getResultBuilderElementFromASTNode(const ASTNode node) {
9921008
if (auto *D = node.dyn_cast<Decl *>()) {
9931009
if (auto *patternBinding = dyn_cast<PatternBindingDecl>(D)) {
9941010
if (auto originalInit = patternBinding->getOriginalInit(0)) {
995-
return extractCompileTimeValue(originalInit);
1011+
return extractCompileTimeValue(
1012+
originalInit, patternBinding->getInnermostDeclContext());
9961013
}
9971014
}
9981015
}
9991016
return std::nullopt;
10001017
}
10011018

10021019
BuilderValue::ConditionalMember
1003-
getConditionalMemberFromIfStmt(const IfStmt *ifStmt) {
1004-
std::vector<AvailabilitySpec> AvailabilityAttributes;
1020+
getConditionalMemberFromIfStmt(const IfStmt *ifStmt,
1021+
const DeclContext *declContext) {
1022+
std::vector<BuilderValue::ConditionalMember::AvailabilitySpec>
1023+
AvailabilitySpecs;
10051024
std::vector<std::shared_ptr<BuilderValue::BuilderMember>> IfElements;
10061025
std::vector<std::shared_ptr<BuilderValue::BuilderMember>> ElseElements;
10071026
if (auto thenBraceStmt = ifStmt->getThenStmt()) {
@@ -1016,7 +1035,7 @@ getConditionalMemberFromIfStmt(const IfStmt *ifStmt) {
10161035
if (auto elseStmt = ifStmt->getElseStmt()) {
10171036
if (auto *elseIfStmt = dyn_cast<IfStmt>(elseStmt)) {
10181037
ElseElements.push_back(std::make_shared<BuilderValue::ConditionalMember>(
1019-
getConditionalMemberFromIfStmt(elseIfStmt)));
1038+
getConditionalMemberFromIfStmt(elseIfStmt, declContext)));
10201039
} else if (auto *elseBraceStmt = dyn_cast<BraceStmt>(elseStmt)) {
10211040
for (auto elem : elseBraceStmt->getElements()) {
10221041
if (auto memberElement = getResultBuilderElementFromASTNode(elem)) {
@@ -1035,20 +1054,22 @@ getConditionalMemberFromIfStmt(const IfStmt *ifStmt) {
10351054
if (elt.getKind() == StmtConditionElement::CK_Availability) {
10361055
for (auto *Q : elt.getAvailability()->getQueries()) {
10371056
if (Q->getPlatform() != PlatformKind::none) {
1038-
AvailabilityAttributes.push_back(*Q);
1057+
auto spec = BuilderValue::ConditionalMember::AvailabilitySpec(
1058+
*Q->getDomain(), Q->getVersion());
1059+
AvailabilitySpecs.push_back(spec);
10391060
}
10401061
}
10411062
memberKind = BuilderValue::LimitedAvailability;
10421063
break;
10431064
}
10441065
}
10451066

1046-
if (AvailabilityAttributes.empty()) {
1067+
if (AvailabilitySpecs.empty()) {
10471068
return BuilderValue::ConditionalMember(memberKind, IfElements,
10481069
ElseElements);
10491070
}
10501071

1051-
return BuilderValue::ConditionalMember(memberKind, AvailabilityAttributes,
1072+
return BuilderValue::ConditionalMember(memberKind, AvailabilitySpecs,
10521073
IfElements, ElseElements);
10531074
}
10541075

@@ -1067,7 +1088,8 @@ getBuildArrayMemberFromForEachStmt(const ForEachStmt *forEachStmt) {
10671088
}
10681089

10691090
std::vector<std::shared_ptr<BuilderValue::BuilderMember>>
1070-
getResultBuilderMembersFromBraceStmt(BraceStmt *braceStmt) {
1091+
getResultBuilderMembersFromBraceStmt(BraceStmt *braceStmt,
1092+
const DeclContext *declContext) {
10711093
std::vector<std::shared_ptr<BuilderValue::BuilderMember>>
10721094
ResultBuilderMembers;
10731095
for (auto elem : braceStmt->getElements()) {
@@ -1079,7 +1101,7 @@ getResultBuilderMembersFromBraceStmt(BraceStmt *braceStmt) {
10791101
if (auto *ifStmt = dyn_cast<IfStmt>(stmt)) {
10801102
ResultBuilderMembers.push_back(
10811103
std::make_shared<BuilderValue::ConditionalMember>(
1082-
getConditionalMemberFromIfStmt(ifStmt)));
1104+
getConditionalMemberFromIfStmt(ifStmt, declContext)));
10831105
} else if (auto *doStmt = dyn_cast<DoStmt>(stmt)) {
10841106
if (auto body = doStmt->getBody()) {
10851107
for (auto elem : body->getElements()) {
@@ -1106,7 +1128,8 @@ createBuilderCompileTimeValue(CustomAttr *AttachedResultBuilder,
11061128
if (!VarDecl->getAllAccessors().empty()) {
11071129
if (auto accessor = VarDecl->getAllAccessors()[0]) {
11081130
if (auto braceStmt = accessor->getTypecheckedBody()) {
1109-
ResultBuilderMembers = getResultBuilderMembersFromBraceStmt(braceStmt);
1131+
ResultBuilderMembers = getResultBuilderMembersFromBraceStmt(
1132+
braceStmt, accessor->getDeclContext());
11101133
}
11111134
}
11121135
}
@@ -1159,12 +1182,13 @@ void writeBuilderMember(
11591182

11601183
default: {
11611184
auto member = cast<BuilderValue::ConditionalMember>(Member);
1162-
if (auto availabilityAttributes = member->getAvailabilityAttributes()) {
1185+
if (auto availabilitySpecs = member->getAvailabilitySpecs()) {
11631186
JSON.attributeArray("availabilityAttributes", [&] {
1164-
for (auto elem : *availabilityAttributes) {
1187+
for (auto elem : *availabilitySpecs) {
11651188
JSON.object([&] {
1166-
JSON.attribute("platform",
1167-
platformString(elem.getPlatform()).str());
1189+
JSON.attribute(
1190+
"platform",
1191+
platformString(elem.getDomain().getPlatformKind()).str());
11681192
JSON.attribute("minVersion", elem.getVersion().getAsString());
11691193
});
11701194
}

0 commit comments

Comments
 (0)