warn about inconsistent spacing around binary operators; fixes #7582

This commit is contained in:
Andreas Rumpf 2018-05-05 14:58:33 +02:00
commit 1aa359febb
12 changed files with 28 additions and 27 deletions

View file

@ -17,6 +17,9 @@
- The ``not nil`` type annotation now has to be enabled explicitly - The ``not nil`` type annotation now has to be enabled explicitly
via ``{.experimental: "notnil"}`` as we are still not pleased with how this via ``{.experimental: "notnil"}`` as we are still not pleased with how this
feature works with Nim's containers. feature works with Nim's containers.
- The parser now warns about inconsistent spacing around binary operators as
these can easily be confused with unary operators. This warning will likely
become an error in the future.
#### Breaking changes in the standard library #### Breaking changes in the standard library
@ -89,7 +92,7 @@
- Accessing the binary zero terminator in Nim's native strings - Accessing the binary zero terminator in Nim's native strings
is now invalid. Internally a Nim string still has the trailing zero for is now invalid. Internally a Nim string still has the trailing zero for
zero-copy interoperability with ``cstring``. Compile your code with the zero-copy interoperability with ``cstring``. Compile your code with the
next switch ``--laxStrings:on`` if you need a transition period. new switch ``--laxStrings:on`` if you need a transition period.
### Tool changes ### Tool changes

View file

@ -131,7 +131,7 @@ type
warnEachIdentIsTuple, warnShadowIdent, warnEachIdentIsTuple, warnShadowIdent,
warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2, warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2,
warnUninit, warnGcMem, warnDestructor, warnLockLevel, warnResultShadowed, warnUninit, warnGcMem, warnDestructor, warnLockLevel, warnResultShadowed,
warnUser, warnInconsistentSpacing, warnUser,
hintSuccess, hintSuccessX, hintSuccess, hintSuccessX,
hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded, hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded,
hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled, hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled,
@ -416,6 +416,7 @@ const
warnDestructor: "usage of a type with a destructor in a non destructible context. This will become a compile time error in the future.", warnDestructor: "usage of a type with a destructor in a non destructible context. This will become a compile time error in the future.",
warnLockLevel: "$1", warnLockLevel: "$1",
warnResultShadowed: "Special variable 'result' is shadowed.", warnResultShadowed: "Special variable 'result' is shadowed.",
warnInconsistentSpacing: "Number of spaces around '$#' is not consistent",
warnUser: "$1", warnUser: "$1",
hintSuccess: "operation successful", hintSuccess: "operation successful",
hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#; $#)", hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#; $#)",
@ -454,7 +455,8 @@ const
"TypelessParam", "UseBase", "WriteToForeignHeap", "TypelessParam", "UseBase", "WriteToForeignHeap",
"UnsafeCode", "EachIdentIsTuple", "ShadowIdent", "UnsafeCode", "EachIdentIsTuple", "ShadowIdent",
"ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit", "ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit",
"GcMem", "Destructor", "LockLevel", "ResultShadowed", "User"] "GcMem", "Destructor", "LockLevel", "ResultShadowed",
"Spacing", "User"]
HintsToStr* = ["Success", "SuccessX", "LineTooLong", HintsToStr* = ["Success", "SuccessX", "LineTooLong",
"XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded", "XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",

View file

@ -268,13 +268,9 @@ proc isUnary(p: TParser): bool =
proc checkBinary(p: TParser) {.inline.} = proc checkBinary(p: TParser) {.inline.} =
## Check if the current parser token is a binary operator. ## Check if the current parser token is a binary operator.
# we don't check '..' here as that's too annoying # we don't check '..' here as that's too annoying
if p.strongSpaces and p.tok.tokType == tkOpr: if p.tok.tokType == tkOpr:
if p.tok.strongSpaceB > 0 and p.tok.strongSpaceA != p.tok.strongSpaceB: if p.tok.strongSpaceB > 0 and p.tok.strongSpaceA != p.tok.strongSpaceB:
parMessage(p, errGenerated, parMessage(p, warnInconsistentSpacing, prettyTok(p.tok))
"Number of spaces around '$#' not consistent" %
prettyTok(p.tok))
elif p.tok.strongSpaceA notin {0,1,2,4,8}:
parMessage(p, errGenerated, "Number of spaces must be 0,1,2,4 or 8")
#| module = stmt ^* (';' / IND{=}) #| module = stmt ^* (';' / IND{=})
#| #|