mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #72310 from rintaro/ifconfigregisons-per-clause
[SourceKit] Use recorded #if regions in 'active-regions' request
This commit is contained in:
@@ -2778,56 +2778,66 @@ SourceFile::getImportAccessLevel(const ModuleDecl *targetModule) const {
|
||||
return restrictiveImport;
|
||||
}
|
||||
|
||||
SmallVector<CharSourceRange, 2>
|
||||
IfConfigRangeInfo::getRangesWithoutActiveBody(const SourceManager &SM) const {
|
||||
SmallVector<CharSourceRange, 2> result;
|
||||
if (ActiveBodyRange.isValid()) {
|
||||
// Split the whole range by the active range.
|
||||
result.emplace_back(SM, WholeRange.getStart(), ActiveBodyRange.getStart());
|
||||
result.emplace_back(SM, ActiveBodyRange.getEnd(), WholeRange.getEnd());
|
||||
} else {
|
||||
// No active body, we just return the whole range.
|
||||
result.push_back(WholeRange);
|
||||
CharSourceRange
|
||||
IfConfigClauseRangeInfo::getDirectiveRange(const SourceManager &SM) const {
|
||||
return CharSourceRange(SM, DirectiveLoc, BodyLoc);
|
||||
}
|
||||
|
||||
CharSourceRange
|
||||
IfConfigClauseRangeInfo::getBodyRange(const SourceManager &SM) const {
|
||||
return CharSourceRange(SM, BodyLoc, EndLoc);
|
||||
}
|
||||
|
||||
CharSourceRange
|
||||
IfConfigClauseRangeInfo::getWholeRange(const SourceManager &SM) const {
|
||||
return CharSourceRange(SM, DirectiveLoc, EndLoc);
|
||||
}
|
||||
|
||||
void SourceFile::recordIfConfigClauseRangeInfo(
|
||||
const IfConfigClauseRangeInfo &range) {
|
||||
IfConfigClauseRanges.Ranges.push_back(range);
|
||||
IfConfigClauseRanges.IsSorted = false;
|
||||
}
|
||||
|
||||
ArrayRef<IfConfigClauseRangeInfo> SourceFile::getIfConfigClauseRanges() const {
|
||||
if (!IfConfigClauseRanges.IsSorted) {
|
||||
auto &SM = getASTContext().SourceMgr;
|
||||
// Sort the ranges if we need to.
|
||||
llvm::sort(
|
||||
IfConfigClauseRanges.Ranges, [&](const IfConfigClauseRangeInfo &lhs,
|
||||
const IfConfigClauseRangeInfo &rhs) {
|
||||
return SM.isBeforeInBuffer(lhs.getStartLoc(), rhs.getStartLoc());
|
||||
});
|
||||
|
||||
// Be defensive and eliminate duplicates in case we've parsed twice.
|
||||
auto newEnd = llvm::unique(
|
||||
IfConfigClauseRanges.Ranges, [&](const IfConfigClauseRangeInfo &lhs,
|
||||
const IfConfigClauseRangeInfo &rhs) {
|
||||
if (lhs.getStartLoc() != rhs.getStartLoc())
|
||||
return false;
|
||||
assert(lhs.getBodyRange(SM) == rhs.getBodyRange(SM) &&
|
||||
"range changed on a re-parse?");
|
||||
return true;
|
||||
});
|
||||
IfConfigClauseRanges.Ranges.erase(newEnd,
|
||||
IfConfigClauseRanges.Ranges.end());
|
||||
IfConfigClauseRanges.IsSorted = true;
|
||||
}
|
||||
return result;
|
||||
|
||||
return IfConfigClauseRanges.Ranges;
|
||||
}
|
||||
|
||||
void SourceFile::recordIfConfigRangeInfo(IfConfigRangeInfo ranges) {
|
||||
IfConfigRanges.Ranges.push_back(ranges);
|
||||
IfConfigRanges.IsSorted = false;
|
||||
}
|
||||
|
||||
ArrayRef<IfConfigRangeInfo>
|
||||
SourceFile::getIfConfigsWithin(SourceRange outer) const {
|
||||
ArrayRef<IfConfigClauseRangeInfo>
|
||||
SourceFile::getIfConfigClausesWithin(SourceRange outer) const {
|
||||
auto &SM = getASTContext().SourceMgr;
|
||||
assert(SM.getRangeForBuffer(BufferID).contains(outer.Start) &&
|
||||
"Range not within this file?");
|
||||
|
||||
if (!IfConfigRanges.IsSorted) {
|
||||
// Sort the ranges if we need to.
|
||||
llvm::sort(IfConfigRanges.Ranges, [&](IfConfigRangeInfo lhs,
|
||||
IfConfigRangeInfo rhs) {
|
||||
return SM.isBeforeInBuffer(lhs.getStartLoc(), rhs.getStartLoc());
|
||||
});
|
||||
|
||||
// Be defensive and eliminate duplicates in case we've parsed twice.
|
||||
auto newEnd = std::unique(
|
||||
IfConfigRanges.Ranges.begin(), IfConfigRanges.Ranges.end(),
|
||||
[&](const IfConfigRangeInfo &lhs, const IfConfigRangeInfo &rhs) {
|
||||
if (lhs.getWholeRange() != rhs.getWholeRange())
|
||||
return false;
|
||||
|
||||
assert(lhs == rhs && "Active ranges changed on a re-parse?");
|
||||
return true;
|
||||
});
|
||||
IfConfigRanges.Ranges.erase(newEnd, IfConfigRanges.Ranges.end());
|
||||
IfConfigRanges.IsSorted = true;
|
||||
}
|
||||
|
||||
// First let's find the first #if that is after the outer start loc.
|
||||
auto ranges = llvm::ArrayRef(IfConfigRanges.Ranges);
|
||||
auto ranges = getIfConfigClauseRanges();
|
||||
auto lower = llvm::lower_bound(
|
||||
ranges, outer.Start, [&](IfConfigRangeInfo range, SourceLoc loc) {
|
||||
ranges, outer.Start,
|
||||
[&](const IfConfigClauseRangeInfo &range, SourceLoc loc) {
|
||||
return SM.isBeforeInBuffer(range.getStartLoc(), loc);
|
||||
});
|
||||
if (lower == ranges.end() ||
|
||||
@@ -2836,7 +2846,8 @@ SourceFile::getIfConfigsWithin(SourceRange outer) const {
|
||||
}
|
||||
// Next let's find the first #if that's after the outer end loc.
|
||||
auto upper = llvm::upper_bound(
|
||||
ranges, outer.End, [&](SourceLoc loc, IfConfigRangeInfo range) {
|
||||
ranges, outer.End,
|
||||
[&](SourceLoc loc, const IfConfigClauseRangeInfo &range) {
|
||||
return SM.isBeforeInBuffer(loc, range.getStartLoc());
|
||||
});
|
||||
return llvm::ArrayRef(lower, upper - lower);
|
||||
|
||||
Reference in New Issue
Block a user