| 1232 | }, |
| 1233 | |
| 1234 | EachBlock(node, { state, visit }) { |
| 1235 | visit(node.expression); |
| 1236 | |
| 1237 | // context and children are a new scope |
| 1238 | const scope = state.scope.child(); |
| 1239 | scopes.set(node, scope); |
| 1240 | |
| 1241 | if (node.context) { |
| 1242 | // declarations |
| 1243 | for (const id of extract_identifiers(node.context)) { |
| 1244 | const binding = scope.declare(id, 'each', 'const'); |
| 1245 | |
| 1246 | let inside_rest = false; |
| 1247 | let is_rest_id = false; |
| 1248 | walk(node.context, null, { |
| 1249 | Identifier(node) { |
| 1250 | if (inside_rest && node === id) { |
| 1251 | is_rest_id = true; |
| 1252 | } |
| 1253 | }, |
| 1254 | RestElement(_, { next }) { |
| 1255 | const prev = inside_rest; |
| 1256 | inside_rest = true; |
| 1257 | next(); |
| 1258 | inside_rest = prev; |
| 1259 | } |
| 1260 | }); |
| 1261 | |
| 1262 | binding.metadata = { inside_rest: is_rest_id }; |
| 1263 | } |
| 1264 | |
| 1265 | // Visit to pick up references from default initializers |
| 1266 | visit(node.context, { scope }); |
| 1267 | } |
| 1268 | |
| 1269 | if (node.index) { |
| 1270 | const is_keyed = |
| 1271 | node.key && |
| 1272 | (node.key.type !== 'Identifier' || !node.index || node.key.name !== node.index); |
| 1273 | scope.declare(b.id(node.index), is_keyed ? 'template' : 'static', 'const', node); |
| 1274 | } |
| 1275 | if (node.key) visit(node.key, { scope }); |
| 1276 | |
| 1277 | // children |
| 1278 | for (const child of node.body.nodes) { |
| 1279 | visit(child, { scope }); |
| 1280 | } |
| 1281 | if (node.fallback) visit(node.fallback, { scope }); |
| 1282 | |
| 1283 | node.metadata = { |
| 1284 | expression: new ExpressionMetadata(), |
| 1285 | keyed: false, |
| 1286 | contains_group_binding: false, |
| 1287 | index: scope.root.unique('$$index'), |
| 1288 | declarations: scope.declarations, |
| 1289 | is_controlled: false, |
| 1290 | // filled in during analysis |
| 1291 | transitive_deps: new Set() |