[cls] write flexible type information to cls
^KTIJ-25172 this information would be used to create resolved FirElements from stubs, so no ProtoBuf would be kept in memory
This commit is contained in:
@@ -28,7 +28,7 @@ object KotlinStubVersions {
|
||||
// Binary stub version should be increased if stub format (org.jetbrains.kotlin.psi.stubs.impl) is changed
|
||||
// or changes are made to the core stub building code (org.jetbrains.kotlin.idea.decompiler.stubBuilder).
|
||||
// Increasing this version will lead to reindexing of all binary files that are potentially kotlin binaries (including all class files).
|
||||
private const val BINARY_STUB_VERSION = 83
|
||||
private const val BINARY_STUB_VERSION = 84
|
||||
|
||||
// Classfile stub version should be increased if changes are made to classfile stub building subsystem (org.jetbrains.kotlin.idea.decompiler.classFile)
|
||||
// Increasing this version will lead to reindexing of all classfiles.
|
||||
|
||||
+90
-5
@@ -21,9 +21,18 @@ import com.intellij.psi.stubs.StubInputStream;
|
||||
import com.intellij.psi.stubs.StubOutputStream;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.psi.KtProjectionKind;
|
||||
import org.jetbrains.kotlin.psi.KtUserType;
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinUserTypeStub;
|
||||
import org.jetbrains.kotlin.psi.stubs.impl.KotlinUserTypeStubImpl;
|
||||
import org.jetbrains.kotlin.psi.stubs.StubUtils;
|
||||
import org.jetbrains.kotlin.psi.stubs.impl.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class KtUserTypeElementType extends KtStubElementType<KotlinUserTypeStub, KtUserType> {
|
||||
public KtUserTypeElementType(@NotNull @NonNls String debugName) {
|
||||
@@ -33,16 +42,92 @@ public class KtUserTypeElementType extends KtStubElementType<KotlinUserTypeStub,
|
||||
@NotNull
|
||||
@Override
|
||||
public KotlinUserTypeStub createStub(@NotNull KtUserType psi, StubElement parentStub) {
|
||||
return new KotlinUserTypeStubImpl((StubElement<?>) parentStub);
|
||||
return new KotlinUserTypeStubImpl((StubElement<?>) parentStub, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(@NotNull KotlinUserTypeStub stub, @NotNull StubOutputStream dataStream) {
|
||||
public void serialize(@NotNull KotlinUserTypeStub stub, @NotNull StubOutputStream dataStream) throws IOException {
|
||||
serializeType(dataStream, ((KotlinUserTypeStubImpl) stub).getUpperBound());
|
||||
}
|
||||
|
||||
private enum KotlinTypeBeanKind {
|
||||
CLASS, TYPE_PARAMETER, FLEXIBLE, NONE;
|
||||
|
||||
static KotlinTypeBeanKind fromBean(@Nullable KotlinTypeBean typeBean) {
|
||||
if (typeBean == null) return NONE;
|
||||
if (typeBean instanceof KotlinTypeParameterTypeBean) return TYPE_PARAMETER;
|
||||
if (typeBean instanceof KotlinClassTypeBean) return CLASS;
|
||||
return FLEXIBLE;
|
||||
}
|
||||
}
|
||||
|
||||
private static void serializeType(@NotNull StubOutputStream dataStream, @Nullable KotlinTypeBean type) throws IOException {
|
||||
dataStream.writeInt(KotlinTypeBeanKind.fromBean(type).ordinal());
|
||||
if (type instanceof KotlinClassTypeBean) {
|
||||
StubUtils.serializeClassId(dataStream, ((KotlinClassTypeBean) type).getClassId());
|
||||
dataStream.writeBoolean(type.getNullable());
|
||||
List<KotlinTypeArgumentBean> arguments = ((KotlinClassTypeBean) type).getArguments();
|
||||
dataStream.writeInt(arguments.size());
|
||||
for (KotlinTypeArgumentBean argument : arguments) {
|
||||
KtProjectionKind kind = argument.getProjectionKind();
|
||||
dataStream.writeInt(kind.ordinal());
|
||||
if (kind != KtProjectionKind.STAR) {
|
||||
serializeType(dataStream, argument.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type instanceof KotlinTypeParameterTypeBean) {
|
||||
dataStream.writeName(((KotlinTypeParameterTypeBean) type).getTypeParameterName());
|
||||
dataStream.writeBoolean(type.getNullable());
|
||||
dataStream.writeBoolean(((KotlinTypeParameterTypeBean) type).getDefinitelyNotNull());
|
||||
}
|
||||
else if (type instanceof KotlinFlexibleTypeBean) {
|
||||
serializeType(dataStream, ((KotlinFlexibleTypeBean) type).getLowerBound());
|
||||
serializeType(dataStream, ((KotlinFlexibleTypeBean) type).getUpperBound());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public KotlinUserTypeStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) {
|
||||
return new KotlinUserTypeStubImpl((StubElement<?>) parentStub);
|
||||
public KotlinUserTypeStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException {
|
||||
return new KotlinUserTypeStubImpl((StubElement<?>) parentStub, deserializeType(dataStream));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static KotlinTypeBean deserializeType(@NotNull StubInputStream dataStream) throws IOException {
|
||||
KotlinTypeBeanKind typeKind = KotlinTypeBeanKind.values()[dataStream.readInt()];
|
||||
switch (typeKind) {
|
||||
case CLASS: {
|
||||
ClassId classId = Objects.requireNonNull(StubUtils.deserializeClassId(dataStream));
|
||||
boolean isNullable = dataStream.readBoolean();
|
||||
int count = dataStream.readInt();
|
||||
List<KotlinTypeArgumentBean> arguments = new ArrayList<>();
|
||||
for (int i = 0; i < count; i++) {
|
||||
int kind = dataStream.readInt();
|
||||
KotlinTypeArgumentBean argument;
|
||||
if (kind != KtProjectionKind.STAR.ordinal()) {
|
||||
argument = new KotlinTypeArgumentBean(KtProjectionKind.values()[kind], deserializeType(dataStream));
|
||||
}
|
||||
else {
|
||||
argument = new KotlinTypeArgumentBean(KtProjectionKind.STAR, null);
|
||||
}
|
||||
arguments.add(argument);
|
||||
}
|
||||
return new KotlinClassTypeBean(classId, arguments, isNullable);
|
||||
}
|
||||
case TYPE_PARAMETER: {
|
||||
String typeParameterName = Objects.requireNonNull(dataStream.readNameString());
|
||||
boolean nullable = dataStream.readBoolean();
|
||||
boolean definitelyNotNull = dataStream.readBoolean();
|
||||
return new KotlinTypeParameterTypeBean(typeParameterName, nullable, definitelyNotNull);
|
||||
}
|
||||
case FLEXIBLE: {
|
||||
return new KotlinFlexibleTypeBean(Objects.requireNonNull(deserializeType(dataStream)),
|
||||
Objects.requireNonNull(deserializeType(dataStream)));
|
||||
}
|
||||
case NONE:
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,36 @@ package org.jetbrains.kotlin.psi.stubs.impl
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.stubs.StubElement
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.psi.KtProjectionKind
|
||||
import org.jetbrains.kotlin.psi.KtUserType
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinUserTypeStub
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||
|
||||
class KotlinUserTypeStubImpl(
|
||||
parent: StubElement<out PsiElement>?
|
||||
parent: StubElement<out PsiElement>?,
|
||||
val upperBound: KotlinTypeBean? = null
|
||||
) : KotlinStubBaseImpl<KtUserType>(parent, KtStubElementTypes.USER_TYPE), KotlinUserTypeStub
|
||||
|
||||
sealed interface KotlinTypeBean {
|
||||
val nullable: Boolean
|
||||
}
|
||||
|
||||
data class KotlinFlexibleTypeBean(val lowerBound: KotlinTypeBean, val upperBound: KotlinTypeBean) : KotlinTypeBean {
|
||||
override val nullable: Boolean
|
||||
get() = lowerBound.nullable
|
||||
}
|
||||
|
||||
data class KotlinClassTypeBean(
|
||||
val classId: ClassId,
|
||||
val arguments: List<KotlinTypeArgumentBean>,
|
||||
override val nullable: Boolean,
|
||||
) : KotlinTypeBean
|
||||
|
||||
data class KotlinTypeArgumentBean(val projectionKind: KtProjectionKind, val type: KotlinTypeBean?)
|
||||
|
||||
data class KotlinTypeParameterTypeBean(
|
||||
val typeParameterName: String,
|
||||
override val nullable: Boolean,
|
||||
val definitelyNotNull: Boolean
|
||||
) : KotlinTypeBean
|
||||
Reference in New Issue
Block a user