Initial annotation support
This commit is contained in:
committed by
Dmitry Petrov
parent
0bc3cc5e20
commit
4b6ddc4a9d
@@ -67,11 +67,11 @@ public abstract class AnnotationCodegen {
|
|||||||
|
|
||||||
private static final AnnotationVisitor NO_ANNOTATION_VISITOR = new AnnotationVisitor(Opcodes.ASM5) {};
|
private static final AnnotationVisitor NO_ANNOTATION_VISITOR = new AnnotationVisitor(Opcodes.ASM5) {};
|
||||||
|
|
||||||
private final MemberCodegen<?> memberCodegen;
|
private final InnerClassConsumer innerClassConsumer;
|
||||||
private final KotlinTypeMapper typeMapper;
|
private final KotlinTypeMapper typeMapper;
|
||||||
|
|
||||||
private AnnotationCodegen(@NotNull MemberCodegen<?> memberCodegen, @NotNull KotlinTypeMapper mapper) {
|
private AnnotationCodegen(@NotNull InnerClassConsumer innerClassConsumer, @NotNull KotlinTypeMapper mapper) {
|
||||||
this.memberCodegen = memberCodegen;
|
this.innerClassConsumer = innerClassConsumer;
|
||||||
this.typeMapper = mapper;
|
this.typeMapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,7 +288,7 @@ public abstract class AnnotationCodegen {
|
|||||||
String descriptor = typeMapper.mapType(annotationDescriptor.getType()).getDescriptor();
|
String descriptor = typeMapper.mapType(annotationDescriptor.getType()).getDescriptor();
|
||||||
|
|
||||||
if (classifierDescriptor instanceof ClassDescriptor) {
|
if (classifierDescriptor instanceof ClassDescriptor) {
|
||||||
memberCodegen.addInnerClassInfoFromAnnotation(((ClassDescriptor) classifierDescriptor));
|
innerClassConsumer.addInnerClassInfoFromAnnotation(((ClassDescriptor) classifierDescriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnotationVisitor annotationVisitor = visitAnnotation(descriptor, rp == RetentionPolicy.RUNTIME);
|
AnnotationVisitor annotationVisitor = visitAnnotation(descriptor, rp == RetentionPolicy.RUNTIME);
|
||||||
@@ -486,10 +486,10 @@ public abstract class AnnotationCodegen {
|
|||||||
|
|
||||||
public static AnnotationCodegen forClass(
|
public static AnnotationCodegen forClass(
|
||||||
final @NotNull ClassVisitor cv,
|
final @NotNull ClassVisitor cv,
|
||||||
@NotNull MemberCodegen<?> memberCodegen,
|
@NotNull InnerClassConsumer innerClassConsumer,
|
||||||
@NotNull KotlinTypeMapper mapper
|
@NotNull KotlinTypeMapper mapper
|
||||||
) {
|
) {
|
||||||
return new AnnotationCodegen(memberCodegen, mapper) {
|
return new AnnotationCodegen(innerClassConsumer, mapper) {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
||||||
@@ -500,10 +500,10 @@ public abstract class AnnotationCodegen {
|
|||||||
|
|
||||||
public static AnnotationCodegen forMethod(
|
public static AnnotationCodegen forMethod(
|
||||||
final @NotNull MethodVisitor mv,
|
final @NotNull MethodVisitor mv,
|
||||||
@NotNull MemberCodegen<?> memberCodegen,
|
@NotNull InnerClassConsumer innerClassConsumer,
|
||||||
@NotNull KotlinTypeMapper mapper
|
@NotNull KotlinTypeMapper mapper
|
||||||
) {
|
) {
|
||||||
return new AnnotationCodegen(memberCodegen, mapper) {
|
return new AnnotationCodegen(innerClassConsumer, mapper) {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
||||||
@@ -514,10 +514,10 @@ public abstract class AnnotationCodegen {
|
|||||||
|
|
||||||
public static AnnotationCodegen forField(
|
public static AnnotationCodegen forField(
|
||||||
final @NotNull FieldVisitor fv,
|
final @NotNull FieldVisitor fv,
|
||||||
@NotNull MemberCodegen<?> memberCodegen,
|
@NotNull InnerClassConsumer innerClassConsumer,
|
||||||
@NotNull KotlinTypeMapper mapper
|
@NotNull KotlinTypeMapper mapper
|
||||||
) {
|
) {
|
||||||
return new AnnotationCodegen(memberCodegen, mapper) {
|
return new AnnotationCodegen(innerClassConsumer, mapper) {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
||||||
@@ -529,10 +529,10 @@ public abstract class AnnotationCodegen {
|
|||||||
public static AnnotationCodegen forParameter(
|
public static AnnotationCodegen forParameter(
|
||||||
final int parameter,
|
final int parameter,
|
||||||
final @NotNull MethodVisitor mv,
|
final @NotNull MethodVisitor mv,
|
||||||
@NotNull MemberCodegen<?> memberCodegen,
|
@NotNull InnerClassConsumer innerClassConsumer,
|
||||||
@NotNull KotlinTypeMapper mapper
|
@NotNull KotlinTypeMapper mapper
|
||||||
) {
|
) {
|
||||||
return new AnnotationCodegen(memberCodegen, mapper) {
|
return new AnnotationCodegen(innerClassConsumer, mapper) {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
||||||
@@ -543,10 +543,10 @@ public abstract class AnnotationCodegen {
|
|||||||
|
|
||||||
public static AnnotationCodegen forAnnotationDefaultValue(
|
public static AnnotationCodegen forAnnotationDefaultValue(
|
||||||
final @NotNull MethodVisitor mv,
|
final @NotNull MethodVisitor mv,
|
||||||
@NotNull MemberCodegen<?> memberCodegen,
|
@NotNull InnerClassConsumer innerClassConsumer,
|
||||||
@NotNull KotlinTypeMapper mapper
|
@NotNull KotlinTypeMapper mapper
|
||||||
) {
|
) {
|
||||||
return new AnnotationCodegen(memberCodegen, mapper) {
|
return new AnnotationCodegen(innerClassConsumer, mapper) {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
||||||
|
|||||||
@@ -272,7 +272,17 @@ public class FunctionCodegen {
|
|||||||
Method asmMethod,
|
Method asmMethod,
|
||||||
MethodVisitor mv
|
MethodVisitor mv
|
||||||
) {
|
) {
|
||||||
AnnotationCodegen annotationCodegen = AnnotationCodegen.forMethod(mv, memberCodegen, typeMapper);
|
generateMethodAnnotations(functionDescriptor, asmMethod, mv, memberCodegen, typeMapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void generateMethodAnnotations(
|
||||||
|
@NotNull FunctionDescriptor functionDescriptor,
|
||||||
|
Method asmMethod,
|
||||||
|
MethodVisitor mv,
|
||||||
|
@NotNull InnerClassConsumer consumer,
|
||||||
|
@NotNull KotlinTypeMapper typeMapper
|
||||||
|
) {
|
||||||
|
AnnotationCodegen annotationCodegen = AnnotationCodegen.forMethod(mv, consumer, typeMapper);
|
||||||
|
|
||||||
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
|
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
|
||||||
AnnotationUseSiteTarget target = functionDescriptor instanceof PropertySetterDescriptor ? PROPERTY_SETTER : PROPERTY_GETTER;
|
AnnotationUseSiteTarget target = functionDescriptor instanceof PropertySetterDescriptor ? PROPERTY_SETTER : PROPERTY_GETTER;
|
||||||
@@ -288,6 +298,17 @@ public class FunctionCodegen {
|
|||||||
@NotNull MethodVisitor mv,
|
@NotNull MethodVisitor mv,
|
||||||
@NotNull JvmMethodSignature jvmSignature
|
@NotNull JvmMethodSignature jvmSignature
|
||||||
) {
|
) {
|
||||||
|
generateParameterAnnotations(functionDescriptor, mv, jvmSignature, memberCodegen, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void generateParameterAnnotations(
|
||||||
|
@NotNull FunctionDescriptor functionDescriptor,
|
||||||
|
@NotNull MethodVisitor mv,
|
||||||
|
@NotNull JvmMethodSignature jvmSignature,
|
||||||
|
@NotNull InnerClassConsumer innerClassConsumer,
|
||||||
|
@NotNull GenerationState state
|
||||||
|
) {
|
||||||
|
KotlinTypeMapper typeMapper = state.getTypeMapper();
|
||||||
Iterator<ValueParameterDescriptor> iterator = functionDescriptor.getValueParameters().iterator();
|
Iterator<ValueParameterDescriptor> iterator = functionDescriptor.getValueParameters().iterator();
|
||||||
List<JvmMethodParameterSignature> kotlinParameterTypes = jvmSignature.getValueParameters();
|
List<JvmMethodParameterSignature> kotlinParameterTypes = jvmSignature.getValueParameters();
|
||||||
|
|
||||||
@@ -295,13 +316,13 @@ public class FunctionCodegen {
|
|||||||
JvmMethodParameterSignature parameterSignature = kotlinParameterTypes.get(i);
|
JvmMethodParameterSignature parameterSignature = kotlinParameterTypes.get(i);
|
||||||
JvmMethodParameterKind kind = parameterSignature.getKind();
|
JvmMethodParameterKind kind = parameterSignature.getKind();
|
||||||
if (kind.isSkippedInGenericSignature()) {
|
if (kind.isSkippedInGenericSignature()) {
|
||||||
markEnumOrInnerConstructorParameterAsSynthetic(mv, i);
|
markEnumOrInnerConstructorParameterAsSynthetic(mv, i, state.getClassBuilderMode());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kind == JvmMethodParameterKind.VALUE) {
|
if (kind == JvmMethodParameterKind.VALUE) {
|
||||||
ValueParameterDescriptor parameter = iterator.next();
|
ValueParameterDescriptor parameter = iterator.next();
|
||||||
AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, memberCodegen, typeMapper);
|
AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, innerClassConsumer, typeMapper);
|
||||||
|
|
||||||
if (functionDescriptor instanceof PropertySetterDescriptor) {
|
if (functionDescriptor instanceof PropertySetterDescriptor) {
|
||||||
PropertyDescriptor propertyDescriptor = ((PropertySetterDescriptor) functionDescriptor).getCorrespondingProperty();
|
PropertyDescriptor propertyDescriptor = ((PropertySetterDescriptor) functionDescriptor).getCorrespondingProperty();
|
||||||
@@ -320,7 +341,7 @@ public class FunctionCodegen {
|
|||||||
ReceiverParameterDescriptor receiver = JvmCodegenUtil.getDirectMember(functionDescriptor).getExtensionReceiverParameter();
|
ReceiverParameterDescriptor receiver = JvmCodegenUtil.getDirectMember(functionDescriptor).getExtensionReceiverParameter();
|
||||||
|
|
||||||
if (receiver != null) {
|
if (receiver != null) {
|
||||||
AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, memberCodegen, typeMapper);
|
AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, innerClassConsumer, typeMapper);
|
||||||
Annotated targetedAnnotations = new AnnotatedWithOnlyTargetedAnnotations(receiver.getType());
|
Annotated targetedAnnotations = new AnnotatedWithOnlyTargetedAnnotations(receiver.getType());
|
||||||
annotationCodegen.genAnnotations(targetedAnnotations, parameterSignature.getAsmType(), RECEIVER);
|
annotationCodegen.genAnnotations(targetedAnnotations, parameterSignature.getAsmType(), RECEIVER);
|
||||||
|
|
||||||
@@ -330,9 +351,9 @@ public class FunctionCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markEnumOrInnerConstructorParameterAsSynthetic(MethodVisitor mv, int i) {
|
private static void markEnumOrInnerConstructorParameterAsSynthetic(MethodVisitor mv, int i, ClassBuilderMode mode) {
|
||||||
// IDEA's ClsPsi builder fails to annotate synthetic parameters
|
// IDEA's ClsPsi builder fails to annotate synthetic parameters
|
||||||
if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES) return;
|
if (mode == ClassBuilderMode.LIGHT_CLASSES) return;
|
||||||
|
|
||||||
// This is needed to avoid RuntimeInvisibleParameterAnnotations error in javac:
|
// This is needed to avoid RuntimeInvisibleParameterAnnotations error in javac:
|
||||||
// see MethodWriter.visitParameterAnnotation()
|
// see MethodWriter.visitParameterAnnotation()
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.codegen
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
|
||||||
|
interface InnerClassConsumer {
|
||||||
|
fun addInnerClassInfoFromAnnotation(classDescriptor: ClassDescriptor)
|
||||||
|
}
|
||||||
@@ -73,7 +73,7 @@ import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.
|
|||||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt.Synthetic;
|
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt.Synthetic;
|
||||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclarationContainer*/> {
|
public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclarationContainer*/> implements InnerClassConsumer {
|
||||||
protected final GenerationState state;
|
protected final GenerationState state;
|
||||||
protected final T element;
|
protected final T element;
|
||||||
protected final FieldOwnerContext context;
|
protected final FieldOwnerContext context;
|
||||||
@@ -304,6 +304,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
|||||||
|
|
||||||
// It's necessary for proper recovering of classId by plain string JVM descriptor when loading annotations
|
// It's necessary for proper recovering of classId by plain string JVM descriptor when loading annotations
|
||||||
// See FileBasedKotlinClass.convertAnnotationVisitor
|
// See FileBasedKotlinClass.convertAnnotationVisitor
|
||||||
|
@Override
|
||||||
public void addInnerClassInfoFromAnnotation(@NotNull ClassDescriptor classDescriptor) {
|
public void addInnerClassInfoFromAnnotation(@NotNull ClassDescriptor classDescriptor) {
|
||||||
DeclarationDescriptor current = classDescriptor;
|
DeclarationDescriptor current = classDescriptor;
|
||||||
while (current != null && !isTopLevelDeclaration(current)) {
|
while (current != null && !isTopLevelDeclaration(current)) {
|
||||||
|
|||||||
+25
-4
@@ -18,10 +18,10 @@ package org.jetbrains.kotlin.backend.jvm.codegen
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmSpecialDescriptor
|
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmSpecialDescriptor
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.FileClassDescriptor
|
import org.jetbrains.kotlin.backend.jvm.lower.FileClassDescriptor
|
||||||
import org.jetbrains.kotlin.codegen.*
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
|
||||||
import org.jetbrains.kotlin.codegen.MemberCodegen.badDescriptor
|
import org.jetbrains.kotlin.codegen.MemberCodegen.badDescriptor
|
||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.name.SpecialNames
|
import org.jetbrains.kotlin.name.SpecialNames
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils.isTopLevelDeclaration
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
||||||
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||||
@@ -38,7 +39,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
|||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import java.lang.RuntimeException
|
import java.lang.RuntimeException
|
||||||
|
|
||||||
class ClassCodegen private constructor(val irClass: IrClass, val context: JvmBackendContext, val parentClassCodegen: ClassCodegen? = null) {
|
class ClassCodegen private constructor(val irClass: IrClass, val context: JvmBackendContext, val parentClassCodegen: ClassCodegen? = null) : InnerClassConsumer {
|
||||||
|
|
||||||
private val innerClasses = mutableListOf<ClassDescriptor>()
|
private val innerClasses = mutableListOf<ClassDescriptor>()
|
||||||
|
|
||||||
@@ -69,6 +70,7 @@ class ClassCodegen private constructor(val irClass: IrClass, val context: JvmBac
|
|||||||
signature.superclassName,
|
signature.superclassName,
|
||||||
signature.interfaces.toTypedArray()
|
signature.interfaces.toTypedArray()
|
||||||
)
|
)
|
||||||
|
AnnotationCodegen.forClass(visitor.visitor, this, typeMapper).genAnnotations(descriptor, null)
|
||||||
|
|
||||||
irClass.declarations.forEach {
|
irClass.declarations.forEach {
|
||||||
generateDeclaration(it)
|
generateDeclaration(it)
|
||||||
@@ -121,8 +123,15 @@ class ClassCodegen private constructor(val irClass: IrClass, val context: JvmBac
|
|||||||
fun generateField(field: IrField) {
|
fun generateField(field: IrField) {
|
||||||
val fieldType = typeMapper.mapType(field.descriptor)
|
val fieldType = typeMapper.mapType(field.descriptor)
|
||||||
val fieldSignature = typeMapper.mapFieldSignature(field.descriptor.type, field.descriptor)
|
val fieldSignature = typeMapper.mapFieldSignature(field.descriptor.type, field.descriptor)
|
||||||
visitor.newField(field.OtherOrigin, field.descriptor.calculateCommonFlags(), field.descriptor.name.asString(), fieldType.descriptor,
|
val fv = visitor.newField(field.OtherOrigin, field.descriptor.calculateCommonFlags(), field.descriptor.name.asString(), fieldType.descriptor,
|
||||||
fieldSignature, null/*TODO support default values*/)
|
fieldSignature, null/*TODO support default values*/)
|
||||||
|
|
||||||
|
if (field.origin == JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_ENTRY) {
|
||||||
|
AnnotationCodegen.forField(fv, this, typeMapper).genAnnotations(field.descriptor, null)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateMethod(method: IrFunction) {
|
fun generateMethod(method: IrFunction) {
|
||||||
@@ -157,6 +166,18 @@ class ClassCodegen private constructor(val irClass: IrClass, val context: JvmBac
|
|||||||
return if (parentClassCodegen != null) descriptor else null
|
return if (parentClassCodegen != null) descriptor else null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It's necessary for proper recovering of classId by plain string JVM descriptor when loading annotations
|
||||||
|
// See FileBasedKotlinClass.convertAnnotationVisitor
|
||||||
|
override fun addInnerClassInfoFromAnnotation(classDescriptor: ClassDescriptor) {
|
||||||
|
var current: DeclarationDescriptor? = classDescriptor
|
||||||
|
while (current != null && !isTopLevelDeclaration(current)) {
|
||||||
|
if (current is ClassDescriptor) {
|
||||||
|
innerClasses.add(current)
|
||||||
|
}
|
||||||
|
current = current.containingDeclaration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ClassDescriptor.calculateClassFlags(): Int {
|
fun ClassDescriptor.calculateClassFlags(): Int {
|
||||||
|
|||||||
+10
-5
@@ -313,11 +313,16 @@ class ExpressionCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateLocal(descriptor: CallableDescriptor, type: Type): StackValue {
|
private fun generateLocal(descriptor: CallableDescriptor, type: Type): StackValue {
|
||||||
|
val index = findLocalIndex(descriptor)
|
||||||
|
StackValue.local(index, type).put(type, mv)
|
||||||
|
return onStack(type)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findLocalIndex(descriptor: CallableDescriptor): Int {
|
||||||
val index = frame.getIndex(descriptor).apply {
|
val index = frame.getIndex(descriptor).apply {
|
||||||
if (this < 0) throw AssertionError("Non-mapped local variable descriptor: $descriptor")
|
if (this < 0) throw AssertionError("Non-mapped local variable descriptor: $descriptor")
|
||||||
}
|
}
|
||||||
StackValue.local(index, type).put(type, mv)
|
return index
|
||||||
return onStack(type)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitGetObjectValue(expression: IrGetObjectValue, data: BlockInfo): StackValue {
|
override fun visitGetObjectValue(expression: IrGetObjectValue, data: BlockInfo): StackValue {
|
||||||
@@ -330,7 +335,7 @@ class ExpressionCodegen(
|
|||||||
|
|
||||||
override fun visitSetVariable(expression: IrSetVariable, data: BlockInfo): StackValue {
|
override fun visitSetVariable(expression: IrSetVariable, data: BlockInfo): StackValue {
|
||||||
val value = expression.value.accept(this, data)
|
val value = expression.value.accept(this, data)
|
||||||
StackValue.local(frame.getIndex(expression.descriptor), expression.descriptor.asmType).store(value, mv)
|
StackValue.local(findLocalIndex(expression.descriptor), expression.descriptor.asmType).store(value, mv)
|
||||||
return none()
|
return none()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -494,8 +499,8 @@ class ExpressionCodegen(
|
|||||||
val end = Label()
|
val end = Label()
|
||||||
|
|
||||||
thenBranch.apply {
|
thenBranch.apply {
|
||||||
gen(this, data)
|
gen(this, type, data)
|
||||||
coerceNotToUnit(this.asmType, type)
|
//coerceNotToUnit(this.asmType, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
mv.goTo(end)
|
mv.goTo(end)
|
||||||
|
|||||||
+5
-5
@@ -17,16 +17,13 @@
|
|||||||
package org.jetbrains.kotlin.backend.jvm.codegen
|
package org.jetbrains.kotlin.backend.jvm.codegen
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.InitializersLowering
|
import org.jetbrains.kotlin.backend.jvm.lower.InitializersLowering
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil.isStaticMethod
|
import org.jetbrains.kotlin.codegen.AsmUtil.isStaticMethod
|
||||||
import org.jetbrains.kotlin.codegen.FrameMap
|
import org.jetbrains.kotlin.codegen.FunctionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
|
||||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.util.dump
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
||||||
@@ -60,6 +57,9 @@ class FunctionCodegen(val irFunction: IrFunction, val classCodegen: ClassCodegen
|
|||||||
signature.asmMethod.name, signature.asmMethod.descriptor,
|
signature.asmMethod.name, signature.asmMethod.descriptor,
|
||||||
signature.genericsSignature, null/*TODO support exception*/)
|
signature.genericsSignature, null/*TODO support exception*/)
|
||||||
|
|
||||||
|
FunctionCodegen.generateMethodAnnotations(descriptor, signature.asmMethod, methodVisitor, classCodegen, state.typeMapper)
|
||||||
|
FunctionCodegen.generateParameterAnnotations(descriptor, methodVisitor, signature, classCodegen, state)
|
||||||
|
|
||||||
if (!state.classBuilderMode.generateBodies || flags.and(Opcodes.ACC_ABSTRACT) != 0) {
|
if (!state.classBuilderMode.generateBodies || flags.and(Opcodes.ACC_ABSTRACT) != 0) {
|
||||||
methodVisitor.visitEnd()
|
methodVisitor.visitEnd()
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user