aboutsummaryrefslogtreecommitdiffstats
path: root/include/lldb/Expression/REPL.h
blob: 850d2f6f961a963a5894f6d131a2da2d295a0f52 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
//===-- REPL.h --------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef lldb_REPL_h
#define lldb_REPL_h

#include <string>

#include "lldb/Core/IOHandler.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
#include "lldb/Target/Target.h"

namespace lldb_private {

class REPL : public IOHandlerDelegate {
public:
  // See TypeSystem.h for how to add subclasses to this.
  enum LLVMCastKind { eKindClang, eKindSwift, eKindGo, kNumKinds };

  LLVMCastKind getKind() const { return m_kind; }

  REPL(LLVMCastKind kind, Target &target);

  ~REPL() override;

  /// Get a REPL with an existing target (or, failing that, a debugger to use),
  /// and (optional) extra arguments for the compiler.
  ///
  /// \param[out] error
  ///     If this language is supported but the REPL couldn't be created, this
  ///     error is populated with the reason.
  ///
  /// \param[in] language
  ///     The language to create a REPL for.
  ///
  /// \param[in] debugger
  ///     If provided, and target is nullptr, the debugger to use when setting
  ///     up a top-level REPL.
  ///
  /// \param[in] target
  ///     If provided, the target to put the REPL inside.
  ///
  /// \param[in] repl_options
  ///     If provided, additional options for the compiler when parsing REPL
  ///     expressions.
  ///
  /// \return
  ///     The range of the containing object in the target process.
  static lldb::REPLSP Create(Status &Status, lldb::LanguageType language,
                             Debugger *debugger, Target *target,
                             const char *repl_options);

  void SetFormatOptions(const OptionGroupFormat &options) {
    m_format_options = options;
  }

  void
  SetValueObjectDisplayOptions(const OptionGroupValueObjectDisplay &options) {
    m_varobj_options = options;
  }

  void SetEvaluateOptions(const EvaluateExpressionOptions &options) {
    m_expr_options = options;
  }

  void SetCompilerOptions(const char *options) {
    if (options)
      m_compiler_options = options;
  }

  lldb::IOHandlerSP GetIOHandler();

  Status RunLoop();

  // IOHandler::Delegate functions
  void IOHandlerActivated(IOHandler &io_handler, bool interactive) override;

  bool IOHandlerInterrupt(IOHandler &io_handler) override;

  void IOHandlerInputInterrupted(IOHandler &io_handler,
                                 std::string &line) override;

  const char *IOHandlerGetFixIndentationCharacters() override;

  ConstString IOHandlerGetControlSequence(char ch) override;

  const char *IOHandlerGetCommandPrefix() override;

  const char *IOHandlerGetHelpPrologue() override;

  bool IOHandlerIsInputComplete(IOHandler &io_handler,
                                StringList &lines) override;

  int IOHandlerFixIndentation(IOHandler &io_handler, const StringList &lines,
                              int cursor_position) override;

  void IOHandlerInputComplete(IOHandler &io_handler,
                              std::string &line) override;

  int IOHandlerComplete(IOHandler &io_handler, const char *current_line,
                        const char *cursor, const char *last_char,
                        int skip_first_n_matches, int max_matches,
                        StringList &matches, StringList &descriptions) override;

protected:
  static int CalculateActualIndentation(const StringList &lines);

  // Subclasses should override these functions to implement a functional REPL.

  virtual Status DoInitialization() = 0;

  virtual ConstString GetSourceFileBasename() = 0;

  virtual const char *GetAutoIndentCharacters() = 0;

  virtual bool SourceIsComplete(const std::string &source) = 0;

  virtual lldb::offset_t GetDesiredIndentation(
      const StringList &lines, int cursor_position,
      int tab_size) = 0; // LLDB_INVALID_OFFSET means no change

  virtual lldb::LanguageType GetLanguage() = 0;

  virtual bool PrintOneVariable(Debugger &debugger,
                                lldb::StreamFileSP &output_sp,
                                lldb::ValueObjectSP &valobj_sp,
                                ExpressionVariable *var = nullptr) = 0;

  virtual int CompleteCode(const std::string &current_code,
                           StringList &matches) = 0;

  OptionGroupFormat m_format_options = OptionGroupFormat(lldb::eFormatDefault);
  OptionGroupValueObjectDisplay m_varobj_options;
  EvaluateExpressionOptions m_expr_options;
  std::string m_compiler_options;

  bool m_enable_auto_indent = true;
  std::string m_indent_str; // Use this string for each level of indentation
  std::string m_current_indent_str;
  uint32_t m_current_indent_level = 0;

  std::string m_repl_source_path;
  bool m_dedicated_repl_mode = false;

  StringList m_code; // All accumulated REPL statements are saved here

  Target &m_target;
  lldb::IOHandlerSP m_io_handler_sp;
  LLVMCastKind m_kind;

private:
  std::string GetSourcePath();
};

} // namespace lldb_private

#endif // lldb_REPL_h