[textmate] hide byte array behind TextMateString interface

GitOrigin-RevId: b27b724a9f9eef4d120824ccfe7ac50d7fa6da46
This commit is contained in:
Alexander Zolotov
2025-07-28 12:14:17 +00:00
committed by intellij-monorepo-bot
parent 4587f7fafc
commit ce74e7b46d
4 changed files with 17 additions and 10 deletions
@@ -44,8 +44,7 @@ internal object SyntaxMatchUtils {
digitIndex++
}
if (hasGroupIndex && matchData.count() > groupIndex) {
val range = matchData.byteRange(groupIndex)
val replacement = matchingString.bytes.decodeToString(range.start.offset, range.end.offset)
val replacement = matchingString.subSequenceByByteRange(matchData.byteRange(groupIndex))
append(BACK_REFERENCE_REPLACEMENT_REGEX.replace(replacement, "\\\\$0"))
charIndex = digitIndex
continue
@@ -88,8 +87,7 @@ internal object SyntaxMatchUtils {
val groupIndex = (matcher.groups[1] ?: matcher.groups[2])?.value?.toIntOrNull() ?: -1
if (groupIndex >= 0 && matchData.count() > groupIndex) {
append(string, lastPosition, matcher.range.first)
val range = matchData.byteRange(groupIndex)
val capturedText = matchingString.bytes.decodeToString(range.start.offset, range.end.offset)
val capturedText = matchingString.subSequenceByByteRange(matchData.byteRange(groupIndex)).toString()
val replacement = capturedText.trimStart('.')
val command = matcher.groups[3]?.value
when (command) {
@@ -27,7 +27,7 @@ class TextMateLexerState(
result
}
val matchedEOL: Boolean = matchData.matched && line != null && matchData.byteRange().end.offset == line.bytes.size
val matchedEOL: Boolean = matchData.matched && line != null && matchData.byteRange().end.offset == line.bytesLength
val string: TextMateString? = if (matchData.matched) line else null
@@ -3,13 +3,15 @@ package org.jetbrains.plugins.textmate.regex
interface TextMateString: AutoCloseable {
val id: Any
val bytes: ByteArray
val bytesLength: Int
fun subSequenceByByteRange(byteRange: TextMateByteRange): CharSequence
fun charRangeByByteRange(byteRange: TextMateByteRange): TextMateCharRange
fun charOffsetByByteOffset(startByteOffset: TextMateByteOffset, targetByteOffset: TextMateByteOffset): TextMateCharOffset
}
class TextMateStringImpl private constructor(override val bytes: ByteArray): TextMateString {
class TextMateStringImpl private constructor(val bytes: ByteArray): TextMateString {
override val id: Any = Any()
override val bytesLength: Int
get() = bytes.size
companion object {
fun fromString(string: String): TextMateString {
@@ -17,13 +19,17 @@ class TextMateStringImpl private constructor(override val bytes: ByteArray): Tex
}
}
override fun subSequenceByByteRange(byteRange: TextMateByteRange): CharSequence {
return bytes.decodeToString(byteRange.start.offset, byteRange.end.offset)
}
override fun charRangeByByteRange(byteRange: TextMateByteRange): TextMateCharRange {
val startOffset = charOffsetByByteOffset(0.byteOffset(), byteRange.start)
val endOffset = startOffset + charOffsetByByteOffset(byteRange.start, byteRange.end)
return TextMateCharRange(startOffset, endOffset)
}
override fun charOffsetByByteOffset(startByteOffset: TextMateByteOffset, targetByteOffset: TextMateByteOffset): TextMateCharOffset {
private fun charOffsetByByteOffset(startByteOffset: TextMateByteOffset, targetByteOffset: TextMateByteOffset): TextMateCharOffset {
return if (targetByteOffset.offset <= 0) {
0.charOffset()
}
@@ -5,6 +5,7 @@ import org.jetbrains.plugins.textmate.regex.MatchData.Companion.NOT_MATCHED
import org.jetbrains.plugins.textmate.regex.RegexFacade
import org.jetbrains.plugins.textmate.regex.TextMateByteOffset
import org.jetbrains.plugins.textmate.regex.TextMateString
import org.jetbrains.plugins.textmate.regex.TextMateStringImpl
import org.joni.Option
import org.joni.Regex
import org.joni.Region
@@ -29,6 +30,8 @@ internal class JoniRegexFacade(private val myRegex: Regex) : RegexFacade {
matchBeginString: Boolean,
checkCancelledCallback: Runnable?
): MatchData {
require(string is TextMateStringImpl)
val gosOffset = if (matchBeginPosition) byteOffset.offset else Int.MAX_VALUE
val options = if (matchBeginString) Option.NONE else Option.NOTBOS
@@ -70,7 +73,7 @@ internal class JoniRegexFacade(private val myRegex: Regex) : RegexFacade {
private val MATCHING_TIMEOUT = 300.milliseconds.inWholeNanoseconds
private val LOGGER: Logger = LoggerFactory.getLogger(JoniRegexFacade::class.java)
private fun checkMatched(match: MatchData, string: TextMateString) {
private fun checkMatched(match: MatchData, string: TextMateStringImpl) {
check(!(match.matched && match.byteRange().end.offset > string.bytes.size)) {
"Match data out of bounds: " + match.byteRange().start + " > " + string.bytes.size + "\n" + String(string.bytes, Charsets.UTF_8)
}