diff --git a/plugins/java-decompiler/engine/BUILD.bazel b/plugins/java-decompiler/engine/BUILD.bazel index 2399fcec49ca..f9d72d5cd3fa 100644 --- a/plugins/java-decompiler/engine/BUILD.bazel +++ b/plugins/java-decompiler/engine/BUILD.bazel @@ -25,6 +25,7 @@ jvm_library( "@lib//:junit4", "@lib//:assert_j", "@lib//:jetbrains-annotations", + "@lib//:hamcrest", ] ) ### auto-generated section `build intellij.java.decompiler.engine` end diff --git a/plugins/java-decompiler/engine/intellij.java.decompiler.engine.iml b/plugins/java-decompiler/engine/intellij.java.decompiler.engine.iml index 88c1aeb4a94d..9a68a32888d3 100644 --- a/plugins/java-decompiler/engine/intellij.java.decompiler.engine.iml +++ b/plugins/java-decompiler/engine/intellij.java.decompiler.engine.iml @@ -12,5 +12,6 @@ + \ No newline at end of file diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassWriter.java index 26e0b3299c0f..5ff32101d59c 100644 --- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -1475,10 +1475,13 @@ public class ClassWriter { TargetInfo.TypeParameterTarget.extract(typeAnnotations, i).forEach(typeAnnotation -> typeAnnotation.writeTo(buffer)); buffer.append(parameters.get(i)); List parameterBounds = bounds.get(i); - if (parameterBounds.size() > 1 || !"java/lang/Object".equals(parameterBounds.get(0).getValue())) { + List firstTypeAnnotations = TargetInfo.TypeParameterBoundTarget.extract(typeAnnotations, i, 0); + if (parameterBounds.size() > 1 || + (parameterBounds.size() == 1 && !"java/lang/Object".equals(parameterBounds.getFirst().getValue()) || + !firstTypeAnnotations.isEmpty())) { buffer.append(" extends "); - TargetInfo.TypeParameterBoundTarget.extract(typeAnnotations, i, 0).forEach(typeAnnotation -> typeAnnotation.writeTo(buffer)); - buffer.append(ExprProcessor.getCastTypeName(parameterBounds.get(0), Collections.emptyList())); + firstTypeAnnotations.forEach(typeAnnotation -> typeAnnotation.writeTo(buffer)); + buffer.append(ExprProcessor.getCastTypeName(parameterBounds.getFirst(), Collections.emptyList())); for (int j = 1; j < parameterBounds.size(); j++) { buffer.append(" & "); TargetInfo.TypeParameterBoundTarget.extract(typeAnnotations, i, j).forEach(typeAnnotation -> typeAnnotation.writeTo(buffer)); diff --git a/plugins/java-decompiler/engine/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/plugins/java-decompiler/engine/test/org/jetbrains/java/decompiler/SingleClassesTest.java index c4b25e26e5a7..9531ee1e288a 100644 --- a/plugins/java-decompiler/engine/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/plugins/java-decompiler/engine/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -264,4 +264,7 @@ public class SingleClassesTest extends SingleClassesTestBase { "typeAnnotations/A", "typeAnnotations/B", "typeAnnotations/C", "typeAnnotations/D", "typeAnnotations/E", "typeAnnotations/F", "typeAnnotations/Z", "typeAnnotations/P", "typeAnnotations/S", "typeAnnotations/T"); } + @Test public void testAnnotationExtendObjectStaticMethods() { doTest("pkg/TestAnnotationExtendObjectStaticMethods"); } + @Test public void testAnnotationExtendObjectClass() { doTest("pkg/TestAnnotationExtendObjectClass"); } + @Test public void testAnnotationExtendWildcard() { doTest("pkg/TestAnnotationExtendWildcard"); } } \ No newline at end of file diff --git a/plugins/java-decompiler/engine/testData/classes/pkg/TestAnnotationExtendObjectClass.class b/plugins/java-decompiler/engine/testData/classes/pkg/TestAnnotationExtendObjectClass.class new file mode 100644 index 000000000000..bdfeed33e80c Binary files /dev/null and b/plugins/java-decompiler/engine/testData/classes/pkg/TestAnnotationExtendObjectClass.class differ diff --git a/plugins/java-decompiler/engine/testData/classes/pkg/TestAnnotationExtendObjectStaticMethods.class b/plugins/java-decompiler/engine/testData/classes/pkg/TestAnnotationExtendObjectStaticMethods.class new file mode 100644 index 000000000000..155d8a986dc1 Binary files /dev/null and b/plugins/java-decompiler/engine/testData/classes/pkg/TestAnnotationExtendObjectStaticMethods.class differ diff --git a/plugins/java-decompiler/engine/testData/classes/pkg/TestAnnotationExtendWildcard.class b/plugins/java-decompiler/engine/testData/classes/pkg/TestAnnotationExtendWildcard.class new file mode 100644 index 000000000000..ef9f74054a2c Binary files /dev/null and b/plugins/java-decompiler/engine/testData/classes/pkg/TestAnnotationExtendWildcard.class differ diff --git a/plugins/java-decompiler/engine/testData/results/TestAnnotationExtendObjectClass.dec b/plugins/java-decompiler/engine/testData/results/TestAnnotationExtendObjectClass.dec new file mode 100644 index 000000000000..d4ce5ddf01b9 --- /dev/null +++ b/plugins/java-decompiler/engine/testData/results/TestAnnotationExtendObjectClass.dec @@ -0,0 +1,17 @@ +package org.example; + +import org.jetbrains.annotations.Nullable; + +public class TestAnnotationExtendObjectClass { + public static void main(String[] args) { + }// 8 +} + +class 'org/example/TestAnnotationExtendObjectClass' { + method 'main ([Ljava/lang/String;)V' { + 0 6 + } +} + +Lines mapping: +8 <-> 7 diff --git a/plugins/java-decompiler/engine/testData/results/TestAnnotationExtendObjectStaticMethods.dec b/plugins/java-decompiler/engine/testData/results/TestAnnotationExtendObjectStaticMethods.dec new file mode 100644 index 000000000000..33449ea64e8f --- /dev/null +++ b/plugins/java-decompiler/engine/testData/results/TestAnnotationExtendObjectStaticMethods.dec @@ -0,0 +1,25 @@ +package org.example; + +import org.jetbrains.annotations.Nullable; + +public class TestAnnotationExtendObjectStaticMethods { + public static void main(String[] args) { + }// 8 + + public static native Iterable concat(Iterable var0, Iterable var1); + + public static native Iterable concat2(Iterable var0, Iterable var1); + + public static native Iterable concat3(Iterable var0, Iterable var1); + + public static native Iterable concat4(Iterable var0, Iterable var1); +} + +class 'org/example/TestAnnotationExtendObjectStaticMethods' { + method 'main ([Ljava/lang/String;)V' { + 0 6 + } +} + +Lines mapping: +8 <-> 7 diff --git a/plugins/java-decompiler/engine/testData/results/TestAnnotationExtendWildcard.dec b/plugins/java-decompiler/engine/testData/results/TestAnnotationExtendWildcard.dec new file mode 100644 index 000000000000..dfd352f06a45 --- /dev/null +++ b/plugins/java-decompiler/engine/testData/results/TestAnnotationExtendWildcard.dec @@ -0,0 +1,68 @@ +package org.example; + +import java.util.List; +import org.jetbrains.annotations.Nullable; + +public class TestAnnotationExtendWildcard { + public static void main(String[] args) { + }// 10 + + List getA() { + return null;// 13 + } + + List getA5() { + return null;// 17 + } + + List getA3() { + return null;// 21 + } + + List getA2() { + return null;// 25 + } + + List getA4() { + return null;// 29 + } +} + +class 'org/example/TestAnnotationExtendWildcard' { + method 'main ([Ljava/lang/String;)V' { + 0 7 + } + + method 'getA ()Ljava/util/List;' { + 0 10 + 1 10 + } + + method 'getA5 ()Ljava/util/List;' { + 0 14 + 1 14 + } + + method 'getA3 ()Ljava/util/List;' { + 0 18 + 1 18 + } + + method 'getA2 ()Ljava/util/List;' { + 0 22 + 1 22 + } + + method 'getA4 ()Ljava/util/List;' { + 0 26 + 1 26 + } +} + +Lines mapping: +10 <-> 8 +13 <-> 11 +17 <-> 15 +21 <-> 19 +25 <-> 23 +29 <-> 27 diff --git a/plugins/java-decompiler/engine/testData/src/pkg/TestAnnotationExtendObjectClass.java b/plugins/java-decompiler/engine/testData/src/pkg/TestAnnotationExtendObjectClass.java new file mode 100644 index 000000000000..e8aed5aac839 --- /dev/null +++ b/plugins/java-decompiler/engine/testData/src/pkg/TestAnnotationExtendObjectClass.java @@ -0,0 +1,9 @@ +package org.example; + +import org.jetbrains.annotations.Nullable; + +public class TestAnnotationExtendObjectClass { + public static void main(String[] args) { + + } +} \ No newline at end of file diff --git a/plugins/java-decompiler/engine/testData/src/pkg/TestAnnotationExtendObjectStaticMethods.java b/plugins/java-decompiler/engine/testData/src/pkg/TestAnnotationExtendObjectStaticMethods.java new file mode 100644 index 000000000000..1f4f03533634 --- /dev/null +++ b/plugins/java-decompiler/engine/testData/src/pkg/TestAnnotationExtendObjectStaticMethods.java @@ -0,0 +1,13 @@ +package org.example; + +import org.jetbrains.annotations.Nullable; + +public class TestAnnotationExtendObjectStaticMethods { + public static void main(String[] args) { + + } + public static native Iterable concat(Iterable a, Iterable b); + public static native Iterable concat2(Iterable a, Iterable b); + public static native Iterable concat3(Iterable a, Iterable b); + public static native Iterable concat4(Iterable a, Iterable b); +} \ No newline at end of file diff --git a/plugins/java-decompiler/engine/testData/src/pkg/TestAnnotationExtendWildcard.java b/plugins/java-decompiler/engine/testData/src/pkg/TestAnnotationExtendWildcard.java new file mode 100644 index 000000000000..ed44f811f81e --- /dev/null +++ b/plugins/java-decompiler/engine/testData/src/pkg/TestAnnotationExtendWildcard.java @@ -0,0 +1,31 @@ +package org.example; + +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class TestAnnotationExtendWildcard { + public static void main(String[] args) { + + } + + List getA() { + return null; + } + + List getA5() { + return null; + } + + List getA3() { + return null; + } + + List getA2() { + return null; + } + + List getA4() { + return null; + } +} \ No newline at end of file