Repository: bnorm/kotlin-power-assert (kotlin)

Issue:
StringIndexOutOfBoundsException in IrStackVariableKt.buildMessage
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

Pull request:
Fixes #20 

The Kotlin compiler removes carriage returns from the text of the file
when calculating the startOffset and endOffset properties for an
IrExpression. This causes the source snippet extraction to not work for
files with Windows-style line-separators.

Before pull substrings out of the file source string, remove all
carriages returns so the IrExpression offsets match the compiler.

Patch:
diff --git a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/PowerAssertCallTransformer.kt b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/PowerAssertCallTransformer.kt
index 34b8561..9558934 100644
--- a/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/PowerAssertCallTransformer.kt
+++ b/kotlin-power-assert-plugin/src/main/kotlin/com/bnorm/power/PowerAssertCallTransformer.kt
@@ -84,7 +84,7 @@ class PowerAssertCallTransformer(
 
   override fun lower(irFile: IrFile) {
     file = irFile
-    fileSource = File(irFile.path).readText()
+    fileSource = File(irFile.path).readText().replace("\r\n", "\n")
 
     irFile.transformChildrenVoid()
   }


Test patch:
diff --git a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/test.kt b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/test.kt
index 7223d11..e088ad4 100644
--- a/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/test.kt
+++ b/kotlin-power-assert-plugin/src/test/kotlin/com/bnorm/power/test.kt
@@ -382,6 +382,23 @@ check(1 == 2) { "the world is broken" }
       PowerAssertComponentRegistrar(setOf(FqName("kotlin.check")))
     )
   }
+
+  @Test
+  fun carriageReturnRemoval() {
+    assertMessage(
+      """
+fun main() {
+  val a = 0
+  assert(a == 42)
+}""".replace("\n", "\r\n"),
+      """
+Assertion failed
+assert(a == 42)
+       | |
+       | false
+       0
+""".trimIndent())
+  }
 }
 
 fun assertMessage(
@@ -390,7 +407,7 @@ fun assertMessage(
   vararg plugins: ComponentRegistrar = arrayOf(PowerAssertComponentRegistrar(setOf(FqName("kotlin.assert"))))
 ) {
   val result = KotlinCompilation().apply {
-    sources = listOf(SourceFile.kotlin("main.kt", source))
+    sources = listOf(SourceFile.kotlin("main.kt", source, trimIndent = false))
     useIR = true
     messageOutputStream = System.out
     compilerPlugins = plugins.toList()