Skip to content

Commit 41120da

Browse files
[SymbolGraphGen] add flags to filter platforms out of availability metadata (#80778)
* add option to filter availability metadata in symbol graphs * filter out platform-specific availability in the stdlib docs rdar://144379124
1 parent fed5b26 commit 41120da

File tree

7 files changed

+155
-3
lines changed

7 files changed

+155
-3
lines changed

Diff for: include/swift/Option/Options.td

+20
Original file line numberDiff line numberDiff line change
@@ -1764,6 +1764,16 @@ def symbol_graph_minimum_access_level: Separate<["-"], "symbol-graph-minimum-acc
17641764
HelpText<"Include symbols with this access level or more when emitting a symbol graph">,
17651765
MetaVarName<"<level>">;
17661766

1767+
def symbol_graph_allow_availability_platforms: Separate<["-"], "symbol-graph-allow-availability-platforms">,
1768+
Flags<[FrontendOption, NoInteractiveOption, SupplementaryOutput, HelpHidden]>,
1769+
HelpText<"Restrict availability metadata to the given platforms, e.g. 'macOS,Swift'">,
1770+
MetaVarName<"<platforms>">;
1771+
1772+
def symbol_graph_block_availability_platforms: Separate<["-"], "symbol-graph-block-availability-platforms">,
1773+
Flags<[FrontendOption, NoInteractiveOption, SupplementaryOutput, HelpHidden]>,
1774+
HelpText<"Remove the given platforms from symbol graph availability metadata, e.g. 'macOS,Swift'">,
1775+
MetaVarName<"<platforms>">;
1776+
17671777
def pretty_print: Flag<["-"], "pretty-print">,
17681778
Flags<[SwiftSymbolGraphExtractOption]>,
17691779
HelpText<"Pretty-print the output JSON">;
@@ -1778,6 +1788,16 @@ def omit_extension_block_symbols: Flag<["-"], "omit-extension-block-symbols">,
17781788
NoInteractiveOption, SupplementaryOutput, HelpHidden]>,
17791789
HelpText<"Directly associate members and conformances with the extended nominal when generating symbol graphs instead of emitting 'swift.extension' symbols for extensions to external types">;
17801790

1791+
def allow_availability_platforms: Separate<["-"], "allow-availability-platforms">,
1792+
Flags<[SwiftSymbolGraphExtractOption]>,
1793+
HelpText<"Restrict availability metadata to the given platforms, e.g. 'macOS,Swift'">,
1794+
MetaVarName<"<platforms>">;
1795+
1796+
def block_availability_platforms: Separate<["-"], "block-availability-platforms">,
1797+
Flags<[SwiftSymbolGraphExtractOption]>,
1798+
HelpText<"Remove the given platforms from symbol graph availability metadata, e.g. 'macOS,Swift'">,
1799+
MetaVarName<"<platforms>">;
1800+
17811801
// swift-synthesize-interface-only options
17821802
def include_submodules : Flag<["-"], "include-submodules">,
17831803
Flags<[NoDriverOption, SwiftSynthesizeInterfaceOption]>,

Diff for: include/swift/SymbolGraphGen/SymbolGraphOptions.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#include "llvm/TargetParser/Triple.h"
1413
#include "llvm/ADT/ArrayRef.h"
14+
#include "llvm/ADT/DenseSet.h"
15+
#include "llvm/TargetParser/Triple.h"
1516

1617
#include "swift/AST/AttrKind.h"
1718

@@ -69,6 +70,13 @@ struct SymbolGraphOptions {
6970
/// If this has a value specifies an explicit allow list of reexported module
7071
/// names that should be included symbol graph.
7172
std::optional<llvm::ArrayRef<StringRef>> AllowedReexportedModules = {};
73+
74+
/// If set, a list of availability platforms to restrict (or block) when
75+
/// rendering symbol graphs.
76+
std::optional<llvm::DenseSet<StringRef>> AvailabilityPlatforms = {};
77+
78+
/// Whether `AvailabilityPlatforms` is an allow list or a block list.
79+
bool AvailabilityIsBlockList = false;
7280
};
7381

7482
} // end namespace symbolgraphgen

Diff for: lib/DriverTool/swift_symbolgraph_extract_main.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,25 @@ int swift_symbolgraph_extract_main(ArrayRef<const char *> Args,
203203
.Default(AccessLevel::Public);
204204
}
205205

206+
if (auto *A = ParsedArgs.getLastArg(OPT_allow_availability_platforms)) {
207+
llvm::SmallVector<StringRef> AvailabilityPlatforms;
208+
StringRef(A->getValue())
209+
.split(AvailabilityPlatforms, ',', /*MaxSplits*/ -1,
210+
/*KeepEmpty*/ false);
211+
Options.AvailabilityPlatforms = llvm::DenseSet<StringRef>(
212+
AvailabilityPlatforms.begin(), AvailabilityPlatforms.end());
213+
Options.AvailabilityIsBlockList = false;
214+
} else if (auto *A =
215+
ParsedArgs.getLastArg(OPT_block_availability_platforms)) {
216+
llvm::SmallVector<StringRef> AvailabilityPlatforms;
217+
StringRef(A->getValue())
218+
.split(AvailabilityPlatforms, ',', /*MaxSplits*/ -1,
219+
/*KeepEmpty*/ false);
220+
Options.AvailabilityPlatforms = llvm::DenseSet<StringRef>(
221+
AvailabilityPlatforms.begin(), AvailabilityPlatforms.end());
222+
Options.AvailabilityIsBlockList = true;
223+
}
224+
206225
Invocation.getLangOptions().setCxxInteropFromArgs(ParsedArgs, Diags);
207226

208227
std::string InstanceSetupError;

Diff for: lib/Frontend/CompilerInvocation.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -2215,6 +2215,25 @@ static void ParseSymbolGraphArgs(symbolgraphgen::SymbolGraphOptions &Opts,
22152215
Opts.MinimumAccessLevel = AccessLevel::Public;
22162216
}
22172217

2218+
if (auto *A = Args.getLastArg(OPT_symbol_graph_allow_availability_platforms)) {
2219+
llvm::SmallVector<StringRef> AvailabilityPlatforms;
2220+
StringRef(A->getValue())
2221+
.split(AvailabilityPlatforms, ',', /*MaxSplits*/ -1,
2222+
/*KeepEmpty*/ false);
2223+
Opts.AvailabilityPlatforms = llvm::DenseSet<StringRef>(
2224+
AvailabilityPlatforms.begin(), AvailabilityPlatforms.end());
2225+
Opts.AvailabilityIsBlockList = false;
2226+
} else if (auto *A = Args.getLastArg(
2227+
OPT_symbol_graph_block_availability_platforms)) {
2228+
llvm::SmallVector<StringRef> AvailabilityPlatforms;
2229+
StringRef(A->getValue())
2230+
.split(AvailabilityPlatforms, ',', /*MaxSplits*/ -1,
2231+
/*KeepEmpty*/ false);
2232+
Opts.AvailabilityPlatforms = llvm::DenseSet<StringRef>(
2233+
AvailabilityPlatforms.begin(), AvailabilityPlatforms.end());
2234+
Opts.AvailabilityIsBlockList = true;
2235+
}
2236+
22182237
// default values for generating symbol graphs during a build
22192238
Opts.PrettyPrint = false;
22202239
Opts.EmitSynthesizedMembers = true;

Diff for: lib/SymbolGraphGen/Symbol.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,26 @@ void Symbol::serializeAvailabilityMixin(llvm::json::OStream &OS) const {
697697
llvm::StringMap<Availability> Availabilities;
698698
getInheritedAvailabilities(D, Availabilities);
699699

700+
// If we were asked to filter the availability platforms for the output graph,
701+
// perform that filtering here.
702+
if (Graph->Walker.Options.AvailabilityPlatforms) {
703+
auto AvailabilityPlatforms =
704+
Graph->Walker.Options.AvailabilityPlatforms.value();
705+
if (Graph->Walker.Options.AvailabilityIsBlockList) {
706+
for (const auto Availability : Availabilities.keys()) {
707+
if (Availability != "*" && AvailabilityPlatforms.contains(Availability)) {
708+
Availabilities.erase(Availability);
709+
}
710+
}
711+
} else {
712+
for (const auto Availability : Availabilities.keys()) {
713+
if (Availability != "*" && !AvailabilityPlatforms.contains(Availability)) {
714+
Availabilities.erase(Availability);
715+
}
716+
}
717+
}
718+
}
719+
700720
if (Availabilities.empty()) {
701721
return;
702722
}

Diff for: stdlib/cmake/modules/AddSwiftStdlib.cmake

+5-2
Original file line numberDiff line numberDiff line change
@@ -932,11 +932,14 @@ function(add_swift_target_library_single target name)
932932
endif()
933933
endif()
934934

935-
# FIXME: swiftDarwin currently trips an assertion in SymbolGraphGen
936-
if (SWIFTLIB_IS_STDLIB AND SWIFT_STDLIB_BUILD_SYMBOL_GRAPHS AND NOT ${name} STREQUAL "swiftDarwin")
935+
# FIXME: swiftDarwin and swiftDifferentiationUnittest currently trip an assertion in SymbolGraphGen
936+
if (SWIFTLIB_IS_STDLIB AND SWIFT_STDLIB_BUILD_SYMBOL_GRAPHS AND NOT ${name} STREQUAL "swiftDarwin"
937+
AND NOT ${name} STREQUAL "swiftDifferentiationUnittest")
937938
list(APPEND SWIFTLIB_SINGLE_SWIFT_COMPILE_FLAGS "-Xfrontend;-emit-symbol-graph")
938939
list(APPEND SWIFTLIB_SINGLE_SWIFT_COMPILE_FLAGS
939940
"-Xfrontend;-emit-symbol-graph-dir;-Xfrontend;${out_lib_dir}/symbol-graph/${VARIANT_NAME}")
941+
list(APPEND SWIFTLIB_SINGLE_SWIFT_COMPILE_FLAGS
942+
"-Xfrontend;-symbol-graph-allow-availability-platforms;-Xfrontend;Swift")
940943
endif()
941944

942945
if(MODULE)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend %s -module-name AvailabilityFilter -emit-module -emit-module-path %t/AvailabilityFilter.swiftmodule -emit-symbol-graph -emit-symbol-graph-dir %t/
3+
// RUN: %FileCheck %s --input-file %t/AvailabilityFilter.symbols.json --check-prefix DEFAULT
4+
5+
// RUN: %target-swift-symbolgraph-extract -module-name AvailabilityFilter -I %t -pretty-print -output-dir %t
6+
// RUN: %FileCheck %s --input-file %t/AvailabilityFilter.symbols.json --check-prefix DEFAULT
7+
8+
// Now checking the allowlist behavior...
9+
10+
// RUN: %empty-directory(%t)
11+
// RUN: %target-swift-frontend %s -module-name AvailabilityFilter -emit-module -emit-module-path %t/AvailabilityFilter.swiftmodule -emit-symbol-graph -emit-symbol-graph-dir %t/ -symbol-graph-allow-availability-platforms macOS,iOS
12+
// RUN: %FileCheck %s --input-file %t/AvailabilityFilter.symbols.json --check-prefix ALLOWLIST
13+
14+
// RUN: %target-swift-symbolgraph-extract -module-name AvailabilityFilter -I %t -pretty-print -output-dir %t -allow-availability-platforms macOS,iOS
15+
// RUN: %FileCheck %s --input-file %t/AvailabilityFilter.symbols.json --check-prefix ALLOWLIST
16+
17+
// Now checking the blocklist behavior...
18+
19+
// RUN: %empty-directory(%t)
20+
// RUN: %target-swift-frontend %s -module-name AvailabilityFilter -emit-module -emit-module-path %t/AvailabilityFilter.swiftmodule -emit-symbol-graph -emit-symbol-graph-dir %t/ -symbol-graph-block-availability-platforms macOS,iOS
21+
// RUN: %FileCheck %s --input-file %t/AvailabilityFilter.symbols.json --check-prefix BLOCKLIST
22+
23+
// RUN: %target-swift-symbolgraph-extract -module-name AvailabilityFilter -I %t -pretty-print -output-dir %t -block-availability-platforms macOS,iOS
24+
// RUN: %FileCheck %s --input-file %t/AvailabilityFilter.symbols.json --check-prefix BLOCKLIST
25+
26+
// Now test to ensure an empty allow list filters out all availability...
27+
28+
// RUN: %empty-directory(%t)
29+
// RUN: %target-swift-frontend %s -module-name AvailabilityFilter -emit-module -emit-module-path %t/AvailabilityFilter.swiftmodule -emit-symbol-graph -emit-symbol-graph-dir %t/ -symbol-graph-allow-availability-platforms ""
30+
// RUN: %FileCheck %s --input-file %t/AvailabilityFilter.symbols.json --check-prefix EMPTY
31+
32+
// RUN: %target-swift-symbolgraph-extract -module-name AvailabilityFilter -I %t -pretty-print -output-dir %t -allow-availability-platforms ""
33+
// RUN: %FileCheck %s --input-file %t/AvailabilityFilter.symbols.json --check-prefix EMPTY
34+
35+
// REQUIRES: OS=macosx
36+
37+
@available(macOS 11.0, iOS 15.0, watchOS 15.0, *)
38+
public struct S {}
39+
40+
/// Ensure that regardless of platforms being removed, that universal availability info,
41+
/// like unconditional deprecation, still lands in the symbol graph.
42+
@available(*, deprecated)
43+
public class C {}
44+
45+
// DEFAULT-DAG: macOS
46+
// DEFAULT-DAG: iOS
47+
// DEFAULT-DAG: watchOS
48+
// DEFAULT-DAG: "isUnconditionallyDeprecated":{{ ?}}true
49+
50+
// ALLOWLIST-NOT: watchOS
51+
// ALLOWLIST-DAG: macOS
52+
// ALLOWLIST-DAG: iOS
53+
// ALLOWLIST-DAG: "isUnconditionallyDeprecated":{{ ?}}true
54+
55+
// BLOCKLIST-NOT: macOS
56+
// BLOCKLIST-NOT: iOS
57+
// BLOCKLIST-DAG: watchOS
58+
// BLOCKLIST-DAG: "isUnconditionallyDeprecated":{{ ?}}true
59+
60+
// EMPTY-NOT: macOS
61+
// EMPTY-NOT: iOS
62+
// EMPTY-NOT: watchOS
63+
// EMPTY-DAG: "isUnconditionallyDeprecated":{{ ?}}true

0 commit comments

Comments
 (0)