Skip to content

Commit 33d7de6

Browse files
committed
[Dependency Scanning] Add libSwiftScan API and JSON output for source import information
1 parent 9b3fabd commit 33d7de6

File tree

7 files changed

+220
-16
lines changed

7 files changed

+220
-16
lines changed

include/swift-c/DependencyScan/DependencyScan.h

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
/// SWIFTSCAN_VERSION_MINOR should increase when there are API additions.
2626
/// SWIFTSCAN_VERSION_MAJOR is intended for "major" source/ABI breaking changes.
2727
#define SWIFTSCAN_VERSION_MAJOR 2
28-
#define SWIFTSCAN_VERSION_MINOR 1
28+
#define SWIFTSCAN_VERSION_MINOR 2
2929

3030
SWIFTSCAN_BEGIN_DECLS
3131

@@ -49,6 +49,9 @@ typedef struct swiftscan_dependency_info_s *swiftscan_dependency_info_t;
4949
/// Opaque container to a link library info.
5050
typedef struct swiftscan_link_library_info_s *swiftscan_link_library_info_t;
5151

52+
/// Opaque container to an import info.
53+
typedef struct swiftscan_import_info_s *swiftscan_import_info_t;
54+
5255
/// Opaque container to a macro dependency.
5356
typedef struct swiftscan_macro_dependency_s *swiftscan_macro_dependency_t;
5457

@@ -76,6 +79,18 @@ typedef struct {
7679
size_t count;
7780
} swiftscan_link_library_set_t;
7881

82+
/// Set of details about source imports
83+
typedef struct {
84+
swiftscan_import_info_t *imports;
85+
size_t count;
86+
} swiftscan_import_info_set_t;
87+
88+
/// Set of source location infos
89+
typedef struct {
90+
swiftscan_source_location_t *source_locations;
91+
size_t count;
92+
} swiftscan_source_location_set_t;
93+
7994
/// Set of macro dependency
8095
typedef struct {
8196
swiftscan_macro_dependency_t *macro_dependencies;
@@ -89,6 +104,16 @@ typedef enum {
89104
SWIFTSCAN_DIAGNOSTIC_SEVERITY_REMARK = 3
90105
} swiftscan_diagnostic_severity_t;
91106

107+
// Must maintain consistency with swift::AccessLevel
108+
typedef enum {
109+
SWIFTSCAN_ACCESS_LEVEL_PRIVATE = 0,
110+
SWIFTSCAN_ACCESS_LEVEL_FILEPRIVATE = 1,
111+
SWIFTSCAN_ACCESS_LEVEL_INTERNAL = 2,
112+
SWIFTSCAN_ACCESS_LEVEL_PACKAGE = 3,
113+
SWIFTSCAN_ACCESS_LEVEL_PUBLIC = 4,
114+
SWIFTSCAN_ACCESS_LEVEL_OPEN = 5,
115+
} swiftscan_access_level_t;
116+
92117
typedef struct {
93118
swiftscan_diagnostic_info_t *diagnostics;
94119
size_t count;
@@ -148,10 +173,23 @@ swiftscan_module_info_get_direct_dependencies(swiftscan_dependency_info_t info);
148173
SWIFTSCAN_PUBLIC swiftscan_link_library_set_t *
149174
swiftscan_module_info_get_link_libraries(swiftscan_dependency_info_t info);
150175

176+
SWIFTSCAN_PUBLIC swiftscan_import_info_set_t *
177+
swiftscan_module_info_get_imports(swiftscan_dependency_info_t info);
178+
151179
SWIFTSCAN_PUBLIC swiftscan_module_details_t
152180
swiftscan_module_info_get_details(swiftscan_dependency_info_t info);
153181

154-
//=== Link Library Info Functions ------------------------------------===//
182+
//=== Import Details Functions -------------------------------------------===//
183+
SWIFTSCAN_PUBLIC swiftscan_source_location_set_t *
184+
swiftscan_import_info_get_source_locations(swiftscan_import_info_t info);
185+
186+
SWIFTSCAN_PUBLIC swiftscan_string_ref_t
187+
swiftscan_import_info_get_identifier(swiftscan_import_info_t info);
188+
189+
SWIFTSCAN_PUBLIC swiftscan_access_level_t
190+
swiftscan_import_info_get_access_level(swiftscan_import_info_t info);
191+
192+
//=== Link Library Info Functions ----------------------------------------===//
155193
SWIFTSCAN_PUBLIC swiftscan_string_ref_t
156194
swiftscan_link_library_info_get_link_name(
157195
swiftscan_link_library_info_t info);

include/swift/DependencyScan/DependencyScanImpl.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ struct swiftscan_dependency_info_s {
6363
/// The list of link libraries for this module.
6464
swiftscan_link_library_set_t *link_libraries;
6565

66+
/// The list of source import infos.
67+
swiftscan_import_info_set_t *imports;
68+
6669
/// Specific details of a particular kind of module.
6770
swiftscan_module_details_t details;
6871
};
@@ -74,10 +77,16 @@ struct swiftscan_link_library_info_s {
7477
bool forceLoad;
7578
};
7679

80+
struct swiftscan_import_info_s {
81+
swiftscan_string_ref_t import_identifier;
82+
swiftscan_source_location_set_t *source_locations;
83+
swiftscan_access_level_t access_level;
84+
};
85+
7786
struct swiftscan_macro_dependency_s {
78-
swiftscan_string_ref_t moduleName;
79-
swiftscan_string_ref_t libraryPath;
80-
swiftscan_string_ref_t executablePath;
87+
swiftscan_string_ref_t module_name;
88+
swiftscan_string_ref_t library_path;
89+
swiftscan_string_ref_t executable_path;
8190
};
8291

8392
/// Swift modules to be built from a module interface, may have a bridging

lib/DependencyScan/DependencyScanJSON.cpp

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ void writeJSONValue(llvm::raw_ostream &out, bool value, unsigned indentLevel) {
7777
out.write_escaped(value ? "true" : "false");
7878
}
7979

80+
/// Write a boolean value as JSON.
81+
void writeJSONValue(llvm::raw_ostream &out, uint32_t value, unsigned indentLevel) {
82+
out.write_escaped(std::to_string(value));
83+
}
84+
8085
/// Write a JSON array.
8186
template <typename T>
8287
void writeJSONValue(llvm::raw_ostream &out, ArrayRef<T> values,
@@ -226,6 +231,93 @@ void writeLinkLibraries(llvm::raw_ostream &out,
226231
out << "\n";
227232
}
228233

234+
void writeImportInfos(llvm::raw_ostream &out,
235+
const swiftscan_import_info_set_t *imports,
236+
unsigned indentLevel, bool trailingComma) {
237+
out.indent(indentLevel * 2);
238+
out << "\"imports\": ";
239+
out << "[\n";
240+
241+
for (size_t i = 0; i < imports->count; ++i) {
242+
const auto &iInfo = *imports->imports[i];
243+
out.indent((indentLevel + 1) * 2);
244+
out << "{\n";
245+
auto entryIndentLevel = ((indentLevel + 2) * 2);
246+
out.indent(entryIndentLevel);
247+
out << "\"identifier\": ";
248+
writeJSONValue(out, iInfo.import_identifier, indentLevel);
249+
out << ",\n";
250+
out.indent(entryIndentLevel);
251+
out << "\"accessLevel\": ";
252+
switch (iInfo.access_level) {
253+
case SWIFTSCAN_ACCESS_LEVEL_PRIVATE:
254+
writeJSONValue(out, StringRef("private"), entryIndentLevel);
255+
break;
256+
case SWIFTSCAN_ACCESS_LEVEL_FILEPRIVATE:
257+
writeJSONValue(out, StringRef("fileprivate"), entryIndentLevel);
258+
break;
259+
case SWIFTSCAN_ACCESS_LEVEL_INTERNAL:
260+
writeJSONValue(out, StringRef("internal"), entryIndentLevel);
261+
break;
262+
case SWIFTSCAN_ACCESS_LEVEL_PACKAGE:
263+
writeJSONValue(out, StringRef("package"), entryIndentLevel);
264+
break;
265+
case SWIFTSCAN_ACCESS_LEVEL_PUBLIC:
266+
writeJSONValue(out, StringRef("public"), entryIndentLevel);
267+
break;
268+
case SWIFTSCAN_ACCESS_LEVEL_OPEN:
269+
writeJSONValue(out, StringRef("open"), entryIndentLevel);
270+
break;
271+
}
272+
273+
if (iInfo.source_locations->count) {
274+
out << ",\n";
275+
out.indent(entryIndentLevel);
276+
out << "\"importLocations\": ";
277+
out << "[\n";
278+
auto slIndentLevel = ((entryIndentLevel + 4));
279+
for (size_t i = 0; i < iInfo.source_locations->count; ++i) {
280+
out.indent(entryIndentLevel + 2);
281+
out << "{\n";
282+
const auto &sl = *iInfo.source_locations->source_locations[i];
283+
out.indent(slIndentLevel);
284+
out << "\"bufferIdentifier\": ";
285+
writeJSONValue(out, sl.buffer_identifier, indentLevel);
286+
out << ",\n";
287+
out.indent(slIndentLevel);
288+
out << "\"linuNumber\": ";
289+
writeJSONValue(out, sl.line_number, indentLevel);
290+
out << ",\n";
291+
out.indent(slIndentLevel);
292+
out << "\"columnNumber\": ";
293+
writeJSONValue(out, sl.column_number, indentLevel);
294+
out << "\n";
295+
out.indent(entryIndentLevel + 2);
296+
out << "}";
297+
if (i != iInfo.source_locations->count - 1)
298+
out << ",";
299+
out << "\n";
300+
}
301+
out.indent(entryIndentLevel);
302+
out << "]\n";
303+
} else {
304+
out << "\n";
305+
}
306+
out.indent((indentLevel + 1) * 2);
307+
out << "}";
308+
if (i != imports->count - 1)
309+
out << ",";
310+
out << "\n";
311+
}
312+
313+
out.indent(indentLevel * 2);
314+
out << "]";
315+
316+
if (trailingComma)
317+
out << ",";
318+
out << "\n";
319+
}
320+
229321
static void
230322
writeMacroDependencies(llvm::raw_ostream &out,
231323
const swiftscan_macro_dependency_set_t *macro_deps,
@@ -243,15 +335,15 @@ writeMacroDependencies(llvm::raw_ostream &out,
243335
auto entryIndentLevel = ((indentLevel + 2) * 2);
244336
out.indent(entryIndentLevel);
245337
out << "\"moduleName\": ";
246-
writeJSONValue(out, macroInfo.moduleName, indentLevel);
338+
writeJSONValue(out, macroInfo.module_name, indentLevel);
247339
out << ",\n";
248340
out.indent(entryIndentLevel);
249341
out << "\"libraryPath\": ";
250-
writeJSONValue(out, macroInfo.libraryPath, entryIndentLevel);
342+
writeJSONValue(out, macroInfo.library_path, entryIndentLevel);
251343
out << ",\n";
252344
out.indent(entryIndentLevel);
253345
out << "\"executablePath\": ";
254-
writeJSONValue(out, macroInfo.executablePath, entryIndentLevel);
346+
writeJSONValue(out, macroInfo.executable_path, entryIndentLevel);
255347
out << "\n";
256348
out.indent((indentLevel + 1) * 2);
257349
out << "}";
@@ -368,6 +460,8 @@ void writeJSON(llvm::raw_ostream &out,
368460
/*trailingComma=*/true);
369461
writeLinkLibraries(out, moduleInfo.link_libraries,
370462
3, /*trailingComma=*/true);
463+
writeImportInfos(out, moduleInfo.imports,
464+
3, /*trailingComma=*/true);
371465
}
372466
// Swift and Clang-specific details.
373467
out.indent(3 * 2);

lib/DependencyScan/DependencyScanningTool.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,13 @@ static swiftscan_dependency_graph_t generateHollowDiagnosticOutput(
238238
hollowLinkLibrarySet->link_libraries = nullptr;
239239
hollowMainModuleInfo->link_libraries = hollowLinkLibrarySet;
240240

241+
// Empty Import set
242+
swiftscan_import_info_set_t *hollowImportInfoSet =
243+
new swiftscan_import_info_set_t;
244+
hollowImportInfoSet->count = 0;
245+
hollowImportInfoSet->imports = nullptr;
246+
hollowMainModuleInfo->imports = hollowImportInfoSet;
247+
241248
// Populate the diagnostic info
242249
hollowResult->diagnostics =
243250
mapCollectedDiagnosticsForOutput(&ScanDiagnosticConsumer);

lib/DependencyScan/ScanDependencies.cpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -747,10 +747,10 @@ static swiftscan_macro_dependency_set_t *createMacroDependencySet(
747747
unsigned SI = 0;
748748
for (auto &entry : macroDeps) {
749749
set->macro_dependencies[SI] = new swiftscan_macro_dependency_s;
750-
set->macro_dependencies[SI]->moduleName = create_clone(entry.first.c_str());
751-
set->macro_dependencies[SI]->libraryPath =
750+
set->macro_dependencies[SI]->module_name = create_clone(entry.first.c_str());
751+
set->macro_dependencies[SI]->library_path =
752752
create_clone(entry.second.LibraryPath.c_str());
753-
set->macro_dependencies[SI]->executablePath =
753+
set->macro_dependencies[SI]->executable_path =
754754
create_clone(entry.second.ExecutablePath.c_str());
755755
++ SI;
756756
}
@@ -976,6 +976,37 @@ generateFullDependencyGraph(const CompilerInstance &instance,
976976
linkLibrarySet->link_libraries[i] = llInfo;
977977
}
978978
moduleInfo->link_libraries = linkLibrarySet;
979+
980+
// Create source import infos set for this module
981+
auto imports = moduleDependencyInfo.getModuleImports();
982+
swiftscan_import_info_set_t *importInfoSet =
983+
new swiftscan_import_info_set_t;
984+
importInfoSet->count = imports.size();
985+
importInfoSet->imports = new swiftscan_import_info_t[importInfoSet->count];
986+
for (size_t i = 0; i < imports.size(); ++i) {
987+
const auto &ii = imports[i];
988+
swiftscan_import_info_s *iInfo = new swiftscan_import_info_s;
989+
iInfo->import_identifier = create_clone(ii.importIdentifier.c_str());
990+
iInfo->access_level = static_cast<swiftscan_access_level_t>(ii.accessLevel);
991+
992+
const auto &sourceLocations = ii.importLocations;
993+
swiftscan_source_location_set_t *sourceLocSet =
994+
new swiftscan_source_location_set_t;
995+
sourceLocSet->count = sourceLocations.size();
996+
sourceLocSet->source_locations =
997+
new swiftscan_source_location_t[sourceLocSet->count];
998+
for (size_t i = 0; i < sourceLocations.size(); ++i) {
999+
const auto &sl = sourceLocations[i];
1000+
swiftscan_source_location_s *slInfo = new swiftscan_source_location_s;
1001+
slInfo->buffer_identifier = create_clone(sl.bufferIdentifier.c_str());
1002+
slInfo->line_number = sl.lineNumber;
1003+
slInfo->column_number = sl.columnNumber;
1004+
sourceLocSet->source_locations[i] = slInfo;
1005+
}
1006+
iInfo->source_locations = sourceLocSet;
1007+
importInfoSet->imports[i] = iInfo;
1008+
}
1009+
moduleInfo->imports = importInfoSet;
9791010
}
9801011

9811012
swiftscan_dependency_graph_t result = new swiftscan_dependency_graph_s;

lib/Tooling/libSwiftScan/libSwiftScan.cpp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ void swiftscan_macro_dependency_dispose(
3535
return;
3636

3737
for (unsigned i = 0; i < macro->count; ++i) {
38-
swiftscan_string_dispose(macro->macro_dependencies[i]->moduleName);
39-
swiftscan_string_dispose(macro->macro_dependencies[i]->libraryPath);
40-
swiftscan_string_dispose(macro->macro_dependencies[i]->executablePath);
38+
swiftscan_string_dispose(macro->macro_dependencies[i]->module_name);
39+
swiftscan_string_dispose(macro->macro_dependencies[i]->library_path);
40+
swiftscan_string_dispose(macro->macro_dependencies[i]->executable_path);
4141
delete macro->macro_dependencies[i];
4242
}
4343
delete[] macro->macro_dependencies;
@@ -240,12 +240,17 @@ swiftscan_link_library_set_t *swiftscan_module_info_get_link_libraries(
240240
return info->link_libraries;
241241
}
242242

243+
swiftscan_import_info_set_t *swiftscan_module_info_get_imports(
244+
swiftscan_dependency_info_t info) {
245+
return info->imports;
246+
}
247+
243248
swiftscan_module_details_t
244249
swiftscan_module_info_get_details(swiftscan_dependency_info_t info) {
245250
return info->details;
246251
}
247252

248-
//=== Link Library Info query APIs -----------------------------------===//
253+
//=== Link Library Info query APIs ---------------------------------------===//
249254

250255
swiftscan_string_ref_t
251256
swiftscan_link_library_info_get_link_name(swiftscan_link_library_info_t info) {
@@ -267,7 +272,23 @@ swiftscan_link_library_info_get_should_force_load(swiftscan_link_library_info_t
267272
return info->forceLoad;
268273
}
269274

270-
//=== Swift Textual Module Details query APIs -----------------------------===//
275+
//=== Import Details Query APIs ------------------------------------------===//
276+
swiftscan_source_location_set_t *
277+
swiftscan_import_info_get_source_locations(swiftscan_import_info_t info) {
278+
return info->source_locations;
279+
}
280+
281+
swiftscan_string_ref_t
282+
swiftscan_import_info_get_identifier(swiftscan_import_info_t info) {
283+
return info->import_identifier;
284+
}
285+
286+
swiftscan_access_level_t
287+
swiftscan_import_info_get_access_level(swiftscan_import_info_t info) {
288+
return info->access_level;
289+
}
290+
291+
//=== Swift Textual Module Details query APIs ----------------------------===//
271292

272293
swiftscan_dependency_info_kind_t
273294
swiftscan_module_detail_get_kind(swiftscan_module_details_t details) {

lib/Tooling/libSwiftScan/libSwiftScan.exports

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@ swiftscan_link_library_info_get_link_name
55
swiftscan_link_library_info_get_is_static
66
swiftscan_link_library_info_get_is_framework
77
swiftscan_link_library_info_get_should_force_load
8+
swiftscan_import_info_get_source_locations
9+
swiftscan_import_info_get_identifier
10+
swiftscan_import_info_get_access_level
811
swiftscan_module_info_get_module_name
912
swiftscan_module_info_get_module_path
1013
swiftscan_module_info_get_source_files
1114
swiftscan_module_info_get_direct_dependencies
1215
swiftscan_module_info_get_link_libraries
16+
swiftscan_module_info_get_imports
1317
swiftscan_module_info_get_details
1418
swiftscan_module_detail_get_kind
1519
swiftscan_swift_textual_detail_get_module_interface_path

0 commit comments

Comments
 (0)