Skip to content

[ModuleInterface] AliasModuleNames workaround support for indirect dependencies and missing imports #62073

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions include/swift/AST/ASTPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,7 @@ class ASTPrinter {
PrintNameContext NameContext = PrintNameContext::Normal);

/// Called when printing the referenced name of a module.
virtual void printModuleRef(ModuleEntity Mod, Identifier Name,
const PrintOptions &Options);
virtual void printModuleRef(ModuleEntity Mod, Identifier Name);

/// Called before printing a synthesized extension.
virtual void printSynthesizedExtensionPre(const ExtensionDecl *ED,
Expand Down
14 changes: 13 additions & 1 deletion include/swift/AST/PrintOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "swift/AST/TypeOrExtensionDecl.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
#include <limits.h>
#include <vector>

Expand Down Expand Up @@ -470,6 +471,14 @@ struct PrintOptions {
/// with types sharing a name with a module.
bool AliasModuleNames = false;

/// Name of the modules that have been aliased in AliasModuleNames mode.
/// Ideally we would use something other than a string to identify a module,
/// but since one alias can apply to more than one module, strings happen
/// to be pretty reliable. That is, unless there's an unexpected name
/// collision between two modules, which isn't supported by this workaround
/// yet.
llvm::SmallSet<StringRef, 4> *AliasModuleNamesTargets = nullptr;

/// When printing an Optional<T>, rather than printing 'T?', print
/// 'T!'. Used as a modifier only when we know we're printing
/// something that was declared as an implicitly unwrapped optional
Expand Down Expand Up @@ -641,7 +650,10 @@ struct PrintOptions {
bool preferTypeRepr,
bool printFullConvention,
bool printSPIs,
bool aliasModuleNames);
bool aliasModuleNames,
llvm::SmallSet<StringRef, 4>
*aliasModuleNamesTargets
);

/// Retrieve the set of options suitable for "Generated Interfaces", which
/// are a prettified representation of the public API of a module, to be
Expand Down
25 changes: 15 additions & 10 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,10 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
bool preferTypeRepr,
bool printFullConvention,
bool printSPIs,
bool aliasModuleNames) {
bool aliasModuleNames,
llvm::SmallSet<StringRef, 4>
*aliasModuleNamesTargets
) {
PrintOptions result;
result.IsForSwiftInterface = true;
result.PrintLongAttrsOnSeparateLines = true;
Expand All @@ -154,6 +157,7 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
OpaqueReturnTypePrintingMode::StableReference;
result.PreferTypeRepr = preferTypeRepr;
result.AliasModuleNames = aliasModuleNames;
result.AliasModuleNamesTargets = aliasModuleNamesTargets;
if (printFullConvention)
result.PrintFunctionRepresentationAttrs =
PrintOptions::FunctionRepresentationMode::Full;
Expand Down Expand Up @@ -367,11 +371,7 @@ void ASTPrinter::printTypeRef(Type T, const TypeDecl *RefTo, Identifier Name,
printName(Name, Context);
}

void ASTPrinter::printModuleRef(ModuleEntity Mod, Identifier Name,
const PrintOptions &Options) {
if (Options.AliasModuleNames)
printTextImpl(MODULE_DISAMBIGUATING_PREFIX);

void ASTPrinter::printModuleRef(ModuleEntity Mod, Identifier Name) {
printName(Name);
}

Expand Down Expand Up @@ -2509,7 +2509,7 @@ void PrintAST::visitImportDecl(ImportDecl *decl) {
Name = Declaring->getRealName();
}
}
Printer.printModuleRef(Mods.front(), Name, Options);
Printer.printModuleRef(Mods.front(), Name);
Mods = Mods.slice(1);
} else {
Printer << Elem.Item.str();
Expand Down Expand Up @@ -5397,7 +5397,13 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
}
}

Printer.printModuleRef(Mod, Name, Options);
if (Options.AliasModuleNames && Options.AliasModuleNamesTargets &&
Options.AliasModuleNamesTargets->contains(Name.str())) {
auto nameTwine = MODULE_DISAMBIGUATING_PREFIX + Name.str();
Name = Mod->getASTContext().getIdentifier(nameTwine.str());
}

Printer.printModuleRef(Mod, Name);
Printer << ".";
}

Expand Down Expand Up @@ -5748,8 +5754,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
Printer << "module<";
// Should print the module real name in case module aliasing is
// used (see -module-alias), since that's the actual binary name.
Printer.printModuleRef(T->getModule(), T->getModule()->getRealName(),
Options);
Printer.printModuleRef(T->getModule(), T->getModule()->getRealName());
Printer << ">";
}

Expand Down
2 changes: 1 addition & 1 deletion lib/AST/TypeRepr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ void ComponentIdentTypeRepr::printImpl(ASTPrinter &Printer,
const PrintOptions &Opts) const {
if (auto *TD = dyn_cast_or_null<TypeDecl>(getBoundDecl())) {
if (auto MD = dyn_cast<ModuleDecl>(TD))
Printer.printModuleRef(MD, getNameRef().getBaseIdentifier(), Opts);
Printer.printModuleRef(MD, getNameRef().getBaseIdentifier());
else
Printer.printTypeRef(Type(), TD, getNameRef().getBaseIdentifier());
} else {
Expand Down
16 changes: 10 additions & 6 deletions lib/Frontend/ModuleInterfaceSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ version::Version swift::InterfaceFormatVersion({1, 0});
/// construct \p M.
static void printToolVersionAndFlagsComment(raw_ostream &out,
ModuleInterfaceOptions const &Opts,
ModuleDecl *M) {
ModuleDecl *M,
llvm::SmallSet<StringRef, 4>
&AliasModuleNamesTargets) {
auto &Ctx = M->getASTContext();
auto ToolsVersion =
getSwiftInterfaceCompilerVersionForCurrentCompiler(Ctx);
Expand All @@ -62,9 +64,8 @@ static void printToolVersionAndFlagsComment(raw_ostream &out,

// Insert additional -module-alias flags
if (Opts.AliasModuleNames) {
llvm::SmallSet<StringRef, 2> aliasTargets;
StringRef moduleName = M->getNameStr();
aliasTargets.insert(M->getNameStr());
AliasModuleNamesTargets.insert(M->getNameStr());
out << " -module-alias " << MODULE_DISAMBIGUATING_PREFIX <<
moduleName << "=" << moduleName;

Expand All @@ -74,9 +75,10 @@ static void printToolVersionAndFlagsComment(raw_ostream &out,
ModuleDecl::ImportFilterKind::Exported,
ModuleDecl::ImportFilterKind::SPIOnly,
ModuleDecl::ImportFilterKind::SPIAccessControl});
M->getMissingImportedModules(imports);
for (ImportedModule import: imports) {
StringRef importedName = import.importedModule->getNameStr();
if (aliasTargets.insert(importedName).second) {
if (AliasModuleNamesTargets.insert(importedName).second) {
out << " -module-alias " << MODULE_DISAMBIGUATING_PREFIX <<
importedName << "=" << importedName;
}
Expand Down Expand Up @@ -781,12 +783,14 @@ bool swift::emitSwiftInterface(raw_ostream &out,
ModuleDecl *M) {
assert(M);

printToolVersionAndFlagsComment(out, Opts, M);
llvm::SmallSet<StringRef, 4> aliasModuleNamesTargets;
printToolVersionAndFlagsComment(out, Opts, M, aliasModuleNamesTargets);

printImports(out, Opts, M);

const PrintOptions printOptions = PrintOptions::printSwiftInterfaceFile(
M, Opts.PreserveTypesAsWritten, Opts.PrintFullConvention, Opts.PrintSPIs,
Opts.AliasModuleNames);
Opts.AliasModuleNames, &aliasModuleNamesTargets);
InheritedProtocolCollector::PerTypeMap inheritedProtocolMap;

SmallVector<Decl *, 16> topLevelDecls;
Expand Down
5 changes: 2 additions & 3 deletions lib/IDE/ModuleInterfacePrinting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,8 @@ class ClangCommentPrinter : public ASTPrinter {
PrintNameContext NameContext) override {
return OtherPrinter.printTypeRef(T, TD, Name, NameContext);
}
void printModuleRef(ModuleEntity Mod, Identifier Name,
const PrintOptions &Options) override {
return OtherPrinter.printModuleRef(Mod, Name, Options);
void printModuleRef(ModuleEntity Mod, Identifier Name) override {
return OtherPrinter.printModuleRef(Mod, Name);
}
void printSynthesizedExtensionPre(const ExtensionDecl *ED,
TypeOrExtensionDecl Target,
Expand Down
20 changes: 18 additions & 2 deletions test/ModuleInterface/ambiguous-aliases-workaround.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,19 @@
// RUN: %empty-directory(%t)
// RUN: split-file %s %t

// RUN: %target-swift-frontend -emit-module -module-name ExportedLib \
// RUN: -swift-version 5 -enable-library-evolution \
// RUN: -o %t/ExportedLib.swiftmodule \
// RUN: -emit-module-interface-path %t/ExportedLib.swiftinterface \
// RUN: %t/ExportedLib.swift
// RUN: %target-swift-typecheck-module-from-interface(%t/ExportedLib.swiftinterface)

// RUN: %target-swift-frontend -emit-module -module-name AmbiguousLib \
// RUN: -swift-version 5 -enable-library-evolution \
// RUN: -o %t/AmbiguousLib.swiftmodule \
// RUN: -emit-module-interface-path %t/AmbiguousLib.swiftinterface \
// RUN: %t/AmbiguousLib.swift
// RUN: %target-swift-typecheck-module-from-interface(%t/AmbiguousLib.swiftinterface)
// RUN: %t/AmbiguousLib.swift -I%t
// RUN: %target-swift-typecheck-module-from-interface(%t/AmbiguousLib.swiftinterface) -I%t

// RUN: %target-swift-frontend -emit-module -module-name AmbiguousClientName \
// RUN: -swift-version 5 -enable-library-evolution \
Expand Down Expand Up @@ -40,10 +47,17 @@ struct UnderlyingType {};
void underlyingFunc() {}

//--- SomeClangModule.h

struct CType {};

//--- ExportedLib.swift

public struct ExportedStruct {}

//--- AmbiguousLib.swift

@_exported import ExportedLib

// 1. AmbiguousLib defined a type named AmbiguousLib
public struct AmbiguousLib {
public struct Nested {}
Expand Down Expand Up @@ -73,6 +87,8 @@ public func refToStdlib(_ a: Swift.Int) {}
public func refToUnderlying(_ a: UnderlyingType) {}
public func refToC(_ a: CType) {}

public func refToReexport(_ a: ExportedStruct) {}

//--- OverlayClient.swift

import AmbiguousClientName
Expand Down
6 changes: 6 additions & 0 deletions test/Sema/missing-import-inlinable-code.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@
// RUN: %target-swift-emit-module-interface(%t/ClientFixed.swiftinterface) %t/clientFileA-Swift5.swift %t/clientFileB.swift -I %t
// RUN: %target-swift-typecheck-module-from-interface(%t/ClientFixed.swiftinterface) -I %t

/// The inserted missing imports should be aliased.
// RUN: %target-swift-emit-module-interface(%t/ClientFixed.swiftinterface) %t/clientFileA-Swift5.swift %t/clientFileB.swift -I %t -alias-module-names-in-module-interface
// RUN: %target-swift-typecheck-module-from-interface(%t/ClientFixed.swiftinterface) -I %t
// RUN: cat %t/ClientFixed.swiftinterface | %FileCheck -check-prefix ALIASED %s
// ALIASED: import Module___libB

// REQUIRES: asserts

// BEGIN empty.swift
Expand Down
5 changes: 2 additions & 3 deletions tools/SourceKit/lib/SwiftLang/SwiftEditorInterfaceGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,10 @@ class AnnotatingPrinter : public StreamPrinter {
StreamPrinter::printTypeRef(T, TD, Name, NameContext);
}

void printModuleRef(ModuleEntity Mod, Identifier Name,
const PrintOptions &Options) override {
void printModuleRef(ModuleEntity Mod, Identifier Name) override {
unsigned StartOffset = OS.tell();
Info.References.emplace_back(Mod, StartOffset, Name.str().size());
StreamPrinter::printModuleRef(Mod, Name, Options);
StreamPrinter::printModuleRef(Mod, Name);
}
};

Expand Down
5 changes: 2 additions & 3 deletions tools/swift-ide-test/swift-ide-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2841,10 +2841,9 @@ class AnnotatingPrinter : public StreamPrinter {
StreamPrinter::printTypeRef(T, TD, Name, NameContext);
OS << "</ref>";
}
void printModuleRef(ModuleEntity Mod, Identifier Name,
const PrintOptions &Options) override {
void printModuleRef(ModuleEntity Mod, Identifier Name) override {
OS << "<ref:module>";
StreamPrinter::printModuleRef(Mod, Name, Options);
StreamPrinter::printModuleRef(Mod, Name);
OS << "</ref>";
}
};
Expand Down