private void generateParameterAnnotations( @NotNull FunctionDescriptor functionDescriptor, @NotNull MethodVisitor mv, @NotNull JvmMethodSignature jvmSignature) { Iterator<ValueParameterDescriptor> iterator = functionDescriptor.getValueParameters().iterator(); List<JvmMethodParameterSignature> kotlinParameterTypes = jvmSignature.getValueParameters(); for (int i = 0; i < kotlinParameterTypes.size(); i++) { JvmMethodParameterSignature parameterSignature = kotlinParameterTypes.get(i); JvmMethodParameterKind kind = parameterSignature.getKind(); if (kind.isSkippedInGenericSignature()) { markEnumOrInnerConstructorParameterAsSynthetic(mv, i); continue; } if (kind == JvmMethodParameterKind.VALUE) { ValueParameterDescriptor parameter = iterator.next(); if (parameter.getIndex() != i) { v.getSerializationBindings().put(INDEX_FOR_VALUE_PARAMETER, parameter, i); } AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, typeMapper); if (functionDescriptor instanceof PropertySetterDescriptor) { PropertyDescriptor propertyDescriptor = ((PropertySetterDescriptor) functionDescriptor).getCorrespondingProperty(); Annotated targetedAnnotations = new AnnotatedWithOnlyTargetedAnnotations(propertyDescriptor); annotationCodegen.genAnnotations( targetedAnnotations, parameterSignature.getAsmType(), SETTER_PARAMETER); } if (functionDescriptor instanceof ConstructorDescriptor) { annotationCodegen.genAnnotations( parameter, parameterSignature.getAsmType(), CONSTRUCTOR_PARAMETER); } else { annotationCodegen.genAnnotations(parameter, parameterSignature.getAsmType()); } } else if (kind == JvmMethodParameterKind.RECEIVER) { ReceiverParameterDescriptor receiver = ((functionDescriptor instanceof PropertyAccessorDescriptor) ? ((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty() : functionDescriptor) .getExtensionReceiverParameter(); if (receiver != null) { AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, typeMapper); Annotated targetedAnnotations = new AnnotatedWithOnlyTargetedAnnotations(receiver.getType()); annotationCodegen.genAnnotations( targetedAnnotations, parameterSignature.getAsmType(), RECEIVER); } } } }
private static void generateLocalVariableTable( @NotNull MethodVisitor mv, @NotNull JvmMethodSignature jvmMethodSignature, @NotNull FunctionDescriptor functionDescriptor, @Nullable Type thisType, @NotNull Label methodBegin, @NotNull Label methodEnd, @NotNull OwnerKind ownerKind) { Iterator<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters().iterator(); List<JvmMethodParameterSignature> params = jvmMethodSignature.getValueParameters(); int shift = 0; boolean isStatic = AsmUtil.isStaticMethod(ownerKind, functionDescriptor); if (!isStatic) { // add this if (thisType != null) { mv.visitLocalVariable( "this", thisType.getDescriptor(), null, methodBegin, methodEnd, shift); } else { // TODO: provide thisType for callable reference } shift++; } for (int i = 0; i < params.size(); i++) { JvmMethodParameterSignature param = params.get(i); JvmMethodParameterKind kind = param.getKind(); String parameterName; if (kind == JvmMethodParameterKind.VALUE) { ValueParameterDescriptor parameter = valueParameters.next(); parameterName = parameter.getName().asString(); } else { String lowercaseKind = kind.name().toLowerCase(); parameterName = needIndexForVar(kind) ? "$" + lowercaseKind + "$" + i : "$" + lowercaseKind; } Type type = param.getAsmType(); mv.visitLocalVariable( parameterName, type.getDescriptor(), null, methodBegin, methodEnd, shift); shift += type.getSize(); } }
@Override public void writeParameterType(JvmMethodParameterKind parameterKind) { // This magic mimics the behavior of javac that enum constructor have these synthetic parameters // in erased signature, but doesn't // have them in generic signature. IDEA, javac and their friends rely on this behavior. if (parameterKind.isSkippedInGenericSignature()) { generic = true; // pushing dummy visitor, because we don't want these parameters to appear in generic JVM // signature push(new SignatureWriter()); } else { push(signatureVisitor().visitParameterType()); } super.writeParameterType(parameterKind); }