code: function parseDelimitedList(kind, parseElement, considerSemicolonAsDelimiter) {
              var saveParsingContext = parsingContext;
              parsingContext |= 1 << kind;
              var result = [];
              result.pos = getNodePos();
              var commaStart = -1; // Meaning the previous token was not a comma
              while (true) {
                  if (isListElement(kind, /*inErrorRecovery*/ false)) {
                      result.push(parseListElement(kind, parseElement));
                      commaStart = scanner.getTokenPos();
                      if (parseOptional(24 /* CommaToken */)) {
                          continue;
                      }
                      commaStart = -1; // Back to the state where the last token was not a comma
                      if (isListTerminator(kind)) {
                          break;
                      }
                      // We didn't get a comma, and the list wasn't terminated, explicitly parse
                      // out a comma so we give a good error message.
                      parseExpected(24 /* CommaToken */);
                      // If the token was a semicolon, and the caller allows that, then skip it and
                      // continue.  This ensures we get back on track and don't result in tons of
                      // parse errors.  For example, this can happen when people do things like use
                      // a semicolon to delimit object literal members.   Note: we'll have already
                      // reported an error when we called parseExpected above.
                      if (considerSemicolonAsDelimiter && token() === 23 /* SemicolonToken */ && !scanner.hasPrecedingLineBreak()) {
                          nextToken();
                      }
                      continue;
                  }
                  if (isListTerminator(kind)) {
                      break;
                  }
                  if (abortParsingListOrMoveToNextToken(kind)) {
                      break;
                  }
              }
              // Recording the trailing comma is deliberately done after the previous
              // loop, and not just if we see a list terminator. This is because the list
              // may have ended incorrectly, but it is still important to know if there
              // was a trailing comma.
              // Check if the last token was a comma.
              if (commaStart >= 0) {
                  // Always preserve a trailing comma by marking it on the NodeArray
                  result.hasTrailingComma = true;
              }
              result.end = getNodeEnd();
              parsingContext = saveParsingContext;
              return result;
          }
docs: Parses a comma-delimited list of elements