StringIndexOutOfBoundsException in IrStackVariableKt.buildMessage
Closed this issue · 8 comments
Trying a simple test with the following code:
import kotlin.test.*
class TestTest {
@Test
fun testFails() {
val a = 0
assertTrue(a == 42)
}
}
Getting the following exception during build:
e: java.lang.StringIndexOutOfBoundsException: begin 0, end -1, length 7
at java.base/java.lang.String.checkBoundsBeginEnd(String.java:3319)
at java.base/java.lang.String.substring(String.java:1874)
at com.bnorm.power.IrStackVariableKt.buildMessage(IrStackVariable.kt:85)
at com.bnorm.power.PowerAssertCallTransformer$visitCall$$inlined$run$lambda$1.buildAssertThrow(PowerAssertCallTransformer.kt:128)
at com.bnorm.power.PowerAssertGenerator$buildAssert$$inlined$irBlock$lambda$1.invoke(PowerAssertGenerator.kt:41)
at com.bnorm.power.PowerAssertGenerator$buildAssert$$inlined$irBlock$lambda$1.invoke(PowerAssertGenerator.kt:32)
at com.bnorm.power.PowerAssertGenerator.buildAssert(PowerAssertGenerator.kt:123)
at com.bnorm.power.PowerAssertGenerator.buildAssert(PowerAssertGenerator.kt:40)
at com.bnorm.power.PowerAssertCallTransformer.visitCall(PowerAssertCallTransformer.kt:138)
at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitCall(IrElementTransformerVoid.kt:173)
...
Full project can be found here: https://github.com/elizarov/KotlinPowerAssertPlayground
Thanks for the ticket! Unfortunately I've been unable to reproduce even using your project. Is there anything unique about your setup that comes to mind?
While I cannot be 100% confident, breadcrumbs from the stacktrace and the example which is failing leads me to guess it is failing to find the ==
characters in the string a == 42
. The way equality and comparison operators are found in an expression is very sub-optimal and I have been unable to find an alternative to just searching for the strings ==
, !=
, <=
, etc.
I will work on cleaning up this area of the plugin but it would still be interesting to determine the root cause in case there needs to be something added to the README.
Tested it more. It fails only on Windows. Works fine on my MacOS. It might have something to do with platform-specific line terminator (two bytes CRLF on Windows).
That's odd, because while originally I tried to reproduce on MacOS Laptop, I develop this library primarily on a Windows desktop. I quickly cloned the project there as well and was still unable to reproduce. I wonder if git is hiding an issue? Or if default IntelliJ import is hiding something?
Fails for me on Windows with gradlew clean build
from the command line.
Maybe your windows git is configured to checkout with unix-style one-byte line-separators? That's the only thing coming to my mind that could matter.
That was indeed it! Thanks for the assistance!
Hmm... This is rather odd. It appears the startOffset
and endOffset
values of an IrExpression
assume that the file text has had \r
removed. Currently I'm reading the file text as File(irFile.path).readText()
but that appears to be inconsistent with how the IrExpression offsets are calculated.
Firstly, it's trivial to add a .replace("\r", "")
to get this library working with files that have Windows-style line-separators. I'll get that fix pushed out soon.
Secondly, it seems the plugin needs to better coordinate with the compiler what the text of the file is. I'm not aware of any way to get the text of the file directly from the compiler which is why I read the file myself. If the compiler is not going to provide access to its representation of the file text, I think it needs to maintain the offsets without modifications to the raw text of the file. As such, I think there are 3 different ways this situation can go:
- There is already a way to get the file text from the compiler and I'm just unaware.
- The compiler needs to provide access to its representation of the file text.
- The compiler needs to make the
startOffset
andendOffset
of anIrExpression
match the raw text of the file.
I'll create a ticket against the compiler and link it here for tracking.
I've created https://youtrack.jetbrains.com/issue/KT-41888 for the Kotlin compiler.
Released version 0.5.1
which includes a fix.