Skip to content

Commit 50c0dd8

Browse files
committed
[Dependency Scanning] Refactor 'createScanQueryContext' to directly return an error
1 parent b6760e7 commit 50c0dd8

File tree

4 files changed

+144
-96
lines changed

4 files changed

+144
-96
lines changed

include/swift/DependencyScan/DependencyScanningTool.h

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class DepScanInMemoryDiagnosticCollector;
3030

3131
struct ScanQueryContext {
3232
/// Primary CompilerInstance configured for this scanning action
33-
llvm::ErrorOr<std::unique_ptr<CompilerInstance>> ScanInstance;
33+
std::unique_ptr<CompilerInstance> ScanInstance;
3434
/// An thread-safe diagnostic consumer which collects all emitted
3535
/// diagnostics in the scan to be reporte via libSwiftScan API
3636
std::unique_ptr<DepScanInMemoryDiagnosticCollector> InMemoryDiagnosticCollector;
@@ -39,6 +39,22 @@ struct ScanQueryContext {
3939
/// 'ThreadSafeSerializedDiagnosticConsumer'
4040
std::unique_ptr<DiagnosticConsumer> SerializedDiagnosticConsumer;
4141

42+
ScanQueryContext(
43+
std::unique_ptr<CompilerInstance> ScanInstance,
44+
std::unique_ptr<DepScanInMemoryDiagnosticCollector>
45+
InMemoryDiagnosticCollector,
46+
std::unique_ptr<DiagnosticConsumer> SerializedDiagnosticConsumer)
47+
: ScanInstance(std::move(ScanInstance)),
48+
InMemoryDiagnosticCollector(std::move(InMemoryDiagnosticCollector)),
49+
SerializedDiagnosticConsumer(std::move(SerializedDiagnosticConsumer)) {}
50+
51+
ScanQueryContext(ScanQueryContext &&other)
52+
: ScanInstance(std::move(other.ScanInstance)),
53+
InMemoryDiagnosticCollector(
54+
std::move(other.InMemoryDiagnosticCollector)),
55+
SerializedDiagnosticConsumer(
56+
std::move(other.SerializedDiagnosticConsumer)) {}
57+
4258
~ScanQueryContext() {
4359
if (SerializedDiagnosticConsumer)
4460
SerializedDiagnosticConsumer->finishProcessing();
@@ -65,7 +81,7 @@ class ThreadSafeDiagnosticCollector : public DiagnosticConsumer {
6581
/// which may have been used to emit the diagnostic
6682
class DepScanInMemoryDiagnosticCollector
6783
: public ThreadSafeDiagnosticCollector {
68-
private:
84+
public:
6985
struct ScannerDiagnosticInfo {
7086
std::string Message;
7187
llvm::SourceMgr::DiagKind Severity;
@@ -81,7 +97,10 @@ class DepScanInMemoryDiagnosticCollector
8197
friend DependencyScanningTool;
8298
DepScanInMemoryDiagnosticCollector() {}
8399
void reset() { Diagnostics.clear(); }
84-
const std::vector<ScannerDiagnosticInfo> &getDiagnostics() const {
100+
std::vector<ScannerDiagnosticInfo> getDiagnostics() const {
101+
return Diagnostics;
102+
}
103+
const std::vector<ScannerDiagnosticInfo> &getDiagnosticsRef() const {
85104
return Diagnostics;
86105
}
87106
};
@@ -115,9 +134,10 @@ class DependencyScanningTool {
115134

116135
/// Using the specified invocation command, instantiate a CompilerInstance
117136
/// that will be used for this scan.
118-
ScanQueryContext
119-
createScanQueryContext(ArrayRef<const char *> Command,
120-
StringRef WorkingDirectory);
137+
llvm::ErrorOr<ScanQueryContext> createScanQueryContext(
138+
ArrayRef<const char *> Command, StringRef WorkingDirectory,
139+
std::vector<DepScanInMemoryDiagnosticCollector::ScannerDiagnosticInfo>
140+
&initializationDiagnostics);
121141

122142
private:
123143
/// Shared cache of module dependencies, re-used by individual full-scan queries
@@ -130,7 +150,9 @@ class DependencyScanningTool {
130150
llvm::StringSaver Saver;
131151
};
132152

133-
swiftscan_diagnostic_set_t *mapCollectedDiagnosticsForOutput(const DepScanInMemoryDiagnosticCollector *diagnosticCollector);
153+
swiftscan_diagnostic_set_t *mapCollectedDiagnosticsForOutput(
154+
ArrayRef<DepScanInMemoryDiagnosticCollector::ScannerDiagnosticInfo>
155+
diagnostics);
134156

135157
} // end namespace dependencies
136158
} // end namespace swift

lib/DependencyScan/DependencyScanningTool.cpp

Lines changed: 85 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "swift/Basic/LLVMInitialize.h"
1616
#include "swift/Basic/TargetInfo.h"
1717
#include "swift/Basic/ColorUtils.h"
18+
#include "swift/Basic/Defer.h"
1819
#include "swift/DependencyScan/DependencyScanningTool.h"
1920
#include "swift/DependencyScan/DependencyScanImpl.h"
2021
#include "swift/DependencyScan/SerializedModuleDependencyCacheFormat.h"
@@ -131,15 +132,15 @@ void DepScanInMemoryDiagnosticCollector::addDiagnostic(
131132
}
132133

133134
swiftscan_diagnostic_set_t *mapCollectedDiagnosticsForOutput(
134-
const DepScanInMemoryDiagnosticCollector *diagnosticCollector) {
135-
auto collectedDiagnostics = diagnosticCollector->getDiagnostics();
136-
auto numDiagnostics = collectedDiagnostics.size();
135+
ArrayRef<DepScanInMemoryDiagnosticCollector::ScannerDiagnosticInfo>
136+
diagnostics) {
137+
auto numDiagnostics = diagnostics.size();
137138
swiftscan_diagnostic_set_t *diagnosticOutput = new swiftscan_diagnostic_set_t;
138139
diagnosticOutput->count = numDiagnostics;
139140
diagnosticOutput->diagnostics =
140141
new swiftscan_diagnostic_info_t[numDiagnostics];
141142
for (size_t i = 0; i < numDiagnostics; ++i) {
142-
const auto &Diagnostic = collectedDiagnostics[i];
143+
const auto &Diagnostic = diagnostics[i];
143144
swiftscan_diagnostic_info_s *diagnosticInfo =
144145
new swiftscan_diagnostic_info_s;
145146
diagnosticInfo->message =
@@ -183,7 +184,8 @@ swiftscan_diagnostic_set_t *mapCollectedDiagnosticsForOutput(
183184
// module dependnecies but captures the diagnostics emitted during the attempted
184185
// scan query.
185186
static swiftscan_dependency_graph_t generateHollowDiagnosticOutput(
186-
const DepScanInMemoryDiagnosticCollector &ScanDiagnosticConsumer) {
187+
ArrayRef<DepScanInMemoryDiagnosticCollector::ScannerDiagnosticInfo>
188+
diagnostics) {
187189
// Create a dependency graph instance
188190
swiftscan_dependency_graph_t hollowResult = new swiftscan_dependency_graph_s;
189191

@@ -246,20 +248,21 @@ static swiftscan_dependency_graph_t generateHollowDiagnosticOutput(
246248

247249
// Populate the diagnostic info
248250
hollowResult->diagnostics =
249-
mapCollectedDiagnosticsForOutput(&ScanDiagnosticConsumer);
251+
mapCollectedDiagnosticsForOutput(diagnostics);
250252
return hollowResult;
251253
}
252254

253255
// Generate an instance of the `swiftscan_import_set_t` which contains no
254256
// imports but captures the diagnostics emitted during the attempted
255257
// scan query.
256258
static swiftscan_import_set_t generateHollowDiagnosticOutputImportSet(
257-
const DepScanInMemoryDiagnosticCollector &ScanDiagnosticConsumer) {
259+
ArrayRef<DepScanInMemoryDiagnosticCollector::ScannerDiagnosticInfo>
260+
diagnostics) {
258261
// Create an dependency graph instance
259262
swiftscan_import_set_t hollowResult = new swiftscan_import_set_s;
260263
hollowResult->imports = c_string_utils::create_empty_set();
261264
hollowResult->diagnostics =
262-
mapCollectedDiagnosticsForOutput(&ScanDiagnosticConsumer);
265+
mapCollectedDiagnosticsForOutput(diagnostics);
263266
return hollowResult;
264267
}
265268

@@ -270,55 +273,67 @@ DependencyScanningTool::DependencyScanningTool()
270273
llvm::ErrorOr<swiftscan_dependency_graph_t>
271274
DependencyScanningTool::getDependencies(ArrayRef<const char *> Command,
272275
StringRef WorkingDirectory) {
276+
// Diagnostics which may get collected during scanning instance
277+
// initialization
278+
std::vector<DepScanInMemoryDiagnosticCollector::ScannerDiagnosticInfo>
279+
InitializationDiagnostics;
280+
273281
// The primary instance used to scan the query Swift source-code
274-
auto QueryContext = createScanQueryContext(Command, WorkingDirectory);
275-
if (QueryContext.ScanInstance.getError())
276-
return generateHollowDiagnosticOutput(
277-
*QueryContext.InMemoryDiagnosticCollector);
278-
auto ScanInstance = QueryContext.ScanInstance->get();
282+
auto QueryContext = createScanQueryContext(Command, WorkingDirectory,
283+
InitializationDiagnostics);
284+
if (QueryContext.getError())
285+
return generateHollowDiagnosticOutput(InitializationDiagnostics);
286+
auto ScanInstance = QueryContext->ScanInstance.get();
279287

280288
// Local scan cache instance, wrapping the shared global cache.
281289
ModuleDependenciesCache cache(
282290
ScanInstance->getMainModule()->getNameStr().str(),
283291
ScanInstance->getInvocation().getModuleScanningHash());
284292
// Execute the scanning action, retrieving the in-memory result
285293
auto DependenciesOrErr =
286-
performModuleScan(*ScanningService, cache, QueryContext);
294+
performModuleScan(*ScanningService, cache, *QueryContext);
287295

288296
if (DependenciesOrErr.getError())
289297
return generateHollowDiagnosticOutput(
290-
*QueryContext.InMemoryDiagnosticCollector);
298+
QueryContext->InMemoryDiagnosticCollector->getDiagnosticsRef());
291299

292300
return std::move(*DependenciesOrErr);
293301
}
294302

295303
llvm::ErrorOr<swiftscan_import_set_t>
296304
DependencyScanningTool::getImports(ArrayRef<const char *> Command,
297305
StringRef WorkingDirectory) {
306+
// Diagnostics which may get collected during scanning instance
307+
// initialization
308+
std::vector<DepScanInMemoryDiagnosticCollector::ScannerDiagnosticInfo>
309+
InitializationDiagnostics;
310+
298311
// The primary instance used to scan the query Swift source-code
299-
auto QueryContext = createScanQueryContext(Command, WorkingDirectory);
300-
if (QueryContext.ScanInstance.getError())
301-
return generateHollowDiagnosticOutputImportSet(
302-
*QueryContext.InMemoryDiagnosticCollector);
303-
auto ScanInstance = QueryContext.ScanInstance->get();
312+
auto QueryContext = createScanQueryContext(Command, WorkingDirectory,
313+
InitializationDiagnostics);
314+
if (QueryContext.getError())
315+
return generateHollowDiagnosticOutputImportSet(InitializationDiagnostics);
316+
auto ScanInstance = QueryContext->ScanInstance.get();
304317

305318
// Local scan cache instance, wrapping the shared global cache.
306319
ModuleDependenciesCache cache(
307320
ScanInstance->getMainModule()->getNameStr().str(),
308321
ScanInstance->getInvocation().getModuleScanningHash());
309322
// Execute the pre-scanning action, retrieving the in-memory result
310323
auto DependenciesOrErr =
311-
performModulePrescan(*ScanningService, cache, QueryContext);
324+
performModulePrescan(*ScanningService, cache, *QueryContext);
312325

313326
if (DependenciesOrErr.getError())
314327
return generateHollowDiagnosticOutputImportSet(
315-
*QueryContext.InMemoryDiagnosticCollector);
328+
QueryContext->InMemoryDiagnosticCollector->getDiagnosticsRef());
316329

317330
return std::move(*DependenciesOrErr);
318331
}
319332

320-
ScanQueryContext DependencyScanningTool::createScanQueryContext(
321-
ArrayRef<const char *> CommandArgs, StringRef WorkingDir) {
333+
llvm::ErrorOr<ScanQueryContext> DependencyScanningTool::createScanQueryContext(
334+
ArrayRef<const char *> CommandArgs, StringRef WorkingDir,
335+
std::vector<DepScanInMemoryDiagnosticCollector::ScannerDiagnosticInfo>
336+
&InitializationDiagnostics) {
322337
// The remainder of this method operates on shared state in the
323338
// scanning service
324339
llvm::sys::SmartScopedLock<true> Lock(DependencyScanningToolStateLock);
@@ -336,54 +351,58 @@ ScanQueryContext DependencyScanningTool::createScanQueryContext(
336351
auto Instance = std::make_unique<CompilerInstance>();
337352
Instance->addDiagnosticConsumer(ScannerDiagnosticsCollector.get());
338353

339-
// Basic error checking on the arguments
340-
if (CommandArgs.empty()) {
341-
Instance->getDiags().diagnose(SourceLoc(), diag::error_no_frontend_args);
342-
return ScanQueryContext{std::make_error_code(std::errc::invalid_argument),
343-
std::move(ScannerDiagnosticsCollector), nullptr};
344-
}
354+
{
355+
// In case we exit with an error, ensure the client gets the
356+
// diagnostics collected so-far.
357+
SWIFT_DEFER {
358+
InitializationDiagnostics = ScannerDiagnosticsCollector->getDiagnostics();
359+
};
360+
361+
// Basic error checking on the arguments
362+
if (CommandArgs.empty()) {
363+
Instance->getDiags().diagnose(SourceLoc(), diag::error_no_frontend_args);
364+
return std::make_error_code(std::errc::invalid_argument);
365+
}
345366

346-
CompilerInvocation Invocation;
347-
SmallString<128> WorkingDirectory(WorkingDir);
348-
if (WorkingDirectory.empty())
349-
llvm::sys::fs::current_path(WorkingDirectory);
367+
CompilerInvocation Invocation;
368+
SmallString<128> WorkingDirectory(WorkingDir);
369+
if (WorkingDirectory.empty())
370+
llvm::sys::fs::current_path(WorkingDirectory);
350371

351-
// Parse/tokenize arguments.
352-
std::string CommandString;
353-
for (const auto *c : CommandArgs) {
354-
CommandString.append(c);
355-
CommandString.append(" ");
356-
}
357-
SmallVector<const char *, 4> Args;
358-
llvm::BumpPtrAllocator Alloc;
359-
llvm::StringSaver Saver(Alloc);
360-
// Ensure that we use the Windows command line parsing on Windows as we need
361-
// to ensure that we properly handle paths.
362-
if (llvm::Triple(llvm::sys::getProcessTriple()).isOSWindows())
363-
llvm::cl::TokenizeWindowsCommandLine(CommandString, Saver, Args);
364-
else
365-
llvm::cl::TokenizeGNUCommandLine(CommandString, Saver, Args);
366-
367-
if (Invocation.parseArgs(Args, Instance->getDiags(),
368-
nullptr, WorkingDirectory, "/tmp/foo")) {
369-
return ScanQueryContext{std::make_error_code(std::errc::invalid_argument),
370-
std::move(ScannerDiagnosticsCollector), nullptr};
371-
}
372+
// Parse/tokenize arguments.
373+
std::string CommandString;
374+
for (const auto *c : CommandArgs) {
375+
CommandString.append(c);
376+
CommandString.append(" ");
377+
}
378+
SmallVector<const char *, 4> Args;
379+
llvm::BumpPtrAllocator Alloc;
380+
llvm::StringSaver Saver(Alloc);
381+
// Ensure that we use the Windows command line parsing on Windows as we need
382+
// to ensure that we properly handle paths.
383+
if (llvm::Triple(llvm::sys::getProcessTriple()).isOSWindows())
384+
llvm::cl::TokenizeWindowsCommandLine(CommandString, Saver, Args);
385+
else
386+
llvm::cl::TokenizeGNUCommandLine(CommandString, Saver, Args);
387+
388+
if (Invocation.parseArgs(Args, Instance->getDiags(),
389+
nullptr, WorkingDirectory, "/tmp/foo")) {
390+
return std::make_error_code(std::errc::invalid_argument);
391+
}
372392

373-
// Setup the instance
374-
std::string InstanceSetupError;
375-
if (Instance->setup(Invocation, InstanceSetupError))
376-
return ScanQueryContext{std::make_error_code(std::errc::not_supported),
377-
std::move(ScannerDiagnosticsCollector), nullptr};
393+
// Setup the instance
394+
std::string InstanceSetupError;
395+
if (Instance->setup(Invocation, InstanceSetupError))
396+
return std::make_error_code(std::errc::not_supported);
378397

379-
Invocation.getFrontendOptions().LLVMArgs.clear();
398+
Invocation.getFrontendOptions().LLVMArgs.clear();
380399

381-
// Setup the caching service after the instance finishes setup.
382-
if (ScanningService->setupCachingDependencyScanningService(*Instance))
383-
return ScanQueryContext{std::make_error_code(std::errc::invalid_argument),
384-
std::move(ScannerDiagnosticsCollector), nullptr};
400+
// Setup the caching service after the instance finishes setup.
401+
if (ScanningService->setupCachingDependencyScanningService(*Instance))
402+
return std::make_error_code(std::errc::invalid_argument);
385403

386-
(void)Instance->getMainModule();
404+
(void)Instance->getMainModule();
405+
}
387406

388407
auto SerializedDiagnosticsOutputPath =
389408
Instance->getInvocation()

lib/DependencyScan/ScanDependencies.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -966,10 +966,10 @@ static swiftscan_dependency_graph_t generateFullDependencyGraph(
966966
swiftscan_dependency_graph_t result = new swiftscan_dependency_graph_s;
967967
result->main_module_name = create_clone(mainModuleName.c_str());
968968
result->dependencies = dependencySet;
969-
result->diagnostics =
970-
diagnosticCollector
971-
? mapCollectedDiagnosticsForOutput(diagnosticCollector)
972-
: nullptr;
969+
result->diagnostics = diagnosticCollector
970+
? mapCollectedDiagnosticsForOutput(
971+
diagnosticCollector->getDiagnostics())
972+
: nullptr;
973973
return result;
974974
}
975975

@@ -1452,14 +1452,14 @@ static llvm::ErrorOr<swiftscan_import_set_t> performModulePrescanImpl(
14521452
return importInfo.importIdentifier;
14531453
});
14541454
importSet->imports = create_set(importIdentifiers);
1455-
importSet->diagnostics =
1456-
diagnosticCollector
1457-
? mapCollectedDiagnosticsForOutput(diagnosticCollector)
1458-
: nullptr;
1459-
importSet->diagnostics =
1460-
diagnosticCollector
1461-
? mapCollectedDiagnosticsForOutput(diagnosticCollector)
1462-
: nullptr;
1455+
importSet->diagnostics = diagnosticCollector
1456+
? mapCollectedDiagnosticsForOutput(
1457+
diagnosticCollector->getDiagnostics())
1458+
: nullptr;
1459+
importSet->diagnostics = diagnosticCollector
1460+
? mapCollectedDiagnosticsForOutput(
1461+
diagnosticCollector->getDiagnostics())
1462+
: nullptr;
14631463
return importSet;
14641464
}
14651465
} // namespace
@@ -1551,15 +1551,15 @@ llvm::ErrorOr<swiftscan_dependency_graph_t>
15511551
swift::dependencies::performModuleScan(SwiftDependencyScanningService &service,
15521552
ModuleDependenciesCache &cache,
15531553
ScanQueryContext &queryContext) {
1554-
return performModuleScanImpl(service, queryContext.ScanInstance->get(), cache,
1554+
return performModuleScanImpl(service, queryContext.ScanInstance.get(), cache,
15551555
queryContext.InMemoryDiagnosticCollector.get());
15561556
}
15571557

15581558
llvm::ErrorOr<swiftscan_import_set_t> swift::dependencies::performModulePrescan(
15591559
SwiftDependencyScanningService &service, ModuleDependenciesCache &cache,
15601560
ScanQueryContext &queryContext) {
15611561
return performModulePrescanImpl(
1562-
service, queryContext.ScanInstance->get(), cache,
1562+
service, queryContext.ScanInstance.get(), cache,
15631563
queryContext.InMemoryDiagnosticCollector.get());
15641564
}
15651565

0 commit comments

Comments
 (0)