Reformat modules descriptors.jvm, descriptors.runtime

Also remove several unused files (BuiltinOverridabilityCondition.kt,
PackageMappingProvider.kt)
This commit is contained in:
Alexander Udalov
2019-03-15 12:56:13 +01:00
parent 39adfcced1
commit b89d7029b2
61 changed files with 799 additions and 826 deletions
@@ -258,7 +258,7 @@ object JavaToKotlinClassMap : PlatformToKotlinClassMap {
mutabilityKindName: String mutabilityKindName: String
): ClassDescriptor { ): ClassDescriptor {
val oppositeClassFqName = map[DescriptorUtils.getFqName(descriptor)] val oppositeClassFqName = map[DescriptorUtils.getFqName(descriptor)]
?: throw IllegalArgumentException("Given class $descriptor is not a $mutabilityKindName collection") ?: throw IllegalArgumentException("Given class $descriptor is not a $mutabilityKindName collection")
return descriptor.builtIns.getBuiltInClassByFqName(oppositeClassFqName) return descriptor.builtIns.getBuiltInClassByFqName(oppositeClassFqName)
} }
} }
@@ -41,16 +41,16 @@ val TYPE_QUALIFIER_DEFAULT_FQNAME = FqName("javax.annotation.meta.TypeQualifierD
val MIGRATION_ANNOTATION_FQNAME = FqName("kotlin.annotations.jvm.UnderMigration") val MIGRATION_ANNOTATION_FQNAME = FqName("kotlin.annotations.jvm.UnderMigration")
val BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS = mapOf( val BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS = mapOf(
FqName("javax.annotation.ParametersAreNullableByDefault") to FqName("javax.annotation.ParametersAreNullableByDefault") to
NullabilityQualifierWithApplicability( NullabilityQualifierWithApplicability(
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE), NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE),
listOf(AnnotationTypeQualifierResolver.QualifierApplicabilityType.VALUE_PARAMETER) listOf(AnnotationTypeQualifierResolver.QualifierApplicabilityType.VALUE_PARAMETER)
), ),
FqName("javax.annotation.ParametersAreNonnullByDefault") to FqName("javax.annotation.ParametersAreNonnullByDefault") to
NullabilityQualifierWithApplicability( NullabilityQualifierWithApplicability(
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL), NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL),
listOf(AnnotationTypeQualifierResolver.QualifierApplicabilityType.VALUE_PARAMETER) listOf(AnnotationTypeQualifierResolver.QualifierApplicabilityType.VALUE_PARAMETER)
) )
) )
class AnnotationTypeQualifierResolver(storageManager: StorageManager, private val jsr305State: Jsr305State) { class AnnotationTypeQualifierResolver(storageManager: StorageManager, private val jsr305State: Jsr305State) {
@@ -59,21 +59,21 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager, private va
} }
class TypeQualifierWithApplicability( class TypeQualifierWithApplicability(
private val typeQualifier: AnnotationDescriptor, private val typeQualifier: AnnotationDescriptor,
private val applicability: Int private val applicability: Int
) { ) {
operator fun component1() = typeQualifier operator fun component1() = typeQualifier
operator fun component2() = QualifierApplicabilityType.values().filter(this::isApplicableTo) operator fun component2() = QualifierApplicabilityType.values().filter(this::isApplicableTo)
private fun isApplicableTo(elementType: QualifierApplicabilityType) = private fun isApplicableTo(elementType: QualifierApplicabilityType) =
isApplicableConsideringMask(QualifierApplicabilityType.TYPE_USE) || isApplicableConsideringMask(elementType) isApplicableConsideringMask(QualifierApplicabilityType.TYPE_USE) || isApplicableConsideringMask(elementType)
private fun isApplicableConsideringMask(elementType: QualifierApplicabilityType) = private fun isApplicableConsideringMask(elementType: QualifierApplicabilityType) =
(applicability and (1 shl elementType.ordinal)) != 0 (applicability and (1 shl elementType.ordinal)) != 0
} }
private val resolvedNicknames = private val resolvedNicknames =
storageManager.createMemoizedFunctionWithNullableValues(this::computeTypeQualifierNickname) storageManager.createMemoizedFunctionWithNullableValues(this::computeTypeQualifierNickname)
private fun computeTypeQualifierNickname(classDescriptor: ClassDescriptor): AnnotationDescriptor? { private fun computeTypeQualifierNickname(classDescriptor: ClassDescriptor): AnnotationDescriptor? {
if (!classDescriptor.annotations.hasAnnotation(TYPE_QUALIFIER_NICKNAME_FQNAME)) return null if (!classDescriptor.annotations.hasAnnotation(TYPE_QUALIFIER_NICKNAME_FQNAME)) return null
@@ -115,23 +115,23 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager, private va
} }
val typeQualifierDefaultAnnotatedClass = val typeQualifierDefaultAnnotatedClass =
annotationDescriptor.annotationClass?.takeIf { it.annotations.hasAnnotation(TYPE_QUALIFIER_DEFAULT_FQNAME) } annotationDescriptor.annotationClass?.takeIf { it.annotations.hasAnnotation(TYPE_QUALIFIER_DEFAULT_FQNAME) }
?: return null ?: return null
val elementTypesMask = val elementTypesMask =
annotationDescriptor.annotationClass!! annotationDescriptor.annotationClass!!
.annotations.findAnnotation(TYPE_QUALIFIER_DEFAULT_FQNAME)!! .annotations.findAnnotation(TYPE_QUALIFIER_DEFAULT_FQNAME)!!
.allValueArguments .allValueArguments
.flatMap { (parameter, argument) -> .flatMap { (parameter, argument) ->
if (parameter == JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME) if (parameter == JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME)
argument.mapConstantToQualifierApplicabilityTypes() argument.mapConstantToQualifierApplicabilityTypes()
else else
emptyList() emptyList()
} }
.fold(0) { acc: Int, applicabilityType -> acc or (1 shl applicabilityType.ordinal) } .fold(0) { acc: Int, applicabilityType -> acc or (1 shl applicabilityType.ordinal) }
val typeQualifier = typeQualifierDefaultAnnotatedClass.annotations.firstOrNull { resolveTypeQualifierAnnotation(it) != null } val typeQualifier = typeQualifierDefaultAnnotatedClass.annotations.firstOrNull { resolveTypeQualifierAnnotation(it) != null }
?: return null ?: return null
return TypeQualifierWithApplicability(typeQualifier, elementTypesMask) return TypeQualifierWithApplicability(typeQualifier, elementTypesMask)
} }
@@ -148,7 +148,7 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager, private va
private fun ClassDescriptor.migrationAnnotationStatus(): ReportLevel? { private fun ClassDescriptor.migrationAnnotationStatus(): ReportLevel? {
val enumValue = annotations.findAnnotation(MIGRATION_ANNOTATION_FQNAME)?.firstArgument() as? EnumValue val enumValue = annotations.findAnnotation(MIGRATION_ANNOTATION_FQNAME)?.firstArgument() as? EnumValue
?: return null ?: return null
jsr305State.migration?.let { return it } jsr305State.migration?.let { return it }
@@ -164,13 +164,13 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager, private va
when (this) { when (this) {
is ArrayValue -> value.flatMap { it.mapConstantToQualifierApplicabilityTypes() } is ArrayValue -> value.flatMap { it.mapConstantToQualifierApplicabilityTypes() }
is EnumValue -> listOfNotNull( is EnumValue -> listOfNotNull(
when (enumEntryName.identifier) { when (enumEntryName.identifier) {
"METHOD" -> QualifierApplicabilityType.METHOD_RETURN_TYPE "METHOD" -> QualifierApplicabilityType.METHOD_RETURN_TYPE
"FIELD" -> QualifierApplicabilityType.FIELD "FIELD" -> QualifierApplicabilityType.FIELD
"PARAMETER" -> QualifierApplicabilityType.VALUE_PARAMETER "PARAMETER" -> QualifierApplicabilityType.VALUE_PARAMETER
"TYPE_USE" -> QualifierApplicabilityType.TYPE_USE "TYPE_USE" -> QualifierApplicabilityType.TYPE_USE
else -> null else -> null
} }
) )
else -> emptyList() else -> emptyList()
} }
@@ -1,32 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.load.java
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition
import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition.Result
class BuiltinOverridabilityCondition : ExternalOverridabilityCondition {
override fun isOverridable(
superDescriptor: CallableDescriptor,
subDescriptor: CallableDescriptor,
subClassDescriptor: ClassDescriptor?
) = Result.UNKNOWN
override fun getContract() = ExternalOverridabilityCondition.Contract.CONFLICTS_ONLY
}
@@ -27,15 +27,19 @@ import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition.Result
import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.OverridingUtil
class ErasedOverridabilityCondition : ExternalOverridabilityCondition { class ErasedOverridabilityCondition : ExternalOverridabilityCondition {
override fun isOverridable(superDescriptor: CallableDescriptor, subDescriptor: CallableDescriptor, subClassDescriptor: ClassDescriptor?): Result { override fun isOverridable(
superDescriptor: CallableDescriptor,
subDescriptor: CallableDescriptor,
subClassDescriptor: ClassDescriptor?
): Result {
if (subDescriptor !is JavaMethodDescriptor || subDescriptor.typeParameters.isNotEmpty()) return Result.UNKNOWN if (subDescriptor !is JavaMethodDescriptor || subDescriptor.typeParameters.isNotEmpty()) return Result.UNKNOWN
val basicOverridability = OverridingUtil.getBasicOverridabilityProblem(superDescriptor, subDescriptor)?.result val basicOverridability = OverridingUtil.getBasicOverridabilityProblem(superDescriptor, subDescriptor)?.result
if (basicOverridability != null) return Result.UNKNOWN if (basicOverridability != null) return Result.UNKNOWN
val signatureTypes = subDescriptor.valueParameters.asSequence().map { it.type } + val signatureTypes = subDescriptor.valueParameters.asSequence().map { it.type } +
subDescriptor.returnType!! + subDescriptor.returnType!! +
listOfNotNull(subDescriptor.extensionReceiverParameter?.type) listOfNotNull(subDescriptor.extensionReceiverParameter?.type)
if (signatureTypes.any { it.arguments.isNotEmpty() && it.unwrap() !is RawTypeImpl }) return Result.UNKNOWN if (signatureTypes.any { it.arguments.isNotEmpty() && it.unwrap() !is RawTypeImpl }) return Result.UNKNOWN
@@ -47,10 +51,10 @@ class ErasedOverridabilityCondition : ExternalOverridabilityCondition {
} }
val overridabilityResult = val overridabilityResult =
OverridingUtil.DEFAULT.isOverridableByWithoutExternalConditions(erasedSuper, subDescriptor, false).result OverridingUtil.DEFAULT.isOverridableByWithoutExternalConditions(erasedSuper, subDescriptor, false).result
return when (overridabilityResult) { return when (overridabilityResult) {
OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE -> Result.OVERRIDABLE OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE -> Result.OVERRIDABLE
else -> Result.UNKNOWN else -> Result.UNKNOWN
} }
} }
@@ -30,8 +30,10 @@ object FakePureImplementationsProvider {
init { init {
FQ_NAMES.mutableList implementedWith fqNameListOf("java.util.ArrayList", "java.util.LinkedList") FQ_NAMES.mutableList implementedWith fqNameListOf("java.util.ArrayList", "java.util.LinkedList")
FQ_NAMES.mutableSet implementedWith fqNameListOf("java.util.HashSet", "java.util.TreeSet", "java.util.LinkedHashSet") FQ_NAMES.mutableSet implementedWith fqNameListOf("java.util.HashSet", "java.util.TreeSet", "java.util.LinkedHashSet")
FQ_NAMES.mutableMap implementedWith fqNameListOf("java.util.HashMap", "java.util.TreeMap", "java.util.LinkedHashMap", FQ_NAMES.mutableMap implementedWith fqNameListOf(
"java.util.concurrent.ConcurrentHashMap", "java.util.concurrent.ConcurrentSkipListMap") "java.util.HashMap", "java.util.TreeMap", "java.util.LinkedHashMap",
"java.util.concurrent.ConcurrentHashMap", "java.util.concurrent.ConcurrentSkipListMap"
)
FqName("java.util.function.Function") implementedWith fqNameListOf("java.util.function.UnaryOperator") FqName("java.util.function.Function") implementedWith fqNameListOf("java.util.function.UnaryOperator")
FqName("java.util.function.BiFunction") implementedWith fqNameListOf("java.util.function.BinaryOperator") FqName("java.util.function.BiFunction") implementedWith fqNameListOf("java.util.function.BinaryOperator")
} }
@@ -24,7 +24,11 @@ import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition
import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition.Result import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition.Result
class FieldOverridabilityCondition : ExternalOverridabilityCondition { class FieldOverridabilityCondition : ExternalOverridabilityCondition {
override fun isOverridable(superDescriptor: CallableDescriptor, subDescriptor: CallableDescriptor, subClassDescriptor: ClassDescriptor?): Result { override fun isOverridable(
superDescriptor: CallableDescriptor,
subDescriptor: CallableDescriptor,
subClassDescriptor: ClassDescriptor?
): Result {
if (subDescriptor !is PropertyDescriptor || superDescriptor !is PropertyDescriptor) return Result.UNKNOWN if (subDescriptor !is PropertyDescriptor || superDescriptor !is PropertyDescriptor) return Result.UNKNOWN
if (subDescriptor.name != superDescriptor.name) return Result.UNKNOWN if (subDescriptor.name != superDescriptor.name) return Result.UNKNOWN
@@ -36,9 +36,9 @@ import org.jetbrains.kotlin.types.typeUtil.makeNullable
*/ */
class JavaIncompatibilityRulesOverridabilityCondition : ExternalOverridabilityCondition { class JavaIncompatibilityRulesOverridabilityCondition : ExternalOverridabilityCondition {
override fun isOverridable( override fun isOverridable(
superDescriptor: CallableDescriptor, superDescriptor: CallableDescriptor,
subDescriptor: CallableDescriptor, subDescriptor: CallableDescriptor,
subClassDescriptor: ClassDescriptor? subClassDescriptor: ClassDescriptor?
): Result { ): Result {
if (isIncompatibleInAccordanceWithBuiltInOverridabilityRules(superDescriptor, subDescriptor, subClassDescriptor)) { if (isIncompatibleInAccordanceWithBuiltInOverridabilityRules(superDescriptor, subDescriptor, subClassDescriptor)) {
return Result.INCOMPATIBLE return Result.INCOMPATIBLE
@@ -57,12 +57,13 @@ class JavaIncompatibilityRulesOverridabilityCondition : ExternalOverridabilityCo
// it should not override non-special method in further inheritance // it should not override non-special method in further inheritance
// See java.nio.Buffer // See java.nio.Buffer
private fun isIncompatibleInAccordanceWithBuiltInOverridabilityRules( private fun isIncompatibleInAccordanceWithBuiltInOverridabilityRules(
superDescriptor: CallableDescriptor, superDescriptor: CallableDescriptor,
subDescriptor: CallableDescriptor, subDescriptor: CallableDescriptor,
subClassDescriptor: ClassDescriptor? subClassDescriptor: ClassDescriptor?
): Boolean { ): Boolean {
if (superDescriptor !is CallableMemberDescriptor || subDescriptor !is FunctionDescriptor || if (superDescriptor !is CallableMemberDescriptor || subDescriptor !is FunctionDescriptor ||
KotlinBuiltIns.isBuiltIn(subDescriptor)) { KotlinBuiltIns.isBuiltIn(subDescriptor)
) {
return false return false
} }
@@ -74,9 +75,10 @@ class JavaIncompatibilityRulesOverridabilityCondition : ExternalOverridabilityCo
// Checking second condition: special hidden override is not supposed to be an override to non-special irrelevant Java declaration // Checking second condition: special hidden override is not supposed to be an override to non-special irrelevant Java declaration
val isOneOfDescriptorsHidden = val isOneOfDescriptorsHidden =
subDescriptor.isHiddenToOvercomeSignatureClash != (superDescriptor as? FunctionDescriptor)?.isHiddenToOvercomeSignatureClash subDescriptor.isHiddenToOvercomeSignatureClash != (superDescriptor as? FunctionDescriptor)?.isHiddenToOvercomeSignatureClash
if (isOneOfDescriptorsHidden && if (isOneOfDescriptorsHidden &&
(overriddenBuiltin == null || !subDescriptor.isHiddenToOvercomeSignatureClash)) { (overriddenBuiltin == null || !subDescriptor.isHiddenToOvercomeSignatureClash)
) {
return true return true
} }
@@ -100,8 +102,9 @@ class JavaIncompatibilityRulesOverridabilityCondition : ExternalOverridabilityCo
// in `computeJvmDescriptor`. // in `computeJvmDescriptor`.
// TODO: things get more and more complicated here, consider moving signature mapping from backend and using it here instead of all of this magic // TODO: things get more and more complicated here, consider moving signature mapping from backend and using it here instead of all of this magic
if (overriddenBuiltin is FunctionDescriptor && superDescriptor is FunctionDescriptor && if (overriddenBuiltin is FunctionDescriptor && superDescriptor is FunctionDescriptor &&
BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(overriddenBuiltin) != null && BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(overriddenBuiltin) != null &&
subDescriptor.computeJvmDescriptor(withReturnType = false) == superDescriptor.original.computeJvmDescriptor(withReturnType = false)) { subDescriptor.computeJvmDescriptor(withReturnType = false) == superDescriptor.original.computeJvmDescriptor(withReturnType = false)
) {
return false return false
} }
@@ -120,8 +123,8 @@ class JavaIncompatibilityRulesOverridabilityCondition : ExternalOverridabilityCo
* As it comes from it's name it only checks overrides in Java classes * As it comes from it's name it only checks overrides in Java classes
*/ */
fun doesJavaOverrideHaveIncompatibleValueParameterKinds( fun doesJavaOverrideHaveIncompatibleValueParameterKinds(
superDescriptor: CallableDescriptor, superDescriptor: CallableDescriptor,
subDescriptor: CallableDescriptor subDescriptor: CallableDescriptor
): Boolean { ): Boolean {
if (subDescriptor !is JavaMethodDescriptor || superDescriptor !is FunctionDescriptor) return false if (subDescriptor !is JavaMethodDescriptor || superDescriptor !is FunctionDescriptor) return false
assert(subDescriptor.valueParameters.size == superDescriptor.valueParameters.size) { assert(subDescriptor.valueParameters.size == superDescriptor.valueParameters.size) {
@@ -141,10 +144,10 @@ class JavaIncompatibilityRulesOverridabilityCondition : ExternalOverridabilityCo
} }
private fun mapValueParameterType(f: FunctionDescriptor, valueParameterDescriptor: ValueParameterDescriptor) = private fun mapValueParameterType(f: FunctionDescriptor, valueParameterDescriptor: ValueParameterDescriptor) =
if (forceSingleValueParameterBoxing(f) || isPrimitiveCompareTo(f)) if (forceSingleValueParameterBoxing(f) || isPrimitiveCompareTo(f))
valueParameterDescriptor.type.makeNullable().mapToJvmType() valueParameterDescriptor.type.makeNullable().mapToJvmType()
else else
valueParameterDescriptor.type.mapToJvmType() valueParameterDescriptor.type.mapToJvmType()
// It's useful here to suppose that 'Int.compareTo(Int)' requires boxing of it's value parameter // It's useful here to suppose that 'Int.compareTo(Int)' requires boxing of it's value parameter
// As it happens in java.lang.Integer analogue // As it happens in java.lang.Integer analogue
@@ -152,9 +155,9 @@ class JavaIncompatibilityRulesOverridabilityCondition : ExternalOverridabilityCo
private fun isPrimitiveCompareTo(f: FunctionDescriptor): Boolean { private fun isPrimitiveCompareTo(f: FunctionDescriptor): Boolean {
if (f.valueParameters.size != 1) return false if (f.valueParameters.size != 1) return false
val classDescriptor = val classDescriptor =
f.containingDeclaration as? ClassDescriptor ?: return false f.containingDeclaration as? ClassDescriptor ?: return false
val parameterClass = val parameterClass =
f.valueParameters.single().type.constructor.declarationDescriptor as? ClassDescriptor f.valueParameters.single().type.constructor.declarationDescriptor as? ClassDescriptor
?: return false ?: return false
return KotlinBuiltIns.isPrimitiveClass(classDescriptor) && classDescriptor.fqNameSafe == parameterClass.fqNameSafe return KotlinBuiltIns.isPrimitiveClass(classDescriptor) && classDescriptor.fqNameSafe == parameterClass.fqNameSafe
} }
@@ -75,7 +75,6 @@ public final class JvmAbi {
return startsWithIsPrefix(propertyName) return startsWithIsPrefix(propertyName)
? propertyName ? propertyName
: GET_PREFIX + CapitalizeDecapitalizeKt.capitalizeAsciiOnly(propertyName); : GET_PREFIX + CapitalizeDecapitalizeKt.capitalizeAsciiOnly(propertyName);
} }
@NotNull @NotNull
@@ -53,19 +53,19 @@ object JavaAnnotationMapper {
internal val RETENTION_ANNOTATION_VALUE = Name.identifier("value") internal val RETENTION_ANNOTATION_VALUE = Name.identifier("value")
fun mapOrResolveJavaAnnotation(annotation: JavaAnnotation, c: LazyJavaResolverContext): AnnotationDescriptor? = fun mapOrResolveJavaAnnotation(annotation: JavaAnnotation, c: LazyJavaResolverContext): AnnotationDescriptor? =
when (annotation.classId) { when (annotation.classId) {
ClassId.topLevel(JAVA_TARGET_FQ_NAME) -> JavaTargetAnnotationDescriptor(annotation, c) ClassId.topLevel(JAVA_TARGET_FQ_NAME) -> JavaTargetAnnotationDescriptor(annotation, c)
ClassId.topLevel(JAVA_RETENTION_FQ_NAME) -> JavaRetentionAnnotationDescriptor(annotation, c) ClassId.topLevel(JAVA_RETENTION_FQ_NAME) -> JavaRetentionAnnotationDescriptor(annotation, c)
ClassId.topLevel(JAVA_REPEATABLE_FQ_NAME) -> JavaAnnotationDescriptor(c, annotation, KotlinBuiltIns.FQ_NAMES.repeatable) ClassId.topLevel(JAVA_REPEATABLE_FQ_NAME) -> JavaAnnotationDescriptor(c, annotation, KotlinBuiltIns.FQ_NAMES.repeatable)
ClassId.topLevel(JAVA_DOCUMENTED_FQ_NAME) -> JavaAnnotationDescriptor(c, annotation, KotlinBuiltIns.FQ_NAMES.mustBeDocumented) ClassId.topLevel(JAVA_DOCUMENTED_FQ_NAME) -> JavaAnnotationDescriptor(c, annotation, KotlinBuiltIns.FQ_NAMES.mustBeDocumented)
ClassId.topLevel(JAVA_DEPRECATED_FQ_NAME) -> null ClassId.topLevel(JAVA_DEPRECATED_FQ_NAME) -> null
else -> LazyJavaAnnotationDescriptor(c, annotation) else -> LazyJavaAnnotationDescriptor(c, annotation)
} }
fun findMappedJavaAnnotation( fun findMappedJavaAnnotation(
kotlinName: FqName, kotlinName: FqName,
annotationOwner: JavaAnnotationOwner, annotationOwner: JavaAnnotationOwner,
c: LazyJavaResolverContext c: LazyJavaResolverContext
): AnnotationDescriptor? { ): AnnotationDescriptor? {
if (kotlinName == KotlinBuiltIns.FQ_NAMES.deprecated) { if (kotlinName == KotlinBuiltIns.FQ_NAMES.deprecated) {
val javaAnnotation = annotationOwner.findAnnotation(JAVA_DEPRECATED_FQ_NAME) val javaAnnotation = annotationOwner.findAnnotation(JAVA_DEPRECATED_FQ_NAME)
@@ -82,24 +82,28 @@ object JavaAnnotationMapper {
// kotlin.annotation.annotation is treated separately // kotlin.annotation.annotation is treated separately
private val kotlinToJavaNameMap: Map<FqName, FqName> = private val kotlinToJavaNameMap: Map<FqName, FqName> =
mapOf(KotlinBuiltIns.FQ_NAMES.target to JAVA_TARGET_FQ_NAME, mapOf(
KotlinBuiltIns.FQ_NAMES.retention to JAVA_RETENTION_FQ_NAME, KotlinBuiltIns.FQ_NAMES.target to JAVA_TARGET_FQ_NAME,
KotlinBuiltIns.FQ_NAMES.repeatable to JAVA_REPEATABLE_FQ_NAME, KotlinBuiltIns.FQ_NAMES.retention to JAVA_RETENTION_FQ_NAME,
KotlinBuiltIns.FQ_NAMES.mustBeDocumented to JAVA_DOCUMENTED_FQ_NAME) KotlinBuiltIns.FQ_NAMES.repeatable to JAVA_REPEATABLE_FQ_NAME,
KotlinBuiltIns.FQ_NAMES.mustBeDocumented to JAVA_DOCUMENTED_FQ_NAME
)
val javaToKotlinNameMap: Map<FqName, FqName> = val javaToKotlinNameMap: Map<FqName, FqName> =
mapOf(JAVA_TARGET_FQ_NAME to KotlinBuiltIns.FQ_NAMES.target, mapOf(
JAVA_RETENTION_FQ_NAME to KotlinBuiltIns.FQ_NAMES.retention, JAVA_TARGET_FQ_NAME to KotlinBuiltIns.FQ_NAMES.target,
JAVA_DEPRECATED_FQ_NAME to KotlinBuiltIns.FQ_NAMES.deprecated, JAVA_RETENTION_FQ_NAME to KotlinBuiltIns.FQ_NAMES.retention,
JAVA_REPEATABLE_FQ_NAME to KotlinBuiltIns.FQ_NAMES.repeatable, JAVA_DEPRECATED_FQ_NAME to KotlinBuiltIns.FQ_NAMES.deprecated,
JAVA_DOCUMENTED_FQ_NAME to KotlinBuiltIns.FQ_NAMES.mustBeDocumented) JAVA_REPEATABLE_FQ_NAME to KotlinBuiltIns.FQ_NAMES.repeatable,
JAVA_DOCUMENTED_FQ_NAME to KotlinBuiltIns.FQ_NAMES.mustBeDocumented
)
} }
open class JavaAnnotationDescriptor( open class JavaAnnotationDescriptor(
c: LazyJavaResolverContext, c: LazyJavaResolverContext,
annotation: JavaAnnotation?, annotation: JavaAnnotation?,
override val fqName: FqName override val fqName: FqName
): AnnotationDescriptor { ) : AnnotationDescriptor {
override val source: SourceElement = annotation?.let { c.components.sourceElementFactory.source(it) } ?: SourceElement.NO_SOURCE override val source: SourceElement = annotation?.let { c.components.sourceElementFactory.source(it) } ?: SourceElement.NO_SOURCE
override val type: SimpleType by c.storageManager.createLazyValue { c.module.builtIns.getBuiltInClassByFqName(fqName).defaultType } override val type: SimpleType by c.storageManager.createLazyValue { c.module.builtIns.getBuiltInClassByFqName(fqName).defaultType }
@@ -110,18 +114,18 @@ open class JavaAnnotationDescriptor(
} }
class JavaDeprecatedAnnotationDescriptor( class JavaDeprecatedAnnotationDescriptor(
annotation: JavaAnnotation?, annotation: JavaAnnotation?,
c: LazyJavaResolverContext c: LazyJavaResolverContext
): JavaAnnotationDescriptor(c, annotation, KotlinBuiltIns.FQ_NAMES.deprecated) { ) : JavaAnnotationDescriptor(c, annotation, KotlinBuiltIns.FQ_NAMES.deprecated) {
override val allValueArguments: Map<Name, ConstantValue<*>> by c.storageManager.createLazyValue { override val allValueArguments: Map<Name, ConstantValue<*>> by c.storageManager.createLazyValue {
mapOf(JavaAnnotationMapper.DEPRECATED_ANNOTATION_MESSAGE to StringValue("Deprecated in Java")) mapOf(JavaAnnotationMapper.DEPRECATED_ANNOTATION_MESSAGE to StringValue("Deprecated in Java"))
} }
} }
class JavaTargetAnnotationDescriptor( class JavaTargetAnnotationDescriptor(
annotation: JavaAnnotation, annotation: JavaAnnotation,
c: LazyJavaResolverContext c: LazyJavaResolverContext
): JavaAnnotationDescriptor(c, annotation, KotlinBuiltIns.FQ_NAMES.target) { ) : JavaAnnotationDescriptor(c, annotation, KotlinBuiltIns.FQ_NAMES.target) {
override val allValueArguments by c.storageManager.createLazyValue { override val allValueArguments by c.storageManager.createLazyValue {
val targetArgument = when (firstArgument) { val targetArgument = when (firstArgument) {
is JavaArrayAnnotationArgument -> JavaAnnotationTargetMapper.mapJavaTargetArguments(firstArgument.getElements()) is JavaArrayAnnotationArgument -> JavaAnnotationTargetMapper.mapJavaTargetArguments(firstArgument.getElements())
@@ -133,9 +137,9 @@ class JavaTargetAnnotationDescriptor(
} }
class JavaRetentionAnnotationDescriptor( class JavaRetentionAnnotationDescriptor(
annotation: JavaAnnotation, annotation: JavaAnnotation,
c: LazyJavaResolverContext c: LazyJavaResolverContext
): JavaAnnotationDescriptor(c, annotation, KotlinBuiltIns.FQ_NAMES.retention) { ) : JavaAnnotationDescriptor(c, annotation, KotlinBuiltIns.FQ_NAMES.retention) {
override val allValueArguments by c.storageManager.createLazyValue { override val allValueArguments by c.storageManager.createLazyValue {
val retentionArgument = JavaAnnotationTargetMapper.mapJavaRetentionArgument(firstArgument) val retentionArgument = JavaAnnotationTargetMapper.mapJavaRetentionArgument(firstArgument)
retentionArgument?.let { mapOf(JavaAnnotationMapper.RETENTION_ANNOTATION_VALUE to it) }.orEmpty() retentionArgument?.let { mapOf(JavaAnnotationMapper.RETENTION_ANNOTATION_VALUE to it) }.orEmpty()
@@ -143,18 +147,17 @@ class JavaRetentionAnnotationDescriptor(
} }
object JavaAnnotationTargetMapper { object JavaAnnotationTargetMapper {
private val targetNameLists = mapOf("PACKAGE" to EnumSet.noneOf(KotlinTarget::class.java), private val targetNameLists = mapOf(
"TYPE" to EnumSet.of(KotlinTarget.CLASS, KotlinTarget.FILE), "PACKAGE" to EnumSet.noneOf(KotlinTarget::class.java),
"ANNOTATION_TYPE" to EnumSet.of(KotlinTarget.ANNOTATION_CLASS), "TYPE" to EnumSet.of(KotlinTarget.CLASS, KotlinTarget.FILE),
"TYPE_PARAMETER" to EnumSet.of(KotlinTarget.TYPE_PARAMETER), "ANNOTATION_TYPE" to EnumSet.of(KotlinTarget.ANNOTATION_CLASS),
"FIELD" to EnumSet.of(KotlinTarget.FIELD), "TYPE_PARAMETER" to EnumSet.of(KotlinTarget.TYPE_PARAMETER),
"LOCAL_VARIABLE" to EnumSet.of(KotlinTarget.LOCAL_VARIABLE), "FIELD" to EnumSet.of(KotlinTarget.FIELD),
"PARAMETER" to EnumSet.of(KotlinTarget.VALUE_PARAMETER), "LOCAL_VARIABLE" to EnumSet.of(KotlinTarget.LOCAL_VARIABLE),
"CONSTRUCTOR" to EnumSet.of(KotlinTarget.CONSTRUCTOR), "PARAMETER" to EnumSet.of(KotlinTarget.VALUE_PARAMETER),
"METHOD" to EnumSet.of(KotlinTarget.FUNCTION, "CONSTRUCTOR" to EnumSet.of(KotlinTarget.CONSTRUCTOR),
KotlinTarget.PROPERTY_GETTER, "METHOD" to EnumSet.of(KotlinTarget.FUNCTION, KotlinTarget.PROPERTY_GETTER, KotlinTarget.PROPERTY_SETTER),
KotlinTarget.PROPERTY_SETTER), "TYPE_USE" to EnumSet.of(KotlinTarget.TYPE)
"TYPE_USE" to EnumSet.of(KotlinTarget.TYPE)
) )
fun mapJavaTargetArgumentByName(argumentName: String?): Set<KotlinTarget> = targetNameLists[argumentName] ?: emptySet() fun mapJavaTargetArgumentByName(argumentName: String?): Set<KotlinTarget> = targetNameLists[argumentName] ?: emptySet()
@@ -162,23 +165,23 @@ object JavaAnnotationTargetMapper {
internal fun mapJavaTargetArguments(arguments: List<JavaAnnotationArgument>): ConstantValue<*> { internal fun mapJavaTargetArguments(arguments: List<JavaAnnotationArgument>): ConstantValue<*> {
// Map arguments: java.lang.annotation.Target -> kotlin.annotation.Target // Map arguments: java.lang.annotation.Target -> kotlin.annotation.Target
val kotlinTargets = arguments.filterIsInstance<JavaEnumValueAnnotationArgument>() val kotlinTargets = arguments.filterIsInstance<JavaEnumValueAnnotationArgument>()
.flatMap { mapJavaTargetArgumentByName(it.entryName?.asString()) } .flatMap { mapJavaTargetArgumentByName(it.entryName?.asString()) }
.map { kotlinTarget -> .map { kotlinTarget ->
EnumValue(ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.annotationTarget), Name.identifier(kotlinTarget.name)) EnumValue(ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.annotationTarget), Name.identifier(kotlinTarget.name))
} }
return ArrayValue(kotlinTargets) { module -> return ArrayValue(kotlinTargets) { module ->
val parameterDescriptor = DescriptorResolverUtils.getAnnotationParameterByName( val parameterDescriptor = DescriptorResolverUtils.getAnnotationParameterByName(
JavaAnnotationMapper.TARGET_ANNOTATION_ALLOWED_TARGETS, JavaAnnotationMapper.TARGET_ANNOTATION_ALLOWED_TARGETS,
module.builtIns.getBuiltInClassByFqName(KotlinBuiltIns.FQ_NAMES.target) module.builtIns.getBuiltInClassByFqName(KotlinBuiltIns.FQ_NAMES.target)
) )
parameterDescriptor?.type ?: ErrorUtils.createErrorType("Error: AnnotationTarget[]") parameterDescriptor?.type ?: ErrorUtils.createErrorType("Error: AnnotationTarget[]")
} }
} }
private val retentionNameList = mapOf( private val retentionNameList = mapOf(
"RUNTIME" to KotlinRetention.RUNTIME, "RUNTIME" to KotlinRetention.RUNTIME,
"CLASS" to KotlinRetention.BINARY, "CLASS" to KotlinRetention.BINARY,
"SOURCE" to KotlinRetention.SOURCE "SOURCE" to KotlinRetention.SOURCE
) )
internal fun mapJavaRetentionArgument(element: JavaAnnotationArgument?): ConstantValue<*>? { internal fun mapJavaRetentionArgument(element: JavaAnnotationArgument?): ConstantValue<*>? {
@@ -36,9 +36,9 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class ValueParameterData(val type: KotlinType, val hasDefaultValue: Boolean) class ValueParameterData(val type: KotlinType, val hasDefaultValue: Boolean)
fun copyValueParameters( fun copyValueParameters(
newValueParametersTypes: Collection<ValueParameterData>, newValueParametersTypes: Collection<ValueParameterData>,
oldValueParameters: Collection<ValueParameterDescriptor>, oldValueParameters: Collection<ValueParameterDescriptor>,
newOwner: CallableDescriptor newOwner: CallableDescriptor
): List<ValueParameterDescriptor> { ): List<ValueParameterDescriptor> {
assert(newValueParametersTypes.size == oldValueParameters.size) { assert(newValueParametersTypes.size == oldValueParameters.size) {
"Different value parameters sizes: Enhanced = ${newValueParametersTypes.size}, Old = ${oldValueParameters.size}" "Different value parameters sizes: Enhanced = ${newValueParametersTypes.size}, Old = ${oldValueParameters.size}"
@@ -46,17 +46,17 @@ fun copyValueParameters(
return newValueParametersTypes.zip(oldValueParameters).map { (newParameter, oldParameter) -> return newValueParametersTypes.zip(oldValueParameters).map { (newParameter, oldParameter) ->
ValueParameterDescriptorImpl( ValueParameterDescriptorImpl(
newOwner, newOwner,
null, null,
oldParameter.index, oldParameter.index,
oldParameter.annotations, oldParameter.annotations,
oldParameter.name, oldParameter.name,
newParameter.type, newParameter.type,
newParameter.hasDefaultValue, newParameter.hasDefaultValue,
oldParameter.isCrossinline, oldParameter.isCrossinline,
oldParameter.isNoinline, oldParameter.isNoinline,
if (oldParameter.varargElementType != null) newOwner.module.builtIns.getArrayElementType(newParameter.type) else null, if (oldParameter.varargElementType != null) newOwner.module.builtIns.getArrayElementType(newParameter.type) else null,
oldParameter.source oldParameter.source
) )
} }
} }
@@ -72,10 +72,10 @@ fun ClassDescriptor.getParentJavaStaticClassScope(): LazyJavaStaticClassScope? {
} }
fun DeserializedMemberDescriptor.getImplClassNameForDeserialized(): JvmClassName? = fun DeserializedMemberDescriptor.getImplClassNameForDeserialized(): JvmClassName? =
(containerSource as? JvmPackagePartSource)?.className (containerSource as? JvmPackagePartSource)?.className
fun DeserializedMemberDescriptor.isFromJvmPackagePart(): Boolean = fun DeserializedMemberDescriptor.isFromJvmPackagePart(): Boolean =
containerSource is JvmPackagePartSource containerSource is JvmPackagePartSource
fun ValueParameterDescriptor.getParameterNameAnnotation(): AnnotationDescriptor? { fun ValueParameterDescriptor.getParameterNameAnnotation(): AnnotationDescriptor? {
val annotation = annotations.findAnnotation(JvmAnnotationNames.PARAMETER_NAME_FQ_NAME) ?: return null val annotation = annotations.findAnnotation(JvmAnnotationNames.PARAMETER_NAME_FQ_NAME) ?: return null
@@ -92,9 +92,9 @@ object NullDefaultValue : AnnotationDefaultValue()
fun ValueParameterDescriptor.getDefaultValueFromAnnotation(): AnnotationDefaultValue? { fun ValueParameterDescriptor.getDefaultValueFromAnnotation(): AnnotationDefaultValue? {
annotations.findAnnotation(JvmAnnotationNames.DEFAULT_VALUE_FQ_NAME) annotations.findAnnotation(JvmAnnotationNames.DEFAULT_VALUE_FQ_NAME)
?.firstArgument() ?.firstArgument()
?.safeAs<StringValue>()?.value ?.safeAs<StringValue>()?.value
?.let { return StringDefaultValue(it) } ?.let { return StringDefaultValue(it) }
if (annotations.hasAnnotation(JvmAnnotationNames.DEFAULT_NULL_FQ_NAME)) { if (annotations.hasAnnotation(JvmAnnotationNames.DEFAULT_NULL_FQ_NAME)) {
return NullDefaultValue return NullDefaultValue
@@ -24,23 +24,27 @@ import org.jetbrains.kotlin.load.java.structure.JavaAnnotationOwner
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
class LazyJavaAnnotations( class LazyJavaAnnotations(
private val c: LazyJavaResolverContext, private val c: LazyJavaResolverContext,
private val annotationOwner: JavaAnnotationOwner private val annotationOwner: JavaAnnotationOwner
) : Annotations { ) : Annotations {
private val annotationDescriptors = c.components.storageManager.createMemoizedFunctionWithNullableValues { private val annotationDescriptors = c.components.storageManager.createMemoizedFunctionWithNullableValues { annotation: JavaAnnotation ->
annotation: JavaAnnotation -> JavaAnnotationMapper.mapOrResolveJavaAnnotation(annotation, c) JavaAnnotationMapper.mapOrResolveJavaAnnotation(annotation, c)
} }
override fun findAnnotation(fqName: FqName) = override fun findAnnotation(fqName: FqName) =
annotationOwner.findAnnotation(fqName)?.let(annotationDescriptors) annotationOwner.findAnnotation(fqName)?.let(annotationDescriptors)
?: JavaAnnotationMapper.findMappedJavaAnnotation(fqName, annotationOwner, c) ?: JavaAnnotationMapper.findMappedJavaAnnotation(fqName, annotationOwner, c)
override fun iterator() = override fun iterator() =
(annotationOwner.annotations.asSequence().map(annotationDescriptors) (annotationOwner.annotations.asSequence().map(annotationDescriptors) +
+ JavaAnnotationMapper.findMappedJavaAnnotation(KotlinBuiltIns.FQ_NAMES.deprecated, annotationOwner, c)).filterNotNull().iterator() JavaAnnotationMapper.findMappedJavaAnnotation(
KotlinBuiltIns.FQ_NAMES.deprecated,
annotationOwner,
c
)).filterNotNull().iterator()
override fun isEmpty() = annotationOwner.annotations.isEmpty() && !annotationOwner.isDeprecatedInJavaDoc override fun isEmpty() = annotationOwner.annotations.isEmpty() && !annotationOwner.isDeprecatedInJavaDoc
} }
fun LazyJavaResolverContext.resolveAnnotations(annotationsOwner: JavaAnnotationOwner): Annotations fun LazyJavaResolverContext.resolveAnnotations(annotationsOwner: JavaAnnotationOwner): Annotations =
= LazyJavaAnnotations(this, annotationsOwner) LazyJavaAnnotations(this, annotationsOwner)
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.CacheWithNotNullValues import org.jetbrains.kotlin.storage.CacheWithNotNullValues
class LazyJavaPackageFragmentProvider( class LazyJavaPackageFragmentProvider(
components: JavaResolverComponents components: JavaResolverComponents
) : PackageFragmentProvider { ) : PackageFragmentProvider {
private val c = LazyJavaResolverContext(components, TypeParameterResolver.EMPTY, lazyOf(null)) private val c = LazyJavaResolverContext(components, TypeParameterResolver.EMPTY, lazyOf(null))
@@ -42,5 +42,5 @@ class LazyJavaPackageFragmentProvider(
override fun getPackageFragments(fqName: FqName) = listOfNotNull(getPackageFragment(fqName)) override fun getPackageFragments(fqName: FqName) = listOfNotNull(getPackageFragment(fqName))
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean) = override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean) =
getPackageFragment(fqName)?.getSubPackageFqNames().orEmpty() getPackageFragment(fqName)?.getSubPackageFqNames().orEmpty()
} }
@@ -33,6 +33,6 @@ class SingleModuleClassResolver() : ModuleClassResolver {
@Inject set @Inject set
} }
class ModuleClassResolverImpl(private val descriptorResolverByJavaClass: (JavaClass) -> JavaDescriptorResolver): ModuleClassResolver { class ModuleClassResolverImpl(private val descriptorResolverByJavaClass: (JavaClass) -> JavaDescriptorResolver) : ModuleClassResolver {
override fun resolveClass(javaClass: JavaClass): ClassDescriptor? = descriptorResolverByJavaClass(javaClass).resolveClass(javaClass) override fun resolveClass(javaClass: JavaClass): ClassDescriptor? = descriptorResolverByJavaClass(javaClass).resolveClass(javaClass)
} }
@@ -1,30 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//package org.jetbrains.kotlin.load.java.lazy
//interface PackageMappingProvider {
//
// fun findPackageMembers(packageName: String): List<String>
//
// companion object {
// val EMPTY = object : PackageMappingProvider {
// override fun findPackageMembers(packageName: String): List<String> {
// return emptyList()
// }
// }
// }
//}
@@ -40,11 +40,10 @@ interface DeclaredMemberIndex {
} }
open class ClassDeclaredMemberIndex( open class ClassDeclaredMemberIndex(
val jClass: JavaClass, val jClass: JavaClass,
private val memberFilter: (JavaMember) -> Boolean private val memberFilter: (JavaMember) -> Boolean
) : DeclaredMemberIndex { ) : DeclaredMemberIndex {
private val methodFilter = { private val methodFilter = { m: JavaMethod ->
m: JavaMethod ->
memberFilter(m) && !DescriptorResolverUtils.isObjectMethodInInterface(m) memberFilter(m) && !DescriptorResolverUtils.isObjectMethodInInterface(m)
} }
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.load.java.lazy.descriptors
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
// Currently getter is null iff it's loaded from Java field // Currently getter is null iff it's loaded from Java field
val PropertyDescriptor.isJavaField: Boolean val PropertyDescriptor.isJavaField: Boolean
get() = getter == null get() = getter == null
@@ -34,10 +34,10 @@ import org.jetbrains.kotlin.util.collectionUtils.getFromAllScopes
import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.Printer
class JvmPackageScope( class JvmPackageScope(
private val c: LazyJavaResolverContext, private val c: LazyJavaResolverContext,
jPackage: JavaPackage, jPackage: JavaPackage,
private val packageFragment: LazyJavaPackageFragment private val packageFragment: LazyJavaPackageFragment
): MemberScope { ) : MemberScope {
internal val javaScope = LazyJavaPackageScope(c, jPackage, packageFragment) internal val javaScope = LazyJavaPackageScope(c, jPackage, packageFragment)
private val kotlinScopes by c.storageManager.createLazyValue { private val kotlinScopes by c.storageManager.createLazyValue {
@@ -66,13 +66,14 @@ class JvmPackageScope(
} }
override fun getContributedDescriptors( override fun getContributedDescriptors(
kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean
): Collection<DeclarationDescriptor> = ): Collection<DeclarationDescriptor> =
getFromAllScopes(javaScope, kotlinScopes) { it.getContributedDescriptors(kindFilter, nameFilter) } getFromAllScopes(javaScope, kotlinScopes) { it.getContributedDescriptors(kindFilter, nameFilter) }
override fun getFunctionNames() = kotlinScopes.flatMapTo(mutableSetOf()) { it.getFunctionNames() }.apply { override fun getFunctionNames() = kotlinScopes.flatMapTo(mutableSetOf()) { it.getFunctionNames() }.apply {
addAll(javaScope.getFunctionNames()) addAll(javaScope.getFunctionNames())
} }
override fun getVariableNames() = kotlinScopes.flatMapTo(mutableSetOf()) { it.getVariableNames() }.apply { override fun getVariableNames() = kotlinScopes.flatMapTo(mutableSetOf()) { it.getVariableNames() }.apply {
addAll(javaScope.getVariableNames()) addAll(javaScope.getVariableNames())
} }
@@ -37,8 +37,8 @@ import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.isError import org.jetbrains.kotlin.types.isError
class LazyJavaAnnotationDescriptor( class LazyJavaAnnotationDescriptor(
private val c: LazyJavaResolverContext, private val c: LazyJavaResolverContext,
private val javaAnnotation: JavaAnnotation private val javaAnnotation: JavaAnnotation
) : AnnotationDescriptor { ) : AnnotationDescriptor {
override val fqName by c.storageManager.createNullableLazyValue { override val fqName by c.storageManager.createNullableLazyValue {
javaAnnotation.classId?.asSingleFqName() javaAnnotation.classId?.asSingleFqName()
@@ -47,8 +47,8 @@ class LazyJavaAnnotationDescriptor(
override val type by c.storageManager.createLazyValue { override val type by c.storageManager.createLazyValue {
val fqName = fqName ?: return@createLazyValue ErrorUtils.createErrorType("No fqName: $javaAnnotation") val fqName = fqName ?: return@createLazyValue ErrorUtils.createErrorType("No fqName: $javaAnnotation")
val annotationClass = JavaToKotlinClassMap.mapJavaToKotlin(fqName, c.module.builtIns) val annotationClass = JavaToKotlinClassMap.mapJavaToKotlin(fqName, c.module.builtIns)
?: javaAnnotation.resolve()?.let { javaClass -> c.components.moduleClassResolver.resolveClass(javaClass) } ?: javaAnnotation.resolve()?.let { javaClass -> c.components.moduleClassResolver.resolveClass(javaClass) }
?: createTypeForMissingDependencies(fqName) ?: createTypeForMissingDependencies(fqName)
annotationClass.defaultType annotationClass.defaultType
} }
@@ -80,15 +80,15 @@ class LazyJavaAnnotationDescriptor(
if (type.isError) return null if (type.isError) return null
val arrayType = val arrayType =
DescriptorResolverUtils.getAnnotationParameterByName(argumentName, annotationClass!!)?.type DescriptorResolverUtils.getAnnotationParameterByName(argumentName, annotationClass!!)?.type
// Try to load annotation arguments even if the annotation class is not found // Try to load annotation arguments even if the annotation class is not found
?: c.components.module.builtIns.getArrayType( ?: c.components.module.builtIns.getArrayType(
Variance.INVARIANT, Variance.INVARIANT,
ErrorUtils.createErrorType("Unknown array element type") ErrorUtils.createErrorType("Unknown array element type")
) )
val values = elements.map { val values = elements.map { argument ->
argument -> resolveAnnotationArgument(argument) ?: NullValue() resolveAnnotationArgument(argument) ?: NullValue()
} }
return ConstantValueFactory.createArrayValue(values, arrayType) return ConstantValueFactory.createArrayValue(values, arrayType)
@@ -108,8 +108,8 @@ class LazyJavaAnnotationDescriptor(
} }
private fun createTypeForMissingDependencies(fqName: FqName) = private fun createTypeForMissingDependencies(fqName: FqName) =
c.module.findNonGenericClassAcrossDependencies( c.module.findNonGenericClassAcrossDependencies(
ClassId.topLevel(fqName), ClassId.topLevel(fqName),
c.components.deserializedDescriptorResolver.components.notFoundClasses c.components.deserializedDescriptorResolver.components.notFoundClasses
) )
} }
@@ -39,13 +39,15 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.util.* import java.util.*
class LazyJavaClassDescriptor( class LazyJavaClassDescriptor(
val outerContext: LazyJavaResolverContext, val outerContext: LazyJavaResolverContext,
containingDeclaration: DeclarationDescriptor, containingDeclaration: DeclarationDescriptor,
val jClass: JavaClass, val jClass: JavaClass,
private val additionalSupertypeClassDescriptor: ClassDescriptor? = null private val additionalSupertypeClassDescriptor: ClassDescriptor? = null
) : ClassDescriptorBase(outerContext.storageManager, containingDeclaration, jClass.name, ) : ClassDescriptorBase(
outerContext.components.sourceElementFactory.source(jClass), outerContext.storageManager, containingDeclaration, jClass.name,
/* isExternal = */ false), JavaClassDescriptor { outerContext.components.sourceElementFactory.source(jClass),
/* isExternal = */ false
), JavaClassDescriptor {
companion object { companion object {
@JvmStatic @JvmStatic
@@ -69,9 +71,9 @@ class LazyJavaClassDescriptor(
else -> ClassKind.CLASS else -> ClassKind.CLASS
} }
private val modality = if (jClass.isAnnotationType) private val modality =
Modality.FINAL if (jClass.isAnnotationType) Modality.FINAL
else Modality.convertFromFlags(jClass.isAbstract || jClass.isInterface, !jClass.isFinal) else Modality.convertFromFlags(jClass.isAbstract || jClass.isInterface, !jClass.isFinal)
private val visibility = jClass.visibility private val visibility = jClass.visibility
private val isInner = jClass.outerClass != null && !jClass.isStatic private val isInner = jClass.outerClass != null && !jClass.isStatic
@@ -86,7 +88,7 @@ class LazyJavaClassDescriptor(
// Kotlin considers this "private in package" just as "private" and thinks they are invisible for inheritors, // Kotlin considers this "private in package" just as "private" and thinks they are invisible for inheritors,
// so their functions are invisible fake which is not true. // so their functions are invisible fake which is not true.
override fun getVisibility() = override fun getVisibility() =
if (visibility == Visibilities.PRIVATE && jClass.outerClass == null) JavaVisibilities.PACKAGE_VISIBILITY else visibility if (visibility == Visibilities.PRIVATE && jClass.outerClass == null) JavaVisibilities.PACKAGE_VISIBILITY else visibility
override fun isInner() = isInner override fun isInner() = isInner
override fun isData() = false override fun isData() = false
@@ -116,8 +118,7 @@ class LazyJavaClassDescriptor(
override val annotations = c.resolveAnnotations(jClass) override val annotations = c.resolveAnnotations(jClass)
private val declaredParameters = c.storageManager.createLazyValue { private val declaredParameters = c.storageManager.createLazyValue {
jClass.typeParameters.map { jClass.typeParameters.map { p ->
p ->
c.typeParameterResolver.resolveTypeParameter(p) c.typeParameterResolver.resolveTypeParameter(p)
?: throw AssertionError("Parameter $p surely belongs to class $jClass, so it must be resolved") ?: throw AssertionError("Parameter $p surely belongs to class $jClass, so it must be resolved")
} }
@@ -125,7 +126,8 @@ class LazyJavaClassDescriptor(
override fun getDeclaredTypeParameters() = declaredParameters() override fun getDeclaredTypeParameters() = declaredParameters()
override fun getDefaultFunctionTypeForSamInterface(): SimpleType? = c.components.samConversionResolver.resolveFunctionTypeIfSamInterface(this) override fun getDefaultFunctionTypeForSamInterface(): SimpleType? =
c.components.samConversionResolver.resolveFunctionTypeIfSamInterface(this)
override fun isDefinitelyNotSamInterface(): Boolean { override fun isDefinitelyNotSamInterface(): Boolean {
if (kind != ClassKind.INTERFACE) return true if (kind != ClassKind.INTERFACE) return true
@@ -152,7 +154,7 @@ class LazyJavaClassDescriptor(
// Checks if any part of compiler has requested scope content // Checks if any part of compiler has requested scope content
// It's necessary for IC to figure out if there is a need to track symbols in the class // It's necessary for IC to figure out if there is a need to track symbols in the class
fun wasScopeContentRequested() = fun wasScopeContentRequested() =
getUnsubstitutedMemberScope().wasContentRequested() || staticScope.wasContentRequested() getUnsubstitutedMemberScope().wasContentRequested() || staticScope.wasContentRequested()
override fun getSealedSubclasses(): Collection<ClassDescriptor> = emptyList() override fun getSealedSubclasses(): Collection<ClassDescriptor> = emptyList()
@@ -190,10 +192,11 @@ class LazyJavaClassDescriptor(
// Add fake supertype kotlin.collection.Collection<E> to java.util.Collection<E> class if needed // Add fake supertype kotlin.collection.Collection<E> to java.util.Collection<E> class if needed
// Only needed when calculating built-ins member scope // Only needed when calculating built-ins member scope
result.addIfNotNull( result.addIfNotNull(
additionalSupertypeClassDescriptor?.let { additionalSupertypeClassDescriptor?.let {
createMappedTypeParametersSubstitution(it, this@LazyJavaClassDescriptor) createMappedTypeParametersSubstitution(it, this@LazyJavaClassDescriptor)
.buildSubstitutor().substitute(it.defaultType, Variance.INVARIANT) .buildSubstitutor().substitute(it.defaultType, Variance.INVARIANT)
}) }
)
result.addIfNotNull(purelyImplementedSupertype) result.addIfNotNull(purelyImplementedSupertype)
@@ -212,7 +215,7 @@ class LazyJavaClassDescriptor(
} }
val purelyImplementedFqName = val purelyImplementedFqName =
annotatedPurelyImplementedFqName annotatedPurelyImplementedFqName
?: FakePureImplementationsProvider.getPurelyImplementedInterface(fqNameSafe) ?: FakePureImplementationsProvider.getPurelyImplementedInterface(fqNameSafe)
?: return null ?: return null
@@ -224,12 +227,10 @@ class LazyJavaClassDescriptor(
val parametersAsTypeProjections = when { val parametersAsTypeProjections = when {
typeParameterCount == supertypeParameterCount -> typeParameterCount == supertypeParameterCount ->
typeParameters.map { typeParameters.map { parameter ->
parameter ->
TypeProjectionImpl(Variance.INVARIANT, parameter.defaultType) TypeProjectionImpl(Variance.INVARIANT, parameter.defaultType)
} }
typeParameterCount == 1 && supertypeParameterCount > 1 && annotatedPurelyImplementedFqName == null -> typeParameterCount == 1 && supertypeParameterCount > 1 && annotatedPurelyImplementedFqName == null -> {
{
val parameter = TypeProjectionImpl(Variance.INVARIANT, typeParameters.single().defaultType) val parameter = TypeProjectionImpl(Variance.INVARIANT, typeParameters.single().defaultType)
(1..supertypeParameterCount).map { parameter } // TODO: List(supertypeParameterCount) { parameter } (1..supertypeParameterCount).map { parameter } // TODO: List(supertypeParameterCount) { parameter }
} }
@@ -241,7 +242,7 @@ class LazyJavaClassDescriptor(
private fun getPurelyImplementsFqNameFromAnnotation(): FqName? { private fun getPurelyImplementsFqNameFromAnnotation(): FqName? {
val annotation = val annotation =
this@LazyJavaClassDescriptor.annotations.findAnnotation(JvmAnnotationNames.PURELY_IMPLEMENTS_ANNOTATION) this@LazyJavaClassDescriptor.annotations.findAnnotation(JvmAnnotationNames.PURELY_IMPLEMENTS_ANNOTATION)
?: return null ?: return null
val fqNameString = (annotation.allValueArguments.values.singleOrNull() as? StringValue)?.value ?: return null val fqNameString = (annotation.allValueArguments.values.singleOrNull() as? StringValue)?.value ?: return null
@@ -262,8 +263,9 @@ class LazyJavaClassDescriptor(
// Only needed when calculating built-ins member scope // Only needed when calculating built-ins member scope
internal fun copy( internal fun copy(
javaResolverCache: JavaResolverCache, additionalSupertypeClassDescriptor: ClassDescriptor? javaResolverCache: JavaResolverCache, additionalSupertypeClassDescriptor: ClassDescriptor?
) = LazyJavaClassDescriptor( ): LazyJavaClassDescriptor = LazyJavaClassDescriptor(
c.replaceComponents(c.components.replace(javaResolverCache = javaResolverCache)), c.replaceComponents(c.components.replace(javaResolverCache = javaResolverCache)),
containingDeclaration, jClass, additionalSupertypeClassDescriptor) containingDeclaration, jClass, additionalSupertypeClassDescriptor
)
} }
@@ -318,7 +318,7 @@ class LazyJavaClassMemberScope(
result.addAll( result.addAll(
additionalOverrides.map { resolvedOverride -> additionalOverrides.map { resolvedOverride ->
val overriddenBuiltin = resolvedOverride.getOverriddenSpecialBuiltin() val overriddenBuiltin = resolvedOverride.getOverriddenSpecialBuiltin()
?: return@map resolvedOverride ?: return@map resolvedOverride
resolvedOverride.createHiddenCopyIfBuiltinAlreadyAccidentallyOverridden(overriddenBuiltin, allDescriptors) resolvedOverride.createHiddenCopyIfBuiltinAlreadyAccidentallyOverridden(overriddenBuiltin, allDescriptors)
}) })
@@ -353,7 +353,7 @@ class LazyJavaClassMemberScope(
): SimpleFunctionDescriptor? { ): SimpleFunctionDescriptor? {
val overriddenBuiltin = val overriddenBuiltin =
BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(descriptor) BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(descriptor)
?: return null ?: return null
return createOverrideForBuiltinFunctionWithErasedParameterIfNeeded(overriddenBuiltin, functions) return createOverrideForBuiltinFunctionWithErasedParameterIfNeeded(overriddenBuiltin, functions)
?.takeIf(this::isVisibleAsFunctionInCurrentClass) ?.takeIf(this::isVisibleAsFunctionInCurrentClass)
@@ -639,13 +639,13 @@ class LazyJavaClassMemberScope(
if (methodNamedValue != null) { if (methodNamedValue != null) {
val parameterNamedValueJavaType = methodNamedValue.returnType val parameterNamedValueJavaType = methodNamedValue.returnType
val (parameterType, varargType) = val (parameterType, varargType) =
if (parameterNamedValueJavaType is JavaArrayType) if (parameterNamedValueJavaType is JavaArrayType)
Pair( Pair(
c.typeResolver.transformArrayType(parameterNamedValueJavaType, attr, isVararg = true), c.typeResolver.transformArrayType(parameterNamedValueJavaType, attr, isVararg = true),
c.typeResolver.transformJavaType(parameterNamedValueJavaType.componentType, attr) c.typeResolver.transformJavaType(parameterNamedValueJavaType.componentType, attr)
) )
else else
Pair(c.typeResolver.transformJavaType(parameterNamedValueJavaType, attr), null) Pair(c.typeResolver.transformJavaType(parameterNamedValueJavaType, attr), null)
result.addAnnotationValueParameter(constructor, 0, methodNamedValue, parameterType, varargType) result.addAnnotationValueParameter(constructor, 0, methodNamedValue, parameterType, varargType)
} }
@@ -34,8 +34,8 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.storage.getValue import org.jetbrains.kotlin.storage.getValue
class LazyJavaPackageFragment( class LazyJavaPackageFragment(
outerContext: LazyJavaResolverContext, outerContext: LazyJavaResolverContext,
private val jPackage: JavaPackage private val jPackage: JavaPackage
) : PackageFragmentDescriptorImpl(outerContext.module, jPackage.fqName) { ) : PackageFragmentDescriptorImpl(outerContext.module, jPackage.fqName) {
private val c = outerContext.childForClassOrPackage(this) private val c = outerContext.childForClassOrPackage(this)
@@ -49,15 +49,15 @@ class LazyJavaPackageFragment(
private val scope = JvmPackageScope(c, jPackage, this) private val scope = JvmPackageScope(c, jPackage, this)
private val subPackages = c.storageManager.createRecursionTolerantLazyValue( private val subPackages = c.storageManager.createRecursionTolerantLazyValue(
{ jPackage.subPackages.map(JavaPackage::fqName) }, { jPackage.subPackages.map(JavaPackage::fqName) },
// This breaks infinite recursion between loading Java descriptors and building light classes // This breaks infinite recursion between loading Java descriptors and building light classes
onRecursiveCall = listOf() onRecursiveCall = listOf()
) )
override val annotations = override val annotations =
// Do not resolve package annotations if JSR-305 is disabled // Do not resolve package annotations if JSR-305 is disabled
if (c.components.annotationTypeQualifierResolver.disabled) Annotations.EMPTY if (c.components.annotationTypeQualifierResolver.disabled) Annotations.EMPTY
else c.resolveAnnotations(jPackage) else c.resolveAnnotations(jPackage)
internal fun getSubPackageFqNames(): List<FqName> = subPackages() internal fun getSubPackageFqNames(): List<FqName> = subPackages()
@@ -65,7 +65,7 @@ class LazyJavaPackageFragment(
private val partToFacade by c.storageManager.createLazyValue { private val partToFacade by c.storageManager.createLazyValue {
val result = hashMapOf<JvmClassName, JvmClassName>() val result = hashMapOf<JvmClassName, JvmClassName>()
kotlinClasses@for ((partInternalName, kotlinClass) in binaryClasses) { kotlinClasses@ for ((partInternalName, kotlinClass) in binaryClasses) {
val partName = JvmClassName.byInternalName(partInternalName) val partName = JvmClassName.byInternalName(partInternalName)
val header = kotlinClass.classHeader val header = kotlinClass.classHeader
when (header.kind) { when (header.kind) {
@@ -75,7 +75,8 @@ class LazyJavaPackageFragment(
KotlinClassHeader.Kind.FILE_FACADE -> { KotlinClassHeader.Kind.FILE_FACADE -> {
result[partName] = partName result[partName] = partName
} }
else -> {} else -> {
}
} }
} }
result result
@@ -56,7 +56,7 @@ class LazyJavaPackageScope(
val requestClassId = ClassId(ownerDescriptor.fqName, request.name) val requestClassId = ClassId(ownerDescriptor.fqName, request.name)
val kotlinClassOrClassFileContent = val kotlinClassOrClassFileContent =
// These branches should be semantically equal, but the first one could be faster // These branches should be semantically equal, but the first one could be faster
if (request.javaClass != null) if (request.javaClass != null)
c.components.kotlinClassFinder.findKotlinClassOrContent(request.javaClass) c.components.kotlinClassFinder.findKotlinClassOrContent(request.javaClass)
else else
@@ -60,12 +60,12 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
// this lazy value is not used at all in LazyPackageFragmentScopeForJavaPackage because we do not use caching there // this lazy value is not used at all in LazyPackageFragmentScopeForJavaPackage because we do not use caching there
// but is placed in the base class to not duplicate code // but is placed in the base class to not duplicate code
private val allDescriptors = c.storageManager.createRecursionTolerantLazyValue<Collection<DeclarationDescriptor>>( private val allDescriptors = c.storageManager.createRecursionTolerantLazyValue<Collection<DeclarationDescriptor>>(
{ computeDescriptors(DescriptorKindFilter.ALL, MemberScope.ALL_NAME_FILTER, NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS) }, { computeDescriptors(DescriptorKindFilter.ALL, MemberScope.ALL_NAME_FILTER, NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS) },
// This is to avoid the following recursive case: // This is to avoid the following recursive case:
// when computing getAllPackageNames() we ask the JavaPsiFacade for all subpackages of foo // when computing getAllPackageNames() we ask the JavaPsiFacade for all subpackages of foo
// it, in turn, asks JavaElementFinder for subpackages of Kotlin package foo, which calls getAllPackageNames() recursively // it, in turn, asks JavaElementFinder for subpackages of Kotlin package foo, which calls getAllPackageNames() recursively
// when on recursive call we return an empty collection, recursion collapses gracefully // when on recursive call we return an empty collection, recursion collapses gracefully
listOf() listOf()
) )
protected val declaredMemberIndex: NotNullLazyValue<DeclaredMemberIndex> = c.storageManager.createLazyValue { computeMemberIndex() } protected val declaredMemberIndex: NotNullLazyValue<DeclaredMemberIndex> = c.storageManager.createLazyValue { computeMemberIndex() }
@@ -79,8 +79,7 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
protected abstract fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? protected abstract fun getDispatchReceiverParameter(): ReceiverParameterDescriptor?
private val functions = c.storageManager.createMemoizedFunction<Name, Collection<SimpleFunctionDescriptor>> { private val functions = c.storageManager.createMemoizedFunction<Name, Collection<SimpleFunctionDescriptor>> { name ->
name ->
val result = LinkedHashSet<SimpleFunctionDescriptor>() val result = LinkedHashSet<SimpleFunctionDescriptor>()
for (method in declaredMemberIndex().findMethodsByName(name)) { for (method in declaredMemberIndex().findMethodsByName(name)) {
@@ -101,25 +100,25 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
open protected fun JavaMethodDescriptor.isVisibleAsFunction() = true open protected fun JavaMethodDescriptor.isVisibleAsFunction() = true
protected data class MethodSignatureData( protected data class MethodSignatureData(
val returnType: KotlinType, val returnType: KotlinType,
val receiverType: KotlinType?, val receiverType: KotlinType?,
val valueParameters: List<ValueParameterDescriptor>, val valueParameters: List<ValueParameterDescriptor>,
val typeParameters: List<TypeParameterDescriptor>, val typeParameters: List<TypeParameterDescriptor>,
val hasStableParameterNames: Boolean, val hasStableParameterNames: Boolean,
val errors: List<String> val errors: List<String>
) )
protected abstract fun resolveMethodSignature( protected abstract fun resolveMethodSignature(
method: JavaMethod, method: JavaMethod,
methodTypeParameters: List<TypeParameterDescriptor>, methodTypeParameters: List<TypeParameterDescriptor>,
returnType: KotlinType, returnType: KotlinType,
valueParameters: List<ValueParameterDescriptor> valueParameters: List<ValueParameterDescriptor>
): MethodSignatureData ): MethodSignatureData
protected fun resolveMethodToFunctionDescriptor(method: JavaMethod): JavaMethodDescriptor { protected fun resolveMethodToFunctionDescriptor(method: JavaMethod): JavaMethodDescriptor {
val annotations = c.resolveAnnotations(method) val annotations = c.resolveAnnotations(method)
val functionDescriptorImpl = JavaMethodDescriptor.createJavaMethod( val functionDescriptorImpl = JavaMethodDescriptor.createJavaMethod(
ownerDescriptor, annotations, method.name, c.components.sourceElementFactory.source(method) ownerDescriptor, annotations, method.name, c.components.sourceElementFactory.source(method)
) )
val c = c.childForMethod(functionDescriptorImpl, method) val c = c.childForMethod(functionDescriptorImpl, method)
@@ -142,9 +141,9 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
Modality.convertFromFlags(method.isAbstract, !method.isFinal), Modality.convertFromFlags(method.isAbstract, !method.isFinal),
method.visibility, method.visibility,
if (effectiveSignature.receiverType != null) if (effectiveSignature.receiverType != null)
mapOf(JavaMethodDescriptor.ORIGINAL_VALUE_PARAMETER_FOR_EXTENSION_RECEIVER to valueParameters.descriptors.first()) mapOf(JavaMethodDescriptor.ORIGINAL_VALUE_PARAMETER_FOR_EXTENSION_RECEIVER to valueParameters.descriptors.first())
else else
emptyMap<CallableDescriptor.UserDataKey<ValueParameterDescriptor>, ValueParameterDescriptor>() emptyMap<CallableDescriptor.UserDataKey<ValueParameterDescriptor>, ValueParameterDescriptor>()
) )
functionDescriptorImpl.setParameterNamesStatus(effectiveSignature.hasStableParameterNames, valueParameters.hasSynthesizedNames) functionDescriptorImpl.setParameterNamesStatus(effectiveSignature.hasStableParameterNames, valueParameters.hasSynthesizedNames)
@@ -158,18 +157,16 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
protected fun computeMethodReturnType(method: JavaMethod, c: LazyJavaResolverContext): KotlinType { protected fun computeMethodReturnType(method: JavaMethod, c: LazyJavaResolverContext): KotlinType {
val annotationMethod = method.containingClass.isAnnotationType val annotationMethod = method.containingClass.isAnnotationType
val returnTypeAttrs = TypeUsage.COMMON.toAttributes( val returnTypeAttrs = TypeUsage.COMMON.toAttributes(isForAnnotationParameter = annotationMethod)
isForAnnotationParameter = annotationMethod
)
return c.typeResolver.transformJavaType(method.returnType, returnTypeAttrs) return c.typeResolver.transformJavaType(method.returnType, returnTypeAttrs)
} }
protected class ResolvedValueParameters(val descriptors: List<ValueParameterDescriptor>, val hasSynthesizedNames: Boolean) protected class ResolvedValueParameters(val descriptors: List<ValueParameterDescriptor>, val hasSynthesizedNames: Boolean)
protected fun resolveValueParameters( protected fun resolveValueParameters(
c: LazyJavaResolverContext, c: LazyJavaResolverContext,
function: FunctionDescriptor, function: FunctionDescriptor,
jValueParameters: List<JavaValueParameter> jValueParameters: List<JavaValueParameter>
): ResolvedValueParameters { ): ResolvedValueParameters {
var synthesizedNames = false var synthesizedNames = false
val usedNames = mutableSetOf<String>() val usedNames = mutableSetOf<String>()
@@ -178,34 +175,32 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
val annotations = c.resolveAnnotations(javaParameter) val annotations = c.resolveAnnotations(javaParameter)
val typeUsage = TypeUsage.COMMON.toAttributes() val typeUsage = TypeUsage.COMMON.toAttributes()
val parameterName = annotations val parameterName = annotations
.findAnnotation(JvmAnnotationNames.PARAMETER_NAME_FQ_NAME) .findAnnotation(JvmAnnotationNames.PARAMETER_NAME_FQ_NAME)
?.firstArgument() ?.firstArgument()
?.safeAs<StringValue>()?.value ?.safeAs<StringValue>()?.value
val (outType, varargElementType) = val (outType, varargElementType) =
if (javaParameter.isVararg) { if (javaParameter.isVararg) {
val paramType = javaParameter.type as? JavaArrayType val paramType = javaParameter.type as? JavaArrayType
?: throw AssertionError("Vararg parameter should be an array: $javaParameter") ?: throw AssertionError("Vararg parameter should be an array: $javaParameter")
val outType = c.typeResolver.transformArrayType(paramType, typeUsage, true) val outType = c.typeResolver.transformArrayType(paramType, typeUsage, true)
outType to c.module.builtIns.getArrayElementType(outType) outType to c.module.builtIns.getArrayElementType(outType)
} } else {
else { c.typeResolver.transformJavaType(javaParameter.type, typeUsage) to null
c.typeResolver.transformJavaType(javaParameter.type, typeUsage) to null }
}
val name = if (function.name.asString() == "equals" && val name = if (function.name.asString() == "equals" &&
jValueParameters.size == 1 && jValueParameters.size == 1 &&
c.module.builtIns.nullableAnyType == outType) { c.module.builtIns.nullableAnyType == outType
) {
// This is a hack to prevent numerous warnings on Kotlin classes that inherit Java classes: if you override "equals" in such // This is a hack to prevent numerous warnings on Kotlin classes that inherit Java classes: if you override "equals" in such
// class without this hack, you'll be warned that in the superclass the name is "p0" (regardless of the fact that it's // class without this hack, you'll be warned that in the superclass the name is "p0" (regardless of the fact that it's
// "other" in Any) // "other" in Any)
// TODO: fix Java parameter name loading logic somehow (don't always load "p0", "p1", etc.) // TODO: fix Java parameter name loading logic somehow (don't always load "p0", "p1", etc.)
Name.identifier("other") Name.identifier("other")
} } else if (parameterName != null && parameterName.isNotEmpty() && usedNames.add(parameterName)) {
else if (parameterName != null && parameterName.isNotEmpty() && usedNames.add(parameterName)) {
Name.identifier(parameterName) Name.identifier(parameterName)
} } else {
else {
// TODO: parameter names may be drawn from attached sources, which is slow; it's better to make them lazy // TODO: parameter names may be drawn from attached sources, which is slow; it's better to make them lazy
val javaName = javaParameter.name val javaName = javaParameter.name
if (javaName == null) synthesizedNames = true if (javaName == null) synthesizedNames = true
@@ -213,17 +208,17 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
} }
ValueParameterDescriptorImpl( ValueParameterDescriptorImpl(
function, function,
null, null,
index, index,
annotations, annotations,
name, name,
outType, outType,
/* declaresDefaultValue = */ false, /* declaresDefaultValue = */ false,
/* isCrossinline = */ false, /* isCrossinline = */ false,
/* isNoinline = */ false, /* isNoinline = */ false,
varargElementType, varargElementType,
c.components.sourceElementFactory.source(javaParameter) c.components.sourceElementFactory.source(javaParameter)
) )
}.toList() }.toList()
return ResolvedValueParameters(descriptors, synthesizedNames) return ResolvedValueParameters(descriptors, synthesizedNames)
@@ -252,8 +247,7 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
protected abstract fun computePropertyNames(kindFilter: DescriptorKindFilter, nameFilter: ((Name) -> Boolean)?): Set<Name> protected abstract fun computePropertyNames(kindFilter: DescriptorKindFilter, nameFilter: ((Name) -> Boolean)?): Set<Name>
private val properties = c.storageManager.createMemoizedFunction { private val properties = c.storageManager.createMemoizedFunction { name: Name ->
name: Name ->
val properties = ArrayList<PropertyDescriptor>() val properties = ArrayList<PropertyDescriptor>()
val field = declaredMemberIndex().findFieldByName(name) val field = declaredMemberIndex().findFieldByName(name)
@@ -280,9 +274,10 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
if (DescriptorUtils.shouldRecordInitializerForProperty(propertyDescriptor, propertyDescriptor.type)) { if (DescriptorUtils.shouldRecordInitializerForProperty(propertyDescriptor, propertyDescriptor.type)) {
propertyDescriptor.setCompileTimeInitializer( propertyDescriptor.setCompileTimeInitializer(
c.storageManager.createNullableLazyValue { c.storageManager.createNullableLazyValue {
c.components.javaPropertyInitializerEvaluator.getInitializerConstant(field, propertyDescriptor) c.components.javaPropertyInitializerEvaluator.getInitializerConstant(field, propertyDescriptor)
}) }
)
} }
c.components.javaResolverCache.recordField(field, propertyDescriptor) c.components.javaResolverCache.recordField(field, propertyDescriptor)
@@ -295,8 +290,8 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
val annotations = c.resolveAnnotations(field) val annotations = c.resolveAnnotations(field)
return JavaPropertyDescriptor.create( return JavaPropertyDescriptor.create(
ownerDescriptor, annotations, Modality.FINAL, field.visibility, isVar, field.name, ownerDescriptor, annotations, Modality.FINAL, field.visibility, isVar, field.name,
c.components.sourceElementFactory.source(field), /* isConst = */ field.isFinalStatic c.components.sourceElementFactory.source(field), /* isConst = */ field.isFinalStatic
) )
} }
@@ -306,13 +301,10 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
private fun getPropertyType(field: JavaField): KotlinType { private fun getPropertyType(field: JavaField): KotlinType {
// Fields do not have their own generic parameters. // Fields do not have their own generic parameters.
// Simple static constants should not have flexible types. // Simple static constants should not have flexible types.
val propertyType = c.typeResolver.transformJavaType( val propertyType = c.typeResolver.transformJavaType(field.type, TypeUsage.COMMON.toAttributes())
field.type,
TypeUsage.COMMON.toAttributes()
)
val isNotNullable = val isNotNullable =
(KotlinBuiltIns.isPrimitiveType(propertyType) || KotlinBuiltIns.isString(propertyType)) && (KotlinBuiltIns.isPrimitiveType(propertyType) || KotlinBuiltIns.isString(propertyType)) &&
field.isFinalStatic && field.hasConstantNotNullInitializer field.isFinalStatic && field.hasConstantNotNullInitializer
if (isNotNullable) { if (isNotNullable) {
return TypeUtils.makeNotNullable(propertyType) return TypeUtils.makeNotNullable(propertyType)
} }
@@ -328,9 +320,9 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = allDescriptors() override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = allDescriptors()
protected fun computeDescriptors( protected fun computeDescriptors(
kindFilter: DescriptorKindFilter, kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean, nameFilter: (Name) -> Boolean,
location: LookupLocation location: LookupLocation
): List<DeclarationDescriptor> { ): List<DeclarationDescriptor> {
val result = LinkedHashSet<DeclarationDescriptor>() val result = LinkedHashSet<DeclarationDescriptor>()
@@ -35,9 +35,9 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.DFS
class LazyJavaStaticClassScope( class LazyJavaStaticClassScope(
c: LazyJavaResolverContext, c: LazyJavaResolverContext,
private val jClass: JavaClass, private val jClass: JavaClass,
override val ownerDescriptor: LazyJavaClassDescriptor override val ownerDescriptor: LazyJavaClassDescriptor
) : LazyJavaStaticScope(c) { ) : LazyJavaStaticScope(c) {
override fun computeMemberIndex() = ClassDeclaredMemberIndex(jClass) { it.isStatic } override fun computeMemberIndex() = ClassDeclaredMemberIndex(jClass) { it.isStatic }
@@ -80,11 +80,10 @@ class LazyJavaStaticClassScope(
} }
if (result.isNotEmpty()) { if (result.isNotEmpty()) {
result.addAll(resolveOverridesForStaticMembers( result.addAll(
name, propertiesFromSupertypes, result, ownerDescriptor, c.components.errorReporter resolveOverridesForStaticMembers(name, propertiesFromSupertypes, result, ownerDescriptor, c.components.errorReporter)
)) )
} } else {
else {
result.addAll(propertiesFromSupertypes.groupBy { result.addAll(propertiesFromSupertypes.groupBy {
it.realOriginal it.realOriginal
}.flatMap { }.flatMap {
@@ -99,14 +98,14 @@ class LazyJavaStaticClassScope(
} }
private fun <R> flatMapJavaStaticSupertypesScopes( private fun <R> flatMapJavaStaticSupertypesScopes(
root: ClassDescriptor, root: ClassDescriptor,
result: MutableSet<R>, result: MutableSet<R>,
onJavaStaticScope: (MemberScope) -> Collection<R> onJavaStaticScope: (MemberScope) -> Collection<R>
): Set<R> { ): Set<R> {
DFS.dfs(listOf(root), DFS.dfs(listOf(root),
{ {
it.typeConstructor.supertypes.asSequence().mapNotNull { it.typeConstructor.supertypes.asSequence().mapNotNull { supertype ->
supertype -> supertype.constructor.declarationDescriptor as? ClassDescriptor supertype.constructor.declarationDescriptor as? ClassDescriptor
}.asIterable() }.asIterable()
}, },
object : DFS.AbstractNodeHandler<ClassDescriptor, Unit>() { object : DFS.AbstractNodeHandler<ClassDescriptor, Unit>() {
@@ -28,9 +28,10 @@ abstract class LazyJavaStaticScope(c: LazyJavaResolverContext) : LazyJavaScope(c
override fun getDispatchReceiverParameter() = null override fun getDispatchReceiverParameter() = null
override fun resolveMethodSignature( override fun resolveMethodSignature(
method: JavaMethod, methodTypeParameters: List<TypeParameterDescriptor>, returnType: KotlinType, method: JavaMethod, methodTypeParameters: List<TypeParameterDescriptor>, returnType: KotlinType,
valueParameters: List<ValueParameterDescriptor> valueParameters: List<ValueParameterDescriptor>
) = LazyJavaScope.MethodSignatureData(returnType, null, valueParameters, methodTypeParameters, false, emptyList()) ): MethodSignatureData =
LazyJavaScope.MethodSignatureData(returnType, null, valueParameters, methodTypeParameters, false, emptyList())
override fun computeNonDeclaredProperties(name: Name, result: MutableCollection<PropertyDescriptor>) { override fun computeNonDeclaredProperties(name: Name, result: MutableCollection<PropertyDescriptor>) {
//no undeclared properties //no undeclared properties
@@ -29,28 +29,30 @@ import org.jetbrains.kotlin.types.KotlinTypeFactory
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
class LazyJavaTypeParameterDescriptor( class LazyJavaTypeParameterDescriptor(
private val c: LazyJavaResolverContext, private val c: LazyJavaResolverContext,
val javaTypeParameter: JavaTypeParameter, val javaTypeParameter: JavaTypeParameter,
index: Int, index: Int,
containingDeclaration: DeclarationDescriptor containingDeclaration: DeclarationDescriptor
) : AbstractLazyTypeParameterDescriptor( ) : AbstractLazyTypeParameterDescriptor(
c.storageManager, c.storageManager,
containingDeclaration, containingDeclaration,
javaTypeParameter.name, javaTypeParameter.name,
Variance.INVARIANT, Variance.INVARIANT,
/* isReified = */ false, /* isReified = */ false,
index, index,
SourceElement.NO_SOURCE, c.components.supertypeLoopChecker SourceElement.NO_SOURCE, c.components.supertypeLoopChecker
) { ) {
override val annotations = LazyJavaAnnotations(c, javaTypeParameter) override val annotations = LazyJavaAnnotations(c, javaTypeParameter)
override fun resolveUpperBounds(): List<KotlinType> { override fun resolveUpperBounds(): List<KotlinType> {
val bounds = javaTypeParameter.upperBounds val bounds = javaTypeParameter.upperBounds
if (bounds.isEmpty()) { if (bounds.isEmpty()) {
return listOf(KotlinTypeFactory.flexibleType( return listOf(
KotlinTypeFactory.flexibleType(
c.module.builtIns.anyType, c.module.builtIns.anyType,
c.module.builtIns.nullableAnyType c.module.builtIns.nullableAnyType
)) )
)
} }
return bounds.map { return bounds.map {
c.typeResolver.transformJavaType(it, TypeUsage.COMMON.toAttributes(upperBoundForTypeParameter = this)) c.typeResolver.transformJavaType(it, TypeUsage.COMMON.toAttributes(upperBoundForTypeParameter = this))
@@ -32,15 +32,14 @@ interface TypeParameterResolver {
} }
class LazyJavaTypeParameterResolver( class LazyJavaTypeParameterResolver(
private val c: LazyJavaResolverContext, private val c: LazyJavaResolverContext,
private val containingDeclaration: DeclarationDescriptor, private val containingDeclaration: DeclarationDescriptor,
typeParameterOwner: JavaTypeParameterListOwner, typeParameterOwner: JavaTypeParameterListOwner,
private val typeParametersIndexOffset: Int private val typeParametersIndexOffset: Int
) : TypeParameterResolver { ) : TypeParameterResolver {
private val typeParameters: Map<JavaTypeParameter, Int> = typeParameterOwner.typeParameters.mapToIndex() private val typeParameters: Map<JavaTypeParameter, Int> = typeParameterOwner.typeParameters.mapToIndex()
private val resolve = c.storageManager.createMemoizedFunctionWithNullableValues { private val resolve = c.storageManager.createMemoizedFunctionWithNullableValues { typeParameter: JavaTypeParameter ->
typeParameter: JavaTypeParameter ->
typeParameters[typeParameter]?.let { index -> typeParameters[typeParameter]?.let { index ->
LazyJavaTypeParameterDescriptor(c.child(this), typeParameter, typeParametersIndexOffset + index, containingDeclaration) LazyJavaTypeParameterDescriptor(c.child(this), typeParameter, typeParametersIndexOffset + index, containingDeclaration)
} }
@@ -38,8 +38,8 @@ import org.jetbrains.kotlin.utils.sure
private val JAVA_LANG_CLASS_FQ_NAME: FqName = FqName("java.lang.Class") private val JAVA_LANG_CLASS_FQ_NAME: FqName = FqName("java.lang.Class")
class JavaTypeResolver( class JavaTypeResolver(
private val c: LazyJavaResolverContext, private val c: LazyJavaResolverContext,
private val typeParameterResolver: TypeParameterResolver private val typeParameterResolver: TypeParameterResolver
) { ) {
fun transformJavaType(javaType: JavaType?, attr: JavaTypeAttributes): KotlinType { fun transformJavaType(javaType: JavaType?, attr: JavaTypeAttributes): KotlinType {
@@ -68,8 +68,10 @@ class JavaTypeResolver(
else KotlinTypeFactory.flexibleType(jetType, jetType.makeNullableAsSpecified(true)) else KotlinTypeFactory.flexibleType(jetType, jetType.makeNullableAsSpecified(true))
} }
val componentType = transformJavaType(javaComponentType, val componentType = transformJavaType(
COMMON.toAttributes(attr.isForAnnotationParameter)) javaComponentType,
COMMON.toAttributes(attr.isForAnnotationParameter)
)
if (attr.isForAnnotationParameter) { if (attr.isForAnnotationParameter) {
val projectionKind = if (isVararg) OUT_VARIANCE else INVARIANT val projectionKind = if (isVararg) OUT_VARIANCE else INVARIANT
@@ -77,8 +79,8 @@ class JavaTypeResolver(
} }
return KotlinTypeFactory.flexibleType( return KotlinTypeFactory.flexibleType(
c.module.builtIns.getArrayType(INVARIANT, componentType), c.module.builtIns.getArrayType(INVARIANT, componentType),
c.module.builtIns.getArrayType(OUT_VARIANCE, componentType).makeNullableAsSpecified(true) c.module.builtIns.getArrayType(OUT_VARIANCE, componentType).makeNullableAsSpecified(true)
) )
} }
@@ -92,26 +94,26 @@ class JavaTypeResolver(
} }
val lower = val lower =
computeSimpleJavaClassifierType(javaType, attr.withFlexibility(FLEXIBLE_LOWER_BOUND), lowerResult = null) computeSimpleJavaClassifierType(javaType, attr.withFlexibility(FLEXIBLE_LOWER_BOUND), lowerResult = null)
?: return errorType() ?: return errorType()
val upper = val upper =
computeSimpleJavaClassifierType(javaType, attr.withFlexibility(FLEXIBLE_UPPER_BOUND), lowerResult = lower) computeSimpleJavaClassifierType(javaType, attr.withFlexibility(FLEXIBLE_UPPER_BOUND), lowerResult = lower)
?: return errorType() ?: return errorType()
return if (isRaw) { return if (isRaw) {
RawTypeImpl(lower, upper) RawTypeImpl(lower, upper)
} } else {
else {
KotlinTypeFactory.flexibleType(lower, upper) KotlinTypeFactory.flexibleType(lower, upper)
} }
} }
private fun computeSimpleJavaClassifierType( private fun computeSimpleJavaClassifierType(
javaType: JavaClassifierType, attr: JavaTypeAttributes, javaType: JavaClassifierType,
lowerResult: SimpleType? attr: JavaTypeAttributes,
lowerResult: SimpleType?
): SimpleType? { ): SimpleType? {
val annotations = val annotations =
lowerResult?.annotations ?: LazyJavaAnnotations(c, javaType) lowerResult?.annotations ?: LazyJavaAnnotations(c, javaType)
val constructor = computeTypeConstructor(javaType, attr) ?: return null val constructor = computeTypeConstructor(javaType, attr) ?: return null
val isNullable = attr.isNullable() val isNullable = attr.isNullable()
@@ -161,7 +163,8 @@ class JavaTypeResolver(
if (javaToKotlin.isReadOnly(kotlinDescriptor)) { if (javaToKotlin.isReadOnly(kotlinDescriptor)) {
if (attr.flexibility == FLEXIBLE_LOWER_BOUND || if (attr.flexibility == FLEXIBLE_LOWER_BOUND ||
attr.howThisTypeIsUsed == SUPERTYPE || attr.howThisTypeIsUsed == SUPERTYPE ||
javaType.argumentsMakeSenseOnlyForMutableContainer(readOnlyContainer = kotlinDescriptor)) { javaType.argumentsMakeSenseOnlyForMutableContainer(readOnlyContainer = kotlinDescriptor)
) {
return javaToKotlin.convertReadOnlyToMutable(kotlinDescriptor) return javaToKotlin.convertReadOnlyToMutable(kotlinDescriptor)
} }
} }
@@ -174,34 +177,33 @@ class JavaTypeResolver(
// Same for Map<K, in V> // Same for Map<K, in V>
// But both Iterable<in A>, MutableIterable<in A> don't make sense as they are covariant, so return false // But both Iterable<in A>, MutableIterable<in A> don't make sense as they are covariant, so return false
private fun JavaClassifierType.argumentsMakeSenseOnlyForMutableContainer( private fun JavaClassifierType.argumentsMakeSenseOnlyForMutableContainer(
readOnlyContainer: ClassDescriptor readOnlyContainer: ClassDescriptor
): Boolean { ): Boolean {
fun JavaType?.isSuperWildcard(): Boolean = (this as? JavaWildcardType)?.let { it.bound != null && !it.isExtends } ?: false fun JavaType?.isSuperWildcard(): Boolean = (this as? JavaWildcardType)?.let { it.bound != null && !it.isExtends } ?: false
if (!typeArguments.lastOrNull().isSuperWildcard()) return false if (!typeArguments.lastOrNull().isSuperWildcard()) return false
val mutableLastParameterVariance = JavaToKotlinClassMap.convertReadOnlyToMutable(readOnlyContainer) val mutableLastParameterVariance = JavaToKotlinClassMap.convertReadOnlyToMutable(readOnlyContainer)
.typeConstructor.parameters.lastOrNull()?.variance ?: return false .typeConstructor.parameters.lastOrNull()?.variance ?: return false
return mutableLastParameterVariance != OUT_VARIANCE return mutableLastParameterVariance != OUT_VARIANCE
} }
private fun computeArguments( private fun computeArguments(
javaType: JavaClassifierType, javaType: JavaClassifierType,
attr: JavaTypeAttributes, attr: JavaTypeAttributes,
constructor: TypeConstructor constructor: TypeConstructor
): List<TypeProjection> { ): List<TypeProjection> {
val isRaw = javaType.isRaw val isRaw = javaType.isRaw
val eraseTypeParameters = val eraseTypeParameters =
isRaw || isRaw ||
// This option is needed because sometimes we get weird versions of JDK classes in the class path, // This option is needed because sometimes we get weird versions of JDK classes in the class path,
// such as collections with no generics, so the Java types are not raw, formally, but they don't match with // such as collections with no generics, so the Java types are not raw, formally, but they don't match with
// their Kotlin analogs, so we treat them as raw to avoid exceptions // their Kotlin analogs, so we treat them as raw to avoid exceptions
(javaType.typeArguments.isEmpty() && !constructor.parameters.isEmpty()) (javaType.typeArguments.isEmpty() && !constructor.parameters.isEmpty())
val typeParameters = constructor.parameters val typeParameters = constructor.parameters
if (eraseTypeParameters) { if (eraseTypeParameters) {
return typeParameters.map { return typeParameters.map { parameter ->
parameter ->
// Some activity for preventing recursion in cases like `class A<T extends A, F extends T>` // Some activity for preventing recursion in cases like `class A<T extends A, F extends T>`
// //
// When calculating upper bound of some parameter (attr.upperBoundOfTypeParameter), // When calculating upper bound of some parameter (attr.upperBoundOfTypeParameter),
@@ -215,17 +217,17 @@ class JavaTypeResolver(
// so we get A<*, *>. // so we get A<*, *>.
// Summary result for upper bound of T is `A<A<*, *>, A<*, *>>..A<out A<*, *>, out A<*, *>>` // Summary result for upper bound of T is `A<A<*, *>, A<*, *>>..A<out A<*, *>, out A<*, *>>`
val erasedUpperBound = val erasedUpperBound =
LazyWrappedType(c.storageManager) { LazyWrappedType(c.storageManager) {
parameter.getErasedUpperBound(attr.upperBoundOfTypeParameter) { parameter.getErasedUpperBound(attr.upperBoundOfTypeParameter) {
constructor.declarationDescriptor!!.defaultType.replaceArgumentsWithStarProjections() constructor.declarationDescriptor!!.defaultType.replaceArgumentsWithStarProjections()
}
} }
}
RawSubstitution.computeProjection( RawSubstitution.computeProjection(
parameter, parameter,
// if erasure happens due to invalid arguments number, use star projections instead // if erasure happens due to invalid arguments number, use star projections instead
if (isRaw) attr else attr.withFlexibility(INFLEXIBLE), if (isRaw) attr else attr.withFlexibility(INFLEXIBLE),
erasedUpperBound erasedUpperBound
) )
}.toList() }.toList()
} }
@@ -234,8 +236,7 @@ class JavaTypeResolver(
// Most of the time this means there is an error in the Java code // Most of the time this means there is an error in the Java code
return typeParameters.map { p -> TypeProjectionImpl(ErrorUtils.createErrorType(p.name.asString())) }.toList() return typeParameters.map { p -> TypeProjectionImpl(ErrorUtils.createErrorType(p.name.asString())) }.toList()
} }
return javaType.typeArguments.withIndex().map { return javaType.typeArguments.withIndex().map { indexedArgument ->
indexedArgument ->
val (i, javaTypeArgument) = indexedArgument val (i, javaTypeArgument) = indexedArgument
assert(i < typeParameters.size) { assert(i < typeParameters.size) {
@@ -248,9 +249,9 @@ class JavaTypeResolver(
} }
private fun transformToTypeProjection( private fun transformToTypeProjection(
javaType: JavaType?, javaType: JavaType?,
attr: JavaTypeAttributes, attr: JavaTypeAttributes,
typeParameter: TypeParameterDescriptor typeParameter: TypeParameterDescriptor
): TypeProjection { ): TypeProjection {
return when (javaType) { return when (javaType) {
is JavaWildcardType -> { is JavaWildcardType -> {
@@ -260,9 +261,9 @@ class JavaTypeResolver(
makeStarProjection(typeParameter, attr) makeStarProjection(typeParameter, attr)
else { else {
createProjection( createProjection(
type = transformJavaType(bound, COMMON.toAttributes()), type = transformJavaType(bound, COMMON.toAttributes()),
projectionKind = projectionKind, projectionKind = projectionKind,
typeParameterDescriptor = typeParameter typeParameterDescriptor = typeParameter
) )
} }
} }
@@ -284,8 +285,8 @@ class JavaTypeResolver(
} }
internal fun makeStarProjection( internal fun makeStarProjection(
typeParameter: TypeParameterDescriptor, typeParameter: TypeParameterDescriptor,
attr: JavaTypeAttributes attr: JavaTypeAttributes
): TypeProjection { ): TypeProjection {
return if (attr.howThisTypeIsUsed == SUPERTYPE) return if (attr.howThisTypeIsUsed == SUPERTYPE)
TypeProjectionImpl(typeParameter.starProjectionType()) TypeProjectionImpl(typeParameter.starProjectionType())
@@ -294,11 +295,11 @@ internal fun makeStarProjection(
} }
data class JavaTypeAttributes( data class JavaTypeAttributes(
val howThisTypeIsUsed: TypeUsage, val howThisTypeIsUsed: TypeUsage,
val flexibility: JavaTypeFlexibility = INFLEXIBLE, val flexibility: JavaTypeFlexibility = INFLEXIBLE,
val isForAnnotationParameter: Boolean = false, val isForAnnotationParameter: Boolean = false,
// Current type is upper bound of this type parameter // Current type is upper bound of this type parameter
val upperBoundOfTypeParameter: TypeParameterDescriptor? = null val upperBoundOfTypeParameter: TypeParameterDescriptor? = null
) { ) {
fun withFlexibility(flexibility: JavaTypeFlexibility) = copy(flexibility = flexibility) fun withFlexibility(flexibility: JavaTypeFlexibility) = copy(flexibility = flexibility)
} }
@@ -310,12 +311,12 @@ enum class JavaTypeFlexibility {
} }
fun TypeUsage.toAttributes( fun TypeUsage.toAttributes(
isForAnnotationParameter: Boolean = false, isForAnnotationParameter: Boolean = false,
upperBoundForTypeParameter: TypeParameterDescriptor? = null upperBoundForTypeParameter: TypeParameterDescriptor? = null
) = JavaTypeAttributes( ) = JavaTypeAttributes(
this, this,
isForAnnotationParameter = isForAnnotationParameter, isForAnnotationParameter = isForAnnotationParameter,
upperBoundOfTypeParameter = upperBoundForTypeParameter upperBoundOfTypeParameter = upperBoundForTypeParameter
) )
// Definition: // Definition:
@@ -323,11 +324,11 @@ fun TypeUsage.toAttributes(
// ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments // ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments
// ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F // ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F
internal fun TypeParameterDescriptor.getErasedUpperBound( internal fun TypeParameterDescriptor.getErasedUpperBound(
// Calculation of `potentiallyRecursiveTypeParameter.upperBounds` may recursively depend on `this.getErasedUpperBound` // Calculation of `potentiallyRecursiveTypeParameter.upperBounds` may recursively depend on `this.getErasedUpperBound`
// E.g. `class A<T extends A, F extends A>` // E.g. `class A<T extends A, F extends A>`
// To prevent recursive calls return defaultValue() instead // To prevent recursive calls return defaultValue() instead
potentiallyRecursiveTypeParameter: TypeParameterDescriptor? = null, potentiallyRecursiveTypeParameter: TypeParameterDescriptor? = null,
defaultValue: (() -> KotlinType) = { ErrorUtils.createErrorType("Can't compute erased upper bound of type parameter `$this`") } defaultValue: (() -> KotlinType) = { ErrorUtils.createErrorType("Can't compute erased upper bound of type parameter `$this`") }
): KotlinType { ): KotlinType {
if (this === potentiallyRecursiveTypeParameter) return defaultValue() if (this === potentiallyRecursiveTypeParameter) return defaultValue()
@@ -31,7 +31,7 @@ import org.jetbrains.kotlin.types.typeUtil.builtIns
class RawTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : FlexibleType(lowerBound, upperBound), RawType { class RawTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : FlexibleType(lowerBound, upperBound), RawType {
init { init {
assert (KotlinTypeChecker.DEFAULT.isSubtypeOf(lowerBound, upperBound)) { assert(KotlinTypeChecker.DEFAULT.isSubtypeOf(lowerBound, upperBound)) {
"Lower bound $lowerBound of a flexible type must be a subtype of the upper bound $upperBound" "Lower bound $lowerBound of a flexible type must be a subtype of the upper bound $upperBound"
} }
} }
@@ -41,15 +41,15 @@ class RawTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : FlexibleType
override val memberScope: MemberScope override val memberScope: MemberScope
get() { get() {
val classDescriptor = constructor.declarationDescriptor as? ClassDescriptor val classDescriptor = constructor.declarationDescriptor as? ClassDescriptor
?: error("Incorrect classifier: ${constructor.declarationDescriptor}") ?: error("Incorrect classifier: ${constructor.declarationDescriptor}")
return classDescriptor.getMemberScope(RawSubstitution) return classDescriptor.getMemberScope(RawSubstitution)
} }
override fun replaceAnnotations(newAnnotations: Annotations) override fun replaceAnnotations(newAnnotations: Annotations) =
= RawTypeImpl(lowerBound.replaceAnnotations(newAnnotations), upperBound.replaceAnnotations(newAnnotations)) RawTypeImpl(lowerBound.replaceAnnotations(newAnnotations), upperBound.replaceAnnotations(newAnnotations))
override fun makeNullableAsSpecified(newNullability: Boolean) override fun makeNullableAsSpecified(newNullability: Boolean) =
= RawTypeImpl(lowerBound.makeNullableAsSpecified(newNullability), upperBound.makeNullableAsSpecified(newNullability)) RawTypeImpl(lowerBound.makeNullableAsSpecified(newNullability), upperBound.makeNullableAsSpecified(newNullability))
override fun render(renderer: DescriptorRenderer, options: DescriptorRendererOptions): String { override fun render(renderer: DescriptorRenderer, options: DescriptorRendererOptions): String {
fun onlyOutDiffers(first: String, second: String) = first == second.removePrefix("out ") || second == "*" fun onlyOutDiffers(first: String, second: String) = first == second.removePrefix("out ") || second == "*"
@@ -73,9 +73,9 @@ class RawTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : FlexibleType
val upperArgs = renderArguments(upperBound) val upperArgs = renderArguments(upperBound)
val newArgs = lowerArgs.joinToString(", ") { "(raw) $it" } val newArgs = lowerArgs.joinToString(", ") { "(raw) $it" }
val newUpper = val newUpper =
if (lowerArgs.zip(upperArgs).all { onlyOutDiffers(it.first, it.second) }) if (lowerArgs.zip(upperArgs).all { onlyOutDiffers(it.first, it.second) })
upperRendered.replaceArgs(newArgs) upperRendered.replaceArgs(newArgs)
else upperRendered else upperRendered
val newLower = lowerRendered.replaceArgs(newArgs) val newLower = lowerRendered.replaceArgs(newArgs)
if (newLower == newUpper) return newLower if (newLower == newUpper) return newLower
return renderer.renderFlexibleType(newLower, newUpper, builtIns) return renderer.renderFlexibleType(newLower, newUpper, builtIns)
@@ -98,8 +98,7 @@ internal object RawSubstitution : TypeSubstitution() {
if (isRawL || isRawU) { if (isRawL || isRawU) {
RawTypeImpl(lower, upper) RawTypeImpl(lower, upper)
} } else {
else {
KotlinTypeFactory.flexibleType(lower, upper) KotlinTypeFactory.flexibleType(lower, upper)
} }
} }
@@ -109,46 +108,45 @@ internal object RawSubstitution : TypeSubstitution() {
// false means that type cannot be raw // false means that type cannot be raw
private fun eraseInflexibleBasedOnClassDescriptor( private fun eraseInflexibleBasedOnClassDescriptor(
type: SimpleType, declaration: ClassDescriptor, attr: JavaTypeAttributes type: SimpleType, declaration: ClassDescriptor, attr: JavaTypeAttributes
): Pair<SimpleType, Boolean> { ): Pair<SimpleType, Boolean> {
if (type.constructor.parameters.isEmpty()) return type to false if (type.constructor.parameters.isEmpty()) return type to false
if (KotlinBuiltIns.isArray(type)) { if (KotlinBuiltIns.isArray(type)) {
val componentTypeProjection = type.arguments[0] val componentTypeProjection = type.arguments[0]
val arguments = listOf( val arguments = listOf(
TypeProjectionImpl(componentTypeProjection.projectionKind, eraseType(componentTypeProjection.type)) TypeProjectionImpl(componentTypeProjection.projectionKind, eraseType(componentTypeProjection.type))
) )
return KotlinTypeFactory.simpleType( return KotlinTypeFactory.simpleType(
type.annotations, type.constructor, arguments, type.isMarkedNullable type.annotations, type.constructor, arguments, type.isMarkedNullable
) to false ) to false
} }
if (type.isError) return ErrorUtils.createErrorType("Raw error type: ${type.constructor}") to false if (type.isError) return ErrorUtils.createErrorType("Raw error type: ${type.constructor}") to false
return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope( return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
type.annotations, type.constructor, type.annotations, type.constructor,
type.constructor.parameters.map { type.constructor.parameters.map { parameter ->
parameter -> computeProjection(parameter, attr)
computeProjection(parameter, attr) },
}, type.isMarkedNullable, declaration.getMemberScope(RawSubstitution)
type.isMarkedNullable, declaration.getMemberScope(RawSubstitution)
) to true ) to true
} }
fun computeProjection( fun computeProjection(
parameter: TypeParameterDescriptor, parameter: TypeParameterDescriptor,
attr: JavaTypeAttributes, attr: JavaTypeAttributes,
erasedUpperBound: KotlinType = parameter.getErasedUpperBound() erasedUpperBound: KotlinType = parameter.getErasedUpperBound()
) = when (attr.flexibility) { ) = when (attr.flexibility) {
// Raw(List<T>) => (List<Any?>..List<*>) // Raw(List<T>) => (List<Any?>..List<*>)
// Raw(Enum<T>) => (Enum<Enum<*>>..Enum<out Enum<*>>) // Raw(Enum<T>) => (Enum<Enum<*>>..Enum<out Enum<*>>)
// In the last case upper bound is equal to star projection `Enum<*>`, // In the last case upper bound is equal to star projection `Enum<*>`,
// but we want to keep matching tree structure of flexible bounds (at least they should have the same size) // but we want to keep matching tree structure of flexible bounds (at least they should have the same size)
JavaTypeFlexibility.FLEXIBLE_LOWER_BOUND -> TypeProjectionImpl( JavaTypeFlexibility.FLEXIBLE_LOWER_BOUND -> TypeProjectionImpl(
// T : String -> String // T : String -> String
// in T : String -> String // in T : String -> String
// T : Enum<T> -> Enum<*> // T : Enum<T> -> Enum<*>
Variance.INVARIANT, erasedUpperBound Variance.INVARIANT, erasedUpperBound
) )
JavaTypeFlexibility.FLEXIBLE_UPPER_BOUND, JavaTypeFlexibility.INFLEXIBLE -> { JavaTypeFlexibility.FLEXIBLE_UPPER_BOUND, JavaTypeFlexibility.INFLEXIBLE -> {
if (!parameter.variance.allowsOutPosition) if (!parameter.variance.allowsOutPosition)
@@ -21,17 +21,21 @@ import org.jetbrains.kotlin.util.capitalizeDecapitalize.decapitalizeSmart
import org.jetbrains.kotlin.load.java.BuiltinSpecialProperties.getPropertyNameCandidatesBySpecialGetterName import org.jetbrains.kotlin.load.java.BuiltinSpecialProperties.getPropertyNameCandidatesBySpecialGetterName
import org.jetbrains.kotlin.util.capitalizeDecapitalize.decapitalizeSmartForCompiler import org.jetbrains.kotlin.util.capitalizeDecapitalize.decapitalizeSmartForCompiler
fun propertyNameByGetMethodName(methodName: Name): Name? =
propertyNameFromAccessorMethodName(methodName, "get") ?: propertyNameFromAccessorMethodName(methodName, "is", removePrefix = false)
fun propertyNameByGetMethodName(methodName: Name): Name? fun propertyNameBySetMethodName(methodName: Name, withIsPrefix: Boolean): Name? =
= propertyNameFromAccessorMethodName(methodName, "get") ?: propertyNameFromAccessorMethodName(methodName, "is", removePrefix = false) propertyNameFromAccessorMethodName(methodName, "set", addPrefix = if (withIsPrefix) "is" else null)
fun propertyNameBySetMethodName(methodName: Name, withIsPrefix: Boolean): Name? fun propertyNamesBySetMethodName(methodName: Name) =
= propertyNameFromAccessorMethodName(methodName, "set", addPrefix = if (withIsPrefix) "is" else null) listOf(propertyNameBySetMethodName(methodName, false), propertyNameBySetMethodName(methodName, true)).filterNotNull()
fun propertyNamesBySetMethodName(methodName: Name) private fun propertyNameFromAccessorMethodName(
= listOf(propertyNameBySetMethodName(methodName, false), propertyNameBySetMethodName(methodName, true)).filterNotNull() methodName: Name,
prefix: String,
private fun propertyNameFromAccessorMethodName(methodName: Name, prefix: String, removePrefix: Boolean = true, addPrefix: String? = null): Name? { removePrefix: Boolean = true,
addPrefix: String? = null
): Name? {
if (methodName.isSpecial) return null if (methodName.isSpecial) return null
val identifier = methodName.identifier val identifier = methodName.identifier
if (!identifier.startsWith(prefix)) return null if (!identifier.startsWith(prefix)) return null
@@ -61,4 +65,4 @@ fun getPropertyNamesCandidatesByAccessorName(name: Name): List<Name> {
} }
return getPropertyNameCandidatesBySpecialGetterName(name) return getPropertyNameCandidatesBySpecialGetterName(name)
} }
@@ -23,6 +23,6 @@ interface JavaSourceElementFactory {
fun source(javaElement: JavaElement): JavaSourceElement fun source(javaElement: JavaElement): JavaSourceElement
} }
interface JavaSourceElement: SourceElement { interface JavaSourceElement : SourceElement {
val javaElement: JavaElement val javaElement: JavaElement
} }
@@ -15,6 +15,7 @@
*/ */
@file:JvmName("SpecialBuiltinMembers") @file:JvmName("SpecialBuiltinMembers")
package org.jetbrains.kotlin.load.java package org.jetbrains.kotlin.load.java
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
@@ -45,26 +46,27 @@ private fun FqNameUnsafe.childSafe(name: String): FqName = child(Name.identifier
private data class NameAndSignature(val name: Name, val signature: String) private data class NameAndSignature(val name: Name, val signature: String)
private fun String.method(name: String, parameters: String, returnType: String) = private fun String.method(name: String, parameters: String, returnType: String) =
NameAndSignature( NameAndSignature(
Name.identifier(name), Name.identifier(name),
SignatureBuildingComponents.signature(this@method, "$name($parameters)$returnType")) SignatureBuildingComponents.signature(this@method, "$name($parameters)$returnType")
)
object BuiltinSpecialProperties { object BuiltinSpecialProperties {
val PROPERTY_FQ_NAME_TO_JVM_GETTER_NAME_MAP = mapOf( val PROPERTY_FQ_NAME_TO_JVM_GETTER_NAME_MAP = mapOf(
BUILTIN_NAMES._enum.childSafe("name") to Name.identifier("name"), BUILTIN_NAMES._enum.childSafe("name") to Name.identifier("name"),
BUILTIN_NAMES._enum.childSafe("ordinal") to Name.identifier("ordinal"), BUILTIN_NAMES._enum.childSafe("ordinal") to Name.identifier("ordinal"),
BUILTIN_NAMES.collection.child("size") to Name.identifier("size"), BUILTIN_NAMES.collection.child("size") to Name.identifier("size"),
BUILTIN_NAMES.map.child("size") to Name.identifier("size"), BUILTIN_NAMES.map.child("size") to Name.identifier("size"),
BUILTIN_NAMES.charSequence.childSafe("length") to Name.identifier("length"), BUILTIN_NAMES.charSequence.childSafe("length") to Name.identifier("length"),
BUILTIN_NAMES.map.child("keys") to Name.identifier("keySet"), BUILTIN_NAMES.map.child("keys") to Name.identifier("keySet"),
BUILTIN_NAMES.map.child("values") to Name.identifier("values"), BUILTIN_NAMES.map.child("values") to Name.identifier("values"),
BUILTIN_NAMES.map.child("entries") to Name.identifier("entrySet") BUILTIN_NAMES.map.child("entries") to Name.identifier("entrySet")
) )
private val GETTER_JVM_NAME_TO_PROPERTIES_SHORT_NAME_MAP: Map<Name, List<Name>> = private val GETTER_JVM_NAME_TO_PROPERTIES_SHORT_NAME_MAP: Map<Name, List<Name>> =
PROPERTY_FQ_NAME_TO_JVM_GETTER_NAME_MAP.entries PROPERTY_FQ_NAME_TO_JVM_GETTER_NAME_MAP.entries
.map { Pair(it.key.shortName(), it.value) } .map { Pair(it.key.shortName(), it.value) }
.groupBy({ it.second }, { it.first }) .groupBy({ it.second }, { it.first })
private val SPECIAL_FQ_NAMES = PROPERTY_FQ_NAME_TO_JVM_GETTER_NAME_MAP.keys private val SPECIAL_FQ_NAMES = PROPERTY_FQ_NAME_TO_JVM_GETTER_NAME_MAP.keys
internal val SPECIAL_SHORT_NAMES = SPECIAL_FQ_NAMES.map(FqName::shortName).toSet() internal val SPECIAL_SHORT_NAMES = SPECIAL_FQ_NAMES.map(FqName::shortName).toSet()
@@ -83,7 +85,7 @@ object BuiltinSpecialProperties {
} }
fun getPropertyNameCandidatesBySpecialGetterName(name1: Name): List<Name> = fun getPropertyNameCandidatesBySpecialGetterName(name1: Name): List<Name> =
GETTER_JVM_NAME_TO_PROPERTIES_SHORT_NAME_MAP[name1] ?: emptyList() GETTER_JVM_NAME_TO_PROPERTIES_SHORT_NAME_MAP[name1] ?: emptyList()
fun CallableMemberDescriptor.getBuiltinSpecialPropertyGetterName(): String? { fun CallableMemberDescriptor.getBuiltinSpecialPropertyGetterName(): String? {
assert(KotlinBuiltIns.isBuiltIn(this)) { "This method is defined only for builtin members, but $this found" } assert(KotlinBuiltIns.isBuiltIn(this)) { "This method is defined only for builtin members, but $this found" }
@@ -95,7 +97,7 @@ object BuiltinSpecialProperties {
object BuiltinMethodsWithSpecialGenericSignature { object BuiltinMethodsWithSpecialGenericSignature {
private val ERASED_COLLECTION_PARAMETER_NAME_AND_SIGNATURES = setOf( private val ERASED_COLLECTION_PARAMETER_NAME_AND_SIGNATURES = setOf(
"containsAll", "removeAll", "retainAll" "containsAll", "removeAll", "retainAll"
).map { "java/util/Collection".method(it, "Ljava/util/Collection;", JvmPrimitiveType.BOOLEAN.desc) } ).map { "java/util/Collection".method(it, "Ljava/util/Collection;", JvmPrimitiveType.BOOLEAN.desc) }
private val ERASED_COLLECTION_PARAMETER_SIGNATURES = ERASED_COLLECTION_PARAMETER_NAME_AND_SIGNATURES.map { it.signature } private val ERASED_COLLECTION_PARAMETER_SIGNATURES = ERASED_COLLECTION_PARAMETER_NAME_AND_SIGNATURES.map { it.signature }
@@ -112,36 +114,40 @@ object BuiltinMethodsWithSpecialGenericSignature {
} }
private val GENERIC_PARAMETERS_METHODS_TO_DEFAULT_VALUES_MAP = private val GENERIC_PARAMETERS_METHODS_TO_DEFAULT_VALUES_MAP =
signatures { signatures {
mapOf( mapOf(
javaUtil("Collection") javaUtil("Collection")
.method("contains", "Ljava/lang/Object;", JvmPrimitiveType.BOOLEAN.desc) to TypeSafeBarrierDescription.FALSE, .method("contains", "Ljava/lang/Object;", JvmPrimitiveType.BOOLEAN.desc) to TypeSafeBarrierDescription.FALSE,
javaUtil("Collection") javaUtil("Collection")
.method("remove", "Ljava/lang/Object;", JvmPrimitiveType.BOOLEAN.desc) to TypeSafeBarrierDescription.FALSE, .method("remove", "Ljava/lang/Object;", JvmPrimitiveType.BOOLEAN.desc) to TypeSafeBarrierDescription.FALSE,
javaUtil("Map") javaUtil("Map")
.method("containsKey", "Ljava/lang/Object;", JvmPrimitiveType.BOOLEAN.desc) to TypeSafeBarrierDescription.FALSE, .method("containsKey", "Ljava/lang/Object;", JvmPrimitiveType.BOOLEAN.desc) to TypeSafeBarrierDescription.FALSE,
javaUtil("Map") javaUtil("Map")
.method("containsValue", "Ljava/lang/Object;", JvmPrimitiveType.BOOLEAN.desc) to TypeSafeBarrierDescription.FALSE, .method("containsValue", "Ljava/lang/Object;", JvmPrimitiveType.BOOLEAN.desc) to TypeSafeBarrierDescription.FALSE,
javaUtil("Map") javaUtil("Map")
.method("remove", "Ljava/lang/Object;Ljava/lang/Object;", .method(
JvmPrimitiveType.BOOLEAN.desc) to TypeSafeBarrierDescription.FALSE, "remove", "Ljava/lang/Object;Ljava/lang/Object;",
JvmPrimitiveType.BOOLEAN.desc
) to TypeSafeBarrierDescription.FALSE,
javaUtil("Map") javaUtil("Map")
.method("getOrDefault", "Ljava/lang/Object;Ljava/lang/Object;", .method(
"Ljava/lang/Object;") to TypeSafeBarrierDescription.MAP_GET_OR_DEFAULT, "getOrDefault", "Ljava/lang/Object;Ljava/lang/Object;",
"Ljava/lang/Object;"
) to TypeSafeBarrierDescription.MAP_GET_OR_DEFAULT,
javaUtil("Map") javaUtil("Map")
.method("get", "Ljava/lang/Object;", "Ljava/lang/Object;") to TypeSafeBarrierDescription.NULL, .method("get", "Ljava/lang/Object;", "Ljava/lang/Object;") to TypeSafeBarrierDescription.NULL,
javaUtil("Map") javaUtil("Map")
.method("remove", "Ljava/lang/Object;", "Ljava/lang/Object;") to TypeSafeBarrierDescription.NULL, .method("remove", "Ljava/lang/Object;", "Ljava/lang/Object;") to TypeSafeBarrierDescription.NULL,
javaUtil("List") javaUtil("List")
.method("indexOf", "Ljava/lang/Object;", JvmPrimitiveType.INT.desc) to TypeSafeBarrierDescription.INDEX, .method("indexOf", "Ljava/lang/Object;", JvmPrimitiveType.INT.desc) to TypeSafeBarrierDescription.INDEX,
javaUtil("List") javaUtil("List")
.method("lastIndexOf", "Ljava/lang/Object;", JvmPrimitiveType.INT.desc) to TypeSafeBarrierDescription.INDEX .method("lastIndexOf", "Ljava/lang/Object;", JvmPrimitiveType.INT.desc) to TypeSafeBarrierDescription.INDEX
) )
} }
private val SIGNATURE_TO_DEFAULT_VALUES_MAP = GENERIC_PARAMETERS_METHODS_TO_DEFAULT_VALUES_MAP.mapKeys { it.key.signature } private val SIGNATURE_TO_DEFAULT_VALUES_MAP = GENERIC_PARAMETERS_METHODS_TO_DEFAULT_VALUES_MAP.mapKeys { it.key.signature }
private val ERASED_VALUE_PARAMETERS_SHORT_NAMES: Set<Name> private val ERASED_VALUE_PARAMETERS_SHORT_NAMES: Set<Name>
@@ -158,7 +164,7 @@ object BuiltinMethodsWithSpecialGenericSignature {
@JvmStatic @JvmStatic
fun getOverriddenBuiltinFunctionWithErasedValueParametersInJava( fun getOverriddenBuiltinFunctionWithErasedValueParametersInJava(
functionDescriptor: FunctionDescriptor functionDescriptor: FunctionDescriptor
): FunctionDescriptor? { ): FunctionDescriptor? {
if (!functionDescriptor.name.sameAsBuiltinMethodWithErasedValueParameters) return null if (!functionDescriptor.name.sameAsBuiltinMethodWithErasedValueParameters) return null
return functionDescriptor.firstOverridden { it.hasErasedValueParametersInJava } as FunctionDescriptor? return functionDescriptor.firstOverridden { it.hasErasedValueParametersInJava } as FunctionDescriptor?
@@ -191,17 +197,17 @@ object BuiltinMethodsWithSpecialGenericSignature {
if (name !in ERASED_VALUE_PARAMETERS_SHORT_NAMES) return null if (name !in ERASED_VALUE_PARAMETERS_SHORT_NAMES) return null
val builtinSignature = firstOverridden { it is FunctionDescriptor && it.hasErasedValueParametersInJava }?.computeJvmSignature() val builtinSignature = firstOverridden { it is FunctionDescriptor && it.hasErasedValueParametersInJava }?.computeJvmSignature()
?: return null ?: return null
if (builtinSignature in ERASED_COLLECTION_PARAMETER_SIGNATURES) return SpecialSignatureInfo.ONE_COLLECTION_PARAMETER if (builtinSignature in ERASED_COLLECTION_PARAMETER_SIGNATURES) return SpecialSignatureInfo.ONE_COLLECTION_PARAMETER
val defaultValue = SIGNATURE_TO_DEFAULT_VALUES_MAP[builtinSignature]!! val defaultValue = SIGNATURE_TO_DEFAULT_VALUES_MAP[builtinSignature]!!
return if (defaultValue == TypeSafeBarrierDescription.NULL) return if (defaultValue == TypeSafeBarrierDescription.NULL)
// return type is some generic type as 'Map.get' // return type is some generic type as 'Map.get'
SpecialSignatureInfo.OBJECT_PARAMETER_GENERIC SpecialSignatureInfo.OBJECT_PARAMETER_GENERIC
else else
SpecialSignatureInfo.OBJECT_PARAMETER_NON_GENERIC SpecialSignatureInfo.OBJECT_PARAMETER_NON_GENERIC
} }
} }
@@ -210,31 +216,31 @@ object BuiltinMethodsWithDifferentJvmName {
// e.g. 'java/lang/CharSequence.get(I)C' does not actually exist in JDK // e.g. 'java/lang/CharSequence.get(I)C' does not actually exist in JDK
// But it doesn't matter here, because signatures are only used to distinguish overloaded built-in definitions // But it doesn't matter here, because signatures are only used to distinguish overloaded built-in definitions
private val REMOVE_AT_NAME_AND_SIGNATURE = private val REMOVE_AT_NAME_AND_SIGNATURE =
"java/util/List".method("removeAt", JvmPrimitiveType.INT.desc, "Ljava/lang/Object;") "java/util/List".method("removeAt", JvmPrimitiveType.INT.desc, "Ljava/lang/Object;")
private val NAME_AND_SIGNATURE_TO_JVM_REPRESENTATION_NAME_MAP: Map<NameAndSignature, Name> = signatures { private val NAME_AND_SIGNATURE_TO_JVM_REPRESENTATION_NAME_MAP: Map<NameAndSignature, Name> = signatures {
mapOf( mapOf(
javaLang("Number").method("toByte", "", JvmPrimitiveType.BYTE.desc) to Name.identifier("byteValue"), javaLang("Number").method("toByte", "", JvmPrimitiveType.BYTE.desc) to Name.identifier("byteValue"),
javaLang("Number").method("toShort", "", JvmPrimitiveType.SHORT.desc) to Name.identifier("shortValue"), javaLang("Number").method("toShort", "", JvmPrimitiveType.SHORT.desc) to Name.identifier("shortValue"),
javaLang("Number").method("toInt", "", JvmPrimitiveType.INT.desc) to Name.identifier("intValue"), javaLang("Number").method("toInt", "", JvmPrimitiveType.INT.desc) to Name.identifier("intValue"),
javaLang("Number").method("toLong", "", JvmPrimitiveType.LONG.desc) to Name.identifier("longValue"), javaLang("Number").method("toLong", "", JvmPrimitiveType.LONG.desc) to Name.identifier("longValue"),
javaLang("Number").method("toFloat", "", JvmPrimitiveType.FLOAT.desc) to Name.identifier("floatValue"), javaLang("Number").method("toFloat", "", JvmPrimitiveType.FLOAT.desc) to Name.identifier("floatValue"),
javaLang("Number").method("toDouble", "", JvmPrimitiveType.DOUBLE.desc) to Name.identifier("doubleValue"), javaLang("Number").method("toDouble", "", JvmPrimitiveType.DOUBLE.desc) to Name.identifier("doubleValue"),
REMOVE_AT_NAME_AND_SIGNATURE to Name.identifier("remove"), REMOVE_AT_NAME_AND_SIGNATURE to Name.identifier("remove"),
javaLang("CharSequence") javaLang("CharSequence")
.method("get", JvmPrimitiveType.INT.desc, JvmPrimitiveType.CHAR.desc) to Name.identifier("charAt") .method("get", JvmPrimitiveType.INT.desc, JvmPrimitiveType.CHAR.desc) to Name.identifier("charAt")
) )
} }
private val SIGNATURE_TO_JVM_REPRESENTATION_NAME: Map<String, Name> = private val SIGNATURE_TO_JVM_REPRESENTATION_NAME: Map<String, Name> =
NAME_AND_SIGNATURE_TO_JVM_REPRESENTATION_NAME_MAP.mapKeys { it.key.signature } NAME_AND_SIGNATURE_TO_JVM_REPRESENTATION_NAME_MAP.mapKeys { it.key.signature }
val ORIGINAL_SHORT_NAMES: List<Name> = NAME_AND_SIGNATURE_TO_JVM_REPRESENTATION_NAME_MAP.keys.map { it.name } val ORIGINAL_SHORT_NAMES: List<Name> = NAME_AND_SIGNATURE_TO_JVM_REPRESENTATION_NAME_MAP.keys.map { it.name }
private val JVM_SHORT_NAME_TO_BUILTIN_SHORT_NAMES_MAP: Map<Name, List<Name>> = private val JVM_SHORT_NAME_TO_BUILTIN_SHORT_NAMES_MAP: Map<Name, List<Name>> =
NAME_AND_SIGNATURE_TO_JVM_REPRESENTATION_NAME_MAP.entries NAME_AND_SIGNATURE_TO_JVM_REPRESENTATION_NAME_MAP.entries
.map { Pair(it.key.name, it.value) } .map { Pair(it.key.name, it.value) }
.groupBy({ it.second }, { it.first }) .groupBy({ it.second }, { it.first })
val Name.sameAsRenamedInJvmBuiltin: Boolean val Name.sameAsRenamedInJvmBuiltin: Boolean
get() = this in ORIGINAL_SHORT_NAMES get() = this in ORIGINAL_SHORT_NAMES
@@ -250,7 +256,7 @@ object BuiltinMethodsWithDifferentJvmName {
} }
fun getBuiltinFunctionNamesByJvmName(name: Name): List<Name> = fun getBuiltinFunctionNamesByJvmName(name: Name): List<Name> =
JVM_SHORT_NAME_TO_BUILTIN_SHORT_NAMES_MAP[name] ?: emptyList() JVM_SHORT_NAME_TO_BUILTIN_SHORT_NAMES_MAP[name] ?: emptyList()
val SimpleFunctionDescriptor.isRemoveAtByIndex: Boolean val SimpleFunctionDescriptor.isRemoveAtByIndex: Boolean
@@ -260,7 +266,8 @@ object BuiltinMethodsWithDifferentJvmName {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
fun <T : CallableMemberDescriptor> T.getOverriddenBuiltinWithDifferentJvmName(): T? { fun <T : CallableMemberDescriptor> T.getOverriddenBuiltinWithDifferentJvmName(): T? {
if (name !in BuiltinMethodsWithDifferentJvmName.ORIGINAL_SHORT_NAMES if (name !in BuiltinMethodsWithDifferentJvmName.ORIGINAL_SHORT_NAMES
&& propertyIfAccessor.name !in BuiltinSpecialProperties.SPECIAL_SHORT_NAMES) return null && propertyIfAccessor.name !in BuiltinSpecialProperties.SPECIAL_SHORT_NAMES
) return null
return when (this) { return when (this) {
is PropertyDescriptor, is PropertyAccessorDescriptor -> is PropertyDescriptor, is PropertyAccessorDescriptor ->
@@ -304,7 +311,7 @@ fun <T : CallableMemberDescriptor> T.getOverriddenBuiltinReflectingJvmDescriptor
fun getJvmMethodNameIfSpecial(callableMemberDescriptor: CallableMemberDescriptor): String? { fun getJvmMethodNameIfSpecial(callableMemberDescriptor: CallableMemberDescriptor): String? {
val overriddenBuiltin = getOverriddenBuiltinThatAffectsJvmName(callableMemberDescriptor)?.propertyIfAccessor val overriddenBuiltin = getOverriddenBuiltinThatAffectsJvmName(callableMemberDescriptor)?.propertyIfAccessor
?: return null ?: return null
return when (overriddenBuiltin) { return when (overriddenBuiltin) {
is PropertyDescriptor -> overriddenBuiltin.getBuiltinSpecialPropertyGetterName() is PropertyDescriptor -> overriddenBuiltin.getBuiltinSpecialPropertyGetterName()
is SimpleFunctionDescriptor -> BuiltinMethodsWithDifferentJvmName.getJvmName(overriddenBuiltin)?.asString() is SimpleFunctionDescriptor -> BuiltinMethodsWithDifferentJvmName.getJvmName(overriddenBuiltin)?.asString()
@@ -313,13 +320,13 @@ fun getJvmMethodNameIfSpecial(callableMemberDescriptor: CallableMemberDescriptor
} }
private fun getOverriddenBuiltinThatAffectsJvmName( private fun getOverriddenBuiltinThatAffectsJvmName(
callableMemberDescriptor: CallableMemberDescriptor callableMemberDescriptor: CallableMemberDescriptor
): CallableMemberDescriptor? = ): CallableMemberDescriptor? =
if (KotlinBuiltIns.isBuiltIn(callableMemberDescriptor)) callableMemberDescriptor.getOverriddenBuiltinWithDifferentJvmName() if (KotlinBuiltIns.isBuiltIn(callableMemberDescriptor)) callableMemberDescriptor.getOverriddenBuiltinWithDifferentJvmName()
else null else null
fun ClassDescriptor.hasRealKotlinSuperClassWithOverrideOf( fun ClassDescriptor.hasRealKotlinSuperClassWithOverrideOf(
specialCallableDescriptor: CallableDescriptor specialCallableDescriptor: CallableDescriptor
): Boolean { ): Boolean {
val builtinContainerDefaultType = (specialCallableDescriptor.containingDeclaration as ClassDescriptor).defaultType val builtinContainerDefaultType = (specialCallableDescriptor.containingDeclaration as ClassDescriptor).defaultType
@@ -330,7 +337,7 @@ fun ClassDescriptor.hasRealKotlinSuperClassWithOverrideOf(
// Kotlin class // Kotlin class
val doesOverrideBuiltinDeclaration = val doesOverrideBuiltinDeclaration =
TypeCheckingProcedure.findCorrespondingSupertype(superClassDescriptor.defaultType, builtinContainerDefaultType) != null TypeCheckingProcedure.findCorrespondingSupertype(superClassDescriptor.defaultType, builtinContainerDefaultType) != null
if (doesOverrideBuiltinDeclaration) { if (doesOverrideBuiltinDeclaration) {
return !KotlinBuiltIns.isBuiltIn(superClassDescriptor) return !KotlinBuiltIns.isBuiltIn(superClassDescriptor)
@@ -26,8 +26,8 @@ class TypeEnhancementInfo(val map: Map<Int, JavaTypeQualifiers>) {
} }
class PredefinedFunctionEnhancementInfo( class PredefinedFunctionEnhancementInfo(
val returnTypeInfo: TypeEnhancementInfo? = null, val returnTypeInfo: TypeEnhancementInfo? = null,
val parametersInfo: List<TypeEnhancementInfo?> = emptyList() val parametersInfo: List<TypeEnhancementInfo?> = emptyList()
) )
/** Type is always nullable: `T?` */ /** Type is always nullable: `T?` */
@@ -196,14 +196,14 @@ val PREDEFINED_FUNCTION_ENHANCEMENT_INFO_BY_SIGNATURE = signatures {
} }
private inline fun enhancement(block: SignatureEnhancementBuilder.() -> Unit): Map<String, PredefinedFunctionEnhancementInfo> private inline fun enhancement(block: SignatureEnhancementBuilder.() -> Unit): Map<String, PredefinedFunctionEnhancementInfo> =
= SignatureEnhancementBuilder().apply(block).build() SignatureEnhancementBuilder().apply(block).build()
private class SignatureEnhancementBuilder { private class SignatureEnhancementBuilder {
private val signatures = mutableMapOf<String, PredefinedFunctionEnhancementInfo>() private val signatures = mutableMapOf<String, PredefinedFunctionEnhancementInfo>()
inline fun forClass(internalName: String, block: ClassEnhancementBuilder.() -> Unit) = inline fun forClass(internalName: String, block: ClassEnhancementBuilder.() -> Unit) =
ClassEnhancementBuilder(internalName).block() ClassEnhancementBuilder(internalName).block()
inner class ClassEnhancementBuilder(val className: String) { inner class ClassEnhancementBuilder(val className: String) {
fun function(name: String, block: FunctionEnhancementBuilder.() -> Unit) { fun function(name: String, block: FunctionEnhancementBuilder.() -> Unit) {
@@ -218,20 +218,29 @@ private class SignatureEnhancementBuilder {
parameters += type to parameters += type to
if (pairs.isEmpty()) null else TypeEnhancementInfo(*pairs) if (pairs.isEmpty()) null else TypeEnhancementInfo(*pairs)
} }
fun parameter(type: String, vararg qualifiers: JavaTypeQualifiers) { fun parameter(type: String, vararg qualifiers: JavaTypeQualifiers) {
parameters += type to parameters += type to
if (qualifiers.isEmpty()) null else TypeEnhancementInfo(qualifiers.withIndex().associateBy({it.index}, {it.value})) if (qualifiers.isEmpty()) null else TypeEnhancementInfo(
qualifiers.withIndex().associateBy(
{ it.index },
{ it.value })
)
} }
fun returns(type: String, vararg pairs: Pair<Int, JavaTypeQualifiers>) { fun returns(type: String, vararg pairs: Pair<Int, JavaTypeQualifiers>) {
returnType = type to TypeEnhancementInfo(*pairs) returnType = type to TypeEnhancementInfo(*pairs)
} }
fun returns(type: String, vararg qualifiers: JavaTypeQualifiers) { fun returns(type: String, vararg qualifiers: JavaTypeQualifiers) {
returnType = type to TypeEnhancementInfo(qualifiers.withIndex().associateBy({it.index}, {it.value})) returnType = type to TypeEnhancementInfo(qualifiers.withIndex().associateBy({ it.index }, { it.value }))
} }
fun returns(type: JvmPrimitiveType) { fun returns(type: JvmPrimitiveType) {
returnType = type.desc to null returnType = type.desc to null
} }
fun build() = with (SignatureBuildingComponents) {
fun build() = with(SignatureBuildingComponents) {
signature(className, jvmDescriptor(functionName, parameters.map { it.first }, returnType.first)) to signature(className, jvmDescriptor(functionName, parameters.map { it.first }, returnType.first)) to
PredefinedFunctionEnhancementInfo(returnType.second, parameters.map { it.second }) PredefinedFunctionEnhancementInfo(returnType.second, parameters.map { it.second })
} }
@@ -244,9 +244,9 @@ class SignatureEnhancement(
private fun KotlinType.extractQualifiers(): JavaTypeQualifiers { private fun KotlinType.extractQualifiers(): JavaTypeQualifiers {
val (lower, upper) = val (lower, upper) =
if (this.isFlexible()) if (this.isFlexible())
asFlexibleType().let { Pair(it.lowerBound, it.upperBound) } asFlexibleType().let { Pair(it.lowerBound, it.upperBound) }
else Pair(this, this) else Pair(this, this)
val mapping = JavaToKotlinClassMap val mapping = JavaToKotlinClassMap
return JavaTypeQualifiers( return JavaTypeQualifiers(
@@ -42,8 +42,7 @@ import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
// For flexible types, both bounds are indexed in the same way: `(A<B>..C<D>)` gives `0 - (A<B>..C<D>), 1 - B and D`. // For flexible types, both bounds are indexed in the same way: `(A<B>..C<D>)` gives `0 - (A<B>..C<D>), 1 - B and D`.
fun KotlinType.enhance(qualifiers: (Int) -> JavaTypeQualifiers) = unwrap().enhancePossiblyFlexible(qualifiers, 0).typeIfChanged fun KotlinType.enhance(qualifiers: (Int) -> JavaTypeQualifiers) = unwrap().enhancePossiblyFlexible(qualifiers, 0).typeIfChanged
fun KotlinType.hasEnhancedNullability() fun KotlinType.hasEnhancedNullability() = annotations.findAnnotation(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION) != null
= annotations.findAnnotation(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION) != null
enum class TypeComponentPosition { enum class TypeComponentPosition {
FLEXIBLE_LOWER, FLEXIBLE_LOWER,
@@ -55,27 +54,27 @@ private open class Result(open val type: KotlinType, val subtreeSize: Int, val w
val typeIfChanged: KotlinType? get() = type.takeIf { wereChanges } val typeIfChanged: KotlinType? get() = type.takeIf { wereChanges }
} }
private class SimpleResult(override val type: SimpleType, subtreeSize: Int, wereChanges: Boolean): Result(type, subtreeSize, wereChanges) private class SimpleResult(override val type: SimpleType, subtreeSize: Int, wereChanges: Boolean) : Result(type, subtreeSize, wereChanges)
private fun UnwrappedType.enhancePossiblyFlexible(qualifiers: (Int) -> JavaTypeQualifiers, index: Int): Result { private fun UnwrappedType.enhancePossiblyFlexible(qualifiers: (Int) -> JavaTypeQualifiers, index: Int): Result {
if (isError) return Result(this, 1, false) if (isError) return Result(this, 1, false)
return when(this) { return when (this) {
is FlexibleType -> { is FlexibleType -> {
val lowerResult = lowerBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_LOWER) val lowerResult = lowerBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_LOWER)
val upperResult = upperBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_UPPER) val upperResult = upperBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_UPPER)
assert(lowerResult.subtreeSize == upperResult.subtreeSize) { assert(lowerResult.subtreeSize == upperResult.subtreeSize) {
"Different tree sizes of bounds: " + "Different tree sizes of bounds: " +
"lower = ($lowerBound, ${lowerResult.subtreeSize}), " + "lower = ($lowerBound, ${lowerResult.subtreeSize}), " +
"upper = ($upperBound, ${upperResult.subtreeSize})" "upper = ($upperBound, ${upperResult.subtreeSize})"
} }
val wereChanges = lowerResult.wereChanges || upperResult.wereChanges val wereChanges = lowerResult.wereChanges || upperResult.wereChanges
val enhancement = lowerResult.type.getEnhancement() ?: upperResult.type.getEnhancement() val enhancement = lowerResult.type.getEnhancement() ?: upperResult.type.getEnhancement()
val type = if (!wereChanges) this@enhancePossiblyFlexible val type = if (!wereChanges) this@enhancePossiblyFlexible
else when { else when {
this is RawTypeImpl -> RawTypeImpl(lowerResult.type, upperResult.type) this is RawTypeImpl -> RawTypeImpl(lowerResult.type, upperResult.type)
else -> KotlinTypeFactory.flexibleType(lowerResult.type, upperResult.type) else -> KotlinTypeFactory.flexibleType(lowerResult.type, upperResult.type)
}.wrapEnhancement(enhancement) }.wrapEnhancement(enhancement)
Result( Result(
type, type,
@@ -87,12 +86,16 @@ private fun UnwrappedType.enhancePossiblyFlexible(qualifiers: (Int) -> JavaTypeQ
} }
} }
private fun SimpleType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers, index: Int, position: TypeComponentPosition): SimpleResult { private fun SimpleType.enhanceInflexible(
qualifiers: (Int) -> JavaTypeQualifiers,
index: Int,
position: TypeComponentPosition
): SimpleResult {
val shouldEnhance = position.shouldEnhance() val shouldEnhance = position.shouldEnhance()
if (!shouldEnhance && arguments.isEmpty()) return SimpleResult(this, 1, false) if (!shouldEnhance && arguments.isEmpty()) return SimpleResult(this, 1, false)
val originalClass = constructor.declarationDescriptor val originalClass = constructor.declarationDescriptor
?: return SimpleResult(this, 1, false) ?: return SimpleResult(this, 1, false)
val effectiveQualifiers = qualifiers(index) val effectiveQualifiers = qualifiers(index)
val (enhancedClassifier, enhancedMutabilityAnnotations) = originalClass.enhanceMutability(effectiveQualifiers, position) val (enhancedClassifier, enhancedMutabilityAnnotations) = originalClass.enhanceMutability(effectiveQualifiers, position)
@@ -101,13 +104,11 @@ private fun SimpleType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers
var globalArgIndex = index + 1 var globalArgIndex = index + 1
var wereChanges = enhancedMutabilityAnnotations != null var wereChanges = enhancedMutabilityAnnotations != null
val enhancedArguments = arguments.mapIndexed { val enhancedArguments = arguments.mapIndexed { localArgIndex, arg ->
localArgIndex, arg ->
if (arg.isStarProjection) { if (arg.isStarProjection) {
globalArgIndex++ globalArgIndex++
TypeUtils.makeStarProjection(enhancedClassifier.typeConstructor.parameters[localArgIndex]) TypeUtils.makeStarProjection(enhancedClassifier.typeConstructor.parameters[localArgIndex])
} } else {
else {
val enhanced = arg.type.unwrap().enhancePossiblyFlexible(qualifiers, globalArgIndex) val enhanced = arg.type.unwrap().enhancePossiblyFlexible(qualifiers, globalArgIndex)
wereChanges = wereChanges || enhanced.wereChanges wereChanges = wereChanges || enhanced.wereChanges
globalArgIndex += enhanced.subtreeSize globalArgIndex += enhanced.subtreeSize
@@ -122,16 +123,16 @@ private fun SimpleType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers
if (!wereChanges) return SimpleResult(this, subtreeSize, wereChanges = false) if (!wereChanges) return SimpleResult(this, subtreeSize, wereChanges = false)
val newAnnotations = listOf( val newAnnotations = listOf(
annotations, annotations,
enhancedMutabilityAnnotations, enhancedMutabilityAnnotations,
enhancedNullabilityAnnotations enhancedNullabilityAnnotations
).filterNotNull().compositeAnnotationsOrSingle() ).filterNotNull().compositeAnnotationsOrSingle()
val enhancedType = KotlinTypeFactory.simpleType( val enhancedType = KotlinTypeFactory.simpleType(
newAnnotations, newAnnotations,
typeConstructor, typeConstructor,
enhancedArguments, enhancedArguments,
enhancedNullability enhancedNullability
) )
val enhancement = if (effectiveQualifiers.isNotNullTypeParameter) NotNullTypeParameter(enhancedType) else enhancedType val enhancement = if (effectiveQualifiers.isNotNullTypeParameter) NotNullTypeParameter(enhancedType) else enhancedType
@@ -150,11 +151,15 @@ private fun List<Annotations>.compositeAnnotationsOrSingle() = when (size) {
fun TypeComponentPosition.shouldEnhance() = this != TypeComponentPosition.INFLEXIBLE fun TypeComponentPosition.shouldEnhance() = this != TypeComponentPosition.INFLEXIBLE
private data class EnhancementResult<out T>(val result: T, val enhancementAnnotations: Annotations?) private data class EnhancementResult<out T>(val result: T, val enhancementAnnotations: Annotations?)
private fun <T> T.noChange() = EnhancementResult(this, null) private fun <T> T.noChange() = EnhancementResult(this, null)
private fun <T> T.enhancedNullability() = EnhancementResult(this, ENHANCED_NULLABILITY_ANNOTATIONS) private fun <T> T.enhancedNullability() = EnhancementResult(this, ENHANCED_NULLABILITY_ANNOTATIONS)
private fun <T> T.enhancedMutability() = EnhancementResult(this, ENHANCED_MUTABILITY_ANNOTATIONS) private fun <T> T.enhancedMutability() = EnhancementResult(this, ENHANCED_MUTABILITY_ANNOTATIONS)
private fun ClassifierDescriptor.enhanceMutability(qualifiers: JavaTypeQualifiers, position: TypeComponentPosition): EnhancementResult<ClassifierDescriptor> { private fun ClassifierDescriptor.enhanceMutability(
qualifiers: JavaTypeQualifiers,
position: TypeComponentPosition
): EnhancementResult<ClassifierDescriptor> {
if (!position.shouldEnhance()) return this.noChange() if (!position.shouldEnhance()) return this.noChange()
if (this !is ClassDescriptor) return this.noChange() // mutability is not applicable for type parameters if (this !is ClassDescriptor) return this.noChange() // mutability is not applicable for type parameters
@@ -167,7 +172,7 @@ private fun ClassifierDescriptor.enhanceMutability(qualifiers: JavaTypeQualifier
} }
} }
MUTABLE -> { MUTABLE -> {
if (position == TypeComponentPosition.FLEXIBLE_UPPER && mapping.isReadOnly(this) ) { if (position == TypeComponentPosition.FLEXIBLE_UPPER && mapping.isReadOnly(this)) {
return mapping.convertReadOnlyToMutable(this).enhancedMutability() return mapping.convertReadOnlyToMutable(this).enhancedMutability()
} }
} }
@@ -222,8 +227,8 @@ internal class NotNullTypeParameter(override val delegate: SimpleType) : CustomT
return when (unwrappedType) { return when (unwrappedType) {
is SimpleType -> unwrappedType.prepareReplacement() is SimpleType -> unwrappedType.prepareReplacement()
is FlexibleType -> KotlinTypeFactory.flexibleType( is FlexibleType -> KotlinTypeFactory.flexibleType(
unwrappedType.lowerBound.prepareReplacement(), unwrappedType.lowerBound.prepareReplacement(),
unwrappedType.upperBound.prepareReplacement() unwrappedType.upperBound.prepareReplacement()
).wrapEnhancement(unwrappedType.getEnhancement()) ).wrapEnhancement(unwrappedType.getEnhancement())
else -> error("Incorrect type: $unwrappedType") else -> error("Incorrect type: $unwrappedType")
} }
@@ -37,8 +37,8 @@ fun KotlinType.lexicalCastFrom(value: String): JavaDefaultValue? {
val typeDescriptor = constructor.declarationDescriptor val typeDescriptor = constructor.declarationDescriptor
if (typeDescriptor is ClassDescriptor && typeDescriptor.kind == ClassKind.ENUM_CLASS) { if (typeDescriptor is ClassDescriptor && typeDescriptor.kind == ClassKind.ENUM_CLASS) {
val descriptor = typeDescriptor.unsubstitutedInnerClassesScope.getContributedClassifier( val descriptor = typeDescriptor.unsubstitutedInnerClassesScope.getContributedClassifier(
Name.identifier(value), Name.identifier(value),
NoLookupLocation.FROM_BACKEND NoLookupLocation.FROM_BACKEND
) )
return if (descriptor is ClassDescriptor && descriptor.kind == ClassKind.ENUM_ENTRY) EnumEntry(descriptor) else null return if (descriptor is ClassDescriptor && descriptor.kind == ClassKind.ENUM_ENTRY) EnumEntry(descriptor) else null
@@ -32,17 +32,17 @@ import org.jetbrains.kotlin.utils.compact
import java.util.* import java.util.*
class BinaryClassAnnotationAndConstantLoaderImpl( class BinaryClassAnnotationAndConstantLoaderImpl(
private val module: ModuleDescriptor, private val module: ModuleDescriptor,
private val notFoundClasses: NotFoundClasses, private val notFoundClasses: NotFoundClasses,
storageManager: StorageManager, storageManager: StorageManager,
kotlinClassFinder: KotlinClassFinder kotlinClassFinder: KotlinClassFinder
) : AbstractBinaryClassAnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>>( ) : AbstractBinaryClassAnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>>(
storageManager, kotlinClassFinder storageManager, kotlinClassFinder
) { ) {
private val annotationDeserializer = AnnotationDeserializer(module, notFoundClasses) private val annotationDeserializer = AnnotationDeserializer(module, notFoundClasses)
override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): AnnotationDescriptor = override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): AnnotationDescriptor =
annotationDeserializer.deserializeAnnotation(proto, nameResolver) annotationDeserializer.deserializeAnnotation(proto, nameResolver)
override fun loadConstant(desc: String, initializer: Any): ConstantValue<*>? { override fun loadConstant(desc: String, initializer: Any): ConstantValue<*>? {
val normalizedValue: Any = if (desc in "ZBCS") { val normalizedValue: Any = if (desc in "ZBCS") {
@@ -54,8 +54,7 @@ class BinaryClassAnnotationAndConstantLoaderImpl(
"S" -> intValue.toShort() "S" -> intValue.toShort()
else -> throw AssertionError(desc) else -> throw AssertionError(desc)
} }
} } else {
else {
initializer initializer
} }
@@ -73,9 +72,9 @@ class BinaryClassAnnotationAndConstantLoaderImpl(
} }
override fun loadAnnotation( override fun loadAnnotation(
annotationClassId: ClassId, annotationClassId: ClassId,
source: SourceElement, source: SourceElement,
result: MutableList<AnnotationDescriptor> result: MutableList<AnnotationDescriptor>
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { ): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
val annotationClass = resolveClass(annotationClassId) val annotationClass = resolveClass(annotationClassId)
@@ -124,7 +123,7 @@ class BinaryClassAnnotationAndConstantLoaderImpl(
override fun visitAnnotation(name: Name, classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { override fun visitAnnotation(name: Name, classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
val list = ArrayList<AnnotationDescriptor>() val list = ArrayList<AnnotationDescriptor>()
val visitor = loadAnnotation(classId, SourceElement.NO_SOURCE, list)!! val visitor = loadAnnotation(classId, SourceElement.NO_SOURCE, list)!!
return object: KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor { return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor {
override fun visitEnd() { override fun visitEnd() {
visitor.visitEnd() visitor.visitEnd()
arguments[name] = AnnotationValue(list.single()) arguments[name] = AnnotationValue(list.single())
@@ -138,7 +137,7 @@ class BinaryClassAnnotationAndConstantLoaderImpl(
private fun createConstant(name: Name?, value: Any?): ConstantValue<*> { private fun createConstant(name: Name?, value: Any?): ConstantValue<*> {
return ConstantValueFactory.createConstantValue(value) return ConstantValueFactory.createConstantValue(value)
?: ErrorValue.create("Unsupported annotation argument: $name") ?: ErrorValue.create("Unsupported annotation argument: $name")
} }
} }
} }
@@ -30,16 +30,16 @@ import org.jetbrains.kotlin.storage.StorageManager
// This class is needed only for easier injection: exact types of needed components are specified in the constructor here. // This class is needed only for easier injection: exact types of needed components are specified in the constructor here.
// Otherwise injector generator is not smart enough to deduce, for example, which package fragment provider DeserializationComponents needs // Otherwise injector generator is not smart enough to deduce, for example, which package fragment provider DeserializationComponents needs
class DeserializationComponentsForJava( class DeserializationComponentsForJava(
storageManager: StorageManager, storageManager: StorageManager,
moduleDescriptor: ModuleDescriptor, moduleDescriptor: ModuleDescriptor,
configuration: DeserializationConfiguration, configuration: DeserializationConfiguration,
classDataFinder: JavaClassDataFinder, classDataFinder: JavaClassDataFinder,
annotationAndConstantLoader: BinaryClassAnnotationAndConstantLoaderImpl, annotationAndConstantLoader: BinaryClassAnnotationAndConstantLoaderImpl,
packageFragmentProvider: LazyJavaPackageFragmentProvider, packageFragmentProvider: LazyJavaPackageFragmentProvider,
notFoundClasses: NotFoundClasses, notFoundClasses: NotFoundClasses,
errorReporter: ErrorReporter, errorReporter: ErrorReporter,
lookupTracker: LookupTracker, lookupTracker: LookupTracker,
contractDeserializer: ContractDeserializer contractDeserializer: ContractDeserializer
) { ) {
val components: DeserializationComponents val components: DeserializationComponents
@@ -47,12 +47,12 @@ class DeserializationComponentsForJava(
// currently built-ins may be not an instance of JvmBuiltIns only in case of built-ins serialization // currently built-ins may be not an instance of JvmBuiltIns only in case of built-ins serialization
val jvmBuiltIns = moduleDescriptor.builtIns as? JvmBuiltIns val jvmBuiltIns = moduleDescriptor.builtIns as? JvmBuiltIns
components = DeserializationComponents( components = DeserializationComponents(
storageManager, moduleDescriptor, configuration, classDataFinder, annotationAndConstantLoader, packageFragmentProvider, storageManager, moduleDescriptor, configuration, classDataFinder, annotationAndConstantLoader, packageFragmentProvider,
LocalClassifierTypeSettings.Default, errorReporter, lookupTracker, JavaFlexibleTypeDeserializer, LocalClassifierTypeSettings.Default, errorReporter, lookupTracker, JavaFlexibleTypeDeserializer,
emptyList(), notFoundClasses, contractDeserializer, emptyList(), notFoundClasses, contractDeserializer,
additionalClassPartsProvider = jvmBuiltIns?.settings ?: AdditionalClassPartsProvider.None, additionalClassPartsProvider = jvmBuiltIns?.settings ?: AdditionalClassPartsProvider.None,
platformDependentDeclarationFilter = jvmBuiltIns?.settings ?: PlatformDependentDeclarationFilter.NoPlatformDependent, platformDependentDeclarationFilter = jvmBuiltIns?.settings ?: PlatformDependentDeclarationFilter.NoPlatformDependent,
extensionRegistryLite = JvmProtoBufUtil.EXTENSION_REGISTRY extensionRegistryLite = JvmProtoBufUtil.EXTENSION_REGISTRY
) )
} }
} }
@@ -103,12 +103,10 @@ class DeserializedDescriptorResolver {
try { try {
try { try {
return block() return block()
} } catch (e: InvalidProtocolBufferException) {
catch (e: InvalidProtocolBufferException) {
throw IllegalStateException("Could not read data from ${klass.location}", e) throw IllegalStateException("Could not read data from ${klass.location}", e)
} }
} } catch (e: Throwable) {
catch (e: Throwable) {
if (skipMetadataVersionCheck || klass.classHeader.metadataVersion.isCompatible()) { if (skipMetadataVersionCheck || klass.classHeader.metadataVersion.isCompatible()) {
throw e throw e
} }
@@ -122,7 +120,7 @@ class DeserializedDescriptorResolver {
internal val KOTLIN_CLASS = setOf(KotlinClassHeader.Kind.CLASS) internal val KOTLIN_CLASS = setOf(KotlinClassHeader.Kind.CLASS)
private val KOTLIN_FILE_FACADE_OR_MULTIFILE_CLASS_PART = private val KOTLIN_FILE_FACADE_OR_MULTIFILE_CLASS_PART =
setOf(KotlinClassHeader.Kind.FILE_FACADE, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART) setOf(KotlinClassHeader.Kind.FILE_FACADE, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART)
private val KOTLIN_1_1_EAP_METADATA_VERSION = JvmMetadataVersion(1, 1, 2) private val KOTLIN_1_1_EAP_METADATA_VERSION = JvmMetadataVersion(1, 1, 2)
@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.serialization.deserialization.ClassData
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
class JavaClassDataFinder( class JavaClassDataFinder(
internal val kotlinClassFinder: KotlinClassFinder, internal val kotlinClassFinder: KotlinClassFinder,
private val deserializedDescriptorResolver: DeserializedDescriptorResolver private val deserializedDescriptorResolver: DeserializedDescriptorResolver
) : ClassDataFinder { ) : ClassDataFinder {
override fun findClassData(classId: ClassId): ClassData? { override fun findClassData(classId: ClassId): ClassData? {
val kotlinClass = kotlinClassFinder.findKotlinClass(classId) ?: return null val kotlinClass = kotlinClassFinder.findKotlinClass(classId) ?: return null
@@ -58,7 +58,7 @@ class JvmPackagePartSource(
val moduleName = val moduleName =
packageProto.getExtensionOrNull(JvmProtoBuf.packageModuleName)?.let(nameResolver::getString) packageProto.getExtensionOrNull(JvmProtoBuf.packageModuleName)?.let(nameResolver::getString)
?: JvmAbi.DEFAULT_MODULE_NAME ?: JvmAbi.DEFAULT_MODULE_NAME
override val presentableString: String override val presentableString: String
get() = "Class '${classId.asSingleFqName().asString()}'" get() = "Class '${classId.asSingleFqName().asString()}'"
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor
class KotlinJvmBinaryPackageSourceElement( class KotlinJvmBinaryPackageSourceElement(
private val packageFragment: LazyJavaPackageFragment private val packageFragment: LazyJavaPackageFragment
) : SourceElement { ) : SourceElement {
override fun toString() = "$packageFragment: ${packageFragment.binaryClasses.keys}" override fun toString() = "$packageFragment: ${packageFragment.binaryClasses.keys}"
@@ -22,9 +22,9 @@ import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErr
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
class KotlinJvmBinarySourceElement( class KotlinJvmBinarySourceElement(
val binaryClass: KotlinJvmBinaryClass, val binaryClass: KotlinJvmBinaryClass,
override val incompatibility: IncompatibleVersionErrorData<JvmMetadataVersion>? = null, override val incompatibility: IncompatibleVersionErrorData<JvmMetadataVersion>? = null,
override val isPreReleaseInvisible: Boolean = false override val isPreReleaseInvisible: Boolean = false
) : DeserializedContainerSource { ) : DeserializedContainerSource {
override val presentableString: String override val presentableString: String
get() = "Class '${binaryClass.classId.asSingleFqName().asString()}'" get() = "Class '${binaryClass.classId.asSingleFqName().asString()}'"
@@ -23,15 +23,15 @@ import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmBytecodeBinaryVersio
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
class KotlinClassHeader( class KotlinClassHeader(
val kind: KotlinClassHeader.Kind, val kind: KotlinClassHeader.Kind,
val metadataVersion: JvmMetadataVersion, val metadataVersion: JvmMetadataVersion,
val bytecodeVersion: JvmBytecodeBinaryVersion, val bytecodeVersion: JvmBytecodeBinaryVersion,
val data: Array<String>?, val data: Array<String>?,
val incompatibleData: Array<String>?, val incompatibleData: Array<String>?,
val strings: Array<String>?, val strings: Array<String>?,
val extraString: String?, val extraString: String?,
val extraInt: Int, val extraInt: Int,
val packageName: String? val packageName: String?
) { ) {
// See kotlin.Metadata // See kotlin.Metadata
enum class Kind(val id: Int) { enum class Kind(val id: Int) {
@@ -68,9 +68,7 @@ class KotlinClassHeader(
INHERITING INHERITING
else else
DELEGATING DELEGATING
} } else null
else
null
val isPreRelease: Boolean val isPreRelease: Boolean
get() = (extraInt and JvmAnnotationNames.METADATA_PRE_RELEASE_FLAG) != 0 get() = (extraInt and JvmAnnotationNames.METADATA_PRE_RELEASE_FLAG) != 0
@@ -39,9 +39,10 @@ object SignatureBuildingComponents {
fun signature(internalName: String, jvmDescriptor: String) = internalName + "." + jvmDescriptor fun signature(internalName: String, jvmDescriptor: String) = internalName + "." + jvmDescriptor
fun jvmDescriptor(name: String, vararg parameters: String, ret: String = "V") = fun jvmDescriptor(name: String, vararg parameters: String, ret: String = "V") =
jvmDescriptor(name, parameters.asList(), ret) jvmDescriptor(name, parameters.asList(), ret)
fun jvmDescriptor(name: String, parameters: List<String>, ret: String = "V") = fun jvmDescriptor(name: String, parameters: List<String>, ret: String = "V") =
"$name(${parameters.joinToString("") { escapeClassName(it) }})${escapeClassName(internalName = ret)}" "$name(${parameters.joinToString("") { escapeClassName(it) }})${escapeClassName(internalName = ret)}"
private fun escapeClassName(internalName: String) = if (internalName.length > 1) "L$internalName;" else internalName private fun escapeClassName(internalName: String) = if (internalName.length > 1) "L$internalName;" else internalName
} }
@@ -49,12 +49,12 @@ fun forceSingleValueParameterBoxing(f: CallableDescriptor): Boolean {
if ((f.original.valueParameters.single().type.mapToJvmType() as? JvmType.Primitive)?.jvmPrimitiveType != JvmPrimitiveType.INT) return false if ((f.original.valueParameters.single().type.mapToJvmType() as? JvmType.Primitive)?.jvmPrimitiveType != JvmPrimitiveType.INT) return false
val overridden = val overridden =
BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(f) BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(f)
?: return false ?: return false
val overriddenParameterType = overridden.original.valueParameters.single().type.mapToJvmType() val overriddenParameterType = overridden.original.valueParameters.single().type.mapToJvmType()
return overridden.containingDeclaration.fqNameUnsafe == KotlinBuiltIns.FQ_NAMES.mutableCollection.toUnsafe() return overridden.containingDeclaration.fqNameUnsafe == KotlinBuiltIns.FQ_NAMES.mutableCollection.toUnsafe()
&& overriddenParameterType is JvmType.Object && overriddenParameterType.internalName == "java/lang/Object" && overriddenParameterType is JvmType.Object && overriddenParameterType.internalName == "java/lang/Object"
} }
// This method only returns not-null for class methods // This method only returns not-null for class methods
@@ -65,8 +65,8 @@ internal fun CallableDescriptor.computeJvmSignature(): String? = signatures {
if (classDescriptor.name.isSpecial) return null if (classDescriptor.name.isSpecial) return null
signature( signature(
classDescriptor, classDescriptor,
(original as? SimpleFunctionDescriptor ?: return null).computeJvmDescriptor() (original as? SimpleFunctionDescriptor ?: return null).computeJvmDescriptor()
) )
} }
@@ -101,6 +101,7 @@ internal fun KotlinType.mapToJvmType() =
sealed class JvmType { sealed class JvmType {
// null means 'void' // null means 'void'
class Primitive(val jvmPrimitiveType: JvmPrimitiveType?) : JvmType() class Primitive(val jvmPrimitiveType: JvmPrimitiveType?) : JvmType()
class Object(val internalName: String) : JvmType() class Object(val internalName: String) : JvmType()
class Array(val elementType: JvmType) : JvmType() class Array(val elementType: JvmType) : JvmType()
@@ -109,13 +110,13 @@ sealed class JvmType {
private object JvmTypeFactoryImpl : JvmTypeFactory<JvmType> { private object JvmTypeFactoryImpl : JvmTypeFactory<JvmType> {
override fun boxType(possiblyPrimitiveType: JvmType) = override fun boxType(possiblyPrimitiveType: JvmType) =
when { when {
possiblyPrimitiveType is JvmType.Primitive && possiblyPrimitiveType.jvmPrimitiveType != null -> possiblyPrimitiveType is JvmType.Primitive && possiblyPrimitiveType.jvmPrimitiveType != null ->
createObjectType( createObjectType(
JvmClassName.byFqNameWithoutInnerClasses( JvmClassName.byFqNameWithoutInnerClasses(possiblyPrimitiveType.jvmPrimitiveType.wrapperFqName).internalName
possiblyPrimitiveType.jvmPrimitiveType.wrapperFqName).internalName) )
else -> possiblyPrimitiveType else -> possiblyPrimitiveType
} }
override fun createFromString(representation: String): JvmType { override fun createFromString(representation: String): JvmType {
assert(representation.length > 0) { "empty string as JvmType" } assert(representation.length > 0) { "empty string as JvmType" }
@@ -141,11 +142,11 @@ private object JvmTypeFactoryImpl : JvmTypeFactory<JvmType> {
override fun createObjectType(internalName: String) = JvmType.Object(internalName) override fun createObjectType(internalName: String) = JvmType.Object(internalName)
override fun toString(type: JvmType): String = override fun toString(type: JvmType): String =
when (type) { when (type) {
is JvmType.Array -> "[" + toString(type.elementType) is JvmType.Array -> "[" + toString(type.elementType)
is JvmType.Primitive -> type.jvmPrimitiveType?.desc ?: "V" is JvmType.Primitive -> type.jvmPrimitiveType?.desc ?: "V"
is JvmType.Object -> "L" + type.internalName + ";" is JvmType.Object -> "L" + type.internalName + ";"
} }
override val javaLangClassType: JvmType override val javaLangClassType: JvmType
get() = createObjectType("java/lang/Class") get() = createObjectType("java/lang/Class")
@@ -123,12 +123,12 @@ fun <T : Any> mapType(
descriptorTypeWriter?.writeArrayType() descriptorTypeWriter?.writeArrayType()
arrayElementType = arrayElementType =
mapType( mapType(
memberType, factory, memberType, factory,
mode.toGenericArgumentMode(memberProjection.projectionKind), mode.toGenericArgumentMode(memberProjection.projectionKind),
typeMappingConfiguration, descriptorTypeWriter, writeGenericType, typeMappingConfiguration, descriptorTypeWriter, writeGenericType,
isIrBackend isIrBackend
) )
descriptorTypeWriter?.writeArrayEnd() descriptorTypeWriter?.writeArrayEnd()
} }
@@ -365,11 +365,11 @@ open class JvmDescriptorTypeWriter<T : Any>(private val jvmTypeFactory: JvmTypeF
protected fun writeJvmTypeAsIs(type: T) { protected fun writeJvmTypeAsIs(type: T) {
if (jvmCurrentType == null) { if (jvmCurrentType == null) {
jvmCurrentType = jvmCurrentType =
if (jvmCurrentTypeArrayLevel > 0) { if (jvmCurrentTypeArrayLevel > 0) {
jvmTypeFactory.createFromString("[".repeat(jvmCurrentTypeArrayLevel) + jvmTypeFactory.toString(type)) jvmTypeFactory.createFromString("[".repeat(jvmCurrentTypeArrayLevel) + jvmTypeFactory.toString(type))
} else { } else {
type type
} }
} }
} }
@@ -24,8 +24,8 @@ import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
class JavaDescriptorResolver( class JavaDescriptorResolver(
val packageFragmentProvider: LazyJavaPackageFragmentProvider, val packageFragmentProvider: LazyJavaPackageFragmentProvider,
private val javaResolverCache: JavaResolverCache private val javaResolverCache: JavaResolverCache
) { ) {
fun resolveClass(javaClass: JavaClass): ClassDescriptor? { fun resolveClass(javaClass: JavaClass): ClassDescriptor? {
val fqName = javaClass.fqName val fqName = javaClass.fqName
@@ -30,8 +30,8 @@ class ReflectJavaClassFinder(private val classLoader: ClassLoader) : JavaClassFi
val packageFqName = classId.packageFqName val packageFqName = classId.packageFqName
val relativeClassName = classId.relativeClassName.asString().replace('.', '$') val relativeClassName = classId.relativeClassName.asString().replace('.', '$')
val name = val name =
if (packageFqName.isRoot) relativeClassName if (packageFqName.isRoot) relativeClassName
else packageFqName.asString() + "." + relativeClassName else packageFqName.asString() + "." + relativeClassName
val klass = classLoader.tryLoadClass(name) val klass = classLoader.tryLoadClass(name)
return if (klass != null) ReflectJavaClass(klass) else null return if (klass != null) ReflectJavaClass(klass) else null
@@ -46,9 +46,8 @@ class ReflectJavaClassFinder(private val classLoader: ClassLoader) : JavaClassFi
} }
fun ClassLoader.tryLoadClass(fqName: String) = fun ClassLoader.tryLoadClass(fqName: String) =
try { try {
loadClass(fqName) loadClass(fqName)
} } catch (e: ClassNotFoundException) {
catch (e: ClassNotFoundException) { null
null }
}
@@ -35,23 +35,22 @@ import kotlin.reflect.jvm.internal.structure.isEnumClassOrSpecializedEnumEntryCl
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
private val TYPES_ELIGIBLE_FOR_SIMPLE_VISIT = setOf<Class<*>>( private val TYPES_ELIGIBLE_FOR_SIMPLE_VISIT = setOf<Class<*>>(
// Primitives // Primitives
java.lang.Integer::class.java, java.lang.Character::class.java, java.lang.Byte::class.java, java.lang.Long::class.java, java.lang.Integer::class.java, java.lang.Character::class.java, java.lang.Byte::class.java, java.lang.Long::class.java,
java.lang.Short::class.java, java.lang.Boolean::class.java, java.lang.Double::class.java, java.lang.Float::class.java, java.lang.Short::class.java, java.lang.Boolean::class.java, java.lang.Double::class.java, java.lang.Float::class.java,
// Arrays of primitives // Arrays of primitives
IntArray::class.java, CharArray::class.java, ByteArray::class.java, LongArray::class.java, IntArray::class.java, CharArray::class.java, ByteArray::class.java, LongArray::class.java,
ShortArray::class.java, BooleanArray::class.java, DoubleArray::class.java, FloatArray::class.java, ShortArray::class.java, BooleanArray::class.java, DoubleArray::class.java, FloatArray::class.java,
// Others // Others
Class::class.java, String::class.java Class::class.java, String::class.java
) )
class ReflectKotlinClass private constructor( class ReflectKotlinClass private constructor(
val klass: Class<*>, val klass: Class<*>,
override val classHeader: KotlinClassHeader override val classHeader: KotlinClassHeader
) : KotlinJvmBinaryClass { ) : KotlinJvmBinaryClass {
companion object Factory { companion object Factory {
fun create(klass: Class<*>): ReflectKotlinClass? { fun create(klass: Class<*>): ReflectKotlinClass? {
val headerReader = ReadKotlinClassHeaderAnnotationVisitor() val headerReader = ReadKotlinClassHeaderAnnotationVisitor()
ReflectClassStructure.loadClassAnnotations(klass, headerReader) ReflectClassStructure.loadClassAnnotations(klass, headerReader)
@@ -137,7 +136,7 @@ private object ReflectClassStructure {
for (annotation in annotations) { for (annotation in annotations) {
val annotationType = annotation.annotationClass.java val annotationType = annotation.annotationClass.java
visitor.visitParameterAnnotation( visitor.visitParameterAnnotation(
parameterIndex + shift, annotationType.classId, ReflectAnnotationSource(annotation) parameterIndex + shift, annotationType.classId, ReflectAnnotationSource(annotation)
)?.let { )?.let {
processAnnotationArguments(it, annotation, annotationType) processAnnotationArguments(it, annotation, annotationType)
} }
@@ -169,15 +168,14 @@ private object ReflectClassStructure {
} }
private fun processAnnotationArguments( private fun processAnnotationArguments(
visitor: KotlinJvmBinaryClass.AnnotationArgumentVisitor, visitor: KotlinJvmBinaryClass.AnnotationArgumentVisitor,
annotation: Annotation, annotation: Annotation,
annotationType: Class<*> annotationType: Class<*>
) { ) {
for (method in annotationType.declaredMethods) { for (method in annotationType.declaredMethods) {
val value = try { val value = try {
method(annotation)!! method(annotation)!!
} } catch (e: IllegalAccessException) {
catch (e: IllegalAccessException) {
// This is possible if the annotation class is package local. In this case, we can't read the value into descriptor. // This is possible if the annotation class is package local. In this case, we can't read the value into descriptor.
// However, this might be OK, because we do not use any data from AnnotationDescriptor in KAnnotatedElement implementations // However, this might be OK, because we do not use any data from AnnotationDescriptor in KAnnotatedElement implementations
// anyway; we use the source element and the underlying physical Annotation object to implement the needed API // anyway; we use the source element and the underlying physical Annotation object to implement the needed API
@@ -241,13 +239,11 @@ private object ReflectClassStructure {
for (element in value as Array<*>) { for (element in value as Array<*>) {
v.visitEnum(enumClassId, Name.identifier((element as Enum<*>).name)) v.visitEnum(enumClassId, Name.identifier((element as Enum<*>).name))
} }
} } else if (componentType == Class::class.java) {
else if (componentType == Class::class.java) {
for (element in value as Array<*>) { for (element in value as Array<*>) {
v.visitClassLiteral((element as Class<*>).classLiteralValue()) v.visitClassLiteral((element as Class<*>).classLiteralValue())
} }
} } else {
else {
for (element in value as Array<*>) { for (element in value as Array<*>) {
v.visit(element) v.visit(element)
} }
@@ -47,8 +47,8 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.utils.Jsr305State import org.jetbrains.kotlin.utils.Jsr305State
class RuntimeModuleData private constructor( class RuntimeModuleData private constructor(
val deserialization: DeserializationComponents, val deserialization: DeserializationComponents,
val packagePartProvider: RuntimePackagePartProvider val packagePartProvider: RuntimePackagePartProvider
) { ) {
val module: ModuleDescriptor get() = deserialization.moduleDescriptor val module: ModuleDescriptor get() = deserialization.moduleDescriptor
@@ -66,15 +66,13 @@ class RuntimeModuleData private constructor(
val notFoundClasses = NotFoundClasses(storageManager, module) val notFoundClasses = NotFoundClasses(storageManager, module)
val annotationTypeQualifierResolver = AnnotationTypeQualifierResolver(storageManager, Jsr305State.DISABLED) val annotationTypeQualifierResolver = AnnotationTypeQualifierResolver(storageManager, Jsr305State.DISABLED)
val globalJavaResolverContext = JavaResolverComponents( val globalJavaResolverContext = JavaResolverComponents(
storageManager, ReflectJavaClassFinder(classLoader), reflectKotlinClassFinder, deserializedDescriptorResolver, storageManager, ReflectJavaClassFinder(classLoader), reflectKotlinClassFinder, deserializedDescriptorResolver,
SignaturePropagator.DO_NOTHING, RuntimeErrorReporter, javaResolverCache, SignaturePropagator.DO_NOTHING, RuntimeErrorReporter, javaResolverCache,
JavaPropertyInitializerEvaluator.DoNothing, SamConversionResolver.Empty, RuntimeSourceElementFactory, singleModuleClassResolver, JavaPropertyInitializerEvaluator.DoNothing, SamConversionResolver.Empty, RuntimeSourceElementFactory,
runtimePackagePartProvider, SupertypeLoopChecker.EMPTY, LookupTracker.DO_NOTHING, module, singleModuleClassResolver, runtimePackagePartProvider, SupertypeLoopChecker.EMPTY, LookupTracker.DO_NOTHING, module,
ReflectionTypes(module, notFoundClasses), ReflectionTypes(module, notFoundClasses), annotationTypeQualifierResolver,
annotationTypeQualifierResolver, SignatureEnhancement(annotationTypeQualifierResolver, Jsr305State.DISABLED),
SignatureEnhancement(annotationTypeQualifierResolver, Jsr305State.DISABLED), JavaClassesTracker.Default, JavaResolverSettings.Default
JavaClassesTracker.Default,
JavaResolverSettings.Default
) )
val lazyJavaPackageFragmentProvider = LazyJavaPackageFragmentProvider(globalJavaResolverContext) val lazyJavaPackageFragmentProvider = LazyJavaPackageFragmentProvider(globalJavaResolverContext)
@@ -84,12 +82,12 @@ class RuntimeModuleData private constructor(
val javaDescriptorResolver = JavaDescriptorResolver(lazyJavaPackageFragmentProvider, javaResolverCache) val javaDescriptorResolver = JavaDescriptorResolver(lazyJavaPackageFragmentProvider, javaResolverCache)
val javaClassDataFinder = JavaClassDataFinder(reflectKotlinClassFinder, deserializedDescriptorResolver) val javaClassDataFinder = JavaClassDataFinder(reflectKotlinClassFinder, deserializedDescriptorResolver)
val binaryClassAnnotationAndConstantLoader = BinaryClassAnnotationAndConstantLoaderImpl( val binaryClassAnnotationAndConstantLoader = BinaryClassAnnotationAndConstantLoaderImpl(
module, notFoundClasses, storageManager, reflectKotlinClassFinder module, notFoundClasses, storageManager, reflectKotlinClassFinder
) )
val deserializationComponentsForJava = DeserializationComponentsForJava( val deserializationComponentsForJava = DeserializationComponentsForJava(
storageManager, module, DeserializationConfiguration.Default, javaClassDataFinder, storageManager, module, DeserializationConfiguration.Default, javaClassDataFinder,
binaryClassAnnotationAndConstantLoader, lazyJavaPackageFragmentProvider, notFoundClasses, binaryClassAnnotationAndConstantLoader, lazyJavaPackageFragmentProvider, notFoundClasses,
RuntimeErrorReporter, LookupTracker.DO_NOTHING, ContractDeserializer.DEFAULT RuntimeErrorReporter, LookupTracker.DO_NOTHING, ContractDeserializer.DEFAULT
) )
singleModuleClassResolver.resolver = javaDescriptorResolver singleModuleClassResolver.resolver = javaDescriptorResolver
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
abstract class ReflectJavaAnnotationArgument( abstract class ReflectJavaAnnotationArgument(
override val name: Name? override val name: Name?
) : JavaAnnotationArgument { ) : JavaAnnotationArgument {
companion object Factory { companion object Factory {
fun create(value: Any, name: Name?): ReflectJavaAnnotationArgument { fun create(value: Any, name: Name?): ReflectJavaAnnotationArgument {
@@ -37,20 +37,20 @@ abstract class ReflectJavaAnnotationArgument(
} }
class ReflectJavaLiteralAnnotationArgument( class ReflectJavaLiteralAnnotationArgument(
name: Name?, name: Name?,
override val value: Any override val value: Any
) : ReflectJavaAnnotationArgument(name), JavaLiteralAnnotationArgument ) : ReflectJavaAnnotationArgument(name), JavaLiteralAnnotationArgument
class ReflectJavaArrayAnnotationArgument( class ReflectJavaArrayAnnotationArgument(
name: Name?, name: Name?,
private val values: Array<*> private val values: Array<*>
) : ReflectJavaAnnotationArgument(name), JavaArrayAnnotationArgument { ) : ReflectJavaAnnotationArgument(name), JavaArrayAnnotationArgument {
override fun getElements() = values.map { ReflectJavaAnnotationArgument.create(it!!, null) } override fun getElements() = values.map { ReflectJavaAnnotationArgument.create(it!!, null) }
} }
class ReflectJavaEnumValueAnnotationArgument( class ReflectJavaEnumValueAnnotationArgument(
name: Name?, name: Name?,
private val value: Enum<*> private val value: Enum<*>
) : ReflectJavaAnnotationArgument(name), JavaEnumValueAnnotationArgument { ) : ReflectJavaAnnotationArgument(name), JavaEnumValueAnnotationArgument {
override val enumClassId: ClassId? override val enumClassId: ClassId?
get() { get() {
@@ -64,15 +64,15 @@ class ReflectJavaEnumValueAnnotationArgument(
} }
class ReflectJavaClassObjectAnnotationArgument( class ReflectJavaClassObjectAnnotationArgument(
name: Name?, name: Name?,
private val klass: Class<*> private val klass: Class<*>
) : ReflectJavaAnnotationArgument(name), JavaClassObjectAnnotationArgument { ) : ReflectJavaAnnotationArgument(name), JavaClassObjectAnnotationArgument {
override fun getReferencedType(): JavaType = ReflectJavaType.create(klass) override fun getReferencedType(): JavaType = ReflectJavaType.create(klass)
} }
class ReflectJavaAnnotationAsAnnotationArgument( class ReflectJavaAnnotationAsAnnotationArgument(
name: Name?, name: Name?,
private val annotation: Annotation private val annotation: Annotation
) : ReflectJavaAnnotationArgument(name), JavaAnnotationAsAnnotationArgument { ) : ReflectJavaAnnotationArgument(name), JavaAnnotationAsAnnotationArgument {
override fun getAnnotation(): JavaAnnotation = ReflectJavaAnnotation(annotation) override fun getAnnotation(): JavaAnnotation = ReflectJavaAnnotation(annotation)
} }
@@ -27,7 +27,7 @@ interface ReflectJavaAnnotationOwner : JavaAnnotationOwner {
get() = element?.declaredAnnotations?.getAnnotations() ?: emptyList() get() = element?.declaredAnnotations?.getAnnotations() ?: emptyList()
override fun findAnnotation(fqName: FqName) = override fun findAnnotation(fqName: FqName) =
element?.declaredAnnotations?.findAnnotation(fqName) element?.declaredAnnotations?.findAnnotation(fqName)
override val isDeprecatedInJavaDoc: Boolean override val isDeprecatedInJavaDoc: Boolean
get() = false get() = false
@@ -21,7 +21,7 @@ import java.lang.reflect.GenericArrayType
import java.lang.reflect.Type import java.lang.reflect.Type
class ReflectJavaArrayType(override val reflectType: Type) : ReflectJavaType(), JavaArrayType { class ReflectJavaArrayType(override val reflectType: Type) : ReflectJavaType(), JavaArrayType {
override val componentType: ReflectJavaType = with (reflectType) { override val componentType: ReflectJavaType = with(reflectType) {
when { when {
this is GenericArrayType -> ReflectJavaType.create(genericComponentType) this is GenericArrayType -> ReflectJavaType.create(genericComponentType)
this is Class<*> && isArray() -> ReflectJavaType.create(getComponentType()) this is Class<*> && isArray() -> ReflectJavaType.create(getComponentType())
@@ -25,7 +25,7 @@ import java.lang.reflect.Method
import java.util.* import java.util.*
class ReflectJavaClass( class ReflectJavaClass(
private val klass: Class<*> private val klass: Class<*>
) : ReflectJavaElement(), ReflectJavaAnnotationOwner, ReflectJavaModifierListOwner, JavaClass { ) : ReflectJavaElement(), ReflectJavaAnnotationOwner, ReflectJavaModifierListOwner, JavaClass {
override val element: Class<*> get() = klass override val element: Class<*> get() = klass
@@ -33,20 +33,20 @@ class ReflectJavaClass(
override val innerClassNames: List<Name> override val innerClassNames: List<Name>
get() = klass.declaredClasses get() = klass.declaredClasses
.asSequence() .asSequence()
.filterNot { .filterNot {
// getDeclaredClasses() returns anonymous classes sometimes, for example enums with specialized entries (which are // getDeclaredClasses() returns anonymous classes sometimes, for example enums with specialized entries (which are
// in fact anonymous classes) or in case of a special anonymous class created for the synthetic accessor to a private // in fact anonymous classes) or in case of a special anonymous class created for the synthetic accessor to a private
// nested class constructor accessed from the outer class // nested class constructor accessed from the outer class
it.simpleName.isEmpty() it.simpleName.isEmpty()
} }
.mapNotNull { it.simpleName.takeIf(Name::isValidIdentifier)?.let(Name::identifier) }.toList() .mapNotNull { it.simpleName.takeIf(Name::isValidIdentifier)?.let(Name::identifier) }.toList()
override fun findInnerClass(name: Name) = klass.declaredClasses override fun findInnerClass(name: Name) = klass.declaredClasses
.asSequence() .asSequence()
.firstOrNull { .firstOrNull {
it.simpleName == name.asString() it.simpleName == name.asString()
}?.let(::ReflectJavaClass) }?.let(::ReflectJavaClass)
override val fqName: FqName override val fqName: FqName
get() = klass.classId.asSingleFqName() get() = klass.classId.asSingleFqName()
@@ -62,16 +62,16 @@ class ReflectJavaClass(
override val methods: List<ReflectJavaMethod> override val methods: List<ReflectJavaMethod>
get() = klass.declaredMethods get() = klass.declaredMethods
.asSequence() .asSequence()
.filter { method -> .filter { method ->
when { when {
method.isSynthetic -> false method.isSynthetic -> false
isEnum -> !isEnumValuesOrValueOf(method) isEnum -> !isEnumValuesOrValueOf(method)
else -> true else -> true
}
} }
.map(::ReflectJavaMethod) }
.toList() .map(::ReflectJavaMethod)
.toList()
private fun isEnumValuesOrValueOf(method: Method): Boolean { private fun isEnumValuesOrValueOf(method: Method): Boolean {
return when (method.name) { return when (method.name) {
@@ -83,17 +83,17 @@ class ReflectJavaClass(
override val fields: List<ReflectJavaField> override val fields: List<ReflectJavaField>
get() = klass.declaredFields get() = klass.declaredFields
.asSequence() .asSequence()
.filter { field -> !field.isSynthetic } .filter { field -> !field.isSynthetic }
.map(::ReflectJavaField) .map(::ReflectJavaField)
.toList() .toList()
override val constructors: List<ReflectJavaConstructor> override val constructors: List<ReflectJavaConstructor>
get() = klass.declaredConstructors get() = klass.declaredConstructors
.asSequence() .asSequence()
.filter { constructor -> !constructor.isSynthetic } .filter { constructor -> !constructor.isSynthetic }
.map(::ReflectJavaConstructor) .map(::ReflectJavaConstructor)
.toList() .toList()
override val lightClassOriginKind: LightClassOriginKind? override val lightClassOriginKind: LightClassOriginKind?
get() = null get() = null
@@ -40,9 +40,9 @@ abstract class ReflectJavaMember : ReflectJavaElement(), ReflectJavaAnnotationOw
get() = ReflectJavaClass(member.declaringClass) get() = ReflectJavaClass(member.declaringClass)
protected fun getValueParameters( protected fun getValueParameters(
parameterTypes: Array<Type>, parameterTypes: Array<Type>,
parameterAnnotations: Array<Array<Annotation>>, parameterAnnotations: Array<Array<Annotation>>,
isVararg: Boolean isVararg: Boolean
): List<JavaValueParameter> { ): List<JavaValueParameter> {
val result = ArrayList<JavaValueParameter>(parameterTypes.size) val result = ArrayList<JavaValueParameter>(parameterTypes.size)
val names = Java8ParameterNamesLoader.loadParameterNames(member) val names = Java8ParameterNamesLoader.loadParameterNames(member)
@@ -79,8 +79,7 @@ private object Java8ParameterNamesLoader {
val getParameters = try { val getParameters = try {
methodOrConstructorClass.getMethod("getParameters") methodOrConstructorClass.getMethod("getParameters")
} } catch (e: NoSuchMethodException) {
catch (e: NoSuchMethodException) {
return Cache(null, null) return Cache(null, null)
} }
@@ -22,7 +22,7 @@ import java.lang.reflect.AnnotatedElement
import java.lang.reflect.TypeVariable import java.lang.reflect.TypeVariable
class ReflectJavaTypeParameter( class ReflectJavaTypeParameter(
val typeVariable: TypeVariable<*> val typeVariable: TypeVariable<*>
) : ReflectJavaElement(), JavaTypeParameter, ReflectJavaAnnotationOwner { ) : ReflectJavaElement(), JavaTypeParameter, ReflectJavaAnnotationOwner {
override val upperBounds: List<ReflectJavaClassifierType> override val upperBounds: List<ReflectJavaClassifierType>
get() { get() {
@@ -21,16 +21,16 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
class ReflectJavaValueParameter( class ReflectJavaValueParameter(
override val type: ReflectJavaType, override val type: ReflectJavaType,
private val reflectAnnotations: Array<Annotation>, private val reflectAnnotations: Array<Annotation>,
private val reflectName: String?, private val reflectName: String?,
override val isVararg: Boolean override val isVararg: Boolean
) : ReflectJavaElement(), JavaValueParameter { ) : ReflectJavaElement(), JavaValueParameter {
override val annotations: List<ReflectJavaAnnotation> override val annotations: List<ReflectJavaAnnotation>
get() = reflectAnnotations.getAnnotations() get() = reflectAnnotations.getAnnotations()
override fun findAnnotation(fqName: FqName) = override fun findAnnotation(fqName: FqName) =
reflectAnnotations.findAnnotation(fqName) reflectAnnotations.findAnnotation(fqName)
override val isDeprecatedInJavaDoc: Boolean override val isDeprecatedInJavaDoc: Boolean
get() = false get() = false
@@ -19,7 +19,7 @@ package kotlin.reflect.jvm.internal.structure
import org.jetbrains.kotlin.load.java.structure.JavaWildcardType import org.jetbrains.kotlin.load.java.structure.JavaWildcardType
import java.lang.reflect.WildcardType import java.lang.reflect.WildcardType
class ReflectJavaWildcardType(override val reflectType: WildcardType): ReflectJavaType(), JavaWildcardType { class ReflectJavaWildcardType(override val reflectType: WildcardType) : ReflectJavaType(), JavaWildcardType {
override val bound: ReflectJavaType? override val bound: ReflectJavaType?
get() { get() {
val upperBounds = reflectType.upperBounds val upperBounds = reflectType.upperBounds
@@ -27,10 +27,10 @@ val Class<*>.safeClassLoader: ClassLoader
get() = classLoader ?: ClassLoader.getSystemClassLoader() get() = classLoader ?: ClassLoader.getSystemClassLoader()
fun Class<*>.isEnumClassOrSpecializedEnumEntryClass(): Boolean = fun Class<*>.isEnumClassOrSpecializedEnumEntryClass(): Boolean =
Enum::class.java.isAssignableFrom(this) Enum::class.java.isAssignableFrom(this)
private val PRIMITIVE_CLASSES = private val PRIMITIVE_CLASSES =
listOf(Boolean::class, Byte::class, Char::class, Double::class, Float::class, Int::class, Long::class, Short::class) listOf(Boolean::class, Byte::class, Char::class, Double::class, Float::class, Int::class, Long::class, Short::class)
private val WRAPPER_TO_PRIMITIVE = PRIMITIVE_CLASSES.map { it.javaObjectType to it.javaPrimitiveType }.toMap() private val WRAPPER_TO_PRIMITIVE = PRIMITIVE_CLASSES.map { it.javaObjectType to it.javaPrimitiveType }.toMap()
private val PRIMITIVE_TO_WRAPPER = PRIMITIVE_CLASSES.map { it.javaPrimitiveType to it.javaObjectType }.toMap() private val PRIMITIVE_TO_WRAPPER = PRIMITIVE_CLASSES.map { it.javaPrimitiveType to it.javaObjectType }.toMap()
@@ -41,13 +41,13 @@ val Class<*>.wrapperByPrimitive: Class<*>?
get() = PRIMITIVE_TO_WRAPPER[this] get() = PRIMITIVE_TO_WRAPPER[this]
private val FUNCTION_CLASSES = private val FUNCTION_CLASSES =
listOf( listOf(
Function0::class.java, Function1::class.java, Function2::class.java, Function3::class.java, Function4::class.java, Function0::class.java, Function1::class.java, Function2::class.java, Function3::class.java, Function4::class.java,
Function5::class.java, Function6::class.java, Function7::class.java, Function8::class.java, Function9::class.java, Function5::class.java, Function6::class.java, Function7::class.java, Function8::class.java, Function9::class.java,
Function10::class.java, Function11::class.java, Function12::class.java, Function13::class.java, Function14::class.java, Function10::class.java, Function11::class.java, Function12::class.java, Function13::class.java, Function14::class.java,
Function15::class.java, Function16::class.java, Function17::class.java, Function18::class.java, Function19::class.java, Function15::class.java, Function16::class.java, Function17::class.java, Function18::class.java, Function19::class.java,
Function20::class.java, Function21::class.java, Function22::class.java Function20::class.java, Function21::class.java, Function22::class.java
).mapIndexed { i, clazz -> clazz to i }.toMap() ).mapIndexed { i, clazz -> clazz to i }.toMap()
val Class<*>.functionClassArity: Int? val Class<*>.functionClassArity: Int?
get() = FUNCTION_CLASSES[this] get() = FUNCTION_CLASSES[this]
@@ -75,7 +75,7 @@ val Class<*>.desc: String
} }
fun Class<*>.createArrayType(): Class<*> = fun Class<*>.createArrayType(): Class<*> =
Array.newInstance(this, 0)::class.java Array.newInstance(this, 0)::class.java
/** /**
* @return all arguments of a parameterized type, including those of outer classes in case this type represents an inner generic. * @return all arguments of a parameterized type, including those of outer classes in case this type represents an inner generic.
@@ -47,7 +47,7 @@ abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdir() {
private val renderer = DescriptorRenderer.withOptions { private val renderer = DescriptorRenderer.withOptions {
withDefinedIn = false withDefinedIn = false
excludedAnnotationClasses = setOf( excludedAnnotationClasses = setOf(
FqName(ExpectedLoadErrorsUtil.ANNOTATION_CLASS_NAME) FqName(ExpectedLoadErrorsUtil.ANNOTATION_CLASS_NAME)
) )
overrideRenderingPolicy = OverrideRenderingPolicy.RENDER_OPEN_OVERRIDE overrideRenderingPolicy = OverrideRenderingPolicy.RENDER_OPEN_OVERRIDE
parameterNameRenderingPolicy = ParameterNameRenderingPolicy.NONE parameterNameRenderingPolicy = ParameterNameRenderingPolicy.NONE
@@ -71,8 +71,8 @@ abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdir() {
if (InTextDirectivesUtils.isDirectiveDefined(text, "SKIP_IN_RUNTIME_TEST")) return if (InTextDirectivesUtils.isDirectiveDefined(text, "SKIP_IN_RUNTIME_TEST")) return
val jdkKind = val jdkKind =
if (InTextDirectivesUtils.isDirectiveDefined(text, "FULL_JDK")) TestJdkKind.FULL_JDK if (InTextDirectivesUtils.isDirectiveDefined(text, "FULL_JDK")) TestJdkKind.FULL_JDK
else defaultJdkKind else defaultJdkKind
compileFile(file, text, jdkKind) compileFile(file, text, jdkKind)
@@ -81,14 +81,14 @@ abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdir() {
val actual = createReflectedPackageView(classLoader, KotlinTestUtils.TEST_MODULE_NAME) val actual = createReflectedPackageView(classLoader, KotlinTestUtils.TEST_MODULE_NAME)
val comparatorConfiguration = Configuration( val comparatorConfiguration = Configuration(
/* checkPrimaryConstructors = */ fileName.endsWith(".kt"), /* checkPrimaryConstructors = */ fileName.endsWith(".kt"),
/* checkPropertyAccessors = */ true, /* checkPropertyAccessors = */ true,
/* includeMethodsOfKotlinAny = */ false, /* includeMethodsOfKotlinAny = */ false,
/* renderDeclarationsFromOtherModules = */ true, /* renderDeclarationsFromOtherModules = */ true,
/* checkFunctionContract = */ false, /* checkFunctionContract = */ false,
// Skip Java annotation constructors because order of their parameters is not retained at runtime // Skip Java annotation constructors because order of their parameters is not retained at runtime
{ descriptor -> !descriptor!!.isJavaAnnotationConstructor() }, { descriptor -> !descriptor!!.isJavaAnnotationConstructor() },
errorTypesForbidden(), renderer errorTypesForbidden(), renderer
) )
val differentResultFile = KotlinTestUtils.replaceExtension(file, "runtime.txt") val differentResultFile = KotlinTestUtils.replaceExtension(file, "runtime.txt")
@@ -98,16 +98,16 @@ abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdir() {
} }
val expected = LoadDescriptorUtil.loadTestPackageAndBindingContextFromJavaRoot( val expected = LoadDescriptorUtil.loadTestPackageAndBindingContextFromJavaRoot(
tmpdir, testRootDisposable, jdkKind, ConfigurationKind.ALL, true, false, false, null tmpdir, testRootDisposable, jdkKind, ConfigurationKind.ALL, true, false, false, null
).first ).first
RecursiveDescriptorComparator.validateAndCompareDescriptors(expected, actual, comparatorConfiguration, null) RecursiveDescriptorComparator.validateAndCompareDescriptors(expected, actual, comparatorConfiguration, null)
} }
private fun DeclarationDescriptor.isJavaAnnotationConstructor() = private fun DeclarationDescriptor.isJavaAnnotationConstructor() =
this is ClassConstructorDescriptor && this is ClassConstructorDescriptor &&
containingDeclaration is JavaClassDescriptor && containingDeclaration is JavaClassDescriptor &&
containingDeclaration.kind == ClassKind.ANNOTATION_CLASS containingDeclaration.kind == ClassKind.ANNOTATION_CLASS
private fun compileFile(file: File, text: String, jdkKind: TestJdkKind) { private fun compileFile(file: File, text: String, jdkKind: TestJdkKind) {
val fileName = file.name val fileName = file.name
@@ -124,7 +124,7 @@ abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdir() {
} }
fileName.endsWith(".kt") -> { fileName.endsWith(".kt") -> {
val environment = KotlinTestUtils.createEnvironmentWithJdkAndNullabilityAnnotationsFromIdea( val environment = KotlinTestUtils.createEnvironmentWithJdkAndNullabilityAnnotationsFromIdea(
myTestRootDisposable, ConfigurationKind.ALL, jdkKind myTestRootDisposable, ConfigurationKind.ALL, jdkKind
) )
for (root in environment.configuration.getList(CLIConfigurationKeys.CONTENT_ROOTS)) { for (root in environment.configuration.getList(CLIConfigurationKeys.CONTENT_ROOTS)) {
LOG.info("root: " + root.toString()) LOG.info("root: " + root.toString())
@@ -157,8 +157,7 @@ abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdir() {
if (!packageScopes.contains(packageView.memberScope)) { if (!packageScopes.contains(packageView.memberScope)) {
packageScopes.add(packageView.memberScope) packageScopes.add(packageView.memberScope)
} }
} } else if (header == null || header.kind == KotlinClassHeader.Kind.CLASS) {
else if (header == null || header.kind == KotlinClassHeader.Kind.CLASS) {
// Either a normal Kotlin class or a Java class // Either a normal Kotlin class or a Java class
val classId = klass.classId val classId = klass.classId
if (!classId.isLocal) { if (!classId.isLocal) {
@@ -180,16 +179,18 @@ abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdir() {
val adaptedSource = typeAnnotations.fold(text) { text, annotation -> text.replace("@$annotation", "") } val adaptedSource = typeAnnotations.fold(text) { text, annotation -> text.replace("@$annotation", "") }
if ("@Retention" !in adaptedSource) { if ("@Retention" !in adaptedSource) {
return adaptedSource.replace( return adaptedSource.replace(
"@interface", "@interface",
"@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @interface" "@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @interface"
) )
} }
return adaptedSource return adaptedSource
} }
private class SyntheticPackageViewForTest(override val module: ModuleDescriptor, private class SyntheticPackageViewForTest(
packageScopes: List<MemberScope>, override val module: ModuleDescriptor,
classes: List<ClassifierDescriptor>) : PackageViewDescriptor { packageScopes: List<MemberScope>,
classes: List<ClassifierDescriptor>
) : PackageViewDescriptor {
private val scope: MemberScope private val scope: MemberScope
init { init {
@@ -204,13 +205,13 @@ abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdir() {
override val memberScope: MemberScope override val memberScope: MemberScope
get() = scope get() = scope
override val fragments: List<PackageFragmentDescriptor> = listOf( override val fragments: List<PackageFragmentDescriptor> = listOf(
object : PackageFragmentDescriptorImpl(module, fqName) { object : PackageFragmentDescriptorImpl(module, fqName) {
override fun getMemberScope(): MemberScope = scope override fun getMemberScope(): MemberScope = scope
} }
) )
override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R = override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R =
visitor.visitPackageViewDescriptor(this, data) visitor.visitPackageViewDescriptor(this, data)
override fun getContainingDeclaration() = null override fun getContainingDeclaration() = null
override fun getOriginal() = throw UnsupportedOperationException() override fun getOriginal() = throw UnsupportedOperationException()
@@ -226,16 +227,23 @@ abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdir() {
init { init {
for (classifier in classifiers) { for (classifier in classifiers) {
classifierMap.put(classifier.name, classifier)?.let { classifierMap.put(classifier.name, classifier)?.let {
throw IllegalStateException(String.format("Redeclaration: %s (%s) and %s (%s) (no line info available)", throw IllegalStateException(
DescriptorUtils.getFqName(it), it, String.format(
DescriptorUtils.getFqName(classifier), classifier)) "Redeclaration: %s (%s) and %s (%s) (no line info available)",
DescriptorUtils.getFqName(it), it,
DescriptorUtils.getFqName(classifier), classifier
)
)
} }
} }
} }
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = classifierMap[name] override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = classifierMap[name]
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> = classifierMap.values override fun getContributedDescriptors(
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean
): Collection<DeclarationDescriptor> = classifierMap.values
override fun printScopeStructure(p: Printer) { override fun printScopeStructure(p: Printer) {
p.println("runtime descriptor loader test") p.println("runtime descriptor loader test")
@@ -244,4 +252,4 @@ abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdir() {
} }
private val LOG = Logger.getInstance(KotlinMultiFileTestWithJava::class.java) private val LOG = Logger.getInstance(KotlinMultiFileTestWithJava::class.java)