REPL: Extract IDE-specific tests to a separate test set
This commit is contained in:
@@ -67,4 +67,6 @@ projectTest(taskName = "embeddableTest", parallel = true) {
|
|||||||
workingDir = rootDir
|
workingDir = rootDir
|
||||||
dependsOn(embeddableTestRuntime)
|
dependsOn(embeddableTestRuntime)
|
||||||
classpath = embeddableTestRuntime
|
classpath = embeddableTestRuntime
|
||||||
|
|
||||||
|
exclude("**/JvmReplIdeTest.class")
|
||||||
}
|
}
|
||||||
|
|||||||
+75
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 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.scripting.ide_services
|
||||||
|
|
||||||
|
import com.intellij.mock.MockApplication
|
||||||
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
import com.intellij.openapi.vfs.VirtualFileManager
|
||||||
|
import com.intellij.util.indexing.FileContentImpl
|
||||||
|
import junit.framework.TestCase
|
||||||
|
import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinClassFileDecompiler
|
||||||
|
import org.jetbrains.kotlin.analysis.decompiler.stub.file.ClsKotlinBinaryClassCache
|
||||||
|
import org.jetbrains.kotlin.analysis.decompiler.stub.file.FileAttributeService
|
||||||
|
import org.jetbrains.kotlin.analysis.decompiler.stub.files.DummyFileAttributeService
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
|
import org.jetbrains.kotlin.psi.stubs.KotlinClassStub
|
||||||
|
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmCompiledModuleInMemoryImpl
|
||||||
|
import org.jetbrains.kotlin.scripting.ide_services.test_util.JvmTestRepl
|
||||||
|
import org.jetbrains.kotlin.scripting.ide_services.test_util.checkCompile
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.io.path.ExperimentalPathApi
|
||||||
|
import kotlin.io.path.createTempDirectory
|
||||||
|
import kotlin.script.experimental.jvm.impl.KJvmCompiledModuleInMemory
|
||||||
|
import kotlin.script.experimental.util.get
|
||||||
|
|
||||||
|
// This test checks the functionality that works only in IDE
|
||||||
|
// and doesn't run with embeddableTest configuration
|
||||||
|
class JvmReplIdeTest : TestCase() {
|
||||||
|
fun testReplScriptClassFileDecompilation() {
|
||||||
|
JvmTestRepl()
|
||||||
|
.use { repl ->
|
||||||
|
val compiledSnippet = checkCompile(repl, "10 + 10")
|
||||||
|
val snippetValue = compiledSnippet.get()!!
|
||||||
|
|
||||||
|
val compiledModule = snippetValue.getCompiledModule() as KJvmCompiledModuleInMemoryImpl
|
||||||
|
val folder = saveCompiledOutput("repl-script-decompilation", compiledModule)
|
||||||
|
|
||||||
|
val scriptClassName = "Line_0_simplescript"
|
||||||
|
val fileUrl = "file://" + folder.resolve("$scriptClassName.class").invariantSeparatorsPath
|
||||||
|
val vFile = VirtualFileManager.getInstance().findFileByUrl(fileUrl)!!
|
||||||
|
val fileContent = FileContentImpl.createByContent(vFile, vFile.contentsToByteArray(false))
|
||||||
|
|
||||||
|
val application = ApplicationManager.getApplication() as MockApplication
|
||||||
|
KotlinCoreEnvironment.underApplicationLock {
|
||||||
|
registerDecompilerServices(application)
|
||||||
|
}
|
||||||
|
|
||||||
|
val fileStub = KotlinClassFileDecompiler().stubBuilder.buildFileStub(fileContent)!!
|
||||||
|
val childrenStubs = fileStub.childrenStubs
|
||||||
|
assertTrue(childrenStubs.any { it is KotlinClassStub && it.name == scriptClassName })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalPathApi::class)
|
||||||
|
companion object {
|
||||||
|
private val outputJarDir = createTempDirectory("temp-ide-services-ide-test")
|
||||||
|
|
||||||
|
private fun saveCompiledOutput(subfolder: String, module: KJvmCompiledModuleInMemory): File {
|
||||||
|
val folder = outputJarDir.resolve(subfolder).toFile()
|
||||||
|
module.compilerOutputFiles.forEach { (name, contents) ->
|
||||||
|
val file = folder.resolve(name)
|
||||||
|
file.parentFile.mkdirs()
|
||||||
|
file.writeBytes(contents)
|
||||||
|
}
|
||||||
|
return folder
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerDecompilerServices(application: MockApplication) {
|
||||||
|
application.registerService(FileAttributeService::class.java, DummyFileAttributeService)
|
||||||
|
application.registerService(ClsKotlinBinaryClassCache::class.java, ClsKotlinBinaryClassCache())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
-158
@@ -5,23 +5,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.scripting.ide_services
|
package org.jetbrains.kotlin.scripting.ide_services
|
||||||
|
|
||||||
import com.intellij.mock.MockApplication
|
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
|
||||||
import com.intellij.openapi.vfs.VirtualFileManager
|
|
||||||
import com.intellij.util.indexing.FileContentImpl
|
|
||||||
import junit.framework.TestCase
|
import junit.framework.TestCase
|
||||||
import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinClassFileDecompiler
|
|
||||||
import org.jetbrains.kotlin.analysis.decompiler.stub.file.ClsKotlinBinaryClassCache
|
|
||||||
import org.jetbrains.kotlin.analysis.decompiler.stub.file.FileAttributeService
|
|
||||||
import org.jetbrains.kotlin.analysis.decompiler.stub.files.DummyFileAttributeService
|
|
||||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocationWithRange
|
|
||||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||||
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
|
||||||
import org.jetbrains.kotlin.config.Services
|
import org.jetbrains.kotlin.config.Services
|
||||||
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmCompiledModuleInMemoryImpl
|
|
||||||
import org.jetbrains.kotlin.scripting.ide_services.test_util.*
|
import org.jetbrains.kotlin.scripting.ide_services.test_util.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.io.path.ExperimentalPathApi
|
import kotlin.io.path.ExperimentalPathApi
|
||||||
@@ -29,15 +18,11 @@ import kotlin.io.path.createTempDirectory
|
|||||||
import kotlin.io.path.invariantSeparatorsPathString
|
import kotlin.io.path.invariantSeparatorsPathString
|
||||||
import kotlin.reflect.full.isSubclassOf
|
import kotlin.reflect.full.isSubclassOf
|
||||||
import kotlin.script.experimental.api.*
|
import kotlin.script.experimental.api.*
|
||||||
import kotlin.script.experimental.jvm.impl.KJvmCompiledModuleInMemory
|
|
||||||
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
|
|
||||||
import kotlin.script.experimental.jvm.jvm
|
import kotlin.script.experimental.jvm.jvm
|
||||||
import kotlin.script.experimental.jvm.updateClasspath
|
import kotlin.script.experimental.jvm.updateClasspath
|
||||||
import kotlin.script.experimental.jvm.util.isError
|
import kotlin.script.experimental.jvm.util.isError
|
||||||
import kotlin.script.experimental.jvm.util.isIncomplete
|
import kotlin.script.experimental.jvm.util.isIncomplete
|
||||||
import kotlin.script.experimental.jvm.util.scriptCompilationClasspathFromContext
|
import kotlin.script.experimental.jvm.util.scriptCompilationClasspathFromContext
|
||||||
import kotlin.script.experimental.util.LinkedSnippet
|
|
||||||
import kotlin.script.experimental.util.get
|
|
||||||
|
|
||||||
// Adapted form GenericReplTest
|
// Adapted form GenericReplTest
|
||||||
|
|
||||||
@@ -353,28 +338,6 @@ class JvmIdeServicesTest : TestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testReplScriptClassFileDecompilation() {
|
|
||||||
JvmTestRepl()
|
|
||||||
.use { repl ->
|
|
||||||
val compiledSnippet = checkCompile(repl, "10 + 10")
|
|
||||||
val snippetValue = compiledSnippet.get()!!
|
|
||||||
|
|
||||||
val compiledModule = snippetValue.getCompiledModule() as KJvmCompiledModuleInMemoryImpl
|
|
||||||
val folder = saveCompiledOutput("repl-script-decompilation", compiledModule)
|
|
||||||
|
|
||||||
val vFile = VirtualFileManager.getInstance().findFileByNioPath(folder.resolve("Line_0_simplescript.class").toPath())!!
|
|
||||||
val fileContent = FileContentImpl.createByFile(vFile)
|
|
||||||
|
|
||||||
val application = ApplicationManager.getApplication() as MockApplication
|
|
||||||
KotlinCoreEnvironment.underApplicationLock {
|
|
||||||
registerDecompilerServices(application)
|
|
||||||
}
|
|
||||||
|
|
||||||
val fileStub = KotlinClassFileDecompiler().stubBuilder.buildFileStub(fileContent)
|
|
||||||
assertNotNull(fileStub)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalPathApi::class)
|
@OptIn(ExperimentalPathApi::class)
|
||||||
companion object {
|
companion object {
|
||||||
private const val MODULE_PATH = "plugins/scripting/scripting-ide-services-test"
|
private const val MODULE_PATH = "plugins/scripting/scripting-ide-services-test"
|
||||||
@@ -401,21 +364,6 @@ class JvmIdeServicesTest : TestCase() {
|
|||||||
|
|
||||||
return CliCompilationResult(exitCode, jarPath)
|
return CliCompilationResult(exitCode, jarPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveCompiledOutput(subfolder: String, module: KJvmCompiledModuleInMemory): File {
|
|
||||||
val folder = outputJarDir.resolve(subfolder).toFile()
|
|
||||||
module.compilerOutputFiles.forEach { (name, contents) ->
|
|
||||||
val file = folder.resolve(name)
|
|
||||||
file.parentFile.mkdirs()
|
|
||||||
file.writeBytes(contents)
|
|
||||||
}
|
|
||||||
return folder
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun registerDecompilerServices(application: MockApplication) {
|
|
||||||
application.registerService(ClsKotlinBinaryClassCache::class.java)
|
|
||||||
application.registerService(FileAttributeService::class.java, DummyFileAttributeService)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -472,109 +420,3 @@ class LegacyReplTestLong : TestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JvmTestRepl.compileAndEval(codeLine: SourceCode): Pair<ResultWithDiagnostics<LinkedSnippet<out CompiledSnippet>>, EvaluatedSnippet?> {
|
|
||||||
|
|
||||||
val compRes = compile(codeLine)
|
|
||||||
|
|
||||||
val evalRes = compRes.valueOrNull()?.let {
|
|
||||||
eval(it)
|
|
||||||
}
|
|
||||||
return compRes to evalRes?.valueOrNull().get()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun assertCompileFails(
|
|
||||||
repl: JvmTestRepl,
|
|
||||||
@Suppress("SameParameterValue")
|
|
||||||
line: String
|
|
||||||
) {
|
|
||||||
val compiledSnippet =
|
|
||||||
checkCompile(repl, line)
|
|
||||||
|
|
||||||
TestCase.assertNull(compiledSnippet)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun assertEvalUnit(
|
|
||||||
repl: JvmTestRepl,
|
|
||||||
@Suppress("SameParameterValue")
|
|
||||||
line: String
|
|
||||||
) {
|
|
||||||
val compiledSnippet =
|
|
||||||
checkCompile(repl, line)
|
|
||||||
|
|
||||||
val evalResult = repl.eval(compiledSnippet!!)
|
|
||||||
val valueResult = evalResult.valueOrNull().get()
|
|
||||||
|
|
||||||
TestCase.assertNotNull("Unexpected eval result: $evalResult", valueResult)
|
|
||||||
TestCase.assertTrue(valueResult!!.result is ResultValue.Unit)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <R> assertEvalResult(repl: JvmTestRepl, line: String, expectedResult: R) {
|
|
||||||
val compiledSnippet =
|
|
||||||
checkCompile(repl, line)
|
|
||||||
|
|
||||||
val evalResult = repl.eval(compiledSnippet!!)
|
|
||||||
val valueResult = evalResult.valueOrNull().get()
|
|
||||||
|
|
||||||
TestCase.assertNotNull("Unexpected eval result: $evalResult", valueResult)
|
|
||||||
TestCase.assertTrue(valueResult!!.result is ResultValue.Value)
|
|
||||||
TestCase.assertEquals(expectedResult, (valueResult.result as ResultValue.Value).value)
|
|
||||||
}
|
|
||||||
|
|
||||||
private inline fun <reified R> assertEvalResultIs(repl: JvmTestRepl, line: String) {
|
|
||||||
val compiledSnippet =
|
|
||||||
checkCompile(repl, line)
|
|
||||||
|
|
||||||
val evalResult = repl.eval(compiledSnippet!!)
|
|
||||||
val valueResult = evalResult.valueOrNull().get()
|
|
||||||
|
|
||||||
TestCase.assertNotNull("Unexpected eval result: $evalResult", valueResult)
|
|
||||||
TestCase.assertTrue(valueResult!!.result is ResultValue.Value)
|
|
||||||
TestCase.assertTrue((valueResult.result as ResultValue.Value).value is R)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkCompile(repl: JvmTestRepl, line: String): LinkedSnippet<KJvmCompiledScript>? {
|
|
||||||
val codeLine = repl.nextCodeLine(line)
|
|
||||||
val compileResult = repl.compile(codeLine)
|
|
||||||
return compileResult.valueOrNull()
|
|
||||||
}
|
|
||||||
|
|
||||||
private data class CompilationErrors(
|
|
||||||
val message: String,
|
|
||||||
val location: CompilerMessageLocationWithRange?
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun <T> ResultWithDiagnostics<T>.getErrors(): CompilationErrors =
|
|
||||||
CompilationErrors(
|
|
||||||
reports.joinToString("\n") { report ->
|
|
||||||
report.location?.let { loc ->
|
|
||||||
CompilerMessageLocationWithRange.create(
|
|
||||||
report.sourcePath,
|
|
||||||
loc.start.line,
|
|
||||||
loc.start.col,
|
|
||||||
loc.end?.line,
|
|
||||||
loc.end?.col,
|
|
||||||
null
|
|
||||||
)?.toString()?.let {
|
|
||||||
"$it "
|
|
||||||
}
|
|
||||||
}.orEmpty() + report.message
|
|
||||||
},
|
|
||||||
reports.firstOrNull {
|
|
||||||
when (it.severity) {
|
|
||||||
ScriptDiagnostic.Severity.ERROR -> true
|
|
||||||
ScriptDiagnostic.Severity.FATAL -> true
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
}?.let {
|
|
||||||
val loc = it.location ?: return@let null
|
|
||||||
CompilerMessageLocationWithRange.create(
|
|
||||||
it.sourcePath,
|
|
||||||
loc.start.line,
|
|
||||||
loc.start.col,
|
|
||||||
loc.end?.line,
|
|
||||||
loc.end?.col,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|||||||
+111
@@ -5,14 +5,18 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.scripting.ide_services.test_util
|
package org.jetbrains.kotlin.scripting.ide_services.test_util
|
||||||
|
|
||||||
|
import junit.framework.TestCase
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocationWithRange
|
||||||
import org.jetbrains.kotlin.scripting.ide_services.compiler.KJvmReplCompilerWithIdeServices
|
import org.jetbrains.kotlin.scripting.ide_services.compiler.KJvmReplCompilerWithIdeServices
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import kotlin.script.experimental.api.*
|
import kotlin.script.experimental.api.*
|
||||||
import kotlin.script.experimental.jvm.BasicJvmReplEvaluator
|
import kotlin.script.experimental.jvm.BasicJvmReplEvaluator
|
||||||
|
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
|
||||||
import kotlin.script.experimental.util.LinkedSnippet
|
import kotlin.script.experimental.util.LinkedSnippet
|
||||||
import kotlin.script.experimental.jvm.util.toSourceCodePosition
|
import kotlin.script.experimental.jvm.util.toSourceCodePosition
|
||||||
|
import kotlin.script.experimental.util.get
|
||||||
|
|
||||||
internal class JvmTestRepl (
|
internal class JvmTestRepl (
|
||||||
private val compileConfiguration: ScriptCompilationConfiguration = simpleScriptCompilationConfiguration,
|
private val compileConfiguration: ScriptCompilationConfiguration = simpleScriptCompilationConfiguration,
|
||||||
@@ -55,3 +59,110 @@ fun <T> ResultWithDiagnostics<Iterable<T>>.toList() = this.valueOrNull()?.toList
|
|||||||
|
|
||||||
@JvmName("sequenceToList")
|
@JvmName("sequenceToList")
|
||||||
fun <T> ResultWithDiagnostics<Sequence<T>>.toList() = this.valueOrNull()?.toList().orEmpty()
|
fun <T> ResultWithDiagnostics<Sequence<T>>.toList() = this.valueOrNull()?.toList().orEmpty()
|
||||||
|
|
||||||
|
internal fun JvmTestRepl.compileAndEval(codeLine: SourceCode): Pair<ResultWithDiagnostics<LinkedSnippet<out CompiledSnippet>>, EvaluatedSnippet?> {
|
||||||
|
|
||||||
|
val compRes = compile(codeLine)
|
||||||
|
|
||||||
|
val evalRes = compRes.valueOrNull()?.let {
|
||||||
|
eval(it)
|
||||||
|
}
|
||||||
|
return compRes to evalRes?.valueOrNull().get()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun assertCompileFails(
|
||||||
|
repl: JvmTestRepl,
|
||||||
|
@Suppress("SameParameterValue")
|
||||||
|
line: String
|
||||||
|
) {
|
||||||
|
val compiledSnippet =
|
||||||
|
checkCompile(repl, line)
|
||||||
|
|
||||||
|
TestCase.assertNull(compiledSnippet)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun assertEvalUnit(
|
||||||
|
repl: JvmTestRepl,
|
||||||
|
@Suppress("SameParameterValue")
|
||||||
|
line: String
|
||||||
|
) {
|
||||||
|
val compiledSnippet =
|
||||||
|
checkCompile(repl, line)
|
||||||
|
|
||||||
|
val evalResult = repl.eval(compiledSnippet!!)
|
||||||
|
val valueResult = evalResult.valueOrNull().get()
|
||||||
|
|
||||||
|
TestCase.assertNotNull("Unexpected eval result: $evalResult", valueResult)
|
||||||
|
TestCase.assertTrue(valueResult!!.result is ResultValue.Unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun <R> assertEvalResult(repl: JvmTestRepl, line: String, expectedResult: R) {
|
||||||
|
val compiledSnippet =
|
||||||
|
checkCompile(repl, line)
|
||||||
|
|
||||||
|
val evalResult = repl.eval(compiledSnippet!!)
|
||||||
|
val valueResult = evalResult.valueOrNull().get()
|
||||||
|
|
||||||
|
TestCase.assertNotNull("Unexpected eval result: $evalResult", valueResult)
|
||||||
|
TestCase.assertTrue(valueResult!!.result is ResultValue.Value)
|
||||||
|
TestCase.assertEquals(expectedResult, (valueResult.result as ResultValue.Value).value)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inline fun <reified R> assertEvalResultIs(repl: JvmTestRepl, line: String) {
|
||||||
|
val compiledSnippet =
|
||||||
|
checkCompile(repl, line)
|
||||||
|
|
||||||
|
val evalResult = repl.eval(compiledSnippet!!)
|
||||||
|
val valueResult = evalResult.valueOrNull().get()
|
||||||
|
|
||||||
|
TestCase.assertNotNull("Unexpected eval result: $evalResult", valueResult)
|
||||||
|
TestCase.assertTrue(valueResult!!.result is ResultValue.Value)
|
||||||
|
TestCase.assertTrue((valueResult.result as ResultValue.Value).value is R)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun checkCompile(repl: JvmTestRepl, line: String): LinkedSnippet<KJvmCompiledScript>? {
|
||||||
|
val codeLine = repl.nextCodeLine(line)
|
||||||
|
val compileResult = repl.compile(codeLine)
|
||||||
|
return compileResult.valueOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal data class CompilationErrors(
|
||||||
|
val message: String,
|
||||||
|
val location: CompilerMessageLocationWithRange?
|
||||||
|
)
|
||||||
|
|
||||||
|
internal fun <T> ResultWithDiagnostics<T>.getErrors(): CompilationErrors =
|
||||||
|
CompilationErrors(
|
||||||
|
reports.joinToString("\n") { report ->
|
||||||
|
report.location?.let { loc ->
|
||||||
|
CompilerMessageLocationWithRange.create(
|
||||||
|
report.sourcePath,
|
||||||
|
loc.start.line,
|
||||||
|
loc.start.col,
|
||||||
|
loc.end?.line,
|
||||||
|
loc.end?.col,
|
||||||
|
null
|
||||||
|
)?.toString()?.let {
|
||||||
|
"$it "
|
||||||
|
}
|
||||||
|
}.orEmpty() + report.message
|
||||||
|
},
|
||||||
|
reports.firstOrNull {
|
||||||
|
when (it.severity) {
|
||||||
|
ScriptDiagnostic.Severity.ERROR -> true
|
||||||
|
ScriptDiagnostic.Severity.FATAL -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}?.let {
|
||||||
|
val loc = it.location ?: return@let null
|
||||||
|
CompilerMessageLocationWithRange.create(
|
||||||
|
it.sourcePath,
|
||||||
|
loc.start.line,
|
||||||
|
loc.start.col,
|
||||||
|
loc.end?.line,
|
||||||
|
loc.end?.col,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user