From 7cc64b6079d1bff881d3ec4d424d34bf7d26ff5f Mon Sep 17 00:00:00 2001 From: Srikanth Sankaran <131454720+srikanth-sankaran@users.noreply.github.com> Date: Fri, 27 Dec 2024 08:35:23 +0530 Subject: [PATCH] Proper sealing of hierarchy rejected in incremental builds if permitted class is generic (#3490) * Fixes https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3488 --- .../compiler/lookup/BinaryTypeBinding.java | 7 ++- .../core/tests/builder/IncrementalTests.java | 60 ++++++++++++++++++- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java index e5f6ffa46a2..08e20333b9e 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java @@ -245,6 +245,11 @@ public static TypeBinding resolveType(TypeBinding type, LookupEnvironment enviro return type; } +private static TypeBinding resolveType(TypeBinding type, LookupEnvironment environment, boolean convertGenericToRawType, boolean convertRawToGenericType) { + TypeBinding retVal = resolveType(type, environment, convertGenericToRawType); + return convertRawToGenericType ? retVal.actualType() : retVal; +} + /** * Default empty constructor for subclasses only. */ @@ -2552,7 +2557,7 @@ public ReferenceBinding[] permittedTypes() { return this.permittedTypes = this.prototype.permittedTypes(); } for (int i = this.permittedTypes.length; --i >= 0;) - this.permittedTypes[i] = (ReferenceBinding) resolveType(this.permittedTypes[i], this.environment, false); // re-resolution seems harmless + this.permittedTypes[i] = (ReferenceBinding) resolveType(this.permittedTypes[i], this.environment, false, true); // re-resolution seems harmless; while permitted classes/interfaces cannot be parameterized with type arguments, they are not raw either return this.permittedTypes; } diff --git a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java index b6b56c65508..e8156913b02 100644 --- a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java +++ b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java @@ -667,10 +667,10 @@ public void testMemberTypeOfOtherProject() throws JavaModelException { //https://bugs.eclipse.org/bugs/show_bug.cgi?id=377401 public void test$InTypeName() throws JavaModelException { - IPath projectPath1 = env.addProject("Project1", CompilerOptions.getFirstSupportedJavaVersion()); //$NON-NLS-1$ //$NON-NLS-2$ + IPath projectPath1 = env.addProject("Project1", CompilerOptions.getFirstSupportedJavaVersion()); //$NON-NLS-1$ env.addExternalJars(projectPath1, Util.getJavaClassLibs()); - IPath projectPath2 = env.addProject("Project2", CompilerOptions.getFirstSupportedJavaVersion()); //$NON-NLS-1$ //$NON-NLS-2$ + IPath projectPath2 = env.addProject("Project2", CompilerOptions.getFirstSupportedJavaVersion()); //$NON-NLS-1$ env.addExternalJars(projectPath2, Util.getJavaClassLibs()); // remove old package fragment root so that names don't collide @@ -1725,4 +1725,60 @@ static E getE() { env.removeProject(projectPath); } + // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3488 + // [Sealed types] Proper sealing of hierarchy rejected in incremental builds if permitted class is generic + public void testIssue3488() throws JavaModelException { + IPath projectPath = env.addProject("Project", "19"); + env.addExternalJars(projectPath, Util.getJavaClassLibs()); + + // remove old package fragment root so that names don't collide + env.removePackageFragmentRoot(projectPath, ""); + + IPath root = env.addPackageFragmentRoot(projectPath, "src"); + env.setOutputFolder(projectPath, "bin"); + + env.addClass(root, "", "Message", + """ + public sealed abstract class Message permits Request { + public final String id; + + protected Message(String id) { + this.id = id; + } + } + """); + + env.addClass(root, "", "Request", + """ + public final class Request extends Message { // Error here + public final T payload; + + public Request(String id, T payload) { + super(id); + this.payload = payload; + } + } + """); + + fullBuild(projectPath); + expectingNoProblems(); + + env.addClass(root, "", "Request", + """ + public final class Request extends Message { // Error here + public final T payload; + + public Request(String id, T payload) { + super(id); + this.payload = payload; + } + } + """); + + incrementalBuild(projectPath); + expectingNoProblems(); + + env.removeProject(projectPath); + } + }