support --hint:all:off --hint:x (ditto with --warnings + friends) (#17852)

* select all hints via `--hint:all:on|off`, etc
* simplify code with setutils
* address comment
This commit is contained in:
Timothee Cour
2021-06-20 10:52:22 -07:00
committed by GitHub
parent 92cb765714
commit 7d5e6b0169
5 changed files with 45 additions and 44 deletions

View File

@@ -429,6 +429,10 @@
- `--hint:CC` now goes to stderr (like all other hints) instead of stdout.
- `--hint:all:on|off` is now supported to select or deselect all hints; it
differs from `--hints:on|off` which acts as a (reversible) gate.
Likewise with `--warning:all:on|off`.
- json build instructions are now generated in `$nimcache/outFileBasename.json`
instead of `$nimcache/projectName.json`. This allows avoiding recompiling a given project
compiled with different options if the output file differs.

View File

@@ -25,10 +25,10 @@ bootSwitch(usedMarkAndSweep, defined(gcmarkandsweep), "--gc:markAndSweep")
bootSwitch(usedGoGC, defined(gogc), "--gc:go")
bootSwitch(usedNoGC, defined(nogc), "--gc:none")
import std/[setutils, os, strutils, parseutils, parseopt, sequtils, strtabs]
import
os, msgs, options, nversion, condsyms, strutils, extccomp, platform,
wordrecg, parseutils, nimblecmd, parseopt, sequtils, lineinfos,
pathutils, strtabs, pathnorm
msgs, options, nversion, condsyms, extccomp, platform,
wordrecg, nimblecmd, lineinfos, pathutils, pathnorm
from ast import eqTypeFlags, tfGcSafe, tfNoSideEffect
@@ -182,7 +182,7 @@ proc processSpecificNote*(arg: string, state: TSpecialWord, pass: TCmdLinePass,
info: TLineInfo; orig: string; conf: ConfigRef) =
var id = "" # arg = key or [key] or key:val or [key]:val; with val=on|off
var i = 0
var n = hintMin
var notes: set[TMsgKind]
var isBracket = false
if i < arg.len and arg[i] == '[':
isBracket = true
@@ -197,37 +197,36 @@ proc processSpecificNote*(arg: string, state: TSpecialWord, pass: TCmdLinePass,
if i == arg.len: discard
elif i < arg.len and (arg[i] in {':', '='}): inc(i)
else: invalidCmdLineOption(conf, pass, orig, info)
# unfortunately, hintUser and warningUser clash
if state in {wHint, wHintAsError}:
let x = findStr(hintMin, hintMax, id, errUnknown)
if x != errUnknown: n = TNoteKind(x)
else: localError(conf, info, "unknown hint: " & id)
else:
let x = findStr(warnMin, warnMax, id, errUnknown)
if x != errUnknown: n = TNoteKind(x)
else: localError(conf, info, "unknown warning: " & id)
let isSomeHint = state in {wHint, wHintAsError}
template findNote(noteMin, noteMax, name) =
# unfortunately, hintUser and warningUser clash, otherwise implementation would simplify a bit
let x = findStr(noteMin, noteMax, id, errUnknown)
if x != errUnknown: notes = {TNoteKind(x)}
else: localError(conf, info, "unknown $#: $#" % [name, id])
case id.normalize
of "all": # other note groups would be easy to support via additional cases
notes = if isSomeHint: {hintMin..hintMax} else: {warnMin..warnMax}
elif isSomeHint: findNote(hintMin, hintMax, "hint")
else: findNote(warnMin, warnMax, "warning")
var val = substr(arg, i).normalize
if val == "": val = "on"
if val notin ["on", "off"]:
# xxx in future work we should also allow users to have control over `foreignPackageNotes`
# so that they can enable `hints|warnings|warningAsErrors` for all the code they depend on.
localError(conf, info, errOnOrOffExpectedButXFound % arg)
elif n notin conf.cmdlineNotes or pass == passCmd1:
if pass == passCmd1: incl(conf.cmdlineNotes, n)
incl(conf.modifiedyNotes, n)
case val
of "on":
if state in {wWarningAsError, wHintAsError}:
incl(conf.warningAsErrors, n) # xxx rename warningAsErrors to noteAsErrors
else:
incl(conf.notes, n)
incl(conf.mainPackageNotes, n)
of "off":
if state in {wWarningAsError, wHintAsError}:
excl(conf.warningAsErrors, n)
else:
excl(conf.notes, n)
excl(conf.mainPackageNotes, n)
excl(conf.foreignPackageNotes, n)
else:
let isOn = val == "on"
for n in notes:
if n notin conf.cmdlineNotes or pass == passCmd1:
if pass == passCmd1: incl(conf.cmdlineNotes, n)
incl(conf.modifiedyNotes, n)
if state in {wWarningAsError, wHintAsError}:
conf.warningAsErrors[n] = isOn # xxx rename warningAsErrors to noteAsErrors
else:
conf.notes[n] = isOn
conf.mainPackageNotes[n] = isOn
if not isOn: excl(conf.foreignPackageNotes, n)
proc processCompile(conf: ConfigRef; filename: string) =
var found = findFile(conf, filename)

View File

@@ -134,5 +134,5 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimHasUnifiedTuple")
defineSymbol("nimHasIterable")
defineSymbol("nimHasTypeofVoid")
defineSymbol("nimHasDragonBox")
defineSymbol("nimHasHintAll")

View File

@@ -48,14 +48,15 @@ Advanced options:
--spellSuggest|:num show at most `num >= 0` spelling suggestions on typos.
if `num` is not specified (or `auto`), return
an implementation defined set of suggestions.
-w:on|off|list, --warnings:on|off|list
turn all warnings on|off or list all available
--warning:X:on|off turn specific warning X on|off.
`warning:X` means `warning:X:on`, as with similar flags.
--hints:on|off|list turn all hints on|off or list all available
--hint:X:on|off turn specific hint X on|off.
--warningAsError:X:on|off turn specific warning X into an error on|off
--hints:on|off|list. `on|off` enables or disables hints.
`list` reports which hints are selected.
--hint:X:on|off turn specific hint X on|off. `hint:X` means `hint:X:on`,
as with similar flags. `all` can be used for "all hints".
--hintAsError:X:on|off turn specific hint X into an error on|off
-w:on|off|list, --warnings:on|off|list
same as `--hints` but for warnings.
--warning:X:on|off ditto
--warningAsError:X:on|off ditto
--styleCheck:off|hint|error
produce hints or errors for Nim identifiers that
do not adhere to Nim's official style guide

View File

@@ -23,9 +23,6 @@ proc isDots(a: string): bool =
a.startsWith(".") and a.strip(chars = {'.'}) == ""
const
defaultHintsOff = "--hint:successx:off --hint:exec:off --hint:link:off --hint:cc:off --hint:conf:off --hint:processing:off --hint:QuitCalled:off"
# useful when you want to turn only some hints on, and some common ones off.
# pending https://github.com/timotheecour/Nim/issues/453, simplify to: `--hints:off`
nim = getCurrentCompilerExe()
mode = querySetting(backend)
nimcache = buildDir / "nimcacheTrunner"
@@ -236,7 +233,7 @@ sub/mmain.idx""", context
check execCmdEx(cmd) == ("witness\n", 0)
block: # config.nims, nim.cfg, hintConf, bug #16557
let cmd = fmt"{nim} r {defaultHintsOff} --hint:conf tests/newconfig/bar/mfoo.nim"
let cmd = fmt"{nim} r --hint:all:off --hint:conf tests/newconfig/bar/mfoo.nim"
let (outp, exitCode) = execCmdEx(cmd, options = {poStdErrToStdOut})
doAssert exitCode == 0
let dir = getCurrentDir()
@@ -268,7 +265,7 @@ tests/newconfig/bar/mfoo.nims""".splitLines
check fmt"""{nim} r -b:js {opt} --eval:"echo defined(js)"""".execCmdEx == ("true\n", 0)
block: # `hintProcessing` dots should not interfere with `static: echo` + friends
let cmd = fmt"""{nim} r {defaultHintsOff} --hint:processing -f --eval:"static: echo 1+1""""
let cmd = fmt"""{nim} r --hint:all:off --hint:processing -f --eval:"static: echo 1+1""""
let (outp, exitCode) = execCmdEx(cmd, options = {poStdErrToStdOut})
template check3(cond) = doAssert cond, $(outp,)
doAssert exitCode == 0
@@ -282,7 +279,7 @@ tests/newconfig/bar/mfoo.nims""".splitLines
check3 "2" in outp
block: # nim secret
let opt = fmt"{defaultHintsOff} --hint:processing"
let opt = "--hint:all:off --hint:processing"
template check3(cond) = doAssert cond, $(outp,)
for extra in ["", "--stdout"]:
let cmd = fmt"""{nim} secret {opt} {extra}"""