mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Prevent PrintOptions from being implicitly copied.
NFC *except* that I noticed a bug by inspection where we suppress `@escaping` when print enum element types. Since this affects recursive positions, we end up suppressing `@escaping` in places we shouldn't. This is unlikely to affect much real code, but should still obviously be fixed. The new design is a little sketchy in that we're using `const` to prevent direct use (and allow initialization of `const &` parameters) but still relying on modification of the actual object. Essentially, we are treating the `const`-ness of the reference as a promise to leave the original value in the object after computation rather than a guarantee of not modifying the object. This is okay --- a temporary bound to a `const` reference is still a non-`const` object formally and can be modified without invoking UB --- but makes me a little uncomfortable.
This commit is contained in:
@@ -94,15 +94,15 @@ printTypeInterface(ModuleDecl *M, StringRef TypeUSR, ASTPrinter &Printer,
|
||||
Printer, TypeName, Error);
|
||||
}
|
||||
|
||||
static void adjustPrintOptions(PrintOptions &AdjustedOptions) {
|
||||
static void adjustPrintOptions(PrintOptions::OverrideScope &Options) {
|
||||
// Don't print empty curly braces while printing the module interface.
|
||||
AdjustedOptions.FunctionDefinitions = false;
|
||||
OVERRIDE_PRINT_OPTION(Options, FunctionDefinitions, false);
|
||||
|
||||
AdjustedOptions.PrintGetSetOnRWProperties = false;
|
||||
OVERRIDE_PRINT_OPTION(Options, PrintGetSetOnRWProperties, false);
|
||||
|
||||
// Print var declarations separately, one variable per decl.
|
||||
AdjustedOptions.ExplodePatternBindingDecls = true;
|
||||
AdjustedOptions.VarInitializers = false;
|
||||
OVERRIDE_PRINT_OPTION(Options, ExplodePatternBindingDecls, true);
|
||||
OVERRIDE_PRINT_OPTION(Options, VarInitializers, false);
|
||||
}
|
||||
|
||||
void swift::ide::collectModuleGroups(ModuleDecl *M,
|
||||
@@ -138,7 +138,7 @@ std::optional<StringRef> swift::ide::findGroupNameForUSR(ModuleDecl *M,
|
||||
/// \returns Whether the given decl was printed.
|
||||
static bool printModuleInterfaceDecl(Decl *D,
|
||||
ASTPrinter &Printer,
|
||||
PrintOptions &Options,
|
||||
const PrintOptions &Options,
|
||||
bool PrintSynthesizedExtensions,
|
||||
StringRef LeadingComment = StringRef()) {
|
||||
if (!Options.shouldPrint(D)) {
|
||||
@@ -156,16 +156,27 @@ static bool printModuleInterfaceDecl(Decl *D,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// It'd be nice to avoid cloning the options here, but that would require
|
||||
// SynthesizedExtensionAnalyzer to promise to stay within the lifetime of
|
||||
// the options it was constructed with, and besides, it isn't easy to see
|
||||
// whether the mutations we make to Options here are meant to be independent
|
||||
// of what might be done with the analyzer.
|
||||
PrintOptions::OverrideScope OptionAdjustment(Options);
|
||||
|
||||
std::unique_ptr<SynthesizedExtensionAnalyzer> pAnalyzer;
|
||||
if (auto NTD = dyn_cast<NominalTypeDecl>(D)) {
|
||||
if (PrintSynthesizedExtensions) {
|
||||
pAnalyzer.reset(new SynthesizedExtensionAnalyzer(NTD, Options));
|
||||
Options.BracketOptions = {
|
||||
pAnalyzer.reset(new SynthesizedExtensionAnalyzer(NTD, Options.clone()));
|
||||
|
||||
BracketOptions NewBracketOptions = {
|
||||
NTD, true, true,
|
||||
!pAnalyzer->hasMergeGroup(
|
||||
SynthesizedExtensionAnalyzer::MergeGroupKind::MergeableWithTypeDef
|
||||
)
|
||||
};
|
||||
OVERRIDE_PRINT_OPTION_UNCONDITIONAL(OptionAdjustment, BracketOptions,
|
||||
NewBracketOptions);
|
||||
}
|
||||
}
|
||||
if (!LeadingComment.empty() && Options.shouldPrint(D)) {
|
||||
@@ -175,7 +186,8 @@ static bool printModuleInterfaceDecl(Decl *D,
|
||||
if (D->print(Printer, Options)) {
|
||||
if (Options.BracketOptions.shouldCloseNominal(D))
|
||||
Printer.printNewline();
|
||||
Options.BracketOptions = BracketOptions();
|
||||
OVERRIDE_PRINT_OPTION_UNCONDITIONAL(OptionAdjustment, BracketOptions,
|
||||
BracketOptions());
|
||||
if (auto NTD = dyn_cast<NominalTypeDecl>(D)) {
|
||||
std::queue<NominalTypeDecl *> SubDecls{{NTD}};
|
||||
|
||||
@@ -222,15 +234,18 @@ static bool printModuleInterfaceDecl(Decl *D,
|
||||
SynthesizedExtensionAnalyzer::MergeGroupKind::MergeableWithTypeDef,
|
||||
[&](ArrayRef<ExtensionInfo> Decls) {
|
||||
for (auto ET : Decls) {
|
||||
Options.BracketOptions = {
|
||||
PrintOptions::OverrideScope ETOptionsScope(Options);
|
||||
|
||||
BracketOptions NewBracketOptions = {
|
||||
ET.Ext, false, Decls.back().Ext == ET.Ext, true
|
||||
};
|
||||
OVERRIDE_PRINT_OPTION_UNCONDITIONAL(ETOptionsScope, BracketOptions,
|
||||
NewBracketOptions);
|
||||
|
||||
if (ET.IsSynthesized)
|
||||
Options.initForSynthesizedExtension(NTD);
|
||||
Options.initForSynthesizedExtensionInScope(NTD, ETOptionsScope);
|
||||
ET.Ext->print(Printer, Options);
|
||||
if (ET.IsSynthesized)
|
||||
Options.clearSynthesizedExtension();
|
||||
if (Options.BracketOptions.shouldCloseExtension(ET.Ext))
|
||||
if (NewBracketOptions.shouldCloseExtension(ET.Ext))
|
||||
Printer.printNewline();
|
||||
}
|
||||
});
|
||||
@@ -238,7 +253,7 @@ static bool printModuleInterfaceDecl(Decl *D,
|
||||
|
||||
// If the printed Decl is not the top-level one, reset analyzer.
|
||||
if (!IsTopLevelDecl)
|
||||
pAnalyzer.reset(new SynthesizedExtensionAnalyzer(NTD, Options));
|
||||
pAnalyzer.reset(new SynthesizedExtensionAnalyzer(NTD, Options.clone()));
|
||||
|
||||
// Print the rest as synthesized extensions.
|
||||
pAnalyzer->forEachExtensionMergeGroup(
|
||||
@@ -251,10 +266,15 @@ static bool printModuleInterfaceDecl(Decl *D,
|
||||
// Whether we've started the extension merge group in printing.
|
||||
bool Opened = false;
|
||||
for (auto ET : Decls) {
|
||||
Options.BracketOptions = {
|
||||
PrintOptions::OverrideScope ETOptionsScope(Options);
|
||||
|
||||
BracketOptions NewBracketOptions = {
|
||||
ET.Ext, !Opened, Decls.back().Ext == ET.Ext, true
|
||||
};
|
||||
if (Options.BracketOptions.shouldOpenExtension(ET.Ext)) {
|
||||
OVERRIDE_PRINT_OPTION_UNCONDITIONAL(ETOptionsScope, BracketOptions,
|
||||
NewBracketOptions);
|
||||
|
||||
if (NewBracketOptions.shouldOpenExtension(ET.Ext)) {
|
||||
Printer.printNewline();
|
||||
if (Options.shouldPrint(ET.Ext) && !LeadingComment.empty()) {
|
||||
Printer << LeadingComment;
|
||||
@@ -263,20 +283,19 @@ static bool printModuleInterfaceDecl(Decl *D,
|
||||
}
|
||||
if (ET.IsSynthesized) {
|
||||
if (ET.EnablingExt)
|
||||
Options.initForSynthesizedExtension(ET.EnablingExt);
|
||||
Options.initForSynthesizedExtensionInScope(ET.EnablingExt,
|
||||
ETOptionsScope);
|
||||
else
|
||||
Options.initForSynthesizedExtension(NTD);
|
||||
Options.initForSynthesizedExtensionInScope(NTD, ETOptionsScope);
|
||||
}
|
||||
// Set opened if we actually printed this extension.
|
||||
Opened |= ET.Ext->print(Printer, Options);
|
||||
if (ET.IsSynthesized)
|
||||
Options.clearSynthesizedExtension();
|
||||
if (Options.BracketOptions.shouldCloseExtension(ET.Ext)) {
|
||||
|
||||
if (NewBracketOptions.shouldCloseExtension(ET.Ext)) {
|
||||
Printer.printNewline();
|
||||
}
|
||||
}
|
||||
});
|
||||
Options.BracketOptions = BracketOptions();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -395,7 +414,7 @@ getDeclsFromCrossImportOverlay(ModuleDecl *Overlay, ModuleDecl *Declaring,
|
||||
|
||||
static void printCrossImportOverlays(ModuleDecl *Declaring, ASTContext &Ctx,
|
||||
ASTPrinter &Printer,
|
||||
PrintOptions Options,
|
||||
const PrintOptions &Options,
|
||||
bool PrintSynthesizedExtensions) {
|
||||
SmallVector<Decl *, 1> OverlayDecls;
|
||||
SmallVector<Identifier, 1> Bystanders;
|
||||
@@ -483,8 +502,8 @@ void swift::ide::printModuleInterface(
|
||||
auto &Importer =
|
||||
static_cast<ClangImporter &>(*SwiftContext.getClangModuleLoader());
|
||||
|
||||
auto AdjustedOptions = Options;
|
||||
adjustPrintOptions(AdjustedOptions);
|
||||
PrintOptions::OverrideScope OptionAdjustment(Options);
|
||||
adjustPrintOptions(OptionAdjustment);
|
||||
|
||||
llvm::DenseSet<const void *> SeenImportedDecls;
|
||||
SmallVector<ModuleDecl *, 1> ModuleList;
|
||||
@@ -722,7 +741,7 @@ void swift::ide::printModuleInterface(
|
||||
std::stable_sort(SwiftDecls.begin(), SwiftDecls.end(), compareSwiftDecls);
|
||||
|
||||
auto PrintDecl = [&](Decl *D) {
|
||||
return printModuleInterfaceDecl(D, Printer, AdjustedOptions,
|
||||
return printModuleInterfaceDecl(D, Printer, Options,
|
||||
PrintSynthesizedExtensions);
|
||||
};
|
||||
|
||||
@@ -767,7 +786,7 @@ void swift::ide::printModuleInterface(
|
||||
// is the underlying module of, transitively.
|
||||
if (GroupNames.empty()) {
|
||||
printCrossImportOverlays(TargetMod, SwiftContext, Printer,
|
||||
AdjustedOptions, PrintSynthesizedExtensions);
|
||||
Options, PrintSynthesizedExtensions);
|
||||
}
|
||||
}
|
||||
// Flush pending newlines.
|
||||
@@ -842,8 +861,8 @@ void swift::ide::printHeaderInterface(
|
||||
ASTContext &Ctx,
|
||||
ASTPrinter &Printer,
|
||||
const PrintOptions &Options) {
|
||||
auto AdjustedOptions = Options;
|
||||
adjustPrintOptions(AdjustedOptions);
|
||||
PrintOptions::OverrideScope OptionAdjustment(Options);
|
||||
adjustPrintOptions(OptionAdjustment);
|
||||
|
||||
auto &Importer = static_cast<ClangImporter &>(*Ctx.getClangModuleLoader());
|
||||
auto &ClangSM = Importer.getClangASTContext().getSourceManager();
|
||||
@@ -874,11 +893,11 @@ void swift::ide::printHeaderInterface(
|
||||
// equivalent Swift decl may not be. E.g. a top-level function may be mapped
|
||||
// to a property accessor in Swift.
|
||||
D = getTopLevelDecl(D);
|
||||
if (!AdjustedOptions.shouldPrint(D)) {
|
||||
if (!Options.shouldPrint(D)) {
|
||||
Printer.callAvoidPrintDeclPost(D);
|
||||
continue;
|
||||
}
|
||||
if (D->print(Printer, AdjustedOptions))
|
||||
if (D->print(Printer, Options))
|
||||
Printer.printNewline();
|
||||
}
|
||||
Printer.forceNewlines();
|
||||
|
||||
Reference in New Issue
Block a user