21
21
#include " swift/AST/AvailabilityDomain.h"
22
22
#include " swift/AST/Identifier.h"
23
23
#include " swift/AST/PlatformKind.h"
24
+ #include " swift/Basic/STLExtras.h"
24
25
#include " swift/Basic/SourceLoc.h"
25
26
#include " llvm/ADT/DenseMap.h"
26
27
#include " llvm/ADT/StringMap.h"
28
+ #include " llvm/ADT/iterator_range.h"
27
29
#include " llvm/Support/VersionTuple.h"
28
30
29
31
namespace swift {
@@ -45,6 +47,8 @@ enum class AvailabilitySpecKind {
45
47
PackageDescriptionVersionConstraint,
46
48
};
47
49
50
+ class SemanticAvailabilitySpec ;
51
+
48
52
// / The root class for specifications of API availability in availability
49
53
// / queries.
50
54
class AvailabilitySpec : public ASTAllocated <AvailabilitySpec> {
@@ -109,7 +113,14 @@ class AvailabilitySpec : public ASTAllocated<AvailabilitySpec> {
109
113
110
114
AvailabilitySpecKind getKind () const { return Kind; }
111
115
112
- bool isWildcard () { return getKind () == AvailabilitySpecKind::Wildcard; }
116
+ bool isWildcard () const {
117
+ return getKind () == AvailabilitySpecKind::Wildcard;
118
+ }
119
+
120
+ // / Returns a type-checked representation of the spec, or `std::nullopt` if
121
+ // / the spec is invalid.
122
+ std::optional<SemanticAvailabilitySpec>
123
+ getSemanticAvailabilitySpec (const DeclContext *declContext) const ;
113
124
114
125
SourceRange getSourceRange () const { return SrcRange; }
115
126
SourceLoc getStartLoc () const { return SrcRange.Start ; }
@@ -122,13 +133,8 @@ class AvailabilitySpec : public ASTAllocated<AvailabilitySpec> {
122
133
return PlatformKind::none;
123
134
}
124
135
125
- // The platform version to compare against.
126
- llvm::VersionTuple getVersion () const ;
127
-
128
- // The version to be used in codegen for version comparisons at run time.
129
- // This is required to support beta versions of macOS Big Sur that
130
- // report 10.16 at run time.
131
- llvm::VersionTuple getRuntimeVersion () const { return Version; }
136
+ // The version tuple that was written in source.
137
+ llvm::VersionTuple getRawVersion () const { return Version; }
132
138
133
139
SourceRange getVersionSrcRange () const {
134
140
if (!VersionStartLoc)
@@ -141,6 +147,67 @@ class AvailabilitySpec : public ASTAllocated<AvailabilitySpec> {
141
147
void setMacroLoc (SourceLoc loc) { MacroLoc = loc; }
142
148
};
143
149
150
+ // / The type-checked representation of `AvailabilitySpec` which guaranatees that
151
+ // / the spec has a valid `AvailabilityDomain`.
152
+ class SemanticAvailabilitySpec {
153
+ const AvailabilitySpec *spec;
154
+
155
+ public:
156
+ SemanticAvailabilitySpec (const AvailabilitySpec *spec) : spec(spec) {
157
+ // The domain must be resolved in order to wrap it in a semantic spec.
158
+ ASSERT (spec->isWildcard () || spec->getDomain ());
159
+ }
160
+
161
+ const AvailabilitySpec *getParsedSpec () const { return spec; }
162
+
163
+ AvailabilityDomain getDomain () const {
164
+ if (isWildcard ())
165
+ return AvailabilityDomain::forUniversal ();
166
+ return spec->getDomain ().value ();
167
+ }
168
+
169
+ bool isWildcard () const { return spec->isWildcard (); }
170
+
171
+ // The platform version to compare against.
172
+ llvm::VersionTuple getVersion () const ;
173
+
174
+ // The version to be used in codegen for version comparisons at run time.
175
+ // This is required to support beta versions of macOS Big Sur that
176
+ // report 10.16 at run time.
177
+ llvm::VersionTuple getRuntimeVersion () const { return spec->getRawVersion (); }
178
+ };
179
+
180
+ // / Wraps an array of availability specs and provides an iterator for their
181
+ // / semantic representations.
182
+ class SemanticAvailabilitySpecs {
183
+ public:
184
+ class Filter final {
185
+ const DeclContext *declContext;
186
+
187
+ public:
188
+ Filter (const DeclContext *declContext) : declContext(declContext) {}
189
+
190
+ std::optional<SemanticAvailabilitySpec>
191
+ operator ()(const AvailabilitySpec *spec) const ;
192
+ };
193
+
194
+ using Range = OptionalTransformRange<
195
+ iterator_range<ArrayRef<AvailabilitySpec *>::const_iterator>, Filter>;
196
+
197
+ private:
198
+ Range specRange;
199
+
200
+ public:
201
+ SemanticAvailabilitySpecs (ArrayRef<AvailabilitySpec *> specs,
202
+ const DeclContext *declContext)
203
+ : specRange(llvm::make_range(specs.begin(), specs.end()),
204
+ Filter (declContext)) {}
205
+
206
+ Range::iterator begin () const { return specRange.begin (); }
207
+ Range::iterator end () const { return specRange.end (); }
208
+ bool empty () const { return specRange.empty (); }
209
+ };
210
+
144
211
// / Maps of macro name and version to availability specifications.
145
212
// / Organized as two nested \c DenseMap keyed first on the macro name then
146
213
// / the macro version. This structure allows to peek at macro names before
0 commit comments