From d7da8b7bd33b1ba461f39952286bb3109a79a42e Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Fri, 2 Oct 2015 23:39:13 +0300 Subject: [PATCH] J2K: Special conversion for java.lang.String methods. #KT-7732 --- .../org/jetbrains/kotlin/j2k/CodeConverter.kt | 3 + .../org/jetbrains/kotlin/j2k/SpecialMethod.kt | 141 ++++++++++++++++-- j2k/src/org/jetbrains/kotlin/j2k/ast/Block.kt | 2 + .../methodCallExpression/stringMethods.java | 117 +++++++++++++++ .../methodCallExpression/stringMethods.kt | 127 ++++++++++++++++ ...otlinConverterForWebDemoTestGenerated.java | 6 + ...otlinConverterSingleFileTestGenerated.java | 6 + 7 files changed, 392 insertions(+), 10 deletions(-) create mode 100644 j2k/testData/fileOrElement/methodCallExpression/stringMethods.java create mode 100644 j2k/testData/fileOrElement/methodCallExpression/stringMethods.kt diff --git a/j2k/src/org/jetbrains/kotlin/j2k/CodeConverter.kt b/j2k/src/org/jetbrains/kotlin/j2k/CodeConverter.kt index b9a2ba008cd..9e40b4627a2 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/CodeConverter.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/CodeConverter.kt @@ -60,6 +60,9 @@ class CodeConverter( public fun convertExpressions(expressions: Array): List = expressions.map { convertExpression(it) } + public fun convertExpressions(expressions: List): List + = expressions.map { convertExpression(it) } + public fun convertExpression(expression: PsiExpression?): Expression { if (expression == null) return Expression.Empty diff --git a/j2k/src/org/jetbrains/kotlin/j2k/SpecialMethod.kt b/j2k/src/org/jetbrains/kotlin/j2k/SpecialMethod.kt index 9705fd9d9da..dbd76ad31df 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/SpecialMethod.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/SpecialMethod.kt @@ -16,11 +16,9 @@ package org.jetbrains.kotlin.j2k +import com.intellij.psi.* import com.intellij.psi.CommonClassNames.JAVA_LANG_OBJECT -import com.intellij.psi.PsiExpression -import com.intellij.psi.PsiMethod -import com.intellij.psi.PsiReferenceExpression -import com.intellij.psi.PsiSuperExpression +import com.intellij.psi.CommonClassNames.JAVA_LANG_STRING import org.jetbrains.kotlin.j2k.ast.* enum class SpecialMethod(val qualifiedClassName: String?, val methodName: String, val parameterCount: Int?) { @@ -71,7 +69,16 @@ enum class SpecialMethod(val qualifiedClassName: String?, val methodName: String = MethodCallExpression.build(null, "setOf", listOf(codeConverter.convertExpression(arguments.single())), typeArgumentsConverted, false) }, - STRING_REPLACE_ALL("java.lang.String", "replaceAll", 2) { + STRING_TRIM(JAVA_LANG_STRING, "trim", 0) { + override fun convertCall(qualifier: PsiExpression?, arguments: Array, typeArgumentsConverted: List, codeConverter: CodeConverter): Expression? { + val comparison = BinaryExpression(Identifier("it", isNullable = false).assignNoPrototype(), LiteralExpression("' '").assignNoPrototype(), "<=").assignNoPrototype() + return MethodCallExpression.buildNotNull( + codeConverter.convertExpression(qualifier), "trim", + listOf(LambdaExpression(null, Block.of(comparison).assignNoPrototype())), emptyList()) + } + }, + + STRING_REPLACE_ALL(JAVA_LANG_STRING, "replaceAll", 2) { override fun convertCall(qualifier: PsiExpression?, arguments: Array, typeArgumentsConverted: List, codeConverter: CodeConverter) = MethodCallExpression.build(codeConverter.convertExpression(qualifier), "replace", listOf( @@ -80,6 +87,104 @@ enum class SpecialMethod(val qualifiedClassName: String?, val methodName: String ), emptyList(), false) }, + STRING_REPLACE_FIRST(JAVA_LANG_STRING, "replaceFirst", 2) { + override fun convertCall(qualifier: PsiExpression?, arguments: Array, typeArgumentsConverted: List, codeConverter: CodeConverter) + = MethodCallExpression.build(codeConverter.convertExpression(qualifier), "replaceFirst", + listOf( + codeConverter.convertToRegex(arguments[0]), + codeConverter.convertExpression(arguments[1]) + ), emptyList(), false) + }, + + STRING_MATCHES(JAVA_LANG_STRING, "matches", 1) { + override fun convertCall(qualifier: PsiExpression?, arguments: Array, typeArgumentsConverted: List, codeConverter: CodeConverter) + = MethodCallExpression.build(codeConverter.convertExpression(qualifier), "matches", listOf(codeConverter.convertToRegex(arguments.single())), emptyList(), false) + }, + + STRING_SPLIT(JAVA_LANG_STRING, "split", 1) { + override fun convertCall(qualifier: PsiExpression?, arguments: Array, typeArgumentsConverted: List, codeConverter: CodeConverter): Expression? { + val splitCall = MethodCallExpression.buildNotNull(codeConverter.convertExpression(qualifier), "split", listOf(codeConverter.convertToRegex(arguments.single())), emptyList()).assignNoPrototype() + val isEmptyCall = MethodCallExpression.buildNotNull(Identifier("it", isNullable = false).assignNoPrototype(), "isEmpty", emptyList(), emptyList()).assignNoPrototype() + val isEmptyCallBlock = Block.of(isEmptyCall).assignNoPrototype() + val dropLastCall = MethodCallExpression.buildNotNull(splitCall, "dropLastWhile", listOf(LambdaExpression(null, isEmptyCallBlock).assignNoPrototype())).assignNoPrototype() + return MethodCallExpression.buildNotNull(dropLastCall, "toTypedArray", emptyList(), emptyList()) + } + }, + + STRING_SPLIT_LIMIT(JAVA_LANG_STRING, "split", 2) { + override fun convertCall(qualifier: PsiExpression?, arguments: Array, typeArgumentsConverted: List, codeConverter: CodeConverter): Expression? { + val patternArgument = codeConverter.convertToRegex(arguments[0]) + val limitArgument = codeConverter.convertExpression(arguments[1]) + val splitArguments = + if (limitArgument is PrefixExpression && limitArgument.op == "-" && limitArgument.expression.let { it is LiteralExpression && it.literalText == "1" }) + listOf(patternArgument) + else if (limitArgument is LiteralExpression && limitArgument.literalText.all { it.isDigit() }) { + if (limitArgument.literalText.toInt() == 0) { + return STRING_SPLIT.convertCall(qualifier, arrayOf(arguments[0]), typeArgumentsConverted, codeConverter) + } + listOf(patternArgument, limitArgument) + } + else + listOf(patternArgument, MethodCallExpression.buildNotNull(limitArgument, "coerceAtLeast", listOf(LiteralExpression("0").assignNoPrototype()), emptyList()).assignNoPrototype()) + + val splitCall = MethodCallExpression.buildNotNull(codeConverter.convertExpression(qualifier), "split", splitArguments, emptyList()).assignNoPrototype() + return MethodCallExpression.buildNotNull(splitCall, "toTypedArray", emptyList(), emptyList()) + } + }, + + + STRING_COMPARE_TO_IGNORE_CASE(JAVA_LANG_STRING, "compareToIgnoreCase", 1) { + override fun convertCall(qualifier: PsiExpression?, arguments: Array, typeArgumentsConverted: List, codeConverter: CodeConverter) + = addIgnoreCaseArgument(qualifier, "compareTo", arguments, typeArgumentsConverted, codeConverter) + }, + + STRING_EQUALS_IGNORE_CASE(JAVA_LANG_STRING, "equalsIgnoreCase", 1) { + override fun convertCall(qualifier: PsiExpression?, arguments: Array, typeArgumentsConverted: List, codeConverter: CodeConverter) + = addIgnoreCaseArgument(qualifier, "equals", arguments, typeArgumentsConverted, codeConverter) + }, + + STRING_REGION_MATCHES(JAVA_LANG_STRING, "regionMatches", 5) { + override fun convertCall(qualifier: PsiExpression?, arguments: Array, typeArgumentsConverted: List, codeConverter: CodeConverter) + = addIgnoreCaseArgument(qualifier, "regionMatches", arguments.drop(1).toTypedArray(), typeArgumentsConverted, codeConverter, arguments.first()) + }, + + STRING_GET_BYTES(JAVA_LANG_STRING, "getBytes", null) { + override fun convertCall(qualifier: PsiExpression?, arguments: Array, typeArgumentsConverted: List, codeConverter: CodeConverter) + = MethodCallExpression.build(codeConverter.convertExpression(qualifier), "toByteArray", codeConverter.convertExpressions(arguments), emptyList(), false) + }, + + STRING_FORMAT_WITH_LOCALE(JAVA_LANG_STRING, "format", null) { + override fun matches(method: PsiMethod) + = super.matches(method) && method.parameterList.parametersCount >= 2 && method.parameterList.parameters.first().type.canonicalText == "java.util.Locale" + + override fun convertCall(qualifier: PsiExpression?, arguments: Array, typeArgumentsConverted: List, codeConverter: CodeConverter) + = MethodCallExpression.build(codeConverter.convertExpression(arguments[1]), "format", codeConverter.convertExpressions(listOf(arguments[0]) + arguments.drop(2)), emptyList(), false) + }, + + STRING_FORMAT(JAVA_LANG_STRING, "format", null) { + override fun matches(method: PsiMethod) + = super.matches(method) && method.parameterList.parametersCount >= 1 + + override fun convertCall(qualifier: PsiExpression?, arguments: Array, typeArgumentsConverted: List, codeConverter: CodeConverter) + = MethodCallExpression.build(codeConverter.convertExpression(arguments.first()), "format", codeConverter.convertExpressions(arguments.drop(1)), emptyList(), false) + }, + + STRING_VALUE_OF_CHAR_ARRAY(JAVA_LANG_STRING, "valueOf", null) { + override fun matches(method: PsiMethod) + = matchesClass(method) && + (matchesName(method) || matchesName(method, "copyValueOf")) && + method.parameterList.parametersCount.let { it == 1 || it == 3} && + method.parameterList.parameters.first().type.canonicalText == "char[]" + + override fun convertCall(qualifier: PsiExpression?, arguments: Array, typeArgumentsConverted: List, codeConverter: CodeConverter) + = MethodCallExpression.build(null, "String", codeConverter.convertExpressions(arguments), emptyList(), false) + }, + + STRING_VALUE_OF(JAVA_LANG_STRING, "valueOf", 1) { + override fun convertCall(qualifier: PsiExpression?, arguments: Array, typeArgumentsConverted: List, codeConverter: CodeConverter) + = MethodCallExpression.build(codeConverter.convertExpression(arguments.single()), "toString", emptyList(), emptyList(), false) + }, + SYSTEM_OUT_PRINTLN("java.io.PrintStream", "println", null) { override fun convertCall(qualifier: PsiExpression?, arguments: Array, typeArgumentsConverted: List, codeConverter: CodeConverter) = convertSystemOutMethodCall(methodName, qualifier, arguments, typeArgumentsConverted, codeConverter) @@ -90,11 +195,11 @@ enum class SpecialMethod(val qualifiedClassName: String?, val methodName: String = convertSystemOutMethodCall(methodName, qualifier, arguments, typeArgumentsConverted, codeConverter) }; - open fun matches(method: PsiMethod): Boolean { - if (method.getName() != methodName) return false - if (qualifiedClassName != null && method.getContainingClass()?.getQualifiedName() != qualifiedClassName) return false - return parameterCount == null || parameterCount == method.getParameterList().getParametersCount() - } + open fun matches(method: PsiMethod): Boolean = matchesName(method) && matchesClass(method) && matchesParameterCount(method) + + protected fun matchesName(method: PsiMethod, name: String? = null) = method.name == (name ?: methodName) + protected fun matchesClass(method: PsiMethod) = qualifiedClassName == null || method.containingClass?.qualifiedName == qualifiedClassName + protected fun matchesParameterCount(method: PsiMethod) = parameterCount == null || parameterCount == method.parameterList.parametersCount abstract fun convertCall(qualifier: PsiExpression?, arguments: Array, typeArgumentsConverted: List, codeConverter: CodeConverter): Expression? } @@ -116,3 +221,19 @@ private fun convertSystemOutMethodCall( private fun CodeConverter.convertToRegex(expression: PsiExpression?): Expression = MethodCallExpression.build(convertExpression(expression), "toRegex", emptyList(), emptyList(), false).assignNoPrototype() + +private fun addIgnoreCaseArgument( + qualifier: PsiExpression?, + methodName: String, + arguments: Array, + typeArgumentsConverted: List, + codeConverter: CodeConverter, + ignoreCaseArgument: PsiExpression? = null +): Expression { + val ignoreCaseExpression = ignoreCaseArgument?.let { codeConverter.convertExpression(it) } ?: LiteralExpression("true").assignNoPrototype() + val ignoreCaseArgumentExpression = AssignmentExpression(Identifier("ignoreCase").assignNoPrototype(), ignoreCaseExpression, "=").assignNoPrototype() + return MethodCallExpression.build(codeConverter.convertExpression(qualifier), methodName, + codeConverter.convertExpressions(arguments) + ignoreCaseArgumentExpression, + typeArgumentsConverted, false) +} + diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ast/Block.kt b/j2k/src/org/jetbrains/kotlin/j2k/ast/Block.kt index 344a899e995..c5be98e9f30 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ast/Block.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ast/Block.kt @@ -33,6 +33,8 @@ class Block(val statements: List, val lBrace: LBrace, val rBrace: RBr companion object { val Empty = Block(listOf(), LBrace(), RBrace()) + fun of(statement: Statement) = of(listOf(statement)) + fun of(statements: List) = Block(statements, LBrace().assignNoPrototype(), RBrace().assignNoPrototype(), notEmpty = true) } } diff --git a/j2k/testData/fileOrElement/methodCallExpression/stringMethods.java b/j2k/testData/fileOrElement/methodCallExpression/stringMethods.java new file mode 100644 index 00000000000..17897e02f83 --- /dev/null +++ b/j2k/testData/fileOrElement/methodCallExpression/stringMethods.java @@ -0,0 +1,117 @@ +import java.nio.charset.Charset; +import java.util.*; + +class A { + void constructors() throws Exception { + new String(); + // TODO: new String("original"); + new String(new char[] {'a', 'b', 'c'}); + new String(new char[] {'b', 'd'}, 1, 1); + new String(new int[] { 32, 65, 127 }, 0, 3); + + byte[] bytes = new byte[] { 32, 65, 100, 81 }; + Charset charset = Charset.forName("utf-8"); + new String(bytes); + new String(bytes, charset); + new String(bytes, 0, 2); + new String(bytes, "utf-8"); + new String(bytes, 0, 2, "utf-8"); + new String(bytes, 0, 2, charset); + + new String(new StringBuilder("content")); + new String(new StringBuffer("content")); + } + + void normalMethods() { + String s = "test string"; + s.length(); + s.isEmpty(); + s.charAt(1); + s.codePointAt(2); + s.codePointBefore(2); + s.codePointCount(0, s.length()); + s.offsetByCodePoints(0, 4); + s.compareTo("test 2"); + s.concat(" another"); + s.contains("seq"); + s.contentEquals(new StringBuilder(s)); + s.contentEquals(new StringBuffer(s)); + s.endsWith("ng"); + s.startsWith("te"); + s.startsWith("st", 2); + s.indexOf("st"); + s.indexOf("st", 5); + s.substring(1); + s.substring(0, 4); + s.subSequence(0, 4); + s.replace('e', 'i'); + s.replace("est", "oast"); + s.intern(); + s.toLowerCase(); + s.toLowerCase(Locale.FRENCH); + s.toUpperCase(); + s.toUpperCase(Locale.FRENCH); + + s.toString(); + s.toCharArray(); + + char[] chars = new char[10]; + s.getChars(1, 11, chars, 0); + } + + void specialMethods() throws Exception { + String s = "test string"; + s.equals("test"); + s.equalsIgnoreCase("tesT"); + s.compareToIgnoreCase("Test"); + s.regionMatches(true, 0, "TE", 0, 2); + s.regionMatches(0, "st", 1, 2); + s.matches("\\w+"); + s.replaceAll("\\w+", "---"); + s.replaceFirst("([s-t])", "A$1"); + useSplit(s.split("\\s+")); + useSplit(s.split("\\s+", 0)); + useSplit(s.split("\\s+", -1)); + useSplit(s.split("\\s+", 2)); + int limit = 5; + useSplit(s.split("\\s+", limit)); + s.trim(); + + s.getBytes(); + s.getBytes(Charset.forName("utf-8")); + s.getBytes("utf-8"); + } + + void staticMethods() { + String.valueOf(1); + String.valueOf(1L); + String.valueOf('a'); + String.valueOf(true); + String.valueOf(1.11F); + String.valueOf(3.14); + String.valueOf(new Object()); + + String.format(Locale.FRENCH, "Je ne mange pas %d jours", 6); + String.format("Operation completed with %s", "success"); + + char[] chars = {'a', 'b', 'c'}; + String.valueOf(chars); + String.valueOf(chars, 1, 2); + String.copyValueOf(chars); + String.copyValueOf(chars, 1, 2); + + Comparator order = String.CASE_INSENSITIVE_ORDER; + } + + void unsupportedMethods() { + String s = "test string"; + /* TODO: + s.indexOf(32); + s.indexOf(32, 2); + s.lastIndexOf(32); + s.lastIndexOf(32, 2); + */ + } + + void useSplit(String[] result) {} +} \ No newline at end of file diff --git a/j2k/testData/fileOrElement/methodCallExpression/stringMethods.kt b/j2k/testData/fileOrElement/methodCallExpression/stringMethods.kt new file mode 100644 index 00000000000..26a06d76eec --- /dev/null +++ b/j2k/testData/fileOrElement/methodCallExpression/stringMethods.kt @@ -0,0 +1,127 @@ +// ERROR: Overload resolution ambiguity: public fun kotlin.String.split(regex: [ERROR : java.util.regex.Pattern], limit: kotlin.Int = ...): kotlin.List defined in kotlin public fun kotlin.String.split(pattern: kotlin.text.Regex, limit: kotlin.Int = ...): kotlin.List defined in kotlin +// ERROR: Unresolved reference: it +// ERROR: Overload resolution ambiguity: public fun kotlin.String.split(regex: [ERROR : java.util.regex.Pattern], limit: kotlin.Int = ...): kotlin.List defined in kotlin public fun kotlin.String.split(pattern: kotlin.text.Regex, limit: kotlin.Int = ...): kotlin.List defined in kotlin +// ERROR: Unresolved reference: it +// ERROR: Overload resolution ambiguity: public fun kotlin.String.split(regex: [ERROR : java.util.regex.Pattern], limit: kotlin.Int = ...): kotlin.List defined in kotlin public fun kotlin.String.split(pattern: kotlin.text.Regex, limit: kotlin.Int = ...): kotlin.List defined in kotlin +// ERROR: Overload resolution ambiguity: public fun kotlin.String.split(regex: [ERROR : java.util.regex.Pattern], limit: kotlin.Int = ...): kotlin.List defined in kotlin public fun kotlin.String.split(pattern: kotlin.text.Regex, limit: kotlin.Int = ...): kotlin.List defined in kotlin +// ERROR: Overload resolution ambiguity: public fun kotlin.String.split(regex: [ERROR : java.util.regex.Pattern], limit: kotlin.Int = ...): kotlin.List defined in kotlin public fun kotlin.String.split(pattern: kotlin.text.Regex, limit: kotlin.Int = ...): kotlin.List defined in kotlin +import java.nio.charset.Charset +import java.util.* + +internal class A { + @Throws(Exception::class) + fun constructors() { + String() + // TODO: new String("original"); + String(charArrayOf('a', 'b', 'c')) + String(charArrayOf('b', 'd'), 1, 1) + String(intArrayOf(32, 65, 127), 0, 3) + + val bytes = byteArrayOf(32, 65, 100, 81) + val charset = Charset.forName("utf-8") + String(bytes) + String(bytes, charset) + String(bytes, 0, 2) + String(bytes, "utf-8") + String(bytes, 0, 2, "utf-8") + String(bytes, 0, 2, charset) + + String(StringBuilder("content")) + String(StringBuffer("content")) + } + + fun normalMethods() { + val s = "test string" + s.length() + s.isEmpty() + s.charAt(1) + s.codePointAt(2) + s.codePointBefore(2) + s.codePointCount(0, s.length()) + s.offsetByCodePoints(0, 4) + s.compareTo("test 2") + s.concat(" another") + s.contains("seq") + s.contentEquals(StringBuilder(s)) + s.contentEquals(StringBuffer(s)) + s.endsWith("ng") + s.startsWith("te") + s.startsWith("st", 2) + s.indexOf("st") + s.indexOf("st", 5) + s.substring(1) + s.substring(0, 4) + s.subSequence(0, 4) + s.replace('e', 'i') + s.replace("est", "oast") + s.intern() + s.toLowerCase() + s.toLowerCase(Locale.FRENCH) + s.toUpperCase() + s.toUpperCase(Locale.FRENCH) + + s.toString() + s.toCharArray() + + val chars = CharArray(10) + s.getChars(1, 11, chars, 0) + } + + @Throws(Exception::class) + fun specialMethods() { + val s = "test string" + s == "test" + s.equals("tesT", ignoreCase = true) + s.compareTo("Test", ignoreCase = true) + s.regionMatches(0, "TE", 0, 2, ignoreCase = true) + s.regionMatches(0, "st", 1, 2) + s.matches("\\w+".toRegex()) + s.replace("\\w+".toRegex(), "---") + s.replaceFirst("([s-t])".toRegex(), "A$1") + useSplit(s.split("\\s+".toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()) + useSplit(s.split("\\s+".toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()) + useSplit(s.split("\\s+".toRegex()).toTypedArray()) + useSplit(s.split("\\s+".toRegex(), 2).toTypedArray()) + val limit = 5 + useSplit(s.split("\\s+".toRegex(), limit.coerceAtLeast(0)).toTypedArray()) + s.trim { it <= ' ' } + + s.toByteArray() + s.toByteArray(Charset.forName("utf-8")) + s.toByteArray("utf-8") + } + + fun staticMethods() { + 1.toString() + 1L.toString() + 'a'.toString() + true.toString() + 1.11f.toString() + 3.14.toString() + Object().toString() + + "Je ne mange pas %d jours".format(Locale.FRENCH, 6) + "Operation completed with %s".format("success") + + val chars = charArrayOf('a', 'b', 'c') + String(chars) + String(chars, 1, 2) + String(chars) + String(chars, 1, 2) + + val order = String.CASE_INSENSITIVE_ORDER + } + + fun unsupportedMethods() { + val s = "test string" + /* TODO: + s.indexOf(32); + s.indexOf(32, 2); + s.lastIndexOf(32); + s.lastIndexOf(32, 2); + */ + } + + fun useSplit(result: Array) { + } +} \ No newline at end of file diff --git a/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterForWebDemoTestGenerated.java b/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterForWebDemoTestGenerated.java index 9ebbf0cabc7..5319ea30b20 100644 --- a/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterForWebDemoTestGenerated.java +++ b/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterForWebDemoTestGenerated.java @@ -3148,6 +3148,12 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo doTest(fileName); } + @TestMetadata("stringMethods.java") + public void testStringMethods() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/methodCallExpression/stringMethods.java"); + doTest(fileName); + } + @TestMetadata("systemOut.java") public void testSystemOut() throws Exception { String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/methodCallExpression/systemOut.java"); diff --git a/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterSingleFileTestGenerated.java b/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterSingleFileTestGenerated.java index fd8d3474e85..b38572d62ad 100644 --- a/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterSingleFileTestGenerated.java +++ b/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterSingleFileTestGenerated.java @@ -3148,6 +3148,12 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo doTest(fileName); } + @TestMetadata("stringMethods.java") + public void testStringMethods() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/methodCallExpression/stringMethods.java"); + doTest(fileName); + } + @TestMetadata("systemOut.java") public void testSystemOut() throws Exception { String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/methodCallExpression/systemOut.java");