Merge pull request #22429 from rintaro/sourcekit-conformingmethods

[IDE/SourceKit] New SourceKit request for filtered method list
This commit is contained in:
Rintaro Ishizaki
2019-02-11 18:13:15 -08:00
committed by GitHub
24 changed files with 1040 additions and 210 deletions

View File

@@ -33,6 +33,7 @@
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
#include "swift/IDE/CodeCompletion.h"
#include "swift/IDE/CommentConversion.h"
#include "swift/IDE/ConformingMethodList.h"
#include "swift/IDE/ModuleInterfacePrinting.h"
#include "swift/IDE/REPLCodeCompletion.h"
#include "swift/IDE/SourceEntityWalker.h"
@@ -101,6 +102,7 @@ enum class ActionType {
ReconstructType,
Range,
TypeContextInfo,
ConformingMethodList,
};
class NullDebuggerClient : public DebuggerClient {
@@ -225,7 +227,10 @@ Action(llvm::cl::desc("Mode:"), llvm::cl::init(ActionType::None),
"Print indexed symbol information"),
clEnumValN(ActionType::TypeContextInfo,
"type-context-info",
"Perform expression context info analysis")));
"Perform expression context info analysis"),
clEnumValN(ActionType::ConformingMethodList,
"conforming-methods",
"Perform conforming method analysis for expression")));
static llvm::cl::opt<std::string>
SourceFilename("source-filename", llvm::cl::desc("Name of the source file"),
@@ -419,6 +424,13 @@ DebugClientDiscriminator("debug-client-discriminator",
llvm::cl::desc("A discriminator to prefer in lookups"),
llvm::cl::cat(Category));
// '-conforming-methods' options.
static llvm::cl::list<std::string>
ConformingMethodListExpectedTypes("conforming-methods-expected-types",
llvm::cl::desc("Set expected types for comforming method list"),
llvm::cl::cat(Category));
// '-syntax-coloring' options.
static llvm::cl::opt<bool>
@@ -748,6 +760,70 @@ static int doTypeContextInfo(const CompilerInvocation &InitInvok,
return 0;
}
static int
doConformingMethodList(const CompilerInvocation &InitInvok,
StringRef SourceFilename, StringRef SecondSourceFileName,
StringRef CodeCompletionToken,
bool CodeCompletionDiagnostics,
const std::vector<std::string> expectedTypeNames) {
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
llvm::MemoryBuffer::getFile(SourceFilename);
if (!FileBufOrErr) {
llvm::errs() << "error opening input file: "
<< FileBufOrErr.getError().message() << '\n';
return 1;
}
unsigned Offset;
std::unique_ptr<llvm::MemoryBuffer> CleanFile(removeCodeCompletionTokens(
FileBufOrErr.get().get(), CodeCompletionToken, &Offset));
if (Offset == ~0U) {
llvm::errs() << "could not find code completion token \""
<< CodeCompletionToken << "\"\n";
return 1;
}
llvm::outs() << "found code completion token " << CodeCompletionToken
<< " at offset " << Offset << "\n";
llvm::errs() << "found code completion token " << CodeCompletionToken
<< " at offset " << Offset << "\n";
CompilerInvocation Invocation(InitInvok);
Invocation.setCodeCompletionPoint(CleanFile.get(), Offset);
SmallVector<const char *, 4> typeNames;
for (auto &name : expectedTypeNames)
typeNames.push_back(name.c_str());
// Create a CodeCompletionConsumer.
std::unique_ptr<ide::ConformingMethodListConsumer> Consumer(
new ide::PrintingConformingMethodListConsumer(llvm::outs()));
// Create a factory for code completion callbacks that will feed the
// Consumer.
std::unique_ptr<CodeCompletionCallbacksFactory> callbacksFactory(
ide::makeConformingMethodListCallbacksFactory(typeNames, *Consumer));
Invocation.setCodeCompletionFactory(callbacksFactory.get());
if (!SecondSourceFileName.empty()) {
Invocation.getFrontendOptions().InputsAndOutputs.addInputFile(
SecondSourceFileName);
}
CompilerInstance CI;
PrintingDiagnosticConsumer PrintDiags;
if (CodeCompletionDiagnostics) {
// Display diagnostics to stderr.
CI.addDiagnosticConsumer(&PrintDiags);
}
if (CI.setup(Invocation))
return 1;
CI.performSema();
return 0;
}
static int doCodeCompletion(const CompilerInvocation &InitInvok,
StringRef SourceFilename,
StringRef SecondSourceFileName,
@@ -3277,6 +3353,19 @@ int main(int argc, char *argv[]) {
options::CodeCompletionDiagnostics);
break;
case ActionType::ConformingMethodList:
if (options::CodeCompletionToken.empty()) {
llvm::errs() << "token name required\n";
return 1;
}
ExitCode = doConformingMethodList(InitInvok,
options::SourceFilename,
options::SecondSourceFilename,
options::CodeCompletionToken,
options::CodeCompletionDiagnostics,
options::ConformingMethodListExpectedTypes);
break;
case ActionType::SyntaxColoring:
ExitCode = doSyntaxColoring(InitInvok,
options::SourceFilename,