diff --git a/include/Feature/CodeCompletion.h b/include/Feature/CodeCompletion.h index a15ccf77..9d158591 100644 --- a/include/Feature/CodeCompletion.h +++ b/include/Feature/CodeCompletion.h @@ -77,7 +77,8 @@ struct CodeCompletionOption { namespace clice::feature { /// Run code completion in given file and location. `compiler` should be -/// set properly if any PCH or PCM is needed. +/// set properly if any PCH or PCM is needed. Each completion requires a +/// new compiler instance. std::vector codeCompletion(Compiler& compiler, llvm::StringRef filepath, proto::Position position, diff --git a/include/Feature/SignatureHelp.h b/include/Feature/SignatureHelp.h new file mode 100644 index 00000000..e69de29b diff --git a/src/Compiler/Compiler.cpp b/src/Compiler/Compiler.cpp index 67aa099b..4829bd8b 100644 --- a/src/Compiler/Compiler.cpp +++ b/src/Compiler/Compiler.cpp @@ -78,11 +78,25 @@ void Compiler::generatePCM(llvm::StringRef outpath) { } void Compiler::codeCompletion(llvm::StringRef filepath, std::uint32_t line, std::uint32_t column) { - auto& completion = instance->getFrontendOpts().CodeCompletionAt; - completion.FileName = filepath; - completion.Line = line; - completion.Column = column; - buildAST(); + auto& location = instance->getFrontendOpts().CodeCompletionAt; + location.FileName = filepath; + location.Line = line; + location.Column = column; + + if(content != "") { + auto buffer = llvm::MemoryBuffer::getMemBufferCopy(content); + instance->getPreprocessorOpts().addRemappedFile(filepath, buffer.release()); + } + + if(!action->BeginSourceFile(*instance, instance->getFrontendOpts().Inputs[0])) { + llvm::errs() << "Failed to begin source file\n"; + std::terminate(); + } + + if(auto error = action->Execute()) { + llvm::errs() << "Failed to execute action: " << error << "\n"; + std::terminate(); + } } void Compiler::ExecuteAction() { @@ -102,7 +116,7 @@ void Compiler::ExecuteAction() { // Beacuse CompilerInstance may create new Preprocessor in `BeginSourceFile`, // So we must need to create TokenCollector here. // clang::syntax::TokenCollector collector{preproc}; - CodeCompleteCollector collect2(*instance); + // CodeCompleteCollector collect2(*instance); // FIXME: clang-tidy, include-fixer, etc? diff --git a/src/Compiler/CodeCompletion.cpp b/src/Feature/CodeCompletion.cpp similarity index 66% rename from src/Compiler/CodeCompletion.cpp rename to src/Feature/CodeCompletion.cpp index ade34c1d..16eea7fb 100644 --- a/src/Compiler/CodeCompletion.cpp +++ b/src/Feature/CodeCompletion.cpp @@ -1,13 +1,14 @@ -#include -#include +#include +#include +#include -namespace clice { +namespace clice::feature { namespace { -class CodeCompleteConsumer final : public clang::CodeCompleteConsumer { +class CodeCompletionCollector final : public clang::CodeCompleteConsumer { public: - CodeCompleteConsumer(clang::CodeCompleteOptions options) : + CodeCompletionCollector(clang::CodeCompleteOptions options) : clang::CodeCompleteConsumer(options), allocator(new clang::GlobalCodeCompletionAllocator()), info(allocator) { // TODO: @@ -41,21 +42,6 @@ public: } } - void ProcessOverloadCandidates(clang::Sema& sema, - unsigned CurrentArg, - OverloadCandidate* candidates, - unsigned count, - clang::SourceLocation openParLoc, - bool braced) final { - llvm::outs() << "ProcessOverloadCandidates\n"; - auto range = llvm::make_range(candidates, candidates + count); - for(auto& candidate: range) { - switch(candidate.getKind()) { - // case - } - } - } - clang::CodeCompletionAllocator& getAllocator() final { return *allocator; } @@ -71,4 +57,11 @@ private: } // namespace -} // namespace clice +std::vector codeCompletion(Compiler& compiler, + llvm::StringRef filepath, + proto::Position position, + const config::CodeCompletionOption& option) { + // TODO: decode here. +} + +} // namespace clice::feature diff --git a/src/Feature/SignatureHelp.cpp b/src/Feature/SignatureHelp.cpp new file mode 100644 index 00000000..f7370584 --- /dev/null +++ b/src/Feature/SignatureHelp.cpp @@ -0,0 +1,65 @@ +#include +#include +#include + +namespace clice::feature { + +namespace { + +class SignatureHelpCollector final : public clang::CodeCompleteConsumer { +public: + SignatureHelpCollector(clang::CodeCompleteOptions options) : + clang::CodeCompleteConsumer(options), allocator(new clang::GlobalCodeCompletionAllocator()), + info(allocator) { + // TODO: + } + + void ProcessOverloadCandidates(clang::Sema& sema, + unsigned CurrentArg, + OverloadCandidate* candidates, + unsigned count, + clang::SourceLocation openParLoc, + bool braced) final { + llvm::outs() << "ProcessOverloadCandidates\n"; + auto range = llvm::make_range(candidates, candidates + count); + for(auto& candidate: range) { + switch(candidate.getKind()) { + case clang::CodeCompleteConsumer::OverloadCandidate::CK_Function: { + break; + } + case clang::CodeCompleteConsumer::OverloadCandidate::CK_FunctionTemplate: { + break; + } + case clang::CodeCompleteConsumer::OverloadCandidate::CK_FunctionType: { + break; + } + case clang::CodeCompleteConsumer::OverloadCandidate::CK_FunctionProtoTypeLoc: { + break; + } + case clang::CodeCompleteConsumer::OverloadCandidate::CK_Template: { + break; + } + case clang::CodeCompleteConsumer::OverloadCandidate::CK_Aggregate: { + break; + } + } + } + } + + clang::CodeCompletionAllocator& getAllocator() final { + return *allocator; + } + + clang::CodeCompletionTUInfo& getCodeCompletionTUInfo() final { + return info; + } + +private: + std::shared_ptr allocator; + clang::CodeCompletionTUInfo info; +}; + +} // namespace + +} // namespace clice::feature +