6
6
#include < sstream>
7
7
#include < memory>
8
8
#include < unistd.h>
9
+ #include < unordered_set>
9
10
10
11
#include < swift/AST/SourceFile.h>
12
+ #include < swift/Basic/FileTypes.h>
11
13
#include < llvm/ADT/SmallString.h>
12
14
#include < llvm/Support/FileSystem.h>
13
15
#include < llvm/Support/Path.h>
@@ -124,6 +126,17 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config,
124
126
125
127
void codeql::extractSwiftFiles (const SwiftExtractorConfiguration& config,
126
128
swift::CompilerInstance& compiler) {
129
+ // The frontend can be called in many different ways.
130
+ // At each invocation we only extract system and builtin modules and any input source files that
131
+ // have an output associated with them.
132
+ std::unordered_set<std::string> sourceFiles;
133
+ auto inputFiles = compiler.getInvocation ().getFrontendOptions ().InputsAndOutputs .getAllInputs ();
134
+ for (auto & input : inputFiles) {
135
+ if (input.getType () == swift::file_types::TY_Swift && !input.outputFilename ().empty ()) {
136
+ sourceFiles.insert (input.getFileName ());
137
+ }
138
+ }
139
+
127
140
for (auto & [_, module ] : compiler.getASTContext ().getLoadedModules ()) {
128
141
// We only extract system and builtin modules here as the other "user" modules can be built
129
142
// during the build process and then re-used at a later stage. In this case, we extract the
@@ -135,12 +148,13 @@ void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config,
135
148
// TODO: pass ModuleDecl directly when we have module extraction in place?
136
149
extractDeclarations (config, decls, compiler, *module );
137
150
} else {
138
- // The extraction will only work if one (or more) `-primary-file` CLI option is provided,
139
- // which is what always happens in case of `swift build` and `xcodebuild`
140
- for (auto primaryFile : module ->getPrimarySourceFiles ()) {
141
- archiveFile (config, *primaryFile);
142
- extractDeclarations (config, primaryFile->getTopLevelDecls (), compiler, *module ,
143
- primaryFile);
151
+ for (auto file : module ->getFiles ()) {
152
+ auto sourceFile = llvm::dyn_cast<swift::SourceFile>(file);
153
+ if (!sourceFile || sourceFiles.count (sourceFile->getFilename ().str ()) == 0 ) {
154
+ continue ;
155
+ }
156
+ archiveFile (config, *sourceFile);
157
+ extractDeclarations (config, sourceFile->getTopLevelDecls (), compiler, *module , sourceFile);
144
158
}
145
159
}
146
160
}
0 commit comments