28
28
29
29
using namespace swift ;
30
30
31
- TypeRefinementContext::TypeRefinementContext (
32
- ASTContext &Ctx, IntroNode Node, TypeRefinementContext *Parent,
33
- SourceRange SrcRange, const AvailabilityRange &Info,
34
- const AvailabilityRange &ExplicitInfo)
35
- : Node(Node), SrcRange(SrcRange), AvailabilityInfo(Info),
36
- ExplicitAvailabilityInfo(ExplicitInfo) {
31
+ TypeRefinementContext::TypeRefinementContext (ASTContext &Ctx, IntroNode Node,
32
+ TypeRefinementContext *Parent,
33
+ SourceRange SrcRange,
34
+ const AvailabilityRange &Info)
35
+ : Node(Node), SrcRange(SrcRange), AvailabilityInfo(Info) {
37
36
if (Parent) {
38
37
assert (SrcRange.isValid ());
39
38
Parent->addChild (this , Ctx);
@@ -78,18 +77,15 @@ TypeRefinementContext::createForSourceFile(SourceFile *SF,
78
77
}
79
78
80
79
return new (Ctx)
81
- TypeRefinementContext (Ctx, SF, parentContext, range, availabilityRange,
82
- AvailabilityRange::alwaysAvailable ());
80
+ TypeRefinementContext (Ctx, SF, parentContext, range, availabilityRange);
83
81
}
84
82
85
83
TypeRefinementContext *TypeRefinementContext::createForDecl (
86
84
ASTContext &Ctx, Decl *D, TypeRefinementContext *Parent,
87
- const AvailabilityRange &Info, const AvailabilityRange &ExplicitInfo,
88
- SourceRange SrcRange) {
85
+ const AvailabilityRange &Info, SourceRange SrcRange) {
89
86
assert (D);
90
87
assert (Parent);
91
- return new (Ctx)
92
- TypeRefinementContext (Ctx, D, Parent, SrcRange, Info, ExplicitInfo);
88
+ return new (Ctx) TypeRefinementContext (Ctx, D, Parent, SrcRange, Info);
93
89
}
94
90
95
91
TypeRefinementContext *TypeRefinementContext::createForDeclImplicit (
@@ -98,8 +94,7 @@ TypeRefinementContext *TypeRefinementContext::createForDeclImplicit(
98
94
assert (D);
99
95
assert (Parent);
100
96
return new (Ctx) TypeRefinementContext (
101
- Ctx, IntroNode (D, Reason::DeclImplicit), Parent, SrcRange, Info,
102
- AvailabilityRange::alwaysAvailable ());
97
+ Ctx, IntroNode (D, Reason::DeclImplicit), Parent, SrcRange, Info);
103
98
}
104
99
105
100
TypeRefinementContext *
@@ -110,8 +105,7 @@ TypeRefinementContext::createForIfStmtThen(ASTContext &Ctx, IfStmt *S,
110
105
assert (Parent);
111
106
return new (Ctx)
112
107
TypeRefinementContext (Ctx, IntroNode (S, /* IsThen=*/ true ), Parent,
113
- S->getThenStmt ()->getSourceRange (),
114
- Info, /* ExplicitInfo */ Info);
108
+ S->getThenStmt ()->getSourceRange (), Info);
115
109
}
116
110
117
111
TypeRefinementContext *
@@ -122,8 +116,7 @@ TypeRefinementContext::createForIfStmtElse(ASTContext &Ctx, IfStmt *S,
122
116
assert (Parent);
123
117
return new (Ctx)
124
118
TypeRefinementContext (Ctx, IntroNode (S, /* IsThen=*/ false ), Parent,
125
- S->getElseStmt ()->getSourceRange (),
126
- Info, /* ExplicitInfo */ Info);
119
+ S->getElseStmt ()->getSourceRange (), Info);
127
120
}
128
121
129
122
TypeRefinementContext *TypeRefinementContext::createForConditionFollowingQuery (
@@ -133,8 +126,7 @@ TypeRefinementContext *TypeRefinementContext::createForConditionFollowingQuery(
133
126
assert (PAI);
134
127
assert (Parent);
135
128
SourceRange Range (PAI->getEndLoc (), LastElement.getEndLoc ());
136
- return new (Ctx) TypeRefinementContext (Ctx, PAI, Parent, Range,
137
- Info, /* ExplicitInfo */ Info);
129
+ return new (Ctx) TypeRefinementContext (Ctx, PAI, Parent, Range, Info);
138
130
}
139
131
140
132
TypeRefinementContext *TypeRefinementContext::createForGuardStmtFallthrough (
@@ -144,9 +136,8 @@ TypeRefinementContext *TypeRefinementContext::createForGuardStmtFallthrough(
144
136
assert (ContainingBraceStmt);
145
137
assert (Parent);
146
138
SourceRange Range (RS->getEndLoc (), ContainingBraceStmt->getEndLoc ());
147
- return new (Ctx) TypeRefinementContext (Ctx,
148
- IntroNode (RS, /* IsFallthrough=*/ true ),
149
- Parent, Range, Info, /* ExplicitInfo */ Info);
139
+ return new (Ctx) TypeRefinementContext (
140
+ Ctx, IntroNode (RS, /* IsFallthrough=*/ true ), Parent, Range, Info);
150
141
}
151
142
152
143
TypeRefinementContext *
@@ -157,7 +148,7 @@ TypeRefinementContext::createForGuardStmtElse(ASTContext &Ctx, GuardStmt *RS,
157
148
assert (Parent);
158
149
return new (Ctx)
159
150
TypeRefinementContext (Ctx, IntroNode (RS, /* IsFallthrough=*/ false ), Parent,
160
- RS->getBody ()->getSourceRange (), Info, /* ExplicitInfo */ Info );
151
+ RS->getBody ()->getSourceRange (), Info);
161
152
}
162
153
163
154
TypeRefinementContext *
@@ -166,8 +157,8 @@ TypeRefinementContext::createForWhileStmtBody(ASTContext &Ctx, WhileStmt *S,
166
157
const AvailabilityRange &Info) {
167
158
assert (S);
168
159
assert (Parent);
169
- return new (Ctx) TypeRefinementContext (
170
- Ctx, S, Parent, S->getBody ()->getSourceRange (), Info, /* ExplicitInfo */ Info);
160
+ return new (Ctx) TypeRefinementContext (Ctx, S, Parent,
161
+ S->getBody ()->getSourceRange (), Info);
171
162
}
172
163
173
164
void TypeRefinementContext::addChild (TypeRefinementContext *Child,
@@ -365,6 +356,38 @@ TypeRefinementContext::getAvailabilityConditionVersionSourceRange(
365
356
llvm_unreachable (" Unhandled Reason in switch." );
366
357
}
367
358
359
+ std::optional<const AvailabilityRange>
360
+ TypeRefinementContext::getExplicitAvailabilityRange () const {
361
+ switch (getReason ()) {
362
+ case Reason::Root:
363
+ return std::nullopt;
364
+
365
+ case Reason::Decl: {
366
+ auto decl = Node.getAsDecl ();
367
+ auto &ctx = decl->getASTContext ();
368
+ if (auto attr =
369
+ AvailabilityInference::attrForAnnotatedAvailableRange (decl, ctx))
370
+ return AvailabilityInference::availableRange (attr, ctx);
371
+
372
+ return std::nullopt;
373
+ }
374
+
375
+ case Reason::DeclImplicit:
376
+ return std::nullopt;
377
+
378
+ case Reason::IfStmtThenBranch:
379
+ case Reason::IfStmtElseBranch:
380
+ case Reason::ConditionFollowingAvailabilityQuery:
381
+ case Reason::GuardStmtFallthrough:
382
+ case Reason::GuardStmtElseBranch:
383
+ case Reason::WhileStmtBody:
384
+ // Availability is inherently explicit for all of these nodes.
385
+ return getAvailabilityInfo ();
386
+ }
387
+
388
+ llvm_unreachable (" Unhandled Reason in switch." );
389
+ }
390
+
368
391
static std::string
369
392
stringForAvailability (const AvailabilityRange &availability) {
370
393
if (availability.isAlwaysAvailable ())
@@ -425,9 +448,8 @@ void TypeRefinementContext::print(raw_ostream &OS, SourceManager &SrcMgr,
425
448
}
426
449
}
427
450
428
- if (!ExplicitAvailabilityInfo.isAlwaysAvailable ())
429
- OS << " explicit_version="
430
- << stringForAvailability (ExplicitAvailabilityInfo);
451
+ if (auto explicitAvailability = getExplicitAvailabilityRange ())
452
+ OS << " explicit_version=" << stringForAvailability (*explicitAvailability);
431
453
432
454
for (TypeRefinementContext *Child : Children) {
433
455
OS << ' \n ' ;
0 commit comments