Skip to content

Commit 711b9a5

Browse files
authored
Merge pull request #814 from olafurpg/inspect
Inline scalameta-structure into repo
2 parents e72a2e2 + ff49910 commit 711b9a5

File tree

3 files changed

+168
-0
lines changed

3 files changed

+168
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package scalafix.internal.util
2+
3+
import scala.meta.Tree
4+
import scala.meta._
5+
import org.typelevel.paiges._
6+
7+
object Inspect {
8+
9+
def prettyList(tree: List[Tree], showFieldNames: Boolean): Doc = {
10+
wrapList(tree.map(t => prettyTree(t, showFieldNames)))
11+
}
12+
13+
def prettyOption(tree: Option[Tree], showFieldNames: Boolean): Doc = {
14+
wrapOption(tree.map(t => prettyTree(t, showFieldNames)))
15+
}
16+
17+
def prettyTree(tree: Tree, showFieldNames: Boolean): Doc = {
18+
tree match {
19+
case _ if tree.tokens.isEmpty =>
20+
Doc.empty
21+
case v: Term.Name =>
22+
Doc.text(v.structure)
23+
case t: Type.Name =>
24+
Doc.text(t.structure)
25+
case _ =>
26+
val args = tree.productFields.zip(tree.productIterator.toList).map {
27+
case (fieldName, value) =>
28+
val rhs = value match {
29+
case v: Term.Name => Doc.text(v.structure)
30+
case t: Tree => prettyTree(t, showFieldNames)
31+
case o: Option[_] =>
32+
o match {
33+
case Some(t: Tree) =>
34+
wrap(
35+
Doc.text("Some") + Doc.char('('),
36+
List(prettyTree(t, showFieldNames)),
37+
Doc.char(')')
38+
)
39+
case None =>
40+
Doc.text("None")
41+
case _ =>
42+
throw new Exception("cannot handle: " + o)
43+
}
44+
case vs: List[_] =>
45+
vs match {
46+
case Nil => Doc.text("Nil")
47+
case (_: Tree) :: _ =>
48+
prettyList(vs.asInstanceOf[List[Tree]], showFieldNames)
49+
case (_: List[_]) :: _ =>
50+
val vsT = vs.asInstanceOf[List[List[Tree]]]
51+
wrapList(vsT.map(v => prettyList(v, showFieldNames)))
52+
case _ =>
53+
throw new IllegalArgumentException("cannot handle: " + vs)
54+
}
55+
case _ => Doc.text(value.toString)
56+
}
57+
58+
if (showFieldNames) Doc.text(fieldName) + Doc.text(" = ") + rhs
59+
else rhs
60+
}
61+
62+
wrap(Doc.text(tree.productPrefix) + Doc.char('('), args, Doc.char(')'))
63+
}
64+
}
65+
66+
private def wrapList(args: List[Doc]): Doc = {
67+
if (args.nonEmpty) {
68+
wrap(Doc.text("List") + Doc.char('('), args, Doc.char(')'))
69+
} else {
70+
Doc.text("Nil")
71+
}
72+
}
73+
74+
private def wrapOption(opt: Option[Doc]): Doc = {
75+
opt match {
76+
case Some(doc) => Doc.text("Some") + Doc.char('(') + doc + Doc.char(')')
77+
case None => Doc.text("None")
78+
}
79+
}
80+
81+
private def wrap(prefix: Doc, args: List[Doc], suffix: Doc): Doc = {
82+
val body = Doc.intercalate(Doc.char(',') + Doc.line, args)
83+
body.tightBracketBy(prefix, suffix)
84+
}
85+
}

scalafix-core/src/main/scala/scalafix/util/Api.scala

+24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package scalafix.util
22

3+
import scala.meta.Tree
4+
import scalafix.internal.util.Inspect
5+
36
trait Api {
47

58
type RuleName = scalafix.rule.RuleName
@@ -22,4 +25,25 @@ trait Api {
2225
type CustomMessage[T] = scalafix.config.CustomMessage[T]
2326
val CustomMessage = scalafix.config.CustomMessage
2427

28+
implicit class XtensionScalafixTreeInspect(tree: Tree) {
29+
def inspect: String =
30+
Inspect.prettyTree(tree, showFieldNames = false).render(1)
31+
def inspectLabeled: String =
32+
Inspect.prettyTree(tree, showFieldNames = true).render(1)
33+
}
34+
35+
implicit class XtensionScalafixOptionTreeInspect(tree: Option[Tree]) {
36+
def inspect: String =
37+
Inspect.prettyOption(tree, showFieldNames = false).render(1)
38+
def inspectLabeled: String =
39+
Inspect.prettyOption(tree, showFieldNames = true).render(1)
40+
}
41+
42+
implicit class XtensionScalafixListTreeInspect(tree: List[Tree]) {
43+
def inspect: String =
44+
Inspect.prettyList(tree, showFieldNames = false).render(1)
45+
def inspectLabeled: String =
46+
Inspect.prettyList(tree, showFieldNames = true).render(1)
47+
}
48+
2549
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package scalafix.tests.util
2+
3+
import scala.meta._
4+
import org.scalatest.FunSuite
5+
import scalafix.testkit.DiffAssertions
6+
import scalafix.v1._
7+
8+
class InspectSuite extends FunSuite with DiffAssertions {
9+
test("pretty(t)") {
10+
val obtained = q"a.b.c.d".inspect
11+
val expected =
12+
"""|Term.Select(
13+
| Term.Select(
14+
| Term.Select(
15+
| Term.Name("a"),
16+
| Term.Name("b")
17+
| ),
18+
| Term.Name("c")
19+
| ),
20+
| Term.Name("d")
21+
|)""".stripMargin
22+
assert(obtained == expected)
23+
}
24+
25+
test("pretty(t, showFieldNames = true)") {
26+
val obtained = q"a.b.c.d".inspectLabeled
27+
val expected =
28+
"""|Term.Select(
29+
| qual = Term.Select(
30+
| qual = Term.Select(
31+
| qual = Term.Name("a"),
32+
| name = Term.Name("b")
33+
| ),
34+
| name = Term.Name("c")
35+
| ),
36+
| name = Term.Name("d")
37+
|)""".stripMargin
38+
assert(obtained == expected)
39+
}
40+
41+
test("option") {
42+
assertNoDiff(
43+
q"def foo: A = ???".decltpe.inspect,
44+
"""|
45+
|Some(Type.Name("A"))
46+
|""".stripMargin
47+
)
48+
}
49+
50+
test("list") {
51+
assertNoDiff(
52+
q"foo(a)".args.inspect,
53+
"""|List(
54+
| Term.Name("a")
55+
|)
56+
|""".stripMargin
57+
)
58+
}
59+
}

0 commit comments

Comments
 (0)