diff --git a/build.sbt b/build.sbt
index f10157a..e4cd9b8 100644
--- a/build.sbt
+++ b/build.sbt
@@ -8,7 +8,7 @@ lazy val root = project
scalaVersion := dottyVersion,
scalacOptions ++= Seq(
- "-deprecation"
+ "-deprecation", "-feature", "-language:implicitConversions"
),
libraryDependencies ++= Seq(
"org.scala-lang.modules" % "scala-parser-combinators_2.13" % "1.1.2",
diff --git a/src/main/scala/dotty/xml/interpolator/internal/Expand.scala b/src/main/scala/dotty/xml/interpolator/internal/Expand.scala
index df11bd1..46c599d 100644
--- a/src/main/scala/dotty/xml/interpolator/internal/Expand.scala
+++ b/src/main/scala/dotty/xml/interpolator/internal/Expand.scala
@@ -1,20 +1,18 @@
package dotty.xml.interpolator
package internal
-import scala.language.implicitConversions
import scala.quoted._
-import dotty.xml.interpolator.internal.Tree._
+import Tree.*
-object Expand {
+object Expand:
- def apply(nodes: Seq[Node])(implicit ctx: XmlContext, q: Quotes): Expr[scala.xml.Node | scala.xml.NodeBuffer] = {
- if (nodes.size == 1) expandNode(nodes.head).asInstanceOf[Expr[scala.xml.Node]]
+ def apply(nodes: Seq[Node])(using XmlContext, Quotes): Expr[scala.xml.Node | scala.xml.NodeBuffer] =
+ if nodes.size == 1 then expandNode(nodes.head).asInstanceOf[Expr[scala.xml.Node]]
else expandNodes(nodes)
- }
- private def expandNode(node: Node)(implicit ctx: XmlContext, q: Quotes): Expr[Any] = {
- node match {
+ private def expandNode(node: Node)(using XmlContext, Quotes): Expr[Any] =
+ node match
case group: Group => expandGroup(group)
case elem: Elem => expandElem(elem)
case text: Text => expandText(text)
@@ -24,33 +22,32 @@ object Expand {
case procInstr: ProcInstr => expandProcInstr(procInstr)
case entityRef: EntityRef => expandEntityRef(entityRef)
case unparsed: Unparsed => expandUnparsed(unparsed)
- }
- }
+ end expandNode
- private def expandNodes(nodes: Seq[Node])(implicit ctx: XmlContext, q: Quotes): Expr[scala.xml.NodeBuffer] = {
- nodes.foldLeft('{ new _root_.scala.xml.NodeBuffer() })((expr, node) => '{ $expr &+ ${expandNode(node)} } )
- }
+ private def expandNodes(nodes: Seq[Node])(using XmlContext, Quotes): Expr[scala.xml.NodeBuffer] =
+ nodes.foldLeft('{ scala.xml.NodeBuffer() }): (expr, node) =>
+ '{ $expr &+ ${ expandNode(node) } }
- private def expandGroup(group: Group)(implicit ctx: XmlContext, q: Quotes): Expr[scala.xml.Group] =
- '{ new _root_.scala.xml.Group(${expandNodes(group.nodes)}) }
+ private def expandGroup(group: Group)(using XmlContext, Quotes): Expr[scala.xml.Group] =
+ '{ scala.xml.Group(${ expandNodes(group.nodes) }) }
- private def expandElem(elem: Elem)(implicit ctx: XmlContext, q: Quotes): Expr[scala.xml.Elem] = {
+ private def expandElem(elem: Elem)(using ctx: XmlContext, q: Quotes): Expr[scala.xml.Elem] =
val (namespaces, attributes) = elem.attributes.partition(_.isNamespace)
- val prefix = if (elem.prefix.nonEmpty) Expr(elem.prefix) else '{ null: String }
+ val prefix = if elem.prefix.nonEmpty then Expr(elem.prefix) else '{ null }
val label = Expr(elem.label)
val attributes1 = expandAttributes(attributes)
val scope = expandNamespaces(namespaces)
val empty = Expr(elem.end.isEmpty)
- val child = expandNodes(elem.children)(new XmlContext(ctx.args, scope), q)
- if (elem.children.isEmpty)
- '{ new _root_.scala.xml.Elem($prefix, $label, $attributes1, $scope, $empty) }
+ val child = expandNodes(elem.children)(using new XmlContext(ctx.args, scope), q)
+ if elem.children.isEmpty then
+ '{ new scala.xml.Elem($prefix, $label, $attributes1, $scope, $empty) }
else
- '{ new _root_.scala.xml.Elem($prefix, $label, $attributes1, $scope, $empty, _root_.scala.xml.NodeSeq.seqToNodeSeq($child): _*) }
- }
+ '{ new scala.xml.Elem($prefix, $label, $attributes1, $scope, $empty, scala.xml.NodeSeq.seqToNodeSeq($child)*) }
+ end expandElem
- private def expandAttributes(attributes: Seq[Attribute])(implicit ctx: XmlContext, q: Quotes): Expr[scala.xml.MetaData] = {
+ private def expandAttributes(attributes: Seq[Attribute])(using XmlContext, Quotes): Expr[scala.xml.MetaData] =
import quotes.reflect._
- attributes.foldRight('{ _root_.scala.xml.Null }: Expr[scala.xml.MetaData])((attribute, rest) => {
+ attributes.foldRight('{ _root_.scala.xml.Null }: Expr[scala.xml.MetaData]): (attribute, rest) =>
val value = attribute.value match {
case Seq(v) => expandNode(v)
case vs => expandNodes(vs)
@@ -71,57 +68,52 @@ object Expand {
*/
val term = value.asTerm
- if (term.tpe <:< TypeRepr.of[String]) {
+ if term.tpe <:< TypeRepr.of[String] then
val value = term.asExprOf[String]
- if (attribute.prefix.isEmpty) '{ new _root_.scala.xml.UnprefixedAttribute(${Expr(attribute.key)}, $value, $rest) }
- else '{ new _root_.scala.xml.PrefixedAttribute(${Expr(attribute.prefix)}, ${Expr(attribute.key)}, $value, $rest) }
- } else if (term.tpe <:< TypeRepr.of[collection.Seq[scala.xml.Node]]) {
+ if attribute.prefix.isEmpty then '{ scala.xml.UnprefixedAttribute(${ Expr(attribute.key) }, $value, $rest) }
+ else '{ scala.xml.PrefixedAttribute(${ Expr(attribute.prefix) }, ${ Expr(attribute.key) }, $value, $rest) }
+ else if term.tpe <:< TypeRepr.of[collection.Seq[scala.xml.Node]] then
val value = term.asExprOf[collection.Seq[scala.xml.Node]]
- if (attribute.prefix.isEmpty) '{ new _root_.scala.xml.UnprefixedAttribute(${Expr(attribute.key)}, $value, $rest) }
- else '{ new _root_.scala.xml.PrefixedAttribute(${Expr(attribute.prefix)}, ${Expr(attribute.key)}, $value, $rest) }
- } else {
+ if attribute.prefix.isEmpty then '{ scala.xml.UnprefixedAttribute(${ Expr(attribute.key) }, $value, $rest) }
+ else '{ scala.xml.PrefixedAttribute(${ Expr(attribute.prefix) }, ${ Expr(attribute.key) }, $value, $rest) }
+ else
val value = term.asExprOf[Option[collection.Seq[scala.xml.Node]]]
- if (attribute.prefix.isEmpty) '{ new _root_.scala.xml.UnprefixedAttribute(${Expr(attribute.key)}, $value, $rest) }
- else '{ new _root_.scala.xml.PrefixedAttribute(${Expr(attribute.prefix)}, ${Expr(attribute.key)}, $value, $rest) }
- }
- })
- }
+ if attribute.prefix.isEmpty then '{ scala.xml.UnprefixedAttribute(${ Expr(attribute.key) }, $value, $rest) }
+ else '{ scala.xml.PrefixedAttribute(${ Expr(attribute.prefix) }, ${ Expr(attribute.key) }, $value, $rest) }
+ end expandAttributes
- private def expandNamespaces(namespaces: Seq[Attribute])(implicit ctx: XmlContext, q: Quotes): Expr[scala.xml.NamespaceBinding] = {
+ private def expandNamespaces(namespaces: Seq[Attribute])(using XmlContext, Quotes): Expr[Scope] =
import quotes.reflect._
- namespaces.foldLeft(ctx.scope)((rest, namespace) => {
- val prefix = if (namespace.prefix.nonEmpty) Expr(namespace.key) else '{ null: String }
- val uri = (namespace.value.head: @unchecked) match {
+ namespaces.foldLeft(ctx.scope): (rest, namespace) =>
+ val prefix = if namespace.prefix.nonEmpty then Expr(namespace.key) else '{ null }
+ val uri = (namespace.value.head: @unchecked) match
case Text(text) => Expr(text)
case Placeholder(id) =>
- val call = '{ ${ctx.args(id)}(using _root_.scala.xml.TopScope) }
+ val call = '{ ${ctx.args(id)}(using scala.xml.TopScope) }
Expr.betaReduce(call).asExprOf[String]
- }
- '{ new _root_.scala.xml.NamespaceBinding($prefix, $uri, $rest) }
- })
- }
+ '{ scala.xml.NamespaceBinding($prefix, $uri, $rest) }
+ end expandNamespaces
private def expandText(text: Text)(using Quotes): Expr[scala.xml.Text] =
- '{ new _root_.scala.xml.Text(${Expr(text.text)}) }
+ '{ scala.xml.Text(${ Expr(text.text) }) }
private def expandComment(comment: Comment)(using Quotes): Expr[scala.xml.Comment] =
- '{ new _root_.scala.xml.Comment(${Expr(comment.text)}) }
+ '{ scala.xml.Comment(${ Expr(comment.text) }) }
- private def expandPlaceholder(placeholder: Placeholder)(implicit ctx: XmlContext, q: Quotes): Expr[Any] = {
+ private def expandPlaceholder(placeholder: Placeholder)(using XmlContext, Quotes): Expr[Any] =
val arg = ctx.args(placeholder.id)
- val scope = ctx.scope
- Expr.betaReduce('{ $arg(using $scope) })
- }
+ Expr.betaReduce('{ $arg(using ${ ctx.scope }) })
private def expandPCData(pcdata: PCData)(using Quotes): Expr[scala.xml.PCData] =
- '{ new _root_.scala.xml.PCData(${Expr(pcdata.data)}) }
+ '{ scala.xml.PCData(${ Expr(pcdata.data) }) }
private def expandProcInstr(instr: ProcInstr)(using Quotes): Expr[scala.xml.ProcInstr] =
- '{ new _root_.scala.xml.ProcInstr(${Expr(instr.target)}, ${Expr(instr.proctext)}) }
+ '{ scala.xml.ProcInstr(${ Expr(instr.target) }, ${ Expr(instr.proctext) }) }
private def expandEntityRef(ref: EntityRef)(using Quotes): Expr[scala.xml.EntityRef] =
- '{ new _root_.scala.xml.EntityRef(${Expr(ref.name)}) }
+ '{ scala.xml.EntityRef(${ Expr(ref.name) }) }
private def expandUnparsed(unparsed: Unparsed)(using Quotes): Expr[scala.xml.Unparsed] =
- '{ new _root_.scala.xml.Unparsed(${Expr(unparsed.data)}) }
-}
+ '{ scala.xml.Unparsed(${ Expr(unparsed.data) }) }
+
+end Expand
diff --git a/src/main/scala/dotty/xml/interpolator/internal/Hole.scala b/src/main/scala/dotty/xml/interpolator/internal/Hole.scala
index db29f42..656e8b1 100644
--- a/src/main/scala/dotty/xml/interpolator/internal/Hole.scala
+++ b/src/main/scala/dotty/xml/interpolator/internal/Hole.scala
@@ -1,8 +1,7 @@
package dotty.xml.interpolator
package internal
-object Hole {
+object Hole:
val HoleStart = 0xE000.toChar.toString
val HoleChar = 0xE001.toChar.toString
- def encode(i: Int) = HoleStart + HoleChar * i
-}
\ No newline at end of file
+ def encode(i: Int) = HoleStart + HoleChar * i
\ No newline at end of file
diff --git a/src/main/scala/dotty/xml/interpolator/internal/Macro.scala b/src/main/scala/dotty/xml/interpolator/internal/Macro.scala
index a2e5681..65be6bc 100644
--- a/src/main/scala/dotty/xml/interpolator/internal/Macro.scala
+++ b/src/main/scala/dotty/xml/interpolator/internal/Macro.scala
@@ -6,38 +6,43 @@ import scala.quoted._
import scala.collection.mutable.ArrayBuffer
import scala.language.implicitConversions
-object Macro {
+object Macro:
- def impl(strCtxExpr: Expr[StringContext], argsExpr: Expr[Seq[Scope ?=> Any]], scope: Expr[Scope])(using qctx: Quotes): Expr[scala.xml.Node | scala.xml.NodeBuffer] = {
- ((strCtxExpr, argsExpr): @unchecked) match {
+ /** ??? */
+ def impl(strCtxExpr: Expr[StringContext], argsExpr: Expr[Seq[Scope ?=> Any]], scope: Expr[Scope])
+ (using Quotes): Expr[scala.xml.Node | scala.xml.NodeBuffer] =
+
+ (strCtxExpr, argsExpr) match
case ('{ StringContext(${Varargs(parts)}: _*) }, Varargs(args)) =>
+
val (xmlStr, offsets) = encode(parts)
- implicit val ctx: XmlContext = new XmlContext(args, scope)
- implicit val reporter: Reporter = new Reporter {
- import quotes.reflect._
- def error(msg: String, idx: Int): Unit = {
- val (part, offset) = Reporter.from(idx, offsets, parts)
- val pos = part.asTerm.pos
- val (srcF, start) = (pos.sourceFile, pos.start)
- report.error(msg, Position(srcF, start + offset, start + offset + 1))
- }
+ given XmlContext = new XmlContext(args, scope)
+ given Reporter = new Reporter {
+ import quotes.reflect.*
+
+ def error(msg: String, idx: Int): Unit = {
+ val (part, offset) = Reporter.from(idx, offsets, parts)
+ val pos = part.asTerm.pos
+ val (srcF, start) = (pos.sourceFile, pos.start)
+ report.error(msg, Position(srcF, start + offset, start + offset + 1))
+ }
+
+ def error(msg: String, expr: Expr[Any]): Unit =
+ report.error(msg, expr)
+ }
- def error(msg: String, expr: Expr[Any]): Unit = {
- report.error(msg, expr)
- }
- }
implCore(xmlStr)
- }
- }
+ end impl
- def implErrors(strCtxExpr: Expr[StringContext], argsExpr: Expr[Seq[Scope ?=> Any]], scope: Expr[Scope])(using qctx: Quotes): Expr[List[(Int, String)]] = {
- ((strCtxExpr, argsExpr): @unchecked) match {
+ def implErrors(strCtxExpr: Expr[StringContext], argsExpr: Expr[Seq[Scope ?=> Any]], scope: Expr[Scope])
+ (using Quotes): Expr[List[(Int, String)]] =
+ (strCtxExpr, argsExpr) match
case ('{ StringContext(${Varargs(parts)}: _*) }, Varargs(args)) =>
val errors = List.newBuilder[Expr[(Int, String)]]
val (xmlStr, offsets) = encode(parts)
- implicit val ctx: XmlContext = new XmlContext(args, scope)
- implicit val reporter: Reporter = new Reporter {
+ given XmlContext = new XmlContext(args, scope)
+ given Reporter = new Reporter {
import quotes.reflect._
def error(msg: String, idx: Int): Unit = {
@@ -53,48 +58,43 @@ object Macro {
}
implCore(xmlStr)
Expr.ofList(errors.result())
- }
- }
+ end implErrors
- private def implCore(xmlStr: String)(using XmlContext, Reporter, Quotes): Expr[scala.xml.Node | scala.xml.NodeBuffer] = {
+ private def implCore(xmlStr: String)(using XmlContext, Reporter, Quotes): Expr[scala.xml.Node | scala.xml.NodeBuffer] =
- import Parse.{apply => parse}
- import Transform.{apply => transform}
- import Validate.{apply => validate}
- import TypeCheck.{apply => typecheck}
- import Expand.{apply => expand}
+ import Parse.apply as parse
+ import Transform.apply as transform
+ import Validate.apply as validate
+ import TypeCheck.apply as typecheck
+ import Expand.apply as expand
- val interpolate = (
- parse
- andThen transform
- andThen validate
- andThen typecheck
- andThen expand
- )
+ val interpolate =
+ parse andThen
+ transform andThen
+ validate andThen
+ typecheck andThen
+ expand
interpolate(xmlStr)
- }
+ end implCore
- private def encode(parts: Seq[Expr[String]])(using Quotes): (String, Array[Int]) = {
+ private def encode(parts: Seq[Expr[String]])(using Quotes): (String, Array[Int]) =
val sb = new StringBuilder()
val bf = ArrayBuffer.empty[Int]
- def appendPart(part: Expr[String]) = {
+ def appendPart(part: Expr[String]) =
bf += sb.length
sb ++= part.valueOrAbort
bf += sb.length
- }
- def appendHole(index: Int) = {
- sb ++= Hole.encode(index)
- }
+ def appendHole(index: Int) = sb ++= Hole.encode(index)
- for ((part, index) <- parts.init.zipWithIndex) {
+ for (part, index) <- parts.init.zipWithIndex do
appendPart(part)
appendHole(index)
- }
appendPart(parts.last)
(sb.toString, bf.toArray)
- }
-}
+ end encode
+
+end Macro
diff --git a/src/main/scala/dotty/xml/interpolator/internal/Reporter.scala b/src/main/scala/dotty/xml/interpolator/internal/Reporter.scala
index fce4cd2..0f6f56a 100644
--- a/src/main/scala/dotty/xml/interpolator/internal/Reporter.scala
+++ b/src/main/scala/dotty/xml/interpolator/internal/Reporter.scala
@@ -1,14 +1,13 @@
package dotty.xml.interpolator
package internal
-import scala.quoted._
+import scala.quoted.*
-trait Reporter {
+trait Reporter:
def error(msg: String, idx: Int): Unit
def error(msg: String, expr: Expr[Any]): Unit
-}
-object Reporter {
+object Reporter:
def from(idx: Int, offsets: Array[Int], parts: Seq[Expr[String]]): (Expr[String], Int) = {
val index = offsets.lastIndexWhere(idx >= _)
val isWithinHoleOrAtTheEnd = index % 2 != 0
@@ -17,5 +16,4 @@ object Reporter {
case false => (index / 2, idx - offsets(index))
}
(parts(partIndex), offset)
- }
-}
\ No newline at end of file
+ }
\ No newline at end of file
diff --git a/src/main/scala/dotty/xml/interpolator/internal/Transform.scala b/src/main/scala/dotty/xml/interpolator/internal/Transform.scala
index 5e77265..9a0bacb 100644
--- a/src/main/scala/dotty/xml/interpolator/internal/Transform.scala
+++ b/src/main/scala/dotty/xml/interpolator/internal/Transform.scala
@@ -1,16 +1,17 @@
package dotty.xml.interpolator
package internal
-import dotty.xml.interpolator.internal.Tree._
+import Tree.*
-object Transform {
- def apply(nodes: Seq[Node]): Seq[Node] = {
- nodes.map {
+object Transform:
+
+ def apply(nodes: Seq[Node]): Seq[Node] =
+ nodes.map:
case elem : Elem =>
val children = apply(elem.children)
- if (elem.name == "xml:group" && !elem.end.isEmpty) Group(elem.children).setPos(elem.pos)
+ if elem.name == "xml:group" && !elem.end.isEmpty then Group(elem.children).setPos(elem.pos)
else elem.copy(children = children).setPos(elem.pos)
case node => node
- }
- }
-}
\ No newline at end of file
+ end apply
+
+end Transform
\ No newline at end of file
diff --git a/src/main/scala/dotty/xml/interpolator/internal/Tree.scala b/src/main/scala/dotty/xml/interpolator/internal/Tree.scala
index cec244a..c7db1d8 100644
--- a/src/main/scala/dotty/xml/interpolator/internal/Tree.scala
+++ b/src/main/scala/dotty/xml/interpolator/internal/Tree.scala
@@ -1,27 +1,34 @@
package dotty.xml.interpolator
package internal
-import scala.util.parsing.input._
+import scala.util.parsing.input.*
+
+object Tree:
-object Tree {
- sealed abstract class Node extends Positional
- final case class Group(nodes: Seq[Node]) extends Node
- final case class Elem(name: String, attributes: Seq[Attribute], children: Seq[Node], end: Option[String]) extends Node {
- def prefix: String = name.take(prefixEnd)
- def label: String = name.drop(prefixEnd + 1)
- private def prefixEnd = name.indexOf(':')
- }
- final case class Text(text: String) extends Node
- final case class Comment(text: String) extends Node
- final case class Placeholder(id: Int) extends Node
- final case class PCData(data: String) extends Node
- final case class ProcInstr(target: String, proctext: String) extends Node
- final case class EntityRef(name: String) extends Node
- final case class Unparsed(data: String) extends Node
final case class Attribute(name: String, value: Seq[Node]) extends Positional {
def prefix: String = name.take(prefixEnd)
def key: String = name.drop(prefixEnd + 1)
def isNamespace = name.startsWith("xmlns")
private def prefixEnd = name.indexOf(':')
}
-}
\ No newline at end of file
+
+ enum Node extends Positional:
+ case Group(nodes: Seq[Node])
+ case Elem(name: String, attributes: Seq[Attribute], children: Seq[Node], end: Option[String])
+ case Text(text: String)
+ case Comment(text: String)
+ case Placeholder(id: Int)
+ case PCData(data: String)
+ case ProcInstr(target: String, proctext: String)
+ case EntityRef(name: String)
+ case Unparsed(data: String)
+ end Node
+
+ export Node.*
+
+ extension (elem: Node.Elem)
+ private inline def prefixEnd = elem.name.indexOf(':')
+ def prefix: String = elem.name.take(prefixEnd)
+ def label: String = elem.name.drop(prefixEnd + 1)
+
+end Tree
\ No newline at end of file
diff --git a/src/main/scala/dotty/xml/interpolator/internal/TypeCheck.scala b/src/main/scala/dotty/xml/interpolator/internal/TypeCheck.scala
index 72fb42f..f21326b 100644
--- a/src/main/scala/dotty/xml/interpolator/internal/TypeCheck.scala
+++ b/src/main/scala/dotty/xml/interpolator/internal/TypeCheck.scala
@@ -1,45 +1,41 @@
package dotty.xml.interpolator
package internal
-import scala.quoted._
+import scala.quoted.*
-import dotty.xml.interpolator.internal.Tree._
+import Tree.*
-object TypeCheck {
- def apply(nodes: Seq[Node])(using XmlContext, Reporter, Quotes): Seq[Node] = {
+object TypeCheck:
+
+ def apply(nodes: Seq[Node])(using XmlContext, Reporter, Quotes): Seq[Node] =
typecheck(nodes)
nodes
- }
- private def typecheck(nodes: Seq[Node])(using XmlContext, Reporter)(using Quotes): Unit = {
- import quotes.reflect._
- nodes.foreach {
+ private def typecheck(nodes: Seq[Node])(using XmlContext, Reporter, Quotes): Unit =
+ import quotes.reflect.*
+ nodes.foreach:
case elem : Elem =>
- elem.attributes.foreach(attribute =>
- attribute.value match {
+ elem.attributes.foreach: attribute =>
+ attribute.value match
case Seq(Placeholder(id)) =>
- val dummy = '{ _root_.scala.xml.TopScope }
- val expr = summon[XmlContext].args(id)
- val term = Expr.betaReduce('{$expr(using $dummy)}).asTerm
- val expected = attribute.isNamespace match {
+ val expr = ctx.args(id)
+ val term = Expr.betaReduce('{$expr(using scala.xml.TopScope)}).asTerm
+ val expected = attribute.isNamespace match
case true => Seq(TypeRepr.of[String])
case _ => Seq(
TypeRepr.of[String],
TypeRepr.of[collection.Seq[scala.xml.Node]],
TypeRepr.of[Option[collection.Seq[scala.xml.Node]]]
)
- }
- if (!expected.exists(term.tpe <:< _)) {
- summon[Reporter].error(
+ if !expected.exists(term.tpe <:< _) then
+ reporter.error(
s"""type mismatch;
| found : ${term.tpe.widen.show}
| required: ${expected.map(_.show).mkString(" | ")}
""".stripMargin, term.asExpr)
- }
case _ =>
- })
typecheck(elem.children)
case _ =>
- }
- }
-}
+ end typecheck
+
+end TypeCheck
diff --git a/src/main/scala/dotty/xml/interpolator/internal/Validate.scala b/src/main/scala/dotty/xml/interpolator/internal/Validate.scala
index 5490830..45fb1c4 100644
--- a/src/main/scala/dotty/xml/interpolator/internal/Validate.scala
+++ b/src/main/scala/dotty/xml/interpolator/internal/Validate.scala
@@ -1,28 +1,24 @@
package dotty.xml.interpolator
package internal
-import scala.language.implicitConversions
+import Tree.*
-import dotty.xml.interpolator.internal.Tree._
-
-object Validate {
- def apply(nodes: Seq[Node])(using Reporter): Seq[Node] = {
+object Validate:
+ def apply(nodes: Seq[Node])(using Reporter): Seq[Node] =
mismatchedElements(nodes)
duplicateAttributes(nodes)
nodes
- }
- private def mismatchedElements(nodes: Seq[Node])(using reporter: Reporter): Unit = {
- nodes.foreach {
+ private def mismatchedElements(nodes: Seq[Node])(using Reporter): Unit =
+ nodes.foreach:
case elem@Elem(name, _, _, Some(end)) =>
- if (name != end) reporter.error(s"closing tag `${name}` expected but `${end}` found", elem.pos)
+ if name != end then reporter.error(s"closing tag `$name` expected but `$end` found", elem.pos)
mismatchedElements(elem.children)
case _ =>
- }
- }
+ end mismatchedElements
- private def duplicateAttributes(nodes: Seq[Node])(using reporter: Reporter): Unit = {
- nodes.foreach {
+ private def duplicateAttributes(nodes: Seq[Node])(using Reporter): Unit =
+ nodes.foreach:
case Elem(_, attributes, children, _) =>
attributes
.groupBy(_.name)
@@ -30,6 +26,6 @@ object Validate {
.foreach { attribute => reporter.error(s"attribute `${attribute.name}` may only be defined once", attribute.pos) }
duplicateAttributes(children)
case _ =>
- }
- }
-}
+ end duplicateAttributes
+
+end Validate
\ No newline at end of file
diff --git a/src/main/scala/dotty/xml/interpolator/internal/XmlContext.scala b/src/main/scala/dotty/xml/interpolator/internal/XmlContext.scala
index b7e9c62..991d768 100644
--- a/src/main/scala/dotty/xml/interpolator/internal/XmlContext.scala
+++ b/src/main/scala/dotty/xml/interpolator/internal/XmlContext.scala
@@ -1,6 +1,6 @@
package dotty.xml.interpolator
package internal
-import scala.quoted._
+import scala.quoted.*
-class XmlContext(val args: Seq[Expr[Scope ?=> Any]], val scope: Expr[scala.xml.NamespaceBinding])
+class XmlContext(val args: Seq[Expr[Scope ?=> Any]], val scope: Expr[Scope])
diff --git a/src/main/scala/dotty/xml/interpolator/internal/package.scala b/src/main/scala/dotty/xml/interpolator/internal/package.scala
index f7a2798..8608bc8 100644
--- a/src/main/scala/dotty/xml/interpolator/internal/package.scala
+++ b/src/main/scala/dotty/xml/interpolator/internal/package.scala
@@ -1,12 +1,13 @@
-package dotty.xml.interpolator.internal
+package dotty.xml.interpolator
+package internal
-import scala.util.parsing.input._
+import scala.util.parsing.input.*
-given Conversion[Position, Int] with {
- def apply(pos: Position): Int = {
- pos match {
+given Conversion[Position, Int] with
+ def apply(pos: Position): Int =
+ pos match
case OffsetPosition(_, offset) => offset
case _ => throw new Exception("expected offset position")
- }
- }
-}
+
+private[internal] inline def ctx(using XmlContext): XmlContext = summon
+private[internal] inline def reporter(using Reporter): Reporter = summon
diff --git a/src/main/scala/dotty/xml/interpolator/package.scala b/src/main/scala/dotty/xml/interpolator/package.scala
index a5cba9b..03a0898 100644
--- a/src/main/scala/dotty/xml/interpolator/package.scala
+++ b/src/main/scala/dotty/xml/interpolator/package.scala
@@ -1,9 +1,12 @@
package dotty.xml.interpolator
-import scala.quoted._
+import scala.quoted.*
-type Scope = scala.xml.NamespaceBinding
-implicit val top: Scope = scala.xml.TopScope
+private [interpolator] type Scope = scala.xml.NamespaceBinding
-extension (inline ctx: StringContext) transparent inline def xml (inline args: (Scope ?=> Any)*)(using scope: Scope): Any =
- ${ dotty.xml.interpolator.internal.Macro.impl('ctx, 'args, 'scope) }
+given Scope = scala.xml.TopScope
+
+/** TODO: THIS NEED TO BE DOCUMENTED */
+extension (inline ctx: StringContext)
+ transparent inline def xml (inline args: (Scope ?=> Any)*)(using inline scope: Scope): Any =
+ ${ internal.Macro.impl('ctx, 'args, 'scope) }
diff --git a/src/test/scala/dotty/xml/interpolator/TrailingWhitespaceTest.scala b/src/test/scala/dotty/xml/interpolator/TrailingWhitespaceTest.scala
index 854d3f7..18ceb72 100644
--- a/src/test/scala/dotty/xml/interpolator/TrailingWhitespaceTest.scala
+++ b/src/test/scala/dotty/xml/interpolator/TrailingWhitespaceTest.scala
@@ -1,7 +1,8 @@
package dotty.xml.interpolator
-import org.junit.Test
+import org.junit.*
import org.junit.Assert._
+import scala.language.experimental
class TrailingWhitespaceTest {
@@ -29,6 +30,7 @@ class TrailingWhitespaceTest {
assert(xml" " ≈ )
}
+ /*
@Test def multiline(): Unit = {
val expected = xml"""
@@ -43,4 +45,6 @@ class TrailingWhitespaceTest {
assert(expected ≈ obtained)
}
+ */
+
}
\ No newline at end of file