Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## [0.8.0]

### Changed
- Kotlin version to 1.9.22

### Fixed
- scientific notation numbers highlight length
- redundant keyword highlights in strings and comments
- ambiguous nested forEach returns

## [0.7.1]

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
![highlights_banner_opaque](https://github.com/SnipMeDev/Highlights/assets/8405055/e123ce0f-6f58-451a-9e0a-893c0809b909)

[![Maven Central](https://img.shields.io/maven-central/v/dev.snipme/highlights)](https://mvnrepository.com/artifact/dev.snipme)
[![Kotlin](https://img.shields.io/badge/kotlin-1.9.0-blue.svg?logo=kotlin)](http://kotlinlang.org)
[![Kotlin](https://img.shields.io/badge/kotlin-1.9.22-blue.svg?logo=kotlin)](http://kotlinlang.org)
[![GitHub License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0)

# Highlights
Expand All @@ -15,7 +15,7 @@ repositories {
```

```shell
implementation("dev.snipme:highlights:0.7.1")
implementation("dev.snipme:highlights:0.8.0")
```

## Features ✨
Expand Down
9 changes: 2 additions & 7 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.configurationcache.extensions.capitalized
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.archivesName

apply(from = "publish-root.gradle")

plugins {
kotlin("multiplatform") version "1.9.0"
kotlin("multiplatform") version "1.9.22"
id("maven-publish")
id("io.github.gradle-nexus.publish-plugin") version "1.3.0"
id("signing")
}

group = "dev.snipme"
version = "0.7.1"
version = "0.8.0"

kotlin {
// Android
Expand Down
2 changes: 1 addition & 1 deletion sample/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
kotlin("jvm") version "1.9.0"
kotlin("jvm") version "1.9.22"
application
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package dev.snipme.highlights.internal

import dev.snipme.highlights.internal.locator.AnnotationLocator
import dev.snipme.highlights.model.CodeStructure
import dev.snipme.highlights.model.SyntaxLanguage
import dev.snipme.highlights.model.SyntaxLanguage.*
import dev.snipme.highlights.internal.SyntaxTokens.ALL_KEYWORDS
import dev.snipme.highlights.internal.SyntaxTokens.ALL_MIXED_KEYWORDS
import dev.snipme.highlights.internal.SyntaxTokens.COFFEE_KEYWORDS
Expand All @@ -19,13 +15,31 @@ import dev.snipme.highlights.internal.SyntaxTokens.RUBY_KEYWORDS
import dev.snipme.highlights.internal.SyntaxTokens.RUST_KEYWORDS
import dev.snipme.highlights.internal.SyntaxTokens.SH_KEYWORDS
import dev.snipme.highlights.internal.SyntaxTokens.SWIFT_KEYWORDS
import dev.snipme.highlights.internal.locator.AnnotationLocator
import dev.snipme.highlights.internal.locator.CommentLocator
import dev.snipme.highlights.internal.locator.KeywordLocator
import dev.snipme.highlights.internal.locator.NumericLiteralLocator
import dev.snipme.highlights.internal.locator.MarkLocator
import dev.snipme.highlights.internal.locator.MultilineCommentLocator
import dev.snipme.highlights.internal.locator.NumericLiteralLocator
import dev.snipme.highlights.internal.locator.PunctuationLocator
import dev.snipme.highlights.internal.locator.StringLocator
import dev.snipme.highlights.model.CodeStructure
import dev.snipme.highlights.model.SyntaxLanguage
import dev.snipme.highlights.model.SyntaxLanguage.C
import dev.snipme.highlights.model.SyntaxLanguage.COFFEESCRIPT
import dev.snipme.highlights.model.SyntaxLanguage.CPP
import dev.snipme.highlights.model.SyntaxLanguage.CSHARP
import dev.snipme.highlights.model.SyntaxLanguage.DEFAULT
import dev.snipme.highlights.model.SyntaxLanguage.JAVA
import dev.snipme.highlights.model.SyntaxLanguage.JAVASCRIPT
import dev.snipme.highlights.model.SyntaxLanguage.KOTLIN
import dev.snipme.highlights.model.SyntaxLanguage.MIXED
import dev.snipme.highlights.model.SyntaxLanguage.PERL
import dev.snipme.highlights.model.SyntaxLanguage.PYTHON
import dev.snipme.highlights.model.SyntaxLanguage.RUBY
import dev.snipme.highlights.model.SyntaxLanguage.RUST
import dev.snipme.highlights.model.SyntaxLanguage.SHELL
import dev.snipme.highlights.model.SyntaxLanguage.SWIFT

data class CodeSnapshot(
val code: String,
Expand Down Expand Up @@ -90,14 +104,20 @@ internal object CodeAnalyzer {
}

private fun analyzeCodeWithKeywords(code: String, keywords: List<String>): CodeStructure {
val comments = CommentLocator.locate(code)
val multiLineComments = MultilineCommentLocator.locate(code)
val strings = StringLocator.locate(code)

val plainTextRanges = comments + multiLineComments + strings

return CodeStructure(
marks = MarkLocator.locate(code),
punctuations = PunctuationLocator.locate(code),
keywords = KeywordLocator.locate(code, keywords),
strings = StringLocator.locate(code),
keywords = KeywordLocator.locate(code, keywords, plainTextRanges),
strings = strings,
literals = NumericLiteralLocator.locate(code),
comments = CommentLocator.locate(code),
multilineComments = MultilineCommentLocator.locate(code),
comments = comments,
multilineComments = multiLineComments,
annotations = AnnotationLocator.locate(code),
incremental = false,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
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.internal.isIndependentPhrase

import dev.snipme.highlights.model.PhraseLocation

internal object KeywordLocator {

fun locate(code: String, keywords: List<String>): List<PhraseLocation> {
fun locate(
code: String,
keywords: List<String>,
ignoreRanges: List<PhraseLocation> = emptyList(),
): List<PhraseLocation> {
val locations = mutableListOf<PhraseLocation>()
val foundKeywords = findKeywords(code, keywords)
foundKeywords.forEach { keyword ->

val interpretedKeywords = foundKeywords.filterNot { keyword ->
val index = code.indexOf(keyword)
val length = keyword.length
ignoreRanges.any { it.start <= index && it.end >= index + length }
}

interpretedKeywords.forEach { keyword ->
val indices = code
.indicesOf(keyword)
.filter { keyword.isIndependentPhrase(code, it) }
Expand Down
Original file line number Diff line number Diff line change
@@ -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 {

Expand All @@ -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)
Expand All @@ -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))
}

Expand Down Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,42 @@ internal class KeywordLocatorTest {

assertEquals(0, result.size)
}

@Test
fun `Not returns keywords from single comment`() {
val testCode = """
// 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, 55)))

assertEquals(0, result.size)
}

@Test
fun `Not returns keywords from multiline comment`() {
val testCode = """
/*
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, 56)))

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)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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])
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand Down