[Dependency Scanning] Add serialization of optional imports to the JSON output

And to the corresponding graph data structure the output gets generated from
This commit is contained in:
Artem Chikin
2025-08-15 14:49:43 -07:00
parent bc30953c15
commit b14cbbb039
5 changed files with 57 additions and 35 deletions

View File

@@ -65,6 +65,9 @@ struct swiftscan_dependency_info_s {
/// The list of source import infos. /// The list of source import infos.
swiftscan_import_info_set_t *imports; swiftscan_import_info_set_t *imports;
/// The list of source optional import infos.
swiftscan_import_info_set_t *optional_imports;
/// Specific details of a particular kind of module. /// Specific details of a particular kind of module.
swiftscan_module_details_t details; swiftscan_module_details_t details;
}; };

View File

@@ -41,7 +41,7 @@ using llvm::BCVBR;
const unsigned char MODULE_DEPENDENCY_CACHE_FORMAT_SIGNATURE[] = {'I', 'M', 'D','C'}; const unsigned char MODULE_DEPENDENCY_CACHE_FORMAT_SIGNATURE[] = {'I', 'M', 'D','C'};
const unsigned MODULE_DEPENDENCY_CACHE_FORMAT_VERSION_MAJOR = 10; const unsigned MODULE_DEPENDENCY_CACHE_FORMAT_VERSION_MAJOR = 10;
/// Increment this on every change. /// Increment this on every change.
const unsigned MODULE_DEPENDENCY_CACHE_FORMAT_VERSION_MINOR = 3; const unsigned MODULE_DEPENDENCY_CACHE_FORMAT_VERSION_MINOR = 4;
/// Various identifiers in this format will rely on having their strings mapped /// Various identifiers in this format will rely on having their strings mapped
/// using this ID. /// using this ID.

View File

@@ -228,9 +228,13 @@ void writeLinkLibraries(llvm::raw_ostream &out,
void writeImportInfos(llvm::raw_ostream &out, void writeImportInfos(llvm::raw_ostream &out,
const swiftscan_import_info_set_t *imports, const swiftscan_import_info_set_t *imports,
unsigned indentLevel, bool trailingComma) { bool optional, unsigned indentLevel,
bool trailingComma) {
out.indent(indentLevel * 2); out.indent(indentLevel * 2);
out << "\"imports\": "; if (optional)
out << "\"optionalImports\": ";
else
out << "\"imports\": ";
out << "[\n"; out << "[\n";
for (size_t i = 0; i < imports->count; ++i) { for (size_t i = 0; i < imports->count; ++i) {
@@ -441,7 +445,9 @@ void writeJSON(llvm::raw_ostream &out,
/*trailingComma=*/true); /*trailingComma=*/true);
writeLinkLibraries(out, moduleInfo.link_libraries, writeLinkLibraries(out, moduleInfo.link_libraries,
3, /*trailingComma=*/true); 3, /*trailingComma=*/true);
writeImportInfos(out, moduleInfo.imports, writeImportInfos(out, moduleInfo.imports, /*optional*/ false,
3, /*trailingComma=*/true);
writeImportInfos(out, moduleInfo.optional_imports, /*optional*/ true,
3, /*trailingComma=*/true); 3, /*trailingComma=*/true);
} }
// Swift and Clang-specific details. // Swift and Clang-specific details.

View File

@@ -922,37 +922,44 @@ static swiftscan_dependency_graph_t generateFullDependencyGraph(
} }
moduleInfo->link_libraries = linkLibrarySet; moduleInfo->link_libraries = linkLibrarySet;
// Create source import infos set for this module auto createImportSetInfo = [&](ArrayRef<ScannerImportStatementInfo> imports)
auto imports = moduleDependencyInfo.getModuleImports(); -> swiftscan_import_info_set_t * {
swiftscan_import_info_set_t *importInfoSet = swiftscan_import_info_set_t *importInfoSet =
new swiftscan_import_info_set_t; new swiftscan_import_info_set_t;
importInfoSet->count = imports.size(); importInfoSet->count = imports.size();
importInfoSet->imports = new swiftscan_import_info_t[importInfoSet->count]; importInfoSet->imports =
for (size_t i = 0; i < imports.size(); ++i) { new swiftscan_import_info_t[importInfoSet->count];
const auto &ii = imports[i]; for (size_t i = 0; i < imports.size(); ++i) {
swiftscan_import_info_s *iInfo = new swiftscan_import_info_s; const auto &ii = imports[i];
iInfo->import_identifier = create_clone(ii.importIdentifier.c_str()); swiftscan_import_info_s *iInfo = new swiftscan_import_info_s;
iInfo->access_level = iInfo->import_identifier = create_clone(ii.importIdentifier.c_str());
static_cast<swiftscan_access_level_t>(ii.accessLevel); iInfo->access_level =
static_cast<swiftscan_access_level_t>(ii.accessLevel);
const auto &sourceLocations = ii.importLocations; const auto &sourceLocations = ii.importLocations;
swiftscan_source_location_set_t *sourceLocSet = swiftscan_source_location_set_t *sourceLocSet =
new swiftscan_source_location_set_t; new swiftscan_source_location_set_t;
sourceLocSet->count = sourceLocations.size(); sourceLocSet->count = sourceLocations.size();
sourceLocSet->source_locations = sourceLocSet->source_locations =
new swiftscan_source_location_t[sourceLocSet->count]; new swiftscan_source_location_t[sourceLocSet->count];
for (size_t j = 0; j < sourceLocations.size(); ++j) { for (size_t j = 0; j < sourceLocations.size(); ++j) {
const auto &sl = sourceLocations[j]; const auto &sl = sourceLocations[j];
swiftscan_source_location_s *slInfo = new swiftscan_source_location_s; swiftscan_source_location_s *slInfo = new swiftscan_source_location_s;
slInfo->buffer_identifier = create_clone(sl.bufferIdentifier.c_str()); slInfo->buffer_identifier = create_clone(sl.bufferIdentifier.c_str());
slInfo->line_number = sl.lineNumber; slInfo->line_number = sl.lineNumber;
slInfo->column_number = sl.columnNumber; slInfo->column_number = sl.columnNumber;
sourceLocSet->source_locations[j] = slInfo; sourceLocSet->source_locations[j] = slInfo;
}
iInfo->source_locations = sourceLocSet;
importInfoSet->imports[i] = iInfo;
} }
iInfo->source_locations = sourceLocSet; return importInfoSet;
importInfoSet->imports[i] = iInfo; };
} // Create source import infos set for this module
moduleInfo->imports = importInfoSet; moduleInfo->imports =
createImportSetInfo(moduleDependencyInfo.getModuleImports());
moduleInfo->optional_imports =
createImportSetInfo(moduleDependencyInfo.getOptionalModuleImports());
} }
swiftscan_dependency_graph_t result = new swiftscan_dependency_graph_s; swiftscan_dependency_graph_t result = new swiftscan_dependency_graph_s;

View File

@@ -40,10 +40,16 @@
// CHECK-IMPORTS-NEXT: "importLocations": [ // CHECK-IMPORTS-NEXT: "importLocations": [
// CHECK-IMPORTS-NEXT: { // CHECK-IMPORTS-NEXT: {
// CHECK-IMPORTS-NEXT: "bufferIdentifier": "{{.*}}serialized_imports.swift", // CHECK-IMPORTS-NEXT: "bufferIdentifier": "{{.*}}serialized_imports.swift",
// CHECK-IMPORTS-NEXT: "linuNumber": 49, // CHECK-IMPORTS-NEXT: "linuNumber": 54,
// CHECK-IMPORTS-NEXT: "columnNumber": 8 // CHECK-IMPORTS-NEXT: "columnNumber": 8
// CHECK-IMPORTS-NEXT: } // CHECK-IMPORTS-NEXT: }
// CHECK-IMPORTS-NEXT: ]
// CHECK-IMPORTS: "optionalImports": [
// CHECK-IMPORTS-NEXT: {
// CHECK-IMPORTS-NEXT: "identifier": "E_Private",
// CHECK-IMPORTS-NEXT: "accessLevel": "public"
// CHECK-IMPORTS-NEXT: } // CHECK-IMPORTS-NEXT: }
// CHECK-IMPORTS-NEXT: ],
import E import E
import E.Private