Merge pull request #72310 from rintaro/ifconfigregisons-per-clause

[SourceKit] Use recorded #if regions in 'active-regions' request
This commit is contained in:
Rintaro Ishizaki
2024-03-15 06:22:51 +09:00
committed by GitHub
7 changed files with 188 additions and 127 deletions

View File

@@ -49,36 +49,41 @@ enum class RestrictedImportKind {
using ImportAccessLevel = std::optional<AttributedImport<ImportedModule>>;
/// Stores range information for a \c #if block in a SourceFile.
class IfConfigRangeInfo final {
/// The range of the entire \c #if block, including \c #else and \c #endif.
CharSourceRange WholeRange;
class IfConfigClauseRangeInfo final {
public:
enum ClauseKind {
// Active '#if', '#elseif', or '#else' clause.
ActiveClause,
// Inactive '#if', '#elseif', or '#else' clause.
InactiveClause,
// '#endif' directive.
EndDirective,
};
/// The range of the active selected body, if there is one. This does not
/// include the outer syntax of the \c #if. This may be invalid, which
/// indicates there is no active body.
CharSourceRange ActiveBodyRange;
private:
/// Source location of '#if', '#elseif', etc.
SourceLoc DirectiveLoc;
/// Character source location of body starts.
SourceLoc BodyLoc;
/// Location of the end of the body.
SourceLoc EndLoc;
ClauseKind Kind;
public:
IfConfigRangeInfo(CharSourceRange wholeRange, CharSourceRange activeBodyRange)
: WholeRange(wholeRange), ActiveBodyRange(activeBodyRange) {
assert(wholeRange.getByteLength() > 0 && "Range must be non-empty");
assert(activeBodyRange.isInvalid() || wholeRange.contains(activeBodyRange));
IfConfigClauseRangeInfo(SourceLoc DirectiveLoc, SourceLoc BodyLoc,
SourceLoc EndLoc, ClauseKind Kind)
: DirectiveLoc(DirectiveLoc), BodyLoc(BodyLoc), EndLoc(EndLoc),
Kind(Kind) {
assert(DirectiveLoc.isValid() && BodyLoc.isValid() && EndLoc.isValid());
}
CharSourceRange getWholeRange() const { return WholeRange; }
SourceLoc getStartLoc() const { return WholeRange.getStart(); }
SourceLoc getStartLoc() const { return DirectiveLoc; }
CharSourceRange getDirectiveRange(const SourceManager &SM) const;
CharSourceRange getWholeRange(const SourceManager &SM) const;
CharSourceRange getBodyRange(const SourceManager &SM) const;
friend bool operator==(const IfConfigRangeInfo &lhs,
const IfConfigRangeInfo &rhs) {
return lhs.WholeRange == rhs.WholeRange &&
lhs.ActiveBodyRange == rhs.ActiveBodyRange;
}
/// Retrieve the ranges produced by subtracting the active body range from
/// the whole range. This includes both inactive branches as well as the
/// other syntax of the \c #if.
SmallVector<CharSourceRange, 2>
getRangesWithoutActiveBody(const SourceManager &SM) const;
ClauseKind getKind() const { return Kind; }
};
/// A file containing Swift source code.
@@ -244,9 +249,9 @@ private:
ParserStatePtr DelayedParserState =
ParserStatePtr(/*ptr*/ nullptr, /*deleter*/ nullptr);
struct IfConfigRangesData {
struct IfConfigClauseRangesData {
/// All the \c #if source ranges in this file.
std::vector<IfConfigRangeInfo> Ranges;
std::vector<IfConfigClauseRangeInfo> Ranges;
/// Whether the elemnts in \c Ranges are sorted in source order within
/// this file. We flip this to \c false any time a new range gets recorded,
@@ -255,7 +260,7 @@ private:
};
/// Stores all the \c #if source range info in this file.
mutable IfConfigRangesData IfConfigRanges;
mutable IfConfigClauseRangesData IfConfigClauseRanges;
friend class HasImportsMatchingFlagRequest;
@@ -500,12 +505,16 @@ public:
const_cast<SourceFile *>(this)->MissingImportedModules.insert(module);
}
/// Record the source range info for a parsed \c #if block.
void recordIfConfigRangeInfo(IfConfigRangeInfo ranges);
/// Record the source range info for a parsed \c #if clause.
void recordIfConfigClauseRangeInfo(const IfConfigClauseRangeInfo &range);
/// Retrieve the source range infos for any \c #if blocks contained within a
/// Retrieve the source range info for any \c #if clauses in the file.
ArrayRef<IfConfigClauseRangeInfo> getIfConfigClauseRanges() const;
/// Retrieve the source range infos for any \c #if clauses contained within a
/// given source range of this file.
ArrayRef<IfConfigRangeInfo> getIfConfigsWithin(SourceRange outer) const;
ArrayRef<IfConfigClauseRangeInfo>
getIfConfigClausesWithin(SourceRange outer) const;
void getMissingImportedModules(
SmallVectorImpl<ImportedModule> &imports) const override;