docs: private AstNode arrayLiteral()
          throws IOException
      {
          if (currentToken != Token.LB) codeBug();
          int pos = ts.tokenBeg, end = ts.tokenEnd;
          List<AstNode> elements = new ArrayList<AstNode>();
          ArrayLiteral pn = new ArrayLiteral(pos);
          boolean after_lb_or_comma = true;
          int afterComma = -1;
          int skipCount = 0;
          for (;;) {
              int tt = peekToken();
              if (tt == Token.COMMA) {
                  consumeToken();
                  afterComma = ts.tokenEnd;
                  if (!after_lb_or_comma) {
                      after_lb_or_comma = true;
                  } else {
                      elements.add(new EmptyExpression(ts.tokenBeg, 1));
                      skipCount++;
                  }
              } else if (tt == Token.RB) {
                  consumeToken();
                  // for ([a,] in obj) is legal, but for ([a] in obj) is
                  // not since we have both key and value supplied. The
                  // trick is that [a,] and [a] are equivalent in other
                  // array literal contexts. So we calculate a special
                  // length value just for destructuring assignment.
                  end = ts.tokenEnd;
                  pn.setDestructuringLength(elements.size() +
                                            (after_lb_or_comma ? 1 : 0));
                  pn.setSkipCount(skipCount);
                  if (afterComma != -1)
                      warnTrailingComma(pos, elements, afterComma);
                  break;
              } else if (tt == Token.FOR && !after_lb_or_comma
                         && elements.size() == 1) {
                  return arrayComprehension(elements.get(0), pos);
              } else if (tt == Token.EOF) {
                  reportError("msg.no.bracket.arg");
                  break;
              } else {
                  if (!after_lb_or_comma) {
                      reportError("msg.no.bracket.arg");
                  }
                  elements.add(assignExpr());
                  after_lb_or_comma = false;
                  afterComma = -1;
              }
          }
          for (AstNode e : elements) {
              pn.addElement(e);
          }
          pn.setLength(end - pos);
          return pn;
      }