New J2K: handle static imports from Java correctly & do not ignore imports in tests

This commit is contained in:
Ilya Kirillov
2019-05-30 18:49:21 +03:00
parent 879abdafc2
commit 3944a976df
52 changed files with 115 additions and 138 deletions
@@ -74,7 +74,7 @@ class JavaToJKTreeBuilder constructor(
private fun PsiImportList?.toJK(filterOutUsedImports: Boolean): JKImportList =
JKImportListImpl(
this?.importStatements?.let { imports ->
this?.allImportStatements?.let { imports ->
if (filterOutUsedImports) {
imports.filter { import ->
when {
@@ -84,15 +84,15 @@ class JavaToJKTreeBuilder constructor(
}
}
} else imports.toList()
}?.map { it.toJK() }.orEmpty()
}?.mapNotNull { it.toJK() }.orEmpty()
)
private fun PsiImportStatement.isSingleUnusedImport(): Boolean {
private fun PsiImportStatementBase.isSingleUnusedImport(): Boolean {
if (isOnDemand) return false
val target = resolve() ?: return true
val ussages = ReferencesSearch.search(target).toList()
return ussages.size == 1 && PsiTreeUtil.isAncestor(this, ussages.iterator().next().element, true)
val usages = ReferencesSearch.search(target).toList()
return usages.size == 1 && PsiTreeUtil.isAncestor(this, usages.iterator().next().element, true)
}
private fun PsiPackageStatement.toJK(): JKPackageDeclaration =
@@ -102,11 +102,11 @@ class JavaToJKTreeBuilder constructor(
}
private fun PsiImportStatement.toJK(): JKImportStatement {
private fun PsiImportStatementBase.toJK(): JKImportStatement? {
val target = resolve()
val rawName = text.substringAfter("import").substringBeforeLast(";").trim()
val rawName = (importReference?.canonicalText ?: return null) + if (isOnDemand) ".*" else ""
val name =
if (target is KtLightClassForFacade) rawName.replaceAfterLast('.', "*")
if (target is KtLightClassForFacade) target.fqName.parent().asString() + ".*"
else rawName
return JKImportStatementImpl(JKNameIdentifierImpl(name))
.also {
-1
View File
@@ -11,7 +11,6 @@ import javaApi.Anon7
import javaApi.Anon8
import javaApi.E
@Anon1(value = ["a"], stringArray = ["b"], intArray = [1, 2], string = "x")
@Anon2(value = "a", intValue = 1, charValue = 'a')
@Anon3(e = E.A, stringArray = [], value = ["a", "b"])
@@ -1,5 +1,3 @@
import java.util.HashSet
internal class Foo {
fun foo(o: HashSet<*>) {
var foo = 0
+3 -2
View File
@@ -1,11 +1,12 @@
// ERROR: Null can not be a value of a non-null type Int
internal class Boxing {
fun test() {
var i: Int? = 0
var i = 0
val n: Number = 0.0f
i = 1
var j = i
val k = i + 2
i = null
j = i!!
j = i
}
}
-1
View File
@@ -4,7 +4,6 @@ package foo
// we use package 'foo'
// imports:
import java.util.ArrayList
// we need ArrayList
// let's declare a class:
@@ -10,7 +10,8 @@ class A {
this.b = b;
}
@Deprecated // this constructor will not be replaced by default parameter value in primary because of this annotation
// this constructor will not be replaced by default parameter value in primary because of this annotation
@Deprecated
public A(int a) {
this(a, 1);
}
@@ -2,7 +2,8 @@ import javaApi.Anon5
internal class A @Anon5(10) constructor(private val a: Int, private val b: Int) {
@Deprecated("") // this constructor will not be replaced by default parameter value in primary because of this annotation
// this constructor will not be replaced by default parameter value in primary because of this annotation
@Deprecated("")
constructor(a: Int) : this(a, 1) {
}
}
@@ -1,5 +1,7 @@
package pack
import pack.A.Nested
internal class A @JvmOverloads constructor(nested: Nested = Nested(Nested.FIELD)) {
internal class Nested(p: Int) {
companion object {
@@ -9,5 +11,5 @@ internal class A @JvmOverloads constructor(nested: Nested = Nested(Nested.FIELD)
}
internal class B {
var nested: A.Nested? = null
var nested: Nested? = null
}
@@ -1,6 +1,6 @@
package test
import kotlinApi.*
import kotlinApi.KotlinClassAbstractProperty
class KotlinClassAbstractPropertyImpl : KotlinClassAbstractProperty() {
override var isVisible = false
+5 -3
View File
@@ -1,8 +1,10 @@
//class
enum E {
FOO;
void foo() {
FOO.toString();
}
class A {
public static void main(String[] args) {
System.out.println(E.FOO.toString());
}
}
+5 -5
View File
@@ -1,7 +1,7 @@
internal enum class E {
FOO;
fun foo() {
FOO.toString()
internal enum class E { FOO }
internal object A {
@JvmStatic
fun main(args: Array<String>) {
println(E.FOO.toString())
}
}
-2
View File
@@ -1,5 +1,3 @@
import java.util.Objects
internal interface I
internal class C {
+1 -1
View File
@@ -1,4 +1,4 @@
import java.util.*
import java.util.ArrayList
internal class A {
private val field1: List<String> = ArrayList()
-2
View File
@@ -1,5 +1,3 @@
import java.util.ArrayList
internal class C {
fun foo(list: MutableList<String>) {
for (i in list.indices) {
@@ -1,4 +1,3 @@
// ERROR: Unresolved reference: clone
// ERROR: Unresolved reference: finalize
internal class Test : Base() {
override fun hashCode(): Int {
@@ -43,7 +42,7 @@ internal open class Base : Cloneable {
}
@Throws(Throwable::class)
protected override fun finalize() {
protected open fun finalize() {
super.finalize()
}
}
+4 -1
View File
@@ -1,6 +1,9 @@
package test
import javaApi.*
import javaApi.JFunction0
import javaApi.JFunction1
import javaApi.JFunction2
import javaApi.MethodReferenceHelperClass
internal class Test {
fun memberFun(): Int {
@@ -1,5 +1,3 @@
package test.j2k
import org.jetbrains.annotations.*
class Converter
+1 -1
View File
@@ -1,3 +1,3 @@
// ERROR: Unresolved reference: ArrayBlockingQueue
import java.util.Arrays
import java.util.concurrent.ArrayBlockingQueue
import java.util.concurrent.ArrayBlockingQueue
+5 -2
View File
@@ -1,7 +1,10 @@
// ERROR: Type mismatch: inferred type is DataInputStream but InputStream! was expected
// ERROR: Unresolved reference: close
import java.io.*
import java.lang.Exception
import java.io.BufferedReader
import java.io.DataInputStream
import java.io.File
import java.io.FileInputStream
import java.io.InputStreamReader
internal object FileRead {
@JvmStatic
+1 -1
View File
@@ -1,4 +1,4 @@
import java.util.*
import java.util.ArrayList
internal class A {
var list: List<String> = ArrayList()
@@ -1,7 +0,0 @@
public class JavaClass {
public String v = "";
public void m(String s) {
s.
this.v.
}
}
@@ -1,7 +0,0 @@
// ERROR: The expression cannot be a selector (occur after a dot)
class JavaClass {
var v = ""
fun m(s: String) {
s.this.v.
}
}
@@ -1,5 +1,3 @@
import kotlinApi.KotlinClass
import kotlinApi.KotlinClass.Companion
import kotlinApi.KotlinClass.Companion.staticFun
import kotlinApi.KotlinClass.Companion.staticProperty
import kotlinApi.KotlinClass.Companion.staticVar
@@ -1,9 +1,10 @@
import kotlinApi.*
import kotlinApi.KotlinClass.Companion
import kotlinApi.KotlinClass
import kotlinApi.KotlinClass.Companion.nullableStaticFun
import kotlinApi.KotlinClass.Companion.nullableStaticVar
import kotlinApi.KotlinClass.Companion.staticFun
import kotlinApi.KotlinClass.Companion.staticVar
import kotlinApi.globalFunction
import kotlinApi.nullableGlobalFunction
internal class A {
fun foo(c: KotlinClass): Int {
@@ -1,4 +1,4 @@
import kotlinApi.*
import kotlinApi.globalGenericFunction
internal class C {
fun foo() {
-1
View File
@@ -1,5 +1,4 @@
import kotlinApi.KotlinObject
import kotlinApi.KotlinObject.foo
import kotlinApi.KotlinObject.property1
import kotlinApi.KotlinObject.property2
@@ -1,4 +1,3 @@
import kotlinApi.KotlinClass
import kotlinApi.KotlinClass.Companion.staticProperty
internal class C {
+1 -1
View File
@@ -1,5 +1,5 @@
// ERROR: Unresolved reference: LinkedList
import java.util.*
import java.util.ArrayList
class ForEach {
fun test() {
+1 -1
View File
@@ -1,5 +1,5 @@
// ERROR: Unresolved reference: LinkedList
import java.util.*
import java.util.ArrayList
class Lists {
fun test() {
@@ -1,5 +1,3 @@
import java.util.*
internal class A {
fun foo(): Map<String, String> {
val list1: List<String> = emptyList()
@@ -1,5 +1,3 @@
import java.util.*
internal class A {
fun foo() {
val list: List<String?> = listOf(null)
@@ -14,6 +14,7 @@ class A {
int f = map.keySet().size();
int g = map.values().size();
int h = map.entrySet().size();
int i = map.entrySet().iterator().next().getKey() + 1
}
void bar(List<String> list, HashMap<String, Integer> map) {
@@ -34,10 +35,9 @@ class A {
}
for (Map.Entry<String, Integer> entry : map.entrySet()) {
String key = entry.getKey();
Integer value = entry.getValue();
if (entry.getKey() != null) {
println(value + 1)
}
entry.setValue(value + 1);
}
}
}
@@ -1,11 +1,8 @@
import java.lang.Exception
import java.lang.RuntimeException
import java.util.*
import kotlin.collections.Map.Entry
import java.util.HashMap
internal enum class E { A, B, C }
internal class A {
fun foo(list: List<String?>, collection: Collection<Int?>, map: Map<Int?, Int?>) {
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
@@ -14,15 +11,17 @@ internal class A {
val f = map.keys.size
val g = map.values.size
val h = map.entries.size
val i = map.entries.iterator().next().key + 1
}
fun bar(list: MutableList<String>, map: HashMap<String?, Int>) {
fun bar(list: MutableList<String>, map: HashMap<String, Int>) {
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()
try {
val removed = list.removeAt(10)
val isRemoved = list.remove("a")
@@ -30,10 +29,11 @@ internal class A {
System.err.println(e.message)
throw RuntimeException(e.cause)
}
for ((key, value) in map) {
if (key != null) {
println(value + 1)
}
for (entry in map.entries) {
val key = entry.key
val value = entry.value
entry.setValue(value + 1)
}
}
}
}
@@ -7,9 +7,9 @@ class A {
// 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);
new String(new int[] {32, 65, 127}, 0, 3);
byte[] bytes = new byte[] { 32, 65, 100, 81 };
byte[] bytes = new byte[] {32, 65, 100, 81};
Charset charset = Charset.forName("utf-8");
new String(bytes);
new String(bytes, charset);
@@ -59,7 +59,7 @@ class A {
s.toString();
s.toCharArray();
}
}
void specialMethods() throws Exception {
String s = "test string";
@@ -76,15 +76,18 @@ class A {
2
);
s.regionMatches(0, "st", 1, 2);
s.matches("\\w+");
s.replaceAll("\\w+", "---")
.replaceFirst("([s-t])", "A$1");
.replaceFirst("([s-t])", "A$1");
/* TODO
s.matches("\\w+");
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.concat(" another");
@@ -131,4 +134,5 @@ class A {
*/
}
void useSplit(String[] result) {}
void useSplit(String[] result) {
}
+24 -22
View File
@@ -1,7 +1,9 @@
// ERROR: Type mismatch: inferred type is String but Charset was expected
// ERROR: Type mismatch: inferred type is String but Charset was expected
// ERROR: Type mismatch: inferred type is kotlin.Comparator<String> /* = java.util.Comparator<String> */ but java.util.Comparator<String?> was expected
import java.nio.charset.Charset
import java.util.*
import java.util.Comparator
import java.util.Locale
internal class A {
@Throws(Exception::class)
@@ -69,25 +71,26 @@ internal class A {
val s = "test string"
s == "test"
s.equals(
"tesT", ignoreCase = true
)
"tesT"
, ignoreCase = true)
s.compareTo("Test", ignoreCase = true)
s.regionMatches(
0,
"TE",
0,
2, ignoreCase = true
)
2
, ignoreCase = true)
s.regionMatches(0, "st", 1, 2)
s.matches("\\w+".toRegex())
s.replace("\\w+".toRegex(), "---")
.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.replace("\\w+".toRegex(), "---").replaceFirst("([s-t])".toRegex(), "A$1")
/* TODO
s.matches("\\w+");
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 { it <= ' ' }
"$s another"
@@ -120,19 +123,18 @@ internal class A {
String(chars, 1, 2)
String(chars)
String(chars, 1, 2)
val order = String.CASE_INSENSITIVE_ORDER
val order: Comparator<String?> = 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);
*/
s.indexOf(32);
s.indexOf(32, 2);
s.lastIndexOf(32);
s.lastIndexOf(32, 2);
*/
}
fun useSplit(result: Array<String>) {}
fun useSplit(result: Array<String?>?) {}
}
@@ -1,5 +1,3 @@
import java.util.*
internal class A<T> {
fun foo(nonMutableCollection: Collection<String>,
mutableCollection: MutableCollection<String>,
@@ -1,5 +1,3 @@
import java.util.*
internal class A {
fun foo(set: MutableSet<String>) {
bar(set)
@@ -1,4 +1,4 @@
import java.util.*
import java.util.ArrayList
internal class A {
fun createCollection(): MutableCollection<String> {
@@ -1,4 +1,4 @@
import java.util.*
import java.util.ArrayList
internal class A {
private val collection: MutableCollection<String>
+1 -2
View File
@@ -1,9 +1,8 @@
import java.util.*
import java.util.HashMap
internal class IteratorTest {
var mutableMap1: MutableMap<String, String> = HashMap()
var mutableMap2: MutableMap<String, String> = HashMap()
fun testFields() {
mutableMap1.values.add("")
mutableMap2.entries.iterator().remove()
+1 -3
View File
@@ -1,5 +1,3 @@
import java.util.*
internal class A {
fun foo(collection: MutableCollection<String>) {
bar(collection)
@@ -12,4 +10,4 @@ internal class A {
collection.add("a")
}
}
}
}
@@ -1,9 +1,6 @@
package org.test
import java.util.ArrayList
internal class Member
internal class User {
fun main() {
val members: MutableList<Member> = ArrayList()
@@ -1,5 +1,4 @@
internal class A {
/* rare nullable, handle with caution */
fun nullableString(): String? {
return if (Math.random() > 0.999) {
+1 -1
View File
@@ -1,4 +1,4 @@
import java.util.*
import java.util.ArrayList
internal class A {
private val field1: List<String> = ArrayList()
@@ -1,5 +1,4 @@
import java.util.ArrayList
internal interface I<T : List<Iterator<String?>?>?>
internal class C : I<ArrayList<Iterator<String?>?>?>
@@ -2,8 +2,6 @@
// ERROR: Null can not be a value of a non-null type Iterator<String?>
package demo
import java.util.*
internal class Test : Iterable<String?> {
override fun iterator(): Iterator<String?> {
return null
-1
View File
@@ -10,6 +10,5 @@ internal class A {
} catch (e: IOException) {
e.printStackTrace()
}
}
}
+1 -3
View File
@@ -4,8 +4,6 @@ import java.io.IOException
class C {
@Throws(IOException::class)
internal fun foo() {
ByteArrayInputStream(ByteArray(10)).use { stream ->
println(stream.read())
}
ByteArrayInputStream(ByteArray(10)).use { stream -> println(stream.read()) }
}
}
@@ -1,4 +1,6 @@
import java.io.*
import java.io.ByteArrayInputStream
import java.io.IOException
import java.io.InputStream
internal interface I {
@Throws(IOException::class)
@@ -1,4 +1,6 @@
import java.io.*
import java.io.ByteArrayInputStream
import java.io.IOException
import java.io.InputStream
internal interface I {
@Throws(IOException::class)
+7 -1
View File
@@ -1,4 +1,10 @@
import java.util.*
// ERROR: Type mismatch: inferred type is Any? but String? was expected
// ERROR: Type mismatch: inferred type is (CapturedType(*)!!..CapturedType(*)) but String? was expected
// ERROR: Type mismatch: inferred type is Any? but String? was expected
// ERROR: Type mismatch: inferred type is (CapturedType(*)!!..CapturedType(*)) but String? was expected
// ERROR: Type mismatch: inferred type is HashMap<Any?, Any?> but Map<String?, String?> was expected
import java.util.HashMap
import java.util.Properties
internal object A {
fun foo(): Map<String?, String?> {
@@ -23,9 +23,6 @@ internal fun KtFile.dumpStructureText(): String {
}
return
}
if (element is KtImportDirective) {
return
}
if (element is PsiComment && (element.text.startsWith("// ERROR") || element.text.startsWith("// !"))) {
return
}