Linterは、さまざまなバグ、非効率性、およびスタイルの問題についてコンパイル時間チェックを追加するScala静的分析コンパイラプラグインです。
Linterの開発をサポートしてください。
このラインをbuild.sbtに追加して、リナーをプロジェクトに追加します。
addCompilerPlugin("org.psywerx.hairyfotr" %% "linter" % "0.1.17")
常に最新の変更が必要な場合は、スナップショットも利用できます。
resolvers += Resolver.sonatypeRepo("snapshots")
addCompilerPlugin("org.psywerx.hairyfotr" %% "linter" % "0.1-SNAPSHOT")
「CompilerPlugin」セクションでpom.xml更新して、プロジェクトにリナーを追加します。
<configuration>
<compilerPlugins>
<compilerPlugin>
<groupId>org.psywerx.hairyfotr</groupId>
<artifactId>linter_2.11</artifactId>
<version>0.1.17</version>
</compilerPlugin>
</compilerPlugins>
</configuration>
通常の構築方法とJenkins警告プラグインを使用します。
リンジターを使用する別の可能な方法は、これらのスナップショットジャーを手動でダウンロードして使用することです。
Scala 2.12、Scala 2.11、Scala 2.10、
Scala 2.9.3(時代遅れ)
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>
注:別のビルドツールまたはIDEの指示がある場合は、プルリクエストをお願いします。
出力にチェック名を表示することを無効にするには、printWarningNamesスイッチを使用します。
scalacOptions += "-P:linter:printWarningNames:false"
注:バージョン0.1.17以降、デフォルトでtrueに設定します
小切手名のプラス分離リストを使用して、小切手を無効にすることができます。
scalacOptions += "-P:linter:disable:UseHypot+CloseSourceFile+OptionOfOption"
または、以下を使用して特定のチェックのみを有効にすることができます。
scalacOptions += "-P:linter:enable-only:UseHypot+CloseSourceFile+OptionOfOption"
いくつかの警告が誤検知であると思われる場合は、コードコメントでそれらを無視できます。
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 warnings注:将来のバージョンで削除できるように、誤検知を報告することを検討してください。
UnextendedSealeDtrait、equality、uselog1p、uselog10、useexpm1、usehypot、usecbrt、usesqrt、suspiouspow、useabsnotsqrtsquare、useisnannotselfcomparison、useisnannotnancomparison、usesignum、bigdedecimalnummat、useisnannonnannotnancomparison、 ReplexiveasSignment、closeSourceFile、Javaconverters、Cantaint -femismatch、numberStanceof、patternMatchConstant、forticalcasebodies、同一の測定、reflexiveComparsison、Yodacontitions、ecodhingditiondirectly、usexpression、us unreefspressiondirectly、同一フェルセクション、mergenestedifs、variableassignedunusedValue、不正行為、同一の条件、同一の測定、nedingwithnegativenumber、option ofofoption、assigingoptiontonull、wrapnullwithoption、回避、回避、回避、回避、回避、回避、 useoptionorornull、useoptiongetorelse、useexistsnotfindisdisdidised、useexistnotfilterisempty、usefindnotfilterhead、usecontainsnotexist sevesals、usequantifierfuncnotfold、usefuncnotreduce、usefuncnotfold、mergemaps、filtfuncnottthap、filtfuncnottthap、fildfuncnottthe、usefuncnotfold useminormaxnotsort、usemapnotflatmap、usefilternotflatmap、risnoptionmethod、transformnotmap、duplicatekeyinmap、非効率化と測定値、blockreturningfunction、intdivision -assignedtofloat、useflattendotfilteroption、usecuntfilteroptuntnottoftotunt、 useexistsnotcountCompare、passpartialFunction -directly、unitimplicitorderding、regexwarning、invariantCondition、Decomposemptemptycollection、invariantextrema、nubersarymethodcall、生成、生成、運用道路生成、ゼロ、ディビエーション、ディバイドバイオン、 useuntilnottominusone、invalidparamtorandomnextint、Unsed forloopiteratorValue、stringmultipationbynonsofundive、unnediveraryturn、invariantreturn、unushstringformat、invalidstringformat、validstringconversion、unnnedarystringnemptysy、nusestringnemptysythy、unsedstringformat、unsedstringparamat可能性のある抑制、UNSAFEABS、TypeTotype、emptyStringInterpolator、無効化、未脱出、不審なマッチ、パスンロントプチオン、ifdowhile、floatingpointnumerrange、useinitnotreversetailreverse、usetakerightnotreverse、uselastreverse、useLastreverse、useTakerightnotreverse、 useheadnotapply、uselastnotapply、useheadoptionnotif、uselastoptionnotif、usezipwithindexnotzipindices、usegetorelseNotpatmatch、suseorelsenotpatmatch、useoptionflatmapnotpatmatch、useopnotpatmatch、useoptionflattpatpatmatch useoptionforeachnotpatmatch、useoptionisisdefinednotpatmatch、useoptionisemptynotpatmatch、useoptionforallnotpatmatch、useoptionexistsistnotpatmatch
上記のリンクは現在、そのチェックのテストに移動します。
チェックアウトする別のファイルはWarning.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( " ? " , " . " )
^log1p(a)の代わりにlog(1 + 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
^ 自分のアイデアを自由に追加するか、これらを実装してください。リクエストをプル歓迎!
var a = 4; { val a = 5 } )func("arg1", force = true) )他の静的分析ツールのルールリスト: