Rst test check messages (fix #17280) (#17338)

This commit is contained in:
Andrey Makarov 2021-03-17 22:13:04 +03:00 • committed by GitHub
commit 4bfc5a9551
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 155 additions and 89 deletions

View file

@ -146,7 +146,8 @@
## .. _Sphinx directives: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html
import
os, strutils, rstast, algorithm, lists, sequtils
os, strutils, rstast, std/enumutils, algorithm, lists, sequtils,
std/private/miscdollars
type
RstParseOption* = enum ## options for the RST parser
@ -477,9 +478,10 @@ type
EParseError* = object of ValueError
const
LineRstInit* = 1 ## Initial line number for standalone RST text
ColRstInit* = 0 ## Initial column number for standalone RST text
## (Nim global reporting adds ColOffset=1)
LineRstInit* = 1 ## Initial line number for standalone RST text
ColRstInit* = 0 ## Initial column number for standalone RST text
## (Nim global reporting adds ColOffset=1)
ColRstOffset* = 1 ## 1: a replica of ColOffset for internal use
template currentTok(p: RstParser): Token = p.tok[p.idx]
template prevTok(p: RstParser): Token = p.tok[p.idx - 1]
@ -487,7 +489,7 @@ template nextTok(p: RstParser): Token = p.tok[p.idx + 1]
proc whichMsgClass*(k: MsgKind): MsgClass =
## returns which message class `k` belongs to.
case ($k)[1]
case k.symbolName[1]
of 'e', 'E': result = mcError
of 'w', 'W': result = mcWarning
of 'h', 'H': result = mcHint
@ -497,7 +499,9 @@ proc defaultMsgHandler*(filename: string, line, col: int, msgkind: MsgKind,
arg: string) =
let mc = msgkind.whichMsgClass
let a = $msgkind % arg
let message = "$1($2, $3) $4: $5" % [filename, $line, $col, $mc, a]
var message: string
toLocation(message, filename, line, col + ColRstOffset)
message.add " $1: $2" % [$mc, a]
if mc == mcError: raise newException(EParseError, message)
else: writeLine(stdout, message)
@ -1973,25 +1977,32 @@ proc parseEnumList(p: var RstParser): PRstNode =
if match(p, p.idx, wildcards[w]): break
inc w
assert w < wildcards.len
proc checkAfterNewline(p: RstParser, report: bool): bool =
## If no indentation on the next line then parse as a normal paragraph
## according to the RST spec. And report a warning with suggestions
let j = tokenAfterNewline(p, start=p.idx+1)
let requiredIndent = p.tok[p.idx+wildToken[w]].col
if p.tok[j].kind notin {tkIndent, tkEof} and
p.tok[j].col < p.tok[p.idx+wildToken[w]].col and
p.tok[j].col < requiredIndent and
(p.tok[j].col > col or
(p.tok[j].col == col and not match(p, j, wildcards[w]))):
if report:
let n = p.line + p.tok[j].line
let msg = "\n" & """
not enough indentation on line $2
(if it's continuation of enumeration list),
(should be at column $3 if it's a continuation of enum. list),
or no blank line after line $1 (if it should be the next paragraph),
or no escaping \ at the beginning of line $1
(if lines $1..$2 are a normal paragraph, not enum. list)""".
unindent(8)
rstMessage(p, mwRstStyle, msg % [$(n-1), $n])
let c = p.col + requiredIndent + ColRstOffset
rstMessage(p, mwRstStyle, msg % [$(n-1), $n, $c],
p.tok[j].line, p.tok[j].col)
result = false
else:
result = true
if not checkAfterNewline(p, report = true):
return nil
result = newRstNodeA(p, rnEnumList)