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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
//! Procedural macros for GPUI.
//!
//! `gpui` re-exports these macros, so use them as `gpui::test`,
//! `#[derive(gpui::Action)]`, and so on. Application crates do not need a
//! direct dependency on this crate.
//!
//! Derives:
//!
//! - `Action`: implements `gpui::Action` for a type that you can bind to keys.
//! - `IntoElement`, `Render`: implement the traits that let a type enter the element tree.
//! - `Styled`, `ParentElement`, `InteractiveElement`, `StatefulInteractiveElement`:
//! implement the builder traits for a type that holds a field for them.
//! - `AppContext`, `VisualContext`: forward context methods from a wrapper around
//! `&mut App` or `&mut Window`.
//!
//! Attributes and function-like macros:
//!
//! - `#[gpui::test]`, `#[gpui::property_test]` and `#[gpui::bench]` define
//! tests and benchmarks that run with GPUI support.
//! - `register_action!` registers a hand-written `Action` impl.
//! - The `*_style_methods!` macros generate the builder methods of `Styled`.
use TokenStream;
use ;
/// Derives `gpui::Action` for a type and registers it with the runtime.
///
/// Use it for any type that a keymap or the command palette should be able to
/// name. The type must implement `Clone` and `PartialEq`. Unless the type is a
/// unit struct or `no_json` is set, it must also implement `serde::Deserialize`
/// and `schemars::JsonSchema`, so that keymaps can build it from JSON.
///
/// The doc comment on the type becomes the action's documentation. The
/// `#[action(...)]` attribute sets the name, namespace, aliases and
/// deprecation. See `gpui::Action` for the full attribute reference.
///
/// Use [`register_action!`] if you implement `gpui::Action` by hand.
/// Registers a type that implements `gpui::Action` by hand.
///
/// Use this when `#[derive(Action)]` doesn't fit, such as when you need a
/// custom `build` or `name`. Pass the type's name, which must be in scope in
/// the module that calls the macro. Call it once per type, in the same crate
/// that defines the type, because the macro adds an inherent `impl` block to
/// the type.
///
/// `register_action!(MyAction);`
/// Derives `gpui::IntoElement` for a type that implements `gpui::RenderOnce`.
///
/// The generated `into_element` wraps the value in a `gpui::ViewElement`, which
/// renders it as part of the element tree. This lets you pass the value
/// directly as a child of another element.
/// Derives `gpui::Styled` for a struct with a `#[style]` field.
///
/// The field must have the type `gpui::StyleRefinement`. The derived `style`
/// method returns that field, so the builder methods such as `flex` and `gap`
/// write to it. Mark at most one field.
/// Derives `gpui::ParentElement` for a struct with a `#[children]` field.
///
/// The field must be a collection that has an `extend` method that accepts
/// `gpui::AnyElement` values, typically a `Vec<AnyElement>`. Its `child` and
/// `children` methods add to it. Mark at most one field.
/// Derives `gpui::InteractiveElement` for a struct with an `#[interactivity]`
/// field.
///
/// The field must have the type `gpui::Interactivity`. Mark at most one field.
/// Derives `gpui::StatefulInteractiveElement`, which adds methods such as `role`.
///
/// The derive writes an empty impl, so the trait's default methods become available.
/// The type must also implement `gpui::InteractiveElement`, which you can derive with
/// `#[derive(InteractiveElement)]`.
/// Derives `gpui::Render` with a `render` method that returns `gpui::Empty`.
///
/// Use it for a view that holds state but draws nothing. Write `impl Render`
/// by hand for any view that draws something.
/// Derives `gpui::AppContext` for a struct that holds a `&mut gpui::App`.
///
/// Mark the field that holds the `&mut App` with `#[app]`. The derived methods
/// forward to that field, so the struct can be used wherever an `AppContext`
/// is accepted. The attribute is required.
///
/// Without the attribute the derive fails to compile:
///
/// ```compile_fail
/// # #[macro_use] extern crate gpui_macros;
/// # #[macro_use] extern crate gpui;
/// #[derive(AppContext)]
/// struct MyContext<'a> {
/// app: &'a mut gpui::App
/// }
/// ```
/// Derives `gpui::VisualContext` for a struct that holds a `&mut gpui::App`
/// and a `&mut gpui::Window`.
///
/// Mark the `&mut App` field with `#[app]` and the `&mut Window` field with
/// `#[window]`. Both attributes are required. The derived methods forward to
/// those fields.
///
/// Failing to add either attribute causes a compile error:
///
/// ```compile_fail
/// # #[macro_use] extern crate gpui_macros;
/// # #[macro_use] extern crate gpui;
/// #[derive(VisualContext)]
/// struct MyContext<'a, 'b> {
/// #[app]
/// app: &'a mut gpui::App,
/// window: &'b mut gpui::Window
/// }
/// ```
///
/// ```compile_fail
/// # #[macro_use] extern crate gpui_macros;
/// # #[macro_use] extern crate gpui;
/// #[derive(VisualContext)]
/// struct MyContext<'a, 'b> {
/// app: &'a mut gpui::App,
/// #[window]
/// window: &'b mut gpui::Window
/// }
/// ```
/// Generates the style helper methods on `Styled`. Used inside `gpui`.
/// Generates the style transition builder and its application code. Used inside `gpui`.
/// Generates the `visible` and `invisible` methods for `Styled`.
///
/// Call it in the body of the `Styled` trait. The optional
/// `{ visibility: pub }` argument sets the visibility of the generated methods.
/// Generates the margin methods for `Styled`, such as `m_4` and `mx_auto`.
///
/// Call it in the body of the `Styled` trait. The optional
/// `{ visibility: pub }` argument sets the visibility of the generated methods.
/// Generates the padding methods for `Styled`, such as `p_4` and `px_2`.
///
/// Call it in the body of the `Styled` trait. The optional
/// `{ visibility: pub }` argument sets the visibility of the generated methods.
/// Generates the position methods for `Styled`, such as `relative` and `absolute`.
///
/// Call it in the body of the `Styled` trait. The optional
/// `{ visibility: pub }` argument sets the visibility of the generated methods.
/// Generates the overflow methods for `Styled`, such as `overflow_hidden`.
///
/// Call it in the body of the `Styled` trait. The optional
/// `{ visibility: pub }` argument sets the visibility of the generated methods.
/// Generates the cursor methods for `Styled`, such as `cursor_pointer`.
///
/// Call it in the body of the `Styled` trait. The optional
/// `{ visibility: pub }` argument sets the visibility of the generated methods.
/// Generates the border methods for `Styled`, such as `border_1` and `border_color`.
///
/// Call it in the body of the `Styled` trait. The optional
/// `{ visibility: pub }` argument sets the visibility of the generated methods.
/// Generates the box-shadow and corner methods for `Styled`.
///
/// Call it in the body of the `Styled` trait. The optional
/// `{ visibility: pub }` argument sets the visibility of the generated methods.
/// Marks a function as a GPUI test. The generated function is a `#[test]`, so
/// it runs under `cargo test` or `cargo nextest`.
///
/// The function can be synchronous or `async`. Its parameters decide what it
/// receives:
///
/// - `&mut TestAppContext` (or `&TestAppContext`): a fresh test context. Use one
/// per app you need. Any number is allowed.
/// - `&mut App`: a synchronous test only. The test gets the app directly.
/// - `BackgroundExecutor`: an `async` test only. An executor for the test's
/// scheduler.
/// - `StdRng`: a random number generator seeded with the current run's seed.
/// Use it to vary inputs. Each run sees the same values for the same seed, so
/// changing the seed explores other interleavings.
///
/// Any other parameter type is a compile error.
///
/// An `async` test takes a context, for example
/// `async fn test_counter(cx: &mut TestAppContext)`, and runs inside the test
/// scheduler.
///
/// Your crate needs `rand` as a dev-dependency, because the generated code
/// calls `rand::SeedableRng` to seed a `StdRng` parameter.
///
/// # Arguments
///
/// - `#[gpui::test]` with no arguments runs once, with seed `0` or the value of
/// the `SEED` environment variable.
/// - `#[gpui::test(seed = 10)]` runs once with seed `10`.
/// - `#[gpui::test(seeds(10, 20, 30))]` runs once for each of seeds `10`, `20`
/// and `30`.
/// - `#[gpui::test(iterations = 5)]` runs with seeds `0` to `4`.
/// - `#[gpui::test(retries = 3)]` retries a failing seed up to three more times,
/// so a seed runs at most four times. The retries are per seed.
/// - `#[gpui::test(on_failure = "crate::test::report_failure")]` calls the named
/// function with no arguments once a seed has failed on its final attempt,
/// before the test panics. Use it to write out more details about the failure.
/// The path must be a `fn()`.
///
/// `iterations` combines with `seed` and `seeds`. The iteration seeds run first,
/// then the explicit seeds. For example, `#[gpui::test(iterations = 5, seed = 10)]`
/// runs seeds `0, 1, 2, 3, 4, 10`.
///
/// When a run has more than one seed, the macro prints each seed to stderr. It
/// prints the failing seed too, along with how to rerun it.
///
/// # Environment Variables
///
/// - `SEED`: runs only that seed (or `SEED` through `SEED + iterations - 1` when
/// `iterations` is set). It overrides every explicit seed.
/// - `ITERATIONS`: overrides the value of the `iterations` argument.
/// Turns a function into a Criterion benchmark that runs with GPUI support.
///
/// The function takes a `&mut gpui::BenchAppContext`, and it is not `async`.
/// Put the work to measure in the body, and the macro measures it with
/// Criterion. Benchmarks with an `inputs` argument take the input as their
/// first parameter, before the context: `fn bench(input: T, cx: &mut BenchAppContext)`.
///
/// The macro generates a function that takes `&mut criterion::Criterion`, so
/// register it with `criterion_group!` and `criterion_main!` in the benchmark
/// target. Each benchmark prints a GPUI report when it finishes.
///
/// # Arguments
///
/// - `fps = N` sets the frame rate that the report budgets against. `N` must be
/// greater than zero. The default comes from `gpui::BenchReport`.
/// - `inputs = EXPR` runs the benchmark once for each item of `EXPR`, using
/// Criterion's `bench_with_input`.
/// - `input_name = "..."` sets the name of each input in the report. Requires
/// `inputs`. The default is the function name.
/// - `group = "..."` sets the name of the benchmark group. Requires `inputs`.
/// The default is the function name.
/// - `sample_size = N` sets the number of Criterion samples for the group.
/// Requires `inputs`, and `N` must be greater than zero.
///
/// # Dependencies
///
/// The benchmark crate needs `criterion` and `gpui_platform` as dev-dependencies,
/// because the generated code calls both. Enable the `bench-support` feature on
/// `gpui`, which provides `BenchAppContext`.
///
/// A benchmark that takes a `StdRng` parameter (by value, in any position) is run
/// once per seed, with the RNG seeded from it. Seeds are chosen exactly as for
/// `#[gpui::test]`: `seed = N`, `seeds(...)`, and `iterations = N` take the same
/// meaning, and the `SEED` and `ITERATIONS` environment variables override them the
/// same way, so one `SEED` reproduces a test or a benchmark. Each seed is its own
/// Criterion benchmark, named `<input>/seed-<seed>` (or `<function>/seed-<seed>`
/// without inputs), and the RNG is rebuilt for every Criterion routine call so all
/// samples measure the same seed. The generated code seeds it through gpui's own
/// `rand`, so the crate needs `rand` only to name `StdRng` in the signature.
///
/// ```ignore
/// #[gpui::bench(inputs = families(), iterations = 6)]
/// fn full_refresh(family: &Family, mut rng: StdRng, cx: &mut BenchAppContext) {
/// let tree = family.sample(&mut rng);
/// // ...
/// }
/// ```
///
/// The benchmark crate must add `criterion` and `gpui_platform` (with its
/// `test-support` feature) to its dev-dependencies and enable gpui's `bench`
/// feature, since the generated code references all three.
/// A variant of `#[gpui::test]` that runs a test with many generated inputs.
///
/// A property test checks a claim for many generated inputs. For example, a
/// function with `x: i32` and `y: i32` runs for generated pairs of integers;
/// the test body should hold for every pair.
///
/// Standard GPUI randomized tests provide you with an instance of `StdRng` to
/// generate random data in a controlled manner. Property-based tests have some
/// advantages, however:
/// - Shrinking reduces a failing input to a smaller case that still fails.
/// - The harness generates values, so the test body contains only the property.
/// - Failing cases are saved to a file and replayed before new cases.
///
/// Property tests work best when all inputs can be generated up-front and kept
/// in a simple data structure. Sometimes, this isn't possible - for example, if
/// a test needs to make a random decision based on the current state of some
/// structure. In this case, a standard GPUI randomized test may be more
/// suitable.
///
/// ## Customizing random values
///
/// This macro is based on the [`#[proptest::property_test]`] macro, but handles
/// some of the same GPUI-specific arguments as `#[gpui::test]`. Specifically,
/// `&{mut,} TestAppContext` and `BackgroundExecutor` work as normal. `StdRng`
/// arguments are **explicitly forbidden**, since they break shrinking, and are
/// a common footgun.
///
/// All other arguments are forwarded to the underlying proptest macro.
///
/// The code that proptest's macro generates names the `proptest` crate directly, so a crate that
/// uses this macro needs `proptest`, with its `attr-macro` feature, in its dev-dependencies.
///
/// The following terms come from proptest's
/// [`#[proptest::property_test]`] documentation.
///
/// Random values of type `T` are generated by a `Strategy<Value = T>` object.
/// Some types have a canonical `Strategy` - these types also implement
/// `Arbitrary`. Parameters to a `#[gpui::property_test]`, by default, use a
/// type's `Arbitrary` implementation. If you'd like to provide a custom
/// strategy, put `#[strategy = ...]` on the argument. For example,
/// `#[strategy = 1..10] x: i32` draws `x` from the range `1..10`.
///
/// For more information on writing custom `Strategy` and `Arbitrary`
/// implementations, see [the proptest book][book], and the [`Strategy`] trait.
///
/// ## Scheduler
///
/// Each case receives a scheduler seed, which the macro supplies as a parameter
/// that doesn't shrink, because all seeds are equally simple. Without `SEED`,
/// the case seeds come from a proptest generator fixed at `0`, so runs are
/// reproducible. If `SEED` is set, every case uses that value as its scheduler
/// seed, and the proptest generator is seeded with it too. To control other
/// values, use custom `Strategy`s.
///
/// [`#[proptest::property_test]`]: https://docs.rs/proptest/latest/proptest/attr.property_test.html
/// [book]: https://proptest-rs.github.io/proptest/intro.html
/// [`Strategy`]: https://docs.rs/proptest/latest/proptest/strategy/trait.Strategy.html
/// When added to a trait, `#[derive_inspector_reflection]` generates a module which provides
/// enumeration and lookup by name of all methods that have the shape `fn method(self) -> Self`.
/// This is used by the inspector so that it can use the builder methods in `Styled` and
/// `StyledExt`.
///
/// The generated module is named `<snake_case_trait_name>_reflection`. It has two
/// generic functions, `methods::<T>()`, which returns every reflected method
/// as a `Vec<gpui::inspector_reflection::FunctionReflection<T>>`, and
/// `find_method::<T>(name)`, which looks one up by name and returns an
/// `Option` of the same type. `T` must implement the trait and be `'static`.
///
/// The `invoke` method on `FunctionReflection` runs the method. `FunctionReflection`
/// also provides the method's documentation.
///
/// This attribute is only compiled with the `inspector` feature or in debug builds.
pub