max / quasi
| 1 | //! The declared form's syntax tree. |
| 2 | //! |
| 3 | //! This is the grammar of wiki `quasi-declare-form` section 4, narrowed to what |
| 4 | //! a real screen has actually demanded. It grows one production at a time, and |
| 5 | //! every production here exists because a conversion needed it: nothing is |
| 6 | //! specified ahead of a screen that wants it. |
| 7 | //! |
| 8 | //! What the form refuses is as load-bearing as what it admits. There is no |
| 9 | //! expression node, no block in argument position, no closure and no struct |
| 10 | //! literal, because those four are what keep `Node: Eq` intact and keep an |
| 11 | //! argument from reopening into a sub-grammar. A shape that needs one of them |
| 12 | //! calls a supplier function beside the declaration instead. |
| 13 | |
| 14 | use Span; |
| 15 | use ; |
| 16 | |
| 17 | /// One declared shape: a header and the items its body emits. |
| 18 | |
| 19 | pub docs: , |
| 20 | /// The bare attributes the generated function carries, `must_use` and |
| 21 | /// `inline`. Nothing that takes an argument: an attribute with a body is a |
| 22 | /// second grammar, and none of the converted screens has wanted one. |
| 23 | pub flags: , |
| 24 | pub vis: , |
| 25 | pub name: Ident, |
| 26 | pub params: , |
| 27 | pub returns: Type, |
| 28 | pub items: , |
| 29 | |
| 30 | |
| 31 | |
| 32 | |
| 33 | pub name: Ident, |
| 34 | pub ty: Type, |
| 35 | |
| 36 | |
| 37 | |
| 38 | |
| 39 | /// `let name = <source>;` |
| 40 | Bind , |
| 41 | /// `<builder> <arg>* <guard>?;` -- one setting on the enclosing container. |
| 42 | /// |
| 43 | /// The ident is the **builder method's** name and not the struct field's, |
| 44 | /// which is what ATTRIBUTE NAMING settles: `Slot::named` writes `name`, and |
| 45 | /// a form that spelled the field would be naming something no caller can |
| 46 | /// reach. |
| 47 | /// |
| 48 | /// A setting takes a guard for the same reason a member does: the rule is |
| 49 | /// that a guard is allowed where something may be absent, and a setting |
| 50 | /// that is sometimes not made is exactly that. `git_explore`'s `more` is |
| 51 | /// the live instance -- a table says what it has not shown only when there |
| 52 | /// is another page. |
| 53 | Attribute |
| 54 | name: Ident, |
| 55 | args: , |
| 56 | guard: , |
| 57 | , |
| 58 | /// `for <binder> in <hole> { .. }` -- the same body once per element. |
| 59 | /// |
| 60 | /// A loop is the one item that cannot be hoisted above its container: its |
| 61 | /// members name the binder, which does not exist until the loop does. |
| 62 | For |
| 63 | /// `&name` where the elements are references to values the members |
| 64 | /// take by value. Written where the code writes it, as R8 requires, |
| 65 | /// and a pattern rather than an expression. |
| 66 | dereferenced: bool, |
| 67 | binder: Ident, |
| 68 | iterable: Hole, |
| 69 | body: , |
| 70 | , |
| 71 | /// Anything that puts something into the enclosing container. |
| 72 | Emit, |
| 73 | |
| 74 | |
| 75 | |
| 76 | |
| 77 | /// A string literal, which may carry `{hole}` interpolations. |
| 78 | Str, |
| 79 | /// A hole: one eager evaluation whose owned result lands in a field. |
| 80 | Hole, |
| 81 | /// `given <hole> { <literal> -> <source>, .. }` in value position. |
| 82 | /// |
| 83 | /// This is the production the record's amendment 9 was reaching for and |
| 84 | /// missed: it put `dispatch` on the statement side, where an arm is an |
| 85 | /// emission and no emission is a value. Here a value dispatch is its own |
| 86 | /// node whose arms are sources, so it produces a value by construction and |
| 87 | /// cannot admit a block. |
| 88 | Choose |
| 89 | scrutinee: Hole, |
| 90 | arms: , |
| 91 | otherwise: , |
| 92 | , |
| 93 | |
| 94 | |
| 95 | /// A pattern in value-dispatch position. Literals only: a binding pattern would |
| 96 | /// need a scope, and a scope is how an arm becomes a block. |
| 97 | |
| 98 | |
| 99 | Int, |
| 100 | Str, |
| 101 | Bool, |
| 102 | /// `Enum::Variant`, emitted verbatim so rustc judges exhaustiveness. |
| 103 | Path, |
| 104 | |
| 105 | |
| 106 | /// A string with `{hole}` interpolations, compiled to a literal push or a |
| 107 | /// `format!` depending on whether it has any. |
| 108 | |
| 109 | |
| 110 | pub parts: , |
| 111 | pub span: Span, |
| 112 | |
| 113 | |
| 114 | |
| 115 | |
| 116 | Lit, |
| 117 | Hole, |
| 118 | |
| 119 | |
| 120 | /// One evaluation: a path, optionally called, then field and method steps. |
| 121 | /// |
| 122 | /// A hole is deliberately not an expression. It cannot contain an operator, a |
| 123 | /// closure, a turbofish, an index or a block, so the macro can place its result |
| 124 | /// in a field without reasoning about evaluation order. |
| 125 | |
| 126 | |
| 127 | pub root: HoleRoot, |
| 128 | pub steps: , |
| 129 | |
| 130 | |
| 131 | |
| 132 | |
| 133 | /// A bare lowercase ident: a binding, innermost first. |
| 134 | Binding, |
| 135 | /// A `::`-qualified or uppercase-initial path: a Rust path, binding nothing. |
| 136 | Path, |
| 137 | /// A module function called at the root of a hole. |
| 138 | Call , |
| 139 | |
| 140 | |
| 141 | |
| 142 | |
| 143 | Field, |
| 144 | Method , |
| 145 | |
| 146 | |
| 147 | |
| 148 | |
| 149 | Str, |
| 150 | /// `[ <arg>, .. ]`, which is an array literal and never a collection: what |
| 151 | /// it can hold is an arg, so it cannot reopen into a sub-grammar. |
| 152 | List, |
| 153 | Hole, |
| 154 | Int, |
| 155 | Bool, |
| 156 | /// `&<hole>`. Nothing borrows implicitly, so the ampersand is written where |
| 157 | /// the code writes it. |
| 158 | Borrow, |
| 159 | |
| 160 | |
| 161 | /// Everything that emits into the enclosing container. |
| 162 | |
| 163 | |
| 164 | /// `<member> <arg>* ( "{" { item } "}" | ";" )` -- one of `Node`'s own |
| 165 | /// constructors, by its own name, and whatever it is told afterwards. |
| 166 | /// |
| 167 | /// The body is what `forum_memberships` demanded: `Node::empty` carries a |
| 168 | /// way out (`offering`) on the library's pane and not on the settings pane, |
| 169 | /// so an empty state is a member with a setting rather than a bare one. |
| 170 | Simple |
| 171 | member: Ident, |
| 172 | args: , |
| 173 | body: , |
| 174 | , |
| 175 | /// `chip <value> to <action> { .. }`, and `removable <value> to <action>`. |
| 176 | /// |
| 177 | /// Its own emission rather than a `Simple` member because `Tag::chip` takes |
| 178 | /// an `Action`, and an action is spelled `to <verb>` rather than as an arg. |
| 179 | /// |
| 180 | /// One emission for both because they differ by one constructor and nothing |
| 181 | /// else. `Tag` has three constructors and the form now says all three: |
| 182 | /// `badge` is the inert one, `chip` goes somewhere, and `removable` goes |
| 183 | /// somewhere and says the going takes it off. |
| 184 | Chip |
| 185 | value: Arg, |
| 186 | action: Action, |
| 187 | /// Whether the tag says it can be taken off, which is `Tag::removable`. |
| 188 | removable: bool, |
| 189 | body: , |
| 190 | , |
| 191 | /// `screen <arrangement> <arg> { .. }` |
| 192 | Screen |
| 193 | arrangement: Ident, |
| 194 | /// What the arrangement is told. Every one takes a title; `list_detail` |
| 195 | /// takes whether it is tabbed as well, which is why this is a list |
| 196 | /// rather than the one title it was until wave 9. |
| 197 | args: , |
| 198 | body: , |
| 199 | , |
| 200 | /// `row <arg> { .. }` |
| 201 | Row , |
| 202 | /// `form <action> { submit <arg>; field .. }` |
| 203 | Form , |
| 204 | /// `field <kind> <name> <label> ( { .. } | ; )` |
| 205 | Field |
| 206 | kind: Ident, |
| 207 | name: Arg, |
| 208 | label: Arg, |
| 209 | body: , |
| 210 | , |
| 211 | /// `list { .. }` -- the rows built in place rather than supplied. |
| 212 | /// |
| 213 | /// Its own member rather than a container in the general sense: a `Vec` |
| 214 | /// does not chain, so the one thing that accretes by pushing is kept where |
| 215 | /// it can be read instead of bending every other container's shape. |
| 216 | List, |
| 217 | /// `act <arg> to <action> ( { .. } | ; )` |
| 218 | Act |
| 219 | label: Arg, |
| 220 | action: Action, |
| 221 | body: , |
| 222 | , |
| 223 | /// `offers <arg> to <action> ( { .. } | ; )` -- `act`'s held-back twin. |
| 224 | /// |
| 225 | /// A control a row carries but does not show: `Row::offers` pushes onto the |
| 226 | /// menu a host reveals when it is asked, where `Row::act` puts the control |
| 227 | /// in the row. One word apart because that is the whole of the difference, |
| 228 | /// and a member rather than a setting because a menu control is told the |
| 229 | /// same things an inline one is -- audiofiles' sidebar greys a vault's |
| 230 | /// Delete when it is the last vault, which a control written as an |
| 231 | /// expression cannot say. |
| 232 | Offers |
| 233 | label: Arg, |
| 234 | action: Action, |
| 235 | body: , |
| 236 | , |
| 237 | /// `table { column ..; cells { .. } }` |
| 238 | /// |
| 239 | /// Columns and rows accrete rather than arriving as two lists, which is |
| 240 | /// what `Table::column` and `Row::cell` were added to `quasi-router` for. |
| 241 | /// The form has no expression to hold a list in, and a production that |
| 242 | /// admitted one would be the door this grammar exists to keep shut. |
| 243 | Table, |
| 244 | /// `column <name> ( "{" .. "}" | ";" )` -- one column and how it narrows. |
| 245 | Column , |
| 246 | /// `cells { cell ..; }` -- one row of a table. |
| 247 | /// |
| 248 | /// A row's cells are all positional or all named; mixing the two is what |
| 249 | /// `Row::at`'s own docs warn against. |
| 250 | Cells, |
| 251 | /// `cell [ "at" <column> ] <value> ( "{" .. "}" | ";" )` |
| 252 | /// |
| 253 | /// Positional without the column, named with it. `item_sales` demanded the |
| 254 | /// named form: its columns are module consts and its cells are a function |
| 255 | /// away, so a row written by position would be lined up against headings |
| 256 | /// nobody reading the row can see. Naming is `Row::at`, and the two are |
| 257 | /// not mixed in one row -- that warning is `at`'s own. |
| 258 | Cell |
| 259 | column: , |
| 260 | value: Arg, |
| 261 | body: , |
| 262 | , |
| 263 | /// `offering <arg> to <action> ( "{" { item } "}" | ";" )` -- the way out an |
| 264 | /// empty or failed state offers. |
| 265 | /// |
| 266 | /// Spelled like `act` and placed like a setting, because `Node::offering` |
| 267 | /// takes an `Act` and a setting's arguments are args. Its own member rather |
| 268 | /// than an `act` the container reinterprets: a body holding a control and a |
| 269 | /// body holding a way out would otherwise read the same and mean different |
| 270 | /// things. |
| 271 | Offering |
| 272 | label: Arg, |
| 273 | action: Action, |
| 274 | body: , |
| 275 | , |
| 276 | /// `removes <arg> to <action> ( "{" { item } "}" | ";" )` -- the control one |
| 277 | /// slot of a repeating question carries to take itself away. |
| 278 | /// |
| 279 | /// `act`'s shape and `Slot::removes`'s meaning, which is one word apart for |
| 280 | /// the reason `offers` was: a control that takes its own region away is told |
| 281 | /// the same things every other control is, and written as an expression in |
| 282 | /// argument position it can be told none of them. audiofiles' rule editor is |
| 283 | /// the site, twice. |
| 284 | Removes |
| 285 | label: Arg, |
| 286 | action: Action, |
| 287 | body: , |
| 288 | , |
| 289 | /// `repeats <arg> adds <arg> to <action> ( "{" { item } "}" | ";" )` |
| 290 | /// |
| 291 | /// A region that is a repeating question: what one of them is called, the |
| 292 | /// control that adds another, and how few may be left standing. The add |
| 293 | /// control is in the header rather than the body because `Repeating::new` |
| 294 | /// takes it, and the body is that type's own settings. |
| 295 | /// |
| 296 | /// Spelled `repeats` and not `repeating`, which is the setting it calls, |
| 297 | /// because `Field::repeating` takes a different type and one name cannot |
| 298 | /// mean both. Same rule and same remedy as `underway` and `proportion`. |
| 299 | Repeats |
| 300 | one: Arg, |
| 301 | label: Arg, |
| 302 | action: Action, |
| 303 | body: , |
| 304 | , |
| 305 | /// `activate to <action>;` -- what opening this row or cell does. |
| 306 | /// |
| 307 | /// A setting in shape, and a member in the tree, because the thing it sets |
| 308 | /// is an action and a setting's arguments are args. Rows, rows of cells and |
| 309 | /// single cells all carry one. |
| 310 | Activate, |
| 311 | /// `include <hole>;` -- whatever another shape built. |
| 312 | Include, |
| 313 | /// `include each <shape>`: a shape answering many members, spliced whole. |
| 314 | /// |
| 315 | /// The plural of [`Include`](Self::Include), and a separate emission rather |
| 316 | /// than a flag on it because what it places is a run and not a node: only |
| 317 | /// a container that holds many members can take one. |
| 318 | IncludeEach, |
| 319 | /// `link <arg> to <action>;` |
| 320 | Link , |
| 321 | /// `region <arg> as <kind> { .. }` |
| 322 | Region |
| 323 | name: Arg, |
| 324 | kind: RegionKind, |
| 325 | body: , |
| 326 | , |
| 327 | /// `across <fallback> { .. }` |
| 328 | Across , |
| 329 | /// `beside <priority> <emission>` |
| 330 | /// |
| 331 | /// An `Arg` rather than an `Ident`, which is rule R1(4) reaching the last |
| 332 | /// vocabulary slot that did not have it: `tone`, `width`, `priority` and |
| 333 | /// `fit` have all taken a hole since wave 2, and a bare uppercase ident |
| 334 | /// still reads as the variant, so every existing site is unchanged. |
| 335 | /// audiofiles' toolbar is what asked -- its six panel toggles each carry |
| 336 | /// what they are worth, and a rank that has to be a literal cannot say it. |
| 337 | /// `framed <label> <emission>` -- a member placed as a named frame. |
| 338 | /// |
| 339 | /// The placement modifier for a region that shows one member at a time. The |
| 340 | /// name belongs to the placement rather than to the member, because it names |
| 341 | /// the control that reveals it (quasicoherent `2cdc6761`), and a member |
| 342 | /// written in another `declare!` cannot carry one at all: a shape answers a |
| 343 | /// `Slot`, and since that ruling a `Slot` has no label. |
| 344 | /// |
| 345 | /// Inside one invocation the macro hoists a child region's own `label` |
| 346 | /// instead, so the common spelling is unchanged. This is for the case a |
| 347 | /// hoist cannot reach, which is exactly the case that went wrong: goingson's |
| 348 | /// `summary_body` is its own shape and its parent includes it. |
| 349 | Framed , |
| 350 | Beside |
| 351 | priority: Arg, |
| 352 | /// How much of the row it asks for, where it said. |
| 353 | /// |
| 354 | /// Optional because most members have no opinion: a strip's members and |
| 355 | /// a band's take what they need, which is what a run already drew. |
| 356 | /// Written between the rank and the member (`beside Essential Fill |
| 357 | /// include pane(x)`) and told from the member by R1's rule -- a member |
| 358 | /// is one of the known lowercase words, so anything else in that |
| 359 | /// position is the width. |
| 360 | /// |
| 361 | /// A row only. The body of a region is a stack and its members each get |
| 362 | /// the whole width, so a width there is refused rather than ignored. |
| 363 | width: , |
| 364 | inner: , |
| 365 | , |
| 366 | /// `at <arg> <emission>` -- one thing on an axis, and where it sits. |
| 367 | /// |
| 368 | /// Only inside a `timeline`, where the argument is a `Placement` and the |
| 369 | /// emission is the row that sits at it. The keyword is `cell at <arg>`'s, |
| 370 | /// and the container is the whole of how the two are told apart, exactly as |
| 371 | /// it is for `beside` and for `include`. A timeline holds nothing but |
| 372 | /// entries and a row of cells holds nothing but cells, so no body can be |
| 373 | /// read both ways. |
| 374 | At , |
| 375 | /// `<emission> when <predicate>` / `unless <predicate>`. |
| 376 | /// |
| 377 | /// A guard suppresses the emission and nothing else. R9: the holes inside |
| 378 | /// it are still evaluated, because a hole is one eager evaluation and a |
| 379 | /// guard is not a scope. |
| 380 | Guarded , |
| 381 | /// `given <hole> { <pattern> -> <emission> .. }` in member position. |
| 382 | /// |
| 383 | /// Every arm emits exactly one member, which is what makes the dispatch a |
| 384 | /// member itself rather than a statement. R7: this is a real `match`, so |
| 385 | /// exhaustiveness and arm order are rustc's. |
| 386 | Given |
| 387 | scrutinee: Hole, |
| 388 | arms: , |
| 389 | otherwise: , |
| 390 | , |
| 391 | |
| 392 | |
| 393 | /// What kind of region this is: a variant, or a hole that answers with one. |
| 394 | /// |
| 395 | /// `RegionKind::Widget` carries a name, so it is the one kind a bare ident |
| 396 | /// cannot spell. `media_picker` has three widget regions and a `widget(name)` |
| 397 | /// helper beside them, which is the deferred table's own remedy for a value the |
| 398 | /// form cannot say; this lets the declaration call it. |
| 399 | /// |
| 400 | /// Told apart by R1's rule and not by a keyword: a bare uppercase ident is a |
| 401 | /// variant, and anything else is a hole. |
| 402 | |
| 403 | |
| 404 | Variant, |
| 405 | Supplied, |
| 406 | |
| 407 | |
| 408 | /// `when <predicate>`, or `unless <predicate>`, which is its negation. |
| 409 | |
| 410 | |
| 411 | pub negated: bool, |
| 412 | pub predicate: Predicate, |
| 413 | pub span: Span, |
| 414 | |
| 415 | |
| 416 | |
| 417 | |
| 418 | /// `<clause> and <clause>`, or `<clause> or <clause>`. One connective per |
| 419 | /// predicate: mixing them would need precedence, and precedence is how a |
| 420 | /// predicate becomes an expression. |
| 421 | Joined |
| 422 | connective: Ident, |
| 423 | clauses: , |
| 424 | , |
| 425 | /// `not <clause>`. |
| 426 | Not, |
| 427 | /// A hole that is already a `bool`. |
| 428 | Truth, |
| 429 | /// `<hole> <compare> <arg>`. The comparison is a word rather than an |
| 430 | /// operator, so nothing in the form is an expression. |
| 431 | Comparison |
| 432 | left: Hole, |
| 433 | compare: Ident, |
| 434 | right: Arg, |
| 435 | , |
| 436 | |
| 437 | |
| 438 | |
| 439 | |
| 440 | /// One of the verbs, or `doing`, which takes the whole action from a |
| 441 | /// supplier. Amendment 6: a screen whose action is decided by something |
| 442 | /// the form cannot say gets a function beside it rather than a production. |
| 443 | pub verb: Ident, |
| 444 | pub target: , |
| 445 | pub modifiers: , |
| 446 | |
| 447 | |
| 448 | /// One word after the verb, and whatever it needs to say it. |
| 449 | |
| 450 | |
| 451 | pub name: Ident, |
| 452 | pub args: , |
| 453 | |
| 454 |