Scratch: implement compiling executor

This commit is contained in:
Natalia Selezneva
2018-01-19 11:54:31 +03:00
parent dda0b38fb9
commit 654890fac3
16 changed files with 529 additions and 47 deletions
@@ -735,7 +735,8 @@ fun main(args: Array<String>) {
}
testClass<AbstractScratchRunActionTest> {
model("scratch", extension = "kts")
model("scratch", extension = "kts", testMethod = "doCompilingTest", testClassName = "Compiling")
model("scratch", extension = "kts", testMethod = "doReplTest", testClassName = "Repl")
}
}
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.idea.scratch
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.idea.scratch.compile.KtCompilingExecutor
import org.jetbrains.kotlin.idea.scratch.output.InlayScratchOutputHandler
import org.jetbrains.kotlin.idea.scratch.repl.KtScratchReplExecutor
import org.jetbrains.kotlin.psi.KtFile
@@ -27,5 +28,7 @@ class KtScratchFileLanguageProvider : ScratchFileLanguageProvider() {
}
override fun createReplExecutor(file: ScratchFile) = KtScratchReplExecutor(file)
override fun createCompilingExecutor(file: ScratchFile) = KtCompilingExecutor(file)
override fun getOutputHandler() = InlayScratchOutputHandler
}
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.scratch.output.ScratchOutputHandler
abstract class ScratchFileLanguageProvider {
abstract fun createFile(psiFile: PsiFile): ScratchFile?
abstract fun createReplExecutor(file: ScratchFile): ScratchExecutor?
abstract fun createCompilingExecutor(file: ScratchFile): ScratchExecutor?
abstract fun getOutputHandler(): ScratchOutputHandler
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.idea.scratch.ScratchFile
import org.jetbrains.kotlin.idea.scratch.ScratchFileLanguageProvider
import org.jetbrains.kotlin.idea.scratch.getScratchPanelFromSelectedEditor
import org.jetbrains.kotlin.idea.scratch.output.ScratchOutputHandlerAdapter
import org.jetbrains.kotlin.idea.scratch.ui.scratchTopPanel
class RunScratchAction : AnAction(
KotlinBundle.message("scratch.run.button"),
@@ -38,7 +39,7 @@ class RunScratchAction : AnAction(
val scratchFile = scratchTopPanel.scratchFile
val isMakeBeforeRun = false // todo use property from panel
val isRepl = true //todo use property from panel
val isRepl = scratchTopPanel.isRepl()
val provider = ScratchFileLanguageProvider.get(scratchFile.psiFile.language) ?: return
@@ -52,9 +53,9 @@ class RunScratchAction : AnAction(
}
val runnable = r@ {
val executor = provider.createReplExecutor(scratchFile)
val executor = if (isRepl) provider.createReplExecutor(scratchFile) else provider.createCompilingExecutor(scratchFile)
if (executor == null) {
handler.error(scratchFile, "Couldn't run file using REPL")
handler.error(scratchFile, "Couldn't run ${scratchFile.psiFile.name}")
handler.onFinish(scratchFile)
return@r
}
@@ -0,0 +1,268 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.scratch.compile
import com.intellij.execution.configurations.GeneralCommandLine
import com.intellij.execution.process.CapturingProcessHandler
import com.intellij.execution.process.ProcessOutput
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.compiler.ex.CompilerPathsEx
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.module.Module
import com.intellij.openapi.roots.OrderEnumerator
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
import org.jetbrains.kotlin.codegen.CompilationErrorHandler
import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
import org.jetbrains.kotlin.codegen.filterClassFiles
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.console.KotlinConsoleKeeper
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.debugger.DebuggerUtils
import org.jetbrains.kotlin.idea.refactoring.getLineNumber
import org.jetbrains.kotlin.idea.scratch.ScratchExecutor
import org.jetbrains.kotlin.idea.scratch.ScratchExpression
import org.jetbrains.kotlin.idea.scratch.ScratchFile
import org.jetbrains.kotlin.idea.scratch.output.ScratchOutput
import org.jetbrains.kotlin.idea.scratch.output.ScratchOutputType
import org.jetbrains.kotlin.idea.scratch.ui.scratchTopPanel
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.KtScript
import org.jetbrains.kotlin.resolve.AnalyzingUtils
import java.io.File
class KtCompilingExecutor(file: ScratchFile) : ScratchExecutor(file) {
private val log = Logger.getInstance(this.javaClass)
override fun execute() {
handlers.forEach { it.onStart(file) }
val module = file.scratchTopPanel?.getModule() ?: return error("Module should be selected")
if (!checkForErrors(file.psiFile as KtFile)) {
return error("Compilation Error")
}
val result = KtScratchSourceFileProcessor().process(file)
when (result) {
is KtScratchSourceFileProcessor.Result.Error -> return error(result.message)
is KtScratchSourceFileProcessor.Result.OK -> {
ApplicationManager.getApplication().invokeLater {
val modifiedScratchSourceFile =
KtPsiFactory(file.psiFile.project).createFileWithLightClassSupport("tmp.kt", result.code, file.psiFile)
try {
val tempDir = compileFileToTempDir(modifiedScratchSourceFile) ?: return@invokeLater
try {
val handler = CapturingProcessHandler(createCommandLine(module, result.mainClassName, tempDir.path))
ProcessOutputParser().parse(handler.runProcess())
} finally {
tempDir.delete()
}
} catch (e: Throwable) {
log.info(result.code, e)
handlers.forEach { it.error(file, e.message ?: "Couldn't compile ${file.psiFile.name}") }
} finally {
handlers.forEach { it.onFinish(file) }
}
}
}
}
}
private fun compileFileToTempDir(psiFile: KtFile): File? {
if (!checkForErrors(psiFile)) return null
val resolutionFacade = psiFile.getResolutionFacade()
val (bindingContext, files) = DebuggerUtils.analyzeInlinedFunctions(resolutionFacade, psiFile, false)
val generateClassFilter = object : GenerationState.GenerateClassFilter() {
override fun shouldGeneratePackagePart(ktFile: KtFile) = ktFile == psiFile
override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject) = true
override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject) = processingClassOrObject.containingKtFile == psiFile
override fun shouldGenerateScript(script: KtScript) = false
}
val state = GenerationState.Builder(
file.psiFile.project,
ClassBuilderFactories.binaries(false),
resolutionFacade.moduleDescriptor,
bindingContext,
files,
CompilerConfiguration.EMPTY
).generateDeclaredClassFilter(generateClassFilter).build()
KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION)
return writeClassFilesToTempDir(state)
}
private fun writeClassFilesToTempDir(state: GenerationState): File {
val classFiles = state.factory.asList().filterClassFiles()
val dir = FileUtil.createTempDirectory("compile", "scratch")
for (classFile in classFiles) {
val tmpOutFile = File(dir, classFile.relativePath)
tmpOutFile.parentFile.mkdirs()
tmpOutFile.createNewFile()
tmpOutFile.writeBytes(classFile.asByteArray())
}
return dir
}
private fun createCommandLine(module: Module, mainClassName: String, tempOutDir: String): GeneralCommandLine {
val javaParameters = KotlinConsoleKeeper.createJavaParametersWithSdk(module)
javaParameters.mainClass = mainClassName
val compiledModulePath = CompilerPathsEx.getOutputPaths(arrayOf(module)).toList()
val moduleDependencies = OrderEnumerator.orderEntries(module).recursively().pathsList.pathList
javaParameters.classPath.add(tempOutDir)
javaParameters.classPath.addAll(compiledModulePath)
javaParameters.classPath.addAll(moduleDependencies)
return javaParameters.toCommandLine()
}
private fun checkForErrors(psiFile: KtFile): Boolean {
return runReadAction {
try {
AnalyzingUtils.checkForSyntacticErrors(psiFile)
} catch (e: IllegalArgumentException) {
handlers.forEach { it.error(file, e.message ?: "Couldn't compile ${psiFile.name}") }
return@runReadAction false
}
val analysisResult = psiFile.analyzeFullyAndGetResult()
if (analysisResult.isError()) {
handlers.forEach { it.error(file, analysisResult.error.message ?: "Couldn't compile ${psiFile.name}") }
return@runReadAction false
}
val bindingContext = analysisResult.bindingContext
val diagnostics = bindingContext.diagnostics.filter { it.severity == Severity.ERROR }
if (diagnostics.isNotEmpty()) {
diagnostics.forEach { diagnostic ->
if (diagnostic.psiElement.containingFile == psiFile) {
val scratchExpression = file.findExpression(
diagnostic.psiElement.getLineNumber(true),
diagnostic.psiElement.getLineNumber(false)
)
handlers.forEach {
it.handle(
file,
scratchExpression,
ScratchOutput(DefaultErrorMessages.render(diagnostic), ScratchOutputType.ERROR)
)
}
}
}
return@runReadAction false
}
return@runReadAction true
}
}
private fun error(message: String) {
handlers.forEach { it.error(file, message) }
handlers.forEach { it.onFinish(file) }
}
private fun ScratchFile.findExpression(lineStart: Int, lineEnd: Int): ScratchExpression {
return getExpressions().first { it.lineStart == lineStart && it.lineEnd == lineEnd }
}
private inner class ProcessOutputParser {
fun parse(processOutput: ProcessOutput) {
val out = processOutput.stdout
val err = processOutput.stderr
if (err.isNotBlank()) {
handlers.forEach { it.error(file, err) }
}
if (out.isNotBlank()) {
parseStdOut(out)
}
}
private fun parseStdOut(out: String) {
var results = arrayListOf<String>()
var userOutput = arrayListOf<String>()
for (line in out.split("\n")) {
if (isOutputEnd(line)) {
return
}
if (isGeneratedOutput(line)) {
val lineWoPrefix = line.removePrefix(KtScratchSourceFileProcessor.GENERATED_OUTPUT_PREFIX)
if (isResultEnd(lineWoPrefix)) {
val (startLine, endLine) = extractLineInfoFrom(lineWoPrefix)
?: return error("Couldn't extract line info from line: $lineWoPrefix")
val scratchExpression = file.findExpression(startLine, endLine)
userOutput.forEach { output ->
handlers.forEach {
it.handle(file, scratchExpression, ScratchOutput(output, ScratchOutputType.OUTPUT))
}
}
results.forEach { result ->
handlers.forEach {
it.handle(file, scratchExpression, ScratchOutput(result, ScratchOutputType.RESULT))
}
}
results = arrayListOf()
userOutput = arrayListOf()
} else if (lineWoPrefix != Unit.toString()) {
results.add(lineWoPrefix)
}
} else {
userOutput.add(line)
}
}
}
private fun isOutputEnd(line: String) = line.removeSuffix("\n") == KtScratchSourceFileProcessor.END_OUTPUT_MARKER
private fun isResultEnd(line: String) = line.startsWith(KtScratchSourceFileProcessor.LINES_INFO_MARKER)
private fun isGeneratedOutput(line: String) = line.startsWith(KtScratchSourceFileProcessor.GENERATED_OUTPUT_PREFIX)
private fun extractLineInfoFrom(encoded: String): Pair<Int, Int>? {
val lineInfo = encoded
.removePrefix(KtScratchSourceFileProcessor.LINES_INFO_MARKER)
.removeSuffix("\n")
.split('|')
if (lineInfo.size == 2) {
try {
val (a, b) = lineInfo[0].toInt() to lineInfo[1].toInt()
if (a > -1 && b > -1) {
return a to b
}
} catch (e: NumberFormatException) {
}
}
return null
}
}
}
@@ -0,0 +1,117 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.scratch.compile
import org.jetbrains.kotlin.diagnostics.rendering.Renderers
import org.jetbrains.kotlin.diagnostics.rendering.RenderingContext
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.scratch.ScratchExpression
import org.jetbrains.kotlin.idea.scratch.ScratchFile
import org.jetbrains.kotlin.psi.*
class KtScratchSourceFileProcessor {
companion object {
const val GENERATED_OUTPUT_PREFIX = "##scratch##generated##"
const val LINES_INFO_MARKER = "end##"
const val END_OUTPUT_MARKER = "end##!@#%^&*"
const val OBJECT_NAME = "ScratchFileRunnerGenerated"
const val INSTANCE_NAME = "instanceScratchFileRunner"
const val PACKAGE_NAME = "org.jetbrains.kotlin.idea.scratch.generated"
const val GET_RES_FUN_NAME_PREFIX = "generated_get_instance_res"
}
fun process(file: ScratchFile): Result {
val sourceProcessor = KtSourceProcessor()
file.getExpressions().forEach {
sourceProcessor.process(it)
}
val codeResult =
"""
package $PACKAGE_NAME
${sourceProcessor.imports.joinToString("\n") { it.text }}
object $OBJECT_NAME {
class $OBJECT_NAME {
${sourceProcessor.classBuilder}
}
@JvmStatic fun main(args: Array<String>) {
val $INSTANCE_NAME = $OBJECT_NAME()
${sourceProcessor.objectBuilder}
println("$END_OUTPUT_MARKER")
}
}
"""
return Result.OK("$PACKAGE_NAME.$OBJECT_NAME", codeResult)
}
class KtSourceProcessor {
val classBuilder = StringBuilder()
val objectBuilder = StringBuilder()
val imports = arrayListOf<KtImportDirective>()
private var resCount = 0
fun process(expression: ScratchExpression) {
val psiElement = expression.element
when (psiElement) {
is KtVariableDeclaration -> processDeclaration(expression, psiElement)
is KtFunction -> processDeclaration(expression, psiElement)
is KtClassOrObject -> processDeclaration(expression, psiElement)
is KtImportDirective -> imports.add(psiElement)
is KtExpression -> processExpression(expression, psiElement)
}
}
private fun processDeclaration(e: ScratchExpression, c: KtDeclaration) {
classBuilder.append(c.text).newLine()
val descriptor = c.resolveToDescriptorIfAny() ?: return
val context = RenderingContext.of(descriptor)
objectBuilder.println(Renderers.COMPACT.render(descriptor, context))
objectBuilder.appendLineInfo(e)
}
private fun processExpression(e: ScratchExpression, expr: KtExpression) {
val resName = "$GET_RES_FUN_NAME_PREFIX$resCount"
classBuilder.append("fun $resName() = run { ${expr.text} }").newLine()
objectBuilder.printlnObj("$INSTANCE_NAME.$resName()")
objectBuilder.appendLineInfo(e)
resCount += 1
}
private fun StringBuilder.appendLineInfo(e: ScratchExpression) {
println("$LINES_INFO_MARKER${e.lineStart}|${e.lineEnd}")
}
private fun StringBuilder.println(str: String) = append("println(\"$GENERATED_OUTPUT_PREFIX$str\")").newLine()
private fun StringBuilder.printlnObj(str: String) = append("println(\"$GENERATED_OUTPUT_PREFIX\${$str}\")").newLine()
private fun StringBuilder.newLine() = append("\n")
}
sealed class Result {
class Error(val message: String) : Result()
class OK(val mainClassName: String, val code: String) : Result()
}
}
@@ -27,15 +27,13 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiManager
import com.intellij.ui.components.panels.HorizontalLayout
import com.intellij.uiDesigner.core.Spacer
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.idea.scratch.ScratchFile
import org.jetbrains.kotlin.idea.scratch.ScratchFileLanguageProvider
import org.jetbrains.kotlin.idea.scratch.actions.ClearScratchAction
import org.jetbrains.kotlin.idea.scratch.actions.RunScratchAction
import org.jetbrains.kotlin.idea.scratch.getScratchPanel
import javax.swing.JComponent
import javax.swing.JLabel
import javax.swing.JPanel
import javax.swing.JSeparator
import javax.swing.*
val ScratchFile.scratchTopPanel: ScratchTopPanel?
get() = getScratchPanel(psiFile)?.takeIf { it.scratchFile == this@scratchTopPanel }
@@ -50,10 +48,14 @@ class ScratchTopPanel private constructor(val scratchFile: ScratchFile) : JPanel
}
private val moduleChooser: ModulesComboBox
private val isReplCheckbox: JCheckBox
init {
add(createActionsToolbar())
add(JSeparator())
isReplCheckbox = JCheckBox("Use Repl", false)
add(isReplCheckbox)
add(JSeparator())
add(JLabel("Use classpath of module: "))
moduleChooser = createModuleChooser(scratchFile.psiFile.project)
add(moduleChooser)
@@ -68,6 +70,13 @@ class ScratchTopPanel private constructor(val scratchFile: ScratchFile) : JPanel
}
}
fun isRepl() = isReplCheckbox.isEnabled
@TestOnly
fun setReplMode(isEnabled: Boolean) {
isReplCheckbox.isEnabled = isEnabled
}
private fun createActionsToolbar(): JComponent {
val toolbarGroup = DefaultActionGroup().apply {
add(RunScratchAction())
@@ -85,7 +85,7 @@ class KotlinConsoleKeeper(val project: Project) {
return commandLine
}
private fun createJavaParametersWithSdk(module: Module): JavaParameters {
fun createJavaParametersWithSdk(module: Module): JavaParameters {
val params = JavaParameters()
params.charset = null
+7
View File
@@ -0,0 +1,7 @@
package myTest;
public class MyJavaClass {
public int test() {
return 1;
}
}
+3
View File
@@ -0,0 +1,3 @@
for (i in 0..5) { // OUTPUT: 0; 1; 2; 3; 4; 5
println(i)
}
+2
View File
@@ -0,0 +1,2 @@
val a = 1 // RESULT: val a: Int
a // RESULT: 1
+5
View File
@@ -0,0 +1,5 @@
fun foo(): Int { // RESULT: fun foo(): Int
return 1
}
foo() // RESULT: 1
+1
View File
@@ -0,0 +1 @@
foo() // ERROR: Unresolved reference: foo
+1
View File
@@ -0,0 +1 @@
println("hello") // OUTPUT: hello
@@ -32,12 +32,22 @@ import com.intellij.util.ui.UIUtil
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.scratch.actions.RunScratchAction
import org.jetbrains.kotlin.idea.scratch.output.InlayScratchOutputHandler
import org.jetbrains.kotlin.idea.scratch.ui.scratchTopPanel
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.junit.Assert
import java.io.File
abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
fun doTest(fileName: String) {
fun doReplTest(fileName: String) {
doTest(fileName, true)
}
fun doCompilingTest(fileName: String) {
doTest(fileName, false)
}
fun doTest(fileName: String, isRepl: Boolean) {
val sourceFile = File(testDataPath, fileName)
val fileText = sourceFile.readText()
@@ -51,9 +61,13 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
myFixture.openFileInEditor(scratchFile)
ScratchFileLanguageProvider.createFile(myFixture.file)?.scratchTopPanel?.setReplMode(isRepl)
val event = getActionEvent(myFixture.file.virtualFile, RunScratchAction())
launchAction(event, RunScratchAction())
UIUtil.dispatchAllInvocationEvents()
val start = System.currentTimeMillis()
// wait until output is displayed in editor or for 1 minute
while (!event.presentation.isEnabled && (System.currentTimeMillis() - start) < 60000) {
@@ -62,9 +76,8 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
UIUtil.dispatchAllInvocationEvents()
val editors = FileEditorManager.getInstance(project).getEditors(myFixture.file.virtualFile).filterIsInstance<TextEditor>()
val doc =
PsiDocumentManager.getInstance(project).getDocument(myFixture.file) ?: error("Document for ${myFixture.file.name} is null")
val editors = FileEditorManager.getInstance(project).getEditors(scratchFile).filterIsInstance<TextEditor>()
val doc = PsiDocumentManager.getInstance(project).getDocument(myFixture.file) ?: error("Document for ${myFixture.file.name} is null")
val actualOutput = StringBuilder(myFixture.file.text)
for (line in doc.lineCount - 1 downTo 0) {
@@ -79,7 +92,7 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
}
}
val expectedFileName = fileName.replace(".kts", ".repl.after")
val expectedFileName = if (isRepl) fileName.replace(".kts", ".repl.after") else fileName.replace(".kts", ".comp.after")
val expectedFile = File("$testDataPath/$expectedFileName")
KotlinTestUtils.assertEqualsToFile(expectedFile, actualOutput.toString())
}
@@ -98,4 +111,6 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
}
override fun getTestDataPath() = KotlinTestUtils.getHomeDirectory()
override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_FULL_JDK
}
@@ -17,47 +17,95 @@ import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("idea/testData/scratch")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class ScratchRunActionTestGenerated extends AbstractScratchRunActionTest {
public void testAllFilesPresentInScratch() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/scratch"), Pattern.compile("^(.+)\\.kts$"), TargetBackend.ANY, true);
@TestMetadata("idea/testData/scratch")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Compiling extends AbstractScratchRunActionTest {
public void testAllFilesPresentInCompiling() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/scratch"), Pattern.compile("^(.+)\\.kts$"), TargetBackend.ANY, true);
}
@TestMetadata("for.kts")
public void testFor() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/for.kts");
doCompilingTest(fileName);
}
@TestMetadata("simple.kts")
public void testSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/simple.kts");
doCompilingTest(fileName);
}
@TestMetadata("simpleFun.kts")
public void testSimpleFun() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/simpleFun.kts");
doCompilingTest(fileName);
}
@TestMetadata("stdlibFun.kts")
public void testStdlibFun() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/stdlibFun.kts");
doCompilingTest(fileName);
}
@TestMetadata("unresolved.kts")
public void testUnresolved() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/unresolved.kts");
doCompilingTest(fileName);
}
@TestMetadata("userOutput.kts")
public void testUserOutput() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/userOutput.kts");
doCompilingTest(fileName);
}
}
@TestMetadata("for.kts")
public void testFor() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/for.kts");
doTest(fileName);
}
@TestMetadata("idea/testData/scratch")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Repl extends AbstractScratchRunActionTest {
public void testAllFilesPresentInRepl() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/scratch"), Pattern.compile("^(.+)\\.kts$"), TargetBackend.ANY, true);
}
@TestMetadata("simple.kts")
public void testSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/simple.kts");
doTest(fileName);
}
@TestMetadata("for.kts")
public void testFor() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/for.kts");
doReplTest(fileName);
}
@TestMetadata("simpleFun.kts")
public void testSimpleFun() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/simpleFun.kts");
doTest(fileName);
}
@TestMetadata("simple.kts")
public void testSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/simple.kts");
doReplTest(fileName);
}
@TestMetadata("stdlibFun.kts")
public void testStdlibFun() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/stdlibFun.kts");
doTest(fileName);
}
@TestMetadata("simpleFun.kts")
public void testSimpleFun() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/simpleFun.kts");
doReplTest(fileName);
}
@TestMetadata("unresolved.kts")
public void testUnresolved() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/unresolved.kts");
doTest(fileName);
}
@TestMetadata("stdlibFun.kts")
public void testStdlibFun() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/stdlibFun.kts");
doReplTest(fileName);
}
@TestMetadata("userOutput.kts")
public void testUserOutput() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/userOutput.kts");
doTest(fileName);
@TestMetadata("unresolved.kts")
public void testUnresolved() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/unresolved.kts");
doReplTest(fileName);
}
@TestMetadata("userOutput.kts")
public void testUserOutput() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/scratch/userOutput.kts");
doReplTest(fileName);
}
}
}