Bug 564766 - [14] Code Clean Up: ClassCastException

Change-Id: I8a5ccbecf8cac4efa8dd701bf785a50e11bff7e3
Signed-off-by: Jay Arthanareeswaran <jarthana@in.ibm.com>
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter14Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter14Test.java
index 82deb0e..2e78416 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter14Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter14Test.java
@@ -979,5 +979,53 @@
 			javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
 		}
 	}
-
+	// Test the code with error doesn't cause a CCE and
+	// produces a decent recovered AST
+	public void testBug564766() throws JavaModelException {
+		if (!isJRE14) {
+			System.err.println("Test "+getName()+" requires a JRE 14");
+			return;
+		}
+		String contents =
+				"record Foo(int y) {\n" +
+				"    record Bar(int x) {\n" +
+				"        public Bar {\n" +
+				"            c(a.b);\n" +
+				"        }\n" +
+				"    }\n" +
+				"    enum Letter { \n" +
+				"        A\n" +
+				"        private Letter { }\n" +
+				"    }\n" +
+				"}";
+		this.workingCopy = getWorkingCopy("/Converter14/src/Foo.java", true/*resolve*/);
+		IJavaProject javaProject = this.workingCopy.getJavaProject();
+		String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);
+		try {
+			javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+			javaProject.setOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+			ASTNode node = buildAST(
+					contents,
+					this.workingCopy,
+					false);
+			assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
+			CompilationUnit compilationUnit = (CompilationUnit) node;
+			assertProblemsSize(compilationUnit, 3,
+					"a cannot be resolved to a variable\n" +
+					"Syntax error on token \"A\", invalid Modifiers\n" +
+					"Illegal modifier for the enum constant Letter; no modifier is allowed");
+			List types = compilationUnit.types();
+			assertEquals("incorrect child elements", 1, types.size());
+			RecordDeclaration rec = (RecordDeclaration) types.get(0);
+			List bodyDeclarations = rec.bodyDeclarations();
+			assertEquals("Incorrect child elements", 2, bodyDeclarations.size());
+			node = (ASTNode) bodyDeclarations.get(0);
+			assertEquals("Not a compilation unit", ASTNode.RECORD_DECLARATION, node.getNodeType());
+			node = (ASTNode) bodyDeclarations.get(1);
+			assertEquals("Not a compilation unit", ASTNode.ENUM_DECLARATION, node.getNodeType());
+			assertTrue("must be marked as malformed", ((node.getFlags() & ASTNode.MALFORMED) != 0));
+		} finally {
+			javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+		}
+	}
 }
diff --git a/org.eclipse.jdt.core/.settings/.api_filters b/org.eclipse.jdt.core/.settings/.api_filters
index 9f702d0..df3c560 100644
--- a/org.eclipse.jdt.core/.settings/.api_filters
+++ b/org.eclipse.jdt.core/.settings/.api_filters
@@ -299,6 +299,14 @@
             </message_arguments>
         </filter>
     </resource>
+    <resource path="dom/org/eclipse/jdt/core/dom/RecordDeclaration.java" type="org.eclipse.jdt.core.dom.RecordDeclaration">
+        <filter comment="method not needed" id="338792546">
+            <message_arguments>
+                <message_argument value="org.eclipse.jdt.core.dom.RecordDeclaration"/>
+                <message_argument value="getTypes()"/>
+            </message_arguments>
+        </filter>
+    </resource>
     <resource path="dom/org/eclipse/jdt/core/dom/SimpleName.java" type="org.eclipse.jdt.core.dom.SimpleName">
         <filter id="576778288">
             <message_arguments>
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
index d22994a..5e7a47b 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
@@ -4809,8 +4809,11 @@
 			}
 			if (currentNode instanceof TypeDeclaration
 				|| currentNode instanceof EnumDeclaration
-				|| currentNode instanceof AnnotationTypeDeclaration) {
-				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDecl = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
+				|| currentNode instanceof AnnotationTypeDeclaration
+				|| currentNode instanceof RecordDeclaration) {
+				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDecl =
+						(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)
+						this.ast.getBindingResolver().getCorrespondingNode(currentNode);
 				if ((initializer.getModifiers() & Modifier.STATIC) != 0) {
 					return typeDecl.staticInitializerScope;
 				} else {
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecordDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecordDeclaration.java
index ca78834..d902836 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecordDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecordDeclaration.java
@@ -448,36 +448,6 @@
 		return methods;
 	}
 
-	/**
-	 * Returns the ordered list of member type declarations of this type
-	 * declaration.
-	 * <p>
-	 * This convenience method returns this node's body declarations
-	 * with non-types filtered out. Unlike <code>bodyDeclarations</code>,
-	 * this method does not return a live result.
-	 * </p>
-	 *
-	 * @return the (possibly empty) list of member type declarations
-	 */
-	public RecordDeclaration[] getTypes() {
-		List bd = bodyDeclarations();
-		int typeCount = 0;
-		for (Iterator it = bd.listIterator(); it.hasNext(); ) {
-			if (it.next() instanceof RecordDeclaration) {
-				typeCount++;
-			}
-		}
-		RecordDeclaration[] memberTypes = new RecordDeclaration[typeCount];
-		int next = 0;
-		for (Iterator it = bd.listIterator(); it.hasNext(); ) {
-			Object decl = it.next();
-			if (decl instanceof RecordDeclaration) {
-				memberTypes[next++] = (RecordDeclaration) decl;
-			}
-		}
-		return memberTypes;
-	}
-
 	@Override
 	ITypeBinding internalResolveBinding() {
 		return this.ast.getBindingResolver().resolveType(this);