Skip to content

Commit fed504c

Browse files
authored
Merge pull request github#12348 from github/alexdenisov/extract-emission-body-decisions
Swift: move decision making out of dispatcher. NFC
2 parents c0f9b11 + 8194fe3 commit fed504c

File tree

5 files changed

+61
-37
lines changed

5 files changed

+61
-37
lines changed

swift/extractor/SwiftExtractor.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "swift/extractor/SwiftBuiltinSymbols.h"
1414
#include "swift/extractor/infra/file/Path.h"
1515
#include "swift/extractor/infra/SwiftLocationExtractor.h"
16+
#include "swift/extractor/infra/SwiftBodyEmissionStrategy.h"
1617

1718
using namespace codeql;
1819
using namespace std::string_literals;
@@ -142,7 +143,8 @@ static std::unordered_set<swift::ModuleDecl*> extractDeclarations(
142143

143144
SwiftLocationExtractor locationExtractor(*trap);
144145
locationExtractor.emitFile(primaryFile);
145-
SwiftVisitor visitor(compiler.getSourceMgr(), *trap, locationExtractor, module, primaryFile);
146+
SwiftBodyEmissionStrategy bodyEmissionStrategy(module, primaryFile);
147+
SwiftVisitor visitor(compiler.getSourceMgr(), *trap, locationExtractor, bodyEmissionStrategy);
146148
auto topLevelDecls = getTopLevelDecls(module, primaryFile);
147149
for (auto decl : topLevelDecls) {
148150
visitor.extract(decl);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include "swift/extractor/infra/SwiftBodyEmissionStrategy.h"
2+
3+
using namespace codeql;
4+
5+
// In order to not emit duplicated entries for declarations, we restrict emission to only
6+
// Decls declared within the current "scope".
7+
// Depending on the whether we are extracting a primary source file or not the scope is defined as
8+
// follows:
9+
// - not extracting a primary source file (`currentPrimarySourceFile == nullptr`): the current
10+
// scope means the current module. This is used in the case of system or builtin modules.
11+
// - extracting a primary source file: in this mode, we extract several files belonging to the
12+
// same module one by one. In this mode, we restrict emission only to the same file ignoring
13+
// all the other files.
14+
bool SwiftBodyEmissionStrategy::shouldEmitDeclBody(const swift::Decl& decl) {
15+
auto module = decl.getModuleContext();
16+
if (module != &currentModule) {
17+
return false;
18+
}
19+
// ModuleDecl is a special case: if it passed the previous test, it is the current module
20+
// but it never has a source file, so we short circuit to emit it in any case
21+
if (!currentPrimarySourceFile || decl.getKind() == swift::DeclKind::Module) {
22+
return true;
23+
}
24+
if (auto context = decl.getDeclContext()) {
25+
return currentPrimarySourceFile == context->getParentSourceFile();
26+
}
27+
return false;
28+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
3+
#include <swift/AST/SourceFile.h>
4+
#include <swift/AST/Module.h>
5+
6+
namespace codeql {
7+
8+
class SwiftBodyEmissionStrategy {
9+
public:
10+
SwiftBodyEmissionStrategy(swift::ModuleDecl& currentModule,
11+
swift::SourceFile* currentPrimarySourceFile)
12+
: currentModule(currentModule), currentPrimarySourceFile(currentPrimarySourceFile) {}
13+
bool shouldEmitDeclBody(const swift::Decl& decl);
14+
15+
private:
16+
swift::ModuleDecl& currentModule;
17+
swift::SourceFile* currentPrimarySourceFile;
18+
};
19+
20+
} // namespace codeql

swift/extractor/infra/SwiftDispatcher.h

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "swift/extractor/infra/SwiftTagTraits.h"
1212
#include "swift/extractor/trap/generated/TrapClasses.h"
1313
#include "swift/extractor/infra/SwiftLocationExtractor.h"
14+
#include "swift/extractor/infra/SwiftBodyEmissionStrategy.h"
1415

1516
namespace codeql {
1617

@@ -46,13 +47,11 @@ class SwiftDispatcher {
4647
SwiftDispatcher(const swift::SourceManager& sourceManager,
4748
TrapDomain& trap,
4849
SwiftLocationExtractor& locationExtractor,
49-
swift::ModuleDecl& currentModule,
50-
swift::SourceFile* currentPrimarySourceFile = nullptr)
50+
SwiftBodyEmissionStrategy& bodyEmissionStrategy)
5151
: sourceManager{sourceManager},
5252
trap{trap},
5353
locationExtractor{locationExtractor},
54-
currentModule{currentModule},
55-
currentPrimarySourceFile{currentPrimarySourceFile} {}
54+
bodyEmissionStrategy{bodyEmissionStrategy} {}
5655

5756
const std::unordered_set<swift::ModuleDecl*> getEncounteredModules() && {
5857
return std::move(encounteredModules);
@@ -238,36 +237,9 @@ class SwiftDispatcher {
238237
trap.debug(args...);
239238
}
240239

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
256240
bool shouldEmitDeclBody(const swift::Decl& decl) {
257-
auto module = decl.getModuleContext();
258-
if (module != &currentModule) {
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);
271243
}
272244

273245
void emitComment(swift::Token& comment) {
@@ -333,9 +305,8 @@ class SwiftDispatcher {
333305
TrapDomain& trap;
334306
Store store;
335307
SwiftLocationExtractor& locationExtractor;
308+
SwiftBodyEmissionStrategy& bodyEmissionStrategy;
336309
Store::Handle waitingForNewLabel{std::monostate{}};
337-
swift::ModuleDecl& currentModule;
338-
swift::SourceFile* currentPrimarySourceFile;
339310
std::unordered_set<swift::ModuleDecl*> encounteredModules;
340311
};
341312

swift/extractor/invocation/SwiftInvocationExtractor.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,10 @@ void emitSourceObjectDependencies(const SwiftExtractorState& state,
8787
object->emitObject(id);
8888
for (auto encounteredModule : state.encounteredModules) {
8989
if (auto depHash = getModuleHash(encounteredModule)) {
90-
object->emitObjectDependency(getModuleId(encounteredModule, *depHash));
90+
auto encounteredModuleId = getModuleId(encounteredModule, *depHash);
91+
if (encounteredModuleId != id) {
92+
object->emitObjectDependency(encounteredModuleId);
93+
}
9194
}
9295
}
9396
for (const auto& requestedTrap : state.traps) {

0 commit comments

Comments
 (0)