Fix for KT-11590: IllegalAccessError: SAM adapter generated with invalid accessibility for inline function
#KT-11590 Fixed
This commit is contained in:
@@ -2317,7 +2317,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
final Type asmType =
|
||||
state.getSamWrapperClasses().getSamWrapperClass(samType, expression.getContainingKtFile(), getParentCodegen());
|
||||
state.getSamWrapperClasses().getSamWrapperClass(samType, expression.getContainingKtFile(), this);
|
||||
|
||||
return StackValue.operation(asmType, new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.intellij.openapi.util.Factory;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class SamWrapperClasses {
|
||||
private final GenerationState state;
|
||||
|
||||
private final Map<Pair<SamType, KtFile>, Type> samInterfaceToWrapperClass = Maps.newHashMap();
|
||||
|
||||
public SamWrapperClasses(@NotNull GenerationState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Type getSamWrapperClass(@NotNull final SamType samType, @NotNull final KtFile file, @NotNull final MemberCodegen<?> parentCodegen) {
|
||||
return ContainerUtil.getOrCreate(samInterfaceToWrapperClass, Pair.create(samType, file),
|
||||
new Factory<Type>() {
|
||||
@Override
|
||||
public Type create() {
|
||||
return new SamWrapperCodegen(state, samType, parentCodegen).genWrapper(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class SamWrapperClasses(private val state: GenerationState) {
|
||||
|
||||
private data class WrapperKey(val samType: SamType, val file: KtFile, val insideInline: Boolean)
|
||||
|
||||
private val samInterfaceToWrapperClass = hashMapOf<WrapperKey, Type>()
|
||||
|
||||
fun getSamWrapperClass(samType: SamType, file: KtFile, expressionCodegen: ExpressionCodegen): Type {
|
||||
val isInsideInline = InlineUtil.isInlineOrContainingInline(expressionCodegen.context.contextDescriptor)
|
||||
return samInterfaceToWrapperClass.getOrPut(WrapperKey(samType, file, isInsideInline)) {
|
||||
SamWrapperCodegen(state, samType, expressionCodegen.parentCodegen, isInsideInline).genWrapper(file)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,17 +49,27 @@ public class SamWrapperCodegen {
|
||||
private static final String FUNCTION_FIELD_NAME = "function";
|
||||
|
||||
private final GenerationState state;
|
||||
private final boolean isInsideInline;
|
||||
private final KotlinTypeMapper typeMapper;
|
||||
private final SamType samType;
|
||||
private final MemberCodegen<?> parentCodegen;
|
||||
private final int visibility;
|
||||
|
||||
public SamWrapperCodegen(@NotNull GenerationState state, @NotNull SamType samType, @NotNull MemberCodegen<?> parentCodegen) {
|
||||
public SamWrapperCodegen(
|
||||
@NotNull GenerationState state,
|
||||
@NotNull SamType samType,
|
||||
@NotNull MemberCodegen<?> parentCodegen,
|
||||
boolean isInsideInline
|
||||
) {
|
||||
this.state = state;
|
||||
this.isInsideInline = isInsideInline;
|
||||
this.typeMapper = state.getTypeMapper();
|
||||
this.samType = samType;
|
||||
this.parentCodegen = parentCodegen;
|
||||
visibility = isInsideInline ? ACC_PUBLIC : NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Type genWrapper(@NotNull KtFile file) {
|
||||
// Name for generated class, in form of whatever$1
|
||||
FqName fqName = getWrapperName(file);
|
||||
@@ -88,7 +98,7 @@ public class SamWrapperCodegen {
|
||||
ClassBuilder cv = state.getFactory().newVisitor(JvmDeclarationOriginKt.OtherOrigin(erasedInterfaceFunction), asmType, file);
|
||||
cv.defineClass(file,
|
||||
V1_6,
|
||||
ACC_FINAL | ACC_SUPER,
|
||||
ACC_FINAL | ACC_SUPER | visibility,
|
||||
asmType.getInternalName(),
|
||||
null,
|
||||
OBJECT_TYPE.getInternalName(),
|
||||
@@ -118,7 +128,7 @@ public class SamWrapperCodegen {
|
||||
|
||||
private void generateConstructor(Type ownerType, Type functionType, ClassBuilder cv) {
|
||||
MethodVisitor mv = cv.newMethod(JvmDeclarationOriginKt.OtherOrigin(samType.getJavaClassDescriptor()),
|
||||
NO_FLAG_PACKAGE_PRIVATE, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, functionType), null, null);
|
||||
visibility, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, functionType), null, null);
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
mv.visitCode();
|
||||
@@ -177,9 +187,10 @@ public class SamWrapperCodegen {
|
||||
int hash = PackagePartClassUtils.getPathHashCode(containingFile.getVirtualFile()) * 31 +
|
||||
DescriptorUtils.getFqNameSafe(descriptor).hashCode();
|
||||
String shortName = String.format(
|
||||
"%s$sam$%s$%08x",
|
||||
"%s$sam$%s%s$%08x",
|
||||
fileClassFqName.shortName().asString(),
|
||||
descriptor.getName().asString(),
|
||||
(isInsideInline ? "$i" : ""),
|
||||
hash
|
||||
);
|
||||
return fileClassFqName.parent().child(Name.identifier(shortName));
|
||||
|
||||
Reference in New Issue
Block a user