Bug 572932 - [quickfix] Create foreach expression var as array

Enhance the creation of variable when the variable is the expression on
which a foreach loop iterates.

Given:
for (int number : numbers) {
                  ^^^^^^^
}

When:
Selecting "Create a local variable"

Actual:
Object numbers;
for (int number : numbers) {
}

Expected:
int[] numbers;
for (int number : numbers) {
}

Also fix test method name typo.

Change-Id: Ic61e45c2c34a7dc45c58f6c3562e06d1509b6272
Signed-off-by: Fabrice Tiercelin <fabrice.tiercelin@yahoo.fr>
Reviewed-on: https://git.eclipse.org/r/c/jdt/eclipse.jdt.ui/+/179459
diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/dom/ASTResolving.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/dom/ASTResolving.java
index d7203f1..df987c0 100644
--- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/dom/ASTResolving.java
+++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/core/manipulation/dom/ASTResolving.java
@@ -40,6 +40,7 @@
 import org.eclipse.jdt.core.dom.CompilationUnit;
 import org.eclipse.jdt.core.dom.ConditionalExpression;
 import org.eclipse.jdt.core.dom.ConstructorInvocation;
+import org.eclipse.jdt.core.dom.EnhancedForStatement;
 import org.eclipse.jdt.core.dom.Expression;
 import org.eclipse.jdt.core.dom.FieldAccess;
 import org.eclipse.jdt.core.dom.FieldDeclaration;
@@ -277,6 +278,16 @@
 				return parent.getAST().resolveWellKnownType("boolean"); //$NON-NLS-1$
 			}
 			return parent.getAST().resolveWellKnownType("int"); //$NON-NLS-1$
+		case ASTNode.ENHANCED_FOR_STATEMENT:
+			if (node.getLocationInParent() == EnhancedForStatement.EXPRESSION_PROPERTY) {
+				EnhancedForStatement enhancedForStatement= (EnhancedForStatement) parent;
+				ITypeBinding parameterTypeBinding= enhancedForStatement.getParameter().getType().resolveBinding();
+
+				if (parameterTypeBinding != null) {
+					return parameterTypeBinding.createArrayType(1);
+				}
+			}
+			break;
 		case ASTNode.IF_STATEMENT:
 		case ASTNode.WHILE_STATEMENT:
 		case ASTNode.DO_STATEMENT:
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedVariablesQuickFixTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedVariablesQuickFixTest.java
index c90f468..e3d567c 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedVariablesQuickFixTest.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedVariablesQuickFixTest.java
@@ -19,6 +19,7 @@
 
 import java.util.ArrayList;
 import java.util.Hashtable;
+import java.util.List;
 
 import org.junit.After;
 import org.junit.Before;
@@ -1933,7 +1934,95 @@
 	}
 
 	@Test
-	public void testVarMultipleOccurances1() throws Exception {
+	public void testUndeclaredPrimitiveVariable() throws Exception {
+		IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null);
+		String given= "" //
+				+ "package test1;\n" //
+				+ "\n" //
+				+ "public class E {\n" //
+				+ "    public void foo() {\n" //
+				+ "        for (int number : numbers) {\n" //
+				+ "        }\n" //
+				+ "    }\n" //
+				+ "}\n";
+
+		ICompilationUnit cu= pack.createCompilationUnit("E.java", given, false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		List<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot, 1);
+		assertNumberOfProposals(proposals, 5);
+		assertCorrectLabels(proposals);
+
+		CUCorrectionProposal localProposal= null;
+		for (IJavaCompletionProposal curr : proposals) {
+			if (curr instanceof NewVariableCorrectionProposal && ((NewVariableCorrectionProposal) curr).getVariableKind() == NewVariableCorrectionProposal.LOCAL) {
+				localProposal= (CUCorrectionProposal) curr;
+			}
+		}
+
+		assertNotNull(localProposal);
+
+		String preview= getPreviewContent(localProposal);
+		String expected= "" //
+				+ "package test1;\n" //
+				+ "\n" //
+				+ "public class E {\n" //
+				+ "    public void foo() {\n" //
+				+ "        int[] numbers;\n" //
+				+ "        for (int number : numbers) {\n" //
+				+ "        }\n" //
+				+ "    }\n" //
+				+ "}\n";
+
+		assertEqualString(preview, expected);
+	}
+
+	@Test
+	public void testUndeclaredObjectVariable() throws Exception {
+		IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null);
+		String given= "" //
+				+ "package test1;\n" //
+				+ "\n" //
+				+ "public class E {\n" //
+				+ "    public void foo() {\n" //
+				+ "        for (Integer number : numbers) {\n" //
+				+ "        }\n" //
+				+ "    }\n" //
+				+ "}\n";
+
+		ICompilationUnit cu= pack.createCompilationUnit("E.java", given, false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		List<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot, 1);
+		assertNumberOfProposals(proposals, 5);
+		assertCorrectLabels(proposals);
+
+		CUCorrectionProposal localProposal= null;
+		for (IJavaCompletionProposal curr : proposals) {
+			if (curr instanceof NewVariableCorrectionProposal && ((NewVariableCorrectionProposal) curr).getVariableKind() == NewVariableCorrectionProposal.LOCAL) {
+				localProposal= (CUCorrectionProposal) curr;
+			}
+		}
+
+		assertNotNull(localProposal);
+
+		String preview= getPreviewContent(localProposal);
+		String expected= "" //
+				+ "package test1;\n" //
+				+ "\n" //
+				+ "public class E {\n" //
+				+ "    public void foo() {\n" //
+				+ "        Integer[] numbers;\n" //
+				+ "        for (Integer number : numbers) {\n" //
+				+ "        }\n" //
+				+ "    }\n" //
+				+ "}\n";
+
+		assertEqualString(preview, expected);
+	}
+
+	@Test
+	public void testVarMultipleOccurences1() throws Exception {
 		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
 		StringBuffer buf= new StringBuffer();
 		buf.append("package test1;\n");
@@ -1973,7 +2062,7 @@
 	}
 
 	@Test
-	public void testVarMultipleOccurances2() throws Exception {
+	public void testVarMultipleOccurences2() throws Exception {
 		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
 		StringBuffer buf= new StringBuffer();
 		buf.append("package test1;\n");
@@ -2015,7 +2104,7 @@
 	}
 
 	@Test
-	public void testVarMultipleOccurances3() throws Exception {
+	public void testVarMultipleOccurences3() throws Exception {
 		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
 		StringBuffer buf= new StringBuffer();
 		buf.append("package test1;\n");