Skip to content

Commit 85bf842

Browse files
committed
[Test] Add signature help to swift-ide-test
1 parent 2f60646 commit 85bf842

File tree

1 file changed

+135
-17
lines changed

1 file changed

+135
-17
lines changed

tools/swift-ide-test/swift-ide-test.cpp

Lines changed: 135 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
#include "swift/IDE/IDERequests.h"
4444
#include "swift/IDE/ModuleInterfacePrinting.h"
4545
#include "swift/IDE/REPLCodeCompletion.h"
46+
#include "swift/IDE/SignatureHelp.h"
47+
#include "swift/IDE/SignatureHelpFormatter.h"
4648
#include "swift/IDE/SourceEntityWalker.h"
4749
#include "swift/IDE/SyntaxModel.h"
4850
#include "swift/IDE/TypeContextInfo.h"
@@ -117,6 +119,7 @@ enum class ActionType {
117119
Range,
118120
TypeContextInfo,
119121
ConformingMethodList,
122+
SignatureHelp,
120123
};
121124

122125
class NullDebuggerClient : public DebuggerClient {
@@ -251,7 +254,9 @@ Action(llvm::cl::desc("Mode:"), llvm::cl::init(ActionType::None),
251254
"Print types for all expressions in the file"),
252255
clEnumValN(ActionType::ConformingMethodList,
253256
"conforming-methods",
254-
"Perform conforming method analysis for expression")));
257+
"Perform conforming method analysis for expression"),
258+
clEnumValN(ActionType::SignatureHelp, "signature-help",
259+
"Perform signature help")));
255260

256261
static llvm::cl::opt<std::string>
257262
SourceFilename("source-filename", llvm::cl::desc("Name of the source file"),
@@ -1446,6 +1451,101 @@ printCodeCompletionLookedupTypeNames(ArrayRef<NullTerminatedStringRef> names,
14461451
OS << "]\n";
14471452
}
14481453

1454+
static void printWithEscaping(StringRef Str, llvm::raw_ostream &OS) {
1455+
for (char C : Str) {
1456+
switch (C) {
1457+
case '\n':
1458+
OS << "\\n";
1459+
break;
1460+
case '\r':
1461+
OS << "\\r";
1462+
break;
1463+
case '\t':
1464+
OS << "\\t";
1465+
break;
1466+
case '\v':
1467+
OS << "\\v";
1468+
break;
1469+
case '\f':
1470+
OS << "\\f";
1471+
break;
1472+
default:
1473+
OS << C;
1474+
break;
1475+
}
1476+
}
1477+
}
1478+
1479+
static void printSignatureHelpResultsImpl(const FormattedSignatureHelp &Result,
1480+
llvm::raw_ostream &OS) {
1481+
OS << "Begin signatures, " << Result.Signatures.size() << " items\n";
1482+
1483+
for (unsigned i = 0; i < Result.Signatures.size(); ++i) {
1484+
const auto &Signature = Result.Signatures[i];
1485+
if (i == Result.ActiveSignature) {
1486+
OS << "Signature[Active]: ";
1487+
} else {
1488+
OS << "Signature: ";
1489+
}
1490+
1491+
StringRef signatureText = Signature.Text;
1492+
std::string formattedSignature;
1493+
llvm::raw_string_ostream signatureOS(formattedSignature);
1494+
1495+
unsigned currentPos = 0;
1496+
for (unsigned j = 0; j < Signature.Params.size(); ++j) {
1497+
const auto &Param = Signature.Params[j];
1498+
1499+
if (Param.Offset > currentPos) {
1500+
signatureOS << signatureText.substr(currentPos,
1501+
Param.Offset - currentPos);
1502+
}
1503+
1504+
signatureOS << "<param name=\"" << Param.Name << "\"";
1505+
if (Signature.ActiveParam && *Signature.ActiveParam == j) {
1506+
signatureOS << " active";
1507+
}
1508+
signatureOS << ">";
1509+
signatureOS << signatureText.substr(Param.Offset, Param.Length);
1510+
signatureOS << "</param>";
1511+
1512+
currentPos = Param.Offset + Param.Length;
1513+
}
1514+
1515+
if (currentPos < signatureText.size()) {
1516+
signatureOS << signatureText.substr(currentPos);
1517+
}
1518+
1519+
OS << formattedSignature;
1520+
1521+
if (!Signature.DocComment.empty()) {
1522+
OS << "; Documentation=";
1523+
printWithEscaping(Signature.DocComment, OS);
1524+
}
1525+
1526+
OS << "\n";
1527+
}
1528+
1529+
OS << "End signatures\n";
1530+
}
1531+
1532+
static int printSignatureHelpResults(
1533+
CancellableResult<SignatureHelpResults> CancellableResult) {
1534+
llvm::raw_fd_ostream &OS = llvm::outs();
1535+
return printResult<SignatureHelpResults>(
1536+
CancellableResult, [&](const SignatureHelpResults &Results) {
1537+
if (Results.Result) {
1538+
llvm::BumpPtrAllocator Allocator;
1539+
SignatureHelpFormatter Formatter(Allocator);
1540+
auto FormattedResult = Formatter.format(*Results.Result);
1541+
printSignatureHelpResultsImpl(FormattedResult, OS);
1542+
} else {
1543+
OS << "No signature help results\n";
1544+
}
1545+
return 0;
1546+
});
1547+
}
1548+
14491549
static int printCodeCompletionResults(
14501550
CancellableResult<CodeCompleteResult> CancellableResult,
14511551
bool IncludeKeywords, bool IncludeComments, bool IncludeSourceText,
@@ -1463,6 +1563,27 @@ static int printCodeCompletionResults(
14631563
});
14641564
}
14651565

1566+
static int doSignatureHelp(const CompilerInvocation &InitInvok,
1567+
StringRef SourceFilename,
1568+
StringRef SecondSourceFileName,
1569+
StringRef SignatureHelpToken,
1570+
bool SignatureHelpDiagnostics) {
1571+
return performWithCompletionLikeOperationParams(
1572+
InitInvok, SourceFilename, SecondSourceFileName, SignatureHelpToken,
1573+
SignatureHelpDiagnostics,
1574+
[&](CompletionLikeOperationParams Params) -> bool {
1575+
IDEInspectionInstance Inst(std::make_shared<PluginRegistry>());
1576+
int ExitCode = 2;
1577+
Inst.signatureHelp(Params.Invocation, Params.Args, Params.FileSystem,
1578+
Params.CompletionBuffer, Params.Offset, Params.DiagC,
1579+
/*CancellationFlag=*/nullptr,
1580+
[&](CancellableResult<SignatureHelpResults> Result) {
1581+
ExitCode = printSignatureHelpResults(Result);
1582+
});
1583+
return ExitCode;
1584+
});
1585+
}
1586+
14661587
static int
14671588
doCodeCompletion(const CompilerInvocation &InitInvok, StringRef SourceFilename,
14681589
StringRef SecondSourceFileName, StringRef CodeCompletionToken,
@@ -3470,19 +3591,6 @@ class ASTCommentPrinter : public ASTWalker {
34703591
ASTCommentPrinter(SourceManager &SM, XMLValidator &TheXMLValidator)
34713592
: OS(llvm::outs()), SM(SM), TheXMLValidator(TheXMLValidator) {}
34723593

3473-
void printWithEscaping(StringRef Str) {
3474-
for (char C : Str) {
3475-
switch (C) {
3476-
case '\n': OS << "\\n"; break;
3477-
case '\r': OS << "\\r"; break;
3478-
case '\t': OS << "\\t"; break;
3479-
case '\v': OS << "\\v"; break;
3480-
case '\f': OS << "\\f"; break;
3481-
default: OS << C; break;
3482-
}
3483-
}
3484-
}
3485-
34863594
void printDeclName(const ValueDecl *VD) {
34873595
if (auto *NTD = dyn_cast<NominalTypeDecl>(VD->getDeclContext())) {
34883596
Identifier Id = NTD->getName();
@@ -3555,7 +3663,7 @@ class ASTCommentPrinter : public ASTWalker {
35553663
}
35563664
OS << "[";
35573665
for (auto &SRC : RC.Comments)
3558-
printWithEscaping(SRC.RawText);
3666+
printWithEscaping(SRC.RawText, OS);
35593667
OS << "]";
35603668
}
35613669

@@ -3566,7 +3674,7 @@ class ASTCommentPrinter : public ASTWalker {
35663674
return;
35673675
}
35683676
OS << "[";
3569-
printWithEscaping(Brief);
3677+
printWithEscaping(Brief, OS);
35703678
OS << "]";
35713679
}
35723680

@@ -3582,7 +3690,7 @@ class ASTCommentPrinter : public ASTWalker {
35823690
return;
35833691
}
35843692
OS << "[";
3585-
printWithEscaping(XML);
3693+
printWithEscaping(XML, OS);
35863694
OS << "]";
35873695

35883696
auto Status = TheXMLValidator.validate(XML);
@@ -4849,6 +4957,16 @@ int main(int argc, char *argv[]) {
48494957
options::ConformingMethodListExpectedTypes);
48504958
break;
48514959

4960+
case ActionType::SignatureHelp:
4961+
if (options::CodeCompletionToken.empty()) {
4962+
llvm::errs() << "signature help token name required\n";
4963+
return 1;
4964+
}
4965+
ExitCode = doSignatureHelp(
4966+
InitInvok, options::SourceFilename, options::SecondSourceFilename,
4967+
options::CodeCompletionToken, options::CodeCompletionDiagnostics);
4968+
break;
4969+
48524970
case ActionType::SyntaxColoring:
48534971
ExitCode = doSyntaxColoring(InitInvok,
48544972
options::SourceFilename,

0 commit comments

Comments
 (0)