Rename Kotlin/Native modules for uniformity

This commit is contained in:
Dmitriy Dolovov
2020-01-29 15:55:56 +07:00
parent abd86107d1
commit 9594b8db42
218 changed files with 21 additions and 21 deletions
+83
View File
@@ -0,0 +1,83 @@
import org.gradle.api.artifacts.maven.Conf2ScopeMappingContainer.COMPILE
plugins {
maven
kotlin("jvm")
id("jps-compatible")
}
val mavenCompileScope by configurations.creating {
the<MavenPluginConvention>()
.conf2ScopeMappings
.addMapping(0, this, COMPILE)
}
description = "Kotlin/Native library commonizer"
dependencies {
compileOnly(project(":compiler:cli-common"))
compileOnly(project(":compiler:frontend"))
compileOnly(project(":compiler:ir.serialization.common"))
// This dependency is necessary to keep the right dependency record inside of POM file:
mavenCompileScope(project(":kotlin-compiler"))
compile(kotlinStdlib())
compile(project(":kotlin-util-klib-metadata"))
compile(project(":native:kotlin-native-utils")) { isTransitive = false }
compile(project(":native:frontend.native")) { isTransitive = false }
testCompile(commonDep("junit:junit"))
testCompile(projectTests(":compiler:tests-common"))
testCompile(intellijCoreDep()) { includeJars("intellij-core") }
testCompile(intellijDep()) {
includeJars(
"openapi",
"jps-model",
"extensions",
"util",
"platform-api",
"platform-impl",
"idea",
"idea_rt",
"guava",
"trove4j",
"picocontainer",
"asm-all",
"log4j",
"jdom",
"streamex",
"bootstrap",
rootProject = rootProject
)
isTransitive = false
}
Platform[192].orHigher {
testCompile(intellijDep()) { includeJars("platform-util-ui", "platform-concurrency", "platform-objectSerializer") }
}
}
val runCommonizer by tasks.registering(NoDebugJavaExec::class) {
classpath(sourceSets.main.get().runtimeClasspath)
main = "org.jetbrains.kotlin.descriptors.commonizer.cli.NativeDistributionCommonizerKt"
}
sourceSets {
"main" {
projectDefault()
runtimeClasspath += configurations.compileOnly
}
"test" { projectDefault() }
}
projectTest(parallel = true) {
dependsOn(":dist")
workingDir = rootDir
}
publish()
standardPublicJars()
@@ -0,0 +1,42 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
class CommonizationParameters(
val statsCollector: StatsCollector? = null
) {
// use linked hash map to preserve order
private val modulesByTargets = LinkedHashMap<InputTarget, Collection<ModuleDescriptor>>()
fun addTarget(target: InputTarget, modules: Collection<ModuleDescriptor>): CommonizationParameters {
require(target !in modulesByTargets) { "Target $target is already added" }
val modulesWithUniqueNames = modules.groupingBy { it.name }.eachCount()
require(modulesWithUniqueNames.size == modules.size) {
"Modules with duplicated names found: ${modulesWithUniqueNames.filter { it.value > 1 }}"
}
modulesByTargets[target] = modules
return this
}
// get them as ordered immutable collection (List) for further processing
fun getModulesByTargets(): List<Pair<InputTarget, Collection<ModuleDescriptor>>> =
modulesByTargets.map { it.key to it.value }
fun hasIntersection(): Boolean {
if (modulesByTargets.size < 2)
return false
return modulesByTargets.flatMap { it.value }
.groupingBy { it.name }
.eachCount()
.any { it.value == modulesByTargets.size }
}
}
@@ -0,0 +1,24 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
sealed class CommonizationResult
object NothingToCommonize : CommonizationResult()
class CommonizationPerformed(
val modulesByTargets: Map<Target, Collection<ModuleDescriptor>>
) : CommonizationResult() {
val commonTarget: OutputTarget by lazy {
modulesByTargets.keys.filterIsInstance<OutputTarget>().single()
}
val concreteTargets: Set<InputTarget> by lazy {
modulesByTargets.keys.filterIsInstance<InputTarget>().toSet()
}
}
@@ -0,0 +1,13 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import java.io.Closeable
interface StatsCollector : Closeable {
fun logStats(output: List<DeclarationDescriptor?>)
}
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer
import org.jetbrains.kotlin.konan.target.KonanTarget
// N.B. TargetPlatform/SimplePlatform are non exhaustive enough to address both target platforms such as
// JVM, JS and concrete Kotlin/Native targets, e.g. macos_x64, ios_x64, linux_x64.
sealed class Target
data class InputTarget(val name: String, val konanTarget: KonanTarget? = null) : Target()
data class OutputTarget(val targets: Set<Target>) : Target() {
init {
require(targets.isNotEmpty())
}
}
@@ -0,0 +1,52 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind.ANNOTATION_CLASS
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirAnnotation
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.AnnotationValue
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.storage.getValue
class CommonizedAnnotationDescriptor(
private val targetComponents: TargetDeclarationsBuilderComponents,
override val fqName: FqName,
rawValueArguments: Map<Name, ConstantValue<*>>
) : AnnotationDescriptor {
constructor(targetComponents: TargetDeclarationsBuilderComponents, cirAnnotation: CirAnnotation) : this(
targetComponents,
cirAnnotation.fqName,
cirAnnotation.allValueArguments
)
override val type by targetComponents.storageManager.createLazyValue {
val annotationClass = findClassOrTypeAlias(targetComponents, fqName)
check(annotationClass is ClassDescriptor && annotationClass.kind == ANNOTATION_CLASS) {
"Not an annotation class: ${annotationClass::class.java}, $annotationClass"
}
annotationClass.defaultType
}
override val allValueArguments by targetComponents.storageManager.createLazyValue {
rawValueArguments.mapValues { (_, value) -> substituteValueArgument(value) }
}
override val source: SourceElement get() = SourceElement.NO_SOURCE
private fun substituteValueArgument(value: ConstantValue<*>) =
(value as? AnnotationValue)?.value?.let { nestedAnnotationDescriptor ->
// re-build annotation descriptors
val fqName = nestedAnnotationDescriptor.fqName
?: error("Annotation with no FQ name: ${nestedAnnotationDescriptor::class.java}, $nestedAnnotationDescriptor")
AnnotationValue(CommonizedAnnotationDescriptor(targetComponents, fqName, nestedAnnotationDescriptor.allValueArguments))
} ?: value // keep other values as they are platform agnostic
}
@@ -0,0 +1,150 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirTypeParameter
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorFactory.*
import org.jetbrains.kotlin.resolve.descriptorUtil.computeSealedSubclasses
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinEnum
import org.jetbrains.kotlin.types.AbstractClassTypeConstructor
import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
class CommonizedClassDescriptor(
targetComponents: TargetDeclarationsBuilderComponents,
containingDeclaration: DeclarationDescriptor,
override val annotations: Annotations,
name: Name,
private val kind: ClassKind,
private val modality: Modality,
private val visibility: Visibility,
private val isCompanion: Boolean,
private val isData: Boolean,
private val isInline: Boolean,
private val isInner: Boolean,
isExternal: Boolean,
private val isExpect: Boolean,
private val isActual: Boolean,
cirDeclaredTypeParameters: List<CirTypeParameter>,
companionObjectName: Name?,
cirSupertypes: Collection<CirType>
) : ClassDescriptorBase(targetComponents.storageManager, containingDeclaration, name, SourceElement.NO_SOURCE, isExternal) {
private lateinit var _unsubstitutedMemberScope: CommonizedMemberScope
private lateinit var constructors: Collection<ClassConstructorDescriptor>
private var primaryConstructor: ClassConstructorDescriptor? = null
private val staticScope = if (kind == ClassKind.ENUM_CLASS)
StaticScopeForKotlinEnum(targetComponents.storageManager, this)
else
MemberScope.Empty
private val typeConstructor = CommonizedClassTypeConstructor(targetComponents, cirSupertypes)
private val sealedSubclasses = targetComponents.storageManager.createLazyValue { computeSealedSubclasses(this) }
private val declaredTypeParametersAndTypeParameterResolver = targetComponents.storageManager.createLazyValue {
val parent = if (isInner) (containingDeclaration as? ClassDescriptor)?.getTypeParameterResolver() else null
cirDeclaredTypeParameters.buildDescriptorsAndTypeParameterResolver(
targetComponents,
parent ?: TypeParameterResolver.EMPTY,
this
)
}
private val companionObjectDescriptor = targetComponents.storageManager.createNullableLazyValue {
if (companionObjectName != null)
unsubstitutedMemberScope.getContributedClassifier(companionObjectName, NoLookupLocation.FOR_ALREADY_TRACKED) as? ClassDescriptor
else
null
}
override fun getKind() = kind
override fun getModality() = modality
override fun getVisibility() = visibility
override fun isCompanionObject() = isCompanion
override fun isData() = isData
override fun isInline() = isInline
override fun isInner() = isInner
override fun isExpect() = isExpect
override fun isActual() = isActual
override fun isFun() = false // TODO: modifier "fun" should be accessible from here too
override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): CommonizedMemberScope {
check(kotlinTypeRefiner == KotlinTypeRefiner.Default) {
"${kotlinTypeRefiner::class.java} is not supported in ${this::class.java}"
}
return _unsubstitutedMemberScope
}
override fun getUnsubstitutedMemberScope(): CommonizedMemberScope = super.getUnsubstitutedMemberScope() as CommonizedMemberScope
fun setUnsubstitutedMemberScope(unsubstitutedMemberScope: CommonizedMemberScope) {
_unsubstitutedMemberScope = unsubstitutedMemberScope
}
override fun getDeclaredTypeParameters() = declaredTypeParametersAndTypeParameterResolver().first
val typeParameterResolver: TypeParameterResolver get() = declaredTypeParametersAndTypeParameterResolver().second
override fun getConstructors() = constructors
override fun getUnsubstitutedPrimaryConstructor() = primaryConstructor
override fun getStaticScope(): MemberScope = staticScope
override fun getTypeConstructor(): TypeConstructor = typeConstructor
override fun getCompanionObjectDescriptor() = companionObjectDescriptor()
override fun getSealedSubclasses() = sealedSubclasses()
fun initialize(constructors: Collection<CommonizedClassConstructorDescriptor>) {
if (isExpect && kind.isSingleton) {
check(constructors.isEmpty())
primaryConstructor = if (kind == ClassKind.ENUM_ENTRY)
createPrimaryConstructorForObject(this, SourceElement.NO_SOURCE).apply { returnType = getDefaultType() }
else
null
this.constructors = listOfNotNull(primaryConstructor)
} else {
constructors.forEach { it.returnType = getDefaultType() }
primaryConstructor = constructors.firstOrNull { it.isPrimary }
this.constructors = constructors
}
}
override fun toString() = (if (isExpect) "expect " else if (isActual) "actual " else "") + "class " + name.toString()
private inner class CommonizedClassTypeConstructor(
targetComponents: TargetDeclarationsBuilderComponents,
cirSupertypes: Collection<CirType>
) : AbstractClassTypeConstructor(targetComponents.storageManager) {
private val parameters = targetComponents.storageManager.createLazyValue {
this@CommonizedClassDescriptor.computeConstructorTypeParameters()
}
private val supertypes = targetComponents.storageManager.createLazyValue {
cirSupertypes.map { it.buildType(targetComponents, this@CommonizedClassDescriptor.typeParameterResolver) }
}
override fun getParameters() = parameters()
override fun computeSupertypes() = supertypes()
override fun isDenotable() = true
override fun getDeclarationDescriptor() = this@CommonizedClassDescriptor
override val supertypeLoopChecker get() = SupertypeLoopChecker.EMPTY
}
}
class CommonizedClassConstructorDescriptor(
containingDeclaration: ClassDescriptor,
annotations: Annotations,
isPrimary: Boolean,
kind: CallableMemberDescriptor.Kind
) : ClassConstructorDescriptorImpl(containingDeclaration, null, annotations, isPrimary, kind, SourceElement.NO_SOURCE)
@@ -0,0 +1,71 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
import org.jetbrains.kotlin.utils.Printer
class CommonizedMemberScope : MemberScopeImpl() {
private val members = ArrayList<DeclarationDescriptor>()
operator fun plusAssign(member: DeclarationDescriptor) {
this.members += member
}
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? =
members.filteredBy<ClassifierDescriptor>(name).firstOrNull()
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> =
members.filteredBy<PropertyDescriptor>(name).toList()
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> =
members.filteredBy<SimpleFunctionDescriptor>(name).toList()
override fun getContributedDescriptors(
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean
): Collection<DeclarationDescriptor> = members.filter { kindFilter.accepts(it) && nameFilter(it.name) }
override fun printScopeStructure(p: Printer) {
p.println(this::class.java.simpleName, " {")
p.pushIndent()
p.println("declarations = $members")
p.popIndent()
p.println("}")
}
companion object {
fun createArray(size: Int) = Array(size) { CommonizedMemberScope() }
operator fun Array<CommonizedMemberScope>.plusAssign(members: List<DeclarationDescriptor?>) {
members.forEachIndexed { index, member ->
if (member != null) {
this[index] += member
}
}
}
operator fun List<CommonizedMemberScope?>.plusAssign(members: List<DeclarationDescriptor?>) {
members.forEachIndexed { index, member ->
if (member != null) {
this[index]?.run { this += member }
}
}
}
}
}
private inline fun <reified T : DeclarationDescriptor> List<*>.filteredBy(name: Name): Sequence<T> =
this.asSequence().filterIsInstance<T>().filter { it.name == name }
@@ -0,0 +1,38 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
internal class CommonizedPackageFragmentProvider : PackageFragmentProvider {
private val packageFragments = ArrayList<PackageFragmentDescriptor>()
operator fun plusAssign(packageFragment: PackageFragmentDescriptor) {
this.packageFragments += packageFragment
}
override fun getPackageFragments(fqName: FqName): List<PackageFragmentDescriptor> =
packageFragments.filter { it.fqName == fqName }
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean): Collection<FqName> =
packageFragments.asSequence()
.map { it.fqName }
.filter { !it.isRoot && it.parent() == fqName }
.toList()
companion object {
fun createArray(size: Int) = Array(size) { CommonizedPackageFragmentProvider() }
operator fun Array<CommonizedPackageFragmentProvider>.plusAssign(packageFragments: List<PackageFragmentDescriptor?>) {
packageFragments.forEachIndexed { index, packageFragment ->
this[index] += packageFragment ?: return@forEachIndexed
}
}
}
}
@@ -0,0 +1,74 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.NotNullLazyValue
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.asSimpleType
class CommonizedTypeAliasDescriptor(
override val storageManager: StorageManager,
containingDeclaration: DeclarationDescriptor,
annotations: Annotations,
name: Name,
visibility: Visibility,
private val isActual: Boolean
) : AbstractTypeAliasDescriptor(containingDeclaration, annotations, name, SourceElement.NO_SOURCE, visibility) {
private lateinit var underlyingTypeImpl: NotNullLazyValue<SimpleType>
override val underlyingType get() = underlyingTypeImpl()
private lateinit var expandedTypeImpl: NotNullLazyValue<SimpleType>
override val expandedType: SimpleType get() = expandedTypeImpl()
private val defaultTypeImpl = storageManager.createLazyValue { computeDefaultType() }
override fun getDefaultType() = defaultTypeImpl()
override val classDescriptor get() = expandedType.constructor.declarationDescriptor as? ClassDescriptor
private val typeConstructorParametersImpl = storageManager.createLazyValue { computeConstructorTypeParameters() }
override fun getTypeConstructorTypeParameters() = typeConstructorParametersImpl()
private val constructorsImpl = storageManager.createLazyValue { getTypeAliasConstructors() }
override val constructors get() = constructorsImpl()
override fun isActual() = isActual
fun initialize(
declaredTypeParameters: List<TypeParameterDescriptor>,
underlyingType: NotNullLazyValue<SimpleType>,
expandedType: NotNullLazyValue<SimpleType>
) {
super.initialize(declaredTypeParameters)
underlyingTypeImpl = underlyingType
expandedTypeImpl = expandedType
}
override fun substitute(substitutor: TypeSubstitutor): ClassifierDescriptorWithTypeParameters {
if (substitutor.isEmpty) return this
val substituted = CommonizedTypeAliasDescriptor(
storageManager = storageManager,
containingDeclaration = containingDeclaration,
annotations = annotations,
name = name,
visibility = visibility,
isActual = isActual
)
substituted.initialize(
declaredTypeParameters,
storageManager.createLazyValue { substitutor.safeSubstitute(underlyingType, Variance.INVARIANT).asSimpleType() },
storageManager.createLazyValue { substitutor.safeSubstitute(expandedType, Variance.INVARIANT).asSimpleType() }
)
return substituted
}
}
@@ -0,0 +1,48 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.SupertypeLoopChecker
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType
import org.jetbrains.kotlin.descriptors.impl.AbstractLazyTypeParameterDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.Variance
class CommonizedTypeParameterDescriptor(
private val targetComponents: TargetDeclarationsBuilderComponents,
private val typeParameterResolver: TypeParameterResolver,
containingDeclaration: DeclarationDescriptor,
override val annotations: Annotations,
name: Name,
variance: Variance,
isReified: Boolean,
index: Int,
private val cirUpperBounds: List<CirType>
) : AbstractLazyTypeParameterDescriptor(
targetComponents.storageManager,
containingDeclaration,
name,
variance,
isReified,
index,
SourceElement.NO_SOURCE,
SupertypeLoopChecker.EMPTY
) {
override fun resolveUpperBounds(): List<UnwrappedType> {
return if (cirUpperBounds.isEmpty())
listOf(targetComponents.builtIns.defaultBound)
else
cirUpperBounds.map { it.buildType(targetComponents, typeParameterResolver) }
}
override fun reportSupertypeLoopError(type: KotlinType) =
error("There should be no cycles for commonized type parameters, but found for: $type in $this")
}
@@ -0,0 +1,147 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.Target
import org.jetbrains.kotlin.descriptors.commonizer.builder.CommonizedMemberScope.Companion.plusAssign
import org.jetbrains.kotlin.descriptors.commonizer.builder.CommonizedPackageFragmentProvider.Companion.plusAssign
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.*
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.utils.addIfNotNull
/**
* Serves two goals:
* 1. Builds and initializes descriptors that do not depend on Kotlin types, such as [ModuleDescriptor], [PackageFragmentDescriptor], etc.
* 2. Builds BUT not initializes classifier descriptors, so that they can be used during the next phase for construction of Kotlin types.
*/
internal class DeclarationsBuilderVisitor1(
private val components: GlobalDeclarationsBuilderComponents
) : CirNodeVisitor<List<DeclarationDescriptor?>, List<DeclarationDescriptor?>> {
override fun visitRootNode(node: CirRootNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
check(data.isEmpty()) // root node may not have containing declarations
check(components.targetComponents.size == node.dimension)
val allTargets = (node.target + node.common()!!).map { it.target }
val modulesByTargets = HashMap<Target, MutableList<ModuleDescriptorImpl>>()
// collect module descriptors:
for (moduleNode in node.modules) {
val modules = moduleNode.accept(this, noContainingDeclarations()).asListContaining<ModuleDescriptorImpl>()
modules.forEachIndexed { index, module ->
val target = allTargets[index]
modulesByTargets.computeIfAbsent(target) { mutableListOf() }.addIfNotNull(module)
}
}
// return result (preserving order of targets):
allTargets.forEachIndexed { index, target ->
components.cache.cache(index, modulesByTargets.getValue(target))
}
return noReturningDeclarations()
}
override fun visitModuleNode(node: CirModuleNode, data: List<DeclarationDescriptor?>): List<ModuleDescriptorImpl?> {
// build module descriptors:
val moduleDescriptorsGroup = CommonizedGroup<ModuleDescriptorImpl>(node.dimension)
node.buildDescriptors(components, moduleDescriptorsGroup)
val moduleDescriptors = moduleDescriptorsGroup.toList()
// build package fragments:
val packageFragmentProviders = CommonizedPackageFragmentProvider.createArray(node.dimension)
for (packageNode in node.packages) {
val packageFragments = packageNode.accept(this, moduleDescriptors).asListContaining<PackageFragmentDescriptor>()
packageFragmentProviders += packageFragments
}
// initialize module descriptors:
moduleDescriptors.forEachIndexed { index, moduleDescriptor ->
moduleDescriptor?.initialize(packageFragmentProviders[index])
}
return moduleDescriptors
}
override fun visitPackageNode(node: CirPackageNode, data: List<DeclarationDescriptor?>): List<PackageFragmentDescriptor?> {
val containingDeclarations = data.asListContaining<ModuleDescriptorImpl>()
// build package fragments:
val packageFragmentsGroup = CommonizedGroup<CommonizedPackageFragmentDescriptor>(node.dimension)
node.buildDescriptors(components, packageFragmentsGroup, containingDeclarations)
val packageFragments = packageFragmentsGroup.toList()
// build package members:
val packageMemberScopes = CommonizedMemberScope.createArray(node.dimension)
for (classNode in node.classes) {
packageMemberScopes += classNode.accept(this, packageFragments)
}
for (typeAliasNode in node.typeAliases) {
packageMemberScopes += typeAliasNode.accept(this, packageFragments)
}
// initialize package fragments:
packageFragments.forEachIndexed { index, packageFragment ->
packageFragment?.initialize(packageMemberScopes[index])
}
return packageFragments
}
override fun visitPropertyNode(node: CirPropertyNode, data: List<DeclarationDescriptor?>) =
error("This method should not be called in ${this::class.java}")
override fun visitFunctionNode(node: CirFunctionNode, data: List<DeclarationDescriptor?>) =
error("This method should not be called in ${this::class.java}")
override fun visitClassNode(node: CirClassNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val classesGroup = CommonizedGroup<ClassifierDescriptorWithTypeParameters>(node.dimension)
node.buildDescriptors(components, classesGroup, data)
val classes = classesGroup.toList().asListContaining<CommonizedClassDescriptor>()
// build class members:
val classMemberScopes = CommonizedMemberScope.createArray(node.dimension)
for (classNode in node.classes) {
classMemberScopes += classNode.accept(this, classes)
}
// save member scope
classes.forEachIndexed { index, clazz ->
clazz?.unsubstitutedMemberScope = classMemberScopes[index]
}
return classes
}
override fun visitClassConstructorNode(node: CirClassConstructorNode, data: List<DeclarationDescriptor?>) =
error("This method should not be called in ${this::class.java}")
override fun visitTypeAliasNode(node: CirTypeAliasNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val typeAliasesGroup = CommonizedGroup<ClassifierDescriptorWithTypeParameters>(node.dimension)
node.buildDescriptors(components, typeAliasesGroup, data)
val typeAliases = typeAliasesGroup.toList()
val commonClass = typeAliases[node.indexOfCommon] as CommonizedClassDescriptor?
commonClass?.unsubstitutedMemberScope = CommonizedMemberScope() // empty member scope
commonClass?.initialize(emptyList()) // no constructors
return typeAliases
}
companion object {
internal inline fun <reified T : DeclarationDescriptor> noContainingDeclarations() = emptyList<T?>()
internal inline fun <reified T : DeclarationDescriptor> noReturningDeclarations() = emptyList<T?>()
@Suppress("UNCHECKED_CAST")
internal inline fun <reified T : DeclarationDescriptor> List<DeclarationDescriptor?>.asListContaining(): List<T?> =
this as List<T?>
}
}
@@ -0,0 +1,125 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.builder.CommonizedMemberScope.Companion.plusAssign
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1.Companion.asListContaining
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1.Companion.noContainingDeclarations
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1.Companion.noReturningDeclarations
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.*
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
/** Builds and initializes the new tree of common descriptors */
/**
* This visitor should be applied right after [DeclarationsBuilderVisitor1]. It does the following:
* 1. Builds and initializes descriptors that depend on Kotlin types, such as [PropertyDescriptor], [SimpleFunctionDescriptor], etc.
* 2. Initializes classifier descriptors.
*/
internal class DeclarationsBuilderVisitor2(
private val components: GlobalDeclarationsBuilderComponents
) : CirNodeVisitor<List<DeclarationDescriptor?>, List<DeclarationDescriptor?>> {
override fun visitRootNode(node: CirRootNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
check(data.isEmpty()) // root node may not have containing declarations
check(components.targetComponents.size == node.dimension)
// visit module descriptors:
for (moduleNode in node.modules) {
moduleNode.accept(this, noContainingDeclarations())
}
return noReturningDeclarations()
}
override fun visitModuleNode(node: CirModuleNode, data: List<DeclarationDescriptor?>): List<ModuleDescriptorImpl?> {
// visit package fragment descriptors:
for (packageNode in node.packages) {
packageNode.accept(this, noContainingDeclarations())
}
return noReturningDeclarations()
}
override fun visitPackageNode(node: CirPackageNode, data: List<DeclarationDescriptor?>): List<PackageFragmentDescriptor?> {
val packageFragments = components.cache.getCachedPackageFragments(node.moduleName, node.fqName)
// build non-classifier package members:
val packageMemberScopes = packageFragments.map { it?.getMemberScope() }
for (propertyNode in node.properties) {
packageMemberScopes += propertyNode.accept(this, packageFragments)
}
for (functionNode in node.functions) {
packageMemberScopes += functionNode.accept(this, packageFragments)
}
for (classNode in node.classes) {
classNode.accept(this, noContainingDeclarations())
}
return noReturningDeclarations()
}
override fun visitPropertyNode(node: CirPropertyNode, data: List<DeclarationDescriptor?>): List<PropertyDescriptor?> {
val propertyDescriptorsGroup = CommonizedGroup<PropertyDescriptor>(node.dimension)
node.buildDescriptors(components, propertyDescriptorsGroup, data)
return propertyDescriptorsGroup.toList()
}
override fun visitFunctionNode(node: CirFunctionNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val functionDescriptorsGroup = CommonizedGroup<SimpleFunctionDescriptor>(node.dimension)
node.buildDescriptors(components, functionDescriptorsGroup, data)
return functionDescriptorsGroup.toList()
}
override fun visitClassNode(node: CirClassNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val classes = components.cache.getCachedClasses(node.fqName)
// build class constructors:
val allConstructorsByTargets = Array<MutableList<CommonizedClassConstructorDescriptor>>(node.dimension) { ArrayList() }
for (constructorNode in node.constructors) {
val constructorsByTargets = constructorNode.accept(this, classes).asListContaining<CommonizedClassConstructorDescriptor>()
constructorsByTargets.forEachIndexed { index, constructor ->
if (constructor != null) allConstructorsByTargets[index].add(constructor)
}
}
// initialize classes
classes.forEachIndexed { index, clazz ->
clazz?.initialize(allConstructorsByTargets[index])
}
// build class members:
val classMemberScopes = classes.map { it?.unsubstitutedMemberScope }
for (propertyNode in node.properties) {
classMemberScopes += propertyNode.accept(this, classes)
}
for (functionNode in node.functions) {
classMemberScopes += functionNode.accept(this, classes)
}
for (classNode in node.classes) {
classNode.accept(this, noContainingDeclarations())
}
return noReturningDeclarations()
}
override fun visitClassConstructorNode(node: CirClassConstructorNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val containingDeclarations = data.asListContaining<CommonizedClassDescriptor>()
val constructorsGroup = CommonizedGroup<ClassConstructorDescriptor>(node.dimension)
node.buildDescriptors(components, constructorsGroup, containingDeclarations)
return constructorsGroup.toList()
}
override fun visitTypeAliasNode(node: CirTypeAliasNode, data: List<DeclarationDescriptor?>) =
error("This method should not be called in ${this::class.java}")
}
@@ -0,0 +1,178 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirSimpleTypeKind.Companion.areCompatible
import org.jetbrains.kotlin.descriptors.commonizer.utils.isUnderStandardKotlinPackages
import org.jetbrains.kotlin.descriptors.commonizer.utils.resolveClassOrTypeAliasByFqName
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.KotlinTypeFactory.flexibleType
import org.jetbrains.kotlin.types.KotlinTypeFactory.simpleType
internal fun List<CirTypeParameter>.buildDescriptorsAndTypeParameterResolver(
targetComponents: TargetDeclarationsBuilderComponents,
parentTypeParameterResolver: TypeParameterResolver,
containingDeclaration: DeclarationDescriptor,
typeParametersIndexOffset: Int = 0
): Pair<List<TypeParameterDescriptor>, TypeParameterResolver> {
val ownTypeParameters = mutableListOf<TypeParameterDescriptor>()
val typeParameterResolver = TypeParameterResolverImpl(
storageManager = targetComponents.storageManager,
ownTypeParameters = ownTypeParameters,
parent = parentTypeParameterResolver
)
forEachIndexed { index, param ->
ownTypeParameters += CommonizedTypeParameterDescriptor(
targetComponents = targetComponents,
typeParameterResolver = typeParameterResolver,
containingDeclaration = containingDeclaration,
annotations = param.annotations,
name = param.name,
variance = param.variance,
isReified = param.isReified,
index = typeParametersIndexOffset + index,
cirUpperBounds = param.upperBounds
)
}
return ownTypeParameters to typeParameterResolver
}
internal fun List<CirValueParameter>.buildDescriptors(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver,
containingDeclaration: CallableDescriptor
): List<ValueParameterDescriptor> = mapIndexed { index, param ->
ValueParameterDescriptorImpl(
containingDeclaration,
null,
index,
param.annotations,
param.name,
param.returnType.buildType(targetComponents, typeParameterResolver),
param.declaresDefaultValue,
param.isCrossinline,
param.isNoinline,
param.varargElementType?.buildType(targetComponents, typeParameterResolver),
SourceElement.NO_SOURCE
)
}
internal fun List<CirAnnotation>.buildDescriptors(targetComponents: TargetDeclarationsBuilderComponents): Annotations =
if (isEmpty())
Annotations.EMPTY
else
Annotations.create(map { CommonizedAnnotationDescriptor(targetComponents, it) })
internal fun CirExtensionReceiver.buildExtensionReceiver(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver,
containingDeclaration: CallableDescriptor
) = DescriptorFactory.createExtensionReceiverParameterForCallable(
containingDeclaration,
type.buildType(targetComponents, typeParameterResolver),
annotations.buildDescriptors(targetComponents)
)
internal fun buildDispatchReceiver(callableDescriptor: CallableDescriptor) =
DescriptorUtils.getDispatchReceiverParameterIfNeeded(callableDescriptor.containingDeclaration)
internal fun CirType.buildType(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver
): UnwrappedType = when (this) {
is CirSimpleType -> buildType(targetComponents, typeParameterResolver)
is CirFlexibleType -> flexibleType(
lowerBound = lowerBound.buildType(targetComponents, typeParameterResolver),
upperBound = upperBound.buildType(targetComponents, typeParameterResolver)
)
}
internal fun CirSimpleType.buildType(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver
): SimpleType {
val classifier: ClassifierDescriptor = when (kind) {
CirSimpleTypeKind.TYPE_PARAMETER -> {
typeParameterResolver.resolve(fqName.shortName())
?: error("Type parameter $fqName not found in ${typeParameterResolver::class.java}, $typeParameterResolver")
}
CirSimpleTypeKind.CLASS, CirSimpleTypeKind.TYPE_ALIAS -> {
val classOrTypeAlias = findClassOrTypeAlias(targetComponents, fqName)
checkClassifier(classOrTypeAlias, kind, fqName.isUnderStandardKotlinPackages || !targetComponents.isCommon)
classOrTypeAlias
}
}
// TODO: commonize annotations, KT-34234
val typeAnnotations = if (!targetComponents.isCommon) annotations.buildDescriptors(targetComponents) else Annotations.EMPTY
val rawType = simpleType(
annotations = typeAnnotations,
constructor = classifier.typeConstructor,
arguments = arguments.map { it.buildArgument(targetComponents, typeParameterResolver) },
nullable = isMarkedNullable,
kotlinTypeRefiner = null
)
return if (isDefinitelyNotNullType) rawType.makeSimpleTypeDefinitelyNotNullOrNotNull() else rawType
}
internal fun findClassOrTypeAlias(
targetComponents: TargetDeclarationsBuilderComponents,
fqName: FqName
): ClassifierDescriptorWithTypeParameters = when {
fqName.isUnderStandardKotlinPackages -> {
// look up for classifier in built-ins module:
val builtInsModule = targetComponents.builtIns.builtInsModule
// TODO: this works fine for Native as far as built-ins module contains full Native stdlib, but this is not enough for JVM and JS
builtInsModule.resolveClassOrTypeAliasByFqName(fqName, NoLookupLocation.FOR_ALREADY_TRACKED)
?: error("Classifier $fqName not found in built-ins module $builtInsModule")
}
else -> {
// otherwise, find the appropriate user classifier:
targetComponents.findAppropriateClassOrTypeAlias(fqName)
?: error("Classifier $fqName not found in created descriptors cache")
}
}
private fun checkClassifier(classifier: ClassifierDescriptor, kind: CirSimpleTypeKind, strict: Boolean) {
val classifierKind = CirSimpleTypeKind.determineKind(classifier)
if (strict) {
check(kind == classifierKind) {
"Mismatched classifier kinds.\nFound: $classifierKind, ${classifier::class.java}, $classifier\nShould be: $kind"
}
} else {
check(areCompatible(classifierKind, kind)) {
"Incompatible classifier kinds.\nExpect: $classifierKind, ${classifier::class.java}, $classifier\nActual: $kind"
}
}
}
private fun CirTypeProjection.buildArgument(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver
): TypeProjection =
if (isStarProjection) {
StarProjectionForAbsentTypeParameter(targetComponents.builtIns)
} else {
TypeProjectionImpl(projectionKind, type.buildType(targetComponents, typeParameterResolver))
}
@@ -0,0 +1,129 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.*
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.name.FqName
internal fun CirClassNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ClassifierDescriptorWithTypeParameters>,
containingDeclarations: List<DeclarationDescriptor?>
) {
val commonClass = common()
val markAsActual = commonClass != null && commonClass.kind != ClassKind.ENUM_ENTRY
target.forEachIndexed { index, clazz ->
clazz?.buildDescriptor(components, output, index, containingDeclarations, fqName, isActual = markAsActual)
}
commonClass?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, fqName, isExpect = true)
// log stats
components.statsCollector?.logStats(output.toList())
}
internal fun CirClass.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<in ClassifierDescriptorWithTypeParameters>,
index: Int,
containingDeclarations: List<DeclarationDescriptor?>,
fqName: FqName,
isExpect: Boolean = false,
isActual: Boolean = false
) {
val targetComponents = components.targetComponents[index]
val containingDeclaration = containingDeclarations[index] ?: error("No containing declaration for class $this")
val classDescriptor = CommonizedClassDescriptor(
targetComponents = targetComponents,
containingDeclaration = containingDeclaration,
annotations = annotations.buildDescriptors(targetComponents),
name = name,
kind = kind,
modality = modality,
visibility = visibility,
isCompanion = isCompanion,
isData = isData,
isInline = isInline,
isInner = isInner,
isExternal = isExternal,
isExpect = isExpect,
isActual = isActual,
cirDeclaredTypeParameters = typeParameters,
companionObjectName = companion?.shortName(),
cirSupertypes = supertypes
)
// cache created class descriptor:
components.cache.cache(fqName, index, classDescriptor)
output[index] = classDescriptor
}
internal fun CirClassConstructorNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ClassConstructorDescriptor>,
containingDeclarations: List<CommonizedClassDescriptor?>
) {
val commonConstructor = common()
val markAsActual = commonConstructor != null
target.forEachIndexed { index, constructor ->
constructor?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsActual)
}
commonConstructor?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = true)
// log stats
components.statsCollector?.logStats(output.toList())
}
private fun CirClassConstructor.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ClassConstructorDescriptor>,
index: Int,
containingDeclarations: List<CommonizedClassDescriptor?>,
isExpect: Boolean = false,
isActual: Boolean = false
) {
val targetComponents = components.targetComponents[index]
val containingDeclaration = containingDeclarations[index] ?: error("No containing declaration for constructor $this")
val constructorDescriptor = CommonizedClassConstructorDescriptor(
containingDeclaration = containingDeclaration,
annotations = annotations.buildDescriptors(targetComponents),
isPrimary = isPrimary,
kind = kind
)
constructorDescriptor.isExpect = isExpect
constructorDescriptor.isActual = isActual
constructorDescriptor.setHasStableParameterNames(hasStableParameterNames)
constructorDescriptor.setHasSynthesizedParameterNames(hasSynthesizedParameterNames)
val classTypeParameters = containingDeclaration.declaredTypeParameters
val (constructorTypeParameters, typeParameterResolver) = typeParameters.buildDescriptorsAndTypeParameterResolver(
targetComponents = targetComponents,
parentTypeParameterResolver = containingDeclaration.typeParameterResolver,
containingDeclaration = constructorDescriptor,
typeParametersIndexOffset = classTypeParameters.size
)
constructorDescriptor.initialize(
valueParameters.buildDescriptors(targetComponents, typeParameterResolver, constructorDescriptor),
visibility,
classTypeParameters + constructorTypeParameters
)
output[index] = constructorDescriptor
}
@@ -0,0 +1,209 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.StatsCollector
import org.jetbrains.kotlin.descriptors.commonizer.Target
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirRootNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.dimension
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroupMap
import org.jetbrains.kotlin.descriptors.commonizer.utils.createKotlinNativeForwardDeclarationsModule
import org.jetbrains.kotlin.descriptors.commonizer.utils.isUnderKotlinNativeSyntheticPackages
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.StorageManager
/**
* Temporary caches for constructed descriptors.
*/
class DeclarationsBuilderCache(dimension: Int) {
init {
check(dimension > 0)
}
private val modules = CommonizedGroup<List<ModuleDescriptorImpl>>(dimension)
private val packageFragments = CommonizedGroupMap<Pair<Name, FqName>, CommonizedPackageFragmentDescriptor>(dimension)
private val classes = CommonizedGroupMap<FqName, CommonizedClassDescriptor>(dimension)
private val typeAliases = CommonizedGroupMap<FqName, CommonizedTypeAliasDescriptor>(dimension)
private val forwardDeclarationsModules = CommonizedGroup<ModuleDescriptorImpl>(dimension)
private val allModulesWithDependencies = CommonizedGroup<List<ModuleDescriptor>>(dimension)
fun getCachedPackageFragments(moduleName: Name, packageFqName: FqName): List<CommonizedPackageFragmentDescriptor?> =
packageFragments.getOrFail(moduleName to packageFqName)
fun getCachedClasses(fqName: FqName): List<CommonizedClassDescriptor?> = classes.getOrFail(fqName)
fun getCachedClassifier(fqName: FqName, index: Int): ClassifierDescriptorWithTypeParameters? =
classes.getOrNull(fqName)?.get(index) ?: typeAliases.getOrNull(fqName)?.get(index)
fun cache(index: Int, modules: List<ModuleDescriptorImpl>) {
this.modules[index] = modules
}
fun cache(moduleName: Name, packageFqName: FqName, index: Int, descriptor: CommonizedPackageFragmentDescriptor) {
packageFragments[moduleName to packageFqName][index] = descriptor
}
fun cache(fqName: FqName, index: Int, descriptor: CommonizedClassDescriptor) {
classes[fqName][index] = descriptor
}
fun cache(fqName: FqName, index: Int, descriptor: CommonizedTypeAliasDescriptor) {
typeAliases[fqName][index] = descriptor
}
fun computeIfAbsentForwardDeclarationsModule(index: Int, computable: () -> ModuleDescriptorImpl): ModuleDescriptorImpl {
forwardDeclarationsModules[index]?.let { return it }
val module = computable()
forwardDeclarationsModules[index] = module
return module
}
fun getAllModules(index: Int): List<ModuleDescriptor> {
allModulesWithDependencies[index]?.let { return it }
val modulesForTarget = modules[index] ?: error("No module descriptors found for index $index")
val forwardDeclarationsModule = forwardDeclarationsModules[index]
// forward declarations module is created on demand (and only when commonizing Kotlin/Native target)
// so, don't return it if it's not necessary
val allModules = if (forwardDeclarationsModule != null)
modulesForTarget + forwardDeclarationsModule
else
modulesForTarget
// set dependencies for target modules and cache them
modulesForTarget.forEach { it.setDependencies(allModules) }
allModulesWithDependencies[index] = allModules
return allModules
}
companion object {
private inline fun <reified K, reified V : DeclarationDescriptor> CommonizedGroupMap<K, V>.getOrFail(key: K): List<V?> =
getOrNull(key)?.toList() ?: error("No cached ${V::class.java} with key $key found")
}
}
class GlobalDeclarationsBuilderComponents(
val storageManager: StorageManager,
val targetComponents: List<TargetDeclarationsBuilderComponents>,
val cache: DeclarationsBuilderCache,
val statsCollector: StatsCollector?
) {
init {
check(targetComponents.size > 1)
targetComponents.forEachIndexed { index, targetComponent -> check(index == targetComponent.index) }
}
}
class TargetDeclarationsBuilderComponents(
val storageManager: StorageManager,
val target: Target,
val builtIns: KotlinBuiltIns,
val isCommon: Boolean,
val index: Int,
private val cache: DeclarationsBuilderCache
) {
// N.B. this function may create new classifiers for types from Kotlin/Native forward declarations packages
fun findAppropriateClassOrTypeAlias(fqName: FqName): ClassifierDescriptorWithTypeParameters? {
return if (fqName.isUnderKotlinNativeSyntheticPackages) {
// that's a synthetic Kotlin/Native classifier that was exported as forward declaration in one or more modules,
// but did not match any existing class or typealias
val module = cache.computeIfAbsentForwardDeclarationsModule(index) {
// N.B. forward declarations module is created only on demand
createKotlinNativeForwardDeclarationsModule(
storageManager = storageManager,
builtIns = builtIns
)
}
// create and return new classifier
module.packageFragmentProvider
.getPackageFragments(fqName.parent())
.single()
.getMemberScope()
.getContributedClassifier(
name = fqName.shortName(),
location = NoLookupLocation.FOR_ALREADY_TRACKED
) as ClassifierDescriptorWithTypeParameters
} else {
// look up in created descriptors cache
cache.getCachedClassifier(fqName, index)
}
}
}
fun CirRootNode.createGlobalBuilderComponents(
storageManager: StorageManager,
statsCollector: StatsCollector?
): GlobalDeclarationsBuilderComponents {
val cache = DeclarationsBuilderCache(dimension)
val targetContexts = (0 until dimension).map { index ->
val isCommon = index == indexOfCommon
val target = (if (isCommon) common()!! else target[index]).target
val builtIns = modules.asSequence()
.mapNotNull { if (isCommon) it.common() else it.target[index] }
.first()
.builtIns
TargetDeclarationsBuilderComponents(
storageManager = storageManager,
target = target,
builtIns = builtIns,
isCommon = isCommon,
index = index,
cache = cache
)
}
return GlobalDeclarationsBuilderComponents(storageManager, targetContexts, cache, statsCollector)
}
interface TypeParameterResolver {
fun resolve(name: Name): TypeParameterDescriptor?
companion object {
val EMPTY = object : TypeParameterResolver {
override fun resolve(name: Name): TypeParameterDescriptor? = null
}
}
}
class TypeParameterResolverImpl(
storageManager: StorageManager,
ownTypeParameters: List<TypeParameterDescriptor>,
private val parent: TypeParameterResolver = TypeParameterResolver.EMPTY
) : TypeParameterResolver {
private val ownTypeParameters = storageManager.createLazyValue {
// memoize the first occurrence of descriptor with the same Name
ownTypeParameters.groupingBy { it.name }.reduce { _, accumulator, _ -> accumulator }
}
override fun resolve(name: Name) = ownTypeParameters()[name] ?: parent.resolve(name)
}
fun DeclarationDescriptor.getTypeParameterResolver(): TypeParameterResolver =
when (this) {
is CommonizedClassDescriptor -> typeParameterResolver
is ClassDescriptor -> {
// all class descriptors must be instances of CommonizedClassDescriptor, and therefore must implement ContainerWithTypeParameterResolver
error("Class descriptor that is not instance of ${CommonizedClassDescriptor::class.java}: ${this::class.java}, $this")
}
else -> TypeParameterResolver.EMPTY
}
@@ -0,0 +1,85 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirFunction
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirFunctionNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
internal fun CirFunctionNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<SimpleFunctionDescriptor>,
containingDeclarations: List<DeclarationDescriptor?>
) {
val commonFunction = common()
val markAsExpectAndActual = commonFunction != null && commonFunction.kind != CallableMemberDescriptor.Kind.SYNTHESIZED
target.forEachIndexed { index, function ->
function?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsExpectAndActual)
}
commonFunction?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = markAsExpectAndActual)
// log stats
components.statsCollector?.logStats(output.toList())
}
private fun CirFunction.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<SimpleFunctionDescriptor>,
index: Int,
containingDeclarations: List<DeclarationDescriptor?>,
isExpect: Boolean = false,
isActual: Boolean = false
) {
val targetComponents = components.targetComponents[index]
val containingDeclaration = containingDeclarations[index] ?: error("No containing declaration for function $this")
val functionDescriptor = SimpleFunctionDescriptorImpl.create(
containingDeclaration,
annotations.buildDescriptors(targetComponents),
name,
kind,
SourceElement.NO_SOURCE
)
functionDescriptor.isOperator = isOperator
functionDescriptor.isInfix = isInfix
functionDescriptor.isInline = isInline
functionDescriptor.isTailrec = isTailrec
functionDescriptor.isSuspend = isSuspend
functionDescriptor.isExternal = isExternal
functionDescriptor.isExpect = isExpect
functionDescriptor.isActual = isActual
functionDescriptor.setHasStableParameterNames(hasStableParameterNames)
functionDescriptor.setHasSynthesizedParameterNames(hasSynthesizedParameterNames)
val (typeParameters, typeParameterResolver) = typeParameters.buildDescriptorsAndTypeParameterResolver(
targetComponents,
containingDeclaration.getTypeParameterResolver(),
functionDescriptor
)
functionDescriptor.initialize(
extensionReceiver?.buildExtensionReceiver(targetComponents, typeParameterResolver, functionDescriptor),
buildDispatchReceiver(functionDescriptor),
typeParameters,
valueParameters.buildDescriptors(targetComponents, typeParameterResolver, functionDescriptor),
returnType.buildType(targetComponents, typeParameterResolver),
modality,
visibility
)
output[index] = functionDescriptor
}
@@ -0,0 +1,41 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirModule
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirModuleNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
internal fun CirModuleNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ModuleDescriptorImpl>
) {
target.forEachIndexed { index, module ->
module?.buildDescriptor(components, output, index)
}
common()?.buildDescriptor(components, output, indexOfCommon)
// log stats
components.statsCollector?.logStats(output.toList())
}
private fun CirModule.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ModuleDescriptorImpl>,
index: Int
) {
val moduleDescriptor = ModuleDescriptorImpl(
moduleName = name,
storageManager = components.storageManager,
builtIns = builtIns,
capabilities = emptyMap() // TODO: preserve capabilities from the original module descriptors, KT-33998
)
output[index] = moduleDescriptor
}
@@ -0,0 +1,56 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirPackage
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirPackageNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
import org.jetbrains.kotlin.name.FqName
internal fun CirPackageNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<CommonizedPackageFragmentDescriptor>,
modules: List<ModuleDescriptorImpl?>
) {
target.forEachIndexed { index, pkg ->
pkg?.buildDescriptor(components, output, index, modules)
}
common()?.buildDescriptor(components, output, indexOfCommon, modules)
}
private fun CirPackage.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<CommonizedPackageFragmentDescriptor>,
index: Int,
modules: List<ModuleDescriptorImpl?>
) {
val module = modules[index] ?: error("No containing declaration for package $this")
val packageFragment = CommonizedPackageFragmentDescriptor(module, fqName)
// cache created package fragment descriptor:
components.cache.cache(module.name, fqName, index, packageFragment)
output[index] = packageFragment
}
class CommonizedPackageFragmentDescriptor(
module: ModuleDescriptor,
fqName: FqName
) : PackageFragmentDescriptorImpl(module, fqName) {
private lateinit var memberScope: CommonizedMemberScope
fun initialize(memberScope: CommonizedMemberScope) {
this.memberScope = memberScope
}
override fun getMemberScope(): CommonizedMemberScope = memberScope
}
@@ -0,0 +1,123 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirProperty
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirPropertyNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.FieldDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.constants.AnnotationValue
internal fun CirPropertyNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<PropertyDescriptor>,
containingDeclarations: List<DeclarationDescriptor?>
) {
val commonProperty = common()
val markAsExpectAndActual = commonProperty != null && commonProperty.kind != CallableMemberDescriptor.Kind.SYNTHESIZED
target.forEachIndexed { index, property ->
property?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsExpectAndActual)
}
commonProperty?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = markAsExpectAndActual)
// log stats
components.statsCollector?.logStats(output.toList())
}
private fun CirProperty.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<PropertyDescriptor>,
index: Int,
containingDeclarations: List<DeclarationDescriptor?>,
isExpect: Boolean = false,
isActual: Boolean = false
) {
val targetComponents = components.targetComponents[index]
val containingDeclaration = containingDeclarations[index] ?: error("No containing declaration for property $this")
val propertyDescriptor = PropertyDescriptorImpl.create(
containingDeclaration,
annotations.buildDescriptors(targetComponents),
modality,
visibility,
isVar,
name,
kind,
SourceElement.NO_SOURCE,
isLateInit,
isConst,
isExpect,
isActual,
isExternal,
isDelegate
)
val (typeParameters, typeParameterResolver) = typeParameters.buildDescriptorsAndTypeParameterResolver(
targetComponents,
containingDeclaration.getTypeParameterResolver(),
propertyDescriptor
)
propertyDescriptor.setType(
returnType.buildType(targetComponents, typeParameterResolver),
typeParameters,
buildDispatchReceiver(propertyDescriptor),
extensionReceiver?.buildExtensionReceiver(targetComponents, typeParameterResolver, propertyDescriptor)
)
val getterDescriptor = getter?.let { getter ->
DescriptorFactory.createGetter(
propertyDescriptor,
getter.annotations,
getter.isDefault,
getter.isExternal,
getter.isInline
).apply {
initialize(null) // use return type from the property descriptor
}
}
val setterDescriptor = setter?.let { setter ->
DescriptorFactory.createSetter(
propertyDescriptor,
setter.annotations,
setter.parameterAnnotations,
setter.isDefault,
setter.isExternal,
setter.isInline,
setter.visibility,
SourceElement.NO_SOURCE
)
}
val backingField = backingFieldAnnotations?.let { FieldDescriptorImpl(it, propertyDescriptor) }
val delegateField = delegateFieldAnnotations?.let { FieldDescriptorImpl(it, propertyDescriptor) }
propertyDescriptor.initialize(
getterDescriptor,
setterDescriptor,
backingField,
delegateField
)
compileTimeInitializer?.let { constantValue ->
check(constantValue !is AnnotationValue) {
"Unexpected type of compile time constant: ${constantValue::class.java}, $constantValue"
}
propertyDescriptor.setCompileTimeInitializer(targetComponents.storageManager.createNullableLazyValue { constantValue })
}
output[index] = propertyDescriptor
}
@@ -0,0 +1,72 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClass
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirTypeAlias
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirTypeAliasNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.name.FqName
internal fun CirTypeAliasNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ClassifierDescriptorWithTypeParameters>,
containingDeclarations: List<DeclarationDescriptor?>
) {
val commonClass: CirClass? = common()
val markAsActual = commonClass != null
target.forEachIndexed { index, typeAlias ->
typeAlias?.buildDescriptor(components, output, index, containingDeclarations, fqName, isActual = markAsActual)
}
commonClass?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, fqName, isExpect = true)
// log stats
components.statsCollector?.logStats(output.toList())
}
private fun CirTypeAlias.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ClassifierDescriptorWithTypeParameters>,
index: Int,
containingDeclarations: List<DeclarationDescriptor?>,
fqName: FqName,
isActual: Boolean = false
) {
val targetComponents = components.targetComponents[index]
val storageManager = targetComponents.storageManager
val containingDeclaration = containingDeclarations[index] ?: error("No containing declaration for type alias $this")
val typeAliasDescriptor = CommonizedTypeAliasDescriptor(
storageManager = storageManager,
containingDeclaration = containingDeclaration,
annotations = annotations.buildDescriptors(targetComponents),
name = name,
visibility = visibility,
isActual = isActual
)
val (declaredTypeParameters, typeParameterResolver) = typeParameters.buildDescriptorsAndTypeParameterResolver(
targetComponents,
TypeParameterResolver.EMPTY,
typeAliasDescriptor
)
typeAliasDescriptor.initialize(
declaredTypeParameters = declaredTypeParameters,
underlyingType = storageManager.createLazyValue { underlyingType.buildType(targetComponents, typeParameterResolver) },
expandedType = storageManager.createLazyValue { expandedType.buildType(targetComponents, typeParameterResolver) }
)
// cache created type alias descriptor:
components.cache.cache(fqName, index, typeAliasDescriptor)
output[index] = typeAliasDescriptor
}
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.cli
import kotlin.system.exitProcess
internal fun parseArgs(
args: Array<String>,
printUsageAndExit: (String) -> Nothing
): Map<String, List<String>> {
val commandLine = mutableMapOf<String, MutableList<String>>()
for (index in args.indices step 2) {
val key = args[index]
if (key[0] != '-') printUsageAndExit("Expected a flag with initial dash: $key")
if (index + 1 == args.size) printUsageAndExit("Expected a value after $key")
val value = args[index + 1]
commandLine.computeIfAbsent(key) { mutableListOf() }.add(value)
}
return commandLine
}
internal fun printErrorAndExit(errorMessage: String): Nothing {
println("Error: $errorMessage")
println()
exitProcess(1)
}
@@ -0,0 +1,57 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.cli
import org.jetbrains.kotlin.descriptors.commonizer.konan.NativeDistributionCommonizer
import org.jetbrains.kotlin.konan.target.HostManager
import java.io.File
import kotlin.system.exitProcess
fun main(args: Array<String>) {
if (args.isEmpty()) printUsageAndExit()
val parsedArgs = parseArgs(args, ::printUsageAndExit)
val repository = parsedArgs["-repository"]?.firstOrNull()?.let(::File) ?: printUsageAndExit("repository not specified")
val targets = with(HostManager()) {
val targetNames = parsedArgs["-target"]?.toSet() ?: printUsageAndExit("no targets specified")
targetNames.map { targetName ->
targets[targetName] ?: printUsageAndExit("unknown target name: $targetName")
}
}
val destination = parsedArgs["-output"]?.firstOrNull()?.let(::File) ?: printUsageAndExit("output not specified")
val withStats = parsedArgs["-stats"]?.firstOrNull()?.toLowerCase() in setOf("1", "on", "yes", "true")
NativeDistributionCommonizer(
repository = repository,
targets = targets,
destination = destination,
copyStdlib = true,
copyEndorsedLibs = true,
withStats = withStats,
handleError = ::printErrorAndExit,
log = ::println
).run()
}
private fun printUsageAndExit(errorMessage: String? = null): Nothing {
if (errorMessage != null) {
println("Error: $errorMessage")
println()
}
println("Usage: commonizer <options>")
println("where possible options include:")
println("\t-repository <path>\tWork with the specified Kotlin/Native repository")
println("\t-target <name>\t\tAdd hardware target to commonization")
println("\t-output <path>\t\tDestination of commonized KLIBs")
println()
exitProcess(if (errorMessage != null) 1 else 0)
}
@@ -0,0 +1,40 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DELEGATION
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirFunctionOrProperty
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.isNonAbstractMemberInInterface
import org.jetbrains.kotlin.name.Name
abstract class AbstractFunctionOrPropertyCommonizer<T : CirFunctionOrProperty>(cache: CirClassifiersCache) : AbstractStandardCommonizer<T, T>() {
protected lateinit var name: Name
protected val modality = ModalityCommonizer.default()
protected val visibility = VisibilityCommonizer.lowering()
protected val extensionReceiver = ExtensionReceiverCommonizer.default(cache)
protected val returnType = TypeCommonizer.default(cache)
protected lateinit var kind: CallableMemberDescriptor.Kind
protected val typeParameters = TypeParameterListCommonizer.default(cache)
override fun initialize(first: T) {
name = first.name
kind = first.kind
}
override fun doCommonizeWith(next: T): Boolean =
!next.isNonAbstractMemberInInterface() // non-abstract callable members declared in interface can't be commonized
&& next.kind != DELEGATION // delegated members should not be commonized
&& (next.kind != SYNTHESIZED || next.containingClassIsData != true) // synthesized members of data classes should not be commonized
&& kind == next.kind
&& modality.commonizeWith(next.modality)
&& visibility.commonizeWith(next)
&& extensionReceiver.commonizeWith(next.extensionReceiver)
&& returnType.commonizeWith(next.returnType)
&& typeParameters.commonizeWith(next.typeParameters)
}
@@ -0,0 +1,56 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType
/**
* Unlike [Commonizer] which commonizes only single elements, this [AbstractListCommonizer] commonizes lists of elements using
* [Commonizer]s produced by [singleElementCommonizerFactory].
*
* Example:
* Input: N lists of [CirType]
* Output: list of [CirType]
*/
abstract class AbstractListCommonizer<T, R>(
private val singleElementCommonizerFactory: () -> Commonizer<T, R>
) : Commonizer<List<T>, List<R>> {
private var commonizers: List<Commonizer<T, R>>? = null
private var error = false
final override val result: List<R>
get() = commonizers?.takeIf { !error }?.map { it.result } ?: throw IllegalCommonizerStateException()
final override fun commonizeWith(next: List<T>): Boolean {
if (error)
return false
val commonizers = commonizers
?: mutableListOf<Commonizer<T, R>>().apply {
repeat(next.size) {
this += singleElementCommonizerFactory()
}
}.also {
this.commonizers = it
}
if (commonizers.size != next.size) // lists must be of the same size
error = true
else
for (index in next.indices) {
val commonizer = commonizers[index]
val nextElement = next[index]
// commonize each element in the list:
if (!commonizer.commonizeWith(nextElement)) {
error = true
break
}
}
return !error
}
}
@@ -0,0 +1,52 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
/**
* A wrapper around [Commonizer] that checks that
* - either all commonized elements are null
* - or all commonized elements are non-null and can be commonized according to the wrapped commonized
*/
abstract class AbstractNullableCommonizer<T : Any, R : Any, WT, WR>(
private val wrappedCommonizerFactory: () -> Commonizer<WT, WR>,
private val extractor: (T) -> WT,
private val builder: (WR) -> R
) : Commonizer<T?, R?> {
private enum class State {
EMPTY,
ERROR,
WITH_WRAPPED,
WITHOUT_WRAPPED
}
private var state = State.EMPTY
private lateinit var wrapped: Commonizer<WT, WR>
final override val result: R?
get() = when (state) {
State.EMPTY, State.ERROR -> throw IllegalCommonizerStateException()
State.WITH_WRAPPED -> builder(wrapped.result)
State.WITHOUT_WRAPPED -> null // null means there is no commonized result
}
final override fun commonizeWith(next: T?): Boolean {
state = when (state) {
State.ERROR -> State.ERROR
State.EMPTY -> next?.let {
wrapped = wrappedCommonizerFactory()
doCommonizeWith(next)
} ?: State.WITHOUT_WRAPPED
State.WITH_WRAPPED -> next?.let(::doCommonizeWith) ?: State.ERROR
State.WITHOUT_WRAPPED -> next?.let { State.ERROR } ?: State.WITHOUT_WRAPPED
}
return state != State.ERROR
}
@Suppress("NOTHING_TO_INLINE")
private inline fun doCommonizeWith(next: T) =
if (wrapped.commonizeWith(extractor(next))) State.WITH_WRAPPED else State.ERROR
}
@@ -0,0 +1,51 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClass
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirCommonClass
import org.jetbrains.kotlin.name.Name
class ClassCommonizer(cache: CirClassifiersCache) : AbstractStandardCommonizer<CirClass, CirClass>() {
private lateinit var name: Name
private lateinit var kind: ClassKind
private val typeParameters = TypeParameterListCommonizer.default(cache)
private val modality = ModalityCommonizer.default()
private val visibility = VisibilityCommonizer.equalizing()
private var isInner = false
private var isInline = false
private var isCompanion = false
override fun commonizationResult() = CirCommonClass(
name = name,
typeParameters = typeParameters.result,
kind = kind,
modality = modality.result,
visibility = visibility.result,
isCompanion = isCompanion,
isInline = isInline,
isInner = isInner
)
override fun initialize(first: CirClass) {
name = first.name
kind = first.kind
isInner = first.isInner
isInline = first.isInline
isCompanion = first.isCompanion
}
override fun doCommonizeWith(next: CirClass) =
kind == next.kind
&& isInner == next.isInner
&& isInline == next.isInline
&& isCompanion == next.isCompanion
&& modality.commonizeWith(next.modality)
&& visibility.commonizeWith(next)
&& typeParameters.commonizeWith(next.typeParameters)
}
@@ -0,0 +1,54 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassConstructor
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirCommonClassConstructor
class ClassConstructorCommonizer(cache: CirClassifiersCache) : AbstractStandardCommonizer<CirClassConstructor, CirClassConstructor>() {
private var isPrimary = false
private lateinit var kind: CallableMemberDescriptor.Kind
private val visibility = VisibilityCommonizer.equalizing()
private val typeParameters = TypeParameterListCommonizer.default(cache)
private val valueParameters = ValueParameterListCommonizer.default(cache)
private var hasStableParameterNames = true
private var hasSynthesizedParameterNames = false
override fun commonizationResult() = CirCommonClassConstructor(
isPrimary = isPrimary,
kind = kind,
visibility = visibility.result,
typeParameters = typeParameters.result,
valueParameters = valueParameters.result,
hasStableParameterNames = hasStableParameterNames,
hasSynthesizedParameterNames = hasSynthesizedParameterNames
)
override fun initialize(first: CirClassConstructor) {
isPrimary = first.isPrimary
kind = first.kind
}
override fun doCommonizeWith(next: CirClassConstructor): Boolean {
val result = !next.containingClassKind.isSingleton // don't commonize constructors for objects and enum entries
&& next.containingClassModality != Modality.SEALED // don't commonize constructors for sealed classes (not not their subclasses)
&& isPrimary == next.isPrimary
&& kind == next.kind
&& visibility.commonizeWith(next)
&& typeParameters.commonizeWith(next.typeParameters)
&& valueParameters.commonizeWith(next.valueParameters)
if (result) {
hasStableParameterNames = hasStableParameterNames && next.hasStableParameterNames
hasSynthesizedParameterNames = hasSynthesizedParameterNames || next.hasSynthesizedParameterNames
}
return result
}
}
@@ -0,0 +1,114 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.*
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroupMap
internal class CommonizationVisitor(
private val root: CirRootNode
) : CirNodeVisitor<Unit, Unit> {
override fun visitRootNode(node: CirRootNode, data: Unit) {
check(node === root)
check(node.common() != null) // root should already be commonized
node.modules.forEach { module ->
module.accept(this, Unit)
}
}
override fun visitModuleNode(node: CirModuleNode, data: Unit) {
node.common() // commonize module
node.packages.forEach { pkg ->
pkg.accept(this, Unit)
}
}
override fun visitPackageNode(node: CirPackageNode, data: Unit) {
node.common() // commonize package
node.properties.forEach { property ->
property.accept(this, Unit)
}
node.functions.forEach { function ->
function.accept(this, Unit)
}
node.classes.forEach { clazz ->
clazz.accept(this, Unit)
}
node.typeAliases.forEach { typeAlias ->
typeAlias.accept(this, Unit)
}
}
override fun visitPropertyNode(node: CirPropertyNode, data: Unit) {
node.common() // commonize property
}
override fun visitFunctionNode(node: CirFunctionNode, data: Unit) {
node.common() // commonize function
}
override fun visitClassNode(node: CirClassNode, data: Unit) {
val commonClass = node.common() as CirCommonClass? // commonize class
node.constructors.forEach { constructor ->
constructor.accept(this, Unit)
}
node.properties.forEach { property ->
property.accept(this, Unit)
}
node.functions.forEach { function ->
function.accept(this, Unit)
}
node.classes.forEach { clazz ->
clazz.accept(this, Unit)
}
if (commonClass != null) {
// companion object should have the same FQ name for each target class, then it could be set to common class
val companionObjectFqName = node.target.mapTo(HashSet()) { it!!.companion }.singleOrNull()
if (companionObjectFqName != null) {
val companionObjectNode = root.cache.classes[companionObjectFqName]
?: error("Can't find companion object with FQ name $companionObjectFqName")
if (companionObjectNode.common() != null) {
// companion object has been successfully commonized
commonClass.companion = companionObjectFqName
}
}
// find out common (and commonized) supertypes
val supertypesMap = CommonizedGroupMap<String, CirType>(node.target.size)
node.target.forEachIndexed { index, clazz ->
for (supertype in clazz!!.supertypes) {
supertypesMap[supertype.fqNameWithTypeParameters][index] = supertype
}
}
for ((_, supertypesGroup) in supertypesMap) {
val commonSupertype = commonize(supertypesGroup.toList(), TypeCommonizer.default(root.cache))
if (commonSupertype != null)
commonClass.supertypes += commonSupertype
}
}
}
override fun visitClassConstructorNode(node: CirClassConstructorNode, data: Unit) {
node.common() // commonize constructor
}
override fun visitTypeAliasNode(node: CirTypeAliasNode, data: Unit) {
node.common() // commonize type alias
}
}
@@ -0,0 +1,47 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
interface Commonizer<T, R> {
val result: R
fun commonizeWith(next: T): Boolean
}
abstract class AbstractStandardCommonizer<T, R> : Commonizer<T, R> {
private enum class State {
EMPTY,
ERROR,
IN_PROGRESS
}
private var state = State.EMPTY
final override val result: R
get() = when (state) {
State.EMPTY, State.ERROR -> throw IllegalCommonizerStateException()
State.IN_PROGRESS -> commonizationResult()
}
final override fun commonizeWith(next: T): Boolean {
if (state == State.ERROR)
return false
if (state == State.EMPTY)
initialize(next)
val result = doCommonizeWith(next)
state = if (!result) State.ERROR else State.IN_PROGRESS
return result
}
protected abstract fun commonizationResult(): R
protected abstract fun initialize(first: T)
protected abstract fun doCommonizeWith(next: T): Boolean
}
class IllegalCommonizerStateException : IllegalStateException("Illegal commonizer state: error or empty")
@@ -0,0 +1,25 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver.Companion.toReceiverNoAnnotations
interface ExtensionReceiverCommonizer : Commonizer<CirExtensionReceiver?, CirExtensionReceiver?> {
companion object {
fun default(cache: CirClassifiersCache): ExtensionReceiverCommonizer = DefaultExtensionReceiverCommonizer(cache)
}
}
private class DefaultExtensionReceiverCommonizer(cache: CirClassifiersCache) :
ExtensionReceiverCommonizer,
AbstractNullableCommonizer<CirExtensionReceiver, CirExtensionReceiver, CirType, CirType>(
wrappedCommonizerFactory = { TypeCommonizer.default(cache) },
extractor = { it.type },
builder = { it.toReceiverNoAnnotations() }
)
@@ -0,0 +1,44 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirCommonFunction
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirFunction
class FunctionCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropertyCommonizer<CirFunction>(cache) {
private val modifiers = FunctionModifiersCommonizer.default()
private val valueParameters = ValueParameterListCommonizer.default(cache)
private var hasStableParameterNames = true
private var hasSynthesizedParameterNames = false
override fun commonizationResult() = CirCommonFunction(
name = name,
modality = modality.result,
visibility = visibility.result,
extensionReceiver = extensionReceiver.result,
returnType = returnType.result,
kind = kind,
modifiers = modifiers.result,
valueParameters = valueParameters.result,
typeParameters = typeParameters.result,
hasStableParameterNames = hasStableParameterNames,
hasSynthesizedParameterNames = hasSynthesizedParameterNames
)
override fun doCommonizeWith(next: CirFunction): Boolean {
val result = super.doCommonizeWith(next)
&& modifiers.commonizeWith(next)
&& valueParameters.commonizeWith(next.valueParameters)
if (result) {
hasStableParameterNames = hasStableParameterNames && next.hasStableParameterNames
hasSynthesizedParameterNames = hasSynthesizedParameterNames || next.hasSynthesizedParameterNames
}
return result
}
}
@@ -0,0 +1,62 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirFunctionModifiers
interface FunctionModifiersCommonizer : Commonizer<CirFunctionModifiers, CirFunctionModifiers> {
companion object {
fun default(): FunctionModifiersCommonizer = DefaultFunctionModifiersCommonizer()
}
}
private class DefaultFunctionModifiersCommonizer : FunctionModifiersCommonizer {
private var modifiers: CirFunctionModifiersImpl? = null
private var error = false
override val result: CirFunctionModifiers
get() = modifiers?.takeIf { !error } ?: throw IllegalCommonizerStateException()
override fun commonizeWith(next: CirFunctionModifiers): Boolean {
if (error)
return false
val modifiers = modifiers
if (modifiers == null)
this.modifiers = CirFunctionModifiersImpl(next)
else {
if (modifiers.isSuspend != next.isSuspend)
error = true
else {
modifiers.isOperator = modifiers.isOperator && next.isOperator
modifiers.isInfix = modifiers.isInfix && next.isInfix
modifiers.isInline = modifiers.isInline && next.isInline
modifiers.isTailrec = modifiers.isTailrec && next.isTailrec
modifiers.isExternal = modifiers.isExternal && next.isExternal
}
}
return !error
}
private data class CirFunctionModifiersImpl(
override var isOperator: Boolean,
override var isInfix: Boolean,
override var isInline: Boolean,
override var isTailrec: Boolean,
override var isSuspend: Boolean,
override var isExternal: Boolean
) : CirFunctionModifiers {
constructor(function: CirFunctionModifiers) : this(
function.isOperator,
function.isInfix,
function.isInline,
function.isTailrec,
function.isSuspend,
function.isExternal
)
}
}
@@ -0,0 +1,41 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.Modality
interface ModalityCommonizer : Commonizer<Modality, Modality> {
companion object {
fun default(): ModalityCommonizer = DefaultModalityCommonizer()
}
}
private class DefaultModalityCommonizer : ModalityCommonizer {
private var temp: Modality? = null
private var error = false
override val result: Modality
get() = temp?.takeIf { !error } ?: throw IllegalCommonizerStateException()
override fun commonizeWith(next: Modality): Boolean {
if (error)
return false
val temp = temp
this.temp = if (temp != null) getNext(temp, next) else next
error = this.temp == null
return !error
}
@Suppress("NOTHING_TO_INLINE")
private inline fun getNext(current: Modality, next: Modality): Modality? = when {
current == Modality.FINAL && next == Modality.OPEN -> Modality.FINAL
current == Modality.OPEN && next == Modality.FINAL -> Modality.FINAL
current == next -> current
else -> null
}
}
@@ -0,0 +1,45 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirModule
import org.jetbrains.kotlin.name.Name
interface ModuleCommonizer : Commonizer<CirModule, CirModule> {
companion object {
fun default(): ModuleCommonizer = DefaultModuleCommonizer()
}
}
private class DefaultModuleCommonizer : ModuleCommonizer, AbstractStandardCommonizer<CirModule, CirModule>() {
private lateinit var name: Name
private var konanBuiltIns: KonanBuiltIns? = null
override fun commonizationResult() = CirModule(
name = name,
builtIns = konanBuiltIns ?: DefaultBuiltIns.Instance
)
override fun initialize(first: CirModule) {
name = first.name
konanBuiltIns = first.konanBuiltIns
}
override fun doCommonizeWith(next: CirModule): Boolean {
// keep the first met KonanBuiltIns when all targets are Kotlin/Native
// otherwise use DefaultBuiltIns
if (konanBuiltIns != null) {
konanBuiltIns = konanBuiltIns.takeIf { next.konanBuiltIns != null }
}
return true
}
private inline val CirModule.konanBuiltIns
get() = builtIns as? KonanBuiltIns
}
@@ -0,0 +1,43 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirCommonProperty
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirProperty
class PropertyCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropertyCommonizer<CirProperty>(cache) {
private val setter = PropertySetterCommonizer.default()
private var isExternal = true
override fun commonizationResult() = CirCommonProperty(
name = name,
modality = modality.result,
visibility = visibility.result,
isExternal = isExternal,
extensionReceiver = extensionReceiver.result,
returnType = returnType.result,
kind = kind,
setter = setter.result,
typeParameters = typeParameters.result
)
override fun doCommonizeWith(next: CirProperty): Boolean {
when {
next.isConst -> return false // expect property can't be const because expect can't have initializer
next.isLateInit -> return false // expect property can't be lateinit
}
val result = super.doCommonizeWith(next)
&& setter.commonizeWith(next.setter)
if (result) {
isExternal = isExternal && next.isExternal
}
return result
}
}
@@ -0,0 +1,24 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirDeclarationWithVisibility
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirSetter
interface PropertySetterCommonizer : Commonizer<CirSetter?, CirSetter?> {
companion object {
fun default(): PropertySetterCommonizer = DefaultPropertySetterCommonizer()
}
}
private class DefaultPropertySetterCommonizer :
PropertySetterCommonizer,
AbstractNullableCommonizer<CirSetter, CirSetter, CirDeclarationWithVisibility, Visibility>(
wrappedCommonizerFactory = { VisibilityCommonizer.equalizing() },
extractor = { it },
builder = { CirSetter.createDefaultNoAnnotations(it) }
)
@@ -0,0 +1,39 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.*
import org.jetbrains.kotlin.name.Name
class TypeAliasCommonizer(cache: CirClassifiersCache) : AbstractStandardCommonizer<CirTypeAlias, CirClass>() {
private lateinit var name: Name
private val underlyingType = TypeCommonizer.default(cache)
private val visibility = VisibilityCommonizer.lowering(allowPrivate = true)
override fun commonizationResult() = CirCommonClass(
name = name,
typeParameters = emptyList(),
kind = ClassKind.CLASS,
modality = Modality.FINAL,
visibility = visibility.result,
isCompanion = false,
isInline = false,
isInner = false
)
override fun initialize(first: CirTypeAlias) {
name = first.name
}
override fun doCommonizeWith(next: CirTypeAlias) =
next.typeParameters.isEmpty() // TAs with declared type parameters can't be commonized
&& next.underlyingType.arguments.isEmpty() // TAs with functional types or types with parameters at the right-hand side can't be commonized
&& next.underlyingType.kind == CirSimpleTypeKind.CLASS // right-hand side could have only class
&& underlyingType.commonizeWith(next.underlyingType)
&& visibility.commonizeWith(next)
}
@@ -0,0 +1,112 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.*
import org.jetbrains.kotlin.descriptors.commonizer.utils.isUnderStandardKotlinPackages
import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker
interface TypeCommonizer : Commonizer<CirType, CirType> {
companion object {
fun default(cache: CirClassifiersCache): TypeCommonizer = DefaultTypeCommonizer(cache)
}
}
private class DefaultTypeCommonizer(private val cache: CirClassifiersCache) :
TypeCommonizer,
AbstractStandardCommonizer<CirType, CirType>() {
private lateinit var temp: CirType
override fun commonizationResult() = temp
override fun initialize(first: CirType) {
temp = first
}
override fun doCommonizeWith(next: CirType) = areTypesEqual(cache, temp, next)
}
/**
* See also [AbstractStrictEqualityTypeChecker].
*/
internal fun areTypesEqual(cache: CirClassifiersCache, a: CirType, b: CirType): Boolean = when {
a === b -> true
a is CirSimpleType -> (b is CirSimpleType) && areSimpleTypesEqual(cache, a, b)
a is CirFlexibleType -> (b is CirFlexibleType)
&& areSimpleTypesEqual(cache, a.lowerBound, b.lowerBound)
&& areSimpleTypesEqual(cache, a.upperBound, b.upperBound)
else -> false
}
private fun areSimpleTypesEqual(cache: CirClassifiersCache, a: CirSimpleType, b: CirSimpleType): Boolean {
if (a.arguments.size != b.arguments.size
|| a.isMarkedNullable != b.isMarkedNullable
|| a.isDefinitelyNotNullType != b.isDefinitelyNotNullType
) {
return false
}
if (a.fqName != b.fqName)
return false
fun isClassOrTypeAliasUnderStandardKotlinPackages() =
// N.B. only for descriptors that represent classes or type aliases, but not type parameters!
a.isClassOrTypeAlias && b.isClassOrTypeAlias
&& a.fqName.isUnderStandardKotlinPackages
// If classes are from the standard Kotlin packages, compare them only by type constructors.
// Effectively, this includes comparison of 1) FQ names of underlying descriptors and 2) number of type constructor parameters.
// See org.jetbrains.kotlin.types.AbstractClassTypeConstructor.equals() for details.
&& a.expandedTypeConstructorId == b.expandedTypeConstructorId
fun descriptorsCanBeCommonizedThemselves() =
a.kind == b.kind && when (a.kind) {
CirSimpleTypeKind.CLASS -> cache.classes[a.fqName].canBeCommonized()
CirSimpleTypeKind.TYPE_ALIAS -> cache.typeAliases[a.fqName].canBeCommonized()
CirSimpleTypeKind.TYPE_PARAMETER -> {
// Real type parameter commonization is performed in TypeParameterCommonizer.
// Here it is enough to check that FQ names are equal (which is already done above).
true
}
}
val descriptorsCanBeCommonized =
/* either class or type alias from Kotlin stdlib */ isClassOrTypeAliasUnderStandardKotlinPackages()
|| /* or descriptors themselves can be commonized */ descriptorsCanBeCommonizedThemselves()
if (!descriptorsCanBeCommonized)
return false
// N.B. both lists of arguments are already known to be of the same size
for (i in a.arguments.indices) {
val aArg = a.arguments[i]
val bArg = b.arguments[i]
if (aArg.isStarProjection != bArg.isStarProjection)
return false
if (!aArg.isStarProjection) {
if (aArg.projectionKind != bArg.projectionKind)
return false
if (!areTypesEqual(cache, aArg.type, bArg.type))
return false
}
}
return true
}
@Suppress("NOTHING_TO_INLINE")
private inline fun CirNode<*, *>?.canBeCommonized() =
if (this == null) {
// No node means that the class or type alias was not subject for commonization at all, probably it lays
// not in commonized module descriptors but somewhere in their dependencies.
true
} else {
// If entry is present, then contents (common declaration) should not be null.
common() != null
}
@@ -0,0 +1,64 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirCommonTypeParameter
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirTypeParameter
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.Variance
interface TypeParameterCommonizer : Commonizer<CirTypeParameter, CirTypeParameter> {
companion object {
fun default(cache: CirClassifiersCache): TypeParameterCommonizer = DefaultTypeParameterCommonizer(cache)
}
}
private class DefaultTypeParameterCommonizer(cache: CirClassifiersCache) :
TypeParameterCommonizer,
AbstractStandardCommonizer<CirTypeParameter, CirTypeParameter>() {
private lateinit var name: Name
private var isReified = false
private lateinit var variance: Variance
private val upperBounds = TypeParameterUpperBoundsCommonizer(cache)
override fun commonizationResult() = CirCommonTypeParameter(
name = name,
isReified = isReified,
variance = variance,
upperBounds = upperBounds.result
)
override fun initialize(first: CirTypeParameter) {
name = first.name
isReified = first.isReified
variance = first.variance
}
override fun doCommonizeWith(next: CirTypeParameter) =
name == next.name
&& isReified == next.isReified
&& variance == next.variance
&& upperBounds.commonizeWith(next.upperBounds)
}
private class TypeParameterUpperBoundsCommonizer(cache: CirClassifiersCache) : AbstractListCommonizer<CirType, CirType>(
singleElementCommonizerFactory = { TypeCommonizer.default(cache) }
)
interface TypeParameterListCommonizer : Commonizer<List<CirTypeParameter>, List<CirTypeParameter>> {
companion object {
fun default(cache: CirClassifiersCache): TypeParameterListCommonizer = DefaultTypeParameterListCommonizer(cache)
}
}
private class DefaultTypeParameterListCommonizer(cache: CirClassifiersCache) :
TypeParameterListCommonizer,
AbstractListCommonizer<CirTypeParameter, CirTypeParameter>(
singleElementCommonizerFactory = { TypeParameterCommonizer.default(cache) }
)
@@ -0,0 +1,71 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirCommonValueParameter
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirValueParameter
import org.jetbrains.kotlin.descriptors.commonizer.utils.isNull
import org.jetbrains.kotlin.name.Name
interface ValueParameterCommonizer : Commonizer<CirValueParameter, CirValueParameter> {
companion object {
fun default(cache: CirClassifiersCache): ValueParameterCommonizer = DefaultValueParameterCommonizer(cache)
}
}
private class DefaultValueParameterCommonizer(cache: CirClassifiersCache) :
ValueParameterCommonizer,
AbstractStandardCommonizer<CirValueParameter, CirValueParameter>() {
private lateinit var name: Name
private val returnType = TypeCommonizer.default(cache)
private var varargElementType: CirType? = null
private var isCrossinline = true
private var isNoinline = true
override fun commonizationResult() = CirCommonValueParameter(
name = name,
returnType = returnType.result,
varargElementType = varargElementType,
isCrossinline = isCrossinline,
isNoinline = isNoinline
)
override fun initialize(first: CirValueParameter) {
name = first.name
varargElementType = first.varargElementType
isCrossinline = first.isCrossinline
isNoinline = first.isNoinline
}
override fun doCommonizeWith(next: CirValueParameter): Boolean {
val result = !next.declaresDefaultValue
&& varargElementType.isNull() == next.varargElementType.isNull()
&& name == next.name
&& returnType.commonizeWith(next.returnType)
if (result) {
isCrossinline = isCrossinline && next.isCrossinline
isNoinline = isNoinline && next.isNoinline
}
return result
}
}
interface ValueParameterListCommonizer : Commonizer<List<CirValueParameter>, List<CirValueParameter>> {
companion object {
fun default(cache: CirClassifiersCache): ValueParameterListCommonizer = DefaultValueParameterListCommonizer(cache)
}
}
private class DefaultValueParameterListCommonizer(cache: CirClassifiersCache) :
ValueParameterListCommonizer,
AbstractListCommonizer<CirValueParameter, CirValueParameter>(
singleElementCommonizerFactory = { ValueParameterCommonizer.default(cache) }
)
@@ -0,0 +1,81 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.core
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirDeclarationWithVisibility
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirFunctionOrProperty
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.isVirtual
abstract class VisibilityCommonizer(private val allowPrivate: Boolean) : Commonizer<CirDeclarationWithVisibility, Visibility> {
companion object {
fun lowering(allowPrivate: Boolean = false): VisibilityCommonizer = LoweringVisibilityCommonizer(allowPrivate)
fun equalizing(): VisibilityCommonizer = EqualizingVisibilityCommonizer()
}
private var temp: Visibility? = null
override val result: Visibility
get() = temp?.takeIf { it != Visibilities.UNKNOWN } ?: throw IllegalCommonizerStateException()
override fun commonizeWith(next: CirDeclarationWithVisibility): Boolean {
if (temp == Visibilities.UNKNOWN)
return false
val nextVisibility = next.visibility
if (!allowPrivate && Visibilities.isPrivate(nextVisibility) || !canBeCommonized(next)) {
temp = Visibilities.UNKNOWN
return false
}
temp = temp?.let { temp -> getNext(temp, nextVisibility) } ?: nextVisibility
return temp != Visibilities.UNKNOWN
}
protected abstract fun canBeCommonized(next: CirDeclarationWithVisibility): Boolean
protected abstract fun getNext(current: Visibility, next: Visibility): Visibility
}
/**
* Choose the lowest possible visibility ignoring private for all given member descriptors, if possible.
* If at least one member descriptor is virtual, then the commonizer succeeds only if all visibilities are equal.
*/
private class LoweringVisibilityCommonizer(allowPrivate: Boolean) : VisibilityCommonizer(allowPrivate) {
private var atLeastOneVirtualCallableMet = false
private var atLeastTwoVisibilitiesMet = false
override fun canBeCommonized(next: CirDeclarationWithVisibility): Boolean {
if (!atLeastOneVirtualCallableMet)
atLeastOneVirtualCallableMet = (next as? CirFunctionOrProperty)?.isVirtual() == true
return !atLeastOneVirtualCallableMet || !atLeastTwoVisibilitiesMet
}
override fun getNext(current: Visibility, next: Visibility): Visibility {
val comparisonResult: Int = Visibilities.compare(current, next)
?: return Visibilities.UNKNOWN // two visibilities that can't be compared against each one, ex: protected vs internal
if (!atLeastTwoVisibilitiesMet)
atLeastTwoVisibilitiesMet = comparisonResult != 0
if (atLeastOneVirtualCallableMet && atLeastTwoVisibilitiesMet)
return Visibilities.UNKNOWN
return if (comparisonResult <= 0) current else next
}
}
/**
* Make sure that visibilities of all member descriptors are equal are not private according to [Visibilities.isPrivate].
*/
private class EqualizingVisibilityCommonizer : VisibilityCommonizer(false) {
override fun canBeCommonized(next: CirDeclarationWithVisibility) = true
override fun getNext(current: Visibility, next: Visibility) =
if (Visibilities.compare(current, next) == 0) current else Visibilities.UNKNOWN
}
@@ -0,0 +1,42 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor2
import org.jetbrains.kotlin.descriptors.commonizer.builder.createGlobalBuilderComponents
import org.jetbrains.kotlin.descriptors.commonizer.core.CommonizationVisitor
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.mergeRoots
import org.jetbrains.kotlin.storage.LockBasedStorageManager
fun runCommonization(parameters: CommonizationParameters): CommonizationResult {
if (!parameters.hasIntersection())
return NothingToCommonize
val storageManager = LockBasedStorageManager("Declaration descriptors commonization")
// build merged tree:
val mergedTree = mergeRoots(storageManager, parameters.getModulesByTargets())
// commonize:
mergedTree.accept(CommonizationVisitor(mergedTree), Unit)
// build resulting descriptors:
val components = mergedTree.createGlobalBuilderComponents(storageManager, parameters.statsCollector)
mergedTree.accept(DeclarationsBuilderVisitor1(components), emptyList())
mergedTree.accept(DeclarationsBuilderVisitor2(components), emptyList())
val modulesByTargets = LinkedHashMap<Target, Collection<ModuleDescriptor>>() // use linked hash map to preserve order
components.targetComponents.forEach {
val target = it.target
check(target !in modulesByTargets)
modulesByTargets[target] = components.cache.getAllModules(it.index)
}
return CommonizationPerformed(modulesByTargets)
}
@@ -0,0 +1,269 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.konan
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMonolithicSerializer
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion
import org.jetbrains.kotlin.backend.common.serialization.metadata.metadataVersion
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.descriptors.commonizer.*
import org.jetbrains.kotlin.descriptors.commonizer.Target
import org.jetbrains.kotlin.descriptors.commonizer.konan.NativeModuleForCommonization.DeserializedModule
import org.jetbrains.kotlin.descriptors.commonizer.konan.NativeModuleForCommonization.SyntheticModule
import org.jetbrains.kotlin.descriptors.commonizer.utils.EmptyDescriptorTable
import org.jetbrains.kotlin.descriptors.commonizer.utils.NativeFactories.DefaultDeserializedDescriptorFactory
import org.jetbrains.kotlin.descriptors.commonizer.utils.ResettableClockMark
import org.jetbrains.kotlin.descriptors.commonizer.utils.createKotlinNativeForwardDeclarationsModule
import org.jetbrains.kotlin.konan.library.*
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.library.SerializedMetadata
import org.jetbrains.kotlin.library.impl.BaseWriterImpl
import org.jetbrains.kotlin.library.impl.KoltinLibraryWriterImpl
import org.jetbrains.kotlin.library.resolveSingleFileKlib
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.konan.impl.KlibResolvedModuleDescriptorsFactoryImpl
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import java.io.File
import org.jetbrains.kotlin.konan.file.File as KFile
class NativeDistributionCommonizer(
private val repository: File,
private val targets: List<KonanTarget>,
private val destination: File,
private val copyStdlib: Boolean,
private val copyEndorsedLibs: Boolean,
private val withStats: Boolean,
private val handleError: (String) -> Nothing,
private val log: (String) -> Unit
) {
fun run() {
checkPreconditions()
with(ResettableClockMark()) {
// 1. load modules
val modulesByTargets = loadModules()
log("Loaded lazy (uninitialized) libraries in ${elapsedSinceLast()}")
// 2. run commonization
val result = commonize(modulesByTargets)
log("Commonization performed in ${elapsedSinceLast()}")
// 3. write new libraries
saveModules(modulesByTargets, result)
log("Written libraries in ${elapsedSinceLast()}")
log("TOTAL: ${elapsedSinceStart()}")
}
log("Done.")
log("")
}
private fun checkPreconditions() {
if (!repository.isDirectory)
handleError("repository does not exist: $repository")
when (targets.size) {
0 -> handleError("no targets specified")
1 -> handleError("too few targets specified: $targets")
}
when {
!destination.exists() -> destination.mkdirs()
!destination.isDirectory -> handleError("output already exists: $destination")
destination.walkTopDown().any { it != destination } -> handleError("output is not empty: $destination")
}
}
private fun loadModules(): Map<InputTarget, List<NativeModuleForCommonization>> {
val stdlibPath = repository.resolve(konanCommonLibraryPath(KONAN_STDLIB_NAME))
val stdlib = loadLibrary(stdlibPath)
val librariesByTargets = targets.map { target ->
val platformLibsPath = repository.resolve(KONAN_DISTRIBUTION_KLIB_DIR)
.resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR)
.resolve(target.name)
val platformLibs = platformLibsPath.takeIf { it.isDirectory }
?.listFiles()
?.takeIf { it.isNotEmpty() }
?.map { loadLibrary(it) }
?: handleError("no platform libraries found for target $target in $platformLibsPath")
InputTarget(target.name, target) to platformLibs
}.toMap()
return librariesByTargets.mapValues { (target, libraries) ->
val storageManager = LockBasedStorageManager("Target $target")
val rawStdlibModule = DefaultDeserializedDescriptorFactory.createDescriptorAndNewBuiltIns(
library = stdlib,
languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
storageManager = storageManager,
packageAccessHandler = null
)
val otherModules = libraries.map { library ->
val rawModule = DefaultDeserializedDescriptorFactory.createDescriptorOptionalBuiltIns(
library = library,
languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
storageManager = storageManager,
builtIns = rawStdlibModule.builtIns,
packageAccessHandler = null
)
val data = NativeSensitiveManifestData.readFrom(library)
DeserializedModule(rawModule, data, File(library.libraryFile.path))
}
val rawForwardDeclarationsModule =
createKotlinNativeForwardDeclarationsModule(
storageManager = storageManager,
builtIns = rawStdlibModule.builtIns
)
val onlyDeserializedModules = listOf(rawStdlibModule) + otherModules.map { it.module }
val allModules = onlyDeserializedModules + rawForwardDeclarationsModule
onlyDeserializedModules.forEach { it.setDependencies(allModules) }
val stdlibModule = DeserializedModule(
rawStdlibModule,
NativeSensitiveManifestData.readFrom(stdlib),
File(stdlib.libraryFile.path)
)
val forwardDeclarationsModule = SyntheticModule(rawForwardDeclarationsModule)
listOf(stdlibModule) + otherModules + forwardDeclarationsModule
}
}
private fun loadLibrary(location: File): KotlinLibrary {
if (!location.isDirectory)
handleError("library not found: $location")
val library = resolveSingleFileKlib(KFile(location.path))
if (library.versions.metadataVersion == null)
handleError("library does not have metadata version specified in manifest: $location")
val metadataVersion = library.metadataVersion
if (metadataVersion?.isCompatible() != true)
handleError(
"""
library has incompatible metadata version ${metadataVersion ?: "\"unknown\""}: $location,
please make sure that all libraries passed to commonizer compatible metadata version ${KlibMetadataVersion.INSTANCE}
""".trimIndent()
)
return library
}
private fun commonize(modulesByTargets: Map<InputTarget, List<NativeModuleForCommonization>>): CommonizationPerformed {
val statsCollector = if (withStats) NativeStatsCollector(targets, destination) else null
statsCollector.use {
val parameters = CommonizationParameters(statsCollector).apply {
modulesByTargets.forEach { (target, modules) ->
addTarget(target, modules.map { it.module })
}
}
val result = runCommonization(parameters)
return when (result) {
is NothingToCommonize -> handleError("too few targets specified: ${modulesByTargets.keys}")
is CommonizationPerformed -> result
}
}
}
private fun saveModules(
originalModulesByTargets: Map<InputTarget, List<NativeModuleForCommonization>>,
result: CommonizationPerformed
) {
// optimization: stdlib and endorsed libraries effectively remain the same across all Kotlin/Native targets,
// so they can be just copied to the new destination without running serializer
if (copyStdlib || copyEndorsedLibs) {
repository.resolve(KONAN_DISTRIBUTION_KLIB_DIR)
.resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR)
.listFiles()
?.filter { it.isDirectory }
?.let {
if (copyStdlib) {
if (copyEndorsedLibs) it else it.filter { dir -> dir.endsWith(KONAN_STDLIB_NAME) }
} else
it.filter { dir -> !dir.endsWith(KONAN_STDLIB_NAME) }
}?.forEach { libraryOrigin ->
val libraryDestination = destination.resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR).resolve(libraryOrigin.name)
libraryOrigin.copyRecursively(libraryDestination)
}
}
val originalModulesManifestData = originalModulesByTargets.mapValues { (_, modules) ->
modules.asSequence()
.filterIsInstance<DeserializedModule>()
.filter { !it.location.endsWith(KONAN_STDLIB_NAME) }
.associate { it.module.name to it.data }
}
val serializer = KlibMetadataMonolithicSerializer(
languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
metadataVersion = KlibMetadataVersion.INSTANCE,
descriptorTable = EmptyDescriptorTable,
skipExpects = false
)
fun serializeTarget(target: Target) {
val libsDestination: File
val newModulesManifestData: Map<Name, NativeSensitiveManifestData>
when (target) {
is InputTarget -> {
libsDestination = destination.resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR).resolve(target.konanTarget!!.name)
newModulesManifestData = originalModulesManifestData.getValue(target)
}
is OutputTarget -> {
libsDestination = destination.resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR)
newModulesManifestData = originalModulesManifestData.values.first() // just take the first one
}
}
val newModules = result.modulesByTargets.getValue(target)
for (newModule in newModules) {
val libraryName = newModule.name
if (!shouldBeSerialized(libraryName))
continue
val metadata = serializer.serializeModule(newModule)
val manifestData = newModulesManifestData.getValue(newModule.name)
val libraryDestination = libsDestination.resolve(libraryName.asString().trimStart('<').trimEnd('>'))
writeLibrary(metadata, manifestData, libraryDestination)
}
}
result.concreteTargets.forEach(::serializeTarget)
result.commonTarget.let(::serializeTarget)
}
private fun writeLibrary(
metadata: SerializedMetadata,
manifestData: NativeSensitiveManifestData,
destination: File
) {
val library = KoltinLibraryWriterImpl(KFile(destination.path), manifestData.uniqueName, manifestData.versions, nopack = true)
library.addMetadata(metadata)
manifestData.applyTo(library.base as BaseWriterImpl)
library.commit()
}
private companion object {
val stdlibName = Name.special("<$KONAN_STDLIB_NAME>")
fun shouldBeSerialized(libraryName: Name) =
libraryName != stdlibName && libraryName != KlibResolvedModuleDescriptorsFactoryImpl.FORWARD_DECLARATIONS_MODULE_NAME
}
}
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.konan
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import java.io.File
internal sealed class NativeModuleForCommonization(val module: ModuleDescriptorImpl) {
class DeserializedModule(
module: ModuleDescriptorImpl,
val data: NativeSensitiveManifestData,
val location: File
) : NativeModuleForCommonization(module)
class SyntheticModule(module: ModuleDescriptorImpl) : NativeModuleForCommonization(module)
}
@@ -0,0 +1,49 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.konan
import org.jetbrains.kotlin.konan.properties.propertyList
import org.jetbrains.kotlin.library.*
import org.jetbrains.kotlin.library.impl.BaseWriterImpl
internal data class NativeSensitiveManifestData(
val uniqueName: String,
val versions: KotlinLibraryVersioning,
val dependencies: List<String>,
val isInterop: Boolean,
val packageFqName: String?,
val exportForwardDeclarations: List<String>
) {
fun applyTo(library: BaseWriterImpl) {
library.manifestProperties[KLIB_PROPERTY_UNIQUE_NAME] = uniqueName
// note: versions can't be added here
fun addOptionalProperty(name: String, condition: Boolean, value: () -> String) =
if (condition)
library.manifestProperties[name] = value()
else
library.manifestProperties.remove(name)
addOptionalProperty(KLIB_PROPERTY_DEPENDS, dependencies.isNotEmpty()) { dependencies.joinToString(separator = " ") }
addOptionalProperty(KLIB_PROPERTY_INTEROP, isInterop) { "true" }
addOptionalProperty(KLIB_PROPERTY_PACKAGE, packageFqName != null) { packageFqName!! }
addOptionalProperty(KLIB_PROPERTY_EXPORT_FORWARD_DECLARATIONS, exportForwardDeclarations.isNotEmpty()) {
exportForwardDeclarations.joinToString(separator = " ")
}
}
companion object {
fun readFrom(library: KotlinLibrary) = NativeSensitiveManifestData(
uniqueName = library.uniqueName,
versions = library.versions,
dependencies = library.manifestProperties.propertyList(KLIB_PROPERTY_DEPENDS, escapeInQuotes = true),
isInterop = library.isInterop,
packageFqName = library.packageFqName,
exportForwardDeclarations = library.exportForwardDeclarations
)
}
}
@@ -0,0 +1,132 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.konan
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.StatsCollector
import org.jetbrains.kotlin.descriptors.commonizer.utils.firstNonNull
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import java.io.File
/**
* Allows printing commonization statistics to the file system.
*
* File format: text, "|"-separated columns.
*
* Header row: "FQ Name|Declaration Type|common|<platform1>|<platform2>[|<platformN>...]"
*
* Possible values for "Declaration Type":
* - MODULE
* - CLASS
* - INTERFACE
* - OBJECT
* - COMPANION_OBJECT
* - ENUM_CLASS
* - ENUM_ENTRY
* - TYPE_ALIAS
* - CLASS_CONSTRUCTOR
* - FUN
* - VAL
*
* Possible values for "common" column:
* - E = successfully commonized, expect declaration generated
* - "-" = no common declaration
*
* Possible values for each target platform column:
* - A = successfully commonized, actual declaration generated
* - O = not commonized, the declaration is as in the original library
* - "-" = no such declaration in the original library
*
* Example of output:
FQ Name|Declaration Type|common|macos_x64|ios_x64
<SystemConfiguration>|MODULE|E|A|A
platform.SystemConfiguration.SCPreferencesContext|CLASS|E|A|A
platform.SystemConfiguration.SCPreferencesContext.Companion|COMPANION_OBJECT|E|A|A
platform.SystemConfiguration.SCNetworkConnectionContext|CLASS|E|A|A
platform.SystemConfiguration.SCNetworkConnectionContext.Companion|COMPANION_OBJECT|E|A|A
platform.SystemConfiguration.SCDynamicStoreRefVar|TYPE_ALIAS|-|O|O
platform.SystemConfiguration.SCVLANInterfaceRef|TYPE_ALIAS|-|O|O
*/
class NativeStatsCollector(
private val targets: List<KonanTarget>,
destination: File
) : StatsCollector {
init {
destination.mkdirs()
}
private val writer = destination.resolve("plain_stats.csv").printWriter()
private var headerWritten = false
override fun logStats(output: List<DeclarationDescriptor?>) {
if (!headerWritten) {
headerWritten = true
writeHeader()
}
val firstNotNull = output.firstNonNull()
val lastIsNull = output.last() == null
val row = buildString {
append((firstNotNull as? ModuleDescriptor)?.name ?: firstNotNull.fqNameSafe) // FQN (or name for module descriptor)
append(SEPARATOR)
append(firstNotNull.declarationType) // readable declaration type
append(SEPARATOR)
append(if (lastIsNull) '-' else 'E') // common
for (index in 0 until output.size - 1) {
append(SEPARATOR)
append(
when {
output[index] == null -> '-' // absent
lastIsNull -> 'O' // original (not commonized)
else -> 'A' // actual (commonized)
}
)
}
}
writer.println(row)
}
override fun close() = writer.close()
private fun writeHeader() {
val row = buildString {
append("FQ Name")
append(SEPARATOR)
append("Declaration Type")
append(SEPARATOR)
append("common")
targets.forEach { target ->
append(SEPARATOR)
append(target.name)
}
}
writer.println(row)
}
companion object {
private const val SEPARATOR = '|'
private inline val DeclarationDescriptor.declarationType: String
get() = when (this) {
is ClassDescriptor -> if (isCompanionObject) "COMPANION_OBJECT" else kind.toString()
is TypeAliasDescriptor -> "TYPE_ALIAS"
is ClassConstructorDescriptor -> "CLASS_CONSTRUCTOR"
is FunctionDescriptor -> "FUN"
is PropertyDescriptor -> "VAL"
is ModuleDescriptor -> "MODULE"
else -> "UNKNOWN: ${this::class.java}"
}
}
}
@@ -0,0 +1,37 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.buildClassConstructorNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.buildFunctionNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.buildPropertyNode
import org.jetbrains.kotlin.storage.NullableLazyValue
import org.jetbrains.kotlin.storage.StorageManager
internal fun mergeProperties(
storageManager: StorageManager,
cache: CirClassifiersCache,
containingDeclarationCommon: NullableLazyValue<*>?,
properties: List<PropertyDescriptor?>
) = buildPropertyNode(storageManager, cache, containingDeclarationCommon, properties)
internal fun mergeFunctions(
storageManager: StorageManager,
cache: CirClassifiersCache,
containingDeclarationCommon: NullableLazyValue<*>?,
properties: List<SimpleFunctionDescriptor?>
) = buildFunctionNode(storageManager, cache, containingDeclarationCommon, properties)
internal fun mergeClassConstructors(
storageManager: StorageManager,
cache: CirClassifiersCache,
containingDeclarationCommon: NullableLazyValue<*>?,
constructors: List<ClassConstructorDescriptor?>
) = buildClassConstructorNode(storageManager, cache, containingDeclarationCommon, constructors)
@@ -0,0 +1,64 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirRootNode.ClassifiersCacheImpl
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.buildClassNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.buildTypeAliasNode
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroupMap
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.NullableLazyValue
import org.jetbrains.kotlin.storage.StorageManager
internal fun mergeClasses(
storageManager: StorageManager,
cacheRW: ClassifiersCacheImpl,
containingDeclarationCommon: NullableLazyValue<*>?,
classes: List<ClassDescriptor?>
): CirClassNode {
val node = buildClassNode(storageManager, cacheRW, containingDeclarationCommon, classes)
val constructorsMap = CommonizedGroupMap<ConstructorApproximationKey, ClassConstructorDescriptor>(classes.size)
val propertiesMap = CommonizedGroupMap<PropertyApproximationKey, PropertyDescriptor>(classes.size)
val functionsMap = CommonizedGroupMap<FunctionApproximationKey, SimpleFunctionDescriptor>(classes.size)
val classesMap = CommonizedGroupMap<Name, ClassDescriptor>(classes.size)
classes.forEachIndexed { index, clazz ->
clazz?.constructors?.forEach { constructorsMap[ConstructorApproximationKey(it)][index] = it }
clazz?.unsubstitutedMemberScope?.collectMembers(
PropertyCollector { propertiesMap[PropertyApproximationKey(it)][index] = it },
FunctionCollector { functionsMap[FunctionApproximationKey(it)][index] = it },
ClassCollector { classesMap[it.name][index] = it }
)
}
for ((_, constructorsGroup) in constructorsMap) {
node.constructors += mergeClassConstructors(storageManager, cacheRW, node.common, constructorsGroup.toList())
}
for ((_, propertiesGroup) in propertiesMap) {
node.properties += mergeProperties(storageManager, cacheRW, node.common, propertiesGroup.toList())
}
for ((_, functionsGroup) in functionsMap) {
node.functions += mergeFunctions(storageManager, cacheRW, node.common, functionsGroup.toList())
}
for ((_, classesGroup) in classesMap) {
node.classes += mergeClasses(storageManager, cacheRW, node.common, classesGroup.toList())
}
return node
}
internal fun mergeTypeAliases(
storageManager: StorageManager,
cacheRW: ClassifiersCacheImpl,
typeAliases: List<TypeAliasDescriptor?>
) = buildTypeAliasNode(storageManager, cacheRW, typeAliases)
@@ -0,0 +1,16 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.ConstantValue
class CirAnnotation(private val wrapped: AnnotationDescriptor) {
val fqName: FqName get() = wrapped.fqName ?: error("Annotation with no FQ name: ${wrapped::class.java}, $wrapped")
val allValueArguments: Map<Name, ConstantValue<*>> get() = wrapped.allValueArguments
}
@@ -0,0 +1,114 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import kotlin.LazyThreadSafetyMode.PUBLICATION
interface CirClass : CirAnnotatedDeclaration, CirNamedDeclaration, CirDeclarationWithTypeParameters, CirDeclarationWithVisibility, CirDeclarationWithModality {
val companion: FqName? // null means no companion object
val kind: ClassKind
val isCompanion: Boolean
val isData: Boolean
val isInline: Boolean
val isInner: Boolean
val isExternal: Boolean
val supertypes: Collection<CirType>
}
interface CirClassConstructor : CirAnnotatedDeclaration, CirDeclarationWithTypeParameters, CirDeclarationWithVisibility, CirMaybeCallableMemberOfClass, CirCallableMemberWithParameters {
val isPrimary: Boolean
val kind: CallableMemberDescriptor.Kind
override val containingClassKind: ClassKind
override val containingClassModality: Modality
override val containingClassIsData: Boolean
}
data class CirCommonClass(
override val name: Name,
override val typeParameters: List<CirTypeParameter>,
override val kind: ClassKind,
override val modality: Modality,
override val visibility: Visibility,
override val isCompanion: Boolean,
override val isInline: Boolean,
override val isInner: Boolean
) : CirClass {
override val annotations: List<CirAnnotation> get() = emptyList() // TODO: commonize annotations, KT-34234
override val isData get() = false
override val isExternal get() = false
override var companion: FqName? = null
override val supertypes: MutableCollection<CirType> = ArrayList()
}
data class CirCommonClassConstructor(
override val isPrimary: Boolean,
override val kind: CallableMemberDescriptor.Kind,
override val visibility: Visibility,
override val typeParameters: List<CirTypeParameter>,
override val valueParameters: List<CirValueParameter>,
override val hasStableParameterNames: Boolean,
override val hasSynthesizedParameterNames: Boolean
) : CirClassConstructor {
override val annotations: List<CirAnnotation> get() = emptyList() // TODO: commonize annotations, KT-34234
override val containingClassKind get() = unsupported()
override val containingClassModality get() = unsupported()
override val containingClassIsData get() = unsupported()
}
class CirWrappedClass(private val wrapped: ClassDescriptor) : CirClass {
override val annotations by lazy(PUBLICATION) { wrapped.annotations.map(::CirAnnotation) }
override val name get() = wrapped.name
override val typeParameters by lazy(PUBLICATION) { wrapped.declaredTypeParameters.map(::CirWrappedTypeParameter) }
override val companion by lazy(PUBLICATION) { wrapped.companionObjectDescriptor?.fqNameSafe }
override val kind get() = wrapped.kind
override val modality get() = wrapped.modality
override val visibility get() = wrapped.visibility
override val isCompanion get() = wrapped.isCompanionObject
override val isData get() = wrapped.isData
override val isInline get() = wrapped.isInline
override val isInner get() = wrapped.isInner
override val isExternal get() = wrapped.isExternal
override val supertypes by lazy(PUBLICATION) { wrapped.typeConstructor.supertypes.map(CirType.Companion::create) }
}
class CirWrappedClassConstructor(private val wrapped: ClassConstructorDescriptor) : CirClassConstructor {
override val isPrimary get() = wrapped.isPrimary
override val kind get() = wrapped.kind
override val containingClassKind get() = wrapped.containingDeclaration.kind
override val containingClassModality get() = wrapped.containingDeclaration.modality
override val containingClassIsData get() = wrapped.containingDeclaration.isData
override val annotations by lazy(PUBLICATION) { wrapped.annotations.map(::CirAnnotation) }
override val visibility get() = wrapped.visibility
override val typeParameters by lazy(PUBLICATION) {
wrapped.typeParameters.mapNotNull { typeParameter ->
// save only type parameters that are contributed by the constructor itself
typeParameter.takeIf { it.containingDeclaration == wrapped }?.let(::CirWrappedTypeParameter)
}
}
override val valueParameters by lazy(PUBLICATION) { wrapped.valueParameters.map(::CirWrappedValueParameter) }
override val hasStableParameterNames get() = wrapped.hasStableParameterNames()
override val hasSynthesizedParameterNames get() = wrapped.hasSynthesizedParameterNames()
}
object CirClassRecursionMarker : CirClass, CirRecursionMarker {
override val companion get() = unsupported()
override val kind get() = unsupported()
override val modality get() = unsupported()
override val isCompanion get() = unsupported()
override val isData get() = unsupported()
override val isInline get() = unsupported()
override val isInner get() = unsupported()
override val isExternal get() = unsupported()
override val supertypes get() = unsupported()
override val annotations get() = unsupported()
override val name get() = unsupported()
override val visibility get() = unsupported()
override val typeParameters get() = unsupported()
}
@@ -0,0 +1,56 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
/**
* An intermediate representation of [DeclarationDescriptor]s for commonization purposes.
*
* The most essential subclasses are:
* - [CirClass] - represents [ClassDescriptor]
* - [CirTypeAlias] - [TypeAliasDescriptor]
* - [CirFunction] - [SimpleFunctionDescriptor]
* - [CirProperty] - [PropertyDescriptor]
* - [CirPackage] - union of multiple [PackageFragmentDescriptor]s with the same [FqName] contributed by commonized [ModuleDescriptor]s
* - [CirModule] - [ModuleDescriptor]
* - [CirRoot] - the root of the whole Commonizer IR tree
*/
interface CirDeclaration
interface CirAnnotatedDeclaration : CirDeclaration {
val annotations: List<CirAnnotation>
}
interface CirNamedDeclaration : CirDeclaration {
val name: Name
}
interface CirDeclarationWithVisibility : CirDeclaration {
val visibility: Visibility
}
interface CirDeclarationWithModality : CirDeclaration {
val modality: Modality
}
interface CirMaybeCallableMemberOfClass : CirDeclaration {
val containingClassKind: ClassKind? // null assumes no containing class
val containingClassModality: Modality? // null assumes no containing class
val containingClassIsData: Boolean? // null assumes no containing class
}
interface CirDeclarationWithTypeParameters : CirDeclaration {
val typeParameters: List<CirTypeParameter>
}
/** Indicates presence of recursion in lazy calculations. */
interface CirRecursionMarker : CirDeclaration
@Suppress("unused", "NOTHING_TO_INLINE")
internal inline fun CirDeclaration.unsupported(): Nothing = error("This method should never be called")
@@ -0,0 +1,84 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.Name
import kotlin.LazyThreadSafetyMode.PUBLICATION
interface CirFunctionModifiers {
val isOperator: Boolean
val isInfix: Boolean
val isInline: Boolean
val isTailrec: Boolean
val isSuspend: Boolean
val isExternal: Boolean
}
interface CirCallableMemberWithParameters {
val valueParameters: List<CirValueParameter>
val hasStableParameterNames: Boolean
val hasSynthesizedParameterNames: Boolean
}
interface CirFunction : CirFunctionOrProperty, CirFunctionModifiers, CirCallableMemberWithParameters
data class CirCommonFunction(
override val name: Name,
override val modality: Modality,
override val visibility: Visibility,
override val extensionReceiver: CirExtensionReceiver?,
override val returnType: CirType,
override val kind: CallableMemberDescriptor.Kind,
private val modifiers: CirFunctionModifiers,
override val valueParameters: List<CirValueParameter>,
override val typeParameters: List<CirTypeParameter>,
override val hasStableParameterNames: Boolean,
override val hasSynthesizedParameterNames: Boolean
) : CirCommonFunctionOrProperty(), CirFunction, CirFunctionModifiers by modifiers
class CirWrappedFunction(wrapped: SimpleFunctionDescriptor) : CirWrappedFunctionOrProperty<SimpleFunctionDescriptor>(wrapped), CirFunction {
override val isOperator get() = wrapped.isOperator
override val isInfix get() = wrapped.isInfix
override val isInline get() = wrapped.isInline
override val isTailrec get() = wrapped.isTailrec
override val isSuspend get() = wrapped.isSuspend
override val valueParameters by lazy(PUBLICATION) { wrapped.valueParameters.map(::CirWrappedValueParameter) }
override val hasStableParameterNames get() = wrapped.hasStableParameterNames()
override val hasSynthesizedParameterNames get() = wrapped.hasSynthesizedParameterNames()
}
interface CirValueParameter {
val name: Name
val annotations: Annotations
val returnType: CirType
val varargElementType: CirType?
val declaresDefaultValue: Boolean
val isCrossinline: Boolean
val isNoinline: Boolean
}
data class CirCommonValueParameter(
override val name: Name,
override val returnType: CirType,
override val varargElementType: CirType?,
override val isCrossinline: Boolean,
override val isNoinline: Boolean
) : CirValueParameter {
override val annotations get() = Annotations.EMPTY
override val declaresDefaultValue get() = false
}
data class CirWrappedValueParameter(private val wrapped: ValueParameterDescriptor) : CirValueParameter {
override val name get() = wrapped.name
override val annotations get() = wrapped.annotations
override val returnType by lazy(PUBLICATION) { CirType.create(wrapped.returnType!!) }
override val varargElementType by lazy(PUBLICATION) { wrapped.varargElementType?.let(CirType.Companion::create) }
override val declaresDefaultValue get() = wrapped.declaresDefaultValue()
override val isCrossinline get() = wrapped.isCrossinline
override val isNoinline get() = wrapped.isNoinline
}
@@ -0,0 +1,58 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver.Companion.toReceiver
import kotlin.LazyThreadSafetyMode.PUBLICATION
interface CirFunctionOrProperty : CirAnnotatedDeclaration, CirNamedDeclaration, CirDeclarationWithTypeParameters, CirDeclarationWithVisibility, CirDeclarationWithModality, CirMaybeCallableMemberOfClass {
val isExternal: Boolean
val extensionReceiver: CirExtensionReceiver?
val returnType: CirType
val kind: CallableMemberDescriptor.Kind
}
abstract class CirCommonFunctionOrProperty : CirFunctionOrProperty {
final override val annotations: List<CirAnnotation> get() = emptyList() // TODO: commonize annotations, KT-34234
final override val containingClassKind: ClassKind? get() = unsupported()
final override val containingClassModality: Modality? get() = unsupported()
final override val containingClassIsData: Boolean? get() = unsupported()
}
abstract class CirWrappedFunctionOrProperty<T : CallableMemberDescriptor>(protected val wrapped: T) : CirFunctionOrProperty {
final override val annotations by lazy(PUBLICATION) { wrapped.annotations.map(::CirAnnotation) }
final override val name get() = wrapped.name
final override val modality get() = wrapped.modality
final override val visibility get() = wrapped.visibility
final override val isExternal get() = wrapped.isExternal
final override val extensionReceiver by lazy(PUBLICATION) { wrapped.extensionReceiverParameter?.toReceiver() }
final override val returnType by lazy(PUBLICATION) { CirType.create(wrapped.returnType!!) }
final override val kind get() = wrapped.kind
final override val containingClassKind: ClassKind? get() = containingClass?.kind
final override val containingClassModality: Modality? get() = containingClass?.modality
final override val containingClassIsData: Boolean? get() = containingClass?.isData
final override val typeParameters by lazy(PUBLICATION) { wrapped.typeParameters.map(::CirWrappedTypeParameter) }
private val containingClass: ClassDescriptor? get() = wrapped.containingDeclaration as? ClassDescriptor
}
data class CirExtensionReceiver(
val annotations: List<CirAnnotation>,
val type: CirType
) {
companion object {
fun CirType.toReceiverNoAnnotations() = CirExtensionReceiver( /* TODO: commonize annotations, KT-34234 */ emptyList(), this)
fun ReceiverParameterDescriptor.toReceiver() = CirExtensionReceiver(annotations.map(::CirAnnotation), CirType.create(type))
}
}
fun CirFunctionOrProperty.isNonAbstractMemberInInterface() =
modality != Modality.ABSTRACT && containingClassKind == ClassKind.INTERFACE
fun CirFunctionOrProperty.isVirtual() =
visibility != Visibilities.PRIVATE
&& modality != Modality.FINAL
&& !(containingClassModality == Modality.FINAL && containingClassKind != ClassKind.ENUM_CLASS)
@@ -0,0 +1,14 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.name.Name
data class CirModule(val name: Name, val builtIns: KotlinBuiltIns) : CirDeclaration {
constructor(descriptor: ModuleDescriptor) : this(descriptor.name, descriptor.builtIns)
}
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree.ir
interface CirNodeVisitor<R, T> {
fun visitRootNode(node: CirRootNode, data: T): R
fun visitModuleNode(node: CirModuleNode, data: T): R
fun visitPackageNode(node: CirPackageNode, data: T): R
fun visitPropertyNode(node: CirPropertyNode, data: T): R
fun visitFunctionNode(node: CirFunctionNode, data: T): R
fun visitClassNode(node: CirClassNode, data: T): R
fun visitClassConstructorNode(node: CirClassConstructorNode, data: T): R
fun visitTypeAliasNode(node: CirTypeAliasNode, data: T): R
}
@@ -0,0 +1,10 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.name.FqName
data class CirPackage(val fqName: FqName) : CirDeclaration
@@ -0,0 +1,112 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirGetter.Companion.toGetter
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirSetter.Companion.toSetter
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import kotlin.LazyThreadSafetyMode.PUBLICATION
interface CirProperty : CirFunctionOrProperty {
val isVar: Boolean
val isLateInit: Boolean
val isConst: Boolean
val isDelegate: Boolean
val getter: CirGetter?
val setter: CirSetter?
val backingFieldAnnotations: Annotations? // null assumes no backing field
val delegateFieldAnnotations: Annotations? // null assumes no backing field
val compileTimeInitializer: ConstantValue<*>?
}
data class CirCommonProperty(
override val name: Name,
override val modality: Modality,
override val visibility: Visibility,
override val isExternal: Boolean,
override val extensionReceiver: CirExtensionReceiver?,
override val returnType: CirType,
override val kind: CallableMemberDescriptor.Kind,
override val setter: CirSetter?,
override val typeParameters: List<CirTypeParameter>
) : CirCommonFunctionOrProperty(), CirProperty {
override val isVar get() = setter != null
override val isLateInit get() = false
override val isConst get() = false
override val isDelegate get() = false
override val getter get() = CirGetter.DEFAULT_NO_ANNOTATIONS
override val backingFieldAnnotations: Annotations? get() = null
override val delegateFieldAnnotations: Annotations? get() = null
override val compileTimeInitializer: ConstantValue<*>? get() = null
}
class CirWrappedProperty(wrapped: PropertyDescriptor) : CirWrappedFunctionOrProperty<PropertyDescriptor>(wrapped), CirProperty {
override val isVar get() = wrapped.isVar
override val isLateInit get() = wrapped.isLateInit
override val isConst get() = wrapped.isConst
override val isDelegate get() = @Suppress("DEPRECATION") wrapped.isDelegated
override val getter by lazy(PUBLICATION) { wrapped.getter?.toGetter() }
override val setter by lazy(PUBLICATION) { wrapped.setter?.toSetter() }
override val backingFieldAnnotations get() = wrapped.backingField?.annotations
override val delegateFieldAnnotations get() = wrapped.delegateField?.annotations
override val compileTimeInitializer get() = wrapped.compileTimeInitializer
}
interface CirPropertyAccessor {
val annotations: Annotations
val isDefault: Boolean
val isExternal: Boolean
val isInline: Boolean
}
data class CirGetter(
override val annotations: Annotations,
override val isDefault: Boolean,
override val isExternal: Boolean,
override val isInline: Boolean
) : CirPropertyAccessor {
companion object {
val DEFAULT_NO_ANNOTATIONS = CirGetter(Annotations.EMPTY, isDefault = true, isExternal = false, isInline = false)
fun PropertyGetterDescriptor.toGetter() =
if (isDefault && annotations.isEmpty())
DEFAULT_NO_ANNOTATIONS
else
CirGetter(annotations, isDefault, isExternal, isInline)
}
}
data class CirSetter(
override val annotations: Annotations,
val parameterAnnotations: Annotations,
override val visibility: Visibility,
override val isDefault: Boolean,
override val isExternal: Boolean,
override val isInline: Boolean
) : CirPropertyAccessor, CirDeclarationWithVisibility {
companion object {
fun createDefaultNoAnnotations(visibility: Visibility) = CirSetter(
Annotations.EMPTY,
Annotations.EMPTY,
visibility,
isDefault = visibility == Visibilities.PUBLIC,
isExternal = false,
isInline = false
)
fun PropertySetterDescriptor.toSetter() = CirSetter(
annotations,
valueParameters.single().annotations,
visibility,
isDefault,
isExternal,
isInline
)
}
}
@@ -0,0 +1,10 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.commonizer.Target
data class CirRoot(val target: Target) : CirDeclaration
@@ -0,0 +1,94 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirSimpleTypeKind.CLASS
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirSimpleTypeKind.TYPE_ALIAS
import org.jetbrains.kotlin.descriptors.commonizer.utils.declarationDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.utils.fqName
import org.jetbrains.kotlin.descriptors.commonizer.utils.fqNameWithTypeParameters
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.*
import kotlin.LazyThreadSafetyMode.PUBLICATION
sealed class CirType {
companion object {
fun create(type: KotlinType): CirType = type.unwrap().run {
when (this) {
is SimpleType -> CirSimpleType(this)
is FlexibleType -> CirFlexibleType(CirSimpleType(lowerBound), CirSimpleType(upperBound))
}
}
}
}
/**
* All attributes except for [expandedTypeConstructorId] are read from the abbreviation type: [AbbreviatedType.abbreviation].
* And [expandedTypeConstructorId] is read from the expanded type: [AbbreviatedType.expandedType].
*
* This is necessary to properly compare types for type aliases, where abbreviation type represents the type alias itself while
* expanded type represents right-hand side declaration that should be processed separately.
*
* There is no difference between [abbreviation] and [expanded] for types representing classes and type parameters.
*/
class CirSimpleType(private val wrapped: SimpleType) : CirType() {
val annotations by lazy(PUBLICATION) { abbreviation.annotations.map(::CirAnnotation) }
val kind = CirSimpleTypeKind.determineKind(abbreviation.declarationDescriptor)
val fqName by lazy(PUBLICATION) { abbreviation.fqName }
val arguments by lazy(PUBLICATION) { abbreviation.arguments.map(::CirTypeProjection) }
val isMarkedNullable get() = abbreviation.isMarkedNullable
val isDefinitelyNotNullType get() = abbreviation.isDefinitelyNotNullType
val expandedTypeConstructorId by lazy(PUBLICATION) { CirTypeConstructorId(expanded) }
inline val isClassOrTypeAlias get() = (kind == CLASS || kind == TYPE_ALIAS)
val fqNameWithTypeParameters by lazy(PUBLICATION) { wrapped.fqNameWithTypeParameters }
override fun equals(other: Any?) = wrapped == (other as? CirSimpleType)?.wrapped
override fun hashCode() = wrapped.hashCode()
private inline val abbreviation: SimpleType get() = (wrapped as? AbbreviatedType)?.abbreviation ?: wrapped
private inline val expanded: SimpleType get() = (wrapped as? AbbreviatedType)?.expandedType ?: wrapped
}
enum class CirSimpleTypeKind {
CLASS,
TYPE_ALIAS,
TYPE_PARAMETER;
companion object {
fun determineKind(classifier: ClassifierDescriptor) = when (classifier) {
is ClassDescriptor -> CLASS
is TypeAliasDescriptor -> TYPE_ALIAS
is TypeParameterDescriptor -> TYPE_PARAMETER
else -> error("Unexpected classifier descriptor type: ${classifier::class.java}, $classifier")
}
fun areCompatible(expect: CirSimpleTypeKind, actual: CirSimpleTypeKind) =
expect == actual || (expect == CLASS && actual == TYPE_ALIAS)
}
}
data class CirTypeConstructorId(val fqName: FqName, val numberOfTypeParameters: Int) {
constructor(type: SimpleType) : this(type.fqName, type.constructor.parameters.size)
}
class CirTypeProjection(private val wrapped: TypeProjection) {
val projectionKind get() = wrapped.projectionKind
val isStarProjection get() = wrapped.isStarProjection
val type by lazy(PUBLICATION) { CirType.create(wrapped.type) }
}
data class CirFlexibleType(val lowerBound: CirSimpleType, val upperBound: CirSimpleType) : CirType()
val CirType.fqNameWithTypeParameters: String
get() = when (this) {
is CirSimpleType -> fqNameWithTypeParameters
is CirFlexibleType -> lowerBound.fqNameWithTypeParameters
}
@@ -0,0 +1,23 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import kotlin.LazyThreadSafetyMode.PUBLICATION
interface CirTypeAlias : CirAnnotatedDeclaration, CirNamedDeclaration, CirDeclarationWithTypeParameters, CirDeclarationWithVisibility {
val underlyingType: CirSimpleType
val expandedType: CirSimpleType
}
class CirWrappedTypeAlias(private val wrapped: TypeAliasDescriptor) : CirTypeAlias {
override val annotations by lazy(PUBLICATION) { wrapped.annotations.map(::CirAnnotation) }
override val name get() = wrapped.name
override val typeParameters by lazy(PUBLICATION) { wrapped.declaredTypeParameters.map(::CirWrappedTypeParameter) }
override val visibility get() = wrapped.visibility
override val underlyingType by lazy(PUBLICATION) { CirSimpleType(wrapped.underlyingType) }
override val expandedType by lazy(PUBLICATION) { CirSimpleType(wrapped.expandedType) }
}
@@ -0,0 +1,37 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.Variance
import kotlin.LazyThreadSafetyMode.PUBLICATION
interface CirTypeParameter {
val annotations: Annotations
val name: Name
val isReified: Boolean
val variance: Variance
val upperBounds: List<CirType>
}
data class CirCommonTypeParameter(
override val name: Name,
override val isReified: Boolean,
override val variance: Variance,
override val upperBounds: List<CirType>
) : CirTypeParameter {
override val annotations get() = Annotations.EMPTY
}
data class CirWrappedTypeParameter(private val wrapped: TypeParameterDescriptor) : CirTypeParameter {
override val annotations get() = wrapped.annotations
override val name get() = wrapped.name
override val isReified get() = wrapped.isReified
override val variance get() = wrapped.variance
override val upperBounds by lazy(PUBLICATION) { wrapped.upperBounds.map(CirType.Companion::create) }
}
@@ -0,0 +1,200 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.InputTarget
import org.jetbrains.kotlin.descriptors.commonizer.OutputTarget
import org.jetbrains.kotlin.descriptors.commonizer.core.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirRootNode.ClassifiersCacheImpl
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.commonizer.utils.firstNonNull
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.NullableLazyValue
import org.jetbrains.kotlin.storage.StorageManager
internal fun buildRootNode(
storageManager: StorageManager,
targets: List<InputTarget>
): CirRootNode = CirRootNode(
target = targets.map { CirRoot(it) },
common = storageManager.createNullableLazyValue {
CirRoot(OutputTarget(targets.toSet()))
}
)
internal fun buildModuleNode(
storageManager: StorageManager,
modules: List<ModuleDescriptor?>
): CirModuleNode = buildNode(
storageManager = storageManager,
descriptors = modules,
targetDeclarationProducer = ::CirModule,
commonValueProducer = { commonize(it, ModuleCommonizer.default()) },
recursionMarker = null,
nodeProducer = ::CirModuleNode
)
internal fun buildPackageNode(
storageManager: StorageManager,
moduleName: Name,
packageFqName: FqName,
packageMemberScopes: List<MemberScope?>
): CirPackageNode = buildNode(
storageManager = storageManager,
descriptors = packageMemberScopes,
targetDeclarationProducer = { CirPackage(packageFqName) },
commonValueProducer = { CirPackage(packageFqName) },
recursionMarker = null,
nodeProducer = ::CirPackageNode
).also { node ->
node.moduleName = moduleName
node.fqName = packageFqName
}
internal fun buildPropertyNode(
storageManager: StorageManager,
cache: CirClassifiersCache,
containingDeclarationCommon: NullableLazyValue<*>?,
properties: List<PropertyDescriptor?>
): CirPropertyNode = buildNode(
storageManager = storageManager,
descriptors = properties,
targetDeclarationProducer = ::CirWrappedProperty,
commonValueProducer = { commonize(containingDeclarationCommon, it, PropertyCommonizer(cache)) },
recursionMarker = null,
nodeProducer = ::CirPropertyNode
)
internal fun buildFunctionNode(
storageManager: StorageManager,
cache: CirClassifiersCache,
containingDeclarationCommon: NullableLazyValue<*>?,
functions: List<SimpleFunctionDescriptor?>
): CirFunctionNode = buildNode(
storageManager = storageManager,
descriptors = functions,
targetDeclarationProducer = ::CirWrappedFunction,
commonValueProducer = { commonize(containingDeclarationCommon, it, FunctionCommonizer(cache)) },
recursionMarker = null,
nodeProducer = ::CirFunctionNode
)
internal fun buildClassNode(
storageManager: StorageManager,
cacheRW: ClassifiersCacheImpl,
containingDeclarationCommon: NullableLazyValue<*>?,
classes: List<ClassDescriptor?>
): CirClassNode = buildNode(
storageManager = storageManager,
descriptors = classes,
targetDeclarationProducer = ::CirWrappedClass,
commonValueProducer = { commonize(containingDeclarationCommon, it, ClassCommonizer(cacheRW)) },
recursionMarker = CirClassRecursionMarker,
nodeProducer = ::CirClassNode
).also { node ->
classes.firstNonNull().fqNameSafe.let { fqName ->
node.fqName = fqName
cacheRW.classes.putSafe(fqName, node)
}
}
internal fun buildClassConstructorNode(
storageManager: StorageManager,
cache: CirClassifiersCache,
containingDeclarationCommon: NullableLazyValue<*>?,
constructors: List<ClassConstructorDescriptor?>
): CirClassConstructorNode = buildNode(
storageManager = storageManager,
descriptors = constructors,
targetDeclarationProducer = ::CirWrappedClassConstructor,
commonValueProducer = { commonize(containingDeclarationCommon, it, ClassConstructorCommonizer(cache)) },
recursionMarker = null,
nodeProducer = ::CirClassConstructorNode
)
internal fun buildTypeAliasNode(
storageManager: StorageManager,
cacheRW: ClassifiersCacheImpl,
typeAliases: List<TypeAliasDescriptor?>
): CirTypeAliasNode = buildNode(
storageManager = storageManager,
descriptors = typeAliases,
targetDeclarationProducer = ::CirWrappedTypeAlias,
commonValueProducer = { commonize(it, TypeAliasCommonizer(cacheRW)) },
recursionMarker = CirClassRecursionMarker,
nodeProducer = ::CirTypeAliasNode
).also { node ->
typeAliases.firstNonNull().fqNameSafe.let { fqName ->
node.fqName = fqName
cacheRW.typeAliases.putSafe(fqName, node)
}
}
private fun <D : Any, T : CirDeclaration, R : CirDeclaration, N : CirNode<T, R>> buildNode(
storageManager: StorageManager,
descriptors: List<D?>,
targetDeclarationProducer: (D) -> T,
commonValueProducer: (List<T?>) -> R?,
recursionMarker: R?,
nodeProducer: (List<T?>, NullableLazyValue<R>) -> N
): N {
val declarationsGroup = CommonizedGroup<T>(descriptors.size)
var canHaveCommon = descriptors.size > 1
descriptors.forEachIndexed { index, descriptor ->
if (descriptor != null)
declarationsGroup[index] = targetDeclarationProducer(descriptor)
else
canHaveCommon = false
}
val declarations = declarationsGroup.toList()
val commonComputable: () -> R? = if (canHaveCommon) {
{ commonValueProducer(declarations) }
} else {
{ null }
}
val commonLazyValue = if (recursionMarker != null)
storageManager.createRecursionTolerantNullableLazyValue(commonComputable, recursionMarker)
else
storageManager.createNullableLazyValue(commonComputable)
return nodeProducer(declarations, commonLazyValue)
}
@Suppress("NOTHING_TO_INLINE")
private inline fun <K, V : Any> MutableMap<K, V>.putSafe(key: K, value: V) = put(key, value)?.let { oldValue ->
error("${oldValue::class.java} with key=$key has been overwritten: $oldValue")
}
internal fun <T, R> commonize(declarations: List<T?>, commonizer: Commonizer<T, R>): R? {
for (declaration in declarations) {
if (declaration == null || !commonizer.commonizeWith(declaration))
return null
}
return commonizer.result
}
@Suppress("NOTHING_TO_INLINE")
private inline fun <T, R> commonize(
containingDeclarationCommon: NullableLazyValue<*>?,
declarations: List<T?>,
commonizer: Commonizer<T, R>
): R? {
if (containingDeclarationCommon != null && containingDeclarationCommon.invoke() == null) {
// don't commonize declaration if it has commonizable containing declaration that has not been successfully commonized
return null
}
return commonize(declarations, commonizer)
}
@@ -0,0 +1,149 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree.ir
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.NullableLazyValue
interface CirNode<T : CirDeclaration, R : CirDeclaration> {
val target: List<T?>
val common: NullableLazyValue<R>
fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R
}
interface CirNodeWithFqName<T : CirDeclaration, R : CirDeclaration> : CirNode<T, R> {
val fqName: FqName
}
class CirRootNode(
override val target: List<CirRoot>,
override val common: NullableLazyValue<CirRoot>
) : CirNode<CirRoot, CirRoot> {
class ClassifiersCacheImpl : CirClassifiersCache {
override val classes = HashMap<FqName, CirClassNode>()
override val typeAliases = HashMap<FqName, CirTypeAliasNode>()
}
val modules: MutableList<CirModuleNode> = ArrayList()
val cache = ClassifiersCacheImpl()
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R =
visitor.visitRootNode(this, data)
override fun toString() = toString(this)
}
class CirModuleNode(
override val target: List<CirModule?>,
override val common: NullableLazyValue<CirModule>
) : CirNode<CirModule, CirModule> {
val packages: MutableList<CirPackageNode> = ArrayList()
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T) =
visitor.visitModuleNode(this, data)
override fun toString() = toString(this)
}
class CirPackageNode(
override val target: List<CirPackage?>,
override val common: NullableLazyValue<CirPackage>
) : CirNodeWithFqName<CirPackage, CirPackage> {
lateinit var moduleName: Name
override lateinit var fqName: FqName
val properties: MutableList<CirPropertyNode> = ArrayList()
val functions: MutableList<CirFunctionNode> = ArrayList()
val classes: MutableList<CirClassNode> = ArrayList()
val typeAliases: MutableList<CirTypeAliasNode> = ArrayList()
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T) =
visitor.visitPackageNode(this, data)
override fun toString() = toString(this)
}
class CirPropertyNode(
override val target: List<CirProperty?>,
override val common: NullableLazyValue<CirProperty>
) : CirNode<CirProperty, CirProperty> {
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T) =
visitor.visitPropertyNode(this, data)
override fun toString() = toString(this)
}
class CirFunctionNode(
override val target: List<CirFunction?>,
override val common: NullableLazyValue<CirFunction>
) : CirNode<CirFunction, CirFunction> {
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T) =
visitor.visitFunctionNode(this, data)
override fun toString() = toString(this)
}
class CirClassNode(
override val target: List<CirClass?>,
override val common: NullableLazyValue<CirClass>
) : CirNodeWithFqName<CirClass, CirClass> {
override lateinit var fqName: FqName
val constructors: MutableList<CirClassConstructorNode> = ArrayList()
val properties: MutableList<CirPropertyNode> = ArrayList()
val functions: MutableList<CirFunctionNode> = ArrayList()
val classes: MutableList<CirClassNode> = ArrayList()
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R =
visitor.visitClassNode(this, data)
override fun toString() = toString(this)
}
class CirClassConstructorNode(
override val target: List<CirClassConstructor?>,
override val common: NullableLazyValue<CirClassConstructor>
) : CirNode<CirClassConstructor, CirClassConstructor> {
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R =
visitor.visitClassConstructorNode(this, data)
override fun toString() = toString(this)
}
class CirTypeAliasNode(
override val target: List<CirTypeAlias?>,
override val common: NullableLazyValue<CirClass>
) : CirNodeWithFqName<CirTypeAlias, CirClass> {
override lateinit var fqName: FqName
override fun <R, T> accept(visitor: CirNodeVisitor<R, T>, data: T): R =
visitor.visitTypeAliasNode(this, data)
override fun toString() = toString(this)
}
interface CirClassifiersCache {
val classes: Map<FqName, CirClassNode>
val typeAliases: Map<FqName, CirTypeAliasNode>
}
internal inline val CirNode<*, *>.indexOfCommon: Int
get() = target.size
internal inline val CirNode<*, *>.dimension: Int
get() = target.size + 1
private fun toString(node: CirNode<*, *>) = buildString {
if (node is CirNodeWithFqName) {
append("fqName=").append(node.fqName).append(", ")
}
append("target=")
node.target.joinTo(this)
append(", common=")
append(if (node.common.isComputed()) node.common() else "<NOT COMPUTED>")
}
@@ -0,0 +1,91 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.core.Commonizer
import org.jetbrains.kotlin.descriptors.commonizer.utils.fqNameWithTypeParameters
import org.jetbrains.kotlin.descriptors.commonizer.utils.isBlacklistedDarwinFunction
import org.jetbrains.kotlin.descriptors.commonizer.utils.isKniBridgeFunction
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope
internal fun MemberScope.collectMembers(vararg collectors: (DeclarationDescriptor) -> Boolean) =
getContributedDescriptors().forEach { member ->
collectors.any { it(member) }
// each member must be consumed, otherwise - error
|| error("Unhandled member declaration: $member")
}
@Suppress("FunctionName")
private inline fun <reified T : DeclarationDescriptor> Collector(
crossinline typedCollector: (T) -> Unit
): (DeclarationDescriptor) -> Boolean = { candidate ->
if (candidate is T) {
typedCollector(candidate)
true
} else
false
}
@Suppress("FunctionName")
internal inline fun ClassCollector(
crossinline typedCollector: (ClassDescriptor) -> Unit
): (DeclarationDescriptor) -> Boolean = Collector(typedCollector)
@Suppress("FunctionName")
internal inline fun TypeAliasCollector(
crossinline typedCollector: (TypeAliasDescriptor) -> Unit
): (DeclarationDescriptor) -> Boolean = Collector(typedCollector)
@Suppress("FunctionName")
internal inline fun PropertyCollector(
crossinline typedCollector: (PropertyDescriptor) -> Unit
): (DeclarationDescriptor) -> Boolean = Collector<PropertyDescriptor> { candidate ->
if (candidate.kind.isReal) // omit fake overrides
typedCollector(candidate)
}
@Suppress("FunctionName")
internal inline fun FunctionCollector(
crossinline typedCollector: (SimpleFunctionDescriptor) -> Unit
): (DeclarationDescriptor) -> Boolean = Collector<SimpleFunctionDescriptor> { candidate ->
if (candidate.kind.isReal && !candidate.isKniBridgeFunction() && !candidate.isBlacklistedDarwinFunction())
typedCollector(candidate)
}
/** Used for approximation of [PropertyDescriptor]s before running concrete [Commonizer]s */
internal data class PropertyApproximationKey(
val name: Name,
val extensionReceiverParameter: String?
) {
constructor(property: PropertyDescriptor) : this(
property.name,
property.extensionReceiverParameter?.type?.fqNameWithTypeParameters
)
}
/** Used for approximation of [SimpleFunctionDescriptor]s before running concrete [Commonizer]s */
internal data class FunctionApproximationKey(
val name: Name,
val valueParameters: List<Pair<Name, String>>,
val extensionReceiverParameter: String?
) {
constructor(function: SimpleFunctionDescriptor) : this(
function.name,
function.valueParameters.map { it.name to it.type.fqNameWithTypeParameters },
function.extensionReceiverParameter?.type?.fqNameWithTypeParameters
)
}
/** Used for approximation of [ConstructorDescriptor]s before running concrete [Commonizer]s */
internal data class ConstructorApproximationKey(
val valueParameters: List<Pair<Name, String>>
) {
constructor(constructor: ConstructorDescriptor) : this(
constructor.valueParameters.map { it.name to it.type.fqNameWithTypeParameters }
)
}
@@ -0,0 +1,73 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.backend.common.serialization.metadata.impl.ExportedForwardDeclarationsPackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirModuleNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirRootNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.buildModuleNode
import org.jetbrains.kotlin.descriptors.commonizer.utils.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.scopes.ChainedMemberScope
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.utils.alwaysTrue
internal fun mergeModules(
storageManager: StorageManager,
cacheRW: CirRootNode.ClassifiersCacheImpl,
modules: List<ModuleDescriptor?>
): CirModuleNode {
val node = buildModuleNode(storageManager, modules)
val packageMemberScopesMap = CommonizedGroupMap<FqName, MemberScope>(modules.size)
modules.forEachIndexed { index, module ->
module?.collectNonEmptyPackageMemberScopes { packageFqName, memberScope ->
packageMemberScopesMap[packageFqName][index] = memberScope
}
}
val moduleName = modules.firstNonNull().name
for ((packageFqName, packageMemberScopesGroup) in packageMemberScopesMap) {
node.packages += mergePackages(storageManager, cacheRW, moduleName, packageFqName, packageMemberScopesGroup.toList())
}
return node
}
// collects member scopes for every non-empty package provided by this module
internal fun ModuleDescriptor.collectNonEmptyPackageMemberScopes(collector: (FqName, MemberScope) -> Unit) {
// we don's need to process fragments from other modules which are the dependencies of this module, so
// let's use the appropriate package fragment provider
val packageFragmentProvider = this.packageFragmentProvider
fun recurse(packageFqName: FqName) {
if (packageFqName.isUnderStandardKotlinPackages || packageFqName.isUnderKotlinNativeSyntheticPackages)
return
val ownPackageFragments = packageFragmentProvider.getPackageFragments(packageFqName)
val ownPackageMemberScopes = ownPackageFragments.asSequence()
.filter { it !is ExportedForwardDeclarationsPackageFragmentDescriptor }
.map { it.getMemberScope() }
.filter { it != MemberScope.Empty }
.toList(ownPackageFragments.size)
if (ownPackageMemberScopes.isNotEmpty()) {
// don't include subpackages into chained member scope
val memberScope = ChainedMemberScope.create(
"package member scope for $packageFqName in $name",
ownPackageMemberScopes
)
collector(packageFqName, memberScope)
}
packageFragmentProvider.getSubPackagesOf(packageFqName, alwaysTrue()).toSet().map { recurse(it) }
}
recurse(FqName.ROOT)
}
@@ -0,0 +1,61 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirPackageNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirRootNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.buildPackageNode
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroupMap
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.StorageManager
internal fun mergePackages(
storageManager: StorageManager,
cacheRW: CirRootNode.ClassifiersCacheImpl,
moduleName: Name,
packageFqName: FqName,
packageMemberScopes: List<MemberScope?>
): CirPackageNode {
val node = buildPackageNode(storageManager, moduleName, packageFqName, packageMemberScopes)
val propertiesMap = CommonizedGroupMap<PropertyApproximationKey, PropertyDescriptor>(packageMemberScopes.size)
val functionsMap = CommonizedGroupMap<FunctionApproximationKey, SimpleFunctionDescriptor>(packageMemberScopes.size)
val classesMap = CommonizedGroupMap<Name, ClassDescriptor>(packageMemberScopes.size)
val typeAliasesMap = CommonizedGroupMap<Name, TypeAliasDescriptor>(packageMemberScopes.size)
packageMemberScopes.forEachIndexed { index, memberScope ->
memberScope?.collectMembers(
PropertyCollector { propertiesMap[PropertyApproximationKey(it)][index] = it },
FunctionCollector { functionsMap[FunctionApproximationKey(it)][index] = it },
ClassCollector { classesMap[it.name][index] = it },
TypeAliasCollector { typeAliasesMap[it.name][index] = it }
)
}
for ((_, propertiesGroup) in propertiesMap) {
node.properties += mergeProperties(storageManager, cacheRW, null, propertiesGroup.toList())
}
for ((_, functionsGroup) in functionsMap) {
node.functions += mergeFunctions(storageManager, cacheRW, null, functionsGroup.toList())
}
for ((_, classesGroup) in classesMap) {
node.classes += mergeClasses(storageManager, cacheRW, null, classesGroup.toList())
}
for ((_, typeAliasesGroup) in typeAliasesMap) {
node.typeAliases += mergeTypeAliases(storageManager, cacheRW, typeAliasesGroup.toList())
}
return node
}
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.InputTarget
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirRootNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.buildRootNode
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroupMap
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.StorageManager
internal fun mergeRoots(
storageManager: StorageManager,
modulesByTargets: List<Pair<InputTarget, Collection<ModuleDescriptor>>>
): CirRootNode {
val node = buildRootNode(storageManager, modulesByTargets.map { it.first })
val modulesMap = CommonizedGroupMap<Name, ModuleDescriptor>(modulesByTargets.size)
modulesByTargets.forEachIndexed { index, (_, modules) ->
for (module in modules) {
modulesMap[module.name][index] = module
}
}
for ((_, modulesGroup) in modulesMap) {
node.modules += mergeModules(storageManager, node.cache, modulesGroup.toList())
}
return node
}
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.utils
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.util.UniqId
internal object EmptyDescriptorTable : DescriptorTable {
private const val DEFAULT_UNIQ_ID_INDEX = 0L
override fun put(descriptor: DeclarationDescriptor, uniqId: UniqId) = error("unsupported")
override fun get(descriptor: DeclarationDescriptor): Long = DEFAULT_UNIQ_ID_INDEX
}
@@ -0,0 +1,12 @@
/*
* Copyright 2010-2020 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.descriptors.commonizer.utils
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
import org.jetbrains.kotlin.konan.util.KlibMetadataFactories
import org.jetbrains.kotlin.serialization.konan.NullFlexibleTypeDeserializer
object NativeFactories : KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer)
@@ -0,0 +1,50 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.utils
import java.lang.System.currentTimeMillis
internal class ResettableClockMark {
internal class Period(val start: Long, val end: Long) {
override fun toString(): String {
var remainder = end - start
val millis = remainder % 1000
remainder /= 1000
val seconds = remainder % 60
remainder /= 60
val minutes = remainder % 60
val hours = remainder / 60
// human-friendly formatted duration
return buildString {
if (hours > 0) append(hours).append("h ")
if (minutes > 0 || isNotEmpty()) append(minutes).append("m ")
if (seconds > 0 || isNotEmpty()) append(seconds).append("s ")
if (millis > 0 || isNotEmpty()) append(millis).append("ms")
}
}
}
private val startMark = currentTimeMillis()
private var lastMark = startMark
fun elapsedSinceLast(): Period = Period(lastMark, currentTimeMillis()).also { lastMark = it.end }
fun elapsedSinceStart(): Period = Period(startMark, currentTimeMillis())
}
// TODO: this is how it should be when Kotlin Time will become non-experimental
//@ExperimentalTime
//internal class ResettableClockMark {
// private val startMark = MonoClock.markNow()
// private var lastMark = startMark
//
// fun elapsedSinceLast(): Duration = lastMark.elapsedNow().also { lastMark = lastMark.plus(it) }
// fun elapsedSinceStart(): Duration = startMark.elapsedNow()
//}
@@ -0,0 +1,38 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.utils
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.getAbbreviation
private val DEPRECATED_ANNOTATION_FQN = FqName(Deprecated::class.java.name)
internal fun SimpleFunctionDescriptor.isKniBridgeFunction() =
name.asString().startsWith("kniBridge")
// the following logic determines Kotlin functions with conflicting overloads in Darwin library:
internal fun SimpleFunctionDescriptor.isBlacklistedDarwinFunction(): Boolean {
if ((containingDeclaration as? PackageFragmentDescriptor)?.fqName?.isUnderDarwinPackage != true)
return false
val name = name.asString()
if (!name.startsWith("simd_") && !name.startsWith("__"))
return false
if (annotations.hasAnnotation(DEPRECATED_ANNOTATION_FQN))
return true
return valueParameters.any { parameter ->
val type = parameter.type
val abbreviationType = type.getAbbreviation()
abbreviationType != null
&& abbreviationType.declarationDescriptor.name.asString().startsWith("simd_")
&& type.declarationDescriptor.name.asString() == "Vector128"
}
}
@@ -0,0 +1,49 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.utils
/** Fixed-size ordered collection with no extra space that represents a commonized group of same-rank elements */
internal class CommonizedGroup<T : Any>(
val size: Int,
initialize: (Int) -> T?
) {
constructor(elements: List<T?>) : this(elements.size, elements::get)
constructor(size: Int) : this(size, { null })
// array constructor requires concrete type which is known only at the call site,
// so let's use `Any?` instead if `T` here
private val elements = Array<Any?>(size, initialize)
operator fun get(index: Int): T? {
@Suppress("UNCHECKED_CAST")
return elements[index] as T?
}
operator fun set(index: Int, value: T) {
val oldValue = this[index]
check(oldValue == null) { "$oldValue can not be overwritten with $value at index $index" }
elements[index] = value
}
fun toList(): List<T?> = object : AbstractList<T?>() {
override val size
get() = this@CommonizedGroup.size
override fun get(index: Int): T? = this@CommonizedGroup[index]
}
}
internal class CommonizedGroupMap<K, V : Any>(val size: Int) : Iterable<Map.Entry<K, CommonizedGroup<V>>> {
private val wrapped: MutableMap<K, CommonizedGroup<V>> = HashMap()
operator fun get(key: K): CommonizedGroup<V> = wrapped.getOrPut(key) { CommonizedGroup(size) }
fun getOrNull(key: K): CommonizedGroup<V>? = wrapped[key]
override fun iterator(): Iterator<Map.Entry<K, CommonizedGroup<V>>> = wrapped.iterator()
}
@@ -0,0 +1,44 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.utils
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.serialization.konan.impl.ForwardDeclarationsFqNames
private val STANDARD_KOTLIN_PACKAGE_PREFIXES = listOf(
KotlinBuiltIns.BUILT_INS_PACKAGE_NAME.asString(),
"kotlinx"
)
private val KOTLIN_NATIVE_SYNTHETIC_PACKAGES_PREFIXES = ForwardDeclarationsFqNames.syntheticPackages
.map { fqName ->
check(!fqName.isRoot)
fqName.asString()
}
private const val DARWIN_PACKAGE_PREFIX = "platform.darwin"
internal val FqName.isUnderStandardKotlinPackages: Boolean
get() = hasAnyPrefix(STANDARD_KOTLIN_PACKAGE_PREFIXES)
internal val FqName.isUnderKotlinNativeSyntheticPackages: Boolean
get() = hasAnyPrefix(KOTLIN_NATIVE_SYNTHETIC_PACKAGES_PREFIXES)
internal val FqName.isUnderDarwinPackage: Boolean
get() = asString().hasPrefix(DARWIN_PACKAGE_PREFIX)
private fun FqName.hasAnyPrefix(prefixes: List<String>): Boolean =
asString().let { fqName -> prefixes.any(fqName::hasPrefix) }
private fun String.hasPrefix(prefix: String): Boolean {
val lengthDifference = length - prefix.length
return when {
lengthDifference == 0 -> this == prefix
lengthDifference > 0 -> this[prefix.length] == '.' && this.startsWith(prefix)
else -> false
}
}
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.utils
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
internal fun <T> Sequence<T>.toList(expectedCapacity: Int): List<T> {
val result = ArrayList<T>(expectedCapacity)
toCollection(result)
return result
}
internal inline fun <reified T> Iterable<T?>.firstNonNull() = firstIsInstance<T>()
internal fun Any?.isNull(): Boolean = this == null
@@ -0,0 +1,48 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.utils
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.utils.NativeFactories.DefaultDeserializedDescriptorFactory
import org.jetbrains.kotlin.descriptors.commonizer.utils.NativeFactories.createDefaultKonanResolvedModuleDescriptorsFactory
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.serialization.konan.impl.KlibResolvedModuleDescriptorsFactoryImpl
import org.jetbrains.kotlin.storage.StorageManager
internal val ModuleDescriptor.packageFragmentProvider
get() = (this as ModuleDescriptorImpl).packageFragmentProviderForModuleContentWithoutDependencies
internal fun createKotlinNativeForwardDeclarationsModule(
storageManager: StorageManager,
builtIns: KotlinBuiltIns
): ModuleDescriptorImpl =
(createDefaultKonanResolvedModuleDescriptorsFactory(DefaultDeserializedDescriptorFactory) as KlibResolvedModuleDescriptorsFactoryImpl)
.createForwardDeclarationsModule(
builtIns = builtIns,
storageManager = storageManager
)
// similar to org.jetbrains.kotlin.descriptors.DescriptorUtilKt#resolveClassByFqName, but resolves also type aliases
internal fun ModuleDescriptor.resolveClassOrTypeAliasByFqName(
fqName: FqName,
lookupLocation: LookupLocation
): ClassifierDescriptorWithTypeParameters? {
if (fqName.isRoot) return null
(getPackage(fqName.parent()).memberScope.getContributedClassifier(
fqName.shortName(),
lookupLocation
) as? ClassifierDescriptorWithTypeParameters)?.let { return it }
return (resolveClassOrTypeAliasByFqName(fqName.parent(), lookupLocation) as? ClassDescriptor)
?.unsubstitutedInnerClassesScope
?.getContributedClassifier(fqName.shortName(), lookupLocation) as? ClassifierDescriptorWithTypeParameters
}
@@ -0,0 +1,66 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.utils
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
internal inline val KotlinType.declarationDescriptor: ClassifierDescriptor
get() = (constructor.declarationDescriptor ?: error("No declaration descriptor found for $constructor"))
internal inline val KotlinType.fqName: FqName
get() = declarationDescriptor.fqNameSafe
internal val KotlinType.fqNameWithTypeParameters: String
get() = buildString { buildFqNameWithTypeParameters(this@fqNameWithTypeParameters, HashSet()) }
private fun StringBuilder.buildFqNameWithTypeParameters(type: KotlinType, exploredTypeParameters: MutableSet<KotlinType>) {
append(type.fqName)
val typeParameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type)
if (typeParameterDescriptor != null) {
// N.B this is type parameter type
if (exploredTypeParameters.add(type.makeNotNullable())) { // print upper bounds once the first time when type parameter type is met
append(":[")
typeParameterDescriptor.upperBounds.forEachIndexed { index, upperBound ->
if (index > 0)
append(",")
buildFqNameWithTypeParameters(upperBound, exploredTypeParameters)
}
append("]")
}
} else {
// N.B. this is classifier type
val arguments = type.arguments
if (arguments.isNotEmpty()) {
append("<")
arguments.forEachIndexed { index, argument ->
if (index > 0)
append(",")
if (argument.isStarProjection)
append("*")
else {
val variance = argument.projectionKind
if (variance != Variance.INVARIANT)
append(variance).append(" ")
buildFqNameWithTypeParameters(argument.type, exploredTypeParameters)
}
}
append(">")
}
}
if (type.isMarkedNullable)
append("?")
}
@@ -0,0 +1,24 @@
expect class Planet(name: String, diameter: Double) {
val name: String
val diameter: Double
}
expect val intProperty: Int
expect val Int.intProperty: Int
expect val Short.intProperty: Int
expect val Long.intProperty: Int
expect val String.intProperty: Int
expect val Planet.intProperty: Int
expect fun intFunction(): Int
expect fun Int.intFunction(): Int
expect fun Short.intFunction(): Int
expect fun Long.intFunction(): Int
expect fun String.intFunction(): Int
expect fun Planet.intFunction(): Int
expect val <T> T.propertyWithTypeParameter1: Int
expect val <T : Any?> T.propertyWithTypeParameter2: Int
expect val <T : CharSequence> T.propertyWithTypeParameter4: Int
expect fun <T> T.functionWithTypeParameter1()
@@ -0,0 +1,36 @@
actual class Planet actual constructor(actual val name: String, actual val diameter: Double)
actual val intProperty get() = 42
actual val Int.intProperty get() = this
actual val Short.intProperty get() = toInt()
actual val Long.intProperty get() = toInt()
actual val String.intProperty get() = length
actual val Planet.intProperty get() = diameter.toInt()
actual fun intFunction() = 42
actual fun Int.intFunction() = this
actual fun Short.intFunction() = toInt()
actual fun Long.intFunction() = toInt()
actual fun String.intFunction() = length
actual fun Planet.intFunction() = diameter.toInt()
val String.mismatchedProperty1 get() = 42
val mismatchedProperty2 get() = 42
fun String.mismatchedFunction1() = 42
fun mismatchedFunction2() = 42
actual val <T> T.propertyWithTypeParameter1 get() = 42
actual val <T> T.propertyWithTypeParameter2 get() = 42
val <T> T.propertyWithTypeParameter3 get() = 42
actual val <T : CharSequence> T.propertyWithTypeParameter4 get() = length
val <T : CharSequence> T.propertyWithTypeParameter5: Int get() = length
val <T : CharSequence> T.propertyWithTypeParameter6: Int get() = length
val <T : CharSequence> T.propertyWithTypeParameter7: Int get() = length
val <T> T.propertyWithTypeParameter8 get() = 42
val <T> T.propertyWithTypeParameter9 get() = 42
actual fun <T> T.functionWithTypeParameter1() {}
fun <T> T.functionWithTypeParameter2() {}
fun <T> T.functionWithTypeParameter3() {}
fun <T> T.functionWithTypeParameter4() {}
@@ -0,0 +1,36 @@
actual class Planet actual constructor(actual val name: String, actual val diameter: Double)
actual val intProperty get() = 42
actual val Int.intProperty get() = this
actual val Short.intProperty get() = toInt()
actual val Long.intProperty get() = toInt()
actual val String.intProperty get() = length
actual val Planet.intProperty get() = diameter.toInt()
actual fun intFunction() = 42
actual fun Int.intFunction() = this
actual fun Short.intFunction() = toInt()
actual fun Long.intFunction() = toInt()
actual fun String.intFunction() = length
actual fun Planet.intFunction() = diameter.toInt()
val mismatchedProperty1 get() = 42
val Double.mismatchedProperty2 get() = 42
fun mismatchedFunction1() = 42
fun Double.mismatchedFunction2() = 42
actual val <T> T.propertyWithTypeParameter1 get() = 42
actual val <T : Any?> T.propertyWithTypeParameter2 get() = 42
val <T : Any> T.propertyWithTypeParameter3 get() = 42
actual val <T : CharSequence> T.propertyWithTypeParameter4 get() = length
val <T : Appendable> T.propertyWithTypeParameter5: Int get() = length
val <T : String> T.propertyWithTypeParameter6: Int get() = length
val String.propertyWithTypeParameter7: Int get() = length
val <Q> Q.propertyWithTypeParameter8 get() = 42
val <T, Q> T.propertyWithTypeParameter9 get() = 42
actual fun <T> T.functionWithTypeParameter1() {}
fun <Q> Q.functionWithTypeParameter2() {}
fun <T, Q> T.functionWithTypeParameter3() {}
fun <T, Q> Q.functionWithTypeParameter4() {}
@@ -0,0 +1,36 @@
class Planet(val name: String, val diameter: Double)
val intProperty get() = 42
val Int.intProperty get() = this
val Short.intProperty get() = toInt()
val Long.intProperty get() = toInt()
val String.intProperty get() = length
val Planet.intProperty get() = diameter.toInt()
fun intFunction() = 42
fun Int.intFunction() = this
fun Short.intFunction() = toInt()
fun Long.intFunction() = toInt()
fun String.intFunction() = length
fun Planet.intFunction() = diameter.toInt()
val String.mismatchedProperty1 get() = 42
val mismatchedProperty2 get() = 42
fun String.mismatchedFunction1() = 42
fun mismatchedFunction2() = 42
val <T> T.propertyWithTypeParameter1 get() = 42
val <T> T.propertyWithTypeParameter2 get() = 42
val <T> T.propertyWithTypeParameter3 get() = 42
val <T : CharSequence> T.propertyWithTypeParameter4: Int get() = length
val <T : CharSequence> T.propertyWithTypeParameter5: Int get() = length
val <T : CharSequence> T.propertyWithTypeParameter6: Int get() = length
val <T : CharSequence> T.propertyWithTypeParameter7: Int get() = length
val <T> T.propertyWithTypeParameter8 get() = 42
val <T> T.propertyWithTypeParameter9 get() = 42
fun <T> T.functionWithTypeParameter1() {}
fun <T> T.functionWithTypeParameter2() {}
fun <T> T.functionWithTypeParameter3() {}
fun <T> T.functionWithTypeParameter4() {}
@@ -0,0 +1,36 @@
class Planet(val name: String, val diameter: Double)
val intProperty get() = 42
val Int.intProperty get() = this
val Short.intProperty get() = toInt()
val Long.intProperty get() = toInt()
val String.intProperty get() = length
val Planet.intProperty get() = diameter.toInt()
fun intFunction() = 42
fun Int.intFunction() = this
fun Short.intFunction() = toInt()
fun Long.intFunction() = toInt()
fun String.intFunction() = length
fun Planet.intFunction() = diameter.toInt()
val mismatchedProperty1 get() = 42
val Double.mismatchedProperty2 get() = 42
fun mismatchedFunction1() = 42
fun Double.mismatchedFunction2() = 42
val <T> T.propertyWithTypeParameter1 get() = 42
val <T : Any?> T.propertyWithTypeParameter2 get() = 42
val <T : Any> T.propertyWithTypeParameter3 get() = 42
val <T : CharSequence> T.propertyWithTypeParameter4: Int get() = length
val <T : Appendable> T.propertyWithTypeParameter5: Int get() = length
val <T : String> T.propertyWithTypeParameter6: Int get() = length
val String.propertyWithTypeParameter7: Int get() = length
val <Q> Q.propertyWithTypeParameter8 get() = 42
val <T, Q> T.propertyWithTypeParameter9 get() = 42
fun <T> T.functionWithTypeParameter1() {}
fun <Q> Q.functionWithTypeParameter2() {}
fun <T, Q> T.functionWithTypeParameter3() {}
fun <T, Q> Q.functionWithTypeParameter4() {}
@@ -0,0 +1,42 @@
expect class Planet(name: String, diameter: Double) {
val name: String
val diameter: Double
}
expect val propertyWithInferredType1: Int
expect val propertyWithInferredType2: String
expect val propertyWithInferredType3: String
expect val propertyWithInferredType4: Nothing?
expect val propertyWithInferredType5: Planet
expect class C
expect val property1: Int
expect val property2: String
expect val property3: Planet
expect val property6: Planet
expect val property7: C
expect fun function1(): Int
expect fun function2(): String
expect fun function3(): Planet
expect fun function6(): Planet
expect fun function7(): C
expect class Box<T>(value: T) {
val value: T
}
expect class Fox()
expect fun functionWithTypeParametersInReturnType1(): Array<Int>
expect fun functionWithTypeParametersInReturnType3(): Array<String>
expect fun functionWithTypeParametersInReturnType4(): List<Int>
expect fun functionWithTypeParametersInReturnType6(): List<String>
expect fun functionWithTypeParametersInReturnType7(): Box<Int>
expect fun functionWithTypeParametersInReturnType9(): Box<String>
expect fun functionWithTypeParametersInReturnType10(): Box<Planet>
expect fun functionWithTypeParametersInReturnType12(): Box<Fox>
expect fun <T> functionWithUnsubstitutedTypeParametersInReturnType1(): T
expect fun <T> functionWithUnsubstitutedTypeParametersInReturnType2(): T
expect fun <T> functionWithUnsubstitutedTypeParametersInReturnType8(): Box<T>
@@ -0,0 +1,64 @@
actual class Planet actual constructor(actual val name: String, actual val diameter: Double)
actual val propertyWithInferredType1 = 1
actual val propertyWithInferredType2 = "hello"
actual val propertyWithInferredType3 = 42.toString()
actual val propertyWithInferredType4 = null
actual val propertyWithInferredType5 = Planet("Earth", 12742)
typealias A = Planet
actual typealias C = Planet
actual val property1 = 1
actual val property2 = "hello"
actual val property3 = Planet("Earth", 12742)
val property4 = A("Earth", 12742)
val property5 = A("Earth", 12742)
actual val property6 = Planet("Earth", 12742)
actual val property7 = C("Earth", 12742)
actual fun function1() = 1
actual fun function2() = "hello"
actual fun function3() = Planet("Earth", 12742)
fun function4() = A("Earth", 12742)
fun function5() = A("Earth", 12742)
actual fun function6() = Planet("Earth", 12742)
actual fun function7() = C("Earth", 12742)
val propertyWithMismatchedType1: Int = 1
val propertyWithMismatchedType2: Int = 1
val propertyWithMismatchedType3: Int = 1
val propertyWithMismatchedType4: Int = 1
val propertyWithMismatchedType5: Int = 1
fun functionWithMismatchedType1(): Int = 1
fun functionWithMismatchedType2(): Int = 1
fun functionWithMismatchedType3(): Int = 1
fun functionWithMismatchedType4(): Int = 1
fun functionWithMismatchedType5(): Int = 1
actual class Box<T> actual constructor(actual val value: T)
actual class Fox actual constructor()
actual fun functionWithTypeParametersInReturnType1() = arrayOf(1)
fun functionWithTypeParametersInReturnType2() = arrayOf(1)
actual fun functionWithTypeParametersInReturnType3() = arrayOf("hello")
actual fun functionWithTypeParametersInReturnType4(): List<Int> = listOf(1)
fun functionWithTypeParametersInReturnType5(): List<Int> = listOf(1)
actual fun functionWithTypeParametersInReturnType6(): List<String> = listOf("hello")
actual fun functionWithTypeParametersInReturnType7() = Box(1)
fun functionWithTypeParametersInReturnType8() = Box(1)
actual fun functionWithTypeParametersInReturnType9() = Box("hello")
actual fun functionWithTypeParametersInReturnType10() = Box(Planet("Earth", 12742))
fun functionWithTypeParametersInReturnType11() = Box(Planet("Earth", 12742))
actual fun functionWithTypeParametersInReturnType12() = Box(Fox())
actual fun <T> functionWithUnsubstitutedTypeParametersInReturnType1(): T = TODO()
actual fun <T> functionWithUnsubstitutedTypeParametersInReturnType2(): T = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType3(): T = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType4(): T = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType5(): T = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType6(): T = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType7(): T = TODO()
actual fun <T> functionWithUnsubstitutedTypeParametersInReturnType8(): Box<T> = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType9(): Box<T> = TODO()
@@ -0,0 +1,64 @@
actual class Planet actual constructor(actual val name: String, actual val diameter: Double)
actual val propertyWithInferredType1 get() = 1
actual val propertyWithInferredType2 get() = "hello"
actual val propertyWithInferredType3 get() = 42.toString()
actual val propertyWithInferredType4 get() = null
actual val propertyWithInferredType5 get() = Planet("Earth", 12742)
typealias B = Planet
actual typealias C = Planet
actual val property1 = 1
actual val property2 = "hello"
actual val property3 = Planet("Earth", 12742)
val property4: B = Planet("Earth", 12742)
val property5: Planet = A("Earth", 12742)
actual val property6: Planet = A("Earth", 12742)
actual val property7: C = Planet("Earth", 12742)
actual fun function1(): Int = 1
actual fun function2(): String = "hello"
actual fun function3(): Planet = Planet("Earth", 12742)
fun function4(): B = A("Earth", 12742)
fun function5(): Planet = A("Earth", 12742)
actual fun function6(): Planet = Planet("Earth", 12742)
actual fun function7(): C = C("Earth", 12742)
val propertyWithMismatchedType1: Long = 1
val propertyWithMismatchedType2: Short = 1
val propertyWithMismatchedType3: Number = 1
val propertyWithMismatchedType4: Comparable<Int> = 1
val propertyWithMismatchedType5: String = 1.toString()
fun functionWithMismatchedType1(): Long = 1
fun functionWithMismatchedType2(): Short = 1
fun functionWithMismatchedType3(): Number = 1
fun functionWithMismatchedType4(): Comparable<Int> = 1
fun functionWithMismatchedType5(): String = 1.toString()
actual class Box<T> actual constructor(actual val value: T)
actual class Fox actual constructor()
actual fun functionWithTypeParametersInReturnType1() = arrayOf(1)
fun functionWithTypeParametersInReturnType2() = arrayOf("hello")
actual fun functionWithTypeParametersInReturnType3() = arrayOf("hello")
actual fun functionWithTypeParametersInReturnType4(): List<Int> = listOf(1)
fun functionWithTypeParametersInReturnType5(): List<String> = listOf("hello")
actual fun functionWithTypeParametersInReturnType6(): List<String> = listOf("hello")
actual fun functionWithTypeParametersInReturnType7() = Box(1)
fun functionWithTypeParametersInReturnType8() = Box("hello")
actual fun functionWithTypeParametersInReturnType9() = Box("hello")
actual fun functionWithTypeParametersInReturnType10() = Box(Planet("Earth", 12742))
fun functionWithTypeParametersInReturnType11() = Box(Fox())
actual fun functionWithTypeParametersInReturnType12() = Box(Fox())
actual fun <T> functionWithUnsubstitutedTypeParametersInReturnType1(): T = TODO()
actual fun <T : Any?> functionWithUnsubstitutedTypeParametersInReturnType2(): T = TODO()
fun <T : Any> functionWithUnsubstitutedTypeParametersInReturnType3(): T = TODO()
fun <Q> functionWithUnsubstitutedTypeParametersInReturnType4(): Q = TODO()
fun <T, Q> functionWithUnsubstitutedTypeParametersInReturnType5(): T = TODO()
fun <T, Q> functionWithUnsubstitutedTypeParametersInReturnType6(): Q = TODO()
fun functionWithUnsubstitutedTypeParametersInReturnType7(): String = TODO()
actual fun <T> functionWithUnsubstitutedTypeParametersInReturnType8(): Box<T> = TODO()
fun functionWithUnsubstitutedTypeParametersInReturnType9(): Box<String> = TODO()
@@ -0,0 +1,66 @@
class Planet(val name: String, val diameter: Double)
val propertyWithInferredType1 = 1
val propertyWithInferredType2 = "hello"
val propertyWithInferredType3 = 42.toString()
val propertyWithInferredType4 = null
val propertyWithInferredType5 = Planet("Earth", 12742)
typealias A = Planet
typealias C = Planet
// with inferred type:
val property1 = 1
val property2 = "hello"
val property3 = Planet("Earth", 12742)
val property4 = A("Earth", 12742)
val property5 = A("Earth", 12742)
val property6 = Planet("Earth", 12742)
val property7 = C("Earth", 12742)
// with inferred type:
fun function1() = 1
fun function2() = "hello"
fun function3() = Planet("Earth", 12742)
fun function4() = A("Earth", 12742)
fun function5() = A("Earth", 12742)
fun function6() = Planet("Earth", 12742)
fun function7() = C("Earth", 12742)
val propertyWithMismatchedType1: Int = 1
val propertyWithMismatchedType2: Int = 1
val propertyWithMismatchedType3: Int = 1
val propertyWithMismatchedType4: Int = 1
val propertyWithMismatchedType5: Int = 1
fun functionWithMismatchedType1(): Int = 1
fun functionWithMismatchedType2(): Int = 1
fun functionWithMismatchedType3(): Int = 1
fun functionWithMismatchedType4(): Int = 1
fun functionWithMismatchedType5(): Int = 1
class Box<T>(val value: T)
class Fox
fun functionWithTypeParametersInReturnType1() = arrayOf(1)
fun functionWithTypeParametersInReturnType2() = arrayOf(1)
fun functionWithTypeParametersInReturnType3() = arrayOf("hello")
fun functionWithTypeParametersInReturnType4(): List<Int> = listOf(1)
fun functionWithTypeParametersInReturnType5(): List<Int> = listOf(1)
fun functionWithTypeParametersInReturnType6(): List<String> = listOf("hello")
fun functionWithTypeParametersInReturnType7() = Box(1)
fun functionWithTypeParametersInReturnType8() = Box(1)
fun functionWithTypeParametersInReturnType9() = Box("hello")
fun functionWithTypeParametersInReturnType10() = Box(Planet("Earth", 12742))
fun functionWithTypeParametersInReturnType11() = Box(Planet("Earth", 12742))
fun functionWithTypeParametersInReturnType12() = Box(Fox())
fun <T> functionWithUnsubstitutedTypeParametersInReturnType1(): T = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType2(): T = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType3(): T = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType4(): T = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType5(): T = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType6(): T = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType7(): T = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType8(): Box<T> = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType9(): Box<T> = TODO()
@@ -0,0 +1,66 @@
class Planet(val name: String, val diameter: Double)
val propertyWithInferredType1 get() = 1
val propertyWithInferredType2 get() = "hello"
val propertyWithInferredType3 get() = 42.toString()
val propertyWithInferredType4 get() = null
val propertyWithInferredType5 get() = Planet("Earth", 12742)
typealias B = Planet
typealias C = Planet
// with explicit type:
val property1: Int = 1
val property2: String = "hello"
val property3: Planet = Planet("Earth", 12742)
val property4: B = Planet("Earth", 12742)
val property5: Planet = A("Earth", 12742)
val property6: Planet = A("Earth", 12742)
val property7: C = Planet("Earth", 12742)
// with explicit type:
fun function1(): Int = 1
fun function2(): String = "hello"
fun function3(): Planet = Planet("Earth", 12742)
fun function4(): B = A("Earth", 12742)
fun function5(): Planet = A("Earth", 12742)
fun function6(): Planet = Planet("Earth", 12742)
fun function7(): C = C("Earth", 12742)
val propertyWithMismatchedType1: Long = 1
val propertyWithMismatchedType2: Short = 1
val propertyWithMismatchedType3: Number = 1
val propertyWithMismatchedType4: Comparable<Int> = 1
val propertyWithMismatchedType5: String = 1.toString()
fun functionWithMismatchedType1(): Long = 1
fun functionWithMismatchedType2(): Short = 1
fun functionWithMismatchedType3(): Number = 1
fun functionWithMismatchedType4(): Comparable<Int> = 1
fun functionWithMismatchedType5(): String = 1.toString()
class Box<T>(val value: T)
class Fox
fun functionWithTypeParametersInReturnType1() = arrayOf(1)
fun functionWithTypeParametersInReturnType2() = arrayOf("hello")
fun functionWithTypeParametersInReturnType3() = arrayOf("hello")
fun functionWithTypeParametersInReturnType4(): List<Int> = listOf(1)
fun functionWithTypeParametersInReturnType5(): List<String> = listOf("hello")
fun functionWithTypeParametersInReturnType6(): List<String> = listOf("hello")
fun functionWithTypeParametersInReturnType7() = Box(1)
fun functionWithTypeParametersInReturnType8() = Box("hello")
fun functionWithTypeParametersInReturnType9() = Box("hello")
fun functionWithTypeParametersInReturnType10() = Box(Planet("Earth", 12742))
fun functionWithTypeParametersInReturnType11() = Box(Fox())
fun functionWithTypeParametersInReturnType12() = Box(Fox())
fun <T> functionWithUnsubstitutedTypeParametersInReturnType1(): T = TODO()
fun <T : Any?> functionWithUnsubstitutedTypeParametersInReturnType2(): T = TODO()
fun <T : Any> functionWithUnsubstitutedTypeParametersInReturnType3(): T = TODO()
fun <Q> functionWithUnsubstitutedTypeParametersInReturnType4(): Q = TODO()
fun <T, Q> functionWithUnsubstitutedTypeParametersInReturnType5(): T = TODO()
fun <T, Q> functionWithUnsubstitutedTypeParametersInReturnType6(): Q = TODO()
fun functionWithUnsubstitutedTypeParametersInReturnType7(): String = TODO()
fun <T> functionWithUnsubstitutedTypeParametersInReturnType8(): Box<T> = TODO()
fun functionWithUnsubstitutedTypeParametersInReturnType9(): Box<String> = TODO()
@@ -0,0 +1,43 @@
expect public val publicProperty: Int
expect internal val publicOrInternalProperty: Int
expect internal val internalProperty: Int
expect public fun publicFunction(): Int
expect internal fun publicOrInternalFunction(): Int
expect internal fun internalFunction(): Int
expect open class Outer1() {
public val publicProperty: Int
internal val publicOrInternalProperty: Int
internal val internalProperty: Int
public fun publicFunction(): Int
internal fun publicOrInternalFunction(): Int
internal fun internalFunction(): Int
open class Inner1() {
public val publicProperty: Int
internal val publicOrInternalProperty: Int
internal val internalProperty: Int
public fun publicFunction(): Int
internal fun publicOrInternalFunction(): Int
internal fun internalFunction(): Int
}
}
expect open class Outer2() {
public open val publicProperty: Int
internal open val internalProperty: Int
public open fun publicFunction(): Int
internal open fun internalFunction(): Int
open class Inner2() {
public open val publicProperty: Int
internal open val internalProperty: Int
public open fun publicFunction(): Int
internal open fun internalFunction(): Int
}
}
@@ -0,0 +1,67 @@
actual public val publicProperty = 1
actual public val publicOrInternalProperty = 1
actual internal val internalProperty = 1
internal val internalOrPrivateProperty = 1
private val privateProperty = 1
actual public fun publicFunction() = 1
actual public fun publicOrInternalFunction() = 1
actual internal fun internalFunction() = 1
internal fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
actual open class Outer1 actual constructor() {
actual public val publicProperty = 1
actual public val publicOrInternalProperty = 1
actual internal val internalProperty = 1
internal val internalOrPrivateProperty = 1
private val privateProperty = 1
actual public fun publicFunction() = 1
actual public fun publicOrInternalFunction() = 1
actual internal fun internalFunction() = 1
internal fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
actual open class Inner1 actual constructor() {
actual public val publicProperty = 1
actual public val publicOrInternalProperty = 1
actual internal val internalProperty = 1
internal val internalOrPrivateProperty = 1
private val privateProperty = 1
actual public fun publicFunction() = 1
actual public fun publicOrInternalFunction() = 1
actual internal fun internalFunction() = 1
internal fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
}
}
actual open class Outer2 actual constructor() {
actual public open val publicProperty = 1
public open val publicOrInternalProperty = 1
actual internal open val internalProperty = 1
internal open val internalOrPrivateProperty = 1
private val privateProperty = 1
actual public open fun publicFunction() = 1
public open fun publicOrInternalFunction() = 1
actual internal open fun internalFunction() = 1
internal open fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
actual open class Inner2 actual constructor() {
actual public open val publicProperty = 1
public open val publicOrInternalProperty = 1
actual internal open val internalProperty = 1
internal open val internalOrPrivateProperty = 1
private val privateProperty = 1
actual public open fun publicFunction() = 1
public open fun publicOrInternalFunction() = 1
actual internal open fun internalFunction() = 1
internal open fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
}
}
@@ -0,0 +1,67 @@
actual public val publicProperty = 1
actual internal val publicOrInternalProperty = 1
actual internal val internalProperty = 1
private val internalOrPrivateProperty = 1
private val privateProperty = 1
actual public fun publicFunction() = 1
actual internal fun publicOrInternalFunction() = 1
actual internal fun internalFunction() = 1
private fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
actual open class Outer1 actual constructor() {
actual public val publicProperty = 1
actual internal val publicOrInternalProperty = 1
actual internal val internalProperty = 1
private val internalOrPrivateProperty = 1
private val privateProperty = 1
actual public fun publicFunction() = 1
actual internal fun publicOrInternalFunction() = 1
actual internal fun internalFunction() = 1
private fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
actual open class Inner1 actual constructor() {
actual public val publicProperty = 1
actual internal val publicOrInternalProperty = 1
actual internal val internalProperty = 1
private val internalOrPrivateProperty = 1
private val privateProperty = 1
actual public fun publicFunction() = 1
actual internal fun publicOrInternalFunction() = 1
actual internal fun internalFunction() = 1
private fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
}
}
actual open class Outer2 actual constructor() {
actual public open val publicProperty = 1
internal open val publicOrInternalProperty = 1
actual internal open val internalProperty = 1
private val internalOrPrivateProperty = 1
private val privateProperty = 1
actual public open fun publicFunction() = 1
internal open fun publicOrInternalFunction() = 1
actual internal open fun internalFunction() = 1
private fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
actual open class Inner2 actual constructor() {
actual public open val publicProperty = 1
internal open val publicOrInternalProperty = 1
actual internal open val internalProperty = 1
private val internalOrPrivateProperty = 1
private val privateProperty = 1
actual public open fun publicFunction() = 1
internal open fun publicOrInternalFunction() = 1
actual internal open fun internalFunction() = 1
private fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
}
}
@@ -0,0 +1,67 @@
public val publicProperty = 1
public val publicOrInternalProperty = 1
internal val internalProperty = 1
internal val internalOrPrivateProperty = 1
private val privateProperty = 1
public fun publicFunction() = 1
public fun publicOrInternalFunction() = 1
internal fun internalFunction() = 1
internal fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
open class Outer1 {
public val publicProperty = 1
public val publicOrInternalProperty = 1
internal val internalProperty = 1
internal val internalOrPrivateProperty = 1
private val privateProperty = 1
public fun publicFunction() = 1
public fun publicOrInternalFunction() = 1
internal fun internalFunction() = 1
internal fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
open class Inner1 {
public val publicProperty = 1
public val publicOrInternalProperty = 1
internal val internalProperty = 1
internal val internalOrPrivateProperty = 1
private val privateProperty = 1
public fun publicFunction() = 1
public fun publicOrInternalFunction() = 1
internal fun internalFunction() = 1
internal fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
}
}
open class Outer2 {
public open val publicProperty = 1
public open val publicOrInternalProperty = 1
internal open val internalProperty = 1
internal open val internalOrPrivateProperty = 1
private val privateProperty = 1
public open fun publicFunction() = 1
public open fun publicOrInternalFunction() = 1
internal open fun internalFunction() = 1
internal open fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
open class Inner2 {
public open val publicProperty = 1
public open val publicOrInternalProperty = 1
internal open val internalProperty = 1
internal open val internalOrPrivateProperty = 1
private val privateProperty = 1
public open fun publicFunction() = 1
public open fun publicOrInternalFunction() = 1
internal open fun internalFunction() = 1
internal open fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
}
}
@@ -0,0 +1,67 @@
public val publicProperty = 1
internal val publicOrInternalProperty = 1
internal val internalProperty = 1
private val internalOrPrivateProperty = 1
private val privateProperty = 1
public fun publicFunction() = 1
internal fun publicOrInternalFunction() = 1
internal fun internalFunction() = 1
private fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
open class Outer1 {
public val publicProperty = 1
internal val publicOrInternalProperty = 1
internal val internalProperty = 1
private val internalOrPrivateProperty = 1
private val privateProperty = 1
public fun publicFunction() = 1
internal fun publicOrInternalFunction() = 1
internal fun internalFunction() = 1
private fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
open class Inner1 {
public val publicProperty = 1
internal val publicOrInternalProperty = 1
internal val internalProperty = 1
private val internalOrPrivateProperty = 1
private val privateProperty = 1
public fun publicFunction() = 1
internal fun publicOrInternalFunction() = 1
internal fun internalFunction() = 1
private fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
}
}
open class Outer2 {
public open val publicProperty = 1
internal open val publicOrInternalProperty = 1
internal open val internalProperty = 1
private val internalOrPrivateProperty = 1
private val privateProperty = 1
public open fun publicFunction() = 1
internal open fun publicOrInternalFunction() = 1
internal open fun internalFunction() = 1
private fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
open class Inner2 {
public open val publicProperty = 1
internal open val publicOrInternalProperty = 1
internal open val internalProperty = 1
private val internalOrPrivateProperty = 1
private val privateProperty = 1
public open fun publicFunction() = 1
internal open fun publicOrInternalFunction() = 1
internal open fun internalFunction() = 1
private fun internalOrPrivateFunction() = 1
private fun privateFunction() = 1
}
}
@@ -0,0 +1,84 @@
expect class A1()
expect interface B1
expect annotation class C1()
expect object D1
expect enum class E1 { FOO, BAR, BAZ }
expect class F() {
inner class G1()
class H1()
interface I1
object J1
enum class K1 { FOO, BAR, BAZ }
}
expect interface L {
class M1()
interface N1
object O1
enum class P1 { FOO, BAR, BAZ }
}
expect object R {
class S1()
interface T1
object U1
enum class V1 { FOO, BAR, BAZ }
}
expect class W() {
object X {
interface Y {
class Z() {
enum class AA { FOO, BAR, BAZ }
}
}
}
}
expect class BB1() { companion object }
expect class BB2()
expect class CC1() { companion object DD1 }
expect class CC2()
expect class CC3()
expect inline class EE1(val value: String)
expect class FF1(property1: String) {
val property1: String
val property2: String
val property3: String
val property4: String
fun function1(): String
fun function2(): String
}
expect class FF2()
expect sealed class GG1
expect sealed class GG2 {
class HH1(): GG2
object HH2 : GG2
}
expect class HH5(): GG2
expect object HH6 : GG2
expect enum class II1
expect enum class II2 { FOO }
expect interface JJ {
val property: String
fun function(): String
}
expect class KK1(property: String) : JJ {
override val property: String
override fun function(): String
}
expect class KK2(wrapped: JJ) : JJ
expect class LL1(value: String) { val value: String }
expect class LL2(value: String) { val value: String }
@@ -0,0 +1,133 @@
actual class A1 actual constructor()
class A2
class A3
class A4
class A5
actual interface B1
interface B2
interface B3
interface B4
actual annotation class C1 actual constructor()
annotation class C2
annotation class C3
actual object D1
object D2
actual enum class E1 { FOO, BAR, BAZ }
actual class F actual constructor() {
actual inner class G1 actual constructor()
inner class G2
inner class G3
inner class G4
inner class G5
inner class G6
actual class H1 actual constructor()
class H2
class H3
class H4
actual interface I1
interface I2
interface I3
actual object J1
object J2
actual enum class K1 { FOO, BAR, BAZ }
}
actual interface L {
actual class M1 actual constructor()
class M2
class M3
class M4
class M5
actual interface N1
interface N2
interface N3
actual object O1
object O2
actual enum class P1 { FOO, BAR, BAZ }
}
actual object R {
actual class S1 actual constructor()
class S2
class S3
class S4
actual interface T1
interface T2
interface T3
actual object U1
object U2
actual enum class V1 { FOO, BAR, BAZ }
}
actual class W actual constructor() {
actual object X {
actual interface Y {
actual class Z actual constructor() {
actual enum class AA { FOO, BAR, BAZ }
}
}
}
}
actual class BB1 actual constructor() { actual companion object }
actual class BB2 actual constructor() { companion object }
actual class CC1 actual constructor() { actual companion object DD1 }
actual class CC2 actual constructor() { companion object DD2 }
actual class CC3 actual constructor() { companion object DD3 }
actual inline class EE1 actual constructor(actual val value: String)
inline class EE2(val value: String)
actual external class FF1 actual constructor(actual val property1: String) {
actual val property2 = property1
actual val property3 get() = property1
actual val property4: String
actual fun function1() = property1
actual fun function2(): String
}
actual external class FF2 actual constructor()
actual sealed class GG1
actual sealed class GG2 {
actual class HH1 actual constructor(): GG2()
actual object HH2 : GG2()
class HH3 : GG2()
}
actual class HH5 actual constructor(): GG2()
actual object HH6 : GG2()
class HH7 : GG2()
actual enum class II1
actual enum class II2 { FOO, BAR }
actual interface JJ {
actual val property: String
actual fun function(): String
}
actual class KK1 actual constructor(actual override val property: String) : JJ {
actual override fun function() = property
}
actual class KK2 actual constructor(private val wrapped: JJ) : JJ by wrapped
actual data class LL1 actual constructor(actual val value: String)
actual data class LL2 actual constructor(actual val value: String)
@@ -0,0 +1,135 @@
actual class A1 actual constructor()
interface A2
annotation class A3
object A4
enum class A5 { FOO, BAR, BAZ }
actual interface B1
annotation class B2
object B3
enum class B4 { FOO, BAR, BAZ }
actual annotation class C1 actual constructor()
object C2
enum class C3 { FOO, BAR, BAZ }
actual object D1
enum class D2 { FOO, BAR, BAZ }
actual enum class E1 { FOO, BAR, BAZ }
actual class F actual constructor() {
actual inner class G1 actual constructor()
class G2
interface G3
object G4
enum class G5 { FOO, BAR, BAZ }
companion object G6
actual class H1 actual constructor()
interface H2
object H3
enum class H4 { FOO, BAR, BAZ }
actual interface I1
object I2
enum class I3 { FOO, BAR, BAZ }
actual object J1
enum class J2 { FOO, BAR, BAZ }
actual enum class K1 { FOO, BAR, BAZ }
}
actual interface L {
actual class M1 actual constructor()
interface M2
object M3
enum class M4 { FOO, BAR, BAZ }
companion object M5
actual interface N1
object N2
enum class N3 { FOO, BAR, BAZ }
actual object O1
enum class O2 { FOO, BAR, BAZ }
actual enum class P1 { FOO, BAR, BAZ }
}
actual object R {
actual class S1 actual constructor()
interface S2
object S3
enum class S4 { FOO, BAR, BAZ }
actual interface T1
object T2
enum class T3 { FOO, BAR, BAZ }
actual object U1
enum class U2 { FOO, BAR, BAZ }
actual enum class V1 { FOO, BAR, BAZ }
}
actual class W actual constructor() {
actual object X {
actual interface Y {
actual class Z actual constructor() {
actual enum class AA { FOO, BAR, BAZ }
}
}
}
}
actual class BB1 actual constructor() { actual companion object }
actual class BB2 actual constructor()
actual class CC1 actual constructor() { actual companion object DD1 }
actual class CC2 actual constructor() { companion object CompanionWithAnotherName }
actual class CC3 actual constructor() { companion object }
actual inline class EE1 actual constructor(actual val value: String)
class EE2(val value: String)
actual class FF1 actual constructor(actual val property1: String) {
actual val property2 = property1
actual val property3 get() = property1
actual val property4 = property1
actual fun function1() = property1
actual fun function2() = function1()
}
actual external class FF2 actual constructor()
actual sealed class GG1
actual sealed class GG2 {
actual class HH1 actual constructor(): GG2()
actual object HH2 : GG2()
class HH4 : GG2()
}
actual class HH5 actual constructor(): GG2()
actual object HH6 : GG2()
class HH8 : GG2()
actual enum class II1
actual enum class II2 { FOO, BAZ }
actual interface JJ {
actual val property: String
val property2: String
actual fun function(): String
}
actual class KK1 actual constructor(actual override val property: String) : JJ {
val property2 = property
actual override fun function() = property
}
actual class KK2 actual constructor(wrapped: JJ) : JJ by wrapped
actual data class LL1 actual constructor(actual val value: String)
actual class LL2 actual constructor(actual val value: String)
@@ -0,0 +1,133 @@
class A1
class A2
class A3
class A4
class A5
interface B1
interface B2
interface B3
interface B4
annotation class C1
annotation class C2
annotation class C3
object D1
object D2
enum class E1 { FOO, BAR, BAZ }
class F {
inner class G1
inner class G2
inner class G3
inner class G4
inner class G5
inner class G6
class H1
class H2
class H3
class H4
interface I1
interface I2
interface I3
object J1
object J2
enum class K1 { FOO, BAR, BAZ }
}
interface L {
class M1
class M2
class M3
class M4
class M5
interface N1
interface N2
interface N3
object O1
object O2
enum class P1 { FOO, BAR, BAZ }
}
object R {
class S1
class S2
class S3
class S4
interface T1
interface T2
interface T3
object U1
object U2
enum class V1 { FOO, BAR, BAZ }
}
class W {
object X {
interface Y {
class Z {
enum class AA { FOO, BAR, BAZ }
}
}
}
}
class BB1 { companion object }
class BB2 { companion object }
class CC1 { companion object DD1 }
class CC2 { companion object DD2 }
class CC3 { companion object DD3 }
inline class EE1(val value: String)
inline class EE2(val value: String)
external class FF1(val property1: String) {
val property2 = property1
val property3 get() = property1
val property4: String
fun function1() = property1
fun function2(): String
}
external class FF2()
sealed class GG1
sealed class GG2 {
class HH1 : GG2()
object HH2 : GG2()
class HH3 : GG2()
}
class HH5 : GG2()
object HH6 : GG2()
class HH7 : GG2()
enum class II1
enum class II2 { FOO, BAR }
interface JJ {
val property: String
fun function(): String
}
class KK1(override val property: String) : JJ {
override fun function() = property
}
class KK2(private val wrapped: JJ) : JJ by wrapped
data class LL1(val value: String)
data class LL2(val value: String)
@@ -0,0 +1,135 @@
class A1
interface A2
annotation class A3
object A4
enum class A5 { FOO, BAR, BAZ }
interface B1
annotation class B2
object B3
enum class B4 { FOO, BAR, BAZ }
annotation class C1
object C2
enum class C3 { FOO, BAR, BAZ }
object D1
enum class D2 { FOO, BAR, BAZ }
enum class E1 { FOO, BAR, BAZ }
class F {
inner class G1
class G2
interface G3
object G4
enum class G5 { FOO, BAR, BAZ }
companion object G6
class H1
interface H2
object H3
enum class H4 { FOO, BAR, BAZ }
interface I1
object I2
enum class I3 { FOO, BAR, BAZ }
object J1
enum class J2 { FOO, BAR, BAZ }
enum class K1 { FOO, BAR, BAZ }
}
interface L {
class M1
interface M2
object M3
enum class M4 { FOO, BAR, BAZ }
companion object M5
interface N1
object N2
enum class N3 { FOO, BAR, BAZ }
object O1
enum class O2 { FOO, BAR, BAZ }
enum class P1 { FOO, BAR, BAZ }
}
object R {
class S1
interface S2
object S3
enum class S4 { FOO, BAR, BAZ }
interface T1
object T2
enum class T3 { FOO, BAR, BAZ }
object U1
enum class U2 { FOO, BAR, BAZ }
enum class V1 { FOO, BAR, BAZ }
}
class W {
object X {
interface Y {
class Z {
enum class AA { FOO, BAR, BAZ }
}
}
}
}
class BB1 { companion object }
class BB2
class CC1 { companion object DD1 }
class CC2 { companion object CompanionWithAnotherName }
class CC3 { companion object }
inline class EE1(val value: String)
class EE2(val value: String)
class FF1(val property1: String) {
val property2 = property1
val property3 get() = property1
val property4 = property1
fun function1() = property1
fun function2() = function1()
}
external class FF2()
sealed class GG1
sealed class GG2 {
class HH1 : GG2()
object HH2 : GG2()
class HH4 : GG2()
}
class HH5 : GG2()
object HH6 : GG2()
class HH8 : GG2()
enum class II1
enum class II2 { FOO, BAZ }
interface JJ {
val property: String
val property2: String
fun function(): String
}
class KK1(override val property: String) : JJ {
val property2 = property
override fun function() = property
}
class KK2(wrapped: JJ) : JJ by wrapped
data class LL1(val value: String)
class LL2(val value: String)
@@ -0,0 +1,30 @@
expect class A1(text: String) { constructor(number: Int) }
expect class A2(text: String) { constructor(number: Int) }
expect class A3
expect class A4
expect class A5
expect class B1 protected constructor(text: String) { protected constructor(number: Int) }
expect class B2
expect class B3
expect class C1 internal constructor(text: String) { internal constructor(number: Int) }
expect class C2
expect class D1
expect class E {
constructor(a: Any)
constructor(a: Any, b: String)
constructor(a: Any, b: Int)
}
expect enum class F {
FOO,
BAR,
BAZ;
// no constructor allowed for enum class
val alias: String
}
@@ -0,0 +1,30 @@
actual class A1 actual constructor(text: String) { actual constructor(number: Int) : this(number.toString()) }
actual class A2 actual constructor(text: String) { actual constructor(number: Int) : this(number.toString()) }
actual class A3(text: String) { constructor(number: Int) : this(number.toString()) }
actual class A4(text: String) { constructor(number: Int) : this(number.toString()) }
actual class A5(text: String) { constructor(number: Int) : this(number.toString()) }
actual class B1 protected actual constructor(text: String) { protected actual constructor(number: Int) : this(number.toString()) }
actual class B2 protected constructor(text: String) { protected constructor(number: Int) : this(number.toString()) }
actual class B3 protected constructor(text: String) { protected constructor(number: Int) : this(number.toString()) }
actual class C1 internal actual constructor(text: String) { internal actual constructor(number: Int) : this(number.toString()) }
actual class C2 internal constructor(text: String) { internal constructor(number: Int) : this(number.toString()) }
actual class D1 private constructor(text: String) { private constructor(number: Int) : this(number.toString()) }
actual class E {
constructor(a: Int)
actual constructor(a: Any)
constructor(a: Int, b: String)
constructor(a: Int, b: Any)
actual constructor(a: Any, b: String)
actual constructor(a: Any, b: Int)
}
actual enum class F(actual val alias: String) {
FOO("foo"),
BAR("bar"),
BAZ("baz")
}
@@ -0,0 +1,30 @@
actual class A1 actual constructor(text: String) { actual constructor(number: Int) : this(number.toString()) }
actual class A2 actual constructor(text: String) { actual constructor(number: Int) : this(number.toString()) }
actual class A3 protected constructor(text: String) { protected constructor(number: Int) : this(number.toString()) }
actual class A4 internal constructor(text: String) { internal constructor(number: Int) : this(number.toString()) }
actual class A5 private constructor(text: String) { private constructor(number: Int) : this(number.toString()) }
actual class B1 protected actual constructor(text: String) { protected actual constructor(number: Int) : this(number.toString()) }
actual class B2 internal constructor(text: String) { internal constructor(number: Int) : this(number.toString()) }
actual class B3 private constructor(text: String) { private constructor(number: Int) : this(number.toString()) }
actual class C1 internal actual constructor(text: String) { internal actual constructor(number: Int) : this(number.toString()) }
actual class C2 private constructor(text: String) { private constructor(number: Int) : this(number.toString()) }
actual class D1 private constructor(text: String) { private constructor(number: Int) : this(number.toString()) }
actual class E {
constructor(a: String)
actual constructor(a: Any)
constructor(a: String, b: Int)
constructor(a: String, b: Any)
actual constructor(a: Any, b: String)
actual constructor(a: Any, b: Int)
}
actual enum class F(actual val alias: String) {
FOO("foo"),
BAR("bar"),
BAZ("baz")
}

Some files were not shown because too many files have changed in this diff Show More