diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index f79198f..cded67e 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -816,7 +816,7 @@ public class ClassWriter { StructAnnDefaultAttribute attr = (StructAnnDefaultAttribute)mt.getAttributes().getWithKey("AnnotationDefault"); if (attr != null) { buffer.append(" default "); - buffer.append(attr.getDefaultValue().toJava(indent + 1, new BytecodeMappingTracer())); // dummy tracer + buffer.append(attr.getDefaultValue().toJava(0, new BytecodeMappingTracer())); // dummy tracer } } @@ -970,7 +970,6 @@ public class ClassWriter { StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS}; private static void appendParameterAnnotations(TextBuffer buffer, StructMethod mt, int param) { - BytecodeMappingTracer tracer_dummy = new BytecodeMappingTracer(); // FIXME: replace with a real one for (String name : PARAMETER_ANNOTATION_ATTRIBUTES) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java index 905bc21..9b797a9 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-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. @@ -24,7 +24,6 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; import java.util.List; public class AnnotationExprent extends Exprent { - public static final int ANNOTATION_NORMAL = 1; public static final int ANNOTATION_MARKER = 2; public static final int ANNOTATION_SINGLE_ELEMENT = 3; @@ -45,12 +44,12 @@ public class AnnotationExprent extends Exprent { TextBuffer buffer = new TextBuffer(); buffer.appendIndent(indent); - buffer.append("@"); + buffer.append('@'); buffer.append(DecompilerContext.getImportCollector().getShortName(ExprProcessor.buildJavaClassName(className))); if (!parNames.isEmpty()) { - buffer.append("("); - if (parNames.size() == 1 && "value".equals(parNames.get(0))) { + buffer.append('('); + if (getAnnotationType() == ANNOTATION_SINGLE_ELEMENT) { buffer.append(parValues.get(0).toJava(indent + 1, tracer)); } else { @@ -58,16 +57,16 @@ public class AnnotationExprent extends Exprent { buffer.appendLineSeparator().appendIndent(indent + 1); buffer.append(parNames.get(i)); buffer.append(" = "); - buffer.append(parValues.get(i).toJava(indent + 2, tracer)); + buffer.append(parValues.get(i).toJava(0, tracer)); if (i < parNames.size() - 1) { - buffer.append(","); + buffer.append(','); } } buffer.appendLineSeparator().appendIndent(indent); } - buffer.append(")"); + buffer.append(')'); } return buffer; @@ -99,4 +98,4 @@ public class AnnotationExprent extends Exprent { InterpreterUtil.equalLists(parNames, ann.parNames) && InterpreterUtil.equalLists(parValues, ann.parValues); } -} +} \ No newline at end of file diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index dd509f6..84434a9 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -83,6 +83,7 @@ public class SingleClassesTest { @Test public void testMethodReferenceSameName() { doTest("pkg/TestMethodReferenceSameName"); } @Test public void testMethodReferenceLetterClass() { doTest("pkg/TestMethodReferenceLetterClass"); } @Test public void testMemberAnnotations() { doTest("pkg/TestMemberAnnotations"); } + @Test public void testMoreAnnotations() { doTest("pkg/MoreAnnotations"); } @Test public void testStaticNameClash() { doTest("pkg/TestStaticNameClash"); } @Test public void testExtendingSubclass() { doTest("pkg/TestExtendingSubclass"); } @Test public void testSyntheticAccess() { doTest("pkg/TestSyntheticAccess"); } diff --git a/testData/classes/pkg/MoreAnnotations$NestedAnnotation.class b/testData/classes/pkg/MoreAnnotations$NestedAnnotation.class new file mode 100644 index 0000000..b4204ad Binary files /dev/null and b/testData/classes/pkg/MoreAnnotations$NestedAnnotation.class differ diff --git a/testData/classes/pkg/MoreAnnotations$TestEnum.class b/testData/classes/pkg/MoreAnnotations$TestEnum.class new file mode 100644 index 0000000..d221ad6 Binary files /dev/null and b/testData/classes/pkg/MoreAnnotations$TestEnum.class differ diff --git a/testData/classes/pkg/MoreAnnotations.class b/testData/classes/pkg/MoreAnnotations.class new file mode 100644 index 0000000..36178de Binary files /dev/null and b/testData/classes/pkg/MoreAnnotations.class differ diff --git a/testData/results/MoreAnnotations.dec b/testData/results/MoreAnnotations.dec new file mode 100644 index 0000000..7ca5d12 --- /dev/null +++ b/testData/results/MoreAnnotations.dec @@ -0,0 +1,107 @@ +package pkg; + +public @interface MoreAnnotations { + @MoreAnnotations( + intValue = 1, + byteValue = 1, + floatValue = 1.0F, + doubleValue = 1.0D, + booleanValue = true, + shortValue = 1, + longValue = 1L, + charValue = '\n', + enumValue = MoreAnnotations.TestEnum.FirstValue, + annotationValue = @MoreAnnotations.NestedAnnotation("a"), + stringValue = "", + classValue = String.class + ) + String annotatedWithValues = ""; + @MoreAnnotations( + intArray = {}, + byteArray = {}, + floatArray = {}, + doubleArray = {}, + booleanArray = {}, + shortArray = {}, + longArray = {}, + charArray = {}, + enumArray = {}, + annotationArray = {}, + stringArray = {}, + classArray = {} + ) + String annotatedWithEmptyArrays = ""; + @MoreAnnotations( + intArray = {1, 0, 2147483647, -2147483648}, + byteArray = {(byte)1, (byte)0, (byte)127, (byte)-128}, + floatArray = {1.0F, 0.0F, 3.4028235E38F, 1.4E-45F, 0.0F / 0.0, 1.0F / 0.0, -1.0F / 0.0}, + doubleArray = {1.0D, 0.0D, 1.7976931348623157E308D, 4.9E-324D, 0.0D / 0.0, 1.0D / 0.0, -1.0D / 0.0}, + booleanArray = {true, false}, + shortArray = {(short)1, (short)0, (short)32767, (short)-32768}, + longArray = {1L, 0L, 9223372036854775807L, -9223372036854775808L}, + charArray = {'a', '\n', '\u0001', '\u0000', '\uffff', '\u0000'}, + enumArray = {MoreAnnotations.TestEnum.FirstValue, MoreAnnotations.TestEnum.SecondValue}, + annotationArray = {@MoreAnnotations.NestedAnnotation("a"), @MoreAnnotations.NestedAnnotation("b")}, + stringArray = {"first", "second", ""}, + classArray = {CharSequence.class, String.class, StringBuilder.class} + ) + String annotatedWithArrays = ""; + + int intValue() default 1; + + byte byteValue() default 1; + + float floatValue() default 1.0F / 0.0; + + double doubleValue() default 0.0D / 0.0; + + boolean booleanValue() default true; + + short shortValue() default 1; + + long longValue() default 1L; + + char charValue() default '0'; + + MoreAnnotations.TestEnum enumValue() default MoreAnnotations.TestEnum.FirstValue; + + MoreAnnotations.NestedAnnotation annotationValue() default @MoreAnnotations.NestedAnnotation; + + String stringValue() default "default"; + + Class classValue() default CharSequence.class; + + int[] intArray() default {1, 0, 2147483647, -2147483648}; + + byte[] byteArray() default {(byte)1, (byte)0, (byte)127, (byte)-128}; + + float[] floatArray() default {1.0F, 0.0F, 3.4028235E38F, 1.4E-45F, 0.0F / 0.0, 1.0F / 0.0, -1.0F / 0.0}; + + double[] doubleArray() default {1.0D, 0.0D, 1.7976931348623157E308D, 4.9E-324D, 0.0D / 0.0, 1.0D / 0.0, -1.0D / 0.0}; + + boolean[] booleanArray() default {true, false}; + + short[] shortArray() default {(short)1, (short)0, (short)32767, (short)-32768}; + + long[] longArray() default {1L, 0L, 9223372036854775807L, -9223372036854775808L}; + + char[] charArray() default {'\u0001', '\u0000', '\uffff', '\u0000'}; + + MoreAnnotations.TestEnum[] enumArray() default {MoreAnnotations.TestEnum.FirstValue}; + + MoreAnnotations.NestedAnnotation[] annotationArray() default {@MoreAnnotations.NestedAnnotation}; + + String[] stringArray() default {"first", "second", ""}; + + Class[] classArray() default {CharSequence.class, String.class, StringBuilder.class}; + + public static enum TestEnum { + FirstValue, + SecondValue; + } + + public @interface NestedAnnotation { + String value() default "MyString"; + } +} + diff --git a/testData/src/pkg/MoreAnnotations.java b/testData/src/pkg/MoreAnnotations.java new file mode 100644 index 0000000..e66835e --- /dev/null +++ b/testData/src/pkg/MoreAnnotations.java @@ -0,0 +1,89 @@ +package pkg; + +public @interface MoreAnnotations { + + int intValue() default 1; + byte byteValue() default 1; + float floatValue() default Float.POSITIVE_INFINITY; + double doubleValue() default Double.NaN; + boolean booleanValue() default true; + short shortValue() default 1; + long longValue() default 1; + char charValue() default '0'; + TestEnum enumValue() default TestEnum.FirstValue; + NestedAnnotation annotationValue() default @NestedAnnotation; + String stringValue() default "default"; + Class classValue() default CharSequence.class; + + int[] intArray() default { 1, 0, Integer.MAX_VALUE, Integer.MIN_VALUE }; + byte[] byteArray() default { 1, 0, Byte.MAX_VALUE, Byte.MIN_VALUE }; + float[] floatArray() default { 1, 0, Float.MAX_VALUE, Float.MIN_VALUE, Float.NaN, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY }; + double[] doubleArray() default { 1, 0, Double.MAX_VALUE, Double.MIN_VALUE, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY }; + boolean[] booleanArray() default { true, false }; + short[] shortArray() default { 1, 0, Short.MAX_VALUE, Short.MIN_VALUE }; + long[] longArray() default { 1, 0, Long.MAX_VALUE, Long.MIN_VALUE }; + char[] charArray() default { 1, 0, Character.MAX_VALUE, Character.MIN_VALUE }; + TestEnum[] enumArray() default { TestEnum.FirstValue }; + NestedAnnotation[] annotationArray() default { @NestedAnnotation }; + String[] stringArray() default { "first", "second", ""}; + Class[] classArray() default { CharSequence.class, String.class, StringBuilder.class }; + + @interface NestedAnnotation { + String value() default "MyString"; + } + + @MoreAnnotations( + intValue = 1, + byteValue = 1, + floatValue = 1, + doubleValue = 1, + booleanValue = true, + shortValue = 1, + longValue = 1, + charValue = '\n', + enumValue = TestEnum.FirstValue, + annotationValue = @NestedAnnotation("a"), + stringValue = "", + classValue = String.class + ) + String annotatedWithValues = ""; + + @MoreAnnotations( + intArray = {}, + byteArray = {}, + floatArray = {}, + doubleArray = {}, + booleanArray = {}, + shortArray = {}, + longArray = {}, + charArray = {}, + enumArray = {}, + annotationArray = {}, + stringArray = {}, + classArray = {} + ) + String annotatedWithEmptyArrays = ""; + + @MoreAnnotations( + intArray = { 1, 0, Integer.MAX_VALUE, Integer.MIN_VALUE }, + byteArray = { 1, 0, Byte.MAX_VALUE, Byte.MIN_VALUE }, + floatArray = { 1, 0, Float.MAX_VALUE, Float.MIN_VALUE, Float.NaN, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY }, + doubleArray = { 1, 0, Double.MAX_VALUE, Double.MIN_VALUE, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY }, + booleanArray = { true, false }, + shortArray = { 1, 0, Short.MAX_VALUE, Short.MIN_VALUE }, + longArray = { 1, 0, Long.MAX_VALUE, Long.MIN_VALUE }, + charArray = { 'a', '\n', 1, 0, Character.MAX_VALUE, Character.MIN_VALUE }, + enumArray = { TestEnum.FirstValue , TestEnum.SecondValue}, + annotationArray = { @NestedAnnotation("a"), @NestedAnnotation("b") }, + stringArray = { "first", "second", ""}, + classArray = { CharSequence.class, String.class, StringBuilder.class } + ) + String annotatedWithArrays = ""; + + public enum TestEnum { + + FirstValue, + SecondValue + + } +}