Unused symbol: don't report for finalize() method #KT-13311 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
503f061c8c
commit
e903b2f92a
@@ -9,16 +9,16 @@ import com.intellij.codeInsight.FileModificationService
|
|||||||
import com.intellij.codeInspection.*
|
import com.intellij.codeInspection.*
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiElementVisitor
|
import com.intellij.psi.PsiElementVisitor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.core.implicitVisibility
|
import org.jetbrains.kotlin.idea.core.implicitVisibility
|
||||||
import org.jetbrains.kotlin.idea.core.isInheritable
|
import org.jetbrains.kotlin.idea.core.isInheritable
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
import org.jetbrains.kotlin.idea.intentions.isFinalizeMethod
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
|
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||||
import org.jetbrains.kotlin.psi.addRemoveModifier.addModifier
|
import org.jetbrains.kotlin.psi.addRemoveModifier.addModifier
|
||||||
|
import org.jetbrains.kotlin.psi.declarationVisitor
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier
|
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
|
||||||
|
|
||||||
class ProtectedInFinalInspection : AbstractKotlinInspection() {
|
class ProtectedInFinalInspection : AbstractKotlinInspection() {
|
||||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
|
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
|
||||||
@@ -43,13 +43,6 @@ class ProtectedInFinalInspection : AbstractKotlinInspection() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtDeclaration.isFinalizeMethod(): Boolean {
|
|
||||||
val function = this as? KtNamedFunction ?: return false
|
|
||||||
return function.name == "finalize"
|
|
||||||
&& function.valueParameters.isEmpty()
|
|
||||||
&& (function.descriptor as? FunctionDescriptor)?.returnType?.isUnit() == true
|
|
||||||
}
|
|
||||||
|
|
||||||
class MakePrivateFix : LocalQuickFix {
|
class MakePrivateFix : LocalQuickFix {
|
||||||
override fun getName(): String = "Make private"
|
override fun getName(): String = "Make private"
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.idea.core.toDescriptor
|
|||||||
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory
|
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory
|
||||||
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindClassUsagesHandler
|
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindClassUsagesHandler
|
||||||
import org.jetbrains.kotlin.idea.imports.importableFqName
|
import org.jetbrains.kotlin.idea.imports.importableFqName
|
||||||
|
import org.jetbrains.kotlin.idea.intentions.isFinalizeMethod
|
||||||
import org.jetbrains.kotlin.idea.isMainFunction
|
import org.jetbrains.kotlin.idea.isMainFunction
|
||||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.idea.quickfix.RemoveUnusedFunctionParameterFix
|
import org.jetbrains.kotlin.idea.quickfix.RemoveUnusedFunctionParameterFix
|
||||||
@@ -168,6 +169,7 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
|
|||||||
val descriptor = declaration.resolveToDescriptorIfAny() ?: return
|
val descriptor = declaration.resolveToDescriptorIfAny() ?: return
|
||||||
if (descriptor is FunctionDescriptor && descriptor.isOperator) return
|
if (descriptor is FunctionDescriptor && descriptor.isOperator) return
|
||||||
if (isEntryPoint(declaration)) return
|
if (isEntryPoint(declaration)) return
|
||||||
|
if (declaration.isFinalizeMethod(descriptor)) return
|
||||||
if (declaration is KtProperty && declaration.isSerializationImplicitlyUsedField()) return
|
if (declaration is KtProperty && declaration.isSerializationImplicitlyUsedField()) return
|
||||||
if (declaration is KtNamedFunction && declaration.isSerializationImplicitlyUsedMethod()) return
|
if (declaration is KtNamedFunction && declaration.isSerializationImplicitlyUsedMethod()) return
|
||||||
// properties can be referred by component1/component2, which is too expensive to search, don't mark them as unused
|
// properties can be referred by component1/component2, which is too expensive to search, don't mark them as unused
|
||||||
@@ -283,7 +285,7 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
|
|||||||
if (import.importedFqName != declaration.fqName) {
|
if (import.importedFqName != declaration.fqName) {
|
||||||
val importedDeclaration =
|
val importedDeclaration =
|
||||||
import.importedReference?.getQualifiedElementSelector()?.mainReference?.resolve() as? KtNamedDeclaration
|
import.importedReference?.getQualifiedElementSelector()?.mainReference?.resolve() as? KtNamedDeclaration
|
||||||
?: return true
|
?: return true
|
||||||
if (declaration is KtObjectDeclaration ||
|
if (declaration is KtObjectDeclaration ||
|
||||||
(declaration is KtClass && declaration.isEnum()) ||
|
(declaration is KtClass && declaration.isEnum()) ||
|
||||||
importedDeclaration.containingClassOrObject is KtObjectDeclaration
|
importedDeclaration.containingClassOrObject is KtObjectDeclaration
|
||||||
|
|||||||
@@ -19,17 +19,17 @@ package org.jetbrains.kotlin.idea.intentions
|
|||||||
import com.intellij.psi.tree.IElementType
|
import com.intellij.psi.tree.IElementType
|
||||||
import org.jetbrains.kotlin.KtNodeTypes
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
||||||
import org.jetbrains.kotlin.idea.core.replaced
|
import org.jetbrains.kotlin.idea.core.replaced
|
||||||
import org.jetbrains.kotlin.idea.core.setType
|
import org.jetbrains.kotlin.idea.core.setType
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
|
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression
|
import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
|||||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.isFlexible
|
import org.jetbrains.kotlin.types.isFlexible
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||||
import java.lang.IllegalArgumentException
|
import java.lang.IllegalArgumentException
|
||||||
|
|
||||||
fun KtContainerNode.description(): String? {
|
fun KtContainerNode.description(): String? {
|
||||||
@@ -311,4 +312,12 @@ fun KtBlockExpression.getParentLambdaLabelName(): String? {
|
|||||||
return lambdaLabelName ?: callExpression.getCallNameExpression()?.text
|
return lambdaLabelName ?: callExpression.getCallNameExpression()?.text
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun KtExpression.getCallableDescriptor() = resolveToCall()?.resultingDescriptor
|
internal fun KtExpression.getCallableDescriptor() = resolveToCall()?.resultingDescriptor
|
||||||
|
|
||||||
|
fun KtDeclaration.isFinalizeMethod(descriptor: DeclarationDescriptor? = null): Boolean {
|
||||||
|
if (containingClass() == null) return false
|
||||||
|
val function = this as? KtNamedFunction ?: return false
|
||||||
|
return function.name == "finalize"
|
||||||
|
&& function.valueParameters.isEmpty()
|
||||||
|
&& ((descriptor ?: function.descriptor) as? FunctionDescriptor)?.returnType?.isUnit() == true
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
class C {
|
||||||
|
protected fun finalize() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -87,4 +87,13 @@
|
|||||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused symbol</problem_class>
|
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused symbol</problem_class>
|
||||||
<description>Function "foo" is never used</description>
|
<description>Function "foo" is never used</description>
|
||||||
</problem>
|
</problem>
|
||||||
|
|
||||||
|
<problem>
|
||||||
|
<file>finalize.kt</file>
|
||||||
|
<line>1</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="temp:///src/finalize.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused symbol</problem_class>
|
||||||
|
<description>Class "C" is never used</description>
|
||||||
|
</problem>
|
||||||
</problems>
|
</problems>
|
||||||
|
|||||||
Reference in New Issue
Block a user