diff --git a/compiler/frontend/src/org/jetbrains/kotlin/extensions/DeclarationAttributeAltererExtension.kt b/compiler/frontend/src/org/jetbrains/kotlin/extensions/DeclarationAttributeAltererExtension.kt index 2bc3f00f720..7a245ed40dc 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/extensions/DeclarationAttributeAltererExtension.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/extensions/DeclarationAttributeAltererExtension.kt @@ -36,7 +36,8 @@ interface DeclarationAttributeAltererExtension { declaration: DeclarationDescriptor?, containingDeclaration: DeclarationDescriptor?, currentModality: Modality, - bindingContext: BindingContext + bindingContext: BindingContext, + isImplicitModality: Boolean ): Modality? = null fun shouldConvertFirstSAMParameterToReceiver(function: FunctionDescriptor) : Boolean = false diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt index 2828669308c..3b8e9420dff 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/ktPsiUtil.kt @@ -178,27 +178,6 @@ fun KtBlockExpression.contentRange(): PsiChildRange { // ----------- Inheritance ----------------------------------------------------------------------------------------------------------------- -fun KtClass.isInheritable(): Boolean { - return isInterface() || hasModifier(KtTokens.OPEN_KEYWORD) || - hasModifier(KtTokens.ABSTRACT_KEYWORD) || hasModifier(KtTokens.SEALED_KEYWORD) -} - -fun KtDeclaration.isOverridable(): Boolean { - val parent = parent - if (!(parent is KtClassBody || parent is KtParameterList)) return false - - val klass = if (parent.parent is KtPrimaryConstructor) - parent.parent.parent as? KtClass - else - parent.parent as? KtClass - if (klass == null || (!klass.isInheritable() && !klass.isEnum())) return false - - if (hasModifier(KtTokens.FINAL_KEYWORD) || hasModifier(KtTokens.PRIVATE_KEYWORD)) return false - - return klass.isInterface() || - hasModifier(KtTokens.ABSTRACT_KEYWORD) || hasModifier(KtTokens.OPEN_KEYWORD) || hasModifier(KtTokens.OVERRIDE_KEYWORD) -} - fun KtClass.isAbstract(): Boolean = isInterface() || hasModifier(KtTokens.ABSTRACT_KEYWORD) /** diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java index bcb718487e3..3d806bdaf29 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java @@ -131,7 +131,7 @@ public class ModifiersChecker { DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, modifierListOwner); for (DeclarationAttributeAltererExtension extension : extensions) { Modality newModality = extension.refineDeclarationModality( - modifierListOwner, descriptor, containingDescriptor, modality, bindingContext); + modifierListOwner, descriptor, containingDescriptor, modality, bindingContext, false); if (newModality != null) { modality = newModality; diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/overridersSearch.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/overridersSearch.kt index 83e46845e2d..27bcf6c6ea5 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/overridersSearch.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/declarationsSearch/overridersSearch.kt @@ -26,10 +26,10 @@ import com.intellij.util.MergeQuery import com.intellij.util.Processor import com.intellij.util.Query import org.jetbrains.kotlin.asJava.toLightMethods +import org.jetbrains.kotlin.idea.core.isOverridable import org.jetbrains.kotlin.idea.search.allScope import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.psi.KtDeclaration -import org.jetbrains.kotlin.psi.psiUtil.isOverridable import java.util.* fun PsiElement.isOverridableElement(): Boolean = when (this) { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt index cd16bd1f9ef..c9ca1930129 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt @@ -19,11 +19,10 @@ package org.jetbrains.kotlin.idea.core import com.intellij.psi.PsiElement import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.impl.source.codeStyle.CodeEditUtil +import com.intellij.psi.tree.IElementType import com.intellij.psi.util.PsiTreeUtil -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers @@ -232,7 +231,84 @@ fun KtModifierListOwner.canBeProtected(): Boolean { } } +fun KtClass.isInheritable(): Boolean { + return when (getModalityFromDescriptor()) { + KtTokens.ABSTRACT_KEYWORD, KtTokens.OPEN_KEYWORD, KtTokens.SEALED_KEYWORD -> true + else -> false + } +} + +fun KtDeclaration.isOverridable(): Boolean { + val parent = parent + if (!(parent is KtClassBody || parent is KtParameterList)) return false + + val klass = if (parent.parent is KtPrimaryConstructor) + parent.parent.parent as? KtClass + else + parent.parent as? KtClass + + if (klass == null || (!klass.isInheritable() && !klass.isEnum())) return false + + if (this.hasModifier(KtTokens.PRIVATE_KEYWORD)) { + // 'private' is incompatible with 'open' + return false + } + + return when (getModalityFromDescriptor()) { + KtTokens.ABSTRACT_KEYWORD, KtTokens.OPEN_KEYWORD -> true + else -> false + } +} + +fun KtDeclaration.getModalityFromDescriptor(): KtModifierKeywordToken? { + val descriptor = this.resolveToDescriptor(BodyResolveMode.PARTIAL) + if (descriptor is MemberDescriptor) { + return mapModality(descriptor.modality) + } + + return null +} + fun KtDeclaration.implicitModality(): KtModifierKeywordToken { + var predictedModality = predictImplicitModality() + val bindingContext = analyze(BodyResolveMode.PARTIAL) + val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, this] ?: return predictedModality + val containingDescriptor = descriptor.containingDeclaration ?: return predictedModality + + val extensions = DeclarationAttributeAltererExtension.getInstances(this.project) + for (extension in extensions) { + val newModality = extension.refineDeclarationModality( + this, + null, + containingDescriptor, + mapModalityToken(predictedModality), + bindingContext, + isImplicitModality = true) + + if (newModality != null) { + predictedModality = mapModality(newModality) + } + } + + return predictedModality +} + +fun mapModality(accurateModality: Modality): KtModifierKeywordToken = when (accurateModality) { + Modality.FINAL -> KtTokens.FINAL_KEYWORD + Modality.SEALED -> KtTokens.SEALED_KEYWORD + Modality.OPEN -> KtTokens.OPEN_KEYWORD + Modality.ABSTRACT -> KtTokens.ABSTRACT_KEYWORD +} + +private fun mapModalityToken(modalityToken: IElementType): Modality = when (modalityToken) { + KtTokens.FINAL_KEYWORD -> Modality.FINAL + KtTokens.SEALED_KEYWORD -> Modality.SEALED + KtTokens.OPEN_KEYWORD -> Modality.OPEN + KtTokens.ABSTRACT_KEYWORD -> Modality.ABSTRACT + else -> error("Unexpected modality keyword $modalityToken") +} + +private fun KtDeclaration.predictImplicitModality(): KtModifierKeywordToken { if (this is KtClassOrObject) { if (this is KtClass && this.isInterface()) return KtTokens.ABSTRACT_KEYWORD return KtTokens.FINAL_KEYWORD diff --git a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateEqualsWizard.kt b/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateEqualsWizard.kt index 03256381616..5137309bd0b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateEqualsWizard.kt +++ b/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateEqualsWizard.kt @@ -25,11 +25,11 @@ import com.intellij.openapi.ui.VerticalFlowLayout import com.intellij.refactoring.classMembers.AbstractMemberInfoModel import com.intellij.ui.NonFocusableCheckBox import com.intellij.util.containers.HashMap +import org.jetbrains.kotlin.idea.core.isInheritable import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfo import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionPanel import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtNamedDeclaration -import org.jetbrains.kotlin.psi.psiUtil.isInheritable import org.jetbrains.kotlin.utils.keysToMap import javax.swing.JLabel import javax.swing.JPanel diff --git a/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinFindUsagesHandlerFactory.kt b/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinFindUsagesHandlerFactory.kt index 33aaa319227..ed694bbb7af 100644 --- a/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinFindUsagesHandlerFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinFindUsagesHandlerFactory.kt @@ -29,6 +29,7 @@ import com.intellij.psi.PsiElement import com.intellij.psi.search.searches.OverridingMethodsSearch import org.jetbrains.kotlin.asJava.toLightMethods import org.jetbrains.kotlin.asJava.unwrapped +import org.jetbrains.kotlin.idea.core.isOverridable import org.jetbrains.kotlin.idea.findUsages.handlers.DelegatingFindMemberUsagesHandler import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindClassUsagesHandler import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindMemberUsagesHandler @@ -36,7 +37,6 @@ import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinTypeParameterFindUsag import org.jetbrains.kotlin.idea.refactoring.checkSuperMethods import org.jetbrains.kotlin.plugin.findUsages.handlers.KotlinFindUsagesHandlerDecorator import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.isOverridable import org.jetbrains.kotlin.psi.psiUtil.parameterIndex import java.lang.IllegalArgumentException diff --git a/idea/src/org/jetbrains/kotlin/idea/findUsages/dialogs/KotlinFindClassUsagesDialog.java b/idea/src/org/jetbrains/kotlin/idea/findUsages/dialogs/KotlinFindClassUsagesDialog.java index 0f5c0054f38..79165721912 100644 --- a/idea/src/org/jetbrains/kotlin/idea/findUsages/dialogs/KotlinFindClassUsagesDialog.java +++ b/idea/src/org/jetbrains/kotlin/idea/findUsages/dialogs/KotlinFindClassUsagesDialog.java @@ -32,12 +32,11 @@ import com.intellij.ui.StateRestoringCheckBox; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.asJava.LightClassUtilsKt; import org.jetbrains.kotlin.idea.KotlinBundle; +import org.jetbrains.kotlin.idea.core.PsiModificationUtilsKt; import org.jetbrains.kotlin.idea.findUsages.KotlinClassFindUsagesOptions; import org.jetbrains.kotlin.idea.refactoring.RenderingUtilsKt; import org.jetbrains.kotlin.psi.KtClass; import org.jetbrains.kotlin.psi.KtClassOrObject; -import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt; - import javax.swing.*; import static org.jetbrains.kotlin.asJava.LightClassUtilsKt.toLightClass; @@ -91,7 +90,7 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog { //noinspection ConstantConditions javaClass.getModifierList().setModifierProperty( PsiModifier.FINAL, - !(classOrObject instanceof KtClass && KtPsiUtilKt.isInheritable((KtClass) classOrObject)) + !(classOrObject instanceof KtClass && PsiModificationUtilsKt.isInheritable((KtClass) classOrObject)) ); javaClass.putUserData(ORIGINAL_CLASS, classOrObject); diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt index 3809c8e3e16..19830505a86 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt @@ -41,13 +41,13 @@ import org.jetbrains.kotlin.descriptors.MemberDescriptor import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.idea.KotlinIcons import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor +import org.jetbrains.kotlin.idea.core.isInheritable +import org.jetbrains.kotlin.idea.core.isOverridable import org.jetbrains.kotlin.idea.core.toDescriptor import org.jetbrains.kotlin.idea.highlighter.allImplementingCompatibleModules import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.isInheritable -import org.jetbrains.kotlin.psi.psiUtil.isOverridable import java.awt.event.MouseEvent import java.util.* import javax.swing.Icon diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/MemberVisibilityCanPrivateInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/MemberVisibilityCanPrivateInspection.kt index 36e5f5a4b83..c65f1f46a3e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/MemberVisibilityCanPrivateInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/MemberVisibilityCanPrivateInspection.kt @@ -27,12 +27,16 @@ import com.intellij.psi.search.PsiSearchHelper import com.intellij.psi.search.searches.ReferencesSearch import com.intellij.util.Processor import org.jetbrains.kotlin.idea.core.toDescriptor +import org.jetbrains.kotlin.idea.core.isInheritable +import org.jetbrains.kotlin.idea.core.isOverridable import org.jetbrains.kotlin.idea.quickfix.AddModifierFix import org.jetbrains.kotlin.idea.refactoring.isConstructorDeclaredProperty import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmFieldAnnotation +import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject +import org.jetbrains.kotlin.psi.psiUtil.getParentOfType class MemberVisibilityCanPrivateInspection : AbstractKotlinInspection() { diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/ProtectedInFinalInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/ProtectedInFinalInspection.kt index 1417a1880a1..f0a3f184add 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/ProtectedInFinalInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/ProtectedInFinalInspection.kt @@ -21,6 +21,7 @@ import com.intellij.codeInspection.* import com.intellij.openapi.project.Project import com.intellij.psi.PsiElementVisitor import org.jetbrains.kotlin.idea.core.implicitVisibility +import org.jetbrains.kotlin.idea.core.isInheritable import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtDeclaration @@ -28,7 +29,6 @@ import org.jetbrains.kotlin.psi.KtModifierListOwner import org.jetbrains.kotlin.psi.KtVisitorVoid import org.jetbrains.kotlin.psi.addRemoveModifier.addModifier import org.jetbrains.kotlin.psi.psiUtil.getParentOfType -import org.jetbrains.kotlin.psi.psiUtil.isInheritable import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier class ProtectedInFinalInspection : AbstractKotlinInspection() { diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantModalityModifierInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantModalityModifierInspection.kt index 34596485dfb..6e9cd92dbce 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantModalityModifierInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantModalityModifierInspection.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.core.implicitModality +import org.jetbrains.kotlin.idea.core.mapModality import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFix import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtDeclaration @@ -41,10 +42,6 @@ class RedundantModalityModifierInspection : AbstractKotlinInspection(), CleanupL if (modalityModifierType != implicitModality) return - // Descriptor may have the different modality (in case of all-open plugin enabled, for example) - val modalityFromPsi = getModality(implicitModality) - if (modalityFromPsi != null && hasRefinedModalityInDescriptor(declaration, modalityFromPsi)) return - holder.registerProblem(modalityModifier, "Redundant modality modifier", ProblemHighlightType.LIKE_UNUSED_SYMBOL, @@ -53,24 +50,4 @@ class RedundantModalityModifierInspection : AbstractKotlinInspection(), CleanupL } } } - - private fun hasRefinedModalityInDescriptor( - declaration: KtDeclaration, - implicitModality: Modality - ): Boolean { - val bindingContext = declaration.analyze(BodyResolveMode.PARTIAL) - val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration] ?: return false - return DeclarationAttributeAltererExtension.getInstances(declaration.project).any { - it.refineDeclarationModality(declaration, descriptor, descriptor.containingDeclaration, - implicitModality, bindingContext) != null - } - } - - private fun getModality(modalityToken: IElementType): Modality? = when (modalityToken) { - KtTokens.FINAL_KEYWORD -> Modality.FINAL - KtTokens.SEALED_KEYWORD -> Modality.SEALED - KtTokens.OPEN_KEYWORD -> Modality.OPEN - KtTokens.ABSTRACT_KEYWORD -> Modality.ABSTRACT - else -> null - } } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedReceiverParameterInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedReceiverParameterInspection.kt index 904f1aaa90b..c4203d82b80 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedReceiverParameterInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedReceiverParameterInspection.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.core.isOverridable import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinChangeSignatureConfiguration import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinMethodDescriptor import org.jetbrains.kotlin.idea.refactoring.changeSignature.modify @@ -33,7 +34,6 @@ import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.idea.util.getThisReceiverOwner import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.isOverridable import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt index c66b0ee27c4..7eccea6d0ea 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt @@ -52,6 +52,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny +import org.jetbrains.kotlin.idea.core.isInheritable import org.jetbrains.kotlin.idea.core.toDescriptor import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindClassUsagesHandler diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionToSupertypeFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionToSupertypeFix.kt index 7e1daf0bb28..c587b369335 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionToSupertypeFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionToSupertypeFix.kt @@ -29,7 +29,6 @@ import com.intellij.util.PlatformIcons import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.diagnostics.Diagnostic -import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/pushDown/KotlinPushDownHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/pushDown/KotlinPushDownHandler.kt index f2d476846fa..7a4568a593b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/pushDown/KotlinPushDownHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/pushDown/KotlinPushDownHandler.kt @@ -25,6 +25,7 @@ import com.intellij.refactoring.HelpID import com.intellij.refactoring.RefactoringBundle import com.intellij.refactoring.util.CommonRefactoringUtil import com.intellij.refactoring.util.RefactoringUIUtil +import org.jetbrains.kotlin.idea.core.isInheritable import org.jetbrains.kotlin.idea.refactoring.AbstractPullPushMembersHandler import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfo import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfoStorage @@ -33,7 +34,6 @@ import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtParameter -import org.jetbrains.kotlin.psi.psiUtil.isInheritable val PUSH_MEMBERS_DOWN = "Push Members Down" diff --git a/idea/src/org/jetbrains/kotlin/idea/slicer/Slicer.kt b/idea/src/org/jetbrains/kotlin/idea/slicer/Slicer.kt index da52124b6d1..5f812717392 100644 --- a/idea/src/org/jetbrains/kotlin/idea/slicer/Slicer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/slicer/Slicer.kt @@ -42,6 +42,7 @@ import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor +import org.jetbrains.kotlin.idea.core.isOverridable import org.jetbrains.kotlin.idea.findUsages.KotlinFunctionFindUsagesOptions import org.jetbrains.kotlin.idea.findUsages.KotlinPropertyFindUsagesOptions import org.jetbrains.kotlin.idea.findUsages.processAllExactUsages diff --git a/idea/testData/inspections/allOpenSimple/inspectionData/expected.xml b/idea/testData/inspections/allOpenSimple/inspectionData/expected.xml index a43466e1377..ca2adc66781 100644 --- a/idea/testData/inspections/allOpenSimple/inspectionData/expected.xml +++ b/idea/testData/inspections/allOpenSimple/inspectionData/expected.xml @@ -1,4 +1,22 @@ + + test.kt + 8 + light_idea_test_case + + Redundant modality modifier + Redundant modality modifier + + + + test.kt + 9 + light_idea_test_case + + Redundant modality modifier + Redundant modality modifier + + test.kt 22 diff --git a/plugins/allopen/allopen-cli/src/AllOpenDeclarationAttributeAltererExtension.kt b/plugins/allopen/allopen-cli/src/AllOpenDeclarationAttributeAltererExtension.kt index 1d8efaabbf3..021a070a7f1 100644 --- a/plugins/allopen/allopen-cli/src/AllOpenDeclarationAttributeAltererExtension.kt +++ b/plugins/allopen/allopen-cli/src/AllOpenDeclarationAttributeAltererExtension.kt @@ -42,7 +42,8 @@ abstract class AbstractAllOpenDeclarationAttributeAltererExtension : Declaration declaration: DeclarationDescriptor?, containingDeclaration: DeclarationDescriptor?, currentModality: Modality, - bindingContext: BindingContext + bindingContext: BindingContext, + isImplicitModality: Boolean ): Modality? { if (currentModality != Modality.FINAL) { return null @@ -54,7 +55,7 @@ abstract class AbstractAllOpenDeclarationAttributeAltererExtension : Declaration val descriptor = declaration as? ClassDescriptor ?: containingDeclaration ?: return null if (descriptor.hasSpecialAnnotation(modifierListOwner)) { - return if (modifierListOwner.hasModifier(KtTokens.FINAL_KEYWORD)) + return if (!isImplicitModality && modifierListOwner.hasModifier(KtTokens.FINAL_KEYWORD)) Modality.FINAL // Explicit final else Modality.OPEN diff --git a/ultimate/src/org/jetbrains/kotlin/idea/spring/inspections/KotlinFinalClassOrFunSpringInspection.kt b/ultimate/src/org/jetbrains/kotlin/idea/spring/inspections/KotlinFinalClassOrFunSpringInspection.kt index c511d075759..b584ed6633d 100644 --- a/ultimate/src/org/jetbrains/kotlin/idea/spring/inspections/KotlinFinalClassOrFunSpringInspection.kt +++ b/ultimate/src/org/jetbrains/kotlin/idea/spring/inspections/KotlinFinalClassOrFunSpringInspection.kt @@ -33,13 +33,13 @@ import org.jetbrains.kotlin.asJava.toLightMethods import org.jetbrains.kotlin.descriptors.MemberDescriptor import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny +import org.jetbrains.kotlin.idea.core.isInheritable +import org.jetbrains.kotlin.idea.core.isOverridable import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection import org.jetbrains.kotlin.idea.spring.isAnnotatedWith import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject -import org.jetbrains.kotlin.psi.psiUtil.isInheritable -import org.jetbrains.kotlin.psi.psiUtil.isOverridable class KotlinFinalClassOrFunSpringInspection : AbstractKotlinInspection() { class QuickFix(private val element: T) : LocalQuickFix {