summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/commands.nim9
-rw-r--r--compiler/linter.nim26
-rw-r--r--compiler/options.nim3
-rw-r--r--compiler/semstmts.nim8
-rw-r--r--compiler/semtypes.nim2
5 files changed, 32 insertions, 16 deletions
diff --git a/compiler/commands.nim b/compiler/commands.nim
index 39967c4bc..b39cc0b72 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -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
diff --git a/compiler/linter.nim b/compiler/linter.nim
index 0b69db8cb..a881f2711 100644
--- a/compiler/linter.nim
+++ b/compiler/linter.nim
@@ -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)
diff --git a/compiler/options.nim b/compiler/options.nim
index 4b7d664f4..1280cb59b 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -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
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index b97a56178..5c7f866ce 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -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)
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index c0f155a49..5215a1d11 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -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