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

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

package com.avsystem.commons
package analyzer

import scala.reflect.internal.util.NoPosition
import scala.tools.nsc.plugins.{Plugin, PluginComponent}
import scala.tools.nsc.{Global, Phase}

final class AnalyzerPlugin(val global: Global) extends Plugin { plugin =>

  override def init(options: List[String], error: String => Unit): Boolean = {
    options.foreach { option =>
      if (option.startsWith("requireJDK=")) {
        val jdkVersionRegex = option.substring(option.indexOf('=') + 1)
        val javaVersion = System.getProperty("java.version", "")
        if (!javaVersion.matches(jdkVersionRegex)) {
          global.reporter.error(NoPosition,
            s"This project must be compiled on JDK version that matches $jdkVersionRegex but got $javaVersion")
        }
      } else {
        val level = option.charAt(0) match {
          case '-' => Level.Off
          case '*' => Level.Info
          case '+' => Level.Error
          case _ => Level.Warn
        }
        val nameArg = if (level != Level.Warn) option.drop(1) else option
        if (nameArg == "_") {
          rules.foreach(_.level = level)
        } else {
          val (name, arg) = nameArg.split(":", 2) match {
            case Array(n, a) => (n, a)
            case Array(n) => (n, null)
          }
          rulesByName.get(name) match {
            case Some(rule) =>
              rule.level = level
              rule.argument = arg
            case None =>
              error(s"Unrecognized AVS analyzer rule: $name")
          }
        }
      }
    }
    true
  }

  private lazy val rules = List(
    new ImportJavaUtil(global),
    new VarargsAtLeast(global),
    new CheckMacroPrivate(global),
    new ExplicitGenerics(global),
    new ValueEnumExhaustiveMatch(global),
    new ShowAst(global),
    new FindUsages(global),
    new CheckBincompat(global),
    new Any2StringAdd(global),
    new ThrowableObjects(global),
    new DiscardedMonixTask(global),
    new BadSingletonComponent(global),
    new ConstantDeclarations(global),
    new BasePackage(global),
  )

  private lazy val rulesByName = rules.map(r => (r.name, r)).toMap

  val name = "AVSystemAnalyzer"
  val description = "AVSystem custom Scala static analyzer"
  val components: List[PluginComponent] = List(component)

  private object component extends PluginComponent {
    val global: plugin.global.type = plugin.global
    val runsAfter = List("typer")
    override val runsBefore = List("patmat")
    val phaseName = "avsAnalyze"

    import global._

    def newPhase(prev: Phase): StdPhase = new StdPhase(prev) {
      def apply(unit: CompilationUnit): Unit =
        rules.foreach(rule => if (rule.level != Level.Off) rule.analyze(unit.asInstanceOf[rule.global.CompilationUnit]))
    }
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy