2323#include  < cxx/ast.h> 
2424#include  < cxx/control.h> 
2525#include  < cxx/gcc_linux_toolchain.h> 
26+ #include  < cxx/lsp/enums.h> 
2627#include  < cxx/lsp/types.h> 
2728#include  < cxx/macos_toolchain.h> 
29+ #include  < cxx/name_printer.h> 
2830#include  < cxx/preprocessor.h> 
2931#include  < cxx/private/path.h> 
3032#include  < cxx/scope.h> 
3133#include  < cxx/symbol_printer.h> 
3234#include  < cxx/symbols.h> 
3335#include  < cxx/translation_unit.h> 
36+ #include  < cxx/type_printer.h> 
37+ #include  < cxx/types.h> 
3438#include  < cxx/wasm32_wasi_toolchain.h> 
3539#include  < cxx/windows_toolchain.h> 
3640
3741#ifndef  CXX_NO_THREADS
3842#include  < atomic> 
3943#endif 
4044
45+ #include  < format> 
46+ #include  < iostream> 
47+ 
4148namespace  cxx ::lsp {
4249
4350namespace  {
@@ -74,6 +81,7 @@ struct CxxDocument::Private {
7481  Diagnostics diagnosticsClient;
7582  TranslationUnit unit{&diagnosticsClient};
7683  std::shared_ptr<Toolchain> toolchain;
84+   Vector<CompletionItem> completionItems;
7785
7886#ifndef  CXX_NO_THREADS
7987  std::atomic<bool > cancelled{false };
@@ -202,10 +210,20 @@ void CxxDocument::cancel() {
202210
203211auto  CxxDocument::fileName () const  -> const  std::string& { return  d->fileName ; }
204212
205- void  CxxDocument::requestCodeCompletion (std::uint32_t  line,
206-                                         std::uint32_t  column) {
213+ void  CxxDocument::codeCompletionAt (std::string source, std::uint32_t  line,
214+                                    std::uint32_t  column,
215+                                    Vector<CompletionItem> completionItems) {
216+   std::swap (d->completionItems , completionItems);
217+ 
207218  auto & unit = d->unit ;
219+ 
220+   (void )unit.blockErrors (true );
221+ 
208222  unit.preprocessor ()->requestCodeCompletionAt (line, column);
223+ 
224+   parse (std::move (source));
225+ 
226+   std::swap (d->completionItems , completionItems);
209227}
210228
211229void  CxxDocument::parse (std::string source) {
@@ -227,13 +245,37 @@ void CxxDocument::parse(std::string source) {
227245
228246  unit.endPreprocessing ();
229247
248+   auto  stopParsingPredicate = [this ] { return  isCancelled (); };
249+ 
250+   auto  complete = [this ](const  CodeCompletionContext& context) {
251+     if  (auto  memberCompletionContext =
252+             std::get_if<MemberCompletionContext>(&context)) {
253+       //  simple member completion
254+       auto  objectType = memberCompletionContext->objectType ;
255+ 
256+       if  (auto  pointerType = type_cast<PointerType>(objectType)) {
257+         objectType = type_cast<ClassType>(pointerType->elementType ());
258+       }
259+ 
260+       if  (auto  classType = type_cast<ClassType>(objectType)) {
261+         auto  classSymbol = classType->symbol ();
262+         for  (auto  member : classSymbol->members ()) {
263+           if  (!member->name ()) continue ;
264+           auto  item = d->completionItems .emplace_back ();
265+           item.label (to_string (member->name ()));
266+         }
267+       }
268+     }
269+   };
270+ 
230271  unit.parse (ParserConfiguration{
231272      .checkTypes  = cli.opt_fcheck ,
232273      .fuzzyTemplateResolution  = true ,
233274      .staticAssert  = cli.opt_fstatic_assert  || cli.opt_fcheck ,
234275      .reflect  = !cli.opt_fno_reflect ,
235276      .templates  = cli.opt_ftemplates ,
236-       .stopParsingPredicate  = [this ] { return  isCancelled (); },
277+       .stopParsingPredicate  = stopParsingPredicate,
278+       .complete  = complete,
237279  });
238280}
239281
0 commit comments