Removed laziness from TypeDeserializer, because DeserializedMemberScope has cache for callable descriptors.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -71,7 +71,6 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature;
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializedType;
|
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor;
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor;
|
||||||
import org.jetbrains.kotlin.types.*;
|
import org.jetbrains.kotlin.types.*;
|
||||||
@@ -450,14 +449,7 @@ public class KotlinTypeMapper {
|
|||||||
PsiElement declarationElement = DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
|
PsiElement declarationElement = DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
|
||||||
|
|
||||||
if (declarationElement == null) {
|
if (declarationElement == null) {
|
||||||
String message = "Error type encountered: %s (%s).";
|
return String.format("Error type encountered: %s (%s).", type, type.getClass().getSimpleName());
|
||||||
if (FlexibleTypesKt.upperIfFlexible(type) instanceof DeserializedType) {
|
|
||||||
message +=
|
|
||||||
" One of the possible reasons may be that this type is not directly accessible from this module. " +
|
|
||||||
"To workaround this error, try adding an explicit dependency on the module or library which contains this type " +
|
|
||||||
"to the classpath";
|
|
||||||
}
|
|
||||||
return String.format(message, type, type.getClass().getSimpleName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||||
|
|||||||
@@ -1,68 +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.types
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
|
||||||
import org.jetbrains.kotlin.storage.getValue
|
|
||||||
|
|
||||||
abstract class AbstractLazyType(storageManager: StorageManager) : SimpleType(), LazyType {
|
|
||||||
|
|
||||||
private val typeConstructor = storageManager.createLazyValue { computeTypeConstructor() }
|
|
||||||
override val constructor by typeConstructor
|
|
||||||
|
|
||||||
protected abstract fun computeTypeConstructor(): TypeConstructor
|
|
||||||
|
|
||||||
private val _arguments = storageManager.createLazyValue { computeArguments() }
|
|
||||||
override val arguments by _arguments
|
|
||||||
|
|
||||||
protected abstract fun computeArguments(): List<TypeProjection>
|
|
||||||
|
|
||||||
override val memberScope by storageManager.createLazyValue { computeMemberScope(constructor, arguments) }
|
|
||||||
|
|
||||||
override val isMarkedNullable: Boolean get() = false
|
|
||||||
|
|
||||||
override val isError: Boolean get() = constructor.declarationDescriptor?.let { d -> ErrorUtils.isError(d) } ?: false
|
|
||||||
|
|
||||||
override val annotations: Annotations get() = Annotations.EMPTY
|
|
||||||
|
|
||||||
// TODO: do not force resolution
|
|
||||||
override fun replaceAnnotations(newAnnotations: Annotations): SimpleType = KotlinTypeFactory.simpleType(this, annotations = newAnnotations)
|
|
||||||
override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType = KotlinTypeFactory.simpleType(this, nullable = newNullability)
|
|
||||||
|
|
||||||
override fun toString() = when {
|
|
||||||
!typeConstructor.isComputed() -> "[Not-computed]"
|
|
||||||
!_arguments.isComputed() ->
|
|
||||||
if (constructor.parameters.isEmpty()) constructor.toString()
|
|
||||||
else "$constructor<not-computed>"
|
|
||||||
else -> super.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun computeMemberScope(constructor: TypeConstructor, arguments: List<TypeProjection>): MemberScope {
|
|
||||||
val descriptor = constructor.declarationDescriptor
|
|
||||||
return when (descriptor) {
|
|
||||||
is TypeParameterDescriptor -> descriptor.getDefaultType().memberScope
|
|
||||||
is ClassDescriptor -> descriptor.getMemberScope(TypeConstructorSubstitution.create(constructor, arguments))
|
|
||||||
else -> throw IllegalStateException("Unsupported classifier: $descriptor")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -464,7 +464,8 @@ public class ErrorUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isError(@NotNull DeclarationDescriptor candidate) {
|
public static boolean isError(@Nullable DeclarationDescriptor candidate) {
|
||||||
|
if (candidate == null) return false;
|
||||||
return isErrorClass(candidate) || isErrorClass(candidate.getContainingDeclaration()) || candidate == ERROR_MODULE;
|
return isErrorClass(candidate) || isErrorClass(candidate.getContainingDeclaration()) || candidate == ERROR_MODULE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-66
@@ -1,66 +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.serialization.deserialization
|
|
||||||
|
|
||||||
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.SimpleType
|
|
||||||
import org.jetbrains.kotlin.types.withAbbreviation
|
|
||||||
import org.jetbrains.kotlin.utils.toReadOnlyList
|
|
||||||
|
|
||||||
class DeserializedType private constructor(
|
|
||||||
private val c: DeserializationContext,
|
|
||||||
private val typeProto: ProtoBuf.Type,
|
|
||||||
private val additionalAnnotations: Annotations = Annotations.EMPTY
|
|
||||||
) : AbstractLazyType(c.storageManager) {
|
|
||||||
override fun computeTypeConstructor() = c.typeDeserializer.typeConstructor(typeProto)
|
|
||||||
|
|
||||||
override fun computeArguments() =
|
|
||||||
typeProto.collectAllArguments().mapIndexed {
|
|
||||||
index, proto ->
|
|
||||||
c.typeDeserializer.typeArgument(constructor.parameters.getOrNull(index), proto)
|
|
||||||
}.toReadOnlyList()
|
|
||||||
|
|
||||||
private fun ProtoBuf.Type.collectAllArguments(): List<ProtoBuf.Type.Argument> =
|
|
||||||
argumentList + outerType(c.typeTable)?.collectAllArguments().orEmpty()
|
|
||||||
|
|
||||||
override val annotations = DeserializedAnnotationsWithPossibleTargets(c.storageManager) {
|
|
||||||
c.components.annotationAndConstantLoader
|
|
||||||
.loadTypeAnnotations(typeProto, c.nameResolver)
|
|
||||||
.map { AnnotationWithTarget(it, null) } + additionalAnnotations.getAllAnnotations()
|
|
||||||
}
|
|
||||||
|
|
||||||
override val isMarkedNullable: Boolean get() = typeProto.nullable
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun create(
|
|
||||||
c: DeserializationContext,
|
|
||||||
typeProto: ProtoBuf.Type,
|
|
||||||
additionalAnnotations: Annotations
|
|
||||||
): SimpleType {
|
|
||||||
val deserializedType = DeserializedType(c, typeProto, additionalAnnotations)
|
|
||||||
val abbreviatedTypeProto = typeProto.abbreviatedType(c.typeTable) ?: return deserializedType
|
|
||||||
|
|
||||||
return deserializedType.withAbbreviation(DeserializedType(c, abbreviatedTypeProto, additionalAnnotations))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
+36
-18
@@ -17,8 +17,10 @@
|
|||||||
package org.jetbrains.kotlin.serialization.deserialization
|
package org.jetbrains.kotlin.serialization.deserialization
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedAnnotationsWithPossibleTargets
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedTypeParameterDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedTypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.utils.toReadOnlyList
|
import org.jetbrains.kotlin.utils.toReadOnlyList
|
||||||
@@ -27,7 +29,7 @@ import java.util.*
|
|||||||
class TypeDeserializer(
|
class TypeDeserializer(
|
||||||
private val c: DeserializationContext,
|
private val c: DeserializationContext,
|
||||||
private val parent: TypeDeserializer?,
|
private val parent: TypeDeserializer?,
|
||||||
private val typeParameterProtos: List<ProtoBuf.TypeParameter>,
|
typeParameterProtos: List<ProtoBuf.TypeParameter>,
|
||||||
private val debugName: String
|
private val debugName: String
|
||||||
) {
|
) {
|
||||||
private val classDescriptors: (Int) -> ClassDescriptor? = c.storageManager.createMemoizedFunctionWithNullableValues {
|
private val classDescriptors: (Int) -> ClassDescriptor? = c.storageManager.createMemoizedFunctionWithNullableValues {
|
||||||
@@ -38,7 +40,7 @@ class TypeDeserializer(
|
|||||||
fqNameIndex -> computeTypeAliasDescriptor(fqNameIndex)
|
fqNameIndex -> computeTypeAliasDescriptor(fqNameIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val typeParameterDescriptors = c.storageManager.createLazyValue {
|
private val typeParameterDescriptors =
|
||||||
if (typeParameterProtos.isEmpty()) {
|
if (typeParameterProtos.isEmpty()) {
|
||||||
mapOf<Int, TypeParameterDescriptor>()
|
mapOf<Int, TypeParameterDescriptor>()
|
||||||
}
|
}
|
||||||
@@ -49,10 +51,9 @@ class TypeDeserializer(
|
|||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val ownTypeParameters: List<TypeParameterDescriptor>
|
val ownTypeParameters: List<TypeParameterDescriptor>
|
||||||
get() = typeParameterDescriptors().values.toReadOnlyList()
|
get() = typeParameterDescriptors.values.toReadOnlyList()
|
||||||
|
|
||||||
// TODO: don't load identical types from TypeTable more than once
|
// TODO: don't load identical types from TypeTable more than once
|
||||||
fun type(proto: ProtoBuf.Type, additionalAnnotations: Annotations = Annotations.EMPTY): KotlinType {
|
fun type(proto: ProtoBuf.Type, additionalAnnotations: Annotations = Annotations.EMPTY): KotlinType {
|
||||||
@@ -66,10 +67,32 @@ class TypeDeserializer(
|
|||||||
return simpleType(proto, additionalAnnotations)
|
return simpleType(proto, additionalAnnotations)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun simpleType(proto: ProtoBuf.Type, additionalAnnotations: Annotations = Annotations.EMPTY)
|
fun simpleType(proto: ProtoBuf.Type, additionalAnnotations: Annotations = Annotations.EMPTY): SimpleType {
|
||||||
= DeserializedType.create(c, proto, additionalAnnotations)
|
val constructor = typeConstructor(proto)
|
||||||
|
if (ErrorUtils.isError(constructor.declarationDescriptor)) {
|
||||||
|
return ErrorUtils.createErrorTypeWithCustomConstructor(constructor.toString(), constructor)
|
||||||
|
}
|
||||||
|
|
||||||
fun typeConstructor(proto: ProtoBuf.Type): TypeConstructor =
|
val annotations = DeserializedAnnotationsWithPossibleTargets(c.storageManager) {
|
||||||
|
c.components.annotationAndConstantLoader
|
||||||
|
.loadTypeAnnotations(proto, c.nameResolver)
|
||||||
|
.map { AnnotationWithTarget(it, null) } + additionalAnnotations.getAllAnnotations()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ProtoBuf.Type.collectAllArguments(): List<ProtoBuf.Type.Argument> =
|
||||||
|
argumentList + outerType(c.typeTable)?.collectAllArguments().orEmpty()
|
||||||
|
|
||||||
|
val arguments = proto.collectAllArguments().mapIndexed { index, proto ->
|
||||||
|
typeArgument(constructor.parameters.getOrNull(index), proto)
|
||||||
|
}.toReadOnlyList()
|
||||||
|
|
||||||
|
val simpleType = KotlinTypeFactory.simpleType(annotations, constructor, arguments, proto.nullable)
|
||||||
|
|
||||||
|
val abbreviatedTypeProto = proto.abbreviatedType(c.typeTable) ?: return simpleType
|
||||||
|
return simpleType.withAbbreviation(simpleType(abbreviatedTypeProto, additionalAnnotations))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun typeConstructor(proto: ProtoBuf.Type): TypeConstructor =
|
||||||
when {
|
when {
|
||||||
proto.hasClassName() -> {
|
proto.hasClassName() -> {
|
||||||
classDescriptors(proto.className)?.typeConstructor
|
classDescriptors(proto.className)?.typeConstructor
|
||||||
@@ -77,27 +100,22 @@ class TypeDeserializer(
|
|||||||
}
|
}
|
||||||
proto.hasTypeParameter() ->
|
proto.hasTypeParameter() ->
|
||||||
typeParameterTypeConstructor(proto.typeParameter)
|
typeParameterTypeConstructor(proto.typeParameter)
|
||||||
?: ErrorUtils.createErrorType("Unknown type parameter ${proto.typeParameter}").constructor
|
?: ErrorUtils.createErrorTypeConstructor("Unknown type parameter ${proto.typeParameter}")
|
||||||
proto.hasTypeParameterName() -> {
|
proto.hasTypeParameterName() -> {
|
||||||
val container = c.containingDeclaration
|
val container = c.containingDeclaration
|
||||||
val typeParameters = when (container) {
|
|
||||||
is ClassifierDescriptorWithTypeParameters -> container.typeConstructor.parameters
|
|
||||||
is CallableDescriptor -> container.typeParameters
|
|
||||||
else -> emptyList<TypeParameterDescriptor>()
|
|
||||||
}
|
|
||||||
val name = c.nameResolver.getString(proto.typeParameterName)
|
val name = c.nameResolver.getString(proto.typeParameterName)
|
||||||
val parameter = typeParameters.find { it.name.asString() == name }
|
val parameter = ownTypeParameters.find { it.name.asString() == name }
|
||||||
parameter?.typeConstructor ?: ErrorUtils.createErrorType("Deserialized type parameter $name in $container").constructor
|
parameter?.typeConstructor ?: ErrorUtils.createErrorTypeConstructor("Deserialized type parameter $name in $container")
|
||||||
}
|
}
|
||||||
proto.hasTypeAliasName() -> {
|
proto.hasTypeAliasName() -> {
|
||||||
typeAliasDescriptors(proto.typeAliasName)?.typeConstructor
|
typeAliasDescriptors(proto.typeAliasName)?.typeConstructor
|
||||||
?: TODO("not found type aliases")
|
?: TODO("not found type aliases")
|
||||||
}
|
}
|
||||||
else -> ErrorUtils.createErrorType("Unknown type").constructor
|
else -> ErrorUtils.createErrorTypeConstructor("Unknown type")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun typeParameterTypeConstructor(typeParameterId: Int): TypeConstructor? =
|
private fun typeParameterTypeConstructor(typeParameterId: Int): TypeConstructor? =
|
||||||
typeParameterDescriptors().get(typeParameterId)?.typeConstructor ?:
|
typeParameterDescriptors.get(typeParameterId)?.typeConstructor ?:
|
||||||
parent?.typeParameterTypeConstructor(typeParameterId)
|
parent?.typeParameterTypeConstructor(typeParameterId)
|
||||||
|
|
||||||
private fun computeClassDescriptor(fqNameIndex: Int): ClassDescriptor? {
|
private fun computeClassDescriptor(fqNameIndex: Int): ClassDescriptor? {
|
||||||
@@ -119,7 +137,7 @@ class TypeDeserializer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun typeArgument(parameter: TypeParameterDescriptor?, typeArgumentProto: ProtoBuf.Type.Argument): TypeProjection {
|
private fun typeArgument(parameter: TypeParameterDescriptor?, typeArgumentProto: ProtoBuf.Type.Argument): TypeProjection {
|
||||||
if (typeArgumentProto.projection == ProtoBuf.Type.Argument.Projection.STAR) {
|
if (typeArgumentProto.projection == ProtoBuf.Type.Argument.Projection.STAR) {
|
||||||
return if (parameter == null)
|
return if (parameter == null)
|
||||||
TypeBasedStarProjectionImpl(c.components.moduleDescriptor.builtIns.nullableAnyType)
|
TypeBasedStarProjectionImpl(c.components.moduleDescriptor.builtIns.nullableAnyType)
|
||||||
|
|||||||
Reference in New Issue
Block a user