|
22 | 22 | #include "swift/AST/ClangModuleLoader.h"
|
23 | 23 | #include "swift/AST/Comment.h"
|
24 | 24 | #include "swift/AST/Decl.h"
|
| 25 | +#include "swift/AST/ExistentialLayout.h" |
25 | 26 | #include "swift/AST/Expr.h"
|
26 | 27 | #include "swift/AST/FileUnit.h"
|
27 | 28 | #include "swift/AST/GenericSignature.h"
|
|
36 | 37 | #include "swift/AST/TypeWalker.h"
|
37 | 38 | #include "swift/AST/Types.h"
|
38 | 39 | #include "swift/Basic/Defer.h"
|
| 40 | +#include "swift/Basic/Feature.h" |
39 | 41 | #include "swift/Basic/PrimitiveParsing.h"
|
40 | 42 | #include "swift/Basic/QuotedString.h"
|
41 | 43 | #include "swift/Basic/STLExtras.h"
|
@@ -137,6 +139,9 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
|
137 | 139 | // We should print __consuming, __owned, etc for the module interface file.
|
138 | 140 | result.SkipUnderscoredKeywords = false;
|
139 | 141 |
|
| 142 | + // We should provide backward-compatible Swift interfaces when we can. |
| 143 | + result.PrintCompatibilityFeatureChecks = true; |
| 144 | + |
140 | 145 | result.FunctionBody = [](const ValueDecl *decl, ASTPrinter &printer) {
|
141 | 146 | auto AFD = dyn_cast<AbstractFunctionDecl>(decl);
|
142 | 147 | if (!AFD)
|
@@ -955,10 +960,17 @@ class PrintAST : public ASTVisitor<PrintAST> {
|
955 | 960 | }
|
956 | 961 | }
|
957 | 962 |
|
| 963 | + |
958 | 964 | Printer.callPrintDeclPre(D, Options.BracketOptions);
|
959 | 965 |
|
| 966 | + bool haveFeatureChecks = Options.PrintCompatibilityFeatureChecks && |
| 967 | + printCompatibilityFeatureChecksPre(Printer, D); |
| 968 | + |
960 | 969 | ASTVisitor::visit(D);
|
961 | 970 |
|
| 971 | + if (haveFeatureChecks) |
| 972 | + printCompatibilityFeatureChecksPost(Printer); |
| 973 | + |
962 | 974 | if (Synthesize) {
|
963 | 975 | Printer.setSynthesizedTarget({});
|
964 | 976 | Printer.printSynthesizedExtensionPost(cast<ExtensionDecl>(D),
|
@@ -2255,6 +2267,11 @@ static void printExtendedTypeName(Type ExtendedType, ASTPrinter &Printer,
|
2255 | 2267 |
|
2256 | 2268 | void PrintAST::printSynthesizedExtension(Type ExtendedType,
|
2257 | 2269 | ExtensionDecl *ExtDecl) {
|
| 2270 | + // Print compatibility features checks first, if we need them. |
| 2271 | + bool haveFeatureChecks = Options.PrintCompatibilityFeatureChecks && |
| 2272 | + Options.BracketOptions.shouldOpenExtension(ExtDecl) && |
| 2273 | + Options.BracketOptions.shouldCloseExtension(ExtDecl) && |
| 2274 | + printCompatibilityFeatureChecksPre(Printer, ExtDecl); |
2258 | 2275 |
|
2259 | 2276 | auto printRequirementsFrom = [&](ExtensionDecl *ED, bool &IsFirst) {
|
2260 | 2277 | auto Sig = ED->getGenericSignature();
|
@@ -2297,7 +2314,6 @@ void PrintAST::printSynthesizedExtension(Type ExtendedType,
|
2297 | 2314 | return true;
|
2298 | 2315 | };
|
2299 | 2316 |
|
2300 |
| - |
2301 | 2317 | if (Options.BracketOptions.shouldOpenExtension(ExtDecl)) {
|
2302 | 2318 | printDocumentationComment(ExtDecl);
|
2303 | 2319 | printAttributes(ExtDecl);
|
@@ -2330,6 +2346,9 @@ void PrintAST::printSynthesizedExtension(Type ExtendedType,
|
2330 | 2346 | Options.BracketOptions.shouldOpenExtension(ExtDecl),
|
2331 | 2347 | Options.BracketOptions.shouldCloseExtension(ExtDecl));
|
2332 | 2348 | }
|
| 2349 | + |
| 2350 | + if (haveFeatureChecks) |
| 2351 | + printCompatibilityFeatureChecksPost(Printer); |
2333 | 2352 | }
|
2334 | 2353 |
|
2335 | 2354 | void PrintAST::printExtension(ExtensionDecl *decl) {
|
@@ -2373,6 +2392,194 @@ void PrintAST::printExtension(ExtensionDecl *decl) {
|
2373 | 2392 | }
|
2374 | 2393 | }
|
2375 | 2394 |
|
| 2395 | +/// Functions to determine which features a particular declaration uses. The |
| 2396 | +/// usesFeatureNNN functions correspond to the features in Features.def. |
| 2397 | + |
| 2398 | +static bool usesFeatureStaticAssert(Decl *decl) { |
| 2399 | + return false; |
| 2400 | +} |
| 2401 | + |
| 2402 | +static bool usesFeatureAsyncAwait(Decl *decl) { |
| 2403 | + if (auto func = dyn_cast<AbstractFunctionDecl>(decl)) { |
| 2404 | + if (func->hasAsync()) |
| 2405 | + return true; |
| 2406 | + } |
| 2407 | + |
| 2408 | + // Check for async functions in the types of declarations. |
| 2409 | + if (auto value = dyn_cast<ValueDecl>(decl)) { |
| 2410 | + if (Type type = value->getInterfaceType()) { |
| 2411 | + bool hasAsync = type.findIf([](Type type) { |
| 2412 | + if (auto fnType = type->getAs<AnyFunctionType>()) { |
| 2413 | + if (fnType->isAsync()) |
| 2414 | + return true; |
| 2415 | + } |
| 2416 | + |
| 2417 | + return false; |
| 2418 | + }); |
| 2419 | + |
| 2420 | + if (hasAsync) |
| 2421 | + return true; |
| 2422 | + } |
| 2423 | + } |
| 2424 | + |
| 2425 | + return false; |
| 2426 | +} |
| 2427 | + |
| 2428 | +static bool usesFeatureMarkerProtocol(Decl *decl) { |
| 2429 | + // Check an inheritance clause for a marker protocol. |
| 2430 | + auto checkInherited = [&](ArrayRef<TypeLoc> inherited) -> bool { |
| 2431 | + for (const auto &inheritedEntry : inherited) { |
| 2432 | + if (auto inheritedType = inheritedEntry.getType()) { |
| 2433 | + if (inheritedType->isExistentialType()) { |
| 2434 | + auto layout = inheritedType->getExistentialLayout(); |
| 2435 | + for (ProtocolType *protoTy : layout.getProtocols()) { |
| 2436 | + if (protoTy->getDecl()->isMarkerProtocol()) |
| 2437 | + return true; |
| 2438 | + } |
| 2439 | + } |
| 2440 | + } |
| 2441 | + } |
| 2442 | + |
| 2443 | + return false; |
| 2444 | + }; |
| 2445 | + |
| 2446 | + // Check generic requirements for a marker protocol. |
| 2447 | + auto checkRequirements = [&](ArrayRef<Requirement> requirements) -> bool { |
| 2448 | + for (const auto &req: requirements) { |
| 2449 | + if (req.getKind() == RequirementKind::Conformance && |
| 2450 | + req.getSecondType()->castTo<ProtocolType>()->getDecl() |
| 2451 | + ->isMarkerProtocol()) |
| 2452 | + return true; |
| 2453 | + } |
| 2454 | + |
| 2455 | + return false; |
| 2456 | + }; |
| 2457 | + |
| 2458 | + if (auto proto = dyn_cast<ProtocolDecl>(decl)) { |
| 2459 | + if (proto->isMarkerProtocol()) |
| 2460 | + return true; |
| 2461 | + |
| 2462 | + if (checkInherited(proto->getInherited())) |
| 2463 | + return true; |
| 2464 | + |
| 2465 | + if (checkRequirements(proto->getRequirementSignature())) |
| 2466 | + return true; |
| 2467 | + } |
| 2468 | + |
| 2469 | + if (auto ext = dyn_cast<ExtensionDecl>(decl)) { |
| 2470 | + if (checkRequirements(ext->getGenericRequirements())) |
| 2471 | + return true; |
| 2472 | + |
| 2473 | + if (checkInherited(ext->getInherited())) |
| 2474 | + return true; |
| 2475 | + } |
| 2476 | + |
| 2477 | + return false; |
| 2478 | +} |
| 2479 | + |
| 2480 | +static bool usesFeatureActors(Decl *decl) { |
| 2481 | + if (auto classDecl = dyn_cast<ClassDecl>(decl)) { |
| 2482 | + if (classDecl->isActor()) |
| 2483 | + return true; |
| 2484 | + } |
| 2485 | + |
| 2486 | + if (auto ext = dyn_cast<ExtensionDecl>(decl)) { |
| 2487 | + if (auto classDecl = ext->getSelfClassDecl()) |
| 2488 | + if (classDecl->isActor()) |
| 2489 | + return true; |
| 2490 | + } |
| 2491 | + |
| 2492 | + // Check for actors in the types of declarations. |
| 2493 | + if (auto value = dyn_cast<ValueDecl>(decl)) { |
| 2494 | + if (Type type = value->getInterfaceType()) { |
| 2495 | + bool hasActor = type.findIf([](Type type) { |
| 2496 | + if (auto classDecl = type->getClassOrBoundGenericClass()) { |
| 2497 | + if (classDecl->isActor()) |
| 2498 | + return true; |
| 2499 | + } |
| 2500 | + |
| 2501 | + return false; |
| 2502 | + }); |
| 2503 | + |
| 2504 | + if (hasActor) |
| 2505 | + return true; |
| 2506 | + } |
| 2507 | + } |
| 2508 | + |
| 2509 | + return false; |
| 2510 | +} |
| 2511 | + |
| 2512 | +/// Determine the set of "new" features used on a given declaration. |
| 2513 | +/// |
| 2514 | +/// Note: right now, all features we check for are "new". At some point, we'll |
| 2515 | +/// want a baseline version. |
| 2516 | +static std::vector<Feature> getFeaturesUsed(Decl *decl) { |
| 2517 | + std::vector<Feature> features; |
| 2518 | + |
| 2519 | + // Go through each of the features, checking whether the declaration uses that |
| 2520 | + // feature. This also ensures that the resulting set is in sorted order. |
| 2521 | +#define LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option) \ |
| 2522 | + if (usesFeature##FeatureName(decl)) \ |
| 2523 | + features.push_back(Feature::FeatureName); |
| 2524 | +#include "swift/Basic/Features.def" |
| 2525 | + |
| 2526 | + return features; |
| 2527 | +} |
| 2528 | + |
| 2529 | +/// Get the set of features that are uniquely used by this declaration, and are |
| 2530 | +/// not part of the enclosing context. |
| 2531 | +static std::vector<Feature> getUniqueFeaturesUsed(Decl *decl) { |
| 2532 | + auto features = getFeaturesUsed(decl); |
| 2533 | + if (features.empty()) |
| 2534 | + return features; |
| 2535 | + |
| 2536 | + auto enclosingDecl = decl->getDeclContext()->getAsDecl(); |
| 2537 | + if (!enclosingDecl) |
| 2538 | + return features; |
| 2539 | + |
| 2540 | + if (!isa<NominalTypeDecl>(enclosingDecl) && |
| 2541 | + !isa<ExtensionDecl>(enclosingDecl)) |
| 2542 | + return features; |
| 2543 | + |
| 2544 | + auto enclosingFeatures = getFeaturesUsed(enclosingDecl); |
| 2545 | + if (enclosingFeatures.empty()) |
| 2546 | + return features; |
| 2547 | + |
| 2548 | + // Remove any features from the enclosing context from this set of features so |
| 2549 | + // that we are left with a unique set. |
| 2550 | + std::vector<Feature> uniqueFeatures; |
| 2551 | + std::set_difference( |
| 2552 | + features.begin(), features.end(), |
| 2553 | + enclosingFeatures.begin(), enclosingFeatures.end(), |
| 2554 | + std::back_inserter(uniqueFeatures)); |
| 2555 | + return uniqueFeatures; |
| 2556 | +} |
| 2557 | + |
| 2558 | + |
| 2559 | +bool swift::printCompatibilityFeatureChecksPre( |
| 2560 | + ASTPrinter &printer, Decl *decl) { |
| 2561 | + auto features = getUniqueFeaturesUsed(decl); |
| 2562 | + if (features.empty()) |
| 2563 | + return false; |
| 2564 | + |
| 2565 | + printer.printNewline(); |
| 2566 | + printer << "#if compiler(>=5.3) && "; |
| 2567 | + llvm::interleave(features.begin(), features.end(), |
| 2568 | + [&](Feature feature) { |
| 2569 | + printer << "$" << getFeatureName(feature); |
| 2570 | + }, |
| 2571 | + [&] { printer << " && "; }); |
| 2572 | + printer.printNewline(); |
| 2573 | + |
| 2574 | + return true; |
| 2575 | +} |
| 2576 | + |
| 2577 | +void swift::printCompatibilityFeatureChecksPost(ASTPrinter &printer) { |
| 2578 | + printer.printNewline(); |
| 2579 | + printer << "#endif\n"; |
| 2580 | +} |
| 2581 | + |
| 2582 | + |
2376 | 2583 | void PrintAST::visitExtensionDecl(ExtensionDecl *decl) {
|
2377 | 2584 | if (Options.TransformContext &&
|
2378 | 2585 | Options.TransformContext->isPrintingSynthesizedExtension()) {
|
@@ -5232,11 +5439,21 @@ swift::getInheritedForPrinting(const Decl *decl, const PrintOptions &options,
|
5232 | 5439 | // Collect explicit inherited types.
|
5233 | 5440 | for (auto TL: inherited) {
|
5234 | 5441 | if (auto ty = TL.getType()) {
|
5235 |
| - bool foundUnprintable = ty.findIf([&options](Type subTy) { |
| 5442 | + bool foundUnprintable = ty.findIf([&](Type subTy) { |
5236 | 5443 | if (auto aliasTy = dyn_cast<TypeAliasType>(subTy.getPointer()))
|
5237 | 5444 | return !options.shouldPrint(aliasTy->getDecl());
|
5238 |
| - if (auto NTD = subTy->getAnyNominal()) |
5239 |
| - return !options.shouldPrint(NTD); |
| 5445 | + if (auto NTD = subTy->getAnyNominal()) { |
| 5446 | + if (!options.shouldPrint(NTD)) |
| 5447 | + return true; |
| 5448 | + |
| 5449 | + if (auto PD = dyn_cast<ProtocolDecl>(NTD)) { |
| 5450 | + // Marker protocols are unprintable on concrete types, but they're |
| 5451 | + // okay on extension declarations and protocols. |
| 5452 | + if (PD->isMarkerProtocol() && !isa<ExtensionDecl>(decl) && |
| 5453 | + !isa<ProtocolDecl>(decl)) |
| 5454 | + return true; |
| 5455 | + } |
| 5456 | + } |
5240 | 5457 | return false;
|
5241 | 5458 | });
|
5242 | 5459 | if (foundUnprintable)
|
|
0 commit comments