Skip to content

Commit 05b59d1

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 3644d98 commit 05b59d1

File tree

6 files changed

+123
-85
lines changed

6 files changed

+123
-85
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
@@ -328,9 +328,9 @@ class CursorInfoDoneParsingCallback : public IDEInspectionCallbacks {
328328
: IDEInspectionCallbacks(P), Consumer(Consumer),
329329
RequestedLoc(RequestedLoc) {}
330330

331-
ResolvedCursorInfoPtr getDeclResult(NodeFinderDeclResult *DeclResult,
332-
SourceFile *SrcFile,
333-
NodeFinder &Finder) const {
331+
SmallVector<ResolvedCursorInfoPtr>
332+
getDeclResult(NodeFinderDeclResult *DeclResult, SourceFile *SrcFile,
333+
NodeFinder &Finder) const {
334334
typeCheckDeclAndParentClosures(DeclResult->getDecl());
335335
return new ResolvedValueRefCursorInfo(
336336
SrcFile, RequestedLoc, DeclResult->getDecl(),
@@ -342,11 +342,12 @@ class CursorInfoDoneParsingCallback : public IDEInspectionCallbacks {
342342
/*IsDynamic=*/false,
343343
/*ReceiverTypes=*/{},
344344
Finder.getShorthandShadowedDecls(DeclResult->getDecl()));
345+
return {CursorInfo};
345346
}
346347

347-
ResolvedCursorInfoPtr getExprResult(NodeFinderExprResult *ExprResult,
348-
SourceFile *SrcFile,
349-
NodeFinder &Finder) const {
348+
SmallVector<ResolvedCursorInfoPtr>
349+
getExprResult(NodeFinderExprResult *ExprResult, SourceFile *SrcFile,
350+
NodeFinder &Finder) const {
350351
Expr *E = ExprResult->getExpr();
351352
DeclContext *DC = ExprResult->getDeclContext();
352353

@@ -359,7 +360,7 @@ class CursorInfoDoneParsingCallback : public IDEInspectionCallbacks {
359360

360361
if (Callback.getResults().empty()) {
361362
// No results.
362-
return nullptr;
363+
return {};
363364
}
364365

365366
for (auto Info : Callback.getResults()) {
@@ -368,34 +369,33 @@ class CursorInfoDoneParsingCallback : public IDEInspectionCallbacks {
368369
typeCheckDeclAndParentClosures(Info.ReferencedDecl);
369370
}
370371

371-
if (Callback.getResults().size() != 1) {
372-
// FIXME: We need to be able to report multiple results.
373-
return nullptr;
374-
}
375-
376372
// Deliver results
377373

378-
auto Res = Callback.getResults()[0];
379-
SmallVector<NominalTypeDecl *> ReceiverTypes;
380-
if (Res.IsDynamicRef && Res.BaseType) {
381-
if (auto ReceiverType = Res.BaseType->getAnyNominal()) {
382-
ReceiverTypes = {ReceiverType};
383-
} else if (auto MT = Res.BaseType->getAs<AnyMetatypeType>()) {
384-
// Look through metatypes to get the nominal type decl.
385-
if (auto ReceiverType = MT->getInstanceType()->getAnyNominal()) {
374+
SmallVector<ResolvedCursorInfoPtr> Results;
375+
for (auto Res : Callback.getResults()) {
376+
SmallVector<NominalTypeDecl *> ReceiverTypes;
377+
if (Res.IsDynamicRef && Res.BaseType) {
378+
if (auto ReceiverType = Res.BaseType->getAnyNominal()) {
386379
ReceiverTypes = {ReceiverType};
380+
} else if (auto MT = Res.BaseType->getAs<AnyMetatypeType>()) {
381+
// Look through metatypes to get the nominal type decl.
382+
if (auto ReceiverType = MT->getInstanceType()->getAnyNominal()) {
383+
ReceiverTypes = {ReceiverType};
384+
}
387385
}
388386
}
389-
}
390387

391-
return new ResolvedValueRefCursorInfo(
392-
SrcFile, RequestedLoc, Res.ReferencedDecl,
393-
/*CtorTyRef=*/nullptr,
394-
/*ExtTyRef=*/nullptr, /*IsRef=*/true, /*Ty=*/Type(),
395-
/*ContainerType=*/Res.BaseType,
396-
/*CustomAttrRef=*/None,
397-
/*IsKeywordArgument=*/false, Res.IsDynamicRef, ReceiverTypes,
398-
Finder.getShorthandShadowedDecls(Res.ReferencedDecl));
388+
auto CursorInfo = new ResolvedValueRefCursorInfo(
389+
SrcFile, RequestedLoc, Res.ReferencedDecl,
390+
/*CtorTyRef=*/nullptr,
391+
/*ExtTyRef=*/nullptr, /*IsRef=*/true, /*Ty=*/Type(),
392+
/*ContainerType=*/Res.BaseType,
393+
/*CustomAttrRef=*/None,
394+
/*IsKeywordArgument=*/false, Res.IsDynamicRef, ReceiverTypes,
395+
Finder.getShorthandShadowedDecls(Res.ReferencedDecl));
396+
Results.push_back(CursorInfo);
397+
}
398+
return Results;
399399
}
400400

401401
void doneParsing(SourceFile *SrcFile) override {
@@ -408,7 +408,7 @@ class CursorInfoDoneParsingCallback : public IDEInspectionCallbacks {
408408
if (!Result) {
409409
return;
410410
}
411-
ResolvedCursorInfoPtr CursorInfo;
411+
SmallVector<ResolvedCursorInfoPtr> CursorInfo;
412412
switch (Result->getKind()) {
413413
case NodeFinderResultKind::Decl:
414414
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)