diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslScriptModel.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslScriptModel.kt index c42ddea554a..e6eb72ca21a 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslScriptModel.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslScriptModel.kt @@ -16,10 +16,24 @@ data class KotlinDslScriptModel( data class Message( val severity: Severity, val text: String, - val position: Position? = null + val details: String = "", + val position: Position? ) data class Position(val line: Int, val column: Int) enum class Severity { WARNING, ERROR } +} + +fun parsePositionFromException(e: String): Pair? { + //org.gradle.internal.exceptions.LocationAwareException: Build file '...\build.gradle.kts' line: 21 + if (e.startsWith("org.gradle.internal.exceptions.LocationAwareException:")) { + val message = e.substringBefore(System.lineSeparator()) + val file = message.substringAfter("Build file '").substringBefore("'") + val line = message.substringAfter("line: ").toIntOrNull() + if (file.isNotBlank() && line != null) { + return file to KotlinDslScriptModel.Position(line, 0) + } + } + return null } \ No newline at end of file diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslScriptModelResolverCommon.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslScriptModelResolverCommon.kt index 339b8b4ee79..93abd2baab3 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslScriptModelResolverCommon.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/scripting/gradle/importing/KotlinDslScriptModelResolverCommon.kt @@ -42,9 +42,17 @@ abstract class KotlinDslScriptModelResolverCommon : AbstractProjectResolverExten val messages = mutableListOf() model.exceptions.forEach { + val fromException = parsePositionFromException(it) + if (fromException != null) { + val (filePath, _) = fromException + if (filePath != file.path) return@forEach + } messages.add( KotlinDslScriptModel.Message( - KotlinDslScriptModel.Severity.ERROR, it + KotlinDslScriptModel.Severity.ERROR, + it.substringBefore(System.lineSeparator()), + it, + fromException?.second ) ) } @@ -57,11 +65,9 @@ abstract class KotlinDslScriptModelResolverCommon : AbstractProjectResolverExten else -> KotlinDslScriptModel.Severity.ERROR }, it.message, - it.position?.let { position -> - KotlinDslScriptModel - .Position(position.line, position.column) - } - )) + position = KotlinDslScriptModel.Position(it.position?.line ?: 0, it.position?.column ?: 0) + ) + ) } // todo(KT-34440): take inputs snapshot before starting import diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/scripting/gradle/KotlinDslScriptModelTest.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/scripting/gradle/KotlinDslScriptModelTest.kt new file mode 100644 index 00000000000..391e78261cb --- /dev/null +++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/scripting/gradle/KotlinDslScriptModelTest.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.scripting.gradle + +import org.gradle.groovy.scripts.TextResourceScriptSource +import org.gradle.internal.exceptions.LocationAwareException +import org.gradle.internal.resource.UriTextResource +import org.jetbrains.kotlin.idea.scripting.gradle.importing.parsePositionFromException +import org.junit.Test +import java.io.File +import java.io.PrintWriter +import java.io.StringWriter +import java.lang.RuntimeException +import kotlin.test.assertEquals +import kotlin.test.assertNotNull + +class KotlinDslScriptModelTest { + @Test + fun testExceptionPositionParsing() { + val file = File(createTempDir("kotlinDslTest"), "build.gradle.kts") + val line = 10 + + val mockScriptSource = TextResourceScriptSource(UriTextResource("build file", file)) + val mockException = LocationAwareException(RuntimeException(), mockScriptSource, line) + val stringWriter = StringWriter() + mockException.printStackTrace(PrintWriter(stringWriter)) + + val fromException = parsePositionFromException(stringWriter.toString()) + assertNotNull(fromException, "Position should be parsed") + assertEquals(fromException.first, file.absolutePath, "Wrong file name parsed") + assertEquals(fromException.second.line, line, "Wrong line number parsed") + } +} \ No newline at end of file