[aa-klib-reader] Implement 'analysis-api-klib-reader' for swift- and objc export
This new module gives the ability to resolve symbols from provided klib KtLibraryModules withing a Analysis Session. ^KT-65327 Fixed
This commit is contained in:
committed by
Space Team
parent
1bb6f869a2
commit
b5b7e5f262
@@ -360,6 +360,7 @@
|
||||
/license/ "Kotlin Build Infrastructure"
|
||||
|
||||
/native/ "Kotlin Native"
|
||||
/native/analysis-api-klib-reader/ "Kotlin Native" "Kotlin in Fleet"
|
||||
/native/commonizer/ "Kotlin Apple Ecosystem"
|
||||
/native/commonizer-api/ "Kotlin Apple Ecosystem"
|
||||
/native/commonizer-embeddable/ "Kotlin Apple Ecosystem"
|
||||
|
||||
+2
-1
@@ -811,10 +811,11 @@ tasks {
|
||||
// - different GCs
|
||||
// ...
|
||||
register("nativeCompilerTest") {
|
||||
dependsOn(":kotlin-atomicfu-compiler-plugin:nativeTest")
|
||||
dependsOn(":native:analysis-api-klib-reader:check")
|
||||
dependsOn(":native:native.tests:test")
|
||||
dependsOn(":native:objcexport-header-generator:check")
|
||||
dependsOn(":native:swift:swift-export-standalone:test")
|
||||
dependsOn(":kotlin-atomicfu-compiler-plugin:nativeTest")
|
||||
}
|
||||
|
||||
// These are unit tests of Native compiler
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
# Native Analysis Api based Klib reader
|
||||
|
||||
## Tasks
|
||||
|
||||
**Run Tests**
|
||||
|
||||
```
|
||||
./gradlew :native:analysis-api-klib-reader:check
|
||||
```
|
||||
|
||||
## Usage: Reading symbols from a given klib module
|
||||
|
||||
A set of top level `KlibDeclarationAddress` can be read from `KtLibraryModule` by
|
||||
|
||||
```kotlin
|
||||
fun example(module: KtLibraryModule) {
|
||||
val addresses = module.readKlibDeclarationAddresses()
|
||||
}
|
||||
```
|
||||
|
||||
Such addresses can be resolved to `KtSymbol`s by
|
||||
|
||||
```kotlin
|
||||
addresses.flatMap { address -> address.getSymbols() }
|
||||
```
|
||||
|
||||
Note: `getSymbols` returns a sequence as multiple symbols can live under the same address.
|
||||
|
||||
## Usage: Getting all library modules in a Standalone Analysis API session.
|
||||
|
||||
Example of creating a session
|
||||
```kotin
|
||||
val session = buildStandaloneAnalysisAPISession {
|
||||
buildKtModuleProvider {
|
||||
// ...
|
||||
addModule(buildKtLibraryModule {
|
||||
addBinaryRoot(pathToKlib)
|
||||
// ..
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Example analyzing libraries within the session
|
||||
```kotlin
|
||||
session.getAllLibraryModules().forEach { module ->
|
||||
analyze(module) {
|
||||
module.readKlibDeclarationAddresses()
|
||||
.flatMap { address -> address.getSymbols() }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Test Strategy
|
||||
|
||||
### Black Box Test:
|
||||
|
||||
We are building a klib from the `testProject`.
|
||||
This klib will be used to read the addresses. Those addresses will be rendered and compared to
|
||||
[!testProject.addresses](testData%2F%21testProject.addresses)
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
explicitApi()
|
||||
|
||||
/* Required to use Analysis Api */
|
||||
freeCompilerArgs.add("-Xcontext-receivers")
|
||||
}
|
||||
}
|
||||
|
||||
projectTest(jUnitMode = JUnitMode.JUnit5) {
|
||||
workingDir = rootDir
|
||||
|
||||
useJUnitPlatform()
|
||||
val testProjectKlib = configurations.create("testProjectKlib") {
|
||||
attributes {
|
||||
attribute(Usage.USAGE_ATTRIBUTE, objects.named(KotlinUsages.KOTLIN_API))
|
||||
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY))
|
||||
attribute(KotlinPlatformType.attribute, KotlinPlatformType.native)
|
||||
attribute(KotlinNativeTarget.konanTargetAttribute, HostManager.host.name)
|
||||
}
|
||||
}
|
||||
|
||||
val testProjectKlibFiles = testProjectKlib.incoming.files
|
||||
|
||||
dependencies {
|
||||
testProjectKlib(project("testProject"))
|
||||
}
|
||||
|
||||
inputs.files(testProjectKlibFiles)
|
||||
.withPathSensitivity(PathSensitivity.RELATIVE)
|
||||
|
||||
doFirst {
|
||||
systemProperty("testKlibs", testProjectKlibFiles.joinToString(File.pathSeparator))
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":analysis:analysis-api"))
|
||||
|
||||
implementation(project(":core:compiler.common"))
|
||||
implementation(project(":core:compiler.common.native"))
|
||||
implementation(project(":kotlin-tooling-core"))
|
||||
|
||||
compileOnly(project(":analysis:analysis-api-standalone"))
|
||||
compileOnly(project(":core:metadata"))
|
||||
compileOnly(project(":kotlin-metadata"))
|
||||
compileOnly(project(":kotlin-util-klib-metadata"))
|
||||
compileOnly(protobufLite())
|
||||
|
||||
testImplementation(kotlinTest("junit5"))
|
||||
testImplementation(project(":compiler:tests-common", "tests-jar"))
|
||||
testImplementation(project(":analysis:analysis-api-standalone"))
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.analysis.api.klib.reader
|
||||
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
public sealed class KlibDeclarationAddress {
|
||||
public abstract val sourceFileName: String?
|
||||
public abstract val packageFqName: FqName
|
||||
}
|
||||
|
||||
public sealed class KlibClassifierAddress : KlibDeclarationAddress() {
|
||||
public abstract val classId: ClassId
|
||||
}
|
||||
|
||||
public data class KlibClassAddress(
|
||||
public override val sourceFileName: String?,
|
||||
public override val packageFqName: FqName,
|
||||
public override val classId: ClassId,
|
||||
) : KlibClassifierAddress()
|
||||
|
||||
public data class KlibTypeAliasAddress(
|
||||
override val packageFqName: FqName,
|
||||
override val classId: ClassId,
|
||||
) : KlibClassifierAddress() {
|
||||
/**
|
||||
* TypeAlias do not encode their source file name into klibs. This value is always null.
|
||||
*/
|
||||
override val sourceFileName: Nothing? = null
|
||||
}
|
||||
|
||||
public sealed class KlibCallableAddress : KlibDeclarationAddress() {
|
||||
public abstract val callableName: Name
|
||||
}
|
||||
|
||||
public data class KlibPropertyAddress(
|
||||
override val sourceFileName: String?,
|
||||
override val packageFqName: FqName,
|
||||
override val callableName: Name,
|
||||
) : KlibCallableAddress()
|
||||
|
||||
public data class KlibFunctionAddress(
|
||||
override val sourceFileName: String?,
|
||||
override val packageFqName: FqName,
|
||||
override val callableName: Name,
|
||||
) : KlibCallableAddress()
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.analysis.api.klib.reader
|
||||
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
|
||||
import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
internal fun PackageFragmentReadingContext(packageFragmentProto: ProtoBuf.PackageFragment): PackageFragmentReadingContext? {
|
||||
val nameResolver = NameResolverImpl(packageFragmentProto.strings, packageFragmentProto.qualifiedNames)
|
||||
val packageFqName = packageFragmentProto.`package`.getExtensionOrNull(KlibMetadataProtoBuf.packageFqName)
|
||||
?.let { packageFqNameStringIndex -> nameResolver.getPackageFqName(packageFqNameStringIndex) } ?: return null
|
||||
return PackageFragmentReadingContext(FqName(packageFqName), nameResolver)
|
||||
}
|
||||
|
||||
internal class PackageFragmentReadingContext(
|
||||
val packageFqName: FqName,
|
||||
val nameResolver: NameResolverImpl,
|
||||
)
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.analysis.api.klib.reader
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.StandaloneAnalysisAPISession
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtStaticProjectStructureProvider
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
|
||||
import org.jetbrains.kotlin.analysis.project.structure.allDirectDependencies
|
||||
import org.jetbrains.kotlin.tooling.core.withClosureSequence
|
||||
|
||||
/**
|
||||
* Returns all registered [KtLibraryModule] in this [StandaloneAnalysisAPISession].
|
||||
* Note: If a library module is not added as a dependency of another module, make sure to add the module directly as in:
|
||||
* ```kotlin
|
||||
* buildKtModuleProvider {
|
||||
* addModule( // <- !! addModule !!
|
||||
* buildKtLibraryModule {
|
||||
* addBinaryRoot(myKlibRootPath)
|
||||
* libraryName = myLibraryName
|
||||
* // ...
|
||||
* }
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
public fun StandaloneAnalysisAPISession.getAllLibraryModules(): Sequence<KtLibraryModule> {
|
||||
val projectStructureProvider = project.getService(ProjectStructureProvider::class.java)
|
||||
?: error("${ProjectStructureProvider::class.java} not found")
|
||||
|
||||
if (projectStructureProvider !is KtStaticProjectStructureProvider) {
|
||||
error("Expected implementation of ${KtStaticProjectStructureProvider::class.java} but found ${projectStructureProvider.javaClass}")
|
||||
}
|
||||
|
||||
return projectStructureProvider.allKtModules
|
||||
.withClosureSequence<KtModule> { module -> module.allDirectDependencies().asIterable() }
|
||||
.filterIsInstance<KtLibraryModule>()
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.analysis.api.klib.reader
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.*
|
||||
|
||||
/**
|
||||
* Note: A single [KlibDeclarationAddress] can be shared by multiple symbols.
|
||||
* e.g. the [KlibDeclarationAddress] for functions with overloads will be shared.
|
||||
*
|
||||
* ```kotlin
|
||||
* fun foo() = 42
|
||||
* fun foo(param: Int) = param
|
||||
* ```
|
||||
*
|
||||
* Both foo functions will live under the same [KlibDeclarationAddress]
|
||||
*
|
||||
* @return all symbols under the given [KlibDeclarationAddress].
|
||||
* @see [getClassOrObjectSymbol]
|
||||
* @see [getFunctionSymbols]
|
||||
* @see [getPropertySymbols]
|
||||
*/
|
||||
context(KtAnalysisSession)
|
||||
public fun KlibDeclarationAddress.getSymbols(): Sequence<KtSymbol> {
|
||||
return when (this) {
|
||||
is KlibClassAddress -> getClassOrObjectSymbol()?.let { symbol -> sequenceOf(symbol) } ?: emptySequence()
|
||||
is KlibTypeAliasAddress -> getTypeAliasSymbol()?.let { symbol -> sequenceOf(symbol) } ?: emptySequence()
|
||||
is KlibFunctionAddress -> getFunctionSymbols()
|
||||
is KlibPropertyAddress -> getPropertySymbols()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see [getSymbols]
|
||||
*/
|
||||
context(KtAnalysisSession)
|
||||
public fun KlibClassAddress.getClassOrObjectSymbol(): KtClassOrObjectSymbol? {
|
||||
return getClassOrObjectSymbolByClassId(classId)
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
public fun KlibTypeAliasAddress.getTypeAliasSymbol(): KtTypeAliasSymbol? {
|
||||
return getTypeAliasByClassId(classId)
|
||||
}
|
||||
|
||||
/**
|
||||
* @see [getSymbols]
|
||||
*/
|
||||
context(KtAnalysisSession)
|
||||
public fun KlibCallableAddress.getCallableSymbols(): Sequence<KtCallableSymbol> {
|
||||
return when (this) {
|
||||
is KlibFunctionAddress -> getFunctionSymbols()
|
||||
is KlibPropertyAddress -> getPropertySymbols()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see [getSymbols]
|
||||
*/
|
||||
context(KtAnalysisSession)
|
||||
public fun KlibFunctionAddress.getFunctionSymbols(): Sequence<KtFunctionSymbol> {
|
||||
return getTopLevelCallableSymbols(packageFqName, callableName)
|
||||
.filterIsInstance<KtFunctionSymbol>()
|
||||
}
|
||||
|
||||
/**
|
||||
* @see [getSymbols]
|
||||
*/
|
||||
context(KtAnalysisSession)
|
||||
public fun KlibPropertyAddress.getPropertySymbols(): Sequence<KtPropertySymbol> {
|
||||
return getTopLevelCallableSymbols(packageFqName, callableName)
|
||||
.filterIsInstance<KtPropertySymbol>()
|
||||
}
|
||||
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.analysis.api.klib.reader
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
|
||||
import org.jetbrains.kotlin.konan.file.File
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.library.ToolingSingleFileKlibResolveStrategy
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||
import org.jetbrains.kotlin.library.metadata.parseModuleHeader
|
||||
import org.jetbrains.kotlin.library.metadata.parsePackageFragment
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.util.DummyLogger
|
||||
import org.jetbrains.kotlin.util.Logger
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.extension
|
||||
import kotlin.io.path.isDirectory
|
||||
|
||||
/**
|
||||
* Provides a set of [KlibDeclarationAddress] contained within the given [KtLibraryModule] (if the library is based upon a klib file).
|
||||
* These addresses will contain all top level declarations such as top level classes, interfaces, objects, ... and
|
||||
* top level callables such as functions and properties.
|
||||
*
|
||||
* Example, given the provided source file
|
||||
* ```kotlin
|
||||
* package com.example
|
||||
* fun topLevelFunction() = 42
|
||||
*
|
||||
* class Foo {
|
||||
* val foo() = 42
|
||||
* class Bar {
|
||||
* fun bar() = 42
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* The read addresses will include `topLevelFunction` as well as `Foo`, as both declarations are top level.
|
||||
* These addresses can then be resolved to its given [KtSymbol] by
|
||||
*
|
||||
* - [KlibClassAddress.getClassOrObjectSymbol]: Resolves to the class symbol or null
|
||||
* - [KlibCallableAddress.getCallableSymbols]: Resolves all callable symbols under this given address
|
||||
*
|
||||
* @return The returned set has a stable order
|
||||
*/
|
||||
public fun KtLibraryModule.readKlibDeclarationAddresses(): Set<KlibDeclarationAddress>? {
|
||||
val binary = getBinaryRoots().singleOrNull() ?: return null
|
||||
if (!(binary.extension == "klib" || binary.isDirectory())) return null
|
||||
return readKlibDeclarationAddresses(binary)
|
||||
}
|
||||
|
||||
internal fun readKlibDeclarationAddresses(path: Path, logger: Logger = DummyLogger): Set<KlibDeclarationAddress>? {
|
||||
val library = ToolingSingleFileKlibResolveStrategy.tryResolve(File(path), logger) ?: return null
|
||||
return readKlibDeclarationAddresses(library)
|
||||
}
|
||||
|
||||
internal fun readKlibDeclarationAddresses(library: KotlinLibrary): Set<KlibDeclarationAddress> {
|
||||
val headerProto = parseModuleHeader(library.moduleHeaderData)
|
||||
|
||||
val packageMetadataSequence = headerProto.packageFragmentNameList.asSequence().flatMap { packageFragmentName ->
|
||||
library.packageMetadataParts(packageFragmentName).asSequence().map { packageMetadataPart ->
|
||||
library.packageMetadata(packageFragmentName, packageMetadataPart)
|
||||
}
|
||||
}
|
||||
|
||||
return packageMetadataSequence.flatMap { packageMetadata ->
|
||||
val packageFragmentProto = parsePackageFragment(packageMetadata)
|
||||
|
||||
with(PackageFragmentReadingContext(packageFragmentProto) ?: return@flatMap emptySet()) {
|
||||
packageFragmentProto.readKlibClassAddresses() +
|
||||
packageFragmentProto.readKlibTypeAliasAddresses() +
|
||||
packageFragmentProto.readKlibPropertyAddresses() +
|
||||
packageFragmentProto.readKlibFunctionAddresses()
|
||||
}
|
||||
}.toSet()
|
||||
|
||||
}
|
||||
|
||||
context(PackageFragmentReadingContext)
|
||||
internal fun ProtoBuf.PackageFragment.readKlibClassAddresses(): Set<KlibClassAddress> {
|
||||
return class_List.mapNotNull { classProto ->
|
||||
val classId = ClassId.fromString(nameResolver.getQualifiedClassName(classProto.fqName))
|
||||
if (classId.isNestedClass) return@mapNotNull null
|
||||
KlibClassAddress(
|
||||
packageFqName = packageFqName,
|
||||
sourceFileName = classProto.getExtensionOrNull(KlibMetadataProtoBuf.classFile)?.let { fileNameId ->
|
||||
nameResolver.strings.getString(fileNameId)
|
||||
},
|
||||
classId = classId
|
||||
)
|
||||
}.toSet()
|
||||
}
|
||||
|
||||
context(PackageFragmentReadingContext)
|
||||
internal fun ProtoBuf.PackageFragment.readKlibTypeAliasAddresses(): Set<KlibTypeAliasAddress> {
|
||||
return this.`package`.typeAliasList.map { typeAliasProto ->
|
||||
val name = Name.identifier(nameResolver.getString(typeAliasProto.name))
|
||||
KlibTypeAliasAddress(
|
||||
packageFqName = packageFqName,
|
||||
classId = ClassId(packageFqName, name)
|
||||
)
|
||||
}.toSet()
|
||||
}
|
||||
|
||||
context(PackageFragmentReadingContext)
|
||||
internal fun ProtoBuf.PackageFragment.readKlibPropertyAddresses(): Set<KlibPropertyAddress> {
|
||||
return `package`.propertyList.map { propertyProto ->
|
||||
KlibPropertyAddress(
|
||||
sourceFileName = propertyProto.getExtensionOrNull(KlibMetadataProtoBuf.propertyFile)?.let { fileNameId ->
|
||||
nameResolver.strings.getString(fileNameId)
|
||||
},
|
||||
packageFqName = packageFqName,
|
||||
callableName = Name.identifier(nameResolver.getString(propertyProto.name))
|
||||
)
|
||||
}.toSet()
|
||||
}
|
||||
|
||||
context(PackageFragmentReadingContext)
|
||||
internal fun ProtoBuf.PackageFragment.readKlibFunctionAddresses(): Set<KlibFunctionAddress> {
|
||||
return `package`.functionList.map { functionProto ->
|
||||
KlibFunctionAddress(
|
||||
sourceFileName = functionProto.getExtensionOrNull(KlibMetadataProtoBuf.functionFile)?.let { fileNameId ->
|
||||
nameResolver.getString(fileNameId)
|
||||
},
|
||||
packageFqName = packageFqName,
|
||||
callableName = Name.identifier(nameResolver.getString(functionProto.name))
|
||||
)
|
||||
}.toSet()
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.analysis.api.klib.reader.testUtils
|
||||
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.Path
|
||||
|
||||
val providedTestKlibs: Set<Path> = System.getProperty("testKlibs").let { testKlibs ->
|
||||
if (testKlibs == null) error("Missing 'testKlibs' System property")
|
||||
testKlibs.split(File.pathSeparator).map(::Path).toSet()
|
||||
}
|
||||
|
||||
val providedTestProjectKlib = providedTestKlibs.find { path ->
|
||||
path.contains(Path("testProject"))
|
||||
} ?: error("Missing 'testProject' klib")
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.analysis.api.klib.reader.testUtils
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.klib.reader.*
|
||||
|
||||
fun Iterable<KlibDeclarationAddress>.render() = joinToString(System.lineSeparator().repeat(2)) { it.render() }
|
||||
|
||||
fun KlibDeclarationAddress.render(): String {
|
||||
return when (this) {
|
||||
is KlibFunctionAddress -> render()
|
||||
is KlibPropertyAddress -> render()
|
||||
is KlibClassAddress -> render()
|
||||
is KlibTypeAliasAddress -> render()
|
||||
}
|
||||
}
|
||||
|
||||
private fun KlibFunctionAddress.render(): String = """
|
||||
Function (${packageFqName.child(callableName).asString()})
|
||||
Source File Name : "$sourceFileName"
|
||||
Package Name : "${packageFqName.asString()}"
|
||||
Function Name : "${callableName.asString()}"
|
||||
""".trimIndent()
|
||||
|
||||
private fun KlibPropertyAddress.render(): String = """
|
||||
Property (${packageFqName.child(callableName).asString()})
|
||||
Source File Name : "$sourceFileName"
|
||||
Package Name : "${packageFqName.asString()}"
|
||||
Property Name : "${callableName.asString()}"
|
||||
""".trimIndent()
|
||||
|
||||
private fun KlibClassAddress.render(): String = """
|
||||
Class (${classId.asFqNameString()})
|
||||
Source File Name : "$sourceFileName"
|
||||
Package Name : "${packageFqName.asString()}"
|
||||
ClassId : "${classId.asString()}"
|
||||
""".trimIndent()
|
||||
|
||||
private fun KlibTypeAliasAddress.render(): String = """
|
||||
TypeAlias (${classId.asFqNameString()})
|
||||
Package Name : "${packageFqName.asString()}"
|
||||
ClassId : "${classId.asString()}"
|
||||
""".trimIndent()
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.analysis.api.klib.reader.testUtils
|
||||
|
||||
import kotlin.io.path.Path
|
||||
|
||||
val testDataDir = Path("native/analysis-api-klib-reader/testData")
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.analysis.api.klib.reader.tests
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.analyze
|
||||
import org.jetbrains.kotlin.analysis.api.klib.reader.*
|
||||
import org.jetbrains.kotlin.analysis.api.klib.reader.testUtils.providedTestProjectKlib
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenProvider
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.KtAlwaysAccessibleLifetimeTokenProvider
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.buildStandaloneAnalysisAPISession
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.nameOrAnonymous
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.builder.buildKtLibraryModule
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.konan.NativePlatforms
|
||||
import kotlin.io.path.nameWithoutExtension
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.fail
|
||||
|
||||
class GetSymbolsTest {
|
||||
@Test
|
||||
fun `test - getClassOrObjectSymbol - RootPkgClass`() {
|
||||
withTestProjectLibraryAnalysisSession {
|
||||
val addresses = (useSiteModule as KtLibraryModule).readKlibDeclarationAddresses()
|
||||
?: error("Failed reading declaration addresses")
|
||||
|
||||
val rootPkgClassAddress = addresses.filterIsInstance<KlibClassAddress>()
|
||||
.first { it.classId == ClassId.fromString("RootPkgClass") }
|
||||
|
||||
|
||||
val rootPkgClassSymbol = assertNotNull(rootPkgClassAddress.getClassOrObjectSymbol())
|
||||
|
||||
assertEquals("RootPkgClass", rootPkgClassSymbol.nameOrAnonymous.asString())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - getClassOrObjectSymbol - AObject`() {
|
||||
withTestProjectLibraryAnalysisSession {
|
||||
val addresses = (useSiteModule as KtLibraryModule).readKlibDeclarationAddresses()
|
||||
?: error("Failed reading declaration addresses")
|
||||
|
||||
val aObjectAddress = addresses.filterIsInstance<KlibClassAddress>()
|
||||
.first { it.classId == ClassId.fromString("org/jetbrains/sample/a/AObject") }
|
||||
|
||||
|
||||
val aObjectSymbol = assertNotNull(aObjectAddress.getClassOrObjectSymbol())
|
||||
|
||||
assertEquals("AObject", aObjectSymbol.nameOrAnonymous.asString())
|
||||
assertEquals(KtClassKind.OBJECT, aObjectSymbol.classKind)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - getSymbols - rootPkgProperty`() {
|
||||
withTestProjectLibraryAnalysisSession {
|
||||
val addresses = (useSiteModule as KtLibraryModule).readKlibDeclarationAddresses()
|
||||
?: error("Failed reading declaration addresses")
|
||||
|
||||
val rootPkgPropertyAddress = addresses.filterIsInstance<KlibPropertyAddress>()
|
||||
.first { it.callableName == Name.identifier("rootPkgProperty") }
|
||||
|
||||
val rootPkgPropertySymbols = rootPkgPropertyAddress.getSymbols().toList()
|
||||
if (rootPkgPropertySymbols.size != 1) fail("Expected only a single 'rootPkgProperty' symbol. Found $rootPkgPropertySymbols")
|
||||
|
||||
/* Check getSymbols and getPropertySymbols behave the same */
|
||||
assertEquals(
|
||||
rootPkgPropertySymbols,
|
||||
rootPkgPropertyAddress.getPropertySymbols().toList(),
|
||||
"Expected 'getSymbols' and 'getPropertySymbols' to be equal"
|
||||
)
|
||||
|
||||
val symbol = rootPkgPropertySymbols.single() as KtPropertySymbol
|
||||
assertEquals("rootPkgProperty", symbol.name.asString())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - getSymbols - aFunction`() {
|
||||
withTestProjectLibraryAnalysisSession {
|
||||
val addresses = (useSiteModule as KtLibraryModule).readKlibDeclarationAddresses()
|
||||
?: error("Failed reading declaration addresses")
|
||||
|
||||
val aFunctionAddress = addresses.filterIsInstance<KlibFunctionAddress>()
|
||||
.first { it.callableName == Name.identifier("aFunction") }
|
||||
|
||||
val aFunctionSymbols = aFunctionAddress.getFunctionSymbols().toList()
|
||||
if (aFunctionSymbols.size != 2) fail("Expected exactly 2 'aFunction' symbols. Found $aFunctionSymbols")
|
||||
|
||||
/* Check: getFunctionSymbols and getSymbols behave the same */
|
||||
assertEquals(
|
||||
aFunctionSymbols,
|
||||
aFunctionAddress.getSymbols().toList(),
|
||||
"Expected 'getSymbols' and 'getFunctionSymbols' to be equal"
|
||||
)
|
||||
|
||||
aFunctionSymbols.forEach { symbol ->
|
||||
assertEquals("aFunction", symbol.name.asString())
|
||||
}
|
||||
|
||||
/* Check: One function does not have any value params, the other function has a single param with name 'seed' */
|
||||
assertEquals(
|
||||
setOf(emptyList(), listOf("seed")), aFunctionSymbols.map { it.valueParameters.map { it.name.asString() } }.toSet()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - getTypeAlias - TypeAliasA`() {
|
||||
withTestProjectLibraryAnalysisSession {
|
||||
val addresses = (useSiteModule as KtLibraryModule).readKlibDeclarationAddresses() ?: fail("Failed reading addresses")
|
||||
val typeAliasAAddress = addresses.filterIsInstance<KlibTypeAliasAddress>()
|
||||
.find { it.classId == ClassId.fromString("org/jetbrains/sample/TypeAliasA") }
|
||||
?: fail("Could not find TypeAliasA")
|
||||
|
||||
val typeAliasASymbol = assertNotNull(typeAliasAAddress.getTypeAliasSymbol())
|
||||
assertEquals(Name.identifier("TypeAliasA"), typeAliasASymbol.name)
|
||||
assertEquals(Name.identifier("AClass"), typeAliasASymbol.expandedType.expandedClassSymbol?.name)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the given [block] in an analysis session that will have the built library as [KtAnalysisSession.useSiteModule]
|
||||
*/
|
||||
private fun <T> withTestProjectLibraryAnalysisSession(block: context(KtAnalysisSession) () -> T): T {
|
||||
val session = buildStandaloneAnalysisAPISession {
|
||||
val currentArchitectureTarget = HostManager.host
|
||||
val nativePlatform = NativePlatforms.nativePlatformByTargets(listOf(currentArchitectureTarget))
|
||||
|
||||
@OptIn(KtAnalysisApiInternals::class)
|
||||
registerProjectService(KtLifetimeTokenProvider::class.java, KtAlwaysAccessibleLifetimeTokenProvider())
|
||||
|
||||
buildKtModuleProvider {
|
||||
platform = nativePlatform
|
||||
addModule(buildKtLibraryModule {
|
||||
addBinaryRoot(providedTestProjectKlib)
|
||||
platform = nativePlatform
|
||||
libraryName = providedTestProjectKlib.nameWithoutExtension
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return analyze(session.getAllLibraryModules().single()) {
|
||||
block(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.analysis.api.klib.reader.tests
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.klib.reader.readKlibDeclarationAddresses
|
||||
import org.jetbrains.kotlin.analysis.api.klib.reader.testUtils.providedTestProjectKlib
|
||||
import org.jetbrains.kotlin.analysis.api.klib.reader.testUtils.render
|
||||
import org.jetbrains.kotlin.analysis.api.klib.reader.testUtils.testDataDir
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.fail
|
||||
|
||||
class ReadKlibDeclarationAddressesBlackBoxTest {
|
||||
|
||||
@Test
|
||||
fun `test - testProject`() {
|
||||
val addresses = readKlibDeclarationAddresses(providedTestProjectKlib) ?: fail("Failed loading klib: $providedTestProjectKlib")
|
||||
KotlinTestUtils.assertEqualsToFile(testDataDir.resolve("!testProject.addresses"), addresses.render())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
Property (rootPkgProperty)
|
||||
Source File Name : "RootPkgCallables.kt"
|
||||
Package Name : ""
|
||||
Property Name : "rootPkgProperty"
|
||||
|
||||
Function (rootPkgFunction)
|
||||
Source File Name : "RootPkgCallables.kt"
|
||||
Package Name : ""
|
||||
Function Name : "rootPkgFunction"
|
||||
|
||||
Class (RootPkgClass)
|
||||
Source File Name : "RootPkgClass.kt"
|
||||
Package Name : ""
|
||||
ClassId : "RootPkgClass"
|
||||
|
||||
Property (org.jetbrains.sample.constantInt)
|
||||
Source File Name : "Constants.kt"
|
||||
Package Name : "org.jetbrains.sample"
|
||||
Property Name : "constantInt"
|
||||
|
||||
Property (org.jetbrains.sample.constantString)
|
||||
Source File Name : "Constants.kt"
|
||||
Package Name : "org.jetbrains.sample"
|
||||
Property Name : "constantString"
|
||||
|
||||
Property (org.jetbrains.sample.aExtensionProperty)
|
||||
Source File Name : "Extensions.kt"
|
||||
Package Name : "org.jetbrains.sample"
|
||||
Property Name : "aExtensionProperty"
|
||||
|
||||
Function (org.jetbrains.sample.aExtensionFun)
|
||||
Source File Name : "Extensions.kt"
|
||||
Package Name : "org.jetbrains.sample"
|
||||
Function Name : "aExtensionFun"
|
||||
|
||||
Class (org.jetbrains.sample.GenericClass)
|
||||
Source File Name : "Generics.kt"
|
||||
Package Name : "org.jetbrains.sample"
|
||||
ClassId : "org/jetbrains/sample/GenericClass"
|
||||
|
||||
Property (org.jetbrains.sample.genericProperty)
|
||||
Source File Name : "Generics.kt"
|
||||
Package Name : "org.jetbrains.sample"
|
||||
Property Name : "genericProperty"
|
||||
|
||||
Function (org.jetbrains.sample.genericFun)
|
||||
Source File Name : "Generics.kt"
|
||||
Package Name : "org.jetbrains.sample"
|
||||
Function Name : "genericFun"
|
||||
|
||||
Class (org.jetbrains.sample.PrivateClass)
|
||||
Source File Name : "SymbolsWithDifferentVisibilities.kt"
|
||||
Package Name : "org.jetbrains.sample"
|
||||
ClassId : "org/jetbrains/sample/PrivateClass"
|
||||
|
||||
Class (org.jetbrains.sample.InternalClass)
|
||||
Source File Name : "SymbolsWithDifferentVisibilities.kt"
|
||||
Package Name : "org.jetbrains.sample"
|
||||
ClassId : "org/jetbrains/sample/InternalClass"
|
||||
|
||||
Class (org.jetbrains.sample.PublicClass)
|
||||
Source File Name : "SymbolsWithDifferentVisibilities.kt"
|
||||
Package Name : "org.jetbrains.sample"
|
||||
ClassId : "org/jetbrains/sample/PublicClass"
|
||||
|
||||
Function (org.jetbrains.sample.privateFun)
|
||||
Source File Name : "SymbolsWithDifferentVisibilities.kt"
|
||||
Package Name : "org.jetbrains.sample"
|
||||
Function Name : "privateFun"
|
||||
|
||||
Function (org.jetbrains.sample.internalFun)
|
||||
Source File Name : "SymbolsWithDifferentVisibilities.kt"
|
||||
Package Name : "org.jetbrains.sample"
|
||||
Function Name : "internalFun"
|
||||
|
||||
Function (org.jetbrains.sample.publicFun)
|
||||
Source File Name : "SymbolsWithDifferentVisibilities.kt"
|
||||
Package Name : "org.jetbrains.sample"
|
||||
Function Name : "publicFun"
|
||||
|
||||
TypeAlias (org.jetbrains.sample.TypeAliasA)
|
||||
Package Name : "org.jetbrains.sample"
|
||||
ClassId : "org/jetbrains/sample/TypeAliasA"
|
||||
|
||||
TypeAlias (org.jetbrains.sample.TypeAliasB)
|
||||
Package Name : "org.jetbrains.sample"
|
||||
ClassId : "org/jetbrains/sample/TypeAliasB"
|
||||
|
||||
Property (org.jetbrains.sample.a.aProperty)
|
||||
Source File Name : "ACallables.kt"
|
||||
Package Name : "org.jetbrains.sample.a"
|
||||
Property Name : "aProperty"
|
||||
|
||||
Function (org.jetbrains.sample.a.aFunction)
|
||||
Source File Name : "ACallables.kt"
|
||||
Package Name : "org.jetbrains.sample.a"
|
||||
Function Name : "aFunction"
|
||||
|
||||
Class (org.jetbrains.sample.a.AClass)
|
||||
Source File Name : "AClass.kt"
|
||||
Package Name : "org.jetbrains.sample.a"
|
||||
ClassId : "org/jetbrains/sample/a/AClass"
|
||||
|
||||
Class (org.jetbrains.sample.a.AObject)
|
||||
Source File Name : "AObject.kt"
|
||||
Package Name : "org.jetbrains.sample.a"
|
||||
ClassId : "org/jetbrains/sample/a/AObject"
|
||||
|
||||
Class (org.jetbrains.sample.b.BClass)
|
||||
Source File Name : "BClass.kt"
|
||||
Package Name : "org.jetbrains.sample.b"
|
||||
ClassId : "org/jetbrains/sample/b/BClass"
|
||||
|
||||
Function (org.jetbrains.sample.filePrivateSymbolsClash.foo)
|
||||
Source File Name : "A.kt"
|
||||
Package Name : "org.jetbrains.sample.filePrivateSymbolsClash"
|
||||
Function Name : "foo"
|
||||
|
||||
Function (org.jetbrains.sample.filePrivateSymbolsClash.foo)
|
||||
Source File Name : "B.kt"
|
||||
Package Name : "org.jetbrains.sample.filePrivateSymbolsClash"
|
||||
Function Name : "foo"
|
||||
@@ -0,0 +1,11 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
macosArm64()
|
||||
macosX64()
|
||||
linuxX64()
|
||||
linuxArm64()
|
||||
mingwX64()
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# https://youtrack.jetbrains.com/issue/KT-65985
|
||||
kotlin.native.toolchain.enabled=false
|
||||
kotlin.native.distribution.downloadFromMaven=false
|
||||
@@ -0,0 +1,14 @@
|
||||
@file:Suppress("unused")
|
||||
|
||||
import kotlin.random.Random
|
||||
|
||||
/*
|
||||
* Copyright 2010-2024 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.
|
||||
*/
|
||||
|
||||
val rootPkgProperty get() = Random.nextInt()
|
||||
|
||||
fun rootPkgFunction() = Random.nextInt()
|
||||
|
||||
fun rootPkgFunction(seed: Int) = Random(seed).nextInt()
|
||||
@@ -0,0 +1,10 @@
|
||||
@file:Suppress("unused")
|
||||
/*
|
||||
* Copyright 2010-2024 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.
|
||||
*/
|
||||
|
||||
class RootPkgClass {
|
||||
fun foo() = Unit
|
||||
class Nested
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package org.jetbrains.sample
|
||||
|
||||
const val constantInt = 42
|
||||
|
||||
const val constantString = "Hello There!"
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package org.jetbrains.sample
|
||||
|
||||
import org.jetbrains.sample.a.AClass
|
||||
|
||||
fun AClass.aExtensionFun() = this.toString()
|
||||
|
||||
val AClass.aExtensionProperty get() = this.toString()
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package org.jetbrains.sample
|
||||
|
||||
class GenericClass<T> {
|
||||
fun foo(value: T) = value
|
||||
}
|
||||
|
||||
fun <T> genericFun(value: T) = value.toString()
|
||||
|
||||
val <T> T.genericProperty get() = toString()
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package org.jetbrains.sample
|
||||
|
||||
private class PrivateClass
|
||||
|
||||
internal class InternalClass
|
||||
|
||||
class PublicClass
|
||||
|
||||
private fun privateFun() = 42
|
||||
|
||||
internal fun internalFun() = 42
|
||||
|
||||
fun publicFun() = 42
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package org.jetbrains.sample
|
||||
|
||||
import org.jetbrains.sample.a.AClass
|
||||
import org.jetbrains.sample.b.BClass
|
||||
|
||||
typealias TypeAliasA = AClass
|
||||
|
||||
internal typealias TypeAliasB = BClass
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package org.jetbrains.sample.a
|
||||
|
||||
import kotlin.random.Random
|
||||
|
||||
val aProperty get() = Random.nextInt()
|
||||
|
||||
fun aFunction() = Random.nextInt()
|
||||
|
||||
fun aFunction(seed: Int) = Random(seed).nextInt()
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package org.jetbrains.sample.a
|
||||
|
||||
class AClass {
|
||||
class Nested
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package org.jetbrains.sample.a
|
||||
|
||||
object AObject {
|
||||
class Nested
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package org.jetbrains.sample.b
|
||||
|
||||
class BClass
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package org.jetbrains.sample.filePrivateSymbolsClash
|
||||
|
||||
private fun foo() = 42
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package org.jetbrains.sample.filePrivateSymbolsClash
|
||||
|
||||
private fun foo() = 42
|
||||
+4
-1
@@ -167,7 +167,10 @@ fun Project.configureKotlinCompilationOptions() {
|
||||
// This is a workaround for KT-50876, but with no clear explanation why doFirst is used.
|
||||
// However, KGP with Native targets is used in the native-xctest project, and this code fails with
|
||||
// The value for property 'freeCompilerArgs' is final and cannot be changed any further.
|
||||
if (project.path != ":native:kotlin-test-native-xctest" && !project.path.startsWith(":native:objcexport-header-generator")) {
|
||||
if (project.path != ":native:kotlin-test-native-xctest" &&
|
||||
!project.path.startsWith(":native:objcexport-header-generator") &&
|
||||
!project.path.startsWith(":native:analysis-api-klib-reader")
|
||||
) {
|
||||
doFirst {
|
||||
if (!useAbsolutePathsInKlib) {
|
||||
@Suppress("DEPRECATION")
|
||||
|
||||
@@ -118,6 +118,8 @@ include ":benchmarks",
|
||||
":native:kotlin-klib-commonizer-embeddable",
|
||||
":native:executors",
|
||||
":native:base",
|
||||
":native:analysis-api-klib-reader",
|
||||
":native:analysis-api-klib-reader:testProject",
|
||||
":native:objcexport-header-generator",
|
||||
":native:objcexport-header-generator-k1",
|
||||
":native:objcexport-header-generator-analysis-api",
|
||||
|
||||
Reference in New Issue
Block a user