<commit_before>package sbt.std

import sbt.internal.util.ConsoleAppender
import sbt.internal.util.appmacro.LinterDSL

import scala.collection.mutable.{ HashSet => MutableSet }
import scala.io.AnsiColor
import scala.reflect.macros.blackbox

object TaskLinterDSL extends LinterDSL {
  override def runLinter(ctx: blackbox.Context)(
      tree: ctx.Tree,
      isApplicableFromContext: => Boolean
  ): Unit = {
    import ctx.universe._
    val isTask = FullConvert.asPredicate(ctx)
    object traverser extends Traverser {
      private val unchecked = symbolOf[sbt.unchecked].asClass
      private val uncheckedWrappers = MutableSet.empty[Tree]
      var insideIf: Boolean = false
      override def traverse(tree: ctx.universe.Tree): Unit = {
        tree match {
          case If(condition, thenp, elsep) =>
            super.traverse(condition)
            insideIf = true
            super.traverse(thenp)
            super.traverse(elsep)
            insideIf = false
          case s @ Apply(TypeApply(Select(_, nme), tpe :: Nil), qual :: Nil) =>
            val shouldIgnore = uncheckedWrappers.contains(s)
            val wrapperName = nme.decodedName.toString
            if (insideIf && !shouldIgnore && isTask(wrapperName, tpe.tpe, qual)) {
              val qualName = qual.symbol.name.decodedName.toString
              ctx.error(s.pos, TaskLinterDSLFeedback.useOfValueInsideIfExpression(qualName))
            }
          // Don't remove, makes the whole analysis work
          case Typed(expr, tt) =>
            super.traverse(expr)
            super.traverse(tt)
          case Typed(expr, tt: TypeTree) if tt.original != null =>
            tt.original match {
              case Annotated(annot, arg) =>
                annot.tpe match {
                  case AnnotatedType(annotations, _) =>
                    val symAnnotations = annotations.map(_.tree.tpe.typeSymbol)
                    val isUnchecked = symAnnotations.contains(unchecked)
                    if (isUnchecked) {
                      val toAdd = arg match {
                        case Typed(`expr`, _) => `expr`
                        case `tree`           => `tree`
                      }
                      uncheckedWrappers.add(toAdd)
                    }
                  case _ =>
                }
            }
            super.traverse(expr)
          case tree => super.traverse(tree)
        }
      }
    }
    if (!isApplicableFromContext) ()<commit_msg>Make sure that macro linter doesn't fail spuriously<commit_after>package sbt.std

import sbt.internal.util.ConsoleAppender
import sbt.internal.util.appmacro.LinterDSL

import scala.collection.mutable.{ HashSet => MutableSet }
import scala.io.AnsiColor
import scala.reflect.macros.blackbox

object TaskLinterDSL extends LinterDSL {
  override def runLinter(ctx: blackbox.Context)(
      tree: ctx.Tree,
      isApplicableFromContext: => Boolean
  ): Unit = {
    import ctx.universe._
    val isTask = FullConvert.asPredicate(ctx)
    object traverser extends Traverser {
      private val unchecked = symbolOf[sbt.unchecked].asClass
      private val uncheckedWrappers = MutableSet.empty[Tree]
      var insideIf: Boolean = false
      override def traverse(tree: ctx.universe.Tree): Unit = {
        tree match {
          case If(condition, thenp, elsep) =>
            super.traverse(condition)
            insideIf = true
            super.traverse(thenp)
            super.traverse(elsep)
            insideIf = false
          case s @ Apply(TypeApply(Select(_, nme), tpe :: Nil), qual :: Nil) =>
            val shouldIgnore = uncheckedWrappers.contains(s)
            val wrapperName = nme.decodedName.toString
            if (insideIf && !shouldIgnore && isTask(wrapperName, tpe.tpe, qual)) {
              val qualName = qual.symbol.name.decodedName.toString
              ctx.error(s.pos, TaskLinterDSLFeedback.useOfValueInsideIfExpression(qualName))
            }
          // Don't remove, makes the whole analysis work
          case Typed(expr, tt) =>
            super.traverse(expr)
            super.traverse(tt)
          case Typed(expr, tt: TypeTree) if tt.original != null =>
            tt.original match {
              case Annotated(annot, arg) =>
                Option(annot.tpe) match {
                  case Some(AnnotatedType(annotations, _)) =>
                    val symAnnotations = annotations.map(_.tree.tpe.typeSymbol)
                    val isUnchecked = symAnnotations.contains(unchecked)
                    if (isUnchecked) {
                      // Unwrap the expression behind the typed that sbt macro adds
                      val toAdd = arg match {
                        case Typed(`expr`, _) => `expr`
                        case `tree`           => `tree`
                      }
                      uncheckedWrappers.add(toAdd)
                    }
                  case _ =>
                }
              case _ =>
            }
            super.traverse(expr)
          case tree => super.traverse(tree)
        }
      }
    }
    if (!isApplicableFromContext) ()
{'fraction_non_alphanumeric': 0.0907843137254902, 'fraction_numerical': 0.0, 'mean_word_length': 1.793537787513691, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1560409', 'n_tokens_mistral': 1426, 'n_tokens_neox': 1385, 'n_words': 308}