Skip to content

Commit 97f7f58

Browse files
committed
fixes pluginsEnterStats
Initial implementation of pluginsEnterStats was incorrect, because I got the foldLeft wrong, making it perpetuate the initial value of stats. This worked fine if zero or one macro plugins were active at a time, but broke down if there were multiple of such plugins (concretely, I discovered this issue when trying to marry macro paradise with scalahost).
1 parent 3a32ae3 commit 97f7f58

File tree

3 files changed

+81
-1
lines changed

3 files changed

+81
-1
lines changed

src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,6 @@ trait AnalyzerPlugins { self: Analyzer =>
447447
// performance opt
448448
if (macroPlugins.isEmpty) stats
449449
else macroPlugins.foldLeft(stats)((current, plugin) =>
450-
if (!plugin.isActive()) current else plugin.pluginsEnterStats(typer, stats))
450+
if (!plugin.isActive()) current else plugin.pluginsEnterStats(typer, current))
451451
}
452452
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[[syntax trees at end of typer]] // newSource1.scala
2+
package <empty> {
3+
class C extends scala.AnyRef {
4+
def <init>(): C = {
5+
C.super.<init>();
6+
()
7+
};
8+
def x: Int = 2;
9+
def xmacroPlugin1: Nothing = scala.this.Predef.???;
10+
def xmacroPlugin2: Nothing = scala.this.Predef.???;
11+
def xmacroPlugin2macroPlugin1: Nothing = scala.this.Predef.???;
12+
def y: Int = 3;
13+
def ymacroPlugin1: Nothing = scala.this.Predef.???;
14+
def ymacroPlugin2: Nothing = scala.this.Predef.???;
15+
def ymacroPlugin2macroPlugin1: Nothing = scala.this.Predef.???
16+
}
17+
}
18+
19+
macroPlugin2:enterStat(class C extends scala.AnyRef { def <init>() = { super.<init>(); () }; def x = 2; def y = 3 })
20+
macroPlugin1:enterStat(class C extends scala.AnyRef { def <init>() = { super.<init>(); () }; def x = 2; def y = 3 })
21+
macroPlugin2:enterStat(def <init>() = { super.<init>(); () })
22+
macroPlugin2:enterStat(def x = 2)
23+
macroPlugin2:enterStat(def y = 3)
24+
macroPlugin1:enterStat(def <init>() = { super.<init>(); () })
25+
macroPlugin1:enterStat(def x = 2)
26+
macroPlugin1:enterStat(def xmacroPlugin2 = $qmark$qmark$qmark)
27+
macroPlugin1:enterStat(def y = 3)
28+
macroPlugin1:enterStat(def ymacroPlugin2 = $qmark$qmark$qmark)
29+
macroPlugin2:enterStat(super.<init>())
30+
macroPlugin1:enterStat(super.<init>())
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import scala.tools.partest._
2+
import scala.tools.nsc._
3+
4+
object Test extends DirectTest {
5+
override def extraSettings: String = "-usejavacp -Xprint:typer"
6+
7+
def code = """
8+
class C {
9+
def x = 2
10+
def y = 3
11+
}
12+
""".trim
13+
14+
def show() {
15+
val global = newCompiler()
16+
import global._
17+
import analyzer._
18+
19+
val output = collection.mutable.ListBuffer[String]()
20+
def log(what: String) = output += what.replace(String.format("%n"), " ")
21+
22+
def logEnterStat(pluginName: String, stat: Tree): Unit = log(s"$pluginName:enterStat($stat)")
23+
def deriveStat(pluginName: String, typer: Typer, stat: Tree): List[Tree] = stat match {
24+
case DefDef(mods, name, Nil, Nil, TypeTree(), body) =>
25+
val derived = DefDef(NoMods, TermName(name + pluginName), Nil, Nil, TypeTree(), Ident(TermName("$qmark$qmark$qmark")))
26+
newNamer(typer.context).enterSym(derived)
27+
List(derived)
28+
case _ =>
29+
Nil
30+
}
31+
32+
object macroPlugin1 extends MacroPlugin {
33+
override def pluginsEnterStats(typer: Typer, stats: List[Tree]): List[Tree] = {
34+
stats.foreach(stat => logEnterStat("macroPlugin1", stat))
35+
stats.flatMap(stat => stat +: deriveStat("macroPlugin1", typer, stat))
36+
}
37+
}
38+
object macroPlugin2 extends MacroPlugin {
39+
override def pluginsEnterStats(typer: Typer, stats: List[Tree]): List[Tree] = {
40+
stats.foreach(stat => logEnterStat("macroPlugin2", stat))
41+
stats.flatMap(stat => stat +: deriveStat("macroPlugin2", typer, stat))
42+
}
43+
}
44+
45+
addMacroPlugin(macroPlugin1)
46+
addMacroPlugin(macroPlugin2)
47+
compileString(global)(code)
48+
println(output.mkString("\n"))
49+
}
50+
}

0 commit comments

Comments
 (0)