Load additional JDK functions into built-ins member scope

#KT-5990 Fixed
 #KT-7127 Fixed
 #KT-10370 Fixed
This commit is contained in:
Denis Zharkov
2016-04-06 16:35:50 +03:00
parent 137847e0c9
commit 5bc5722051
63 changed files with 3395 additions and 147 deletions
@@ -48,7 +48,15 @@ class JavaResolverComponents(
val packageMapper: PackagePartProvider,
val supertypeLoopChecker: SupertypeLoopChecker,
val lookupTracker: LookupTracker
)
) {
fun replace(
javaResolverCache: JavaResolverCache = this.javaResolverCache
) = JavaResolverComponents(
storageManager, finder, kotlinClassFinder, deserializedDescriptorResolver,
externalAnnotationResolver, signaturePropagator, errorReporter, javaResolverCache,
javaPropertyInitializerEvaluator, samConversionResolver, sourceElementFactory,
moduleClassResolver, packageMapper, supertypeLoopChecker, lookupTracker)
}
open class LazyJavaResolverContext(
val components: JavaResolverComponents,
@@ -68,6 +76,9 @@ fun LazyJavaResolverContext.child(
typeParameterResolver: TypeParameterResolver
) = LazyJavaResolverContext(components, packageFragmentProvider, javaClassResolver, module, reflectionTypes, typeParameterResolver)
fun LazyJavaResolverContext.replaceComponents(
components: JavaResolverComponents
) = LazyJavaResolverContext(components, packageFragmentProvider, javaClassResolver, module, reflectionTypes, typeParameterResolver)
fun LazyJavaResolverContext.child(
containingDeclaration: DeclarationDescriptor,
@@ -23,17 +23,17 @@ import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase
import org.jetbrains.kotlin.load.java.FakePureImplementationsProvider
import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.java.components.JavaResolverCache
import org.jetbrains.kotlin.load.java.components.TypeUsage
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.lazy.child
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
import org.jetbrains.kotlin.load.java.lazy.*
import org.jetbrains.kotlin.load.java.lazy.types.toAttributes
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaClassifierType
import org.jetbrains.kotlin.load.java.structure.JavaType
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.isValidJavaFqName
import org.jetbrains.kotlin.platform.createMappedTypeParametersSubstitution
import org.jetbrains.kotlin.resolve.constants.StringValue
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
@@ -48,7 +48,8 @@ import java.util.*
class LazyJavaClassDescriptor(
private val outerContext: LazyJavaResolverContext,
containingDeclaration: DeclarationDescriptor,
private val jClass: JavaClass
private val jClass: JavaClass,
private val additionalSupertypeClassDescriptor: ClassDescriptor? = null
) : ClassDescriptorBase(outerContext.storageManager, containingDeclaration, jClass.name,
outerContext.components.sourceElementFactory.source(jClass)), JavaClassDescriptor {
@@ -157,6 +158,14 @@ class LazyJavaClassDescriptor(
}
}
// Add fake supertype kotlin.collection.Collection<E> to java.util.Collection<E> class if needed
// Only needed when calculating built-ins member scope
result.addIfNotNull(
additionalSupertypeClassDescriptor?.let {
createMappedTypeParametersSubstitution(it, this@LazyJavaClassDescriptor)
.buildSubstitutor().substitute(it.defaultType, Variance.INVARIANT)
})
result.addIfNotNull(purelyImplementedSupertype)
if (incomplete.isNotEmpty()) {
@@ -213,4 +222,11 @@ class LazyJavaClassDescriptor(
override fun toString(): String = getName().asString()
}
// Only needed when calculating built-ins member scope
internal fun copy(
javaResolverCache: JavaResolverCache, additionalSupertypeClassDescriptor: ClassDescriptor?
) = LazyJavaClassDescriptor(
c.replaceComponents(c.components.replace(javaResolverCache = javaResolverCache)),
containingDeclaration, jClass, additionalSupertypeClassDescriptor)
}
@@ -82,7 +82,7 @@ class LazyJavaClassMemberScope(
result.add(descriptor)
result.addIfNotNull(c.components.samConversionResolver.resolveSamAdapter(descriptor))
}
enhanceSignatures(
result.ifEmpty { emptyOrSingletonList(createDefaultConstructor()) }
).toReadOnlyList()
@@ -346,10 +346,10 @@ class LazyJavaClassMemberScope(
}
private fun getFunctionsFromSupertypes(name: Name): Set<SimpleFunctionDescriptor> {
return ownerDescriptor.typeConstructor.supertypes.flatMapTo(LinkedHashSet()) {
it.memberScope.getContributedFunctions(name, NoLookupLocation.WHEN_GET_SUPER_MEMBERS)
}
}
return ownerDescriptor.typeConstructor.supertypes.flatMapTo(LinkedHashSet()) {
it.memberScope.getContributedFunctions(name, NoLookupLocation.WHEN_GET_SUPER_MEMBERS)
}
}
override fun computeNonDeclaredProperties(name: Name, result: MutableCollection<PropertyDescriptor>) {
if (jClass.isAnnotationType) {
@@ -17,28 +17,42 @@
package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.load.java.components.JavaResolverCache
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassMemberScope
import org.jetbrains.kotlin.load.java.lazy.replaceComponents
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.platform.JvmBuiltIns
import org.jetbrains.kotlin.platform.createMappedTypeParametersSubstitution
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.deserialization.AdditionalClassPartsProvider
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
import org.jetbrains.kotlin.types.DelegatingType
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.SmartSet
import org.jetbrains.kotlin.utils.addToStdlib.check
import java.io.Serializable
import java.util.*
class BuiltInClassesAreSerializableOnJvm(
private val moduleDescriptor: ModuleDescriptor
open class BuiltInClassesAreSerializableOnJvm(
private val moduleDescriptor: ModuleDescriptor,
deferredOwnerModuleDescriptor: () -> ModuleDescriptor
) : AdditionalClassPartsProvider {
private val ownerModuleDescriptor: ModuleDescriptor by lazy(deferredOwnerModuleDescriptor)
private val mockSerializableType = createMockJavaIoSerializableType()
private fun createMockJavaIoSerializableType(): KotlinType {
@@ -49,7 +63,7 @@ class BuiltInClassesAreSerializableOnJvm(
//NOTE: can't reference anyType right away, because this is sometimes called when JvmBuiltIns are initializing
val superTypes = listOf(object : DelegatingType() {
override fun getDelegate(): KotlinType {
return JvmBuiltIns.Instance.anyType
return moduleDescriptor.builtIns.anyType
}
})
@@ -68,6 +82,74 @@ class BuiltInClassesAreSerializableOnJvm(
else return listOf()
}
override fun getFunctions(name: Name, classDescriptor: DeserializedClassDescriptor): Collection<SimpleFunctionDescriptor> =
getAdditionalFunctions(classDescriptor) {
it.getContributedFunctions(name, NoLookupLocation.FROM_BUILTINS)
}
.map {
additionalMember ->
additionalMember.newCopyBuilder().apply {
setOwner(classDescriptor)
setDispatchReceiverParameter(classDescriptor.thisAsReceiverParameter)
setPreserveSourceElement()
setSubstitution(createMappedTypeParametersSubstitution(
additionalMember.containingDeclaration as ClassDescriptor, classDescriptor))
}.build()!!
}
override fun getFunctionsNames(classDescriptor: DeserializedClassDescriptor): Collection<Name> =
getAdditionalFunctions(classDescriptor) {
it.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS).filterIsInstance<SimpleFunctionDescriptor>()
}.map(SimpleFunctionDescriptor::getName)
private fun getAdditionalFunctions(
classDescriptor: DeserializedClassDescriptor,
functionsByScope: (MemberScope) -> Collection<SimpleFunctionDescriptor>
): Collection<SimpleFunctionDescriptor> {
// Prevents recursive dependency: memberScope(Any) -> memberScope(Object) -> memberScope(Any)
// No additional members should be added to Any
if (classDescriptor.isAny) return emptyList()
val fqName = classDescriptor.fqNameUnsafe.check { it.isSafe }?.toSafe() ?: return emptyList()
val j2kClassMap = JavaToKotlinClassMap.INSTANCE
val javaAnalogueFqName = j2kClassMap.mapKotlinToJava(fqName.toUnsafe())?.asSingleFqName() ?: return emptyList()
if (javaAnalogueFqName in IGNORE_BY_DEFAULT_CLASS_FQ_NAMES) return emptyList()
val javaAnalogueDescriptor =
ownerModuleDescriptor.resolveClassByFqName(javaAnalogueFqName, NoLookupLocation.FROM_BUILTINS) as? LazyJavaClassDescriptor
?: return emptyList()
val platformClassDescriptors = j2kClassMap.mapPlatformClass(javaAnalogueDescriptor.fqNameSafe, DefaultBuiltIns.Instance)
val kotlinMutableClassIfContainer = platformClassDescriptors.lastOrNull() ?: return emptyList()
val platformVersions = SmartSet.create(platformClassDescriptors.map { it.fqNameSafe })
val isMutable = j2kClassMap.isMutable(classDescriptor)
val fakeJavaClassDescriptor =
javaAnalogueDescriptor.copy(
javaResolverCache = JavaResolverCache.EMPTY,
additionalSupertypeClassDescriptor = kotlinMutableClassIfContainer)
val scope = fakeJavaClassDescriptor.unsubstitutedMemberScope
return functionsByScope(scope)
.filter { analogueMember ->
if (analogueMember.kind != CallableMemberDescriptor.Kind.DECLARATION) return@filter false
if (!analogueMember.visibility.isPublicAPI) return@filter false
val methodFqName = analogueMember.fqNameSafe
if (methodFqName in BLACK_LIST_METHODS_FQ_NAMES) return@filter false
if ((methodFqName in MUTABLE_METHODS_FQ_NAMES) xor isMutable) return@filter false
analogueMember.overriddenDescriptors.none {
it.containingDeclaration.fqNameSafe in platformVersions
}
}
}
companion object {
fun isSerializableInJava(classFqName: FqName): Boolean {
val fqNameUnsafe = classFqName.toUnsafe()
@@ -84,5 +166,35 @@ class BuiltInClassesAreSerializableOnJvm(
return Serializable::class.java.isAssignableFrom(classViaReflection)
}
private val IGNORE_BY_DEFAULT_CLASS_FQ_NAMES =
setOf(FqName("java.lang.String")) +
JvmPrimitiveType.values().map { it.wrapperFqName }
private val BLACK_LIST_METHODS_FQ_NAMES =
buildPrimitiveValueMethodsSet() +
FqName("java.util.Collection.toArray") +
FqName("java.util.List.toArray") +
FqName("java.util.Set.toArray") +
FqName("java.lang.annotation.Annotation.annotationType")
private val MUTABLE_METHODS_FQ_NAMES =
inClass("java.util.Collection",
"removeIf") +
inClass("java.util.List",
"sort", "replaceAll") +
inClass("java.util.Map",
"compute", "computeIfAbsent", "computeIfPresent", "remove", "merge", "putIfAbsent", "replace", "replaceAll")
private fun buildPrimitiveValueMethodsSet() =
JvmPrimitiveType.values().mapTo(LinkedHashSet()) {
it.wrapperFqName.child(Name.identifier(it.javaKeywordName + "Value"))
}
private fun inClass(classFqName: String, vararg names: String) =
names.mapTo(LinkedHashSet()) { FqName(classFqName).child(Name.identifier(it)) }
}
}
}
private val ClassDescriptor.isAny: Boolean get() = fqNameUnsafe == KotlinBuiltIns.FQ_NAMES.any
@@ -43,7 +43,7 @@ class DeserializationComponentsForJava(
storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider, localClassResolver,
errorReporter, lookupTracker, FlexibleJavaClassifierTypeFactory, ClassDescriptorFactory.EMPTY,
notFoundClasses, JavaTypeCapabilitiesLoader,
additionalClassPartsProvider = BuiltInClassesAreSerializableOnJvm(moduleDescriptor)
additionalClassPartsProvider = BuiltInClassesAreSerializableOnJvm(moduleDescriptor, { moduleDescriptor })
)
localClassResolver.setDeserializationComponents(components)
}
@@ -16,23 +16,25 @@
package org.jetbrains.kotlin.platform
import org.jetbrains.kotlin.builtins.BuiltInsInitializer
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.load.kotlin.BuiltInClassesAreSerializableOnJvm
import org.jetbrains.kotlin.serialization.deserialization.AdditionalClassPartsProvider
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.utils.sure
class JvmBuiltIns private constructor() : KotlinBuiltIns() {
companion object {
private val initializer = BuiltInsInitializer {
JvmBuiltIns()
}
class JvmBuiltIns(storageManager: StorageManager) : KotlinBuiltIns(storageManager) {
// Module containing JDK classes or having them among dependencies
private var ownerModuleDescriptor: ModuleDescriptor? = null
@JvmStatic
val Instance: KotlinBuiltIns
get() = initializer.get()
fun setOwnerModuleDescriptor(moduleDescriptor: ModuleDescriptor) {
assert(ownerModuleDescriptor == null) { "JvmBuiltins repeated initialization" }
this.ownerModuleDescriptor = moduleDescriptor
}
override fun getAdditionalClassPartsProvider(): AdditionalClassPartsProvider {
return BuiltInClassesAreSerializableOnJvm(builtInsModule)
return BuiltInClassesAreSerializableOnJvm(builtInsModule, {
ownerModuleDescriptor.sure { "JvmBuiltins has not been initialized properly" }
})
}
}
}
@@ -0,0 +1,34 @@
/*
* 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.platform
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.types.TypeConstructorSubstitution
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
fun createMappedTypeParametersSubstitution(from: ClassDescriptor, to: ClassDescriptor): TypeConstructorSubstitution {
assert(from.declaredTypeParameters.size == to.declaredTypeParameters.size) {
"$from and $to should have same number of type parameters, " +
"but ${from.declaredTypeParameters.size} / ${to.declaredTypeParameters.size} found"
}
return TypeConstructorSubstitution.createByConstructorsMap(
from.declaredTypeParameters.map(TypeParameterDescriptor::getTypeConstructor).zip(
to.declaredTypeParameters.map { it.defaultType.asTypeProjection() }
).toMap())
}
@@ -46,8 +46,8 @@ class RuntimeModuleData private constructor(val deserialization: Deserialization
companion object {
fun create(classLoader: ClassLoader): RuntimeModuleData {
val builtIns = JvmBuiltIns.Instance
val storageManager = LockBasedStorageManager()
val builtIns = JvmBuiltIns(storageManager)
val module = ModuleDescriptorImpl(Name.special("<runtime module for $classLoader>"), storageManager,
ModuleParameters(listOf(), JavaToKotlinClassMap.INSTANCE), builtIns)
@@ -64,6 +64,9 @@ class RuntimeModuleData private constructor(val deserialization: Deserialization
val lazyJavaPackageFragmentProvider =
LazyJavaPackageFragmentProvider(globalJavaResolverContext, module, ReflectionTypes(module))
builtIns.setOwnerModuleDescriptor(module)
val javaDescriptorResolver = JavaDescriptorResolver(lazyJavaPackageFragmentProvider)
val javaClassDataFinder = JavaClassDataFinder(reflectKotlinClassFinder, deserializedDescriptorResolver)
val notFoundClasses = NotFoundClasses(storageManager, module)
@@ -16,7 +16,9 @@
package org.jetbrains.kotlin.builtins
class DefaultBuiltIns private constructor() : KotlinBuiltIns() {
import org.jetbrains.kotlin.storage.LockBasedStorageManager
class DefaultBuiltIns private constructor() : KotlinBuiltIns(LockBasedStorageManager()) {
companion object {
private val initializer = BuiltInsInitializer {
DefaultBuiltIns()
@@ -32,7 +32,7 @@ import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
import org.jetbrains.kotlin.serialization.deserialization.AdditionalClassPartsProvider;
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
import org.jetbrains.kotlin.storage.StorageManager;
import org.jetbrains.kotlin.types.*;
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
@@ -71,12 +71,10 @@ public abstract class KotlinBuiltIns {
private final Map<PrimitiveType, KotlinType> primitiveTypeToArrayKotlinType;
private final Map<KotlinType, KotlinType> primitiveKotlinTypeToKotlinArrayType;
private final Map<KotlinType, KotlinType> kotlinArrayTypeToPrimitiveKotlinType;
private final Map<FqName, PackageFragmentDescriptor> packageNameToPackageFragment;
public static final FqNames FQ_NAMES = new FqNames();
protected KotlinBuiltIns() {
LockBasedStorageManager storageManager = new LockBasedStorageManager();
protected KotlinBuiltIns(@NotNull StorageManager storageManager) {
builtInsModule = new ModuleDescriptorImpl(
Name.special("<built-ins module>"), storageManager, ModuleParameters.Empty.INSTANCE, this
);
@@ -96,7 +94,7 @@ public abstract class KotlinBuiltIns {
builtInsModule.initialize(packageFragmentProvider);
builtInsModule.setDependencies(builtInsModule);
packageNameToPackageFragment = new LinkedHashMap<FqName, PackageFragmentDescriptor>();
Map<FqName, PackageFragmentDescriptor> packageNameToPackageFragment = new LinkedHashMap<FqName, PackageFragmentDescriptor>();
builtInsPackageFragment = createPackage(packageFragmentProvider, packageNameToPackageFragment, BUILT_INS_PACKAGE_FQ_NAME);
collectionsPackageFragment = createPackage(packageFragmentProvider, packageNameToPackageFragment, COLLECTIONS_PACKAGE_FQ_NAME);
@@ -290,23 +288,7 @@ public abstract class KotlinBuiltIns {
@Nullable
public ClassDescriptor getBuiltInClassByFqNameNullable(@NotNull FqName fqName) {
if (!fqName.isRoot()) {
FqName parent = fqName.parent();
PackageFragmentDescriptor packageFragment = packageNameToPackageFragment.get(parent);
if (packageFragment != null) {
ClassDescriptor descriptor = getBuiltInClassByNameNullable(fqName.shortName(), packageFragment);
if (descriptor != null) {
return descriptor;
}
}
ClassDescriptor possiblyOuterClass = getBuiltInClassByFqNameNullable(parent);
if (possiblyOuterClass != null) {
return (ClassDescriptor) possiblyOuterClass.getUnsubstitutedInnerClassesScope().getContributedClassifier(
fqName.shortName(), NoLookupLocation.FROM_BUILTINS);
}
}
return null;
return DescriptorUtilKt.resolveClassByFqName(builtInsModule, fqName, NoLookupLocation.FROM_BUILTINS);
}
@NotNull
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeSubstitution;
import org.jetbrains.kotlin.types.TypeSubstitutor;
import java.util.Collection;
@@ -109,6 +110,9 @@ public interface FunctionDescriptor extends CallableMemberDescriptor {
@NotNull
CopyBuilder<D> setExtensionReceiverType(@Nullable KotlinType type);
@NotNull
CopyBuilder<D> setDispatchReceiverParameter(@Nullable ReceiverParameterDescriptor dispatchReceiverParameter);
@NotNull
CopyBuilder<D> setOriginal(@NotNull FunctionDescriptor original);
@@ -124,6 +128,9 @@ public interface FunctionDescriptor extends CallableMemberDescriptor {
@NotNull
CopyBuilder<D> setHiddenToOvercomeSignatureClash();
@NotNull
CopyBuilder<D> setSubstitution(@NotNull TypeSubstitution substitution);
@Nullable
D build();
}
@@ -0,0 +1,31 @@
/*
* 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.descriptors
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.FqName
fun ModuleDescriptor.resolveClassByFqName(fqName: FqName, lookupLocation: LookupLocation): ClassDescriptor? {
if (fqName.isRoot) return null
(getPackage(fqName.parent())
.memberScope.getContributedClassifier(fqName.shortName(), lookupLocation) as? ClassDescriptor)?.let { return it }
return resolveClassByFqName(fqName.parent(), lookupLocation)
?.unsubstitutedInnerClassesScope
?.getContributedClassifier(fqName.shortName(), lookupLocation) as? ClassDescriptor
}
@@ -299,6 +299,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
protected @NotNull Kind kind;
protected @NotNull List<ValueParameterDescriptor> newValueParameterDescriptors;
protected @Nullable KotlinType newExtensionReceiverParameterType;
protected @Nullable ReceiverParameterDescriptor dispatchReceiverParameter;
protected @NotNull KotlinType newReturnType;
protected @Nullable Name name;
protected boolean copyOverrides = true;
@@ -326,6 +327,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
this.kind = kind;
this.newValueParameterDescriptors = newValueParameterDescriptors;
this.newExtensionReceiverParameterType = newExtensionReceiverParameterType;
this.dispatchReceiverParameter = FunctionDescriptorImpl.this.dispatchReceiverParameter;
this.newReturnType = newReturnType;
this.name = name;
this.isHiddenToOvercomeSignatureClash = isHiddenToOvercomeSignatureClash();
@@ -401,6 +403,13 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
return this;
}
@Override
@NotNull
public CopyConfiguration setDispatchReceiverParameter(@Nullable ReceiverParameterDescriptor dispatchReceiverParameter) {
this.dispatchReceiverParameter = dispatchReceiverParameter;
return this;
}
@Override
@NotNull
public CopyConfiguration setOriginal(@NotNull FunctionDescriptor original) {
@@ -436,6 +445,13 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
return this;
}
@NotNull
@Override
public CopyConfiguration setSubstitution(@NotNull TypeSubstitution substitution) {
this.substitution = substitution;
return this;
}
@Override
@Nullable
public FunctionDescriptor build() {
@@ -498,7 +514,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
}
ReceiverParameterDescriptor substitutedExpectedThis = null;
if (dispatchReceiverParameter != null) {
if (configuration.dispatchReceiverParameter != null) {
// When generating fake-overridden member it's dispatch receiver parameter has type of Base, and it's correct.
// E.g.
// class Base { fun foo() }
@@ -509,7 +525,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
// // but it would if fake-overridden `foo` had `Derived` as it's dispatch receiver parameter type
// x.foo()
// }
substitutedExpectedThis = dispatchReceiverParameter.substitute(substitutor);
substitutedExpectedThis = configuration.dispatchReceiverParameter.substitute(substitutor);
if (substitutedExpectedThis == null) {
return null;
}
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.types.ErrorUtils;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeSubstitution;
import java.util.Collection;
import java.util.List;
@@ -103,6 +104,12 @@ public class ErrorSimpleFunctionDescriptorImpl extends SimpleFunctionDescriptorI
return this;
}
@NotNull
@Override
public CopyBuilder<SimpleFunctionDescriptor> setSubstitution(@NotNull TypeSubstitution substitution) {
return this;
}
@NotNull
@Override
public CopyBuilder<SimpleFunctionDescriptor> setTypeParameters(@NotNull List<TypeParameterDescriptor> parameters) {
@@ -121,6 +128,12 @@ public class ErrorSimpleFunctionDescriptorImpl extends SimpleFunctionDescriptorI
return this;
}
@NotNull
@Override
public CopyBuilder<SimpleFunctionDescriptor> setDispatchReceiverParameter(@Nullable ReceiverParameterDescriptor dispatchReceiverParameter) {
return this;
}
@NotNull
@Override
public CopyBuilder<SimpleFunctionDescriptor> setOriginal(@NotNull FunctionDescriptor original) {
@@ -16,13 +16,19 @@
package org.jetbrains.kotlin.serialization.deserialization
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
import org.jetbrains.kotlin.types.KotlinType
interface AdditionalClassPartsProvider {
fun getSupertypes(classDescriptor: DeserializedClassDescriptor): Collection<KotlinType>
fun getFunctions(name: Name, classDescriptor: DeserializedClassDescriptor): Collection<SimpleFunctionDescriptor>
fun getFunctionsNames(classDescriptor: DeserializedClassDescriptor): Collection<Name>
object None : AdditionalClassPartsProvider {
override fun getSupertypes(classDescriptor: DeserializedClassDescriptor): Collection<KotlinType> = emptyList()
override fun getFunctions(name: Name, classDescriptor: DeserializedClassDescriptor): Collection<SimpleFunctionDescriptor> = emptyList()
override fun getFunctionsNames(classDescriptor: DeserializedClassDescriptor): Collection<Name> = emptyList()
}
}
@@ -199,6 +199,8 @@ class DeserializedClassDescriptor(
for (supertype in classDescriptor.getTypeConstructor().supertypes) {
fromSupertypes.addAll(supertype.memberScope.getContributedFunctions(name, NoLookupLocation.FOR_ALREADY_TRACKED))
}
functions.addAll(c.components.additionalClassPartsProvider.getFunctions(name, this@DeserializedClassDescriptor))
generateFakeOverrides(name, fromSupertypes, functions)
}
@@ -229,7 +231,7 @@ class DeserializedClassDescriptor(
override fun getNonDeclaredFunctionNames(location: LookupLocation): Set<Name> {
return classDescriptor.typeConstructor.supertypes.flatMapTo(LinkedHashSet()) {
it.memberScope.getContributedDescriptors().filterIsInstance<SimpleFunctionDescriptor>().map { it.name }
}
} + c.components.additionalClassPartsProvider.getFunctionsNames(this@DeserializedClassDescriptor)
}
override fun getNonDeclaredVariableNames(location: LookupLocation): Set<Name> {
@@ -33,7 +33,7 @@ class SmartSet<T> private constructor() : AbstractSet<T>() {
fun <T> create() = SmartSet<T>()
@JvmStatic
fun <T> create(set: Set<T>) = SmartSet<T>().apply { this.addAll(set) }
fun <T> create(set: Collection<T>) = SmartSet<T>().apply { this.addAll(set) }
}
// null if size = 0, object if size = 1, array of objects if size < threshold, linked hash set otherwise