[SourceKit] Use recored #if regions in "active regions" request

* Record each IfConfig clause location info in SourceFile
* Update SILProfiler to handle them
* Update SwiftLangSupport::findActiveRegionsInFile() to use the recorded
  regions instead of walking into AST to find #if regions

rdar://118082146
This commit is contained in:
Rintaro Ishizaki
2024-03-14 06:34:30 +09:00
parent 38ca3cc435
commit 2abddcb260
7 changed files with 188 additions and 127 deletions

View File

@@ -2652,36 +2652,6 @@ void SwiftLangSupport::findRelatedIdentifiersInFile(
// SwiftLangSupport::findActiveRegionsInFile
//===----------------------------------------------------------------------===//
namespace {
class IfConfigScanner : public SourceEntityWalker {
unsigned BufferID = -1;
SmallVectorImpl<IfConfigInfo> &Infos;
bool Cancelled = false;
public:
explicit IfConfigScanner(unsigned BufferID,
SmallVectorImpl<IfConfigInfo> &Infos)
: BufferID(BufferID), Infos(Infos) {}
private:
bool walkToDeclPre(Decl *D, CharSourceRange Range) override {
if (Cancelled)
return false;
if (auto *IfDecl = dyn_cast<IfConfigDecl>(D)) {
for (auto &Clause : IfDecl->getClauses()) {
unsigned Offset = D->getASTContext().SourceMgr.getLocOffsetInBuffer(
Clause.Loc, BufferID);
Infos.emplace_back(Offset, Clause.isActive);
}
}
return true;
}
};
} // end anonymous namespace
void SwiftLangSupport::findActiveRegionsInFile(
StringRef PrimaryFilePath, StringRef InputBufferName,
ArrayRef<const char *> Args, SourceKitCancellationToken CancellationToken,
@@ -2717,16 +2687,25 @@ void SwiftLangSupport::findActiveRegionsInFile(
return;
}
SmallVector<IfConfigInfo> Configs;
IfConfigScanner Scanner(*SF->getBufferID(), Configs);
Scanner.walk(SF);
auto &SM = SF->getASTContext().SourceMgr;
auto BufferID = *SF->getBufferID();
// Sort by offset so nested decls are reported
// in source order (not tree order).
llvm::sort(Configs,
[](const IfConfigInfo &LHS, const IfConfigInfo &RHS) -> bool {
return LHS.Offset < RHS.Offset;
});
SmallVector<IfConfigInfo> Configs;
for (auto &range : SF->getIfConfigClauseRanges()) {
bool isActive = false;
switch (range.getKind()) {
case IfConfigClauseRangeInfo::ActiveClause:
isActive = true;
break;
case IfConfigClauseRangeInfo::InactiveClause:
isActive = false;
break;
case IfConfigClauseRangeInfo::EndDirective:
continue;
}
auto offset = SM.getLocOffsetInBuffer(range.getStartLoc(), BufferID);
Configs.emplace_back(offset, isActive);
}
ActiveRegionsInfo Info;
Info.Configs = Configs;
Receiver(RequestResult<ActiveRegionsInfo>::fromResult(Info));