Introduce new naming convention for captured receiver backing fields
'receiver$0' -> '$this_<label>'
This commit is contained in:
@@ -16,28 +16,32 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||||
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.HashCode;
|
import org.jetbrains.kotlin.codegen.intrinsics.HashCode;
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||||
import org.jetbrains.kotlin.config.JvmTarget;
|
import org.jetbrains.kotlin.config.JvmTarget;
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
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.metadata.jvm.deserialization.JvmProtoBufUtil;
|
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil;
|
||||||
import org.jetbrains.kotlin.metadata.jvm.serialization.JvmStringTable;
|
import org.jetbrains.kotlin.metadata.jvm.serialization.JvmStringTable;
|
||||||
import org.jetbrains.kotlin.name.ClassId;
|
import org.jetbrains.kotlin.name.*;
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
|
||||||
import org.jetbrains.kotlin.protobuf.MessageLite;
|
import org.jetbrains.kotlin.protobuf.MessageLite;
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver;
|
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver;
|
||||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker;
|
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker;
|
||||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.*;
|
import org.jetbrains.kotlin.resolve.jvm.*;
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.checkers.DalvikIdentifierUtils;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor;
|
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor;
|
||||||
@@ -88,11 +92,24 @@ public class AsmUtil {
|
|||||||
.put(JavaVisibilities.PACKAGE_VISIBILITY, NO_FLAG_PACKAGE_PRIVATE)
|
.put(JavaVisibilities.PACKAGE_VISIBILITY, NO_FLAG_PACKAGE_PRIVATE)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public static final String BOUND_REFERENCE_RECEIVER = "receiver";
|
public static final String THIS = "this";
|
||||||
public static final String RECEIVER_NAME = "$receiver";
|
|
||||||
public static final String CAPTURED_RECEIVER_FIELD = "receiver$0";
|
private static final String LABELED_THIS_FIELD = THIS + "_";
|
||||||
|
|
||||||
public static final String CAPTURED_THIS_FIELD = "this$0";
|
public static final String CAPTURED_THIS_FIELD = "this$0";
|
||||||
|
|
||||||
|
public static final String RECEIVER_PARAMETER_NAME = "$receiver";
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is basically an old convention. Starting from Kotlin 1.3, it was replaced with `$this_<label>`.
|
||||||
|
Note that it is still used for inlined callable references and anonymous callable extension receivers
|
||||||
|
even in 1.3.
|
||||||
|
*/
|
||||||
|
public static final String CAPTURED_RECEIVER_FIELD = "receiver$0";
|
||||||
|
|
||||||
|
// For non-inlined callable references ('kotlin.jvm.internal.CallableReference' has a 'receiver' field)
|
||||||
|
public static final String BOUND_REFERENCE_RECEIVER = "receiver";
|
||||||
|
|
||||||
private static final ImmutableMap<Integer, JvmPrimitiveType> primitiveTypeByAsmSort;
|
private static final ImmutableMap<Integer, JvmPrimitiveType> primitiveTypeByAsmSort;
|
||||||
private static final ImmutableMap<Type, Type> primitiveTypeByBoxedType;
|
private static final ImmutableMap<Type, Type> primitiveTypeByBoxedType;
|
||||||
|
|
||||||
@@ -111,6 +128,74 @@ public class AsmUtil {
|
|||||||
private AsmUtil() {
|
private AsmUtil() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static String getCapturedFieldName(@NotNull String originalName) {
|
||||||
|
return "$" + originalName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static String getLabeledThisNameForReceiver(
|
||||||
|
@NotNull CallableDescriptor descriptor,
|
||||||
|
@NotNull BindingContext bindingContext,
|
||||||
|
@NotNull LanguageVersionSettings languageVersionSettings
|
||||||
|
) {
|
||||||
|
if (!languageVersionSettings.supportsFeature(LanguageFeature.NewCapturedReceiverFieldNamingConvention)) {
|
||||||
|
return CAPTURED_RECEIVER_FIELD;
|
||||||
|
}
|
||||||
|
|
||||||
|
Name callableName = null;
|
||||||
|
|
||||||
|
if (descriptor instanceof FunctionDescriptor) {
|
||||||
|
String labelName = bindingContext.get(CodegenBinding.CALL_LABEL_FOR_LAMBDA_ARGUMENT, (FunctionDescriptor) descriptor);
|
||||||
|
if (labelName != null) {
|
||||||
|
return getLabeledThisName(labelName, CAPTURED_RECEIVER_FIELD);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (descriptor instanceof VariableAccessorDescriptor) {
|
||||||
|
VariableAccessorDescriptor accessor = (VariableAccessorDescriptor) descriptor;
|
||||||
|
callableName = accessor.getCorrespondingVariable().getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callableName == null) {
|
||||||
|
callableName = descriptor.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callableName.isSpecial()) {
|
||||||
|
return CAPTURED_RECEIVER_FIELD;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getLabeledThisName(callableName.asString(), CAPTURED_RECEIVER_FIELD);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static String getLabeledThisName(@NotNull String callableName, @NotNull String defaultName) {
|
||||||
|
if (!Name.isValidIdentifier(callableName)) {
|
||||||
|
return defaultName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DalvikIdentifierUtils.isValidDalvikIdentifier(callableName)) {
|
||||||
|
return LABELED_THIS_FIELD + mangleLabel(callableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return LABELED_THIS_FIELD + callableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String mangleLabel(String label) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
for (char c : label.toCharArray()) {
|
||||||
|
if (DalvikIdentifierUtils.isValidDalvikCharacter(c)) {
|
||||||
|
sb.append(c);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append("_u").append(Integer.toHexString(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static Type boxType(@NotNull Type type) {
|
public static Type boxType(@NotNull Type type) {
|
||||||
Type boxedType = boxPrimitiveType(type);
|
Type boxedType = boxPrimitiveType(type);
|
||||||
@@ -510,7 +595,12 @@ public class AsmUtil {
|
|||||||
v.athrow();
|
v.athrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void genClosureFields(@NotNull CalculatedClosure closure, ClassBuilder v, KotlinTypeMapper typeMapper) {
|
public static void genClosureFields(
|
||||||
|
@NotNull CalculatedClosure closure,
|
||||||
|
ClassBuilder v,
|
||||||
|
KotlinTypeMapper typeMapper,
|
||||||
|
@NotNull LanguageVersionSettings languageVersionSettings
|
||||||
|
) {
|
||||||
List<Pair<String, Type>> allFields = new ArrayList<>();
|
List<Pair<String, Type>> allFields = new ArrayList<>();
|
||||||
|
|
||||||
ClassifierDescriptor captureThis = closure.getCapturedOuterClassDescriptor();
|
ClassifierDescriptor captureThis = closure.getCapturedOuterClassDescriptor();
|
||||||
@@ -520,7 +610,8 @@ public class AsmUtil {
|
|||||||
|
|
||||||
KotlinType captureReceiverType = closure.getCapturedReceiverFromOuterContext();
|
KotlinType captureReceiverType = closure.getCapturedReceiverFromOuterContext();
|
||||||
if (captureReceiverType != null && !CallableReferenceUtilKt.isForCallableReference(closure)) {
|
if (captureReceiverType != null && !CallableReferenceUtilKt.isForCallableReference(closure)) {
|
||||||
allFields.add(Pair.create(CAPTURED_RECEIVER_FIELD, typeMapper.mapType(captureReceiverType)));
|
String fieldName = closure.getCapturedReceiverFieldName(typeMapper.getBindingContext(), languageVersionSettings);
|
||||||
|
allFields.add(Pair.create(fieldName, typeMapper.mapType(captureReceiverType)));
|
||||||
}
|
}
|
||||||
|
|
||||||
allFields.addAll(closure.getRecordedFields());
|
allFields.addAll(closure.getRecordedFields());
|
||||||
@@ -736,7 +827,7 @@ public class AsmUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void genNotNullAssertionsForParameters(
|
static void genNotNullAssertionsForParameters(
|
||||||
@NotNull InstructionAdapter v,
|
@NotNull InstructionAdapter v,
|
||||||
@NotNull GenerationState state,
|
@NotNull GenerationState state,
|
||||||
@NotNull FunctionDescriptor descriptor,
|
@NotNull FunctionDescriptor descriptor,
|
||||||
@@ -758,7 +849,7 @@ public class AsmUtil {
|
|||||||
if (descriptor.isOperator()) {
|
if (descriptor.isOperator()) {
|
||||||
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
|
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
|
||||||
if (receiverParameter != null) {
|
if (receiverParameter != null) {
|
||||||
genParamAssertion(v, state.getTypeMapper(), frameMap, receiverParameter, "$receiver", descriptor);
|
genParamAssertion(v, state.getTypeMapper(), frameMap, receiverParameter, CAPTURED_RECEIVER_FIELD, descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -766,7 +857,7 @@ public class AsmUtil {
|
|||||||
|
|
||||||
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
|
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
|
||||||
if (receiverParameter != null) {
|
if (receiverParameter != null) {
|
||||||
genParamAssertion(v, state.getTypeMapper(), frameMap, receiverParameter, "$receiver", descriptor);
|
genParamAssertion(v, state.getTypeMapper(), frameMap, receiverParameter, CAPTURED_RECEIVER_FIELD, descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ValueParameterDescriptor parameter : descriptor.getValueParameters()) {
|
for (ValueParameterDescriptor parameter : descriptor.getValueParameters()) {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
|||||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
|
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||||
@@ -171,7 +172,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
|||||||
generateConstInstance(asmType, asmType);
|
generateConstInstance(asmType, asmType);
|
||||||
}
|
}
|
||||||
|
|
||||||
genClosureFields(closure, v, typeMapper);
|
genClosureFields(closure, v, typeMapper, state.getLanguageVersionSettings());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void generateClosureBody() {
|
protected void generateClosureBody() {
|
||||||
@@ -425,7 +426,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
protected Method generateConstructor() {
|
protected Method generateConstructor() {
|
||||||
List<FieldInfo> args = calculateConstructorParameters(typeMapper, closure, asmType);
|
List<FieldInfo> args = calculateConstructorParameters(typeMapper, state.getLanguageVersionSettings(), closure, asmType);
|
||||||
|
|
||||||
Type[] argTypes = fieldListToTypeArray(args);
|
Type[] argTypes = fieldListToTypeArray(args);
|
||||||
|
|
||||||
@@ -482,6 +483,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public static List<FieldInfo> calculateConstructorParameters(
|
public static List<FieldInfo> calculateConstructorParameters(
|
||||||
@NotNull KotlinTypeMapper typeMapper,
|
@NotNull KotlinTypeMapper typeMapper,
|
||||||
|
@NotNull LanguageVersionSettings languageVersionSettings,
|
||||||
@NotNull CalculatedClosure closure,
|
@NotNull CalculatedClosure closure,
|
||||||
@NotNull Type ownerType
|
@NotNull Type ownerType
|
||||||
) {
|
) {
|
||||||
@@ -493,7 +495,8 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
|||||||
}
|
}
|
||||||
KotlinType captureReceiverType = closure.getCapturedReceiverFromOuterContext();
|
KotlinType captureReceiverType = closure.getCapturedReceiverFromOuterContext();
|
||||||
if (captureReceiverType != null) {
|
if (captureReceiverType != null) {
|
||||||
args.add(FieldInfo.createForHiddenField(ownerType, typeMapper.mapType(captureReceiverType), CAPTURED_RECEIVER_FIELD));
|
String fieldName = closure.getCapturedReceiverFieldName(typeMapper.getBindingContext(), languageVersionSettings);
|
||||||
|
args.add(FieldInfo.createForHiddenField(ownerType, typeMapper.mapType(captureReceiverType), fieldName));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (EnclosedValueDescriptor enclosedValueDescriptor : closure.getCaptureVariables().values()) {
|
for (EnclosedValueDescriptor enclosedValueDescriptor : closure.getCaptureVariables().values()) {
|
||||||
|
|||||||
@@ -18,16 +18,19 @@ package org.jetbrains.kotlin.codegen
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
|
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
|
||||||
|
import org.jetbrains.kotlin.psi.KtFunctionLiteral
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
|
|
||||||
class ClosureGenerationStrategy(
|
class ClosureGenerationStrategy(
|
||||||
state: GenerationState,
|
state: GenerationState,
|
||||||
declaration: KtDeclarationWithBody
|
val declaration: KtDeclarationWithBody
|
||||||
) : FunctionGenerationStrategy.FunctionDefault(state, declaration) {
|
) : FunctionGenerationStrategy.FunctionDefault(state, declaration) {
|
||||||
|
|
||||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||||
initializeVariablesForDestructuredLambdaParameters(codegen, codegen.context.functionDescriptor.valueParameters)
|
initializeVariablesForDestructuredLambdaParameters(codegen, codegen.context.functionDescriptor.valueParameters)
|
||||||
|
if (declaration is KtFunctionLiteral) {
|
||||||
|
recordCallLabelForLambdaArgument(declaration, state.bindingTrace)
|
||||||
|
}
|
||||||
super.doGenerateBody(codegen, signature)
|
super.doGenerateBody(codegen, signature)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -286,7 +286,9 @@ public class ConstructorCodegen {
|
|||||||
private void generateClosureInitialization(@NotNull InstructionAdapter iv) {
|
private void generateClosureInitialization(@NotNull InstructionAdapter iv) {
|
||||||
MutableClosure closure = context.closure;
|
MutableClosure closure = context.closure;
|
||||||
if (closure != null) {
|
if (closure != null) {
|
||||||
List<FieldInfo> argsFromClosure = ClosureCodegen.calculateConstructorParameters(typeMapper, closure, classAsmType);
|
List<FieldInfo> argsFromClosure = ClosureCodegen.calculateConstructorParameters(
|
||||||
|
typeMapper, state.getLanguageVersionSettings(), closure, classAsmType);
|
||||||
|
|
||||||
int k = 1;
|
int k = 1;
|
||||||
for (FieldInfo info : argsFromClosure) {
|
for (FieldInfo info : argsFromClosure) {
|
||||||
k = AsmUtil.genAssignInstanceFieldFromParam(info, k, iv);
|
k = AsmUtil.genAssignInstanceFieldFromParam(info, k, iv);
|
||||||
|
|||||||
@@ -431,7 +431,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
|
|
||||||
if (context.closure != null)
|
if (context.closure != null)
|
||||||
genClosureFields(context.closure, v, typeMapper);
|
genClosureFields(context.closure, v, typeMapper, state.getLanguageVersionSettings());
|
||||||
|
|
||||||
for (ExpressionCodegenExtension extension : ExpressionCodegenExtension.Companion.getInstances(state.getProject())) {
|
for (ExpressionCodegenExtension extension : ExpressionCodegenExtension.Companion.getInstances(state.getProject())) {
|
||||||
if (state.getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES
|
if (state.getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES
|
||||||
@@ -679,7 +679,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
if (captureReceiver != null) {
|
if (captureReceiver != null) {
|
||||||
iv.load(0, classAsmType);
|
iv.load(0, classAsmType);
|
||||||
Type type = typeMapper.mapType(captureReceiver);
|
Type type = typeMapper.mapType(captureReceiver);
|
||||||
iv.getfield(classAsmType.getInternalName(), CAPTURED_RECEIVER_FIELD, type.getDescriptor());
|
String fieldName = closure.getCapturedReceiverFieldName(bindingContext, state.getLanguageVersionSettings());
|
||||||
|
iv.getfield(classAsmType.getInternalName(), fieldName, type.getDescriptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Map.Entry<DeclarationDescriptor, EnclosedValueDescriptor> entry : closure.getCaptureVariables().entrySet()) {
|
for (Map.Entry<DeclarationDescriptor, EnclosedValueDescriptor> entry : closure.getCaptureVariables().entrySet()) {
|
||||||
|
|||||||
@@ -78,9 +78,11 @@ class PropertyReferenceCodegen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val constructorArgs = ClosureCodegen.calculateConstructorParameters(typeMapper, closure, asmType).apply {
|
private val constructorArgs =
|
||||||
assert(size <= 1) { "Bound property reference should capture only one value: $this" }
|
ClosureCodegen.calculateConstructorParameters(typeMapper, state.languageVersionSettings, closure, asmType).apply {
|
||||||
}
|
assert(size <= 1) { "Bound property reference should capture only one value: $this" }
|
||||||
|
}
|
||||||
|
|
||||||
private val constructor = method("<init>", Type.VOID_TYPE, *constructorArgs.map { it.fieldType }.toTypedArray())
|
private val constructor = method("<init>", Type.VOID_TYPE, *constructorArgs.map { it.fieldType }.toTypedArray())
|
||||||
|
|
||||||
override fun generateDeclaration() {
|
override fun generateDeclaration() {
|
||||||
@@ -102,7 +104,7 @@ class PropertyReferenceCodegen(
|
|||||||
if (JvmCodegenUtil.isConst(closure)) {
|
if (JvmCodegenUtil.isConst(closure)) {
|
||||||
generateConstInstance(asmType, wrapperMethod.returnType)
|
generateConstInstance(asmType, wrapperMethod.returnType)
|
||||||
} else {
|
} else {
|
||||||
AsmUtil.genClosureFields(closure, v, typeMapper)
|
AsmUtil.genClosureFields(closure, v, typeMapper, state.languageVersionSettings)
|
||||||
}
|
}
|
||||||
|
|
||||||
generateConstructor()
|
generateConstructor()
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.Pair;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor;
|
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor;
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
@@ -40,7 +41,7 @@ public interface CalculatedClosure {
|
|||||||
KotlinType getCapturedReceiverFromOuterContext();
|
KotlinType getCapturedReceiverFromOuterContext();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
String getCapturedReceiverLabel(BindingContext bindingContext);
|
String getCapturedReceiverFieldName(BindingContext bindingContext, LanguageVersionSettings languageVersionSettings);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
Map<DeclarationDescriptor, EnclosedValueDescriptor> getCaptureVariables();
|
Map<DeclarationDescriptor, EnclosedValueDescriptor> getCaptureVariables();
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ public class CodegenBinding {
|
|||||||
public static final WritableSlice<VariableDescriptor, VariableDescriptor> LOCAL_VARIABLE_PROPERTY_METADATA =
|
public static final WritableSlice<VariableDescriptor, VariableDescriptor> LOCAL_VARIABLE_PROPERTY_METADATA =
|
||||||
Slices.createSimpleSlice();
|
Slices.createSimpleSlice();
|
||||||
|
|
||||||
|
public static final WritableSlice<FunctionDescriptor, String> CALL_LABEL_FOR_LAMBDA_ARGUMENT = Slices.createSimpleSlice();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
BasicWritableSlice.initSliceDebugNames(CodegenBinding.class);
|
BasicWritableSlice.initSliceDebugNames(CodegenBinding.class);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,9 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil;
|
import org.jetbrains.kotlin.codegen.AsmUtil;
|
||||||
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor;
|
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor;
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.name.NameUtils;
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
@@ -101,12 +102,19 @@ public final class MutableClosure implements CalculatedClosure {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String getCapturedReceiverLabel(BindingContext bindingContext) {
|
public String getCapturedReceiverFieldName(BindingContext bindingContext, LanguageVersionSettings languageVersionSettings) {
|
||||||
if (captureReceiverType != null) {
|
if (captureReceiverType != null) {
|
||||||
// Should effectively be returned only for callable references
|
// Should effectively be returned only for callable references
|
||||||
return AsmUtil.CAPTURED_RECEIVER_FIELD;
|
return AsmUtil.CAPTURED_RECEIVER_FIELD;
|
||||||
} else if (enclosingFunWithReceiverDescriptor != null) {
|
} else if (enclosingFunWithReceiverDescriptor != null) {
|
||||||
return AsmUtil.CAPTURED_RECEIVER_FIELD;
|
if (!languageVersionSettings.supportsFeature(LanguageFeature.NewCapturedReceiverFieldNamingConvention)) {
|
||||||
|
return AsmUtil.CAPTURED_RECEIVER_FIELD;
|
||||||
|
}
|
||||||
|
|
||||||
|
String labeledThis = AsmUtil.getLabeledThisNameForReceiver(
|
||||||
|
enclosingFunWithReceiverDescriptor, bindingContext, languageVersionSettings);
|
||||||
|
|
||||||
|
return AsmUtil.getCapturedFieldName(labeledThis);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Closure does not capture an outer receiver");
|
throw new IllegalStateException("Closure does not capture an outer receiver");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ fun capturedBoundReferenceReceiver(ownerType: Type, expectedReceiverType: Type,
|
|||||||
StackValue.operation(expectedReceiverType) { iv ->
|
StackValue.operation(expectedReceiverType) { iv ->
|
||||||
iv.load(0, ownerType)
|
iv.load(0, ownerType)
|
||||||
iv.getfield(
|
iv.getfield(
|
||||||
ownerType.internalName,
|
ownerType.internalName,
|
||||||
//HACK for inliner - it should recognize field as captured receiver
|
//HACK for inliner - it should recognize field as captured receiver
|
||||||
if (isInliningStrategy) AsmUtil.CAPTURED_RECEIVER_FIELD else AsmUtil.BOUND_REFERENCE_RECEIVER,
|
if (isInliningStrategy) AsmUtil.CAPTURED_RECEIVER_FIELD else AsmUtil.BOUND_REFERENCE_RECEIVER,
|
||||||
AsmTypes.OBJECT_TYPE.descriptor
|
AsmTypes.OBJECT_TYPE.descriptor
|
||||||
)
|
)
|
||||||
StackValue.coerce(AsmTypes.OBJECT_TYPE, expectedReceiverType, iv)
|
StackValue.coerce(AsmTypes.OBJECT_TYPE, expectedReceiverType, iv)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.codegen
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||||
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||||
import org.jetbrains.kotlin.codegen.context.CodegenContext
|
import org.jetbrains.kotlin.codegen.context.CodegenContext
|
||||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
|
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
|
||||||
@@ -30,11 +31,13 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isSubclass
|
import org.jetbrains.kotlin.resolve.DescriptorUtils.isSubclass
|
||||||
import org.jetbrains.kotlin.resolve.annotations.hasJvmStaticAnnotation
|
import org.jetbrains.kotlin.resolve.annotations.hasJvmStaticAnnotation
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getFirstArgumentExpression
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getFirstArgumentExpression
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.resolve.isInlineClassType
|
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||||
@@ -439,3 +442,26 @@ fun KotlinType.isInlineClassTypeWithPrimitiveEquality(): Boolean {
|
|||||||
|
|
||||||
fun CallableDescriptor.needsExperimentalCoroutinesWrapper() =
|
fun CallableDescriptor.needsExperimentalCoroutinesWrapper() =
|
||||||
(this as? DeserializedMemberDescriptor)?.coroutinesExperimentalCompatibilityMode == CoroutinesCompatibilityMode.NEEDS_WRAPPER
|
(this as? DeserializedMemberDescriptor)?.coroutinesExperimentalCompatibilityMode == CoroutinesCompatibilityMode.NEEDS_WRAPPER
|
||||||
|
|
||||||
|
fun recordCallLabelForLambdaArgument(declaration: KtFunctionLiteral, bindingTrace: BindingTrace) {
|
||||||
|
fun storeLabelName(labelName: String) {
|
||||||
|
val functionDescriptor = bindingTrace[BindingContext.FUNCTION, declaration] ?: return
|
||||||
|
bindingTrace.record(CodegenBinding.CALL_LABEL_FOR_LAMBDA_ARGUMENT, functionDescriptor, labelName)
|
||||||
|
}
|
||||||
|
|
||||||
|
val lambdaExpression = declaration.parent as? KtLambdaExpression ?: return
|
||||||
|
val lambdaExpressionParent = lambdaExpression.parent
|
||||||
|
|
||||||
|
if (lambdaExpressionParent is KtLabeledExpression) {
|
||||||
|
lambdaExpressionParent.name?.let { labelName ->
|
||||||
|
storeLabelName(labelName)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val lambdaArgument = lambdaExpression.parent as? KtLambdaArgument ?: return
|
||||||
|
val callExpression = lambdaArgument.parent as? KtCallExpression ?: return
|
||||||
|
val call = callExpression.getResolvedCall(bindingTrace.bindingContext) ?: return
|
||||||
|
|
||||||
|
storeLabelName(call.resultingDescriptor.name.asString())
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.codegen.context;
|
|||||||
|
|
||||||
import kotlin.text.StringsKt;
|
import kotlin.text.StringsKt;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.kotlin.codegen.AsmUtil;
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
|
||||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil;
|
import org.jetbrains.kotlin.codegen.JvmCodegenUtil;
|
||||||
import org.jetbrains.kotlin.codegen.StackValue;
|
import org.jetbrains.kotlin.codegen.StackValue;
|
||||||
@@ -18,7 +19,6 @@ import org.jetbrains.kotlin.resolve.BindingContext;
|
|||||||
import org.jetbrains.kotlin.types.KotlinType;
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.codegen.AsmUtil.CAPTURED_RECEIVER_FIELD;
|
|
||||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
|
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
|
||||||
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isLocalFunction;
|
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isLocalFunction;
|
||||||
|
|
||||||
@@ -147,8 +147,9 @@ public interface LocalLookup {
|
|||||||
|
|
||||||
KotlinType receiverType = enclosingReceiverDescriptor.getType();
|
KotlinType receiverType = enclosingReceiverDescriptor.getType();
|
||||||
Type type = state.getTypeMapper().mapType(receiverType);
|
Type type = state.getTypeMapper().mapType(receiverType);
|
||||||
|
String fieldName = closure.getCapturedReceiverFieldName(state.getBindingContext(), state.getLanguageVersionSettings());
|
||||||
StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(
|
StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(
|
||||||
type, receiverType, classType, CAPTURED_RECEIVER_FIELD, false, StackValue.LOCAL_0, d
|
type, receiverType, classType, fieldName, false, StackValue.LOCAL_0, d
|
||||||
);
|
);
|
||||||
closure.setNeedsCaptureReceiverFromOuterContext();
|
closure.setNeedsCaptureReceiverFromOuterContext();
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ abstract class AbstractCoroutineCodegen(
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun generateConstructor(): Method {
|
override fun generateConstructor(): Method {
|
||||||
val args = calculateConstructorParameters(typeMapper, closure, asmType)
|
val args = calculateConstructorParameters(typeMapper, languageVersionSettings, closure, asmType)
|
||||||
val argTypes = args.map { it.fieldType }.plus(languageVersionSettings.continuationAsmType()).toTypedArray()
|
val argTypes = args.map { it.fieldType }.plus(languageVersionSettings.continuationAsmType()).toTypedArray()
|
||||||
|
|
||||||
val constructor = Method("<init>", Type.VOID_TYPE, argTypes)
|
val constructor = Method("<init>", Type.VOID_TYPE, argTypes)
|
||||||
@@ -345,7 +345,7 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
dup()
|
dup()
|
||||||
|
|
||||||
// pass captured closure to constructor
|
// pass captured closure to constructor
|
||||||
val constructorParameters = calculateConstructorParameters(typeMapper, closure, owner)
|
val constructorParameters = calculateConstructorParameters(typeMapper, languageVersionSettings, closure, owner)
|
||||||
for (parameter in constructorParameters) {
|
for (parameter in constructorParameters) {
|
||||||
StackValue.field(parameter, thisInstance).put(parameter.fieldType, this)
|
StackValue.field(parameter, thisInstance).put(parameter.fieldType, this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ internal fun generateParameterNames(
|
|||||||
isEnumName = !isEnumName
|
isEnumName = !isEnumName
|
||||||
if (!isEnumName) "\$enum\$name" else "\$enum\$ordinal"
|
if (!isEnumName) "\$enum\$name" else "\$enum\$ordinal"
|
||||||
}
|
}
|
||||||
JvmMethodParameterKind.RECEIVER -> AsmUtil.RECEIVER_NAME
|
JvmMethodParameterKind.RECEIVER -> AsmUtil.RECEIVER_PARAMETER_NAME
|
||||||
JvmMethodParameterKind.OUTER -> AsmUtil.CAPTURED_THIS_FIELD
|
JvmMethodParameterKind.OUTER -> AsmUtil.CAPTURED_THIS_FIELD
|
||||||
JvmMethodParameterKind.VALUE -> iterator.next().name.asString()
|
JvmMethodParameterKind.VALUE -> iterator.next().name.asString()
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -588,8 +588,8 @@ class AnonymousObjectTransformer(
|
|||||||
val parent = parentFieldRemapper.parent as? RegeneratedLambdaFieldRemapper ?:
|
val parent = parentFieldRemapper.parent as? RegeneratedLambdaFieldRemapper ?:
|
||||||
throw AssertionError("Expecting RegeneratedLambdaFieldRemapper, but ${parentFieldRemapper.parent}")
|
throw AssertionError("Expecting RegeneratedLambdaFieldRemapper, but ${parentFieldRemapper.parent}")
|
||||||
val ownerType = Type.getObjectType(parent.originalLambdaInternalName)
|
val ownerType = Type.getObjectType(parent.originalLambdaInternalName)
|
||||||
val desc = CapturedParamDesc(ownerType, THIS, ownerType)
|
val desc = CapturedParamDesc(ownerType, AsmUtil.THIS, ownerType)
|
||||||
val recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, THIS_0/*outer lambda/object*/, false)
|
val recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, AsmUtil.CAPTURED_THIS_FIELD/*outer lambda/object*/, false)
|
||||||
val composed = StackValue.LOCAL_0
|
val composed = StackValue.LOCAL_0
|
||||||
recapturedParamInfo.remapValue = composed
|
recapturedParamInfo.remapValue = composed
|
||||||
allRecapturedParameters.add(desc)
|
allRecapturedParameters.add(desc)
|
||||||
@@ -611,7 +611,7 @@ class AnonymousObjectTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getNewFieldName(oldName: String, originalField: Boolean): String {
|
private fun getNewFieldName(oldName: String, originalField: Boolean): String {
|
||||||
if (THIS_0 == oldName) {
|
if (AsmUtil.CAPTURED_THIS_FIELD == oldName) {
|
||||||
return if (!originalField) {
|
return if (!originalField) {
|
||||||
oldName
|
oldName
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,7 @@ import org.jetbrains.kotlin.config.isReleaseCoroutines
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.isInlineOnly
|
import org.jetbrains.kotlin.descriptors.annotations.isInlineOnly
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
@@ -769,7 +767,8 @@ class PsiInlineCodegen(
|
|||||||
assert(isInlinableParameterExpression(ktLambda)) { "Couldn't find inline expression in ${expression.text}" }
|
assert(isInlinableParameterExpression(ktLambda)) { "Couldn't find inline expression in ${expression.text}" }
|
||||||
|
|
||||||
return PsiExpressionLambda(
|
return PsiExpressionLambda(
|
||||||
ktLambda!!, typeMapper, parameter.isCrossinline, getBoundCallableReferenceReceiver(expression) != null
|
ktLambda!!, typeMapper, state.languageVersionSettings,
|
||||||
|
parameter.isCrossinline, getBoundCallableReferenceReceiver(expression) != null
|
||||||
).also { lambda ->
|
).also { lambda ->
|
||||||
val closureInfo = invocationParamBuilder.addNextValueParameter(type, true, null, parameter.index)
|
val closureInfo = invocationParamBuilder.addNextValueParameter(type, true, null, parameter.index)
|
||||||
closureInfo.lambda = lambda
|
closureInfo.lambda = lambda
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class InlinedLambdaRemapper(
|
|||||||
isDefaultBoundCallableReference && fieldName == AsmUtil.BOUND_REFERENCE_RECEIVER && fieldOwner == originalLambdaInternalName
|
isDefaultBoundCallableReference && fieldName == AsmUtil.BOUND_REFERENCE_RECEIVER && fieldOwner == originalLambdaInternalName
|
||||||
|
|
||||||
override fun getFieldNameForFolding(insnNode: FieldInsnNode): String =
|
override fun getFieldNameForFolding(insnNode: FieldInsnNode): String =
|
||||||
if (isMyBoundReceiverForDefaultLambda(insnNode.owner, insnNode.name)) AsmUtil.RECEIVER_NAME else insnNode.name
|
if (isMyBoundReceiverForDefaultLambda(insnNode.owner, insnNode.name)) AsmUtil.RECEIVER_PARAMETER_NAME else insnNode.name
|
||||||
|
|
||||||
override fun findField(fieldInsnNode: FieldInsnNode, captured: Collection<CapturedParamInfo>) =
|
override fun findField(fieldInsnNode: FieldInsnNode, captured: Collection<CapturedParamInfo>) =
|
||||||
parent!!.findField(fieldInsnNode, captured)
|
parent!!.findField(fieldInsnNode, captured)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding.*
|
|||||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure
|
import org.jetbrains.kotlin.codegen.binding.MutableClosure
|
||||||
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor
|
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
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.psi.KtCallableReferenceExpression
|
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||||
@@ -144,7 +145,7 @@ class DefaultLambda(
|
|||||||
if (isFunctionReference || isPropertyReference)
|
if (isFunctionReference || isPropertyReference)
|
||||||
constructor?.desc?.let { Type.getArgumentTypes(it) }?.singleOrNull()?.let {
|
constructor?.desc?.let { Type.getArgumentTypes(it) }?.singleOrNull()?.let {
|
||||||
originalBoundReceiverType = it
|
originalBoundReceiverType = it
|
||||||
listOf(capturedParamDesc(AsmUtil.RECEIVER_NAME, it.boxReceiverForBoundReference()))
|
listOf(capturedParamDesc(AsmUtil.RECEIVER_PARAMETER_NAME, it.boxReceiverForBoundReference()))
|
||||||
} ?: emptyList()
|
} ?: emptyList()
|
||||||
else
|
else
|
||||||
constructor?.findCapturedFieldAssignmentInstructions()?.map { fieldNode ->
|
constructor?.findCapturedFieldAssignmentInstructions()?.map { fieldNode ->
|
||||||
@@ -197,6 +198,7 @@ abstract class ExpressionLambda(protected val typeMapper: KotlinTypeMapper, isCr
|
|||||||
class PsiExpressionLambda(
|
class PsiExpressionLambda(
|
||||||
expression: KtExpression,
|
expression: KtExpression,
|
||||||
typeMapper: KotlinTypeMapper,
|
typeMapper: KotlinTypeMapper,
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
isCrossInline: Boolean,
|
isCrossInline: Boolean,
|
||||||
override val isBoundCallableReference: Boolean
|
override val isBoundCallableReference: Boolean
|
||||||
) : ExpressionLambda(typeMapper, isCrossInline) {
|
) : ExpressionLambda(typeMapper, isCrossInline) {
|
||||||
@@ -266,9 +268,11 @@ class PsiExpressionLambda(
|
|||||||
val type = typeMapper.mapType(closure.capturedReceiverFromOuterContext!!).let {
|
val type = typeMapper.mapType(closure.capturedReceiverFromOuterContext!!).let {
|
||||||
if (isBoundCallableReference) it.boxReceiverForBoundReference() else it
|
if (isBoundCallableReference) it.boxReceiverForBoundReference() else it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val fieldName = closure.getCapturedReceiverFieldName(typeMapper.bindingContext, languageVersionSettings)
|
||||||
val descriptor = EnclosedValueDescriptor(
|
val descriptor = EnclosedValueDescriptor(
|
||||||
AsmUtil.CAPTURED_RECEIVER_FIELD, null,
|
fieldName, null,
|
||||||
StackValue.field(type, lambdaClassType, AsmUtil.CAPTURED_RECEIVER_FIELD, false, StackValue.LOCAL_0),
|
StackValue.field(type, lambdaClassType, fieldName, false, StackValue.LOCAL_0),
|
||||||
type
|
type
|
||||||
)
|
)
|
||||||
add(getCapturedParamInfo(descriptor))
|
add(getCapturedParamInfo(descriptor))
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ class MethodInliner(
|
|||||||
resultNode.desc.endsWith(")" + languageVersionSettings.continuationAsmType().descriptor)
|
resultNode.desc.endsWith(")" + languageVersionSettings.continuationAsmType().descriptor)
|
||||||
|
|
||||||
for (capturedParamDesc in info.allRecapturedParameters) {
|
for (capturedParamDesc in info.allRecapturedParameters) {
|
||||||
if (capturedParamDesc.fieldName == THIS && isContinuationCreate) {
|
if (capturedParamDesc.fieldName == AsmUtil.THIS && isContinuationCreate) {
|
||||||
// Common inliner logic doesn't support cases when transforming anonymous object can
|
// Common inliner logic doesn't support cases when transforming anonymous object can
|
||||||
// be instantiated by itself.
|
// be instantiated by itself.
|
||||||
// To support such cases workaround with 'oldInfo' is used.
|
// To support such cases workaround with 'oldInfo' is used.
|
||||||
@@ -336,7 +336,7 @@ class MethodInliner(
|
|||||||
// 'This' in outer context corresponds to outer instance in current
|
// 'This' in outer context corresponds to outer instance in current
|
||||||
visitFieldInsn(
|
visitFieldInsn(
|
||||||
Opcodes.GETSTATIC, owner,
|
Opcodes.GETSTATIC, owner,
|
||||||
CAPTURED_FIELD_FOLD_PREFIX + THIS_0, capturedParamDesc.type.descriptor
|
CAPTURED_FIELD_FOLD_PREFIX + AsmUtil.CAPTURED_THIS_FIELD, capturedParamDesc.type.descriptor
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
visitFieldInsn(
|
visitFieldInsn(
|
||||||
@@ -948,6 +948,7 @@ class MethodInliner(
|
|||||||
private fun analyzeMethodNodeBeforeInline(node: MethodNode): Array<Frame<SourceValue>?> {
|
private fun analyzeMethodNodeBeforeInline(node: MethodNode): Array<Frame<SourceValue>?> {
|
||||||
val analyzer = object : Analyzer<SourceValue>(SourceInterpreter()) {
|
val analyzer = object : Analyzer<SourceValue>(SourceInterpreter()) {
|
||||||
override fun newFrame(nLocals: Int, nStack: Int): Frame<SourceValue> {
|
override fun newFrame(nLocals: Int, nStack: Int): Frame<SourceValue> {
|
||||||
|
|
||||||
return object : Frame<SourceValue>(nLocals, nStack) {
|
return object : Frame<SourceValue>(nLocals, nStack) {
|
||||||
@Throws(AnalyzerException::class)
|
@Throws(AnalyzerException::class)
|
||||||
override fun execute(insn: AbstractInsnNode, interpreter: Interpreter<SourceValue>) {
|
override fun execute(insn: AbstractInsnNode, interpreter: Interpreter<SourceValue>) {
|
||||||
|
|||||||
+3
-1
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.inline
|
package org.jetbrains.kotlin.codegen.inline
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
|
import org.jetbrains.kotlin.codegen.AsmUtil.THIS
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
@@ -65,7 +67,7 @@ class RegeneratedLambdaFieldRemapper(
|
|||||||
val field = findFieldInSuper(fin) ?:
|
val field = findFieldInSuper(fin) ?:
|
||||||
//search in parent
|
//search in parent
|
||||||
findFieldInSuper(FieldInsnNode(
|
findFieldInSuper(FieldInsnNode(
|
||||||
Opcodes.GETSTATIC, originalLambdaInternalName, THIS_0,
|
Opcodes.GETSTATIC, originalLambdaInternalName, AsmUtil.CAPTURED_THIS_FIELD,
|
||||||
Type.getObjectType(parent!!.originalLambdaInternalName!!).descriptor
|
Type.getObjectType(parent!!.originalLambdaInternalName!!).descriptor
|
||||||
))?.also { fromParent = true } ?:
|
))?.also { fromParent = true } ?:
|
||||||
throw AssertionError("Couldn't find captured this $originalLambdaInternalName for $fieldName")
|
throw AssertionError("Couldn't find captured this $originalLambdaInternalName for $fieldName")
|
||||||
|
|||||||
@@ -60,8 +60,6 @@ const val API = Opcodes.ASM5
|
|||||||
const val NUMBERED_FUNCTION_PREFIX = "kotlin/jvm/functions/Function"
|
const val NUMBERED_FUNCTION_PREFIX = "kotlin/jvm/functions/Function"
|
||||||
const val INLINE_FUN_VAR_SUFFIX = "\$iv"
|
const val INLINE_FUN_VAR_SUFFIX = "\$iv"
|
||||||
|
|
||||||
internal const val THIS = "this"
|
|
||||||
internal const val THIS_0 = "this$0"
|
|
||||||
internal const val FIRST_FUN_LABEL = "$$$$\$ROOT$$$$$"
|
internal const val FIRST_FUN_LABEL = "$$$$\$ROOT$$$$$"
|
||||||
internal const val SPECIAL_TRANSFORMATION_NAME = "\$special"
|
internal const val SPECIAL_TRANSFORMATION_NAME = "\$special"
|
||||||
const val INLINE_TRANSFORMATION_SUFFIX = "\$inlined"
|
const val INLINE_TRANSFORMATION_SUFFIX = "\$inlined"
|
||||||
@@ -70,7 +68,6 @@ internal const val INLINE_FUN_THIS_0_SUFFIX = "\$inline_fun"
|
|||||||
internal const val DEFAULT_LAMBDA_FAKE_CALL = "$$\$DEFAULT_LAMBDA_FAKE_CALL$$$"
|
internal const val DEFAULT_LAMBDA_FAKE_CALL = "$$\$DEFAULT_LAMBDA_FAKE_CALL$$$"
|
||||||
internal const val CAPTURED_FIELD_FOLD_PREFIX = "$$$"
|
internal const val CAPTURED_FIELD_FOLD_PREFIX = "$$$"
|
||||||
|
|
||||||
private const val RECEIVER_0 = "receiver$0"
|
|
||||||
private const val NON_LOCAL_RETURN = "$$$$\$NON_LOCAL_RETURN$$$$$"
|
private const val NON_LOCAL_RETURN = "$$$$\$NON_LOCAL_RETURN$$$$$"
|
||||||
private const val CAPTURED_FIELD_PREFIX = "$"
|
private const val CAPTURED_FIELD_PREFIX = "$"
|
||||||
private const val NON_CAPTURED_FIELD_PREFIX = "$$"
|
private const val NON_CAPTURED_FIELD_PREFIX = "$$"
|
||||||
@@ -249,9 +246,9 @@ private fun String.isInteger(radix: Int = 10) = toIntOrNull(radix) != null
|
|||||||
|
|
||||||
internal fun isCapturedFieldName(fieldName: String): Boolean {
|
internal fun isCapturedFieldName(fieldName: String): Boolean {
|
||||||
// TODO: improve this heuristic
|
// TODO: improve this heuristic
|
||||||
return fieldName.startsWith(CAPTURED_FIELD_PREFIX) && !fieldName.startsWith(NON_CAPTURED_FIELD_PREFIX) ||
|
return fieldName.startsWith(CAPTURED_FIELD_PREFIX) && !fieldName.startsWith(NON_CAPTURED_FIELD_PREFIX)
|
||||||
THIS_0 == fieldName ||
|
|| AsmUtil.CAPTURED_THIS_FIELD == fieldName
|
||||||
RECEIVER_0 == fieldName
|
|| AsmUtil.CAPTURED_RECEIVER_FIELD == fieldName
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun isReturnOpcode(opcode: Int) = opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN
|
internal fun isReturnOpcode(opcode: Int) = opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN
|
||||||
@@ -521,7 +518,7 @@ fun isFakeLocalVariableForInline(name: String): Boolean {
|
|||||||
return name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) || name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT)
|
return name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) || name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun isThis0(name: String): Boolean = THIS_0 == name
|
internal fun isThis0(name: String): Boolean = AsmUtil.CAPTURED_THIS_FIELD == name
|
||||||
|
|
||||||
internal fun isSpecialEnumMethod(functionDescriptor: FunctionDescriptor): Boolean {
|
internal fun isSpecialEnumMethod(functionDescriptor: FunctionDescriptor): Boolean {
|
||||||
val containingDeclaration = functionDescriptor.containingDeclaration as? PackageFragmentDescriptor ?: return false
|
val containingDeclaration = functionDescriptor.containingDeclaration as? PackageFragmentDescriptor ?: return false
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ package org.jetbrains.kotlin.resolve.jvm.checkers
|
|||||||
fun isValidDalvikIdentifier(identifier: String) = identifier.all { isValidDalvikCharacter(it) }
|
fun isValidDalvikIdentifier(identifier: String) = identifier.all { isValidDalvikCharacter(it) }
|
||||||
|
|
||||||
// https://source.android.com/devices/tech/dalvik/dex-format.html#string-syntax
|
// https://source.android.com/devices/tech/dalvik/dex-format.html#string-syntax
|
||||||
private fun isValidDalvikCharacter(c: Char) = when (c) {
|
fun isValidDalvikCharacter(c: Char) = when (c) {
|
||||||
in 'A'..'Z' -> true
|
in 'A'..'Z' -> true
|
||||||
in 'a'..'z' -> true
|
in 'a'..'z' -> true
|
||||||
in '0'..'9' -> true
|
in '0'..'9' -> true
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// LOCAL_VARIABLE_TABLE
|
||||||
|
|
||||||
|
fun String.foo(count: Int) {
|
||||||
|
val x = false
|
||||||
|
|
||||||
|
block {
|
||||||
|
val y = false
|
||||||
|
block {
|
||||||
|
val z = true
|
||||||
|
block {
|
||||||
|
this@foo + this@block.toString() + x + y + z + count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun block(block: Long.() -> Unit) = 5L.block()
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
public final class DeepInlineKt : java/lang/Object {
|
||||||
|
public final static void block(kotlin.jvm.functions.Function1 block) {
|
||||||
|
Local variables:
|
||||||
|
0 block: Lkotlin/jvm/functions/Function1;
|
||||||
|
1 $i$f$block: I
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static void foo(java.lang.String $receiver, int $i$a$1$block) {
|
||||||
|
Local variables:
|
||||||
|
9 $receiver: J
|
||||||
|
11 $i$a$1$block: I
|
||||||
|
12 $i$f$block: I
|
||||||
|
8 z: Z
|
||||||
|
6 $receiver: J
|
||||||
|
13 $i$a$1$block: I
|
||||||
|
14 $i$f$block: I
|
||||||
|
5 y: Z
|
||||||
|
3 $receiver: J
|
||||||
|
15 $i$a$1$block: I
|
||||||
|
16 $i$f$block: I
|
||||||
|
2 x: Z
|
||||||
|
0 $receiver: Ljava/lang/String;
|
||||||
|
1 count: I
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// LOCAL_VARIABLE_TABLE
|
||||||
|
|
||||||
|
fun String.foo(count: Int) {
|
||||||
|
val x = false
|
||||||
|
|
||||||
|
block b1@ {
|
||||||
|
val y = false
|
||||||
|
block b2@ {
|
||||||
|
val z = true
|
||||||
|
block b3@ {
|
||||||
|
this@foo + this@b1 + this@b2 + this@b3 + x + y + z + count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun block(block: Long.() -> Unit) = 5L.block()
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
public final class DeepInlineWithLabelsKt : java/lang/Object {
|
||||||
|
public final static void block(kotlin.jvm.functions.Function1 block) {
|
||||||
|
Local variables:
|
||||||
|
0 block: Lkotlin/jvm/functions/Function1;
|
||||||
|
1 $i$f$block: I
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static void foo(java.lang.String $receiver, int $i$a$1$block) {
|
||||||
|
Local variables:
|
||||||
|
9 $receiver: J
|
||||||
|
11 $i$a$1$block: I
|
||||||
|
12 $i$f$block: I
|
||||||
|
8 z: Z
|
||||||
|
6 $receiver: J
|
||||||
|
13 $i$a$1$block: I
|
||||||
|
14 $i$f$block: I
|
||||||
|
5 y: Z
|
||||||
|
3 $receiver: J
|
||||||
|
15 $i$a$1$block: I
|
||||||
|
16 $i$f$block: I
|
||||||
|
2 x: Z
|
||||||
|
0 $receiver: Ljava/lang/String;
|
||||||
|
1 count: I
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// LOCAL_VARIABLE_TABLE
|
||||||
|
// LANGUAGE_VERSION: 1.3
|
||||||
|
|
||||||
|
fun String.foo(count: Int) {
|
||||||
|
val x = false
|
||||||
|
|
||||||
|
block b1@ {
|
||||||
|
val y = false
|
||||||
|
block b2@ {
|
||||||
|
val z = true
|
||||||
|
block b3@ {
|
||||||
|
this@foo + this@b1 + this@b2 + this@b3 + x + y + z + count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun block(block: Long.() -> Unit) = 5L.block()
|
||||||
+69
@@ -0,0 +1,69 @@
|
|||||||
|
final class DeepNoinlineWithLabels_afterKt$foo$1$1$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function1 {
|
||||||
|
final long $this_b2
|
||||||
|
|
||||||
|
final boolean $z
|
||||||
|
|
||||||
|
final DeepNoinlineWithLabels_afterKt$foo$1$1 this$0
|
||||||
|
|
||||||
|
void <init>(DeepNoinlineWithLabels_afterKt$foo$1$1 p0, long p1, boolean p2)
|
||||||
|
|
||||||
|
public java.lang.Object invoke(java.lang.Object p0)
|
||||||
|
|
||||||
|
public final void invoke(long $receiver) {
|
||||||
|
Local variables:
|
||||||
|
0 this: LDeepNoinlineWithLabels_afterKt$foo$1$1$1;
|
||||||
|
1 $receiver: J
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class DeepNoinlineWithLabels_afterKt$foo$1$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function1 {
|
||||||
|
final long $this_b1
|
||||||
|
|
||||||
|
final boolean $y
|
||||||
|
|
||||||
|
final DeepNoinlineWithLabels_afterKt$foo$1 this$0
|
||||||
|
|
||||||
|
void <init>(DeepNoinlineWithLabels_afterKt$foo$1 p0, long p1, boolean p2)
|
||||||
|
|
||||||
|
public java.lang.Object invoke(java.lang.Object p0)
|
||||||
|
|
||||||
|
public final void invoke(long this) {
|
||||||
|
Local variables:
|
||||||
|
3 z: Z
|
||||||
|
0 this: LDeepNoinlineWithLabels_afterKt$foo$1$1;
|
||||||
|
1 $receiver: J
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class DeepNoinlineWithLabels_afterKt$foo$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function1 {
|
||||||
|
final int $count
|
||||||
|
|
||||||
|
final java.lang.String $this_foo
|
||||||
|
|
||||||
|
final boolean $x
|
||||||
|
|
||||||
|
void <init>(java.lang.String p0, boolean p1, int p2)
|
||||||
|
|
||||||
|
public java.lang.Object invoke(java.lang.Object p0)
|
||||||
|
|
||||||
|
public final void invoke(long this) {
|
||||||
|
Local variables:
|
||||||
|
3 y: Z
|
||||||
|
0 this: LDeepNoinlineWithLabels_afterKt$foo$1;
|
||||||
|
1 $receiver: J
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class DeepNoinlineWithLabels_afterKt : java/lang/Object {
|
||||||
|
public final static void block(kotlin.jvm.functions.Function1 block) {
|
||||||
|
Local variables:
|
||||||
|
0 block: Lkotlin/jvm/functions/Function1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static void foo(java.lang.String x, int $receiver) {
|
||||||
|
Local variables:
|
||||||
|
2 x: Z
|
||||||
|
0 $receiver: Ljava/lang/String;
|
||||||
|
1 count: I
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// !LANGUAGE: -NewCapturedReceiverFieldNamingConvention
|
||||||
|
// LOCAL_VARIABLE_TABLE
|
||||||
|
|
||||||
|
fun String.foo(count: Int) {
|
||||||
|
val x = false
|
||||||
|
|
||||||
|
block b1@ {
|
||||||
|
val y = false
|
||||||
|
block b2@ {
|
||||||
|
val z = true
|
||||||
|
block b3@ {
|
||||||
|
this@foo + this@b1 + this@b2 + this@b3 + x + y + z + count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun block(block: Long.() -> Unit) = 5L.block()
|
||||||
+69
@@ -0,0 +1,69 @@
|
|||||||
|
final class DeepNoinlineWithLabels_beforeKt$foo$1$1$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function1 {
|
||||||
|
final boolean $z
|
||||||
|
|
||||||
|
final long receiver$0
|
||||||
|
|
||||||
|
final DeepNoinlineWithLabels_beforeKt$foo$1$1 this$0
|
||||||
|
|
||||||
|
void <init>(DeepNoinlineWithLabels_beforeKt$foo$1$1 p0, long p1, boolean p2)
|
||||||
|
|
||||||
|
public java.lang.Object invoke(java.lang.Object p0)
|
||||||
|
|
||||||
|
public final void invoke(long $receiver) {
|
||||||
|
Local variables:
|
||||||
|
0 this: LDeepNoinlineWithLabels_beforeKt$foo$1$1$1;
|
||||||
|
1 $receiver: J
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class DeepNoinlineWithLabels_beforeKt$foo$1$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function1 {
|
||||||
|
final boolean $y
|
||||||
|
|
||||||
|
final long receiver$0
|
||||||
|
|
||||||
|
final DeepNoinlineWithLabels_beforeKt$foo$1 this$0
|
||||||
|
|
||||||
|
void <init>(DeepNoinlineWithLabels_beforeKt$foo$1 p0, long p1, boolean p2)
|
||||||
|
|
||||||
|
public java.lang.Object invoke(java.lang.Object p0)
|
||||||
|
|
||||||
|
public final void invoke(long this) {
|
||||||
|
Local variables:
|
||||||
|
3 z: Z
|
||||||
|
0 this: LDeepNoinlineWithLabels_beforeKt$foo$1$1;
|
||||||
|
1 $receiver: J
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class DeepNoinlineWithLabels_beforeKt$foo$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function1 {
|
||||||
|
final int $count
|
||||||
|
|
||||||
|
final boolean $x
|
||||||
|
|
||||||
|
final java.lang.String receiver$0
|
||||||
|
|
||||||
|
void <init>(java.lang.String p0, boolean p1, int p2)
|
||||||
|
|
||||||
|
public java.lang.Object invoke(java.lang.Object p0)
|
||||||
|
|
||||||
|
public final void invoke(long this) {
|
||||||
|
Local variables:
|
||||||
|
3 y: Z
|
||||||
|
0 this: LDeepNoinlineWithLabels_beforeKt$foo$1;
|
||||||
|
1 $receiver: J
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class DeepNoinlineWithLabels_beforeKt : java/lang/Object {
|
||||||
|
public final static void block(kotlin.jvm.functions.Function1 block) {
|
||||||
|
Local variables:
|
||||||
|
0 block: Lkotlin/jvm/functions/Function1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static void foo(java.lang.String x, int $receiver) {
|
||||||
|
Local variables:
|
||||||
|
2 x: Z
|
||||||
|
0 $receiver: Ljava/lang/String;
|
||||||
|
1 count: I
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// LOCAL_VARIABLE_TABLE
|
||||||
|
// LANGUAGE_VERSION: 1.3
|
||||||
|
|
||||||
|
fun String.foo(count: Int) {
|
||||||
|
val x = false
|
||||||
|
|
||||||
|
block {
|
||||||
|
val y = false
|
||||||
|
block {
|
||||||
|
val z = true
|
||||||
|
block {
|
||||||
|
this@foo + this@block.toString() + x + y + z + count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun block(block: Long.() -> Unit) = 5L.block()
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
final class DeepNoinline_afterKt$foo$1$1$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function1 {
|
||||||
|
final boolean $z
|
||||||
|
|
||||||
|
final DeepNoinline_afterKt$foo$1$1 this$0
|
||||||
|
|
||||||
|
void <init>(DeepNoinline_afterKt$foo$1$1 p0, boolean p1)
|
||||||
|
|
||||||
|
public java.lang.Object invoke(java.lang.Object p0)
|
||||||
|
|
||||||
|
public final void invoke(long $receiver) {
|
||||||
|
Local variables:
|
||||||
|
0 this: LDeepNoinline_afterKt$foo$1$1$1;
|
||||||
|
1 $receiver: J
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class DeepNoinline_afterKt$foo$1$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function1 {
|
||||||
|
final boolean $y
|
||||||
|
|
||||||
|
final DeepNoinline_afterKt$foo$1 this$0
|
||||||
|
|
||||||
|
void <init>(DeepNoinline_afterKt$foo$1 p0, boolean p1)
|
||||||
|
|
||||||
|
public java.lang.Object invoke(java.lang.Object p0)
|
||||||
|
|
||||||
|
public final void invoke(long this) {
|
||||||
|
Local variables:
|
||||||
|
3 z: Z
|
||||||
|
0 this: LDeepNoinline_afterKt$foo$1$1;
|
||||||
|
1 $receiver: J
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class DeepNoinline_afterKt$foo$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function1 {
|
||||||
|
final int $count
|
||||||
|
|
||||||
|
final java.lang.String $this_foo
|
||||||
|
|
||||||
|
final boolean $x
|
||||||
|
|
||||||
|
void <init>(java.lang.String p0, boolean p1, int p2)
|
||||||
|
|
||||||
|
public java.lang.Object invoke(java.lang.Object p0)
|
||||||
|
|
||||||
|
public final void invoke(long this) {
|
||||||
|
Local variables:
|
||||||
|
3 y: Z
|
||||||
|
0 this: LDeepNoinline_afterKt$foo$1;
|
||||||
|
1 $receiver: J
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class DeepNoinline_afterKt : java/lang/Object {
|
||||||
|
public final static void block(kotlin.jvm.functions.Function1 block) {
|
||||||
|
Local variables:
|
||||||
|
0 block: Lkotlin/jvm/functions/Function1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static void foo(java.lang.String x, int $receiver) {
|
||||||
|
Local variables:
|
||||||
|
2 x: Z
|
||||||
|
0 $receiver: Ljava/lang/String;
|
||||||
|
1 count: I
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// !LANGUAGE: -NewCapturedReceiverFieldNamingConvention
|
||||||
|
// LOCAL_VARIABLE_TABLE
|
||||||
|
|
||||||
|
fun String.foo(count: Int) {
|
||||||
|
val x = false
|
||||||
|
|
||||||
|
block {
|
||||||
|
val y = false
|
||||||
|
block {
|
||||||
|
val z = true
|
||||||
|
block {
|
||||||
|
this@foo + this@block.toString() + x + y + z + count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun block(block: Long.() -> Unit) = 5L.block()
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
final class DeepNoinline_beforeKt$foo$1$1$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function1 {
|
||||||
|
final boolean $z
|
||||||
|
|
||||||
|
final DeepNoinline_beforeKt$foo$1$1 this$0
|
||||||
|
|
||||||
|
void <init>(DeepNoinline_beforeKt$foo$1$1 p0, boolean p1)
|
||||||
|
|
||||||
|
public java.lang.Object invoke(java.lang.Object p0)
|
||||||
|
|
||||||
|
public final void invoke(long $receiver) {
|
||||||
|
Local variables:
|
||||||
|
0 this: LDeepNoinline_beforeKt$foo$1$1$1;
|
||||||
|
1 $receiver: J
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class DeepNoinline_beforeKt$foo$1$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function1 {
|
||||||
|
final boolean $y
|
||||||
|
|
||||||
|
final DeepNoinline_beforeKt$foo$1 this$0
|
||||||
|
|
||||||
|
void <init>(DeepNoinline_beforeKt$foo$1 p0, boolean p1)
|
||||||
|
|
||||||
|
public java.lang.Object invoke(java.lang.Object p0)
|
||||||
|
|
||||||
|
public final void invoke(long this) {
|
||||||
|
Local variables:
|
||||||
|
3 z: Z
|
||||||
|
0 this: LDeepNoinline_beforeKt$foo$1$1;
|
||||||
|
1 $receiver: J
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class DeepNoinline_beforeKt$foo$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function1 {
|
||||||
|
final int $count
|
||||||
|
|
||||||
|
final boolean $x
|
||||||
|
|
||||||
|
final java.lang.String receiver$0
|
||||||
|
|
||||||
|
void <init>(java.lang.String p0, boolean p1, int p2)
|
||||||
|
|
||||||
|
public java.lang.Object invoke(java.lang.Object p0)
|
||||||
|
|
||||||
|
public final void invoke(long this) {
|
||||||
|
Local variables:
|
||||||
|
3 y: Z
|
||||||
|
0 this: LDeepNoinline_beforeKt$foo$1;
|
||||||
|
1 $receiver: J
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class DeepNoinline_beforeKt : java/lang/Object {
|
||||||
|
public final static void block(kotlin.jvm.functions.Function1 block) {
|
||||||
|
Local variables:
|
||||||
|
0 block: Lkotlin/jvm/functions/Function1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static void foo(java.lang.String x, int $receiver) {
|
||||||
|
Local variables:
|
||||||
|
2 x: Z
|
||||||
|
0 $receiver: Ljava/lang/String;
|
||||||
|
1 count: I
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
// LOCAL_VARIABLE_TABLE
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
fun foo() {
|
||||||
|
block {
|
||||||
|
this@Foo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class Bar {
|
||||||
|
fun bar() {
|
||||||
|
block {
|
||||||
|
this@Foo
|
||||||
|
this@Bar
|
||||||
|
|
||||||
|
block {
|
||||||
|
this@Foo
|
||||||
|
this@Bar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun block(block: () -> Unit) = block()
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
public final class Foo$Bar : java/lang/Object {
|
||||||
|
final Foo this$0
|
||||||
|
|
||||||
|
public void <init>(Foo $outer) {
|
||||||
|
Local variables:
|
||||||
|
0 this: LFoo$Bar;
|
||||||
|
1 $outer: LFoo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void bar() {
|
||||||
|
Local variables:
|
||||||
|
1 $i$a$1$block: I
|
||||||
|
2 $i$f$block: I
|
||||||
|
3 $i$a$1$block: I
|
||||||
|
4 $i$f$block: I
|
||||||
|
0 this: LFoo$Bar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Foo : java/lang/Object {
|
||||||
|
public void <init>() {
|
||||||
|
Local variables:
|
||||||
|
0 this: LFoo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void foo() {
|
||||||
|
Local variables:
|
||||||
|
1 $i$a$1$block: I
|
||||||
|
2 $i$f$block: I
|
||||||
|
0 this: LFoo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class InlineClassCaptureKt : java/lang/Object {
|
||||||
|
public final static void block(kotlin.jvm.functions.Function0 block) {
|
||||||
|
Local variables:
|
||||||
|
0 block: Lkotlin/jvm/functions/Function0;
|
||||||
|
1 $i$f$block: I
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// LOCAL_VARIABLE_TABLE
|
||||||
|
|
||||||
|
fun String.foo(count: Int) {
|
||||||
|
val x: Boolean = false
|
||||||
|
|
||||||
|
block {
|
||||||
|
this@foo + this@block.toString() + x.toString() + count.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun block(block: Long.() -> Unit) = 5L.block()
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
public final class InlineReceiversKt : java/lang/Object {
|
||||||
|
public final static void block(kotlin.jvm.functions.Function1 block) {
|
||||||
|
Local variables:
|
||||||
|
0 block: Lkotlin/jvm/functions/Function1;
|
||||||
|
1 $i$f$block: I
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static void foo(java.lang.String $receiver, int $i$a$1$block) {
|
||||||
|
Local variables:
|
||||||
|
3 $receiver: J
|
||||||
|
5 $i$a$1$block: I
|
||||||
|
6 $i$f$block: I
|
||||||
|
2 x: Z
|
||||||
|
0 $receiver: Ljava/lang/String;
|
||||||
|
1 count: I
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
class Foo {
|
||||||
|
inner class Bar
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
public final class Foo$Bar : java/lang/Object {
|
||||||
|
final Foo this$0
|
||||||
|
|
||||||
|
public void <init>(Foo $outer)
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Foo : java/lang/Object {
|
||||||
|
public void <init>()
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// LOCAL_VARIABLE_TABLE
|
||||||
|
|
||||||
|
fun String.foo(count: Int) {
|
||||||
|
val x = false
|
||||||
|
|
||||||
|
block {
|
||||||
|
this@foo + this@block.toString() + x.toString() + count.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun block(block: Long.() -> Unit) = 5L.block()
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
final class NonInlineReceivers_afterKt$foo$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function1 {
|
||||||
|
final int $count
|
||||||
|
|
||||||
|
final java.lang.String $this_foo
|
||||||
|
|
||||||
|
final boolean $x
|
||||||
|
|
||||||
|
void <init>(java.lang.String p0, boolean p1, int p2)
|
||||||
|
|
||||||
|
public java.lang.Object invoke(java.lang.Object p0)
|
||||||
|
|
||||||
|
public final void invoke(long $receiver) {
|
||||||
|
Local variables:
|
||||||
|
0 this: LNonInlineReceivers_afterKt$foo$1;
|
||||||
|
1 $receiver: J
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class NonInlineReceivers_afterKt : java/lang/Object {
|
||||||
|
public final static void block(kotlin.jvm.functions.Function1 block) {
|
||||||
|
Local variables:
|
||||||
|
0 block: Lkotlin/jvm/functions/Function1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static void foo(java.lang.String x, int $receiver) {
|
||||||
|
Local variables:
|
||||||
|
2 x: Z
|
||||||
|
0 $receiver: Ljava/lang/String;
|
||||||
|
1 count: I
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// !LANGUAGE: -NewCapturedReceiverFieldNamingConvention
|
||||||
|
// LOCAL_VARIABLE_TABLE
|
||||||
|
|
||||||
|
fun String.foo(count: Int) {
|
||||||
|
val x = false
|
||||||
|
|
||||||
|
block {
|
||||||
|
this@foo + this@block.toString() + x.toString() + count.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun block(block: Long.() -> Unit) = 5L.block()
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
final class NonInlineReceivers_beforeKt$foo$1 : kotlin/jvm/internal/Lambda, kotlin/jvm/functions/Function1 {
|
||||||
|
final int $count
|
||||||
|
|
||||||
|
final boolean $x
|
||||||
|
|
||||||
|
final java.lang.String receiver$0
|
||||||
|
|
||||||
|
void <init>(java.lang.String p0, boolean p1, int p2)
|
||||||
|
|
||||||
|
public java.lang.Object invoke(java.lang.Object p0)
|
||||||
|
|
||||||
|
public final void invoke(long $receiver) {
|
||||||
|
Local variables:
|
||||||
|
0 this: LNonInlineReceivers_beforeKt$foo$1;
|
||||||
|
1 $receiver: J
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class NonInlineReceivers_beforeKt : java/lang/Object {
|
||||||
|
public final static void block(kotlin.jvm.functions.Function1 block) {
|
||||||
|
Local variables:
|
||||||
|
0 block: Lkotlin/jvm/functions/Function1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static void foo(java.lang.String x, int $receiver) {
|
||||||
|
Local variables:
|
||||||
|
2 x: Z
|
||||||
|
0 $receiver: Ljava/lang/String;
|
||||||
|
1 count: I
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
fun String.foo(a: Int) {}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
public final class SimpleKt : java/lang/Object {
|
||||||
|
public final static void foo(java.lang.String $receiver, int a)
|
||||||
|
}
|
||||||
@@ -34,7 +34,7 @@ public final class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1$1 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1 {
|
public final class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1 {
|
||||||
synthetic final field receiver$0$inlined: Sink
|
synthetic final field $this_source$inlined: Sink
|
||||||
synthetic final field this$0: CrossinlineKt$box$1$filter$$inlined$source$1
|
synthetic final field this$0: CrossinlineKt$box$1$filter$$inlined$source$1
|
||||||
inner class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1
|
inner class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1
|
||||||
inner class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1$1
|
inner class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1$1
|
||||||
@@ -46,7 +46,7 @@ public final class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1 {
|
|||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$box$1$filter$$inlined$source$1 {
|
public final class CrossinlineKt$box$1$filter$$inlined$source$1 {
|
||||||
synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1
|
synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1
|
||||||
synthetic final field receiver$0$inlined: SourceCrossinline
|
synthetic final field $this_filter$inlined: SourceCrossinline
|
||||||
inner class CrossinlineKt$box$1$filter$$inlined$source$1
|
inner class CrossinlineKt$box$1$filter$$inlined$source$1
|
||||||
inner class CrossinlineKt$box$1$filter$$inlined$source$1$1
|
inner class CrossinlineKt$box$1$filter$$inlined$source$1$1
|
||||||
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
||||||
@@ -111,7 +111,7 @@ public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2$1 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2 {
|
public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2 {
|
||||||
synthetic final field receiver$0$inlined: Sink
|
synthetic final field $this_source$inlined: Sink
|
||||||
synthetic final field this$0: CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1
|
synthetic final field this$0: CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1
|
||||||
inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2
|
inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2
|
||||||
inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2$1
|
inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2$1
|
||||||
@@ -122,7 +122,7 @@ public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1 {
|
public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1 {
|
||||||
synthetic final field receiver$0$inlined: SourceCrossinline
|
synthetic final field $this_filter$inlined: SourceCrossinline
|
||||||
inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1
|
inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1
|
||||||
inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$1
|
inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$1
|
||||||
public method <init>(p0: SourceCrossinline): void
|
public method <init>(p0: SourceCrossinline): void
|
||||||
@@ -213,7 +213,7 @@ public final class CrossinlineKt$filter$$inlined$source$1$lambda$1$1 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$filter$$inlined$source$1$lambda$1 {
|
public final class CrossinlineKt$filter$$inlined$source$1$lambda$1 {
|
||||||
synthetic final field receiver$0$inlined: Sink
|
synthetic final field $this_source$inlined: Sink
|
||||||
synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1
|
synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1
|
||||||
inner class CrossinlineKt$filter$$inlined$source$1$lambda$1
|
inner class CrossinlineKt$filter$$inlined$source$1$lambda$1
|
||||||
inner class CrossinlineKt$filter$$inlined$source$1$lambda$1$1
|
inner class CrossinlineKt$filter$$inlined$source$1$lambda$1$1
|
||||||
@@ -225,7 +225,7 @@ public final class CrossinlineKt$filter$$inlined$source$1$lambda$1 {
|
|||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$filter$$inlined$source$1 {
|
public final class CrossinlineKt$filter$$inlined$source$1 {
|
||||||
synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1
|
synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1
|
||||||
synthetic final field receiver$0$inlined: SourceCrossinline
|
synthetic final field $this_filter$inlined: SourceCrossinline
|
||||||
inner class CrossinlineKt$filter$$inlined$source$1
|
inner class CrossinlineKt$filter$$inlined$source$1
|
||||||
inner class CrossinlineKt$filter$$inlined$source$1$1
|
inner class CrossinlineKt$filter$$inlined$source$1$1
|
||||||
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
||||||
|
|||||||
+6
-6
@@ -34,7 +34,7 @@ public final class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1$1 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1 {
|
public final class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1 {
|
||||||
synthetic final field receiver$0$inlined: Sink
|
synthetic final field $this_source$inlined: Sink
|
||||||
synthetic final field this$0: CrossinlineKt$box$1$filter$$inlined$source$1
|
synthetic final field this$0: CrossinlineKt$box$1$filter$$inlined$source$1
|
||||||
inner class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1
|
inner class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1
|
||||||
inner class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1$1
|
inner class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1$1
|
||||||
@@ -46,7 +46,7 @@ public final class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1 {
|
|||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$box$1$filter$$inlined$source$1 {
|
public final class CrossinlineKt$box$1$filter$$inlined$source$1 {
|
||||||
synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1
|
synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1
|
||||||
synthetic final field receiver$0$inlined: SourceCrossinline
|
synthetic final field $this_filter$inlined: SourceCrossinline
|
||||||
inner class CrossinlineKt$box$1$filter$$inlined$source$1
|
inner class CrossinlineKt$box$1$filter$$inlined$source$1
|
||||||
inner class CrossinlineKt$box$1$filter$$inlined$source$1$1
|
inner class CrossinlineKt$box$1$filter$$inlined$source$1$1
|
||||||
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
||||||
@@ -111,7 +111,7 @@ public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2$1 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2 {
|
public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2 {
|
||||||
synthetic final field receiver$0$inlined: Sink
|
synthetic final field $this_source$inlined: Sink
|
||||||
synthetic final field this$0: CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1
|
synthetic final field this$0: CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1
|
||||||
inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2
|
inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2
|
||||||
inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2$1
|
inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2$1
|
||||||
@@ -122,7 +122,7 @@ public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1 {
|
public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1 {
|
||||||
synthetic final field receiver$0$inlined: SourceCrossinline
|
synthetic final field $this_filter$inlined: SourceCrossinline
|
||||||
inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1
|
inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1
|
||||||
inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$1
|
inner class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$1
|
||||||
public method <init>(p0: SourceCrossinline): void
|
public method <init>(p0: SourceCrossinline): void
|
||||||
@@ -213,7 +213,7 @@ public final class CrossinlineKt$filter$$inlined$source$1$lambda$1$1 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$filter$$inlined$source$1$lambda$1 {
|
public final class CrossinlineKt$filter$$inlined$source$1$lambda$1 {
|
||||||
synthetic final field receiver$0$inlined: Sink
|
synthetic final field $this_source$inlined: Sink
|
||||||
synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1
|
synthetic final field this$0: CrossinlineKt$filter$$inlined$source$1
|
||||||
inner class CrossinlineKt$filter$$inlined$source$1$lambda$1
|
inner class CrossinlineKt$filter$$inlined$source$1$lambda$1
|
||||||
inner class CrossinlineKt$filter$$inlined$source$1$lambda$1$1
|
inner class CrossinlineKt$filter$$inlined$source$1$lambda$1$1
|
||||||
@@ -225,7 +225,7 @@ public final class CrossinlineKt$filter$$inlined$source$1$lambda$1 {
|
|||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$filter$$inlined$source$1 {
|
public final class CrossinlineKt$filter$$inlined$source$1 {
|
||||||
synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1
|
synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1
|
||||||
synthetic final field receiver$0$inlined: SourceCrossinline
|
synthetic final field $this_filter$inlined: SourceCrossinline
|
||||||
inner class CrossinlineKt$filter$$inlined$source$1
|
inner class CrossinlineKt$filter$$inlined$source$1
|
||||||
inner class CrossinlineKt$filter$$inlined$source$1$1
|
inner class CrossinlineKt$filter$$inlined$source$1$1
|
||||||
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ public fun IntArray.asIterable(): Iterable<Int> {
|
|||||||
return Iterable { this.iterator() }
|
return Iterable { this.iterator() }
|
||||||
}
|
}
|
||||||
/*Threre are two constuctors so we should be sure that we check required one by checking 'receiver$0$inlined' assign*/
|
/*Threre are two constuctors so we should be sure that we check required one by checking 'receiver$0$inlined' assign*/
|
||||||
// 1 <init>\(\[I\)V\s+L0\s+ALOAD 0\s+ALOAD 1\s+PUTFIELD InlinedConstuctorKt\$asIterable\$\$inlined\$Iterable\$1\.receiver\$0\$inlined : \[I
|
// 1 <init>\(\[I\)V\s+L0\s+ALOAD 0\s+ALOAD 1\s+PUTFIELD InlinedConstuctorKt\$asIterable\$\$inlined\$Iterable\$1\.\$this_asIterable\$inlined : \[I
|
||||||
// 1 LOCALVARIABLE this LInlinedConstuctorKt\$asIterable\$\$inlined\$Iterable\$1; L0 L2 0
|
// 1 LOCALVARIABLE this LInlinedConstuctorKt\$asIterable\$\$inlined\$Iterable\$1; L0 L2 0
|
||||||
+104
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.codegen;
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataPath;
|
||||||
|
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||||
|
import org.jetbrains.kotlin.test.TargetBackend;
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
@TestMetadata("compiler/testData/codegen/asmLike")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public class AsmLikeInstructionListingTestGenerated extends AbstractAsmLikeInstructionListingTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInAsmLike() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/asmLike"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/asmLike/receiverMangling")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class ReceiverMangling extends AbstractAsmLikeInstructionListingTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInReceiverMangling() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/asmLike/receiverMangling"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("deepInline.kt")
|
||||||
|
public void testDeepInline() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/asmLike/receiverMangling/deepInline.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("deepInlineWithLabels.kt")
|
||||||
|
public void testDeepInlineWithLabels() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/asmLike/receiverMangling/deepInlineWithLabels.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("deepNoinlineWithLabels_after.kt")
|
||||||
|
public void testDeepNoinlineWithLabels_after() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/asmLike/receiverMangling/deepNoinlineWithLabels_after.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("deepNoinlineWithLabels_before.kt")
|
||||||
|
public void testDeepNoinlineWithLabels_before() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/asmLike/receiverMangling/deepNoinlineWithLabels_before.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("deepNoinline_after.kt")
|
||||||
|
public void testDeepNoinline_after() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/asmLike/receiverMangling/deepNoinline_after.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("deepNoinline_before.kt")
|
||||||
|
public void testDeepNoinline_before() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/asmLike/receiverMangling/deepNoinline_before.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineClassCapture.kt")
|
||||||
|
public void testInlineClassCapture() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/asmLike/receiverMangling/inlineClassCapture.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inlineReceivers.kt")
|
||||||
|
public void testInlineReceivers() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/asmLike/receiverMangling/inlineReceivers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerClass.kt")
|
||||||
|
public void testInnerClass() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/asmLike/receiverMangling/innerClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nonInlineReceivers_after.kt")
|
||||||
|
public void testNonInlineReceivers_after() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/asmLike/receiverMangling/nonInlineReceivers_after.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nonInlineReceivers_before.kt")
|
||||||
|
public void testNonInlineReceivers_before() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/asmLike/receiverMangling/nonInlineReceivers_before.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/asmLike/receiverMangling/simple.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -152,6 +152,10 @@ fun main(args: Array<String>) {
|
|||||||
model("codegen/kapt", targetBackend = TargetBackend.JVM)
|
model("codegen/kapt", targetBackend = TargetBackend.JVM)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractAsmLikeInstructionListingTest> {
|
||||||
|
model("codegen/asmLike", targetBackend = TargetBackend.JVM)
|
||||||
|
}
|
||||||
|
|
||||||
testClass<AbstractBlackBoxInlineCodegenTest> {
|
testClass<AbstractBlackBoxInlineCodegenTest> {
|
||||||
model("codegen/boxInline")
|
model("codegen/boxInline")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ enum class LanguageFeature(
|
|||||||
SoundSmartcastFromLoopConditionForLoopAssignedVariables(KOTLIN_1_3, kind = BUG_FIX),
|
SoundSmartcastFromLoopConditionForLoopAssignedVariables(KOTLIN_1_3, kind = BUG_FIX),
|
||||||
DslMarkerOnFunctionTypeReceiver(KOTLIN_1_4, kind = BUG_FIX),
|
DslMarkerOnFunctionTypeReceiver(KOTLIN_1_4, kind = BUG_FIX),
|
||||||
ProhibitErroneousExpressionsInAnnotationsWithUseSiteTargets(KOTLIN_1_3, kind = BUG_FIX),
|
ProhibitErroneousExpressionsInAnnotationsWithUseSiteTargets(KOTLIN_1_3, kind = BUG_FIX),
|
||||||
|
NewCapturedReceiverFieldNamingConvention(KOTLIN_1_3, kind = BUG_FIX),
|
||||||
|
|
||||||
RestrictReturnStatementTarget(KOTLIN_1_4, kind = BUG_FIX),
|
RestrictReturnStatementTarget(KOTLIN_1_4, kind = BUG_FIX),
|
||||||
NoConstantValueAttributeForNonConstVals(KOTLIN_1_4, kind = BUG_FIX),
|
NoConstantValueAttributeForNonConstVals(KOTLIN_1_4, kind = BUG_FIX),
|
||||||
|
|||||||
@@ -50,4 +50,7 @@ object NameUtils {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getScriptNameForFile(filePath: String): Name =
|
fun getScriptNameForFile(filePath: String): Name =
|
||||||
Name.identifier(NameUtils.getPackagePartClassNamePrefix(filePath.substringAfterLast('/').substringBeforeLast('.')))
|
Name.identifier(NameUtils.getPackagePartClassNamePrefix(filePath.substringAfterLast('/').substringBeforeLast('.')))
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun hasName(name: Name) = name != SpecialNames.NO_NAME_PROVIDED && name != SpecialNames.ANONYMOUS_FUNCTION
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user