Fix visibility flags for lambda classes in InnerClasses attribute

This commit is contained in:
Alexander Udalov
2016-02-18 20:56:44 +03:00
parent 343735e36c
commit 36de3008e3
11 changed files with 102 additions and 18 deletions
@@ -255,7 +255,10 @@ public class AsmUtil {
For other cases use getVisibilityAccessFlag(MemberDescriptor descriptor)
Classes in byte code should be public or package private
*/
public static int getVisibilityAccessFlagForClass(ClassDescriptor descriptor) {
public static int getVisibilityAccessFlagForClass(@NotNull ClassDescriptor descriptor) {
if (descriptor instanceof SyntheticClassDescriptorForLambda) {
return getVisibilityAccessFlagForAnonymous(descriptor);
}
if (descriptor.getVisibility() == Visibilities.PUBLIC ||
// TODO: should be package private, but for now Kotlin's reflection can't access members of such classes
descriptor.getVisibility() == Visibilities.LOCAL ||
@@ -265,12 +268,17 @@ public class AsmUtil {
return NO_FLAG_PACKAGE_PRIVATE;
}
public static int getVisibilityAccessFlagForAnonymous(@NotNull ClassDescriptor descriptor) {
private static int getVisibilityAccessFlagForAnonymous(@NotNull ClassDescriptor descriptor) {
return InlineUtil.isInlineOrContainingInline(descriptor.getContainingDeclaration()) ? ACC_PUBLIC : NO_FLAG_PACKAGE_PRIVATE;
}
public static int calculateInnerClassAccessFlags(@NotNull ClassDescriptor innerClass) {
int visibility = (innerClass.getVisibility() == Visibilities.LOCAL) ? ACC_PUBLIC : getVisibilityAccessFlag(innerClass);
int visibility =
innerClass instanceof SyntheticClassDescriptorForLambda
? getVisibilityAccessFlagForAnonymous(innerClass)
: innerClass.getVisibility() == Visibilities.LOCAL
? ACC_PUBLIC
: getVisibilityAccessFlag(innerClass);
return visibility |
innerAccessFlagsForModalityAndKind(innerClass) |
(innerClass.isInner() ? 0 : ACC_STATIC);
@@ -126,7 +126,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
this.asmType = typeMapper.mapClass(classDescriptor);
visibilityFlag = AsmUtil.getVisibilityAccessFlagForAnonymous(classDescriptor);
visibilityFlag = AsmUtil.getVisibilityAccessFlagForClass(classDescriptor);
}
@Override
@@ -66,7 +66,7 @@ class PropertyReferenceCodegen(
v.defineClass(
element,
V1_6,
ACC_FINAL or ACC_SUPER or AsmUtil.getVisibilityAccessFlagForAnonymous(classDescriptor),
ACC_FINAL or ACC_SUPER or AsmUtil.getVisibilityAccessFlagForClass(classDescriptor),
asmType.internalName,
null,
superAsmType.internalName,
@@ -0,0 +1,38 @@
/*
* Copyright 2010-2016 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
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.source.toSourceElement
import org.jetbrains.kotlin.types.KotlinType
class SyntheticClassDescriptorForLambda(
containingDeclaration: DeclarationDescriptor,
name: Name,
supertypes: Collection<KotlinType>,
element: KtElement
) : ClassDescriptorImpl(containingDeclaration, name, Modality.FINAL, ClassKind.CLASS, supertypes, element.toSourceElement()) {
init {
initialize(MemberScope.Empty, emptySet(), null)
}
}
@@ -24,10 +24,7 @@ import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.cfg.WhenChecker;
import org.jetbrains.kotlin.codegen.AsmUtil;
import org.jetbrains.kotlin.codegen.JvmRuntimeTypes;
import org.jetbrains.kotlin.codegen.SamCodegenUtil;
import org.jetbrains.kotlin.codegen.SamType;
import org.jetbrains.kotlin.codegen.*;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.when.SwitchCodegenUtil;
import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping;
@@ -94,15 +91,12 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
@NotNull String name
) {
String simpleName = name.substring(name.lastIndexOf('/') + 1);
ClassDescriptorImpl classDescriptor = new ClassDescriptorImpl(
ClassDescriptor classDescriptor = new SyntheticClassDescriptorForLambda(
correctContainerForLambda(callableDescriptor, element),
Name.special("<closure-" + simpleName + ">"),
Modality.FINAL,
ClassKind.CLASS,
supertypes,
KotlinSourceElementKt.toSourceElement(element)
element
);
classDescriptor.initialize(MemberScope.Empty.INSTANCE, Collections.<ConstructorDescriptor>emptySet(), null);
bindingTrace.record(CLASS_FOR_CALLABLE, callableDescriptor, classDescriptor);
return classDescriptor;