From 72de9a9ce2e21581c393484dc17b832ebaa732b9 Mon Sep 17 00:00:00 2001 From: Pascal Weisenburger Date: Wed, 6 Dec 2017 18:21:32 +0100 Subject: [PATCH] report silencing extended and factored out --- .../typechecker/ReportingSilencer.scala | 83 +++++++++++++++++++ .../dslparadise/typechecker/Typers.scala | 42 +--------- 2 files changed, 87 insertions(+), 38 deletions(-) create mode 100644 plugin/src/main/scala/dslparadise/typechecker/ReportingSilencer.scala diff --git a/plugin/src/main/scala/dslparadise/typechecker/ReportingSilencer.scala b/plugin/src/main/scala/dslparadise/typechecker/ReportingSilencer.scala new file mode 100644 index 0000000..2530f76 --- /dev/null +++ b/plugin/src/main/scala/dslparadise/typechecker/ReportingSilencer.scala @@ -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 + } + } +} diff --git a/plugin/src/main/scala/dslparadise/typechecker/Typers.scala b/plugin/src/main/scala/dslparadise/typechecker/Typers.scala index 13e5dee..0787e05 100644 --- a/plugin/src/main/scala/dslparadise/typechecker/Typers.scala +++ b/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) @@ -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 @@ -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 =>