summary refs log tree commit diff stats
path: root/nimpretty
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2023-12-13 10:39:10 +0100
committerGitHub <noreply@github.com>2023-12-13 10:39:10 +0100
commitcd4ecddb30a64f5d2c3c6fdde955366c7976577f (patch)
tree16e9c2ffe00db23b01f16cb02bf1064fcd786b51 /nimpretty
parent7e1ea50bc3a495bc8feb69ceb9856a0a28ecc2e9 (diff)
downloadNim-cd4ecddb30a64f5d2c3c6fdde955366c7976577f.tar.gz
nimpretty: check the rendered AST for wrong output (#23057)
Diffstat (limited to 'nimpretty')
-rw-r--r--nimpretty/nimpretty.nim42
1 files changed, 40 insertions, 2 deletions
diff --git a/nimpretty/nimpretty.nim b/nimpretty/nimpretty.nim
index e3b4c9a3a..8e8c58597 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