(node)
| 2405 | } |
| 2406 | |
| 2407 | function parseFunction(node) { |
| 2408 | // TODO: The node creation utilities used here are tightly coupled (e.g. variable names) |
| 2409 | |
| 2410 | var suffix = newAstIdCount++; |
| 2411 | node.id = parseIdent(); |
| 2412 | node.params = []; |
| 2413 | |
| 2414 | // Parse parameters |
| 2415 | |
| 2416 | var formals = []; // In order, maybe with default value |
| 2417 | var argsId = null; // *args |
| 2418 | var kwargsId = null; // **kwargs |
| 2419 | var defaultsFound = false; |
| 2420 | var first = true; |
| 2421 | |
| 2422 | scope.startFn(node.id.name); |
| 2423 | |
| 2424 | expect(_parenL); |
| 2425 | while (!eat(_parenR)) { |
| 2426 | if (!first) expect(_comma); else first = false; |
| 2427 | if (tokVal === '*') { |
| 2428 | if (kwargsId) raise(tokPos, "invalid syntax"); |
| 2429 | next(); argsId = parseIdent(); |
| 2430 | } else if (tokVal === '**') { |
| 2431 | next(); kwargsId = parseIdent(); |
| 2432 | } else { |
| 2433 | if (kwargsId) raise(tokPos, "invalid syntax"); |
| 2434 | var paramId = parseIdent(); |
| 2435 | if (eat(_eq)) { |
| 2436 | formals.push({ id: paramId, expr: parseExprOps(false) }); |
| 2437 | defaultsFound = true; |
| 2438 | } else { |
| 2439 | if (defaultsFound) raise(tokPos, "non-default argument follows default argument"); |
| 2440 | if (argsId) raise(tokPos, "missing required keyword-only argument"); |
| 2441 | formals.push({ id: paramId, expr: null }); |
| 2442 | } |
| 2443 | scope.addVar(paramId.name); |
| 2444 | } |
| 2445 | } |
| 2446 | expect(_colon); |
| 2447 | |
| 2448 | // Start a new scope with regard to the `inFunction` |
| 2449 | // flag (restore them to their old value afterwards). |
| 2450 | // `inFunction` used to throw syntax error for stray `return` |
| 2451 | var oldInFunc = inFunction = true; |
| 2452 | |
| 2453 | // If class method, remove class instance var from params and save for 'this' replacement |
| 2454 | if (scope.isParentClass()) { |
| 2455 | var selfId = formals.shift(); |
| 2456 | scope.setThisReplace(selfId.id.name); |
| 2457 | } |
| 2458 | |
| 2459 | var body = parseSuite(); |
| 2460 | node.body = nc.createNodeSpan(body, body, "BlockStatement", { body: [] }); |
| 2461 | |
| 2462 | // Add runtime parameter processing |
| 2463 | // The caller may pass a complex parameter object as a single parameter like this: |
| 2464 | // {formals:[<expr>, <expr>, ...], keywords:{<id>:<expr>, <id>:<expr>, ...}} |
no test coverage detected