diff options
Diffstat (limited to 'test/files/run/indy-via-macro')
-rw-r--r-- | test/files/run/indy-via-macro/Bootstrap.java | 16 | ||||
-rw-r--r-- | test/files/run/indy-via-macro/Test_2.scala | 5 | ||||
-rw-r--r-- | test/files/run/indy-via-macro/macro_1.scala | 32 |
3 files changed, 53 insertions, 0 deletions
diff --git a/test/files/run/indy-via-macro/Bootstrap.java b/test/files/run/indy-via-macro/Bootstrap.java new file mode 100644 index 0000000000..af4f5dfd4f --- /dev/null +++ b/test/files/run/indy-via-macro/Bootstrap.java @@ -0,0 +1,16 @@ +package test; + +import java.lang.invoke.*; +import java.util.regex.Pattern; + +public final class Bootstrap { + private Bootstrap() { + } + + /** Pre-compile a regex */ + public static CallSite bootstrap(MethodHandles.Lookup lookup, String invokedName, + MethodType invokedType, + String value) throws Throwable { + return new ConstantCallSite(MethodHandles.constant(Pattern.class, Pattern.compile(value))); + } +} diff --git a/test/files/run/indy-via-macro/Test_2.scala b/test/files/run/indy-via-macro/Test_2.scala new file mode 100644 index 0000000000..830947a46b --- /dev/null +++ b/test/files/run/indy-via-macro/Test_2.scala @@ -0,0 +1,5 @@ +object Test { + def main(args: Array[String]) { + assert(Macro.compilePattern("foo.bar").matcher("foo!bar").matches) + } +}
\ No newline at end of file diff --git a/test/files/run/indy-via-macro/macro_1.scala b/test/files/run/indy-via-macro/macro_1.scala new file mode 100644 index 0000000000..26daad7deb --- /dev/null +++ b/test/files/run/indy-via-macro/macro_1.scala @@ -0,0 +1,32 @@ +import java.util.regex.Pattern + +import scala.reflect.internal.SymbolTable +import scala.reflect.macros.blackbox._ +import language.experimental.macros + +object Macro { + /** + * Equivalent to Pattern.compile(s), but caches the compiled regex (using invokedynamic) if + * `s` is a literal. + */ + def compilePattern(s: String): Pattern = macro Macro.impl + def impl(c: Context)(s: c.Tree): c.Tree = { + def Indy(bootstrapMethod: c.Symbol, bootstrapArgs: List[c.universe.Literal]): c.Tree = { + val symtab = c.universe.asInstanceOf[SymbolTable] + import symtab._ + val dummySymbol = NoSymbol.newTermSymbol(TermName("compile")).setInfo(NullaryMethodType(typeOf[Pattern])) + val args: List[Tree] = Literal(Constant(bootstrapMethod)).setType(NoType) :: bootstrapArgs.asInstanceOf[List[Tree]] + val result = ApplyDynamic(Ident(dummySymbol).setType(dummySymbol.info), args) + result.setType(dummySymbol.info.resultType) + result.asInstanceOf[c.Tree] + } + import c.universe._ + s match { + case l @ Literal(Constant(s: String)) => + val bootstrapSym = typeOf[test.Bootstrap].companion.member(TermName("bootstrap")) + Indy(bootstrapSym, l :: Nil) + case _ => + q"_root_.java.util.regex.Pattern.compile($s)" + } + } +} |