mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #63816 from apple/louisd/sourcekit-inactive-ranges-request
[SourceKit] Add "Active Regions" request
This commit is contained in:
@@ -2566,6 +2566,101 @@ void SwiftLangSupport::findRelatedIdentifiersInFile(
|
||||
llvm::vfs::getRealFileSystem());
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SwiftLangSupport::findActiveRegionsInFile
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
class IfConfigScanner : public SourceEntityWalker {
|
||||
SmallVectorImpl<IfConfigInfo> &Infos;
|
||||
SourceManager &SourceMgr;
|
||||
unsigned BufferID = -1;
|
||||
bool Cancelled = false;
|
||||
|
||||
public:
|
||||
explicit IfConfigScanner(SourceFile &SrcFile, unsigned BufferID,
|
||||
SmallVectorImpl<IfConfigInfo> &Infos)
|
||||
: Infos(Infos), SourceMgr(SrcFile.getASTContext().SourceMgr),
|
||||
BufferID(BufferID) {}
|
||||
|
||||
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 = SourceMgr.getLocOffsetInBuffer(Clause.Loc, BufferID);
|
||||
Infos.emplace_back(Offset, Clause.isActive);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
void SwiftLangSupport::findActiveRegionsInFile(
|
||||
StringRef InputFile, ArrayRef<const char *> Args,
|
||||
SourceKitCancellationToken CancellationToken,
|
||||
std::function<void(const RequestResult<ActiveRegionsInfo> &)> Receiver) {
|
||||
|
||||
std::string Error;
|
||||
SwiftInvocationRef Invok =
|
||||
ASTMgr->getTypecheckInvocation(Args, InputFile, Error);
|
||||
if (!Invok) {
|
||||
LOG_WARN_FUNC("failed to create an ASTInvocation: " << Error);
|
||||
Receiver(RequestResult<ActiveRegionsInfo>::fromError(Error));
|
||||
return;
|
||||
}
|
||||
|
||||
class IfConfigConsumer : public SwiftASTConsumer {
|
||||
std::function<void(const RequestResult<ActiveRegionsInfo> &)> Receiver;
|
||||
SwiftInvocationRef Invok;
|
||||
|
||||
public:
|
||||
IfConfigConsumer(
|
||||
std::function<void(const RequestResult<ActiveRegionsInfo> &)> Receiver,
|
||||
SwiftInvocationRef Invok)
|
||||
: Receiver(std::move(Receiver)), Invok(Invok) {}
|
||||
|
||||
void handlePrimaryAST(ASTUnitRef AstUnit) override {
|
||||
auto &SrcFile = AstUnit->getPrimarySourceFile();
|
||||
SmallVector<IfConfigInfo> Configs;
|
||||
auto BufferID = SrcFile.getBufferID();
|
||||
if (!BufferID)
|
||||
return;
|
||||
IfConfigScanner Scanner(SrcFile, *BufferID, Configs);
|
||||
Scanner.walk(SrcFile);
|
||||
|
||||
// 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;
|
||||
});
|
||||
ActiveRegionsInfo Info;
|
||||
Info.Configs = Configs;
|
||||
Receiver(RequestResult<ActiveRegionsInfo>::fromResult(Info));
|
||||
}
|
||||
|
||||
void cancelled() override {
|
||||
Receiver(RequestResult<ActiveRegionsInfo>::cancelled());
|
||||
}
|
||||
|
||||
void failed(StringRef Error) override {
|
||||
LOG_WARN_FUNC("inactive ranges failed: " << Error);
|
||||
Receiver(RequestResult<ActiveRegionsInfo>::fromError(Error));
|
||||
}
|
||||
};
|
||||
|
||||
auto Consumer = std::make_shared<IfConfigConsumer>(Receiver, Invok);
|
||||
ASTMgr->processASTAsync(Invok, std::move(Consumer),
|
||||
/*OncePerASTToken=*/nullptr, CancellationToken,
|
||||
llvm::vfs::getRealFileSystem());
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SwiftLangSupport::semanticRefactoring
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Reference in New Issue
Block a user