Bug 576518 - NewClassWizard should throw an error if a final class is
selected as a super class

Change-Id: I82cd27decb458d8d7ea220ebc82ac1fe0683570a
Signed-off-by: Kalyan Prasad Tatavarthi <kalyan_prasad@in.ibm.com>
Reviewed-on: https://git.eclipse.org/r/c/jdt/eclipse.jdt.ui/+/186451
Tested-by: JDT Bot <jdt-bot@eclipse.org>
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/wizardapi/NewTypeWizardTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/wizardapi/NewTypeWizardTest.java
index 09223d7..712421b 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/wizardapi/NewTypeWizardTest.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/wizardapi/NewTypeWizardTest.java
@@ -17,6 +17,8 @@
 package org.eclipse.jdt.ui.tests.wizardapi;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import java.util.ArrayList;
 import java.util.Hashtable;
@@ -31,6 +33,8 @@
 import org.eclipse.jdt.testplugin.StringAsserts;
 import org.eclipse.jdt.testplugin.TestOptions;
 
+import org.eclipse.core.runtime.IStatus;
+
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.viewers.StructuredSelection;
 
@@ -43,10 +47,16 @@
 import org.eclipse.jdt.core.IPackageFragment;
 import org.eclipse.jdt.core.IPackageFragmentRoot;
 import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.ITypeBinding;
 import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
 
 import org.eclipse.jdt.internal.core.manipulation.CodeTemplateContextType;
 import org.eclipse.jdt.internal.core.manipulation.StubUtility;
+import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving;
+import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels;
+import org.eclipse.jdt.internal.corext.util.Messages;
 
 import org.eclipse.jdt.ui.PreferenceConstants;
 import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup;
@@ -58,6 +68,7 @@
 
 import org.eclipse.jdt.internal.ui.JavaPlugin;
 import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
+import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
 
 /**
  *
@@ -797,4 +808,48 @@
 		String actual= wizardPage.getCreatedType().getCompilationUnit().getElementName();
 		assertEquals("Foo3.java", actual);
 	}
+
+	@Test
+	public void testAddFinalSuperClassError1() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		String test= "" +
+				"package test1;\n" +
+				"\n" +
+				"public final class A{\n" +
+				"}\n";
+		ICompilationUnit superClsUnit= pack1.createCompilationUnit("A.java", test, false, null);
+		ITypeBinding superCls= getTypeBinding(superClsUnit);
+
+		NewClassWizardPage wizardPage= new NewClassWizardPage();
+		wizardPage.setPackageFragmentRoot(fSourceFolder, true);
+		wizardPage.setPackageFragment(pack1, true);
+		wizardPage.setTypeName("E", true);
+		wizardPage.setSuperClass(superCls, true);
+
+		List<String> interfaces= new ArrayList<>();
+		wizardPage.setSuperInterfaces(interfaces, true);
+
+		wizardPage.setAddComments(true, true);
+		wizardPage.enableCommentControl(true);
+
+		String sclassName= wizardPage.getSuperClass();
+		String expected= Messages.format(NewWizardMessages.NewTypeWizardPage_error_InvalidFinalSuperClass, BasicElementLabels.getJavaElementName(sclassName));
+
+		IStatus status= wizardPage.getSuperClassStatus();
+		assertNotNull(status);
+		assertTrue(status.getSeverity() == IStatus.ERROR);
+		assertTrue(expected.equals(status.getMessage()));
+	}
+
+	private static ITypeBinding getTypeBinding(ICompilationUnit cu) {
+		CompilationUnit compUnit= ASTResolving.createQuickFixAST(cu, null);
+		ITypeBinding tBinding= null;
+		if (compUnit != null) {
+			Object typeDecl= compUnit.types().get(0);
+			if (typeDecl instanceof AbstractTypeDeclaration) {
+				tBinding= ((AbstractTypeDeclaration) typeDecl).resolveBinding();
+			}
+		}
+		return tBinding;
+	}
 }
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/wizardapi/NewTypeWizardTest17.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/wizardapi/NewTypeWizardTest17.java
index ea63e10..1e6cddf 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/wizardapi/NewTypeWizardTest17.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/wizardapi/NewTypeWizardTest17.java
@@ -1188,7 +1188,7 @@
 		return ASTResolving.createQuickFixAST(cu, null);
 	}
 
-	public static ITypeBinding getTypeBinding(ICompilationUnit cu) {
+	private static ITypeBinding getTypeBinding(ICompilationUnit cu) {
 		CompilationUnit compUnit= ASTResolving.createQuickFixAST(cu, null);
 		ITypeBinding tBinding= null;
 		if (compUnit != null) {
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/wizards/NewWizardMessages.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/wizards/NewWizardMessages.java
index f9d67c2..d8cf5e6 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/wizards/NewWizardMessages.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/wizards/NewWizardMessages.java
@@ -160,6 +160,7 @@
 	public static String NewTypeWizardPage_error_TypeParameters;
 	public static String NewTypeWizardPage_error_InvalidSuperClassName;
 	public static String NewTypeWizardPage_error_InvalidSuperClassRecord;
+	public static String NewTypeWizardPage_error_InvalidFinalSuperClass;
 	public static String NewTypeWizardPage_error_SuperClassNotParameterized;
 	public static String NewTypeWizardPage_error_InvalidSuperInterfaceName;
 	public static String NewTypeWizardPage_error_SuperInterfaceNotParameterized;
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/wizards/NewWizardMessages.properties b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/wizards/NewWizardMessages.properties
index bef0012..52e00d0 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/wizards/NewWizardMessages.properties
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/wizards/NewWizardMessages.properties
@@ -145,7 +145,8 @@
 NewTypeWizardPage_error_SuperClassNotParameterized=Superclass cannot be parameterized unless source level is 1.5.
 NewTypeWizardPage_error_InvalidSuperInterfaceName=Extended interface ''{0}'' is not valid.
 NewTypeWizardPage_error_SuperInterfaceNotParameterized=Extended interface ''{0}'' cannot be parameterized unless source level is 1.5.
-NewTypeWizardPage_error_InvalidSuperClassRecord=Record ''{0}'' cannot be superclass. A record is final.  
+NewTypeWizardPage_error_InvalidSuperClassRecord=Record ''{0}'' cannot be superclass. A record is final.
+NewTypeWizardPage_error_InvalidFinalSuperClass=Class ''{0}'' cannot be superclass as it is final.  
 
 NewTypeWizardPage_error_SealedFinalNonSealedClass_extend_superclass_notSelected_message=Class extending a sealed superclass should be a sealed or final or non-sealed class.
 NewTypeWizardPage_error_class_SealedSuperClassInDifferentModule=Sealed superclass should be in the same module as the new class, in a modular project.
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/wizards/NewTypeWizardPage.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/wizards/NewTypeWizardPage.java
index 15c3c06..a7f371b 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/wizards/NewTypeWizardPage.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/wizards/NewTypeWizardPage.java
@@ -1664,7 +1664,7 @@
 	 * Sets the super class name.
 	 *
 	 * @param type the binding of superclass
-	 * @param canBeModified if <code>true</code> the superclass name field is editable; 
+	 * @param canBeModified if <code>true</code> the superclass name field is editable;
 	 * otherwise it is read-only.
 	 * @since 3.25
 	 */
@@ -2186,6 +2186,12 @@
 				if (fSuperClass.isRecord()) {
 					status.setError(Messages.format(NewWizardMessages.NewTypeWizardPage_error_InvalidSuperClassRecord, BasicElementLabels.getJavaElementName(sclassName)));
 					return status;
+				} else {
+					int flags= fSuperClass.getFlags();
+					if (Flags.isFinal(flags)) {
+						status.setError(Messages.format(NewWizardMessages.NewTypeWizardPage_error_InvalidFinalSuperClass, BasicElementLabels.getJavaElementName(sclassName)));
+						return status;
+					}
 				}
 			} catch (JavaModelException e) {
 				//do nothing