service
service copied to clipboard
Not elegant code shall not pass! ⚔️🧙♂️
Youshallnotpass
What is it?
Youshallnotpass is the static analyser for your elegant code.
How it works?
Just see, what it can find in seemingly usual code:
package com.example;
import java.util.Collection;
import java.util.StringTokenizer;
public class Words {
public static final String DELIM = " ,.";
private Collection<String> words;
public Words() {
this.words = null;
}
public Words(Collection<String> words) {
this.words = words;
}
boolean containsIn(String text) {
if (words == null) return false;
StringTokenizer tokenizer = new StringTokenizer(text, DELIM);
while (tokenizer.hasMoreTokens()) {
String nextWord = tokenizer.nextToken();
if (words.contains(nextWord)) return true;
}
return false;
}
}
The violations of the youshallnotpass analysis:
nullfree
com.example.Words(Words.java:12) > null
com.example.Words.containsIn(Words.java:20) > null
staticfree
com.example.A.main(A.java:6) > static
com.example.Words(Words.java:7) > static
allfinal
com.example.A.main(A.java:6) > String[] args
com.example.A(A.java:5) > A
com.example.Words(Words.java:9) > words
com.example.Words.containsIn(Words.java:22) > StringTokenizer tokenizer = new StringTokenizer(text, DELIM)
com.example.Words.containsIn(Words.java:24) > String nextWord = tokenizer.nextToken()
com.example.Words(Words.java:15) > Collection<String> words
com.example.Words.containsIn(Words.java:19) > String text
com.example.Words(Words.java:6) > Words
allpublic
com.example.Words.containsIn(Words.java:19)
nomultiplereturn
com.example.Words.containsIn(Words.java:19)
Get started
Gradle
Add the plugin to the root build.gradle
plugins {
id 'dev.youshallnotpass' version 'x.y.z'
}
// then configure it, if you need:
youshallnotpass {
offline = true // default false
nullfree {
disabled = true // default false
threshold = 3 // default 0
skipComparisons = true // default false
}
staticfree {
disabled = true // default false
threshold = 2 // default 0
}
allfinal {
disabled = true // default false
threshold = 1 // default 0
skipInterfaceMethodParams = false // default true
skipLambdaParams = true // default false
skipCatchParams = true // default false
}
allpublic {
disabled = true // default false
threshold = 4 // default 0
}
setterfree {
disabled = true // default false
threshold = 5 // default 0
}
nomultiplereturn {
disabled = true // default false
threshold = 6 // default 0
}
inheritancefree {
disabled = true // default false
threshold = 7 // default 0
}
}
Where x.y.z
is actual version from gradle plugins
Invoke it:
./gradlew youshallnotpass
Maven
Add the plugin to the pom.xml
<plugin>
<groupId>dev.youshallnotpass</groupId>
<artifactId>youshallnotpass-maven-plugin</artifactId>
<version>x.y.z</version>
<!-- then configure it, if you need: -->
<configuration>
<offline>true</offline><!-- default false -->
<nullfree>
<disabled>true</disabled><!-- default false -->
<threshold>3</threshold><!-- default 0 -->
<skipComparisons>true</skipComparisons><!-- default false -->
</nullfree>
<staticfree>
<disabled>true</disabled><!-- default false -->
<threshold>2</threshold><!-- default 0 -->
</staticfree>
<allfinal>
<disabled>true</disabled><!-- default false -->
<threshold>1</threshold><!-- default 0 -->
<skipInterfaceMethodParams>false</skipInterfaceMethodParams><!-- default true -->
<skipLambdaParams>true</skipLambdaParams><!-- default false -->
<skipCatchParams>true</skipCatchParams><!-- default false -->
</allfinal>
<allpublic>
<disabled>true</disabled><!-- default false -->
<threshold>4</threshold><!-- default 0 -->
</allpublic>
<setterfree>
<disabled>true</disabled><!-- default false -->
<threshold>5</threshold><!-- default 0 -->
</setterfree>
<nomultiplereturn>
<disabled>true</disabled><!-- default false -->
<threshold>6</threshold><!-- default 0 -->
</nomultiplereturn>
<inheritancefree>
<disabled>true</disabled><!-- default false -->
<threshold>7</threshold><!-- default 0 -->
</inheritancefree>
</configuration>
</plugin>
Invoke it:
mvn youshallnotpass:youshallnotpass
Where x.y.z
is actual version from maven central
Inspections
-
✅ NullFree (Why
null
is bad?) elegant code must not use thenull
keywords -
✅ StaticFree (Why
static
is bad?) elegant code must not use thestatic
keywords -
✅ AllFinal every class, every field, every argument, every local variable must be
final
in the elegant code -
🔄 instanceoffree
[in progress]
elegant code must not use theinstanceof
keywords -
✅ inheritancefree elegant code must not use the class inheritance (when one class
extends
another one), only composition and type inheritance has been allowed -
🔄 enumfree
[in progress]
elegant code must not use theenum
s -
🔄 switchfree
[in progress]
elegant code must not use theswitch
blocks/expressions -
✅ NoMultipleReturn elegant code must contain only one (or no one) return in an any method
-
🔄 getterfree
[in progress]
elegant code must not contain any getters -
✅ SetterFree elegant code must not contain any setters
-
✅ AllPublic elegant code must use only
public
methods -
🔄 nopublicmethodnotoverrides
[in progress]
every public method in the elegant code must be overrided from an interface
NullFree
Plugin configuration options:
-
skipComparisons
allows usenull
in boolean expressions:
if (some == null) {
...
}
Can be suppressed in the code by @SuppressWarnings("nullfree")
StaticFree
Can be suppressed in the code by @SuppressWarnings("staticfree")
AllFinal
Plugin configuration options:
-
skipInterfaceMethodParams
allows restricting or not interface method parameterfinal
s, by default there is no needed to setfinal
for such places -
skipLambdaParams
allows skipfinal
in lambda parameters, by default lambda parameter needs to befinal
-
skipCatchParams
allows skipfinal
incatch
parameters, by defaultcatch
parameter needs to befinal
Can be suppressed in the code by @SuppressWarnings("allfinal")
AllPublic
Can be suppressed in the code by @SuppressWarnings("allpublic")
SetterFree
Can be suppressed in the code by @SuppressWarnings("setterfree")
NoMultipleReturn
Can be suppressed in the code by @SuppressWarnings("nomultiplereturn")
InheritanceFree
Can be suppressed in the code by @SuppressWarnings("inheritancefree")
Badges
If you use youshallnotpass plugin without offline = true
settings, then you
can attach the inspection badges to your readme file:
-
![nullfree status](https://youshallnotpass.dev/nullfree/<user>/<repo>)
-
![staticfree status](https://youshallnotpass.dev/staticfree/<user>/<repo>)
-
![allfinal status](https://youshallnotpass.dev/allfinal/<user>/<repo>)
-
![allpublic status](https://youshallnotpass.dev/allpublic/<user>/<repo>)
-
![setterfree status](https://youshallnotpass.dev/setterfree/<user>/<repo>)
-
![nomultiplereturn status](https://youshallnotpass.dev/nomultiplereturn/<user>/<repo>)
-
![inheritancefree status](https://youshallnotpass.dev/inheritancefree/<user>/<repo>)
Inspection threshold
Any inspection can be configured with threshold
:
In gradle
youshallnotpass {
...
staticfree {
threshold = 19
}
...
}
In maven
<configuration>
<staticfree>
<threshold>19</threshold>
</staticfree>
</configuration>
Disabling inspections
Any inspection can be disabled by disabled
settings:
In gradle
youshallnotpass {
...
staticfree {
disabled = true
}
...
}
In maven
<configuration>
<staticfree>
<disabled>true</disabled>
</staticfree>
</configuration>
All inspections are enabled by default.
Excluding files from inspects
There is global exclude
settings, which can be used for defining exclude
patterns:
In gradle
youshallnotpass {
exclude = ["glob:**/test/**/*Test.java"]
}
In maven
<configuration>
<exclude>glob:**/test/**/*Test.java</exclude>
</configuration>
There is inspection local exclude configuration option, which has higher priority than global exclude configuration:
In gradle
nullfree {
exclude = ["glob:**/*SomeBadFile.java"]
}
In maven
<nullfree>
<exclude>glob:**/*SomeBadFile.java</exclude>
</nullfree>