diff options
Diffstat (limited to 'plugins/kotlin/jps/jps-plugin/tests/test/org/jetbrains/kotlin/jps/build/AbstractLookupTrackerTest.kt')
-rw-r--r-- | plugins/kotlin/jps/jps-plugin/tests/test/org/jetbrains/kotlin/jps/build/AbstractLookupTrackerTest.kt | 357 |
1 files changed, 0 insertions, 357 deletions
diff --git a/plugins/kotlin/jps/jps-plugin/tests/test/org/jetbrains/kotlin/jps/build/AbstractLookupTrackerTest.kt b/plugins/kotlin/jps/jps-plugin/tests/test/org/jetbrains/kotlin/jps/build/AbstractLookupTrackerTest.kt deleted file mode 100644 index 449345f46ffe..000000000000 --- a/plugins/kotlin/jps/jps-plugin/tests/test/org/jetbrains/kotlin/jps/build/AbstractLookupTrackerTest.kt +++ /dev/null @@ -1,357 +0,0 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - -package org.jetbrains.kotlin.jps.build - -import com.intellij.testFramework.UsefulTestCase -import com.intellij.util.ThrowableRunnable -import com.intellij.util.containers.StringInterner -import org.jetbrains.kotlin.TestWithWorkingDir -import org.jetbrains.kotlin.build.JvmSourceRoot -import org.jetbrains.kotlin.cli.common.ExitCode -import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments -import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler -import org.jetbrains.kotlin.compilerRunner.* -import org.jetbrains.kotlin.config.Services -import org.jetbrains.kotlin.idea.artifacts.KotlinArtifacts -import org.jetbrains.kotlin.idea.test.runAll -import org.jetbrains.kotlin.incremental.components.LookupInfo -import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.incremental.components.Position -import org.jetbrains.kotlin.incremental.components.ScopeKind -import org.jetbrains.kotlin.incremental.isKotlinFile -import org.jetbrains.kotlin.incremental.js.* -import org.jetbrains.kotlin.incremental.makeModuleFile -import org.jetbrains.kotlin.incremental.testingUtils.TouchPolicy -import org.jetbrains.kotlin.incremental.testingUtils.copyTestSources -import org.jetbrains.kotlin.incremental.testingUtils.getModificationsToPerform -import org.jetbrains.kotlin.incremental.utils.TestMessageCollector -import org.jetbrains.kotlin.jps.build.fixtures.EnableICFixture -import org.jetbrains.kotlin.jps.incremental.createTestingCompilerEnvironment -import org.jetbrains.kotlin.jps.incremental.runJSCompiler -import org.jetbrains.kotlin.idea.test.KotlinTestUtils -import org.jetbrains.kotlin.utils.JsMetadataVersion -import java.io.* -import java.util.* - -abstract class AbstractJvmLookupTrackerTest : AbstractLookupTrackerTest() { - - private val sourceToOutputMapping = hashMapOf<File, MutableSet<File>>() - - override fun setUp() { - super.setUp() - sourceToOutputMapping.clear() - } - - override fun markDirty(removedAndModifiedSources: Iterable<File>) { - for (sourceFile in removedAndModifiedSources) { - val outputs = sourceToOutputMapping.remove(sourceFile) ?: continue - for (output in outputs) { - output.delete() - } - } - } - - override fun processCompilationResults(outputItemsCollector: OutputItemsCollectorImpl, services: Services) { - for ((sourceFiles, outputFile) in outputItemsCollector.outputs) { - if (outputFile.extension == "kotlin_module") continue - - for (sourceFile in sourceFiles) { - val outputsForSource = sourceToOutputMapping.getOrPut(sourceFile) { hashSetOf() } - outputsForSource.add(outputFile) - } - } - } - - override fun runCompiler(filesToCompile: Iterable<File>, env: JpsCompilerEnvironment): Any? { - val moduleFile = makeModuleFile( - name = "test", - isTest = true, - outputDir = outDir, - sourcesToCompile = filesToCompile.toList(), - commonSources = emptyList(), - javaSourceRoots = listOf(JvmSourceRoot(srcDir, null)), - classpath = listOf(outDir, KotlinArtifacts.instance.kotlinStdlib).filter { it.exists() }, - friendDirs = emptyList() - ) - - val args = K2JVMCompilerArguments().apply { - disableDefaultScriptingPlugin = true - buildFile = moduleFile.canonicalPath - reportOutputFiles = true - } - val argsArray = ArgumentUtils.convertArgumentsToStringList(args).toTypedArray() - - try { - val stream = ByteArrayOutputStream() - val out = PrintStream(stream) - val exitCode = CompilerRunnerUtil.invokeExecMethod(K2JVMCompiler::class.java.name, argsArray, env, out) - val reader = BufferedReader(StringReader(stream.toString())) - CompilerOutputParser.parseCompilerMessagesFromReader(env.messageCollector, reader, env.outputItemsCollector) - - return exitCode - } - finally { - moduleFile.delete() - } - } -} - -abstract class AbstractJsKlibLookupTrackerTest : AbstractJsLookupTrackerTest() { - override val jsStdlibFile: File - get() = KotlinArtifacts.instance.kotlinStdlibJs - - override fun configureAdditionalArgs(args: K2JSCompilerArguments) { - args.irProduceKlibDir = true - args.irOnly = true - args.outputFile = outDir.resolve("out.klib").absolutePath - } -} - -abstract class AbstractJsLookupTrackerTest : AbstractLookupTrackerTest() { - private var header: ByteArray? = null - private val packageParts: MutableMap<File, TranslationResultValue> = hashMapOf() - private val serializedIrFiles: MutableMap<File, IrTranslationResultValue> = hashMapOf() - - override fun setUp() { - super.setUp() - header = null - packageParts.clear() - serializedIrFiles.clear() - } - - override fun Services.Builder.registerAdditionalServices() { - if (header != null) { - register( - IncrementalDataProvider::class.java, - IncrementalDataProviderImpl( - headerMetadata = header!!, - compiledPackageParts = packageParts, - metadataVersion = JsMetadataVersion.INSTANCE.toArray(), - packageMetadata = emptyMap(), // TODO pass correct metadata - serializedIrFiles = serializedIrFiles - ) - ) - } - - register(IncrementalResultsConsumer::class.java, IncrementalResultsConsumerImpl()) - } - - override fun markDirty(removedAndModifiedSources: Iterable<File>) { - removedAndModifiedSources.forEach { - packageParts.remove(it) - serializedIrFiles.remove(it) - } - } - - override fun processCompilationResults(outputItemsCollector: OutputItemsCollectorImpl, services: Services) { - val incrementalResults = services.get(IncrementalResultsConsumer::class.java) as IncrementalResultsConsumerImpl - header = incrementalResults.headerMetadata - packageParts.putAll(incrementalResults.packageParts) - serializedIrFiles.putAll(incrementalResults.irFileData) - } - - protected open val jsStdlibFile: File - get() = KotlinArtifacts.instance.kotlinStdlibJs - - protected open fun configureAdditionalArgs(args: K2JSCompilerArguments) { - args.outputFile = File(outDir, "out.js").canonicalPath - } - - override fun runCompiler(filesToCompile: Iterable<File>, env: JpsCompilerEnvironment): Any? { - val args = K2JSCompilerArguments().apply { - val libPaths = arrayListOf(jsStdlibFile.absolutePath) + (libraries ?: "").split(File.pathSeparator) - libraries = libPaths.joinToString(File.pathSeparator) - reportOutputFiles = true - freeArgs = filesToCompile.map { it.canonicalPath } - } - configureAdditionalArgs(args) - return runJSCompiler(args, env) - } -} - -abstract class AbstractLookupTrackerTest : TestWithWorkingDir() { - private val DECLARATION_KEYWORDS = listOf("interface", "class", "enum class", "object", "fun", "operator fun", "val", "var") - private val DECLARATION_STARTS_WITH = DECLARATION_KEYWORDS.map { it + " " } - // ignore KDoc like comments which starts with `/**`, example: /** text */ - private val COMMENT_WITH_LOOKUP_INFO = "/\\*[^*]+\\*/".toRegex() - - protected lateinit var srcDir: File - protected lateinit var outDir: File - private val enableICFixture = EnableICFixture() - - override fun setUp() { - super.setUp() - srcDir = File(workingDir, "src").apply { mkdirs() } - outDir = File(workingDir, "out") - enableICFixture.setUp() - } - - override fun tearDown() { - runAll( - ThrowableRunnable { enableICFixture.tearDown() }, - ThrowableRunnable { super.tearDown() } - ) - } - - protected abstract fun markDirty(removedAndModifiedSources: Iterable<File>) - protected abstract fun processCompilationResults(outputItemsCollector: OutputItemsCollectorImpl, services: Services) - protected abstract fun runCompiler(filesToCompile: Iterable<File>, env: JpsCompilerEnvironment): Any? - - fun doTest(path: String) { - val sb = StringBuilder() - fun StringBuilder.indentln(string: String) { - appendLine(" $string") - } - fun CompilerOutput.logOutput(stepName: String) { - sb.appendLine("==== $stepName ====") - - sb.appendLine("Compiling files:") - for (compiledFile in compiledFiles.sortedBy { it.canonicalPath }) { - val lookupsFromFile = lookups[compiledFile] - val lookupStatus = when { - lookupsFromFile == null -> "(unknown)" - lookupsFromFile.isEmpty() -> "(no lookups)" - else -> "" - } - val relativePath = compiledFile.toRelativeString(workingDir).replace("\\", "/") - sb.indentln("$relativePath$lookupStatus") - } - - sb.appendLine("Exit code: $exitCode") - errors.forEach(sb::indentln) - - sb.appendLine() - } - - val testDir = File(path) - val workToOriginalFileMap = HashMap(copyTestSources(testDir, srcDir, filePrefix = "")) - var dirtyFiles = srcDir.walk().filterTo(HashSet()) { it.isKotlinFile(listOf("kt", "kts")) } - val steps = getModificationsToPerform(testDir, moduleNames = null, allowNoFilesWithSuffixInTestData = true, touchPolicy = TouchPolicy.CHECKSUM) - .filter { it.isNotEmpty() } - - val filesToLookups = arrayListOf<Map<File, List<LookupInfo>>>() - fun CompilerOutput.originalFilesToLookups() = - compiledFiles.associateBy({ workToOriginalFileMap[it]!! }, { lookups[it] ?: emptyList() }) - - make(dirtyFiles).apply { - logOutput("INITIAL BUILD") - filesToLookups.add(originalFilesToLookups()) - - } - for ((i, modifications) in steps.withIndex()) { - dirtyFiles = modifications.mapNotNullTo(HashSet()) { it.perform(workingDir, workToOriginalFileMap) } - make(dirtyFiles).apply { - logOutput("STEP ${i + 1}") - filesToLookups.add(originalFilesToLookups()) - } - } - - val expectedBuildLog = File(testDir, "build.log") - UsefulTestCase.assertSameLinesWithFile(expectedBuildLog.canonicalPath, sb.toString()) - - assertEquals(steps.size + 1, filesToLookups.size) - for ((i, lookupsAtStepI) in filesToLookups.withIndex()) { - val step = if (i == 0) "INITIAL BUILD" else "STEP $i" - for ((file, lookups) in lookupsAtStepI) { - checkLookupsInFile(step, file, lookups) - } - } - } - - private class CompilerOutput( - val exitCode: String, - val errors: List<String>, - val compiledFiles: Iterable<File>, - val lookups: Map<File, List<LookupInfo>> - ) - - private fun make(filesToCompile: Iterable<File>): CompilerOutput { - filesToCompile.forEach { - it.writeText(it.readText().replace(COMMENT_WITH_LOOKUP_INFO, "")) - } - - markDirty(filesToCompile) - val lookupTracker = TestLookupTracker() - val messageCollector = TestMessageCollector() - val outputItemsCollector = OutputItemsCollectorImpl() - val services = Services.Builder().run { - register(LookupTracker::class.java, lookupTracker) - registerAdditionalServices() - build() - } - val environment = createTestingCompilerEnvironment(messageCollector, outputItemsCollector, services) - val exitCode = runCompiler(filesToCompile, environment) as? ExitCode - if (exitCode == ExitCode.OK) { - processCompilationResults(outputItemsCollector, environment.services) - } - - val lookups = lookupTracker.lookups.groupBy { File(it.filePath) } - val lookupsFromCompiledFiles = filesToCompile.associate { it to (lookups[it] ?: emptyList()) } - return CompilerOutput(exitCode.toString(), messageCollector.errors, filesToCompile, lookupsFromCompiledFiles) - } - - protected open fun Services.Builder.registerAdditionalServices() {} - - private fun checkLookupsInFile(step: String, expectedFile: File, lookupsFromFile: List<LookupInfo>) { - val text = expectedFile.readText().replace(COMMENT_WITH_LOOKUP_INFO, "") - val lines = text.lines().toMutableList() - - for ((line, lookupsFromLine) in lookupsFromFile.groupBy { it.position.line }) { - val columnToLookups = lookupsFromLine.groupBy { it.position.column }.toList().sortedBy { it.first } - - val lineContent = lines[line - 1] - val parts = ArrayList<CharSequence>(columnToLookups.size * 2) - - var start = 0 - - for ((column, lookupsFromColumn) in columnToLookups) { - val end = column - 1 - parts.add(lineContent.subSequence(start, end)) - - val lookups = lookupsFromColumn.mapTo(sortedSetOf()) { - val rest = lineContent.substring(end) - - val name = - when { - rest.startsWith(it.name) || // same name - rest.startsWith("$" + it.name) || // backing field - DECLARATION_STARTS_WITH.any { rest.startsWith(it) } // it's declaration - -> "" - else -> "(" + it.name + ")" - } - - it.scopeKind.toString()[0].toLowerCase() - .toString() + ":" + it.scopeFqName.let { if (it.isNotEmpty()) it else "<root>" } + name - }.joinToString(separator = " ", prefix = "/*", postfix = "*/") - - parts.add(lookups) - - start = end - } - - lines[line - 1] = parts.joinToString("") + lineContent.subSequence(start, lineContent.length) - } - - val actual = lines.joinToString("\n") - KotlinTestUtils.assertEqualsToFile("Lookups do not match after $step", expectedFile, actual) - } -} - -class TestLookupTracker : LookupTracker { - val lookups = arrayListOf<LookupInfo>() - private val interner = StringInterner() - - override val requiresPosition: Boolean - get() = true - - override fun record(filePath: String, position: Position, scopeFqName: String, scopeKind: ScopeKind, name: String) { - val internedFilePath = interner.intern(filePath) - val internedScopeFqName = interner.intern(scopeFqName) - val internedName = interner.intern(name) - - lookups.add(LookupInfo(internedFilePath, position, internedScopeFqName, scopeKind, internedName)) - } -} - - |