Skip to content

Commit

Permalink
report silencing extended and factored out
Browse files Browse the repository at this point in the history
  • Loading branch information
pweisenburger committed Dec 10, 2017
1 parent 35b9fed commit 72de9a9
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 38 deletions.
@@ -0,0 +1,83 @@
package dslparadise
package typechecker

import scala.collection.mutable.LinkedHashMap

trait ReportingSilencer {
self: Analyzer =>

import global._

trait Silencer {
val warningFields = try {
val allWarningsField = currentRun.reporting.getClass.getDeclaredField("_allConditionalWarnings")
allWarningsField.setAccessible(true)
allWarningsField.get(currentRun.reporting).asInstanceOf[List[_]].headOption map { warning =>
val warningsField = warning.getClass.getDeclaredField("warnings")
warningsField.setAccessible(true)
val doReportField = warning.getClass.getDeclaredField("doReport")
doReportField.setAccessible(true)

val yeasField = settings.warnUnused.getClass.getDeclaredField("yeas")
yeasField.setAccessible(true)
val naysField = settings.warnUnused.getClass.getDeclaredField("nays")
naysField.setAccessible(true)
val compute = settings.warnUnused.getClass.getDeclaredMethod("compute")
compute.setAccessible(true)

val unusedWarnings = settings.getClass.getMethod("UnusedWarnings").invoke(settings)
val imports = unusedWarnings.getClass.getMethod("Imports").invoke(unusedWarnings)

val yeas = yeasField.get(settings.warnUnused)
val plus = yeas.getClass.getMethod("$" + "plus", classOf[Object])
val minus = yeas.getClass.getMethod("$" + "minus", classOf[Object])

(allWarningsField, warningsField, doReportField,
yeasField, naysField, compute,
imports, plus, minus)
}
}
catch {
case _: NoSuchFieldException => None
case _: NoSuchMethodException => None
}

def silenceReporting[T](op: => T): T = warningFields match {
case Some((
allWarningsField, warningsField, doReportField,
yeasField, naysField, compute,
imports, plus, minus)) =>

val allWarnings =
allWarningsField.get(currentRun.reporting).asInstanceOf[List[_]]
val warningBackups = allWarnings map warningsField.get
allWarnings foreach {
warningsField.set(_, LinkedHashMap.empty[Position, (String, String)])
}
val doReportBackups = allWarnings map doReportField.get
allWarnings foreach {
doReportField.set(_, () => false)
}

val yeasBackup = yeasField.get(settings.warnUnused)
yeasField.set(settings.warnUnused, minus.invoke(yeasBackup, imports))
val naysBackup = naysField.get(settings.warnUnused)
naysField.set(settings.warnUnused, plus.invoke(naysBackup, imports))
compute.invoke(settings.warnUnused)

val result = op

yeasField.set(settings.warnUnused, yeasBackup)
naysField.set(settings.warnUnused, naysBackup)
compute.invoke(settings.warnUnused)

allWarnings zip warningBackups foreach (warningsField.set _).tupled
allWarnings zip doReportBackups foreach (doReportField.set _).tupled

result

case None =>
op
}
}
}
42 changes: 4 additions & 38 deletions plugin/src/main/scala/dslparadise/typechecker/Typers.scala
@@ -1,49 +1,15 @@
package dslparadise
package typechecker

import scala.collection.mutable.LinkedHashMap
import scala.reflect.NameTransformer
import scala.reflect.internal.Mode

trait Typers {
trait Typers extends ReportingSilencer {
self: Analyzer =>

import global._

trait ParadiseTyper extends Typer with TyperContextErrors {
val warningFields = try {
val allWarningsField = currentRun.reporting.getClass.getDeclaredField("_allConditionalWarnings")
allWarningsField.setAccessible(true)
allWarningsField.get(currentRun.reporting).asInstanceOf[List[_]].headOption map { warning =>
val warningsField = warning.getClass.getDeclaredField("warnings")
warningsField.setAccessible(true)
val doReportField = warning.getClass.getDeclaredField("doReport")
doReportField.setAccessible(true)
(allWarningsField, warningsField, doReportField)
}
}
catch { case _: NoSuchFieldException => None }

def silenceRunReporter[T](op: => T): T = warningFields match {
case Some((allWarningsField, warningsField, doReportField)) =>
val allWarnings =
allWarningsField.get(currentRun.reporting).asInstanceOf[List[_]]
val warningBackups = allWarnings map warningsField.get
allWarnings foreach {
warningsField.set(_, LinkedHashMap.empty[Position, (String, String)])
}
val doReportBackups = allWarnings map doReportField.get
allWarnings foreach {
doReportField.set(_, () => false)
}
val result = op
allWarnings zip warningBackups foreach (warningsField.set _).tupled
allWarnings zip doReportBackups foreach (doReportField.set _).tupled
result
case None =>
op
}

trait ParadiseTyper extends Typer with Silencer {
def makeArg(name: TermName) =
ValDef(Modifiers(Flag.PARAM), name, TypeTree(), EmptyTree)

Expand Down Expand Up @@ -93,7 +59,7 @@ trait Typers {
rewritings get (NameTransformer decode symbol.fullName) map { rewrite =>

// only rewrite argument if it does not compile in its current form
val rewriteArg = silenceRunReporter {
val rewriteArg = silenceReporting {
context inSilentMode {
super.typedArg(arg.duplicate, mode, newmode, pt)
context.reporter.hasErrors
Expand All @@ -113,7 +79,7 @@ trait Typers {
// - whose message is "missing parameter type", which could be
// misleading if the rewriting introduced a function and the
// original code already had function type
val keepArg = silenceRunReporter {
val keepArg = silenceReporting {
context inSilentMode {
super.typedArg(newarg.duplicate, mode, newmode, pt)
context.reporter.errors exists { e =>
Expand Down

0 comments on commit 72de9a9

Please sign in to comment.