All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.avsystem.commons.analyzer.DiscardedMonixTask.scala Maven / Gradle / Ivy

package com.avsystem.commons
package analyzer

import scala.tools.nsc.Global

class DiscardedMonixTask(g: Global) extends AnalyzerRule(g, "discardedMonixTask") {

  import global._

  lazy val monixTaskTpe: Type = classType("monix.eval.Task") match {
    case NoType => NoType
    case tpe => TypeRef(NoPrefix, tpe.typeSymbol, List(definitions.AnyTpe))
  }

  private def checkDiscardedTask(tree: Tree, discarded: Boolean): Unit = tree match {
    case tree if !discarded && tree.tpe != null && tree.tpe =:= definitions.UnitTpe =>
      checkDiscardedTask(tree, discarded = true)

    case Block(stats, expr) =>
      stats.foreach(checkDiscardedTask(_, discarded = true))
      checkDiscardedTask(expr, discarded)

    case Template(parents, self, body) =>
      parents.foreach(checkDiscardedTask(_, discarded = false))
      checkDiscardedTask(self, discarded = false)
      body.foreach(checkDiscardedTask(_, discarded = true))

    case If(_, thenp, elsep) =>
      checkDiscardedTask(thenp, discarded)
      checkDiscardedTask(elsep, discarded)

    case LabelDef(_, _, rhs) =>
      checkDiscardedTask(rhs, discarded = true)

    case Try(body, catches, finalizer) =>
      checkDiscardedTask(body, discarded)
      catches.foreach(checkDiscardedTask(_, discarded))
      checkDiscardedTask(finalizer, discarded = true)

    case CaseDef(_, _, body) =>
      checkDiscardedTask(body, discarded)

    case Match(_, cases) =>
      cases.foreach(checkDiscardedTask(_, discarded))

    case Annotated(_, arg) =>
      checkDiscardedTask(arg, discarded)

    case Typed(expr, _) =>
      checkDiscardedTask(expr, discarded)

    case Apply(TypeApply(Select(prefix, TermName("foreach")), List(_)), List(Function(_, body))) =>
      checkDiscardedTask(prefix, discarded = false)
      checkDiscardedTask(body, discarded)

    case _: Ident | _: Select | _: Apply | _: TypeApply if discarded &&
      tree.tpe != null && tree.tpe <:< monixTaskTpe && !(tree.tpe <:< definitions.NullTpe) =>
      report(tree.pos, "discarded Monix Task - this is probably a mistake because the Task must be run for its side effects")

    case tree =>
      tree.children.foreach(checkDiscardedTask(_, discarded = false))
  }

  def analyze(unit: CompilationUnit): Unit =
    if (monixTaskTpe != NoType) {
      checkDiscardedTask(unit.body, discarded = false)
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy