diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 0260b64804d..4cf6674fdd8 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -121,7 +121,7 @@ public class FunctionCodegen extends GenerationStateAware { AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor); if (state.getClassBuilderMode() == ClassBuilderMode.SIGNATURES) return; - generateParameterAnnotations(functionDescriptor, mv); + generateParameterAnnotations(functionDescriptor, mv, jvmSignature); generateJetValueParameterAnnotations(mv, functionDescriptor, jvmSignature); @@ -141,9 +141,25 @@ public class FunctionCodegen extends GenerationStateAware { methodContext.recordSyntheticAccessorIfNeeded(functionDescriptor, typeMapper); } - private void generateParameterAnnotations(@NotNull FunctionDescriptor functionDescriptor, @NotNull MethodVisitor mv) { - for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) { - AnnotationCodegen.forParameter(parameter.getIndex(), mv, typeMapper).genAnnotations(parameter); + private void generateParameterAnnotations( + @NotNull FunctionDescriptor functionDescriptor, + @NotNull MethodVisitor mv, + @NotNull JvmMethodSignature jvmSignature + ) { + Iterator iterator = functionDescriptor.getValueParameters().iterator(); + List kotlinParameterTypes = jvmSignature.getKotlinParameterTypes(); + + for (int i = 0; i < kotlinParameterTypes.size(); i++) { + JvmMethodParameterKind kind = kotlinParameterTypes.get(i).getKind(); + if (kind == JvmMethodParameterKind.ENUM_NAME || kind == JvmMethodParameterKind.ENUM_ORDINAL) { + markEnumConstructorParameterAsSynthetic(mv, i); + continue; + } + + if (kind == JvmMethodParameterKind.VALUE) { + ValueParameterDescriptor parameter = iterator.next(); + AnnotationCodegen.forParameter(i, mv, typeMapper).genAnnotations(parameter); + } } } @@ -159,8 +175,7 @@ public class FunctionCodegen extends GenerationStateAware { for (int i = 0; i < kotlinParameterTypes.size(); i++) { JvmMethodParameterKind kind = kotlinParameterTypes.get(i).getKind(); if (kind == JvmMethodParameterKind.ENUM_NAME || kind == JvmMethodParameterKind.ENUM_ORDINAL) { - // We shouldn't generate annotations for invisible in runtime parameters otherwise we get bad - // RuntimeInvisibleParameterAnnotations error in javac + markEnumConstructorParameterAsSynthetic(mv, i); continue; } @@ -199,6 +214,14 @@ public class FunctionCodegen extends GenerationStateAware { } } + private static void markEnumConstructorParameterAsSynthetic(MethodVisitor mv, int i) { + // This is needed to avoid RuntimeInvisibleParameterAnnotations error in javac: + // see MethodWriter.visitParameterAnnotation() + + AnnotationVisitor av = mv.visitParameterAnnotation(i, "Ljava/lang/Synthetic;", true); + av.visitEnd(); + } + @Nullable private Type getThisTypeForFunction(@NotNull FunctionDescriptor functionDescriptor, @NotNull MethodContext context) { ReceiverParameterDescriptor expectedThisObject = functionDescriptor.getExpectedThisObject(); diff --git a/compiler/testData/compileJavaAgainstKotlin/class/kt4050.java b/compiler/testData/compileJavaAgainstKotlin/class/kt4050.java new file mode 100644 index 00000000000..688c8324601 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/class/kt4050.java @@ -0,0 +1,7 @@ +package test; + +public class kt4050 { + public static void main(String[] args) { + MyEnum.ENTRY.getOrd(); + } +} \ No newline at end of file diff --git a/compiler/testData/compileJavaAgainstKotlin/class/kt4050.kt b/compiler/testData/compileJavaAgainstKotlin/class/kt4050.kt new file mode 100644 index 00000000000..0d06d5b8b1a --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/class/kt4050.kt @@ -0,0 +1,9 @@ +package test + +enum class MyEnum(deprecated("") val ord: Int) { + ENTRY: MyEnum(239) + + fun f(Deprecated p: Int) { + + } +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/AnnotationGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/AnnotationGenTest.java index 7a04f621cf1..7cc96e1788b 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/AnnotationGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/AnnotationGenTest.java @@ -107,6 +107,16 @@ public class AnnotationGenTest extends CodegenTestCase { assertNotNull(getDeprecatedAnnotationFromList(annotations)); } + public void testAnnotationForParamInInstanceExtensionFunction() throws NoSuchFieldException, NoSuchMethodException { + loadText("class A() { fun String.x([Deprecated] i: Int) {}}"); + Class aClass = generateClass("A"); + Method x = aClass.getMethod("x", String.class, int.class); + assertNotNull(x); + // Get annotations for first real parameter + Annotation[] annotations = x.getParameterAnnotations()[1]; + assertNotNull(getDeprecatedAnnotationFromList(annotations)); + } + public void testParamInConstructor() throws NoSuchFieldException, NoSuchMethodException { loadText("class A ([Deprecated] x: Int) {}"); Class aClass = generateClass("A"); @@ -117,6 +127,27 @@ public class AnnotationGenTest extends CodegenTestCase { assertNotNull(getDeprecatedAnnotationFromList(annotations)); } + public void testParamInEnumConstructor() throws NoSuchFieldException, NoSuchMethodException { + loadText("enum class E([Deprecated] p: String)"); + Class klass = generateClass("E"); + Constructor constructor = klass.getDeclaredConstructor(String.class, int.class, String.class); + assertNotNull(constructor); + // Get annotations for first parameter + Annotation[] annotations = constructor.getParameterAnnotations()[0]; + assertNotNull(getDeprecatedAnnotationFromList(annotations)); + } + + public void testParamInInnerConstructor() throws NoSuchFieldException, NoSuchMethodException { + loadText("class Outer { inner class Inner([Deprecated] x: Int) }"); + Class outer = generateClass("Outer"); + Class inner = outer.getDeclaredClasses()[0]; + Constructor constructor = inner.getDeclaredConstructor(outer, int.class); + assertNotNull(constructor); + // Get annotations for first real parameter + Annotation[] annotations = constructor.getParameterAnnotations()[1]; + assertNotNull(getDeprecatedAnnotationFromList(annotations)); + } + public void testPropFieldInConstructor() throws NoSuchFieldException, NoSuchMethodException { loadText("class A ([Deprecated] var x: Int) {}"); Class aClass = generateClass("A"); diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 7be82d0a42b..99462994a13 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -950,7 +950,7 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode public void testCopyToArray() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/toArray/copyToArray.kt"); } - + @TestMetadata("kt3177-copyToArray.kt") public void testKt3177_copyToArray() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/toArray/kt3177-copyToArray.kt"); diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileJavaAgainstKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileJavaAgainstKotlinTestGenerated.java index ff7efe887b7..e0d3b35680b 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileJavaAgainstKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileJavaAgainstKotlinTestGenerated.java @@ -78,6 +78,11 @@ public class CompileJavaAgainstKotlinTestGenerated extends AbstractCompileJavaAg doTest("compiler/testData/compileJavaAgainstKotlin/class/kt3561.kt"); } + @TestMetadata("kt4050.kt") + public void testKt4050() throws Exception { + doTest("compiler/testData/compileJavaAgainstKotlin/class/kt4050.kt"); + } + @TestMetadata("Simple.kt") public void testSimple() throws Exception { doTest("compiler/testData/compileJavaAgainstKotlin/class/Simple.kt"); diff --git a/jdk-annotations/java/lang/reflect/annotations.xml b/jdk-annotations/java/lang/reflect/annotations.xml index a57658639a9..74cd9b98ccd 100644 --- a/jdk-annotations/java/lang/reflect/annotations.xml +++ b/jdk-annotations/java/lang/reflect/annotations.xml @@ -1,230 +1,233 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +