Skip to content

Commit 43cfd91

Browse files
Option to inform about members of a deprecated type not being deprecated (#4569)
Raise problem for non-private fields, methods, member types of a deprecated type. Do not raise a problem against annotation elements. Problem is raised as info by default, but can be configured to other severity. Fixes #4568
1 parent 52c7b04 commit 43cfd91

File tree

12 files changed

+240
-9
lines changed

12 files changed

+240
-9
lines changed

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/IProblem.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2267,6 +2267,9 @@ public interface IProblem {
22672267
/** @since 3.14 */
22682268
int UsingTerminallyDeprecatedSinceVersionModule = ModuleRelated + 1432;
22692269

2270+
/** @since 3.44 */
2271+
int MemberOfDeprecatedTypeNotDeprecated = TypeRelated + 1433;
2272+
22702273
/** @since 3.14 */
22712274
int NotAccessibleType = TypeRelated + 1450;
22722275
/** @since 3.14 */

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,8 +1261,8 @@ public void resolve() {
12611261
this.scope.problemReporter().validateRestrictedKeywords(this.name, this);
12621262
// resolve annotations and check @Deprecated annotation
12631263
long annotationTagBits = sourceType.getAnnotationTagBits();
1264-
if ((annotationTagBits & TagBits.AnnotationDeprecated) == 0
1265-
&& (sourceType.modifiers & ClassFileConstants.AccDeprecated) != 0) {
1264+
boolean isDeprecated = (annotationTagBits & TagBits.AnnotationDeprecated) != 0;
1265+
if (!isDeprecated && (sourceType.modifiers & ClassFileConstants.AccDeprecated) != 0) {
12661266
this.scope.problemReporter().missingDeprecatedAnnotationForType(this);
12671267
}
12681268
if ((annotationTagBits & TagBits.AnnotationFunctionalInterface) != 0) {
@@ -1395,6 +1395,8 @@ public void resolve() {
13951395
field.javadoc = this.javadoc;
13961396
}
13971397
field.resolve(field.isStatic() ? this.staticInitializerScope : this.initializerScope);
1398+
if (isDeprecated)
1399+
checkMemberOfDeprecated(sourceType, field.binding, field);
13981400
}
13991401
}
14001402
if (this.maxFieldCount < localMaxFieldCount) {
@@ -1457,8 +1459,14 @@ public void resolve() {
14571459
if (this.methods != null) {
14581460
for (AbstractMethodDeclaration method : this.methods) {
14591461
method.resolve(this.scope);
1462+
if (isDeprecated)
1463+
checkMemberOfDeprecated(sourceType, method.binding, method);
14601464
}
14611465
}
1466+
if (this.memberTypes != null && isDeprecated) {
1467+
for (TypeDeclaration member : this.memberTypes)
1468+
checkMemberOfDeprecated(sourceType, member.binding, member);
1469+
}
14621470
// Resolve javadoc
14631471
if (this.javadoc != null) {
14641472
if (this.scope != null && (this.name != TypeConstants.PACKAGE_INFO_NAME)) {
@@ -1499,6 +1507,22 @@ public void resolve() {
14991507
}
15001508
}
15011509

1510+
private void checkMemberOfDeprecated(SourceTypeBinding declaringType, Binding memberBinding, ASTNode memberDeclaration) {
1511+
if (declaringType.isAnnotationType())
1512+
return; // don't suggest to deprecate annotation attributes
1513+
1514+
if (memberBinding instanceof MethodBinding method && method.isPrivate()) return;
1515+
else if (memberBinding instanceof FieldBinding field && field.isPrivate()) return;
1516+
else if (memberBinding instanceof ReferenceBinding type && type.isPrivate()) return;
1517+
1518+
if (memberBinding != null && memberBinding.isValidBinding() && (memberBinding.tagBits & TagBits.HasMissingType) == 0) {
1519+
if (memberDeclaration instanceof ConstructorDeclaration ctor && ctor.isDefaultConstructor())
1520+
return;
1521+
if ((memberBinding.tagBits & TagBits.AnnotationDeprecated) == 0)
1522+
this.scope.problemReporter().memberOfDeprecatedTypeNotDeprecated(memberDeclaration, declaringType);
1523+
}
1524+
}
1525+
15021526
/**
15031527
* Resolve a local type declaration
15041528
*/

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ public class CompilerOptions {
223223
public static final String OPTION_UseStringConcatFactory = "org.eclipse.jdt.core.compiler.codegen.useStringConcatFactory"; //$NON-NLS-1$
224224

225225
public static final String OPTION_validateOperandStack = "org.eclipse.jdt.core.compiler.codegen.validateOperandStack"; //$NON-NLS-1$
226+
227+
public static final String OPTION_MemberOfDeprecatedTypeNotDeprecated = "org.eclipse.jdt.core.compiler.problem.memberOfDeprecatedTypeNotDeprecated"; //$NON-NLS-1$
226228
/**
227229
* Possible values for configurable options
228230
*/
@@ -402,6 +404,7 @@ public class CompilerOptions {
402404
public static final int InsufficientResourceManagement = IrritantSet.GROUP3 | ASTNode.Bit1;
403405
public static final int IncompatibleOwningContract = IrritantSet.GROUP3 | ASTNode.Bit2;
404406
public static final int UnusedLambdaParameter = IrritantSet.GROUP3 | ASTNode.Bit3;
407+
public static final int MemberOfDeprecatedType = IrritantSet.GROUP3 | ASTNode.Bit4;
405408

406409

407410
// Severity level for handlers
@@ -698,6 +701,8 @@ public static String optionKeyFromIrritant(int irritant) {
698701
case UsingTerminallyDeprecatedAPI :
699702
case (InvalidJavadoc | UsingTerminallyDeprecatedAPI) :
700703
return OPTION_ReportTerminalDeprecation;
704+
case MemberOfDeprecatedType :
705+
return OPTION_MemberOfDeprecatedTypeNotDeprecated;
701706
case MaskedCatchBlock :
702707
return OPTION_ReportHiddenCatchBlock;
703708
case UnusedLocalVariable :
@@ -936,7 +941,7 @@ public static long releaseToJDKLevel(String release) {
936941
}
937942
return 0;
938943
}
939-
944+
940945
public static long releaseToJDKLevel(int release) {
941946
int major = release + ClassFileConstants.MAJOR_VERSION_0;
942947
if (major <= ClassFileConstants.MAJOR_LATEST_VERSION) {
@@ -1353,6 +1358,7 @@ public Map<String, String> getMap() {
13531358
optionsMap.put(OPTION_ReportTerminalDeprecation, getSeverityString(UsingTerminallyDeprecatedAPI));
13541359
optionsMap.put(OPTION_ReportDeprecationInDeprecatedCode, this.reportDeprecationInsideDeprecatedCode ? ENABLED : DISABLED);
13551360
optionsMap.put(OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, this.reportDeprecationWhenOverridingDeprecatedMethod ? ENABLED : DISABLED);
1361+
optionsMap.put(OPTION_MemberOfDeprecatedTypeNotDeprecated, getSeverityString(MemberOfDeprecatedType));
13561362
optionsMap.put(OPTION_ReportHiddenCatchBlock, getSeverityString(MaskedCatchBlock));
13571363
optionsMap.put(OPTION_ReportUnusedLocal, getSeverityString(UnusedLocalVariable));
13581364
optionsMap.put(OPTION_ReportUnusedLambdaParameter, getSeverityString(UnusedLambdaParameter));
@@ -1931,6 +1937,7 @@ public void set(Map<String, String> optionsMap) {
19311937
if ((optionValue = optionsMap.get(OPTION_ReportOverridingPackageDefaultMethod)) != null) updateSeverity(OverriddenPackageDefaultMethod, optionValue);
19321938
if ((optionValue = optionsMap.get(OPTION_ReportDeprecation)) != null) updateSeverity(UsingDeprecatedAPI, optionValue);
19331939
if ((optionValue = optionsMap.get(OPTION_ReportTerminalDeprecation)) != null) updateSeverity(UsingTerminallyDeprecatedAPI, optionValue);
1940+
if ((optionValue = optionsMap.get(OPTION_MemberOfDeprecatedTypeNotDeprecated)) != null) updateSeverity(MemberOfDeprecatedType, optionValue);
19341941
if ((optionValue = optionsMap.get(OPTION_ReportHiddenCatchBlock)) != null) updateSeverity(MaskedCatchBlock, optionValue);
19351942
if ((optionValue = optionsMap.get(OPTION_ReportUnusedLocal)) != null) updateSeverity(UnusedLocalVariable, optionValue);
19361943
if ((optionValue = optionsMap.get(OPTION_ReportUnusedLambdaParameter)) != null) updateSeverity(UnusedLambdaParameter, optionValue);

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ public class IrritantSet {
8787
.set(
8888
CompilerOptions.UnlikelyEqualsArgumentType
8989
| CompilerOptions.SuppressWarningsNotAnalysed
90-
| CompilerOptions.AnnotatedTypeArgumentToUnannotated);
90+
| CompilerOptions.AnnotatedTypeArgumentToUnannotated)
91+
// group-3 infos enabled by default
92+
.set(CompilerOptions.MemberOfDeprecatedType);
9193

9294
COMPILER_DEFAULT_WARNINGS
9395
// group-0 warnings enabled by default

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ public static int getIrritant(int problemID) {
203203
case IProblem.UsingTerminallyDeprecatedSinceVersionModule :
204204
return CompilerOptions.UsingTerminallyDeprecatedAPI;
205205

206+
case IProblem.MemberOfDeprecatedTypeNotDeprecated :
207+
return CompilerOptions.MemberOfDeprecatedType;
208+
206209
case IProblem.LocalVariableIsNeverUsed :
207210
return CompilerOptions.UnusedLocalVariable;
208211

@@ -705,6 +708,7 @@ public static int getProblemCategory(int severity, int problemID) {
705708
case CompilerOptions.UnlikelyEqualsArgumentType:
706709
case CompilerOptions.APILeak:
707710
case CompilerOptions.UnstableAutoModuleName:
711+
case CompilerOptions.MemberOfDeprecatedType:
708712
return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM;
709713

710714
case CompilerOptions.OverriddenPackageDefaultMethod :
@@ -1984,6 +1988,13 @@ String deprecatedSinceValue(Supplier<AnnotationBinding[]> annotations) {
19841988
}
19851989
return null;
19861990
}
1991+
public void memberOfDeprecatedTypeNotDeprecated(ASTNode member, ReferenceBinding enclosingType) {
1992+
handle(IProblem.MemberOfDeprecatedTypeNotDeprecated,
1993+
new String[] { String.valueOf(enclosingType.readableName()) },
1994+
new String[] { String.valueOf(enclosingType.shortReadableName()) },
1995+
member.sourceStart,
1996+
member.sourceEnd);
1997+
}
19871998
public void disallowedTargetForAnnotation(Annotation annotation) {
19881999
this.handle(
19892000
IProblem.DisallowedTargetForAnnotation,

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/messages.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,8 @@
990990
1431 = The module {0} has been deprecated and marked for removal
991991
1432 = The module {0} has been deprecated since version {1} and marked for removal
992992

993+
1433 = The enclosing type {0} is deprecated, perhaps this member should be marked as deprecated, too?
994+
993995
1450 = The type {0} is not accessible
994996
1451 = The field {1}.{0} is not accessible
995997
1452 = The method {1}({2}) from the type {0} is not accessible

org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3656,6 +3656,12 @@ public void test119() {
36563656
" Zork z;\n" +
36573657
"}\n",
36583658
},
3659+
"----------\n" +
3660+
"1. INFO in X.java (at line 3)\n" +
3661+
" void foo(){}\n" +
3662+
" ^^^^^\n" +
3663+
"The enclosing type X is deprecated, perhaps this member should be marked as deprecated, too?\n" +
3664+
"----------\n" +
36593665
"----------\n" +
36603666
"1. WARNING in Y.java (at line 1)\n" +
36613667
" public class Y extends X {\n" +
@@ -3667,7 +3673,7 @@ public void test119() {
36673673
" ^^^^^\n" +
36683674
"The method foo() of type Y should be tagged with @Override since it actually overrides a superclass method\n" +
36693675
"----------\n" +
3670-
"4. ERROR in Y.java (at line 3)\n" +
3676+
"3. ERROR in Y.java (at line 3)\n" +
36713677
" Zork z;\n" +
36723678
" ^^^^\n" +
36733679
"Zork cannot be resolved to a type\n" +
@@ -3688,6 +3694,12 @@ public void test120() {
36883694
" Zork z;\n" +
36893695
"}\n",
36903696
},
3697+
"----------\n" +
3698+
"1. INFO in X.java (at line 3)\n" +
3699+
" void foo(){}\n" +
3700+
" ^^^^^\n" +
3701+
"The enclosing type X is deprecated, perhaps this member should be marked as deprecated, too?\n" +
3702+
"----------\n" +
36913703
"----------\n" +
36923704
"1. WARNING in Y.java (at line 1)\n" +
36933705
" public class Y extends X {\n" +
@@ -3888,7 +3900,7 @@ public void test127() {
38883900
"X.java",
38893901
"@Deprecated\n" +
38903902
"public class X {\n" +
3891-
" void foo(){}\n" +
3903+
" @Deprecated void foo(){}\n" +
38923904
"}\n",
38933905
"Y.java",
38943906
"public class Y extends X {\n" +
@@ -4466,7 +4478,7 @@ public void test142() {
44664478
"package p;\n" +
44674479
"@Deprecated\n" +
44684480
"public class OldStuff {\n" +
4469-
" public void foo() {\n" +
4481+
" @Deprecated public void foo() {\n" +
44704482
" } \n" +
44714483
" Zork z;\n" +
44724484
"}\n",
@@ -4505,7 +4517,7 @@ public void test142b() {
45054517
"package p;\n" +
45064518
"@Deprecated\n" +
45074519
"public class OldStuff {\n" +
4508-
" public void foo() {\n" +
4520+
" @Deprecated public void foo() {\n" +
45094521
" } \n" +
45104522
" Zork z;\n" +
45114523
"}\n",
@@ -4562,6 +4574,12 @@ public void test142c() {
45624574
" public class X extends p.OldStuff {\n" +
45634575
" ^^^^^^^^\n" +
45644576
"The type OldStuff is deprecated\n" +
4577+
"----------\n" +
4578+
"----------\n" +
4579+
"1. INFO in p\\OldStuff.java (at line 4)\n" +
4580+
" public void foo() {\n" +
4581+
" ^^^^^\n" +
4582+
"The enclosing type OldStuff is deprecated, perhaps this member should be marked as deprecated, too?\n" +
45654583
"----------\n",
45664584
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
45674585
}
@@ -4579,7 +4597,7 @@ public void test143() {
45794597
"package p;\n" +
45804598
"@Deprecated\n" +
45814599
"public class OldStuff {\n" +
4582-
" public void foo() {\n" +
4600+
" @Deprecated public void foo() {\n" +
45834601
" } \n" +
45844602
" Zork z;\n" +
45854603
"}\n",

org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,7 @@ public void test013() {
10801080
" <option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef\" value=\"disabled\"/>\n" +
10811081
" <option key=\"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility\" value=\"public\"/>\n" +
10821082
" <option key=\"org.eclipse.jdt.core.compiler.problem.localVariableHiding\" value=\"ignore\"/>\n" +
1083+
" <option key=\"org.eclipse.jdt.core.compiler.problem.memberOfDeprecatedTypeNotDeprecated\" value=\"info\"/>\n" +
10831084
" <option key=\"org.eclipse.jdt.core.compiler.problem.methodWithConstructorName\" value=\"warning\"/>\n" +
10841085
" <option key=\"org.eclipse.jdt.core.compiler.problem.missingDefaultCase\" value=\"ignore\"/>\n" +
10851086
" <option key=\"org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation\" value=\"ignore\"/>\n" +

org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,7 @@ class ProblemAttributes {
813813
expectedProblemAttributes.put("MaskedCatch", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
814814
expectedProblemAttributes.put("MandatoryCloseNotShown", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
815815
expectedProblemAttributes.put("MandatoryCloseNotShownAtExit", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
816+
expectedProblemAttributes.put("MemberOfDeprecatedTypeNotDeprecated", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
816817
expectedProblemAttributes.put("MessageSendWithUnresolvedOwningAnnotation", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
817818
expectedProblemAttributes.put("MethodButWithConstructorName", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
818819
expectedProblemAttributes.put("MethodCanBePotentiallyStatic", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
@@ -1964,6 +1965,7 @@ class ProblemAttributes {
19641965
expectedProblemAttributes.put("MaskedCatch", new ProblemAttributes(JavaCore.COMPILER_PB_HIDDEN_CATCH_BLOCK));
19651966
expectedProblemAttributes.put("MandatoryCloseNotShown", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE));
19661967
expectedProblemAttributes.put("MandatoryCloseNotShownAtExit", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE));
1968+
expectedProblemAttributes.put("MemberOfDeprecatedTypeNotDeprecated", new ProblemAttributes(JavaCore.COMPILER_PB_MEMBER_OF_DEPRECATED_TYPE));
19671969
expectedProblemAttributes.put("MessageSendWithUnresolvedOwningAnnotation", SKIP);
19681970
expectedProblemAttributes.put("MethodButWithConstructorName", new ProblemAttributes(JavaCore.COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME));
19691971
expectedProblemAttributes.put("MethodCanBePotentiallyStatic", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_MISSING_STATIC_ON_METHOD));

0 commit comments

Comments
 (0)