KT-11588 Type aliases
Type alias descriptor serialization Types with type aliases serialization
This commit is contained in:
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||
@@ -112,10 +113,15 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
|
||||
if (declaration instanceof KtNamedFunction) {
|
||||
SimpleFunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, declaration);
|
||||
members.add(functionDescriptor);
|
||||
} else if (declaration instanceof KtProperty) {
|
||||
}
|
||||
else if (declaration instanceof KtProperty) {
|
||||
VariableDescriptor property = bindingContext.get(BindingContext.VARIABLE, declaration);
|
||||
members.add(property);
|
||||
}
|
||||
else if (declaration instanceof KtTypeAlias) {
|
||||
TypeAliasDescriptor typeAlias = bindingContext.get(BindingContext.TYPE_ALIAS, declaration);
|
||||
members.add(typeAlias);
|
||||
}
|
||||
}
|
||||
|
||||
final DescriptorSerializer serializer =
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.codegen.serialization
|
||||
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmNameResolver
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
@@ -53,7 +54,7 @@ class JvmStringTable(private val typeMapper: KotlinTypeMapper) : StringTable {
|
||||
return !hasPredefinedIndex() && !hasOperation() && substringIndexCount == 0 && replaceCharCount == 0
|
||||
}
|
||||
|
||||
override fun getFqNameIndex(descriptor: ClassDescriptor): Int {
|
||||
override fun getFqNameIndex(descriptor: ClassifierDescriptorWithTypeParameters): Int {
|
||||
if (ErrorUtils.isError(descriptor)) {
|
||||
throw IllegalStateException("Cannot get FQ name of error class: " + descriptor)
|
||||
}
|
||||
@@ -109,7 +110,7 @@ class JvmStringTable(private val typeMapper: KotlinTypeMapper) : StringTable {
|
||||
return index
|
||||
}
|
||||
|
||||
private val ClassDescriptor.classId: ClassId
|
||||
private val ClassifierDescriptorWithTypeParameters.classId: ClassId
|
||||
get() {
|
||||
val container = containingDeclaration
|
||||
return when (container) {
|
||||
|
||||
@@ -91,6 +91,7 @@ public interface BindingContext {
|
||||
WritableSlice<KtExpression, CompileTimeConstant<?>> COMPILE_TIME_VALUE = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<KtTypeReference, KotlinType> TYPE = Slices.createSimpleSlice();
|
||||
WritableSlice<KtTypeReference, KotlinType> ABBREVIATED_TYPE = Slices.createSimpleSlice();
|
||||
WritableSlice<KtExpression, KotlinTypeInfo> EXPRESSION_TYPE_INFO = new BasicWritableSlice<KtExpression, KotlinTypeInfo>(DO_NOTHING);
|
||||
WritableSlice<KtExpression, KotlinType> EXPECTED_EXPRESSION_TYPE = new BasicWritableSlice<KtExpression, KotlinType>(DO_NOTHING);
|
||||
WritableSlice<KtFunction, KotlinType> EXPECTED_RETURN_TYPE = new BasicWritableSlice<KtFunction, KotlinType>(DO_NOTHING);
|
||||
@@ -216,7 +217,7 @@ public interface BindingContext {
|
||||
WritableSlice<KtParameter, VariableDescriptor> VALUE_PARAMETER = Slices.createSimpleSlice();
|
||||
WritableSlice<KtPropertyAccessor, PropertyAccessorDescriptor> PROPERTY_ACCESSOR = Slices.createSimpleSlice();
|
||||
WritableSlice<PsiElement, PropertyDescriptor> PRIMARY_CONSTRUCTOR_PARAMETER = Slices.createSimpleSlice();
|
||||
WritableSlice<KtTypeAlias, TypeAliasDescriptor> TYPE_ALIAS = Slices.createSimpleSlice();
|
||||
WritableSlice<PsiElement, TypeAliasDescriptor> TYPE_ALIAS = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice[] DECLARATIONS_TO_DESCRIPTORS = new WritableSlice[] {
|
||||
CLASS, TYPE_PARAMETER, FUNCTION, CONSTRUCTOR, VARIABLE, VALUE_PARAMETER, PROPERTY_ACCESSOR,
|
||||
|
||||
@@ -714,12 +714,21 @@ public class DescriptorResolver {
|
||||
|
||||
final KtTypeReference typeReference = typeAlias.getTypeReference();
|
||||
|
||||
typeAliasDescriptor.initialize(typeParameterDescriptors, storageManager.createLazyValue(new Function0<KotlinType>() {
|
||||
@Override
|
||||
public KotlinType invoke() {
|
||||
return typeResolver.resolveAbbreviatedType(scopeWithTypeParameters, typeReference, trace, true);
|
||||
}
|
||||
}));
|
||||
typeAliasDescriptor.initialize(
|
||||
typeParameterDescriptors,
|
||||
storageManager.createLazyValue(new Function0<KotlinType>() {
|
||||
@Override
|
||||
public KotlinType invoke() {
|
||||
return typeResolver.resolveAbbreviatedType(scopeWithTypeParameters, typeReference, trace, true);
|
||||
}
|
||||
}),
|
||||
storageManager.createLazyValue(new Function0<KotlinType>() {
|
||||
@Override
|
||||
public KotlinType invoke() {
|
||||
// TODO do not reparse
|
||||
return typeResolver.resolveType(scopeWithTypeParameters, typeReference, trace, true);
|
||||
}
|
||||
}));
|
||||
|
||||
trace.record(TYPE_ALIAS, typeAlias, typeAliasDescriptor);
|
||||
return typeAliasDescriptor;
|
||||
|
||||
@@ -371,7 +371,7 @@ class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageValidator
|
||||
val nextPackageOrClassDescriptor =
|
||||
when (currentDescriptor) {
|
||||
is TypeAliasDescriptor -> // TODO type aliases as qualifiers? (would break some assumptions in TypeResolver)
|
||||
currentDescriptor.underlyingClassDescriptor.getContributedClassifier(qualifierPart)
|
||||
currentDescriptor.classDescriptor?.getContributedClassifier(qualifierPart)
|
||||
is ClassDescriptor ->
|
||||
currentDescriptor.getContributedClassifier(qualifierPart)
|
||||
is PackageViewDescriptor -> {
|
||||
|
||||
@@ -81,9 +81,11 @@ class TypeResolver(
|
||||
val cachedType = c.trace.getBindingContext().get(BindingContext.TYPE, typeReference)
|
||||
if (cachedType != null) return type(cachedType)
|
||||
|
||||
val resolvedTypeSlice = if (c.abbreviated) BindingContext.ABBREVIATED_TYPE else BindingContext.TYPE
|
||||
|
||||
val debugType = typeReference.debugTypeInfo
|
||||
if (debugType != null) {
|
||||
c.trace.record(BindingContext.TYPE, typeReference, debugType)
|
||||
c.trace.record(resolvedTypeSlice, typeReference, debugType)
|
||||
return type(debugType)
|
||||
}
|
||||
|
||||
@@ -100,13 +102,13 @@ class TypeResolver(
|
||||
}
|
||||
|
||||
val lazyKotlinType = LazyKotlinType()
|
||||
c.trace.record(BindingContext.TYPE, typeReference, lazyKotlinType)
|
||||
c.trace.record(resolvedTypeSlice, typeReference, lazyKotlinType)
|
||||
return type(lazyKotlinType)
|
||||
}
|
||||
|
||||
val type = doResolvePossiblyBareType(c, typeReference)
|
||||
if (!type.isBare()) {
|
||||
c.trace.record(BindingContext.TYPE, typeReference, type.getActualType())
|
||||
c.trace.record(resolvedTypeSlice, typeReference, type.getActualType())
|
||||
}
|
||||
return type
|
||||
}
|
||||
|
||||
+22
-10
@@ -26,6 +26,7 @@ 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
|
||||
@@ -40,24 +41,35 @@ class TypeAliasDescriptorImpl(
|
||||
TypeAliasDescriptor {
|
||||
|
||||
// TODO kotlinize some interfaces
|
||||
private lateinit var fDeclaredTypeParameters: List<TypeParameterDescriptor>
|
||||
private lateinit var lazyUnderlyingType: NotNullLazyValue<KotlinType>
|
||||
private lateinit var declaredTypeParametersImpl: List<TypeParameterDescriptor>
|
||||
private lateinit var underlyingTypeImpl: NotNullLazyValue<KotlinType>
|
||||
private lateinit var expandedTypeImpl: NotNullLazyValue<KotlinType>
|
||||
|
||||
override val underlyingType: KotlinType get() = lazyUnderlyingType()
|
||||
override val underlyingType: KotlinType get() = underlyingTypeImpl()
|
||||
override val expandedType: KotlinType get() = expandedTypeImpl()
|
||||
|
||||
fun initialize(declaredTypeParameters: List<TypeParameterDescriptor>, lazyUnderlyingType: NotNullLazyValue<KotlinType>) {
|
||||
this.fDeclaredTypeParameters = declaredTypeParameters
|
||||
this.lazyUnderlyingType = lazyUnderlyingType
|
||||
fun initialize(
|
||||
declaredTypeParameters: List<TypeParameterDescriptor>,
|
||||
lazyUnderlyingType: NotNullLazyValue<KotlinType>,
|
||||
lazyExpandedType: NotNullLazyValue<KotlinType>
|
||||
) {
|
||||
this.declaredTypeParametersImpl = declaredTypeParameters
|
||||
this.underlyingTypeImpl = lazyUnderlyingType
|
||||
this.expandedTypeImpl = lazyExpandedType
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R =
|
||||
visitor.visitTypeAliasDescriptor(this, data)
|
||||
|
||||
override fun getDeclaredTypeParameters(): List<TypeParameterDescriptor> =
|
||||
fDeclaredTypeParameters
|
||||
override fun isInner(): Boolean = false // TODO treat all nested type aliases as inner?
|
||||
|
||||
override val underlyingClassDescriptor: ClassDescriptor
|
||||
get() = underlyingType.constructor.declarationDescriptor as ClassDescriptor // TODO
|
||||
override fun getDeclaredTypeParameters(): List<TypeParameterDescriptor> =
|
||||
declaredTypeParametersImpl
|
||||
|
||||
override val classDescriptor: ClassDescriptor?
|
||||
get() = expandedType.let { expandedType ->
|
||||
if (expandedType.isError) null else expandedType.constructor.declarationDescriptor as ClassDescriptor
|
||||
}
|
||||
|
||||
override fun getModality() = Modality.FINAL
|
||||
|
||||
|
||||
+44
-3
@@ -135,7 +135,7 @@ public class DescriptorSerializer {
|
||||
builder.setFlags(flags);
|
||||
}
|
||||
|
||||
builder.setFqName(getClassId(classDescriptor));
|
||||
builder.setFqName(getClassifierId(classDescriptor));
|
||||
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : classDescriptor.getDeclaredTypeParameters()) {
|
||||
builder.addTypeParameter(typeParameter(typeParameterDescriptor));
|
||||
@@ -357,6 +357,32 @@ public class DescriptorSerializer {
|
||||
return builder;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ProtoBuf.TypeAlias.Builder typeAliasProto(@NotNull TypeAliasDescriptor descriptor) {
|
||||
ProtoBuf.TypeAlias.Builder builder = ProtoBuf.TypeAlias.newBuilder();
|
||||
|
||||
int flags = Flags.getTypeAliasFlags(hasAnnotations(descriptor), descriptor.getVisibility());
|
||||
if (flags != builder.getFlags()) {
|
||||
builder.setFlags(flags);
|
||||
}
|
||||
|
||||
builder.setName(getSimpleNameIndex(descriptor.getName()));
|
||||
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getDeclaredTypeParameters()) {
|
||||
builder.addTypeParameter(typeParameter(typeParameterDescriptor));
|
||||
}
|
||||
|
||||
KotlinType underlyingType = descriptor.getUnderlyingType();
|
||||
if (useTypeTable()) {
|
||||
builder.setUnderlyingTypeId(typeId(underlyingType));
|
||||
}
|
||||
else {
|
||||
builder.setUnderlyingType(type(underlyingType));
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ProtoBuf.EnumEntry.Builder enumEntryProto(@NotNull ClassDescriptor descriptor) {
|
||||
ProtoBuf.EnumEntry.Builder builder = ProtoBuf.EnumEntry.newBuilder();
|
||||
@@ -499,6 +525,11 @@ public class DescriptorSerializer {
|
||||
|
||||
assert type.getArguments().isEmpty() : "Found arguments for type constructor build on type parameter: " + descriptor;
|
||||
}
|
||||
if (descriptor instanceof TypeAliasDescriptor) {
|
||||
PossiblyInnerType possiblyInnerType = TypeParameterUtilsKt.buildPossiblyInnerType(type);
|
||||
assert possiblyInnerType != null : "possiblyInnerType should not be null in case of type alias";
|
||||
fillFromPossiblyInnerType(builder, possiblyInnerType);
|
||||
}
|
||||
|
||||
if (type.isMarkedNullable() != builder.getNullable()) {
|
||||
builder.setNullable(type.isMarkedNullable());
|
||||
@@ -513,7 +544,14 @@ public class DescriptorSerializer {
|
||||
@NotNull ProtoBuf.Type.Builder builder,
|
||||
@NotNull PossiblyInnerType type
|
||||
) {
|
||||
builder.setClassName(getClassId(type.getClassDescriptor()));
|
||||
ClassifierDescriptorWithTypeParameters classifierDescriptor = type.getClassifierDescriptor();
|
||||
int classifierId = getClassifierId(classifierDescriptor);
|
||||
if (classifierDescriptor instanceof ClassDescriptor) {
|
||||
builder.setClassName(classifierId);
|
||||
}
|
||||
else {
|
||||
builder.setTypeAliasName(classifierId);
|
||||
}
|
||||
|
||||
for (TypeProjection projection : type.getArguments()) {
|
||||
builder.addArgument(typeArgument(projection));
|
||||
@@ -606,6 +644,9 @@ public class DescriptorSerializer {
|
||||
else if (declaration instanceof FunctionDescriptor) {
|
||||
builder.addFunction(functionProto((FunctionDescriptor) declaration));
|
||||
}
|
||||
else if (declaration instanceof TypeAliasDescriptor) {
|
||||
builder.addTypeAlias(typeAliasProto((TypeAliasDescriptor) declaration));
|
||||
}
|
||||
}
|
||||
|
||||
ProtoBuf.TypeTable typeTableProto = typeTable.serialize();
|
||||
@@ -631,7 +672,7 @@ public class DescriptorSerializer {
|
||||
throw new IllegalStateException("Unknown projectionKind: " + projectionKind);
|
||||
}
|
||||
|
||||
private int getClassId(@NotNull ClassDescriptor descriptor) {
|
||||
private int getClassifierId(@NotNull ClassifierDescriptorWithTypeParameters descriptor) {
|
||||
return getStringTable().getFqNameIndex(descriptor);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,13 +18,14 @@ package org.jetbrains.kotlin.serialization;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
public interface StringTable {
|
||||
int getStringIndex(@NotNull String string);
|
||||
|
||||
int getFqNameIndex(@NotNull ClassDescriptor descriptor);
|
||||
int getFqNameIndex(@NotNull ClassifierDescriptorWithTypeParameters descriptor);
|
||||
|
||||
void serializeTo(@NotNull OutputStream output);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.serialization;
|
||||
import kotlin.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
@@ -73,7 +74,7 @@ public class StringTableImpl implements StringTable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFqNameIndex(@NotNull ClassDescriptor descriptor) {
|
||||
public int getFqNameIndex(@NotNull ClassifierDescriptorWithTypeParameters descriptor) {
|
||||
if (ErrorUtils.isError(descriptor)) {
|
||||
throw new IllegalStateException("Cannot get FQ name of error class: " + descriptor);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package
|
||||
|
||||
public val x: WithVariance<kotlin.Int, kotlin.Int> [= kotlin.Int] = 0
|
||||
public typealias WithBounds1</*0*/ T : [ERROR : Cyclic upper bounds]> = kotlin.Int
|
||||
public typealias WithBounds2</*0*/ X : [ERROR : Cyclic upper bounds], /*1*/ Y : [ERROR : Cyclic upper bounds]> = kotlin.Int
|
||||
public typealias WithVariance</*0*/ in X, /*1*/ out Y> = kotlin.Int
|
||||
public val x: WithVariance<kotlin.Int, kotlin.Int> [= kotlin.Int] = 0
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package
|
||||
|
||||
public typealias CA</*0*/ T> = C<T>
|
||||
public val ca1: CA<kotlin.Int> [= C<kotlin.Int>]
|
||||
public val ca2: CA<CA<kotlin.Int> [= C<kotlin.Int>]> [= C<CA<kotlin.Int> [= C<kotlin.Int>]>]
|
||||
public val ca3: CA<C<kotlin.Int>> [= C<C<kotlin.Int>>]
|
||||
@@ -11,4 +12,3 @@ public final class C</*0*/ T> {
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
public typealias CA</*0*/ T> = C<T>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
package
|
||||
|
||||
public val x: [ERROR : Recursive type alias: A]
|
||||
public typealias A = B
|
||||
public typealias B = A
|
||||
public val x: [ERROR : Recursive type alias: A]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package
|
||||
|
||||
public typealias S = kotlin.String
|
||||
public typealias SS = S
|
||||
public typealias SSS = SS
|
||||
public val s1: SSS [= kotlin.String] = ""
|
||||
public val s2: SSS [= kotlin.String?] = null
|
||||
public val s3: kotlin.collections.List<SSS [= kotlin.String]>? = null
|
||||
public val s4: kotlin.collections.List<kotlin.collections.List<SSS [= kotlin.String]>?>? = null
|
||||
public typealias S = kotlin.String
|
||||
public typealias SS = S
|
||||
public typealias SSS = SS
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
package
|
||||
|
||||
public typealias In1</*0*/ T> = In<T>
|
||||
public typealias In2</*0*/ T> = In<in T>
|
||||
public typealias In3</*0*/ T> = In<out T>
|
||||
public typealias In4</*0*/ T> = In<*>
|
||||
public typealias Inv1</*0*/ T> = Inv<T>
|
||||
public typealias Inv2</*0*/ T> = Inv<in T>
|
||||
public typealias Inv3</*0*/ T> = Inv<out T>
|
||||
public typealias Inv4</*0*/ T> = Inv<*>
|
||||
public typealias Out1</*0*/ T> = Out<T>
|
||||
public typealias Out2</*0*/ T> = Out<in T>
|
||||
public typealias Out3</*0*/ T> = Out<out T>
|
||||
public typealias Out4</*0*/ T> = Out<*>
|
||||
public val inv1: Inv1<kotlin.Int> [= Inv<kotlin.Int>]
|
||||
|
||||
public final class In</*0*/ in T> {
|
||||
@@ -22,15 +34,3 @@ public final class Out</*0*/ out T> {
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
public typealias In1</*0*/ T> = In<T>
|
||||
public typealias In2</*0*/ T> = In<in T>
|
||||
public typealias In3</*0*/ T> = In<out T>
|
||||
public typealias In4</*0*/ T> = In<*>
|
||||
public typealias Inv1</*0*/ T> = Inv<T>
|
||||
public typealias Inv2</*0*/ T> = Inv<in T>
|
||||
public typealias Inv3</*0*/ T> = Inv<out T>
|
||||
public typealias Inv4</*0*/ T> = Inv<*>
|
||||
public typealias Out1</*0*/ T> = Out<T>
|
||||
public typealias Out2</*0*/ T> = Out<in T>
|
||||
public typealias Out3</*0*/ T> = Out<out T>
|
||||
public typealias Out4</*0*/ T> = Out<*>
|
||||
|
||||
Reference in New Issue
Block a user