Skip to content

Commit 93ec785

Browse files
authored
Merge pull request #66907 from bnbarham/fix-reuse-test
[CursorInfo] Pass primary path to allow comparing previous ASTs
2 parents b1b1698 + ab95dba commit 93ec785

File tree

7 files changed

+105
-62
lines changed

7 files changed

+105
-62
lines changed

test/SourceKit/CursorInfo/cursor_after_edit.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,4 @@
88
// RUN: %sourcekitd-test \
99
// RUN: -req=open -text-input %t/empty.swift %t/func.swift -- %t/func.swift == \
1010
// RUN: -req=edit -offset=0 -length=0 -replace="func foo() {}" -req-opts=enablesyntaxmap=0,enablesubstructure=0,enablediagnostics=0 %t/func.swift -- %t/func.swift == \
11-
// RUN: -req=cursor -offset=5 %t/func.swift -- %t/func.swift == \
12-
// RUN: -req=edit -offset=0 -length=0 -replace="// some comment\n" -req-opts=enablesyntaxmap=0,enablesubstructure=0,enablediagnostics=0 %t/func.swift -- %t/func.swift == \
13-
// RUN: -req=cursor -offset=21 %t/func.swift -- %t/func.swift
11+
// RUN: -req=cursor -offset=5 %t/func.swift -- %t/func.swift
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: touch %t/empty.swift %t/func.swift
3+
4+
// Check that cursor info re-uses the underlying AST if it's able to based
5+
// off edit snapshots.
6+
7+
// RUN: %sourcekitd-test \
8+
// RUN: -shell -- echo '## State 1' == \
9+
// RUN: -req=open -text-input %t/empty.swift %t/func.swift -- %t/func.swift == \
10+
// RUN: -req=edit -offset=0 -length=0 -replace="func foo() {}" -req-opts=enablesyntaxmap=0,enablesubstructure=0,enablediagnostics=0,syntactic_only=1 %t/func.swift -- %t/func.swift == \
11+
// RUN: -req=cursor -offset=5 %t/func.swift -- %t/func.swift == \
12+
// RUN: -shell -- echo '## State 2' == \
13+
// RUN: -req=edit -offset=0 -length=0 -replace="/* some comment */ " -req-opts=enablesyntaxmap=0,enablesubstructure=0,enablediagnostics=0,syntactic_only=1 %t/func.swift -- %t/func.swift == \
14+
// RUN: -req=cursor -offset=24 %t/func.swift -- %t/func.swift | %FileCheck %s
15+
16+
// CHECK: ## State 1
17+
// CHECK: source.lang.swift.decl.function.free
18+
// CHECK: foo()
19+
// CHECK: DID REUSE AST CONTEXT: 0
20+
// CHECK: ## State 2
21+
// CHECK: source.lang.swift.decl.function.free
22+
// CHECK: foo()
23+
// CHECK: DID REUSE AST CONTEXT: 1

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,8 @@ class LangSupport {
10861086
Receiver) = 0;
10871087

10881088
virtual void
1089-
getNameInfo(StringRef Filename, unsigned Offset, NameTranslatingInfo &Input,
1089+
getNameInfo(StringRef PrimaryFilePath, StringRef InputBufferName,
1090+
unsigned Offset, NameTranslatingInfo &Input,
10901091
ArrayRef<const char *> Args,
10911092
SourceKitCancellationToken CancellationToken,
10921093
std::function<void(const RequestResult<NameTranslatingInfo> &)>

tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -660,8 +660,9 @@ class SwiftLangSupport : public LangSupport {
660660
Receiver) override;
661661

662662
void getNameInfo(
663-
StringRef Filename, unsigned Offset, NameTranslatingInfo &Input,
664-
ArrayRef<const char *> Args, SourceKitCancellationToken CancellationToken,
663+
StringRef PrimaryFilePath, StringRef InputBufferName, unsigned Offset,
664+
NameTranslatingInfo &Input, ArrayRef<const char *> Args,
665+
SourceKitCancellationToken CancellationToken,
665666
std::function<void(const RequestResult<NameTranslatingInfo> &)> Receiver)
666667
override;
667668

tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,7 +1392,8 @@ class CursorRangeInfoConsumer : public SwiftASTConsumer {
13921392
protected:
13931393
SwiftLangSupport &Lang;
13941394
SwiftInvocationRef ASTInvok;
1395-
std::string InputFile;
1395+
std::string PrimaryFilePath;
1396+
std::string InputBufferName;
13961397
unsigned Offset;
13971398
unsigned Length;
13981399

@@ -1408,11 +1409,13 @@ class CursorRangeInfoConsumer : public SwiftASTConsumer {
14081409
}
14091410

14101411
public:
1411-
CursorRangeInfoConsumer(StringRef InputFile, unsigned Offset, unsigned Length,
1412+
CursorRangeInfoConsumer(StringRef PrimaryFilePath, StringRef InputBufferName,
1413+
unsigned Offset, unsigned Length,
14121414
SwiftLangSupport &Lang, SwiftInvocationRef ASTInvok,
14131415
bool TryExistingAST, bool CancelOnSubsequentRequest)
1414-
: Lang(Lang), ASTInvok(ASTInvok), InputFile(InputFile.str()),
1415-
Offset(Offset), Length(Length), TryExistingAST(TryExistingAST),
1416+
: Lang(Lang), ASTInvok(ASTInvok), PrimaryFilePath(PrimaryFilePath.str()),
1417+
InputBufferName(InputBufferName.str()), Offset(Offset), Length(Length),
1418+
TryExistingAST(TryExistingAST),
14161419
CancelOnSubsequentRequest(CancelOnSubsequentRequest) {}
14171420

14181421
bool canUseASTWithSnapshots(ArrayRef<ImmutableTextSnapshotRef> Snapshots) override {
@@ -1429,7 +1432,7 @@ class CursorRangeInfoConsumer : public SwiftASTConsumer {
14291432

14301433
ImmutableTextSnapshotRef InputSnap;
14311434
if (auto EditorDoc = Lang.getEditorDocuments()->findByPath(
1432-
InputFile, /*IsRealpath=*/true))
1435+
PrimaryFilePath, /*IsRealpath=*/true))
14331436
InputSnap = EditorDoc->getLatestSnapshot();
14341437
if (!InputSnap)
14351438
return false;
@@ -1498,8 +1501,8 @@ static SourceFile *retrieveInputFile(StringRef inputBufferName,
14981501
}
14991502

15001503
static void resolveCursor(
1501-
SwiftLangSupport &Lang, StringRef InputFile, unsigned Offset,
1502-
unsigned Length, bool Actionables, bool SymbolGraph,
1504+
SwiftLangSupport &Lang, StringRef PrimaryFile, StringRef InputBufferName,
1505+
unsigned Offset, unsigned Length, bool Actionables, bool SymbolGraph,
15031506
SwiftInvocationRef Invok, bool TryExistingAST,
15041507
bool CancelOnSubsequentRequest,
15051508
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fileSystem,
@@ -1516,20 +1519,22 @@ static void resolveCursor(
15161519

15171520
public:
15181521
CursorInfoConsumer(
1519-
StringRef InputFile, unsigned Offset, unsigned Length, bool Actionables,
1520-
bool SymbolGraph, SwiftLangSupport &Lang, SwiftInvocationRef ASTInvok,
1522+
StringRef PrimaryFile, StringRef InputBufferName, unsigned Offset,
1523+
unsigned Length, bool Actionables, bool SymbolGraph,
1524+
SwiftLangSupport &Lang, SwiftInvocationRef ASTInvok,
15211525
bool TryExistingAST, bool CancelOnSubsequentRequest,
15221526
SourceKitCancellationToken CancellationToken,
15231527
std::function<void(const RequestResult<CursorInfoData> &)> Receiver)
1524-
: CursorRangeInfoConsumer(InputFile, Offset, Length, Lang, ASTInvok,
1525-
TryExistingAST, CancelOnSubsequentRequest),
1528+
: CursorRangeInfoConsumer(PrimaryFile, InputBufferName, Offset, Length,
1529+
Lang, ASTInvok, TryExistingAST,
1530+
CancelOnSubsequentRequest),
15261531
Actionables(Actionables), SymbolGraph(SymbolGraph),
15271532
CancellationToken(CancellationToken), Receiver(std::move(Receiver)) {}
15281533

15291534
void handlePrimaryAST(ASTUnitRef AstUnit) override {
15301535
auto &CompIns = AstUnit->getCompilerInstance();
15311536

1532-
SourceFile *SF = retrieveInputFile(InputFile, CompIns);
1537+
SourceFile *SF = retrieveInputFile(InputBufferName, CompIns);
15331538
if (!SF) {
15341539
Receiver(RequestResult<CursorInfoData>::fromError(
15351540
"Unable to find input file"));
@@ -1604,14 +1609,14 @@ static void resolveCursor(
16041609
cast<ResolvedValueRefCursorInfo>(CursorInfo), Actionables,
16051610
SymbolGraph, Actions, Lang, CompInvok, Diagnostic,
16061611
getPreviousASTSnaps(),
1607-
/*DidReuseAST=*/false, Receiver);
1612+
/*DidReuseAST=*/!getPreviousASTSnaps().empty(), Receiver);
16081613
if (!Success) {
16091614
if (!getPreviousASTSnaps().empty()) {
16101615
// Attempt again using the up-to-date AST.
1611-
resolveCursor(Lang, InputFile, Offset, Length, Actionables,
1612-
SymbolGraph, ASTInvok, /*TryExistingAST=*/false,
1613-
CancelOnSubsequentRequest, SM.getFileSystem(),
1614-
CancellationToken, Receiver);
1616+
resolveCursor(Lang, PrimaryFilePath, InputBufferName, Offset,
1617+
Length, Actionables, SymbolGraph, ASTInvok,
1618+
/*TryExistingAST=*/false, CancelOnSubsequentRequest,
1619+
SM.getFileSystem(), CancellationToken, Receiver);
16151620
} else {
16161621
CursorInfoData Info;
16171622
Info.InternalDiagnostic = Diagnostic;
@@ -1662,8 +1667,9 @@ static void resolveCursor(
16621667
};
16631668

16641669
auto Consumer = std::make_shared<CursorInfoConsumer>(
1665-
InputFile, Offset, Length, Actionables, SymbolGraph, Lang, Invok,
1666-
TryExistingAST, CancelOnSubsequentRequest, CancellationToken, Receiver);
1670+
PrimaryFile, InputBufferName, Offset, Length, Actionables, SymbolGraph,
1671+
Lang, Invok, TryExistingAST, CancelOnSubsequentRequest, CancellationToken,
1672+
Receiver);
16671673

16681674
/// FIXME: When request cancellation is implemented and Xcode adopts it,
16691675
/// don't use 'OncePerASTToken'.
@@ -1710,8 +1716,9 @@ static void computeDiagnostics(
17101716
}
17111717

17121718
static void resolveName(
1713-
SwiftLangSupport &Lang, StringRef InputFile, unsigned Offset,
1714-
SwiftInvocationRef Invok, bool TryExistingAST, NameTranslatingInfo &Input,
1719+
SwiftLangSupport &Lang, StringRef PrimaryFilePath,
1720+
StringRef InputBufferName, unsigned Offset, SwiftInvocationRef Invok,
1721+
bool TryExistingAST, NameTranslatingInfo &Input,
17151722
SourceKitCancellationToken CancellationToken,
17161723
std::function<void(const RequestResult<NameTranslatingInfo> &)> Receiver) {
17171724
assert(Invok);
@@ -1723,21 +1730,22 @@ static void resolveName(
17231730

17241731
public:
17251732
NameInfoConsumer(
1726-
StringRef InputFile, unsigned Offset, SwiftLangSupport &Lang,
1727-
SwiftInvocationRef ASTInvok, bool TryExistingAST,
1728-
NameTranslatingInfo Input, SourceKitCancellationToken CancellationToken,
1733+
StringRef PrimaryFilePath, StringRef InputBufferName, unsigned Offset,
1734+
SwiftLangSupport &Lang, SwiftInvocationRef ASTInvok,
1735+
bool TryExistingAST, NameTranslatingInfo Input,
1736+
SourceKitCancellationToken CancellationToken,
17291737
std::function<void(const RequestResult<NameTranslatingInfo> &)>
17301738
Receiver)
1731-
: CursorRangeInfoConsumer(InputFile, Offset, 0, Lang, ASTInvok,
1732-
TryExistingAST,
1739+
: CursorRangeInfoConsumer(PrimaryFilePath, InputBufferName, Offset, 0,
1740+
Lang, ASTInvok, TryExistingAST,
17331741
/*CancelOnSubsequentRequest=*/false),
17341742
Input(std::move(Input)), CancellationToken(CancellationToken),
17351743
Receiver(std::move(Receiver)) {}
17361744

17371745
void handlePrimaryAST(ASTUnitRef AstUnit) override {
17381746
auto &CompIns = AstUnit->getCompilerInstance();
17391747

1740-
SourceFile *SF = retrieveInputFile(InputFile, CompIns);
1748+
SourceFile *SF = retrieveInputFile(InputBufferName, CompIns);
17411749
if (!SF) {
17421750
Receiver(RequestResult<NameTranslatingInfo>::fromError(
17431751
"Unable to find input file"));
@@ -1778,9 +1786,9 @@ static void resolveName(
17781786
if (!Success) {
17791787
if (!getPreviousASTSnaps().empty()) {
17801788
// Attempt again using the up-to-date AST.
1781-
resolveName(Lang, InputFile, Offset, ASTInvok,
1782-
/*TryExistingAST=*/false, Input, CancellationToken,
1783-
Receiver);
1789+
resolveName(
1790+
Lang, PrimaryFilePath, InputBufferName, Offset, ASTInvok,
1791+
/*TryExistingAST=*/false, Input, CancellationToken, Receiver);
17841792
} else {
17851793
NameTranslatingInfo Info;
17861794
Info.InternalDiagnostic = Diagnostic;
@@ -1813,17 +1821,18 @@ static void resolveName(
18131821
};
18141822

18151823
auto Consumer = std::make_shared<NameInfoConsumer>(
1816-
InputFile, Offset, Lang, Invok, TryExistingAST, Input, CancellationToken,
1817-
Receiver);
1824+
PrimaryFilePath, InputBufferName, Offset, Lang, Invok, TryExistingAST,
1825+
Input, CancellationToken, Receiver);
18181826

18191827
Lang.getASTManager()->processASTAsync(
18201828
Invok, std::move(Consumer), /*OncePerASTToken=*/nullptr,
18211829
CancellationToken, llvm::vfs::getRealFileSystem());
18221830
}
18231831

18241832
static void
1825-
resolveRange(SwiftLangSupport &Lang, StringRef InputFile, unsigned Offset,
1826-
unsigned Length, SwiftInvocationRef Invok, bool TryExistingAST,
1833+
resolveRange(SwiftLangSupport &Lang, StringRef PrimaryFilePath,
1834+
StringRef InputBufferName, unsigned Offset, unsigned Length,
1835+
SwiftInvocationRef Invok, bool TryExistingAST,
18271836
bool CancelOnSubsequentRequest,
18281837
SourceKitCancellationToken CancellationToken,
18291838
std::function<void(const RequestResult<RangeInfo> &)> Receiver) {
@@ -1835,20 +1844,21 @@ resolveRange(SwiftLangSupport &Lang, StringRef InputFile, unsigned Offset,
18351844

18361845
public:
18371846
RangeInfoConsumer(
1838-
StringRef InputFile, unsigned Offset, unsigned Length,
1839-
SwiftLangSupport &Lang, SwiftInvocationRef ASTInvok,
1847+
StringRef PrimaryFilePath, StringRef InputBufferName, unsigned Offset,
1848+
unsigned Length, SwiftLangSupport &Lang, SwiftInvocationRef ASTInvok,
18401849
bool TryExistingAST, bool CancelOnSubsequentRequest,
18411850
SourceKitCancellationToken CancellationToken,
18421851
std::function<void(const RequestResult<RangeInfo> &)> Receiver)
1843-
: CursorRangeInfoConsumer(InputFile, Offset, Length, Lang, ASTInvok,
1844-
TryExistingAST, CancelOnSubsequentRequest),
1852+
: CursorRangeInfoConsumer(PrimaryFilePath, InputBufferName, Offset,
1853+
Length, Lang, ASTInvok, TryExistingAST,
1854+
CancelOnSubsequentRequest),
18451855
CancellationToken(CancellationToken), Receiver(std::move(Receiver)) {}
18461856

18471857
void handlePrimaryAST(ASTUnitRef AstUnit) override {
18481858
// FIXME: Implement tracing
18491859
auto &CompIns = AstUnit->getCompilerInstance();
18501860

1851-
SourceFile *SF = retrieveInputFile(InputFile, CompIns);
1861+
SourceFile *SF = retrieveInputFile(InputBufferName, CompIns);
18521862
if (!SF) {
18531863
Receiver(
18541864
RequestResult<RangeInfo>::fromError("Unable to find input file"));
@@ -1892,7 +1902,8 @@ resolveRange(SwiftLangSupport &Lang, StringRef InputFile, unsigned Offset,
18921902
case RangeKind::Invalid:
18931903
if (!getPreviousASTSnaps().empty()) {
18941904
// Attempt again using the up-to-date AST.
1895-
resolveRange(Lang, InputFile, Offset, Length, ASTInvok,
1905+
resolveRange(Lang, PrimaryFilePath, InputBufferName, Offset, Length,
1906+
ASTInvok,
18961907
/*TryExistingAST=*/false, CancelOnSubsequentRequest,
18971908
CancellationToken, Receiver);
18981909
} else {
@@ -1913,8 +1924,8 @@ resolveRange(SwiftLangSupport &Lang, StringRef InputFile, unsigned Offset,
19131924
};
19141925

19151926
auto Consumer = std::make_shared<RangeInfoConsumer>(
1916-
InputFile, Offset, Length, Lang, Invok, TryExistingAST,
1917-
CancelOnSubsequentRequest, CancellationToken, Receiver);
1927+
PrimaryFilePath, InputBufferName, Offset, Length, Lang, Invok,
1928+
TryExistingAST, CancelOnSubsequentRequest, CancellationToken, Receiver);
19181929
/// FIXME: When request cancellation is implemented and Xcode adopts it,
19191930
/// don't use 'OncePerASTToken'.
19201931
static const char OncePerASTToken = 0;
@@ -2097,8 +2108,8 @@ void SwiftLangSupport::getCursorInfo(
20972108
}
20982109
};
20992110

2100-
resolveCursor(*this, InputBufferName, Offset, Length, Actionables,
2101-
SymbolGraph, Invok, /*TryExistingAST=*/true,
2111+
resolveCursor(*this, PrimaryFilePath, InputBufferName, Offset, Length,
2112+
Actionables, SymbolGraph, Invok, /*TryExistingAST=*/true,
21022113
CancelOnSubsequentRequest, fileSystem, CancellationToken,
21032114
ASTBasedReceiver);
21042115
}
@@ -2152,17 +2163,18 @@ void SwiftLangSupport::getRangeInfo(
21522163
Receiver(RequestResult<RangeInfo>::fromError("Invalid range length."));
21532164
return;
21542165
}
2155-
resolveRange(*this, InputBufferName, Offset, Length, Invok,
2166+
resolveRange(*this, PrimaryFilePath, InputBufferName, Offset, Length, Invok,
21562167
/*TryExistingAST=*/true, CancelOnSubsequentRequest,
21572168
CancellationToken, Receiver);
21582169
}
21592170

21602171
void SwiftLangSupport::getNameInfo(
2161-
StringRef InputFile, unsigned Offset, NameTranslatingInfo &Input,
2162-
ArrayRef<const char *> Args, SourceKitCancellationToken CancellationToken,
2172+
StringRef PrimaryFilePath, StringRef InputBufferName, unsigned Offset,
2173+
NameTranslatingInfo &Input, ArrayRef<const char *> Args,
2174+
SourceKitCancellationToken CancellationToken,
21632175
std::function<void(const RequestResult<NameTranslatingInfo> &)> Receiver) {
21642176

2165-
if (auto IFaceGenRef = IFaceGenContexts.get(InputFile)) {
2177+
if (auto IFaceGenRef = IFaceGenContexts.get(PrimaryFilePath)) {
21662178
IFaceGenRef->accessASTAsync([IFaceGenRef, Offset, Input, Receiver] {
21672179
SwiftInterfaceGenContext::ResolvedEntity Entity;
21682180
Entity = IFaceGenRef->resolveEntityForOffset(Offset);
@@ -2187,15 +2199,15 @@ void SwiftLangSupport::getNameInfo(
21872199

21882200
std::string Error;
21892201
SwiftInvocationRef Invok =
2190-
ASTMgr->getTypecheckInvocation(Args, InputFile, Error);
2202+
ASTMgr->getTypecheckInvocation(Args, PrimaryFilePath, Error);
21912203
if (!Invok) {
21922204
LOG_WARN_FUNC("failed to create an ASTInvocation: " << Error);
21932205
Receiver(RequestResult<NameTranslatingInfo>::fromError(Error));
21942206
return;
21952207
}
21962208

2197-
resolveName(*this, InputFile, Offset, Invok, /*TryExistingAST=*/true, Input,
2198-
CancellationToken, Receiver);
2209+
resolveName(*this, PrimaryFilePath, InputBufferName, Offset, Invok,
2210+
/*TryExistingAST=*/true, Input, CancellationToken, Receiver);
21992211
}
22002212

22012213
static void resolveCursorFromUSR(

tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,16 +1379,24 @@ static bool handleResponse(sourcekitd_response_t Resp, const TestOptions &Opts,
13791379
KeepResponseAlive = true;
13801380
break;
13811381

1382-
case SourceKitRequest::Edit:
1383-
if (Opts.Length == 0 && Opts.ReplaceText->empty()) {
1384-
// Length=0, replace="" is a nop and will not trigger sema.
1382+
case SourceKitRequest::Edit: {
1383+
// Length=0, replace="" is a nop and will not trigger sema.
1384+
bool SyntacticOnly = Opts.Length == 0 && Opts.ReplaceText->empty();
1385+
for (const std::string &ReqOpt : Opts.RequestOptions) {
1386+
if (SyntacticOnly)
1387+
break;
1388+
if (ReqOpt.find("syntactic_only=1") != std::string::npos) {
1389+
SyntacticOnly = true;
1390+
}
1391+
}
1392+
if (SyntacticOnly) {
13851393
printRawResponse(Resp);
13861394
} else {
13871395
getSemanticInfo(Info, SourceFile);
13881396
KeepResponseAlive = true;
13891397
}
13901398
break;
1391-
1399+
}
13921400
case SourceKitRequest::DemangleNames:
13931401
printDemangleResults(sourcekitd_response_get_value(Resp), outs());
13941402
break;

tools/SourceKit/tools/sourcekitd/lib/Service/Requests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1735,7 +1735,7 @@ handleRequestNameTranslation(const RequestDict &Req,
17351735
llvm::transform(Selectors, std::back_inserter(Input.ArgNames),
17361736
[](const char *C) { return StringRef(C); });
17371737
return Lang.getNameInfo(
1738-
*PrimaryFilePath, Offset, Input, Args, CancellationToken,
1738+
*PrimaryFilePath, "", Offset, Input, Args, CancellationToken,
17391739
[Rec](const RequestResult<NameTranslatingInfo> &Result) {
17401740
reportNameInfo(Result, Rec);
17411741
});

0 commit comments

Comments
 (0)