diff --git a/utbot-framework-test/src/test/kotlin/org/utbot/sarif/SarifReportTest.kt b/utbot-framework-test/src/test/kotlin/org/utbot/sarif/SarifReportTest.kt index 44aa51e5f3..57835a16f9 100644 --- a/utbot-framework-test/src/test/kotlin/org/utbot/sarif/SarifReportTest.kt +++ b/utbot-framework-test/src/test/kotlin/org/utbot/sarif/SarifReportTest.kt @@ -72,7 +72,7 @@ class SarifReportTest { UtImplicitlyThrownException(NullPointerException(), false) ) Mockito.`when`(mockUtExecution.stateBefore.parameters).thenReturn(listOf()) - Mockito.`when`(mockUtExecution.path.lastOrNull()?.stmt?.javaSourceStartLineNumber).thenReturn(1337) + Mockito.`when`(mockUtExecution.coverage?.coveredInstructions?.lastOrNull()?.lineNumber).thenReturn(1337) Mockito.`when`(mockUtExecution.testMethodName).thenReturn("testMain_ThrowArithmeticException") val report = sarifReportMain.createReport() @@ -243,8 +243,8 @@ class SarifReportTest { Mockito.`when`(mockUtExecution2.result).thenReturn(UtImplicitlyThrownException(NullPointerException(), false)) // different locations - Mockito.`when`(mockUtExecution1.path.lastOrNull()?.stmt?.javaSourceStartLineNumber).thenReturn(11) - Mockito.`when`(mockUtExecution2.path.lastOrNull()?.stmt?.javaSourceStartLineNumber).thenReturn(22) + Mockito.`when`(mockUtExecution1.coverage?.coveredInstructions?.lastOrNull()?.lineNumber).thenReturn(11) + Mockito.`when`(mockUtExecution2.coverage?.coveredInstructions?.lastOrNull()?.lineNumber).thenReturn(22) val testSets = listOf( UtMethodTestSet(mockExecutableId, listOf(mockUtExecution1)), diff --git a/utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt b/utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt index 670e76e4f9..ad1a3d17a5 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt @@ -150,7 +150,7 @@ class SarifReport( if (classFqn == null) return listOf() val sourceRelativePath = sourceFinding.getSourceRelativePath(classFqn) - val startLine = getLastLineNumber(utExecution) ?: defaultLineNumber + val startLine = getLastLineNumber(utExecution, classFqn) ?: defaultLineNumber val sourceCode = sourceFinding.getSourceFile(classFqn)?.readText() ?: "" val sourceRegion = SarifRegion.withStartLine(sourceCode, startLine) return listOf( @@ -317,26 +317,25 @@ class SarifReport( } /** - * Returns the number of the last line in the execution path. + * Returns the number of the last line in the execution path which is located in the [classFqn]. */ - private fun getLastLineNumber(utExecution: UtExecution): Int? { - // if for some reason we can't extract the last line from the path - val lastCoveredInstruction = - utExecution.coverage?.coveredInstructions?.lastOrNull()?.lineNumber - - return if (utExecution is UtSymbolicExecution) { - val lastPathLine = try { - // path/fullPath might be empty when engine executes in another process - - // soot entities cannot be passed to the main process because kryo cannot deserialize them - utExecution.path.lastOrNull()?.stmt?.javaSourceStartLineNumber - } catch (t: Throwable) { - null - } - - lastPathLine ?: lastCoveredInstruction - } else { - lastCoveredInstruction + private fun getLastLineNumber(utExecution: UtExecution, classFqn: String): Int? { + val classFqnPath = classFqn.replace(".", "/") + val coveredInstructions = utExecution.coverage?.coveredInstructions + val lastCoveredInstruction = coveredInstructions?.lastOrNull { it.className == classFqnPath } + ?: coveredInstructions?.lastOrNull() + if (lastCoveredInstruction != null) + return lastCoveredInstruction.lineNumber + + // if for some reason we can't extract the last line from the coverage + val lastPathElementLineNumber = try { + // path/fullPath might be empty when engine executes in another process - + // soot entities cannot be passed to the main process because kryo cannot deserialize them + (utExecution as? UtSymbolicExecution)?.path?.lastOrNull()?.stmt?.javaSourceStartLineNumber + } catch (t: Throwable) { + null } + return lastPathElementLineNumber } private fun shouldProcessExecutionResult(result: UtExecutionResult): Boolean {