KT-12045 J2K: creating Object() instance could be converted to Any()

#KT-12045 Fixed
This commit is contained in:
Valentin Kipyatkov
2016-04-28 19:55:36 +03:00
parent 76e067c43a
commit 92af610322
11 changed files with 85 additions and 48 deletions
@@ -1,4 +1,4 @@
fun main(args: Array<String>) {
{
val a = Object()
val a = Any()
}
@@ -155,7 +155,7 @@ class Converter private constructor(
}
private fun convertFile(javaFile: PsiJavaFile): File {
var convertedChildren = javaFile.children.mapNotNull { convertTopElement(it) }
val convertedChildren = javaFile.children.mapNotNull { convertTopElement(it) }
return File(convertedChildren).assignPrototype(javaFile)
}
@@ -537,10 +537,10 @@ class Converter private constructor(
}
}
var params = convertParameterList(method, overloadReducer)
val params = convertParameterList(method, overloadReducer)
val typeParameterList = convertTypeParameterList(method.typeParameterList)
var body = deferredElement { codeConverter: CodeConverter ->
val body = deferredElement { codeConverter: CodeConverter ->
val body = codeConverter.withMethodReturnType(method.returnType).convertBlock(method.body)
postProcessBody(body)
}
@@ -617,6 +617,12 @@ class Converter private constructor(
fun convertCodeReferenceElement(element: PsiJavaCodeReferenceElement, hasExternalQualifier: Boolean, typeArgsConverted: List<Element>? = null): ReferenceElement {
val typeArgs = typeArgsConverted ?: typeConverter.convertTypes(element.typeParameters)
val targetClass = element.resolve() as? PsiClass
if (targetClass != null) {
convertToKotlinAnalogIdentifier(targetClass.qualifiedName, Mutability.Default)
?.let { return ReferenceElement(it, typeArgs).assignNoPrototype() }
}
if (element.isQualified) {
var result = Identifier.toKotlin(element.referenceName!!)
var qualifier = element.qualifier
@@ -630,7 +636,6 @@ class Converter private constructor(
else {
if (!hasExternalQualifier) {
// references to nested classes may need correction
val targetClass = element.resolve() as? PsiClass
if (targetClass != null) {
val identifier = constructNestedClassReferenceIdentifier(targetClass, specialContext ?: element)
if (identifier != null) {
@@ -374,7 +374,7 @@ class TypeConverter(val converter: Converter) {
override fun fromType(type: PsiType): Mutability {
val target = (type as? PsiClassType)?.resolve() ?: return Mutability.NonMutable
if (target.qualifiedName !in TypeVisitor.toKotlinMutableTypesMap.keys) return Mutability.NonMutable
if (target.qualifiedName !in toKotlinMutableTypesMap.keys) return Mutability.NonMutable
return Mutability.Default
}
@@ -437,6 +437,6 @@ class TypeConverter(val converter: Converter) {
"add", "remove", "set", "addAll", "removeAll", "retainAll", "clear", "put", "putAll", "putIfAbsent", "replace", "replaceAll", "merge", "compute", "computeIfAbsent", "computeIfPresent"
)
private val mutableKotlinClasses = TypeVisitor.toKotlinMutableTypesMap.values.toSet()
private val mutableKotlinClasses = toKotlinMutableTypesMap.values.toSet()
}
}
@@ -70,10 +70,8 @@ class TypeVisitor(
val psiClass = classType.resolve()
if (psiClass != null) {
val javaClassName = psiClass.qualifiedName
val kotlinClassName = (if (mutability.isMutable(converter.settings)) toKotlinMutableTypesMap[javaClassName] else null)
?: toKotlinTypesMap[javaClassName]
if (kotlinClassName != null) {
return ReferenceElement(Identifier(getShortName(kotlinClassName)).assignNoPrototype(), typeArgs).assignNoPrototype()
converter.convertToKotlinAnalogIdentifier(javaClassName, mutability)?.let {
return ReferenceElement(it, typeArgs).assignNoPrototype()
}
if (inAnnotationType && javaClassName == "java.lang.Class") {
@@ -90,8 +88,6 @@ class TypeVisitor(
return ReferenceElement(Identifier(classType.className ?: "").assignNoPrototype(), typeArgs).assignNoPrototype()
}
private fun getShortName(className: String): String = className.substringAfterLast('.', className)
private fun convertTypeArgs(classType: PsiClassType): List<Type> {
if (classType.parameterCount == 0) {
return createTypeArgsForRawTypeUsage(classType, Mutability.Default)
@@ -122,37 +118,4 @@ class TypeVisitor(
override fun visitEllipsisType(ellipsisType: PsiEllipsisType): Type {
return VarArgType(typeConverter.convertType(ellipsisType.componentType, inAnnotationType = inAnnotationType))
}
companion object {
private val toKotlinTypesMap: Map<String, String> = mapOf(
CommonClassNames.JAVA_LANG_OBJECT to BUILTIN_NAMES.any.asString(),
CommonClassNames.JAVA_LANG_BYTE to BUILTIN_NAMES._byte.asString(),
CommonClassNames.JAVA_LANG_CHARACTER to BUILTIN_NAMES._char.asString(),
CommonClassNames.JAVA_LANG_DOUBLE to BUILTIN_NAMES._double.asString(),
CommonClassNames.JAVA_LANG_FLOAT to BUILTIN_NAMES._float.asString(),
CommonClassNames.JAVA_LANG_INTEGER to BUILTIN_NAMES._int.asString(),
CommonClassNames.JAVA_LANG_LONG to BUILTIN_NAMES._long.asString(),
CommonClassNames.JAVA_LANG_SHORT to BUILTIN_NAMES._short.asString(),
CommonClassNames.JAVA_LANG_BOOLEAN to BUILTIN_NAMES._boolean.asString(),
CommonClassNames.JAVA_LANG_ITERABLE to BUILTIN_NAMES.iterable.asString(),
CommonClassNames.JAVA_UTIL_ITERATOR to BUILTIN_NAMES.iterator.asString(),
CommonClassNames.JAVA_UTIL_LIST to BUILTIN_NAMES.list.asString(),
CommonClassNames.JAVA_UTIL_COLLECTION to BUILTIN_NAMES.collection.asString(),
CommonClassNames.JAVA_UTIL_SET to BUILTIN_NAMES.set.asString(),
CommonClassNames.JAVA_UTIL_MAP to BUILTIN_NAMES.map.asString(),
CommonClassNames.JAVA_UTIL_MAP_ENTRY to BUILTIN_NAMES.mapEntry.asString(),
java.util.ListIterator::class.java.canonicalName to BUILTIN_NAMES.listIterator.asString()
)
val toKotlinMutableTypesMap: Map<String, String> = mapOf(
CommonClassNames.JAVA_UTIL_ITERATOR to BUILTIN_NAMES.mutableIterator.asString(),
CommonClassNames.JAVA_UTIL_LIST to BUILTIN_NAMES.mutableList.asString(),
CommonClassNames.JAVA_UTIL_COLLECTION to BUILTIN_NAMES.mutableCollection.asString(),
CommonClassNames.JAVA_UTIL_SET to BUILTIN_NAMES.mutableSet.asString(),
CommonClassNames.JAVA_UTIL_MAP to BUILTIN_NAMES.mutableMap.asString(),
CommonClassNames.JAVA_UTIL_MAP_ENTRY to BUILTIN_NAMES.mutableMapEntry.asString(),
java.util.ListIterator::class.java.canonicalName to BUILTIN_NAMES.mutableListIterator.asString()
)
}
}
+43
View File
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.j2k
import com.intellij.psi.*
import com.intellij.psi.util.PsiMethodUtil
import org.jetbrains.kotlin.asJava.KtLightClass
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.j2k.ast.*
import org.jetbrains.kotlin.types.expressions.OperatorConventions
@@ -129,3 +130,45 @@ fun PsiExpression.isNullLiteral() = this is PsiLiteralExpression && type == PsiT
// TODO: set origin for facade classes in library
fun isFacadeClassFromLibrary(element: PsiElement?) = element is KtLightClass && element.kotlinOrigin == null
fun Converter.convertToKotlinAnalog(classQualifiedName: String?, mutability: Mutability): String? {
if (classQualifiedName == null) return null
return (if (mutability.isMutable(settings)) toKotlinMutableTypesMap[classQualifiedName] else null)
?: toKotlinTypesMap[classQualifiedName]
}
fun Converter.convertToKotlinAnalogIdentifier(classQualifiedName: String?, mutability: Mutability): Identifier? {
val kotlinClassName = convertToKotlinAnalog(classQualifiedName, mutability) ?: return null
return Identifier(kotlinClassName.substringAfterLast('.')).assignNoPrototype()
}
private val toKotlinTypesMap: Map<String, String> = mapOf(
CommonClassNames.JAVA_LANG_OBJECT to KotlinBuiltIns.FQ_NAMES.any.asString(),
CommonClassNames.JAVA_LANG_BYTE to KotlinBuiltIns.FQ_NAMES._byte.asString(),
CommonClassNames.JAVA_LANG_CHARACTER to KotlinBuiltIns.FQ_NAMES._char.asString(),
CommonClassNames.JAVA_LANG_DOUBLE to KotlinBuiltIns.FQ_NAMES._double.asString(),
CommonClassNames.JAVA_LANG_FLOAT to KotlinBuiltIns.FQ_NAMES._float.asString(),
CommonClassNames.JAVA_LANG_INTEGER to KotlinBuiltIns.FQ_NAMES._int.asString(),
CommonClassNames.JAVA_LANG_LONG to KotlinBuiltIns.FQ_NAMES._long.asString(),
CommonClassNames.JAVA_LANG_SHORT to KotlinBuiltIns.FQ_NAMES._short.asString(),
CommonClassNames.JAVA_LANG_BOOLEAN to KotlinBuiltIns.FQ_NAMES._boolean.asString(),
CommonClassNames.JAVA_LANG_ITERABLE to KotlinBuiltIns.FQ_NAMES.iterable.asString(),
CommonClassNames.JAVA_UTIL_ITERATOR to KotlinBuiltIns.FQ_NAMES.iterator.asString(),
CommonClassNames.JAVA_UTIL_LIST to KotlinBuiltIns.FQ_NAMES.list.asString(),
CommonClassNames.JAVA_UTIL_COLLECTION to KotlinBuiltIns.FQ_NAMES.collection.asString(),
CommonClassNames.JAVA_UTIL_SET to KotlinBuiltIns.FQ_NAMES.set.asString(),
CommonClassNames.JAVA_UTIL_MAP to KotlinBuiltIns.FQ_NAMES.map.asString(),
CommonClassNames.JAVA_UTIL_MAP_ENTRY to KotlinBuiltIns.FQ_NAMES.mapEntry.asString(),
java.util.ListIterator::class.java.canonicalName to KotlinBuiltIns.FQ_NAMES.listIterator.asString()
)
val toKotlinMutableTypesMap: Map<String, String> = mapOf(
CommonClassNames.JAVA_UTIL_ITERATOR to KotlinBuiltIns.FQ_NAMES.mutableIterator.asString(),
CommonClassNames.JAVA_UTIL_LIST to KotlinBuiltIns.FQ_NAMES.mutableList.asString(),
CommonClassNames.JAVA_UTIL_COLLECTION to KotlinBuiltIns.FQ_NAMES.mutableCollection.asString(),
CommonClassNames.JAVA_UTIL_SET to KotlinBuiltIns.FQ_NAMES.mutableSet.asString(),
CommonClassNames.JAVA_UTIL_MAP to KotlinBuiltIns.FQ_NAMES.mutableMap.asString(),
CommonClassNames.JAVA_UTIL_MAP_ENTRY to KotlinBuiltIns.FQ_NAMES.mutableMapEntry.asString(),
java.util.ListIterator::class.java.canonicalName to KotlinBuiltIns.FQ_NAMES.mutableListIterator.asString()
)
+1 -1
View File
@@ -1,5 +1,5 @@
internal object Outer {
var o: Any? = Object()
var o: Any? = Any()
class Nested {
fun foo() {
@@ -103,7 +103,7 @@ internal class A {
true.toString()
1.11f.toString()
3.14.toString()
Object().toString()
Any().toString()
String.format(Locale.FRENCH, "Je ne mange pas %d jours", 6)
String.format("Operation completed with %s", "success")
@@ -0,0 +1,6 @@
class C {
void foo() {
Object o1 = new Object() {};
Object o2 = new Object();
}
}
@@ -0,0 +1,8 @@
internal class C {
fun foo() {
val o1 = object : Any() {
}
val o2 = Any()
}
}
@@ -3460,6 +3460,12 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo
doTest(fileName);
}
@TestMetadata("javaLangObject.java")
public void testJavaLangObject() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/newClassExpression/javaLangObject.java");
doTest(fileName);
}
@TestMetadata("lineBreaks.java")
public void testLineBreaks() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/newClassExpression/lineBreaks.java");
@@ -3460,6 +3460,12 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo
doTest(fileName);
}
@TestMetadata("javaLangObject.java")
public void testJavaLangObject() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/newClassExpression/javaLangObject.java");
doTest(fileName);
}
@TestMetadata("lineBreaks.java")
public void testLineBreaks() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/fileOrElement/newClassExpression/lineBreaks.java");