diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2012-11-21 14:01:04 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2012-11-26 22:47:22 +0100 |
commit | a0001fcfd06fc2eca9ee965aeb766c832797aa9e (patch) | |
tree | 5486401e5d72d08fbca350b96dd3762a0397f968 /src/reflect | |
parent | 6cb08a1aabd915bbf3562c03d1b89af617eed81d (diff) | |
download | scala-a0001fcfd06fc2eca9ee965aeb766c832797aa9e.tar.gz scala-a0001fcfd06fc2eca9ee965aeb766c832797aa9e.tar.bz2 scala-a0001fcfd06fc2eca9ee965aeb766c832797aa9e.zip |
Adds a margin stripping string interpolator.
Currently only for compiler internal use.
Designed to avoid surprises if the interpolated values
themselves contain the margin delimiter.
Before:
val bip = "\n |.."
s"""fooo
|bar $bip
|baz""".stripMargin
"fooo
bar
..
baz"
After:
sm"""fooo
|bar $bip
|baz"""
"fooo
bar
|..
baz"
Diffstat (limited to 'src/reflect')
3 files changed, 55 insertions, 0 deletions
diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala index 554acf9c0b..02ac59a461 100644 --- a/src/reflect/scala/reflect/internal/SymbolTable.scala +++ b/src/reflect/scala/reflect/internal/SymbolTable.scala @@ -345,6 +345,12 @@ abstract class SymbolTable extends macros.Universe /** Is this symbol table a part of a compiler universe? */ def isCompilerUniverse = false + + /** + * Adds the `sm` String interpolator to a [[scala.StringContext]]. + */ + implicit val StringContextStripMarginOps: StringContext => StringContextStripMarginOps = util.StringContextStripMarginOps + } object SymbolTableStats { diff --git a/src/reflect/scala/reflect/internal/util/StripMarginInterpolator.scala b/src/reflect/scala/reflect/internal/util/StripMarginInterpolator.scala new file mode 100644 index 0000000000..e7579229b2 --- /dev/null +++ b/src/reflect/scala/reflect/internal/util/StripMarginInterpolator.scala @@ -0,0 +1,40 @@ +package scala.reflect +package internal +package util + +trait StripMarginInterpolator { + def stringContext: StringContext + + /** + * A safe combination of `[[scala.collection.immutable.StringLike#stripMargin]] + * and [[scala.StringContext#raw]]. + * + * The margin of each line is defined by whitespace leading up to a '|' character. + * This margin is stripped '''before''' the arguments are interpolated into to string. + * + * String escape sequences are '''not''' processed; this interpolater is designed to + * be used with triple quoted Strings. + * + * {{{ + * scala> val foo = "f|o|o" + * foo: String = f|o|o + * scala> sm"""|${foo} + * |""" + * res0: String = + * "f|o|o + * " + * }}} + */ + final def sm(args: Any*): String = { + def isLineBreak(c: Char) = c == '\n' || c == '\f' // compatible with StringLike#isLineBreak + def stripTrailingPart(s: String) = { + val (pre, post) = s.span(c => !isLineBreak(c)) + pre + post.stripMargin + } + val stripped: List[String] = stringContext.parts.toList match { + case head :: tail => head.stripMargin :: (tail map stripTrailingPart) + case Nil => Nil + } + new StringContext(stripped: _*).raw(args: _*) + } +} diff --git a/src/reflect/scala/reflect/internal/util/package.scala b/src/reflect/scala/reflect/internal/util/package.scala new file mode 100644 index 0000000000..6d77235db6 --- /dev/null +++ b/src/reflect/scala/reflect/internal/util/package.scala @@ -0,0 +1,9 @@ +package scala.reflect +package internal + +package object util { + /** + * Adds the `sm` String interpolator to a [[scala.StringContext]]. + */ + implicit class StringContextStripMarginOps(val stringContext: StringContext) extends StripMarginInterpolator +} |