diff --git a/annotations/org/jetbrains/asm4/annotations.xml b/annotations/org/jetbrains/asm4/annotations.xml new file mode 100644 index 00000000000..78608dfca6b --- /dev/null +++ b/annotations/org/jetbrains/asm4/annotations.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java index 139a2127618..b58e2cdade2 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java @@ -42,6 +42,8 @@ import java.util.*; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration; public abstract class AnnotationCodegen { + private static final AnnotationVisitor NO_ANNOTATION_VISITOR = new AnnotationVisitor(Opcodes.ASM4) {}; + private final JetTypeMapper typeMapper; private final BindingContext bindingContext; @@ -271,50 +273,61 @@ public abstract class AnnotationCodegen { return RetentionPolicy.CLASS; } + @NotNull abstract AnnotationVisitor visitAnnotation(String descr, boolean visible); public static AnnotationCodegen forClass(final ClassVisitor cv, JetTypeMapper mapper) { return new AnnotationCodegen(mapper) { + @NotNull @Override AnnotationVisitor visitAnnotation(String descr, boolean visible) { - return cv.visitAnnotation(descr, visible); + return safe(cv.visitAnnotation(descr, visible)); } }; } public static AnnotationCodegen forMethod(final MethodVisitor mv, JetTypeMapper mapper) { return new AnnotationCodegen(mapper) { + @NotNull @Override AnnotationVisitor visitAnnotation(String descr, boolean visible) { - return mv.visitAnnotation(descr, visible); + return safe(mv.visitAnnotation(descr, visible)); } }; } public static AnnotationCodegen forField(final FieldVisitor fv, JetTypeMapper mapper) { return new AnnotationCodegen(mapper) { + @NotNull @Override AnnotationVisitor visitAnnotation(String descr, boolean visible) { - return fv.visitAnnotation(descr, visible); + return safe(fv.visitAnnotation(descr, visible)); } }; } public static AnnotationCodegen forParameter(final int parameter, final MethodVisitor mv, JetTypeMapper mapper) { return new AnnotationCodegen(mapper) { + @NotNull @Override AnnotationVisitor visitAnnotation(String descr, boolean visible) { - return mv.visitParameterAnnotation(parameter, descr, visible); + return safe(mv.visitParameterAnnotation(parameter, descr, visible)); } }; } public static AnnotationCodegen forAnnotationDefaultValue(final MethodVisitor mv, JetTypeMapper mapper) { return new AnnotationCodegen(mapper) { + @NotNull @Override AnnotationVisitor visitAnnotation(String descr, boolean visible) { - return mv.visitAnnotationDefault(); + return safe(mv.visitAnnotationDefault()); } }; } + + @NotNull + private static AnnotationVisitor safe(@Nullable AnnotationVisitor av) { + return av == null ? NO_ANNOTATION_VISITOR : av; + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 8f9b0ac2869..76b301408d4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -203,11 +203,13 @@ public class FunctionCodegen extends ParentCodegenAwareImpl { AnnotationVisitor av = mv.visitParameterAnnotation(i, asmDescByFqNameWithoutInnerClasses(fqNameByClass(JetValueParameter.class)), true); - av.visit("name", name); - if (nullableType) { - av.visit("type", "?"); + if (av != null) { + av.visit("name", name); + if (nullableType) { + av.visit("type", "?"); + } + av.visitEnd(); } - av.visitEnd(); } } @@ -219,7 +221,9 @@ public class FunctionCodegen extends ParentCodegenAwareImpl { // see MethodWriter.visitParameterAnnotation() AnnotationVisitor av = mv.visitParameterAnnotation(i, "Ljava/lang/Synthetic;", true); - av.visitEnd(); + if (av != null) { + av.visitEnd(); + } } @Nullable diff --git a/compiler/testData/asJava/nullabilityAnnotations/Synthetic.java b/compiler/testData/asJava/nullabilityAnnotations/Synthetic.java new file mode 100644 index 00000000000..8316c691c26 --- /dev/null +++ b/compiler/testData/asJava/nullabilityAnnotations/Synthetic.java @@ -0,0 +1,15 @@ +public final class Synthetic implements jet.JetObject { + @org.jetbrains.annotations.NotNull + private final void foo() { /* compiled code */ } + + @org.jetbrains.annotations.NotNull + public Synthetic() { /* compiled code */ } + + public final class Inner implements jet.JetObject { + @org.jetbrains.annotations.NotNull + public final void test() { /* compiled code */ } + + @org.jetbrains.annotations.NotNull + public Inner() { /* compiled code */ } + } +} \ No newline at end of file diff --git a/compiler/testData/asJava/nullabilityAnnotations/Synthetic.kt b/compiler/testData/asJava/nullabilityAnnotations/Synthetic.kt new file mode 100644 index 00000000000..6ee1844c9df --- /dev/null +++ b/compiler/testData/asJava/nullabilityAnnotations/Synthetic.kt @@ -0,0 +1,9 @@ +class Synthetic { + inner class Inner { + fun test() { + foo() + } + } + + private fun foo() {} +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/asJava/NullabilityAnnotationsTest.java b/compiler/tests/org/jetbrains/jet/asJava/NullabilityAnnotationsTest.java index e12f31a8869..920dc4ecd95 100644 --- a/compiler/tests/org/jetbrains/jet/asJava/NullabilityAnnotationsTest.java +++ b/compiler/tests/org/jetbrains/jet/asJava/NullabilityAnnotationsTest.java @@ -61,6 +61,10 @@ public class NullabilityAnnotationsTest extends KotlinAsJavaTestBase { doTest(getTestName(false)); } + public void testSynthetic() throws Exception { + doTest(getTestName(false)); + } + private void doTest(@NotNull String fqName) { PsiClass psiClass = finder.findClass(fqName, GlobalSearchScope.allScope(getProject())); if (!(psiClass instanceof KotlinLightClass)) {