Unused Symbol: Check descriptor before creating light class to prevent InvalidMirrorException on red code
This commit is contained in:
@@ -29,7 +29,10 @@ import org.jetbrains.kotlin.psi.JetDeclaration
|
|||||||
import org.jetbrains.kotlin.psi.JetElement
|
import org.jetbrains.kotlin.psi.JetElement
|
||||||
import org.jetbrains.kotlin.psi.JetFile
|
import org.jetbrains.kotlin.psi.JetFile
|
||||||
import org.jetbrains.kotlin.psi.JetPsiFactory
|
import org.jetbrains.kotlin.psi.JetPsiFactory
|
||||||
import org.jetbrains.kotlin.resolve.*
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingTraceContext
|
||||||
|
import org.jetbrains.kotlin.resolve.ImportPath
|
||||||
|
import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.resolve.lazy.FileScopeProvider
|
import org.jetbrains.kotlin.resolve.lazy.FileScopeProvider
|
||||||
import org.jetbrains.kotlin.resolve.lazy.LazyFileScope
|
import org.jetbrains.kotlin.resolve.lazy.LazyFileScope
|
||||||
@@ -42,6 +45,10 @@ public fun JetDeclaration.resolveToDescriptor(): DeclarationDescriptor {
|
|||||||
return getResolutionFacade().resolveToDescriptor(this)
|
return getResolutionFacade().resolveToDescriptor(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun JetDeclaration.resolveToDescriptorIfAny(): DeclarationDescriptor? {
|
||||||
|
return analyze(BodyResolveMode.PARTIAL).get(BindingContext.DECLARATION_TO_DESCRIPTOR, this)
|
||||||
|
}
|
||||||
|
|
||||||
public fun JetFile.resolveImportReference(fqName: FqName): Collection<DeclarationDescriptor> {
|
public fun JetFile.resolveImportReference(fqName: FqName): Collection<DeclarationDescriptor> {
|
||||||
val facade = getResolutionFacade()
|
val facade = getResolutionFacade()
|
||||||
return facade.resolveImportReference(facade.moduleDescriptor, fqName)
|
return facade.resolveImportReference(facade.moduleDescriptor, fqName)
|
||||||
|
|||||||
+2
-5
@@ -26,13 +26,11 @@ import com.intellij.psi.PsiElement
|
|||||||
import org.jetbrains.kotlin.asJava.KotlinLightClass
|
import org.jetbrains.kotlin.asJava.KotlinLightClass
|
||||||
import org.jetbrains.kotlin.asJava.toLightClass
|
import org.jetbrains.kotlin.asJava.toLightClass
|
||||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
import org.jetbrains.kotlin.psi.JetClassOrObject
|
import org.jetbrains.kotlin.psi.JetClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.JetNamedDeclaration
|
import org.jetbrains.kotlin.psi.JetNamedDeclaration
|
||||||
import org.jetbrains.kotlin.psi.JetNamedFunction
|
import org.jetbrains.kotlin.psi.JetNamedFunction
|
||||||
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.lazy.BodyResolveMode
|
|
||||||
import javax.swing.Icon
|
import javax.swing.Icon
|
||||||
|
|
||||||
class KotlinTestRunLineMarkerContributor : RunLineMarkerContributor() {
|
class KotlinTestRunLineMarkerContributor : RunLineMarkerContributor() {
|
||||||
@@ -47,8 +45,7 @@ class KotlinTestRunLineMarkerContributor : RunLineMarkerContributor() {
|
|||||||
if (declaration.nameIdentifier != element) return null
|
if (declaration.nameIdentifier != element) return null
|
||||||
|
|
||||||
// To prevent IDEA failing on red code
|
// To prevent IDEA failing on red code
|
||||||
if (declaration.analyze(BodyResolveMode.PARTIAL)
|
if (declaration.resolveToDescriptorIfAny() == null) return null
|
||||||
.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration) == null) return null
|
|
||||||
|
|
||||||
val project = element.project
|
val project = element.project
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.idea.JetBundle
|
import org.jetbrains.kotlin.idea.JetBundle
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.JetFunctionPsiElementCellRenderer
|
import org.jetbrains.kotlin.idea.codeInsight.JetFunctionPsiElementCellRenderer
|
||||||
import org.jetbrains.kotlin.psi.JetDeclaration
|
import org.jetbrains.kotlin.psi.JetDeclaration
|
||||||
@@ -112,8 +113,7 @@ public data class ResolveWithParentsResult(
|
|||||||
val overriddenDescriptors: Collection<CallableMemberDescriptor>)
|
val overriddenDescriptors: Collection<CallableMemberDescriptor>)
|
||||||
|
|
||||||
public fun resolveDeclarationWithParents(element: JetDeclaration): ResolveWithParentsResult {
|
public fun resolveDeclarationWithParents(element: JetDeclaration): ResolveWithParentsResult {
|
||||||
val bindingContext = element.analyze()
|
val descriptor = element.resolveToDescriptorIfAny()
|
||||||
val descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element)
|
|
||||||
|
|
||||||
if (descriptor !is CallableMemberDescriptor) return ResolveWithParentsResult(null, listOf())
|
if (descriptor !is CallableMemberDescriptor) return ResolveWithParentsResult(null, listOf())
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ import org.jetbrains.kotlin.asJava.LightClassUtil
|
|||||||
import org.jetbrains.kotlin.asJava.toLightClass
|
import org.jetbrains.kotlin.asJava.toLightClass
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||||
import org.jetbrains.kotlin.idea.JetBundle
|
import org.jetbrains.kotlin.idea.JetBundle
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
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.search.usagesSearch.*
|
import org.jetbrains.kotlin.idea.search.usagesSearch.*
|
||||||
@@ -52,7 +54,9 @@ import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
import org.jetbrains.kotlin.utils.singletonOrEmptyList
|
import org.jetbrains.kotlin.utils.singletonOrEmptyList
|
||||||
import java.awt.GridBagConstraints
|
import java.awt.GridBagConstraints
|
||||||
@@ -159,6 +163,7 @@ public class UnusedSymbolInspection : AbstractKotlinInspection() {
|
|||||||
if (declaration is JetNamedFunction && isConventionalName(declaration)) return
|
if (declaration is JetNamedFunction && isConventionalName(declaration)) return
|
||||||
|
|
||||||
// More expensive, resolve-based checks
|
// More expensive, resolve-based checks
|
||||||
|
if (declaration.resolveToDescriptorIfAny() == null) return
|
||||||
if (isEntryPoint(declaration)) return
|
if (isEntryPoint(declaration)) return
|
||||||
if (declaration is JetProperty && declaration.isSerializationImplicitlyUsedField()) return
|
if (declaration is JetProperty && declaration.isSerializationImplicitlyUsedField()) return
|
||||||
if (isCompanionObject && (declaration as JetObjectDeclaration).hasSerializationImplicitlyUsedField()) return
|
if (isCompanionObject && (declaration as JetObjectDeclaration).hasSerializationImplicitlyUsedField()) return
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// Closing brace is intentionally missed
|
||||||
|
val id = array("kotlin.FlexibleType"
|
||||||
|
|
||||||
|
private class Some() {
|
||||||
|
override fun foo() = 1
|
||||||
|
}
|
||||||
@@ -47,4 +47,12 @@
|
|||||||
<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>Class 'B' is never used</description>
|
<description>Class 'B' is never used</description>
|
||||||
</problem>
|
</problem>
|
||||||
|
<problem>
|
||||||
|
<file>BadCodeNoExceptions.kt</file>
|
||||||
|
<line>2</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="temp:///src/badCodeNoExceptions.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused Symbol</problem_class>
|
||||||
|
<description>Property 'id' is never used</description>
|
||||||
|
</problem>
|
||||||
</problems>
|
</problems>
|
||||||
|
|||||||
Reference in New Issue
Block a user