New Check: AvoidFinalConditionInversion #112

Closed
romani opened this Issue Apr 14, 2013 · 8 comments

Projects

None yet

5 participants

@romani
Member
romani commented Apr 14, 2013

We need a check that could catch "not" operator - "!" (an exclamation mark) that is used as final operation, but it is possible without changing a meaning of condition change its parts to make condition more readable.

Bad code examples:
isDifferent(): return ! (a == b); ==should be==> return a != b;
isLower(): boolean c = !(a > b); ==should be==> boolean c = a <= b;
isLowerLimits(): if (! ((a>=8) && (b>=5)) ) ==should be==> if ((a<8) || (b<5))

Big example (not sure we could catch such cases):

return !(timeLoadMlls < maxMasterSymbolLoadStampMills 
          && fileName.toLowerCase().contains(MASTER_SYMBOL_NAME_PART) 
          || timeLoadMlls < maxOtherLoadStampMills 
          && !fileName.toLowerCase().contains(MASTER_SYMBOL_NAME_PART));

==should be==>

return (timeLoadMlls >= maxMasterSymbolLoadStampMills 
           || !fileName.toLowerCase().contains(MASTER_SYMBOL_NAME_PART) 
           && timeLoadMlls >= maxOtherLoadStampMills 
           || fileName.toLowerCase().contains(MASTER_SYMBOL_NAME_PART));
@ilumar ilumar was assigned Apr 30, 2013
@ilumar ilumar was unassigned by romani Feb 11, 2014
@daniilyar daniilyar added difficult and removed enhancement labels Aug 15, 2014
@alexkravin
Contributor

It would be a good idea to insert "how to avoid" advice into violation message, but sure it's impossible to cover all cases, so Check has to put violation like (Condition inversion could be avoided.)

@alexkravin
Contributor

That should be done in: return, loops and if conditions, right?

@romani
Member
romani commented Sep 29, 2014

Message should be simple, do not propose solution.

Yes, loops, if , returns should be checked.

Beware that check might find some very debatable cases, please run it on big projects and try to make sure that code would become better after required changes (some additional options might be required)

@romani
Member
romani commented Nov 29, 2014

implemented by Alexey.

@romani romani closed this Nov 29, 2014
@rdiachenko
Member

if (! ((a>=8) && (b>=5)) ) ==should be==> if ((a<8) && (b<5))


return !(timeLoadMlls < maxMasterSymbolLoadStampMills
&& fileName.toLowerCase().contains(MASTER_SYMBOL_NAME_PART)
|| timeLoadMlls < maxOtherLoadStampMills
&& !fileName.toLowerCase().contains(MASTER_SYMBOL_NAME_PART));
==should be==>
return (timeLoadMlls >= maxMasterSymbolLoadStampMills
&& fileName.toLowerCase().contains(MASTER_SYMBOL_NAME_PART)
|| timeLoadMlls >= maxOtherLoadStampMills
&& !fileName.toLowerCase().contains(MASTER_SYMBOL_NAME_PART));

According to De Morgan's lows the resulted expressions should be as follows:

if (! ((a>=8) && (b>=5)) ) ==should be==> if ((a<8) || (b<5))

and

return !(timeLoadMlls < maxMasterSymbolLoadStampMills 
&& fileName.toLowerCase().contains(MASTER_SYMBOL_NAME_PART) 
|| timeLoadMlls < maxOtherLoadStampMills 
&& !fileName.toLowerCase().contains(MASTER_SYMBOL_NAME_PART));

==should be==>

return (timeLoadMlls >= maxMasterSymbolLoadStampMills 
|| !fileName.toLowerCase().contains(MASTER_SYMBOL_NAME_PART) 
&& timeLoadMlls >= maxOtherLoadStampMills 
|| fileName.toLowerCase().contains(MASTER_SYMBOL_NAME_PART));
@romani
Member
romani commented Jun 25, 2015

description was updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment