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 | #include "llvm/Support/ExtensibleRTTI.h" |
19 | |
20 | namespace lldb_private { |
21 | |
22 | class REPL : public IOHandlerDelegate, |
23 | public llvm::RTTIExtends<REPL, llvm::RTTIRoot> { |
24 | public: |
25 | /// LLVM RTTI support |
26 | static char ID; |
27 | |
28 | REPL(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 | |
59 | void SetFormatOptions(const OptionGroupFormat &options) { |
60 | m_format_options = options; |
61 | } |
62 | |
63 | void |
64 | SetValueObjectDisplayOptions(const OptionGroupValueObjectDisplay &options) { |
65 | m_varobj_options = options; |
66 | } |
67 | |
68 | void SetEvaluateOptions(const EvaluateExpressionOptions &options) { |
69 | m_expr_options = options; |
70 | } |
71 | |
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 | llvm::StringRef 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 | /// Method that can be optionally overriden by subclasses to get notified |
111 | /// whenever an expression has been evaluated. The params of this method |
112 | /// include the inputs and outputs of the expression evaluation. |
113 | /// |
114 | /// Note: meta commands that start with : are not covered by this method. |
115 | /// |
116 | /// \return |
117 | /// An \a Error object that, if it is a failure, aborts the regular |
118 | /// REPL expression result handling. |
119 | virtual llvm::Error |
120 | OnExpressionEvaluated(const ExecutionContext &exe_ctx, llvm::StringRef code, |
121 | const EvaluateExpressionOptions &expr_options, |
122 | lldb::ExpressionResults execution_results, |
123 | const lldb::ValueObjectSP &result_valobj_sp, |
124 | const Status &error) { |
125 | return llvm::Error::success(); |
126 | } |
127 | |
128 | static int CalculateActualIndentation(const StringList &lines); |
129 | |
130 | // Subclasses should override these functions to implement a functional REPL. |
131 | |
132 | virtual Status DoInitialization() = 0; |
133 | |
134 | virtual llvm::StringRef GetSourceFileBasename() = 0; |
135 | |
136 | virtual const char *GetAutoIndentCharacters() = 0; |
137 | |
138 | virtual bool SourceIsComplete(const std::string &source) = 0; |
139 | |
140 | virtual lldb::offset_t GetDesiredIndentation( |
141 | const StringList &lines, int cursor_position, |
142 | int tab_size) = 0; // LLDB_INVALID_OFFSET means no change |
143 | |
144 | virtual lldb::LanguageType GetLanguage() = 0; |
145 | |
146 | virtual bool PrintOneVariable(Debugger &debugger, |
147 | lldb::StreamFileSP &output_sp, |
148 | lldb::ValueObjectSP &valobj_sp, |
149 | ExpressionVariable *var = nullptr) = 0; |
150 | |
151 | virtual void CompleteCode(const std::string ¤t_code, |
152 | CompletionRequest &request) = 0; |
153 | |
154 | OptionGroupFormat m_format_options = OptionGroupFormat(lldb::eFormatDefault); |
155 | OptionGroupValueObjectDisplay m_varobj_options; |
156 | EvaluateExpressionOptions m_expr_options; |
157 | std::string m_compiler_options; |
158 | |
159 | bool m_enable_auto_indent = true; |
160 | std::string m_indent_str; // Use this string for each level of indentation |
161 | std::string m_current_indent_str; |
162 | uint32_t m_current_indent_level = 0; |
163 | |
164 | std::string m_repl_source_path; |
165 | bool m_dedicated_repl_mode = false; |
166 | |
167 | StringList m_code; // All accumulated REPL statements are saved here |
168 | |
169 | Target &m_target; |
170 | lldb::IOHandlerSP m_io_handler_sp; |
171 | |
172 | private: |
173 | std::string GetSourcePath(); |
174 | }; |
175 | |
176 | } // namespace lldb_private |
177 | |
178 | #endif // LLDB_EXPRESSION_REPL_H |
179 | |