From f0b1b9ece051373f02d644c3af4db8bf2a490500 Mon Sep 17 00:00:00 2001 From: Stephan Herrmann Date: Tue, 24 Sep 2024 23:58:39 +0200 Subject: [PATCH] Test uniqueness of problem IDs (#1754) - exclude deprecated constants (from pre Java 5 time / 2004) - mark deprecation using annotation (was not possible in 2004) Fixes https://bugs.eclipse.org/bugs/show_bug.cgi?id=509643. --- .../eclipse/jdt/core/compiler/IProblem.java | 35 +++++++++++++++++++ .../regression/CompilerInvocationTests.java | 30 ++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/IProblem.java index 84aae3af827..84ed1618b9a 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/IProblem.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/IProblem.java @@ -835,25 +835,35 @@ public interface IProblem { int IllegalModifierCombinationForType = TypeRelated + 334; /** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */ + @Deprecated int SuperclassNotFound = TypeRelated + 329 + ProblemReasons.NotFound; // TypeRelated + 330 /** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */ + @Deprecated int SuperclassNotVisible = TypeRelated + 329 + ProblemReasons.NotVisible; // TypeRelated + 331 /** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */ + @Deprecated int SuperclassAmbiguous = TypeRelated + 329 + ProblemReasons.Ambiguous; // TypeRelated + 332 /** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */ + @Deprecated int SuperclassInternalNameProvided = TypeRelated + 329 + ProblemReasons.InternalNameProvided; // TypeRelated + 333 /** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */ + @Deprecated int SuperclassInheritedNameHidesEnclosingName = TypeRelated + 329 + ProblemReasons.InheritedNameHidesEnclosingName; // TypeRelated + 334 /** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */ + @Deprecated int InterfaceNotFound = TypeRelated + 334 + ProblemReasons.NotFound; // TypeRelated + 335 /** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */ + @Deprecated int InterfaceNotVisible = TypeRelated + 334 + ProblemReasons.NotVisible; // TypeRelated + 336 /** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */ + @Deprecated int InterfaceAmbiguous = TypeRelated + 334 + ProblemReasons.Ambiguous; // TypeRelated + 337 /** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */ + @Deprecated int InterfaceInternalNameProvided = TypeRelated + 334 + ProblemReasons.InternalNameProvided; // TypeRelated + 338 /** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */ + @Deprecated int InterfaceInheritedNameHidesEnclosingName = TypeRelated + 334 + ProblemReasons.InheritedNameHidesEnclosingName; // TypeRelated + 339 // field related problems @@ -890,8 +900,10 @@ public interface IProblem { int AbstractMethodInAbstractClass = MethodRelated + 363; int ArgumentTypeCannotBeVoid = MethodRelated + 364; /** @deprecated - problem is no longer generated, use {@link #CannotAllocateVoidArray} instead */ + @Deprecated int ArgumentTypeCannotBeVoidArray = MethodRelated + 365; /** @deprecated - problem is no longer generated, use {@link #CannotAllocateVoidArray} instead */ + @Deprecated int ReturnTypeCannotBeVoidArray = MethodRelated + 366; int NativeMethodsCannotBeStrictfp = MethodRelated + 367; int DuplicateModifierForArgument = MethodRelated + 368; @@ -899,36 +911,51 @@ public interface IProblem { int IllegalModifierForConstructor = MethodRelated + 369; /** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */ + @Deprecated int ArgumentTypeNotFound = MethodRelated + 369 + ProblemReasons.NotFound; // MethodRelated + 370 /** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */ + @Deprecated int ArgumentTypeNotVisible = MethodRelated + 369 + ProblemReasons.NotVisible; // MethodRelated + 371 /** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */ + @Deprecated int ArgumentTypeAmbiguous = MethodRelated + 369 + ProblemReasons.Ambiguous; // MethodRelated + 372 /** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */ + @Deprecated int ArgumentTypeInternalNameProvided = MethodRelated + 369 + ProblemReasons.InternalNameProvided; // MethodRelated + 373 /** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */ + @Deprecated int ArgumentTypeInheritedNameHidesEnclosingName = MethodRelated + 369 + ProblemReasons.InheritedNameHidesEnclosingName; // MethodRelated + 374 /** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */ + @Deprecated int ExceptionTypeNotFound = MethodRelated + 374 + ProblemReasons.NotFound; // MethodRelated + 375 /** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */ + @Deprecated int ExceptionTypeNotVisible = MethodRelated + 374 + ProblemReasons.NotVisible; // MethodRelated + 376 /** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */ + @Deprecated int ExceptionTypeAmbiguous = MethodRelated + 374 + ProblemReasons.Ambiguous; // MethodRelated + 377 /** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */ + @Deprecated int ExceptionTypeInternalNameProvided = MethodRelated + 374 + ProblemReasons.InternalNameProvided; // MethodRelated + 378 /** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */ + @Deprecated int ExceptionTypeInheritedNameHidesEnclosingName = MethodRelated + 374 + ProblemReasons.InheritedNameHidesEnclosingName; // MethodRelated + 379 /** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */ + @Deprecated int ReturnTypeNotFound = MethodRelated + 379 + ProblemReasons.NotFound; // MethodRelated + 380 /** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */ + @Deprecated int ReturnTypeNotVisible = MethodRelated + 379 + ProblemReasons.NotVisible; // MethodRelated + 381 /** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */ + @Deprecated int ReturnTypeAmbiguous = MethodRelated + 379 + ProblemReasons.Ambiguous; // MethodRelated + 382 /** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */ + @Deprecated int ReturnTypeInternalNameProvided = MethodRelated + 379 + ProblemReasons.InternalNameProvided; // MethodRelated + 383 /** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */ + @Deprecated int ReturnTypeInheritedNameHidesEnclosingName = MethodRelated + 379 + ProblemReasons.InheritedNameHidesEnclosingName; // MethodRelated + 384 // import related problems @@ -939,12 +966,16 @@ public interface IProblem { int ImportNotFound = ImportRelated + 389 + ProblemReasons.NotFound; // ImportRelated + 390 /** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */ + @Deprecated int ImportNotVisible = ImportRelated + 389 + ProblemReasons.NotVisible; // ImportRelated + 391 /** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */ + @Deprecated int ImportAmbiguous = ImportRelated + 389 + ProblemReasons.Ambiguous; // ImportRelated + 392 /** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */ + @Deprecated int ImportInternalNameProvided = ImportRelated + 389 + ProblemReasons.InternalNameProvided; // ImportRelated + 393 /** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */ + @Deprecated int ImportInheritedNameHidesEnclosingName = ImportRelated + 389 + ProblemReasons.InheritedNameHidesEnclosingName; // ImportRelated + 394 /** @since 3.1 */ @@ -954,10 +985,13 @@ public interface IProblem { int DuplicateModifierForVariable = MethodRelated + 395; int IllegalModifierForVariable = MethodRelated + 396; /** @deprecated - problem is no longer generated, use {@link #RedundantNullCheckOnNonNullLocalVariable} instead */ + @Deprecated int LocalVariableCannotBeNull = Internal + 397; // since 3.3: semantics are LocalVariableRedundantCheckOnNonNull /** @deprecated - problem is no longer generated, use {@link #NullLocalVariableReference}, {@link #RedundantNullCheckOnNullLocalVariable} or {@link #RedundantLocalVariableNullAssignment} instead */ + @Deprecated int LocalVariableCanOnlyBeNull = Internal + 398; // since 3.3: split with LocalVariableRedundantCheckOnNull depending on context /** @deprecated - problem is no longer generated, use {@link #PotentialNullLocalVariableReference} instead */ + @Deprecated int LocalVariableMayBeNull = Internal + 399; // method verifier problems @@ -1755,6 +1789,7 @@ public interface IProblem { int DuplicateBoundInIntersectionCast = TypeRelated + 894; /** @deprecated This problem is no longer reported; number Of functional interface is not an issue, number of abstract methods is. * @since 3.10 */ + @Deprecated int MultipleFunctionalInterfaces = TypeRelated + 895; /** @since 3.10 */ int StaticInterfaceMethodNotBelow18 = Internal + Syntax + 896; diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java index 3a3af4f2ddd..fd08e6915e2 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java @@ -50,11 +50,15 @@ *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; +import java.lang.annotation.Annotation; import java.lang.reflect.Field; +import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import junit.framework.Test; @@ -2552,4 +2556,30 @@ public int compare(Object o1, Object o2) { fail("could not access members"); } } + public void testuniqueIDs() throws IllegalArgumentException, IllegalAccessException { + Field[] fields = IProblem.class.getFields(); + Map> id2names = new HashMap<>(); + for (int i = 0, length = fields.length; i < length; i++) { + Field field = fields[i]; + if (field.getType() == Integer.TYPE && !isDeprecated(field)) { + int problemId = field.getInt(null); + List names = id2names.computeIfAbsent(problemId, k -> new ArrayList<>()); + names.add(field.getName()); + } + } + String duplicates = id2names.entrySet().stream() + .filter(e -> e.getValue().size() > 1) + .map(e -> e.getKey().toString()+": "+e.getValue().toString()) + .collect(Collectors.joining(", ")); + if (!duplicates.isEmpty()) + fail("The following problem IDs are used more than once: "+duplicates); + } + + private boolean isDeprecated(Field field) { + for (Annotation annotation : field.getAnnotations()) { + if (annotation.annotationType() == Deprecated.class) + return true; + } + return false; + } } \ No newline at end of file