Skip to content

Commit e5ca8e5

Browse files
committed
Allow loading package interface if in same package.
Add a new flag to enable package interface loading. Use the last value of package-name in case of dupes. Rename PrintInterfaceContentMode as InterfaceMode. Update diagnostics. Test package interface loading with various scenarios. Test duplicate package-name.
1 parent aba3b6c commit e5ca8e5

18 files changed

+314
-138
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,14 +1103,14 @@ ERROR(module_not_testable,Fatal,
11031103
ERROR(module_not_compiled_for_private_import,none,
11041104
"module %0 was not compiled for private import", (Identifier))
11051105

1106-
ERROR(in_package_module_not_compiled_from_source,none,
1107-
"module %0 is in package '%1' but was built from interface; "
1108-
"modules of the same package can only be loaded if built from source: %2",
1106+
ERROR(in_package_module_not_compiled_from_source_or_package_interface,none,
1107+
"module %0 is in package '%1' but was built from a non-package interface; "
1108+
"modules of the same package can only be loaded if built from source or package interface: %2",
11091109
(Identifier, StringRef, StringRef))
11101110

11111111
WARNING(in_package_module_not_compiled_locally,none,
11121112
"module %0 is in package %1 but was loaded from SDK; "
1113-
"modules of the same package should be built locally from source only: %2",
1113+
"modules of the same package should be built locally: %2",
11141114
(Identifier, Identifier, StringRef))
11151115

11161116
ERROR(import_restriction_conflict,none,

include/swift/AST/PrintOptions.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ struct ShouldPrintChecker {
118118
virtual ~ShouldPrintChecker() = default;
119119
};
120120

121-
enum class PrintInterfaceContentMode : uint8_t {
121+
enum class InterfaceMode : uint8_t {
122122
Public, // prints public/inlinable decls
123123
Private, // prints SPI and public/inlinable decls
124124
Package // prints package, SPI, and public/inlinable decls
@@ -305,7 +305,7 @@ struct PrintOptions {
305305
/// Whether to skip keywords with a prefix of underscore such as __consuming.
306306
bool SkipUnderscoredKeywords = false;
307307

308-
PrintInterfaceContentMode InterfaceContentMode;
308+
InterfaceMode InterfaceContentMode;
309309

310310
/// Prints type variables and unresolved types in an expanded notation suitable
311311
/// for debugging.
@@ -689,7 +689,7 @@ struct PrintOptions {
689689
static PrintOptions printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
690690
bool preferTypeRepr,
691691
bool printFullConvention,
692-
PrintInterfaceContentMode interfaceContentMode,
692+
InterfaceMode interfaceContentMode,
693693
bool useExportedModuleNames,
694694
bool aliasModuleNames,
695695
llvm::SmallSet<StringRef, 4>

include/swift/Basic/LangOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ namespace swift {
216216
/// Should access control be respected?
217217
bool EnableAccessControl = true;
218218

219+
/// Enable loading a package interface if both client and depdency module are in the
220+
/// same package determined by `package-name` flag.
221+
bool EnablePackageInterfaceLoad = false;
222+
219223
/// Enable 'availability' restrictions for App Extensions.
220224
bool EnableAppExtensionRestrictions = false;
221225

include/swift/Frontend/ModuleInterfaceSupport.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ struct ModuleInterfaceOptions {
5656
std::string IgnorablePrivateFlags;
5757

5858
/// Prints package, SPIs, or public/inlinable decls depending on the mode.
59-
PrintInterfaceContentMode InterfaceContentMode = PrintInterfaceContentMode::Public;
59+
InterfaceMode InterfaceContentMode = InterfaceMode::Public;
6060

6161
/// Print imports with both @_implementationOnly and @_spi, only applies
6262
/// when PrintSPIs is true.

include/swift/Option/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,11 @@ def experimental_hermetic_seal_at_link:
758758
Flags<[FrontendOption, HelpHidden]>,
759759
HelpText<"Library code can assume that all clients are visible at linktime, and aggressively strip unused code">;
760760

761+
def experimental_package_interface_load:
762+
Flag<["-"], "experimental-package-interface-load">,
763+
Flags<[FrontendOption, HelpHidden]>,
764+
HelpText<"Enables loading a package interface if in the same package specified with package-name">;
765+
761766
// Diagnostic control options
762767
def suppress_warnings : Flag<["-"], "suppress-warnings">,
763768
Flags<[FrontendOption]>,

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,12 @@ struct SerializedModuleBaseName {
6767
/// private interface if there is one, else public). Return an empty optional otherwise.
6868
llvm::Optional<std::string>
6969
findInterfacePath(llvm::vfs::FileSystem &fs, ASTContext &ctx) const;
70-
70+
7171
/// Returns the .package.swiftinterface path if its package-name also applies to
7272
/// the the importing module. Returns an empty optional otherwise.
7373
llvm::Optional<std::string>
74-
getPackageInterfacePathIfInSamePackage(llvm::vfs::FileSystem &fs, ASTContext &ctx) const;
74+
getPackageInterfacePathIfInSamePackage(llvm::vfs::FileSystem &fs,
75+
ASTContext &ctx) const;
7576
};
7677

7778
/// Common functionality shared between \c ImplicitSerializedModuleLoader,
@@ -183,6 +184,7 @@ class SerializedModuleLoaderBase : public ModuleLoader {
183184
/// Load the module file into a buffer and also collect its module name.
184185
static std::unique_ptr<llvm::MemoryBuffer>
185186
getModuleName(ASTContext &Ctx, StringRef modulePath, std::string &Name);
187+
186188
public:
187189
virtual ~SerializedModuleLoaderBase();
188190
SerializedModuleLoaderBase(const SerializedModuleLoaderBase &) = delete;

lib/AST/ASTPrinter.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ static bool shouldTypeCheck(const PrintOptions &options) {
174174
PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
175175
bool preferTypeRepr,
176176
bool printFullConvention,
177-
PrintInterfaceContentMode interfaceContentMode,
177+
InterfaceMode interfaceContentMode,
178178
bool useExportedModuleNames,
179179
bool aliasModuleNames,
180180
llvm::SmallSet<StringRef, 4>
@@ -238,7 +238,7 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
238238
return false;
239239

240240
// Skip SPI decls if `PrintSPIs`.
241-
if (options.InterfaceContentMode == PrintInterfaceContentMode::Public && D->isSPI())
241+
if (options.InterfaceContentMode == InterfaceMode::Public && D->isSPI())
242242
return false;
243243

244244
if (auto *VD = dyn_cast<ValueDecl>(D)) {
@@ -252,7 +252,7 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
252252
if (contributesToParentTypeStorage(ASD))
253253
return true;
254254

255-
if (options.InterfaceContentMode != PrintInterfaceContentMode::Package || !isPackage(VD))
255+
if (options.InterfaceContentMode != InterfaceMode::Package || !isPackage(VD))
256256
return false;
257257
}
258258

@@ -288,7 +288,7 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
288288

289289
for (const Requirement &req : ED->getGenericRequirements()) {
290290
if (!isPublicOrUsableFromInline(req.getFirstType())) {
291-
if (options.InterfaceContentMode != PrintInterfaceContentMode::Package || !isPackage(req.getSecondType()))
291+
if (options.InterfaceContentMode != InterfaceMode::Package || !isPackage(req.getSecondType()))
292292
return false;
293293
}
294294

@@ -297,7 +297,7 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
297297
case RequirementKind::Superclass:
298298
case RequirementKind::SameType:
299299
if (!isPublicOrUsableFromInline(req.getSecondType())) {
300-
if (options.InterfaceContentMode != PrintInterfaceContentMode::Package || !isPackage(req.getSecondType()))
300+
if (options.InterfaceContentMode != InterfaceMode::Package || !isPackage(req.getSecondType()))
301301
return false;
302302
}
303303
break;
@@ -1205,7 +1205,7 @@ void PrintAST::printAttributes(const Decl *D) {
12051205
}
12061206

12071207
// Add SPIs to both private and package interfaces
1208-
if (Options.InterfaceContentMode != PrintInterfaceContentMode::Public &&
1208+
if (Options.InterfaceContentMode != InterfaceMode::Public &&
12091209
DeclAttribute::canAttributeAppearOnDeclKind(
12101210
DAK_SPIAccessControl, D->getKind())) {
12111211
interleave(D->getSPIGroups(),
@@ -1294,7 +1294,7 @@ static bool mustPrintPropertyName(VarDecl *decl, const PrintOptions &opts) {
12941294
if (contributesToParentTypeStorage(decl)) return true;
12951295

12961296
// Print a package decl if in print package mode (for .package.swiftinterface),
1297-
if (opts.InterfaceContentMode == PrintInterfaceContentMode::Package && isPackage(decl))
1297+
if (opts.InterfaceContentMode == InterfaceMode::Package && isPackage(decl))
12981298
return true;
12991299

13001300
// If it's public or @usableFromInline, we must print the name because it's a
@@ -6007,8 +6007,11 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
60076007
Filter |= ModuleDecl::ImportFilterKind::Default;
60086008

60096009
// For private or package swiftinterfaces, also look through @_spiOnly imports.
6010-
if (Options.InterfaceContentMode != PrintInterfaceContentMode::Public)
6010+
if (Options.InterfaceContentMode != InterfaceMode::Public)
60116011
Filter |= ModuleDecl::ImportFilterKind::SPIOnly;
6012+
// Consider package import for package interface
6013+
if (Options.InterfaceContentMode == InterfaceMode::Package)
6014+
Filter |= ModuleDecl::ImportFilterKind::PackageOnly;
60126015

60136016
SmallVector<ImportedModule, 4> Imports;
60146017
Options.CurrentModule->getImportedModules(Imports, Filter);

lib/AST/Attr.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,7 +1048,7 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
10481048
return true;
10491049

10501050
case DAK_SPIAccessControl: {
1051-
if (Options.InterfaceContentMode == PrintInterfaceContentMode::Public) return false;
1051+
if (Options.InterfaceContentMode == InterfaceMode::Public) return false;
10521052

10531053
auto spiAttr = static_cast<const SPIAccessControlAttr*>(this);
10541054
interleave(spiAttr->getSPIGroups(),
@@ -1100,7 +1100,7 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
11001100
auto Attr = cast<AvailableAttr>(this);
11011101
if (Options.SuppressNoAsyncAvailabilityAttr && Attr->isNoAsync())
11021102
return false;
1103-
if (Options.InterfaceContentMode == PrintInterfaceContentMode::Public && Attr->IsSPI) {
1103+
if (Options.InterfaceContentMode == InterfaceMode::Public && Attr->IsSPI) {
11041104
assert(Attr->hasPlatform());
11051105
assert(Attr->Introduced.has_value());
11061106
Printer.printAttrName("@available");
@@ -1196,7 +1196,7 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
11961196
auto *attr = cast<SpecializeAttr>(this);
11971197
// Don't print the _specialize attribute if it is marked spi and we are
11981198
// asked to skip SPI.
1199-
if (Options.InterfaceContentMode == PrintInterfaceContentMode::Public && !attr->getSPIGroups().empty())
1199+
if (Options.InterfaceContentMode == InterfaceMode::Public && !attr->getSPIGroups().empty())
12001200
return false;
12011201

12021202
// Don't print the _specialize attribute if we are asked to skip the ones

lib/Frontend/CompilerInvocation.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ static void ParseModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
417417
if (const Arg *A = Args.getLastArg(OPT_library_level)) {
418418
StringRef contents = A->getValue();
419419
if (contents == "spi") {
420-
Opts.InterfaceContentMode = PrintInterfaceContentMode::Private;
420+
Opts.InterfaceContentMode = InterfaceMode::Private;
421421
}
422422
}
423423
for (auto val: Args.getAllArgValues(OPT_skip_import_in_public_interface)) {
@@ -622,6 +622,12 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
622622
Opts.EnableAccessControl
623623
= A->getOption().matches(OPT_enable_access_control);
624624
}
625+
if (auto A = Args.getLastArg(OPT_experimental_package_interface_load,
626+
OPT_experimental_package_interface_load)) {
627+
Opts.EnablePackageInterfaceLoad
628+
= A->getOption().matches(OPT_experimental_package_interface_load);
629+
}
630+
625631
Opts.ForceWorkaroundBrokenModules
626632
|= Args.hasArg(OPT_force_workaround_broken_modules);
627633

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ static void printToolVersionAndFlagsComment(raw_ostream &out,
7171

7272
ModuleDecl::ImportFilter filter = {ModuleDecl::ImportFilterKind::Default,
7373
ModuleDecl::ImportFilterKind::Exported};
74-
if (Opts.InterfaceContentMode != PrintInterfaceContentMode::Public)
74+
if (Opts.InterfaceContentMode != InterfaceMode::Public)
7575
filter |= ModuleDecl::ImportFilterKind::SPIOnly;
76+
if (Opts.InterfaceContentMode == InterfaceMode::Package)
77+
filter |= ModuleDecl::ImportFilterKind::PackageOnly;
7678

7779
SmallVector<ImportedModule> imports;
7880
M->getImportedModules(imports, filter);
@@ -99,7 +101,7 @@ static void printToolVersionAndFlagsComment(raw_ostream &out,
99101
<< Opts.IgnorableFlags << "\n";
100102
}
101103

102-
auto hasPrivateIgnorableFlags = Opts.InterfaceContentMode != PrintInterfaceContentMode::Public && !Opts.IgnorablePrivateFlags.empty();
104+
auto hasPrivateIgnorableFlags = Opts.InterfaceContentMode != InterfaceMode::Public && !Opts.IgnorablePrivateFlags.empty();
103105
if (hasPrivateIgnorableFlags) {
104106
out << "// " SWIFT_MODULE_FLAGS_IGNORABLE_PRIVATE_KEY ": "
105107
<< Opts.IgnorablePrivateFlags << "\n";
@@ -245,7 +247,7 @@ static void printImports(raw_ostream &out,
245247
// imports only if they are also SPI. First, list all implementation-only imports and
246248
// filter them later.
247249
llvm::SmallSet<ImportedModule, 4, ImportedModule::Order> ioiImportSet;
248-
if (Opts.InterfaceContentMode != PrintInterfaceContentMode::Public && Opts.ExperimentalSPIImports) {
250+
if (Opts.InterfaceContentMode != InterfaceMode::Public && Opts.ExperimentalSPIImports) {
249251

250252
SmallVector<ImportedModule, 4> ioiImports, allImports;
251253
M->getImportedModules(ioiImports,
@@ -266,7 +268,7 @@ static void printImports(raw_ostream &out,
266268

267269
/// Collect @_spiOnly imports that are not imported elsewhere publicly.
268270
llvm::SmallSet<ImportedModule, 4, ImportedModule::Order> spiOnlyImportSet;
269-
if (Opts.InterfaceContentMode != PrintInterfaceContentMode::Public) {
271+
if (Opts.InterfaceContentMode != InterfaceMode::Public) {
270272
SmallVector<ImportedModule, 4> spiOnlyImports, otherImports;
271273
M->getImportedModules(spiOnlyImports,
272274
ModuleDecl::ImportFilterKind::SPIOnly);
@@ -333,7 +335,7 @@ static void printImports(raw_ostream &out,
333335
if (publicImportSet.count(import))
334336
out << "@_exported ";
335337

336-
if (Opts.InterfaceContentMode != PrintInterfaceContentMode::Public) {
338+
if (Opts.InterfaceContentMode != InterfaceMode::Public) {
337339
// An import visible in the private or package swiftinterface only.
338340
//
339341
// In the long term, we want to print this attribute for consistency and
@@ -621,7 +623,7 @@ class InheritedProtocolCollector {
621623
return;
622624

623625
// Skip SPI extensions in the public interface.
624-
if (printOptions.InterfaceContentMode == PrintInterfaceContentMode::Public && extension->isSPI())
626+
if (printOptions.InterfaceContentMode == InterfaceMode::Public && extension->isSPI())
625627
return;
626628

627629
const NominalTypeDecl *nominal = extension->getExtendedNominal();
@@ -702,7 +704,7 @@ class InheritedProtocolCollector {
702704
inherited->isSpecificProtocol(KnownProtocolKind::Actor))
703705
return TypeWalker::Action::SkipChildren;
704706

705-
if (inherited->isSPI() && printOptions.InterfaceContentMode == PrintInterfaceContentMode::Public)
707+
if (inherited->isSPI() && printOptions.InterfaceContentMode == InterfaceMode::Public)
706708
return TypeWalker::Action::Continue;
707709

708710
if (isPublicOrUsableFromInline(inherited) &&
@@ -782,7 +784,7 @@ class InheritedProtocolCollector {
782784
return false;
783785
assert(nominal->isGenericContext());
784786

785-
if (printOptions.InterfaceContentMode != PrintInterfaceContentMode::Public)
787+
if (printOptions.InterfaceContentMode != InterfaceMode::Public)
786788
out << "@_spi(" << DummyProtocolName << ")\n";
787789
out << "@available(*, unavailable)\nextension ";
788790
nominal->getDeclaredType().print(out, printOptions);
@@ -823,7 +825,7 @@ bool swift::emitSwiftInterface(raw_ostream &out,
823825

824826
printImports(out, Opts, M, aliasModuleNamesTargets);
825827

826-
bool useExportedModuleNames = Opts.InterfaceContentMode == PrintInterfaceContentMode::Public;
828+
bool useExportedModuleNames = Opts.InterfaceContentMode == InterfaceMode::Public;
827829

828830
const PrintOptions printOptions = PrintOptions::printSwiftInterfaceFile(
829831
M, Opts.PreserveTypesAsWritten, Opts.PrintFullConvention,

0 commit comments

Comments
 (0)