KT-11588 Type aliases

Deserialization
This commit is contained in:
Dmitry Petrov
2016-05-17 18:08:07 +03:00
parent f296b17861
commit 32f61c3918
30 changed files with 348 additions and 101 deletions
@@ -46,7 +46,7 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfoFactory;
import org.jetbrains.kotlin.resolve.dataClassUtils.DataClassUtilsKt;
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
import org.jetbrains.kotlin.resolve.lazy.descriptors.TypeAliasDescriptorImpl;
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyTypeAliasDescriptor;
import org.jetbrains.kotlin.resolve.scopes.*;
import org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt;
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
@@ -688,7 +688,7 @@ public class DescriptorResolver {
Annotations allAnnotations = annotationResolver.resolveAnnotationsWithArguments(scope, modifierList, trace);
Name name = KtPsiUtil.safeName(typeAlias.getName());
SourceElement sourceElement = KotlinSourceElementKt.toSourceElement(typeAlias);
TypeAliasDescriptorImpl typeAliasDescriptor = TypeAliasDescriptorImpl.create(
LazyTypeAliasDescriptor typeAliasDescriptor = LazyTypeAliasDescriptor.create(
containingDeclaration, allAnnotations, name, sourceElement, visibility);
List<TypeParameterDescriptorImpl> typeParameterDescriptors;
@@ -484,15 +484,6 @@ class TypeResolver(
}
}
private class AbbreviatedTypeImpl(override val abbreviatedType: KotlinType): AbbreviatedType
private fun KotlinType.withAbbreviatedType(abbreviatedType: KotlinType): KotlinType =
if (isError)
this
else
replace(newCapabilities = capabilities.overrideCapability(AbbreviatedType::class.java,
AbbreviatedTypeImpl(abbreviatedType)))
private class TypeAliasExpansion(
val parent: TypeAliasExpansion?,
val descriptor: TypeAliasDescriptor,
@@ -0,0 +1,61 @@
/*
* 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.resolve.lazy.descriptors
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.NotNullLazyValue
import org.jetbrains.kotlin.types.KotlinType
class LazyTypeAliasDescriptor(
containingDeclaration: DeclarationDescriptor,
annotations: Annotations,
name: Name,
sourceElement: SourceElement,
visibility: Visibility
) : AbstractTypeAliasDescriptor(containingDeclaration, annotations, name, sourceElement, visibility),
TypeAliasDescriptor {
private lateinit var underlyingTypeImpl: NotNullLazyValue<KotlinType>
private lateinit var expandedTypeImpl: NotNullLazyValue<KotlinType>
override val underlyingType: KotlinType get() = underlyingTypeImpl()
override val expandedType: KotlinType get() = expandedTypeImpl()
fun initialize(
declaredTypeParameters: List<TypeParameterDescriptor>,
lazyUnderlyingType: NotNullLazyValue<KotlinType>,
lazyExpandedType: NotNullLazyValue<KotlinType>
) {
super.initialize(declaredTypeParameters)
this.underlyingTypeImpl = lazyUnderlyingType
this.expandedTypeImpl = lazyExpandedType
}
companion object {
@JvmStatic fun create(
containingDeclaration: DeclarationDescriptor,
annotations: Annotations,
name: Name,
sourceElement: SourceElement,
visibility: Visibility
): LazyTypeAliasDescriptor =
LazyTypeAliasDescriptor(containingDeclaration, annotations, name, sourceElement, visibility)
}
}
@@ -380,6 +380,14 @@ public class DescriptorSerializer {
builder.setUnderlyingType(type(underlyingType));
}
KotlinType expandedType = descriptor.getExpandedType();
if (useTypeTable()) {
builder.setExpandedTypeId(typeId(expandedType));
}
else {
builder.setExpandedType(type(expandedType));
}
return builder;
}
@@ -535,6 +543,16 @@ public class DescriptorSerializer {
builder.setNullable(type.isMarkedNullable());
}
KotlinType abbreviatedType = TypeCapabilitiesKt.getAbbreviatedType(type);
if (abbreviatedType != null) {
if (useTypeTable()) {
builder.setAbbreviatedTypeId(typeId(abbreviatedType));
}
else {
builder.setAbbreviatedType(type(abbreviatedType));
}
}
extension.serializeType(type, builder);
return builder;
@@ -549,7 +567,7 @@ public class DescriptorSerializer {
if (classifierDescriptor instanceof ClassDescriptor) {
builder.setClassName(classifierId);
}
else {
else if (classifierDescriptor instanceof TypeAliasDescriptor) {
builder.setTypeAliasName(classifierId);
}
@@ -38,7 +38,7 @@ class DeserializationComponentsForJava(
val components: DeserializationComponents
init {
val localClassResolver = LocalClassResolverImpl()
val localClassResolver = LocalClassifierResolverImpl()
val settings = JvmBuiltInsSettings(moduleDescriptor, storageManager, { moduleDescriptor })
components = DeserializationComponents(
storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider, localClassResolver,
@@ -36,13 +36,13 @@ import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.platform.JvmBuiltIns
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
import org.jetbrains.kotlin.serialization.deserialization.LocalClassResolver
import org.jetbrains.kotlin.serialization.deserialization.LocalClassifierResolver
import org.jetbrains.kotlin.serialization.deserialization.NotFoundClasses
import org.jetbrains.kotlin.storage.LockBasedStorageManager
class RuntimeModuleData private constructor(val deserialization: DeserializationComponents, val packageFacadeProvider: RuntimePackagePartProvider) {
val module: ModuleDescriptor get() = deserialization.moduleDescriptor
val localClassResolver: LocalClassResolver get() = deserialization.localClassResolver
val localClassifierResolver: LocalClassifierResolver get() = deserialization.localClassifierResolver
companion object {
fun create(classLoader: ClassLoader): RuntimeModuleData {
@@ -41,7 +41,7 @@ fun createBuiltInPackageFragmentProvider(
val provider = PackageFragmentProviderImpl(packageFragments)
val notFoundClasses = NotFoundClasses(storageManager, module)
val localClassResolver = LocalClassResolverImpl()
val localClassResolver = LocalClassifierResolverImpl()
val components = DeserializationComponents(
storageManager,
@@ -14,48 +14,31 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.resolve.lazy.descriptors
package org.jetbrains.kotlin.descriptors.impl
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorNonRootImpl
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.storage.NotNullLazyValue
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.TypeSubstitutor
class TypeAliasDescriptorImpl(
abstract class AbstractTypeAliasDescriptor(
containingDeclaration: DeclarationDescriptor,
annotations: Annotations,
name: Name,
sourceElement: SourceElement,
private val fVisibility: Visibility
private val visibilityImpl: Visibility
) : DeclarationDescriptorNonRootImpl(containingDeclaration, annotations, name, sourceElement),
TypeAliasDescriptor {
// TODO kotlinize some interfaces
private lateinit var declaredTypeParametersImpl: List<TypeParameterDescriptor>
private lateinit var underlyingTypeImpl: NotNullLazyValue<KotlinType>
private lateinit var expandedTypeImpl: NotNullLazyValue<KotlinType>
override val underlyingType: KotlinType get() = underlyingTypeImpl()
override val expandedType: KotlinType get() = expandedTypeImpl()
fun initialize(
declaredTypeParameters: List<TypeParameterDescriptor>,
lazyUnderlyingType: NotNullLazyValue<KotlinType>,
lazyExpandedType: NotNullLazyValue<KotlinType>
) {
fun initialize(declaredTypeParameters: List<TypeParameterDescriptor>) {
this.declaredTypeParametersImpl = declaredTypeParameters
this.underlyingTypeImpl = lazyUnderlyingType
this.expandedTypeImpl = lazyExpandedType
}
override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R =
@@ -73,7 +56,7 @@ class TypeAliasDescriptorImpl(
override fun getModality() = Modality.FINAL
override fun getVisibility() = fVisibility
override fun getVisibility() = visibilityImpl
override fun substitute(substitutor: TypeSubstitutor): TypeAliasDescriptor =
if (substitutor.isEmpty) this
@@ -89,7 +72,7 @@ class TypeAliasDescriptorImpl(
private val typeConstructor = object : TypeConstructor {
override fun getDeclarationDescriptor(): TypeAliasDescriptor =
this@TypeAliasDescriptorImpl
this@AbstractTypeAliasDescriptor
override fun getParameters(): List<TypeParameterDescriptor> =
declarationDescriptor.declaredTypeParameters // TODO type parameters of outer class
@@ -110,14 +93,4 @@ class TypeAliasDescriptorImpl(
declarationDescriptor.annotations
}
companion object {
@JvmStatic fun create(
containingDeclaration: DeclarationDescriptor,
annotations: Annotations,
name: Name,
sourceElement: SourceElement,
visibility: Visibility
): TypeAliasDescriptorImpl =
TypeAliasDescriptorImpl(containingDeclaration, annotations, name, sourceElement, visibility)
}
}
@@ -74,20 +74,20 @@ fun KotlinType.buildPossiblyInnerType(): PossiblyInnerType? {
return buildPossiblyInnerType(constructor.declarationDescriptor as? ClassifierDescriptorWithTypeParameters, 0)
}
private fun KotlinType.buildPossiblyInnerType(classDescriptor: ClassifierDescriptorWithTypeParameters?, index: Int): PossiblyInnerType? {
if (classDescriptor == null || ErrorUtils.isError(classDescriptor)) return null
private fun KotlinType.buildPossiblyInnerType(classifierDescriptor: ClassifierDescriptorWithTypeParameters?, index: Int): PossiblyInnerType? {
if (classifierDescriptor == null || ErrorUtils.isError(classifierDescriptor)) return null
val toIndex = classDescriptor.declaredTypeParameters.size + index
if (!classDescriptor.isInner) {
assert(toIndex == arguments.size || DescriptorUtils.isLocal(classDescriptor)) {
val toIndex = classifierDescriptor.declaredTypeParameters.size + index
if (!classifierDescriptor.isInner) {
assert(toIndex == arguments.size || DescriptorUtils.isLocal(classifierDescriptor)) {
"${arguments.size - toIndex} trailing arguments were found in $this type"
}
return PossiblyInnerType(classDescriptor, arguments.subList(index, arguments.size), null)
return PossiblyInnerType(classifierDescriptor, arguments.subList(index, arguments.size), null)
}
val argumentsSubList = arguments.subList(index, toIndex)
return PossiblyInnerType(
classDescriptor, argumentsSubList,
buildPossiblyInnerType(classDescriptor.containingDeclaration as? ClassifierDescriptorWithTypeParameters, toIndex))
classifierDescriptor, argumentsSubList,
buildPossiblyInnerType(classifierDescriptor.containingDeclaration as? ClassifierDescriptorWithTypeParameters, toIndex))
}
@@ -128,7 +128,7 @@ internal class DescriptorRendererImpl(
}
private fun renderNormalizedType(type: KotlinType): String {
val abbreviated = type.getCapability(AbbreviatedType::class.java)?.abbreviatedType
val abbreviated = type.getAbbreviatedType()
if (abbreviated != null) {
// TODO nullability is lost for abbreviated type?
@@ -102,3 +102,11 @@ fun KotlinType.hasAbbreviatedType(): Boolean =
fun KotlinType.getAbbreviatedType(): KotlinType? =
getCapability(AbbreviatedType::class.java)?.abbreviatedType
private class AbbreviatedTypeImpl(override val abbreviatedType: KotlinType): AbbreviatedType
fun TypeCapabilities.withAbbreviatedType(abbreviatedType: KotlinType): TypeCapabilities =
overrideCapability(AbbreviatedType::class.java, AbbreviatedTypeImpl(abbreviatedType))
fun KotlinType.withAbbreviatedType(abbreviatedType: KotlinType): KotlinType =
if (!isError) replace(newCapabilities = capabilities.withAbbreviatedType(abbreviatedType)) else this
@@ -20,10 +20,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedAnnotationsWithPossibleTargets
import org.jetbrains.kotlin.types.AbstractLazyType
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.LazyType
import org.jetbrains.kotlin.types.TypeCapabilities
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.utils.toReadOnlyList
class DeserializedType(
@@ -59,6 +56,15 @@ class DeserializedType(
override val capabilities: TypeCapabilities get() = typeCapabilities()
private val typeCapabilities = c.storageManager.createLazyValue {
c.components.typeCapabilitiesLoader.loadCapabilities(typeProto)
val deserializedCapabilities = c.components.typeCapabilitiesLoader.loadCapabilities(typeProto)
val abbreviatedTypeProto = typeProto.abbreviatedType(c.typeTable)
if (abbreviatedTypeProto == null) {
deserializedCapabilities
}
else {
val abbreviatedType = c.typeDeserializer.type(abbreviatedTypeProto, additionalAnnotations)
deserializedCapabilities.withAbbreviatedType(abbreviatedType)
}
}
}
@@ -17,8 +17,10 @@
package org.jetbrains.kotlin.serialization.deserialization
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.name.ClassId
interface LocalClassResolver {
interface LocalClassifierResolver {
fun resolveLocalClass(classId: ClassId): ClassDescriptor?
fun resolveLocalTypeAlias(typeAliasId: ClassId): ClassifierDescriptor?
}
@@ -17,11 +17,13 @@
package org.jetbrains.kotlin.serialization.deserialization
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.name.ClassId
import javax.inject.Inject
import kotlin.properties.Delegates
class LocalClassResolverImpl : LocalClassResolver {
class LocalClassifierResolverImpl : LocalClassifierResolver {
var components: DeserializationComponents by Delegates.notNull()
// component dependency cycle
@@ -32,4 +34,8 @@ class LocalClassResolverImpl : LocalClassResolver {
override fun resolveLocalClass(classId: ClassId): ClassDescriptor? {
return components.deserializeClass(classId)
}
override fun resolveLocalTypeAlias(typeAliasId: ClassId): ClassifierDescriptor? {
return components.deserializeTypeAlias(typeAliasId)
}
}
@@ -167,6 +167,25 @@ class MemberDeserializer(private val c: DeserializationContext) {
return function
}
fun loadTypeAlias(proto: ProtoBuf.TypeAlias): TypeAliasDescriptor {
val annotations = Annotations.EMPTY // TODO generate & load type alias annotations
val visibility = Deserialization.visibility(Flags.VISIBILITY.get(proto.flags))
val typeAlias = DeserializedTypeAliasDescriptor(
c.containingDeclaration, annotations, c.nameResolver.getName(proto.name),
visibility, proto, c.nameResolver, c.typeTable, c.containerSource
)
val local = c.childContext(typeAlias, proto.typeParameterList)
typeAlias.initialize(
local.typeDeserializer.ownTypeParameters,
local.typeDeserializer.type(proto.underlyingType(c.typeTable)),
local.typeDeserializer.type(proto.expandedType(c.typeTable))
)
return typeAlias
}
private fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? {
return (c.containingDeclaration as? ClassDescriptor)?.thisAsReceiverParameter
}
@@ -0,0 +1,38 @@
/*
* 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.serialization.deserialization
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.ClassId
class TypeAliasDeserializer(private val components: DeserializationComponents) {
fun deserializeTypeAlias(typeAliasId: ClassId): TypeAliasDescriptor? {
val parentScope = if (typeAliasId.isNestedClass) {
val outerClass = components.classDeserializer.deserializeClass(typeAliasId.outerClassId) ?: return null
outerClass.unsubstitutedMemberScope
}
else {
val packageFragment = components.packageFragmentProvider.getPackageFragments(typeAliasId.packageFqName).single()
packageFragment.getMemberScope()
}
return parentScope.getContributedClassifier(typeAliasId.shortClassName, NoLookupLocation.FROM_DESERIALIZATION) as? TypeAliasDescriptor
}
}
@@ -16,9 +16,7 @@
package org.jetbrains.kotlin.serialization.deserialization
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedTypeParameterDescriptor
@@ -36,6 +34,10 @@ class TypeDeserializer(
fqNameIndex -> computeClassDescriptor(fqNameIndex)
}
private val typeAliasDescriptors: (Int) -> ClassifierDescriptor? = c.storageManager.createMemoizedFunctionWithNullableValues {
fqNameIndex -> computeTypeAliasDescriptor(fqNameIndex)
}
private val typeParameterDescriptors = c.storageManager.createLazyValue {
if (typeParameterProtos.isEmpty()) {
mapOf<Int, TypeParameterDescriptor>()
@@ -88,6 +90,10 @@ class TypeDeserializer(
val parameter = typeParameters.find { it.name.asString() == name }
parameter?.typeConstructor ?: ErrorUtils.createErrorType("Deserialized type parameter $name in $container").constructor
}
proto.hasTypeAliasName() -> {
typeAliasDescriptors(proto.typeAliasName)?.typeConstructor
?: TODO("not found type aliases")
}
else -> ErrorUtils.createErrorType("Unknown type").constructor
}
@@ -99,11 +105,21 @@ class TypeDeserializer(
val id = c.nameResolver.getClassId(fqNameIndex)
if (id.isLocal) {
// Local classes can't be found in scopes
return c.components.localClassResolver.resolveLocalClass(id)
return c.components.localClassifierResolver.resolveLocalClass(id)
}
return c.components.moduleDescriptor.findClassAcrossModuleDependencies(id)
}
private fun computeTypeAliasDescriptor(fqNameIndex: Int): ClassifierDescriptor? {
val id = c.nameResolver.getClassId(fqNameIndex)
return if (id.isLocal) {
c.components.localClassifierResolver.resolveLocalTypeAlias(id)
}
else {
c.components.moduleDescriptor.findTypeAliasAcrossModuleDependencies(id)
}
}
fun typeArgument(parameter: TypeParameterDescriptor?, typeArgumentProto: ProtoBuf.Type.Argument): TypeProjection {
if (typeArgumentProto.projection == ProtoBuf.Type.Argument.Projection.STAR) {
return if (parameter == null)
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.TypeAliasDeserializer
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.FlexibleTypeFactory
@@ -32,7 +33,7 @@ class DeserializationComponents(
val classDataFinder: ClassDataFinder,
val annotationAndConstantLoader: AnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>, AnnotationWithTarget>,
val packageFragmentProvider: PackageFragmentProvider,
val localClassResolver: LocalClassResolver,
val localClassifierResolver: LocalClassifierResolver,
val errorReporter: ErrorReporter,
val lookupTracker: LookupTracker,
val flexibleTypeFactory: FlexibleTypeFactory,
@@ -43,6 +44,7 @@ class DeserializationComponents(
val platformDependentDeclarationFilter: PlatformDependentDeclarationFilter = PlatformDependentDeclarationFilter.All
) {
val classDeserializer: ClassDeserializer = ClassDeserializer(this)
val typeAliasDeserializer: TypeAliasDeserializer = TypeAliasDeserializer(this)
fun deserializeClass(classId: ClassId): ClassDescriptor? = classDeserializer.deserializeClass(classId)
@@ -54,6 +56,8 @@ class DeserializationComponents(
): DeserializationContext =
DeserializationContext(this, nameResolver, descriptor, typeTable, containerSource,
parentTypeDeserializer = null, typeParameters = listOf())
fun deserializeTypeAlias(typeAliasId: ClassId): TypeAliasDescriptor? = typeAliasDeserializer.deserializeTypeAlias(typeAliasId)
}
@@ -65,6 +65,7 @@ class DeserializedClassDescriptor(
private val containingDeclaration = outerContext.containingDeclaration
private val primaryConstructor = c.storageManager.createNullableLazyValue { computePrimaryConstructor() }
private val constructors = c.storageManager.createLazyValue { computeConstructors() }
private val nestedTypeAliases = c.storageManager.createLazyValue { computeTypeAliases() }
private val companionObjectDescriptor = c.storageManager.createNullableLazyValue { computeCompanionObjectDescriptor() }
internal val thisAsProtoContainer: ProtoContainer.Class = ProtoContainer.Class(
@@ -123,6 +124,11 @@ class DeserializedClassDescriptor(
c.memberDeserializer.loadConstructor(it, false)
}
private fun computeTypeAliases(): List<TypeAliasDescriptor> =
classProto.typeAliasList.map {
c.memberDeserializer.loadTypeAlias(it)
}
override fun getConstructors() = constructors()
private fun computeCompanionObjectDescriptor(): ClassDescriptor? {
@@ -185,7 +191,9 @@ class DeserializedClassDescriptor(
get() = SupertypeLoopChecker.EMPTY
}
private inner class DeserializedClassMemberScope : DeserializedMemberScope(c, classProto.functionList, classProto.propertyList) {
private inner class DeserializedClassMemberScope : DeserializedMemberScope(
c, classProto.functionList, classProto.propertyList, classProto.typeAliasList
) {
private val classDescriptor: DeserializedClassDescriptor get() = this@DeserializedClassDescriptor
private val allDescriptors = c.storageManager.createLazyValue {
computeDescriptors(DescriptorKindFilter.ALL, MemberScope.ALL_NAME_FILTER, NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS)
@@ -255,13 +263,21 @@ class DeserializedClassDescriptor(
}
}
override fun getNonDeclaredTypeAliasNames(location: LookupLocation): Set<Name> {
return classDescriptor.typeConstructor.supertypes.flatMapTo(LinkedHashSet()) {
it.memberScope.getContributedDescriptors().filterIsInstance<TypeAliasDescriptor>().map { it.name }
}
}
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
recordLookup(name, location)
return classDescriptor.enumEntries?.findEnumEntry(name) ?: classDescriptor.nestedClasses?.findNestedClass(name)
}
override fun addClassDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean) {
override fun addClassifierDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean) {
result.addAll(classDescriptor.nestedClasses?.all().orEmpty())
result.addAll(classDescriptor.nestedTypeAliases())
// TODO non-declared type aliases
}
override fun addEnumEntryDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean) {
@@ -19,16 +19,14 @@ package org.jetbrains.kotlin.serialization.deserialization.descriptors
import com.google.protobuf.MessageLite
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ConstructorDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
import org.jetbrains.kotlin.types.KotlinType
interface DeserializedCallableMemberDescriptor : CallableMemberDescriptor {
interface DeserializedMemberDescriptor : MemberDescriptor {
val proto: MessageLite
val nameResolver: NameResolver
@@ -39,6 +37,8 @@ interface DeserializedCallableMemberDescriptor : CallableMemberDescriptor {
val containerSource: SourceElement?
}
interface DeserializedCallableMemberDescriptor : DeserializedMemberDescriptor, CallableMemberDescriptor
class DeserializedSimpleFunctionDescriptor(
containingDeclaration: DeclarationDescriptor,
original: SimpleFunctionDescriptor?,
@@ -133,3 +133,32 @@ class DeserializedConstructorDescriptor(
override fun isTailrec(): Boolean = false
}
class DeserializedTypeAliasDescriptor(
containingDeclaration: DeclarationDescriptor,
annotations: Annotations,
name: Name,
visibility: Visibility,
override val proto: ProtoBuf.TypeAlias,
override val nameResolver: NameResolver,
override val typeTable: TypeTable,
override val containerSource: SourceElement?
) : AbstractTypeAliasDescriptor(containingDeclaration, annotations, name, SourceElement.NO_SOURCE, visibility),
DeserializedMemberDescriptor {
private lateinit var underlyingTypeImpl: KotlinType
private lateinit var expandedTypeImpl: KotlinType
override val underlyingType: KotlinType get() = underlyingTypeImpl
override val expandedType: KotlinType get() = expandedTypeImpl
fun initialize(
declaredTypeParameters: List<TypeParameterDescriptor>,
underlyingType: KotlinType,
expandedType: KotlinType
) {
initialize(declaredTypeParameters)
underlyingTypeImpl = underlyingType
expandedTypeImpl = expandedType
}
}
@@ -17,10 +17,7 @@
package org.jetbrains.kotlin.serialization.deserialization.descriptors
import com.google.protobuf.MessageLite
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
@@ -35,7 +32,8 @@ import java.util.*
abstract class DeserializedMemberScope protected constructor(
protected val c: DeserializationContext,
functionList: Collection<ProtoBuf.Function>,
propertyList: Collection<ProtoBuf.Property>
propertyList: Collection<ProtoBuf.Property>,
typeAliasList: Collection<ProtoBuf.TypeAlias>
) : MemberScopeImpl() {
private data class ProtoKey(val name: Name, val isExtension: Boolean)
@@ -48,11 +46,21 @@ abstract class DeserializedMemberScope protected constructor(
c.storageManager.createLazyValue {
groupByKey(propertyList, { it.name }) { it.receiverType(c.typeTable) != null }
}
private val typeAliasProtos =
c.storageManager.createLazyValue {
typeAliasList.groupBy { c.nameResolver.getName(it.name) }
}
protected val typeAliasNames =
c.storageManager.createLazyValue {
typeAliasList.map { c.nameResolver.getName(it.name) }
}
private val functions =
c.storageManager.createMemoizedFunction<Name, Collection<SimpleFunctionDescriptor>> { computeFunctions(it) }
private val properties =
c.storageManager.createMemoizedFunction<Name, Collection<PropertyDescriptor>> { computeProperties(it) }
private val typeAliases =
c.storageManager.createMemoizedFunction<Name, Collection<TypeAliasDescriptor>> { computeTypeAliases(it) }
private fun <M : MessageLite> groupByKey(
protos: Collection<M>, getNameIndex: (M) -> Int, isExtension: (M) -> Boolean
@@ -97,9 +105,23 @@ abstract class DeserializedMemberScope protected constructor(
protected open fun computeNonDeclaredProperties(name: Name, descriptors: MutableCollection<PropertyDescriptor>) {
}
private fun computeTypeAliases(name: Name): Collection<TypeAliasDescriptor> {
val protos = typeAliasProtos()[name].orEmpty()
val descriptors = protos.mapTo(linkedSetOf()) {
c.memberDeserializer.loadTypeAlias(it)
}
computeNonDeclaredTypeAliases(name, descriptors)
return descriptors.toReadOnlyList()
}
protected open fun computeNonDeclaredTypeAliases(name: Name, descriptors: MutableCollection<TypeAliasDescriptor>) {
}
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> = properties(name)
protected abstract fun addClassDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean)
protected fun getContributedTypeAliases(name: Name): Collection<TypeAliasDescriptor> = typeAliases(name)
protected abstract fun addClassifierDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean)
protected fun computeDescriptors(
kindFilter: DescriptorKindFilter,
@@ -119,7 +141,7 @@ abstract class DeserializedMemberScope protected constructor(
addNonDeclaredDescriptors(result, location)
if (kindFilter.acceptsKinds(DescriptorKindFilter.CLASSIFIERS_MASK)) {
addClassDescriptors(result, nameFilter)
addClassifierDescriptors(result, nameFilter)
}
return result.toReadOnlyList()
@@ -161,6 +183,7 @@ abstract class DeserializedMemberScope protected constructor(
protected abstract fun getNonDeclaredFunctionNames(location: LookupLocation): Set<Name>
protected abstract fun getNonDeclaredVariableNames(location: LookupLocation): Set<Name>
protected abstract fun getNonDeclaredTypeAliasNames(location: LookupLocation): Set<Name>
protected abstract fun addEnumEntryDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean)
@@ -39,7 +39,7 @@ open class DeserializedPackageMemberScope(
classNames: () -> Collection<Name>
) : DeserializedMemberScope(
components.createContext(packageDescriptor, nameResolver, TypeTable(proto.typeTable), containerSource),
proto.functionList, proto.propertyList
proto.functionList, proto.propertyList, proto.typeAliasList
) {
private val packageFqName = packageDescriptor.fqName
@@ -53,22 +53,28 @@ open class DeserializedPackageMemberScope(
(name in classNames || c.components.fictitiousClassDescriptorFactory.shouldCreateClass(packageFqName, name))) {
return getClassDescriptor(name)
}
return null
return getContributedTypeAliases(name).singleOrNull()
}
private fun getClassDescriptor(name: Name): ClassDescriptor? =
c.components.deserializeClass(ClassId(packageFqName, name))
override fun addClassDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean) {
override fun addClassifierDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean) {
for (className in classNames) {
if (nameFilter(className)) {
result.addIfNotNull(getClassDescriptor(className))
}
}
for (typeAliasName in typeAliasNames()) {
if (nameFilter(typeAliasName)) {
result.addAll(getContributedTypeAliases(typeAliasName))
}
}
}
override fun getNonDeclaredFunctionNames(location: LookupLocation): Set<Name> = emptySet()
override fun getNonDeclaredVariableNames(location: LookupLocation): Set<Name> = emptySet()
override fun getNonDeclaredTypeAliasNames(location: LookupLocation): Set<Name> = emptySet()
override fun addEnumEntryDescriptors(result: MutableCollection<DeclarationDescriptor>, nameFilter: (Name) -> Boolean) {
// Do nothing
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.serialization.deserialization
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.ClassId
@@ -43,3 +44,22 @@ fun ModuleDescriptor.findNonGenericClassAcrossDependencies(classId: ClassId, not
return notFoundClasses.get(classId, typeParametersCount).declarationDescriptor as ClassDescriptor
}
fun ModuleDescriptor.findTypeAliasAcrossModuleDependencies(classId: ClassId): TypeAliasDescriptor? {
// TODO refactor with findClassAcrossModuleDependencies
// TODO what if typealias becomes a class / interface?
val packageViewDescriptor = getPackage(classId.packageFqName)
val segments = classId.relativeClassName.pathSegments()
val lastNameIndex = segments.size - 1
val topLevelClassifier = packageViewDescriptor.memberScope.getContributedClassifier(segments.first(), NoLookupLocation.FROM_DESERIALIZATION)
if (lastNameIndex == 0) return topLevelClassifier as? TypeAliasDescriptor
var currentClass = topLevelClassifier as? ClassDescriptor ?: return null
for (name in segments.subList(1, lastNameIndex)) {
currentClass = currentClass.unsubstitutedInnerClassesScope.getContributedClassifier(name, NoLookupLocation.FROM_DESERIALIZATION) as? ClassDescriptor ?: return null
}
val lastName = segments[lastNameIndex]
return currentClass.unsubstitutedMemberScope.getContributedClassifier(lastName, NoLookupLocation.FROM_DESERIALIZATION) as? TypeAliasDescriptor
}
@@ -90,3 +90,16 @@ fun ProtoBuf.Type.outerType(typeTable: TypeTable): ProtoBuf.Type? {
else -> null
}
}
fun ProtoBuf.Type.abbreviatedType(typeTable: TypeTable): ProtoBuf.Type? =
when {
hasAbbreviatedType() -> abbreviatedType
hasAbbreviatedTypeId() -> typeTable[abbreviatedTypeId]
else -> null
}
fun ProtoBuf.TypeAlias.underlyingType(typeTable: TypeTable): ProtoBuf.Type =
if (hasUnderlyingTypeId()) typeTable[underlyingTypeId] else underlyingType
fun ProtoBuf.TypeAlias.expandedType(typeTable: TypeTable): ProtoBuf.Type =
if (hasExpandedTypeId()) typeTable[expandedTypeId] else expandedType
@@ -40,7 +40,7 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
val classId = classId
val descriptor =
if (classId.isLocal) moduleData.localClassResolver.resolveLocalClass(classId)
if (classId.isLocal) moduleData.localClassifierResolver.resolveLocalClass(classId)
else moduleData.module.findClassAcrossModuleDependencies(classId)
descriptor ?: reportUnresolvedClass()
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DeserializerForDecompilerBase
import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter
import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolveEverythingToKotlinAnyLocalClassResolver
import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolveEverythingToKotlinAnyLocalClassifierResolver
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.TargetPlatform
@@ -51,7 +51,7 @@ class KotlinBuiltInDeserializerForDecompiler(
deserializationComponents = DeserializationComponents(
storageManager, moduleDescriptor, BuiltInsClassDataFinder(proto, nameResolver),
AnnotationAndConstantLoaderImpl(moduleDescriptor, notFoundClasses, BuiltInSerializerProtocol), packageFragmentProvider,
ResolveEverythingToKotlinAnyLocalClassResolver(builtIns), LoggingErrorReporter(LOG),
ResolveEverythingToKotlinAnyLocalClassifierResolver(builtIns), LoggingErrorReporter(LOG),
LookupTracker.DO_NOTHING, FlexibleTypeFactory.ThrowException, ClassDescriptorFactory.EMPTY,
notFoundClasses
)
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.caches.IDEKotlinBinaryClassCache
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DeserializerForDecompilerBase
import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter
import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolveEverythingToKotlinAnyLocalClassResolver
import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolveEverythingToKotlinAnyLocalClassifierResolver
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.load.java.lazy.types.LazyJavaTypeResolver.FlexibleJavaClassifierTypeFactory
import org.jetbrains.kotlin.load.java.structure.JavaClass
@@ -67,7 +67,7 @@ class DeserializerForClassfileDecompiler(
deserializationComponents = DeserializationComponents(
storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider,
ResolveEverythingToKotlinAnyLocalClassResolver(builtIns), LoggingErrorReporter(LOG),
ResolveEverythingToKotlinAnyLocalClassifierResolver(builtIns), LoggingErrorReporter(LOG),
LookupTracker.DO_NOTHING, FlexibleJavaClassifierTypeFactory, ClassDescriptorFactory.EMPTY, notFoundClasses
)
}
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DeserializerForDecompilerBase
import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter
import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolveEverythingToKotlinAnyLocalClassResolver
import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolveEverythingToKotlinAnyLocalClassifierResolver
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.js.resolve.JsPlatform
import org.jetbrains.kotlin.name.FqName
@@ -64,7 +64,7 @@ class KotlinJavaScriptDeserializerForDecompiler(
deserializationComponents = DeserializationComponents(
storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider,
ResolveEverythingToKotlinAnyLocalClassResolver(builtIns), LoggingErrorReporter(LOG),
ResolveEverythingToKotlinAnyLocalClassifierResolver(builtIns), LoggingErrorReporter(LOG),
LookupTracker.DO_NOTHING, DynamicTypeFactory, ClassDescriptorFactory.EMPTY,
notFoundClasses
)
@@ -18,10 +18,7 @@ package org.jetbrains.kotlin.idea.decompiler.textBuilder
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleParameters
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
import org.jetbrains.kotlin.name.ClassId
@@ -29,7 +26,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
import org.jetbrains.kotlin.serialization.deserialization.LocalClassResolver
import org.jetbrains.kotlin.serialization.deserialization.LocalClassifierResolver
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.storage.StorageManager
@@ -69,6 +66,7 @@ abstract class DeserializerForDecompilerBase(
}
}
class ResolveEverythingToKotlinAnyLocalClassResolver(private val builtIns: KotlinBuiltIns) : LocalClassResolver {
class ResolveEverythingToKotlinAnyLocalClassifierResolver(private val builtIns: KotlinBuiltIns) : LocalClassifierResolver {
override fun resolveLocalClass(classId: ClassId): ClassDescriptor = builtIns.any
override fun resolveLocalTypeAlias(typeAliasId: ClassId): ClassifierDescriptor = builtIns.any
}
@@ -38,7 +38,7 @@ fun createKotlinJavascriptPackageFragmentProvider(
val provider = PackageFragmentProviderImpl(packageFragments)
val notFoundClasses = NotFoundClasses(storageManager, module)
val localClassResolver = LocalClassResolverImpl()
val localClassResolver = LocalClassifierResolverImpl()
val components = DeserializationComponents(
storageManager,