From 310b384361c4ef45c2d58db4680792160d8f183a Mon Sep 17 00:00:00 2001
From: xuwei-k <6b656e6a69@gmail.com>
Date: Sat, 15 Apr 2023 14:19:49 +0900
Subject: [PATCH] Token
---
.../scala/scalameta_ast/ScalametaAST.scala | 86 +++++++++++++++++--
.../main/scala/scalameta_ast/TreeType.scala | 8 ++
.../scalameta_ast/ScalametaASTSpec.scala | 79 +++++++++++++++++
sources/index.html | 4 +
sources/main.js | 5 +-
5 files changed, 176 insertions(+), 6 deletions(-)
create mode 100644 core/src/main/scala/scalameta_ast/TreeType.scala
diff --git a/core/src/main/scala/scalameta_ast/ScalametaAST.scala b/core/src/main/scala/scalameta_ast/ScalametaAST.scala
index 1e1d2b1..3cf7467 100644
--- a/core/src/main/scala/scalameta_ast/ScalametaAST.scala
+++ b/core/src/main/scala/scalameta_ast/ScalametaAST.scala
@@ -8,6 +8,7 @@ import scala.meta._
import scala.meta.common.Convert
import scala.meta.parsers.Parse
import scala.meta.parsers.Parsed
+import scala.meta.tokens.Token
import scala.util.control.NonFatal
class ScalametaAST {
@@ -121,6 +122,72 @@ class ScalametaAST {
implicitly[Parse[Term]].apply(Input.String(str), dialects.Scala3).toOption.exists(_.is[Term.Name])
}
+ private def treeToString(tree: Tree, treeType: TreeType): String = {
+ treeType match {
+ case TreeType.Tree =>
+ scalametaBugWorkaround.foldLeft(tree.structure) { case (s, (x1, x2)) =>
+ s.replace(x1, x2)
+ }
+ case TreeType.Token =>
+ tree.tokens.tokens.map { x =>
+ val n = x.getClass.getSimpleName
+ def q(a: String): String = s"(\"${a}\")"
+
+ PartialFunction
+ .condOpt(x) {
+ case y: Token.Ident =>
+ s"Ident${q(y.value)}"
+ case y: Token.Comment =>
+ s"Comment${q(y.value)}"
+ case y: Token.Interpolation.Id =>
+ s"Interpolation.Id${q(y.value)}"
+ case y: Token.Interpolation.Part =>
+ s"Interpolation.Part${q(y.value)}"
+ case _: Token.Interpolation.Start =>
+ s"Interpolation.$n"
+ case _: Token.Interpolation.SpliceStart =>
+ s"Interpolation.$n"
+ case _: Token.Interpolation.SpliceEnd =>
+ s"Interpolation.$n"
+ case _: Token.Interpolation.End =>
+ s"Interpolation.$n"
+ case y: Token.Constant[?] =>
+ y match {
+ case z: Token.Constant.Int =>
+ s"Constant.Int(BigInt${q(z.value.toString)})"
+ case z: Token.Constant.Long =>
+ s"Constant.Long(BigInt${q(z.value.toString)})"
+ case z: Token.Constant.Float =>
+ s"Constant.Float(BigDecimal${q(z.value.toString)})"
+ case z: Token.Constant.Double =>
+ s"Constant.Double(BigDecimal${q(z.value.toString)})"
+ case z: Token.Constant.Char =>
+ s"Constant.Char('${z.value}')"
+ case z: Token.Constant.Symbol =>
+ s"Constant.Symbol(scala.Symbol${q(z.value.name)})"
+ case z: Token.Constant.String =>
+ s"Constant.String${q(z.value)}"
+ }
+ case _: Token.Xml.Start =>
+ s"Xml.${n}"
+ case y: Token.Xml.Part =>
+ s"Xml.Part${q(y.value)}"
+ case _: Token.Xml.SpliceStart =>
+ s"Xml.${n}"
+ case _: Token.Xml.SpliceEnd =>
+ s"Xml.${n}"
+ case _: Token.Xml.End =>
+ s"Xml.${n}"
+ case _: Token.Indentation.Indent =>
+ s"Indentation.${n}"
+ case _: Token.Indentation.Outdent =>
+ s"Indentation.${n}"
+ }
+ .getOrElse(n)
+ }.map("Token." + _).mkString("Seq(", ", ", ")")
+ }
+ }
+
def convert(
src: String,
format: Boolean,
@@ -134,7 +201,7 @@ class ScalametaAST {
): Output = {
val input = convert.apply(src)
val (ast, astBuildMs) = stopwatch {
- val x = loop(
+ val tree = loop(
input,
for {
x1 <- parsers
@@ -147,10 +214,19 @@ class ScalametaAST {
)
}
} yield (x1, x2)
- ).structure
- scalametaBugWorkaround.foldLeft(x) { case (s, (x1, x2)) =>
- s.replace(x1, x2)
- }
+ )
+
+ treeToString(
+ tree = tree,
+ treeType = {
+ outputType match {
+ case "tokens" =>
+ TreeType.Token
+ case _ =>
+ TreeType.Tree
+ }
+ }
+ )
}
val ruleNameRaw = ruleNameOption.getOrElse("Example").filterNot(char => char == '`' || char == '"')
val ruleName = {
diff --git a/core/src/main/scala/scalameta_ast/TreeType.scala b/core/src/main/scala/scalameta_ast/TreeType.scala
new file mode 100644
index 0000000..1f3d855
--- /dev/null
+++ b/core/src/main/scala/scalameta_ast/TreeType.scala
@@ -0,0 +1,8 @@
+package scalameta_ast
+
+sealed abstract class TreeType extends Product with Serializable
+
+object TreeType {
+ case object Tree extends TreeType
+ case object Token extends TreeType
+}
diff --git a/core/src/test/scala/scalameta_ast/ScalametaASTSpec.scala b/core/src/test/scala/scalameta_ast/ScalametaASTSpec.scala
index bc02e7b..8679626 100644
--- a/core/src/test/scala/scalameta_ast/ScalametaASTSpec.scala
+++ b/core/src/test/scala/scalameta_ast/ScalametaASTSpec.scala
@@ -58,6 +58,85 @@ class ScalametaASTSpec extends AnyFreeSpec {
|""".stripMargin
assert(result.ast == expect)
}
+
+ "convert token" in {
+ val result = main.convert(
+ src = """def x(y: Z) = ('y, 'a', "b", 1.5, 4.4f, 2L, 3, s"x1${x2}",