Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove deprecated calculateLineColByOffset methods from Ktlint #394

Merged
merged 4 commits into from
Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.cqfn.diktat.ruleset.rules

import com.pinterest.ktlint.core.KtLint.calculateLineColByOffset
import com.pinterest.ktlint.core.Rule
import com.pinterest.ktlint.core.ast.ElementType.BINARY_EXPRESSION
import com.pinterest.ktlint.core.ast.ElementType.BLOCK
Expand Down Expand Up @@ -40,6 +39,7 @@ import org.cqfn.diktat.common.config.rules.getRuleConfig
import org.cqfn.diktat.ruleset.constants.Warnings.LONG_LINE
import org.cqfn.diktat.ruleset.utils.KotlinParser
import org.cqfn.diktat.ruleset.utils.appendNewlineMergingWhiteSpace
import org.cqfn.diktat.ruleset.utils.calculateLineColByOffset
import org.cqfn.diktat.ruleset.utils.hasChildOfType
import org.jetbrains.kotlin.com.intellij.lang.ASTNode
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.CompositeElement
Expand Down Expand Up @@ -101,7 +101,7 @@ class LineLength(private val configRules: List<RulesConfig>) : Rule("line-length
val newNode = node.psi.findElementAt(offset + configuration.lineLength.toInt())!!.node
if ((newNode.elementType != KDOC_TEXT && newNode.elementType != KDOC_MARKDOWN_INLINE_LINK) ||
!isKDocValid(newNode)) {
positionByOffset = calculateLineColByOffset(node.treeParent.text)
positionByOffset = node.treeParent.calculateLineColByOffset()
val fixableType = isFixable(newNode, configuration)
LONG_LINE.warnAndFix(configRules, emitWarn, isFixMode,
"max line length ${configuration.lineLength}, but was ${it.length}",
Expand Down Expand Up @@ -394,12 +394,12 @@ class LineLength(private val configRules: List<RulesConfig>) : Rule("line-length
}

sealed class LongLineFixableCases {
object None: LongLineFixableCases()
class Comment(val node: ASTNode, val indexLastSpace: Int): LongLineFixableCases()
class Condition(val maximumLineLength: Long, val leftOffset: Int, val binList: MutableList<ASTNode>): LongLineFixableCases()
class Fun(val node: ASTNode): LongLineFixableCases()
class Property(val node: ASTNode, val indexLastSpace: Int, val text: String): LongLineFixableCases()
object None : LongLineFixableCases()
class Comment(val node: ASTNode, val indexLastSpace: Int) : LongLineFixableCases()
class Condition(val maximumLineLength: Long, val leftOffset: Int, val binList: MutableList<ASTNode>) : LongLineFixableCases()
class Fun(val node: ASTNode) : LongLineFixableCases()
class Property(val node: ASTNode, val indexLastSpace: Int, val text: String) : LongLineFixableCases()
class PropertyWithTemplateEntry(val node: ASTNode, val maximumLineLength: Long,
val leftOffset: Int, val binList: MutableList<ASTNode>): LongLineFixableCases()
val leftOffset: Int, val binList: MutableList<ASTNode>) : LongLineFixableCases()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package org.cqfn.diktat.ruleset.utils

import com.pinterest.ktlint.core.KtLint
import com.pinterest.ktlint.core.ast.ElementType
import com.pinterest.ktlint.core.ast.ElementType.ANNOTATION
import com.pinterest.ktlint.core.ast.ElementType.ANNOTATION_ENTRY
import com.pinterest.ktlint.core.ast.ElementType.CONST_KEYWORD
import com.pinterest.ktlint.core.ast.ElementType.FILE
Expand Down Expand Up @@ -515,6 +514,10 @@ fun ASTNode.firstLineOfText(suffix: String = "") = text.lines().run { singleOrNu

fun ASTNode.lastLineNumber(isFixMode: Boolean) = getLineNumber(isFixMode)?.plus(text.count { it == '\n' })

fun ASTNode.calculateLineColByOffset(): (offset: Int) -> Pair<Int, Int> {
return buildPositionInTextLocator(text)
}

fun ASTNode.getFileName(): String = getUserData(KtLint.FILE_PATH_USER_DATA_KEY).let {
require(it != null) { "File path is not present in user data" }
it
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package org.cqfn.diktat.ruleset.utils

//fixme this code is copy-pasted from ktlint. Change it
internal typealias LineAndColumn = Pair<Int, Int>

/**
* Calculate position in text - line and column based on offset from the text start.
*/
internal fun buildPositionInTextLocator(text: String): (offset: Int) -> LineAndColumn {
val textLength = text.length
val identifierArray = ArrayList<Int>()
var endOfLineIndex = -1

do {
identifierArray.add(endOfLineIndex + 1)
endOfLineIndex = text.indexOf('\n', endOfLineIndex + 1)
} while (endOfLineIndex != -1)

identifierArray.add(textLength + if (identifierArray.last() == textLength) 1 else 0)

val segmentTree = SegmentTree(identifierArray.toIntArray())

return { offset ->
val line = segmentTree.indexOf(offset)
if (line != -1) {
val column = offset - segmentTree.get(line).left
line + 1 to column + 1
} else {
1 to 1
}
}
}

private class SegmentTree(sortedArray: IntArray) {

init {
require(sortedArray.size > 1) { "At least two data points are required" }
sortedArray.reduce { current, next ->
require(current <= next) { "Data points are not sorted (ASC)" }
next
}
}

private val segments: List<Segment> = sortedArray
.dropLast(1)
.mapIndexed { index: Int, element: Int ->
Segment(element, sortedArray[index + 1] - 1)
}

fun get(index: Int): Segment = segments[index]

fun indexOf(index: Int): Int = binarySearch(index, 0, segments.size - 1)

private fun binarySearch(compareElement: Int, left: Int, right: Int): Int = when {
left > right -> -1
else -> {
val index = left + (right - left) / 2
val midElement = segments[index]
if (compareElement < midElement.left) {
binarySearch(compareElement, left, index - 1)
} else {
if (midElement.right < compareElement) binarySearch(compareElement, index + 1, right) else index
}
}
}
}

private data class Segment(
val left: Int,
val right: Int
)