Bug 566853 - [15] record - generate Delegate Methods does not give any output

Added an API in JDT core to find out if a method is a synthetic record method or not.

Change-Id: I80ef0aa44c347f0f1075518f57e81b1d873dce35
Signed-off-by: Kalyan Prasad Tatavarthi <kalyan_prasad@in.ibm.com>
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter_15Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter_15Test.java
index c374727..c38256a 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter_15Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter_15Test.java
@@ -555,6 +555,54 @@
 		}
 	}
 
+	public void testRecord012() throws CoreException {
+		if (!isJRE15) {
+			System.err.println("Test "+getName()+" requires a JRE 15");
+			return;
+		}
+		String contents =
+			"public record X(int myComp) {\n" +
+			"		public void foo() {\n" +
+			"			System.out.println(\"no error\");\n" +
+			"		}\n" +
+			"\n" +
+			"}\n";
+		this.workingCopy = getWorkingCopy("/Converter_15/src/X.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);
+			assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
+			CompilationUnit compilationUnit = (CompilationUnit) node;
+			assertProblemsSize(compilationUnit, 0);
+			List<AbstractTypeDeclaration> types = compilationUnit.types();
+			assertEquals("No. of Types is not 1", types.size(), 1);
+			AbstractTypeDeclaration type = types.get(0);
+			assertTrue("type not a Record", type instanceof RecordDeclaration);
+			RecordDeclaration recDecl = (RecordDeclaration)type;
+			MethodDeclaration[] methods = recDecl.getMethods();
+			assertEquals("No. of methods is not 1", methods.length, 1);
+			ITypeBinding typeBinding = type.resolveBinding();
+			assertNotNull("typeBinding is null", typeBinding);
+			IMethodBinding[] mBindings = typeBinding.getDeclaredMethods();
+			assertEquals("No. of declared methods is not 6", mBindings.length, 6);
+			for (IMethodBinding mBinding : mBindings) {
+				if (mBinding.getName().equals("X") || mBinding.getName().equals("foo")) {
+					assertFalse("foo is not a synthetic method", mBinding.isSyntheticRecordMethod());
+				} else {
+					assertTrue("expected a synthetic method", mBinding.isSyntheticRecordMethod());
+				}
+			}
+
+		} finally {
+			javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+		}
+	}
+
 	public void testClass001() throws CoreException {
 		if (!isJRE15) {
 			System.err.println("Test "+getName()+" requires a JRE 15");
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java
index f5f8f71..d6ed09e 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java
@@ -438,4 +438,18 @@
 	 */
 	public IVariableBinding[] getSyntheticOuterLocals();
 
+	/**
+	 * Returns if this is a compiler generated  equals(), hashCode(), toString() or any accessor
+	 * method of a Record or not.
+	 * Methods equals(), hashCode() and toString() and accessor methods of a Record do not have
+	 * AccSynthetic flag set for them even if they are compiler generated methods. To differentiate
+	 * between these above compiler generated methods and user created methods equals(), hashCode()
+	 * and toString() or accessor methods in a Record, this function can be used.
+	 *
+	 * @return <code>true</code> for compiler generated  equals(), hashCode() and toString() or any
+	 * accessor method of a Record, else it returns <code>false</code>.
+	 * @noreference This method is not intended to be referenced by clients.
+	 */
+	public boolean isSyntheticRecordMethod();
+
 }
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
index 7d938bf..585f650 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
@@ -24,6 +24,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TagBits;
 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
@@ -607,4 +608,10 @@
 	public IVariableBinding[] getSyntheticOuterLocals() {
 		return NO_VARIABLE_BINDINGS;
 	}
+
+	@Override
+	public boolean isSyntheticRecordMethod() {
+		return ((getDeclaringClass().isRecord()) &&
+				(this.binding instanceof SyntheticMethodBinding));
+	}
 }
\ No newline at end of file