Code Monkey home page Code Monkey logo

scapegoat's People

Contributors

avdv avatar dbronecki avatar dependabot[bot] avatar erdeszt avatar eugene-sy avatar fabianschmitthenner avatar gregsymons avatar hairyfotr avatar hugocodacy avatar ikr0m avatar johnnei avatar joshrosen avatar joshrosen-stripe avatar jozic avatar jyoo980 avatar lespea avatar lolgab avatar marconilanna avatar mccartney avatar mwz avatar paulp avatar richardbradley avatar rtfpessoa avatar saeltz avatar scala-steward avatar sksamuel avatar ssanj avatar tafit3 avatar vdichev avatar zgrannan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

scapegoat's Issues

False positive on Set.empty

Related to #19

    scalaCompilerJar,
    scalaReflectJar,
    scalaLibraryJar).flatten

Is reporting as a use (ensime, ProjectConfig.scala:751)

Set[T]() creates a new instance. Consider Set.empty which does not allocate a new object. scala.this.Predef.Set.apply[Option[org.ensime.util.CanonFile]]``

Feedback on first use

I tried scapegoat on our large Scala codebase.

Here is what I found:

  • "asInstanceOf" - inappropriate warning when used deliberately

We use this in a few places, e.g.

In one place we dive into the Akka internals in order to do some reporting that Akka doesn't offer:

  def examineAllActors(system: ActorSystem): ActorStats = {
    ...
    walk(system.asInstanceOf[ActorSystemImpl].lookupRoot)
  }

The warning here is just "asInstanceOf used near ... Consider using collect.", which doesn't quite make sense.

Perhaps there just needs to be an option to suppress warnings?

  • "asInstanceOf" - false warning from actor Receive

The following actor Receive method triggers this warning:

  def receive: Receive = LoggingReceive {
    case requestStart: ChunkedRequestStart =>
      // start by establishing a new HTTP connection
      val host = requestStart.request.uri.authority.host.address
      val port = requestStart.request.uri.authority.port

      ioActor ! Http.Connect(host, port)
      owner = sender()
      context.become(connecting(requestStart))
  }

This seems to happen on many of our receive blocks.

  • Use of Option.get

We use this in a few places, and it is flagged as an error by scapegoat.
The warning doesn't offer any justification for a blanket ban on this feature, nor any suggestions on alternatives.
Much of our use of "option.get" is in stateful actors.

  • Use of var, use of null, use of return

Again, no justifications are given for a blanket ban on these features, nor any suggestions on alternatives.

  • Use of java conversions

What's wrong with Java conversions?
Again, no justification is given for a blanket ban on this feature, nor any suggestions on alternatives.

  • Unused method parameter

This is generally a good one. We have some false positives where the param is required to implement an interface, but not used by all implementors.

  • Unused method parameter - false positive when macros are used

We have some macro use, and every param is flagged as "unused", even though they are all used.

  • Use of var -- false positive in XML literals

Code like this:

 <xml>{myVariable}</xml>

Generates "var used: var $tmpscope: scala.xml.NamespaceBinding = $scope"

  • Unused method parameter - false positive on abstract method

We have an abstract method:

  def xml(sessionId: Option[String]): Elem

which generates "Unused method parameter (val sessionId: Option[String] = _) at xml"

  • Report format

The report is pretty and easy to read, but it's static. There is no way to sort or filter. The Findbugs report viewer is more fully featured in this respect.

  • Override warnings

Is there any way to explicit override a warning, e.g. with a code comment?

Generally this looks good. I think it might be more effective to make Findbugs scala-friendly though. I'll reply to your other email.

Improvement: Improve message on duplicate case

Warning Repeated case body com.sksamuel.scapegoat.inspections.matching.RepeatedCaseBody
x0$1 match { case '\n' => ' ' case '\r' => ' ' case (c @ _) => c }

The rule is good, but needs a description (ie. that two cases have the same result code).

Compiler crash -> head of empty list

Running this against some auto-genned code from scalaxb I got this stack trace (sorry for the lenght). Compiling without the "experimental" compiler options (ie genbcode / closure elim / const-opt & delamdafy) still caused the exception. I also completely removed HairyFotr's linter (even though it's disabled in this sub-project) which also caused no change.

Compile options:
[debug] Calling Scala compiler with arguments  (CompilerInterface):
[debug]         -encoding
[debug]         utf8
[debug]         -language:implicitConversions
[debug]         -target:jvm-1.7
[debug]         -Ybackend:GenBCode
[debug]         -Yclosure-elim
[debug]         -Yconst-opt
[debug]         -Ydelambdafy:method
[debug]         -language:_
[debug]         -Xplugin-disable:linter
[debug]         -Xplugin:/.../linter_2.11-0.1-SNAPSHOT.jar
[debug]         -Xplugin:/.../scalac-scapegoat-plugin_2.11-0.90.5.jar
[debug]         -P:scapegoat:dataDir:/.../target/scala-2.11/scapegoat-report
[debug]         -P:scapegoat:disabledInspections:
Stack trace
java.util.NoSuchElementException: head of empty list
    at scala.collection.immutable.Nil$.head(List.scala:420)
    at scala.collection.immutable.Nil$.head(List.scala:417)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.inspect(UnsafeContains.scala:16)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.traverse(Inspection.scala:58)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at scala.reflect.api.Trees$Traverser.traverseGuard(Trees.scala:2477)
    at scala.reflect.internal.Trees$class.traverseComponents$1(Trees.scala:1231)
    at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1323)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.com$sksamuel$scapegoat$InspectionContext$Traverser$$super$traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.continue(Inspection.scala:48)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.continue(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.inspect(UnsafeContains.scala:19)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.traverse(Inspection.scala:58)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at scala.reflect.api.Trees$Traverser.traverseTrees(Trees.scala:2484)
    at scala.reflect.api.Trees$Traverser.traverseCases(Trees.scala:2487)
    at scala.reflect.internal.Trees$class.traverseComponents$1(Trees.scala:1258)
    at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1323)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.com$sksamuel$scapegoat$InspectionContext$Traverser$$super$traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.continue(Inspection.scala:48)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.continue(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.inspect(UnsafeContains.scala:19)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.traverse(Inspection.scala:58)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at scala.reflect.internal.Trees$$anonfun$itraverse$1.apply$mcV$sp(Trees.scala:1322)
    at scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2507)
    at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1322)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.com$sksamuel$scapegoat$InspectionContext$Traverser$$super$traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.continue(Inspection.scala:48)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.continue(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.inspect(UnsafeContains.scala:19)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.traverse(Inspection.scala:58)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at scala.reflect.api.Trees$Traverser.traverseTrees(Trees.scala:2484)
    at scala.reflect.internal.Trees$class.traverseComponents$1(Trees.scala:1277)
    at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1323)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.com$sksamuel$scapegoat$InspectionContext$Traverser$$super$traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.continue(Inspection.scala:48)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.continue(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.inspect(UnsafeContains.scala:19)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.traverse(Inspection.scala:58)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at scala.reflect.internal.Trees$class.traverseComponents$1(Trees.scala:1276)
    at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1323)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.com$sksamuel$scapegoat$InspectionContext$Traverser$$super$traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.continue(Inspection.scala:48)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.continue(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.inspect(UnsafeContains.scala:19)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.traverse(Inspection.scala:58)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at scala.reflect.internal.Trees$$anonfun$traverseMemberDef$1$1.apply$mcV$sp(Trees.scala:1202)
    at scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2507)
    at scala.reflect.internal.Trees$class.traverseMemberDef$1(Trees.scala:1196)
    at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1321)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.com$sksamuel$scapegoat$InspectionContext$Traverser$$super$traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.continue(Inspection.scala:48)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.continue(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.inspect(UnsafeContains.scala:19)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.traverse(Inspection.scala:58)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at scala.reflect.api.Trees$Traverser.traverseTrees(Trees.scala:2484)
    at scala.reflect.internal.Trees$class.traverseComponents$1(Trees.scala:1227)
    at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1323)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.com$sksamuel$scapegoat$InspectionContext$Traverser$$super$traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.continue(Inspection.scala:48)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.continue(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.inspect(UnsafeContains.scala:19)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.traverse(Inspection.scala:58)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at scala.reflect.internal.Trees$$anonfun$traverseMemberDef$1$1.apply$mcV$sp(Trees.scala:1208)
    at scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2507)
    at scala.reflect.internal.Trees$class.traverseMemberDef$1(Trees.scala:1196)
    at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1321)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.com$sksamuel$scapegoat$InspectionContext$Traverser$$super$traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.continue(Inspection.scala:48)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.continue(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.inspect(UnsafeContains.scala:19)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.traverse(Inspection.scala:58)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at scala.reflect.api.Trees$Traverser$$anonfun$traverseStats$1$$anonfun$apply$1.apply$mcV$sp(Trees.scala:2498)
    at scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2507)
    at scala.reflect.api.Trees$Traverser.traverseStats(Trees.scala:2497)
    at scala.reflect.internal.Trees$class.traverseComponents$1(Trees.scala:1225)
    at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1323)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.com$sksamuel$scapegoat$InspectionContext$Traverser$$super$traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.continue(Inspection.scala:48)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.continue(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.inspect(UnsafeContains.scala:19)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.traverse(Inspection.scala:58)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at scala.reflect.internal.Trees$$anonfun$traverseMemberDef$1$1.apply$mcV$sp(Trees.scala:1201)
    at scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2507)
    at scala.reflect.internal.Trees$class.traverseMemberDef$1(Trees.scala:1196)
    at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1320)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.com$sksamuel$scapegoat$InspectionContext$Traverser$$super$traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.continue(Inspection.scala:48)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.continue(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.inspect(UnsafeContains.scala:19)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.traverse(Inspection.scala:58)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at scala.reflect.api.Trees$Traverser$$anonfun$traverseStats$1$$anonfun$apply$1.apply$mcV$sp(Trees.scala:2498)
    at scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2507)
    at scala.reflect.api.Trees$Traverser.traverseStats(Trees.scala:2497)
    at scala.reflect.internal.Trees$class.itraverse(Trees.scala:1319)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:16)
    at scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2475)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.com$sksamuel$scapegoat$InspectionContext$Traverser$$super$traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.continue(Inspection.scala:48)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.continue(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.inspect(UnsafeContains.scala:19)
    at com.sksamuel.scapegoat.InspectionContext$Traverser$class.traverse(Inspection.scala:58)
    at com.sksamuel.scapegoat.inspections.collections.UnsafeContains$$anon$2$$anon$1.traverse(UnsafeContains.scala:9)
    at com.sksamuel.scapegoat.ScapegoatComponent$Transformer$$anonfun$transform$1.apply(plugin.scala:84)
    at com.sksamuel.scapegoat.ScapegoatComponent$Transformer$$anonfun$transform$1.apply(plugin.scala:82)
    at scala.collection.immutable.List.foreach(List.scala:381)
    at com.sksamuel.scapegoat.ScapegoatComponent$Transformer.transform(plugin.scala:82)
    at com.sksamuel.scapegoat.ScapegoatComponent$Transformer.transform(plugin.scala:78)
    at scala.tools.nsc.ast.Trees$Transformer.transformUnit(Trees.scala:147)
    at scala.tools.nsc.transform.Transform$Phase.apply(Transform.scala:30)
    at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:410)
    at scala.tools.nsc.Global$GlobalPhase$$anonfun$run$1.apply(Global.scala:377)
    at scala.tools.nsc.Global$GlobalPhase$$anonfun$run$1.apply(Global.scala:377)
    at scala.collection.Iterator$class.foreach(Iterator.scala:743)
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1177)
    at scala.tools.nsc.Global$GlobalPhase.run(Global.scala:377)
    at com.sksamuel.scapegoat.ScapegoatComponent$$anon$1.run(plugin.scala:62)
    at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1557)
    at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1542)
    at scala.tools.nsc.Global$Run.compileSources(Global.scala:1537)
    at scala.tools.nsc.Global$Run.compile(Global.scala:1644)
    at xsbt.CachedCompiler0.run(CompilerInterface.scala:123)
    at xsbt.CachedCompiler0.run(CompilerInterface.scala:99)
    at xsbt.CompilerInterface.run(CompilerInterface.scala:27)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:102)
    at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:48)
    at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:41)
    at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply$mcV$sp(AggressiveCompile.scala:99)
    at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply(AggressiveCompile.scala:99)
    at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply(AggressiveCompile.scala:99)
    at sbt.compiler.AggressiveCompile.sbt$compiler$AggressiveCompile$$timed(AggressiveCompile.scala:166)
    at sbt.compiler.AggressiveCompile$$anonfun$3.compileScala$1(AggressiveCompile.scala:98)
    at sbt.compiler.AggressiveCompile$$anonfun$3.apply(AggressiveCompile.scala:143)
    at sbt.compiler.AggressiveCompile$$anonfun$3.apply(AggressiveCompile.scala:87)
    at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:39)
    at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:37)
    at sbt.inc.IncrementalCommon.cycle(Incremental.scala:99)
    at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:38)
    at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:37)
    at sbt.inc.Incremental$.manageClassfiles(Incremental.scala:65)
    at sbt.inc.Incremental$.compile(Incremental.scala:37)
    at sbt.inc.IncrementalCompile$.apply(Compile.scala:27)
    at sbt.compiler.AggressiveCompile.compile2(AggressiveCompile.scala:157)
    at sbt.compiler.AggressiveCompile.compile1(AggressiveCompile.scala:71)
    at sbt.compiler.AggressiveCompile.apply(AggressiveCompile.scala:46)
    at sbt.Compiler$.apply(Compiler.scala:75)
    at sbt.Compiler$.apply(Compiler.scala:66)
    at sbt.Defaults$.sbt$Defaults$$compileTaskImpl(Defaults.scala:770)
    at sbt.Defaults$$anonfun$compileTask$1.apply(Defaults.scala:762)
    at sbt.Defaults$$anonfun$compileTask$1.apply(Defaults.scala:762)
    at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
    at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:42)
    at sbt.std.Transform$$anon$4.work(System.scala:64)
    at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237)
    at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237)
    at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:18)
    at sbt.Execute.work(Execute.scala:244)
    at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237)
    at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237)
    at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:160)
    at sbt.CompletionService$$anon$2.call(CompletionService.scala:30)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Enhancement: unused public methods

For standalone projects (i.e. not libraries), unused public methods are a nuisance that can be hard to track down.

Possibly scapegoat could detect these and warn?

The difficulty with this inspection is that it is completely inapplicable to many projects (i.e. those intended as libraries).

False positive: duplicate case class (0.90.10)

    val nonNil = items.filter {
      case (s, NilAtom) => false
      case (s, SExpList(items)) if items.isEmpty => false
      case _ => true
    }

Is reporting the first two cases as duplicate

    result match {
      case Success(value, next) => value
      case Failure(errMsg, next) =>
        println(errMsg)
        NilAtom
      case Error(errMsg, next) =>
        println(errMsg)
        NilAtom
    }

As far as I understand these matches cannot be combined (i.e you cant do Failure(s,n) | Error(s,n) as you lose the ability to access s.

False positive: ClassNames 0.90.13

Info Class name not recommended com.sksamuel.scapegoat.inspections.naming.ClassNames
Class names should begin with uppercase letter (bad = $anon)

reported on an anonymous class:

        classReader.accept(new ClassVisitor(Opcodes.ASM5) {
          override def visitSource(source: String, debug: String) {
  ....

False positive: AvoidOperatorOverload reporting (0.90.11)

I thought I was doing well getting the warnings down,then up updated to 0.90.11 ;) )

I've got a lot (>100) AvoidOperatorOverload warnings all over the code, in really odd places such as:

case class CallCompletionReq(id: Int)
case class TypeAtPointReq(file: File, range: OffsetRange)

reports the first line once and the second line twice.

Null use should be okay for comparisons

There are many times when you need to check if something is null (either with a direct comparison or through a match statement), especially when dealing with Java. This should not throw a warning.

Absolute path generates broken links

Absolute links for right side navigation (class links) are broken.

I generate coverage on virtual machine and when viewing reports on host machine left side package links are pointing to href="com/package.html"

class links on right side are pointing to href="/mnt/scala/project/project-common/target/scala-2.10/scoverage-report/com/ApplicationConfig.scala.html"

False positive on Seq.empty

Seq(file) (ensime, FileUtil.scala:56)
or
Seq(AbstractFile.getFile(f)) (ensime, FileUtil.scala:110)

reports

Info Prefer Seq.empty com.sksamuel.scapegoat.inspections.collections.PreferSeqEmpty Seq[T]() creates a new instance. Consider Set.empty which does not allocate a new object. scala.collection.Seq.apply[java.io.File]

I guess its thinking that Seq.apply(x) is Seq.apply()

XML var use

Reported by @RichardBradley

Code like this:

 <xml>{myVariable}</xml>

Generates "var used: var $tmpscope: scala.xml.NamespaceBinding = $scope"

PointlessTypeBounds - false positive if multiple parameters

If a class/def has multiple type parameters, one being "empty" and one containing a bound then this check incorrectly flags it. An example:

trait TestTrait
class Test1[A, B <: TestTrait]() {}  // Throws warning
class Test2[B <: TestTrait]() {}     // Works fine

Incorrect Set.empty report

Last one for tonight, and a weird one:

Set[T]() creates a new instance. Consider Set.empty which does not allocate a new object. scala.this.Predef.Set.apply[String]

On ensime Server.scala:25 ->


  private val blacklist = Set("sun.", "java.", "scala.Console", "scala.Predef")

Enhancement: matching on type literals where unapply was meant

In some cases, particularly no-arg case classes, it is possible to create match blocks that look for type literals when an unapply matcher was intended.

Perhaps scapegoat could detect this and warn?

e.g.

case class Deletion()

class DeletorActor extends Actor {
  override def receive = {
    case Deletion => 
      println("this is never hit, as it looks for people sending us classOf[Deletion]")
  }
}

Bug: MaxParameters message is broken (0.90.13)

The message output on MaxParameters is broken.

Info Max parameters com.sksamuel.scapegoat.inspections.MaxParameters
Method $name has ${vparams.size} parameters. Consider refactoring to a containing instance.

I believe you have forgotten an 's' .

False positive: 0.90.13

This has been there in there since at least the previous version.

Warning Zero numerator com.sksamuel.scapegoat.inspections.math.ZeroNumerator
Dividing zero by any number will always return zero

reports on:

      state.getBoost * (1F / state.getLength)

Whilst I accept that state.getBoost could in theory be 0 I'm not quite sure that what the rule is aiming for.

False positive: RepeatedCaseBody (0.90.11)

The below triggers a RepeatedCaseBody w

sym match {
    case NoSymbol => None
    case sym: Symbol => Some(sym)
    case _ => None
}

I don't think there is a way to reorganise this to avoid the duplication. As NoSymbol is a instance of Symbol.

False positive case class reported as convertable to case object

case class Undo(id: Int, summary: String, changes: List[FileEdit]) (ensime, Project.scala:49)

Reports

Info Empty case class com.sksamuel.scapegoat.inspections.EmptyCaseClassInspection
Empty case class can be rewritten as a case object

This should only refer to the pattern

case class Foo() 

scapegoat duplicates scala/scala-abide?

It looks like Scala-core have recently come up with the same idea as scapegoat and are busy implementing their own scalac plugin that also duplicates Findbugs: https://github.com/scala/scala-abide

It might be worth hacking on that instead, as it's likely to capture scapegoat's mindshare / user base, since it is backed by the core scala team.

(No-one else seems interested in adapting Findbugs for Scala; everyone seems to want to reinvent the wheel. Maybe I'll moan about that on the Scala mailing list.)

BrokenOddness check could use clarifying

What is "BrokenOddness" checking for?

The warning could do with clarifying.

Are you saying that i % 2 == 1 should always be replaced with i & 0x1 == 1? If so, I think you should a) clarify the warning to suggest that alternate form and b) cite some evidence, as opinion appears to be divided on the matter.

... also the rule doesn't check for tests like i % 2 == 0

AsInstanceOf in actor receive

Reported by @RichardBradley

The following actor Receive method triggers AsInstanceOf warnings

  def receive: Receive = LoggingReceive {
    case requestStart: ChunkedRequestStart =>
      // start by establishing a new HTTP connection
      val host = requestStart.request.uri.authority.host.address
      val port = requestStart.request.uri.authority.port

      ioActor ! Http.Connect(host, port)
      owner = sender()
      context.become(connecting(requestStart))
  }

AsInstanceOf reported in Async macro

Use of asInstanceOf com.sksamuel.scapegoat.inspections.unsafe.AsInstanceOf
asInstanceOf used near tr.get.asInstanceOf[com.x.x.x.FinancialService]. Consider using pattern matching.

Prefer Seq.empty reported for non empty Seq

Prefer Seq.empty com.sksamuel.scapegoat.inspections.collections.PreferSeqEmpty
SeqT creates a new instance. Consider Set.empty which does not allocate a new object. collection.this.Seq.apply[com.x.x.x.RqParam]

Should not inspect generated sources

e.g. with Play, finds "Use of asInstanceOf" in target/scala-2.11/src_managed/main/routes_routing.scala

(maybe a bug for the related sbt plugin?)

False positive: LonelySealedTrait (0.90.11)

LonelySealedTrait appears to be triggering more often than it should. E.g. in the below SExp is being marked:

(ensime SExp.scala)

sealed trait SExp extends WireFormat ...
...
case class SExpList(items: List[SExp]) extends SExp with Iterable[SExp] {
... // more implementations...

Enhancement: check for string that ought to be interpolated

Suggested new inspection: warn for strings that look like they ought to be interpolated but aren't, e.g.

try {
  require(false, "inner exception details here")
} catch {
  case NonFatal(e) =>
    throw new IOException("Error attempting foo: $e")
}

i.e. if a non-interpolated string contains "$foo" when there is a variable named "foo" in scope, warn that you need to add "s" to make the string interpolated.

idea for case some/none

Here is something I do quite a bit.

I'll have

a match {
case Some(b) =>
case None =>
}

And then I'll add a guard to the some because something has changed

a match {
case Some(b) if b .... =>
case None =>
}

And now I don't have a full match, and if my unit tests aren't sufficient I can get a match error later on. Does anyone else do this?

Warning for use of Scala Enumeration

Enumeration isn't particular elegant, and most people just use case objects. I need to find an article that explains why enumeration should be avoided as the justification in the inspection.

False postive: AvoidOperatorOverload (0.90.13)

AvoidOperatorOverload warning being generated (100s)

Info Avoid operator overload com.sksamuel.scapegoat.inspections.style.AvoidOperatorOverload
Scala style guide advocates against using operators as method names, except in special circumstances. See http://docs.scala-lang.org/style/naming-conventions.html#symbolic-method-names

Is being reported in very weird places (see comments):

case class TypeSearchResult(
  name: String,   // this line
  localName: String, // this line
  declaredAs: scala.Symbol, // this line
  pos: Option[(String, Int)]) extends SymbolSearchResult // this line

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.