ghik / silencer

Scala compiler plugin for warning suppression
Apache License 2.0
255 stars 33 forks source link

NullPointerException at SilencerPlugin's FindSuppressions.addSuppression #56

Closed ohze closed 4 years ago

ohze commented 4 years ago

When compile zio on scala 2.13.3 using silencer 1.7.0:

```scala [error] java.lang.NullPointerException [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.addSuppression(SilencerPlugin.scala:156) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.traverse(SilencerPlugin.scala:179) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.traverse(SilencerPlugin.scala:150) [error] scala.reflect.internal.Trees$Match.traverse(Trees.scala:693) [error] scala.reflect.internal.Trees.itraverse(Trees.scala:1606) [error] scala.reflect.internal.Trees.itraverse$(Trees.scala:1605) [error] scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:28) [error] scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:28) [error] scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2497) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.traverse(SilencerPlugin.scala:176) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.traverse(SilencerPlugin.scala:150) [error] scala.reflect.internal.Trees$Function.$anonfun$traverse$7(Trees.scala:649) [error] scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2529) [error] scala.reflect.internal.Trees$Function.traverse(Trees.scala:648) [error] scala.reflect.internal.Trees.itraverse(Trees.scala:1606) [error] scala.reflect.internal.Trees.itraverse$(Trees.scala:1605) [error] scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:28) [error] scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:28) [error] scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2497) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.traverse(SilencerPlugin.scala:176) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.traverse(SilencerPlugin.scala:150) [error] scala.reflect.api.Trees$Traverser.traverseTrees(Trees.scala:2506) [error] scala.reflect.internal.Trees$Apply.traverse(Trees.scala:789) [error] scala.reflect.internal.Trees.itraverse(Trees.scala:1606) [error] scala.reflect.internal.Trees.itraverse$(Trees.scala:1605) [error] scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:28) [error] scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:28) [error] scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2497) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.traverse(SilencerPlugin.scala:176) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.traverse(SilencerPlugin.scala:150) [error] scala.reflect.api.Trees$Traverser.$anonfun$traverseStats$1(Trees.scala:2521) [error] scala.reflect.api.Trees$Traverser.traverseStats(Trees.scala:2519) [error] scala.reflect.internal.Trees$Template.traverse(Trees.scala:548) [error] scala.reflect.internal.Trees.itraverse(Trees.scala:1606) [error] scala.reflect.internal.Trees.itraverse$(Trees.scala:1605) [error] scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:28) [error] scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:28) [error] scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2497) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.traverse(SilencerPlugin.scala:176) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.traverse(SilencerPlugin.scala:150) [error] scala.reflect.internal.Trees$ModuleDef.$anonfun$traverse$2(Trees.scala:401) [error] scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2529) [error] scala.reflect.internal.Trees$ModuleDef.traverse(Trees.scala:398) [error] scala.reflect.internal.Trees.itraverse(Trees.scala:1606) [error] scala.reflect.internal.Trees.itraverse$(Trees.scala:1605) [error] scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:28) [error] scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:28) [error] scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2497) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.traverse(SilencerPlugin.scala:176) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.traverse(SilencerPlugin.scala:150) [error] scala.reflect.api.Trees$Traverser.traverseTrees(Trees.scala:2506) [error] scala.reflect.internal.Trees$Apply.traverse(Trees.scala:789) [error] scala.reflect.internal.Trees.itraverse(Trees.scala:1606) [error] scala.reflect.internal.Trees.itraverse$(Trees.scala:1605) [error] scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:28) [error] scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:28) [error] scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2497) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.traverse(SilencerPlugin.scala:176) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.traverse(SilencerPlugin.scala:168) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.traverse(SilencerPlugin.scala:150) [error] scala.reflect.api.Trees$Traverser.$anonfun$traverseStats$2(Trees.scala:2520) [error] scala.reflect.api.Trees$Traverser.atOwner(Trees.scala:2529) [error] scala.reflect.api.Trees$Traverser.$anonfun$traverseStats$1(Trees.scala:2520) [error] scala.reflect.api.Trees$Traverser.traverseStats(Trees.scala:2519) [error] scala.reflect.internal.Trees$PackageDef.traverse(Trees.scala:347) [error] scala.reflect.internal.Trees.itraverse(Trees.scala:1606) [error] scala.reflect.internal.Trees.itraverse$(Trees.scala:1605) [error] scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:28) [error] scala.reflect.internal.SymbolTable.itraverse(SymbolTable.scala:28) [error] scala.reflect.api.Trees$Traverser.traverse(Trees.scala:2497) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$FindSuppressions$1$.traverse(SilencerPlugin.scala:176) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$.applySuppressions(SilencerPlugin.scala:197) [error] com.github.ghik.silencer.SilencerPlugin$extractSuppressions$$anon$1.apply(SilencerPlugin.scala:96) [error] scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:454) [error] scala.tools.nsc.Global$GlobalPhase.run(Global.scala:401) [error] scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1515) [error] scala.tools.nsc.Global$Run.compileUnits(Global.scala:1499) [error] scala.tools.nsc.Global$Run.compileSources(Global.scala:1491) [error] scala.tools.nsc.Global$Run.compile(Global.scala:1626) [error] xsbt.CachedCompiler0.run(CompilerInterface.scala:153) [error] xsbt.CachedCompiler0.run(CompilerInterface.scala:125) [error] xsbt.CompilerInterface.run(CompilerInterface.scala:39) [error] sun.reflect.GeneratedMethodAccessor19.invoke(Unknown Source) [error] sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [error] java.lang.reflect.Method.invoke(Method.java:498) [error] sbt.internal.inc.AnalyzingCompiler.call(AnalyzingCompiler.scala:248) [error] sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:122) [error] sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:95) [error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4(MixedAnalyzingCompiler.scala:91) [error] scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23) [error] sbt.internal.inc.MixedAnalyzingCompiler.timed(MixedAnalyzingCompiler.scala:186) [error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$3(MixedAnalyzingCompiler.scala:82) [error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$3$adapted(MixedAnalyzingCompiler.scala:77) [error] sbt.internal.inc.JarUtils$.withPreviousJar(JarUtils.scala:215) [error] sbt.internal.inc.MixedAnalyzingCompiler.compileScala$1(MixedAnalyzingCompiler.scala:77) [error] sbt.internal.inc.MixedAnalyzingCompiler.compile(MixedAnalyzingCompiler.scala:146) [error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1(IncrementalCompilerImpl.scala:343) [error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1$adapted(IncrementalCompilerImpl.scala:343) [error] sbt.internal.inc.Incremental$.doCompile(Incremental.scala:120) [error] sbt.internal.inc.Incremental$.$anonfun$compile$4(Incremental.scala:100) [error] sbt.internal.inc.IncrementalCommon.recompileClasses(IncrementalCommon.scala:180) [error] sbt.internal.inc.IncrementalCommon.cycle(IncrementalCommon.scala:98) [error] sbt.internal.inc.Incremental$.$anonfun$compile$3(Incremental.scala:102) [error] sbt.internal.inc.Incremental$.manageClassfiles(Incremental.scala:155) [error] sbt.internal.inc.Incremental$.compile(Incremental.scala:92) [error] sbt.internal.inc.IncrementalCompile$.apply(Compile.scala:75) [error] sbt.internal.inc.IncrementalCompilerImpl.compileInternal(IncrementalCompilerImpl.scala:348) [error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileIncrementally$1(IncrementalCompilerImpl.scala:301) [error] sbt.internal.inc.IncrementalCompilerImpl.handleCompilationError(IncrementalCompilerImpl.scala:168) [error] sbt.internal.inc.IncrementalCompilerImpl.compileIncrementally(IncrementalCompilerImpl.scala:248) [error] sbt.internal.inc.IncrementalCompilerImpl.compile(IncrementalCompilerImpl.scala:74) [error] sbt.Defaults$.compileIncrementalTaskImpl(Defaults.scala:1765) [error] sbt.Defaults$.$anonfun$compileIncrementalTask$1(Defaults.scala:1738) [error] scala.Function1.$anonfun$compose$1(Function1.scala:49) [error] sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62) [error] sbt.std.Transform$$anon$4.work(Transform.scala:67) [error] sbt.Execute.$anonfun$submit$2(Execute.scala:281) [error] sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:19) [error] sbt.Execute.work(Execute.scala:290) [error] sbt.Execute.$anonfun$submit$1(Execute.scala:281) [error] sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:178) [error] sbt.CompletionService$$anon$2.call(CompletionService.scala:37) [error] java.util.concurrent.FutureTask.run(FutureTask.java:266) [error] java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [error] java.util.concurrent.FutureTask.run(FutureTask.java:266) [error] java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [error] java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [error] java.lang.Thread.run(Thread.java:748) ```

Inspect

object FindSuppressions extends Traverser {
  def addSuppression(tree: Tree, annot: Tree,... =
    val annotSym = annot.tpe.typeSymbol // error here! (SilencerPlugin.scala:156)
    ...
  def traverse(t: Tree) =
    t match {
      case Annotated(annot, arg) => addSuppression(arg, annot, annot.pos)
      ...

Error when compiling zio.examples.macros.AccessibleMacroExample:

@zio.macros.accessible
object AccessibleMacroExample {
  trait Service {
    val foo: zio.UIO[Unit]
  }
  val program = for(_ <- AccessibleMacroExample.foo) yield ()
}

Note, AccessibleMacroExample.foo is auto generated by:

import scala.annotation.{ compileTimeOnly, StaticAnnotation }

@compileTimeOnly("enable macro paradise to expand macro annotations")
class accessible[A] extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro AccessibleMacro.apply
}
class AccessibleMacro(val c: whitebox.Context) {
  ...
  @silent("pattern var [^\\s]+ in method unapply is never used")
  def apply(annottees: c.Tree*): c.Tree = ...
}
ohze commented 4 years ago

https://github.com/ghik/silencer/blob/fe701d47330fbe73672a8c19c9759a828ee19e4d/silencer-plugin/src/main/scala/com/github/ghik/silencer/SilencerPlugin.scala#L154-L162

Maybe fix by:

val annotSym = Option(annot.tpe).fold(NoSymbol)(_.typeSymbol)
ohze commented 4 years ago

Ah. This issue can be reproduced with:

@accessible
object AccessibleMacroExample {
  (0: @scala.unchecked) match { case _ => }
}

class accessible extends scala.annotation.StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro AccessibleMacro.apply
}

import scala.reflect.macros.whitebox
class AccessibleMacro(val c: whitebox.Context) {
  def apply(annottees: c.Tree*): c.Tree = annottees.head
}
git clone https://github.com/giabao/silencer-bug.git
sbt compile
ghik commented 4 years ago

1.7.1 is on the way.