Swift: extract only primary files

While the (removed) comment is correct and the frontend can be called in
different modes, both `swift build` and `xcodebuild` always use
`-primary-files` when compiling Swift projects.
The other mode was present only within our test runner (`qltest.sh`), so
removing it and doing what the official build systems do simplifies our
code base.

Additionally, file archival is now a separate function/operation.
This commit is contained in:
Alex Denisov
2022-06-02 08:44:33 +02:00
parent 4b2b6fae88
commit 6419af39f3
2 changed files with 16 additions and 22 deletions

View File

@@ -18,9 +18,7 @@
using namespace codeql;
static void extractFile(const SwiftExtractorConfiguration& config,
swift::CompilerInstance& compiler,
swift::SourceFile& file) {
static void archiveFile(const SwiftExtractorConfiguration& config, swift::SourceFile* file) {
if (std::error_code ec = llvm::sys::fs::create_directories(config.trapDir)) {
std::cerr << "Cannot create TRAP directory: " << ec.message() << "\n";
return;
@@ -31,7 +29,7 @@ static void extractFile(const SwiftExtractorConfiguration& config,
return;
}
llvm::SmallString<PATH_MAX> srcFilePath(file.getFilename());
llvm::SmallString<PATH_MAX> srcFilePath(file->getFilename());
llvm::sys::fs::make_absolute(srcFilePath);
llvm::SmallString<PATH_MAX> dstFilePath(config.sourceArchiveDir);
@@ -49,12 +47,16 @@ static void extractFile(const SwiftExtractorConfiguration& config,
<< dstFilePath.str().str() << "': " << ec.message() << "\n";
return;
}
}
static void extractFile(const SwiftExtractorConfiguration& config,
swift::CompilerInstance& compiler,
swift::SourceFile* file) {
// The extractor can be called several times from different processes with
// the same input file(s)
// We are using PID to avoid concurrent access
// TODO: find a more robust approach to avoid collisions?
std::string tempTrapName = file.getFilename().str() + '.' + std::to_string(getpid()) + ".trap";
std::string tempTrapName = file->getFilename().str() + '.' + std::to_string(getpid()) + ".trap";
llvm::SmallString<PATH_MAX> tempTrapPath(config.trapDir);
llvm::sys::path::append(tempTrapPath, tempTrapName);
@@ -84,17 +86,20 @@ static void extractFile(const SwiftExtractorConfiguration& config,
// In the case of emtpy files, the dispatcher is not called, but we still want to 'record' the
// fact that the file was extracted
// TODO: to be moved elsewhere
llvm::SmallString<PATH_MAX> srcFilePath(file->getFilename());
llvm::sys::fs::make_absolute(srcFilePath);
auto fileLabel = arena.allocateLabel<FileTag>();
trap.assignKey(fileLabel, srcFilePath.str().str());
trap.emit(FilesTrap{fileLabel, srcFilePath.str().str()});
SwiftVisitor visitor(compiler.getSourceMgr(), arena, trap);
for (swift::Decl* decl : file.getTopLevelDecls()) {
for (swift::Decl* decl : file->getTopLevelDecls()) {
visitor.extract(decl);
}
// TODO: Pick a better name to avoid collisions
std::string trapName = file.getFilename().str() + ".trap";
std::string trapName = file->getFilename().str() + ".trap";
llvm::SmallString<PATH_MAX> trapPath(config.trapDir);
llvm::sys::path::append(trapPath, trapName);
@@ -107,19 +112,8 @@ static void extractFile(const SwiftExtractorConfiguration& config,
void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config,
swift::CompilerInstance& compiler) {
// Swift frontend can be called in several different modes, we are interested
// only in the cases when either a primary or a main source file is present
if (compiler.getPrimarySourceFiles().empty()) {
swift::ModuleDecl* module = compiler.getMainModule();
if (!module->getFiles().empty() &&
module->getFiles().front()->getKind() == swift::FileUnitKind::Source) {
// We can only call getMainSourceFile if the first file is of a Source kind
swift::SourceFile& file = module->getMainSourceFile();
extractFile(config, compiler, file);
}
} else {
for (auto s : compiler.getPrimarySourceFiles()) {
extractFile(config, compiler, *s);
}
for (auto s : compiler.getPrimarySourceFiles()) {
archiveFile(config, s);
extractFile(config, compiler, s);
}
}

View File

@@ -7,5 +7,5 @@ QLTEST_LOG="$CODEQL_EXTRACTOR_SWIFT_LOG_DIR"/qltest.log
export LD_LIBRARY_PATH="$CODEQL_EXTRACTOR_SWIFT_ROOT/tools/$CODEQL_PLATFORM"
for src in *.swift; do
"$CODEQL_EXTRACTOR_SWIFT_ROOT/tools/$CODEQL_PLATFORM/extractor" -sdk "$CODEQL_EXTRACTOR_SWIFT_ROOT/qltest/$CODEQL_PLATFORM/sdk" -c $src >> $QLTEST_LOG 2>&1
"$CODEQL_EXTRACTOR_SWIFT_ROOT/tools/$CODEQL_PLATFORM/extractor" -sdk "$CODEQL_EXTRACTOR_SWIFT_ROOT/qltest/$CODEQL_PLATFORM/sdk" -c -primary-file $src >> $QLTEST_LOG 2>&1
done