diff options
author | Paul Phillips <paulp@improving.org> | 2012-11-28 09:32:18 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-11-28 09:32:18 -0800 |
commit | b149c7b5f26b6771557849aa04b96a3ca3bdedee (patch) | |
tree | 310918089ca81392b72b99e1a0058fa90636fa76 /src/reflect | |
parent | 4c3aaad77fd41765aa2a06039ede143d6911d422 (diff) | |
parent | 8fcbee5e2d0fcff2f42c94b9ecf6599e586c8166 (diff) | |
download | scala-b149c7b5f26b6771557849aa04b96a3ca3bdedee.tar.gz scala-b149c7b5f26b6771557849aa04b96a3ca3bdedee.tar.bz2 scala-b149c7b5f26b6771557849aa04b96a3ca3bdedee.zip |
Merge pull request #1676 from retronym/topic/sm-interpolator
Adds a margin stripping string interpolator.
Diffstat (limited to 'src/reflect')
4 files changed, 63 insertions, 9 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 +} diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 2d08cd887b..ab93d7033a 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -129,11 +129,10 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni private def ErrorStaticModule(sym: Symbol) = throw new ScalaReflectionException(s"$sym is a static module, use reflectModule on a RuntimeMirror to obtain its ModuleMirror") private def ErrorNotMember(sym: Symbol, owner: Symbol) = throw new ScalaReflectionException(s"expected a member of $owner, you provided ${sym.kindString} ${sym.fullName}") private def ErrorNotField(sym: Symbol) = throw new ScalaReflectionException(s"expected a field or an accessor method symbol, you provided $sym") - private def ErrorNonExistentField(sym: Symbol) = throw new ScalaReflectionException(s""" - |Scala field ${sym.name} isn't represented as a Java field, neither it has a Java accessor method - |note that private parameters of class constructors don't get mapped onto fields and/or accessors, - |unless they are used outside of their declaring constructors. - """.trim.stripMargin) + private def ErrorNonExistentField(sym: Symbol) = throw new ScalaReflectionException( + sm"""Scala field ${sym.name} isn't represented as a Java field, neither it has a Java accessor method + |note that private parameters of class constructors don't get mapped onto fields and/or accessors, + |unless they are used outside of their declaring constructors.""") private def ErrorSetImmutableField(sym: Symbol) = throw new ScalaReflectionException(s"cannot set an immutable field ${sym.name}") private def ErrorNotConstructor(sym: Symbol, owner: Symbol) = throw new ScalaReflectionException(s"expected a constructor of $owner, you provided $sym") private def ErrorFree(member: Symbol, freeType: Symbol) = throw new ScalaReflectionException(s"cannot reflect ${member.kindString} ${member.name}, because it's a member of a weak type ${freeType.name}") @@ -541,8 +540,8 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni val result = anns find (_.annotationType == annotClass) if (result.isEmpty && (anns exists (_.annotationType.getName == name))) throw new ClassNotFoundException( - s"""Mirror classloader mismatch: $jclazz (loaded by ${ReflectionUtils.show(jclazz.getClassLoader)}) - |is unrelated to the mirror's classloader: (${ReflectionUtils.show(classLoader)})""".stripMargin) + sm"""Mirror classloader mismatch: $jclazz (loaded by ${ReflectionUtils.show(jclazz.getClassLoader)}) + |is unrelated to the mirror's classloader: (${ReflectionUtils.show(classLoader)})""") result } def loadBytes[T: ClassTag](name: String): Option[T] = @@ -955,8 +954,8 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni javaTypeToValueClass(jclazz) orElse lookupClass assert (cls.isType, - s"""${if (cls == NoSymbol) "not a type: symbol" else "no symbol could be"} - | loaded from $jclazz in $owner with name $simpleName and classloader $classLoader""".stripMargin) + sm"""${if (cls == NoSymbol) "not a type: symbol" else "no symbol could be"} + | loaded from $jclazz in $owner with name $simpleName and classloader $classLoader""") cls.asClass } |