KT-11588 Type aliases

Type alias descriptor serialization
Types with type aliases serialization
This commit is contained in:
Dmitry Petrov
2016-05-11 13:51:19 +03:00
parent 59472927cd
commit 65293008fd
26 changed files with 5012 additions and 246 deletions
@@ -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
}
@@ -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
@@ -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<*>