New J2K: Finish DefaultArgumentsConversion

This commit is contained in:
Ilya Kirillov
2019-04-08 20:32:43 +03:00
parent 008e7a5add
commit ae3920d535
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.nj2k.conversions
import org.jetbrains.kotlin.nj2k.ConversionContext
import org.jetbrains.kotlin.nj2k.copyTreeAndDetach
import org.jetbrains.kotlin.nj2k.jvmAnnotation
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKFieldAccessExpressionImpl
@@ -25,10 +26,9 @@ class DefaultArgumentsConversion(private val context: ConversionContext) : Recur
override fun applyToElement(element: JKTreeElement): JKTreeElement {
// TODO: Declaration list owner
if (element !is JKClass) return recurse(element)
if (element !is JKClassBody) return recurse(element)
val methods = element.declarationList.filterIsInstance<JKMethod>().sortedBy { it.parameters.size }
val methods = element.declarations.filterIsInstance<JKMethod>().sortedBy { it.parameters.size }
checkMethod@ for (method in methods) {
val block = method.block as? JKBlock ?: continue
@@ -47,7 +47,6 @@ class DefaultArgumentsConversion(private val context: ConversionContext) : Recur
}
// TODO: Filter by annotations, visibility, modality, extraModifiers like synchronized
if (calledMethod.visibility != method.visibility) continue@checkMethod
if (calledMethod.canNotBeMerged()) continue
@@ -58,6 +57,28 @@ class DefaultArgumentsConversion(private val context: ConversionContext) : Recur
if (parameter.name.value != targetParameter.name.value) continue@checkMethod
if (parameter.type.type != targetParameter.type.type) continue@checkMethod
if (argument !is JKFieldAccessExpression || argument.identifier.target != parameter) continue@checkMethod
if (parameter.initializer !is JKStubExpression
&& targetParameter.initializer !is JKStubExpression
&& !areTheSameExpressions(targetParameter.initializer, parameter.initializer)
) continue@checkMethod
}
for (i in method.parameters.indices) {
val parameter = method.parameters[i]
val targetParameter = calledMethod.parameters[i]
if (parameter.initializer !is JKStubExpression
&& targetParameter.initializer is JKStubExpression
) {
targetParameter.initializer = parameter.initializer.copyTreeAndDetach()
}
}
for (index in (method.parameters.lastIndex + 1)..calledMethod.parameters.lastIndex) {
val calleeExpression = call.arguments.arguments[index].value
val defaultArgument = calledMethod.parameters[index].initializer.takeIf { it !is JKStubExpression } ?: continue
if (!areTheSameExpressions(calleeExpression, defaultArgument)) continue@checkMethod
}
@@ -67,6 +88,7 @@ class DefaultArgumentsConversion(private val context: ConversionContext) : Recur
.zip(calledMethod.parameters)
.drop(method.parameters.size)
for ((defaultValue, parameter) in defaults) {
fun remapParameterSymbol(on: JKTreeElement): JKTreeElement {
if (on is JKFieldAccessExpression) {
@@ -83,12 +105,14 @@ class DefaultArgumentsConversion(private val context: ConversionContext) : Recur
parameter.initializer = remapParameterSymbol(defaultValue) as JKExpression
}
element.classBody.declarations -= method
element.declarations -= method
}
for (method in element.declarationList) {
for (method in element.declarations) {
if (method !is JKJavaMethod) continue
if (method.hasParametersWithDefaultValues() && (method.visibility == Visibility.PUBLIC || method.visibility == Visibility.INTERNAL)) {
if (method.hasParametersWithDefaultValues()
&& (method.visibility == Visibility.PUBLIC || method.visibility == Visibility.INTERNAL)
) {
method.annotationList.annotations += jvmAnnotation("JvmOverloads", context.symbolProvider)
}
}
@@ -97,6 +121,35 @@ class DefaultArgumentsConversion(private val context: ConversionContext) : Recur
}
private fun areTheSameExpressions(first: JKElement, second: JKElement): Boolean {
if (first::class != second::class) return false
if (first is JKNameIdentifier && second is JKNameIdentifier) return first.value == second.value
if (first is JKLiteralExpression && second is JKLiteralExpression) return first.literal == second.literal
if (first is JKFieldAccessExpression && second is JKFieldAccessExpression && first.identifier != second.identifier) return false
if (first is JKMethodCallExpression && second is JKMethodCallExpression && first.identifier != second.identifier) return false
return if (first is JKBranchElement && second is JKBranchElement) {
first.children.zip(second.children) { childOfFirst, childOfSecond ->
when {
childOfFirst is JKBranchElement && childOfSecond is JKBranchElement -> {
areTheSameExpressions(
childOfFirst,
childOfSecond
)
}
childOfFirst is List<*> && childOfSecond is List<*> -> {
childOfFirst.zip(childOfSecond) { child1, child2 ->
areTheSameExpressions(
child1 as JKElement,
child2 as JKElement
)
}.reduce(Boolean::and)
}
else -> false
}
}.reduce(Boolean::and)
} else false
}
private fun JKMethod.hasParametersWithDefaultValues() =
parameters.any { it.initializer !is JKStubExpression }