diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-05-20 14:39:40 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-05-20 14:39:40 +0200 |
commit | 2be2b5579a9cb07ea35558e5a01c5590141d8825 (patch) | |
tree | 1e5a91fd710a2bb08c5922b2d69cab5517cb1fa3 /src | |
parent | d99aa87b07f0414d5bdd9c921ff338ecdfb29f44 (diff) | |
parent | dc5251eda0a48b9e749a157d689d3ea497ea7045 (diff) | |
download | scala-2be2b5579a9cb07ea35558e5a01c5590141d8825.tar.gz scala-2be2b5579a9cb07ea35558e5a01c5590141d8825.tar.bz2 scala-2be2b5579a9cb07ea35558e5a01c5590141d8825.zip |
Merge pull request #3761 from som-snytt/issue/8507-only
SI-8507 Avoid lazy val in StringContext
Diffstat (limited to 'src')
-rw-r--r-- | src/library/scala/StringContext.scala | 97 |
1 files changed, 50 insertions, 47 deletions
diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala index cd928a2b61..c0468e8b02 100644 --- a/src/library/scala/StringContext.scala +++ b/src/library/scala/StringContext.scala @@ -8,6 +8,9 @@ package scala +import java.lang.{ StringBuilder => JLSBuilder } +import scala.annotation.tailrec + /** This class provides the basic mechanism to do String Interpolation. * String Interpolation allows users * to embed variable references directly in *processed* string literals. @@ -41,7 +44,7 @@ package scala * val x: JSONObject = json"{ a: $a }" * }}} * - * Here the `JsonHelper` extenion class implicitly adds the `json` method to + * Here the `JsonHelper` extension class implicitly adds the `json` method to * `StringContext` which can be used for `json` string literals. * * @since 2.10.0 @@ -118,7 +121,7 @@ case class StringContext(parts: String*) { checkLengths(args) val pi = parts.iterator val ai = args.iterator - val bldr = new java.lang.StringBuilder(process(pi.next())) + val bldr = new JLSBuilder(process(pi.next())) while (ai.hasNext) { bldr append ai.next bldr append process(pi.next()) @@ -186,60 +189,60 @@ object StringContext { */ def treatEscapes(str: String): String = treatEscapes0(str, strict = false) + /** Treats escapes, but disallows octal escape sequences. */ def processEscapes(str: String): String = treatEscapes0(str, strict = true) private def treatEscapes0(str: String, strict: Boolean): String = { - lazy val bldr = new java.lang.StringBuilder val len = str.length - var start = 0 - var cur = 0 - var idx = 0 - def output(ch: Char) = { - bldr.append(str, start, cur) - bldr append ch - start = idx - } - while (idx < len) { - cur = idx - if (str(idx) == '\\') { - idx += 1 - if (idx >= len) throw new InvalidEscapeException(str, cur) - if ('0' <= str(idx) && str(idx) <= '7') { - if (strict) throw new InvalidEscapeException(str, cur) - val leadch = str(idx) - var oct = leadch - '0' - idx += 1 - if (idx < len && '0' <= str(idx) && str(idx) <= '7') { - oct = oct * 8 + str(idx) - '0' - idx += 1 - if (idx < len && leadch <= '3' && '0' <= str(idx) && str(idx) <= '7') { - oct = oct * 8 + str(idx) - '0' + // replace escapes with given first escape + def replace(first: Int): String = { + val b = new JLSBuilder + // append replacement starting at index `i`, with `next` backslash + @tailrec def loop(i: Int, next: Int): String = { + if (next >= 0) { + //require(str(next) == '\\') + if (next > i) b.append(str, i, next) + var idx = next + 1 + if (idx >= len) throw new InvalidEscapeException(str, next) + val c = str(idx) match { + case 'b' => '\b' + case 't' => '\t' + case 'n' => '\n' + case 'f' => '\f' + case 'r' => '\r' + case '"' => '"' + case '\'' => '\'' + case '\\' => '\\' + case o if '0' <= o && o <= '7' => + if (strict) throw new InvalidEscapeException(str, next) + val leadch = str(idx) + var oct = leadch - '0' idx += 1 - } + if (idx < len && '0' <= str(idx) && str(idx) <= '7') { + oct = oct * 8 + str(idx) - '0' + idx += 1 + if (idx < len && leadch <= '3' && '0' <= str(idx) && str(idx) <= '7') { + oct = oct * 8 + str(idx) - '0' + idx += 1 + } + } + idx -= 1 // retreat + oct.toChar + case _ => throw new InvalidEscapeException(str, next) } - output(oct.toChar) + idx += 1 // advance + b append c + loop(idx, str.indexOf('\\', idx)) } else { - val ch = str(idx) - idx += 1 - output { - ch match { - case 'b' => '\b' - case 't' => '\t' - case 'n' => '\n' - case 'f' => '\f' - case 'r' => '\r' - case '\"' => '\"' - case '\'' => '\'' - case '\\' => '\\' - case _ => throw new InvalidEscapeException(str, cur) - } - } + if (i < len) b.append(str, i, len) + b.toString } - } else { - idx += 1 } + loop(0, first) + } + str indexOf '\\' match { + case -1 => str + case i => replace(i) } - if (start == 0) str - else bldr.append(str, start, idx).toString } } |