New J2K: introduce external code processing for new J2K

It will update usages from files not in conversion scope to a valid ones:
1. When converting (field, getter, setter) triple from Java to a Kotlin property,
   it will:
      1. Update every usage of getter/setter in Java/Kotlin code to a usage of actual property
      2. If property is used in Java directly then will add @JvmField to it
2. When converting static method or static field without getter and setter, which has Java usages then add @JvmStatic to it

#KT-34164 fixed
This commit is contained in:
Ilya Kirillov
2019-10-09 17:19:02 +03:00
parent 7535c2f249
commit f951ed9dba
16 changed files with 532 additions and 28 deletions
@@ -56,7 +56,7 @@ enum class ParseContext {
}
interface ExternalCodeProcessing {
fun prepareWriteOperation(progress: ProgressIndicator): () -> Unit
fun prepareWriteOperation(progress: ProgressIndicator?): (List<KtFile>) -> Unit
}
@@ -190,7 +190,8 @@ class OldJavaToKotlinConverter(
if (map.isEmpty()) return null
return object : ExternalCodeProcessing {
override fun prepareWriteOperation(progress: ProgressIndicator): () -> Unit {
override fun prepareWriteOperation(progress: ProgressIndicator?): (List<KtFile>) -> Unit {
if (progress == null) error("Progress should not be null for old J2K")
val refs = ArrayList<ReferenceInfo>()
progress.text = "Searching usages to update..."
@@ -322,7 +323,7 @@ class OldWithProgressProcessor(private val progress: ProgressIndicator?, private
}
}
private class ProgressPortionReporter(
class ProgressPortionReporter(
indicator: ProgressIndicator,
private val start: Double,
private val portion: Double
@@ -58,11 +58,20 @@ class AccessorToPropertyProcessing(val accessorMethod: PsiMethod, val accessorKi
if (accessorMethod.hasModifierProperty(PsiModifier.PRIVATE))
emptyList()
else
listOf(AccessorToPropertyProcessor())
listOf(AccessorToPropertyProcessor(propertyName, accessorKind))
inner class AccessorToPropertyProcessor: ExternalCodeProcessor {
class AccessorToPropertyProcessor(
private val propertyName: String,
private val accessorKind: AccessorKind
) : ExternalCodeProcessor {
override fun processUsage(reference: PsiReference): Array<PsiReference>? {
val nameExpr = reference.element as? KtSimpleNameExpression ?: return null
return processUsage(reference.element, propertyName, accessorKind)
}
}
companion object {
fun processUsage(element: PsiElement, propertyName: String, accessorKind: AccessorKind): Array<PsiReference>? {
val nameExpr = element as? KtSimpleNameExpression ?: return null
val callExpr = nameExpr.parent as? KtCallExpression ?: return null
val arguments = callExpr.valueArguments
@@ -73,8 +82,7 @@ class AccessorToPropertyProcessing(val accessorMethod: PsiMethod, val accessorKi
if (arguments.size != 0) return null // incorrect call
propertyNameExpr = callExpr.replace(propertyNameExpr) as KtSimpleNameExpression
return propertyNameExpr.references
}
else {
} else {
val value = arguments.singleOrNull()?.getArgumentExpression() ?: return null
var assignment = factory.createExpression("a = b") as KtBinaryExpression
assignment.right!!.replace(value)
@@ -85,8 +93,7 @@ class AccessorToPropertyProcessing(val accessorMethod: PsiMethod, val accessorKi
assignment.left!!.replace(qualifiedExpression)
assignment = qualifiedExpression.replace(assignment) as KtBinaryExpression
(assignment.left as KtQualifiedExpression).selectorExpression!!.references
}
else {
} else {
assignment.left!!.replace(propertyNameExpr)
assignment = callExpr.replace(assignment) as KtBinaryExpression
assignment.left!!.references