diff --git a/idea/src/org/jetbrains/kotlin/idea/j2k/NewJ2kPostProcessings.kt b/idea/src/org/jetbrains/kotlin/idea/j2k/NewJ2kPostProcessings.kt index b882c2bb33d..cd8397e369e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/j2k/NewJ2kPostProcessings.kt +++ b/idea/src/org/jetbrains/kotlin/idea/j2k/NewJ2kPostProcessings.kt @@ -46,6 +46,8 @@ import org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions.I import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isTrivialStatementBody import org.jetbrains.kotlin.idea.j2k.postProcessing.ConvertDataClass import org.jetbrains.kotlin.idea.j2k.postProcessing.ConvertGettersAndSetters +import org.jetbrains.kotlin.idea.j2k.postProcessing.resolve +import org.jetbrains.kotlin.idea.j2k.postProcessing.topLevelContainingClassOrObject import org.jetbrains.kotlin.idea.quickfix.* import org.jetbrains.kotlin.idea.references.KtSimpleNameReference import org.jetbrains.kotlin.idea.references.mainReference @@ -161,6 +163,9 @@ object NewJ2KPostProcessingRegistrarImpl : J2KPostProcessingRegistrar { override val writeActionNeeded: Boolean = true }), + SingleProcessing(RemoveRedundantTypeQualifierProcessing()), + SingleProcessing(RemoveRedundantExpressionQualifierProcessing()), + registerDiagnosticBasedProcessing(Errors.USELESS_CAST) { element, _ -> val expression = RemoveUselessCastFix.invoke(element) @@ -667,4 +672,48 @@ object NewJ2KPostProcessingRegistrarImpl : J2KPostProcessingRegistrar { } } + private class RemoveRedundantExpressionQualifierProcessing : J2kPostProcessing { + private fun check(qualifiedExpression: KtQualifiedExpression): Boolean { + val qualifier = (qualifiedExpression.receiverExpression as? KtNameReferenceExpression) + ?.referenceExpression() + ?.resolve() as? KtClassOrObject ?: return false + val topLevelClass = qualifiedExpression.getStrictParentOfType() ?: return false + return topLevelClass == qualifier + } + + override fun createAction(element: KtElement, diagnostics: Diagnostics): (() -> Unit)? { + if (element !is KtQualifiedExpression) return null + if (!check(element)) return null + return { + if (element.isValid() && check(element)) { + element.replace(element.selectorExpression!!) + } + } + } + + override val writeActionNeeded: Boolean = true + } + + private class RemoveRedundantTypeQualifierProcessing : J2kPostProcessing { + private fun check(reference: KtUserType): Boolean { + val qualifierClass = reference.qualifier + ?.referenceExpression + ?.resolve() as? KtClassOrObject ?: return false + val topLevelClass = reference.topLevelContainingClassOrObject() ?: return false + return topLevelClass.isAncestor(qualifierClass) + } + + override fun createAction(element: KtElement, diagnostics: Diagnostics): (() -> Unit)? { + if (element !is KtUserType) return null + if (!check(element)) return null + return { + if (element.isValid && check(element)) { + element.deleteQualifier() + } + } + } + + override val writeActionNeeded: Boolean = true + } + } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/j2k/postProcessing/utils.kt b/idea/src/org/jetbrains/kotlin/idea/j2k/postProcessing/utils.kt index 1cbf57fd449..2dc323ef5e0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/j2k/postProcessing/utils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/j2k/postProcessing/utils.kt @@ -11,6 +11,8 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.references.KtSimpleNameReference import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.containingClass +import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType fun KtExpression.asProperty(): KtProperty? = @@ -32,4 +34,14 @@ fun KtExpression.unpackedReferenceToProperty(): KtProperty? = fun KtDeclaration.type() = - (resolveToDescriptorIfAny() as? CallableDescriptor)?.returnType \ No newline at end of file + (resolveToDescriptorIfAny() as? CallableDescriptor)?.returnType + +fun KtElement.topLevelContainingClassOrObject(): KtClassOrObject? = + generateSequence(getStrictParentOfType()) { + it.getStrictParentOfType() + }.lastOrNull() + +fun KtReferenceExpression.resolve() = + references + .firstOrNull { it is KtSimpleNameReference } + ?.resolve() \ No newline at end of file