Bug 572571 - Error messages appear out of nowhere

- Added instanceof check before cast to IVariableBinding
- Fix better handling of parameterized Type with default constructor
- Add new test case

Change-Id: I2cb7881ebca7cfa1c1f0fa24bd17c0794a061915
Signed-off-by: Kenneth Styrberg <kenneth@kean.nu>
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest.java
index 2828441..6b78b05 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest.java
@@ -2887,6 +2887,76 @@
 	}
 
 	@Test
+	public void testUninitializedField_12() throws Exception {
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=572571
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E<T> {\n");
+		buf.append("    final Class<Integer> i1;\n");
+		buf.append("    final Class<? extends Class<Integer>> i2;\n");
+		buf.append("    final E<String> e;\n");
+		buf.append("    final E<T> et;\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		IProblem[] problems= astRoot.getProblems();
+
+		List<ICompletionProposal> proposals= collectAllCorrections(cu, astRoot, problems.length);
+		assertNumberOfProposals(proposals, problems.length);
+		assertCorrectLabels(proposals);
+
+		String[] previews = new String[proposals.size()];
+		for (int i= 0; i < proposals.size(); i++) {
+			previews[i] =  getPreviewContent((CUCorrectionProposal)proposals.get(i));
+		}
+		String[] expected = new String[previews.length];
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E<T> {\n");
+		buf.append("    final Class<Integer> i1 = new Class<Integer>();\n");
+		buf.append("    final Class<? extends Class<Integer>> i2;\n");
+		buf.append("    final E<String> e;\n");
+		buf.append("    final E<T> et;\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E<T> {\n");
+		buf.append("    final Class<Integer> i1;\n");
+		buf.append("    final Class<? extends Class<Integer>> i2 = new Class<? extends Class<Integer>>();\n");
+		buf.append("    final E<String> e;\n");
+		buf.append("    final E<T> et;\n");
+		buf.append("}\n");
+		expected[1]= buf.toString();
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E<T> {\n");
+		buf.append("    final Class<Integer> i1;\n");
+		buf.append("    final Class<? extends Class<Integer>> i2;\n");
+		buf.append("    final E<String> e = new E<String>();\n");
+		buf.append("    final E<T> et;\n");
+		buf.append("}\n");
+		expected[2]= buf.toString();
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E<T> {\n");
+		buf.append("    final Class<Integer> i1;\n");
+		buf.append("    final Class<? extends Class<Integer>> i2;\n");
+		buf.append("    final E<String> e;\n");
+		buf.append("    final E<T> et = new E<T>();\n");
+		buf.append("}\n");
+		expected[3]= buf.toString();
+
+		assertEqualStringsIgnoreOrder(previews, expected);
+	}
+
+	@Test
 	public void testUnimplementedMethods() throws Exception {
 		IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null);
 		StringBuffer buf= new StringBuffer();
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/InitializeFinalFieldProposal.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/InitializeFinalFieldProposal.java
index b70b6e7..24cdf2a 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/InitializeFinalFieldProposal.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/InitializeFinalFieldProposal.java
@@ -27,6 +27,7 @@
 import org.eclipse.jdt.core.dom.Assignment;
 import org.eclipse.jdt.core.dom.Block;
 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
+import org.eclipse.jdt.core.dom.CompilationUnit;
 import org.eclipse.jdt.core.dom.Expression;
 import org.eclipse.jdt.core.dom.ExpressionStatement;
 import org.eclipse.jdt.core.dom.FieldAccess;
@@ -41,12 +42,11 @@
 import org.eclipse.jdt.core.dom.PrimitiveType;
 import org.eclipse.jdt.core.dom.RecordDeclaration;
 import org.eclipse.jdt.core.dom.SimpleName;
-import org.eclipse.jdt.core.dom.SimpleType;
 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
 import org.eclipse.jdt.core.dom.Type;
 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
-import org.eclipse.jdt.core.dom.WildcardType;
 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
 
 import org.eclipse.jdt.internal.core.manipulation.StubUtility;
 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
@@ -145,17 +145,17 @@
 			declaration.setType(ast.newSimpleType(ast.newName(variableTypeName)));
 			expression= ast.newStringLiteral();
 		} else {
+			Type newType= null;
 			if (type.isParameterizedType()) {
-				Type newType= createParameterizedType(ast, type);
-				declaration.setType(newType);
+				newType= createParameterizedType(ast, type);
 			} else {
-				SimpleType newSimpleType= ast.newSimpleType(ast.newName(variableTypeName));
-				declaration.setType(newSimpleType);
+				newType= ast.newSimpleType(ast.newName(variableTypeName));
 			}
+			declaration.setType(newType);
 
 			if (hasDefaultConstructor()) {
 				ClassInstanceCreation cic= ast.newClassInstanceCreation();
-				cic.setType(ast.newSimpleType(ast.newName(variableTypeName)));
+				cic.setType((Type) ASTNode.copySubtree(ast, newType));
 				expression= cic;
 			} else {
 				expression= ast.newNullLiteral();
@@ -182,10 +182,8 @@
 		} else {
 			if (!typeBinding.isTypeVariable()) {
 				if (typeBinding.isWildcardType()) {
-					String newName= typeBinding.getBound().getName();
-					WildcardType newWildcardType= ast.newWildcardType();
-					newWildcardType.setBound(ast.newSimpleType(ast.newSimpleName(newName)), typeBinding.isUpperbound());
-					return newWildcardType;
+					ImportRewrite importRewrite= createImportRewrite((CompilationUnit) fAstNode.getRoot());
+					return importRewrite.addImport(typeBinding, ast);
 				}
 				return ast.newSimpleType(ASTNodeFactory.newName(ast, typeBinding.getErasure().getName()));
 			}
@@ -463,7 +461,7 @@
 					ASTNode assignNode= ASTNodes.getFirstAncestorOrNull(node, Assignment.class);
 					if (assignNode != null) {
 						IBinding resolveBinding= node.resolveBinding();
-						if (resolveBinding != null
+						if (resolveBinding instanceof IVariableBinding
 								&& ((IVariableBinding) resolveBinding).isField()
 								&& resolveBinding.getKind() == IBinding.VARIABLE
 								&& finalFieldList.contains(node.getIdentifier())) {