Bug 571272 - Surround with try-with-resources may add extraneous catch

- add check in SurroundWithTryWithResourcesAnalyzer so must rethrow
  exceptions are not duplicated
- add new tests to AssistQuickFixTest1d8 and
  SurroundWithResourcesTests1d8

Change-Id: I8f8de46b86ebed318ba779742faa893033fa4901
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_in/TestWithThrows3.java b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_in/TestWithThrows3.java
new file mode 100644
index 0000000..e402e69
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_in/TestWithThrows3.java
@@ -0,0 +1,16 @@
+package trycatch18_in;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+
+class TestWithThrows3 {
+	public FileInputStream foo(int a) throws FileNotFoundException {
+		try {
+			/*[*/FileInputStream f = new FileInputStream("a.b");
+			return f;/*]*/
+		} catch (FileNotFoundException e) {
+			// do nothing
+		}
+		return null;
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestWithThrows3.java b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestWithThrows3.java
new file mode 100644
index 0000000..3c4c1d7
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestWithThrows3.java
@@ -0,0 +1,21 @@
+package trycatch18_in;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+class TestWithThrows3 {
+	public FileInputStream foo(int a) throws FileNotFoundException {
+		try {
+			try (/*[*/ FileInputStream f = new FileInputStream("a.b")) {
+				return f;/*]*/
+			} catch (FileNotFoundException e) {
+				throw e;
+			} catch (IOException e) {
+			}
+		} catch (FileNotFoundException e) {
+			// do nothing
+		}
+		return null;
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/SurroundWithResourcesTests1d8.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/SurroundWithResourcesTests1d8.java
index 0956650..915cd6a 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/SurroundWithResourcesTests1d8.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/SurroundWithResourcesTests1d8.java
@@ -120,6 +120,11 @@
 	}
 
 	@Test
+	public void testWithThrows3() throws Exception {
+		tryResourcesTest();
+	}
+
+	@Test
 	public void testInvalidStatement1() throws Exception {
 		tryResourcesInvalidTest();
 	}
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest1d8.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest1d8.java
index 217150b..0e77ee1 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest1d8.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest1d8.java
@@ -5826,6 +5826,79 @@
 		assertCorrectLabels(proposals);
 	}
 	@Test
+	public void testSurroundWithTryWithResource_04() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null);
+		StringBuffer bufOrg= new StringBuffer();
+		bufOrg.append("package p;\n");
+		bufOrg.append("\n");
+		bufOrg.append("import java.io.FileInputStream;\n");
+		bufOrg.append("import java.io.FileNotFoundException;\n");
+		bufOrg.append("import java.io.InputStream;\n");
+		bufOrg.append("import java.net.Socket;\n");
+		bufOrg.append("\n");
+		bufOrg.append("public class E {\n");
+		bufOrg.append("    public void foo() throws FileNotFoundException {\n");
+		bufOrg.append("        try {\n");
+		bufOrg.append("            /*1*/Socket s = new Socket(), s2 = new Socket();\n");
+		bufOrg.append("            /*2*/InputStream is = s.getInputStream();\n");
+		bufOrg.append("            /*3*/FileInputStream f = new FileInputStream(\"a.b\");\n");
+		bufOrg.append("            /*4*/int i = 0;\n");
+		bufOrg.append("            System.out.println(s.getInetAddress().toString());\n");
+		bufOrg.append("            System.out.println(is.markSupported());/*0*/\n");
+		bufOrg.append("        } catch (FileNotFoundException e) {\n");
+		bufOrg.append("        }\n");
+		bufOrg.append("    }\n");
+		bufOrg.append("}\n");
+		bufOrg.append("\n");
+
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", bufOrg.toString(), false, null);
+		String strEnd= "/*0*/";
+
+		String str1= "/*1*/";
+		AssistContext context= getCorrectionContext(cu, bufOrg.toString().indexOf(str1), bufOrg.toString().indexOf(strEnd) - bufOrg.toString().indexOf(str1));
+		List<IJavaCompletionProposal> proposals= collectAssists(context, false);
+
+		assertCorrectLabels(proposals);
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
+		String preview1= getPreviewContent(proposal);
+
+		StringBuffer buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("import java.io.InputStream;\n");
+		buf.append("import java.net.Socket;\n");
+		buf.append("\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() throws FileNotFoundException {\n");
+		buf.append("        try {\n");
+		buf.append("            try (/*1*/Socket s = new Socket();\n");
+		buf.append("                    Socket s2 = new Socket();\n");
+		buf.append("                    /*2*/InputStream is = s.getInputStream();\n");
+		buf.append("                    /*3*/FileInputStream f = new FileInputStream(\"a.b\")) {\n");
+		buf.append("                /*4*/int i = 0;\n");
+		buf.append("                System.out.println(s.getInetAddress().toString());\n");
+		buf.append("                System.out.println(is.markSupported());/*0*/\n");
+		buf.append("            } catch (FileNotFoundException e) {\n");
+		buf.append("                throw e;\n");
+		buf.append("            } catch (IOException e) {\n");
+		buf.append("                // TODO Auto-generated catch block\n");
+		buf.append("                e.printStackTrace();\n");
+		buf.append("            }\n");
+		buf.append("        } catch (FileNotFoundException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		buf.append("\n");
+		String expected1= buf.toString();
+
+		assertEqualStringsIgnoreOrder(new String[] { preview1 }, new String[] { expected1 });
+		assertCorrectLabels(proposals);
+	}
+	@Test
 	public void testWrapInOptional_01() throws Exception {
 		IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null);
 		StringBuffer buf= new StringBuffer();
@@ -6091,5 +6164,59 @@
 		assertExpectedExistInProposals(proposals, new String[] { expected });
 	}
 
+	@Test
+	public void testAssignInTryWithResources_04() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		String src=
+				"package test1;\n" +
+				"\n" +
+				"import java.io.FileInputStream;\n" +
+				"import java.io.FileNotFoundException;\n" +
+				"\n" +
+				"class E {\n" +
+				"    void f() throws FileNotFoundException {\n" +
+				"        try {\n" +
+				"            new FileInputStream(\"f\");\n" +
+				"        } catch (FileNotFoundException e) {\n" +
+				"            // some action\n" +
+				"        }\n" +
+				"    }\n" +
+				"}";
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", src, false, null);
+
+		int offset= src.indexOf("new");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		List<IJavaCompletionProposal> proposals= collectAssists(context, false);
+
+		assertNumberOfProposals(proposals, 6);
+		assertCorrectLabels(proposals);
+
+		String expected=
+				"package test1;\n" +
+				"\n" +
+				"import java.io.FileInputStream;\n" +
+				"import java.io.FileNotFoundException;\n" +
+				"import java.io.IOException;\n" +
+				"\n" +
+				"class E {\n" +
+				"    void f() throws FileNotFoundException {\n" +
+				"        try {\n" +
+				"            try (FileInputStream fileInputStream = new FileInputStream(\"f\")) {\n" +
+				"                \n" +
+				"            } catch (FileNotFoundException e) {\n" +
+				"                throw e;\n" +
+				"            } catch (IOException e) {\n" +
+	            "                // TODO Auto-generated catch block\n" +
+				"                e.printStackTrace();\n" +
+				"            };\n" +
+				"        } catch (FileNotFoundException e) {\n" +
+				"            // some action\n" +
+				"        }\n" +
+				"    }\n" +
+				"}";
+
+		assertExpectedExistInProposals(proposals, new String[] { expected });
+	}
+
 }
 
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesAnalyzer.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesAnalyzer.java
index bee6a31..b5f0443 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesAnalyzer.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesAnalyzer.java
@@ -170,7 +170,8 @@
 		for (ITypeBinding binding : exceptionList) {
 			for (ITypeBinding thrownException : thrownExceptions) {
 				if (thrownException.isAssignmentCompatible(binding)) {
-					mustRethrowList.add(thrownException);
+					if (!mustRethrowList.contains(thrownException))
+						mustRethrowList.add(thrownException);
 					break;
 				}
 			}