blob: 1422acadd8d80d9536cbf6943dd26076f230d5aa [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2020, 2022 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 java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
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.GuardedPattern;
import org.eclipse.jdt.core.dom.ParenthesizedExpression;
import org.eclipse.jdt.core.dom.Pattern;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.SwitchCase;
import org.eclipse.jdt.core.dom.SwitchStatement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.TypePattern;
import junit.framework.Test;
public class ASTConverter_PreviewTest extends ConverterTestSetup {
ICompilationUnit workingCopy;
public void setUpSuite() throws Exception {
super.setUpSuite();
this.ast = AST.newAST(getASTLatest(), false);
this.currentProject = getJavaProject("Converter_17");
if (this.ast.apiLevel() == AST.JLS18) {
this.currentProject.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_18);
this.currentProject.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_18);
this.currentProject.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_18);
this.currentProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
this.currentProject.setOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
}
}
public ASTConverter_PreviewTest(String name) {
super(name);
}
public static Test suite() {
return buildModelTestSuite(ASTConverter_PreviewTest.class);
}
static int getASTLatest() {
return AST.getJLSLatest();
}
protected void tearDown() throws Exception {
super.tearDown();
if (this.workingCopy != null) {
this.workingCopy.discardWorkingCopy();
this.workingCopy = null;
}
}
private void printJREError() {
System.err.println("Test "+getName()+" requires a JRE 18");
}
@SuppressWarnings("rawtypes")
public void testTypePattern() throws CoreException {
if (!isJRE18) {
printJREError();
return;
}
String contents = "public class X {\n" +
"void foo(Object o) {\n" +
" switch (o) {\n" +
" case Integer i -> System.out.println(i.toString());\n" +
" case String s -> System.out.println(s);\n" +
" default -> System.out.println(o.toString());\n" +
" }\n" +
"}\n" +
"\n" +
"}\n";
this.workingCopy = getWorkingCopy("/Converter_17/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("Switch statement", node.getNodeType(), ASTNode.SWITCH_STATEMENT);
List statements = ((SwitchStatement)node).statements();
assertEquals("incorrect no of statements", 6, statements.size());
SwitchCase caseInteger = (SwitchCase) statements.get(0);
Expression typePattern = (Expression)caseInteger.expressions().get(0);
assertEquals("Type Pattern", typePattern.getNodeType(), ASTNode.TYPE_PATTERN);
SingleVariableDeclaration patternVariable = ((TypePattern)typePattern).getPatternVariable();
assertEquals("Type Pattern Integer", "Integer", patternVariable.getType().toString());
SingleVariableDeclaration patternVariable2 = ((TypePattern)typePattern).patternVariables().get(0);
assertEquals(patternVariable, patternVariable2);
SwitchCase caseString = (SwitchCase) statements.get(2);
typePattern = (Expression)caseString.expressions().get(0);
assertEquals("Type Pattern", typePattern.getNodeType(), ASTNode.TYPE_PATTERN);
patternVariable = ((TypePattern)typePattern).getPatternVariable();
assertEquals("Type Pattern Integer", "String", patternVariable.getType().toString());
patternVariable2 = ((TypePattern)typePattern).patternVariables().get(0);
assertEquals(patternVariable, patternVariable2);
SwitchCase caseDefault = (SwitchCase) statements.get(4);
assertTrue("Default case", caseDefault.isDefault());
}
@SuppressWarnings("rawtypes")
public void testGuardedPattern() throws CoreException {
if (!isJRE18) {
printJREError();
return;
}
String contents = "public class X {\n" +
"void foo(Object o) {\n" +
" switch (o) {\n" +
" case Integer i && (i.intValue() > 10) -> System.out.println(\"Greater than 10 \");\n" +
" case String s && s.equals(\"ff\") -> System.out.println(s);\n" +
" default -> System.out.println(o.toString());\n" +
" }\n" +
"}\n" +
"\n" +
"}\n";
this.workingCopy = getWorkingCopy("/Converter_17/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("Switch statement", node.getNodeType(), ASTNode.SWITCH_STATEMENT);
List statements = ((SwitchStatement)node).statements();
assertEquals("incorrect no of statements", 6, statements.size());
SwitchCase caseInteger = (SwitchCase) statements.get(0);
Expression guardedPattern = (Expression)caseInteger.expressions().get(0);
assertEquals("Guarded Pattern", guardedPattern.getNodeType(), ASTNode.GUARDED_PATTERN);
Pattern pattern = ((GuardedPattern)guardedPattern).getPattern();
SingleVariableDeclaration patternVariable = ((TypePattern)pattern).getPatternVariable();
assertEquals("Type Pattern Integer", "Integer", patternVariable.getType().toString());
SingleVariableDeclaration patternVariable2 = ((TypePattern)pattern).patternVariables().get(0);
assertEquals(patternVariable, patternVariable2);
Expression expression = ((GuardedPattern)guardedPattern).getExpression();
Expression expression2 = ((ParenthesizedExpression)expression).getExpression();
assertEquals("Infix expression", "i.intValue() > 10", expression2.toString());
SwitchCase caseString = (SwitchCase) statements.get(2);
guardedPattern = (Expression)caseString.expressions().get(0);
assertEquals("Guarded Pattern", guardedPattern.getNodeType(), ASTNode.GUARDED_PATTERN);
pattern = ((GuardedPattern)guardedPattern).getPattern();
patternVariable = ((TypePattern)pattern).getPatternVariable();
assertEquals("Type Pattern String", "String", patternVariable.getType().toString());
patternVariable2 = ((TypePattern)pattern).patternVariables().get(0);
assertEquals(patternVariable, patternVariable2);
expression = ((GuardedPattern)guardedPattern).getExpression();
assertEquals("Infix expression", "s.equals(\"ff\")",expression.toString());
SwitchCase caseDefault = (SwitchCase) statements.get(4);
assertTrue("Default case", caseDefault.isDefault());
}
@SuppressWarnings("rawtypes")
public void testParenthesizedExpressionPattern() throws CoreException {
if (!isJRE18) {
printJREError();
return;
}
String contents = "public class X {\n" +
"void foo(Object o) {\n" +
" switch (o) {\n" +
" case (Integer i) : System.out.println(i.toString());\n" +
" default : System.out.println(o.toString());\n" +
" }\n" +
"}\n" +
"\n" +
"}\n";
this.workingCopy = getWorkingCopy("/Converter_17/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("Switch statement", node.getNodeType(), ASTNode.SWITCH_STATEMENT);
List statements = ((SwitchStatement)node).statements();
assertEquals("incorrect no of statements", 4, statements.size());
SwitchCase caseInteger = (SwitchCase) statements.get(0);
Expression parenthesizedExpression = (Expression)caseInteger.expressions().get(0);
assertEquals("Parenthesized Expression", parenthesizedExpression.getNodeType(), ASTNode.PARENTHESIZED_EXPRESSION);
Expression targetPattern = ((ParenthesizedExpression)parenthesizedExpression).getExpression();
assertEquals("Type Pattern", targetPattern.getNodeType(), ASTNode.TYPE_PATTERN);
SingleVariableDeclaration patternVariable = ((TypePattern)targetPattern).getPatternVariable();
assertEquals("Type Pattern Integer", "Integer", patternVariable.getType().toString());
SingleVariableDeclaration patternVariable2 = ((TypePattern)targetPattern).patternVariables().get(0);
assertEquals(patternVariable, patternVariable2);
SwitchCase caseDefault = (SwitchCase) statements.get(2);
assertTrue("Default case", caseDefault.isDefault());
}
@SuppressWarnings("rawtypes")
public void testNullPattern() throws CoreException {
if (!isJRE18) {
printJREError();
return;
}
String contents = "public class X {\n" +
"void foo(Object o) {\n" +
" switch (o) {\n" +
" case Integer i : System.out.println(i.toString());\n" +
" break;\n" +
" case null : System.out.println(\"null\");\n" +
" default : System.out.println(o.toString());\n" +
" }\n" +
"}\n" +
"\n" +
"}\n";
this.workingCopy = getWorkingCopy("/Converter_17/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("Switch statement", node.getNodeType(), ASTNode.SWITCH_STATEMENT);
List statements = ((SwitchStatement)node).statements();
assertEquals("incorrect no of statements", 7, statements.size());
SwitchCase caseInteger = (SwitchCase) statements.get(3);
Expression nullExpression = (Expression)caseInteger.expressions().get(0);
assertEquals("Null Expression", nullExpression.getNodeType(), ASTNode.NULL_LITERAL);
}
@SuppressWarnings("rawtypes")
public void testCaseDefaultExpressionPattern() throws CoreException {
if (!isJRE18) {
printJREError();
return;
}
String contents = "public class X {\n" +
"void foo(Object o) {\n" +
" switch (o) {\n" +
" case Integer i : System.out.println(i.toString());\n" +
" case default : System.out.println(o.toString());\n" +
" }\n" +
"}\n" +
"\n" +
"}\n";
this.workingCopy = getWorkingCopy("/Converter_17/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("Switch statement", node.getNodeType(), ASTNode.SWITCH_STATEMENT);
List statements = ((SwitchStatement)node).statements();
assertEquals("incorrect no of statements", 4, statements.size());
SwitchCase caseDefault = (SwitchCase) statements.get(2);
Expression caseDefaultExpression = (Expression) caseDefault.expressions().get(0);
assertEquals("Case Default Expression",caseDefaultExpression.getNodeType() , ASTNode.CASE_DEFAULT_EXPRESSION);
}
public void testBug575250() throws CoreException {
if (!isJRE18) {
System.err.println("Test "+getName()+" requires a JRE 18");
return;
}
String contents = "public class X {\n" +
" static void foo(Object o) {\n" +
" switch (o) {\n" +
" case (Integer i_1): System.out.println(\"Integer\");\n" +
" default: System.out.println(\"Object\");" +
" }\n" +
" }\n" +
"}\n";
this.workingCopy = getWorkingCopy("/Converter_17/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("incorrect types", types.size(), 1);
AbstractTypeDeclaration type = types.get(0);
assertTrue("should be a type", type instanceof TypeDeclaration);
TypeDeclaration typeDecl = (TypeDeclaration)type;
final List<TypePattern> result = new ArrayList<>();
typeDecl.accept(new ASTVisitor() {
public boolean visit(TypePattern n) {
result.add(n);
return true;
}
});
assertEquals("incorrect no of patterns", 1, result.size());
TypePattern typePattern = result.get(0);
assertNotNull("pattern is null", typePattern);
int start = contents.indexOf("Integer");
int length = "Integer i_1".length();
assertEquals("wrong source range", typePattern.getStartPosition(), start);
assertEquals("wrong source range", typePattern.getLength(), length);
SingleVariableDeclaration patternVariable = typePattern.getPatternVariable();
assertEquals("wrong source range", patternVariable.getStartPosition(), start);
assertEquals("wrong source range", patternVariable.getLength(), length);
Type type2 = patternVariable.getType();
assertEquals("wrong source range", type2.getStartPosition(), start);
assertEquals("wrong source range", type2.getLength(), "Integer".length());
SimpleName name = patternVariable.getName();
start = contents.indexOf("i_1");
assertEquals("wrong source range", name.getStartPosition(), start);
assertEquals("wrong source range", name.getLength(), "i_1".length());
}
}