Java to Kotlin converter: minor code refactorings after code review
This commit is contained in:
@@ -80,8 +80,7 @@ fun PsiElement.getContainingConstructor(): PsiMethod? {
|
||||
fun PsiMethodCallExpression.isSuperConstructorCall(): Boolean {
|
||||
val ref = getMethodExpression()
|
||||
if (ref.getCanonicalText() == "super") {
|
||||
val target = ref.resolve()
|
||||
return target is PsiMethod && target.isConstructor()
|
||||
return ref.resolve()?.isConstructor() ?: false
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -89,3 +88,4 @@ fun PsiMethodCallExpression.isSuperConstructorCall(): Boolean {
|
||||
fun PsiReferenceExpression.isThisConstructorCall(): Boolean
|
||||
= getReferences().filter { it.getCanonicalText() == "this" }.map { it.resolve() }.any { it is PsiMethod && it.isConstructor() }
|
||||
|
||||
fun PsiElement.isConstructor(): Boolean = this is PsiMethod && this.isConstructor()
|
||||
|
||||
@@ -147,7 +147,7 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
// do not convert private static methods into class object if possible
|
||||
private fun shouldGenerateClassObject(psiClass: PsiClass, convertedMembers: Map<PsiMember, Member>): Boolean {
|
||||
if (psiClass.isEnum()) return false
|
||||
val members = convertedMembers.keySet().filter { it !is PsiMethod || !it.isConstructor() }
|
||||
val members = convertedMembers.keySet().filter { !it.isConstructor() }
|
||||
val classObjectMembers = members.filter { it !is PsiClass && it.hasModifierProperty(PsiModifier.STATIC) }
|
||||
val nestedClasses = members.filterIsInstance(javaClass<PsiClass>()).filter { it.hasModifierProperty(PsiModifier.STATIC) }
|
||||
if (classObjectMembers.all { it is PsiMethod && it.hasModifierProperty(PsiModifier.PRIVATE) }) {
|
||||
|
||||
@@ -37,8 +37,7 @@ class TypeConverter(val settings: ConverterSettings, val conversionScope: Conver
|
||||
importNames = importList?.imports?.mapTo(HashSet<String>()) { it.name } ?: setOf()
|
||||
|
||||
}
|
||||
public var importNames: Set<String> = setOf()
|
||||
private set
|
||||
private var importNames: Set<String> = setOf()
|
||||
|
||||
public val importsToAdd: Collection<Import>
|
||||
get() = classesToImport.map { Import(it) }
|
||||
@@ -46,7 +45,7 @@ class TypeConverter(val settings: ConverterSettings, val conversionScope: Conver
|
||||
public fun convertType(`type`: PsiType?, nullability: Nullability = Nullability.Default): Type {
|
||||
if (`type` == null) return Type.Empty
|
||||
|
||||
val result = `type`.accept<Type>(TypeVisitor(this, classesToImport))!!
|
||||
val result = `type`.accept<Type>(TypeVisitor(this, importNames, classesToImport))!!
|
||||
return when (nullability) {
|
||||
Nullability.NotNull -> result.toNotNullType()
|
||||
Nullability.Nullable -> result.toNullableType()
|
||||
|
||||
@@ -277,39 +277,7 @@ open class StatementVisitor(public val converter: Converter) : JavaElementVisito
|
||||
if (resourceList != null) {
|
||||
val variables = resourceList.getResourceVariables()
|
||||
if (variables.isNotEmpty()) {
|
||||
var wrapResultStatement: (Expression) -> Statement = { it }
|
||||
var converterForBody = converter
|
||||
|
||||
val returns = collectReturns(tryBlock)
|
||||
//TODO: support other returns when non-local returns supported by Kotlin
|
||||
if (returns.size == 1 && returns.single() == tryBlock!!.getStatements().last()) {
|
||||
wrapResultStatement = { ReturnStatement(it) }
|
||||
converterForBody = converter.withStatementVisitor { object : StatementVisitor(it) {
|
||||
override fun visitReturnStatement(statement: PsiReturnStatement) {
|
||||
if (statement == returns.single()) {
|
||||
result = converter.convertExpression(statement.getReturnValue(), tryStatement.getContainingMethod()?.getReturnType())
|
||||
}
|
||||
else {
|
||||
super.visitReturnStatement(statement)
|
||||
}
|
||||
}
|
||||
}}
|
||||
}
|
||||
|
||||
var block = converterForBody.convertBlock(tryBlock)
|
||||
var expression: Expression = Expression.Empty
|
||||
for (variable in variables.reverse()) {
|
||||
val lambda = LambdaExpression(Identifier.toKotlin(variable.getName()!!), block)
|
||||
expression = MethodCallExpression.build(converter.convertExpression(variable.getInitializer()), "use", listOf(), listOf(), false, lambda)
|
||||
block = Block(listOf(expression), LBrace(), RBrace())
|
||||
}
|
||||
|
||||
if (catchesConverted.isEmpty() && finallyConverted.isEmpty) {
|
||||
result = wrapResultStatement(expression)
|
||||
return
|
||||
}
|
||||
|
||||
result = TryStatement(Block(listOf(wrapResultStatement(expression)), LBrace(), RBrace(), true), catchesConverted, finallyConverted)
|
||||
result = convertTryWithResources(tryBlock, variables, catchesConverted, finallyConverted)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -317,6 +285,41 @@ open class StatementVisitor(public val converter: Converter) : JavaElementVisito
|
||||
result = TryStatement(converter.convertBlock(tryBlock), catchesConverted, finallyConverted)
|
||||
}
|
||||
|
||||
private fun convertTryWithResources(tryBlock: PsiCodeBlock?, resourceVariables: List<PsiResourceVariable>, catchesConverted: List<CatchStatement>, finallyConverted: Block): Statement {
|
||||
var wrapResultStatement: (Expression) -> Statement = { it }
|
||||
var converterForBody = converter
|
||||
|
||||
val returns = collectReturns(tryBlock)
|
||||
//TODO: support other returns when non-local returns supported by Kotlin
|
||||
if (returns.size == 1 && returns.single() == tryBlock!!.getStatements().last()) {
|
||||
wrapResultStatement = { ReturnStatement(it) }
|
||||
converterForBody = converter.withStatementVisitor { object : StatementVisitor(it) {
|
||||
override fun visitReturnStatement(statement: PsiReturnStatement) {
|
||||
if (statement == returns.single()) {
|
||||
result = converter.convertExpression(statement.getReturnValue(), tryBlock!!.getContainingMethod()?.getReturnType())
|
||||
}
|
||||
else {
|
||||
super.visitReturnStatement(statement)
|
||||
}
|
||||
}
|
||||
}}
|
||||
}
|
||||
|
||||
var block = converterForBody.convertBlock(tryBlock)
|
||||
var expression: Expression = Expression.Empty
|
||||
for (variable in resourceVariables.reverse()) {
|
||||
val lambda = LambdaExpression(Identifier.toKotlin(variable.getName()!!), block)
|
||||
expression = MethodCallExpression.build(converter.convertExpression(variable.getInitializer()), "use", listOf(), listOf(), false, lambda)
|
||||
block = Block(listOf(expression), LBrace(), RBrace())
|
||||
}
|
||||
|
||||
if (catchesConverted.isEmpty() && finallyConverted.isEmpty) {
|
||||
return wrapResultStatement(expression)
|
||||
}
|
||||
|
||||
return TryStatement(Block(listOf(wrapResultStatement(expression)), LBrace(), RBrace(), true), catchesConverted, finallyConverted)
|
||||
}
|
||||
|
||||
private fun collectReturns(block: PsiCodeBlock?): Collection<PsiReturnStatement> {
|
||||
val returns = ArrayList<PsiReturnStatement>()
|
||||
block?.accept(object: JavaRecursiveElementVisitor() {
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.jet.j2k.TypeConverter
|
||||
|
||||
private val PRIMITIVE_TYPES_NAMES = JvmPrimitiveType.values().map { it.getName() }
|
||||
|
||||
class TypeVisitor(private val converter: TypeConverter, private val classesToImport: MutableSet<String>) : PsiTypeVisitor<Type>() {
|
||||
class TypeVisitor(private val converter: TypeConverter, private val importNames: Set<String>, private val classesToImport: MutableSet<String>) : PsiTypeVisitor<Type>() {
|
||||
override fun visitPrimitiveType(primitiveType: PsiPrimitiveType): Type {
|
||||
val name = primitiveType.getCanonicalText()
|
||||
return if (name == "void") {
|
||||
@@ -75,7 +75,7 @@ class TypeVisitor(private val converter: TypeConverter, private val classesToImp
|
||||
val kotlinClassName = toKotlinTypesMap[javaClassName]
|
||||
if (kotlinClassName != null) {
|
||||
val kotlinShortName = getShortName(kotlinClassName)
|
||||
if (kotlinShortName == getShortName(javaClassName!!) && converter.importNames.contains(getPackageName(javaClassName) + ".*")) {
|
||||
if (kotlinShortName == getShortName(javaClassName!!) && importNames.contains(getPackageName(javaClassName) + ".*")) {
|
||||
classesToImport.add(kotlinClassName)
|
||||
}
|
||||
return Identifier(kotlinShortName)
|
||||
|
||||
Reference in New Issue
Block a user