Make top-level property backing field private in bytecode

This commit is contained in:
Michael Bogdanov
2015-10-19 14:20:05 +03:00
parent 376c188cf7
commit c8c3e88c82
17 changed files with 112 additions and 41 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.codegen;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import kotlin.CollectionsKt;
import kotlin.StringsKt;
import kotlin.jvm.functions.Function1;
@@ -31,7 +32,6 @@ import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.kotlin.ModuleMapping;
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityUtilsKt;
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider;
import org.jetbrains.kotlin.psi.JetFile;
import org.jetbrains.kotlin.psi.JetFunction;
import org.jetbrains.kotlin.psi.codeFragmentUtil.CodeFragmentUtilKt;
@@ -77,25 +77,21 @@ public class JvmCodegenUtil {
return !isFakeOverride && !isDelegate &&
(((context.hasThisDescriptor() && containingDeclaration == context.getThisDescriptor()) ||
((context.getParentContext() instanceof PackageContext || context.getParentContext() instanceof MultifileClassPartContext)
&& isSamePackageInSameModule(context.getParentContext().getContextDescriptor(), containingDeclaration)))
((context.getParentContext() instanceof FacadePartWithSourceFile)
&& isWithinSameFile(((FacadePartWithSourceFile) context.getParentContext()).getSourceFile(), descriptor)))
&& context.getContextKind() != OwnerKind.DEFAULT_IMPLS);
}
private static boolean isSamePackageInSameModule(
@NotNull DeclarationDescriptor callerOwner,
@NotNull DeclarationDescriptor calleeOwner
private static boolean isWithinSameFile(
@Nullable JetFile callerFile,
@NotNull CallableMemberDescriptor descriptor
) {
if (callerOwner instanceof PackageFragmentDescriptor && calleeOwner instanceof PackageFragmentDescriptor) {
PackageFragmentDescriptor callerFragment = (PackageFragmentDescriptor) callerOwner;
PackageFragmentDescriptor calleeFragment = (PackageFragmentDescriptor) calleeOwner;
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration().getOriginal();
if (containingDeclaration instanceof PackageFragmentDescriptor) {
PsiElement calleeElement = DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
PsiFile calleeFile = calleeElement != null ? calleeElement.getContainingFile() : null;
return callerFile != null && callerFile != SourceFile.NO_SOURCE_FILE && calleeFile == callerFile;
// backing field should be used directly within same module of same package
if (callerFragment == calleeFragment) {
return true;
}
return callerFragment.getFqName().equals(calleeFragment.getFqName())
&& calleeFragment instanceof IncrementalPackageFragmentProvider.IncrementalPackageFragment;
}
return false;
}
@@ -162,7 +162,7 @@ public class MultifileClassCodegen(
var generatePart = false
val partClassInfo = state.fileClassesProvider.getFileClassInfo(file)
val partType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(partClassInfo.fileClassFqName)
val partContext = state.rootContext.intoMultifileClassPart(packageFragment, facadeClassType, partType)
val partContext = state.rootContext.intoMultifileClassPart(packageFragment, facadeClassType, partType, file)
for (declaration in file.declarations) {
if (declaration is JetProperty || declaration is JetNamedFunction) {
@@ -87,7 +87,7 @@ public class PackageCodegen {
}
Type fileClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.getFileClassFqName());
PackageContext packagePartContext = state.getRootContext().intoPackagePart(packageFragment, fileClassType);
PackageContext packagePartContext = state.getRootContext().intoPackagePart(packageFragment, fileClassType, file);
boolean generatePackagePart = false;
@@ -340,7 +340,7 @@ public class PropertyCodegen {
else if (!isDelegate && hasJvmFieldAnnotation) {
modifiers |= getDefaultVisibilityFlag(propertyDescriptor.getVisibility());
}
else if (kind != OwnerKind.PACKAGE || isDelegate) {
else {
modifiers |= ACC_PRIVATE;
}
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.codegen.binding.MutableClosure;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.psi.JetFile;
import org.jetbrains.kotlin.psi.JetSuperExpression;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
@@ -180,17 +181,18 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
}
@NotNull
public PackageContext intoPackagePart(@NotNull PackageFragmentDescriptor descriptor, Type packagePartType) {
return new PackageContext(descriptor, this, packagePartType);
public PackageContext intoPackagePart(@NotNull PackageFragmentDescriptor descriptor, Type packagePartType, @Nullable JetFile sourceFile) {
return new PackageContext(descriptor, this, packagePartType, sourceFile);
}
@NotNull
public FieldOwnerContext<PackageFragmentDescriptor> intoMultifileClassPart(
@NotNull PackageFragmentDescriptor descriptor,
@NotNull Type multifileClassType,
@NotNull Type filePartType
@NotNull Type filePartType,
@NotNull JetFile sourceFile
) {
return new MultifileClassPartContext(descriptor, this, multifileClassType, filePartType);
return new MultifileClassPartContext(descriptor, this, multifileClassType, filePartType, sourceFile);
}
@NotNull
@@ -0,0 +1,26 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen.context;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.psi.JetFile;
public interface FacadePartWithSourceFile {
@Nullable
JetFile getSourceFile();
}
@@ -16,18 +16,24 @@
package org.jetbrains.kotlin.codegen.context;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.kotlin.psi.JetFile;
import org.jetbrains.org.objectweb.asm.Type;
public class MultifileClassPartContext extends MultifileClassContextBase implements DelegatingToPartContext {
public class MultifileClassPartContext extends MultifileClassContextBase implements DelegatingToPartContext, FacadePartWithSourceFile {
private final JetFile sourceFile;
public MultifileClassPartContext(
PackageFragmentDescriptor descriptor,
CodegenContext parent,
Type multifileClassType,
Type filePartType
Type filePartType,
@NotNull JetFile sourceFile
) {
super(descriptor, parent, multifileClassType, filePartType);
this.sourceFile = sourceFile;
}
@Nullable
@@ -35,4 +41,10 @@ public class MultifileClassPartContext extends MultifileClassContextBase impleme
public Type getImplementationOwnerClassType() {
return getFilePartType();
}
@NotNull
@Override
public JetFile getSourceFile() {
return sourceFile;
}
}
@@ -20,18 +20,22 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.OwnerKind;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.kotlin.psi.JetFile;
import org.jetbrains.org.objectweb.asm.Type;
public class PackageContext extends FieldOwnerContext<PackageFragmentDescriptor> implements DelegatingToPartContext {
public class PackageContext extends FieldOwnerContext<PackageFragmentDescriptor> implements DelegatingToPartContext, FacadePartWithSourceFile {
private final Type packagePartType;
@Nullable private JetFile sourceFile;
public PackageContext(
@NotNull PackageFragmentDescriptor contextDescriptor,
@NotNull CodegenContext parent,
@Nullable Type packagePartType
@Nullable Type packagePartType,
@Nullable JetFile sourceFile
) {
super(contextDescriptor, OwnerKind.PACKAGE, parent, null, null, null);
this.packagePartType = packagePartType;
this.sourceFile = sourceFile;
}
@Override
@@ -49,4 +53,10 @@ public class PackageContext extends FieldOwnerContext<PackageFragmentDescriptor>
public Type getImplementationOwnerClassType() {
return packagePartType;
}
@Nullable
@Override
public JetFile getSourceFile() {
return sourceFile;
}
}
@@ -38,7 +38,7 @@ public class PackageFacadeContext extends PackageContext implements DelegatingFa
@NotNull Type packagePartType,
@NotNull Type publicFacadeType
) {
super(contextDescriptor, parent, packagePartType);
super(contextDescriptor, parent, packagePartType, null);
this.publicFacadeType = publicFacadeType;
}
@@ -109,7 +109,8 @@ public class InlineCodegen extends CallGenerator {
initialFrameSize = codegen.getFrameMap().getCurrentSize();
context = (MethodContext) getContext(functionDescriptor, state);
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor);
context = (MethodContext) getContext(functionDescriptor, state, element != null ? (JetFile) element.getContainingFile() : null);
jvmSignature = typeMapper.mapSignature(functionDescriptor, context.getContextKind());
// TODO: implement AS_FUNCTION inline strategy
@@ -586,12 +587,12 @@ public class InlineCodegen extends CallGenerator {
activeLambda = null;
}
public static CodegenContext getContext(DeclarationDescriptor descriptor, GenerationState state) {
public static CodegenContext getContext(@NotNull DeclarationDescriptor descriptor, @NotNull GenerationState state, @Nullable JetFile sourceFile) {
if (descriptor instanceof PackageFragmentDescriptor) {
return new PackageContext((PackageFragmentDescriptor) descriptor, state.getRootContext(), null);
return new PackageContext((PackageFragmentDescriptor) descriptor, state.getRootContext(), null, sourceFile);
}
CodegenContext parent = getContext(descriptor.getContainingDeclaration(), state);
CodegenContext parent = getContext(descriptor.getContainingDeclaration(), state, sourceFile);
if (descriptor instanceof ClassDescriptor) {
OwnerKind kind = DescriptorUtils.isInterface(descriptor) ? OwnerKind.DEFAULT_IMPLS : OwnerKind.IMPLEMENTATION;