[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"
|
/license/ "Kotlin Build Infrastructure"
|
||||||
|
|
||||||
/native/ "Kotlin Native"
|
/native/ "Kotlin Native"
|
||||||
|
/native/analysis-api-klib-reader/ "Kotlin Native" "Kotlin in Fleet"
|
||||||
/native/commonizer/ "Kotlin Apple Ecosystem"
|
/native/commonizer/ "Kotlin Apple Ecosystem"
|
||||||
/native/commonizer-api/ "Kotlin Apple Ecosystem"
|
/native/commonizer-api/ "Kotlin Apple Ecosystem"
|
||||||
/native/commonizer-embeddable/ "Kotlin Apple Ecosystem"
|
/native/commonizer-embeddable/ "Kotlin Apple Ecosystem"
|
||||||
|
|||||||
+2
-1
@@ -811,10 +811,11 @@ tasks {
|
|||||||
// - different GCs
|
// - different GCs
|
||||||
// ...
|
// ...
|
||||||
register("nativeCompilerTest") {
|
register("nativeCompilerTest") {
|
||||||
|
dependsOn(":kotlin-atomicfu-compiler-plugin:nativeTest")
|
||||||
|
dependsOn(":native:analysis-api-klib-reader:check")
|
||||||
dependsOn(":native:native.tests:test")
|
dependsOn(":native:native.tests:test")
|
||||||
dependsOn(":native:objcexport-header-generator:check")
|
dependsOn(":native:objcexport-header-generator:check")
|
||||||
dependsOn(":native:swift:swift-export-standalone:test")
|
dependsOn(":native:swift:swift-export-standalone:test")
|
||||||
dependsOn(":kotlin-atomicfu-compiler-plugin:nativeTest")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are unit tests of Native compiler
|
// 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.
|
// 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
|
// 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.
|
// 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 {
|
doFirst {
|
||||||
if (!useAbsolutePathsInKlib) {
|
if (!useAbsolutePathsInKlib) {
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
|
|||||||
@@ -118,6 +118,8 @@ include ":benchmarks",
|
|||||||
":native:kotlin-klib-commonizer-embeddable",
|
":native:kotlin-klib-commonizer-embeddable",
|
||||||
":native:executors",
|
":native:executors",
|
||||||
":native:base",
|
":native:base",
|
||||||
|
":native:analysis-api-klib-reader",
|
||||||
|
":native:analysis-api-klib-reader:testProject",
|
||||||
":native:objcexport-header-generator",
|
":native:objcexport-header-generator",
|
||||||
":native:objcexport-header-generator-k1",
|
":native:objcexport-header-generator-k1",
|
||||||
":native:objcexport-header-generator-analysis-api",
|
":native:objcexport-header-generator-analysis-api",
|
||||||
|
|||||||
Reference in New Issue
Block a user