KT-19565: J2K: Determine mutability using iterator

#KT-19565 fixed
This commit is contained in:
Denis Grachev
2017-09-18 14:07:57 +03:00
committed by Simon Ogorodnik
parent d312996f3a
commit 0722c5c13a
7 changed files with 100 additions and 2 deletions
@@ -438,7 +438,10 @@ class TypeConverter(val converter: Converter) {
private fun isMutableFromUsage(usage: PsiExpression): Boolean {
val parent = usage.parent
if (parent is PsiReferenceExpression && usage == parent.qualifierExpression && parent.parent is PsiMethodCallExpression) {
return modificationMethodNames.contains(parent.referenceName as Any?)
return if (possibleModificationMethodNames.contains(parent.referenceName))
isMutableFromUsage(parent.parent as PsiExpression)
else
modificationMethodNames.contains(parent.referenceName)
}
else if (parent is PsiExpressionList) {
val call = parent.parent as? PsiCall ?: return false
@@ -472,7 +475,12 @@ class TypeConverter(val converter: Converter) {
)
private val modificationMethodNames = setOf(
"add", "remove", "set", "addAll", "removeAll", "retainAll", "clear", "put", "putAll", "putIfAbsent", "replace", "replaceAll", "merge", "compute", "computeIfAbsent", "computeIfPresent"
"add", "remove", "set", "addAll", "removeAll", "retainAll", "clear", "put", "putAll", "putIfAbsent", "replace",
"replaceAll", "merge", "compute", "computeIfAbsent", "computeIfPresent", "removeIf"
)
private val possibleModificationMethodNames = setOf(
"iterator", "listIterator", "spliterator", "keySet", "entrySet", "values"
)
private val mutableKotlinClasses = toKotlinMutableTypesMap.values.toSet()
@@ -0,0 +1,19 @@
import java.util.*;
class Iterator {
Map<String, String> mutableMap1 = new HashMap<>();
Map<String, String> mutableMap2 = new HashMap<>();
void testFields() {
mutableMap1.values().add("")
mutableMap2.entrySet().iterator().remove();
}
void testFunctionParameters(Collection<String> immutableCollection, List<Integer> mutableList) {
for (Iterator<String> it = immutableCollection.iterator(); it.hasNext(); ) {
it.next();
}
mutableList.listIterator().add(2);
}
}
@@ -0,0 +1,20 @@
import java.util.*
internal class Iterator {
var mutableMap1: MutableMap<String, String> = HashMap()
var mutableMap2: MutableMap<String, String> = HashMap()
fun testFields() {
mutableMap1.values.add("")
mutableMap2.entries.iterator().remove()
}
fun testFunctionParameters(immutableCollection: Collection<String>, mutableList: MutableList<Int>) {
val it = immutableCollection.iterator()
while (it.hasNext()) {
it.next()
}
mutableList.listIterator().add(2)
}
}
@@ -0,0 +1,14 @@
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class TestMutableCollection {
public final List<String> list = new ArrayList<>();
public void test() {
for (Iterator<String> it = list.iterator(); it.hasNext(); ) {
String s = it.next();
if (s.equals("")) it.remove();
}
}
}
@@ -0,0 +1,13 @@
import java.util.ArrayList
class TestMutableCollection {
val list: MutableList<String> = ArrayList()
fun test() {
val it = list.iterator()
while (it.hasNext()) {
val s = it.next()
if (s == "") it.remove()
}
}
}
@@ -3653,6 +3653,18 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo
doTest(fileName);
}
@TestMetadata("Iterator.java")
public void testIterator() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/mutableCollections/Iterator.java");
doTest(fileName);
}
@TestMetadata("Iterator2.java")
public void testIterator2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/mutableCollections/Iterator2.java");
doTest(fileName);
}
@TestMetadata("Overrides.java")
public void testOverrides() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/mutableCollections/Overrides.java");
@@ -3653,6 +3653,18 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo
doTest(fileName);
}
@TestMetadata("Iterator.java")
public void testIterator() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/mutableCollections/Iterator.java");
doTest(fileName);
}
@TestMetadata("Iterator2.java")
public void testIterator2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/mutableCollections/Iterator2.java");
doTest(fileName);
}
@TestMetadata("Overrides.java")
public void testOverrides() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/mutableCollections/Overrides.java");