diff options
author | Timothee Cour <timothee.cour2@gmail.com> | 2021-02-01 22:41:33 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-02 07:41:33 +0100 |
commit | 4b2054a7bf2443f01db80aaac9d5de6f42e555cd (patch) | |
tree | 77e4f18e88e81870a7b59ce195748710f8234f98 | |
parent | 15d6be52a17b4991b8b226fbd8f890242dac3d77 (diff) | |
download | Nim-4b2054a7bf2443f01db80aaac9d5de6f42e555cd.tar.gz |
`dumpToString`: improves on `sugar.dump` (#16841)
* dumpToString * _ * fixup * changelog * address comment: removed the word "Deprecated"
-rw-r--r-- | changelog.md | 1 | ||||
-rw-r--r-- | lib/pure/sugar.nim | 35 | ||||
-rw-r--r-- | tests/stdlib/tsugar.nim | 12 |
3 files changed, 44 insertions, 4 deletions
diff --git a/changelog.md b/changelog.md index 5f5222e59..b07186eed 100644 --- a/changelog.md +++ b/changelog.md @@ -104,6 +104,7 @@ with other backends. see #9125. Use `-d:nimLegacyJsRound` for previous behavior. `-d:nimLegacyParseQueryStrict`. `cgi.decodeData` which uses the same underlying code is also updated the same way. +- Added `sugar.dumpToString` which improves on `sugar.dump`. diff --git a/lib/pure/sugar.nim b/lib/pure/sugar.nim index 428136a4b..5e71ca54b 100644 --- a/lib/pure/sugar.nim +++ b/lib/pure/sugar.nim @@ -156,16 +156,45 @@ macro dump*(x: untyped): untyped = ## It accepts any expression and prints a textual representation ## of the tree representing the expression - as it would appear in ## source code - together with the value of the expression. + ## + ## See also: `dumpToString` which is more convenient and useful since + ## it expands intermediate templates/macros, returns a string instead of + ## calling `echo`, and works with statements and expressions. runnableExamples: let x = 10 y = 20 - dump(x + y) # will print `x + y = 30` + if false: dump(x + y) # if true would print `x + y = 30` let s = x.toStrLit - let r = quote do: + result = quote do: debugEcho `s`, " = ", `x` - return r + +macro dumpToStringImpl(s: static string, x: typed): string = + let s2 = x.toStrLit + if x.typeKind == ntyVoid: + result = quote do: + `s` & ": " & `s2` + else: + result = quote do: + `s` & ": " & `s2` & " = " & $`x` + +macro dumpToString*(x: untyped): string = + ## Returns the content of a statement or expression `x` after semantic analysis, + ## useful for debugging. + runnableExamples: + const a = 1 + let x = 10 + doAssert dumpToString(a + 2) == "a + 2: 3 = 3" + doAssert dumpToString(a + x) == "a + x: 1 + x = 11" + template square(x): untyped = x * x + doAssert dumpToString(square(x)) == "square(x): x * x = 100" + doAssert not compiles dumpToString(1 + nonexistant) + import std/strutils + doAssert "failedAssertImpl" in dumpToString(doAssert true) # example with a statement + result = newCall(bindSym"dumpToStringImpl") + result.add newLit repr(x) + result.add x # TODO: consider exporting this in macros.nim proc freshIdentNodes(ast: NimNode): NimNode = diff --git a/tests/stdlib/tsugar.nim b/tests/stdlib/tsugar.nim index 2f79a9174..26b4eca1a 100644 --- a/tests/stdlib/tsugar.nim +++ b/tests/stdlib/tsugar.nim @@ -107,4 +107,14 @@ doAssert collect(for d in data.items: {d}) == data.toHashSet # bug #14332 template foo = discard collect(newSeq, for i in 1..3: i) -foo() \ No newline at end of file +foo() + +block: # dumpToString + template square(x): untyped = x * x + let x = 10 + doAssert dumpToString(square(x)) == "square(x): x * x = 100" + let s = dumpToString(doAssert 1+1 == 2) + doAssert "failedAssertImpl" in s + let s2 = dumpToString: + doAssertRaises(AssertionDefect): doAssert false + doAssert "except AssertionDefect" in s2 |