[Dependency Scanning] Add a field of source-imported dependencies

For the main source module, provide info on which dependencies are directly imported into the user program, explicitly ('import' statement) or implicitly (e.g. stdlib). Thist list does not include Swift overlay dependencies, cross-import dependencies, bridging header dependencies.
This commit is contained in:
Artem Chikin
2025-04-18 11:22:35 -07:00
parent e9b21cff7d
commit f0518f64ec
12 changed files with 82 additions and 0 deletions

View File

@@ -212,6 +212,10 @@ SWIFTSCAN_PUBLIC swiftscan_string_set_t *
swiftscan_swift_textual_detail_get_swift_overlay_dependencies(
swiftscan_module_details_t details);
SWIFTSCAN_PUBLIC swiftscan_string_set_t *
swiftscan_swift_textual_detail_get_swift_source_import_module_dependencies(
swiftscan_module_details_t details);
SWIFTSCAN_PUBLIC swiftscan_string_ref_t
swiftscan_swift_textual_detail_get_cas_fs_root_id(
swiftscan_module_details_t details);

View File

@@ -102,6 +102,9 @@ typedef struct {
/// Clang module dependencies
swiftscan_string_set_t *swift_overlay_module_dependencies;
/// Directly-imported in source module dependencies
swiftscan_string_set_t *source_import_module_dependencies;
/// Options to the compile command required to build this module interface
swiftscan_string_set_t *command_line;

View File

@@ -424,6 +424,9 @@ void writeJSON(llvm::raw_ostream &out,
bool hasOverlayDependencies =
swiftTextualDeps->swift_overlay_module_dependencies &&
swiftTextualDeps->swift_overlay_module_dependencies->count > 0;
bool hasSourceImportedDependencies =
swiftTextualDeps->source_import_module_dependencies &&
swiftTextualDeps->source_import_module_dependencies->count > 0;
bool commaAfterBridgingHeaderPath = hasOverlayDependencies;
bool commaAfterFramework =
hasBridgingHeader || commaAfterBridgingHeaderPath;
@@ -448,6 +451,11 @@ void writeJSON(llvm::raw_ostream &out,
/*trailingComma=*/true);
writeMacroDependencies(out, swiftTextualDeps->macro_dependencies, 5,
/*trailingComma=*/true);
if (hasSourceImportedDependencies) {
writeDependencies(out, swiftTextualDeps->source_import_module_dependencies,
"sourceImportedDependencies", 5,
/*trailingComma=*/true);
}
writeJSONSingleField(out, "isFramework", swiftTextualDeps->is_framework,
5, commaAfterFramework);
/// Bridging header and its source file dependencies, if any.

View File

@@ -222,6 +222,7 @@ static swiftscan_dependency_graph_t generateHollowDiagnosticOutput(
c_string_utils::create_empty_set(),
c_string_utils::create_empty_set(),
c_string_utils::create_empty_set(),
c_string_utils::create_empty_set(),
c_string_utils::create_null(),
false,
false,

View File

@@ -786,6 +786,7 @@ generateFullDependencyGraph(const CompilerInstance &instance,
swiftTextualDeps->textualModuleDetails.bridgingSourceFiles),
create_set(clangHeaderDependencyNames),
create_set(bridgedOverlayDependencyNames),
/*sourceImportedDependencies*/ create_set({}),
create_set(swiftTextualDeps->textualModuleDetails.buildCommandLine),
/*bridgingHeaderBuildCommand*/ create_set({}),
create_clone(swiftTextualDeps->contextHash.c_str()),
@@ -813,12 +814,25 @@ generateFullDependencyGraph(const CompilerInstance &instance,
bridgeDependencyIDs(swiftSourceDeps->swiftOverlayDependencies,
bridgedOverlayDependencyNames);
// Create a set of directly-source-imported dependencies
std::vector<ModuleDependencyID> sourceImportDependencies;
std::copy(swiftSourceDeps->importedSwiftModules.begin(),
swiftSourceDeps->importedSwiftModules.end(),
std::back_inserter(sourceImportDependencies));
std::copy(swiftSourceDeps->importedClangModules.begin(),
swiftSourceDeps->importedClangModules.end(),
std::back_inserter(sourceImportDependencies));
std::vector<std::string> bridgedSourceImportedDependencyNames;
bridgeDependencyIDs(sourceImportDependencies,
bridgedSourceImportedDependencyNames);
details->swift_textual_details = {
moduleInterfacePath, create_empty_set(), bridgingHeaderPath,
create_set(
swiftSourceDeps->textualModuleDetails.bridgingSourceFiles),
create_set(clangHeaderDependencyNames),
create_set(bridgedOverlayDependencyNames),
create_set(bridgedSourceImportedDependencyNames),
create_set(swiftSourceDeps->textualModuleDetails.buildCommandLine),
create_set(swiftSourceDeps->bridgingHeaderBuildCommandLine),
/*contextHash*/

View File

@@ -61,6 +61,8 @@ void swiftscan_dependency_info_details_dispose(
details_impl->swift_textual_details.bridging_module_dependencies);
swiftscan_string_set_dispose(
details_impl->swift_textual_details.swift_overlay_module_dependencies);
swiftscan_string_set_dispose(
details_impl->swift_textual_details.source_import_module_dependencies);
swiftscan_string_set_dispose(
details_impl->swift_textual_details.command_line);
swiftscan_string_dispose(details_impl->swift_textual_details.context_hash);
@@ -326,6 +328,11 @@ swiftscan_string_set_t *swiftscan_swift_textual_detail_get_swift_overlay_depende
return details->swift_textual_details.swift_overlay_module_dependencies;
}
swiftscan_string_set_t *swiftscan_swift_textual_detail_get_swift_source_import_module_dependencies(
swiftscan_module_details_t details) {
return details->swift_textual_details.source_import_module_dependencies;
}
swiftscan_string_ref_t swiftscan_swift_textual_detail_get_cas_fs_root_id(
swiftscan_module_details_t details) {
return details->swift_textual_details.cas_fs_root_id;

View File

@@ -22,6 +22,7 @@ swiftscan_swift_textual_detail_get_bridging_pch_command_line
swiftscan_swift_textual_detail_get_context_hash
swiftscan_swift_textual_detail_get_is_framework
swiftscan_swift_textual_detail_get_swift_overlay_dependencies
swiftscan_swift_textual_detail_get_swift_source_import_module_dependencies
swiftscan_swift_textual_detail_get_cas_fs_root_id
swiftscan_swift_textual_detail_get_module_cache_key
swiftscan_swift_textual_detail_get_user_module_version

View File

@@ -16,6 +16,9 @@ import ImportsMacroSpecificClangModule
// CHECK-DAG: "swift": "Swift"
// CHECK-DAG: "swift": "SwiftOnoneSupport"
// Additional occurence in source-imported dependencies field
//CHECK: "swift": "ImportsMacroSpecificClangModule"
//CHECK: "swift": "ImportsMacroSpecificClangModule"
//CHECK-NEXT: },
//CHECK-NEXT: {

View File

@@ -16,6 +16,9 @@ import TestModule
// CHECK-DAG: "swift": "Swift"
// CHECK-DAG: "swift": "SwiftOnoneSupport"
// Additional occurence in source-imported dependencies field
// CHECK: "swift": "TestModule"
// CHECK: "swift": "TestModule"
// CHECK-NEXT: },
// CHECK-NEXT: {

View File

@@ -17,6 +17,9 @@ func foo() {
// CHECK-DAG: "swift": "Swift"
// CHECK-DAG: "swift": "SwiftOnoneSupport"
// Additional occurence in source-imported dependencies field
// CHECK: "swift": "ExtensionAvailable"
// CHECK: "swift": "ExtensionAvailable"
// CHECK-NEXT: },
// CHECK-NEXT: {

View File

@@ -15,8 +15,15 @@
import Foo
// Appears as a dependency of the main module
// CHECK: "swiftPrebuiltExternal": "Foo"
// Appears as, specifically, a source-imported dependency of the main module
// CHECK: "swiftPrebuiltExternal": "Foo"
// Actual node in the dependency graph for module 'Foo'
// CHECK: "swiftPrebuiltExternal": "Foo"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "modulePath":

View File

@@ -0,0 +1,28 @@
// RUN: %empty-directory(%t)
// RUN: %empty-directory(%t/module-cache)
// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import
// Check the contents of the JSON output
// RUN: %validate-json %t/deps.json | %FileCheck %s
// Ensure that round-trip serialization does not affect result
// RUN: %target-swift-frontend -scan-dependencies -test-dependency-scan-cache-serialization -module-cache-path %t/module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -disable-implicit-concurrency-module-import -disable-implicit-string-processing-module-import
// RUN: %validate-json %t/deps.json | %FileCheck %s
// REQUIRES: executable_test
// REQUIRES: objc_interop
import C
// CHECK: "sourceImportedDependencies": [
// CHECK-NEXT: {
// CHECK-DAG: "swift": "Swift"
// CHECK-DAG: "swift": "SwiftOnoneSupport"
// CHECK-DAG: "clang": "C"
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK: "swiftOverlayDependencies": [
// CHECK-NEXT: {
// CHECK-NEXT: "swift": "A"
// CHECK-NEXT: }
// CHECK-NEXT: ]