diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java index bbe0ba5..23ff4c1 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -47,7 +47,7 @@ // Static initializer to specify tests subset using TESTS_* static variables // All specified tests which do not belong to the class are skipped... static { -// TESTS_NAMES = new String[] { "test293" }; +// TESTS_NAMES = new String[] { "testBug365437" }; // TESTS_NUMBERS = new int[] { 297 }; // TESTS_RANGE = new int[] { 294, -1 }; } @@ -10148,4 +10148,135 @@ "Bla cannot be resolved to a type\n" + "----------\n"); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=365437 +public void testBug365437a() { + Map customOptions = getCompilerOptions(); + customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); + String exclusionAnnotations = + "p1.PreDestroy," + + "p1.PostConstruct"; + customOptions.put(CompilerOptions.OPTION_AnnotationsToExemptUnusedMethods, exclusionAnnotations); + String testFiles [] = new String[] { + "p/A.java", + "package p;\n" + + "import p1.*;\n" + + "public class A {\n" + + " @p1.PreDestroy\n" + + " private void foo1(){}\n" + + " @PreDestroy\n" + + " private void foo2(){}\n" + + " @p1.PostConstruct\n" + + " private void foo1a(){}\n" + + " @PostConstruct\n" + + " private void foo2a(){}\n" + + " private void foo3(){}" + + "}\n", + "p1/PreDestroy.java", + "package p1;\n" + + "public @interface PreDestroy{}", + "p1/PostConstruct.java", + "package p1;\n" + + "public @interface PostConstruct{}" + }; + String expectedErrorString = + "----------\n" + + "1. ERROR in p\\A.java (at line 12)\n" + + " private void foo3(){}}\n" + + " ^^^^^^\n" + + "The method foo3() from the type A is never used locally\n" + + "----------\n"; + runNegativeTest( + true, + testFiles, + null, + customOptions, + expectedErrorString, + JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=365437 +public void testBug365437b() { + Map customOptions = getCompilerOptions(); + customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); + String exclusionAnnotations = + "javax.annotation.PreDestroy," + + "javax.annotation.Resource"; + customOptions.put(CompilerOptions.OPTION_AnnotationsToExemptUnusedMethods, exclusionAnnotations); + String testFiles [] = new String[] { + "A.java", + "import javax.annotation.*;\n" + + "public class A {\n" + + " @javax.annotation.PreDestroy\n" + + " private void foo1(){}\n" + + " @PreDestroy\n" + + " private void foo2(){}\n" + + " @javax.annotation.Resource\n" + + " private void foo1a(){}\n" + + " @Resource\n" + + " private void foo2a(){}\n" + + " @javax.annotation.PostConstruct\n" + + " private void foo3(){}\n" + + " @javax.annotation.PostConstruct\n" + + " @Resource\n" + + " private void foo3a(){}" + + "}\n" + }; + String expectedErrorString = + "----------\n" + + "1. ERROR in A.java (at line 12)\n" + + " private void foo3(){}\n" + + " ^^^^^^\n" + + "The method foo3() from the type A is never used locally\n" + + "----------\n"; + runNegativeTest( + true, + testFiles, + null, + customOptions, + expectedErrorString, + JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=365437 +// test defaults +public void testBug365437c() { + Map customOptions = getCompilerOptions(); + customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); + String testFiles [] = new String[] { + "A.java", + "import javax.annotation.*;\n" + + "public class A {\n" + + " @javax.annotation.PreDestroy\n" + + " private void foo1(){}\n" + + " @PreDestroy\n" + + " private void foo2(){}\n" + + " @javax.annotation.Resource\n" + + " private void foo1a(){}\n" + + " @Resource\n" + + " private void foo2a(){}\n" + + " @javax.annotation.PostConstruct\n" + + " private void foo3(){}\n" + + " @javax.annotation.PostConstruct\n" + + " @Resource\n" + + " private void foo3a(){}" + + "}\n" + }; + String expectedErrorString = + "----------\n" + + "1. ERROR in A.java (at line 8)\n" + + " private void foo1a(){}\n" + + " ^^^^^^^\n" + + "The method foo1a() from the type A is never used locally\n" + + "----------\n" + + "2. ERROR in A.java (at line 10)\n" + + " private void foo2a(){}\n" + + " ^^^^^^^\n" + + "The method foo2a() from the type A is never used locally\n" + + "----------\n"; + runNegativeTest( + true, + testFiles, + null, + customOptions, + expectedErrorString, + JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); +} } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java index 3e46fd6..e310dbd 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -52,7 +52,7 @@ private static final Main MAIN = new Main(null/*outWriter*/, null/*errWriter*/, false/*systemExit*/, null/*options*/, null/*progress*/); static { -// TESTS_NAMES = new String[] { "test295_warn_options" }; +// TESTS_NAMES = new String[] { "test311_warn_options" }; // TESTS_NUMBERS = new int[] { 306 }; // TESTS_RANGE = new int[] { 298, -1 }; } @@ -1668,7 +1668,7 @@ " allDeprecation deprecation including inside deprecated code\n" + " allJavadoc invalid or missing javadoc\n" + " allOver-ann all missing @Override annotations\n" + - " all-static-method all method can be declared as static warnings\n" + + " all-static-method all method can be declared as static warnings\n" + " assertIdentifier + ''assert'' used as identifier\n" + " boxing autoboxing conversion\n" + " charConcat + char[] in String concat\n" + @@ -1722,7 +1722,7 @@ " syntheticAccess synthetic access for innerclass\n" + " tasks() tasks identified by tags inside comments\n" + " typeHiding + type parameter hiding another type\n" + - " unavoidableGenericProblems + ignore unavoidable type safety problems\n" + + " unavoidableGenericProblems + ignore unavoidable type safety problems\n" + " due to raw APIs\n" + " unchecked + unchecked type operation\n" + " unnecessaryElse unnecessary else clause\n" + @@ -1736,6 +1736,7 @@ " unusedLabel + unused label\n" + " unusedLocal + unread local variable\n" + " unusedPrivate + unused private member declaration\n" + + " unusedPrivateExempt() annotations mark method used\n" + " unusedThrown unused declared thrown exception\n" + " unusedTypeArgs + unused type arguments for method and constructor\n" + " uselessTypeCheck unnecessary cast/instanceof operation\n" + @@ -1800,11 +1801,11 @@ " \n" + " \n" + " \n" + - " \n" + " NORMALIZED SECTION\n" + " \n" + @@ -12352,4 +12354,43 @@ "1 problem (1 warning)", true); } + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=365437 +// test batch compiler option to specify annotations to exclude private methods +// from unused warning +public void test311_warn_options() { + String testFiles [] = new String[] { + "A.java", + "import javax.annotation.*;\n" + + "public class A {\n" + + " @javax.annotation.PreDestroy\n" + + " private void foo1(){}\n" + + " @PreDestroy\n" + + " private void foo2(){}\n" + + " @javax.annotation.Resource\n" + + " private void foo1a(){}\n" + + " @Resource\n" + + " private void foo2a(){}\n" + + " @javax.annotation.PostConstruct\n" + + " private void foo3(){}\n" + + " @javax.annotation.PostConstruct\n" + + " @Resource\n" + + " private void foo3a(){}" + + "}\n" + }; + runConformTest( + testFiles, + "\"" + OUTPUT_DIR + File.separator + "A.java\"" + + " -sourcepath \"" + OUTPUT_DIR + "\"" + + " -warn:unusedPrivateExempt(javax.annotation.PreDestroy|javax.annotation.Resource) -1.5 -proc:none -d \"" + OUTPUT_DIR + "\"", + "", + "----------\n" + + "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/A.java (at line 12)\n" + + " private void foo3(){}\n" + + " ^^^^^^\n" + + "The method foo3() from the type A is never used locally\n" + + "----------\n" + + "1 problem (1 warning)", + true); +} } diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java index a67f3cc..d853288 100644 --- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java +++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -3535,6 +3535,23 @@ } else if (token.equals("unusedPrivate")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnusedPrivateMember, severity, isEnabling); return; + } else if (token.startsWith("unusedPrivateExempt")) { //$NON-NLS-1$ + String unusedWarningExcludingAnnotations = Util.EMPTY_STRING; + int start = token.indexOf('('); + int end = token.indexOf(')'); + if (start >= 0 && end >= 0 && start < end){ + unusedWarningExcludingAnnotations = token.substring(start+1, end).trim(); + unusedWarningExcludingAnnotations = unusedWarningExcludingAnnotations.replace('|',','); + } + if (unusedWarningExcludingAnnotations.length() == 0){ + throw new IllegalArgumentException(this.bind("configure.invalidUnusedPrivateExempt", token)); //$NON-NLS-1$ + } + this.options.put( + CompilerOptions.OPTION_AnnotationsToExemptUnusedMethods, + isEnabling ? unusedWarningExcludingAnnotations : Util.EMPTY_STRING); + + setSeverity(CompilerOptions.OPTION_ReportUnusedPrivateMember, severity, isEnabling); + return; } else if (token.equals("unusedLabel")) { //$NON-NLS-1$ setSeverity(CompilerOptions.OPTION_ReportUnusedLabel, severity, isEnabling); return; diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties index 6985fe3..0871d0b 100644 --- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties +++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties @@ -82,6 +82,7 @@ configure.unsupportedEncoding = unsupported encoding format: {0} configure.duplicateDefaultEncoding = duplicate default encoding format specification: {0} configure.invalidTaskTag ={0} is an invalid task tag +configure.invalidUnusedPrivateExempt = fully qualified annotation type names expected configure.incorrectExtDirsEntry = incorrect ext dir entry; {0} must be a directory configure.incorrectEndorsedDirsEntry = incorrect endorsed dir entry; {0} must be a directory configure.duplicateEndorsedDirs = duplicate endorseddirs specification: {0} @@ -340,6 +341,7 @@ \ unusedLabel + unused label\n\ \ unusedLocal + unread local variable\n\ \ unusedPrivate + unused private member declaration\n\ +\ unusedPrivateExempt() annotations mark method used\n\ \ unusedThrown unused declared thrown exception\n\ \ unusedTypeArgs + unused type arguments for method and constructor\n\ \ uselessTypeCheck unnecessary cast/instanceof operation\n\ diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java index bc76ad7..28496da 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -168,11 +168,8 @@ case TypeIds.T_JavaLangInvokeMethodHandlePolymorphicSignature : tagBits |= TagBits.AnnotationPolymorphicSignature; break; - case TypeIds.T_JavaxAnnotationPostConstruct : - tagBits |= TagBits.AnnotationPostConstruct; - break; - case TypeIds.T_JavaxAnnotationPreDestroy : - tagBits |= TagBits.AnnotationPreDestroy; + case TypeIds.T_UnusedWarningExclusionAnnotation : + tagBits |= TagBits.AnnotationToExcludeUnusedWarning; break; case TypeIds.T_ConfiguredAnnotationNullable : tagBits |= TagBits.AnnotationNullable; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationInfo.java index 3357d7d..d81ec1c 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationInfo.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationInfo.java @@ -303,10 +303,6 @@ currentOffset += 2; return readTargetValue(currentOffset); } - if (CharOperation.equals(typeName, ConstantPool.JAVAX_ANNOTATION_PREDESTROY)) { - this.standardAnnotationTagBits |= TagBits.AnnotationPreDestroy; - return currentOffset; - } break; case 32: if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_RETENTION)) { @@ -315,10 +311,6 @@ } if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_INHERITED)) { this.standardAnnotationTagBits |= TagBits.AnnotationInherited; - return currentOffset; - } - if (CharOperation.equals(typeName, ConstantPool.JAVAX_ANNOTATION_POSTCONSTRUCT)) { - this.standardAnnotationTagBits |= TagBits.AnnotationPostConstruct; return currentOffset; } break; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java index c875c9b..c449385 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -248,8 +248,6 @@ public static final char[] JAVA_LANG_SAFEVARARGS = "Ljava/lang/SafeVarargs;".toCharArray(); //$NON-NLS-1$ // java 7 java.lang.invoke.MethodHandle.invokeExact(..)/invokeGeneric(..) public static final char[] JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE = "Ljava/lang/invoke/MethodHandle$PolymorphicSignature;".toCharArray(); //$NON-NLS-1$ - public static final char[] JAVAX_ANNOTATION_POSTCONSTRUCT = "Ljavax/annotation/PostConstruct;".toCharArray(); //$NON-NLS-1$ - public static final char[] JAVAX_ANNOTATION_PREDESTROY = "Ljavax/annotation/PreDestroy;".toCharArray(); //$NON-NLS-1$ public static final char[] HashCode = "hashCode".toCharArray(); //$NON-NLS-1$ public static final char[] HashCodeSignature = "()I".toCharArray(); //$NON-NLS-1$; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java index bd0c98d..1357a55 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -157,6 +157,8 @@ static final char[][] DEFAULT_NONNULL_ANNOTATION_NAME = CharOperation.splitOn('.', "org.eclipse.jdt.annotation.NonNull".toCharArray()); //$NON-NLS-1$ static final char[][] DEFAULT_NONNULLBYDEFAULT_ANNOTATION_NAME = CharOperation.splitOn('.', "org.eclipse.jdt.annotation.NonNullByDefault".toCharArray()); //$NON-NLS-1$ public static final String OPTION_NonNullIsDefault = "org.eclipse.jdt.core.compiler.annotation.nonnullisdefault"; //$NON-NLS-1$ + + public static final String OPTION_AnnotationsToExemptUnusedMethods = "org.eclipse.jdt.core.compiler.problem.annotationsToExemptUnusedPrivateMethods"; //$NON-NLS-1$ /** * Possible values for configurable options */ @@ -388,6 +390,8 @@ public boolean includeNullInfoFromAsserts; /** Controls whether forced generic type problems get reported */ public boolean reportUnavoidableGenericTypeProblems; + /** Private methods tagged with these annotation types will not be reported as unused */ + public char[][] annotationsToExcludeUnusedMethods; // === Support for Null Annotations: === /** Master switch for null analysis based on annotations: */ @@ -780,7 +784,8 @@ OPTION_ReportNullSpecViolation, OPTION_ReportPotentialNullSpecViolation, OPTION_ReportNullSpecInsufficientInfo, - OPTION_ReportRedundantNullAnnotation + OPTION_ReportRedundantNullAnnotation, + OPTION_AnnotationsToExemptUnusedMethods }; return result; } @@ -1072,6 +1077,7 @@ optionsMap.put(OPTION_NullableAnnotationName, String.valueOf(CharOperation.concatWith(this.nullableAnnotationName, '.'))); optionsMap.put(OPTION_NonNullAnnotationName, String.valueOf(CharOperation.concatWith(this.nonNullAnnotationName, '.'))); optionsMap.put(OPTION_NonNullByDefaultAnnotationName, String.valueOf(CharOperation.concatWith(this.nonNullByDefaultAnnotationName, '.'))); + optionsMap.put(OPTION_AnnotationsToExemptUnusedMethods, this.annotationsToExcludeUnusedMethods == null ? Util.EMPTY_STRING : new String(CharOperation.concatWith(this.annotationsToExcludeUnusedMethods,','))); if (this.defaultNonNullness == TagBits.AnnotationNonNull) optionsMap.put(OPTION_NonNullIsDefault, CompilerOptions.ENABLED); else @@ -1232,6 +1238,11 @@ this.nonNullAnnotationName = DEFAULT_NONNULL_ANNOTATION_NAME; this.nonNullByDefaultAnnotationName = DEFAULT_NONNULLBYDEFAULT_ANNOTATION_NAME; this.defaultNonNullness = 0; + + this.annotationsToExcludeUnusedMethods = new char[][] { + "javax.annotation.PreDestroy".toCharArray(), //$NON-NLS-1$ + "javax.annotation.PostConstruct".toCharArray() //$NON-NLS-1$ + }; } public void set(Map optionsMap) { @@ -1548,6 +1559,17 @@ this.defaultNonNullness = 0; } } + + if ((optionValue = optionsMap.get(OPTION_AnnotationsToExemptUnusedMethods)) != null) { + if (optionValue instanceof String) { + String stringValue = (String) optionValue; + if (stringValue.length() == 0) { + this.annotationsToExcludeUnusedMethods = null; + } else { + this.annotationsToExcludeUnusedMethods = CharOperation.splitAndTrimOn(',', stringValue.toCharArray()); + } + } + } // Javadoc options if ((optionValue = optionsMap.get(OPTION_DocCommentSupport)) != null) { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java index c88c4a1..26fe58b 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -54,10 +54,6 @@ count++; if ((annotationTagBits & TagBits.AnnotationSafeVarargs) != 0) count++; - if ((annotationTagBits & TagBits.AnnotationPostConstruct) != 0) - count++; - if ((annotationTagBits & TagBits.AnnotationPreDestroy) != 0) - count++; // count must be different from 0 int index = recordedAnnotations.length; @@ -81,10 +77,6 @@ result[index++] = buildMarkerAnnotationForMemberType(TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE, env); if ((annotationTagBits & TagBits.AnnotationSafeVarargs) != 0) result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_SAFEVARARGS, env); - if ((annotationTagBits & TagBits.AnnotationPostConstruct) != 0) - result[index++] = buildMarkerAnnotation(TypeConstants.JAVAX_ANNOTATION_POSTCONSTRUCT, env); - if ((annotationTagBits & TagBits.AnnotationPreDestroy) != 0) - result[index++] = buildMarkerAnnotation(TypeConstants.JAVAX_ANNOTATION_PREDESTROY, env); return result; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java index 4a1bad4..645c5a4 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -147,7 +147,7 @@ */ public BinaryTypeBinding(PackageBinding packageBinding, IBinaryType binaryType, LookupEnvironment environment) { this.compoundName = CharOperation.splitOn('/', binaryType.getName()); - computeId(); + computeId(environment); this.tagBits |= TagBits.IsBinaryBinding; this.environment = environment; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java index 0b48bbb..d5d6388 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -1080,6 +1080,10 @@ return packageBinding.getType0(compoundName[compoundName.length - 1]); } +public char[][] getUnusedWarningExclusionAnnotations() { + return this.globalOptions.annotationsToExcludeUnusedMethods; +} + public char[][] getNullableAnnotationName() { return this.globalOptions.nullableAnnotationName; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MissingTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MissingTypeBinding.java index 8b86d8c..0138868 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MissingTypeBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MissingTypeBinding.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -26,7 +26,7 @@ */ public MissingTypeBinding(PackageBinding packageBinding, char[][] compoundName, LookupEnvironment environment) { this.compoundName = compoundName; - computeId(); + computeId(environment); this.tagBits |= TagBits.IsBinaryBinding | TagBits.HierarchyHasProblems | TagBits.HasMissingType; this.environment = environment; this.fPackage = packageBinding; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java index 75de854..c2203a3 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -17,8 +17,10 @@ import java.util.Comparator; import org.eclipse.jdt.core.compiler.CharOperation; +import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; +import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; /* @@ -375,33 +377,28 @@ return result; } -public void computeId() { +public void computeId(LookupEnvironment env) { + char[][] unusedWarningExclusionAnnotations = env.getUnusedWarningExclusionAnnotations(); + if (env.problemReporter.computeSeverity(IProblem.UnusedPrivateMethod) != ProblemSeverities.Ignore + && unusedWarningExclusionAnnotations != null) { + int len = unusedWarningExclusionAnnotations.length; + for (int i = 0; i < len; i++) { + if (CharOperation.equals(CharOperation.concatWith(this.compoundName,'.'), unusedWarningExclusionAnnotations[i])) + this.id = TypeIds.T_UnusedWarningExclusionAnnotation; + } + } // try to avoid multiple checks against a package/type name switch (this.compoundName.length) { case 3 : - if (!CharOperation.equals(TypeConstants.JAVA, this.compoundName[0]) - && !CharOperation.equals(TypeConstants.JAVAX, this.compoundName[0])) + if (!CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) return; char[] packageName = this.compoundName[1]; if (packageName.length == 0) return; // just to be safe char[] typeName = this.compoundName[2]; if (typeName.length == 0) return; // just to be safe - // remaining types MUST be in java.*.* - if (CharOperation.equals(TypeConstants.JAVAX, this.compoundName[0])) { - if (CharOperation.equals(TypeConstants.ANNOTATION, this.compoundName[1])) { - switch (typeName[0]) { - case 'P' : - if (CharOperation.equals(typeName, TypeConstants.JAVAX_ANNOTATION_POSTCONSTRUCT[2])) - this.id = TypeIds.T_JavaxAnnotationPostConstruct; - if (CharOperation.equals(typeName, TypeConstants.JAVAX_ANNOTATION_PREDESTROY[2])) - this.id = TypeIds.T_JavaxAnnotationPreDestroy; - return; - } - } - return; - } + if (!CharOperation.equals(TypeConstants.LANG, this.compoundName[1])) { switch (packageName[0]) { case 'i' : diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java index e96a1f9..81430c0 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -72,7 +72,7 @@ this.fields = Binding.UNINITIALIZED_FIELDS; this.methods = Binding.UNINITIALIZED_METHODS; - computeId(); + computeId(scope.environment()); } private void addDefaultAbstractMethods() { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java index 9ba6da0..7579cab 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -130,9 +130,7 @@ /** @since 3.7 - java 7 MethodHandle.invokeExact(..)/invokeGeneric(..)*/ long AnnotationPolymorphicSignature = ASTNode.Bit53L; /** @since 3.8 */ - long AnnotationPreDestroy = ASTNode.Bit54L; - /** @since 3.8 */ - long AnnotationPostConstruct = ASTNode.Bit55L; + long AnnotationToExcludeUnusedWarning = ASTNode.Bit54L; /** @since 3.8 null annotation for MethodBinding or LocalVariableBinding (argument): */ long AnnotationNullable = ASTNode.Bit56L; /** @since 3.8 null annotation for MethodBinding or LocalVariableBinding (argument): */ @@ -152,8 +150,7 @@ | AnnotationSuppressWarnings | AnnotationSafeVarargs | AnnotationPolymorphicSignature - | AnnotationPostConstruct - | AnnotationPreDestroy + | AnnotationToExcludeUnusedWarning | AnnotationNullable | AnnotationNonNull | AnnotationNonNullByDefault diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java index 0bbef47..7098d37 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -177,18 +177,6 @@ char[] SYNTHETIC_ACCESS_METHOD_PREFIX = "access$".toCharArray(); //$NON-NLS-1$ char[] SYNTHETIC_ENUM_CONSTANT_INITIALIZATION_METHOD_PREFIX = " enum constant initialization$".toCharArray(); //$NON-NLS-1$ char[] SYNTHETIC_STATIC_FACTORY = "".toCharArray(); //$NON-NLS-1$ - char[][] JAVAX_ANNOTATION_POSTCONSTRUCT = - new char[][] { - JAVAX, - ANNOTATION, - "PostConstruct".toCharArray() //$NON-NLS-1$ - }; - char[][] JAVAX_ANNOTATION_PREDESTROY = - new char[][] { - JAVAX, - ANNOTATION, - "PreDestroy".toCharArray() //$NON-NLS-1$ - }; // synthetic package-info name public static final char[] PACKAGE_INFO_NAME = "package-info".toCharArray(); //$NON-NLS-1$ diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java index 7fff434..742e562 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -102,14 +102,12 @@ final int T_JavaLangAutoCloseable = 62; // new in 3.8 - final int T_JavaxAnnotationPostConstruct = 63; - - final int T_JavaxAnnotationPreDestroy = 64; + final int T_UnusedWarningExclusionAnnotation = 63; // new in 3.8 for null annotations: - final int T_ConfiguredAnnotationNullable = 65; - final int T_ConfiguredAnnotationNonNull = 66; - final int T_ConfiguredAnnotationNonNullByDefault = 67; + final int T_ConfiguredAnnotationNullable = 64; + final int T_ConfiguredAnnotationNonNull = 65; + final int T_ConfiguredAnnotationNonNullByDefault = 66; final int NoId = Integer.MAX_VALUE; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java index 9b83933..b6dcd47 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7691,8 +7691,9 @@ && CharOperation.equals(method.selector, TypeConstants.WRITEREPLACE)) { return; } - if ((method.tagBits & (TagBits.AnnotationPostConstruct | TagBits.AnnotationPreDestroy)) != 0) { - // PostConstruct and PreDestroy method are ignored + + if ((method.tagBits & TagBits.AnnotationToExcludeUnusedWarning) != 0) { + // method tagged with annotation that excludes the method from unused warning return; } this.handle( diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java index 5898902..80565e3 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -624,6 +624,19 @@ */ public static final String COMPILER_PB_UNUSED_PRIVATE_MEMBER = PLUGIN_ID + ".compiler.problem.unusedPrivateMember"; //$NON-NLS-1$ /** + * Compiler option ID: Annotations that exempt a private method from being reported as unused. + *

When the {@link #COMPILER_PB_UNUSED_PRIVATE_MEMBER} is enabled, the compiler will not report + * private methods that are declared with these annotations, even if the method is otherwise unused. + *

+ *
Option id:
"org.eclipse.jdt.core.compiler.problem.annotationsToExemptUnusedPrivateMethods"
+ *
Possible values:
Fully qualified annotation type names
+ *
Default:
javax.annotation.PreDestroy, javax.annotation.PostConstruct
+ *
+ * @since 3.8 + * @category CompilerOptionID + */ + public static final String COMPILER_ANNOTATIONS_TO_EXEMPT_UNUSED_PRIVATE_METHOD = PLUGIN_ID + ".compiler.problem.annotationsToExemptUnusedPrivateMethods"; //$NON-NLS-1$ + /** * Compiler option ID: Reporting Local Variable Declaration Hiding another Variable. *

When enabled, the compiler will issue an error or a warning whenever a local variable * declaration is hiding some field or local variable (either locally, inherited or defined in enclosing type). diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMember.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMember.java index 94e6db1..3f6d742 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMember.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMember.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -86,12 +86,6 @@ } if ((tagBits & TagBits.AnnotationSafeVarargs) != 0) { annotations.add(getAnnotation(TypeConstants.JAVA_LANG_SAFEVARARGS)); - } - if ((tagBits & TagBits.AnnotationPostConstruct) != 0) { - annotations.add(getAnnotation(TypeConstants.JAVAX_ANNOTATION_POSTCONSTRUCT)); - } - if ((tagBits & TagBits.AnnotationPreDestroy) != 0) { - annotations.add(getAnnotation(TypeConstants.JAVAX_ANNOTATION_PREDESTROY)); } // note that JAVA_LANG_SUPPRESSWARNINGS and JAVA_LANG_OVERRIDE cannot appear in binaries return (IAnnotation[]) annotations.toArray(new IAnnotation[annotations.size()]); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java index bcf7ceb..e1714a0 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -107,12 +107,6 @@ } if ((tagBits & TagBits.AnnotationSafeVarargs) != 0) { generateStandardAnnotation(javaElement, TypeConstants.JAVA_LANG_SAFEVARARGS, Annotation.NO_MEMBER_VALUE_PAIRS, newElements); - } - if ((tagBits & TagBits.AnnotationPostConstruct) != 0) { - generateStandardAnnotation(javaElement, TypeConstants.JAVAX_ANNOTATION_POSTCONSTRUCT, Annotation.NO_MEMBER_VALUE_PAIRS, newElements); - } - if ((tagBits & TagBits.AnnotationPreDestroy) != 0) { - generateStandardAnnotation(javaElement, TypeConstants.JAVAX_ANNOTATION_PREDESTROY, Annotation.NO_MEMBER_VALUE_PAIRS, newElements); } // note that JAVA_LANG_SUPPRESSWARNINGS and JAVA_LANG_OVERRIDE cannot appear in binaries } diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java index c242fb5..a2bdfe3 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -83,14 +83,6 @@ if ((annotationTagBits & TagBits.AnnotationPolymorphicSignature) != 0) { char[][] compoundName = TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE; - addAnnotationTypeReference(compoundName[compoundName.length-1]); - } - if ((annotationTagBits & TagBits.AnnotationPostConstruct) != 0) { - char[][] compoundName = TypeConstants.JAVAX_ANNOTATION_POSTCONSTRUCT; - addAnnotationTypeReference(compoundName[compoundName.length-1]); - } - if ((annotationTagBits & TagBits.AnnotationPreDestroy) != 0) { - char[][] compoundName = TypeConstants.JAVAX_ANNOTATION_PREDESTROY; addAnnotationTypeReference(compoundName[compoundName.length-1]); } } diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java index 37608aa..0c55837 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -142,18 +142,6 @@ } if ((annotationTagBits & TagBits.AnnotationPolymorphicSignature) != 0) { char[][] compoundName = TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE; - if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) { - return true; - } - } - if ((annotationTagBits & TagBits.AnnotationPostConstruct) != 0) { - char[][] compoundName = TypeConstants.JAVAX_ANNOTATION_POSTCONSTRUCT; - if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) { - return true; - } - } - if ((annotationTagBits & TagBits.AnnotationPreDestroy) != 0) { - char[][] compoundName = TypeConstants.JAVAX_ANNOTATION_PREDESTROY; if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) { return true; }