Skip to content

Commit 07e07a1

Browse files
committed
[Dependency Scanning] Add DependencyScanningTool entry-point for batch scanning
1 parent 7d1d8a4 commit 07e07a1

File tree

8 files changed

+178
-105
lines changed

8 files changed

+178
-105
lines changed

include/swift/SwiftScan/DependencyScanningTool.h

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
#define SWIFT_DEPENDENCY_SCANNING_TOOL_H
1515

1616
#include "swift/AST/ModuleDependencies.h"
17-
#include "llvm/Support/Error.h"
18-
#include "llvm/Support/StringSaver.h"
17+
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
18+
#include "swift/SwiftScan/ScanDependencies.h"
1919
#include "llvm/ADT/StringMap.h"
20-
#include "llvm/ADT/StringSet.h"
2120
#include "llvm/ADT/StringRef.h"
21+
#include "llvm/ADT/StringSet.h"
22+
#include "llvm/Support/Error.h"
23+
#include "llvm/Support/StringSaver.h"
2224

2325
namespace swift {
2426
namespace dependencies {
@@ -30,21 +32,37 @@ class DependencyScanningTool {
3032
/// Construct a dependency scanning tool.
3133
DependencyScanningTool();
3234

33-
/// Collect the full module depenedency graph for the input, ignoring any placeholder
34-
/// modules.
35+
/// Collect the full module depenedency graph for the input, ignoring any
36+
/// placeholder modules.
3537
///
36-
/// \returns a \c StringError with the diagnostic output if clang errors
38+
/// \returns a \c StringError with the diagnostic output if errors
3739
/// occurred, \c FullDependencies otherwise.
3840
llvm::ErrorOr<std::string>
39-
getFullDependencies(ArrayRef<const char *> Command,
40-
const llvm::StringSet<> &InputFiles,
41-
const llvm::StringSet<> &PlaceholderModules);
41+
getDependencies(ArrayRef<const char *> Command,
42+
const llvm::StringSet<> &PlaceholderModules);
43+
44+
/// Collect the full module depenedency graph for the input collection of
45+
/// module names (batch inputs) and output them to the
46+
/// BatchScanInput-specified output locations.
47+
///
48+
/// \returns a \c StringError with the diagnostic output if errors
49+
/// occurred.
50+
std::error_code getDependencies(ArrayRef<const char *> Command,
51+
const std::vector<BatchScanInput> &BatchInput,
52+
const llvm::StringSet<> &PlaceholderModules);
4253

4354
private:
55+
/// Using the specified invocation command, instantiate a CompilerInstance
56+
/// that will be used for this scan.
57+
llvm::ErrorOr<std::unique_ptr<CompilerInstance>>
58+
initCompilerInstanceForScan(ArrayRef<const char *> Command);
59+
4460
/// Shared cache of module dependencies, re-used by individual queries
4561
/// during the lifetime of this Tool
4662
std::unique_ptr<ModuleDependenciesCache> SharedCache;
47-
63+
64+
/// A shared consumer that, for now, just prints the encountered diagnostics
65+
PrintingDiagnosticConsumer PDC;
4866
llvm::BumpPtrAllocator Alloc;
4967
llvm::StringSaver Saver;
5068
};

include/swift/SwiftScan/ScanDependencies.h

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,24 @@
1515

1616
#include "llvm/ADT/StringRef.h"
1717

18+
namespace llvm {
19+
class StringSaver;
20+
}
21+
1822
namespace swift {
1923

2024
class CompilerInvocation;
2125
class CompilerInstance;
2226
class ModuleDependenciesCache;
2327

24-
/// Batch scan the dependencies for modules specified in \c batchInputFile.
25-
bool batchScanModuleDependencies(CompilerInstance &instance,
26-
llvm::StringRef batchInputFile);
28+
namespace dependencies {
29+
30+
struct BatchScanInput {
31+
StringRef moduleName;
32+
StringRef arguments;
33+
StringRef outputPath;
34+
bool isSwift;
35+
};
2736

2837
/// Scans the dependencies of the main module of \c instance and writes out
2938
/// the resulting JSON according to the instance's output parameters.
@@ -40,6 +49,26 @@ bool scanDependencies(CompilerInstance &instance,
4049
ModuleDependenciesCache &cache,
4150
llvm::raw_ostream &out);
4251

52+
/// Batch scan the dependencies for modules specified in \c batchInputFile.
53+
bool batchScanDependencies(CompilerInstance &instance,
54+
llvm::StringRef batchInputFile);
55+
56+
57+
/// Batch scan the dependencies for modules specified in \c batchInputFile.
58+
bool executeBatchModuleScan(CompilerInstance &instance,
59+
ModuleDependenciesCache &cache,
60+
llvm::StringSaver &saver,
61+
const std::vector<BatchScanInput> &BatchInput);
62+
63+
/// Scan for dependencies of a module with a specified name, producing the resulting output
64+
/// at the specified output path.
65+
bool executeSingleModuleScan(CompilerInstance &instance,
66+
ModuleDependenciesCache &cache,
67+
StringRef moduleName,
68+
bool isClang,
69+
StringRef outputPath);
70+
71+
} // end namespace dependencies
4372
} // end namespace swift
4473

4574
#endif

lib/FrontendTool/FrontendTool.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,9 +1136,9 @@ static bool performScanDependencies(CompilerInstance &Instance) {
11361136
Instance.getASTContext().SearchPathOpts.BatchScanInputFilePath;
11371137
ModuleDependenciesCache SingleUseCache;
11381138
if (batchScanInput.empty()) {
1139-
return scanAndOutputDependencies(Instance);
1139+
return dependencies::scanAndOutputDependencies(Instance);
11401140
} else {
1141-
return batchScanModuleDependencies(Instance, batchScanInput);
1141+
return dependencies::batchScanDependencies(Instance, batchScanInput);
11421142
}
11431143
}
11441144

@@ -1226,7 +1226,7 @@ static bool performAction(CompilerInstance &Instance,
12261226
case FrontendOptions::ActionType::ScanDependencies:
12271227
return performScanDependencies(Instance);
12281228
case FrontendOptions::ActionType::ScanClangDependencies:
1229-
return scanClangDependencies(Instance);
1229+
return dependencies::scanClangDependencies(Instance);
12301230

12311231
// MARK: General Compilation Actions
12321232
case FrontendOptions::ActionType::Parse:

lib/SwiftScan/DependencyScanningTool.cpp

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,9 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "swift/SwiftScan/DependencyScanningTool.h"
14-
#include "swift/SwiftScan/ScanDependencies.h"
1514
#include "swift/AST/DiagnosticEngine.h"
1615
#include "swift/AST/DiagnosticsFrontend.h"
1716
#include "swift/Basic/LLVMInitialize.h"
18-
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
1917
#include "swift/Frontend/Frontend.h"
2018
#include "llvm/Support/CommandLine.h"
2119
#include "llvm/Support/FileSystem.h"
@@ -26,22 +24,52 @@ namespace swift {
2624
namespace dependencies {
2725

2826
DependencyScanningTool::DependencyScanningTool()
29-
: SharedCache(std::make_unique<ModuleDependenciesCache>()),
30-
Alloc(), Saver(Alloc) {}
31-
32-
llvm::ErrorOr<std::string>
33-
DependencyScanningTool::getFullDependencies(ArrayRef<const char *> Command,
34-
const llvm::StringSet<> &InputFiles,
35-
const llvm::StringSet<> &PlaceholderModules) {
36-
PrintingDiagnosticConsumer PDC;
27+
: SharedCache(std::make_unique<ModuleDependenciesCache>()), PDC(), Alloc(),
28+
Saver(Alloc) {}
29+
30+
llvm::ErrorOr<std::string> DependencyScanningTool::getDependencies(
31+
ArrayRef<const char *> Command,
32+
const llvm::StringSet<> &PlaceholderModules) {
33+
// The primary instance used to scan the query Swift source-code
34+
auto InstanceOrErr = initCompilerInstanceForScan(Command);
35+
if (std::error_code EC = InstanceOrErr.getError())
36+
return EC;
37+
auto Instance = std::move(*InstanceOrErr);
38+
39+
std::string JSONOutput;
40+
llvm::raw_string_ostream OSS(JSONOutput);
41+
scanDependencies(*Instance.get(), *SharedCache, OSS);
42+
OSS.flush();
43+
44+
// TODO: swiftch to an in-memory representation
45+
return JSONOutput;
46+
}
47+
48+
std::error_code DependencyScanningTool::getDependencies(
49+
ArrayRef<const char *> Command,
50+
const std::vector<BatchScanInput> &BatchInput,
51+
const llvm::StringSet<> &PlaceholderModules) {
52+
// The primary instance used to scan Swift modules
53+
auto InstanceOrErr = initCompilerInstanceForScan(Command);
54+
if (std::error_code EC = InstanceOrErr.getError())
55+
return EC;
56+
auto Instance = std::move(*InstanceOrErr);
57+
58+
executeBatchModuleScan(*Instance.get(), *SharedCache, Saver, BatchInput);
59+
return std::error_code();
60+
}
61+
62+
llvm::ErrorOr<std::unique_ptr<CompilerInstance>>
63+
DependencyScanningTool::initCompilerInstanceForScan(
64+
ArrayRef<const char *> Command) {
3765
// State unique to an individual scan
3866
auto Instance = std::make_unique<CompilerInstance>();
3967
Instance->addDiagnosticConsumer(&PDC);
4068

4169
// Basic error checking on the arguments
4270
if (Command.empty()) {
4371
Instance->getDiags().diagnose(SourceLoc(), diag::error_no_frontend_args);
44-
return std::make_error_code(std::errc::not_supported);
72+
return std::make_error_code(std::errc::invalid_argument);
4573
}
4674

4775
CompilerInvocation Invocation;
@@ -54,21 +82,18 @@ DependencyScanningTool::getFullDependencies(ArrayRef<const char *> Command,
5482
CommandString.append(c);
5583
CommandString.append(" ");
5684
}
57-
SmallVector<const char*, 4> Args;
85+
SmallVector<const char *, 4> Args;
5886
llvm::cl::TokenizeGNUCommandLine(CommandString, Saver, Args);
5987
if (Invocation.parseArgs(Args, Instance->getDiags())) {
60-
return std::make_error_code(std::errc::not_supported);
88+
return std::make_error_code(std::errc::invalid_argument);
6189
}
6290

6391
// Setup the instance
6492
Instance->setup(Invocation);
93+
(void)Instance->getMainModule();
6594

66-
std::string JSONOutput;
67-
llvm::raw_string_ostream Oss(JSONOutput);
68-
scanDependencies(*Instance, *SharedCache, Oss);
69-
Oss.flush();
70-
71-
return JSONOutput;
72-
}
73-
}
95+
return Instance;
7496
}
97+
98+
} // namespace dependencies
99+
} // namespace swift

lib/SwiftScan/ScanDependencies.cpp

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,10 @@
4040
#include <set>
4141

4242
using namespace swift;
43+
using namespace swift::dependencies;
4344
using namespace llvm::yaml;
4445

4546
namespace {
46-
struct BatchScanInput {
47-
StringRef moduleName;
48-
StringRef arguments;
49-
StringRef outputPath;
50-
bool isSwift;
51-
};
5247

5348
static std::string getScalaNodeText(Node *N) {
5449
SmallString<32> Buffer;
@@ -669,11 +664,11 @@ static bool diagnoseCycle(CompilerInstance &instance,
669664
return false;
670665
}
671666

672-
static bool scanModuleDependencies(CompilerInstance &instance,
673-
ModuleDependenciesCache &cache,
674-
StringRef moduleName,
675-
bool isClang,
676-
StringRef outputPath) {
667+
bool swift::dependencies::executeSingleModuleScan(CompilerInstance &instance,
668+
ModuleDependenciesCache &cache,
669+
StringRef moduleName,
670+
bool isClang,
671+
StringRef outputPath) {
677672
ASTContext &ctx = instance.getASTContext();
678673
auto &FEOpts = instance.getInvocation().getFrontendOptions();
679674
ModuleInterfaceLoaderOptions LoaderOpts(FEOpts);
@@ -731,18 +726,18 @@ static bool scanModuleDependencies(CompilerInstance &instance,
731726
return false;
732727
}
733728

734-
bool swift::scanClangDependencies(CompilerInstance &instance) {
729+
bool swift::dependencies::scanClangDependencies(CompilerInstance &instance) {
735730
ModuleDependenciesCache cache;
736-
return scanModuleDependencies(instance, cache,
737-
instance.getMainModule()->getNameStr(),
738-
/*isClang*/true,
739-
instance.getInvocation().getFrontendOptions()
740-
.InputsAndOutputs.getSingleOutputFilename());
731+
return executeSingleModuleScan(instance, cache,
732+
instance.getMainModule()->getNameStr(),
733+
/*isClang*/true,
734+
instance.getInvocation().getFrontendOptions()
735+
.InputsAndOutputs.getSingleOutputFilename());
741736
}
742737

743-
bool swift::batchScanModuleDependencies(CompilerInstance &instance,
744-
llvm::StringRef batchInputFile) {
745-
const CompilerInvocation &invok = instance.getInvocation();
738+
bool
739+
swift::dependencies::batchScanDependencies(CompilerInstance &instance,
740+
llvm::StringRef batchInputFile) {
746741
// The primary cache used for scans carried out with the compiler instance
747742
// we have created
748743
ModuleDependenciesCache cache;
@@ -754,6 +749,16 @@ bool swift::batchScanModuleDependencies(CompilerInstance &instance,
754749
batchInputFile, saver);
755750
if (!results.hasValue())
756751
return true;
752+
753+
return executeBatchModuleScan(instance, cache, saver, *results);
754+
}
755+
756+
bool
757+
swift::dependencies::executeBatchModuleScan(CompilerInstance &instance,
758+
ModuleDependenciesCache &cache,
759+
llvm::StringSaver &saver,
760+
const std::vector<BatchScanInput> &batchInput) {
761+
const CompilerInvocation &invok = instance.getInvocation();
757762
auto &diags = instance.getDiags();
758763
ForwardingDiagnosticConsumer FDC(diags);
759764

@@ -762,7 +767,7 @@ bool swift::batchScanModuleDependencies(CompilerInstance &instance,
762767
// state is no longer shared.
763768
llvm::StringMap<std::pair<std::unique_ptr<CompilerInstance>,
764769
std::unique_ptr<ModuleDependenciesCache>>> subInstanceMap;
765-
for (auto &entry: *results) {
770+
for (auto &entry: batchInput) {
766771
CompilerInstance *pInstance = nullptr;
767772
ModuleDependenciesCache *pCache = nullptr;
768773
if (entry.arguments.empty()) {
@@ -797,16 +802,17 @@ bool swift::batchScanModuleDependencies(CompilerInstance &instance,
797802
}
798803
}
799804
assert(pInstance);
805+
assert(pCache);
800806
// Scan using the chosen compiler instance.
801-
if (scanModuleDependencies(*pInstance, *pCache, entry.moduleName,
802-
!entry.isSwift, entry.outputPath)) {
807+
if (executeSingleModuleScan(*pInstance, *pCache, entry.moduleName,
808+
!entry.isSwift, entry.outputPath)) {
803809
return true;
804810
}
805811
}
806812
return false;
807813
}
808814

809-
bool swift::scanAndOutputDependencies(CompilerInstance &instance) {
815+
bool swift::dependencies::scanAndOutputDependencies(CompilerInstance &instance) {
810816
ASTContext &Context = instance.getASTContext();
811817
const FrontendOptions &opts = instance.getInvocation().getFrontendOptions();
812818
std::string path = opts.InputsAndOutputs.getSingleOutputFilename();
@@ -826,9 +832,9 @@ bool swift::scanAndOutputDependencies(CompilerInstance &instance) {
826832
return scanDependencies(instance, SingleUseCache, out);
827833
}
828834

829-
bool swift::scanDependencies(CompilerInstance &instance,
830-
ModuleDependenciesCache &cache,
831-
llvm::raw_ostream &out) {
835+
bool swift::dependencies::scanDependencies(CompilerInstance &instance,
836+
ModuleDependenciesCache &cache,
837+
llvm::raw_ostream &out) {
832838
ASTContext &Context = instance.getASTContext();
833839
ModuleDecl *mainModule = instance.getMainModule();
834840
const CompilerInvocation &invocation = instance.getInvocation();

0 commit comments

Comments
 (0)