From 82f2fdd693d7107dc0c7dff2de5daeca83f4bb67 Mon Sep 17 00:00:00 2001 From: tkadziolka Date: Tue, 13 Feb 2024 08:00:30 +0100 Subject: [PATCH 1/2] Ignored keywords in strings --- .../dev/snipme/highlights/internal/CodeAnalyzer.kt | 7 ++++--- .../internal/locator/KeywordLocatorTest.kt | 12 ++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/commonMain/kotlin/dev/snipme/highlights/internal/CodeAnalyzer.kt b/src/commonMain/kotlin/dev/snipme/highlights/internal/CodeAnalyzer.kt index 9d67aba..2c1f5d1 100644 --- a/src/commonMain/kotlin/dev/snipme/highlights/internal/CodeAnalyzer.kt +++ b/src/commonMain/kotlin/dev/snipme/highlights/internal/CodeAnalyzer.kt @@ -106,14 +106,15 @@ internal object CodeAnalyzer { private fun analyzeCodeWithKeywords(code: String, keywords: List): CodeStructure { val comments = CommentLocator.locate(code) val multiLineComments = MultilineCommentLocator.locate(code) + val strings = StringLocator.locate(code) - val allComments = comments + multiLineComments + val plainTextRanges = comments + multiLineComments + strings return CodeStructure( marks = MarkLocator.locate(code), punctuations = PunctuationLocator.locate(code), - keywords = KeywordLocator.locate(code, keywords, allComments), - strings = StringLocator.locate(code), + keywords = KeywordLocator.locate(code, keywords, plainTextRanges), + strings = strings, literals = NumericLiteralLocator.locate(code), comments = comments, multilineComments = multiLineComments, diff --git a/src/commonTest/kotlin/dev/snipme/highlights/internal/locator/KeywordLocatorTest.kt b/src/commonTest/kotlin/dev/snipme/highlights/internal/locator/KeywordLocatorTest.kt index 52abada..c2d1fa1 100644 --- a/src/commonTest/kotlin/dev/snipme/highlights/internal/locator/KeywordLocatorTest.kt +++ b/src/commonTest/kotlin/dev/snipme/highlights/internal/locator/KeywordLocatorTest.kt @@ -122,4 +122,16 @@ internal class KeywordLocatorTest { assertEquals(0, result.size) } + + @Test + fun `Not returns keywords from string`() { + val testCode = """ + val text = "This class is static and should extend another class" + """.trimIndent() + val keywords = listOf("static", "class", "extends") + + val result = KeywordLocator.locate(testCode, keywords, listOf(PhraseLocation(0, 54))) + + assertEquals(0, result.size) + } } \ No newline at end of file From 2967e5e7ad8893de5709bd58385e3a6afd275008 Mon Sep 17 00:00:00 2001 From: tkadziolka Date: Sun, 25 Feb 2024 20:03:19 +0100 Subject: [PATCH 2/2] Handled letters in numbers in non standard places --- .../internal/locator/NumericLiteralLocator.kt | 26 +++++++---- .../locator/NumericLiteralLocatorTest.kt | 46 +++++++++++++++++++ .../internal/locator/StringLocatorTest.kt | 1 - 3 files changed, 64 insertions(+), 9 deletions(-) diff --git a/src/commonMain/kotlin/dev/snipme/highlights/internal/locator/NumericLiteralLocator.kt b/src/commonMain/kotlin/dev/snipme/highlights/internal/locator/NumericLiteralLocator.kt index c3aa17b..c50f4ab 100644 --- a/src/commonMain/kotlin/dev/snipme/highlights/internal/locator/NumericLiteralLocator.kt +++ b/src/commonMain/kotlin/dev/snipme/highlights/internal/locator/NumericLiteralLocator.kt @@ -1,13 +1,13 @@ package dev.snipme.highlights.internal.locator -import dev.snipme.highlights.model.PhraseLocation import dev.snipme.highlights.internal.SyntaxTokens.TOKEN_DELIMITERS import dev.snipme.highlights.internal.indicesOf +import dev.snipme.highlights.model.PhraseLocation -private const val NUMBER_ENDING_LETTER_COUNT = 1 private val NUMBER_START_CHARACTERS = listOf('-', '.') private val NUMBER_TYPE_CHARACTERS = listOf('e', 'u', 'f', 'l') private val HEX_NUMBER_CHARACTERS = listOf('a', 'b', 'c', 'd', 'e', 'f') +private val NUMBER_SPECIAL_CHARACTERS = listOf('_') internal object NumericLiteralLocator { @@ -24,7 +24,7 @@ internal object NumericLiteralLocator { code.split(*delimiters) // Separate words .asSequence() // Manipulate on given word separately .filterNot { foundPhrases.contains(it) } - .filter { it.isNotEmpty() } // Filter spaces and others + .filter { it.isNotBlank() } // Filter spaces and others .filter { it.first().isDigit() || (NUMBER_START_CHARACTERS.contains(it.first()) && it.getOrNull(1)?.isDigit() == true) @@ -36,7 +36,7 @@ internal object NumericLiteralLocator { // Omit in the middle of text, probably variable name (this100) if (code.isNumberFirstIndex(startIndex).not()) return@forEach // Add matching occurrence to the output locations - val length = calculateNumberLength(number) + val length = calculateNumberLength(number.lowercase()) locations.add(PhraseLocation(startIndex, startIndex + length)) } @@ -79,13 +79,23 @@ internal object NumericLiteralLocator { } } + // Highlight only 4f when e.g. number is like 4fff if (NUMBER_TYPE_CHARACTERS.any { letters.contains(it) }) { - return number.count { it.isDigit() } + - number.count { NUMBER_START_CHARACTERS.contains(it) } + - NUMBER_ENDING_LETTER_COUNT + var length = 1 // Single letter + length += number.count { it.isDigit() } + length += number.count { NUMBER_START_CHARACTERS.contains(it) } + length += number.count { NUMBER_SPECIAL_CHARACTERS.contains(it) } + if ("e+" in number) length++ + return length } - return number.length + return number.filter { + it.isDigit() || + NUMBER_START_CHARACTERS.contains(it) || + NUMBER_TYPE_CHARACTERS.contains(it) || + NUMBER_SPECIAL_CHARACTERS.contains(it) + + }.length } private fun getLengthOfSubstringFor(number: String, condition: (Char) -> Boolean): Int { diff --git a/src/commonTest/kotlin/dev/snipme/highlights/internal/locator/NumericLiteralLocatorTest.kt b/src/commonTest/kotlin/dev/snipme/highlights/internal/locator/NumericLiteralLocatorTest.kt index 89889c1..7aecbcd 100644 --- a/src/commonTest/kotlin/dev/snipme/highlights/internal/locator/NumericLiteralLocatorTest.kt +++ b/src/commonTest/kotlin/dev/snipme/highlights/internal/locator/NumericLiteralLocatorTest.kt @@ -142,4 +142,50 @@ internal class NumericLiteralLocatorTest { assertEquals(0, result.size) } + + @Test + fun `Returns whole location of the all scientific notations`() { + val testCode = """ + 1e+10 + 100e100 + 0.11E-10 + 123.456E+10 + 100_00E10 + 12e+1000 + """.trimIndent() + + val result = NumericLiteralLocator.locate(testCode) + + assertEquals(6, result.size) + assertEquals(PhraseLocation(0, 5), result[0]) + assertEquals(PhraseLocation(6, 13), result[1]) + assertEquals(PhraseLocation(14, 22), result[2]) + assertEquals(PhraseLocation(23, 34), result[3]) + assertEquals(PhraseLocation(35, 44), result[4]) + assertEquals(PhraseLocation(45, 53), result[5]) + } + + @Test + fun `Returns only proper length number with letter`() { + val testCode = """ + 12e+1000 + 12.dp + 12f.d + -2b + 12sss + 0b10000 + 13.22f + """.trimIndent() + + val result = NumericLiteralLocator.locate(testCode) + + assertEquals(7, result.size) + assertEquals(PhraseLocation(0, 8), result[0]) + assertEquals(PhraseLocation(9, 12), result[1]) + assertEquals(PhraseLocation(15, 19), result[2]) + assertEquals(PhraseLocation(21, 23), result[3]) + assertEquals(PhraseLocation(25, 27), result[4]) + assertEquals(PhraseLocation(31, 38), result[5]) + assertEquals(PhraseLocation(39, 45), result[6]) + } } \ No newline at end of file diff --git a/src/commonTest/kotlin/dev/snipme/highlights/internal/locator/StringLocatorTest.kt b/src/commonTest/kotlin/dev/snipme/highlights/internal/locator/StringLocatorTest.kt index 09b5758..e854675 100644 --- a/src/commonTest/kotlin/dev/snipme/highlights/internal/locator/StringLocatorTest.kt +++ b/src/commonTest/kotlin/dev/snipme/highlights/internal/locator/StringLocatorTest.kt @@ -1,6 +1,5 @@ package dev.snipme.highlights.internal.locator -import dev.snipme.highlights.internal.printResults import dev.snipme.highlights.model.PhraseLocation import kotlin.test.Test import kotlin.test.assertEquals