From 008e7a5add4b7f62b5d6c826262baa34d6fde71a Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Mon, 8 Apr 2019 19:33:46 +0300 Subject: [PATCH] New J2K: do not use some keyword removing processings due to incorrect formatting after it --- .../kotlin/nj2k/NewJ2kPostProcessings.kt | 71 ++++++++++++++++++- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/NewJ2kPostProcessings.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/NewJ2kPostProcessings.kt index 266814aaf69..99bee0492f9 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/NewJ2kPostProcessings.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/NewJ2kPostProcessings.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.nj2k import com.intellij.codeInspection.* import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.project.Project +import com.intellij.psi.PsiComment import com.intellij.psi.PsiElement import com.intellij.psi.search.LocalSearchScope import com.intellij.psi.search.searches.ReferencesSearch @@ -22,8 +23,11 @@ import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.idea.analysis.analyzeInContext import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny +import org.jetbrains.kotlin.idea.core.implicitModality +import org.jetbrains.kotlin.idea.core.implicitVisibility import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.setVisibility +import org.jetbrains.kotlin.idea.formatter.commitAndUnblockDocument import org.jetbrains.kotlin.idea.inspections.* import org.jetbrains.kotlin.idea.inspections.branchedTransformations.IfThenToSafeAccessInspection import org.jetbrains.kotlin.idea.inspections.conventionNameCalls.ReplaceGetOrSetInspection @@ -40,13 +44,13 @@ import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.references.readWriteAccess import org.jetbrains.kotlin.idea.util.getResolutionScope import org.jetbrains.kotlin.j2k.ConverterSettings +import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.nj2k.postProcessing.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny import org.jetbrains.kotlin.resolve.calls.callUtil.getType import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode @@ -57,6 +61,8 @@ import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.mapToIndex import java.util.* +import kotlin.reflect.KClass +import kotlin.reflect.full.isSubclassOf interface NewJ2kPostProcessing { fun createAction(element: PsiElement, diagnostics: Diagnostics, settings: ConverterSettings?): (() -> Unit)? = @@ -124,8 +130,9 @@ object NewJ2KPostProcessingRegistrar { SingleOneTimeProcessing(registerGeneralInspectionBasedProcessing(RedundantSetterInspection())), SingleOneTimeProcessing(ConvertDataClass()), RepeatableProcessingGroup( - registerGeneralInspectionBasedProcessing(RedundantModalityModifierInspection()), - registerGeneralInspectionBasedProcessing(RedundantVisibilityModifierInspection()), + RemoveRedundantVisibilityModifierProcessing(), + RemoveRedundantModalityModifierProcessing(), + RemoveRedundantConstructorKeywordProcessing(), registerDiagnosticBasedProcessing(Errors.REDUNDANT_OPEN_IN_INTERFACE) { element: KtDeclaration, diagnostic -> element.removeModifier(KtTokens.OPEN_KEYWORD) }, @@ -868,4 +875,62 @@ object NewJ2KPostProcessingRegistrar { override val writeActionNeeded: Boolean = true } + private class RemoveRedundantConstructorKeywordProcessing : CheckableProcessing(KtPrimaryConstructor::class) { + override fun check(element: KtPrimaryConstructor): Boolean = + element.containingClassOrObject is KtClass + && element.getConstructorKeyword() != null + && element.annotationEntries.isEmpty() + && element.visibilityModifier() == null + + + override fun action(element: KtPrimaryConstructor) { + element.removeRedundantConstructorKeywordAndSpace() + } + } + + private class RemoveRedundantModalityModifierProcessing : CheckableProcessing(KtDeclaration::class) { + override fun check(element: KtDeclaration): Boolean { + val modalityModifier = element.modalityModifier() ?: return false + val modalityModifierType = modalityModifier.node.elementType + val implicitModality = element.implicitModality() + + return modalityModifierType == implicitModality + } + + override fun action(element: KtDeclaration) { + element.removeModifierSmart(element.modalityModifierType()!!) + } + } + + //hack until KT-30804 is fixed + private fun KtModifierListOwner.removeModifierSmart(modifierToken: KtModifierKeywordToken) { + val modifier = modifierList?.getModifier(modifierToken) + val comment = modifier?.getPrevSiblingIgnoringWhitespace() as? PsiComment + comment?.also { + it.parent.addAfter(KtPsiFactory(this).createNewLine(), it) + } + val newElement = copy() as KtModifierListOwner + newElement.removeModifier(modifierToken) + replace(newElement) + containingFile.commitAndUnblockDocument() + } + + private class RemoveRedundantVisibilityModifierProcessing : CheckableProcessing(KtDeclaration::class) { + override fun check(element: KtDeclaration): Boolean { + val visibilityModifier = element.visibilityModifier() ?: return false + val implicitVisibility = element.implicitVisibility() + return when { + visibilityModifier.node.elementType == implicitVisibility -> + true + element.hasModifier(KtTokens.INTERNAL_KEYWORD) && element.containingClassOrObject?.isLocal == true -> + true + else -> false + } + } + + override fun action(element: KtDeclaration) { + element.removeModifierSmart(element.visibilityModifierType()!!) + } + } + } \ No newline at end of file