diff options
Diffstat (limited to 'nimpretty')
-rw-r--r-- | nimpretty/nimpretty.nim | 54 | ||||
-rw-r--r-- | nimpretty/tester.nim | 7 | ||||
-rw-r--r-- | nimpretty/tests/exhaustive.nim | 12 | ||||
-rw-r--r-- | nimpretty/tests/expected/exhaustive.nim | 12 | ||||
-rw-r--r-- | nimpretty/tests/expected/simple.nim | 11 | ||||
-rw-r--r-- | nimpretty/tests/simple.nim | 11 |
6 files changed, 87 insertions, 20 deletions
diff --git a/nimpretty/nimpretty.nim b/nimpretty/nimpretty.nim index a7940349d..e5abf0d2d 100644 --- a/nimpretty/nimpretty.nim +++ b/nimpretty/nimpretty.nim @@ -12,7 +12,7 @@ when not defined(nimpretty): {.error: "This needs to be compiled with --define:nimPretty".} -import ../compiler / [idents, msgs, syntaxes, options, pathutils, layouter] +import ../compiler / [idents, llstream, ast, msgs, syntaxes, options, pathutils, layouter] import parseopt, strutils, os, sequtils @@ -48,6 +48,42 @@ type indWidth*: Natural maxLineLen*: Positive +proc goodEnough(a, b: PNode): bool = + if a.kind == b.kind and a.safeLen == b.safeLen: + case a.kind + of nkNone, nkEmpty, nkNilLit: result = true + of nkIdent: result = a.ident.id == b.ident.id + of nkSym: result = a.sym == b.sym + of nkType: result = true + of nkCharLit, nkIntLit..nkInt64Lit, nkUIntLit..nkUInt64Lit: + result = a.intVal == b.intVal + of nkFloatLit..nkFloat128Lit: + result = a.floatVal == b.floatVal + of nkStrLit, nkRStrLit, nkTripleStrLit: + result = a.strVal == b.strVal + else: + for i in 0 ..< a.len: + if not goodEnough(a[i], b[i]): return false + return true + elif a.kind == nkStmtList and a.len == 1: + result = goodEnough(a[0], b) + elif b.kind == nkStmtList and b.len == 1: + result = goodEnough(a, b[0]) + else: + result = false + +proc finalCheck(content: string; origAst: PNode): bool {.nimcall.} = + var conf = newConfigRef() + let oldErrors = conf.errorCounter + var parser: Parser + parser.em.indWidth = 2 + let fileIdx = fileInfoIdx(conf, AbsoluteFile "nimpretty_bug.nim") + + openParser(parser, fileIdx, llStreamOpen(content), newIdentCache(), conf) + let newAst = parseAll(parser) + closeParser(parser) + result = conf.errorCounter == oldErrors # and goodEnough(newAst, origAst) + proc prettyPrint*(infile, outfile: string, opt: PrettyOptions) = var conf = newConfigRef() let fileIdx = fileInfoIdx(conf, AbsoluteFile infile) @@ -58,8 +94,10 @@ proc prettyPrint*(infile, outfile: string, opt: PrettyOptions) = parser.em.indWidth = opt.indWidth if setupParser(parser, fileIdx, newIdentCache(), conf): parser.em.maxLineLen = opt.maxLineLen - discard parseAll(parser) + let fullAst = parseAll(parser) closeParser(parser) + when defined(nimpretty): + closeEmitter(parser.em, fullAst, finalCheck) proc main = var outfile, outdir: string @@ -69,8 +107,8 @@ proc main = var backup = false # when `on`, create a backup file of input in case - # `prettyPrint` could over-write it (note that the backup may happen even - # if input is not actually over-written, when nimpretty is a noop). + # `prettyPrint` could overwrite it (note that the backup may happen even + # if input is not actually overwritten, when nimpretty is a noop). # --backup was un-documented (rely on git instead). var opt = PrettyOptions(indWidth: 0, maxLineLen: 80) @@ -78,7 +116,13 @@ proc main = for kind, key, val in getopt(): case kind of cmdArgument: - infiles.add(key.addFileExt(".nim")) + if dirExists(key): + for file in walkDirRec(key, skipSpecial = true): + if file.endsWith(".nim") or file.endsWith(".nimble"): + infiles.add(file) + else: + infiles.add(key.addFileExt(".nim")) + of cmdLongOption, cmdShortOption: case normalize(key) of "help", "h": writeHelp() diff --git a/nimpretty/tester.nim b/nimpretty/tester.nim index d646b25ce..b1f15aee6 100644 --- a/nimpretty/tester.nim +++ b/nimpretty/tester.nim @@ -1,9 +1,10 @@ # Small program that runs the test cases import strutils, os, sequtils +from std/private/gitutils import diffFiles const - dir = "nimpretty/tests/" + dir = "nimpretty/tests" outputdir = dir / "outputdir" var @@ -26,7 +27,7 @@ proc test(infile, ext: string) = let produced = dir / nimFile.changeFileExt(ext) if readFile(expected) != readFile(produced): echo "FAILURE: files differ: ", nimFile - discard execShellCmd("diff -uNdr " & expected & " " & produced) + echo diffFiles(expected, produced).output failures += 1 else: echo "SUCCESS: files identical: ", nimFile @@ -43,7 +44,7 @@ proc testTogether(infiles: seq[string]) = let produced = dir / "outputdir" / infile if readFile(expected) != readFile(produced): echo "FAILURE: files differ: ", nimFile - discard execShellCmd("diff -uNdr " & expected & " " & produced) + echo diffFiles(expected, produced).output failures += 1 else: echo "SUCCESS: files identical: ", nimFile diff --git a/nimpretty/tests/exhaustive.nim b/nimpretty/tests/exhaustive.nim index 30cfc47a9..e5a73305b 100644 --- a/nimpretty/tests/exhaustive.nim +++ b/nimpretty/tests/exhaustive.nim @@ -267,7 +267,7 @@ proc emitTok*(em: var Emitter; L: TLexer; tok: TToken) = if not em.endsInWhite: wr(" ") wr(tok.ident.s) template isUnary(tok): bool = - tok.strongSpaceB == 0 and tok.strongSpaceA > 0 + tok.spacing == {tsLeading} if not isUnary(tok) or em.lastTok in {tkOpr, tkDotDot}: wr(" ") @@ -693,11 +693,11 @@ proc newRecordGen(ctx: Context; typ: TypRef): PNode = String `interpolation`:idx: / `format`:idx: inspired by Python's ``f``-strings. -.. code-block:: nim - - import strformat - let msg = "hello" - doAssert fmt"{msg}\n" == "hello\\n" + ```nim + import strformat + let msg = "hello" + doAssert fmt"{msg}\n" == "hello\\n" + ``` Because the literal is a raw string literal, the ``\n`` is not interpreted as an escape sequence. diff --git a/nimpretty/tests/expected/exhaustive.nim b/nimpretty/tests/expected/exhaustive.nim index 82927a11c..7f78b7e56 100644 --- a/nimpretty/tests/expected/exhaustive.nim +++ b/nimpretty/tests/expected/exhaustive.nim @@ -272,7 +272,7 @@ proc emitTok*(em: var Emitter; L: TLexer; tok: TToken) = if not em.endsInWhite: wr(" ") wr(tok.ident.s) template isUnary(tok): bool = - tok.strongSpaceB == 0 and tok.strongSpaceA > 0 + tok.spacing == {tsLeading} if not isUnary(tok) or em.lastTok in {tkOpr, tkDotDot}: wr(" ") @@ -699,11 +699,11 @@ proc newRecordGen(ctx: Context; typ: TypRef): PNode = String `interpolation`:idx: / `format`:idx: inspired by Python's ``f``-strings. -.. code-block:: nim - - import strformat - let msg = "hello" - doAssert fmt"{msg}\n" == "hello\\n" + ```nim + import strformat + let msg = "hello" + doAssert fmt"{msg}\n" == "hello\\n" + ``` Because the literal is a raw string literal, the ``\n`` is not interpreted as an escape sequence. diff --git a/nimpretty/tests/expected/simple.nim b/nimpretty/tests/expected/simple.nim index d13558621..e711eb3b6 100644 --- a/nimpretty/tests/expected/simple.nim +++ b/nimpretty/tests/expected/simple.nim @@ -16,3 +16,14 @@ proc a() = discard ## comment 3 discard # comment 4 + + +# bug #20553 + +let `'hello` = 12 +echo `'hello` + + +proc `'u4`(n: string) = + # The leading ' is required. + discard diff --git a/nimpretty/tests/simple.nim b/nimpretty/tests/simple.nim index 435bd6bd2..2a01a176e 100644 --- a/nimpretty/tests/simple.nim +++ b/nimpretty/tests/simple.nim @@ -16,3 +16,14 @@ proc a() = discard## comment 3 discard # comment 4 + + +# bug #20553 + +let `'hello` = 12 +echo `'hello` + + +proc `'u4`(n: string) = + # The leading ' is required. + discard |