[Commonizer] Properly detect commonized KLIBs in IDE
This commit is contained in:
+25
-26
@@ -5,11 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.configuration.klib
|
package org.jetbrains.kotlin.idea.configuration.klib
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.library.KONAN_DISTRIBUTION_COMMON_LIBS_DIR
|
|
||||||
import org.jetbrains.kotlin.konan.library.KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR
|
|
||||||
import org.jetbrains.kotlin.konan.library.KONAN_DISTRIBUTION_SOURCES_DIR
|
|
||||||
import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME
|
|
||||||
import org.jetbrains.kotlin.idea.configuration.klib.KlibInfoProvider.Origin.*
|
import org.jetbrains.kotlin.idea.configuration.klib.KlibInfoProvider.Origin.*
|
||||||
|
import org.jetbrains.kotlin.konan.library.*
|
||||||
import org.jetbrains.kotlin.konan.target.Distribution
|
import org.jetbrains.kotlin.konan.target.Distribution
|
||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
@@ -22,10 +19,7 @@ import java.nio.file.Files.*
|
|||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class KlibInfoProvider(
|
class KlibInfoProvider(kotlinNativeHome: File) {
|
||||||
kotlinNativeHome: File,
|
|
||||||
nativeDistributionCommonizedLibsDir: File? = null
|
|
||||||
) {
|
|
||||||
private enum class Origin {
|
private enum class Origin {
|
||||||
NATIVE_DISTRIBUTION,
|
NATIVE_DISTRIBUTION,
|
||||||
NATIVE_DISTRIBUTION_COMMONIZED,
|
NATIVE_DISTRIBUTION_COMMONIZED,
|
||||||
@@ -34,8 +28,7 @@ class KlibInfoProvider(
|
|||||||
|
|
||||||
private class ResultWrapper<T>(val result: T)
|
private class ResultWrapper<T>(val result: T)
|
||||||
|
|
||||||
private val kotlinNativePath = kotlinNativeHome.toPath()
|
private val nativeDistributionLibrariesPath = kotlinNativeHome.resolve(KONAN_DISTRIBUTION_KLIB_DIR).toPath()
|
||||||
private val nativeDistributionCommonizedLibsPath = nativeDistributionCommonizedLibsDir?.toPath()
|
|
||||||
|
|
||||||
private val hostManager by lazy {
|
private val hostManager by lazy {
|
||||||
HostManager(
|
HostManager(
|
||||||
@@ -80,11 +73,15 @@ class KlibInfoProvider(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun detectOrigin(libraryPath: Path): Origin? = when {
|
private fun detectOrigin(libraryPath: Path): Origin? =
|
||||||
libraryPath.startsWith(kotlinNativePath) -> NATIVE_DISTRIBUTION
|
if (!libraryPath.startsWith(nativeDistributionLibrariesPath)) {
|
||||||
nativeDistributionCommonizedLibsPath?.let { libraryPath.startsWith(it) } == true -> NATIVE_DISTRIBUTION_COMMONIZED
|
null
|
||||||
else -> null
|
} else {
|
||||||
}
|
if (libraryPath.getNameOrNull(nativeDistributionLibrariesPath.nameCount) == KONAN_DISTRIBUTION_COMMONIZED_LIBS_DIR)
|
||||||
|
NATIVE_DISTRIBUTION_COMMONIZED
|
||||||
|
else
|
||||||
|
NATIVE_DISTRIBUTION
|
||||||
|
}
|
||||||
|
|
||||||
private fun findManifestFile(libraryPath: Path): Path? {
|
private fun findManifestFile(libraryPath: Path): Path? {
|
||||||
libraryPath.resolve(KLIB_MANIFEST_FILE_NAME).let { propertiesPath ->
|
libraryPath.resolve(KLIB_MANIFEST_FILE_NAME).let { propertiesPath ->
|
||||||
@@ -131,7 +128,7 @@ class KlibInfoProvider(
|
|||||||
if (parentDirName == KONAN_DISTRIBUTION_COMMON_LIBS_DIR)
|
if (parentDirName == KONAN_DISTRIBUTION_COMMON_LIBS_DIR)
|
||||||
return ResultWrapper(/* common */ null)
|
return ResultWrapper(/* common */ null)
|
||||||
else {
|
else {
|
||||||
val target = parentDirName.safeToTarget() ?: return null
|
val target = parentDirName.toTargetOrNull() ?: return null
|
||||||
val grandParentDirName = libraryPath.getName(libraryPath.nameCount - 3).toString()
|
val grandParentDirName = libraryPath.getName(libraryPath.nameCount - 3).toString()
|
||||||
return if (grandParentDirName == KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR)
|
return if (grandParentDirName == KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR)
|
||||||
ResultWrapper(target)
|
ResultWrapper(target)
|
||||||
@@ -144,13 +141,17 @@ class KlibInfoProvider(
|
|||||||
if (libraryPath.nameCount < 4) return null
|
if (libraryPath.nameCount < 4) return null
|
||||||
|
|
||||||
val additionalOffset = if (ownTarget == null) /* common */ 0 else 1
|
val additionalOffset = if (ownTarget == null) /* common */ 0 else 1
|
||||||
val basePath = libraryPath.subpath(0, libraryPath.nameCount - 2 - additionalOffset)
|
val commonizedLibsDirName = libraryPath.getName(libraryPath.nameCount - 3 - additionalOffset).toString()
|
||||||
|
|
||||||
val props = loadProperties(basePath.resolve(COMMONIZED_PROPERTIES_FILE_NAME))
|
val rawTargets = commonizedLibsDirName.split('-').dropLast(1)
|
||||||
val rawTargets = props.getProperty(COMMONIZED_TARGETS)?.split(' ') ?: return null
|
val targets = rawTargets.mapNotNullTo(mutableSetOf()) { it.toTargetOrNull() }
|
||||||
|
|
||||||
val targets = rawTargets.mapNotNullTo(mutableSetOf()) { it.safeToTarget() }
|
if (targets.isEmpty()
|
||||||
if (targets.isEmpty() || targets.size != rawTargets.size || ownTarget !in targets) return null
|
|| targets.size != rawTargets.size
|
||||||
|
|| (ownTarget != null && ownTarget !in targets)
|
||||||
|
) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
return ResultWrapper(targets)
|
return ResultWrapper(targets)
|
||||||
}
|
}
|
||||||
@@ -166,14 +167,12 @@ class KlibInfoProvider(
|
|||||||
return nativeDistributionLibrarySourceFiles.filter { nameFilter(it.name) }
|
return nativeDistributionLibrarySourceFiles.filter { nameFilter(it.name) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun String.safeToTarget(): KonanTarget? = try {
|
private fun String.toTargetOrNull(): KonanTarget? = try {
|
||||||
hostManager.targetByName(this)
|
hostManager.targetByName(this)
|
||||||
} catch (_: TargetSupportException) {
|
} catch (_: TargetSupportException) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
private fun Path.getNameOrNull(index: Int): String? =
|
||||||
const val COMMONIZED_PROPERTIES_FILE_NAME = ".commonized"
|
if (index < 0 || index >= nameCount) null else getName(index).toString()
|
||||||
const val COMMONIZED_TARGETS = "targets"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+118
-41
@@ -7,43 +7,71 @@ package org.jetbrains.kotlin.idea.configuration.klib
|
|||||||
|
|
||||||
import com.intellij.testFramework.PlatformTestUtil.getTestName
|
import com.intellij.testFramework.PlatformTestUtil.getTestName
|
||||||
import junit.framework.TestCase
|
import junit.framework.TestCase
|
||||||
|
import org.jetbrains.kotlin.konan.library.*
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils.getHomeDirectory
|
import org.jetbrains.kotlin.test.KotlinTestUtils.getHomeDirectory
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class KlibInfoProviderTest : TestCase() {
|
class KlibInfoProviderTest : TestCase() {
|
||||||
|
|
||||||
fun testOldStyleKlibsFromNativeDistributionRecognized() = doTest()
|
fun testOldStyleKlibsFromNativeDistributionRecognized() = doTest(
|
||||||
|
::generateExpectedKlibsFromDistribution
|
||||||
|
)
|
||||||
|
|
||||||
fun testKlibsFromNativeDistributionWithSingleComponentRecognized() = doTest()
|
fun testKlibsFromNativeDistributionWithSingleComponentRecognized() = doTest(
|
||||||
|
::generateExpectedKlibsFromDistribution
|
||||||
|
)
|
||||||
|
|
||||||
fun testKlibsFromNativeDistributionWithMultipleComponentsRecognized() = doTest()
|
fun testKlibsFromNativeDistributionWithMultipleComponentsRecognized() = doTest(
|
||||||
|
::generateExpectedKlibsFromDistribution
|
||||||
|
)
|
||||||
|
|
||||||
private fun doTest() {
|
fun testCommonizedKlibsFromNativeDistributionRecognized() = doTest(
|
||||||
|
::generateExpectedKlibsFromDistribution,
|
||||||
|
::generateExpectedCommonizedKlibsFromDistribution
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun doTest(vararg expectedKlibsGenerators: (kotlinNativeHome: File) -> Map<File, KlibInfo>) {
|
||||||
val kotlinNativeHome = testDataDir.resolve(getTestName(name, true)).resolve("kotlin-native-PLATFORM-VERSION")
|
val kotlinNativeHome = testDataDir.resolve(getTestName(name, true)).resolve("kotlin-native-PLATFORM-VERSION")
|
||||||
val sourcesDir = kotlinNativeHome.resolve("sources")
|
val sourcesDir = kotlinNativeHome.resolve(KONAN_DISTRIBUTION_SOURCES_DIR)
|
||||||
|
|
||||||
val klibProvider = KlibInfoProvider(kotlinNativeHome = kotlinNativeHome)
|
val klibProvider = KlibInfoProvider(kotlinNativeHome = kotlinNativeHome)
|
||||||
|
|
||||||
val potentialKlibPaths = mutableListOf<File>()
|
val potentialKlibPaths = mutableListOf<File>()
|
||||||
potentialKlibPaths += externalLibsDir.children()
|
potentialKlibPaths += externalLibsDir.children()
|
||||||
potentialKlibPaths += kotlinNativeHome.resolve("klib", "common").children()
|
|
||||||
potentialKlibPaths += kotlinNativeHome.resolve("klib", "platform", "macos_x64").children()
|
|
||||||
|
|
||||||
val actualKlibs = potentialKlibPaths
|
with(kotlinNativeHome.resolve(KONAN_DISTRIBUTION_KLIB_DIR)) {
|
||||||
.mapNotNull { klibProvider.getKlibInfo(it) as? NativeDistributionKlibInfo }
|
potentialKlibPaths += resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR).children()
|
||||||
|
potentialKlibPaths += resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR, "macos_x64").children()
|
||||||
|
|
||||||
|
with(resolve(KONAN_DISTRIBUTION_COMMONIZED_LIBS_DIR, "ios_arm64-ios_x64-discriminator")) {
|
||||||
|
potentialKlibPaths += resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR).children()
|
||||||
|
potentialKlibPaths += resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR, "ios_arm64").children()
|
||||||
|
potentialKlibPaths += resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR, "ios_x64").children()
|
||||||
|
}
|
||||||
|
|
||||||
|
with(resolve(KONAN_DISTRIBUTION_COMMONIZED_LIBS_DIR, "ios_arm32-ios_arm64-ios_x64-discriminator")) {
|
||||||
|
potentialKlibPaths += resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR).children()
|
||||||
|
potentialKlibPaths += resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR, "ios_arm32").children()
|
||||||
|
potentialKlibPaths += resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR, "ios_arm64").children()
|
||||||
|
potentialKlibPaths += resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR, "ios_x64").children()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val actualKlibs = potentialKlibPaths.mapNotNull { klibProvider.getKlibInfo(it) }
|
||||||
.associateBy { it.path.relativeTo(kotlinNativeHome) }
|
.associateBy { it.path.relativeTo(kotlinNativeHome) }
|
||||||
|
|
||||||
val expectedKlibsFromDistribution = generateExpectedKlibsFromDistribution(
|
val expectedKlibsFromDistribution = mutableMapOf<File, KlibInfo>().apply {
|
||||||
kotlinNativeHome = kotlinNativeHome,
|
expectedKlibsGenerators.forEach { this += it(kotlinNativeHome) }
|
||||||
sourcesDir = sourcesDir
|
}
|
||||||
)
|
|
||||||
|
|
||||||
assertEquals(expectedKlibsFromDistribution.keys, actualKlibs.keys)
|
assertEquals(expectedKlibsFromDistribution.keys, actualKlibs.keys)
|
||||||
for (klibPath in actualKlibs.keys) {
|
for (klibPath in actualKlibs.keys) {
|
||||||
val actualKlib = actualKlibs.getValue(klibPath)
|
val actualKlib = actualKlibs.getValue(klibPath)
|
||||||
val expectedKlib = expectedKlibsFromDistribution.getValue(klibPath)
|
val expectedKlib = expectedKlibsFromDistribution.getValue(klibPath)
|
||||||
|
|
||||||
|
assertEquals(expectedKlib::class.java, actualKlib::class.java)
|
||||||
|
|
||||||
assertEquals(expectedKlib.path, actualKlib.path)
|
assertEquals(expectedKlib.path, actualKlib.path)
|
||||||
assertEquals(expectedKlib.name, actualKlib.name)
|
assertEquals(expectedKlib.name, actualKlib.name)
|
||||||
|
|
||||||
@@ -51,48 +79,98 @@ class KlibInfoProviderTest : TestCase() {
|
|||||||
val expectedSources = expectedKlib.sourcePaths.map { it.relativeTo(sourcesDir) }.toSet()
|
val expectedSources = expectedKlib.sourcePaths.map { it.relativeTo(sourcesDir) }.toSet()
|
||||||
|
|
||||||
assertEquals(expectedSources, actualSources)
|
assertEquals(expectedSources, actualSources)
|
||||||
assertEquals(expectedKlib.target, actualKlib.target)
|
|
||||||
|
if (expectedKlib is NativeDistributionKlibInfo) {
|
||||||
|
require(actualKlib is NativeDistributionKlibInfo)
|
||||||
|
|
||||||
|
assertEquals(expectedKlib.target, actualKlib.target)
|
||||||
|
} else if (expectedKlib is NativeDistributionCommonizedKlibInfo) {
|
||||||
|
require(actualKlib is NativeDistributionCommonizedKlibInfo)
|
||||||
|
|
||||||
|
assertEquals(expectedKlib.ownTarget, actualKlib.ownTarget)
|
||||||
|
assertEquals(expectedKlib.commonizedTargets, actualKlib.commonizedTargets)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateExpectedKlibsFromDistribution(kotlinNativeHome: File, sourcesDir: File) = listOf(
|
private fun generateExpectedKlibsFromDistribution(kotlinNativeHome: File): Map<File, NativeDistributionKlibInfo> {
|
||||||
NativeDistributionKlibInfo(
|
val sourcesDir = kotlinNativeHome.resolve(KONAN_DISTRIBUTION_SOURCES_DIR)
|
||||||
path = kotlinNativeHome.resolve("klib", "common", "stdlib"),
|
val basePath = kotlinNativeHome.resolve(KONAN_DISTRIBUTION_KLIB_DIR)
|
||||||
|
|
||||||
|
val result = mutableListOf<NativeDistributionKlibInfo>()
|
||||||
|
|
||||||
|
result += NativeDistributionKlibInfo(
|
||||||
|
path = basePath.resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR, KONAN_STDLIB_NAME),
|
||||||
sourcePaths = listOf(
|
sourcePaths = listOf(
|
||||||
sourcesDir.resolve("kotlin-stdlib-native-sources.zip"),
|
sourcesDir.resolve("kotlin-stdlib-native-sources.zip"),
|
||||||
sourcesDir.resolve("kotlin-test-anotations-common-sources.zip")
|
sourcesDir.resolve("kotlin-test-anotations-common-sources.zip")
|
||||||
),
|
),
|
||||||
name = "stdlib",
|
name = KONAN_STDLIB_NAME,
|
||||||
target = null
|
target = null
|
||||||
),
|
)
|
||||||
NativeDistributionKlibInfo(
|
|
||||||
path = kotlinNativeHome.resolve("klib", "common", "kotlinx-cli"),
|
result += NativeDistributionKlibInfo(
|
||||||
|
path = basePath.resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR, "kotlinx-cli"),
|
||||||
sourcePaths = listOf(
|
sourcePaths = listOf(
|
||||||
sourcesDir.resolve("kotlinx-cli-common-sources.zip"),
|
sourcesDir.resolve("kotlinx-cli-common-sources.zip"),
|
||||||
sourcesDir.resolve("kotlinx-cli-native-sources.zip")
|
sourcesDir.resolve("kotlinx-cli-native-sources.zip")
|
||||||
),
|
),
|
||||||
name = "kotlinx-cli",
|
name = "kotlinx-cli",
|
||||||
target = null
|
target = null
|
||||||
),
|
|
||||||
NativeDistributionKlibInfo(
|
|
||||||
path = kotlinNativeHome.resolve("klib", "platform", "macos_x64", "foo"),
|
|
||||||
sourcePaths = emptyList(),
|
|
||||||
name = "foo",
|
|
||||||
target = KonanTarget.MACOS_X64
|
|
||||||
),
|
|
||||||
NativeDistributionKlibInfo(
|
|
||||||
path = kotlinNativeHome.resolve("klib", "platform", "macos_x64", "bar"),
|
|
||||||
sourcePaths = emptyList(),
|
|
||||||
name = "bar",
|
|
||||||
target = KonanTarget.MACOS_X64
|
|
||||||
),
|
|
||||||
NativeDistributionKlibInfo(
|
|
||||||
path = kotlinNativeHome.resolve("klib", "platform", "macos_x64", "baz"),
|
|
||||||
sourcePaths = emptyList(),
|
|
||||||
name = "baz",
|
|
||||||
target = KonanTarget.MACOS_X64
|
|
||||||
)
|
)
|
||||||
).associateBy { it.path.relativeTo(kotlinNativeHome) }
|
|
||||||
|
result += listOf("foo", "bar", "baz").map { name ->
|
||||||
|
NativeDistributionKlibInfo(
|
||||||
|
path = basePath.resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR, "macos_x64", name),
|
||||||
|
sourcePaths = emptyList(),
|
||||||
|
name = name,
|
||||||
|
target = KonanTarget.MACOS_X64
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.associateBy { it.path.relativeTo(kotlinNativeHome) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateExpectedCommonizedKlibsFromDistribution(kotlinNativeHome: File): Map<File, NativeDistributionCommonizedKlibInfo> {
|
||||||
|
val basePath = kotlinNativeHome.resolve(KONAN_DISTRIBUTION_KLIB_DIR, KONAN_DISTRIBUTION_COMMONIZED_LIBS_DIR)
|
||||||
|
|
||||||
|
fun generateCommonizedKlibsForDir(commonizedLibsDirName: String): Map<File, NativeDistributionCommonizedKlibInfo> {
|
||||||
|
val rawTargets = commonizedLibsDirName.split('-').dropLast(1)
|
||||||
|
val targets = rawTargets.map {
|
||||||
|
when (it) {
|
||||||
|
"ios_x64" -> KonanTarget.IOS_X64
|
||||||
|
"ios_arm32" -> KonanTarget.IOS_ARM32
|
||||||
|
"ios_arm64" -> KonanTarget.IOS_ARM64
|
||||||
|
else -> error("Unexpected target: $it")
|
||||||
|
}
|
||||||
|
}.toSet()
|
||||||
|
|
||||||
|
val result = mutableListOf<NativeDistributionCommonizedKlibInfo>()
|
||||||
|
|
||||||
|
with(basePath.resolve(commonizedLibsDirName)) {
|
||||||
|
val libraryDirsToTargets: Map<File, KonanTarget?> =
|
||||||
|
targets.associateBy { resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR, it.name) } +
|
||||||
|
(resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR) to null)
|
||||||
|
|
||||||
|
libraryDirsToTargets.forEach { (libraryDir, target) ->
|
||||||
|
result += listOf("foo", "bar", "baz").map { name ->
|
||||||
|
NativeDistributionCommonizedKlibInfo(
|
||||||
|
path = libraryDir.resolve(name),
|
||||||
|
sourcePaths = emptyList(),
|
||||||
|
name = name,
|
||||||
|
ownTarget = target,
|
||||||
|
commonizedTargets = targets
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.associateBy { it.path.relativeTo(kotlinNativeHome) }
|
||||||
|
}
|
||||||
|
|
||||||
|
return generateCommonizedKlibsForDir("ios_arm64-ios_x64-discriminator") +
|
||||||
|
generateCommonizedKlibsForDir("ios_arm32-ios_arm64-ios_x64-discriminator")
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val testDataDir = File(getHomeDirectory() + "/idea/testData/configuration/klib")
|
private val testDataDir = File(getHomeDirectory() + "/idea/testData/configuration/klib")
|
||||||
@@ -101,7 +179,6 @@ class KlibInfoProviderTest : TestCase() {
|
|||||||
private val externalLibsDir = testDataDir.resolve("external-libs")
|
private val externalLibsDir = testDataDir.resolve("external-libs")
|
||||||
|
|
||||||
private fun File.children(): List<File> = (listFiles()?.toList() ?: emptyList())
|
private fun File.children(): List<File> = (listFiles()?.toList() ?: emptyList())
|
||||||
.also { assertTrue("$this does not have children files or directories", it.isNotEmpty()) }
|
|
||||||
|
|
||||||
private fun File.resolve(relative: String, next: String, vararg others: String): File {
|
private fun File.resolve(relative: String, next: String, vararg others: String): File {
|
||||||
var temp = resolve(relative).resolve(next)
|
var temp = resolve(relative).resolve(next)
|
||||||
|
|||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=kotlinx-cli
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=stdlib
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=bar
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=baz
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=foo
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
SPOILED_unique_name=invalid2
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=invalid3
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=bar
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=baz
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=foo
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
SPOILED_unique_name=invalid2
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=invalid3
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=bar
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=baz
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=foo
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
SPOILED_unique_name=invalid2
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=invalid3
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=bar
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=baz
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=foo
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
SPOILED_unique_name=invalid2
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=invalid3
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=bar
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=baz
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=foo
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
SPOILED_unique_name=invalid2
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=invalid3
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=bar
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=baz
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=foo
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
SPOILED_unique_name=invalid2
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=invalid3
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=bar
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=baz
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=foo
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
SPOILED_unique_name=invalid2
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=invalid3
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=bar
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=baz
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=foo
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
SPOILED_unique_name=invalid2
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
unique_name=invalid3
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
// this file is empty
|
||||||
BIN
Binary file not shown.
+1
@@ -0,0 +1 @@
|
|||||||
|
// this file is empty
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
// this file is empty
|
||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+1
@@ -0,0 +1 @@
|
|||||||
|
// this file is empty
|
||||||
BIN
Binary file not shown.
Reference in New Issue
Block a user