[FIR] Add REDUNDANT_NULLABLE diagnostics

This commit is contained in:
Ivan Kochurkin
2021-11-19 16:21:51 +03:00
committed by TeamCityServer
parent 4caf3c5e83
commit 51b73bb6ae
37 changed files with 233 additions and 87 deletions
@@ -14,7 +14,6 @@ import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.KtNodeType
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.diagnostics.PositioningStrategies
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.lexer.KtTokens.MODALITY_MODIFIERS
import org.jetbrains.kotlin.lexer.KtTokens.VISIBILITY_MODIFIERS
@@ -827,6 +826,40 @@ object LightTreePositioningStrategies {
}
}
val REDUNDANT_NULLABLE: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(
node: LighterASTNode,
startOffset: Int,
endOffset: Int,
tree: FlyweightCapableTreeStructure<LighterASTNode>
): List<TextRange> {
val ref = Ref<Array<LighterASTNode?>>()
var child: LighterASTNode? = node
var lastQuest: LighterASTNode? = null
var prevQuest: LighterASTNode? = null
var quest: LighterASTNode? = null
while (child != null) {
child = getNullableChild(tree, child, ref)
prevQuest = quest
quest = ref.get().elementAtOrNull(1)
if (lastQuest == null) {
lastQuest = quest
}
}
return markRange(prevQuest ?: lastQuest ?: node, lastQuest ?: node, startOffset, endOffset, tree, node)
}
private fun getNullableChild(
tree: FlyweightCapableTreeStructure<LighterASTNode>,
node: LighterASTNode,
ref: Ref<Array<LighterASTNode?>>
): LighterASTNode? {
tree.getChildren(node, ref)
val firstChild = ref.get().firstOrNull() ?: return null
return if (firstChild.tokenType != KtNodeTypes.NULLABLE_TYPE) null else firstChild
}
}
val QUESTION_MARK_BY_TYPE: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(
node: LighterASTNode,
@@ -1154,6 +1187,7 @@ private fun FlyweightCapableTreeStructure<LighterASTNode>.referenceExpression(
}
return result
}
fun FlyweightCapableTreeStructure<LighterASTNode>.unwrapParenthesesLabelsAndAnnotations(node: LighterASTNode): LighterASTNode {
var unwrapped = node
while (true) {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.diagnostics
import com.intellij.lang.ASTNode
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.tree.TokenSet
@@ -549,6 +550,30 @@ object PositioningStrategies {
}
}
@JvmField
val REDUNDANT_NULLABLE: PositioningStrategy<KtTypeReference> = object : PositioningStrategy<KtTypeReference>() {
override fun mark(element: KtTypeReference): List<TextRange> {
var typeElement = element.typeElement
var question: ASTNode? = null
var prevQuestion: ASTNode? = null
var lastQuestion: ASTNode? = null
while (typeElement is KtNullableType) {
prevQuestion = question
question = typeElement.questionMarkNode
if (lastQuestion == null) {
lastQuestion = question
}
typeElement = typeElement.innerType
}
if (lastQuestion != null) {
return markRange((prevQuestion ?: lastQuestion).psi, lastQuestion.psi)
}
return super.mark(element)
}
}
@JvmField
val NULLABLE_TYPE: PositioningStrategy<KtNullableType> = object : PositioningStrategy<KtNullableType>() {
override fun mark(element: KtNullableType): List<TextRange> {
@@ -248,6 +248,11 @@ object SourceElementPositioningStrategies {
PositioningStrategies.NAME_IDENTIFIER
)
val REDUNDANT_NULLABLE = SourceElementPositioningStrategy(
LightTreePositioningStrategies.REDUNDANT_NULLABLE,
PositioningStrategies.REDUNDANT_NULLABLE
)
val QUESTION_MARK_BY_TYPE = SourceElementPositioningStrategy(
LightTreePositioningStrategies.QUESTION_MARK_BY_TYPE,
PositioningStrategies.QUESTION_MARK_BY_TYPE