From 69ed78b30f1627897b2e650afb9dfb5bd867b2d3 Mon Sep 17 00:00:00 2001 From: Adam Strzelecki Date: Mon, 20 Apr 2015 22:02:25 +0200 Subject: [PATCH 1/3] msg: Output column numbers starting from 1 Most of editors/IDEs expect column numbers to start from 1, so (1, 1) means beginning of the file. This change applies only to diagnostics output, however Nim will still internally number columns starting from 0. --- compiler/msgs.nim | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 778b839f3..7681b4eb8 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -804,8 +804,11 @@ proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string, ignoreMsg = optHints notin gOptions or msg notin gNotes frmt = PosHintFormat inc(gHintCounter) + # NOTE: currently line info line numbers start with 1, + # but column numbers start with 0, however most editors expect + # first column to be 1, so we need to +1 here let s = frmt % [toMsgFilename(info), coordToStr(info.line), - coordToStr(info.col), getMessageStr(msg, arg)] + coordToStr(info.col+1), getMessageStr(msg, arg)] if not ignoreMsg and not ignoreMsgBecauseOfIdeTools(msg): msgWriteln(s) if optPrintSurroundingSrc and msg in errMin..errMax: From 07b13251d173226cd29290935297bc9efee023b8 Mon Sep 17 00:00:00 2001 From: Adam Strzelecki Date: Thu, 16 Apr 2015 00:36:42 +0200 Subject: [PATCH 2/3] Parser: Fix location (line, col) for diagnostics Previously parser was using lexMessage which was taking location from current buffer position which was pointing after recently consumed token. But since parser shows diagnostics about that token it should point to the location where token starts. This makes diagnostics like: `test.nim(2, 2) Error: ':' expected` point properly at the beginning of the wrong token. --- compiler/lexer.nim | 4 ++++ compiler/parser.nim | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/compiler/lexer.nim b/compiler/lexer.nim index 694d6f4d7..a2db5ac30 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -221,6 +221,10 @@ proc dispMessage(L: TLexer; info: TLineInfo; msg: TMsgKind; arg: string) = proc lexMessage*(L: TLexer, msg: TMsgKind, arg = "") = L.dispMessage(getLineInfo(L), msg, arg) +proc lexMessageTok*(L: TLexer, msg: TMsgKind, tok: TToken, arg = "") = + var info = newLineInfo(L.fileIdx, tok.line, tok.col) + L.dispMessage(info, msg, arg) + proc lexMessagePos(L: var TLexer, msg: TMsgKind, pos: int, arg = "") = var info = newLineInfo(L.fileIdx, L.lineNumber, pos - L.lineStart) L.dispMessage(info, msg, arg) diff --git a/compiler/parser.nim b/compiler/parser.nim index 7da2f0d22..4516f3603 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -91,7 +91,7 @@ proc closeParser(p: var TParser) = proc parMessage(p: TParser, msg: TMsgKind, arg = "") = ## Produce and emit the parser message `arg` to output. - lexMessage(p.lex, msg, arg) + lexMessageTok(p.lex, msg, p.tok, arg) proc parMessage(p: TParser, msg: TMsgKind, tok: TToken) = ## Produce and emit a parser message to output about the token `tok` @@ -154,7 +154,7 @@ proc eat(p: var TParser, tokType: TTokType) = if p.tok.tokType == tokType: getTok(p) else: - lexMessage(p.lex, errTokenExpected, TokTypeToStr[tokType]) + lexMessageTok(p.lex, errTokenExpected, p.tok, TokTypeToStr[tokType]) proc parLineInfo(p: TParser): TLineInfo = ## Retrieve the line information associated with the parser's current state. @@ -1636,7 +1636,7 @@ proc parseEnum(p: var TParser): PNode = p.tok.tokType == tkEof: break if result.len <= 1: - lexMessage(p.lex, errIdentifierExpected, prettyTok(p.tok)) + lexMessageTok(p.lex, errIdentifierExpected, p.tok, prettyTok(p.tok)) proc parseObjectPart(p: var TParser): PNode proc parseObjectWhen(p: var TParser): PNode = From dc1b15647cfc2feea7fb41609d45910aee57573f Mon Sep 17 00:00:00 2001 From: Adam Strzelecki Date: Sun, 19 Apr 2015 17:44:04 +0200 Subject: [PATCH 3/3] Parser: Test for exact missing ':' location column This ensures compiler points to the right place when claiming that ':' is missing. --- tests/parser/tinvcolonlocation1.nim | 12 ++++++++++++ tests/parser/tinvcolonlocation2.nim | 15 +++++++++++++++ tests/parser/tinvcolonlocation3.nim | 12 ++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 tests/parser/tinvcolonlocation1.nim create mode 100644 tests/parser/tinvcolonlocation2.nim create mode 100644 tests/parser/tinvcolonlocation3.nim diff --git a/tests/parser/tinvcolonlocation1.nim b/tests/parser/tinvcolonlocation1.nim new file mode 100644 index 000000000..cacde48bd --- /dev/null +++ b/tests/parser/tinvcolonlocation1.nim @@ -0,0 +1,12 @@ +discard """ + file: "tinvcolonlocation1.nim" + line: 8 + column: 3 + errormsg: "':' expected" +""" +try #<- missing ':' + echo "try" +except: + echo "except" +finally: + echo "finally" diff --git a/tests/parser/tinvcolonlocation2.nim b/tests/parser/tinvcolonlocation2.nim new file mode 100644 index 000000000..2b6a92b9d --- /dev/null +++ b/tests/parser/tinvcolonlocation2.nim @@ -0,0 +1,15 @@ +discard """ + file: "tinvcolonlocation2.nim" + line: 11 + column: 1 + errormsg: "':' expected" +""" +try: + echo "try" +except #<- missing ':' + echo "except" +finally: +#<-- error will be here above, at the beginning of finally, +# since compiler tries to consome echo and part of except +# expression + echo "finally" diff --git a/tests/parser/tinvcolonlocation3.nim b/tests/parser/tinvcolonlocation3.nim new file mode 100644 index 000000000..2b30b1dbe --- /dev/null +++ b/tests/parser/tinvcolonlocation3.nim @@ -0,0 +1,12 @@ +discard """ + file: "tinvcolonlocation3.nim" + line: 12 + column: 3 + errormsg: "':' expected" +""" +try: + echo "try" +except: + echo "except" +finally #<- missing ':' + echo "finally"