Skip to content

Commit f930b46

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 dde391e commit f930b46

File tree

6 files changed

+121
-84
lines changed

6 files changed

+121
-84
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: 29 additions & 31 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
ResolvedValueRefCursorInfoPtr CursorInfo = new ResolvedValueRefCursorInfo(
329329
new ResolvedCursorInfo(SrcFile), DeclResult->getDecl(),
@@ -333,12 +333,12 @@ class CursorInfoDoneParsingCallback : public IDEInspectionCallbacks {
333333
CursorInfo->setLoc(RequestedLoc);
334334
CursorInfo->setShorthandShadowedDecls(
335335
Finder.getShorthandShadowedDecls(DeclResult->getDecl()));
336-
return CursorInfo;
336+
return {CursorInfo};
337337
}
338338

339-
ResolvedCursorInfoPtr getExprResult(NodeFinderExprResult *ExprResult,
340-
SourceFile *SrcFile,
341-
NodeFinder &Finder) const {
339+
SmallVector<ResolvedCursorInfoPtr>
340+
getExprResult(NodeFinderExprResult *ExprResult, SourceFile *SrcFile,
341+
NodeFinder &Finder) const {
342342
Expr *E = ExprResult->getExpr();
343343
DeclContext *DC = ExprResult->getDeclContext();
344344

@@ -351,7 +351,7 @@ class CursorInfoDoneParsingCallback : public IDEInspectionCallbacks {
351351

352352
if (Callback.getResults().empty()) {
353353
// No results.
354-
return nullptr;
354+
return {};
355355
}
356356

357357
for (auto Info : Callback.getResults()) {
@@ -360,34 +360,32 @@ class CursorInfoDoneParsingCallback : public IDEInspectionCallbacks {
360360
typeCheckDeclAndParentClosures(Info.ReferencedDecl);
361361
}
362362

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

370-
auto Res = Callback.getResults()[0];
371-
ResolvedValueRefCursorInfoPtr CursorInfo = new ResolvedValueRefCursorInfo(
372-
new ResolvedCursorInfo(SrcFile), Res.ReferencedDecl,
373-
/*CtorTyRef=*/nullptr,
374-
/*ExtTyRef=*/nullptr, /*IsRef=*/true, /*Ty=*/Type(),
375-
/*ContainerType=*/Res.BaseType);
376-
CursorInfo->setLoc(RequestedLoc);
377-
CursorInfo->setIsDynamic(Res.IsDynamicRef);
378-
if (Res.IsDynamicRef && Res.BaseType) {
379-
if (auto ReceiverType = Res.BaseType->getAnyNominal()) {
380-
CursorInfo->setReceiverTypes({ReceiverType});
381-
} else if (auto MT = Res.BaseType->getAs<AnyMetatypeType>()) {
382-
// Look through metatypes to get the nominal type decl.
383-
if (auto ReceiverType = MT->getInstanceType()->getAnyNominal()) {
365+
SmallVector<ResolvedCursorInfoPtr> Results;
366+
for (auto Res : Callback.getResults()) {
367+
ResolvedValueRefCursorInfoPtr CursorInfo = new ResolvedValueRefCursorInfo(
368+
new ResolvedCursorInfo(SrcFile), Res.ReferencedDecl,
369+
/*CtorTyRef=*/nullptr,
370+
/*ExtTyRef=*/nullptr, /*IsRef=*/true, /*Ty=*/Type(),
371+
/*ContainerType=*/Res.BaseType);
372+
CursorInfo->setLoc(RequestedLoc);
373+
CursorInfo->setIsDynamic(Res.IsDynamicRef);
374+
if (Res.IsDynamicRef && Res.BaseType) {
375+
if (auto ReceiverType = Res.BaseType->getAnyNominal()) {
384376
CursorInfo->setReceiverTypes({ReceiverType});
377+
} else if (auto MT = Res.BaseType->getAs<AnyMetatypeType>()) {
378+
// Look through metatypes to get the nominal type decl.
379+
if (auto ReceiverType = MT->getInstanceType()->getAnyNominal()) {
380+
CursorInfo->setReceiverTypes({ReceiverType});
381+
}
385382
}
386383
}
384+
CursorInfo->setShorthandShadowedDecls(
385+
Finder.getShorthandShadowedDecls(Res.ReferencedDecl));
386+
Results.push_back(CursorInfo);
387387
}
388-
CursorInfo->setShorthandShadowedDecls(
389-
Finder.getShorthandShadowedDecls(Res.ReferencedDecl));
390-
return CursorInfo;
388+
return Results;
391389
}
392390

393391
void doneParsing(SourceFile *SrcFile) override {
@@ -400,7 +398,7 @@ class CursorInfoDoneParsingCallback : public IDEInspectionCallbacks {
400398
if (!Result) {
401399
return;
402400
}
403-
ResolvedCursorInfoPtr CursorInfo;
401+
SmallVector<ResolvedCursorInfoPtr> CursorInfo;
404402
switch (Result->getKind()) {
405403
case NodeFinderResultKind::Decl:
406404
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)