Giter Site home page Giter Site logo

extrawarts's Introduction

ExtraWarts

Build Status Maven Central

Some extra WartRemover warts that aren't available out of the box.

Versions

ExtraWarts version WartRemover version Scala version sbt version Supported
1.0.3 2.2.1 2.11.11, 2.12.3 0.13.x, 1.0.x
0.3.0 2.1.1 2.11.8, 2.12.2 0.13.x No

Usage

  1. Setup WartRemover.

  2. Add the following to your plugins.sbt:

    addSbtPlugin("org.danielnixon" % "sbt-extrawarts" % "1.0.3")
  3. Add the following to your build.sbt:

    wartremoverWarnings ++= Seq(
      ExtraWart.EnumerationPartial,
      ExtraWart.FutureObject,
      ExtraWart.GenMapLikePartial,
      ExtraWart.GenTraversableLikeOps,
      ExtraWart.GenTraversableOnceOps,
      ExtraWart.ScalaGlobalExecutionContext,
      ExtraWart.StringOpsPartial,
      ExtraWart.ThrowablePartial,
      ExtraWart.TraversableOnceOps,
      ExtraWart.UnsafeContains)

Warts

EnumerationPartial

scala.Enumeration#withName is disabled because is will throw a NoSuchElementException if there is no value matching the specified name. You can wrap it in an implicit that might look like this:

implicit class EnumerationWrapper[A <: Enumeration](val enum: A) extends AnyVal {
  @SuppressWarnings(Array("org.danielnixon.extrawarts.EnumerationPartial"))
  def withNameOpt(s: String): Option[A#Value] = {
    catching[A#Value](classOf[NoSuchElementException]) opt enum.withName(s)
  }
}

FutureObject

scala.concurrent.Future has a reduce method that can throw NoSuchElementException if the collection is empty. Use Future#fold instead.

GenMapLikePartial

scala.collection.GenMapLike has an apply method that can throw NoSuchElementException if there is no mapping for the given key. Use GenMapLike#get instead.

GenTraversableLikeOps

WartRemover's TraversableOps wart only applies to scala.collection.Traversable. The GenTraversableLikeOps wart extends it to everything that implements scala.collection.GenTraversableLike.

scala.collection.GenTraversableLike has:

  • head,
  • tail,
  • init and
  • last methods,

all of which will throw if the list is empty. The program should be refactored to use:

  • GenTraversableLike#headOption,
  • GenTraversableLike#drop(1),
  • GenTraversableLike#dropRight(1) and
  • GenTraversableLike#lastOption respectively,

to explicitly handle both populated and empty GenTraversableLikes.

ScalaGlobalExecutionContext

Scala's global execution context scala.concurrent.ExecutionContext#global is disabled. Declare a dependency on an ExecutionContext instead. See MUST NOT hardcode the thread-pool / execution context.

StringOpsPartial

scala.collection.immutable.StringOps has

  • toBoolean,
  • toByte,
  • toShort,
  • toInt,
  • toLong,
  • toFloat and
  • toDouble methods,

all of which will throw NumberFormatException (or IllegalArgumentException in the case of toBoolean) if the string cannot be parsed.

You can hide these unsafe StringOps methods with an implicit class that might look something like this:

implicit class StringWrapper(val value: String) extends AnyVal {
  import scala.util.control.Exception.catching

  @SuppressWarnings(Array("org.danielnixon.extrawarts.StringOpsPartial"))
  def toIntOpt: Option[Int] = catching[Int](classOf[NumberFormatException]) opt value.toInt
}

ThrowablePartial

java.lang.Throwable#getCause is disabled because it can return null. You can wrap it in an implicit that might look like this:

implicit class ThrowableWrapper(val t: Throwable) extends AnyVal {
  @SuppressWarnings(Array("org.danielnixon.extrawarts.ThrowablePartial"))
  def cause: Option[Throwable] = Option(t.getCause)
}

TraversableOnceOps

scala.collection.TraversableOnce has a reduceLeft method that will throw if the collection is empty. Use TraversableOnce#reduceLeftOption or TraversableOnce#foldLeft instead.

scala.collection.TraversableOnce has

  • max,
  • min,
  • maxBy and
  • minBy methods,

all of which will throw UnsupportedOperationException if the collection is empty. You can wrap these unsafe methods in an implicit class that might look something like this:

implicit class TraversableOnceWrapper[A](val traversable: TraversableOnce[A]) extends AnyVal {
  @SuppressWarnings(Array("org.danielnixon.extrawarts.TraversableOnceOps"))
  def maxOpt[B >: A](implicit cmp: Ordering[B]): Option[A] = {
    if (traversable.isEmpty) None else Some(traversable.max(cmp))
  }
}

UnsafeContains

scala.collection.SeqLike#contains is based on universal equality (seq.contains(elem) is equivalent to seq.exists(_ == elem)) so it is disabled.

If you use Scalaz, you can replace it with something like this:

import scalaz._
import Scalaz._

implicit class SeqLikeWrapper[A](val seq: SeqLike[A, _]) extends AnyVal {
  def containsSafe(elem: A)(implicit ev: Equal[A]): Boolean = {
    seq.exists(x => elem === x)
  }
}

If you use Cats, you can replace it with something like this:

import cats.Eq
import cats.implicits._

implicit class SeqLikeWrapper[A](val seq: SeqLike[A, _]) extends AnyVal {
  def containsSafe(elem: A)(implicit ev: Eq[A]): Boolean = {
    seq.exists(x => elem === x)
  }
}

Or simply (if you're willing to tolerate the universal equality):

implicit class SeqLikeWrapper[A](val seq: SeqLike[A, _]) extends AnyVal {
  @SuppressWarnings(Array("org.danielnixon.extrawarts.UnsafeContains"))
  def containsSafe(elem: A): Boolean = seq.contains(elem)
}

See also

extrawarts's People

Contributors

danielnixon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

extrawarts's Issues

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.