mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-13 06:43:52 +00:00
* refs #15667 improve invalid indentation errors * also show line info where = is missing * add test * add more tests
This commit is contained in:
@@ -163,6 +163,7 @@ proc prettyTok*(tok: Token): string =
|
||||
else: $tok
|
||||
|
||||
proc printTok*(conf: ConfigRef; tok: Token) =
|
||||
# xxx factor with toLocation
|
||||
msgWriteln(conf, $tok.line & ":" & $tok.col & "\t" & $tok.tokType & " " & $tok)
|
||||
|
||||
proc initToken*(L: var Token) =
|
||||
|
||||
@@ -44,6 +44,9 @@ type
|
||||
hasProgress: bool # some while loop requires progress ensurance
|
||||
lex*: Lexer # The lexer that is used for parsing
|
||||
tok*: Token # The current token
|
||||
lineStartPrevious*: int
|
||||
lineNumberPrevious*: int
|
||||
bufposPrevious*: int
|
||||
inPragma*: int # Pragma level
|
||||
inSemiStmtList*: int
|
||||
emptyNode: PNode
|
||||
@@ -77,7 +80,7 @@ proc eat*(p: var Parser, tokType: TokType)
|
||||
proc skipInd*(p: var Parser)
|
||||
proc optPar*(p: var Parser)
|
||||
proc optInd*(p: var Parser, n: PNode)
|
||||
proc indAndComment*(p: var Parser, n: PNode)
|
||||
proc indAndComment*(p: var Parser, n: PNode, maybeMissEquals = false)
|
||||
proc setBaseFlags*(n: PNode, base: NumericalBase)
|
||||
proc parseSymbol*(p: var Parser, mode = smNormal): PNode
|
||||
proc parseTry(p: var Parser; isExpr: bool): PNode
|
||||
@@ -100,6 +103,9 @@ template prettySection(body) =
|
||||
proc getTok(p: var Parser) =
|
||||
## Get the next token from the parser's lexer, and store it in the parser's
|
||||
## `tok` member.
|
||||
p.lineNumberPrevious = p.lex.lineNumber
|
||||
p.lineStartPrevious = p.lex.lineStart
|
||||
p.bufposPrevious = p.lex.bufpos
|
||||
rawGetTok(p.lex, p.tok)
|
||||
p.hasProgress = true
|
||||
when defined(nimpretty):
|
||||
@@ -223,9 +229,13 @@ proc parLineInfo(p: Parser): TLineInfo =
|
||||
## Retrieve the line information associated with the parser's current state.
|
||||
result = getLineInfo(p.lex, p.tok)
|
||||
|
||||
proc indAndComment(p: var Parser, n: PNode) =
|
||||
proc indAndComment(p: var Parser, n: PNode, maybeMissEquals = false) =
|
||||
if p.tok.indent > p.currInd:
|
||||
if p.tok.tokType == tkComment: rawSkipComment(p, n)
|
||||
elif maybeMissEquals:
|
||||
let col = p.bufposPrevious - p.lineStartPrevious
|
||||
var info = newLineInfo(p.lex.fileIdx, p.lineNumberPrevious, col)
|
||||
parMessage(p, "invalid indentation, maybe you forgot a '=' at $1 ?" % [p.lex.config$info])
|
||||
else: parMessage(p, errInvalidIndentation)
|
||||
else:
|
||||
skipComment(p, n)
|
||||
@@ -1773,13 +1783,14 @@ proc parseRoutine(p: var Parser, kind: TNodeKind): PNode =
|
||||
else: result.add(p.emptyNode)
|
||||
# empty exception tracking:
|
||||
result.add(p.emptyNode)
|
||||
if p.tok.tokType == tkEquals and p.validInd:
|
||||
let maybeMissEquals = p.tok.tokType != tkEquals
|
||||
if (not maybeMissEquals) and p.validInd:
|
||||
getTok(p)
|
||||
skipComment(p, result)
|
||||
result.add(parseStmt(p))
|
||||
else:
|
||||
result.add(p.emptyNode)
|
||||
indAndComment(p, result)
|
||||
indAndComment(p, result, maybeMissEquals)
|
||||
|
||||
proc newCommentStmt(p: var Parser): PNode =
|
||||
#| commentStmt = COMMENT
|
||||
|
||||
58
tests/parser/t15667.nim
Normal file
58
tests/parser/t15667.nim
Normal file
@@ -0,0 +1,58 @@
|
||||
discard """
|
||||
cmd: "nim check $options $file"
|
||||
action: "reject"
|
||||
nimout: '''
|
||||
t15667.nim(23, 5) Error: invalid indentation, maybe you forgot a '=' at t15667.nim(22, 13) ?
|
||||
t15667.nim(28, 5) Error: invalid indentation, maybe you forgot a '=' at t15667.nim(26, 13) ?
|
||||
t15667.nim(33, 5) Error: invalid indentation, maybe you forgot a '=' at t15667.nim(31, 25) ?
|
||||
t15667.nim(42, 5) Error: invalid indentation, maybe you forgot a '=' at t15667.nim(38, 12) ?
|
||||
t15667.nim(56, 5) Error: invalid indentation, maybe you forgot a '=' at t15667.nim(55, 13) ?
|
||||
'''
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# line 20
|
||||
block:
|
||||
proc fn1()
|
||||
discard
|
||||
|
||||
block:
|
||||
proc fn2()
|
||||
#
|
||||
discard
|
||||
|
||||
block:
|
||||
proc fn3() {.exportc.}
|
||||
#
|
||||
discard
|
||||
|
||||
block: # complex example
|
||||
proc asdfasdfsd() {. exportc,
|
||||
inline
|
||||
.} # foo
|
||||
#[
|
||||
bar
|
||||
]#
|
||||
discard
|
||||
|
||||
block: # xxx this doesn't work yet (only a bare `invalid indentation` error)
|
||||
proc fn5()
|
||||
##
|
||||
discard
|
||||
|
||||
block: # ditto
|
||||
proc fn6*()
|
||||
## foo bar
|
||||
runnableExamples: discard
|
||||
|
||||
block:
|
||||
proc fn8()
|
||||
runnableExamples:
|
||||
discard
|
||||
discard
|
||||
Reference in New Issue
Block a user