MCPcopy Create free account
hub / github.com/codecombat/codecombat / ConvertForOfStatement

Method ConvertForOfStatement

app/lib/code-to-blocks.js:217–270  ·  view source on GitHub ↗
(n, ctx)

Source from the content-addressed store, hash-verified

215 }
216
217 static ConvertForOfStatement (n, ctx) {
218 ctx.scope[n.left.name] = { type: 'var' }
219 const body = convert(n.body, { ...ctx, nospace: true, context: 'statement' })
220 let o
221 if (n.right?.type === 'CallExpression' && n.right.callee?.name === 'range' && n.right.arguments?.length && (!n.right.arguments[2] || n.right.arguments[2].value === 1)) {
222 try {
223 // Use controls_repeat_ext block instead of a controls_forEach block for Python ranges that are just repeating N times
224 let start, end, endNode
225 if (n.right.arguments.length > 1) {
226 start = n.right.arguments[0].value
227 end = n.right.arguments[1].value
228 endNode = n.right.arguments[1]
229 } else {
230 start = 0
231 end = n.right.arguments[0].value
232 endNode = n.right.arguments[0]
233 }
234 const times = end - start
235 // For Junior, we have simplified dropdown block if the range is in 1-7
236 const type = times >= 1 && times <= 7 && _.find(ctx.plan, p => p[0].type === 'controls_repeat_dropdown') ? 'controls_repeat_dropdown' : 'controls_repeat_ext'
237 if (type === 'controls_repeat_ext' && !_.find(ctx.plan, p => p[0].type === 'controls_repeat_ext')) {
238 // TODO: figure out how to include both block definitions without breaking code-to-blocks finding right one in its planning
239 throw new Error('controls_repeat_ext block not available for loop with range', start, 'to', end)
240 }
241 if (type === 'controls_repeat_dropdown') {
242 // Change input to field
243 o = { type, inputs: {}, fields: { TIMES: '' + times } }
244 } else {
245 const fakeTimesNode = _.cloneDeep(endNode)
246 fakeTimesNode.raw = '' + times
247 fakeTimesNode.value = times
248 const fakeBlock = convert(fakeTimesNode, ctx)
249 o = { type, inputs: { TIMES: { block: fakeBlock } } }
250 }
251 } catch (err) {
252 console.error("Couldn't convert for-in range to simple repeat block:", n, err)
253 }
254 }
255 if (!o) {
256 o = {
257 // type: 'controls_untyped_for_each',
258 type: 'controls_forEach',
259 fields: {
260 VAR: { id: n.left.name },
261 },
262 inputs: {
263 LIST: { block: convert(n.right, { ...ctx, context: 'value' }) },
264 },
265 }
266 }
267
268 if (body) o.inputs.DO = { block: body[0] }
269 return o
270 }
271
272 static ConvertIfStatement (n, ctx) {
273 // TODO: ELSE, ELSEIF

Callers

nothing calls this directly

Calls 2

convertFunction · 0.85
errorMethod · 0.45

Tested by

no test coverage detected