11
11
// ===----------------------------------------------------------------------===//
12
12
13
13
#include " swift/AST/ASTContext.h"
14
- #include " swift/AST/ASTPrinter.h"
15
14
#include " swift/AST/Decl.h"
16
15
#include " swift/AST/DiagnosticsFrontend.h"
17
16
#include " swift/AST/DiagnosticsSema.h"
@@ -164,69 +163,47 @@ namespace {
164
163
class InheritedProtocolCollector {
165
164
static const StringLiteral DummyProtocolName;
166
165
167
- using AvailableAttrList = TinyPtrVector<const AvailableAttr *>;
168
- using ProtocolAndAvailability =
169
- std::pair<ProtocolDecl *, AvailableAttrList>;
170
-
171
166
// / Protocols that will be included by the ASTPrinter without any extra work.
172
167
SmallVector<ProtocolDecl *, 8 > IncludedProtocols;
173
- // / Protocols that will not be printed by the ASTPrinter, along with the
174
- // / availability they were declared with.
175
- SmallVector<ProtocolAndAvailability, 8 > ExtraProtocols;
168
+ // / Protocols that will not be printed by the ASTPrinter.
169
+ SmallVector<ProtocolDecl *, 8 > ExtraProtocols;
176
170
// / Protocols that can be printed, but whose conformances are constrained with
177
171
// / something that \e can't be printed.
178
172
SmallVector<const ProtocolType *, 8 > ConditionalConformanceProtocols;
179
173
180
- // / Helper to extract the `@available` attributes on a decl.
181
- AvailableAttrList getAvailabilityAttrs (const Decl *D) {
182
- AvailableAttrList result;
183
- auto attrRange = D->getAttrs ().getAttributes <AvailableAttr>();
184
- result.insert (result.begin (), attrRange.begin (), attrRange.end ());
185
- return result;
186
- }
187
-
188
174
// / For each type in \p directlyInherited, classify the protocols it refers to
189
175
// / as included for printing or not, and record them in the appropriate
190
176
// / vectors.
191
- void recordProtocols (ArrayRef<TypeLoc> directlyInherited, const Decl *D) {
192
- Optional<AvailableAttrList> availableAttrs;
193
-
177
+ void recordProtocols (ArrayRef<TypeLoc> directlyInherited) {
194
178
for (TypeLoc inherited : directlyInherited) {
195
179
Type inheritedTy = inherited.getType ();
196
180
if (!inheritedTy || !inheritedTy->isExistentialType ())
197
181
continue ;
198
182
199
183
bool canPrintNormally = isPublicOrUsableFromInline (inheritedTy);
200
- if (!canPrintNormally && !availableAttrs. hasValue ())
201
- availableAttrs = getAvailabilityAttrs (D) ;
184
+ SmallVectorImpl<ProtocolDecl *> &whichProtocols =
185
+ canPrintNormally ? IncludedProtocols : ExtraProtocols ;
202
186
203
187
ExistentialLayout layout = inheritedTy->getExistentialLayout ();
204
- for (ProtocolType *protoTy : layout.getProtocols ()) {
205
- if (canPrintNormally)
206
- IncludedProtocols.push_back (protoTy->getDecl ());
207
- else
208
- ExtraProtocols.push_back ({protoTy->getDecl (),
209
- availableAttrs.getValue ()});
210
- }
188
+ for (ProtocolType *protoTy : layout.getProtocols ())
189
+ whichProtocols.push_back (protoTy->getDecl ());
211
190
// FIXME: This ignores layout constraints, but currently we don't support
212
191
// any of those besides 'AnyObject'.
213
192
}
214
193
}
215
194
216
- // / For each type directly inherited by \p extension , record any protocols
217
- // / that we would have printed in ConditionalConformanceProtocols.
218
- void recordConditionalConformances (const ExtensionDecl *extension ) {
219
- for (TypeLoc inherited : extension-> getInherited () ) {
195
+ // / For each type in \p directlyInherited , record any protocols that we would
196
+ // / have printed in ConditionalConformanceProtocols.
197
+ void recordConditionalConformances (ArrayRef<TypeLoc> directlyInherited ) {
198
+ for (TypeLoc inherited : directlyInherited ) {
220
199
Type inheritedTy = inherited.getType ();
221
200
if (!inheritedTy || !inheritedTy->isExistentialType ())
222
201
continue ;
223
202
224
203
ExistentialLayout layout = inheritedTy->getExistentialLayout ();
225
- for (ProtocolType *protoTy : layout.getProtocols ()) {
226
- if (!isPublicOrUsableFromInline (protoTy))
227
- continue ;
228
- ConditionalConformanceProtocols.push_back (protoTy);
229
- }
204
+ for (ProtocolType *protoTy : layout.getProtocols ())
205
+ if (isPublicOrUsableFromInline (protoTy))
206
+ ConditionalConformanceProtocols.push_back (protoTy);
230
207
// FIXME: This ignores layout constraints, but currently we don't support
231
208
// any of those besides 'AnyObject'.
232
209
}
@@ -266,7 +243,7 @@ class InheritedProtocolCollector {
266
243
if (!isPublicOrUsableFromInline (nominal))
267
244
return ;
268
245
269
- map[nominal].recordProtocols (directlyInherited, D );
246
+ map[nominal].recordProtocols (directlyInherited);
270
247
271
248
// Recurse to find any nested types.
272
249
for (const Decl *member : memberContext->getMembers ())
@@ -287,7 +264,7 @@ class InheritedProtocolCollector {
287
264
if (!isPublicOrUsableFromInline (nominal))
288
265
return ;
289
266
290
- map[nominal].recordConditionalConformances (extension);
267
+ map[nominal].recordConditionalConformances (extension-> getInherited () );
291
268
// No recursion here because extensions are never nested.
292
269
}
293
270
@@ -330,19 +307,16 @@ class InheritedProtocolCollector {
330
307
// Note: We could do this in one pass, but the logic is easier to
331
308
// understand if we build up the list and then print it, even if it takes
332
309
// a bit more memory.
333
- // FIXME: This will pick the availability attributes from the first sight
334
- // of a protocol rather than the maximally available case.
335
- SmallVector<std::pair<ProtocolDecl *, AvailableAttrList>, 16 >
336
- protocolsToPrint;
337
- for (const auto &protoAndAvailability : ExtraProtocols) {
338
- protoAndAvailability.first ->walkInheritedProtocols (
310
+ SmallVector<ProtocolDecl *, 16 > protocolsToPrint;
311
+ for (ProtocolDecl *proto : ExtraProtocols) {
312
+ proto->walkInheritedProtocols (
339
313
[&](ProtocolDecl *inherited) -> TypeWalker::Action {
340
314
if (!handledProtocols.insert (inherited).second )
341
315
return TypeWalker::Action::SkipChildren;
342
316
343
317
if (isPublicOrUsableFromInline (inherited) &&
344
318
conformanceDeclaredInModule (M, nominal, inherited)) {
345
- protocolsToPrint.push_back ({ inherited, protoAndAvailability. second } );
319
+ protocolsToPrint.push_back (inherited);
346
320
return TypeWalker::Action::SkipChildren;
347
321
}
348
322
@@ -352,20 +326,14 @@ class InheritedProtocolCollector {
352
326
if (protocolsToPrint.empty ())
353
327
return ;
354
328
355
- for (const auto &protoAndAvailability : protocolsToPrint) {
356
- StreamPrinter printer (out);
357
- for (const AvailableAttr *attr : protoAndAvailability.second )
358
- attr->print (printer, printOptions);
359
-
360
- printer << " extension " ;
361
- nominal->getDeclaredType ().print (printer, printOptions);
362
- printer << " : " ;
363
-
364
- ProtocolDecl *proto = protoAndAvailability.first ;
365
- proto->getDeclaredType ()->print (printer, printOptions);
366
-
367
- printer << " {}\n " ;
368
- }
329
+ out << " extension " ;
330
+ nominal->getDeclaredType ().print (out, printOptions);
331
+ out << " : " ;
332
+ swift::interleave (protocolsToPrint,
333
+ [&out, &printOptions](ProtocolDecl *proto) {
334
+ proto->getDeclaredType ()->print (out, printOptions);
335
+ }, [&out] { out << " , " ; });
336
+ out << " {}\n " ;
369
337
}
370
338
371
339
// / If there were any conditional conformances that couldn't be printed,
@@ -378,7 +346,7 @@ class InheritedProtocolCollector {
378
346
return false ;
379
347
assert (nominal->isGenericContext ());
380
348
381
- out << " @available(*, unavailable) \n extension " ;
349
+ out << " extension " ;
382
350
nominal->getDeclaredType ().print (out, printOptions);
383
351
out << " : " ;
384
352
swift::interleave (ConditionalConformanceProtocols,
0 commit comments