parseDoctype method Null safety

Doctype? parseDoctype()

Implementation

Doctype? parseDoctype() {
  if (!next(TokenType.lt)) return null;
  var lt = _current;

  if (!next(TokenType.doctype)) {
    _index--;
    return null;
  }
  var doctype = _current;
  var html = parseIdentifier();
  if (html == null || html.span.text.toLowerCase() != 'html') {
    errors.add(JaelError(
        JaelErrorSeverity.error,
        'Expected "html" in doctype declaration.',
        html?.span ?? doctype.span));

    return null;
  }

  var public = parseIdentifier();
  if (public == null) {
    if (!next(TokenType.gt)) {
      errors.add(JaelError(JaelErrorSeverity.error,
          'Expected ">" in doctype declaration.', html.span));
      // ?? doctype.span));
      return null;
    }

    return Doctype(lt, doctype, html, null, null, null, _current);
  }

  if (public.span.text.toLowerCase() != 'public') {
    //errors.add(JaelError(
    //    JaelErrorSeverity.error,
    //    'Expected "public" in doctype declaration.',
    //    public!.span ?? html?.span));

    errors.add(JaelError(JaelErrorSeverity.error,
        'Expected "public" in doctype declaration.', public.span));

    return null;
  }

  var stringParser = prefixParselets[TokenType.string];

  if (!next(TokenType.string)) {
    errors.add(JaelError(JaelErrorSeverity.error,
        'Expected string in doctype declaration.', public.span));
    return null;
  }

  var name = stringParser?.parse(this, _current) as StringLiteral;

  if (!next(TokenType.string)) {
    errors.add(JaelError(JaelErrorSeverity.error,
        'Expected string in doctype declaration.', name.span));
    return null;
  }

  var url = stringParser?.parse(this, _current) as StringLiteral;

  if (!next(TokenType.gt)) {
    errors.add(JaelError(JaelErrorSeverity.error,
        'Expected ">" in doctype declaration.', url.span));
    return null;
  }

  return Doctype(lt, doctype, html, public, name, url, _current);
}