* parse accessors: * - function invocation in round brackets (...), for example sqrt(2) or sqrt?.(2) with optional chaining * - index enclosed in square brackets [...], for example A[2,3] or A?.[2,3] with optional chaining * - dot notation for properties, like foo.bar or foo?.bar with optio
(state, node, types)
| 1419 | * @private |
| 1420 | */ |
| 1421 | function parseAccessors (state, node, types) { |
| 1422 | let params |
| 1423 | |
| 1424 | // Iterate and handle chained accessors, including repeated optional chaining |
| 1425 | while (true) { // eslint-disable-line no-unmodified-loop-condition |
| 1426 | // Track whether an optional chaining operator precedes the next accessor |
| 1427 | let optional = false |
| 1428 | |
| 1429 | // Consume an optional chaining operator if present |
| 1430 | if (state.token === '?.') { |
| 1431 | optional = true |
| 1432 | // consume the '?.' token |
| 1433 | getToken(state) |
| 1434 | } |
| 1435 | |
| 1436 | const hasNextAccessor = |
| 1437 | (state.token === '(' || state.token === '[' || state.token === '.') && |
| 1438 | (!types || types.includes(state.token)) |
| 1439 | |
| 1440 | if (!(optional || hasNextAccessor)) { |
| 1441 | break |
| 1442 | } |
| 1443 | |
| 1444 | params = [] |
| 1445 | |
| 1446 | if (state.token === '(') { |
| 1447 | if (optional || isSymbolNode(node) || isAccessorNode(node)) { |
| 1448 | // function invocation: fn(2, 3) or obj.fn(2, 3) or (anything)?.(2, 3) |
| 1449 | openParams(state) |
| 1450 | getToken(state) |
| 1451 | |
| 1452 | if (state.token !== ')') { |
| 1453 | params.push(parseAssignment(state)) |
| 1454 | |
| 1455 | // parse a list with parameters |
| 1456 | while (state.token === ',') { // eslint-disable-line no-unmodified-loop-condition |
| 1457 | getToken(state) |
| 1458 | params.push(parseAssignment(state)) |
| 1459 | } |
| 1460 | } |
| 1461 | |
| 1462 | if (state.token !== ')') { |
| 1463 | throw createSyntaxError(state, 'Parenthesis ) expected') |
| 1464 | } |
| 1465 | closeParams(state) |
| 1466 | getToken(state) |
| 1467 | |
| 1468 | node = new FunctionNode(node, params, optional) |
| 1469 | } else { |
| 1470 | // implicit multiplication like (2+3)(4+5) or sqrt(2)(1+2) |
| 1471 | // don't parse it here but let it be handled by parseImplicitMultiplication |
| 1472 | // with correct precedence |
| 1473 | return node |
| 1474 | } |
| 1475 | } else if (state.token === '[') { |
| 1476 | // index notation like variable[2, 3] |
| 1477 | openParams(state) |
| 1478 | getToken(state) |
no test coverage detected
searching dependent graphs…