Re-implement SourceFile::getIfConfigClauseRanges on top of SwiftIfConfig

The SwiftIfConfig library provides APIs for evaluating and extracting
the active #if regions in source code. Use its "configured regions" API
along with the ASTContext-backed build configuration to reimplement the
extraction of active/inactive regions from the source.

This approach has the benefit of being effectively stateless: where the
existing solution relies on the C++ parser recording all of the `#if`
clauses it sees as it is parsing (and then might have to sort them later),
this version does a scan of source to collect the list without requiring
any other state. The newer implementation is also conceptually cleaner,
and can be shared with other clients that have their own take on the
build configuration.

The primary client of this information is the SourceKit request that
identifies "inactive" regions within the source file, which IDEs can
use to grey out inactive code within the current build configuration.
There is also some profiling information that uses it. Those clients
should be unaffected by this under-the-hood change.

For the moment, I'm leaving the old code path in place for compiler
builds that don't have swift-syntax. This should be considered
temporary, and that code should be removed in favor of request'ifying
this function and removing the incrementally-built state entirely.
This commit is contained in:
Doug Gregor
2024-07-06 19:42:36 -07:00
parent 5c3b7777e7
commit d06e40877f
7 changed files with 185 additions and 38 deletions

View File

@@ -47,6 +47,7 @@
#include "swift/Basic/SourceManager.h"
#include "swift/Basic/Statistic.h"
#include "swift/Basic/StringExtras.h"
#include "swift/Bridging/ASTGen.h"
#include "swift/Demangling/ManglingMacros.h"
#include "swift/Parse/Token.h"
#include "swift/Strings.h"
@@ -2964,6 +2965,21 @@ void SourceFile::recordIfConfigClauseRangeInfo(
}
ArrayRef<IfConfigClauseRangeInfo> SourceFile::getIfConfigClauseRanges() const {
#if SWIFT_BUILD_SWIFT_SYNTAX
if (!IfConfigClauseRanges.IsSorted) {
IfConfigClauseRanges.Ranges.clear();
BridgedIfConfigClauseRangeInfo *regions;
intptr_t numRegions = swift_ASTGen_configuredRegions(
getASTContext(), getExportedSourceFile(), &regions);
IfConfigClauseRanges.Ranges.reserve(numRegions);
for (intptr_t i = 0; i != numRegions; ++i)
IfConfigClauseRanges.Ranges.push_back(regions[i].unbridged());
free(regions);
IfConfigClauseRanges.IsSorted = true;
}
#else
if (!IfConfigClauseRanges.IsSorted) {
auto &SM = getASTContext().SourceMgr;
// Sort the ranges if we need to.
@@ -2987,6 +3003,7 @@ ArrayRef<IfConfigClauseRangeInfo> SourceFile::getIfConfigClauseRanges() const {
IfConfigClauseRanges.Ranges.end());
IfConfigClauseRanges.IsSorted = true;
}
#endif
return IfConfigClauseRanges.Ranges;
}