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
//! The `vue.*` dialect family: genuinely Vue-specific ops that ride along
//! the neutral core instead of shaping it.
//!
//! A dialect op lands with the transform that needs it, never
//! speculatively. The fairness litmus test (P2-16) is what keeps this
//! family honest - a lint rule written against `ui.*` must run unchanged
//! on SFC and JSX, so anything only Vue understands belongs here. Style
//! `v-bind()` (P2-10) has no JSX twin: CSS `v-bind(color)` is SFC-only.
//! The Vue 2 template-sugar surfaces (P2-9 installment 7) are the same
//! kind of exception: `.sync`, `slot-scope`/`scope`, and pipe filters
//! have no JSX twin. `v-once` / `v-memo` / `v-show` / `v-html` / `v-text`
//! / `v-cloak` (P2-11) are the same kind: one-shot / dependency-memoized /
//! display-toggle / content-prop rendering / DOM cloak removal is Vue's,
//! not a fair `ui.*` core op.
use ;
use DynamicName;
use crateExprRef;
/// `vue.directive` - a Vue directive carried through L2 for a consumer
/// that understands it (`v-pin:top.lazy="value"`).
///
/// Most built-ins normalize into `ui.*` ops at lowering (`v-if` into
/// [`super::IfOp`], `v-model` into [`super::ModelOp`], ...). The exception is
/// JSX `v-slots={slots}` forwarding: the value is an opaque slots object, so it
/// rides here as `name == "slots"` until component DOM emission spreads it into
/// the children argument. Other entries are user-defined directives, exactly as
/// the shipped pipeline emits runtime directive references for them today.
/// `vue.css-bind` - one CSS `v-bind()` in an SFC style block (P2-10).
///
/// Not `ui.bind`: that is the template one-way binding. The CSS form
/// points into a style block, and its spans are still the L0
/// file-absolute authored offsets of the complete SFC. The bound text
/// rides as [`ExprRef`] under P2-5b's contract — CSS `v-bind()` contents
/// are exactly the kind of text that may have no retained AST.
/// `vue.sync` - Vue 2's `:foo.sync="bar"` two-way bind sugar.
///
/// The bounded subset the shipped pre-transform expands: a static
/// argument, a value expression, and the `sync` modifier. Remaining
/// modifiers (`camel`, …) ride here so the desugar pass can put them
/// on the resulting `ui.bind`. Dynamic-argument `:\[foo].sync` stays
/// `ui.bind` — the shipped lane skips it the same way. The name is a
/// static identifier because desugar emits `update:<name>` and cannot
/// spell that from a computed argument.
/// `vue.slot-scope` - Vue 2's `slot-scope` / `scope` scoped-slot sugar.
///
/// The companion static `slot="name"` attribute is consumed at lowering
/// into [`VueSlotScopeOp::name`]; its absence is the default slot. A
/// carrier that already authors `v-slot` keeps the attributes as
/// attributes — the shipped lane will not emit a conflicting directive.
/// `vue.once` - Vue's `v-once` one-shot render flag.
///
/// A presence op: the well-formed spelling is the bare directive
/// (no argument, no modifier, no value). Realization (`has_v_once` in
/// the shipped codegen) reads the flag; this increment only names it.
/// `vue.memo` - Vue's `v-memo` dependency-memoized render.
///
/// The well-formed spelling carries a value expression and no
/// argument or modifier. The expression rides as [`ExprRef`] under
/// P2-5b — opaque is allowed (the shipped extractor's comment-bearing
/// contents have no retained AST). Realization (`get_memo_exp`) is
/// later; this increment only names the op.
/// `vue.show` - Vue's `v-show` runtime display toggle.
///
/// It stays a Vue dialect binding rather than a custom `vue.directive`:
/// the runtime helper is `vShow`, not a resolved user directive, and the
/// builtin remains visible to consumers that want to reason about
/// display toggles before DOM realization.
/// `vue.html` - Vue's `v-html` raw-HTML property realization.
///
/// It stays a Vue dialect binding instead of a plain `ui.bind` because
/// authored `v-html` is not equivalent to a user prop: it writes the
/// special `innerHTML` DOM prop and consumers may want to flag or
/// isolate that raw-HTML surface before DOM realization.
/// `vue.text` - Vue's `v-text` text-content property realization.
///
/// It stays a Vue dialect binding instead of a plain `ui.bind`: authored
/// `v-text` is not a user prop, it forces the DOM `textContent` prop through
/// Vue's display-string coercion.
/// `vue.cloak` - Vue's `v-cloak` DOM cloak marker.
///
/// This is a presence op. The shipped DOM compiler removes the marker from
/// generated props rather than resolving a runtime directive, so L2 must keep
/// the authored span for consumers without letting it affect prop emission.
/// See [`crate::op`] for the guard rationale.
const _: = ;