code: private ParseTree parseArrayLiteral() {
      // ArrayLiteral :
      //   [ Elisionopt ]
      //   [ ElementList ]
      //   [ ElementList , Elisionopt ]
      //
      // ElementList :
      //   Elisionopt AssignmentOrSpreadExpression
      //   ElementList , Elisionopt AssignmentOrSpreadExpression
      //
      // Elision :
      //   ,
      //   Elision ,
  
      SourcePosition start = getTreeStartLocation();
      ImmutableList.Builder<ParseTree> elements = ImmutableList.builder();
  
      eat(TokenType.OPEN_SQUARE);
      Token trailingCommaToken = null;
      while (peek(TokenType.COMMA) || peek(TokenType.SPREAD) || peekAssignmentExpression()) {
        trailingCommaToken = null;
        if (peek(TokenType.COMMA)) {
          elements.add(new NullTree(getTreeLocation(getTreeStartLocation())));
        } else {
          if (peek(TokenType.SPREAD)) {
            recordFeatureUsed(Feature.SPREAD_EXPRESSIONS);
            elements.add(parseSpreadExpression());
          } else {
            elements.add(parseAssignmentExpression());
          }
        }
        if (!peek(TokenType.CLOSE_SQUARE)) {
          trailingCommaToken = eat(TokenType.COMMA);
        }
      }
      eat(TokenType.CLOSE_SQUARE);
  
      maybeReportTrailingComma(trailingCommaToken);
  
      return new ArrayLiteralExpressionTree(
          getTreeLocation(start), elements.build());
    }
docs: 11.1.4 Array Literal Expression