Skip to content

Commit aebcd85

Browse files
authored
Merge pull request #64798 from bnbarham/cherry-cursor-macro-fixes
[5.9] Cherry-pick macro indexing/cursor info fixes
2 parents 5bad3c1 + 843b278 commit aebcd85

File tree

16 files changed

+880
-494
lines changed

16 files changed

+880
-494
lines changed

include/swift/AST/DiagnosticsRefactoring.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ ERROR(decl_no_accessibility, none, "cannot rename as accessibility could not be
4646

4747
ERROR(decl_from_clang, none, "cannot rename a Clang symbol from its Swift reference", ())
4848

49+
ERROR(decl_in_macro, none, "cannot rename a symbol defined in a macro", ())
50+
4951
ERROR(value_decl_referenced_out_of_range, none, "value decl '%0' is referenced out of range", (DeclName))
5052

5153
ERROR(multi_entry_range, none, "selected range has more than one entry point", ())

include/swift/AST/Module.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,11 @@ class ModuleDecl
410410
/// the given location isn't in this module.
411411
bool isInGeneratedBuffer(SourceLoc loc);
412412

413+
// Retrieve the buffer ID and source location of the outermost location that
414+
// caused the generation of the buffer containing \p loc. \p loc and its
415+
// buffer if it isn't in a generated buffer or has no original location.
416+
std::pair<unsigned, SourceLoc> getOriginalLocation(SourceLoc loc) const;
417+
413418
/// Creates a map from \c #filePath strings to corresponding \c #fileID
414419
/// strings, diagnosing any conflicts.
415420
///

include/swift/Refactoring/Refactoring.h

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -72,23 +72,24 @@ struct RenameRangeDetail {
7272
Optional<unsigned> Index;
7373
};
7474

75-
enum class RenameAvailableKind {
75+
enum class RefactorAvailableKind {
7676
Available,
7777
Unavailable_system_symbol,
7878
Unavailable_has_no_location,
7979
Unavailable_has_no_name,
8080
Unavailable_has_no_accessibility,
8181
Unavailable_decl_from_clang,
82+
Unavailable_decl_in_macro,
8283
};
8384

84-
struct RenameAvailabilityInfo {
85+
struct RefactorAvailabilityInfo {
8586
RefactoringKind Kind;
86-
RenameAvailableKind AvailableKind;
87-
RenameAvailabilityInfo(RefactoringKind Kind,
88-
RenameAvailableKind AvailableKind)
87+
RefactorAvailableKind AvailableKind;
88+
RefactorAvailabilityInfo(RefactoringKind Kind,
89+
RefactorAvailableKind AvailableKind)
8990
: Kind(Kind), AvailableKind(AvailableKind) {}
90-
RenameAvailabilityInfo(RefactoringKind Kind)
91-
: RenameAvailabilityInfo(Kind, RenameAvailableKind::Available) {}
91+
RefactorAvailabilityInfo(RefactoringKind Kind)
92+
: RefactorAvailabilityInfo(Kind, RefactorAvailableKind::Available) {}
9293
};
9394

9495
class FindRenameRangesConsumer {
@@ -112,7 +113,7 @@ class FindRenameRangesAnnotatingConsumer : public FindRenameRangesConsumer {
112113

113114
StringRef getDescriptiveRefactoringKindName(RefactoringKind Kind);
114115

115-
StringRef getDescriptiveRenameUnavailableReason(RenameAvailableKind Kind);
116+
StringRef getDescriptiveRenameUnavailableReason(RefactorAvailableKind Kind);
116117

117118
bool refactorSwiftModule(ModuleDecl *M, RefactoringOptions Opts,
118119
SourceEditConsumer &EditConsumer,
@@ -131,25 +132,13 @@ int findLocalRenameRanges(SourceFile *SF, RangeConfig Range,
131132
FindRenameRangesConsumer &RenameConsumer,
132133
DiagnosticConsumer &DiagConsumer);
133134

134-
void collectAvailableRefactorings(
135-
SourceFile *SF, RangeConfig Range, bool &RangeStartMayNeedRename,
136-
llvm::SmallVectorImpl<RefactoringKind> &Kinds,
137-
llvm::ArrayRef<DiagnosticConsumer *> DiagConsumers);
138-
139-
void collectAvailableRefactorings(ResolvedCursorInfoPtr CursorInfo,
140-
llvm::SmallVectorImpl<RefactoringKind> &Kinds,
141-
bool ExcludeRename);
142-
143-
/// Stores information about the reference that rename availability is being
144-
/// queried on.
145-
struct RenameRefInfo {
146-
SourceFile *SF; ///< The source file containing the reference.
147-
SourceLoc Loc; ///< The reference's source location.
148-
bool IsArgLabel; ///< Whether Loc is on an arg label, rather than base name.
149-
};
135+
SmallVector<RefactorAvailabilityInfo, 0>
136+
collectRefactorings(SourceFile *SF, RangeConfig Range,
137+
bool &RangeStartMayNeedRename,
138+
llvm::ArrayRef<DiagnosticConsumer *> DiagConsumers);
150139

151-
Optional<RenameAvailabilityInfo>
152-
renameAvailabilityInfo(const ValueDecl *VD, Optional<RenameRefInfo> RefInfo);
140+
SmallVector<RefactorAvailabilityInfo, 0>
141+
collectRefactorings(ResolvedCursorInfoPtr CursorInfo, bool ExcludeRename);
153142

154143
} // namespace ide
155144
} // namespace swift

lib/AST/Module.cpp

Lines changed: 70 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,49 @@ bool ModuleDecl::isInGeneratedBuffer(SourceLoc loc) {
816816
return file->Kind == SourceFileKind::MacroExpansion;
817817
}
818818

819+
std::pair<unsigned, SourceLoc>
820+
ModuleDecl::getOriginalLocation(SourceLoc loc) const {
821+
assert(loc.isValid());
822+
823+
SourceManager &SM = getASTContext().SourceMgr;
824+
unsigned bufferID = SM.findBufferContainingLoc(loc);
825+
826+
SourceLoc startLoc = loc;
827+
unsigned startBufferID = bufferID;
828+
while (Optional<GeneratedSourceInfo> info =
829+
SM.getGeneratedSourceInfo(bufferID)) {
830+
switch (info->kind) {
831+
case GeneratedSourceInfo::ExpressionMacroExpansion:
832+
case GeneratedSourceInfo::FreestandingDeclMacroExpansion:
833+
case GeneratedSourceInfo::AccessorMacroExpansion:
834+
case GeneratedSourceInfo::MemberAttributeMacroExpansion:
835+
case GeneratedSourceInfo::MemberMacroExpansion:
836+
case GeneratedSourceInfo::PeerMacroExpansion:
837+
case GeneratedSourceInfo::ConformanceMacroExpansion: {
838+
// Location was within a macro expansion, return the expansion site, not
839+
// the insertion location.
840+
if (info->attachedMacroCustomAttr) {
841+
loc = info->attachedMacroCustomAttr->getLocation();
842+
} else {
843+
ASTNode expansionNode = ASTNode::getFromOpaqueValue(info->astNode);
844+
loc = expansionNode.getStartLoc();
845+
}
846+
bufferID = SM.findBufferContainingLoc(loc);
847+
break;
848+
}
849+
case GeneratedSourceInfo::ReplacedFunctionBody:
850+
// There's not really any "original" location for locations within
851+
// replaced function bodies. The body is actually different code to the
852+
// original file.
853+
case GeneratedSourceInfo::PrettyPrinted:
854+
// No original location, return the original buffer/location
855+
return {startBufferID, startLoc};
856+
}
857+
}
858+
859+
return {bufferID, loc};
860+
}
861+
819862
ArrayRef<SourceFile *>
820863
PrimarySourceFilesRequest::evaluate(Evaluator &evaluator,
821864
ModuleDecl *mod) const {
@@ -1353,14 +1396,24 @@ SourceFile::getExternalRawLocsForDecl(const Decl *D) const {
13531396
return None;
13541397
}
13551398

1356-
SourceLoc Loc = D->getLoc(/*SerializedOK=*/false);
1357-
if (Loc.isInvalid())
1399+
SourceLoc MainLoc = D->getLoc(/*SerializedOK=*/false);
1400+
if (MainLoc.isInvalid())
13581401
return None;
13591402

1403+
// TODO: Rather than grabbing the location of the macro expansion, we should
1404+
// instead add the generated buffer tree - that would need to include source
1405+
// if we want to be able to retrieve documentation within generated buffers.
13601406
SourceManager &SM = getASTContext().SourceMgr;
1361-
auto BufferID = SM.findBufferContainingLoc(Loc);
1407+
bool InGeneratedBuffer =
1408+
!SM.rangeContainsTokenLoc(SM.getRangeForBuffer(BufferID), MainLoc);
1409+
if (InGeneratedBuffer) {
1410+
int UnderlyingBufferID;
1411+
std::tie(UnderlyingBufferID, MainLoc) =
1412+
D->getModuleContext()->getOriginalLocation(MainLoc);
1413+
if (BufferID != UnderlyingBufferID)
1414+
return None;
1415+
}
13621416

1363-
ExternalSourceLocs::RawLocs Result;
13641417
auto setLoc = [&](ExternalSourceLocs::RawLoc &RawLoc, SourceLoc Loc) {
13651418
if (!Loc.isValid())
13661419
return;
@@ -1379,15 +1432,20 @@ SourceFile::getExternalRawLocsForDecl(const Decl *D) const {
13791432
RawLoc.Directive.Name = StringRef(VF->Name);
13801433
};
13811434

1435+
ExternalSourceLocs::RawLocs Result;
1436+
13821437
Result.SourceFilePath = SM.getIdentifierForBuffer(BufferID);
1383-
for (const auto &SRC : D->getRawComment(/*SerializedOK=*/false).Comments) {
1384-
Result.DocRanges.emplace_back(ExternalSourceLocs::RawLoc(),
1385-
SRC.Range.getByteLength());
1386-
setLoc(Result.DocRanges.back().first, SRC.Range.getStart());
1387-
}
1388-
setLoc(Result.Loc, D->getLoc(/*SerializedOK=*/false));
1389-
setLoc(Result.StartLoc, D->getStartLoc());
1390-
setLoc(Result.EndLoc, D->getEndLoc());
1438+
setLoc(Result.Loc, MainLoc);
1439+
if (!InGeneratedBuffer) {
1440+
for (const auto &SRC : D->getRawComment(/*SerializedOK=*/false).Comments) {
1441+
Result.DocRanges.emplace_back(ExternalSourceLocs::RawLoc(),
1442+
SRC.Range.getByteLength());
1443+
setLoc(Result.DocRanges.back().first, SRC.Range.getStart());
1444+
}
1445+
setLoc(Result.StartLoc, D->getStartLoc());
1446+
setLoc(Result.EndLoc, D->getEndLoc());
1447+
}
1448+
13911449
return Result;
13921450
}
13931451

0 commit comments

Comments
 (0)