org.jetbrains.kotlin.diagnostics.UnreachableCodeLightTreeHelper.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-compiler-embeddable Show documentation
Show all versions of kotlin-compiler-embeddable Show documentation
the Kotlin compiler embeddable
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.diagnostics
import com.intellij.lang.LighterASTNode
import com.intellij.openapi.util.TextRange
import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.util.getChildren
typealias Node = LighterASTNode
class UnreachableCodeLightTreeHelper(val tree: FlyweightCapableTreeStructure) {
fun Node.hasChildrenInSet(set: Set): Boolean {
var result = false
tree.traverseDescendants(this) {
if (!result && it != this && it in set) {
result = true
}
!result
}
return result
}
fun Node.getLeavesOrReachableChildren(reachable: Set, unreachable: Set): List {
val result = mutableListOf()
tree.traverseDescendants(this) { element ->
val isReachable = element in reachable && !element.hasChildrenInSet(unreachable)
if (isReachable || element.getChildren(tree).isEmpty()) {
result.add(element)
false
} else {
true
}
}
return result
}
fun List.removeReachableElementsWithMeaninglessSiblings(reachableElements: Set): List {
val childrenToRemove = mutableSetOf()
fun collectSiblingsIfMeaningless(elementIndex: Int, direction: Int) {
val index = elementIndex + direction
if (index !in 0 until size) return
val element = this[index]
if (element.isFiller() || element.tokenType == KtTokens.COMMA) {
childrenToRemove.add(element)
collectSiblingsIfMeaningless(index, direction)
}
}
for ((index, element) in this.withIndex()) {
if (reachableElements.contains(element)) {
childrenToRemove.add(element)
collectSiblingsIfMeaningless(index, -1)
collectSiblingsIfMeaningless(index, 1)
}
}
return filter { it !in childrenToRemove }
}
fun List.mergeAdjacentTextRanges(): List {
val result = ArrayList()
val lastRange = fold(null as TextRange?) { currentTextRange, elementRange ->
when {
currentTextRange == null -> {
elementRange
}
currentTextRange.endOffset == elementRange.startOffset -> {
currentTextRange.union(elementRange)
}
else -> {
result.add(currentTextRange)
elementRange
}
}
}
if (lastRange != null) {
result.add(lastRange)
}
return result
}
}