VarianceChecker refactoring: move checkClassOrObject to IDE

This commit is contained in:
Mikhail Glukhikh
2017-04-27 20:51:34 +03:00
parent b66401a41d
commit 19021ec1aa
2 changed files with 39 additions and 36 deletions
@@ -20,20 +20,46 @@ import com.intellij.codeInsight.FileModificationService
import com.intellij.codeInspection.*
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElementVisitor
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.MemberDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtTypeParameter
import org.jetbrains.kotlin.psi.KtVisitorVoid
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.addRemoveModifier.addModifier
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.ManualVariance
import org.jetbrains.kotlin.resolve.VarianceCheckerCore
import org.jetbrains.kotlin.types.Variance
class AddVarianceModifierInspection : AbstractKotlinInspection() {
private fun VarianceCheckerCore.checkClassOrObject(klass: KtClassOrObject): Boolean {
if (klass is KtClass) {
if (!checkClassHeader(klass)) return false
if (klass.getSuperTypeList()?.anyDescendantOfType<KtClassOrObject> { !checkClassOrObject(it) } == true) return false
}
for (member in klass.declarations + klass.primaryConstructorParameters) {
val descriptor = when (member) {
is KtParameter -> context.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, member)
is KtDeclaration -> context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, member)
else -> null
} as? MemberDescriptor ?: continue
when (member) {
is KtClassOrObject -> {
if (!checkClassOrObject(member)) return false
}
is KtCallableDeclaration -> {
if (descriptor is CallableMemberDescriptor && !checkMember(member, descriptor)) return false
if (member.anyDescendantOfType<KtClassOrObject> { !checkClassOrObject(it) }) return false
}
}
}
return true
}
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
return object : KtVisitorVoid() {