1 //===-- REPL.h --------------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_EXPRESSION_REPL_H 10 #define LLDB_EXPRESSION_REPL_H 11 12 #include <string> 13 14 #include "lldb/Core/IOHandler.h" 15 #include "lldb/Interpreter/OptionGroupFormat.h" 16 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" 17 #include "lldb/Target/Target.h" 18 19 namespace lldb_private { 20 21 class REPL : public IOHandlerDelegate { 22 public: 23 // See TypeSystem.h for how to add subclasses to this. 24 enum LLVMCastKind { eKindClang, eKindSwift, eKindGo, kNumKinds }; 25 getKind()26 LLVMCastKind getKind() const { return m_kind; } 27 28 REPL(LLVMCastKind kind, Target &target); 29 30 ~REPL() override; 31 32 /// Get a REPL with an existing target (or, failing that, a debugger to use), 33 /// and (optional) extra arguments for the compiler. 34 /// 35 /// \param[out] Status 36 /// If this language is supported but the REPL couldn't be created, this 37 /// error is populated with the reason. 38 /// 39 /// \param[in] language 40 /// The language to create a REPL for. 41 /// 42 /// \param[in] debugger 43 /// If provided, and target is nullptr, the debugger to use when setting 44 /// up a top-level REPL. 45 /// 46 /// \param[in] target 47 /// If provided, the target to put the REPL inside. 48 /// 49 /// \param[in] repl_options 50 /// If provided, additional options for the compiler when parsing REPL 51 /// expressions. 52 /// 53 /// \return 54 /// The range of the containing object in the target process. 55 static lldb::REPLSP Create(Status &Status, lldb::LanguageType language, 56 Debugger *debugger, Target *target, 57 const char *repl_options); 58 SetFormatOptions(const OptionGroupFormat & options)59 void SetFormatOptions(const OptionGroupFormat &options) { 60 m_format_options = options; 61 } 62 63 void SetValueObjectDisplayOptions(const OptionGroupValueObjectDisplay & options)64 SetValueObjectDisplayOptions(const OptionGroupValueObjectDisplay &options) { 65 m_varobj_options = options; 66 } 67 SetEvaluateOptions(const EvaluateExpressionOptions & options)68 void SetEvaluateOptions(const EvaluateExpressionOptions &options) { 69 m_expr_options = options; 70 } 71 SetCompilerOptions(const char * options)72 void SetCompilerOptions(const char *options) { 73 if (options) 74 m_compiler_options = options; 75 } 76 77 lldb::IOHandlerSP GetIOHandler(); 78 79 Status RunLoop(); 80 81 // IOHandler::Delegate functions 82 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override; 83 84 bool IOHandlerInterrupt(IOHandler &io_handler) override; 85 86 void IOHandlerInputInterrupted(IOHandler &io_handler, 87 std::string &line) override; 88 89 const char *IOHandlerGetFixIndentationCharacters() override; 90 91 ConstString IOHandlerGetControlSequence(char ch) override; 92 93 const char *IOHandlerGetCommandPrefix() override; 94 95 const char *IOHandlerGetHelpPrologue() override; 96 97 bool IOHandlerIsInputComplete(IOHandler &io_handler, 98 StringList &lines) override; 99 100 int IOHandlerFixIndentation(IOHandler &io_handler, const StringList &lines, 101 int cursor_position) override; 102 103 void IOHandlerInputComplete(IOHandler &io_handler, 104 std::string &line) override; 105 106 void IOHandlerComplete(IOHandler &io_handler, 107 CompletionRequest &request) override; 108 109 protected: 110 static int CalculateActualIndentation(const StringList &lines); 111 112 // Subclasses should override these functions to implement a functional REPL. 113 114 virtual Status DoInitialization() = 0; 115 116 virtual ConstString GetSourceFileBasename() = 0; 117 118 virtual const char *GetAutoIndentCharacters() = 0; 119 120 virtual bool SourceIsComplete(const std::string &source) = 0; 121 122 virtual lldb::offset_t GetDesiredIndentation( 123 const StringList &lines, int cursor_position, 124 int tab_size) = 0; // LLDB_INVALID_OFFSET means no change 125 126 virtual lldb::LanguageType GetLanguage() = 0; 127 128 virtual bool PrintOneVariable(Debugger &debugger, 129 lldb::StreamFileSP &output_sp, 130 lldb::ValueObjectSP &valobj_sp, 131 ExpressionVariable *var = nullptr) = 0; 132 133 virtual void CompleteCode(const std::string ¤t_code, 134 CompletionRequest &request) = 0; 135 136 OptionGroupFormat m_format_options = OptionGroupFormat(lldb::eFormatDefault); 137 OptionGroupValueObjectDisplay m_varobj_options; 138 EvaluateExpressionOptions m_expr_options; 139 std::string m_compiler_options; 140 141 bool m_enable_auto_indent = true; 142 std::string m_indent_str; // Use this string for each level of indentation 143 std::string m_current_indent_str; 144 uint32_t m_current_indent_level = 0; 145 146 std::string m_repl_source_path; 147 bool m_dedicated_repl_mode = false; 148 149 StringList m_code; // All accumulated REPL statements are saved here 150 151 Target &m_target; 152 lldb::IOHandlerSP m_io_handler_sp; 153 LLVMCastKind m_kind; 154 155 private: 156 std::string GetSourcePath(); 157 }; 158 159 } // namespace lldb_private 160 161 #endif // LLDB_EXPRESSION_REPL_H 162