pureconfig icon indicating copy to clipboard operation
pureconfig copied to clipboard

How to avoid false "unused import"-warnings in Intelli?

Open tjarvstrand opened this issue 5 years ago • 1 comments

Hi!

We're currently using PureConfig and it's great (thanks)! One slight issue however, is that imports of ConfigConverts tend to be falsely reported by Intellij as unused. This leads to some annoyance since we make frequent use of "Optimize imports" and accidental commits with missing imports happen from time to time, especially with less senior devs.

Here's an example:

package com.example

import java.time.ZonedDateTime

import akka.actor.ActorContext
import akka.actor.ActorSystem
import akka.actor.Props
import akka.actor.{Actor => AkkaActor}
import pureconfig.ConfigConvert
import pureconfig.ConfigReader
import pureconfig.ConfigSource
import pureconfig.ConfigWriter
import pureconfig.generic.auto.exportReader
import pureconfig.generic.auto.exportWriter

import scala.reflect.ClassTag
import scala.util.Try

// This is in one shared module/subproject
object Converters {
  implicit val ZonedDateTimeConfigConverter: ConfigConvert[ZonedDateTime] =
    ConfigConvert.viaNonEmptyStringTry({ s => Try(ZonedDateTime.parse(s)) }, _.toString)
}

// This is in another shared module/subproject
object App {
  private class Actor[Cfg <: Product](config: Cfg,
                                      app: App[Cfg]) extends AkkaActor {
    override def receive: Receive = AkkaActor.emptyBehavior
    app.init(config, context)
  }
}

abstract class App[Cfg <: Product: ClassTag: ConfigReader: ConfigWriter] {
  def name: String

  def main(args: Array[String]): Unit = {
    val config: Cfg = ConfigSource.default.at(name).loadOrThrow[Cfg]
    // ..More stuff here
    Try(ActorSystem("example").actorOf(Props(new App.Actor[Cfg](config, this))))
      .map(_ => ())
      .get
  }

  def init(config: Cfg, context: ActorContext): Unit
}

// This is in a third module/subproject
import Converters._ // <--- Unused import in Intellij

case class MyMicroServiceConfig(someDate: ZonedDateTime)

object MyMicroServiceMain extends App[MyMicroServiceConfig] {
  override val name = "some-service"
  override def init(config: MyMicroServiceConfig, context: ActorContext): Unit = {
    // ...Initialization
    ()
  }
}

Granted, this can be "fixed" by marking the imports as always used but that is not really ideal since it hides actual unused imports and has to be redone by every developer and also every time the project is reimported from scratch (which happens).

Is there any way to get around this?

tjarvstrand avatar Feb 16 '21 09:02 tjarvstrand

I don't know of a way around it. It's been an annoyance to the teams I've worked on for years.

That said, I've never bothered to file a bug with IntelliJ IDEA. Because scalac doesn't report that the import is unused, I call the spurious error report a bug in IntelliJ IDEA.

leifwickland avatar Feb 16 '21 15:02 leifwickland