Private visibility for top-level private members

This commit is contained in:
Michael Bogdanov
2015-10-15 12:11:54 +03:00
committed by Max Kammerer
parent 10784644a5
commit 5b3a7a473e
10 changed files with 167 additions and 162 deletions
@@ -383,9 +383,6 @@ public class AsmUtil {
return null;
}
if (containingDeclaration instanceof PackageFragmentDescriptor) {
return NO_FLAG_PACKAGE_PRIVATE;
}
return null;
}
@@ -280,7 +280,7 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
ImplementationBodyCodegen.markLineNumberForSyntheticFunction(DescriptorUtils.getParentOfType(funDescriptor, ClassDescriptor.class), iv);
MemberCodegen.markLineNumberForSyntheticFunction(DescriptorUtils.getParentOfType(funDescriptor, ClassDescriptor.class), iv);
iv.load(0, asmType);
@@ -846,7 +846,7 @@ public class FunctionCodegen {
Type[] originalArgTypes = delegateTo.getArgumentTypes();
InstructionAdapter iv = new InstructionAdapter(mv);
ImplementationBodyCodegen.markLineNumberForSyntheticFunction(owner.getThisDescriptor(), iv);
MemberCodegen.markLineNumberForSyntheticFunction(owner.getThisDescriptor(), iv);
generateInstanceOfBarrierIfNeeded(iv, descriptor, bridge, delegateTo);
@@ -37,7 +37,6 @@ import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.lexer.JetTokens;
@@ -49,7 +48,6 @@ import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilKt;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument;
@@ -57,7 +55,6 @@ import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature;
@@ -835,144 +832,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
FunctionCodegen.endVisit(mv, "valueOf()", myClass);
}
protected void generateSyntheticAccessors() {
for (AccessorForCallableDescriptor<?> accessor : ((CodegenContext<?>) context).getAccessors()) {
generateSyntheticAccessor(accessor);
}
}
private void generateSyntheticAccessor(@NotNull AccessorForCallableDescriptor<?> accessorForCallableDescriptor) {
if (accessorForCallableDescriptor instanceof FunctionDescriptor) {
final FunctionDescriptor accessor = (FunctionDescriptor) accessorForCallableDescriptor;
final FunctionDescriptor original = (FunctionDescriptor) accessorForCallableDescriptor.getCalleeDescriptor();
functionCodegen.generateMethod(
JvmDeclarationOriginKt.Synthetic(null, original), accessor,
new FunctionGenerationStrategy.CodegenBased<FunctionDescriptor>(state, accessor) {
@Override
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
markLineNumberForSyntheticFunction(descriptor, codegen.v);
generateMethodCallTo(original, accessor, codegen.v);
codegen.v.areturn(signature.getReturnType());
}
}
);
}
else if (accessorForCallableDescriptor instanceof AccessorForPropertyDescriptor) {
final AccessorForPropertyDescriptor accessor = (AccessorForPropertyDescriptor) accessorForCallableDescriptor;
final PropertyDescriptor original = accessor.getCalleeDescriptor();
class PropertyAccessorStrategy extends FunctionGenerationStrategy.CodegenBased<PropertyAccessorDescriptor> {
public PropertyAccessorStrategy(@NotNull PropertyAccessorDescriptor callableDescriptor) {
super(ImplementationBodyCodegen.this.state, callableDescriptor);
}
@Override
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
boolean forceField = AsmUtil.isPropertyWithBackingFieldInOuterClass(original) &&
!isCompanionObject(accessor.getContainingDeclaration());
StackValue property = codegen.intermediateValueForProperty(
original, forceField, accessor.getSuperCallExpression(), true, StackValue.none()
);
InstructionAdapter iv = codegen.v;
markLineNumberForSyntheticFunction(descriptor, iv);
Type[] argTypes = signature.getAsmMethod().getArgumentTypes();
for (int i = 0, reg = 0; i < argTypes.length; i++) {
Type argType = argTypes[i];
iv.load(reg, argType);
//noinspection AssignmentToForLoopParameter
reg += argType.getSize();
}
if (callableDescriptor instanceof PropertyGetterDescriptor) {
property.put(property.type, iv);
}
else {
property.store(StackValue.onStack(property.type), iv, true);
}
iv.areturn(signature.getReturnType());
}
}
PropertyGetterDescriptor getter = accessor.getGetter();
assert getter != null;
functionCodegen.generateMethod(
JvmDeclarationOriginKt.Synthetic(null, original.getGetter() != null ? original.getGetter() : original),
getter, new PropertyAccessorStrategy(getter));
if (accessor.isVar()) {
PropertySetterDescriptor setter = accessor.getSetter();
assert setter != null;
functionCodegen.generateMethod(
JvmDeclarationOriginKt.Synthetic(null, original.getSetter() != null ? original.getSetter() : original),
setter, new PropertyAccessorStrategy(setter));
}
}
else {
throw new UnsupportedOperationException();
}
}
public static void markLineNumberForSyntheticFunction(@Nullable ClassDescriptor declarationDescriptor, @NotNull InstructionAdapter v) {
if (declarationDescriptor == null) {
return;
}
PsiElement classElement = DescriptorToSourceUtils.getSourceFromDescriptor(declarationDescriptor);
if (classElement != null) {
Integer lineNumber = CodegenUtil.getLineNumberForElement(classElement, false);
if (lineNumber != null) {
Label label = new Label();
v.visitLabel(label);
v.visitLineNumber(lineNumber, label);
}
}
}
private void generateMethodCallTo(
@NotNull FunctionDescriptor functionDescriptor,
@Nullable FunctionDescriptor accessorDescriptor,
@NotNull InstructionAdapter iv
) {
CallableMethod callableMethod = typeMapper.mapToCallableMethod(
functionDescriptor,
accessorDescriptor instanceof AccessorForCallableDescriptor &&
((AccessorForCallableDescriptor) accessorDescriptor).getSuperCallExpression() != null
);
int reg = 1;
boolean accessorIsConstructor = accessorDescriptor instanceof AccessorForConstructorDescriptor;
if (!accessorIsConstructor && functionDescriptor instanceof ConstructorDescriptor) {
iv.anew(callableMethod.getOwner());
iv.dup();
reg = 0;
}
else if (accessorIsConstructor || (accessorDescriptor != null && JetTypeMapper.isAccessor(accessorDescriptor))) {
if (!AnnotationUtilKt.isPlatformStaticInObjectOrClass(functionDescriptor)) {
iv.load(0, OBJECT_TYPE);
}
}
for (Type argType : callableMethod.getParameterTypes()) {
if (AsmTypes.DEFAULT_CONSTRUCTOR_MARKER.equals(argType)) {
iv.aconst(null);
}
else {
iv.load(reg, argType);
reg += argType.getSize();
}
}
callableMethod.genInvokeInstruction(iv);
}
private void generateFieldForSingleton() {
if (isEnumEntry(descriptor)) return;
@@ -989,7 +848,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
// Invoke the object constructor but ignore the result because INSTANCE$ will be initialized in the first line of <init>
InstructionAdapter v = createOrGetClInitCodegen().v;
markLineNumberForSyntheticFunction(descriptor, v);
markLineNumberForSyntheticFunction(element, v);
v.anew(classAsmType);
v.invokespecial(classAsmType.getInternalName(), "<init>", "()V", false);
if (isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
@@ -17,11 +17,13 @@
package org.jetbrains.kotlin.codegen;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.psi.PsiElement;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.CodegenUtil;
import org.jetbrains.kotlin.codegen.context.*;
import org.jetbrains.kotlin.codegen.inline.*;
import org.jetbrains.kotlin.codegen.state.GenerationState;
@@ -35,15 +37,14 @@ import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.name.SpecialNames;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingContextUtils;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
@@ -51,6 +52,7 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager;
import org.jetbrains.kotlin.storage.NotNullLazyValue;
import org.jetbrains.kotlin.types.ErrorUtils;
import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
@@ -62,8 +64,12 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.calculateInnerClassAccessFlag
import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
import static org.jetbrains.kotlin.resolve.BindingContext.VARIABLE;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isTopLevelDeclaration;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.PROPERTY_METADATA_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt.Synthetic;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclarationContainer*/> {
@@ -138,6 +144,26 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
return null;
}
public static void markLineNumberForSyntheticFunction(@Nullable ClassDescriptor declarationDescriptor, @NotNull InstructionAdapter v) {
if (declarationDescriptor == null) {
return;
}
PsiElement classElement = DescriptorToSourceUtils.getSourceFromDescriptor(declarationDescriptor);
if (classElement != null) {
markLineNumberForSyntheticFunction(classElement, v);
}
}
public static void markLineNumberForSyntheticFunction(@NotNull PsiElement element, @NotNull InstructionAdapter v) {
Integer lineNumber = CodegenUtil.getLineNumberForElement(element, false);
if (lineNumber != null) {
Label label = new Label();
v.visitLabel(label);
v.visitLineNumber(lineNumber, label);
}
}
protected void done() {
if (clInit != null) {
clInit.v.visitInsn(RETURN);
@@ -552,4 +578,124 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
iv.putstatic(thisAsmType.getInternalName(), JvmAbi.INSTANCE_FIELD, fieldAsmType.getDescriptor());
}
}
protected void generateSyntheticAccessors() {
for (AccessorForCallableDescriptor<?> accessor : ((CodegenContext<?>) context).getAccessors()) {
generateSyntheticAccessor(accessor);
}
}
private void generateSyntheticAccessor(@NotNull AccessorForCallableDescriptor<?> accessorForCallableDescriptor) {
if (accessorForCallableDescriptor instanceof FunctionDescriptor) {
final FunctionDescriptor accessor = (FunctionDescriptor) accessorForCallableDescriptor;
final FunctionDescriptor original = (FunctionDescriptor) accessorForCallableDescriptor.getCalleeDescriptor();
functionCodegen.generateMethod(
Synthetic(null, original), accessor,
new FunctionGenerationStrategy.CodegenBased<FunctionDescriptor>(state, accessor) {
@Override
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
markLineNumberForSyntheticFunction(element, codegen.v);
generateMethodCallTo(original, accessor, codegen.v);
codegen.v.areturn(signature.getReturnType());
}
}
);
}
else if (accessorForCallableDescriptor instanceof AccessorForPropertyDescriptor) {
final AccessorForPropertyDescriptor accessor = (AccessorForPropertyDescriptor) accessorForCallableDescriptor;
final PropertyDescriptor original = accessor.getCalleeDescriptor();
class PropertyAccessorStrategy extends FunctionGenerationStrategy.CodegenBased<PropertyAccessorDescriptor> {
public PropertyAccessorStrategy(@NotNull PropertyAccessorDescriptor callableDescriptor) {
super(MemberCodegen.this.state, callableDescriptor);
}
@Override
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
boolean forceField = AsmUtil.isPropertyWithBackingFieldInOuterClass(original) &&
!isCompanionObject(accessor.getContainingDeclaration());
StackValue property = codegen.intermediateValueForProperty(
original, forceField, accessor.getSuperCallExpression(), true, StackValue.none()
);
InstructionAdapter iv = codegen.v;
markLineNumberForSyntheticFunction(element, iv);
Type[] argTypes = signature.getAsmMethod().getArgumentTypes();
for (int i = 0, reg = 0; i < argTypes.length; i++) {
Type argType = argTypes[i];
iv.load(reg, argType);
//noinspection AssignmentToForLoopParameter
reg += argType.getSize();
}
if (callableDescriptor instanceof PropertyGetterDescriptor) {
property.put(property.type, iv);
}
else {
property.store(StackValue.onStack(property.type), iv, true);
}
iv.areturn(signature.getReturnType());
}
}
PropertyGetterDescriptor getter = accessor.getGetter();
assert getter != null;
functionCodegen.generateMethod(Synthetic(null, original.getGetter() != null ? original.getGetter() : original),
getter, new PropertyAccessorStrategy(getter));
if (accessor.isVar()) {
PropertySetterDescriptor setter = accessor.getSetter();
assert setter != null;
functionCodegen.generateMethod(Synthetic(null, original.getSetter() != null ? original.getSetter() : original),
setter, new PropertyAccessorStrategy(setter));
}
}
else {
throw new UnsupportedOperationException();
}
}
private void generateMethodCallTo(
@NotNull FunctionDescriptor functionDescriptor,
@Nullable FunctionDescriptor accessorDescriptor,
@NotNull InstructionAdapter iv
) {
CallableMethod callableMethod = typeMapper.mapToCallableMethod(
functionDescriptor,
accessorDescriptor instanceof AccessorForCallableDescriptor &&
((AccessorForCallableDescriptor) accessorDescriptor).getSuperCallExpression() != null
);
boolean isTopLevelDeclaration = isTopLevelDeclaration(functionDescriptor);
int reg = isTopLevelDeclaration ? 0 : 1;
boolean accessorIsConstructor = accessorDescriptor instanceof AccessorForConstructorDescriptor;
if (!accessorIsConstructor && functionDescriptor instanceof ConstructorDescriptor) {
iv.anew(callableMethod.getOwner());
iv.dup();
reg = 0;
}
else if (accessorIsConstructor || (accessorDescriptor != null && JetTypeMapper.isAccessor(accessorDescriptor) && !isTopLevelDeclaration)) {
if (!AnnotationUtilKt.isPlatformStaticInObjectOrClass(functionDescriptor)) {
iv.load(0, OBJECT_TYPE);
}
}
for (Type argType : callableMethod.getParameterTypes()) {
if (AsmTypes.DEFAULT_CONSTRUCTOR_MARKER.equals(argType)) {
iv.aconst(null);
}
else {
iv.load(reg, argType);
reg += argType.getSize();
}
}
callableMethod.genInvokeInstruction(iv);
}
}
@@ -95,4 +95,8 @@ public class MultifileClassPartCodegen(
av.visit(JvmAnnotationNames.MULTIFILE_CLASS_NAME_FIELD_NAME, multifileClassType.internalName)
av.visitEnd()
}
override fun generateSyntheticParts() {
generateSyntheticAccessors()
}
}
@@ -131,4 +131,9 @@ public class PackagePartCodegen extends MemberCodegen<JetFile> {
writeModuleName(av, state);
av.visitEnd();
}
@Override
protected void generateSyntheticParts() {
generateSyntheticAccessors();
}
}
@@ -167,7 +167,7 @@ public class PropertyCodegen {
if (isCompanionObject(descriptor.getContainingDeclaration())) return true;
// Private class properties have accessors only in cases when those accessors are non-trivial
if (kind == OwnerKind.IMPLEMENTATION && Visibilities.isPrivate(descriptor.getVisibility())) {
if (Visibilities.isPrivate(descriptor.getVisibility())) {
return !isDefaultAccessor;
}
@@ -174,6 +174,9 @@ public class JetTypeMapper {
@NotNull
private String internalNameForPackageMemberOwner(@NotNull CallableMemberDescriptor descriptor, boolean isImplementation) {
if (descriptor instanceof AccessorForCallableDescriptor) {
descriptor = ((AccessorForCallableDescriptor) descriptor).getCalleeDescriptor();
}
JetFile file = DescriptorToSourceUtils.getContainingFile(descriptor);
if (file != null) {
Visibility visibility = descriptor.getVisibility();
@@ -53,14 +53,6 @@ public final class _DefaultPackage {
@org.jetbrains.annotations.NotNull
public static final void setNullableVarWithGetSet(@org.jetbrains.annotations.Nullable java.lang.String v) { /* compiled code */ }
@kotlin.jvm.internal.KotlinDelegatedMethod(implementationClassName = "_DefaultPackageKt")
@org.jetbrains.annotations.Nullable
static final java.lang.String getPrivateN() { /* compiled code */ }
@kotlin.jvm.internal.KotlinDelegatedMethod(implementationClassName = "_DefaultPackageKt")
@org.jetbrains.annotations.NotNull
static final java.lang.String getPrivateNn() { /* compiled code */ }
@kotlin.jvm.internal.KotlinDelegatedMethod(implementationClassName = "_DefaultPackageKt")
@org.jetbrains.annotations.NotNull
public static final java.lang.String notNull(@org.jetbrains.annotations.NotNull java.lang.String a) { /* compiled code */ }
@@ -88,6 +80,5 @@ public final class _DefaultPackage {
public static final java.lang.String nullableWithNN() { /* compiled code */ }
@kotlin.jvm.internal.KotlinDelegatedMethod(implementationClassName = "_DefaultPackageKt")
@org.jetbrains.annotations.Nullable
static final java.lang.String privateFun(@org.jetbrains.annotations.NotNull java.lang.String a, @org.jetbrains.annotations.Nullable java.lang.String b) { /* compiled code */ }
private static final java.lang.String privateFun(java.lang.String a, java.lang.String b) { /* compiled code */ }
}