Bug 567975 - AssertionFailedException thrown by o.e.ltk.ui.refactoring

- fix ASTRewriteAnalyzer.visit(YieldStatement) to check for an
  implicit yield statement before scanning the file for the end
- add new test to ASTRewritingSwitchExpressionsTest

Change-Id: I38faa5b830f98feb0ca081c52ef7ec80d2efadba
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingSwitchExpressionsTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingSwitchExpressionsTest.java
index 7f86179..cf76e8e 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingSwitchExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingSwitchExpressionsTest.java
@@ -23,6 +23,7 @@
 import org.eclipse.jdt.core.dom.Block;
 import org.eclipse.jdt.core.dom.BreakStatement;
 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.MethodDeclaration;
 import org.eclipse.jdt.core.dom.SimpleName;
@@ -859,4 +860,62 @@
 		builder.append("}\n");
 		assertEqualString(preview, builder.toString());
 	}
+
+	@SuppressWarnings("rawtypes")
+	public void testSwitchExpressions_Bug567975_since_12() throws Exception {
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=567975
+		IPackageFragment pack1= this.sourceFolder.createPackageFragment("test1", false, null);
+		StringBuilder builder= new StringBuilder();
+		builder.append(
+				"package test1;\n" +
+				"public class X {\n" +
+				"    public String foo(int i) {\n" +
+				"		String ret = switch(i) {\n" +
+				"		case 0 -> \"abc\";\n" +
+				"		default -> \"\";\n" +
+				"		};\n" +
+				"		return ret;" +
+				"    }\n" +
+				"}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("X.java", builder.toString(), false, null);
+
+		CompilationUnit astRoot= createAST(cu);
+		ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST());
+
+		assertTrue("Parse errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0);
+		TypeDeclaration type= findTypeDeclaration(astRoot, "X");
+		MethodDeclaration methodDecl= findMethodDeclaration(type, "foo");
+		Block block= methodDecl.getBody();
+		List blockStatements= block.statements();
+		{
+			VariableDeclarationStatement varStatement= (VariableDeclarationStatement) blockStatements.get(0);
+			List fragments = varStatement.fragments();
+			assertEquals("Incorrect no of fragments", 1, fragments.size());
+			VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.get(0);
+			SwitchExpression initializer = (SwitchExpression) fragment.getInitializer();
+			List statements= initializer.statements();
+			assertEquals("incorrect Number of statements", 4, statements.size());
+
+			// replace the implicit yield expression to exercise the fix
+			YieldStatement yieldStmt = (YieldStatement) statements.get(1);
+			Expression exp = yieldStmt.getExpression();
+			ASTNode newLiteral = rewrite.createStringPlaceholder("\"def\"", ASTNode.STRING_LITERAL);
+			rewrite.replace(exp, newLiteral, null);
+		}
+		String preview= evaluateRewrite(cu, rewrite);
+		builder= new StringBuilder();
+		builder.append(
+				"package test1;\n" +
+				"public class X {\n" +
+				"    public String foo(int i) {\n" +
+				"		String ret = switch(i) {\n" +
+				"		case 0 -> \"def\";\n" +
+				"		default -> \"\";\n" +
+				"		};\n" +
+				"		return ret;" +
+				"    }\n" +
+				"}\n");
+		assertEqualString(preview, builder.toString());
+	}
+
 }
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
index 2c0cef0..3ec9c4d 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2020 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -4566,7 +4566,7 @@
 		}
 
 		try {
-			int offset= getScanner().getTokenEndOffset(TerminalTokens.TokenNamebreak, node.getStartPosition());
+			int offset= node.isImplicit() ? node.getStartPosition() : getScanner().getTokenEndOffset(TerminalTokens.TokenNamebreak, node.getStartPosition());
 			if ((node.getAST().apiLevel() >= JLS14_INTERNAL)) {
 				rewriteNode(node, YieldStatement.EXPRESSION_PROPERTY, offset, ASTRewriteFormatter.SPACE); // space between yield and label
 			}