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