diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2013-12-07 14:10:10 +0100 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2013-12-30 19:06:29 +0300 |
commit | 447e7371742c498fb62a999d009d11bff8a70db7 (patch) | |
tree | 31106e698afb9c983beee12d7e1a73f292be8ae0 | |
parent | 9e14058dd246b7e9d93c4fd4e4aab326d45460d6 (diff) | |
download | scala-447e7371742c498fb62a999d009d11bff8a70db7.tar.gz scala-447e7371742c498fb62a999d009d11bff8a70db7.tar.bz2 scala-447e7371742c498fb62a999d009d11bff8a70db7.zip |
removes some copy/paste from AnalyzerPlugins
Abstracts away the foldLeft-based iteration pattern behind CumulativeOp[T].
In order to avoid performance regressions, `pluginsPt` and `pluginsTyped`
are special-cased for empty lists of analyzer plugins.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala | 80 |
1 files changed, 43 insertions, 37 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala b/src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala index 54e4fefc15..4e524323a6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala +++ b/src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala @@ -167,59 +167,65 @@ trait AnalyzerPlugins { self: Analyzer => analyzerPlugins = plugin :: analyzerPlugins } + private abstract class CumulativeOp[T] { + def default: T + def accumulate: (T, AnalyzerPlugin) => T + } + + private def invoke[T](op: CumulativeOp[T]): T = { + if (analyzerPlugins.isEmpty) op.default + else analyzerPlugins.foldLeft(op.default)((current, plugin) => + if (!plugin.isActive()) current else op.accumulate(current, plugin)) + } /** @see AnalyzerPlugin.pluginsPt */ def pluginsPt(pt: Type, typer: Typer, tree: Tree, mode: Mode): Type = + // performance opt if (analyzerPlugins.isEmpty) pt - else analyzerPlugins.foldLeft(pt)((pt, plugin) => - if (!plugin.isActive()) pt else plugin.pluginsPt(pt, typer, tree, mode)) + else invoke(new CumulativeOp[Type] { + def default = pt + def accumulate = (pt, p) => p.pluginsPt(pt, typer, tree, mode) + }) /** @see AnalyzerPlugin.pluginsTyped */ - def pluginsTyped(tpe: Type, typer: Typer, tree: Tree, mode: Mode, pt: Type): Type = { - // support deprecated methods in annotation checkers - val annotCheckersTpe = addAnnotations(tree, tpe) - if (analyzerPlugins.isEmpty) annotCheckersTpe - else analyzerPlugins.foldLeft(annotCheckersTpe)((tpe, plugin) => - if (!plugin.isActive()) tpe else plugin.pluginsTyped(tpe, typer, tree, mode, pt)) - } + def pluginsTyped(tpe: Type, typer: Typer, tree: Tree, mode: Mode, pt: Type): Type = + // performance opt + if (analyzerPlugins.isEmpty) addAnnotations(tree, tpe) + else invoke(new CumulativeOp[Type] { + // support deprecated methods in annotation checkers + def default = addAnnotations(tree, tpe) + def accumulate = (tpe, p) => p.pluginsTyped(tpe, typer, tree, mode, pt) + }) /** @see AnalyzerPlugin.pluginsTypeSig */ - def pluginsTypeSig(tpe: Type, typer: Typer, defTree: Tree, pt: Type): Type = - if (analyzerPlugins.isEmpty) tpe - else analyzerPlugins.foldLeft(tpe)((tpe, plugin) => - if (!plugin.isActive()) tpe else plugin.pluginsTypeSig(tpe, typer, defTree, pt)) + def pluginsTypeSig(tpe: Type, typer: Typer, defTree: Tree, pt: Type): Type = invoke(new CumulativeOp[Type] { + def default = tpe + def accumulate = (tpe, p) => p.pluginsTypeSig(tpe, typer, defTree, pt) + }) /** @see AnalyzerPlugin.pluginsTypeSigAccessor */ - def pluginsTypeSigAccessor(tpe: Type, typer: Typer, tree: ValDef, sym: Symbol): Type = - if (analyzerPlugins.isEmpty) tpe - else analyzerPlugins.foldLeft(tpe)((tpe, plugin) => - if (!plugin.isActive()) tpe else plugin.pluginsTypeSigAccessor(tpe, typer, tree, sym)) + def pluginsTypeSigAccessor(tpe: Type, typer: Typer, tree: ValDef, sym: Symbol): Type = invoke(new CumulativeOp[Type] { + def default = tpe + def accumulate = (tpe, p) => p.pluginsTypeSigAccessor(tpe, typer, tree, sym) + }) /** @see AnalyzerPlugin.canAdaptAnnotations */ - def canAdaptAnnotations(tree: Tree, typer: Typer, mode: Mode, pt: Type): Boolean = { + def canAdaptAnnotations(tree: Tree, typer: Typer, mode: Mode, pt: Type): Boolean = invoke(new CumulativeOp[Boolean] { // support deprecated methods in annotation checkers - val annotCheckersExists = global.canAdaptAnnotations(tree, mode, pt) - annotCheckersExists || { - if (analyzerPlugins.isEmpty) false - else analyzerPlugins.exists(plugin => - plugin.isActive() && plugin.canAdaptAnnotations(tree, typer, mode, pt)) - } - } + def default = global.canAdaptAnnotations(tree, mode, pt) + def accumulate = (curr, p) => curr || p.canAdaptAnnotations(tree, typer, mode, pt) + }) /** @see AnalyzerPlugin.adaptAnnotations */ - def adaptAnnotations(tree: Tree, typer: Typer, mode: Mode, pt: Type): Tree = { + def adaptAnnotations(tree: Tree, typer: Typer, mode: Mode, pt: Type): Tree = invoke(new CumulativeOp[Tree] { // support deprecated methods in annotation checkers - val annotCheckersTree = global.adaptAnnotations(tree, mode, pt) - if (analyzerPlugins.isEmpty) annotCheckersTree - else analyzerPlugins.foldLeft(annotCheckersTree)((tree, plugin) => - if (!plugin.isActive()) tree else plugin.adaptAnnotations(tree, typer, mode, pt)) - } + def default = global.adaptAnnotations(tree, mode, pt) + def accumulate = (tree, p) => p.adaptAnnotations(tree, typer, mode, pt) + }) /** @see AnalyzerPlugin.pluginsTypedReturn */ - def pluginsTypedReturn(tpe: Type, typer: Typer, tree: Return, pt: Type): Type = { - val annotCheckersType = adaptTypeOfReturn(tree.expr, pt, tpe) - if (analyzerPlugins.isEmpty) annotCheckersType - else analyzerPlugins.foldLeft(annotCheckersType)((tpe, plugin) => - if (!plugin.isActive()) tpe else plugin.pluginsTypedReturn(tpe, typer, tree, pt)) - } + def pluginsTypedReturn(tpe: Type, typer: Typer, tree: Return, pt: Type): Type = invoke(new CumulativeOp[Type] { + def default = adaptTypeOfReturn(tree.expr, pt, tpe) + def accumulate = (tpe, p) => p.pluginsTypedReturn(tpe, typer, tree, pt) + }) } |