feat(diag): add parser severity filtering and source map heuristic for bux build
This commit is contained in:
+17
-1
@@ -449,6 +449,11 @@ func String_FromChar(c: int) -> String {
|
|||||||
return buf as String;
|
return buf as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Count lines in a string (split by newline) */
|
||||||
|
func Cli_CountLines(content: String) -> uint {
|
||||||
|
return bux_str_split_count(content, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
// Collect stdlib module paths imported by user code.
|
// Collect stdlib module paths imported by user code.
|
||||||
// Returns number of unique stdlib files to merge (paths written into outPaths).
|
// Returns number of unique stdlib files to merge (paths written into outPaths).
|
||||||
func Cli_CollectStdlibImports(mod: *Module, outPaths: *String, maxCount: int, stdlibDir: String) -> int {
|
func Cli_CollectStdlibImports(mod: *Module, outPaths: *String, maxCount: int, stdlibDir: String) -> int {
|
||||||
@@ -1077,7 +1082,18 @@ func Cli_BuildProject(projectDir: String) -> int {
|
|||||||
column: sema.diags[i].column,
|
column: sema.diags[i].column,
|
||||||
severity: 0,
|
severity: 0,
|
||||||
};
|
};
|
||||||
Diagnostic_Print(&diag, "<merged>");
|
/* Try to guess which source file has this line */
|
||||||
|
let errLine: uint32 = sema.diags[i].line;
|
||||||
|
let mainSrc: String = bux_path_join(projectDir, "src/Main.bux");
|
||||||
|
let mainContent: String = bux_read_file(mainSrc);
|
||||||
|
var sourcePath: String = "<merged>";
|
||||||
|
if !String_Eq(mainContent, "") {
|
||||||
|
let mainLines: uint = Cli_CountLines(mainContent);
|
||||||
|
if errLine <= mainLines {
|
||||||
|
sourcePath = mainSrc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Diagnostic_Print(&diag, sourcePath);
|
||||||
i = i + 1;
|
i = i + 1;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
+33
-3
@@ -30,6 +30,7 @@ struct ParserDiag {
|
|||||||
line: uint32,
|
line: uint32,
|
||||||
column: uint32,
|
column: uint32,
|
||||||
message: String,
|
message: String,
|
||||||
|
severity: int, /* 0=error (fatal), 1=warning (recoverable) */
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -104,7 +105,7 @@ func parserExpect(p: *Parser, kind: int, msg: String) -> LexToken {
|
|||||||
let tok: LexToken = parserCurToken(p);
|
let tok: LexToken = parserCurToken(p);
|
||||||
if p.diagCount < 256 {
|
if p.diagCount < 256 {
|
||||||
p.diags[p.diagCount] = ParserDiag {
|
p.diags[p.diagCount] = ParserDiag {
|
||||||
line: tok.line, column: tok.column, message: msg
|
line: tok.line, column: tok.column, message: msg, severity: 1
|
||||||
};
|
};
|
||||||
p.diagCount = p.diagCount + 1;
|
p.diagCount = p.diagCount + 1;
|
||||||
}
|
}
|
||||||
@@ -114,7 +115,7 @@ func parserExpect(p: *Parser, kind: int, msg: String) -> LexToken {
|
|||||||
func parserEmitDiag(p: *Parser, line: uint32, col: uint32, msg: String) {
|
func parserEmitDiag(p: *Parser, line: uint32, col: uint32, msg: String) {
|
||||||
if p.diagCount < 256 {
|
if p.diagCount < 256 {
|
||||||
p.diags[p.diagCount] = ParserDiag {
|
p.diags[p.diagCount] = ParserDiag {
|
||||||
line: line, column: col, message: msg
|
line: line, column: col, message: msg, severity: 1
|
||||||
};
|
};
|
||||||
p.diagCount = p.diagCount + 1;
|
p.diagCount = p.diagCount + 1;
|
||||||
}
|
}
|
||||||
@@ -133,7 +134,7 @@ func parserExpectIdentOrKeyword(p: *Parser, msg: String) -> LexToken {
|
|||||||
}
|
}
|
||||||
if p.diagCount < 256 {
|
if p.diagCount < 256 {
|
||||||
p.diags[p.diagCount] = ParserDiag {
|
p.diags[p.diagCount] = ParserDiag {
|
||||||
line: tok.line, column: tok.column, message: msg
|
line: tok.line, column: tok.column, message: msg, severity: 1
|
||||||
};
|
};
|
||||||
p.diagCount = p.diagCount + 1;
|
p.diagCount = p.diagCount + 1;
|
||||||
}
|
}
|
||||||
@@ -1773,6 +1774,35 @@ func Parser_Parse(tokens: *LexToken, tokenCount: int) -> *Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Print fatal parser diagnostics (severity == 0) or if nothing valid was parsed */
|
||||||
|
if p.diagCount > 0 && mod.itemCount == 0 {
|
||||||
|
var di: int = 0;
|
||||||
|
while di < p.diagCount {
|
||||||
|
let d: ParserDiag = p.diags[di];
|
||||||
|
Print("error: ");
|
||||||
|
PrintLine(d.message);
|
||||||
|
Print(" --> <input>:");
|
||||||
|
PrintInt(d.line as int64);
|
||||||
|
Print(":");
|
||||||
|
PrintInt(d.column as int64);
|
||||||
|
PrintLine("");
|
||||||
|
Print(" |");
|
||||||
|
PrintLine("");
|
||||||
|
Print(" ");
|
||||||
|
PrintInt(d.line as int64);
|
||||||
|
Print(" | <source unavailable>");
|
||||||
|
PrintLine("");
|
||||||
|
Print(" | ");
|
||||||
|
var sp: uint32 = 0;
|
||||||
|
while sp < d.column - 1 && sp < 120 {
|
||||||
|
Print(" ");
|
||||||
|
sp = sp + 1;
|
||||||
|
}
|
||||||
|
PrintLine("^");
|
||||||
|
di = di + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return mod;
|
return mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user