regex: Clean TODOs

This commit is contained in:
Ilya Matveev
2017-06-16 16:19:23 +07:00
committed by ilmat192
parent bfcc0fc0d0
commit 1e7d132a88
32 changed files with 31 additions and 107 deletions
@@ -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
}
}