Skip to content

Commit 7731b93

Browse files
committed
showAst annotation interpreted by commons-analyzer
1 parent d847023 commit 7731b93

File tree

5 files changed

+47
-4
lines changed

5 files changed

+47
-4
lines changed

commons-analyzer/src/main/scala/com/avsystem/commons/analyzer/AnalyzerPlugin.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ final class AnalyzerPlugin(val global: Global) extends Plugin { plugin =>
1111
new VarargsAtLeast[global.type](global),
1212
new CheckMacroPrivate[global.type](global),
1313
new ExplicitGenerics[global.type](global),
14-
new ValueEnumExhaustiveMatch[global.type](global)
14+
new ValueEnumExhaustiveMatch[global.type](global),
15+
new ShowAst[global.type](global)
1516
)
1617
val rulesByName = rules.map(r => (r.name, r)).toMap
1718

commons-analyzer/src/main/scala/com/avsystem/commons/analyzer/AnalyzerRule.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ import java.io.{PrintWriter, StringWriter}
66
import scala.tools.nsc.Global
77
import scala.util.control.NonFatal
88

9-
abstract class AnalyzerRule[C <: Global with Singleton](val global: C, val name: String) {
9+
abstract class AnalyzerRule[C <: Global with Singleton](
10+
val global: C, val name: String, defaultLevel: Level = Level.Warn) {
1011

1112
import global._
1213

13-
var level: Level = Level.Warn
14+
var level: Level = defaultLevel
1415

1516
protected def classType(fullName: String) =
1617
try rootMirror.staticClass(fullName).asType.toType.erasure catch {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.avsystem.commons
2+
package analyzer
3+
4+
import scala.tools.nsc.Global
5+
6+
class ShowAst[C <: Global with Singleton](g: C) extends AnalyzerRule(g, "showAst", Level.Error) {
7+
8+
import global._
9+
10+
lazy val showAstAnnotType: Type = classType("com.avsystem.commons.annotation.showAst")
11+
12+
def analyze(unit: CompilationUnit) = if (showAstAnnotType != NoType) {
13+
def analyzeTree(tree: Tree): Unit = analyzer.macroExpandee(tree) match {
14+
case `tree` | EmptyTree =>
15+
tree match {
16+
case Annotated(annot, arg) if annot.tpe <:< showAstAnnotType =>
17+
report(arg.pos, showCode(arg))
18+
case Typed(expr, tpt) if tpt.tpe.annotations.exists(_.tpe <:< showAstAnnotType) =>
19+
report(expr.pos, showCode(expr))
20+
case _: MemberDef if tree.symbol.annotations.exists(_.tpe <:< showAstAnnotType) =>
21+
report(tree.pos, showCode(tree))
22+
case _ =>
23+
}
24+
tree.children.foreach(analyzeTree)
25+
case prevTree =>
26+
analyzeTree(prevTree)
27+
}
28+
analyzeTree(unit.body)
29+
}
30+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.avsystem.commons
2+
package annotation
3+
4+
import scala.annotation.StaticAnnotation
5+
6+
/**
7+
* When applied on a definition (`class`, `object`, `def`, `val`, etc.) or expression, will cause the
8+
* AVSystem static analyzer to print compilation error with AST of annotated code fragment.
9+
* This is useful primarily for debugging macro expansions.
10+
*/
11+
class showAst extends StaticAnnotation

version.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version in ThisBuild := "1.28.0"
1+
version in ThisBuild := "1.28.1"

0 commit comments

Comments
 (0)