|
11 | 11 | #include "swift/extractor/infra/SwiftTagTraits.h" |
12 | 12 | #include "swift/extractor/trap/generated/TrapClasses.h" |
13 | 13 | #include "swift/extractor/infra/SwiftLocationExtractor.h" |
| 14 | +#include "swift/extractor/infra/SwiftBodyEmissionStrategy.h" |
14 | 15 |
|
15 | 16 | namespace codeql { |
16 | 17 |
|
@@ -46,13 +47,11 @@ class SwiftDispatcher { |
46 | 47 | SwiftDispatcher(const swift::SourceManager& sourceManager, |
47 | 48 | TrapDomain& trap, |
48 | 49 | SwiftLocationExtractor& locationExtractor, |
49 | | - swift::ModuleDecl& currentModule, |
50 | | - swift::SourceFile* currentPrimarySourceFile = nullptr) |
| 50 | + SwiftBodyEmissionStrategy& bodyEmissionStrategy) |
51 | 51 | : sourceManager{sourceManager}, |
52 | 52 | trap{trap}, |
53 | 53 | locationExtractor{locationExtractor}, |
54 | | - currentModule{currentModule}, |
55 | | - currentPrimarySourceFile{currentPrimarySourceFile} {} |
| 54 | + bodyEmissionStrategy{bodyEmissionStrategy} {} |
56 | 55 |
|
57 | 56 | const std::unordered_set<swift::ModuleDecl*> getEncounteredModules() && { |
58 | 57 | return std::move(encounteredModules); |
@@ -238,36 +237,9 @@ class SwiftDispatcher { |
238 | 237 | trap.debug(args...); |
239 | 238 | } |
240 | 239 |
|
241 | | - // In order to not emit duplicated entries for declarations, we restrict emission to only |
242 | | - // Decls declared within the current "scope". |
243 | | - // Depending on the whether we are extracting a primary source file or not the scope is defined as |
244 | | - // follows: |
245 | | - // - not extracting a primary source file (`currentPrimarySourceFile == nullptr`): the current |
246 | | - // scope means the current module. This is used in the case of system or builtin modules. |
247 | | - // - extracting a primary source file: in this mode, we extract several files belonging to the |
248 | | - // same module one by one. In this mode, we restrict emission only to the same file ignoring |
249 | | - // all the other files. |
250 | | - // This is also used to register the modules we encounter. |
251 | | - // TODO calls to this function should be taken away from `DeclVisitor` and moved around with a |
252 | | - // clearer separation between naming entities (some decls, all types), deciding whether to emit |
253 | | - // them and finally visiting emitting the contents of the entity (which should remain in the |
254 | | - // visitors). Then this double responsibility (carrying out the test and registering encountered |
255 | | - // modules) should also be cleared out |
256 | 240 | bool shouldEmitDeclBody(const swift::Decl& decl) { |
257 | | - auto module = decl.getModuleContext(); |
258 | | - if (module != ¤tModule) { |
259 | | - encounteredModules.insert(module); |
260 | | - return false; |
261 | | - } |
262 | | - // ModuleDecl is a special case: if it passed the previous test, it is the current module |
263 | | - // but it never has a source file, so we short circuit to emit it in any case |
264 | | - if (!currentPrimarySourceFile || decl.getKind() == swift::DeclKind::Module) { |
265 | | - return true; |
266 | | - } |
267 | | - if (auto context = decl.getDeclContext()) { |
268 | | - return currentPrimarySourceFile == context->getParentSourceFile(); |
269 | | - } |
270 | | - return false; |
| 241 | + encounteredModules.insert(decl.getModuleContext()); |
| 242 | + return bodyEmissionStrategy.shouldEmitDeclBody(decl); |
271 | 243 | } |
272 | 244 |
|
273 | 245 | void emitComment(swift::Token& comment) { |
@@ -333,9 +305,8 @@ class SwiftDispatcher { |
333 | 305 | TrapDomain& trap; |
334 | 306 | Store store; |
335 | 307 | SwiftLocationExtractor& locationExtractor; |
| 308 | + SwiftBodyEmissionStrategy& bodyEmissionStrategy; |
336 | 309 | Store::Handle waitingForNewLabel{std::monostate{}}; |
337 | | - swift::ModuleDecl& currentModule; |
338 | | - swift::SourceFile* currentPrimarySourceFile; |
339 | 310 | std::unordered_set<swift::ModuleDecl*> encounteredModules; |
340 | 311 | }; |
341 | 312 |
|
|
0 commit comments