All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.diagnostics.UnreachableCodeLightTreeHelper.kt Maven / Gradle / Ivy

There is a newer version: 2.1.0-RC
Show newest version
/*
 * 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
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy