@@ -90,27 +90,41 @@ void SwiftASTManipulator::WrapExpression(
90
90
__builtin_logger_initialize()
91
91
)" ;
92
92
93
- // The debug function declarations need only be declared once per session - on the first REPL call.
94
- // This code assumes that the first call is the first REPL call; don't call playground once then playground || repl again
93
+ // The debug function declarations need only be declared once per session -
94
+ // on the first REPL call. This code assumes that the first call is the
95
+ // first REPL call; don't call playground once then playground || repl
96
+ // again
95
97
bool first_expression = options.GetPreparePlaygroundStubFunctions ();
96
98
97
- const char *playground_prefix = first_expression ? playground_logger_declarations : " " ;
99
+ const char *playground_prefix =
100
+ first_expression ? playground_logger_declarations : " " ;
98
101
99
102
if (pound_file && pound_line) {
100
103
wrapped_stream.Printf (" %s#sourceLocation(file: \" %s\" , line: %u)\n %s\n " ,
101
104
playground_prefix, pound_file, pound_line,
102
105
orig_text);
103
106
} else {
104
- // In 2017+, xcode playgrounds send orig_text that starts with a module loading prefix (not the above prefix), then a sourceLocation specifier that indicates the page name, and then the page body text.
105
- // The first_body_line mechanism in this function cannot be used to compensate for the playground_prefix added here, since it incorrectly continues to apply even after sourceLocation directives are read frmo the orig_text.
106
- // To make sure playgrounds work correctly whether or not they supply their own sourceLocation, create a dummy sourceLocation here with a fake filename that starts counting the first line of orig_text as line 1.
107
+ // In 2017+, xcode playgrounds send orig_text that starts with a module
108
+ // loading prefix (not the above prefix), then a sourceLocation specifier
109
+ // that indicates the page name, and then the page body text. The
110
+ // first_body_line mechanism in this function cannot be used to
111
+ // compensate for the playground_prefix added here, since it incorrectly
112
+ // continues to apply even after sourceLocation directives are read from
113
+ // the orig_text. To make sure playgrounds work correctly whether or not
114
+ // they supply their own sourceLocation, create a dummy sourceLocation
115
+ // here with a fake filename that starts counting the first line of
116
+ // orig_text as line 1.
107
117
wrapped_stream.Printf (" %s#sourceLocation(file: \" %s\" , line: %u)\n %s\n " ,
108
118
playground_prefix, " Playground.swift" , 1 ,
109
119
orig_text);
110
120
}
111
121
first_body_line = 1 ;
112
122
return ;
113
- } else if (repl) { // repl but not playground.
123
+ }
124
+
125
+ assert (!playground && " Playground mode not expected" );
126
+
127
+ if (repl) {
114
128
if (pound_file && pound_line) {
115
129
wrapped_stream.Printf (" #sourceLocation(file: \" %s\" , line: %u)\n %s\n " ,
116
130
llvm::sys::path::filename (pound_file).str ().c_str (),
@@ -122,87 +136,85 @@ __builtin_logger_initialize()
122
136
return ;
123
137
}
124
138
125
- std::string expr_source_path ;
139
+ assert (!playground && !repl && " Playground/REPL mode not expected " ) ;
126
140
127
141
if (pound_file && pound_line) {
128
142
fixed_text.Printf (" #sourceLocation(file: \" %s\" , line: %u)\n %s\n " ,
129
143
pound_file, pound_line, orig_text);
130
144
text = fixed_text.GetString ().data ();
131
145
} else if (generate_debug_info) {
146
+ std::string expr_source_path;
132
147
if (SwiftASTManipulator::SaveExpressionTextToTempFile (orig_text, options,
133
- expr_source_path)) {
148
+ expr_source_path)) {
134
149
fixed_text.Printf (" #sourceLocation(file: \" %s\" , line: 1)\n %s\n " ,
135
150
expr_source_path.c_str (), orig_text);
136
151
text = fixed_text.GetString ().data ();
137
152
}
138
153
}
139
154
140
155
// Note: All the wrapper functions we make are marked with the
141
- // @LLDBDebuggerFunction macro so that the compiler
142
- // can do whatever special treatment it need to do on them. If you add new
143
- // variants be sure to mark them this way.
144
- // Also, any function that might end up being in an extension of swift class
145
- // needs to be marked final, since otherwise
146
- // the compiler might try to dispatch them dynamically, which it can't do
147
- // correctly for these functions.
148
-
149
- llvm::SmallString<32 > buffer;
150
- llvm::raw_svector_ostream os (buffer);
156
+ // @LLDBDebuggerFunction macro so that the compiler can do whatever special
157
+ // treatment it need to do on them. If you add new variants be sure to mark
158
+ // them this way. Also, any function that might end up being in an extension
159
+ // of swift class needs to be marked final, since otherwise the compiler
160
+ // might try to dispatch them dynamically, which it can't do correctly for
161
+ // these functions.
162
+
163
+ std::string availability = " " ;
151
164
if (!os_version.empty ())
152
- os << " @available(" << os_version << " , *)" ;
153
- std::string availability = os.str ();
165
+ availability = (llvm::Twine (" @available(" ) + os_version + " , *)" ).str ();
154
166
155
167
StreamString wrapped_expr_text;
156
- wrapped_expr_text.Printf (" do\n "
157
- " {\n "
158
- " %s%s%s\n " // Don't indent the code so error columns
159
- // match up with errors from compiler
160
- " }\n "
161
- " catch (let __lldb_tmp_error)\n "
162
- " {\n "
163
- " var %s = __lldb_tmp_error\n "
164
- " }\n " ,
168
+
169
+ // Avoid indenting user code: this makes column information from compiler
170
+ // errors match up with what the user typed.
171
+ wrapped_expr_text.Printf (R"(
172
+ do {
173
+ %s%s%s
174
+ } catch (let __lldb_tmp_error) {
175
+ var %s = __lldb_tmp_error
176
+ }
177
+ )" ,
165
178
GetUserCodeStartMarker (), text,
166
179
GetUserCodeEndMarker (), GetErrorName ());
167
180
168
- if (needs_object_ptr | static_method) {
181
+ if (needs_object_ptr || static_method) {
169
182
const char *func_decorator = " " ;
170
183
if (static_method) {
171
184
if (is_class)
172
185
func_decorator = " final class" ;
173
186
else
174
187
func_decorator = " static" ;
175
- } else if (is_class &&
176
- !(weak_self)) {
188
+ } else if (is_class && !weak_self) {
177
189
func_decorator = " final" ;
178
190
} else {
179
191
func_decorator = " mutating" ;
180
192
}
181
193
182
194
const char *optional_extension =
183
- ( weak_self)
184
- ? " Swift.Optional where Wrapped == "
185
- : " " ;
186
-
187
- wrapped_stream. Printf (
188
- " extension %s$__lldb_context { \n "
189
- " @LLDBDebuggerFunction %s \n "
190
- " %s func $__lldb_wrapped_expr_%u(_ $__lldb_arg : "
191
- " UnsafeMutablePointer<Any>) { \n "
192
- " %s " // This is the expression text (with newlines).
193
- " } \n "
194
- " } \n "
195
- " %s \n "
196
- " func $__lldb_expr(_ $__lldb_arg : UnsafeMutablePointer<Any>) { \n "
197
- " do { \n "
198
- " $__lldb_injected_self.$__lldb_wrapped_expr_%u( \n "
199
- " $__lldb_arg \n "
200
- " ) \n "
201
- " } \n "
202
- " } \n " ,
203
- optional_extension, availability. c_str (), func_decorator,
204
- current_counter, wrapped_expr_text.GetData (), availability.c_str (),
205
- current_counter);
195
+ weak_self ? " Swift.Optional where Wrapped == " : " " ;
196
+
197
+ // The expression text is inserted into the body of $__lldb_wrapped_expr_%u.
198
+ wrapped_stream. Printf ( R"(
199
+ extension %s$__lldb_context {
200
+ @LLDBDebuggerFunction %s
201
+ %s func $__lldb_wrapped_expr_%u(_ $__lldb_arg : UnsafeMutablePointer<Any>) {
202
+ %s
203
+ }
204
+ }
205
+ %s
206
+ func $__lldb_expr(_ $__lldb_arg : UnsafeMutablePointer<Any>) {
207
+ do {
208
+ $__lldb_injected_self.$__lldb_wrapped_expr_%u(
209
+ $__lldb_arg
210
+ )
211
+ }
212
+ }
213
+ )" ,
214
+ optional_extension, availability. c_str () ,
215
+ func_decorator, current_counter ,
216
+ wrapped_expr_text.GetData (), availability.c_str (),
217
+ current_counter);
206
218
207
219
first_body_line = 5 ;
208
220
} else {
0 commit comments