Skip to content

Commit 7a73c99

Browse files
committed
Migrate VariableTypeCollector to SourceRange
- Add SourceRange::contains and SourceRange::overlaps - Use SourceRange in VariableTypeCollector
1 parent ebe1b91 commit 7a73c99

File tree

5 files changed

+76
-25
lines changed

5 files changed

+76
-25
lines changed

include/swift/Basic/SourceLoc.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,14 @@ class SourceRange {
123123
/// includes both this range and the other one.
124124
void widen(SourceRange Other);
125125

126+
/// Checks whether this range contains the given location. Note that the given
127+
/// location should correspond to the start of a token, since locations inside
128+
/// the last token may be considered outside the range by this function.
129+
bool contains(SourceLoc Loc) const;
130+
131+
/// Checks whether this range overlaps with the given range.
132+
bool overlaps(SourceRange Other) const;
133+
126134
bool operator==(const SourceRange &other) const {
127135
return Start == other.Start && End == other.End;
128136
}

include/swift/Sema/IDETypeChecking.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,13 +225,13 @@ namespace swift {
225225
};
226226

227227
/// Collect type information for every variable declaration in \c SF
228-
/// within the given range, defined by \c Offset and \c Length.
228+
/// within the given range.
229229
/// All types will be printed to \c OS and the type offsets of the
230230
/// \c VariableTypeInfos will index into the string that backs this
231231
/// stream.
232-
void collectVariableType(
233-
SourceFile &SF, Optional<unsigned> Offset, Optional<unsigned> Length,
234-
std::vector<VariableTypeInfo> &Scratch, llvm::raw_ostream &OS);
232+
void collectVariableType(SourceFile &SF, SourceRange Range,
233+
std::vector<VariableTypeInfo> &Scratch,
234+
llvm::raw_ostream &OS);
235235

236236
/// FIXME: All of the below goes away once CallExpr directly stores its
237237
/// arguments.

lib/Basic/SourceLoc.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,15 @@ void SourceRange::widen(SourceRange Other) {
270270
End = Other.End;
271271
}
272272

273+
bool SourceRange::contains(SourceLoc Loc) const {
274+
return Start.Value.getPointer() <= Loc.Value.getPointer() &&
275+
Loc.Value.getPointer() <= End.Value.getPointer();
276+
}
277+
278+
bool SourceRange::overlaps(SourceRange Other) const {
279+
return contains(Other.Start) || Other.contains(Start);
280+
}
281+
273282
void SourceLoc::printLineAndColumn(raw_ostream &OS, const SourceManager &SM,
274283
unsigned BufferID) const {
275284
if (isInvalid()) {

lib/IDE/IDETypeChecking.cpp

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -738,11 +738,8 @@ class VariableTypeCollector : public SourceEntityWalker {
738738
SourceManager &SM;
739739
unsigned int BufferId;
740740

741-
/// The start offset of the range in which variable types are to be collected.
742-
Optional<unsigned> TotalOffset;
743-
744-
/// The length of the range in which variable types are to be collected.
745-
Optional<unsigned> TotalLength;
741+
/// The range in which variable types are to be collected.
742+
SourceRange TotalRange;
746743

747744
/// The output vector for VariableTypeInfos emitted during traversal.
748745
std::vector<VariableTypeInfo> &Results;
@@ -768,26 +765,31 @@ class VariableTypeCollector : public SourceEntityWalker {
768765
return {TypeOffsets[PrintedType], PrintedType.size()};
769766
}
770767

768+
/// Checks whether the given range overlaps the total range in which we
769+
/// collect variable types.
770+
bool overlapsTotalRange(SourceRange Range) {
771+
return TotalRange.isInvalid() || Range.overlaps(TotalRange);
772+
}
773+
771774
public:
772-
VariableTypeCollector(SourceFile &SF, Optional<unsigned> Offset,
773-
Optional<unsigned> Length,
775+
VariableTypeCollector(SourceFile &SF, SourceRange Range,
774776
std::vector<VariableTypeInfo> &Results,
775777
llvm::raw_ostream &OS)
776778
: SM(SF.getASTContext().SourceMgr), BufferId(*SF.getBufferID()),
777-
TotalOffset(Offset), TotalLength(Length), Results(Results), OS(OS) {}
779+
TotalRange(Range), Results(Results), OS(OS) {}
778780

779-
bool walkToDeclPre(Decl *D, CharSourceRange Range) override {
780-
if (Range.isInvalid()) {
781+
bool walkToDeclPre(Decl *D, CharSourceRange DeclRange) override {
782+
if (DeclRange.isInvalid()) {
781783
return false;
782784
}
783-
unsigned Offset = SM.getLocOffsetInBuffer(Range.getStart(), BufferId);
784-
unsigned Length = Range.getByteLength();
785785
// Skip this declaration and its subtree if outside the range
786-
if (TotalOffset.hasValue() && TotalLength.hasValue() &&
787-
(Offset < *TotalOffset || Offset >= (*TotalOffset + *TotalLength))) {
786+
if (!overlapsTotalRange(D->getSourceRange())) {
788787
return false;
789788
}
790789
if (auto VD = dyn_cast<VarDecl>(D)) {
790+
unsigned VarOffset =
791+
SM.getLocOffsetInBuffer(DeclRange.getStart(), BufferId);
792+
unsigned VarLength = DeclRange.getByteLength();
791793
// Print the type to a temporary buffer
792794
SmallString<64> Buffer;
793795
{
@@ -802,21 +804,36 @@ class VariableTypeCollector : public SourceEntityWalker {
802804
bool HasExplicitType =
803805
VD->getTypeReprOrParentPatternTypeRepr() != nullptr;
804806
// Add the type information to the result list.
805-
Results.emplace_back(Offset, Length, HasExplicitType, Ty.first);
807+
Results.emplace_back(VarOffset, VarLength, HasExplicitType, Ty.first);
806808
}
807809
return true;
808810
}
811+
812+
bool walkToStmtPre(Stmt *S) override {
813+
// Skip this statement and its subtree if outside the range
814+
return overlapsTotalRange(S->getSourceRange());
815+
}
816+
817+
bool walkToExprPre(Expr *E) override {
818+
// Skip this expression and its subtree if outside the range
819+
return overlapsTotalRange(E->getSourceRange());
820+
}
821+
822+
bool walkToPatternPre(Pattern *P) override {
823+
// Skip this pattern and its subtree if outside the range
824+
return overlapsTotalRange(P->getSourceRange());
825+
}
809826
};
810827

811828
VariableTypeInfo::VariableTypeInfo(uint32_t Offset, uint32_t Length,
812829
bool HasExplicitType, uint32_t TypeOffset)
813830
: Offset(Offset), Length(Length), HasExplicitType(HasExplicitType),
814831
TypeOffset(TypeOffset) {}
815832

816-
void swift::collectVariableType(
817-
SourceFile &SF, Optional<unsigned> Offset, Optional<unsigned> Length,
818-
std::vector<VariableTypeInfo> &Scratch, llvm::raw_ostream &OS) {
819-
VariableTypeCollector Walker(SF, Offset, Length, Scratch, OS);
833+
void swift::collectVariableType(SourceFile &SF, SourceRange Range,
834+
std::vector<VariableTypeInfo> &Scratch,
835+
llvm::raw_ostream &OS) {
836+
VariableTypeCollector Walker(SF, Range, Scratch, OS);
820837
Walker.walk(SF);
821838
}
822839

tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2396,12 +2396,29 @@ void SwiftLangSupport::collectVariableTypes(
23962396
: Receiver(std::move(Receiver)), Offset(Offset), Length(Length) {}
23972397

23982398
void handlePrimaryAST(ASTUnitRef AstUnit) override {
2399-
auto *SF = AstUnit->getCompilerInstance().getPrimarySourceFile();
2399+
auto &CompInst = AstUnit->getCompilerInstance();
2400+
auto *SF = CompInst.getPrimarySourceFile();
2401+
2402+
// Construct the range for which variable types are to be queried. If
2403+
// offset/length are unset, the (default) range will be used, which
2404+
// corresponds to the entire document.
2405+
SourceRange Range;
2406+
if (Offset.hasValue() && Length.hasValue()) {
2407+
auto &SM = CompInst.getSourceMgr();
2408+
unsigned BufferID = SF->getBufferID().getValue();
2409+
SourceLoc Start = Lexer::getLocForStartOfToken(SM, BufferID, *Offset);
2410+
SourceLoc End =
2411+
Lexer::getLocForStartOfToken(SM, BufferID, *Offset + *Length);
2412+
Range = SourceRange(Start, End);
2413+
}
2414+
24002415
std::vector<VariableTypeInfo> Infos;
24012416
std::string TypeBuffer;
24022417
llvm::raw_string_ostream OS(TypeBuffer);
24032418
VariableTypesInFile Result;
2404-
collectVariableType(*SF, Offset, Length, Infos, OS);
2419+
2420+
collectVariableType(*SF, Range, Infos, OS);
2421+
24052422
for (auto Info : Infos) {
24062423
Result.Results.push_back({Info.Offset, Info.Length, Info.TypeOffset, Info.HasExplicitType});
24072424
}

0 commit comments

Comments
 (0)