From 7abfe4d47bcda549bf04b8c691d67bc3a0a3de1f Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Fri, 3 Dec 2021 02:04:18 +0300 Subject: [PATCH] [Native][tests] Rework PackageName entity --- .../AbstractNativeBlackBoxTest.kt | 13 ++-- .../TestInfra_CompressedNamesTest.kt | 6 ++ .../blackboxtest/support/NamedEntities.kt | 24 ++++++++ .../konan/blackboxtest/support/TestCase.kt | 5 +- .../blackboxtest/support/TestCompiler.kt | 6 +- .../blackboxtest/support/TestExecutable.kt | 11 ++-- .../blackboxtest/support/TestRunProvider.kt | 4 +- .../support/group/ExtTestCaseGroupProvider.kt | 4 +- .../group/PredefinedTestCaseGroupProvider.kt | 2 +- .../group/StandardTestCaseGroupProvider.kt | 4 +- .../support/util/CompressedNames.kt | 6 +- .../blackboxtest/support/util/PackageNames.kt | 59 ++++++++++--------- .../support/util/SourceDiscovery.kt | 5 +- .../blackboxtest/support/util/TestListing.kt | 16 +++-- .../blackboxtest/support/util/TreeNode.kt | 23 ++++---- 15 files changed, 112 insertions(+), 76 deletions(-) create mode 100644 native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/NamedEntities.kt diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeBlackBoxTest.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeBlackBoxTest.kt index 207bcb48218..85b6b44e84c 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeBlackBoxTest.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeBlackBoxTest.kt @@ -7,10 +7,11 @@ package org.jetbrains.kotlin.konan.blackboxtest import com.intellij.testFramework.TestDataFile import org.jetbrains.kotlin.konan.blackboxtest.support.* -import org.jetbrains.kotlin.konan.blackboxtest.support.util.TreeNode -import org.jetbrains.kotlin.konan.blackboxtest.support.util.getAbsoluteFile -import org.jetbrains.kotlin.konan.blackboxtest.support.util.joinPackageNames -import org.jetbrains.kotlin.konan.blackboxtest.support.util.prependPackageName +import org.jetbrains.kotlin.konan.blackboxtest.support.PackageName +import org.jetbrains.kotlin.konan.blackboxtest.support.TestCaseId +import org.jetbrains.kotlin.konan.blackboxtest.support.TestRun +import org.jetbrains.kotlin.konan.blackboxtest.support.TestRunProvider +import org.jetbrains.kotlin.konan.blackboxtest.support.util.* import org.junit.jupiter.api.DynamicNode import org.junit.jupiter.api.DynamicTest.dynamicTest import org.junit.jupiter.api.extension.ExtendWith @@ -89,7 +90,7 @@ abstract class AbstractNativeBlackBoxTest { // } // } buildList { - fun TreeNode.processItems(parentPackageSegment: String) { + fun TreeNode.processItems(parentPackageSegment: PackageName) { val ownPackageSegment = joinPackageNames(parentPackageSegment, packageSegment) items.mapTo(this@buildList) { testRun -> val displayName = testRun.displayName.prependPackageName(ownPackageSegment) @@ -99,7 +100,7 @@ abstract class AbstractNativeBlackBoxTest { children.forEach { it.processItems(ownPackageSegment) } } - testRunNodes.forEach { testRunNode -> testRunNode.processItems("") } + testRunNodes.forEach { testRunNode -> testRunNode.processItems(PackageName.EMPTY) } } private fun performTestRun(testRun: TestRun) { diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/TestInfra_CompressedNamesTest.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/TestInfra_CompressedNamesTest.kt index 7cba59f247f..d6edf306843 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/TestInfra_CompressedNamesTest.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/TestInfra_CompressedNamesTest.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.konan.blackboxtest +import org.jetbrains.kotlin.konan.blackboxtest.support.PackageName import org.jetbrains.kotlin.konan.blackboxtest.support.util.compressedName import org.jetbrains.kotlin.konan.blackboxtest.support.util.compressedPackageName import org.jetbrains.kotlin.konan.blackboxtest.support.util.compressedSimpleName @@ -90,4 +91,9 @@ class TestInfra_CompressedNamesTest { "foo.bar.baz.foo.bar.baz.foo.bar.baz.foo.bar.baz.foo.bar.baz".compressedPackageName ) } + + companion object { + private val String.compressedPackageName + get() = PackageName(this).compressedPackageName + } } diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/NamedEntities.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/NamedEntities.kt new file mode 100644 index 00000000000..453d6e294dd --- /dev/null +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/NamedEntities.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2010-2021 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.konan.blackboxtest.support + +/** + * Represents a package name. + */ +internal class PackageName private constructor(private val fqn: String, val segments: List) { + constructor(segments: List) : this(segments.joinToString("."), segments) + constructor(fqn: String) : this(fqn, if (fqn.isNotEmpty()) fqn.split('.') else emptyList()) + + fun isEmpty(): Boolean = segments.isEmpty() + + override fun toString() = fqn + override fun equals(other: Any?) = fqn == (other as? PackageName)?.fqn + override fun hashCode() = fqn.hashCode() + + companion object { + val EMPTY = PackageName("", emptyList()) + } +} diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestCase.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestCase.kt index 49ef11ae726..7093d551359 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestCase.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestCase.kt @@ -15,13 +15,12 @@ import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertTrue import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail import java.io.File -internal typealias PackageFQN = String internal typealias FunctionName = String /** * Represents a single test function (i.e. a function annotated with [kotlin.test.Test]) inside of a [TestFile]. */ -internal data class TestFunction(val packageName: PackageFQN, val functionName: FunctionName) +internal data class TestFunction(val packageName: PackageName, val functionName: FunctionName) /** * Represents a single file that will be supplied to the compiler. @@ -179,7 +178,7 @@ internal class TestCase( val kind: TestKind, val modules: Set, val freeCompilerArgs: TestCompilerArgs, - val nominalPackageName: PackageFQN, + val nominalPackageName: PackageName, val expectedOutputDataFile: File?, val extras: Extras ) { diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestCompiler.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestCompiler.kt index e986d98c62c..3b23d3f30b6 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestCompiler.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestCompiler.kt @@ -113,7 +113,7 @@ internal class TestCompilationFactory(private val settings: Settings) { private fun multiModuleArtifactFile(modules: Collection, extension: String): File { var filesCount = 0 var hash = 0 - val uniquePackageNames = hashSetOf() + val uniquePackageNames = hashSetOf() modules.forEach { module -> module.files.forEach { file -> @@ -132,7 +132,7 @@ internal class TestCompilationFactory(private val settings: Settings) { repeat(4 - prefix.length) { append('0') } append(prefix).append('-') - if (commonPackageName != null) + if (!commonPackageName.isEmpty()) append(commonPackageName.compressedPackageName).append('-') append(prettyHash(hash)) @@ -143,7 +143,7 @@ internal class TestCompilationFactory(private val settings: Settings) { return artifactDirForPackageName(commonPackageName).resolve(artifactFileName) } - private fun artifactDirForPackageName(packageName: PackageFQN?): File { + private fun artifactDirForPackageName(packageName: PackageName?): File { val baseDir = settings.get().testBinariesDir val outputDir = if (packageName != null) baseDir.resolve(packageName.compressedPackageName) else baseDir diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestExecutable.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestExecutable.kt index 90bcab6048c..0d8d87a035b 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestExecutable.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestExecutable.kt @@ -5,7 +5,8 @@ package org.jetbrains.kotlin.konan.blackboxtest.support -import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertTrue +import org.jetbrains.kotlin.konan.blackboxtest.support.util.TestName +import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertFalse import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import java.io.File @@ -28,9 +29,9 @@ internal sealed interface TestRunParameter { abstract fun testMatches(testName: String): Boolean } - class WithPackageFilter(packageName: PackageFQN) : WithFilter() { + class WithPackageFilter(packageName: PackageName) : WithFilter() { init { - assertTrue(packageName.isNotEmpty()) + assertFalse(packageName.isEmpty()) } private val packagePrefix = "$packageName." @@ -39,11 +40,11 @@ internal sealed interface TestRunParameter { programArgs += "--ktest_filter=$packagePrefix*" } - override fun testMatches(testName: String) = testName.startsWith(packagePrefix) + override fun testMatches(testName: TestName) = testName.startsWith(packagePrefix) } class WithFunctionFilter(val testFunction: TestFunction) : WithFilter() { - private val packagePrefix = if (testFunction.packageName.isNotEmpty()) "${testFunction.packageName}." else "" + private val packagePrefix = if (testFunction.packageName.isEmpty()) "" else "${testFunction.packageName}." override fun applyTo(programArgs: MutableList) { programArgs += "--ktest_regex_filter=${packagePrefix.replace(".", "\\.")}([^\\.]+)\\.${testFunction.functionName}" diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestRunProvider.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestRunProvider.kt index 4c75af45dbd..60707f59eb3 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestRunProvider.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/TestRunProvider.kt @@ -16,10 +16,10 @@ import org.jetbrains.kotlin.konan.blackboxtest.support.runner.LocalTestFunctionE import org.jetbrains.kotlin.konan.blackboxtest.support.runner.LocalTestRunner import org.jetbrains.kotlin.konan.blackboxtest.support.settings.GlobalSettings import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Settings +import org.jetbrains.kotlin.konan.blackboxtest.support.util.* import org.jetbrains.kotlin.konan.blackboxtest.support.util.ThreadSafeCache import org.jetbrains.kotlin.konan.blackboxtest.support.util.TreeNode import org.jetbrains.kotlin.konan.blackboxtest.support.util.buildTree -import org.jetbrains.kotlin.konan.blackboxtest.support.util.isSameOrSubpackageOf import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertTrue import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail import org.junit.jupiter.api.Assumptions.assumeTrue @@ -199,7 +199,7 @@ internal class TestRunProvider( private fun Collection.filterIrrelevant(testCase: TestCase) = if (testCase.kind == TestKind.REGULAR) - filter { testFunction -> testFunction.packageName.isSameOrSubpackageOf(testCase.nominalPackageName) } + filter { testFunction -> testFunction.packageName.startsWith(testCase.nominalPackageName) } else this diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/group/ExtTestCaseGroupProvider.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/group/ExtTestCaseGroupProvider.kt index d12d37f5943..2fc1156b273 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/group/ExtTestCaseGroupProvider.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/group/ExtTestCaseGroupProvider.kt @@ -279,7 +279,7 @@ private class ExtTestDataFile( private fun patchPackageNames(isStandaloneTest: Boolean) = with(structure) { if (isStandaloneTest) return // Don't patch packages for standalone tests. - val basePackageName = FqName(testDataFileSettings.nominalPackageName) + val basePackageName = FqName(testDataFileSettings.nominalPackageName.toString()) val oldPackageNames: Set = filesToTransform.mapToSet { it.packageFqName } val oldToNewPackageNameMapping: Map = oldPackageNames.associateWith { oldPackageName -> @@ -650,7 +650,7 @@ private class ExtTestDataFileSettings( val optInsForCompiler: Set, val expectActualLinker: Boolean, val generatedSourcesDir: File, - val nominalPackageName: PackageFQN + val nominalPackageName: PackageName ) private typealias SharedModuleGenerator = (sharedModulesDir: File) -> TestModule.Shared? diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/group/PredefinedTestCaseGroupProvider.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/group/PredefinedTestCaseGroupProvider.kt index b1101622dc3..e00c1903cba 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/group/PredefinedTestCaseGroupProvider.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/group/PredefinedTestCaseGroupProvider.kt @@ -58,7 +58,7 @@ internal class PredefinedTestCaseGroupProvider(annotation: PredefinedTestCases) modules = setOf(module), freeCompilerArgs = predefinedTestCase.freeCompilerArgs .parseCompilerArgs { "Failed to parse free compiler arguments for test case $testCaseId" }, - nominalPackageName = testCaseId.uniqueName, + nominalPackageName = PackageName(testCaseId.uniqueName), expectedOutputDataFile = null, extras = WithTestRunnerExtras ) diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/group/StandardTestCaseGroupProvider.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/group/StandardTestCaseGroupProvider.kt index f33d9ba73e6..86da7e8dee2 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/group/StandardTestCaseGroupProvider.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/group/StandardTestCaseGroupProvider.kt @@ -221,7 +221,7 @@ internal class StandardTestCaseGroupProvider(private val settings: Settings) : T } companion object { - private fun fixPackageNames(testModules: Collection, basePackageName: PackageFQN, testDataFile: File) { + private fun fixPackageNames(testModules: Collection, basePackageName: PackageName, testDataFile: File) { testModules.forEach { testModule -> testModule.files.forEach { testFile -> val firstMeaningfulLine = testFile.text.dropNonMeaningfulLines().firstOrNull() @@ -230,7 +230,7 @@ internal class StandardTestCaseGroupProvider(private val settings: Settings) : T val existingPackageName = firstMeaningfulLine?.getExistingPackageName() if (existingPackageName != null) { // Validate it. - assertTrue(existingPackageName.isSameOrSubpackageOf(basePackageName)) { + assertTrue(existingPackageName.startsWith(basePackageName)) { val location = Location(testDataFile, firstMeaningfulLine.number) """ $location: Invalid package name declaration found: $firstMeaningfulLine diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/CompressedNames.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/CompressedNames.kt index 336c8ccce2f..825ae897b62 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/CompressedNames.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/CompressedNames.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.konan.blackboxtest.support.util import org.apache.commons.lang.StringUtils.splitByCharacterTypeCamelCase -import org.jetbrains.kotlin.konan.blackboxtest.support.PackageFQN +import org.jetbrains.kotlin.konan.blackboxtest.support.PackageName import org.jetbrains.kotlin.konan.target.Architecture import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.konan.target.KonanTarget @@ -48,9 +48,9 @@ internal val Architecture.compressedName: String internal val Class<*>.compressedSimpleName: String get() = splitByCharacterTypeCamelCase(simpleName).joinToString("") { it.take(3) } -internal val PackageFQN.compressedPackageName: String +internal val PackageName.compressedPackageName: String get() { - val sanitizedName = replace('.', '_') + val sanitizedName = segments.joinToString("_") return if (sanitizedName.length > COMPRESSED_PACKAGE_FQN_MAX_LENGTH) { val suffix = "-" + prettyHash(sanitizedName.hashCode()) sanitizedName.substring(0, COMPRESSED_PACKAGE_FQN_MAX_LENGTH - suffix.length) + suffix diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/PackageNames.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/PackageNames.kt index 38a605ab9d4..37aa180e5da 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/PackageNames.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/PackageNames.kt @@ -5,15 +5,14 @@ package org.jetbrains.kotlin.konan.blackboxtest.support.util -import org.jetbrains.kotlin.konan.blackboxtest.support.PackageFQN +import org.jetbrains.kotlin.konan.blackboxtest.support.PackageName import org.jetbrains.kotlin.renderer.KeywordStringsGenerated.KEYWORDS import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertTrue import java.io.File -import java.nio.file.Path import kotlin.io.path.name import kotlin.math.min -internal fun computePackageName(testDataBaseDir: File, testDataFile: File): PackageFQN { +internal fun computePackageName(testDataBaseDir: File, testDataFile: File): PackageName { assertTrue(testDataFile.startsWith(testDataBaseDir)) { """ The file is outside of the directory. @@ -26,13 +25,13 @@ internal fun computePackageName(testDataBaseDir: File, testDataFile: File): Pack .relativeTo(testDataBaseDir) .resolve(testDataFile.nameWithoutExtension) .toPath() - .map(Path::name) - .joinToString(".") { packagePart -> - if (packagePart in KEYWORDS) - "_${packagePart}_" + .map { pathSegment -> + val packageSegment = pathSegment.name + if (packageSegment in KEYWORDS) + "_${packageSegment}_" else buildString { - packagePart.forEachIndexed { index, ch -> + packageSegment.forEachIndexed { index, ch -> if (ch.isJavaIdentifierPart()) { if (index == 0 && !ch.isJavaIdentifierStart()) { // If the first character is not suitable for start, escape it with '_'. @@ -46,36 +45,42 @@ internal fun computePackageName(testDataBaseDir: File, testDataFile: File): Pack } } } + .let(::PackageName) } -internal fun Set.findCommonPackageName(): PackageFQN? = when (size) { - 0 -> null +internal fun Set.findCommonPackageName(): PackageName = when (size) { + 0 -> PackageName.EMPTY 1 -> first() - else -> map { packageName: PackageFQN -> - packageName.split('.') - }.reduce { commonPackageNameParts: List, packageNameParts: List -> - ArrayList(min(commonPackageNameParts.size, packageNameParts.size)).apply { - val i = commonPackageNameParts.iterator() - val j = packageNameParts.iterator() + else -> map { packageName -> packageName.segments } + .reduce { commonSegments: List, segments: List -> + buildList(min(commonSegments.size, segments.size)) { + val i = commonSegments.iterator() + val j = segments.iterator() - while (i.hasNext() && j.hasNext()) { - val packageNamePart = i.next() - if (packageNamePart == j.next()) add(packageNamePart) else break + while (i.hasNext() && j.hasNext()) { + val segment = i.next() + if (segment == j.next()) add(segment) else break + } } } - }.takeIf { it.isNotEmpty() }?.joinToString(".") + .let(::PackageName) } -internal fun joinPackageNames(a: PackageFQN, b: PackageFQN): PackageFQN = when { +internal fun joinPackageNames(a: PackageName, b: PackageName): PackageName = when { a.isEmpty() -> b b.isEmpty() -> a - else -> "$a.$b" + else -> PackageName(a.segments + b.segments) } -internal fun String.prependPackageName(packageName: PackageFQN): String = +internal fun String.prependPackageName(packageName: PackageName): String = if (packageName.isEmpty()) this else "$packageName.$this" -internal fun PackageFQN.isSameOrSubpackageOf(parentPackageName: PackageFQN): Boolean = - parentPackageName.isEmpty() - || this == parentPackageName - || (length > parentPackageName.length && startsWith(parentPackageName) && this[parentPackageName.length] == '.') +internal fun PackageName.startsWith(other: PackageName): Boolean { + if (segments.size < other.segments.size) return false + + for (i in other.segments.indices) { + if (segments[i] != other.segments[i]) return false + } + + return true +} diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/SourceDiscovery.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/SourceDiscovery.kt index 23635b30602..29eff80cba1 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/SourceDiscovery.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/SourceDiscovery.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.konan.blackboxtest.support.util -import org.jetbrains.kotlin.konan.blackboxtest.support.PackageFQN +import org.jetbrains.kotlin.konan.blackboxtest.support.PackageName internal typealias SourceText = CharSequence internal typealias SourceLine = String @@ -17,10 +17,11 @@ internal data class NumberedSourceLine(val number: Int, val text: SourceLine) : internal fun SourceText.hasAnythingButComments(): Boolean = dropNonMeaningfulLines().firstOrNull() != null -internal fun NumberedSourceLine.getExistingPackageName(): PackageFQN? = +internal fun NumberedSourceLine.getExistingPackageName(): PackageName? = text.substringAfter("package ", missingDelimiterValue = "") .trimStart() .takeIf(String::isNotEmpty) + ?.let(::PackageName) internal fun SourceText.dropNonMeaningfulLines(): Sequence { var inMultilineComment = false diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/TestListing.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/TestListing.kt index 2f753141b27..92631fe2ecd 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/TestListing.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/support/util/TestListing.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.konan.blackboxtest.support.util -import org.jetbrains.kotlin.konan.blackboxtest.support.PackageFQN +import org.jetbrains.kotlin.konan.blackboxtest.support.PackageName import org.jetbrains.kotlin.konan.blackboxtest.support.TestFunction import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail import org.jetbrains.kotlin.konan.blackboxtest.support.util.GTestListingParseState as State @@ -48,14 +48,12 @@ internal fun parseGTestListing(rawGTestListing: String): Collection when (state) { is State.Begin, is State.NewTest -> { - val packageParts = line.trimEnd().removeSuffix(".").split('.') - if (packageParts.isEmpty()) parseError("Malformed test suite name") + val packageSegments = line.trimEnd().removeSuffix(".").split('.') + if (packageSegments.isEmpty()) parseError("Malformed test suite name") // Drop the last part because it is related to class name (or file-class name). // TODO: How to handle nested classes? - val packageName = packageParts.dropLast(1).joinToString(".") - - State.NewTestSuite(packageName) + State.NewTestSuite(PackageName(packageSegments.dropLast(1))) } else -> parseError("Unexpected test suite name") } @@ -66,11 +64,11 @@ internal fun parseGTestListing(rawGTestListing: String): Collection { - val packageSegment: String + val packageSegment: PackageName val items: Collection val children: Collection> @@ -16,15 +16,15 @@ internal interface TreeNode { fun oneLevel(vararg items: T) = oneLevel(listOf(*items)) fun oneLevel(items: Iterable): List> = listOf(object : TreeNode { - override val packageSegment get() = "" + override val packageSegment get() = PackageName.EMPTY override val items = items.toList() override val children get() = emptyList>() }) } } -internal fun Collection.buildTree(extractPackageName: (T) -> PackageFQN, transform: (T) -> R): Collection> { - val groupedItems: Map> = groupBy(extractPackageName).mapValues { (_, items) -> items.map(transform) } +internal fun Collection.buildTree(extractPackageName: (T) -> PackageName, transform: (T) -> R): Collection> { + val groupedItems: Map> = groupBy(extractPackageName).mapValues { (_, items) -> items.map(transform) } // Fast pass. when (groupedItems.size) { @@ -33,13 +33,14 @@ internal fun Collection.buildTree(extractPackageName: (T) -> PackageFQ } // Long pass. - val root = TreeBuilder("") + val root = TreeBuilder(PackageName.EMPTY) // Populate the tree. - groupedItems.forEach { (packageFQN, items) -> + groupedItems.forEach { (packageName, items) -> var node = root - packageFQN.split('.').forEach { packageSegment -> - node = node.childrenMap.computeIfAbsent(packageSegment) { TreeBuilder(packageSegment) } + packageName.segments.forEach { packageSegment -> + val packageSegmentAsName = PackageName(listOf(packageSegment)) + node = node.childrenMap.computeIfAbsent(packageSegmentAsName) { TreeBuilder(packageSegmentAsName) } } node.items += items } @@ -54,9 +55,9 @@ internal fun Collection.buildTree(extractPackageName: (T) -> PackageFQ meaningfulNode.childrenMap.values } -private class TreeBuilder(override var packageSegment: String) : TreeNode { +private class TreeBuilder(override var packageSegment: PackageName) : TreeNode { override val items = mutableListOf() - val childrenMap = hashMapOf>() + val childrenMap = hashMapOf>() override val children: Collection> get() = childrenMap.values }