commit 79d0f6184ef00ba6daa7bc6e30b046e36af4ae4c
parent 310ab1300e0548af73dcbe6012f5235443da44f4
Author: Sebastian <sebastian@sebsite.pw>
Date: Sat, 20 Apr 2024 22:16:16 -0400
haredoc: warn and continue on parsing error
This only applies to -Ftty; -Fhtml is unchanged.
Prior to this commit, haredoc would exit with a failure status if any
file failed to parse. Now, when a file fails to parse, haredoc will
display a warning showing all the parsing errors that occurred, but it
won't terminate; it will still show documentation from all files that
parsed successfully.
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
4 files changed, 66 insertions(+), 10 deletions(-)
diff --git a/cmd/haredoc/doc/resolve.ha b/cmd/haredoc/doc/resolve.ha
@@ -148,8 +148,9 @@ fn lookup_remote_enum(ctx: *context, what: ast::ident) (ast::ident | void | erro
free(decls);
};
for (let in .. srcs.ha) {
- let u = scan(in)?;
- append(decls, u.decls...);
+ let d = scan(in)?;
+ defer free(d);
+ append(decls, d...);
};
for (let decl .. decls) {
@@ -178,7 +179,7 @@ fn lookup_remote_enum(ctx: *context, what: ast::ident) (ast::ident | void | erro
};
};
-export fn scan(path: str) (ast::subunit | error) = {
+export fn scan(path: str) ([]ast::decl | parse::error) = {
const input = match (os::open(path)) {
case let f: io::file =>
yield f;
@@ -189,5 +190,7 @@ export fn scan(path: str) (ast::subunit | error) = {
let sc = bufio::newscanner(input, types::SIZE_MAX);
defer bufio::finish(&sc);
let lexer = lex::init(&sc, path, lex::flag::COMMENTS);
- return parse::subunit(&lexer)?;
+ let su = parse::subunit(&lexer)?;
+ ast::imports_finish(su.imports);
+ return su.decls;
};
diff --git a/cmd/haredoc/doc/tty.ha b/cmd/haredoc/doc/tty.ha
@@ -4,6 +4,7 @@
use bufio;
use fmt;
use hare::ast;
+use hare::lex;
use hare::unparse;
use io;
use memio;
@@ -38,6 +39,25 @@ export fn emit_tty(ctx: *context) (void | error) = {
fmt::fprintln(ctx.out, "\n")?;
};
+ if (len(ctx.parse_errs) > 0) {
+ if (!no_color) fmt::fprintf(ctx.out, "\x1b[{}m",
+ color(unparse::synkind::COMMENT))?;
+ fmt::fprint(ctx.out, "// ")?;
+ if (!no_color) fmt::fprint(ctx.out, "\x1b[93m")?;
+ fmt::fprint(ctx.out, "WARNING")?;
+ if (!no_color) fmt::fprintf(ctx.out, "\x1b[m" "\x1b[{}m",
+ color(unparse::synkind::COMMENT))?;
+ fmt::fprintln(ctx.out,
+ ": parsing errors occurred; documentation may be incomplete")?;
+ if (!no_color) fmt::fprint(ctx.out, "\x1b[m")?;
+ };
+ for (let i = 0z; i < len(ctx.parse_errs); i += 1) {
+ fmt::fprintln(ctx.out, "//", lex::strerror(ctx.parse_errs[i]))?;
+ };
+ if (len(ctx.parse_errs) > 0) {
+ fmt::fprintln(ctx.out)?;
+ };
+
match (ctx.readme) {
case let readme: io::file =>
let rbuf: [os::BUFSZ]u8 = [0...];
diff --git a/cmd/haredoc/doc/types.ha b/cmd/haredoc/doc/types.ha
@@ -51,6 +51,7 @@ export type context = struct {
ident: ast::ident,
tags: []str,
ambiguous: bool,
+ parse_errs: []lex::syntax,
srcs: module::srcset,
submods: []str,
summary: summary,
diff --git a/cmd/haredoc/main.ha b/cmd/haredoc/main.ha
@@ -152,11 +152,28 @@ fn doc(name: str, cmd: *getopt::command) (void | error) = {
free(decls);
};
+ let parse_errs: []lex::syntax = [];
+ defer free(parse_errs);
+
if (declpath != "") {
for (let ha .. declsrcs.ha) {
- let u = doc::scan(ha)?;
- ast::imports_finish(u.imports);
- append(decls, u.decls...);
+ let d = match (doc::scan(ha)) {
+ case let d: []ast::decl =>
+ yield d;
+ case let err: parse::error =>
+ if (html) {
+ return err;
+ };
+ match (err) {
+ case let err: lex::syntax =>
+ append(parse_errs, err);
+ continue;
+ case =>
+ return err;
+ };
+ };
+ defer free(d);
+ append(decls, d...);
};
let matching: []ast::decl = [];
@@ -199,9 +216,23 @@ fn doc(name: str, cmd: *getopt::command) (void | error) = {
if (len(decls) == 0) {
for (let ha .. modsrcs.ha) {
- let u = doc::scan(ha)?;
- ast::imports_finish(u.imports);
- append(decls, u.decls...);
+ let d = match (doc::scan(ha)) {
+ case let d: []ast::decl =>
+ yield d;
+ case let err: parse::error =>
+ if (html) {
+ return err;
+ };
+ match (err) {
+ case let err: lex::syntax =>
+ append(parse_errs, err);
+ continue;
+ case =>
+ return err;
+ };
+ };
+ defer free(d);
+ append(decls, d...);
};
const rpath = path::init(modpath, "README")!;
@@ -228,6 +259,7 @@ fn doc(name: str, cmd: *getopt::command) (void | error) = {
ident = id,
tags = tags,
ambiguous = ambiguous,
+ parse_errs = parse_errs,
srcs = srcs,
submods = submods,
summary = summary,