regex: Clean TODOs
This commit is contained in:
@@ -47,7 +47,6 @@ internal abstract class AbstractLineTerminator {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Replace with property or another Kotlin-way singleton.
|
||||
fun getInstance(flag: Int): AbstractLineTerminator {
|
||||
if (flag and Pattern.UNIX_LINES != 0) {
|
||||
return unixLT
|
||||
|
||||
@@ -55,7 +55,6 @@ internal abstract class SpecialToken {
|
||||
*/
|
||||
abstract val type: Type
|
||||
|
||||
// TODO: Replace with an enum?
|
||||
enum class Type {
|
||||
CHARCLASS,
|
||||
QUANTIFIER
|
||||
@@ -87,8 +86,6 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
/** When in [Mode.ESCAPE] mode, this field will save the previous one */
|
||||
private var savedMode = Mode.PATTERN
|
||||
|
||||
// TODO: Remove it.
|
||||
// TODO: Harmony doesn't allow us to set the ESCAPE mode from outside of the lexer. DO we need this limitation?
|
||||
fun setModeWithReread(value: Mode) {
|
||||
if(value == Mode.PATTERN || value == Mode.RANGE) {
|
||||
mode = value
|
||||
@@ -99,7 +96,6 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
}
|
||||
|
||||
// Tokens ==========================================================================================================
|
||||
// TODO: May be add getters.
|
||||
internal var lookBack: Int = 0 // Previous char read.
|
||||
private set
|
||||
internal var currentChar: Int = 0 // Current character read. Returns 0 if there is no more characters.
|
||||
@@ -107,7 +103,6 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
internal var lookAhead: Int = 0 // Next character.
|
||||
private set
|
||||
|
||||
// TODO: Investigate if we can make it not nullable or not
|
||||
internal var curSpecialToken: SpecialToken? = null // Current special token (e.g. quantifier)
|
||||
private set
|
||||
internal var lookAheadSpecialToken: SpecialToken? = null // Next special token
|
||||
@@ -116,7 +111,7 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
// Indices in the pattern.
|
||||
private var index = 0 // Current char being processed index.
|
||||
private var prevNonWhitespaceIndex = 0 // Previous non-whitespace character index.
|
||||
private var curTokenIndex = 0 // Current token start index. TODO: == index?
|
||||
private var curTokenIndex = 0 // Current token start index.
|
||||
private var lookAheadTokenIndex = 0 // Next token index.
|
||||
|
||||
init {
|
||||
@@ -124,7 +119,7 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
if (flags and Pattern.LITERAL > 0) {
|
||||
processedPattern = Pattern.quote(patternString)
|
||||
} else if (flags and Pattern.CANON_EQ > 0) {
|
||||
processedPattern = Lexer.normalize(patternString) // TODO: rewrite normalization
|
||||
processedPattern = Lexer.normalize(patternString)
|
||||
}
|
||||
|
||||
this.pattern = processedPattern.toCharArray().copyOf(processedPattern.length + 2)
|
||||
@@ -142,7 +137,6 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
val isQuantifier: Boolean get() = isSpecial && curSpecialToken!!.type == SpecialToken.Type.QUANTIFIER
|
||||
val isNextSpecial: Boolean get() = lookAheadSpecialToken != null
|
||||
|
||||
// TODO: May be replace with some already existing.
|
||||
private fun Int.isSurrogatePair() : Boolean {
|
||||
val high = (this ushr 16).toChar()
|
||||
val low = this.toChar()
|
||||
@@ -152,7 +146,6 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
private fun Char.isLineSeparator(): Boolean =
|
||||
this == '\n' || this == '\r' || this == '\u0085' || this.toInt() or 1 == '\u2029'.toInt()
|
||||
|
||||
// TODO: Replace with properties
|
||||
/** Checks if there are any characters in the pattern. */
|
||||
fun isEmpty(): Boolean =
|
||||
currentChar == 0 && lookAhead == 0 && index >= pattern.size && !isSpecial
|
||||
@@ -170,7 +163,6 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
* Restores flags for Lexer
|
||||
* @param flags
|
||||
*/
|
||||
// TODO: Refactor.
|
||||
fun restoreFlags(flags: Int) {
|
||||
this.flags = flags
|
||||
lookAhead = currentChar
|
||||
@@ -221,7 +213,7 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
*/
|
||||
private fun nextIndex(): Int {
|
||||
prevNonWhitespaceIndex = index
|
||||
if (flags and Pattern.COMMENTS != 0) { // TODO: Refactor flags.
|
||||
if (flags and Pattern.COMMENTS != 0) {
|
||||
skipComments()
|
||||
} else {
|
||||
index++
|
||||
@@ -310,7 +302,6 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
if (lookAheadChar == 'E') {
|
||||
// If \E found - change the mode to the previous one and shift to the next char.
|
||||
mode = savedMode
|
||||
// TODO: + we create an array with 2 additional characters but check the index here. May be there is not need to check it?
|
||||
lookAhead = if (index <= pattern.size - 2) nextCodePoint() else 0
|
||||
} else {
|
||||
// If \ have no E - make a step back and return.
|
||||
@@ -332,8 +323,9 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
return processEscapedChar()
|
||||
}
|
||||
|
||||
// TODO: Look like we can create a quantifier here.
|
||||
when (lookAheadChar) {
|
||||
// Quantifier (*, +, ?). TODO: May be create a quantifier here.
|
||||
// Quantifier (*, +, ?).
|
||||
'+', '*', '?' -> {
|
||||
val mode = if (index < pattern.size) pattern[index] else '*'
|
||||
// look at the next character to determine if the mode is greedy, reluctant or possessive.
|
||||
@@ -407,14 +399,6 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
|
||||
')' -> lookAhead = CHAR_RIGHT_PARENTHESIS
|
||||
'[' -> { lookAhead = CHAR_LEFT_SQUARE_BRACKET; mode = Mode.RANGE }
|
||||
// TODO: No need in this case.
|
||||
/*']' -> {
|
||||
assert(mode == Mode.PATTERN)
|
||||
/* // TODO: Think we cannot meet it here. because we already checked the mode and it is PATTERN, not RANGE. Check it.
|
||||
if (mode == Lexer.MODE_RANGE) {
|
||||
lookAhead = CHAR_RIGHT_SQUARE_BRACKET
|
||||
}*/
|
||||
}*/
|
||||
'^' -> lookAhead = CHAR_CARET
|
||||
'|' -> lookAhead = CHAR_VERTICAL_BAR
|
||||
'.' -> lookAhead = CHAR_DOT
|
||||
@@ -457,15 +441,12 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
val cs = parseCharClassName()
|
||||
val negative = lookAheadChar == 'P'
|
||||
|
||||
// TODO: Harmony processes errors thrown from the getPredefinedClass
|
||||
lookAheadSpecialToken = AbstractCharClass.getPredefinedClass(cs, negative)
|
||||
lookAhead = 0
|
||||
}
|
||||
|
||||
// Word/whitespace/digit.
|
||||
'w', 's', 'd', 'W', 'S', 'D' -> {
|
||||
// TODO: Strange string creation. Can we do easily
|
||||
// TODO: may be use parseCharClassName here?
|
||||
lookAheadSpecialToken = AbstractCharClass.getPredefinedClass(
|
||||
fromCharArray(pattern, prevNonWhitespaceIndex, 1),
|
||||
false
|
||||
@@ -496,7 +477,6 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
}
|
||||
|
||||
// A literal: octal, hex, or hex unicode.
|
||||
// TODO: May be use standard Kotlin methods here.
|
||||
'0' -> lookAhead = readOctals()
|
||||
'x' -> lookAhead = readHex(2)
|
||||
'u' -> lookAhead = readHex(4)
|
||||
@@ -520,7 +500,6 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: May be throw an exception in any not supported case?
|
||||
'C', 'E', 'F', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'R', 'T', 'U', 'V', 'X', 'Y', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'o', 'q', 'y' -> throw PatternSyntaxException()
|
||||
}
|
||||
return false
|
||||
@@ -570,8 +549,7 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Double check this contition.
|
||||
if (min < 0 || max >=0 && max - min < 0) {
|
||||
if (min < 0 || max >=0 && max < min) {
|
||||
throw PatternSyntaxException()
|
||||
}
|
||||
|
||||
@@ -581,7 +559,7 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
'?' -> { lookAhead = Lexer.QUANT_COMP_R; nextIndex() }
|
||||
else -> lookAhead = Lexer.QUANT_COMP
|
||||
}
|
||||
return Quantifier(min, max) // TODO: Save mode (P, R, G) in the Quantifier
|
||||
return Quantifier(min, max)
|
||||
}
|
||||
|
||||
// Reading methods for specific tokens =============================================================================
|
||||
@@ -652,7 +630,6 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
if (index < pattern.size - 2) {
|
||||
// one symbol family
|
||||
if (pattern[index] != '{') {
|
||||
// TODO: Replace such string formation with something like patter.substring(..)
|
||||
return "Is${pattern[nextIndex()]}"
|
||||
}
|
||||
|
||||
@@ -692,11 +669,9 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
}
|
||||
|
||||
/** Process octal integer. */
|
||||
// TODO: Replace with String.toInt(8)
|
||||
private fun readOctals(): Int {
|
||||
val length = pattern.size - 2 // TODO: Add a special method for check 'index < pattern.size - 2'
|
||||
val length = pattern.size - 2
|
||||
var result = 0
|
||||
// TODO: Add digit conversion.
|
||||
var digit = digitOf(pattern[index], 8)
|
||||
if (digit == -1) {
|
||||
throw PatternSyntaxException()
|
||||
@@ -758,7 +733,7 @@ internal class Lexer(val patternString: String, flags: Int) {
|
||||
val QUANT_COMP_P = QMOD_POSSESSIVE or '{'.toInt()
|
||||
val QUANT_COMP_R = QMOD_RELUCTANT or '{'.toInt()
|
||||
|
||||
/** Returns true if [ch] is a plain token. */ // TODO: May be rename
|
||||
/** Returns true if [ch] is a plain token. */
|
||||
fun isLetter(ch: Int): Boolean {
|
||||
// All supplementary codepoints have integer value that is >= 0.
|
||||
return ch >= 0
|
||||
|
||||
@@ -22,12 +22,7 @@ package kotlin.text.regex
|
||||
* @author Nikolay A. Kuznetsov
|
||||
*/
|
||||
|
||||
// TODO: rework defaults.
|
||||
// TODO: May be we can remove left/rightBound and just create a substring for matching/searching.
|
||||
// TODO: We don't use right/leftBound in our API now. So this function can be removed.
|
||||
// TODO: But I think it may be useful to save them for further improvements of the API.
|
||||
internal class MatchResultImpl
|
||||
// TODO: Refactor the constructor comment.
|
||||
/**
|
||||
* @param input an input sequence for matching/searching.
|
||||
* @param regex a [Regex] instance used for matching/searching.
|
||||
@@ -37,20 +32,18 @@ constructor (internal val input: CharSequence,
|
||||
internal val regex: Regex) : MatchResult {
|
||||
|
||||
// Harmony's implementation ========================================================================================
|
||||
// TODO: Rework number of groups
|
||||
private val nativePattern = regex.nativePattern
|
||||
private val groupCount = nativePattern.capturingGroupCount
|
||||
private val groupBounds = IntArray(groupCount * 2) { -1 }
|
||||
|
||||
private val consumers = IntArray(nativePattern.consumersCount + 1) { -1 } // TODO: What is consumers array?
|
||||
private val consumers = IntArray(nativePattern.consumersCount + 1) { -1 }
|
||||
|
||||
// Used by quantifiers to store a count of a quantified expression occurrences.
|
||||
val enterCounters: IntArray = IntArray( maxOf(nativePattern.groupQuantifierCount, 0) ) // TODO remove maxOf
|
||||
val enterCounters: IntArray = IntArray( maxOf(nativePattern.groupQuantifierCount, 0) )
|
||||
|
||||
var startIndex: Int = 0
|
||||
set (startIndex: Int) {
|
||||
field = startIndex
|
||||
// TODO: what is it? And do we need it?
|
||||
if (previousMatch < 0) {
|
||||
previousMatch = startIndex
|
||||
}
|
||||
@@ -62,7 +55,7 @@ constructor (internal val input: CharSequence,
|
||||
// MatchResult interface ===========================================================================================
|
||||
/** The range of indices in the original string where match was captured. */
|
||||
override val range: IntRange
|
||||
get() = getStart(0) until getEnd(0) // TODO: I don't like these get... set... methods. Rename them or make properties.
|
||||
get() = getStart(0) until getEnd(0)
|
||||
|
||||
/** The substring from the input string captured by this match. */
|
||||
override val value: String
|
||||
@@ -136,7 +129,6 @@ constructor (internal val input: CharSequence,
|
||||
|
||||
|
||||
// Harmony's implementation ========================================================================================
|
||||
// TODO: What is it?
|
||||
fun setConsumed(counter: Int, value: Int) {
|
||||
this.consumers[counter] = value
|
||||
}
|
||||
@@ -148,7 +140,6 @@ constructor (internal val input: CharSequence,
|
||||
fun isCaptured(group: Int): Boolean = getStart(group) >= 0
|
||||
|
||||
// Setters and getters for starts and ends of groups ===============================================================
|
||||
// TODO: Decide what access modifier should we use in this class.
|
||||
internal fun setStart(group: Int, offset: Int) {
|
||||
checkGroup(group)
|
||||
groupBounds[group * 2] = offset
|
||||
@@ -189,14 +180,12 @@ constructor (internal val input: CharSequence,
|
||||
* @param group the group, ranging from 0 to groupCount() - 1, with 0 representing the whole pattern.
|
||||
* @return the text that matched the group.
|
||||
*/
|
||||
// TODO: Reread and maybe rewrite.
|
||||
fun group(group: Int = 0): String? {
|
||||
val start = getStart(group)
|
||||
val end = getEnd(group)
|
||||
if (start < 0) { // TODO: Do we need to check end?
|
||||
if (start < 0 || end < 0) {
|
||||
return null
|
||||
}
|
||||
assert(start <= end && end >= 0 && end <= input.length) // TODO: remove the assert.
|
||||
return input.subSequence(getStart(group), getEnd(group)).toString()
|
||||
}
|
||||
|
||||
@@ -207,7 +196,7 @@ constructor (internal val input: CharSequence,
|
||||
* @return the number of groups.
|
||||
*/
|
||||
fun groupCount(): Int {
|
||||
return groupCount - 1 // TODO: Do something with it. These +/-1 are terrible.
|
||||
return groupCount - 1
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -43,7 +43,9 @@ internal class Pattern(val pattern: String, flags: Int = 0) {
|
||||
if (flags != 0 && flags or flagsBitMask != flagsBitMask) {
|
||||
throw IllegalArgumentException()
|
||||
}
|
||||
AbstractSet.counter = 1 // TODO: It's for debug purposes.
|
||||
|
||||
// It's for debug purposes.
|
||||
AbstractSet.counter = 1
|
||||
|
||||
startNode = processExpression(-1, this.flags, null)
|
||||
|
||||
@@ -108,7 +110,6 @@ internal class Pattern(val pattern: String, flags: Int = 0) {
|
||||
fSet = FinalSet()
|
||||
saveChangedFlags = true
|
||||
} else {
|
||||
// TODO: Looks like next here is null. Or it is set later.
|
||||
fSet = FSet(capturingGroupCount)
|
||||
}
|
||||
if (capturingGroupCount < BACK_REF_NUMBER) {
|
||||
@@ -136,7 +137,6 @@ internal class Pattern(val pattern: String, flags: Int = 0) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: Do we realy need this null check? Looks like child cannot be null.
|
||||
children.add(child)
|
||||
} while (!(lexemes.isEmpty() || lexemes.currentChar == Lexer.CHAR_RIGHT_PARENTHESIS))
|
||||
|
||||
@@ -184,7 +184,6 @@ internal class Pattern(val pattern: String, flags: Int = 0) {
|
||||
|| lexemes.lookAhead == Lexer.CHAR_DOLLAR)) {
|
||||
val ch = lexemes.next()
|
||||
|
||||
// TODO: Adapt to our checks.
|
||||
if (Char.isSupplementaryCodePoint(ch)) {
|
||||
substring.append(Char.toChars(ch))
|
||||
} else {
|
||||
@@ -197,7 +196,6 @@ internal class Pattern(val pattern: String, flags: Int = 0) {
|
||||
/**
|
||||
* D->a
|
||||
*/
|
||||
// TODO: Refactor
|
||||
private fun processDecomposedChar(): AbstractSet {
|
||||
val codePoints = IntArray(Lexer.MAX_DECOMPOSITION_LENGTH)
|
||||
val codePointsHangul: CharArray
|
||||
@@ -288,7 +286,7 @@ internal class Pattern(val pattern: String, flags: Int = 0) {
|
||||
}
|
||||
}
|
||||
lexemes.isHighSurrogate() || lexemes.isLowSurrogate() -> {
|
||||
val term = processTerminal(last) // TODO: term is not null.
|
||||
val term = processTerminal(last)
|
||||
cur = processQuantifier(last, term)
|
||||
}
|
||||
else -> {
|
||||
@@ -479,7 +477,6 @@ internal class Pattern(val pattern: String, flags: Int = 0) {
|
||||
if (lexemes.currentChar != Lexer.CHAR_RIGHT_SQUARE_BRACKET) {
|
||||
throw PatternSyntaxException()
|
||||
}
|
||||
// TODO: Set mode lexer as Mode.Range is set.
|
||||
lexemes.setModeWithReread(Lexer.Mode.PATTERN)
|
||||
lexemes.next()
|
||||
}
|
||||
@@ -598,7 +595,6 @@ internal class Pattern(val pattern: String, flags: Int = 0) {
|
||||
/**
|
||||
* Process [...] ranges
|
||||
*/
|
||||
// TODO: We can merge it with processRangeExpression.
|
||||
private fun processRange(negative: Boolean, last: AbstractSet): AbstractSet {
|
||||
val res = processRangeExpression(negative)
|
||||
val rangeSet = processRangeSet(res)
|
||||
@@ -760,7 +756,6 @@ internal class Pattern(val pattern: String, flags: Int = 0) {
|
||||
return result
|
||||
}
|
||||
|
||||
// TODO: Reread
|
||||
private fun processRangeSet(charClass: AbstractCharClass): AbstractSet {
|
||||
if (charClass.hasLowHighSurrogates()) {
|
||||
val lowHighSurrRangeSet = SurrogateRangeSet(charClass.surrogates)
|
||||
|
||||
@@ -10,7 +10,6 @@ import kotlin.IllegalArgumentException
|
||||
|
||||
* @author Nikolay A. Kuznetsov
|
||||
*/
|
||||
// TODO: May be replace with some other class (Range?).
|
||||
internal class Quantifier(val min: Int, val max: Int = min) : SpecialToken() {
|
||||
|
||||
init {
|
||||
|
||||
@@ -98,7 +98,7 @@ internal abstract class AbstractSet(val type: Int = 0) {
|
||||
|
||||
/**
|
||||
* @param leftLimit - an index, to finish search back (left limit, inclusive).
|
||||
* @param rightLimit - an index to start search from (right limit, exclusive). // TODO: Is it really exclusive
|
||||
* @param rightLimit - an index to start search from (right limit, exclusive).
|
||||
* @param testString - test string.
|
||||
* @param matchResult - match result.
|
||||
* @return an index to start back search next time if this search fails(new left bound);
|
||||
@@ -128,7 +128,6 @@ internal abstract class AbstractSet(val type: Int = 0) {
|
||||
* @param set - A node the intersection is checked for. Usually a previous node.
|
||||
* @return true if the given node intersects with this one, false otherwise.
|
||||
*/
|
||||
// TODO: May be rename. e.g. intersects for something else.
|
||||
open fun first(set: AbstractSet): Boolean = true
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,8 +32,7 @@ open internal class AtomicJointSet(children: List<AbstractSet>, fSet: FSet) : No
|
||||
val shift = it.matches(startIndex, testString, matchResult)
|
||||
if (shift >= 0) {
|
||||
// AtomicFset always returns true, but saves the index to run this next.match() from;
|
||||
// TODO: Try to get rid of this explicit cast to AtomicFSet
|
||||
return next.matches((fSet as AtomicFSet).index, testString, matchResult) // TODO: We use next here.
|
||||
return next.matches((fSet as AtomicFSet).index, testString, matchResult)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +43,5 @@ open internal class AtomicJointSet(children: List<AbstractSet>, fSet: FSet) : No
|
||||
override val name: String
|
||||
get() = "AtomicJointSet"
|
||||
|
||||
// TODO: looks like we can replace it with just next property.
|
||||
override var next: AbstractSet = dummyNext
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ package kotlin.text.regex
|
||||
*
|
||||
* @author Nikolay A. Kuznetsov
|
||||
*/
|
||||
// TODO: Process next better - it is non-null in almost all cases.
|
||||
open internal class CharSet(char: Char, val ignoreCase: Boolean = false) : LeafSet() {
|
||||
|
||||
// We use only low case characters when working in case insensitive mode.
|
||||
|
||||
@@ -87,8 +87,6 @@ package kotlin.text.regex
|
||||
* the first consisting of these surrogate characters and the second consisting of all others characters
|
||||
* from the parent range. This class represents the parent range split in such a manner.
|
||||
*/
|
||||
// TODO: May be we can merge sets with surrogates and without them.
|
||||
// TODO: Use more specific constructor params (e.g. RangeSet)
|
||||
internal class CompositeRangeSet(/* range without surrogates */ val withoutSurrogates: AbstractSet,
|
||||
/* range containing surrogates only */ val surrogates: AbstractSet) : SimpleSet() {
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package kotlin.text.regex
|
||||
|
||||
/** Represents canonical decomposition of Unicode character. Is used when CANON_EQ flag of Pattern class is specified. */
|
||||
// TODO: Refactor it.
|
||||
open internal class DecomposedCharSet(
|
||||
/** Decomposition of the Unicode codepoint */
|
||||
private val decomposedChar: IntArray,
|
||||
|
||||
@@ -22,7 +22,6 @@ package kotlin.text.regex
|
||||
*
|
||||
* @author Nikolay A. Kuznetsov
|
||||
*/
|
||||
// TODO: Looks like we can extend AbstractSet instead of JointSet here.
|
||||
internal class DotSet(val lt: AbstractLineTerminator, val matchLineTerminator: Boolean)
|
||||
: SimpleSet(AbstractSet.TYPE_DOTSET) {
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ package kotlin.text.regex
|
||||
*
|
||||
* @author Nikolay A. Kuznetsov
|
||||
*/
|
||||
// TODO: What is consCounter?
|
||||
// TODO: rename consCounter?
|
||||
internal class EOLSet(val consCounter: Int, val lt: AbstractLineTerminator, val multiline: Boolean = false) : SimpleSet() {
|
||||
|
||||
override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int {
|
||||
|
||||
@@ -21,7 +21,6 @@ package kotlin.text.regex
|
||||
* The node which marks end of the particular group.
|
||||
* @author Nikolay A. Kuznetsov
|
||||
*/
|
||||
// TODO: Rename?
|
||||
open internal class FSet(val groupIndex: Int) : SimpleSet() {
|
||||
|
||||
var isBackReferenced = false
|
||||
@@ -96,7 +95,7 @@ internal class FinalSet : FSet(0) {
|
||||
internal class NonCapFSet(groupIndex: Int) : FSet(groupIndex) {
|
||||
|
||||
override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int {
|
||||
matchResult.setConsumed(groupIndex, startIndex - matchResult.getConsumed(groupIndex)) // TODO: Don't understand it.
|
||||
matchResult.setConsumed(groupIndex, startIndex - matchResult.getConsumed(groupIndex))
|
||||
return next.matches(startIndex, testString, matchResult)
|
||||
}
|
||||
|
||||
|
||||
@@ -43,8 +43,6 @@ open internal class GroupQuantifierSet(
|
||||
return next.matches(startIndex, testString, matchResult)
|
||||
}
|
||||
|
||||
// TODO: We can store an optimized functions for specific cases (like *) in a separate callable reference and
|
||||
// TODO: call it instead of checks during matching.
|
||||
// Fast case: '*' or {0, } - no need to count occurrences.
|
||||
if (min == 0 && max == Quantifier.INF) {
|
||||
val nextIndex = innerSet.matches(startIndex, testString, matchResult)
|
||||
|
||||
@@ -21,7 +21,6 @@ package kotlin.text.regex
|
||||
* Represents canonical decomposition of Hangul syllable. Is used when
|
||||
* CANON_EQ flag of Pattern class is specified.
|
||||
*/
|
||||
// TODO: Refactor it.
|
||||
internal class HangulDecomposedCharSet(
|
||||
/**
|
||||
* Decomposed Hangul syllable.
|
||||
|
||||
@@ -36,7 +36,6 @@ open internal class JointSet(children: List<AbstractSet>, fSet: FSet) : Abstract
|
||||
/**
|
||||
* Returns startIndex+shift, the next position to match
|
||||
*/
|
||||
// TODO: Why don't we use a next here?
|
||||
override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int {
|
||||
if (children.isEmpty()) {
|
||||
return -1
|
||||
|
||||
@@ -26,11 +26,7 @@ internal abstract class LeafSet : SimpleSet(AbstractSet.TYPE_LEAF) {
|
||||
|
||||
open val charCount = 1
|
||||
|
||||
/**
|
||||
* Returns "shift", the number of accepted chars.
|
||||
* Commonly internal function, but called by quantifiers.
|
||||
*/
|
||||
// TODO: Magic function. Use by another way?
|
||||
/** Returns "shift", the number of accepted chars. Commonly internal function, but called by quantifiers. */
|
||||
abstract fun accepts(startIndex: Int, testString: CharSequence): Int
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,7 +36,7 @@ internal class PositiveLookAheadSet(children: List<AbstractSet>, fSet: FSet) : A
|
||||
return -1
|
||||
}
|
||||
|
||||
override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true // TODO: May be false?
|
||||
override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true
|
||||
override val name: String
|
||||
get() = "PositiveLookaheadJointSet"
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ internal class PositiveLookBehindSet(children: List<AbstractSet>, fSet: FSet) :
|
||||
return -1
|
||||
}
|
||||
|
||||
override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true // TODO: False was here. It's true just for experiment.
|
||||
override fun hasConsumed(matchResult: MatchResultImpl): Boolean = true
|
||||
override val name: String
|
||||
get() = "PositiveBehindJointSet"
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ internal class PossessiveGroupQuantifierSet(
|
||||
): GroupQuantifierSet(quantifier, innerSet, next, type, setCounter) {
|
||||
|
||||
init {
|
||||
innerSet.next = FSet.possessiveFSet // TODO: Try to use such an approach for other sets.
|
||||
innerSet.next = FSet.possessiveFSet
|
||||
}
|
||||
|
||||
override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int {
|
||||
@@ -45,8 +45,7 @@ internal class PossessiveGroupQuantifierSet(
|
||||
nextIndex = innerSet.matches(index, testString, matchResult)
|
||||
}
|
||||
|
||||
// TODO: Do we need this check?
|
||||
if (/* nextIndex < 0 && */ occurrences < quantifier.min) {
|
||||
if (occurrences < quantifier.min) {
|
||||
return -1
|
||||
} else {
|
||||
return next.matches(index, testString, matchResult)
|
||||
|
||||
@@ -36,7 +36,6 @@ internal class PossessiveLeafQuantifierSet(
|
||||
var index = startIndex
|
||||
var occurrences = 0
|
||||
|
||||
// TODO: Create a separate functions for these loops?
|
||||
while (occurrences < min) {
|
||||
if (index + leaf.charCount > testString.length) {
|
||||
return -1
|
||||
|
||||
@@ -22,11 +22,9 @@ package kotlin.text.regex
|
||||
*
|
||||
* @author Nikolay A. Kuznetsov
|
||||
*/
|
||||
// TODO: check of innerSet must be nullable or not
|
||||
internal abstract class QuantifierSet(open var innerSet: AbstractSet, override var next: AbstractSet, type: Int)
|
||||
: SimpleSet(type) {
|
||||
|
||||
// TODO: Looks like we need true by default here.
|
||||
override fun first(set: AbstractSet): Boolean =
|
||||
innerSet.first(set) || next.first(set)
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
package kotlin.text.regex
|
||||
|
||||
/**
|
||||
* Represents node accepting single character from the given char class. (TODO: Not a surrogate character?)
|
||||
* Represents node accepting single character from the given char class.
|
||||
*
|
||||
* @author Nikolay A. Kuznetsov
|
||||
*/
|
||||
|
||||
@@ -50,7 +50,7 @@ internal class ReluctantGroupQuantifierSet(
|
||||
|
||||
// can't go inner set;
|
||||
if (enterCounter >= max) {
|
||||
matchResult.enterCounters[groupQuantifierIndex] = 0 // TODO: Do we need it?
|
||||
matchResult.enterCounters[groupQuantifierIndex] = 0
|
||||
return next.matches(startIndex, testString, matchResult)
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,6 @@ internal class ReluctantLeafQuantifierSet(
|
||||
occurrences++
|
||||
}
|
||||
|
||||
// TODO: May be refactor this loop.
|
||||
do {
|
||||
var shift = next.matches(index, testString, matchResult)
|
||||
if (shift >= 0) {
|
||||
|
||||
@@ -32,8 +32,6 @@ internal class SOLSet(val lt: AbstractLineTerminator, val multiline: Boolean = f
|
||||
return next.matches(startIndex, testString, matchResult)
|
||||
}
|
||||
} else {
|
||||
// TODO: In Kotlin JVM the empty string doesn't match to "^.$" pattern in multiline mode and matches in single-line mode.
|
||||
// TODO: So do we need to implement this behaviour or we can match to the pattern in the both cases?
|
||||
if (startIndex != testString.length
|
||||
&& (startIndex == 0
|
||||
|| lt.isAfterLineTerminator(testString[startIndex - 1], testString[startIndex]))) {
|
||||
|
||||
@@ -86,7 +86,6 @@ open internal class SequenceSet(substring: CharSequence, val ignoreCase: Boolean
|
||||
return -1
|
||||
}
|
||||
|
||||
// TODO: reread/rewrite
|
||||
override fun first(set: AbstractSet): Boolean {
|
||||
if (ignoreCase) {
|
||||
return super.first(set) // TODO: Add correct checks for this case.
|
||||
@@ -94,7 +93,6 @@ open internal class SequenceSet(substring: CharSequence, val ignoreCase: Boolean
|
||||
return when (set) {
|
||||
is CharSet -> set.char == patternString[0]
|
||||
is RangeSet -> set.accepts(0, patternString.substring(0, 1)) > 0
|
||||
// TODO: perfrom a char to codepoint converter.
|
||||
is SupplementaryRangeSet -> set.contains(patternString[0]) || patternString.length > 1 && set.contains(Char.toCodePoint(patternString[0], patternString[1]))
|
||||
is SupplementaryCharSet -> if (patternString.length > 1) set.codePoint == Char.toCodePoint(patternString[0], patternString[1])
|
||||
else false
|
||||
|
||||
@@ -87,8 +87,6 @@ package kotlin.text.regex
|
||||
*
|
||||
* @author Nikolay A. Kuznetsov
|
||||
*/
|
||||
//assumes int value of this supplementary codepoint as a parameter
|
||||
// TODO: Tests crash here. Investigate why.
|
||||
internal class SupplementaryCharSet(val codePoint: Int, ignoreCase: Boolean)
|
||||
: SequenceSet(fromCharArray(Char.toChars(codePoint), 0, 2), ignoreCase) {
|
||||
|
||||
@@ -96,7 +94,6 @@ internal class SupplementaryCharSet(val codePoint: Int, ignoreCase: Boolean)
|
||||
get() = patternString
|
||||
|
||||
override fun first(set: AbstractSet): Boolean {
|
||||
// TODO: replace with when
|
||||
return when (set) {
|
||||
is SupplementaryCharSet -> set.codePoint == codePoint
|
||||
is SupplementaryRangeSet -> set.contains(codePoint)
|
||||
|
||||
@@ -91,7 +91,6 @@ package kotlin.text.regex
|
||||
*/
|
||||
open internal class SupplementaryRangeSet(charClass: AbstractCharClass, val ignoreCase: Boolean = false): SimpleSet() {
|
||||
|
||||
// TODO: may be add ignoreCase flag to CharClass
|
||||
val chars = charClass.instance
|
||||
|
||||
override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int {
|
||||
|
||||
@@ -91,10 +91,8 @@ package kotlin.text.regex
|
||||
*
|
||||
* @author Nikolay A. Kuznetsov
|
||||
*/
|
||||
// TODO: Could we use just CharSet instead of this one?
|
||||
internal class LowSurrogateCharSet(low: Char) : CharSet(low) {
|
||||
|
||||
// TODO: Remove bounds from MatchResultImpl.
|
||||
override fun accepts(startIndex: Int, testString: CharSequence): Int {
|
||||
val result = super.accepts(startIndex, testString)
|
||||
if (result < 0 || testString.isHighSurrogate(startIndex - 1)) {
|
||||
|
||||
@@ -108,7 +108,7 @@ internal class SurrogateRangeSet(surrChars: AbstractCharClass) : RangeSet(surrCh
|
||||
|
||||
override fun first(set: AbstractSet): Boolean {
|
||||
return when (set) {
|
||||
is SurrogateRangeSet -> true // TODO: May be add some check here.
|
||||
is SurrogateRangeSet -> true
|
||||
is CharSet,
|
||||
is RangeSet,
|
||||
is SupplementaryCharSet,
|
||||
|
||||
@@ -23,7 +23,6 @@ package kotlin.text.regex
|
||||
*
|
||||
* @author Nikolay A. Kuznetsov
|
||||
*/
|
||||
// TODO: May be rename?
|
||||
internal class UnifiedQuantifierSet(quant: LeafQuantifierSet) : LeafQuantifierSet(Quantifier.starQuantifier, quant.leaf, quant.next, quant.type) {
|
||||
|
||||
override fun matches(startIndex: Int, testString: CharSequence, matchResult: MatchResultImpl): Int {
|
||||
@@ -50,6 +49,6 @@ internal class UnifiedQuantifierSet(quant: LeafQuantifierSet) : LeafQuantifierSe
|
||||
}
|
||||
|
||||
init {
|
||||
innerSet.next = this // TODO: O_o
|
||||
innerSet.next = this
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user