Move utilities about companion property fields to JvmAbi

To reuse that logic in reflection
This commit is contained in:
Alexander Udalov
2015-12-25 19:27:52 +03:00
parent 0685f06200
commit 3513a64351
9 changed files with 34 additions and 28 deletions
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.load.java.JavaVisibilities; import org.jetbrains.kotlin.load.java.JavaVisibilities;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames; import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
import org.jetbrains.kotlin.resolve.DeprecationUtilKt; import org.jetbrains.kotlin.resolve.DeprecationUtilKt;
import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt; import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
@@ -682,11 +681,6 @@ public class AsmUtil {
isObject(propertyDescriptor.getContainingDeclaration()); isObject(propertyDescriptor.getContainingDeclaration());
} }
public static boolean isPropertyWithBackingFieldInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) {
return propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
isCompanionObjectWithBackingFieldsInOuter(propertyDescriptor.getContainingDeclaration());
}
public static int getVisibilityForSpecialPropertyBackingField(@NotNull PropertyDescriptor propertyDescriptor, boolean isDelegate) { public static int getVisibilityForSpecialPropertyBackingField(@NotNull PropertyDescriptor propertyDescriptor, boolean isDelegate) {
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null; boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
if (isDelegate || isExtensionProperty) { if (isDelegate || isExtensionProperty) {
@@ -718,12 +712,6 @@ public class AsmUtil {
&& getVisibilityForSpecialPropertyBackingField(propertyDescriptor, false) == ACC_PUBLIC; && getVisibilityForSpecialPropertyBackingField(propertyDescriptor, false) == ACC_PUBLIC;
} }
public static boolean isCompanionObjectWithBackingFieldsInOuter(@NotNull DeclarationDescriptor companionObject) {
return isCompanionObject(companionObject) &&
isClassOrEnumClass(companionObject.getContainingDeclaration()) &&
!JavaToKotlinClassMap.INSTANCE.isMappedCompanion((ClassDescriptor) companionObject);
}
private static boolean areBothAccessorDefault(@NotNull PropertyDescriptor propertyDescriptor) { private static boolean areBothAccessorDefault(@NotNull PropertyDescriptor propertyDescriptor) {
return isAccessorWithEmptyBody(propertyDescriptor.getGetter()) return isAccessorWithEmptyBody(propertyDescriptor.getGetter())
&& (!propertyDescriptor.isVar() || isAccessorWithEmptyBody(propertyDescriptor.getSetter())); && (!propertyDescriptor.isVar() || isAccessorWithEmptyBody(propertyDescriptor.getSetter()));
@@ -54,6 +54,7 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo; import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo;
import org.jetbrains.kotlin.jvm.bindingContextSlices.BindingContextSlicesKt; import org.jetbrains.kotlin.jvm.bindingContextSlices.BindingContextSlicesKt;
import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor; import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.*;
@@ -2116,7 +2117,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
FieldAccessorKind fieldAccessorKind = FieldAccessorKind.NORMAL; FieldAccessorKind fieldAccessorKind = FieldAccessorKind.NORMAL;
boolean isBackingFieldInClassCompanion = AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor); boolean isBackingFieldInClassCompanion = JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
if (isBackingFieldInClassCompanion && forceField) { if (isBackingFieldInClassCompanion && forceField) {
fieldAccessorKind = FieldAccessorKind.IN_CLASS_COMPANION; fieldAccessorKind = FieldAccessorKind.IN_CLASS_COMPANION;
} }
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation; import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames; import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
@@ -1020,7 +1021,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
parentCodegen.generateCompanionObjectInitializer(descriptor); parentCodegen.generateCompanionObjectInitializer(descriptor);
} }
if (isCompanionObjectWithBackingFieldsInOuter(descriptor)) { if (JvmAbi.isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
final ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen(); final ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
generateInitializers(new Function0<ExpressionCodegen>() { generateInitializers(new Function0<ExpressionCodegen>() {
@Override @Override
@@ -601,7 +601,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
@Override @Override
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) { public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
boolean syntheticBackingField = accessor instanceof AccessorForPropertyBackingFieldFromLocal; boolean syntheticBackingField = accessor instanceof AccessorForPropertyBackingFieldFromLocal;
boolean forceField = (AsmUtil.isPropertyWithBackingFieldInOuterClass(original) && boolean forceField = (JvmAbi.isPropertyWithBackingFieldInOuterClass(original) &&
!isCompanionObject(accessor.getContainingDeclaration())) || !isCompanionObject(accessor.getContainingDeclaration())) ||
syntheticBackingField || syntheticBackingField ||
original.getVisibility() == JavaVisibilities.PROTECTED_STATIC_VISIBILITY; original.getVisibility() == JavaVisibilities.PROTECTED_STATIC_VISIBILITY;
@@ -318,7 +318,7 @@ public class PropertyCodegen {
modifiers |= getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegate); modifiers |= getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegate);
} }
if (AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) { if (JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) {
ImplementationBodyCodegen codegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen(); ImplementationBodyCodegen codegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
builder = codegen.v; builder = codegen.v;
backingFieldContext = codegen.context; backingFieldContext = codegen.context;
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtObjectDeclaration import org.jetbrains.kotlin.psi.KtObjectDeclaration
import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.DescriptorRenderer
@@ -82,7 +83,7 @@ fun populateCompanionBackingFieldNamesToOuterContextIfNeeded(companion: KtObject
return return
} }
if (!AsmUtil.isCompanionObjectWithBackingFieldsInOuter(descriptor)) { if (!JvmAbi.isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
return return
} }
val properties = companion.declarations.filterIsInstance<KtProperty>() val properties = companion.declarations.filterIsInstance<KtProperty>()
@@ -16,14 +16,22 @@
package org.jetbrains.kotlin.load.java; package org.jetbrains.kotlin.load.java;
import kotlin.StringsKt; import kotlin.text.StringsKt;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
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.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion; import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion;
import org.jetbrains.kotlin.util.capitalizeDecapitalize.CapitalizeDecapitalizeKt; import org.jetbrains.kotlin.util.capitalizeDecapitalize.CapitalizeDecapitalizeKt;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isClassOrEnumClass;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
public final class JvmAbi { public final class JvmAbi {
/** /**
* This constant is used to identify binary format (class file) versions * This constant is used to identify binary format (class file) versions
@@ -97,5 +105,16 @@ public final class JvmAbi {
public static String sanitizeAsJavaIdentifier(@NotNull String str) { public static String sanitizeAsJavaIdentifier(@NotNull String str) {
return StringsKt.replace(str, StringsKt.toRegex("[^\\p{L}\\p{Digit}]"), "_"); return StringsKt.replace(str, StringsKt.toRegex("[^\\p{L}\\p{Digit}]"), "_");
} }
public static boolean isPropertyWithBackingFieldInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) {
return propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
isCompanionObjectWithBackingFieldsInOuter(propertyDescriptor.getContainingDeclaration());
}
public static boolean isCompanionObjectWithBackingFieldsInOuter(@NotNull DeclarationDescriptor companionObject) {
return isCompanionObject(companionObject) &&
isClassOrEnumClass(companionObject.getContainingDeclaration()) &&
!JavaToKotlinClassMap.INSTANCE.isMappedCompanion((ClassDescriptor) companionObject);
}
} }
@@ -16,10 +16,8 @@
package kotlin.reflect.jvm.internal package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.resolve.DescriptorUtils.isClassOrEnumClass import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
import java.lang.reflect.Field import java.lang.reflect.Field
import kotlin.reflect.jvm.internal.JvmPropertySignature.JavaField import kotlin.reflect.jvm.internal.JvmPropertySignature.JavaField
@@ -53,10 +51,9 @@ internal abstract class DescriptorBasedProperty<out R> protected constructor(
when (jvmSignature) { when (jvmSignature) {
is KotlinProperty -> { is KotlinProperty -> {
JvmProtoBufUtil.getJvmFieldSignature(jvmSignature.proto, jvmSignature.nameResolver, jvmSignature.typeTable)?.let { JvmProtoBufUtil.getJvmFieldSignature(jvmSignature.proto, jvmSignature.nameResolver, jvmSignature.typeTable)?.let {
val isCompanionOfClass = (descriptor.containingDeclaration as? ClassDescriptor)?.let { containingClass -> container.findFieldBySignature(
isCompanionObject(containingClass) && isClassOrEnumClass(containingClass.containingDeclaration) it.name, JvmAbi.isCompanionObjectWithBackingFieldsInOuter(descriptor.containingDeclaration)
} ?: false )
container.findFieldBySignature(it.name, isCompanionOfClass)
} }
} }
is JavaField -> jvmSignature.field is JavaField -> jvmSignature.field
@@ -39,7 +39,6 @@ import com.sun.jdi.Location
import com.sun.jdi.ReferenceType import com.sun.jdi.ReferenceType
import com.sun.jdi.request.ClassPrepareRequest import com.sun.jdi.request.ClassPrepareRequest
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.ClassBuilderFactories import org.jetbrains.kotlin.codegen.ClassBuilderFactories
import org.jetbrains.kotlin.codegen.binding.CodegenBinding import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
@@ -53,10 +52,10 @@ import org.jetbrains.kotlin.fileClasses.internalNameWithoutInnerClasses
import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
import org.jetbrains.kotlin.idea.refactoring.getLineStartOffset
import org.jetbrains.kotlin.idea.debugger.breakpoints.getLambdasAtLineIfAny import org.jetbrains.kotlin.idea.debugger.breakpoints.getLambdasAtLineIfAny
import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinCodeFragmentFactory import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinCodeFragmentFactory
import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile
import org.jetbrains.kotlin.idea.refactoring.getLineStartOffset
import org.jetbrains.kotlin.idea.search.usagesSearch.isImportUsage import org.jetbrains.kotlin.idea.search.usagesSearch.isImportUsage
import org.jetbrains.kotlin.idea.util.DebuggerUtils import org.jetbrains.kotlin.idea.util.DebuggerUtils
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
@@ -448,7 +447,7 @@ public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : M
public fun getJvmInternalNameForPropertyOwner(typeMapper: JetTypeMapper, descriptor: PropertyDescriptor): String { public fun getJvmInternalNameForPropertyOwner(typeMapper: JetTypeMapper, descriptor: PropertyDescriptor): String {
return typeMapper.mapOwner( return typeMapper.mapOwner(
if (AsmUtil.isPropertyWithBackingFieldInOuterClass(descriptor)) descriptor.containingDeclaration else descriptor if (JvmAbi.isPropertyWithBackingFieldInOuterClass(descriptor)) descriptor.containingDeclaration else descriptor
).internalName ).internalName
} }