mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-04 02:44:44 +00:00
Nim style checker: document the switch; fixes #9564
This commit is contained in:
@@ -115,6 +115,7 @@ const
|
||||
errInvalidCmdLineOption = "invalid command line option: '$1'"
|
||||
errOnOrOffExpectedButXFound = "'on' or 'off' expected, but '$1' found"
|
||||
errOnOffOrListExpectedButXFound = "'on', 'off' or 'list' expected, but '$1' found"
|
||||
errOffHintsError = "'off', 'hint' or 'error' expected, but '$1' found"
|
||||
|
||||
proc invalidCmdLineOption(conf: ConfigRef; pass: TCmdLinePass, switch: string, info: TLineInfo) =
|
||||
if switch == " ": localError(conf, info, errInvalidCmdLineOption % "-")
|
||||
@@ -732,8 +733,12 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||
doAssert(conf != nil)
|
||||
incl(conf.features, destructor)
|
||||
defineSymbol(conf.symbols, "nimNewRuntime")
|
||||
of "nep1":
|
||||
processOnOffSwitchG(conf, {optCheckNep1}, arg, pass, info)
|
||||
of "stylecheck":
|
||||
case arg.normalize
|
||||
of "off": conf.globalOptions = conf.globalOptions - {optStyleHint, optStyleError}
|
||||
of "hint": conf.globalOptions = conf.globalOptions + {optStyleHint}
|
||||
of "error": conf.globalOptions = conf.globalOptions + {optStyleError}
|
||||
else: localError(conf, info, errOffHintsError % arg)
|
||||
of "cppcompiletonamespace":
|
||||
if arg.len > 0:
|
||||
conf.cppCustomNamespace = arg
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
## This module implements the code "prettifier". This is part of the toolchain
|
||||
## to convert Nim code into a consistent style.
|
||||
## This module implements the style checker.
|
||||
|
||||
import
|
||||
strutils, os, intsets, strtabs
|
||||
@@ -23,9 +22,6 @@ proc identLen*(line: string, start: int): int =
|
||||
while start+result < line.len and line[start+result] in Letters:
|
||||
inc result
|
||||
|
||||
when false:
|
||||
import prettybase
|
||||
|
||||
type
|
||||
StyleCheck* {.pure.} = enum None, Warn, Auto
|
||||
|
||||
@@ -71,9 +67,9 @@ proc beautifyName(s: string, k: TSymKind): string =
|
||||
if s =~ ["int", "uint", "cint", "cuint", "clong", "cstring", "string",
|
||||
"char", "byte", "bool", "openArray", "seq", "array", "void",
|
||||
"pointer", "float", "csize", "cdouble", "cchar", "cschar",
|
||||
"cshort", "cu", "nil", "expr", "stmt", "typedesc", "auto", "any",
|
||||
"range", "openarray", "varargs", "set", "cfloat"
|
||||
]:
|
||||
"cshort", "cu", "nil", "typedesc", "auto", "any",
|
||||
"range", "openarray", "varargs", "set", "cfloat", "ref", "ptr",
|
||||
"untyped", "typed", "static", "sink", "lent", "type"]:
|
||||
result.add s[i]
|
||||
else:
|
||||
result.add toUpperAscii(s[i])
|
||||
@@ -122,6 +118,12 @@ proc replaceInFile(conf: ConfigRef; info: TLineInfo; newName: string) =
|
||||
system.shallowCopy(conf.m.fileInfos[info.fileIndex.int].lines[info.line.int-1], x)
|
||||
conf.m.fileInfos[info.fileIndex.int].dirty = true
|
||||
|
||||
proc lintReport(conf: ConfigRef; info: TLineInfo, beau: string) =
|
||||
if optStyleError in conf.globalOptions:
|
||||
localError(conf, info, "name should be: '$1'" % beau)
|
||||
else:
|
||||
message(conf, info, hintName, beau)
|
||||
|
||||
proc checkStyle(conf: ConfigRef; cache: IdentCache; info: TLineInfo, s: string, k: TSymKind; sym: PSym) =
|
||||
let beau = beautifyName(s, k)
|
||||
if s != beau:
|
||||
@@ -129,7 +131,7 @@ proc checkStyle(conf: ConfigRef; cache: IdentCache; info: TLineInfo, s: string,
|
||||
sym.name = getIdent(cache, beau)
|
||||
replaceInFile(conf, info, beau)
|
||||
else:
|
||||
message(conf, info, hintName, beau)
|
||||
lintReport(conf, info, beau)
|
||||
|
||||
proc styleCheckDefImpl(conf: ConfigRef; cache: IdentCache; info: TLineInfo; s: PSym; k: TSymKind) =
|
||||
# operators stay as they are:
|
||||
@@ -142,12 +144,14 @@ proc nep1CheckDefImpl(conf: ConfigRef; info: TLineInfo; s: PSym; k: TSymKind) =
|
||||
# operators stay as they are:
|
||||
if k in {skResult, skTemp} or s.name.s[0] notin Letters: return
|
||||
if k in {skType, skGenericParam} and sfAnon in s.flags: return
|
||||
if s.typ != nil and s.typ.kind == tyTypeDesc: return
|
||||
if {sfImportc, sfExportc} * s.flags != {}: return
|
||||
let beau = beautifyName(s.name.s, k)
|
||||
if s.name.s != beau:
|
||||
message(conf, info, hintName, beau)
|
||||
lintReport(conf, info, beau)
|
||||
|
||||
template styleCheckDef*(conf: ConfigRef; info: TLineInfo; s: PSym; k: TSymKind) =
|
||||
if optCheckNep1 in conf.globalOptions:
|
||||
if {optStyleHint, optStyleError} * conf.globalOptions != {}:
|
||||
nep1CheckDefImpl(conf, info, s, k)
|
||||
when defined(nimfix):
|
||||
if gStyleCheck != StyleCheck.None: styleCheckDefImpl(conf, cache, info, s, k)
|
||||
|
||||
@@ -54,7 +54,8 @@ type # please make sure we have under 32 options
|
||||
optGenScript, # generate a script file to compile the *.c files
|
||||
optGenMapping, # generate a mapping file
|
||||
optRun, # run the compiled project
|
||||
optCheckNep1, # check that the names adhere to NEP-1
|
||||
optStyleHint, # check that the names adhere to NEP-1
|
||||
optStyleError, # enforce that the names adhere to NEP-1
|
||||
optSkipSystemConfigFile, # skip the system's cfg/nims config file
|
||||
optSkipProjConfigFile, # skip the project's cfg/nims config file
|
||||
optSkipUserConfigFile, # skip the users's cfg/nims config file
|
||||
|
||||
@@ -318,7 +318,6 @@ proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym =
|
||||
if result.owner.kind == skModule:
|
||||
incl(result.flags, sfGlobal)
|
||||
suggestSym(c.config, n.info, result, c.graph.usageSym)
|
||||
styleCheckDef(c.config, result)
|
||||
|
||||
proc checkNilable(c: PContext; v: PSym) =
|
||||
if {sfGlobal, sfImportC} * v.flags == {sfGlobal} and
|
||||
@@ -359,6 +358,7 @@ proc semUsing(c: PContext; n: PNode): PNode =
|
||||
let typ = semTypeNode(c, a.sons[length-2], nil)
|
||||
for j in countup(0, length-3):
|
||||
let v = semIdentDef(c, a.sons[j], skParam)
|
||||
styleCheckDef(c.config, v)
|
||||
v.typ = typ
|
||||
strTableIncl(c.signatures, v)
|
||||
else:
|
||||
@@ -489,6 +489,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||
addToVarSection(c, result, n, a)
|
||||
continue
|
||||
var v = semIdentDef(c, a.sons[j], symkind)
|
||||
styleCheckDef(c.config, v)
|
||||
if sfGenSym notin v.flags and not isDiscardUnderscore(v):
|
||||
addInterfaceDecl(c, v)
|
||||
when oKeepVariableNames:
|
||||
@@ -542,6 +543,7 @@ proc semConst(c: PContext, n: PNode): PNode =
|
||||
if a.kind != nkConstDef: illFormedAst(a, c.config)
|
||||
checkSonsLen(a, 3, c.config)
|
||||
var v = semIdentDef(c, a.sons[0], skConst)
|
||||
styleCheckDef(c.config, v)
|
||||
var typ: PType = nil
|
||||
if a.sons[1].kind != nkEmpty: typ = semTypeNode(c, a.sons[1], nil)
|
||||
|
||||
@@ -873,6 +875,7 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) =
|
||||
let typsym = pkg.tab.strTableGet(typName)
|
||||
if typsym.isNil:
|
||||
s = semIdentDef(c, name[1], skType)
|
||||
styleCheckDef(c.config, s)
|
||||
s.typ = newTypeS(tyObject, c)
|
||||
s.typ.sym = s
|
||||
s.flags.incl sfForward
|
||||
@@ -886,6 +889,7 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) =
|
||||
s = typsym
|
||||
else:
|
||||
s = semIdentDef(c, name, skType)
|
||||
styleCheckDef(c.config, s)
|
||||
s.typ = newTypeS(tyForward, c)
|
||||
s.typ.sym = s # process pragmas:
|
||||
if name.kind == nkPragmaExpr:
|
||||
@@ -1616,6 +1620,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
pragma(c, s, n.sons[pragmasPos], validPragmas)
|
||||
else:
|
||||
implicitPragmas(c, s, n, validPragmas)
|
||||
styleCheckDef(c.config, s)
|
||||
else:
|
||||
if n.sons[pragmasPos].kind != nkEmpty:
|
||||
pragma(c, s, n.sons[pragmasPos], validPragmas)
|
||||
@@ -1628,6 +1633,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
if proto.typ.callConv != s.typ.callConv or proto.typ.flags < s.typ.flags:
|
||||
localError(c.config, n.sons[pragmasPos].info, errPragmaOnlyInHeaderOfProcX %
|
||||
("'" & proto.name.s & "' from " & c.config$proto.info))
|
||||
styleCheckDef(c.config, s)
|
||||
if sfForward notin proto.flags and proto.magic == mNone:
|
||||
wrongRedefinition(c, n.info, proto.name.s, proto.info)
|
||||
excl(proto.flags, sfForward)
|
||||
|
||||
@@ -505,7 +505,6 @@ proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode,
|
||||
else: discard
|
||||
else:
|
||||
result = semIdentVis(c, kind, n, allowed)
|
||||
styleCheckDef(c.config, n.info, result)
|
||||
|
||||
proc checkForOverlap(c: PContext, t: PNode, currentEx, branchIndex: int) =
|
||||
let ex = t[branchIndex][currentEx].skipConv
|
||||
@@ -689,6 +688,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||
else: rectype.sym
|
||||
for i in countup(0, sonsLen(n)-3):
|
||||
var f = semIdentWithPragma(c, skField, n.sons[i], {sfExported})
|
||||
styleCheckDef(c.config, n.sons[i].info, f)
|
||||
suggestSym(c.config, n.sons[i].info, f, c.graph.usageSym)
|
||||
f.typ = typ
|
||||
f.position = pos
|
||||
|
||||
@@ -25,6 +25,10 @@ Advanced options:
|
||||
--warning[X]:on|off turn specific warning X on|off
|
||||
--hints:on|off|list turn all hints on|off or list all available
|
||||
--hint[X]:on|off turn specific hint X on|off
|
||||
--styleCheck:off|hint|error
|
||||
produce hints or errors for Nim identifiers that
|
||||
do not adhere to Nim's official style guide
|
||||
https://nim-lang.org/docs/nep1.html
|
||||
--lib:PATH set the system library path
|
||||
--import:PATH add an automatically imported module
|
||||
--include:PATH add an automatically included module
|
||||
|
||||
Reference in New Issue
Block a user