Linter ist ein scala statischer Analyse-Compiler-Plugin, das Kompilierungszeitprüfungen für verschiedene mögliche Fehler, Ineffizienzen und Stilprobleme hinzufügt.
Bitte unterstützen Sie die Entwicklung von Linter.
Fügen Sie Ihr Projekt zu Ihrem Projekt hinzu, indem Sie diese Zeile Ihrem build.sbt anhängen:
addCompilerPlugin("org.psywerx.hairyfotr" %% "linter" % "0.1.17")
Wenn Sie immer die neuesten Änderungen haben möchten, sind auch Schnappschüsse verfügbar:
resolvers += Resolver.sonatypeRepo("snapshots")
addCompilerPlugin("org.psywerx.hairyfotr" %% "linter" % "0.1-SNAPSHOT")
Fügen Sie Ihr Projekt zu einem Linter hinzu, indem Sie Ihren pom.xml mit einem "compilerplugin" -Abschnitt aktualisieren.
<configuration>
<compilerPlugins>
<compilerPlugin>
<groupId>org.psywerx.hairyfotr</groupId>
<artifactId>linter_2.11</artifactId>
<version>0.1.17</version>
</compilerPlugin>
</compilerPlugins>
</configuration>
Verwenden Sie Ihre übliche Gebäudemethode und das Jenkins Warnings -Plugin.
Eine weitere mögliche Möglichkeit zur Verwendung von Linter besteht darin, diese Snapshot -Gläser manuell herunterzuladen und zu verwenden:
Scala 2.12, Scala 2.11, Scala 2.10,
Scala 2.9.3 (veraltet)
terminal:
scalac -Xplugin:<path-to-linter-jar>.jar ...
sbt: (in build.sbt)
scalacOptions += "-Xplugin:<path-to-linter-jar>.jar"
maven: (in pom.xml inside scala-maven-plugin configuration)
<configuration>
<args>
<arg>-Xplugin:<path-to-linter-jar>.jar</arg>
</args>
</configuration>
Hinweis: Wenn Sie Anweisungen für ein anderes Build -Tool oder eine andere IDE haben, stellen Sie bitte eine Pull -Anfrage vor.
So deaktivieren Sie das Anzeigen von Überprüfungsnamen in der Ausgabe. Verwenden Sie den PrintWarningNames -Switch:
scalacOptions += "-P:linter:printWarningNames:false"
HINWEIS: SETTIGE SEITEN auf TRUE seit Version 0.1.17 auf TRUE
Überprüfungen können mithilfe einer Plus-getrennten Liste von Schecknamen deaktiviert werden:
scalacOptions += "-P:linter:disable:UseHypot+CloseSourceFile+OptionOfOption"
Oder nur bestimmte Überprüfungen können aktiviert werden:
scalacOptions += "-P:linter:enable-only:UseHypot+CloseSourceFile+OptionOfOption"
Wenn Sie glauben, dass einige Warnungen falsch positiv sind, können Sie sie mit einem Code -Kommentar ignorieren:
scala > val x = math.pow( 5 , 1 / 3d ) + 1 / 0 // linter:ignore UseCbrt,DivideByZero // ignores UseCbrt and DivideByZero
< console > : 8 : warning : Integer division detected in an expression assigned to a floating point variable.
math.pow( 5 , 1 / 3d ) + 1 / 0 // linter:ignore UseCbrt,DivideByZero // ignores UseCbrt and DivideByZero
^
scala > val x = math.pow( 5 , 1 / 3d ) + 1 / 0 // linter:ignore // ignores all warningsHINWEIS: Bitte überlegen Sie, ob sie falsch -positives Bestehen melden, damit sie in zukünftigen Versionen entfernt werden können.
UntendedSealedTrait, UntheyyElyEquality, Uselog1p, Uselog10, UseExpm1, Usehypot, Usecbrt, useqrt, musciousPow, useExp, useAwsnotsqrtSquare, nutzungskenner Reflexivease, ClossourceFile, Javaconverters, contentstypemismatch, numberInstanceof, mustermatchConstant, bevorzugungsobooleanmatch, identische CaseBodies, identische Konditions, ReflexiveComparison, Yodaconditions, UseconditionDirectly, verwenden Sie, unnötig, Dachungsvraktikum, unnötig, duplodititionsift, nutzen die Unnötigung, unnötig, duplodititionsiftly, nutze, nutze, unnötig, gulditions, dirtitions, directly, nutze, nutze, unnötig, gulditions, duplodition, nutze, nutze, nutze, unnötig, gulditions, dirtition, nutze, nutze, nutze, unnötig, gulditions, duploditionly, benutze die Identicalifelsecondition, mulgenestedifs, variableaSsignedUnusedValue, MalmaleformedSwap, Identicalifcondition, IdenticalStatements, Indexing mit UseOptionGetOrElse, UseExistsNotFindIsDefined, UseExistsNotFilterIsEmpty, UseFindNotFilterHead, UseContainsNotExistsEquals, UseQuantifierFuncNotFold, UseFuncNotReduce, UseFuncNotFold, MergeMaps, FuncFirstThenMap, FilterFirstThenSort, UseMinOrMaxNotSort, UseMapNotFlatMap, UseFilterNotFlatMap, AvoidOptionMethod, TransformNotMap, DuplicateKeyInMap, InefficientUseOfListSize, OnceEvaluatedStatementsInBlockReturningFunction, IntDivisionAssignedToFloat, UseFlattenNotFilterOption, UseCountNotFilterLength, UseExistsNotCountCompare, PasspartialfunktionDirekt, Unitimplicitordering, RegexWarning, InvarianteCondition, Dekomposierungemptykollektion, Invariantextrema, unnötiges Methodcall, produzieren InvalyParamtorandomNextint, unbenutzt LeerStringInterpolator, unwahrscheinlicher, unwirksam, verdächtige Matches, Passingnullintooption, Ifdowhile, FloatingPointnumericRange, UseInitnotreversetailReverse, Usetakerightnotreversetakeversevers, UselastnotReversehead, UseDrunntracnotreverse, Verwendung, Anwendung, Verwendung, Verwendung, Verwendung, Verwendung, Verwendung, Verwendung, Verwendung, Verwendung, Verwendung, Verwendung, verwendete, verwendete, verwendete, verwendete, verwendete, verwendete, verwendungsweiche, verwendete Uselastoptionnotif, usezipwithIndexnotzIpindices, useGetorElsenotpatMatch, UseOrElsenotpatMatch, UseoptionFlatMapnotpatMatch, UseoptionMapNotpatMatch, UseoptionFlatttennotpatMatchPatTeOptionForachNoTPatMatch, verwenden, verwenden, verwenden Sie, verwenden. UseoptionISemptyNOtpatMatch, UseoptionForAllnotpatMatch, UseoptionExistsNotpatMatch
Die obigen Links finden Sie derzeit zum Test für diesen Scheck.
Eine andere Datei zum Auschecken ist Warnung.scala
scala > if (a == 10 || b == 10 ) 0 else if (a == 20 && b == 10 ) 1 else 2
< console > : 10 : warning : This condition has appeared earlier in the if - else chain and will never hold here.
if (a == 10 || b == 10 ) 0 else if (a == 20 && b == 10 ) 1 else 2
^ scala > if (b > 4 ) ( 2 ,a) else ( 2 ,a)
< console > : 9 : warning : If statement branches have the same structure.
if (b > 4 ) ( 2 ,a) else ( 2 ,a)
^ scala > if (a == b) true else false
< console > : 9 : warning : Remove the if expression and use the condition directly.
if (a == b) true else false
^scala > (x,y) match { case (a, 5 ) if a > 5 => 0 case (c, 5 ) if c > 5 => 1 }
< console > : 10 : warning : Identical case condition detected above. This case will never match .
(x,y) match { case (a, 5 ) if a > 5 => 0 case (c, 5 ) if c > 5 => 1 }
^ scala > a match { case 3 => " hello " case 4 => " hello " case 5 => " hello " case _ => " how low " }
< console > : 9 : warning : Bodies of 3 neighbouring cases are identical and could be merged.
a match { case 3 => " hello " case 4 => " hello " case 5 => " hello " case _ => " how low " }
^ scala > bool match { case true => 0 case false => 1 }
< console > : 9 : warning : Pattern matching on Boolean is probably better written as an if statement.
a match { case true => 0 case false => 1 }
^scala > for (i <- 10 to 20 ) { if (i > 20 ) " " }
< console > : 8 : warning : This condition will never hold.
for (i <- 10 to 20 ) { if (i > 20 ) " " }
^ scala > for (i <- 1 to 10 ) { 1 / (i - 1 ) }
< console > : 8 : warning : You will likely divide by zero here.
for (i <- 1 to 10 ) { 1 / (i - 1 ) }
^ scala > { val a = List ( 1 , 2 , 3 ); for (i <- 1 to 10 ) { println(a(i)) } }
< console > : 8 : warning : You will likely use a too large index.
{ val a = List ( 1 , 2 , 3 ); for (i <- 1 to 10 ) { println(a(i)) } }
^scala > for (i <- 10 to 20 ) { if (i.toString.length == 3 ) " " }
< console > : 8 : warning : This condition will never hold.
for (i <- 10 to 20 ) { if (i.toString.length == 3 ) " " }
^ scala > { val a = " hello " + util. Random .nextString( 10 ) + " world " + util. Random .nextString( 10 ) + " ! " ; if (a contains " world " ) " " ; if (a startsWith " hell " ) " " }
< console > : 8 : warning : This contains will always returns the same value : true
{ val a = " hello " + util. Random .nextString( 10 ) + " world " + util. Random .nextString( 10 ) + " ! " ; if (a contains " world " ) " " ; if (a startsWith " hell " ) " " }
^
< console > : 8 : warning : This startsWith always returns the same value : true
{ val a = " hello " + util. Random .nextString( 10 ) + " world " + util. Random .nextString( 10 ) + " ! " ; if (a contains " world " ) " " ; if (a startsWith " hell " ) " " }
^ scala > str.replaceAll( " ? " , " . " )
< console > : 9 : warning : Regex pattern syntax error : Dangling meta character '?'
str.replaceAll( " ? " , " . " )
^log(1 + a) anstelle von log1p(a) scala > math.log( 1d + a)
< console > : 9 : warning : Use math.log1p(x), instead of math.log( 1 + x) for added accuracy when x is near 0 .
math.log( 1 + a)
^ scala > BigDecimal ( 0.555555555555555555555555555 )
< console > : 8 : warning : Possible loss of precision. Literal cannot be represented exactly by Double . ( 0.555555555555555555555555555 != 0.5555555555555556 )
BigDecimal ( 0.555555555555555555555555555 )
^scala > val a = Some ( List ( 1 , 2 , 3 )); if (a.size > 3 ) " "
< console > : 9 : warning : Did you mean to take the size of the collection inside the Option ?
if (a.size > 3 ) " "
^ scala > if (strOption.isDefined) strOption.get else " "
< console > : 9 : warning : Use strOption.getOrElse(...) instead of if (strOption.isDefined) strOption.get else ...
if (strOption.isDefined) strOption.get else " "
^scala > List ( 1 , 2 , 3 , 4 ).find(x => x % 2 == 0 ).isDefined
< console > : 8 : warning : Use col.exists(...) instead of col.find(...).isDefined.
List ( 1 , 2 , 3 , 4 ).find(x => x % 2 == 0 ).isDefined
^ scala > List ( 1 , 2 , 3 , 4 ).flatMap(x => if (x % 2 == 0 ) List (x) else Nil )
< console > : 8 : warning : Use col.filter(x => condition) instead of col.flatMap(x => if (condition) ... else ...).
List ( 1 , 2 , 3 , 4 ).flatMap(x => if (x % 2 == 0 ) List (x) else Nil )
^scala > def func ( b : Int , c : String , d : String ) = { println(b); b + c }
< console > : 7 : warning : Parameter d is not used in method func
def func ( b : Int , c : String , d : String ) = { println(b); b + c }
^ contains scala > List ( 1 , 2 , 3 ).contains( " 4 " )
< console > : 29 : warning : List [ Int ].contains( String ) will probably return false , since the collection and target element are of unrelated types.
List ( 1 , 2 , 3 ).contains( " 4 " )
^ == scala > Nil == None
< console > : 29 : warning : Comparing with == on instances of unrelated types (scala.collection.immutable. Nil . type , None . type ) will probably return false .
Nil == None
^ Fühlen Sie sich frei, Ihre eigenen Ideen hinzuzufügen oder diese zu implementieren. Anfragen willkommen!
var a = 4; { val a = 5 } )func("arg1", force = true) )Regellisten aus anderen statischen Analysetools: