From 256d746a816190b6a450a6a3803534e4a24655ca Mon Sep 17 00:00:00 2001 From: Jon Schneider Date: Tue, 23 Aug 2016 11:05:50 -0700 Subject: [PATCH] Transform string literals with regexp-escapable characters --- .../refactor/fix/ChangeMethodInvocation.kt | 16 +++-- .../java/refactor/InMemoryDiffEntryTest.kt | 58 +++++++++++++++++++ .../fix/ChangeMethodInvocationTest.kt | 40 +++++++++++++ 3 files changed, 110 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/com/netflix/java/refactor/fix/ChangeMethodInvocation.kt b/src/main/kotlin/com/netflix/java/refactor/fix/ChangeMethodInvocation.kt index 32ec953..6eaace1 100644 --- a/src/main/kotlin/com/netflix/java/refactor/fix/ChangeMethodInvocation.kt +++ b/src/main/kotlin/com/netflix/java/refactor/fix/ChangeMethodInvocation.kt @@ -242,11 +242,19 @@ class ChangeMethodInvocationScanner(val op: ChangeMethodInvocation) : FixingScan // prefix and suffix hold the special characters surrounding the values of primitive-ish types, // e.g. the "" around String, the L at the end of a long, etc. - val valueMatcher = "(.*)${Pattern.quote(value.toString())}(.*)".toRegex().find(node.toString()) - val (prefix, suffix) = valueMatcher!!.groupValues.drop(1) + val valueMatcher = "(.*)${Pattern.quote(value.toString())}(.*)".toRegex().find(node.toString().replace("\\", "")) + return when(valueMatcher) { + is MatchResult -> { + val (prefix, suffix) = valueMatcher.groupValues.drop(1) - val transformed = refactor.refactorLiterals?.invoke(value) ?: value - return if (transformed != value.toString()) listOf(literal.replace("$prefix$transformed$suffix")) else emptyList() + val transformed = refactor.refactorLiterals?.invoke(value) ?: value + if (transformed != value.toString()) listOf(literal.replace("$prefix$transformed$suffix")) else emptyList() + } + else -> { + // this should never happen + emptyList() + } + } } override fun reduce(r1: List?, r2: List?): List = diff --git a/src/test/kotlin/com/netflix/java/refactor/InMemoryDiffEntryTest.kt b/src/test/kotlin/com/netflix/java/refactor/InMemoryDiffEntryTest.kt index 55cf3ff..6556a40 100644 --- a/src/test/kotlin/com/netflix/java/refactor/InMemoryDiffEntryTest.kt +++ b/src/test/kotlin/com/netflix/java/refactor/InMemoryDiffEntryTest.kt @@ -44,4 +44,62 @@ class InMemoryDiffEntryTest { | """.trimMargin(), diff) } + + @Test + fun multipleChangesMoreThanThreeLinesApart() { + val diff = InMemoryDiffEntry("com/netflix/MyJavaClass.java", + """ + |public void test() { + | logger.infof("some %s", 1); + | System.out.println("1"); + | System.out.println("2"); + | System.out.println("3"); + | System.out.println("4"); + | System.out.println("5"); + | System.out.println("6"); + | System.out.println("7"); + | System.out.println("8"); + | logger.infof("some %s", 2); + |} + | + """.trimMargin(), + """ + |public void test() { + | logger.info("some {}", 1); + | System.out.println("1"); + | System.out.println("2"); + | System.out.println("3"); + | System.out.println("4"); + | System.out.println("5"); + | System.out.println("6"); + | System.out.println("7"); + | System.out.println("8"); + | logger.info("some %s", 2); + |} + | + """.trimMargin() + ).diff + + assertEquals(""" + |diff --git a/com/netflix/MyJavaClass.java b/com/netflix/MyJavaClass.java + |index c17f051..bb2dfba 100644 + |--- a/com/netflix/MyJavaClass.java + |+++ b/com/netflix/MyJavaClass.java + |@@ -1,5 +1,5 @@ + | public void test() { + |- logger.infof("some %s", 1); + |+ logger.info("some {}", 1); + | System.out.println("1"); + | System.out.println("2"); + | System.out.println("3"); + |@@ -8,5 +8,5 @@ + | System.out.println("6"); + | System.out.println("7"); + | System.out.println("8"); + |- logger.infof("some %s", 2); + |+ logger.info("some %s", 2); + | } + | + """.trimMargin(), diff) + } } \ No newline at end of file diff --git a/src/test/kotlin/com/netflix/java/refactor/fix/ChangeMethodInvocationTest.kt b/src/test/kotlin/com/netflix/java/refactor/fix/ChangeMethodInvocationTest.kt index c6dcc3e..59f107c 100644 --- a/src/test/kotlin/com/netflix/java/refactor/fix/ChangeMethodInvocationTest.kt +++ b/src/test/kotlin/com/netflix/java/refactor/fix/ChangeMethodInvocationTest.kt @@ -286,6 +286,46 @@ class ChangeMethodInvocationTest: AbstractRefactorTest() { """) } + @Test + fun refactorLiteralStringWithEscapableCharacters() { + val a = java(""" + |package a; + |public class A { + | public void foo(String s) {} + |} + """) + + val b = java(""" + |import a.*; + |public class B { + | A a; + | public void test() { + | a.foo("mystring '%s'"); + | } + |} + """) + + parseJava(b, a).refactor() + .findMethodCalls("a.A foo(..)") + .changeArguments() + .arg(String::class.java) + .changeLiterals { s -> s.toString().replace("%s", "{}") } + .done() + .done() + .done() + .fix() + + assertRefactored(b, """ + |import a.*; + |public class B { + | A a; + | public void test() { + | a.foo("mystring '{}'"); + | } + |} + """) + } + @Test fun refactorReorderArguments() { val a = java("""