Skip to content

Commit 4584c59

Browse files
committed
[IDE] Support reporting multiple cursor results
This hooks up the cursor info infrastructure to be able to pass through multiple, ambiguous results. There are still minor issues that cause solver-based cursor info to not actually report the ambiguous results but those will be fixed in a follow-up PR.
1 parent f210a8e commit 4584c59

File tree

6 files changed

+122
-83
lines changed

6 files changed

+122
-83
lines changed

include/swift/IDE/CursorInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace ide {
2626
class CursorInfoConsumer {
2727
public:
2828
virtual ~CursorInfoConsumer() {}
29-
virtual void handleResults(ResolvedCursorInfoPtr) = 0;
29+
virtual void handleResults(SmallVector<ResolvedCursorInfoPtr>) = 0;
3030
};
3131

3232
/// Create a factory for code completion callbacks.

include/swift/IDETool/IDEInspectionInstance.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ struct ConformingMethodListResults {
8181

8282
/// The results returned from \c IDEInspectionInstance::cursorInfo.
8383
struct CursorInfoResults {
84-
/// The actual results. If \c nullptr, no results were found.
85-
ResolvedCursorInfoPtr Result;
84+
/// The actual results.
85+
SmallVector<ResolvedCursorInfoPtr> ResolvedCursorInfos;
8686
/// Whether an AST was reused to produce the results.
8787
bool DidReuseAST;
8888
};

lib/IDE/CursorInfo.cpp

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -321,9 +321,9 @@ class CursorInfoDoneParsingCallback : public IDEInspectionCallbacks {
321321
: IDEInspectionCallbacks(P), Consumer(Consumer),
322322
RequestedLoc(RequestedLoc) {}
323323

324-
ResolvedCursorInfoPtr getDeclResult(NodeFinderDeclResult *DeclResult,
325-
SourceFile *SrcFile,
326-
NodeFinder &Finder) const {
324+
SmallVector<ResolvedCursorInfoPtr>
325+
getDeclResult(NodeFinderDeclResult *DeclResult, SourceFile *SrcFile,
326+
NodeFinder &Finder) const {
327327
typeCheckDeclAndParentClosures(DeclResult->getDecl());
328328
return new ResolvedValueRefCursorInfo(
329329
SrcFile, RequestedLoc, DeclResult->getDecl(),
@@ -335,11 +335,12 @@ class CursorInfoDoneParsingCallback : public IDEInspectionCallbacks {
335335
/*IsDynamic=*/false,
336336
/*ReceiverTypes=*/{},
337337
Finder.getShorthandShadowedDecls(DeclResult->getDecl()));
338+
return {CursorInfo};
338339
}
339340

340-
ResolvedCursorInfoPtr getExprResult(NodeFinderExprResult *ExprResult,
341-
SourceFile *SrcFile,
342-
NodeFinder &Finder) const {
341+
SmallVector<ResolvedCursorInfoPtr>
342+
getExprResult(NodeFinderExprResult *ExprResult, SourceFile *SrcFile,
343+
NodeFinder &Finder) const {
343344
Expr *E = ExprResult->getExpr();
344345
DeclContext *DC = ExprResult->getDeclContext();
345346

@@ -352,7 +353,7 @@ class CursorInfoDoneParsingCallback : public IDEInspectionCallbacks {
352353

353354
if (Callback.getResults().empty()) {
354355
// No results.
355-
return nullptr;
356+
return {};
356357
}
357358

358359
for (auto Info : Callback.getResults()) {
@@ -361,34 +362,33 @@ class CursorInfoDoneParsingCallback : public IDEInspectionCallbacks {
361362
typeCheckDeclAndParentClosures(Info.ReferencedDecl);
362363
}
363364

364-
if (Callback.getResults().size() != 1) {
365-
// FIXME: We need to be able to report multiple results.
366-
return nullptr;
367-
}
368-
369365
// Deliver results
370366

371-
auto Res = Callback.getResults()[0];
372-
SmallVector<NominalTypeDecl *> ReceiverTypes;
373-
if (Res.IsDynamicRef && Res.BaseType) {
374-
if (auto ReceiverType = Res.BaseType->getAnyNominal()) {
375-
ReceiverTypes = {ReceiverType};
376-
} else if (auto MT = Res.BaseType->getAs<AnyMetatypeType>()) {
377-
// Look through metatypes to get the nominal type decl.
378-
if (auto ReceiverType = MT->getInstanceType()->getAnyNominal()) {
367+
SmallVector<ResolvedCursorInfoPtr> Results;
368+
for (auto Res : Callback.getResults()) {
369+
SmallVector<NominalTypeDecl *> ReceiverTypes;
370+
if (Res.IsDynamicRef && Res.BaseType) {
371+
if (auto ReceiverType = Res.BaseType->getAnyNominal()) {
379372
ReceiverTypes = {ReceiverType};
373+
} else if (auto MT = Res.BaseType->getAs<AnyMetatypeType>()) {
374+
// Look through metatypes to get the nominal type decl.
375+
if (auto ReceiverType = MT->getInstanceType()->getAnyNominal()) {
376+
ReceiverTypes = {ReceiverType};
377+
}
380378
}
381379
}
382-
}
383380

384-
return new ResolvedValueRefCursorInfo(
385-
SrcFile, RequestedLoc, Res.ReferencedDecl,
386-
/*CtorTyRef=*/nullptr,
387-
/*ExtTyRef=*/nullptr, /*IsRef=*/true, /*Ty=*/Type(),
388-
/*ContainerType=*/Res.BaseType,
389-
/*CustomAttrRef=*/None,
390-
/*IsKeywordArgument=*/false, Res.IsDynamicRef, ReceiverTypes,
391-
Finder.getShorthandShadowedDecls(Res.ReferencedDecl));
381+
auto CursorInfo = new ResolvedValueRefCursorInfo(
382+
SrcFile, RequestedLoc, Res.ReferencedDecl,
383+
/*CtorTyRef=*/nullptr,
384+
/*ExtTyRef=*/nullptr, /*IsRef=*/true, /*Ty=*/Type(),
385+
/*ContainerType=*/Res.BaseType,
386+
/*CustomAttrRef=*/None,
387+
/*IsKeywordArgument=*/false, Res.IsDynamicRef, ReceiverTypes,
388+
Finder.getShorthandShadowedDecls(Res.ReferencedDecl));
389+
Results.push_back(CursorInfo);
390+
}
391+
return Results;
392392
}
393393

394394
void doneParsing(SourceFile *SrcFile) override {
@@ -401,7 +401,7 @@ class CursorInfoDoneParsingCallback : public IDEInspectionCallbacks {
401401
if (!Result) {
402402
return;
403403
}
404-
ResolvedCursorInfoPtr CursorInfo;
404+
SmallVector<ResolvedCursorInfoPtr> CursorInfo;
405405
switch (Result->getKind()) {
406406
case NodeFinderResultKind::Decl:
407407
CursorInfo = getDeclResult(cast<NodeFinderDeclResult>(Result.get()),

lib/IDETool/IDEInspectionInstance.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,7 @@ void swift::ide::IDEInspectionInstance::cursorInfo(
827827
: ReusingASTContext(ReusingASTContext),
828828
CancellationFlag(CancellationFlag), Callback(Callback) {}
829829

830-
void handleResults(ResolvedCursorInfoPtr result) override {
830+
void handleResults(SmallVector<ResolvedCursorInfoPtr> result) override {
831831
HandleResultsCalled = true;
832832
if (CancellationFlag &&
833833
CancellationFlag->load(std::memory_order_relaxed)) {
@@ -852,8 +852,8 @@ void swift::ide::IDEInspectionInstance::cursorInfo(
852852
ide::makeCursorInfoCallbacksFactory(Consumer, RequestedLoc));
853853

854854
if (!Result.DidFindIDEInspectionTarget) {
855-
return DeliverTransformed(ResultType::success(
856-
{/*Results=*/nullptr, Result.DidReuseAST}));
855+
return DeliverTransformed(
856+
ResultType::success({/*Results=*/{}, Result.DidReuseAST}));
857857
}
858858

859859
performIDEInspectionSecondPass(
@@ -863,8 +863,8 @@ void swift::ide::IDEInspectionInstance::cursorInfo(
863863
// pass, we didn't receive any results. To make sure Callback
864864
// gets called exactly once, call it manually with no results
865865
// here.
866-
DeliverTransformed(ResultType::success(
867-
{/*Results=*/nullptr, Result.DidReuseAST}));
866+
DeliverTransformed(
867+
ResultType::success({/*Results=*/{}, Result.DidReuseAST}));
868868
}
869869
},
870870
Callback);

tools/SourceKit/include/SourceKit/Core/LangSupport.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,11 +586,14 @@ struct CursorInfoData {
586586
// will be empty). Clients can potentially use this to show a diagnostic
587587
// message to the user in lieu of using the empty response.
588588
StringRef InternalDiagnostic;
589-
llvm::ArrayRef<CursorSymbolInfo> Symbols;
589+
llvm::SmallVector<CursorSymbolInfo, 1> Symbols;
590590
/// All available actions on the code under cursor.
591-
llvm::ArrayRef<RefactoringInfo> AvailableActions;
591+
llvm::SmallVector<RefactoringInfo, 8> AvailableActions;
592592
/// Whether the ASTContext was reused for this cursor info.
593593
bool DidReuseAST = false;
594+
/// An allocator that can be used to allocate data that is referenced by this
595+
/// \c CursorInfoData.
596+
llvm::BumpPtrAllocator Allocator;
594597

595598
void print(llvm::raw_ostream &OS, std::string Indentation) const {
596599
OS << Indentation << "CursorInfoData" << '\n';

0 commit comments

Comments
 (0)