J2K: coversion of specially mapped built-in methods + replacing "get" with "[]" where possible

This commit is contained in:
Valentin Kipyatkov
2015-10-16 22:45:19 +03:00
parent 50f559a1c8
commit dc909ac166
29 changed files with 327 additions and 57 deletions
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.inspections.RedundantSamConstructorInspection
import org.jetbrains.kotlin.idea.intentions.*
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions.IfThenToElvisIntention
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions.IfThenToSafeAccessIntention
import org.jetbrains.kotlin.idea.intentions.conventionNameCalls.ReplaceGetIntention
import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFix
import org.jetbrains.kotlin.idea.quickfix.RemoveRightPartOfBinaryExpressionFix
import org.jetbrains.kotlin.idea.references.mainReference
@@ -58,6 +59,7 @@ object J2KPostProcessingRegistrar {
registerIntentionBasedProcessing(IfThenToElvisIntention()) { applyTo(it) }
registerIntentionBasedProcessing(IfNullToElvisIntention()) { applyTo(it) }
registerIntentionBasedProcessing(SimplifyNegatedBinaryExpressionIntention()) { applyTo(it) }
registerIntentionBasedProcessing(ReplaceGetIntention()) { applyTo(it) }
registerDiagnosticBasedProcessing<JetBinaryExpressionWithTypeRHS>(Errors.USELESS_CAST) { element, diagnostic ->
val expression = RemoveRightPartOfBinaryExpressionFix(element, "").invoke()
@@ -1,6 +1,6 @@
fun foo(o: Any) {
if (o is String) {
val l = o.length()
val l = o.length
}
somethingElse()
}
@@ -1,5 +1,5 @@
fun foo(o: Any) {
if (o !is String) return
val l = o.length()
val l = o.length
somethingElse(o as String/* we should not remove this cast because it's not in pasted range*/)
}
@@ -312,8 +312,8 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
}
if (target is PsiMethod) {
val specialMethod = SpecialMethod.values().firstOrNull { it.matches(target) }
if (specialMethod != null && (specialMethod.parameterCount == null || specialMethod.parameterCount == arguments.size())) {
val specialMethod = SpecialMethod.match(target, arguments.size(), converter.services)
if (specialMethod != null) {
val converted = specialMethod.convertCall(methodExpr.getQualifierExpression(), arguments, typeArguments, codeConverter)
if (converted != null) {
result = converted
@@ -350,23 +350,31 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
}
override fun visitNewExpression(expression: PsiNewExpression) {
val type = expression.type
if (expression.getArrayInitializer() != null) {
result = codeConverter.convertExpression(expression.getArrayInitializer())
}
else if (expression.getArrayDimensions().size() > 0 && expression.getType() is PsiArrayType) {
result = ArrayWithoutInitializationExpression(
typeConverter.convertType(expression.getType(), Nullability.NotNull) as ArrayType,
typeConverter.convertType(expression.type, Nullability.NotNull) as ArrayType,
codeConverter.convertExpressions(expression.getArrayDimensions()))
}
else {
val anonymousClass = expression.getAnonymousClass()
if (type?.canonicalText in PsiPrimitiveType.getAllBoxedTypeNames()) {
val argument = expression.argumentList?.expressions?.singleOrNull()
if (argument != null && argument.type is PsiPrimitiveType) {
result = codeConverter.convertExpression(argument)
return
}
}
val qualifier = expression.getQualifier()
val classRef = expression.getClassOrAnonymousClassReference()
val classRefConverted = if (classRef != null) converter.convertCodeReferenceElement(classRef, hasExternalQualifier = qualifier != null) else null
result = NewClassExpression(classRefConverted,
convertArguments(expression),
codeConverter.convertExpression(qualifier),
if (anonymousClass != null) converter.convertAnonymousClassBody(anonymousClass) else null)
convertArguments(expression),
codeConverter.convertExpression(qualifier),
expression.anonymousClass?.let { converter.convertAnonymousClassBody(it) })
}
}
+158 -29
View File
@@ -21,11 +21,97 @@ import com.intellij.psi.CommonClassNames.JAVA_LANG_OBJECT
import com.intellij.psi.CommonClassNames.JAVA_LANG_STRING
import com.intellij.psi.impl.PsiExpressionEvaluator
import org.jetbrains.kotlin.j2k.ast.*
import org.jetbrains.kotlin.utils.addToStdlib.check
import java.io.PrintStream
import java.util.*
enum class SpecialMethod(val qualifiedClassName: String?, val methodName: String, val parameterCount: Int?) {
CHAR_SEQUENCE_LENGTH(CharSequence::class.java.name, "length", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertMethodCallToPropertyUse(codeConverter, qualifier)
},
COLLECTION_SIZE(Collection::class.java.name, "size", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertMethodCallToPropertyUse(codeConverter, qualifier)
},
MAP_SIZE(Map::class.java.name, "size", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertMethodCallToPropertyUse(codeConverter, qualifier)
},
MAP_KEY_SET(Map::class.java.name, "keySet", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertMethodCallToPropertyUse(codeConverter, qualifier, "keys")
},
MAP_VALUES(Map::class.java.name, "values", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertMethodCallToPropertyUse(codeConverter, qualifier)
},
MAP_ENTRY_SET(Map::class.java.name, "entrySet", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertMethodCallToPropertyUse(codeConverter, qualifier, "entries")
},
ENUM_NAME(Enum::class.java.name, "name", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertMethodCallToPropertyUse(codeConverter, qualifier, "name")
},
ENUM_ORDINAL(Enum::class.java.name, "ordinal", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertMethodCallToPropertyUse(codeConverter, qualifier)
},
CHAR_AT(CharSequence::class.java.name, "charAt", 1) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertWithChangedName("get", qualifier, arguments, typeArgumentsConverted, codeConverter)
},
NUMBER_BYTE_VALUE(Number::class.java.name, "byteValue", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertWithChangedName("toByte", qualifier, arguments, typeArgumentsConverted, codeConverter)
},
NUMBER_SHORT_VALUE(Number::class.java.name, "shortValue", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertWithChangedName("toShort", qualifier, arguments, typeArgumentsConverted, codeConverter)
},
NUMBER_INT_VALUE(Number::class.java.name, "intValue", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertWithChangedName("toInt", qualifier, arguments, typeArgumentsConverted, codeConverter)
},
NUMBER_LONG_VALUE(Number::class.java.name, "longValue", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertWithChangedName("toLong", qualifier, arguments, typeArgumentsConverted, codeConverter)
},
NUMBER_FLOAT_VALUE(Number::class.java.name, "floatValue", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertWithChangedName("toFloat", qualifier, arguments, typeArgumentsConverted, codeConverter)
},
NUMBER_DOUBLE_VALUE(Number::class.java.name, "doubleValue", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertWithChangedName("toDouble", qualifier, arguments, typeArgumentsConverted, codeConverter)
},
LIST_REMOVE(List::class.java.name, "remove", 1) {
override fun matches(method: PsiMethod, superMethodsSearcher: SuperMethodsSearcher)
= super.matches(method, superMethodsSearcher) && method.parameterList.parameters.single().type.canonicalText == "int"
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertWithChangedName("removeAt", qualifier, arguments, typeArgumentsConverted, codeConverter)
},
OBJECT_EQUALS(null, "equals", 1) {
override fun matches(method: PsiMethod)
= super.matches(method) && method.getParameterList().getParameters().single().getType().getCanonicalText() == JAVA_LANG_OBJECT
override fun matches(method: PsiMethod, superMethodsSearcher: SuperMethodsSearcher): Boolean
= super.matches(method, superMethodsSearcher) && method.getParameterList().getParameters().single().getType().getCanonicalText() == JAVA_LANG_OBJECT
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter): Expression? {
if (qualifier == null || qualifier is PsiSuperExpression) return null
@@ -33,7 +119,7 @@ enum class SpecialMethod(val qualifiedClassName: String?, val methodName: String
}
},
OBJECT_GET_CLASS("java.lang.Object", "getClass", 0) {
OBJECT_GET_CLASS(JAVA_LANG_OBJECT, "getClass", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter): Expression {
val identifier = Identifier("javaClass", false).assignNoPrototype()
return if (qualifier != null) QualifiedExpression(codeConverter.convertExpression(qualifier), identifier) else identifier
@@ -45,27 +131,27 @@ enum class SpecialMethod(val qualifiedClassName: String?, val methodName: String
= BinaryExpression(codeConverter.convertExpression(arguments[0]), codeConverter.convertExpression(arguments[1]), "==")
},
COLLECTIONS_EMPTY_LIST("java.util.Collections", "emptyList", 0) {
COLLECTIONS_EMPTY_LIST(Collections::class.java.name, "emptyList", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= MethodCallExpression.build(null, "emptyList", listOf(), typeArgumentsConverted, false)
},
COLLECTIONS_EMPTY_SET("java.util.Collections", "emptySet", 0) {
COLLECTIONS_EMPTY_SET(Collections::class.java.name, "emptySet", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= MethodCallExpression.build(null, "emptySet", listOf(), typeArgumentsConverted, false)
},
COLLECTIONS_EMPTY_MAP("java.util.Collections", "emptyMap", 0) {
COLLECTIONS_EMPTY_MAP(Collections::class.java.name, "emptyMap", 0) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= MethodCallExpression.build(null, "emptyMap", listOf(), typeArgumentsConverted, false)
},
COLLECTIONS_SINGLETON_LIST("java.util.Collections", "singletonList", 1) {
COLLECTIONS_SINGLETON_LIST(Collections::class.java.name, "singletonList", 1) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= MethodCallExpression.build(null, "listOf", listOf(codeConverter.convertExpression(arguments.single())), typeArgumentsConverted, false)
},
COLLECTIONS_SINGLETON("java.util.Collections", "singleton", 1) {
COLLECTIONS_SINGLETON(Collections::class.java.name, "singleton", 1) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= MethodCallExpression.build(null, "setOf", listOf(codeConverter.convertExpression(arguments.single())), typeArgumentsConverted, false)
},
@@ -135,15 +221,16 @@ enum class SpecialMethod(val qualifiedClassName: String?, val methodName: String
},
STRING_JOIN(JAVA_LANG_STRING, "join", 2) {
override fun matches(method: PsiMethod)
= super.matches(method) && method.parameterList.parameters.last().type.canonicalText == "java.lang.Iterable<? extends java.lang.CharSequence>"
override fun matches(method: PsiMethod, superMethodsSearcher: SuperMethodsSearcher): Boolean
= super.matches(method, superMethodsSearcher) && method.parameterList.parameters.last().type.canonicalText == "java.lang.Iterable<? extends java.lang.CharSequence>"
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter): Expression?
= MethodCallExpression.buildNotNull(codeConverter.convertExpression(arguments[1]), "joinToString", codeConverter.convertExpressions(arguments.take(1)), emptyList())
},
STRING_JOIN_VARARG(JAVA_LANG_STRING, "join", null) {
override fun matches(method: PsiMethod): Boolean = super.matches(method) && method.parameterList.let { it.parametersCount == 2 && it.parameters.last().isVarArgs }
override fun matches(method: PsiMethod, superMethodsSearcher: SuperMethodsSearcher): Boolean
= super.matches(method, superMethodsSearcher) && method.parameterList.let { it.parametersCount == 2 && it.parameters.last().isVarArgs }
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter): Expression? {
if (arguments.size() == 2 && arguments.last().isAssignableToCharSequenceArray()) {
@@ -186,59 +273,101 @@ enum class SpecialMethod(val qualifiedClassName: String?, val methodName: String
},
STRING_FORMAT_WITH_LOCALE(JAVA_LANG_STRING, "format", null) {
override fun matches(method: PsiMethod)
= super.matches(method) &&
override fun matches(method: PsiMethod, superMethodsSearcher: SuperMethodsSearcher): Boolean
= super.matches(method, superMethodsSearcher) &&
method.parameterList.parametersCount == 3 &&
method.parameterList.parameters.let { it.first().type.canonicalText == "java.util.Locale" && it.last().isVarArgs }
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= MethodCallExpression.build(codeConverter.convertExpression(arguments[1]), "format", codeConverter.convertExpressions(listOf(arguments[0]) + arguments.drop(2)), emptyList(), false)
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter): Expression? {
if (arguments.size() < 2) return null // incorrect call
return 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): Boolean {
return super.matches(method) &&
override fun matches(method: PsiMethod, superMethodsSearcher: SuperMethodsSearcher): Boolean {
return super.matches(method, superMethodsSearcher) &&
method.parameterList.parametersCount == 2 &&
method.parameterList.parameters.last().isVarArgs
}
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= MethodCallExpression.build(codeConverter.convertExpression(arguments.first()), "format", codeConverter.convertExpressions(arguments.drop(1)), emptyList(), false)
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter): Expression? {
if (arguments.isEmpty()) return null // incorrect call
return 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 matches(method: PsiMethod, superMethodsSearcher: SuperMethodsSearcher): Boolean {
return super.matches(method, superMethodsSearcher)
&& method.parameterList.parametersCount.let { it == 1 || it == 3}
&& method.parameterList.parameters.first().type.canonicalText == "char[]"
}
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= MethodCallExpression.build(null, "String", codeConverter.convertExpressions(arguments), emptyList(), false)
},
STRING_COPY_VALUE_OF_CHAR_ARRAY(JAVA_LANG_STRING, "copyValueOf", null) {
override fun matches(method: PsiMethod, superMethodsSearcher: SuperMethodsSearcher): Boolean {
return super.matches(method, superMethodsSearcher)
&& method.parameterList.parametersCount.let { it == 1 || it == 3 }
&& method.parameterList.parameters.first().type.canonicalText == "char[]"
}
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= STRING_VALUE_OF_CHAR_ARRAY.convertCall(qualifier, arguments, typeArgumentsConverted, codeConverter)
},
STRING_VALUE_OF(JAVA_LANG_STRING, "valueOf", 1) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= MethodCallExpression.build(codeConverter.convertExpression(arguments.single()), "toString", emptyList(), emptyList(), false)
},
SYSTEM_OUT_PRINTLN("java.io.PrintStream", "println", null) {
SYSTEM_OUT_PRINTLN(PrintStream::class.java.name, "println", null) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertSystemOutMethodCall(methodName, qualifier, arguments, typeArgumentsConverted, codeConverter)
},
SYSTEM_OUT_PRINT("java.io.PrintStream", "print", null) {
SYSTEM_OUT_PRINT(PrintStream::class.java.name, "print", null) {
override fun convertCall(qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= convertSystemOutMethodCall(methodName, qualifier, arguments, typeArgumentsConverted, codeConverter)
};
open fun matches(method: PsiMethod): Boolean = matchesName(method) && matchesClass(method) && matchesParameterCount(method)
open fun matches(method: PsiMethod, superMethodsSearcher: SuperMethodsSearcher): Boolean
= method.name == methodName && matchesClass(method, superMethodsSearcher) && matchesParameterCount(method)
protected fun matchesClass(method: PsiMethod, superMethodsSearcher: SuperMethodsSearcher): Boolean {
if (qualifiedClassName == null) return true
val superMethods = superMethodsSearcher.findDeepestSuperMethods(method)
return if (superMethods.isEmpty())
method.containingClass?.qualifiedName == qualifiedClassName
else
superMethods.any { it.containingClass?.qualifiedName == qualifiedClassName }
}
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<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter): Expression?
protected fun convertMethodCallToPropertyUse(codeConverter: CodeConverter, qualifier: PsiExpression?, propertyName: String = methodName): Expression {
val identifier = Identifier(propertyName, false).assignNoPrototype()
return if (qualifier != null) QualifiedExpression(codeConverter.convertExpression(qualifier), identifier) else identifier
}
protected fun convertWithChangedName(name: String, qualifier: PsiExpression?, arguments: Array<PsiExpression>, typeArgumentsConverted: List<Type>, codeConverter: CodeConverter)
= MethodCallExpression.buildNotNull(codeConverter.convertExpression(qualifier), name, codeConverter.convertExpressions(arguments), typeArgumentsConverted)
companion object {
private val valuesByName = values().groupBy { it.methodName }
fun match(method: PsiMethod, argumentCount: Int, services: JavaToKotlinConverterServices): SpecialMethod? {
val candidates = valuesByName[method.name] ?: return null
return candidates
.firstOrNull { it.matches(method, services.superMethodsSearcher) }
?.check { it.parameterCount == null || it.parameterCount == argumentCount } // if parameterCount is specified we should make sure that argument count is correct
}
}
}
private fun convertSystemOutMethodCall(
+2
View File
@@ -6,6 +6,8 @@ public open class KotlinClass(public var field: Int) {
public open fun foo(mutableCollection: MutableCollection<String>, nullableCollection: Collection<Int>?): MutableList<Any> = arrayListOf()
fun get(i: Int) = 0
companion object {
public fun staticFun(p: Int): Int = p
public var staticVar: Int = 1
@@ -6,6 +6,6 @@ internal class Foo {
fun foo(o: HashSet<Any?>?) {
val o2: HashSet<Any?>? = o
var foo: Int = 0
foo = o2!!.size()
foo = o2!!.size
}
}
@@ -4,6 +4,6 @@ internal class Foo {
fun foo(o: HashSet<Any>) {
val o2 = o
var foo = 0
foo = o2.size()
foo = o2.size
}
}
@@ -0,0 +1,22 @@
import java.util.HashMap;
import kotlinApi.KotlinClass;
class X {
int get(int index) {
return 0;
}
}
class C {
String foo(HashMap<String, String> map) {
return map.get("a");
}
int foo(X x) {
return x.get(0);
}
int foo(KotlinClass kotlinClass) {
return kotlinClass.get(0); // not operator!
}
}
@@ -0,0 +1,23 @@
// ERROR: Type mismatch: inferred type is kotlin.String? but kotlin.String was expected
import java.util.HashMap
import kotlinApi.KotlinClass
internal class X {
fun get(index: Int): Int {
return 0
}
}
internal class C {
fun foo(map: HashMap<String, String>): String {
return map["a"]
}
fun foo(x: X): Int {
return x.get(0)
}
fun foo(kotlinClass: KotlinClass): Int {
return kotlinClass.get(0) // not operator!
}
}
@@ -1,7 +1,7 @@
internal class C {
fun foo(o: Any) {
if (o is String) {
val l = o.length()
val l = o.length
}
}
}
@@ -1,7 +1,7 @@
internal class C {
fun foo(o: Any) {
if (o is String) {
val l = o.length()
val l = o.length
val substring = o.substring(l - 2)
}
}
@@ -7,7 +7,7 @@ internal class A// this is a primary constructor
} // end of primary constructor body
// this is a secondary constructor 2
constructor(s: String) : this(s.length()) {
constructor(s: String) : this(s.length) {
} // end of secondary constructor 2 body
}// this is a secondary constructor 1
// end of secondary constructor 1 body
@@ -1,3 +1,3 @@
internal open class Base(o: Any, l: Int)
internal class C(private val string: String) : Base(string, string.length())
internal class C(private val string: String) : Base(string, string.length)
@@ -1 +1 @@
internal class C @JvmOverloads constructor(private val string: String, a: Int = string.length())
internal class C @JvmOverloads constructor(private val string: String, a: Int = string.length)
+1 -1
View File
@@ -2,6 +2,6 @@ internal enum class Color : Runnable {
WHITE, BLACK, RED, YELLOW, BLUE;
override fun run() {
println("name()=" + name() + ", toString()=" + toString())
println("name()=" + name + ", toString()=" + toString())
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
class A {
internal fun foo(collection: Collection<String>) {
for (i in collection.size() downTo 0) {
for (i in collection.size downTo 0) {
println(i)
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
internal object Test {
fun toFileSystemSafeName(name: String): String {
val size = name.length()
val size = name.length
return name
}
}
@@ -2,6 +2,6 @@ import kotlinApi.*
internal class A {
fun foo(t: KotlinTrait): Int {
return t.nullableFun()!!.length() + t.notNullableFun().length()
return t.nullableFun()!!.length + t.notNullableFun().length
}
}
@@ -2,6 +2,6 @@ import kotlinApi.*
internal class A {
fun foo(c: KotlinClass): Int {
return c.nullableProperty!!.length() + c.property.length() + KotlinClass.nullableStaticVar!! + KotlinClass.staticVar + KotlinClass.nullableStaticFun(1)!! + KotlinClass.staticFun(1) + nullableGlobalFunction("")!!.length() + globalFunction("").length()
return c.nullableProperty!!.length + c.property.length + KotlinClass.nullableStaticVar!! + KotlinClass.staticVar + KotlinClass.nullableStaticFun(1)!! + KotlinClass.staticFun(1) + nullableGlobalFunction("")!!.length + globalFunction("").length
}
}
@@ -0,0 +1,30 @@
import java.util.*;
enum E {
A, B, C
}
class A {
void foo(List<String> list, Collection<Integer> collection, Map<Integer, Integer> map) {
int a = "".length();
String b = E.A.name();
int c = E.A.ordinal();
int d = list.size() + collection.size();
int e = map.size();
int f = map.keySet().size();
int g = map.values().size();
int h = map.entrySet().size();
}
void bar(List<String> list) {
char c = "a".charAt(0);
byte b = new Integer(10).byteValue();
int i = new Double(10.1).intValue();
float f = new Double(10.1).floatValue();
long l = new Double(10.1).longValue();
short s = new Double(10.1).shortValue();
String removed = list.remove(10);
Boolean isRemoved = list.remove("a");
}
}
@@ -0,0 +1,30 @@
import java.util.*
internal enum class E {
A, B, C
}
internal class A {
fun foo(list: List<String>, collection: Collection<Int>, map: Map<Int, Int>) {
val a = "".length
val b = E.A.name
val c = E.A.ordinal
val d = list.size + collection.size
val e = map.size
val f = map.keys.size
val g = map.values.size
val h = map.entries.size
}
fun bar(list: MutableList<String>) {
val c = "a"[0]
val b = 10.toByte()
val i = 10.1.toInt()
val f = 10.1.toFloat()
val l = 10.1.toLong()
val s = 10.1.toShort()
val removed = list.removeAt(10)
val isRemoved = list.remove("a")
}
}
@@ -25,12 +25,12 @@ internal class A {
fun normalMethods() {
val s = "test string"
s.length()
s.length
s.isEmpty()
s.charAt(1)
s[1]
s.codePointAt(2)
s.codePointBefore(2)
s.codePointCount(0, s.length())
s.codePointCount(0, s.length)
s.offsetByCodePoints(0, 4)
s.compareTo("test 2")
s.concat(" another")
+1 -1
View File
@@ -6,7 +6,7 @@ internal class A {
}
fun bar(collection: MutableCollection<String>) {
if (collection.size() < 5) {
if (collection.size < 5) {
foo(collection)
} else {
collection.add("a")
@@ -4,6 +4,6 @@ internal class C {
}
fun foo(): Int {
return getString(true)!!.length()
return getString(true)!!.length
}
}
@@ -1,5 +1,5 @@
fun foo(s: String?, b: Boolean): Int {
if (s == null) println("null")
if (b) return s!!.length()
if (b) return s!!.length
return 10
}
+1 -1
View File
@@ -1,7 +1,7 @@
internal class A {
fun foo(s: String?): Int {
if (s != null) {
return s.length()
return s.length
}
return -1
}
@@ -955,6 +955,12 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("j2k/testData/fileOrElement/codeSimplifications"), Pattern.compile("^(.+)\\.java$"), true);
}
@TestMetadata("GetOperator.java")
public void testGetOperator() throws Exception {
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/codeSimplifications/GetOperator.java");
doTest(fileName);
}
@TestMetadata("IfNullReturnToElvis.java")
public void testIfNullReturnToElvis() throws Exception {
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/codeSimplifications/IfNullReturnToElvis.java");
@@ -3148,6 +3154,12 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo
doTest(fileName);
}
@TestMetadata("specialBuiltinMembers.java")
public void testSpecialBuiltinMembers() throws Exception {
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/methodCallExpression/specialBuiltinMembers.java");
doTest(fileName);
}
@TestMetadata("stringMethods.java")
public void testStringMethods() throws Exception {
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/methodCallExpression/stringMethods.java");
@@ -955,6 +955,12 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("j2k/testData/fileOrElement/codeSimplifications"), Pattern.compile("^(.+)\\.java$"), true);
}
@TestMetadata("GetOperator.java")
public void testGetOperator() throws Exception {
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/codeSimplifications/GetOperator.java");
doTest(fileName);
}
@TestMetadata("IfNullReturnToElvis.java")
public void testIfNullReturnToElvis() throws Exception {
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/codeSimplifications/IfNullReturnToElvis.java");
@@ -3148,6 +3154,12 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo
doTest(fileName);
}
@TestMetadata("specialBuiltinMembers.java")
public void testSpecialBuiltinMembers() throws Exception {
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/methodCallExpression/specialBuiltinMembers.java");
doTest(fileName);
}
@TestMetadata("stringMethods.java")
public void testStringMethods() throws Exception {
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/methodCallExpression/stringMethods.java");