[CMI] Fix CodeMetaInfoParser to properly handle nested meta infos

There was a problem with cases like that:
<!FOO!><!BAR!>some text<!><!>
                        ^  ^
                        1  2
(1) is a closing tag for <!FOO!> and (2) is for <!BAR!>, but before the
  fix they were matched contrariwise
This commit is contained in:
Dmitriy Novozhilov
2020-12-02 16:13:48 +03:00
parent c558df5b4a
commit 7960182674
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.codeMetaInfo
import org.jetbrains.kotlin.codeMetaInfo.model.ParsedCodeMetaInfo import org.jetbrains.kotlin.codeMetaInfo.model.ParsedCodeMetaInfo
object CodeMetaInfoParser { object CodeMetaInfoParser {
private val openingRegex = """(<!(.+?)!>)""".toRegex() private val openingRegex = """(<!([^"]*?(".*?")?[^"]*?)!>)""".toRegex()
private val closingRegex = """(<!>)""".toRegex() private val closingRegex = """(<!>)""".toRegex()
/* /*
@@ -22,7 +22,8 @@ object CodeMetaInfoParser {
fun getCodeMetaInfoFromText(renderedText: String): List<ParsedCodeMetaInfo> { fun getCodeMetaInfoFromText(renderedText: String): List<ParsedCodeMetaInfo> {
var text = renderedText var text = renderedText
val openingMatchResults = ArrayDeque<MatchResult>() val openingMatchResults = ArrayDeque<MatchResult>()
val closingMatchResults = ArrayDeque<MatchResult>() val stackOfOpeningMatchResults = ArrayDeque<MatchResult>()
val closingMatchResults = mutableMapOf<MatchResult, MatchResult>()
val result = mutableListOf<ParsedCodeMetaInfo>() val result = mutableListOf<ParsedCodeMetaInfo>()
while (true) { while (true) {
@@ -40,10 +41,11 @@ object CodeMetaInfoParser {
text = if (openingStartOffset < closingStartOffset) { text = if (openingStartOffset < closingStartOffset) {
requireNotNull(opening) requireNotNull(opening)
openingMatchResults.addLast(opening) openingMatchResults.addLast(opening)
stackOfOpeningMatchResults.addLast(opening)
text.removeRange(openingStartOffset, opening.range.last + 1) text.removeRange(openingStartOffset, opening.range.last + 1)
} else { } else {
requireNotNull(closing) requireNotNull(closing)
closingMatchResults.addLast(closing) closingMatchResults[stackOfOpeningMatchResults.removeLast()] = closing
text.removeRange(closingStartOffset, closing.range.last + 1) text.removeRange(closingStartOffset, closing.range.last + 1)
} }
} }
@@ -52,7 +54,7 @@ object CodeMetaInfoParser {
} }
while (!openingMatchResults.isEmpty()) { while (!openingMatchResults.isEmpty()) {
val openingMatchResult = openingMatchResults.removeLast() val openingMatchResult = openingMatchResults.removeLast()
val closingMatchResult = closingMatchResults.removeLast() val closingMatchResult = closingMatchResults.getValue(openingMatchResult)
val allMetaInfos = openingMatchResult.groups[2]!!.value val allMetaInfos = openingMatchResult.groups[2]!!.value
tagRegex.findAll(allMetaInfos).map { it.groups }.forEach { tagRegex.findAll(allMetaInfos).map { it.groups }.forEach {
val tag = it[1]!!.value val tag = it[1]!!.value