/*******************************************************************************
 * Copyright (c) 2020, 2021 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.tests.dom;

import static org.junit.Assert.assertNotEquals;

import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.InstanceofExpression;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.PatternInstanceofExpression;
import org.eclipse.jdt.core.dom.RecordDeclaration;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclarationStatement;

import junit.framework.Test;

public class ASTConverter_16Test extends ConverterTestSetup {

	ICompilationUnit workingCopy;

	static {
//		TESTS_NUMBERS = new int[] { 19 };
//		TESTS_RANGE = new int[] { 1, -1 };
//		TESTS_NAMES = new String[] {"testPatternInstanceOfExpression002"};
	}
	public void setUpSuite() throws Exception {
		super.setUpSuite();
		this.ast = AST.newAST(getAST16(), false);
		this.currentProject = getJavaProject("Converter_16");
		if (this.ast.apiLevel() == AST.JLS16 ) {
			this.currentProject.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_16);
			this.currentProject.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_16);
			this.currentProject.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_16);

		}
	}

	public ASTConverter_16Test(String name) {
		super(name);
	}

	public static Test suite() {
		return buildModelTestSuite(ASTConverter_16Test.class);
	}

	static int getAST16() {
		return AST.JLS16;
	}
	protected void tearDown() throws Exception {
		super.tearDown();
		if (this.workingCopy != null) {
			this.workingCopy.discardWorkingCopy();
			this.workingCopy = null;
		}
	}

	public void testRecord001() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String contents =
			"public record X() {\n" +
			"		public X {\n" +
			"			System.out.println(\"no error\");\n" +
			"		}\n" +
			"\n" +
			"}\n";
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		ASTNode node = buildAST(
			contents,
			this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
	}

	/**
	 * Added for Bug 561193 - [14]record keyword inside method not colored correctly
	 * @throws CoreException
	 */
	public void testRecord002() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String contents =
			"public record X(int param1, int param2) {\n" +
			"		public X {\n" +
			"			if (param1 > 5) {\n" +
			"				System.out.println(\"error\");\n" +
			"			}\n" +
			"		}\n" +
			"\n" +
			"}\n";
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		ASTNode node = buildAST(
			contents,
			this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
	}

	public void testRecord003() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String contents =
			"public record X(int param1, int param2) {\n" +
			"		public X {\n" +
			"			if (param1 > 5) {\n" +
			"				System.out.println(\"error\");\n" +
			"			}\n" +
			"		}\n" +
			"\n" +
			"		public X(int a) {\n" +
			"			this(6,16);\n" +
			"			System.out.println(a);\n" +
			"		}\n" +
			"}\n";
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		ASTNode node = buildAST(
			contents,
			this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
	}

	public void testRecord004() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test " + getName() + " requires a JRE 16");
			return;
		}
		String contents = "public class X {\n" +
						  "	public static void main(String[] args) {\n" +
				          "		record R(int x,int y){}\n" +
						  "		R r = new R(100, 200);\n" +
				          "		System.out.println(r.x());\n" +
						  "	}\n" +
				          "}";
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/* resolve */);
		ASTNode node = buildAST(contents, this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		node = getASTNode(compilationUnit, 0, 0);
		assertEquals("Not a method declaration", ASTNode.METHOD_DECLARATION, node.getNodeType());
		MethodDeclaration methodDeclaration = (MethodDeclaration) node;
		List<ASTNode> statements = methodDeclaration.getBody().statements();
		node = statements.get(0);
		assertEquals("Not a TypDeclaration statement", ASTNode.TYPE_DECLARATION_STATEMENT, node.getNodeType());
		TypeDeclarationStatement tdStmt = (TypeDeclarationStatement) node;
		node = tdStmt.getDeclaration();
		assertEquals("Not a RecordDeclaration", ASTNode.RECORD_DECLARATION, node.getNodeType());
	}

	public void testRecord005() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String contents = "public class X {\n" +
				  "	public static void main(String[] args) {\n" +
		          "		record R(int x,String y){}\n" +
				  "		R r = new R(100, \"Point\");\n" +
		          "		System.out.println(r.x());\n" +
				  "	}\n" +
		          "}";
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		ASTNode node = buildAST(
			contents,
			this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		node = getASTNode(compilationUnit, 0, 0);
		assertEquals("Not a method declaration", ASTNode.METHOD_DECLARATION, node.getNodeType());
		MethodDeclaration methodDeclaration = (MethodDeclaration) node;
		List<ASTNode> statements = methodDeclaration.getBody().statements();
		node = statements.get(0);
		assertEquals("Not a TypDeclaration statement", ASTNode.TYPE_DECLARATION_STATEMENT, node.getNodeType());
		TypeDeclarationStatement tdStmt = (TypeDeclarationStatement) node;
		node = tdStmt.getDeclaration();
		assertEquals("Not a RecordDeclaration", ASTNode.RECORD_DECLARATION, node.getNodeType());
		RecordDeclaration record = (RecordDeclaration)node;
		List<SingleVariableDeclaration> recordComponents = record.recordComponents();
		assertEquals("There should be 2 record components", 2, recordComponents.size());
		SingleVariableDeclaration recordComponent = recordComponents.get(0);
		assertEquals("First record component name should be x","x" , recordComponent.getName().toString());
		assertEquals("First record component type is int" , "int", recordComponent.getType().toString());
		IVariableBinding resolveBinding = recordComponent.resolveBinding();
		assertEquals("First record component binding" , true, resolveBinding.isRecordComponent());
		recordComponent = recordComponents.get(1);
		assertEquals("Second record component name should be y","y" , recordComponent.getName().toString());
		assertEquals("Second record component type is String" , "String", recordComponent.getType().toString());
		resolveBinding = recordComponent.resolveBinding();
		assertEquals("Second record component binding" , true, resolveBinding.isRecordComponent());
	}

	public void testRecord006() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String contents = "import java.lang.annotation.ElementType;\n" +
				"import java.lang.annotation.Target;\n" +
				"record X(@MyAnnot int lo) {\n" +
				"	public int lo() {\n" +
				"		return this.lo;\n" +
				"	}\n" +
				"\n" +
				"}\n" +
				"@Target({ElementType.FIELD})\n" +
				"@interface MyAnnot {}";
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		ASTNode node = buildAST(
			contents,
			this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		node = ((AbstractTypeDeclaration)compilationUnit.types().get(0));
		assertEquals("Not a Record Declaration", ASTNode.RECORD_DECLARATION, node.getNodeType());
		RecordDeclaration record = (RecordDeclaration)node;
		List<SingleVariableDeclaration> recordComponents = record.recordComponents();
		assertEquals("There should be 1 record component", 1, recordComponents.size());
		SingleVariableDeclaration recordComponent = recordComponents.get(0);
		assertEquals("Record component name should be lo","lo" , recordComponent.getName().toString());
		assertEquals("Record component type is int" , "int", recordComponent.getType().toString());
		IVariableBinding resolveBinding = recordComponent.resolveBinding();
		assertEquals("Record component binding" , true, resolveBinding.isRecordComponent());
		MarkerAnnotation annotation = (MarkerAnnotation)recordComponent.modifiers().get(0);
		assertEquals("Record component annotation name should be MyAnnot","@MyAnnot" , annotation.toString());
		assertEquals("Record component binding should not have annotation",0 , resolveBinding.getAnnotations().length);
	}

	public void testRecord007() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String contents = "record X(int lo) {\n" +
				"	public int lo() {\n" +
				"		return this.lo;\n" +
				"	}\n" +
				"\n" +
				"}\n";
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		ASTNode node = buildAST(
			contents,
			this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		node = ((AbstractTypeDeclaration)compilationUnit.types().get(0));
		assertEquals("Not a Record Declaration", ASTNode.RECORD_DECLARATION, node.getNodeType());
		RecordDeclaration record = (RecordDeclaration)node;
		List<SingleVariableDeclaration> recordComponents = record.recordComponents();
		assertEquals("There should be 1 record component", 1, recordComponents.size());
		SingleVariableDeclaration recordComponent = recordComponents.get(0);
		SimpleName recordComponentName = recordComponent.getName();
		assertEquals("Record component name should be lo","lo" , recordComponentName.toString());
		ITypeBinding resolveTypeBinding = recordComponentName.resolveTypeBinding();
		assertEquals("Record component type is int" , "int",resolveTypeBinding.getName() );
		IVariableBinding resolveBinding = (IVariableBinding)recordComponentName.resolveBinding();
		assertEquals("Record component binding" , true, resolveBinding.isRecordComponent());
	}

	public void testRecord008() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String contents = "import java.lang.annotation.*;\n" +
				"@Target (ElementType.METHOD)\n" +
				"@interface MyAnnot {}\n" +
				"public record X(@MyAnnot int lo) {\n" +
				"	public int lo() {\n" +
				"		return this.lo;\n" +
				"	}\n" +
				"\n" +
				"}\n";

		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		ASTNode node = buildAST(
			contents,
			this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		node = ((AbstractTypeDeclaration)compilationUnit.types().get(0));
		assertNotEquals("Not a Record Declaration", ASTNode.RECORD_DECLARATION, node.getNodeType());

	}

	public void testRecord009() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String elementType = "package java.lang.annotation;\n" +
				"public enum ElementType {\n" +
				"    TYPE,\n" +
				"    FIELD,\n" +
				"    METHOD,\n" +
				"    PARAMETER,\n" +
				"    CONSTRUCTOR,\n" +
				"    LOCAL_VARIABLE,\n" +
				"    ANNOTATION_TYPE,\n" +
				"    PACKAGE,\n" +
				"    TYPE_PARAMETER,\n" +
				"    TYPE_USE,\n" +
				"    MODULE,\n" +
				"    RECORD_COMPONENT\n" +
				"}\n";
		ICompilationUnit workingCopy2 = getWorkingCopy("/Converter_16/src/java/lang/annotation/ElementType.java", true/*resolve*/);
		String contents = "import java.lang.annotation.ElementType;\n" +
				"import java.lang.annotation.Target;\n" +
				"record X(@MyAnnot int lo) {\n" +
				"	public int lo() {\n" +
				"		return this.lo;\n" +
				"	}\n" +
				"\n" +
				"}\n" +
				"@Target({ElementType.RECORD_COMPONENT})\n" +
				"@interface MyAnnot {}";
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		buildAST(
				elementType,
				workingCopy2);
		ASTNode node = buildAST(
			contents,
			this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		node = ((AbstractTypeDeclaration)compilationUnit.types().get(0));
		assertEquals("Not a Record Declaration", ASTNode.RECORD_DECLARATION, node.getNodeType());
		RecordDeclaration record = (RecordDeclaration)node;
		List<SingleVariableDeclaration> recordComponents = record.recordComponents();
		assertEquals("There should be 1 record component", 1, recordComponents.size());
		SingleVariableDeclaration recordComponent = recordComponents.get(0);
		SimpleName recordComponentName = recordComponent.getName();
		assertEquals("Record component name should be lo","lo" , recordComponentName.toString());
		ITypeBinding resolveTypeBinding = recordComponentName.resolveTypeBinding();
		assertEquals("Record component type is int" , "int",resolveTypeBinding.getName() );
		IVariableBinding resolveBinding = (IVariableBinding)recordComponentName.resolveBinding();
		assertEquals("Record component binding" , true, resolveBinding.isRecordComponent());

	}

	public void _testRecord010() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String elementType = "package java.lang.annotation;\n" +
				"public enum ElementType {\n" +
				"    TYPE,\n" +
				"    FIELD,\n" +
				"    METHOD,\n" +
				"    PARAMETER,\n" +
				"    CONSTRUCTOR,\n" +
				"    LOCAL_VARIABLE,\n" +
				"    ANNOTATION_TYPE,\n" +
				"    PACKAGE,\n" +
				"    TYPE_PARAMETER,\n" +
				"    TYPE_USE,\n" +
				"    MODULE,\n" +
				"    RECORD_COMPONENT\n" +
				"}\n";
		ICompilationUnit workingCopy2 = getWorkingCopy("/Converter_16/src/java/lang/annotation/ElementType.java", true/*resolve*/);
		String contents = "import java.lang.annotation.ElementType;\n" +
				"import java.lang.annotation.Target;\n" +
				"record X(@MyAnnot int lo) {\n" +
				"	public static @MyAnnot int x;\n" +
				"	public int lo() {\n" +
				"		return this.lo;\n" +
				"	}\n" +
				"\n" +
				"}\n" +
				"@Target({ElementType.RECORD_COMPONENT})\n" +
				"@interface MyAnnot {}";
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		buildAST(
				elementType,
				workingCopy2);
		try {
			buildAST(
			contents,
			this.workingCopy);
		} catch (Exception ex) {
			// This can not be compiled
		}

	}

	public void testRecord011() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String contents =
			"public record X() {\n" +
			"		public X {\n" +
			"			System.out.println(\"no error\");\n" +
			"		}\n" +
			"\n" +
			"}\n";
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		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;
		int startPos = recDecl.getRestrictedIdentifierStartPosition();
		assertEquals("Start position of 'record' keyword is not 7", startPos, 7);
	}

	public void testRecord012() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			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_16/src/X.java", true/*resolve*/);
		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());
			}
		}

	}

	public void testClass001() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String contents =
			"public class X {\n" +
			"		public X() {\n" +
			"			System.out.println(\"no error\");\n" +
			"		}\n" +
			"\n" +
			"}\n";
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		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 type", type instanceof TypeDeclaration);
		TypeDeclaration typeDecl = (TypeDeclaration)type;
		assertTrue("type not a class", !typeDecl.isInterface());
		int startPos = typeDecl.getRestrictedIdentifierStartPosition();
		assertEquals("Restricter identifier position for class' is not -1", startPos, -1);
	}

	public void testInterface001() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String contents =
			"public interface X {\n" +
			"\n" +
			"}\n";
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		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 type", type instanceof TypeDeclaration);
		TypeDeclaration typeDecl = (TypeDeclaration)type;
		assertTrue("type not an interface", typeDecl.isInterface());
		int startPos = typeDecl.getRestrictedIdentifierStartPosition();
		assertEquals("Restricter identifier position for interface' is not -1", startPos, -1);
	}



	public void testPatternInstanceOfExpression001() throws JavaModelException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String contents =
				"public class X {\n" +
						"	public String test001(Object o) {\n" +
						"		if (o instanceof String s){\n" +
						"    		System.out.println(s);\n" +
						"			return s;\n" +
						"		}\n" +
						"		return null;\n" +
						"	}\n" +
						"}" ;
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		ASTNode node = buildAST(
				contents,
				this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		node = getASTNode(compilationUnit, 0, 0, 0);
		assertEquals("Not an if statement", ASTNode.IF_STATEMENT, node.getNodeType());
		IfStatement ifStatement = (IfStatement) node;
		Expression expression = ifStatement.getExpression();
		checkSourceRange(expression, "o instanceof String s", contents);
		assertEquals("Not an instanceof expression", ASTNode.PATTERN_INSTANCEOF_EXPRESSION, expression.getNodeType());
		PatternInstanceofExpression instanceofExpression = (PatternInstanceofExpression) expression;
		SingleVariableDeclaration var = instanceofExpression.getRightOperand();
		checkSourceRange(var, "String s", contents);
	}

	public void testPatternInstanceOfExpression002() throws JavaModelException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String contents =
				"public class X {\n" +
						"	public String test001(Object o) {\n" +
						"		if (o instanceof String){\n" +
						"    		String s = (String)o;\n" +
						"    		System.out.println(s);\n" +
						"			return s;\n" +
						"		}\n" +
						"		return null;\n" +
						"	}\n" +
						"}" ;
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		ASTNode node = buildAST(
				contents,
				this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		node = getASTNode(compilationUnit, 0, 0, 0);
		assertEquals("Not an if statement", ASTNode.IF_STATEMENT, node.getNodeType());
		IfStatement ifStatement = (IfStatement) node;
		Expression expression = ifStatement.getExpression();
		checkSourceRange(expression, "o instanceof String", contents);
		assertEquals("Not an instanceof expression", ASTNode.INSTANCEOF_EXPRESSION, expression.getNodeType());
		InstanceofExpression instanceofExpression = (InstanceofExpression) expression;
		Expression var = instanceofExpression.getLeftOperand();
		assertNotNull(var);
	}

	public void testPatternInstanceOfExpression003() throws JavaModelException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String contents =
				"public class X {\n" +
						"	public String test001(Object o) {\n" +
						"		if (o instanceof String s){\n" +
						"    		System.out.println(s);\n" +
						"			return s;\n" +
						"		}\n" +
						"		return null;\n" +
						"	}\n" +
						"}" ;
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);

		ASTNode node = buildAST(
				contents,
				this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		node = getASTNode(compilationUnit, 0, 0, 0);
		assertEquals("Not an if statement", ASTNode.IF_STATEMENT, node.getNodeType());
		IfStatement ifStatement = (IfStatement) node;
		Expression expression = ifStatement.getExpression();
		checkSourceRange(expression, "o instanceof String s", contents);
		assertEquals("Not an instanceof expression", ASTNode.PATTERN_INSTANCEOF_EXPRESSION, expression.getNodeType());
		PatternInstanceofExpression instanceofExpression = (PatternInstanceofExpression) expression;
		SingleVariableDeclaration var = instanceofExpression.getRightOperand();
		checkSourceRange(var, "String s", contents);
		String instanceofExpressionString = instanceofExpression.toString();
		assertEquals("o instanceof String s", instanceofExpressionString);
	}

	public void testRecordConstructor001() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String contents = "record X(int lo) {\n" +
				"   public X {\n" +
				"   \n}\n" +
				"   public X(String str) {\n" +
				"		this((str != null) ? str.length() : 0);" +
				"   \n}\n" +
				"	public int abc() {\n" +
				"		return this.lo;\n" +
				"	}\n" +
				"\n" +
				"}\n";
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		IJavaProject javaProject = this.workingCopy.getJavaProject();
			ASTNode node = buildAST(
				contents,
				this.workingCopy);
			assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
			CompilationUnit compilationUnit = (CompilationUnit) node;
			assertProblemsSize(compilationUnit, 0);
			node = ((AbstractTypeDeclaration)compilationUnit.types().get(0));
			assertEquals("Not a Type", ASTNode.RECORD_DECLARATION, node.getNodeType());
			ASTParser parser= ASTParser.newParser(getAST16());
			parser.setProject(javaProject);
			IBinding[] bindings = parser.createBindings(new IJavaElement[] { this.workingCopy.findPrimaryType() }, null);
			IMethodBinding methodBinding= ((ITypeBinding) bindings[0]).getDeclaredMethods()[0];
			assertEquals("compact constructor name", "X", methodBinding.getName());
			assertTrue("not a Constructor", methodBinding.isConstructor());
			assertTrue("not a CompactConstructor", methodBinding.isCompactConstructor());
			assertTrue("not a CanonicalConstructor", methodBinding.isCanonicalConstructor());
			methodBinding= ((ITypeBinding) bindings[0]).getDeclaredMethods()[1];
			assertEquals("constructor name", "X", methodBinding.getName());
			assertTrue("not a Constructor", methodBinding.isConstructor());
			assertFalse("Is CompactConstructor?", methodBinding.isCompactConstructor());
			assertFalse("Is CanonicalConstructor?", methodBinding.isCanonicalConstructor());
			methodBinding= ((ITypeBinding) bindings[0]).getDeclaredMethods()[2];
			assertEquals("method name", "abc", methodBinding.getName());
			assertFalse("Is a Constructor?", methodBinding.isConstructor());
			assertFalse("Is a CompactConstructor?", methodBinding.isCompactConstructor());
			assertFalse("Is CanonicalConstructor?", methodBinding.isCanonicalConstructor());
	}

	public void testRecordConstructor002() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String contents = "record X(int lo) {\n" +
				"   public X(int lo) {\n" +
				"		this.lo = lo;" +
				"   \n}\n" +
				"   public X(String str) {\n" +
				"		this((str != null) ? str.length() : 0);" +
				"   \n}\n" +
				"	public int abc() {\n" +
				"		return this.lo;\n" +
				"	}\n" +
				"\n" +
				"}\n";
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		IJavaProject javaProject = this.workingCopy.getJavaProject();
		ASTNode node = buildAST(
			contents,
			this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		node = ((AbstractTypeDeclaration)compilationUnit.types().get(0));
		assertEquals("Not a Type", ASTNode.RECORD_DECLARATION, node.getNodeType());
		ASTParser parser= ASTParser.newParser(getAST16());
		parser.setProject(javaProject);
		IBinding[] bindings = parser.createBindings(new IJavaElement[] { this.workingCopy.findPrimaryType() }, null);
		IMethodBinding methodBinding= ((ITypeBinding) bindings[0]).getDeclaredMethods()[0];
		assertEquals("compact constructor name", "X", methodBinding.getName());
		assertTrue("not a Constructor", methodBinding.isConstructor());
		assertTrue("is a CanonicalConstructor", methodBinding.isCanonicalConstructor());
		assertFalse("is a CompactConstructor", methodBinding.isCompactConstructor());
		methodBinding= ((ITypeBinding) bindings[0]).getDeclaredMethods()[1];
		assertEquals("constructor name", "X", methodBinding.getName());
		assertTrue("not a Constructor", methodBinding.isConstructor());
		assertFalse("Is CanonicalConstructor?", methodBinding.isCanonicalConstructor());
		assertFalse("Is CompactConstructor?", methodBinding.isCompactConstructor());
		methodBinding= ((ITypeBinding) bindings[0]).getDeclaredMethods()[2];
		assertEquals("method name", "abc", methodBinding.getName());
		assertFalse("Is a Constructor?", methodBinding.isConstructor());
		assertFalse("Is a CanonicalConstructor?", methodBinding.isCompactConstructor());
		assertFalse("Is a CompactConstructor?", methodBinding.isCompactConstructor());
	}

	public void testLocalEnum() throws CoreException {
		if (!isJRE16) {
			System.err.println("Test "+getName()+" requires a JRE 16");
			return;
		}
		String contents = "public class X {\n" +
			"	public static void main(String[] args) {\n" +
			"    enum Y1 { \n" +
			"		\n" +
			"		BLEU, \n" +
			"		BLANC, \n" +
			"		ROUGE,\n" +
			"		BLEUN;\n" +
			"	 }\n" +
			"	}\n" +
			"	}\n";
		this.workingCopy = getWorkingCopy("/Converter_16/src/X.java", true/*resolve*/);
		ASTNode node = buildAST(
			contents,
			this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		node = getASTNode(compilationUnit, 0, 0, 0);
		assertEquals("Not an enum statement", ASTNode.ENUM_DECLARATION, ((TypeDeclarationStatement)node).getDeclaration().getNodeType());
	}


}
