aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-09-24 19:13:20 +0200
committerMartin Odersky <odersky@gmail.com>2016-09-24 19:16:29 +0200
commit962377ebc23a4c6a2757bee99e6558dd6a93c067 (patch)
tree19134d4bfb0e804110b74c623e2460f51891af2a /src/dotty
parente2e1e8a43123de3c5594bad24af486b730e0b3c7 (diff)
downloaddotty-962377ebc23a4c6a2757bee99e6558dd6a93c067.tar.gz
dotty-962377ebc23a4c6a2757bee99e6558dd6a93c067.tar.bz2
dotty-962377ebc23a4c6a2757bee99e6558dd6a93c067.zip
Make InterpolatedString conform to ordering requirement
Arrange its sub-elements so that they appear strictly left to right.
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/ast/Desugar.scala14
-rw-r--r--src/dotty/tools/dotc/ast/Positioned.scala1
-rw-r--r--src/dotty/tools/dotc/ast/untpd.scala22
-rw-r--r--src/dotty/tools/dotc/parsing/Parsers.scala40
-rw-r--r--src/dotty/tools/dotc/printing/RefinedPrinter.scala14
5 files changed, 51 insertions, 40 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala
index d7ae1bf85..1bfbcdbeb 100644
--- a/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/src/dotty/tools/dotc/ast/Desugar.scala
@@ -889,7 +889,15 @@ object desugar {
Apply(
ref(defn.SymbolClass.companionModule.termRef),
Literal(Constant(str)) :: Nil)
- case InterpolatedString(id, strs, elems) =>
+ case InterpolatedString(id, segments) =>
+ val strs = segments map {
+ case ts: Thicket => ts.trees.head
+ case t => t
+ }
+ val elems = segments flatMap {
+ case ts: Thicket => ts.trees.tail
+ case t => Nil
+ }
Apply(Select(Apply(Ident(nme.StringContext), strs), id), elems)
case InfixOp(l, op, r) =>
if (ctx.mode is Mode.Type)
@@ -1054,8 +1062,8 @@ object desugar {
ctx.error("illegal variable in pattern alternative", vble.pos)
case Annotated(arg, _) =>
collect(arg)
- case InterpolatedString(_, _, elems) =>
- elems foreach collect
+ case InterpolatedString(_, segments) =>
+ segments foreach collect
case InfixOp(left, _, right) =>
collect(left)
collect(right)
diff --git a/src/dotty/tools/dotc/ast/Positioned.scala b/src/dotty/tools/dotc/ast/Positioned.scala
index 1e992bd01..216446e93 100644
--- a/src/dotty/tools/dotc/ast/Positioned.scala
+++ b/src/dotty/tools/dotc/ast/Positioned.scala
@@ -171,7 +171,6 @@ abstract class Positioned extends DotClass with Product {
}
if (nonOverlapping) {
this match {
- case _: InterpolatedString => // ignore, strings and elements are interleaved in source, separated in tree
case _: Function => // ignore, functions produced from wildcards (e.g. (_ op _) mix parameters and body
case _ =>
assert(!lastPos.exists || !p.pos.exists || lastPos.end <= p.pos.start,
diff --git a/src/dotty/tools/dotc/ast/untpd.scala b/src/dotty/tools/dotc/ast/untpd.scala
index fdc4be823..7e1892253 100644
--- a/src/dotty/tools/dotc/ast/untpd.scala
+++ b/src/dotty/tools/dotc/ast/untpd.scala
@@ -35,7 +35,13 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
case class ParsedTry(expr: Tree, handler: Tree, finalizer: Tree) extends TermTree
case class SymbolLit(str: String) extends TermTree
- case class InterpolatedString(id: TermName, strings: List[Literal], elems: List[Tree]) extends TermTree
+
+ /** An interpolated string
+ * @param segments a list of two element tickets consisting of string literal and argument tree,
+ * possibly with a simple string literal as last element of the list
+ */
+ case class InterpolatedString(id: TermName, segments: List[Tree]) extends TermTree
+
case class Function(args: List[Tree], body: Tree) extends Tree {
override def isTerm = body.isTerm
override def isType = body.isType
@@ -305,9 +311,9 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
case tree: SymbolLit if str == tree.str => tree
case _ => untpd.SymbolLit(str).withPos(tree.pos)
}
- def InterpolatedString(tree: Tree)(id: TermName, strings: List[Literal], elems: List[Tree]) = tree match {
- case tree: InterpolatedString if (id eq tree.id) && (strings eq tree.strings) && (elems eq tree.elems) => tree
- case _ => untpd.InterpolatedString(id, strings, elems).withPos(tree.pos)
+ def InterpolatedString(tree: Tree)(id: TermName, segments: List[Tree]) = tree match {
+ case tree: InterpolatedString if (id eq tree.id) && (segments eq tree.segments) => tree
+ case _ => untpd.InterpolatedString(id, segments).withPos(tree.pos)
}
def Function(tree: Tree)(args: List[Tree], body: Tree) = tree match {
case tree: Function if (args eq tree.args) && (body eq tree.body) => tree
@@ -379,8 +385,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
cpy.ParsedTry(tree)(transform(expr), transform(handler), transform(finalizer))
case SymbolLit(str) =>
cpy.SymbolLit(tree)(str)
- case InterpolatedString(id, strings, elems) =>
- cpy.InterpolatedString(tree)(id, transformSub(strings), transform(elems))
+ case InterpolatedString(id, segments) =>
+ cpy.InterpolatedString(tree)(id, transform(segments))
case Function(args, body) =>
cpy.Function(tree)(transform(args), transform(body))
case InfixOp(left, op, right) =>
@@ -426,8 +432,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
this(this(this(x, expr), handler), finalizer)
case SymbolLit(str) =>
x
- case InterpolatedString(id, strings, elems) =>
- this(this(x, strings), elems)
+ case InterpolatedString(id, segments) =>
+ this(x, segments)
case Function(args, body) =>
this(this(x, args), body)
case InfixOp(left, op, right) =>
diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala
index b8ec38268..6ba576a34 100644
--- a/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -600,30 +600,30 @@ object Parsers {
}
private def interpolatedString(inPattern: Boolean = false): Tree = atPos(in.offset) {
- val partsBuf = new ListBuffer[Literal]
- val exprBuf = new ListBuffer[Tree]
+ val segmentBuf = new ListBuffer[Tree]
val interpolator = in.name
in.nextToken()
while (in.token == STRINGPART) {
- partsBuf += literal().asInstanceOf[Literal]
- exprBuf += atPos(in.offset) {
- if (in.token == IDENTIFIER)
- termIdent()
- else if (in.token == THIS) {
- in.nextToken()
- This(tpnme.EMPTY)
- }
- else if (in.token == LBRACE)
- if (inPattern) Block(Nil, inBraces(pattern()))
- else expr()
- else {
- syntaxErrorOrIncomplete("error in interpolated string: identifier or block expected")
- EmptyTree
- }
- }
+ segmentBuf += Thicket(List(
+ literal(),
+ atPos(in.offset) {
+ if (in.token == IDENTIFIER)
+ termIdent()
+ else if (in.token == THIS) {
+ in.nextToken()
+ This(tpnme.EMPTY)
+ }
+ else if (in.token == LBRACE)
+ if (inPattern) Block(Nil, inBraces(pattern()))
+ else expr()
+ else {
+ syntaxErrorOrIncomplete("error in interpolated string: identifier or block expected")
+ EmptyTree
+ }
+ }))
}
- if (in.token == STRINGLIT) partsBuf += literal().asInstanceOf[Literal]
- InterpolatedString(interpolator, partsBuf.toList, exprBuf.toList)
+ if (in.token == STRINGLIT) segmentBuf += literal()
+ InterpolatedString(interpolator, segmentBuf.toList)
}
/* ------------- NEW LINES ------------------------------------------------- */
diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index 9744e7026..32d152c2e 100644
--- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -446,15 +446,13 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
}
case SymbolLit(str) =>
"'" + str
- case InterpolatedString(id, strings, elems) =>
- def interleave(strs: List[Text], elems: List[Text]): Text = ((strs, elems): @unchecked) match {
- case (Nil, Nil) => ""
- case (str :: Nil, Nil) => str
- case (str :: strs1, elem :: elems1) => str ~ elem ~ interleave(strs1, elems1)
+ case InterpolatedString(id, segments) =>
+ def strText(str: Literal) = Str(escapedString(str.const.stringValue))
+ def segmentText(segment: Tree) = segment match {
+ case Thicket(List(str: Literal, expr)) => strText(str) ~ "{" ~ toTextGlobal(expr) ~ "}"
+ case str: Literal => strText(str)
}
- val strTexts = strings map (str => Str(escapedString(str.const.stringValue)))
- val elemsTexts = elems map (elem => "{" ~ toTextGlobal(elem) ~ "}")
- toText(id) ~ "\"" ~ interleave(strTexts, elemsTexts) ~ "\""
+ toText(id) ~ "\"" ~ Text(segments map segmentText, "") ~ "\""
case Function(args, body) =>
var implicitSeen: Boolean = false
def argToText(arg: Tree) = arg match {