Support reflection for local delegated properties
#KT-15222 Fixed
This commit is contained in:
@@ -56,6 +56,12 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
|||||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) return false
|
if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (old.getExtensionCount(JvmProtoBuf.packageLocalVariable) != new.getExtensionCount(JvmProtoBuf.packageLocalVariable)) return false
|
||||||
|
|
||||||
|
for(i in 0..old.getExtensionCount(JvmProtoBuf.packageLocalVariable) - 1) {
|
||||||
|
if (!checkEquals(old.getExtension(JvmProtoBuf.packageLocalVariable, i), new.getExtension(JvmProtoBuf.packageLocalVariable, i))) return false
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
enum class ProtoBufPackageKind {
|
enum class ProtoBufPackageKind {
|
||||||
@@ -64,7 +70,8 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
|||||||
TYPE_ALIAS_LIST,
|
TYPE_ALIAS_LIST,
|
||||||
TYPE_TABLE,
|
TYPE_TABLE,
|
||||||
SINCE_KOTLIN_INFO_TABLE,
|
SINCE_KOTLIN_INFO_TABLE,
|
||||||
PACKAGE_MODULE_NAME
|
PACKAGE_MODULE_NAME,
|
||||||
|
PACKAGE_LOCAL_VARIABLE_LIST
|
||||||
}
|
}
|
||||||
|
|
||||||
fun difference(old: ProtoBuf.Package, new: ProtoBuf.Package): EnumSet<ProtoBufPackageKind> {
|
fun difference(old: ProtoBuf.Package, new: ProtoBuf.Package): EnumSet<ProtoBufPackageKind> {
|
||||||
@@ -91,6 +98,12 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
|||||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) result.add(ProtoBufPackageKind.PACKAGE_MODULE_NAME)
|
if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) result.add(ProtoBufPackageKind.PACKAGE_MODULE_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (old.getExtensionCount(JvmProtoBuf.packageLocalVariable) != new.getExtensionCount(JvmProtoBuf.packageLocalVariable)) result.add(ProtoBufPackageKind.PACKAGE_LOCAL_VARIABLE_LIST)
|
||||||
|
|
||||||
|
for(i in 0..old.getExtensionCount(JvmProtoBuf.packageLocalVariable) - 1) {
|
||||||
|
if (!checkEquals(old.getExtension(JvmProtoBuf.packageLocalVariable, i), new.getExtension(JvmProtoBuf.packageLocalVariable, i))) result.add(ProtoBufPackageKind.PACKAGE_LOCAL_VARIABLE_LIST)
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,6 +160,12 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
|||||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) return false
|
if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (old.getExtensionCount(JvmProtoBuf.classLocalVariable) != new.getExtensionCount(JvmProtoBuf.classLocalVariable)) return false
|
||||||
|
|
||||||
|
for(i in 0..old.getExtensionCount(JvmProtoBuf.classLocalVariable) - 1) {
|
||||||
|
if (!checkEquals(old.getExtension(JvmProtoBuf.classLocalVariable, i), new.getExtension(JvmProtoBuf.classLocalVariable, i))) return false
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
enum class ProtoBufClassKind {
|
enum class ProtoBufClassKind {
|
||||||
@@ -166,7 +185,8 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
|||||||
TYPE_TABLE,
|
TYPE_TABLE,
|
||||||
SINCE_KOTLIN_INFO,
|
SINCE_KOTLIN_INFO,
|
||||||
SINCE_KOTLIN_INFO_TABLE,
|
SINCE_KOTLIN_INFO_TABLE,
|
||||||
CLASS_MODULE_NAME
|
CLASS_MODULE_NAME,
|
||||||
|
CLASS_LOCAL_VARIABLE_LIST
|
||||||
}
|
}
|
||||||
|
|
||||||
fun difference(old: ProtoBuf.Class, new: ProtoBuf.Class): EnumSet<ProtoBufClassKind> {
|
fun difference(old: ProtoBuf.Class, new: ProtoBuf.Class): EnumSet<ProtoBufClassKind> {
|
||||||
@@ -224,6 +244,12 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
|||||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) result.add(ProtoBufClassKind.CLASS_MODULE_NAME)
|
if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) result.add(ProtoBufClassKind.CLASS_MODULE_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (old.getExtensionCount(JvmProtoBuf.classLocalVariable) != new.getExtensionCount(JvmProtoBuf.classLocalVariable)) result.add(ProtoBufClassKind.CLASS_LOCAL_VARIABLE_LIST)
|
||||||
|
|
||||||
|
for(i in 0..old.getExtensionCount(JvmProtoBuf.classLocalVariable) - 1) {
|
||||||
|
if (!checkEquals(old.getExtension(JvmProtoBuf.classLocalVariable, i), new.getExtension(JvmProtoBuf.classLocalVariable, i))) result.add(ProtoBufClassKind.CLASS_LOCAL_VARIABLE_LIST)
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1053,6 +1079,10 @@ fun ProtoBuf.Package.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int)
|
|||||||
hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.packageModuleName))
|
hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.packageModuleName))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(i in 0..getExtensionCount(JvmProtoBuf.packageLocalVariable) - 1) {
|
||||||
|
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.packageLocalVariable, i).hashCode(stringIndexes, fqNameIndexes)
|
||||||
|
}
|
||||||
|
|
||||||
return hashCode
|
return hashCode
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1125,6 +1155,10 @@ fun ProtoBuf.Class.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) ->
|
|||||||
hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.classModuleName))
|
hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.classModuleName))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(i in 0..getExtensionCount(JvmProtoBuf.classLocalVariable) - 1) {
|
||||||
|
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.classLocalVariable, i).hashCode(stringIndexes, fqNameIndexes)
|
||||||
|
}
|
||||||
|
|
||||||
return hashCode
|
return hashCode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ public final class DebugJvmProtoBuf {
|
|||||||
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.isRaw);
|
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.isRaw);
|
||||||
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.typeParameterAnnotation);
|
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.typeParameterAnnotation);
|
||||||
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.classModuleName);
|
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.classModuleName);
|
||||||
|
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.classLocalVariable);
|
||||||
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.packageModuleName);
|
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.packageModuleName);
|
||||||
|
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.packageLocalVariable);
|
||||||
}
|
}
|
||||||
public interface StringTableTypesOrBuilder extends
|
public interface StringTableTypesOrBuilder extends
|
||||||
// @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.jvm.StringTableTypes)
|
// @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.jvm.StringTableTypes)
|
||||||
@@ -4586,6 +4588,17 @@ public final class DebugJvmProtoBuf {
|
|||||||
.newFileScopedGeneratedExtension(
|
.newFileScopedGeneratedExtension(
|
||||||
java.lang.Integer.class,
|
java.lang.Integer.class,
|
||||||
null);
|
null);
|
||||||
|
public static final int CLASS_LOCAL_VARIABLE_FIELD_NUMBER = 102;
|
||||||
|
/**
|
||||||
|
* <code>extend .org.jetbrains.kotlin.serialization.Class { ... }</code>
|
||||||
|
*/
|
||||||
|
public static final
|
||||||
|
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||||
|
org.jetbrains.kotlin.serialization.DebugProtoBuf.Class,
|
||||||
|
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Property>> classLocalVariable = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||||
|
.newFileScopedGeneratedExtension(
|
||||||
|
org.jetbrains.kotlin.serialization.DebugProtoBuf.Property.class,
|
||||||
|
org.jetbrains.kotlin.serialization.DebugProtoBuf.Property.getDefaultInstance());
|
||||||
public static final int PACKAGE_MODULE_NAME_FIELD_NUMBER = 101;
|
public static final int PACKAGE_MODULE_NAME_FIELD_NUMBER = 101;
|
||||||
/**
|
/**
|
||||||
* <code>extend .org.jetbrains.kotlin.serialization.Package { ... }</code>
|
* <code>extend .org.jetbrains.kotlin.serialization.Package { ... }</code>
|
||||||
@@ -4597,6 +4610,17 @@ public final class DebugJvmProtoBuf {
|
|||||||
.newFileScopedGeneratedExtension(
|
.newFileScopedGeneratedExtension(
|
||||||
java.lang.Integer.class,
|
java.lang.Integer.class,
|
||||||
null);
|
null);
|
||||||
|
public static final int PACKAGE_LOCAL_VARIABLE_FIELD_NUMBER = 102;
|
||||||
|
/**
|
||||||
|
* <code>extend .org.jetbrains.kotlin.serialization.Package { ... }</code>
|
||||||
|
*/
|
||||||
|
public static final
|
||||||
|
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||||
|
org.jetbrains.kotlin.serialization.DebugProtoBuf.Package,
|
||||||
|
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Property>> packageLocalVariable = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||||
|
.newFileScopedGeneratedExtension(
|
||||||
|
org.jetbrains.kotlin.serialization.DebugProtoBuf.Property.class,
|
||||||
|
org.jetbrains.kotlin.serialization.DebugProtoBuf.Property.getDefaultInstance());
|
||||||
private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
|
private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
|
||||||
internal_static_org_jetbrains_kotlin_serialization_jvm_StringTableTypes_descriptor;
|
internal_static_org_jetbrains_kotlin_serialization_jvm_StringTableTypes_descriptor;
|
||||||
private static
|
private static
|
||||||
@@ -4678,9 +4702,15 @@ public final class DebugJvmProtoBuf {
|
|||||||
"g.jetbrains.kotlin.serialization.Annotat" +
|
"g.jetbrains.kotlin.serialization.Annotat" +
|
||||||
"ion:J\n\021class_module_name\022).org.jetbrains" +
|
"ion:J\n\021class_module_name\022).org.jetbrains" +
|
||||||
".kotlin.serialization.Class\030e \001(\005B\004\230\265\030\001:" +
|
".kotlin.serialization.Class\030e \001(\005B\004\230\265\030\001:" +
|
||||||
"N\n\023package_module_name\022+.org.jetbrains.k" +
|
"u\n\024class_local_variable\022).org.jetbrains." +
|
||||||
"otlin.serialization.Package\030e \001(\005B\004\230\265\030\001B" +
|
"kotlin.serialization.Class\030f \003(\0132,.org.j" +
|
||||||
"\022B\020DebugJvmProtoBuf"
|
"etbrains.kotlin.serialization.Property:N",
|
||||||
|
"\n\023package_module_name\022+.org.jetbrains.ko" +
|
||||||
|
"tlin.serialization.Package\030e \001(\005B\004\230\265\030\001:y" +
|
||||||
|
"\n\026package_local_variable\022+.org.jetbrains" +
|
||||||
|
".kotlin.serialization.Package\030f \003(\0132,.or" +
|
||||||
|
"g.jetbrains.kotlin.serialization.Propert" +
|
||||||
|
"yB\022B\020DebugJvmProtoBuf"
|
||||||
};
|
};
|
||||||
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||||
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {
|
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {
|
||||||
@@ -4733,7 +4763,9 @@ public final class DebugJvmProtoBuf {
|
|||||||
isRaw.internalInit(descriptor.getExtensions().get(4));
|
isRaw.internalInit(descriptor.getExtensions().get(4));
|
||||||
typeParameterAnnotation.internalInit(descriptor.getExtensions().get(5));
|
typeParameterAnnotation.internalInit(descriptor.getExtensions().get(5));
|
||||||
classModuleName.internalInit(descriptor.getExtensions().get(6));
|
classModuleName.internalInit(descriptor.getExtensions().get(6));
|
||||||
packageModuleName.internalInit(descriptor.getExtensions().get(7));
|
classLocalVariable.internalInit(descriptor.getExtensions().get(7));
|
||||||
|
packageModuleName.internalInit(descriptor.getExtensions().get(8));
|
||||||
|
packageLocalVariable.internalInit(descriptor.getExtensions().get(9));
|
||||||
org.jetbrains.kotlin.protobuf.ExtensionRegistry registry =
|
org.jetbrains.kotlin.protobuf.ExtensionRegistry registry =
|
||||||
org.jetbrains.kotlin.protobuf.ExtensionRegistry.newInstance();
|
org.jetbrains.kotlin.protobuf.ExtensionRegistry.newInstance();
|
||||||
registry.add(org.jetbrains.kotlin.serialization.DebugExtOptionsProtoBuf.stringIdInTable);
|
registry.add(org.jetbrains.kotlin.serialization.DebugExtOptionsProtoBuf.stringIdInTable);
|
||||||
|
|||||||
@@ -175,8 +175,11 @@ class MultifileClassPartCodegen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val serializer = DescriptorSerializer.createTopLevel(JvmSerializerExtension(v.serializationBindings, state))
|
val extension = JvmSerializerExtension(v.serializationBindings, state)
|
||||||
val packageProto = serializer.packagePartProto(packageFragment.fqName, members).build()
|
val serializer = DescriptorSerializer.createTopLevel(extension)
|
||||||
|
val builder = serializer.packagePartProto(packageFragment.fqName, members)
|
||||||
|
extension.serializeJvmPackage(builder, partType)
|
||||||
|
val packageProto = builder.build()
|
||||||
|
|
||||||
val extraFlags = if (shouldGeneratePartHierarchy) JvmAnnotationNames.METADATA_MULTIFILE_PARTS_INHERIT_FLAG else 0
|
val extraFlags = if (shouldGeneratePartHierarchy) JvmAnnotationNames.METADATA_MULTIFILE_PARTS_INHERIT_FLAG else 0
|
||||||
|
|
||||||
|
|||||||
@@ -119,9 +119,11 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorSerializer serializer =
|
JvmSerializerExtension extension = new JvmSerializerExtension(v.getSerializationBindings(), state);
|
||||||
DescriptorSerializer.createTopLevel(new JvmSerializerExtension(v.getSerializationBindings(), state));
|
DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(extension);
|
||||||
ProtoBuf.Package packageProto = serializer.packagePartProto(element.getPackageFqName(), members).build();
|
ProtoBuf.Package.Builder builder = serializer.packagePartProto(element.getPackageFqName(), members);
|
||||||
|
extension.serializeJvmPackage(builder, packagePartType);
|
||||||
|
ProtoBuf.Package packageProto = builder.build();
|
||||||
|
|
||||||
WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.FILE_FACADE, 0, av -> {
|
WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.FILE_FACADE, 0, av -> {
|
||||||
writeAnnotationData(av, serializer, packageProto);
|
writeAnnotationData(av, serializer, packageProto);
|
||||||
|
|||||||
@@ -17,14 +17,25 @@
|
|||||||
package org.jetbrains.kotlin.codegen
|
package org.jetbrains.kotlin.codegen
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import java.util.ArrayList
|
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a function descriptor, creates another function descriptor with type parameters copied from outer context(s).
|
* Given a function descriptor, creates another function descriptor with type parameters copied from outer context(s).
|
||||||
* This is needed because once we're serializing this to a proto, there's no place to store information about external type parameters.
|
* This is needed because once we're serializing this to a proto, there's no place to store information about external type parameters.
|
||||||
*/
|
*/
|
||||||
fun createFreeFakeLambdaDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor {
|
fun createFreeFakeLambdaDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor {
|
||||||
val builder = descriptor.newCopyBuilder()
|
return createFreeDescriptor(descriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <D : CallableMemberDescriptor> createFreeDescriptor(descriptor: D): D {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val builder = descriptor.newCopyBuilder() as CallableMemberDescriptor.CopyBuilder<D>
|
||||||
|
|
||||||
val typeParameters = ArrayList<TypeParameterDescriptor>(0)
|
val typeParameters = ArrayList<TypeParameterDescriptor>(0)
|
||||||
builder.setTypeParameters(typeParameters)
|
builder.setTypeParameters(typeParameters)
|
||||||
|
|
||||||
@@ -41,3 +52,32 @@ fun createFreeFakeLambdaDescriptor(descriptor: FunctionDescriptor): FunctionDesc
|
|||||||
|
|
||||||
return if (typeParameters.isEmpty()) descriptor else builder.build()!!
|
return if (typeParameters.isEmpty()) descriptor else builder.build()!!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a local delegated variable descriptor, creates a descriptor of a property that should be observed
|
||||||
|
* when using reflection on that local variable at runtime.
|
||||||
|
* Only members used by [DescriptorSerializer.propertyProto] are implemented correctly in this property descriptor.
|
||||||
|
*/
|
||||||
|
fun createFreeFakeLocalPropertyDescriptor(descriptor: LocalVariableDescriptor): PropertyDescriptor {
|
||||||
|
val property = PropertyDescriptorImpl.create(
|
||||||
|
descriptor.containingDeclaration, descriptor.annotations, Modality.FINAL, descriptor.visibility, descriptor.isVar,
|
||||||
|
descriptor.name, CallableMemberDescriptor.Kind.DECLARATION, descriptor.source, false, descriptor.isConst,
|
||||||
|
false, false, false, @Suppress("DEPRECATION") descriptor.isDelegated
|
||||||
|
)
|
||||||
|
property.setType(descriptor.type, descriptor.typeParameters, descriptor.dispatchReceiverParameter, descriptor.extensionReceiverParameter)
|
||||||
|
|
||||||
|
property.initialize(
|
||||||
|
descriptor.getter?.run {
|
||||||
|
PropertyGetterDescriptorImpl(property, annotations, modality, visibility, true, isExternal, isInline, kind, null, source).apply {
|
||||||
|
initialize(this@run.returnType)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
descriptor.setter?.run {
|
||||||
|
PropertySetterDescriptorImpl(property, annotations, modality, visibility, true, isExternal, isInline, kind, null, source).apply {
|
||||||
|
initialize(this@run.valueParameters.single())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return createFreeDescriptor(property)
|
||||||
|
}
|
||||||
|
|||||||
+39
-5
@@ -20,19 +20,22 @@ import com.intellij.openapi.util.Pair;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode;
|
import org.jetbrains.kotlin.codegen.ClassBuilderMode;
|
||||||
|
import org.jetbrains.kotlin.codegen.FakeDescriptorsForReferencesKt;
|
||||||
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||||
import org.jetbrains.kotlin.load.java.lazy.types.RawTypeImpl;
|
import org.jetbrains.kotlin.load.java.lazy.types.RawTypeImpl;
|
||||||
import org.jetbrains.kotlin.load.kotlin.JavaFlexibleTypeDeserializer;
|
import org.jetbrains.kotlin.load.kotlin.JavaFlexibleTypeDeserializer;
|
||||||
import org.jetbrains.kotlin.load.kotlin.TypeSignatureMappingKt;
|
import org.jetbrains.kotlin.load.kotlin.TypeSignatureMappingKt;
|
||||||
import org.jetbrains.kotlin.name.ClassId;
|
import org.jetbrains.kotlin.name.ClassId;
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
import org.jetbrains.kotlin.serialization.AnnotationSerializer;
|
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite;
|
||||||
import org.jetbrains.kotlin.serialization.ProtoBuf;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
import org.jetbrains.kotlin.serialization.SerializerExtension;
|
import org.jetbrains.kotlin.serialization.*;
|
||||||
import org.jetbrains.kotlin.serialization.StringTable;
|
|
||||||
import org.jetbrains.kotlin.serialization.jvm.ClassMapperLite;
|
import org.jetbrains.kotlin.serialization.jvm.ClassMapperLite;
|
||||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf;
|
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf;
|
||||||
import org.jetbrains.kotlin.types.FlexibleType;
|
import org.jetbrains.kotlin.types.FlexibleType;
|
||||||
@@ -40,10 +43,14 @@ import org.jetbrains.kotlin.types.KotlinType;
|
|||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*;
|
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*;
|
||||||
|
|
||||||
public class JvmSerializerExtension extends SerializerExtension {
|
public class JvmSerializerExtension extends SerializerExtension {
|
||||||
private final JvmSerializationBindings bindings;
|
private final JvmSerializationBindings bindings;
|
||||||
|
private final BindingContext codegenBinding;
|
||||||
|
private final KotlinTypeMapper typeMapper;
|
||||||
private final StringTable stringTable;
|
private final StringTable stringTable;
|
||||||
private final AnnotationSerializer annotationSerializer;
|
private final AnnotationSerializer annotationSerializer;
|
||||||
private final boolean useTypeTable;
|
private final boolean useTypeTable;
|
||||||
@@ -52,7 +59,9 @@ public class JvmSerializerExtension extends SerializerExtension {
|
|||||||
|
|
||||||
public JvmSerializerExtension(@NotNull JvmSerializationBindings bindings, @NotNull GenerationState state) {
|
public JvmSerializerExtension(@NotNull JvmSerializationBindings bindings, @NotNull GenerationState state) {
|
||||||
this.bindings = bindings;
|
this.bindings = bindings;
|
||||||
this.stringTable = new JvmStringTable(state.getTypeMapper());
|
this.codegenBinding = state.getBindingContext();
|
||||||
|
this.typeMapper = state.getTypeMapper();
|
||||||
|
this.stringTable = new JvmStringTable(typeMapper);
|
||||||
this.annotationSerializer = new AnnotationSerializer(stringTable);
|
this.annotationSerializer = new AnnotationSerializer(stringTable);
|
||||||
this.useTypeTable = state.getUseTypeTableInSerializer();
|
this.useTypeTable = state.getUseTypeTableInSerializer();
|
||||||
this.moduleName = state.getModuleName();
|
this.moduleName = state.getModuleName();
|
||||||
@@ -75,6 +84,8 @@ public class JvmSerializerExtension extends SerializerExtension {
|
|||||||
if (!moduleName.equals(JvmAbi.DEFAULT_MODULE_NAME)) {
|
if (!moduleName.equals(JvmAbi.DEFAULT_MODULE_NAME)) {
|
||||||
proto.setExtension(JvmProtoBuf.classModuleName, stringTable.getStringIndex(moduleName));
|
proto.setExtension(JvmProtoBuf.classModuleName, stringTable.getStringIndex(moduleName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writeLocalProperties(proto, typeMapper.mapClass(descriptor), JvmProtoBuf.classLocalVariable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -84,6 +95,29 @@ public class JvmSerializerExtension extends SerializerExtension {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void serializeJvmPackage(@NotNull ProtoBuf.Package.Builder proto, @NotNull Type partAsmType) {
|
||||||
|
writeLocalProperties(proto, partAsmType, JvmProtoBuf.packageLocalVariable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <MessageType extends GeneratedMessageLite.ExtendableMessage<MessageType>,
|
||||||
|
BuilderType extends GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>> void writeLocalProperties(
|
||||||
|
@NotNull BuilderType proto,
|
||||||
|
@NotNull Type classAsmType,
|
||||||
|
@NotNull GeneratedMessageLite.GeneratedExtension<MessageType, List<ProtoBuf.Property>> extension
|
||||||
|
) {
|
||||||
|
List<VariableDescriptorWithAccessors> localVariables = codegenBinding.get(CodegenBinding.DELEGATED_PROPERTIES, classAsmType);
|
||||||
|
if (localVariables == null) return;
|
||||||
|
|
||||||
|
for (VariableDescriptorWithAccessors localVariable : localVariables) {
|
||||||
|
if (localVariable instanceof LocalVariableDescriptor) {
|
||||||
|
PropertyDescriptor propertyDescriptor =
|
||||||
|
FakeDescriptorsForReferencesKt.createFreeFakeLocalPropertyDescriptor((LocalVariableDescriptor) localVariable);
|
||||||
|
DescriptorSerializer serializer = DescriptorSerializer.createForLambda(this);
|
||||||
|
proto.addExtension(extension, serializer.propertyProto(propertyDescriptor).build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serializeFlexibleType(
|
public void serializeFlexibleType(
|
||||||
@NotNull FlexibleType flexibleType,
|
@NotNull FlexibleType flexibleType,
|
||||||
|
|||||||
+4
-4
@@ -26,8 +26,8 @@ import org.jetbrains.kotlin.types.TypeSubstitutor;
|
|||||||
|
|
||||||
public class LocalVariableDescriptor extends VariableDescriptorWithInitializerImpl implements VariableDescriptorWithAccessors {
|
public class LocalVariableDescriptor extends VariableDescriptorWithInitializerImpl implements VariableDescriptorWithAccessors {
|
||||||
private final boolean isDelegated;
|
private final boolean isDelegated;
|
||||||
private VariableAccessorDescriptor getter;
|
private LocalVariableAccessorDescriptor.Getter getter;
|
||||||
private VariableAccessorDescriptor setter;
|
private LocalVariableAccessorDescriptor.Setter setter;
|
||||||
|
|
||||||
public LocalVariableDescriptor(
|
public LocalVariableDescriptor(
|
||||||
@NotNull DeclarationDescriptor containingDeclaration,
|
@NotNull DeclarationDescriptor containingDeclaration,
|
||||||
@@ -73,13 +73,13 @@ public class LocalVariableDescriptor extends VariableDescriptorWithInitializerIm
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public VariableAccessorDescriptor getGetter() {
|
public LocalVariableAccessorDescriptor.Getter getGetter() {
|
||||||
return getter;
|
return getter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public VariableAccessorDescriptor getSetter() {
|
public LocalVariableAccessorDescriptor.Setter getSetter() {
|
||||||
return setter;
|
return setter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+75
@@ -0,0 +1,75 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
import kotlin.reflect.*
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
object Delegate {
|
||||||
|
lateinit var property: KProperty<*>
|
||||||
|
|
||||||
|
operator fun getValue(instance: Any?, kProperty: KProperty<*>): List<String?> {
|
||||||
|
property = kProperty
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun setValue(instance: Any?, kProperty: KProperty<*>, value: List<String?>) {
|
||||||
|
throw AssertionError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun check(expectedName: String, p: KProperty0<*>): String? {
|
||||||
|
assertEquals(expectedName, p.name)
|
||||||
|
assertEquals(emptyList<KParameter>(), p.parameters)
|
||||||
|
assertEquals(emptyList<KTypeParameter>(), p.typeParameters)
|
||||||
|
assertEquals(null, p.visibility) // "local" visibility is not representable with reflection API
|
||||||
|
assertEquals("kotlin.collections.List<kotlin.String?>", p.returnType.toString())
|
||||||
|
assertTrue(p.isFinal)
|
||||||
|
assertFalse(p.isOpen)
|
||||||
|
assertFalse(p.isAbstract)
|
||||||
|
assertFalse(p.isLateinit)
|
||||||
|
assertFalse(p.isConst)
|
||||||
|
|
||||||
|
// TODO: support getDelegate for local delegated properties
|
||||||
|
assertEquals(null, (p as KProperty0<*>).getDelegate())
|
||||||
|
|
||||||
|
assertEquals(emptyList<KParameter>(), p.getter.parameters)
|
||||||
|
assertEquals("kotlin.collections.List<kotlin.String?>", p.getter.returnType.toString())
|
||||||
|
|
||||||
|
// TODO: support annotations
|
||||||
|
assertEquals(emptyList<Annotation>(), p.annotations)
|
||||||
|
|
||||||
|
try {
|
||||||
|
p.call()
|
||||||
|
return "Fail: reflective call of a local delegated property should fail because it's not supported"
|
||||||
|
} catch (e: UnsupportedOperationException) { /* ok */ }
|
||||||
|
|
||||||
|
if (p is KMutableProperty0<*>) {
|
||||||
|
assertEquals(listOf("kotlin.collections.List<kotlin.String?>"), p.setter.parameters.map { it.type.toString() })
|
||||||
|
assertEquals("kotlin.Unit", p.setter.returnType.toString())
|
||||||
|
|
||||||
|
try {
|
||||||
|
p.setter.call()
|
||||||
|
return "Fail: reflective call of a local delegated property setter should fail because it's not supported"
|
||||||
|
} catch (e: UnsupportedOperationException) { /* ok */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
annotation class Anno
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
@Anno
|
||||||
|
val localVal by Delegate
|
||||||
|
localVal
|
||||||
|
|
||||||
|
check("localVal", Delegate.property as KProperty0<*>)?.let { error -> return error }
|
||||||
|
|
||||||
|
@Anno
|
||||||
|
var localVar by Delegate
|
||||||
|
localVar
|
||||||
|
|
||||||
|
check("localVar", Delegate.property as KProperty0<*>)?.let { error -> return error }
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
// FILE: 1.kt
|
||||||
|
|
||||||
|
@file:JvmMultifileClass
|
||||||
|
@file:JvmName("Test")
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.*
|
||||||
|
|
||||||
|
object Delegate {
|
||||||
|
lateinit var property: KProperty<*>
|
||||||
|
|
||||||
|
operator fun getValue(instance: Any?, kProperty: KProperty<*>): List<String?> {
|
||||||
|
property = kProperty
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: 2.kt
|
||||||
|
|
||||||
|
@file:JvmMultifileClass
|
||||||
|
@file:JvmName("Test")
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun foo() {
|
||||||
|
val x by Delegate
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
import test.*
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
foo()
|
||||||
|
assertEquals("val x: kotlin.collections.List<kotlin.String?>", Delegate.property.toString())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+31
@@ -0,0 +1,31 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
import kotlin.reflect.*
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
class Delegate<out T>(val value: T) {
|
||||||
|
lateinit var property: KProperty<*>
|
||||||
|
|
||||||
|
operator fun getValue(instance: Any?, kProperty: KProperty<*>): T {
|
||||||
|
property = kProperty
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class A<X> {
|
||||||
|
inner class B<Y> {
|
||||||
|
fun <Z> foo() {
|
||||||
|
val delegate = Delegate<Map<Pair<X, Y>, Z>>(emptyMap())
|
||||||
|
val c: Map<Pair<X, Y>, Z> by delegate
|
||||||
|
c
|
||||||
|
|
||||||
|
assertEquals("kotlin.collections.Map<kotlin.Pair<X, Y>, Z>", delegate.property.returnType.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
A<String>().B<Int>().foo<Double>()
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+27
@@ -16041,6 +16041,33 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class LocalDelegated extends AbstractIrBlackBoxCodegenTest {
|
||||||
|
public void testAllFilesPresentInLocalDelegated() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/properties/localDelegated"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localDelegatedProperty.kt")
|
||||||
|
public void testLocalDelegatedProperty() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/localDelegatedProperty.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multiFileClass.kt")
|
||||||
|
public void testMultiFileClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/multiFileClass.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("variableOfGenericType.kt")
|
||||||
|
public void testVariableOfGenericType() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/variableOfGenericType.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/specialBuiltIns")
|
@TestMetadata("compiler/testData/codegen/box/reflection/specialBuiltIns")
|
||||||
|
|||||||
@@ -16041,6 +16041,33 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class LocalDelegated extends AbstractBlackBoxCodegenTest {
|
||||||
|
public void testAllFilesPresentInLocalDelegated() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/properties/localDelegated"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localDelegatedProperty.kt")
|
||||||
|
public void testLocalDelegatedProperty() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/localDelegatedProperty.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multiFileClass.kt")
|
||||||
|
public void testMultiFileClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/multiFileClass.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("variableOfGenericType.kt")
|
||||||
|
public void testVariableOfGenericType() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/variableOfGenericType.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/specialBuiltIns")
|
@TestMetadata("compiler/testData/codegen/box/reflection/specialBuiltIns")
|
||||||
|
|||||||
@@ -16041,6 +16041,33 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class LocalDelegated extends AbstractLightAnalysisModeTest {
|
||||||
|
public void testAllFilesPresentInLocalDelegated() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/properties/localDelegated"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localDelegatedProperty.kt")
|
||||||
|
public void testLocalDelegatedProperty() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/localDelegatedProperty.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multiFileClass.kt")
|
||||||
|
public void testMultiFileClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/multiFileClass.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("variableOfGenericType.kt")
|
||||||
|
public void testVariableOfGenericType() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/variableOfGenericType.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/specialBuiltIns")
|
@TestMetadata("compiler/testData/codegen/box/reflection/specialBuiltIns")
|
||||||
|
|||||||
@@ -112,8 +112,12 @@ extend TypeParameter {
|
|||||||
extend Class {
|
extend Class {
|
||||||
// If absent, assumed to be JvmAbi.DEFAULT_MODULE_NAME
|
// If absent, assumed to be JvmAbi.DEFAULT_MODULE_NAME
|
||||||
optional int32 class_module_name = 101 [(string_id_in_table) = true];
|
optional int32 class_module_name = 101 [(string_id_in_table) = true];
|
||||||
|
|
||||||
|
repeated Property class_local_variable = 102;
|
||||||
}
|
}
|
||||||
|
|
||||||
extend Package {
|
extend Package {
|
||||||
optional int32 package_module_name = 101 [(string_id_in_table) = true];
|
optional int32 package_module_name = 101 [(string_id_in_table) = true];
|
||||||
|
|
||||||
|
repeated Property package_local_variable = 102;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ class JvmMetadataVersion(vararg numbers: Int) : BinaryVersion(*numbers) {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField
|
@JvmField
|
||||||
val INSTANCE = JvmMetadataVersion(1, 1, 6)
|
val INSTANCE = JvmMetadataVersion(1, 1, 7)
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val INVALID_VERSION = JvmMetadataVersion()
|
val INVALID_VERSION = JvmMetadataVersion()
|
||||||
|
|||||||
+34
@@ -14,7 +14,9 @@ public final class JvmProtoBuf {
|
|||||||
registry.add(org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.isRaw);
|
registry.add(org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.isRaw);
|
||||||
registry.add(org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.typeParameterAnnotation);
|
registry.add(org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.typeParameterAnnotation);
|
||||||
registry.add(org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.classModuleName);
|
registry.add(org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.classModuleName);
|
||||||
|
registry.add(org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.classLocalVariable);
|
||||||
registry.add(org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.packageModuleName);
|
registry.add(org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.packageModuleName);
|
||||||
|
registry.add(org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.packageLocalVariable);
|
||||||
}
|
}
|
||||||
public interface StringTableTypesOrBuilder extends
|
public interface StringTableTypesOrBuilder extends
|
||||||
// @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.jvm.StringTableTypes)
|
// @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.jvm.StringTableTypes)
|
||||||
@@ -3901,6 +3903,22 @@ public final class JvmProtoBuf {
|
|||||||
101,
|
101,
|
||||||
org.jetbrains.kotlin.protobuf.WireFormat.FieldType.INT32,
|
org.jetbrains.kotlin.protobuf.WireFormat.FieldType.INT32,
|
||||||
java.lang.Integer.class);
|
java.lang.Integer.class);
|
||||||
|
public static final int CLASS_LOCAL_VARIABLE_FIELD_NUMBER = 102;
|
||||||
|
/**
|
||||||
|
* <code>extend .org.jetbrains.kotlin.serialization.Class { ... }</code>
|
||||||
|
*/
|
||||||
|
public static final
|
||||||
|
org.jetbrains.kotlin.protobuf.GeneratedMessageLite.GeneratedExtension<
|
||||||
|
org.jetbrains.kotlin.serialization.ProtoBuf.Class,
|
||||||
|
java.util.List<org.jetbrains.kotlin.serialization.ProtoBuf.Property>> classLocalVariable = org.jetbrains.kotlin.protobuf.GeneratedMessageLite
|
||||||
|
.newRepeatedGeneratedExtension(
|
||||||
|
org.jetbrains.kotlin.serialization.ProtoBuf.Class.getDefaultInstance(),
|
||||||
|
org.jetbrains.kotlin.serialization.ProtoBuf.Property.getDefaultInstance(),
|
||||||
|
null,
|
||||||
|
102,
|
||||||
|
org.jetbrains.kotlin.protobuf.WireFormat.FieldType.MESSAGE,
|
||||||
|
false,
|
||||||
|
org.jetbrains.kotlin.serialization.ProtoBuf.Property.class);
|
||||||
public static final int PACKAGE_MODULE_NAME_FIELD_NUMBER = 101;
|
public static final int PACKAGE_MODULE_NAME_FIELD_NUMBER = 101;
|
||||||
/**
|
/**
|
||||||
* <code>extend .org.jetbrains.kotlin.serialization.Package { ... }</code>
|
* <code>extend .org.jetbrains.kotlin.serialization.Package { ... }</code>
|
||||||
@@ -3917,6 +3935,22 @@ public final class JvmProtoBuf {
|
|||||||
101,
|
101,
|
||||||
org.jetbrains.kotlin.protobuf.WireFormat.FieldType.INT32,
|
org.jetbrains.kotlin.protobuf.WireFormat.FieldType.INT32,
|
||||||
java.lang.Integer.class);
|
java.lang.Integer.class);
|
||||||
|
public static final int PACKAGE_LOCAL_VARIABLE_FIELD_NUMBER = 102;
|
||||||
|
/**
|
||||||
|
* <code>extend .org.jetbrains.kotlin.serialization.Package { ... }</code>
|
||||||
|
*/
|
||||||
|
public static final
|
||||||
|
org.jetbrains.kotlin.protobuf.GeneratedMessageLite.GeneratedExtension<
|
||||||
|
org.jetbrains.kotlin.serialization.ProtoBuf.Package,
|
||||||
|
java.util.List<org.jetbrains.kotlin.serialization.ProtoBuf.Property>> packageLocalVariable = org.jetbrains.kotlin.protobuf.GeneratedMessageLite
|
||||||
|
.newRepeatedGeneratedExtension(
|
||||||
|
org.jetbrains.kotlin.serialization.ProtoBuf.Package.getDefaultInstance(),
|
||||||
|
org.jetbrains.kotlin.serialization.ProtoBuf.Property.getDefaultInstance(),
|
||||||
|
null,
|
||||||
|
102,
|
||||||
|
org.jetbrains.kotlin.protobuf.WireFormat.FieldType.MESSAGE,
|
||||||
|
false,
|
||||||
|
org.jetbrains.kotlin.serialization.ProtoBuf.Property.class);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.kotlin.types.TypeSubstitution;
|
import org.jetbrains.kotlin.types.TypeSubstitution;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface CallableMemberDescriptor extends CallableDescriptor, MemberDescriptor {
|
public interface CallableMemberDescriptor extends CallableDescriptor, MemberDescriptor {
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -70,6 +71,9 @@ public interface CallableMemberDescriptor extends CallableDescriptor, MemberDesc
|
|||||||
@NotNull
|
@NotNull
|
||||||
CopyBuilder<D> setKind(@NotNull Kind kind);
|
CopyBuilder<D> setKind(@NotNull Kind kind);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
CopyBuilder<D> setTypeParameters(@NotNull List<TypeParameterDescriptor> parameters);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
CopyBuilder<D> setDispatchReceiverParameter(@Nullable ReceiverParameterDescriptor dispatchReceiverParameter);
|
CopyBuilder<D> setDispatchReceiverParameter(@Nullable ReceiverParameterDescriptor dispatchReceiverParameter);
|
||||||
|
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ public interface FunctionDescriptor extends CallableMemberDescriptor {
|
|||||||
CopyBuilder<D> setValueParameters(@NotNull List<ValueParameterDescriptor> parameters);
|
CopyBuilder<D> setValueParameters(@NotNull List<ValueParameterDescriptor> parameters);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
@Override
|
||||||
CopyBuilder<D> setTypeParameters(@NotNull List<TypeParameterDescriptor> parameters);
|
CopyBuilder<D> setTypeParameters(@NotNull List<TypeParameterDescriptor> parameters);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
+14
-10
@@ -237,24 +237,20 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
|||||||
|
|
||||||
return newCopyBuilder()
|
return newCopyBuilder()
|
||||||
.setSubstitution(originalSubstitutor.getSubstitution())
|
.setSubstitution(originalSubstitutor.getSubstitution())
|
||||||
.setOwner(getContainingDeclaration())
|
|
||||||
.setModality(modality)
|
|
||||||
.setVisibility(visibility)
|
|
||||||
.setOriginal(getOriginal())
|
.setOriginal(getOriginal())
|
||||||
.setCopyOverrides(true)
|
|
||||||
.setKind(getKind())
|
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CopyConfiguration implements PropertyDescriptor.CopyBuilder<PropertyDescriptor> {
|
public class CopyConfiguration implements PropertyDescriptor.CopyBuilder<PropertyDescriptor> {
|
||||||
private DeclarationDescriptor owner;
|
private DeclarationDescriptor owner = getContainingDeclaration();
|
||||||
private Modality modality;
|
private Modality modality = getModality();
|
||||||
private Visibility visibility;
|
private Visibility visibility = getVisibility();
|
||||||
private PropertyDescriptor original = null;
|
private PropertyDescriptor original = null;
|
||||||
private Kind kind;
|
private Kind kind = getKind();
|
||||||
private TypeSubstitution substitution = TypeSubstitution.EMPTY;
|
private TypeSubstitution substitution = TypeSubstitution.EMPTY;
|
||||||
private boolean copyOverrides = true;
|
private boolean copyOverrides = true;
|
||||||
private ReceiverParameterDescriptor dispatchReceiverParameter = PropertyDescriptorImpl.this.dispatchReceiverParameter;
|
private ReceiverParameterDescriptor dispatchReceiverParameter = PropertyDescriptorImpl.this.dispatchReceiverParameter;
|
||||||
|
private List<TypeParameterDescriptor> newTypeParameters = null;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
@@ -290,6 +286,13 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public CopyBuilder<PropertyDescriptor> setTypeParameters(@NotNull List<TypeParameterDescriptor> typeParameters) {
|
||||||
|
this.newTypeParameters = typeParameters;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public CopyConfiguration setDispatchReceiverParameter(@Nullable ReceiverParameterDescriptor dispatchReceiverParameter) {
|
public CopyConfiguration setDispatchReceiverParameter(@Nullable ReceiverParameterDescriptor dispatchReceiverParameter) {
|
||||||
@@ -330,7 +333,8 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
|||||||
copyConfiguration.owner, copyConfiguration.modality, copyConfiguration.visibility,
|
copyConfiguration.owner, copyConfiguration.modality, copyConfiguration.visibility,
|
||||||
copyConfiguration.original, copyConfiguration.kind);
|
copyConfiguration.original, copyConfiguration.kind);
|
||||||
|
|
||||||
List<TypeParameterDescriptor> originalTypeParameters = getTypeParameters();
|
List<TypeParameterDescriptor> originalTypeParameters =
|
||||||
|
copyConfiguration.newTypeParameters == null ? getTypeParameters() : copyConfiguration.newTypeParameters;
|
||||||
List<TypeParameterDescriptor> substitutedTypeParameters = new ArrayList<TypeParameterDescriptor>(originalTypeParameters.size());
|
List<TypeParameterDescriptor> substitutedTypeParameters = new ArrayList<TypeParameterDescriptor>(originalTypeParameters.size());
|
||||||
TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(
|
TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(
|
||||||
originalTypeParameters, copyConfiguration.substitution, substitutedDescriptor, substitutedTypeParameters
|
originalTypeParameters, copyConfiguration.substitution, substitutedDescriptor, substitutedTypeParameters
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ internal object EmptyContainerForLocal : KDeclarationContainerImpl() {
|
|||||||
|
|
||||||
override fun getFunctions(name: Name): Collection<FunctionDescriptor> = fail()
|
override fun getFunctions(name: Name): Collection<FunctionDescriptor> = fail()
|
||||||
|
|
||||||
private fun fail(): Nothing = throw KotlinReflectionInternalError("Introspecting local functions, lambdas and anonymous functions " +
|
override fun getLocalProperty(index: Int): PropertyDescriptor? = null
|
||||||
"is not yet fully supported in Kotlin reflection")
|
|
||||||
|
private fun fail(): Nothing = throw KotlinReflectionInternalError(
|
||||||
|
"Introspecting local functions, lambdas, anonymous functions and local variables " +
|
||||||
|
"is not yet fully supported in Kotlin reflection"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
@@ -268,6 +268,11 @@ internal abstract class FunctionCaller<out M : Member?>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object ThrowingCaller : FunctionCaller<Nothing?>(null, Void.TYPE, null, emptyArray()) {
|
||||||
|
override fun call(args: Array<*>): Any? {
|
||||||
|
throw UnsupportedOperationException("call/callBy are not supported for this declaration.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// TODO lazily allocate array at bound callers?
|
// TODO lazily allocate array at bound callers?
|
||||||
|
|||||||
@@ -30,9 +30,13 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.MemberDeserializer
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
|
||||||
import org.jetbrains.kotlin.utils.compactIfPossible
|
import org.jetbrains.kotlin.utils.compactIfPossible
|
||||||
import kotlin.jvm.internal.TypeIntrinsics
|
import kotlin.jvm.internal.TypeIntrinsics
|
||||||
import kotlin.reflect.*
|
import kotlin.reflect.*
|
||||||
|
import kotlin.reflect.jvm.deserializeToDescriptor
|
||||||
import kotlin.reflect.jvm.internal.KDeclarationContainerImpl.MemberBelonginess.DECLARED
|
import kotlin.reflect.jvm.internal.KDeclarationContainerImpl.MemberBelonginess.DECLARED
|
||||||
import kotlin.reflect.jvm.internal.KDeclarationContainerImpl.MemberBelonginess.INHERITED
|
import kotlin.reflect.jvm.internal.KDeclarationContainerImpl.MemberBelonginess.INHERITED
|
||||||
|
|
||||||
@@ -195,6 +199,14 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
|
|||||||
memberScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION) +
|
memberScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION) +
|
||||||
staticScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION)
|
staticScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION)
|
||||||
|
|
||||||
|
override fun getLocalProperty(index: Int): PropertyDescriptor? {
|
||||||
|
return (descriptor as? DeserializedClassDescriptor)?.let { descriptor ->
|
||||||
|
val proto = descriptor.classProto.getExtension(JvmProtoBuf.classLocalVariable, index)
|
||||||
|
val nameResolver = descriptor.c.nameResolver
|
||||||
|
deserializeToDescriptor(jClass, proto, nameResolver, descriptor.c.typeTable, MemberDeserializer::loadProperty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override val simpleName: String? get() = data().simpleName
|
override val simpleName: String? get() = data().simpleName
|
||||||
|
|
||||||
override val qualifiedName: String? get() = data().qualifiedName
|
override val qualifiedName: String? get() = data().qualifiedName
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
|
|||||||
|
|
||||||
abstract fun getFunctions(name: Name): Collection<FunctionDescriptor>
|
abstract fun getFunctions(name: Name): Collection<FunctionDescriptor>
|
||||||
|
|
||||||
|
abstract fun getLocalProperty(index: Int): PropertyDescriptor?
|
||||||
|
|
||||||
protected fun getMembers(scope: MemberScope, belonginess: MemberBelonginess): Collection<KCallableImpl<*>> {
|
protected fun getMembers(scope: MemberScope, belonginess: MemberBelonginess): Collection<KCallableImpl<*>> {
|
||||||
val visitor = object : DeclarationDescriptorVisitorEmptyBodies<KCallableImpl<*>, Unit>() {
|
val visitor = object : DeclarationDescriptorVisitorEmptyBodies<KCallableImpl<*>, Unit>() {
|
||||||
override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit): KCallableImpl<*> =
|
override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit): KCallableImpl<*> =
|
||||||
@@ -95,9 +97,15 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun findPropertyDescriptor(name: String, signature: String): PropertyDescriptor {
|
fun findPropertyDescriptor(name: String, signature: String): PropertyDescriptor {
|
||||||
|
val match = LOCAL_PROPERTY_SIGNATURE.matchEntire(signature)
|
||||||
|
if (match != null) {
|
||||||
|
val (number) = match.destructured
|
||||||
|
return getLocalProperty(number.toInt())
|
||||||
|
?: throw KotlinReflectionInternalError("Local property #$number not found in $jClass")
|
||||||
|
}
|
||||||
|
|
||||||
val properties = getProperties(Name.identifier(name))
|
val properties = getProperties(Name.identifier(name))
|
||||||
.filter { descriptor ->
|
.filter { descriptor ->
|
||||||
descriptor is PropertyDescriptor &&
|
|
||||||
RuntimeTypeMapper.mapPropertySignature(descriptor).asString() == signature
|
RuntimeTypeMapper.mapPropertySignature(descriptor).asString() == signature
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,5 +287,7 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val DEFAULT_CONSTRUCTOR_MARKER = Class.forName("kotlin.jvm.internal.DefaultConstructorMarker")
|
private val DEFAULT_CONSTRUCTOR_MARKER = Class.forName("kotlin.jvm.internal.DefaultConstructorMarker")
|
||||||
|
|
||||||
|
internal val LOCAL_PROPERTY_SIGNATURE = "<v#(\\d+)>".toRegex()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,14 @@ import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryPackageSourceElement
|
|||||||
import org.jetbrains.kotlin.load.kotlin.reflect.ReflectKotlinClass
|
import org.jetbrains.kotlin.load.kotlin.reflect.ReflectKotlinClass
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
|
import org.jetbrains.kotlin.serialization.PackageData
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.MemberDeserializer
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
||||||
|
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
|
||||||
|
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
||||||
import kotlin.reflect.KCallable
|
import kotlin.reflect.KCallable
|
||||||
|
import kotlin.reflect.jvm.deserializeToDescriptor
|
||||||
import kotlin.reflect.jvm.internal.KDeclarationContainerImpl.MemberBelonginess.DECLARED
|
import kotlin.reflect.jvm.internal.KDeclarationContainerImpl.MemberBelonginess.DECLARED
|
||||||
|
|
||||||
internal class KPackageImpl(
|
internal class KPackageImpl(
|
||||||
@@ -33,7 +39,7 @@ internal class KPackageImpl(
|
|||||||
@Suppress("unused") val usageModuleName: String? = null // may be useful for debug
|
@Suppress("unused") val usageModuleName: String? = null // may be useful for debug
|
||||||
) : KDeclarationContainerImpl() {
|
) : KDeclarationContainerImpl() {
|
||||||
private inner class Data : KDeclarationContainerImpl.Data() {
|
private inner class Data : KDeclarationContainerImpl.Data() {
|
||||||
val kotlinClass: ReflectKotlinClass? by ReflectProperties.lazySoft {
|
private val kotlinClass: ReflectKotlinClass? by ReflectProperties.lazySoft {
|
||||||
// TODO: do not read ReflectKotlinClass multiple times
|
// TODO: do not read ReflectKotlinClass multiple times
|
||||||
ReflectKotlinClass.create(jClass)
|
ReflectKotlinClass.create(jClass)
|
||||||
}
|
}
|
||||||
@@ -57,6 +63,17 @@ internal class KPackageImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val metadata: PackageData? by ReflectProperties.lazy {
|
||||||
|
kotlinClass?.classHeader?.let { header ->
|
||||||
|
val data = header.data
|
||||||
|
val strings = header.strings
|
||||||
|
if (data != null && strings != null) {
|
||||||
|
JvmProtoBufUtil.readPackageDataFrom(data, strings)
|
||||||
|
}
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val members: Collection<KCallableImpl<*>> by ReflectProperties.lazySoft {
|
val members: Collection<KCallableImpl<*>> by ReflectProperties.lazySoft {
|
||||||
getMembers(scope, DECLARED).filter { member ->
|
getMembers(scope, DECLARED).filter { member ->
|
||||||
val callableDescriptor = member.descriptor as DeserializedCallableMemberDescriptor
|
val callableDescriptor = member.descriptor as DeserializedCallableMemberDescriptor
|
||||||
@@ -84,6 +101,13 @@ internal class KPackageImpl(
|
|||||||
override fun getFunctions(name: Name): Collection<FunctionDescriptor> =
|
override fun getFunctions(name: Name): Collection<FunctionDescriptor> =
|
||||||
scope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION)
|
scope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION)
|
||||||
|
|
||||||
|
override fun getLocalProperty(index: Int): PropertyDescriptor? {
|
||||||
|
return data().metadata?.let { (nameResolver, packageProto) ->
|
||||||
|
val proto = packageProto.getExtension(JvmProtoBuf.packageLocalVariable, index)
|
||||||
|
deserializeToDescriptor(jClass, proto, nameResolver, TypeTable(packageProto.typeTable), MemberDeserializer::loadProperty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean =
|
override fun equals(other: Any?): Boolean =
|
||||||
other is KPackageImpl && jClass == other.jClass
|
other is KPackageImpl && jClass == other.jClass
|
||||||
|
|
||||||
|
|||||||
@@ -178,12 +178,14 @@ internal abstract class KPropertyImpl<out R> private constructor(
|
|||||||
|
|
||||||
|
|
||||||
private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Boolean): FunctionCaller<*> {
|
private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Boolean): FunctionCaller<*> {
|
||||||
|
if (KDeclarationContainerImpl.LOCAL_PROPERTY_SIGNATURE.matches(property.signature)) {
|
||||||
|
return FunctionCaller.ThrowingCaller
|
||||||
|
}
|
||||||
|
|
||||||
fun isInsideClassCompanionObject(): Boolean {
|
fun isInsideClassCompanionObject(): Boolean {
|
||||||
val possibleCompanionObject = property.descriptor.containingDeclaration
|
val possibleCompanionObject = property.descriptor.containingDeclaration
|
||||||
if (DescriptorUtils.isCompanionObject(possibleCompanionObject) && !DescriptorUtils.isInterface(possibleCompanionObject.containingDeclaration)) {
|
return DescriptorUtils.isCompanionObject(possibleCompanionObject) &&
|
||||||
return true
|
!DescriptorUtils.isInterface(possibleCompanionObject.containingDeclaration)
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isJvmStaticProperty() =
|
fun isJvmStaticProperty() =
|
||||||
|
|||||||
@@ -18,10 +18,13 @@
|
|||||||
|
|
||||||
package kotlin.reflect.jvm
|
package kotlin.reflect.jvm
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.load.kotlin.JvmNameResolver
|
import org.jetbrains.kotlin.load.kotlin.JvmNameResolver
|
||||||
|
import org.jetbrains.kotlin.protobuf.MessageLite
|
||||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationContext
|
import org.jetbrains.kotlin.serialization.deserialization.DeserializationContext
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.MemberDeserializer
|
import org.jetbrains.kotlin.serialization.deserialization.MemberDeserializer
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
|
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.SinceKotlinInfoTable
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.SinceKotlinInfoTable
|
||||||
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
||||||
@@ -44,12 +47,32 @@ fun <R> Function<R>.reflect(): KFunction<R>? {
|
|||||||
val stringTableTypes = JvmProtoBuf.StringTableTypes.parseDelimitedFrom(input, JvmProtoBufUtil.EXTENSION_REGISTRY)
|
val stringTableTypes = JvmProtoBuf.StringTableTypes.parseDelimitedFrom(input, JvmProtoBufUtil.EXTENSION_REGISTRY)
|
||||||
val nameResolver = JvmNameResolver(stringTableTypes, annotation.d2)
|
val nameResolver = JvmNameResolver(stringTableTypes, annotation.d2)
|
||||||
val proto = ProtoBuf.Function.parseFrom(input, JvmProtoBufUtil.EXTENSION_REGISTRY)
|
val proto = ProtoBuf.Function.parseFrom(input, JvmProtoBufUtil.EXTENSION_REGISTRY)
|
||||||
val moduleData = javaClass.getOrCreateModule()
|
|
||||||
val context = DeserializationContext(
|
val descriptor = deserializeToDescriptor(javaClass, proto, nameResolver, TypeTable(proto.typeTable), MemberDeserializer::loadFunction)
|
||||||
moduleData.deserialization, nameResolver, moduleData.module, TypeTable(proto.typeTable), SinceKotlinInfoTable.EMPTY,
|
?: return null
|
||||||
containerSource = null, parentTypeDeserializer = null, typeParameters = proto.typeParameterList
|
|
||||||
)
|
|
||||||
val descriptor = MemberDeserializer(context).loadFunction(proto)
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return KFunctionImpl(EmptyContainerForLocal, descriptor) as KFunction<R>
|
return KFunctionImpl(EmptyContainerForLocal, descriptor) as KFunction<R>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun <M : MessageLite, D : CallableDescriptor> deserializeToDescriptor(
|
||||||
|
moduleAnchor: Class<*>,
|
||||||
|
proto: M,
|
||||||
|
nameResolver: NameResolver,
|
||||||
|
typeTable: TypeTable,
|
||||||
|
createDescriptor: MemberDeserializer.(M) -> D
|
||||||
|
): D? {
|
||||||
|
val moduleData = moduleAnchor.getOrCreateModule()
|
||||||
|
|
||||||
|
val typeParameters = when (proto) {
|
||||||
|
is ProtoBuf.Function -> proto.typeParameterList
|
||||||
|
is ProtoBuf.Property -> proto.typeParameterList
|
||||||
|
else -> error("Unsupported message: $proto")
|
||||||
|
}
|
||||||
|
|
||||||
|
val context = DeserializationContext(
|
||||||
|
moduleData.deserialization, nameResolver, moduleData.module, typeTable, SinceKotlinInfoTable.EMPTY,
|
||||||
|
containerSource = null, parentTypeDeserializer = null, typeParameters = typeParameters
|
||||||
|
)
|
||||||
|
return MemberDeserializer(context).createDescriptor(proto)
|
||||||
|
}
|
||||||
|
|||||||
@@ -19545,6 +19545,15 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class LocalDelegated extends AbstractJsCodegenBoxTest {
|
||||||
|
public void testAllFilesPresentInLocalDelegated() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/properties/localDelegated"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/specialBuiltIns")
|
@TestMetadata("compiler/testData/codegen/box/reflection/specialBuiltIns")
|
||||||
|
|||||||
Reference in New Issue
Block a user