@@ -320,9 +320,13 @@ llvm::StringRef SwiftREPL::GetSourceFileBasename() {
320
320
bool SwiftREPL::SourceIsComplete (const std::string &source) {
321
321
std::unique_ptr<llvm::MemoryBuffer> source_buffer_ap (
322
322
llvm::MemoryBuffer::getMemBuffer (source));
323
- swift::ide::SourceCompleteResult result =
324
- swift::ide::isSourceInputComplete (std::move (source_buffer_ap),
325
- swift::SourceFileKind::Main);
323
+ auto *swift_ast = getSwiftASTContext ();
324
+ if (!swift_ast)
325
+ return true ;
326
+
327
+ swift::ide::SourceCompleteResult result = swift::ide::isSourceInputComplete (
328
+ std::move (source_buffer_ap), swift::SourceFileKind::Main,
329
+ swift_ast->GetLanguageOptions ());
326
330
return result.IsComplete ;
327
331
}
328
332
@@ -355,9 +359,14 @@ lldb::offset_t SwiftREPL::GetDesiredIndentation(const StringList &lines,
355
359
std::string source_string (prior_lines.CopyList ());
356
360
std::unique_ptr<llvm::MemoryBuffer> source_buffer_ap (
357
361
llvm::MemoryBuffer::getMemBuffer (source_string));
358
- swift::ide::SourceCompleteResult result =
359
- swift::ide::isSourceInputComplete (std::move (source_buffer_ap),
360
- swift::SourceFileKind::Main);
362
+
363
+ auto *swift_ast = getSwiftASTContext ();
364
+ if (!swift_ast)
365
+ return LLDB_INVALID_OFFSET;
366
+
367
+ swift::ide::SourceCompleteResult result = swift::ide::isSourceInputComplete (
368
+ std::move (source_buffer_ap), swift::SourceFileKind::Main,
369
+ swift_ast->GetLanguageOptions ());
361
370
362
371
int desired_indent =
363
372
(result.IndentLevel * tab_size) + result.IndentPrefix .length ();
@@ -551,21 +560,19 @@ bool SwiftREPL::PrintOneVariable(Debugger &debugger, StreamFileSP &output_sp,
551
560
return handled;
552
561
}
553
562
554
- void SwiftREPL::CompleteCode (const std::string ¤t_code,
555
- CompletionRequest &request) {
563
+ SwiftASTContextForExpressions *SwiftREPL::getSwiftASTContext () {
556
564
// ----------------------------------------------------------------------g
557
565
// If we use the target's SwiftASTContext for completion, it reaaallly
558
566
// slows down subsequent expressions. The compiler team doesn't have time
559
567
// to fix this issue currently, so we need to work around it by making
560
568
// our own copy of the AST and using this separate AST for completion.
561
569
// ----------------------------------------------------------------------
562
- Status error;
563
570
if (!m_swift_ast) {
564
571
auto type_system_or_err =
565
572
m_target.GetScratchTypeSystemForLanguage (eLanguageTypeSwift);
566
573
if (!type_system_or_err) {
567
574
llvm::consumeError (type_system_or_err.takeError ());
568
- return ;
575
+ return nullptr ;
569
576
}
570
577
auto *swift_ts =
571
578
llvm::dyn_cast_or_null<TypeSystemSwiftTypeRefForExpressions>(
@@ -576,82 +583,88 @@ void SwiftREPL::CompleteCode(const std::string ¤t_code,
576
583
m_target.shared_from_this (), m_target.GetExecutableModule ())));
577
584
m_swift_ast = target_swift_ast;
578
585
}
579
- SwiftASTContextForExpressions *swift_ast = m_swift_ast;
580
-
581
- if (swift_ast) {
582
- ThreadSafeASTContext ast = swift_ast->GetASTContext ();
583
- swift::REPLCompletions completions;
584
- SourceModule completion_module_info;
585
- completion_module_info.path .push_back (ConstString (" repl" ));
586
- swift::ModuleDecl *repl_module = nullptr ;
587
- if (m_completion_module_initialized)
588
- repl_module = swift_ast->GetModule (completion_module_info, error);
589
- if (repl_module == nullptr ) {
590
- swift::ImplicitImportInfo importInfo;
591
- importInfo.StdlibKind = swift::ImplicitStdlibKind::Stdlib;
592
- repl_module = swift_ast->CreateModule (completion_module_info, error,
593
- importInfo);
594
- auto bufferID = (*ast)->SourceMgr .addMemBufferCopy (" // swift repl\n " );
595
- swift::SourceFile *repl_source_file = new (**ast) swift::SourceFile (
596
- *repl_module, swift::SourceFileKind::Main, bufferID);
597
- repl_module->addFile (*repl_source_file);
598
- swift::performImportResolution (*repl_source_file);
599
- m_completion_module_initialized = true ;
586
+ return m_swift_ast;
587
+ }
588
+
589
+ void SwiftREPL::CompleteCode (const std::string ¤t_code,
590
+ CompletionRequest &request) {
591
+ auto *swift_ast = getSwiftASTContext ();
592
+ if (!swift_ast)
593
+ return ;
594
+
595
+ Status error;
596
+ ThreadSafeASTContext ast = swift_ast->GetASTContext ();
597
+ swift::REPLCompletions completions;
598
+ SourceModule completion_module_info;
599
+ completion_module_info.path .push_back (ConstString (" repl" ));
600
+ swift::ModuleDecl *repl_module = nullptr ;
601
+ if (m_completion_module_initialized)
602
+ repl_module = swift_ast->GetModule (completion_module_info, error);
603
+ if (!repl_module) {
604
+ swift::ImplicitImportInfo importInfo;
605
+ importInfo.StdlibKind = swift::ImplicitStdlibKind::Stdlib;
606
+ repl_module = swift_ast->CreateModule (completion_module_info, error,
607
+ importInfo);
608
+ auto bufferID = (*ast)->SourceMgr .addMemBufferCopy (" // swift repl\n " );
609
+ swift::SourceFile *repl_source_file = new (**ast) swift::SourceFile (
610
+ *repl_module, swift::SourceFileKind::Main, bufferID);
611
+ repl_module->addFile (*repl_source_file);
612
+ swift::performImportResolution (*repl_source_file);
613
+ m_completion_module_initialized = true ;
614
+ }
615
+ if (repl_module) {
616
+ swift::SourceFile &repl_source_file = repl_module->getMainSourceFile ();
617
+
618
+ // Swift likes to give us strings to append to the current token but
619
+ // the CompletionRequest requires a replacement for the full current
620
+ // token. Fix this by getting the current token here and we attach
621
+ // the suffix we get from Swift.
622
+ std::string prefix = request.GetCursorArgumentPrefix ().str ();
623
+ llvm::StringRef current_code_ref (current_code);
624
+ completions.populate (repl_source_file, current_code_ref);
625
+
626
+ // The root is the unique completion we need to use, so let's add it
627
+ // to the completion list. As the completion is unique we can stop here.
628
+ llvm::StringRef root = completions.getRoot ();
629
+ if (!root.empty ()) {
630
+ request.AddCompletion (prefix + root.str (), " " , CompletionMode::Partial);
631
+ return ;
600
632
}
601
- if (repl_module) {
602
- swift::SourceFile &repl_source_file =
603
- repl_module->getMainSourceFile ();
604
-
605
- // Swift likes to give us strings to append to the current token but
606
- // the CompletionRequest requires a replacement for the full current
607
- // token. Fix this by getting the current token here and we attach
608
- // the suffix we get from Swift.
609
- std::string prefix = request.GetCursorArgumentPrefix ().str ();
610
- llvm::StringRef current_code_ref (current_code);
611
- completions.populate (repl_source_file, current_code_ref);
612
-
613
- // The root is the unique completion we need to use, so let's add it
614
- // to the completion list. As the completion is unique we can stop here.
615
- llvm::StringRef root = completions.getRoot ();
616
- if (!root.empty ()) {
617
- request.AddCompletion (prefix + root.str (), " " , CompletionMode::Partial);
618
- return ;
619
- }
620
633
621
- // Otherwise, advance through the completion state machine.
622
- const swift::CompletionState completion_state = completions.getState ();
623
- switch (completion_state) {
624
- case swift::CompletionState::CompletedRoot: {
625
- // Display the completion list.
626
- llvm::ArrayRef<llvm::StringRef> llvm_matches =
627
- completions.getCompletionList ();
628
- for (const auto &llvm_match : llvm_matches) {
629
- // The completions here aren't really useful for actually completing
630
- // the token but are more descriptive hints for the user
631
- // (e.g. "isMultiple(of: Int) -> Bool"). They aren't useful for
632
- // actually completing anything so let's use the current token as
633
- // a placeholder that is always valid.
634
- if (!llvm_match.empty ())
635
- request.AddCompletion (prefix, llvm_match);
636
- }
637
- } break ;
634
+ // Otherwise, advance through the completion state machine.
635
+ const swift::CompletionState completion_state = completions.getState ();
636
+ switch (completion_state) {
637
+ case swift::CompletionState::CompletedRoot: {
638
+ // Display the completion list.
639
+ llvm::ArrayRef<llvm::StringRef> llvm_matches =
640
+ completions.getCompletionList ();
641
+ for (const auto &llvm_match : llvm_matches) {
642
+ // The completions here aren't really useful for actually completing
643
+ // the token but are more descriptive hints for the user
644
+ // (e.g. "isMultiple(of: Int) -> Bool"). They aren't useful for
645
+ // actually completing anything so let's use the current token as
646
+ // a placeholder that is always valid.
647
+ if (!llvm_match.empty ())
648
+ request.AddCompletion (prefix, llvm_match);
649
+ }
650
+ } break ;
638
651
639
- case swift::CompletionState::DisplayedCompletionList: {
640
- // Complete the next completion stem in the cycle.
641
- request.AddCompletion (prefix + completions.getPreviousStem ().InsertableString .str ());
642
- } break ;
652
+ case swift::CompletionState::DisplayedCompletionList: {
653
+ // Complete the next completion stem in the cycle.
654
+ request.AddCompletion (
655
+ prefix + completions.getPreviousStem ().InsertableString .str ());
656
+ } break ;
643
657
644
- case swift::CompletionState::Empty:
645
- case swift::CompletionState::Unique: {
646
- llvm::StringRef root = completions.getRoot ();
658
+ case swift::CompletionState::Empty:
659
+ case swift::CompletionState::Unique: {
660
+ llvm::StringRef root = completions.getRoot ();
647
661
648
- if (!root.empty ())
649
- request.AddCompletion (prefix + root.str ());
650
- } break ;
662
+ if (!root.empty ())
663
+ request.AddCompletion (prefix + root.str ());
664
+ } break ;
651
665
652
- case swift::CompletionState::Invalid:
653
- llvm_unreachable (" got an invalid completion set?!" );
654
- }
666
+ case swift::CompletionState::Invalid:
667
+ llvm_unreachable (" got an invalid completion set?!" );
655
668
}
656
669
}
657
670
}
0 commit comments