From 3f408a8e8ea2fbe8249271413dc0c06f1f28f155 Mon Sep 17 00:00:00 2001 From: ykiko Date: Sun, 30 Mar 2025 21:30:52 +0800 Subject: [PATCH] Stabilize compilation interface (#117) --- include/Compiler/Compilation.h | 11 ++-- src/Compiler/Compilation.cpp | 7 ++- src/Feature/CodeCompletion.cpp | 84 +++++++++------------------- src/Feature/SignatureHelp.cpp | 20 +++---- unittests/Feature/CodeCompletion.cpp | 2 +- unittests/Feature/SignatureHelp.cpp | 14 ++++- 6 files changed, 58 insertions(+), 80 deletions(-) diff --git a/include/Compiler/Compilation.h b/include/Compiler/Compilation.h index f84fd961..727439d1 100644 --- a/include/Compiler/Compilation.h +++ b/include/Compiler/Compilation.h @@ -38,9 +38,7 @@ struct CompilationParams { llvm::StringMap pcms; /// Code completion file:line:column. - llvm::StringRef file = ""; - uint32_t line = 0; - uint32_t column = 0; + std::tuple completion; }; namespace impl { @@ -58,13 +56,14 @@ std::unique_ptr createInstance(CompilationParams& param /// their reusability and update in time. std::expected compile(CompilationParams& params); -/// Run code completion at the given location. -std::expected compile(CompilationParams& params, clang::CodeCompleteConsumer* consumer); - /// Build PCH from given file path and content. std::expected compile(CompilationParams& params, PCHInfo& out); /// Build PCM from given file path and content. std::expected compile(CompilationParams& params, PCMInfo& out); +/// Run code completion at the given location. +std::expected compile(CompilationParams& params, + clang::CodeCompleteConsumer* consumer); + } // namespace clice diff --git a/src/Compiler/Compilation.cpp b/src/Compiler/Compilation.cpp index 58ec4d20..bc89f2d9 100644 --- a/src/Compiler/Compilation.cpp +++ b/src/Compiler/Compilation.cpp @@ -174,10 +174,11 @@ std::expected compile(CompilationParams& params, clang::CodeCompleteConsumer* consumer) { auto instance = impl::createInstance(params); + auto& [file, line, column] = params.completion; /// Set options to run code completion. - instance->getFrontendOpts().CodeCompletionAt.FileName = params.srcPath.str(); - instance->getFrontendOpts().CodeCompletionAt.Line = params.line; - instance->getFrontendOpts().CodeCompletionAt.Column = params.column; + instance->getFrontendOpts().CodeCompletionAt.FileName = std::move(file); + instance->getFrontendOpts().CodeCompletionAt.Line = line; + instance->getFrontendOpts().CodeCompletionAt.Column = column; instance->setCodeCompletionConsumer(consumer); return ExecuteAction(std::move(instance), std::make_unique()); diff --git a/src/Feature/CodeCompletion.cpp b/src/Feature/CodeCompletion.cpp index 4ace76cd..1fa328cd 100644 --- a/src/Feature/CodeCompletion.cpp +++ b/src/Feature/CodeCompletion.cpp @@ -45,53 +45,32 @@ struct CompletionPrefix { class CodeCompletionCollector final : public clang::CodeCompleteConsumer { public: - CodeCompletionCollector(std::vector& completions, - uint32_t line, - uint32_t column, - llvm::StringRef content) : + CodeCompletionCollector(std::vector& completions) : clang::CodeCompleteConsumer({}), completions(completions), - allocator(new clang::GlobalCodeCompletionAllocator()), info(allocator), line(line), - column(column), content(content) {} + allocator(new clang::GlobalCodeCompletionAllocator()), info(allocator) {} void ProcessCodeCompleteResults(clang::Sema& sema, clang::CodeCompletionContext context, - clang::CodeCompletionResult* results, + clang::CodeCompletionResult* candidates, unsigned count) final { - // auto loc = sema.getPreprocessor().getCodeCompletionLoc(); - // auto offset = sema.getSourceManager().getFileOffset(loc); - // auto prefix = CompletionPrefix::from(content, offset); - // - // for(auto& result: llvm::make_range(results, results + count)) { - // auto& item = completions.emplace_back(); - // item.kind = proto::CompletionItemKind::Text; - // switch(result.Kind) { - // case clang::CodeCompletionResult::RK_Declaration: { - // item.label = getName(result.Declaration); - // item.kind = kindForDecl(result.Declaration); - // item.detail = result.Declaration->getNameAsString(); - // break; - // } - // case clang::CodeCompletionResult::RK_Keyword: { - // item.label = result.Keyword; - // item.kind = proto::CompletionItemKind::Keyword; - // break; - // } - // case clang::CodeCompletionResult::RK_Macro: { - // item.label = result.Macro->getName(); - // break; - // } - // case clang::CodeCompletionResult::RK_Pattern: { - // item.kind = proto::CompletionItemKind::Snippet; - // item.label = result.Pattern->getTypedText(); - // break; - // } - // } - // item.textEdit.newText = item.label; - // item.textEdit.range = { - // .start = {line - 1, static_cast(column - 1 - prefix.name.size())}, - // .end = {line - 1, static_cast(column + item.label.size()) - 1 }, - // }; - //} + for(auto& candidate: llvm::make_range(candidates, candidates + count)) { + switch(candidate.Kind) { + case clang::CodeCompletionResult::RK_Declaration: { + break; + } + case clang::CodeCompletionResult::RK_Keyword: { + break; + } + case clang::CodeCompletionResult::RK_Macro: { + break; + } + case clang::CodeCompletionResult::RK_Pattern: { + break; + } + } + + println("{}", refl::enum_name(candidate.Kind)); + } } clang::CodeCompletionAllocator& getAllocator() final { @@ -103,9 +82,6 @@ public: } private: - uint32_t line; - uint32_t column; - llvm::StringRef content; std::shared_ptr allocator; clang::CodeCompletionTUInfo info; std::vector& completions; @@ -115,18 +91,12 @@ private: std::vector codeCompletion(CompilationParams& params, const config::CodeCompletionOption& option) { - // std::vector completions; - // auto consumer = - // new CodeCompletionCollector(completions, params.line, params.column, params.content); - // - // if(auto info = compile(params, consumer)) { - // for(auto& item: completions) {} - // return completions; - //} else { - // std::abort(); - //} - - return std::vector{}; + std::vector completions; + auto consumer = new CodeCompletionCollector(completions); + if(auto info = compile(params, consumer)) { + for(auto& item: completions) {} + } + return completions; } } // namespace clice::feature diff --git a/src/Feature/SignatureHelp.cpp b/src/Feature/SignatureHelp.cpp index 346669c8..b3b3ff2a 100644 --- a/src/Feature/SignatureHelp.cpp +++ b/src/Feature/SignatureHelp.cpp @@ -22,21 +22,27 @@ public: for(auto& candidate: range) { switch(candidate.getKind()) { case clang::CodeCompleteConsumer::OverloadCandidate::CK_Function: { + candidate.getFunction()->dump(); break; } case clang::CodeCompleteConsumer::OverloadCandidate::CK_FunctionTemplate: { + candidate.getFunctionTemplate()->dump(); break; } case clang::CodeCompleteConsumer::OverloadCandidate::CK_FunctionType: { + candidate.getFunctionType()->dump(); break; } case clang::CodeCompleteConsumer::OverloadCandidate::CK_FunctionProtoTypeLoc: { + candidate.getFunctionProtoTypeLoc().dump(); break; } case clang::CodeCompleteConsumer::OverloadCandidate::CK_Template: { + candidate.getTemplate()->dump(); break; } case clang::CodeCompleteConsumer::OverloadCandidate::CK_Aggregate: { + candidate.getAggregate()->dump(); break; } } @@ -60,16 +66,10 @@ private: std::vector signatureHelp(CompilationParams& params, const config::SignatureHelpOption& option) { - // std::vector completions; - // auto consumer = new SignatureHelpCollector({}); - // - // if(auto info = compile(params, consumer)) { - // for(auto& item: completions) {} - // return completions; - //} else { - // std::abort(); - //} - return std::vector{}; + std::vector items; + auto consumer = new SignatureHelpCollector({}); + if(auto info = compile(params, consumer)) {} + return items; } } // namespace clice::feature diff --git a/unittests/Feature/CodeCompletion.cpp b/unittests/Feature/CodeCompletion.cpp index 4b394356..7d833727 100644 --- a/unittests/Feature/CodeCompletion.cpp +++ b/unittests/Feature/CodeCompletion.cpp @@ -18,7 +18,7 @@ int main() { params.content = code; params.srcPath = "main.cpp"; params.command = "clang++ -std=c++20 main.cpp"; - params.file = "main.cpp"; + params.completion = {"main.cpp", 5, 6}; config::CodeCompletionOption options = {}; auto result = feature::codeCompletion(params, options); diff --git a/unittests/Feature/SignatureHelp.cpp b/unittests/Feature/SignatureHelp.cpp index 3959053a..6222a153 100644 --- a/unittests/Feature/SignatureHelp.cpp +++ b/unittests/Feature/SignatureHelp.cpp @@ -7,10 +7,14 @@ namespace { TEST(Feature, SignatureHelp) { const char* code = R"cpp( -int foo = 2; +void foo(); + +void foo(int x); + +void foo(int x, int y); int main() { - foo = 2; + foo(1, 2); } )cpp"; @@ -18,10 +22,14 @@ int main() { params.content = code; params.srcPath = "main.cpp"; params.command = "clang++ -std=c++20 main.cpp"; - params.file = "main.cpp"; + params.completion = {"main.cpp", 9, 10}; config::SignatureHelpOption options = {}; auto result = feature::signatureHelp(params, options); + /// EXPECT + /// foo(int x, int y) + /// foo(int x) + /// foo() } } // namespace