diff --git a/src/main/java/spoon/reflect/code/CtCase.java b/src/main/java/spoon/reflect/code/CtCase.java index 2f9c779fa8f..b6888801314 100644 --- a/src/main/java/spoon/reflect/code/CtCase.java +++ b/src/main/java/spoon/reflect/code/CtCase.java @@ -7,6 +7,7 @@ */ package spoon.reflect.code; +import org.jspecify.annotations.Nullable; import spoon.reflect.annotations.PropertyGetter; import spoon.reflect.annotations.PropertySetter; import spoon.reflect.path.CtRole; @@ -95,6 +96,23 @@ public interface CtCase extends CtStatement, CtStatementList { @PropertySetter(role = CtRole.DEFAULT_EXPRESSION) CtCase setIncludesDefault(boolean includesDefault); + /** + * {@return the guard of this case} + * This method returns {@code null} if no guard is present. + */ + @PropertyGetter(role = CtRole.CONDITION) + @Nullable + CtExpression getGuard(); + + /** + * Sets the guarding expression for this case. + * + * @param guard the expression guarding this case. If {@code null}, no guard will be inserted in the code. + * @return this case. + */ + @PropertySetter(role = CtRole.CONDITION) + CtCase setGuard(@Nullable CtExpression guard); + @Override CtCase clone(); } diff --git a/src/main/java/spoon/reflect/code/CtCasePattern.java b/src/main/java/spoon/reflect/code/CtCasePattern.java index 8b85f5d108e..3c213b5f20b 100644 --- a/src/main/java/spoon/reflect/code/CtCasePattern.java +++ b/src/main/java/spoon/reflect/code/CtCasePattern.java @@ -7,11 +7,9 @@ */ package spoon.reflect.code; -import org.jspecify.annotations.Nullable; import spoon.reflect.annotations.PropertyGetter; import spoon.reflect.annotations.PropertySetter; -import static spoon.reflect.path.CtRole.CONDITION; import static spoon.reflect.path.CtRole.PATTERN; /** @@ -45,22 +43,6 @@ public interface CtCasePattern extends CtExpression { @PropertySetter(role = PATTERN) CtCasePattern setPattern(CtPattern pattern); - /** - * {@return the guard of this case pattern} - * This method returns {@code null} if no guard is present. - */ - @PropertyGetter(role = CONDITION) - @Nullable CtExpression getGuard(); - - /** - * Sets the guarding expression for this case pattern. - * - * @param guard the expression guarding this case pattern. If {@code null}, no guard will be inserted in the code. - * @return this case pattern. - */ - @PropertySetter(role = CONDITION) - CtCasePattern setGuard(@Nullable CtExpression guard); - @Override CtCasePattern clone(); } diff --git a/src/main/java/spoon/reflect/meta/impl/ModelRoleHandlers.java b/src/main/java/spoon/reflect/meta/impl/ModelRoleHandlers.java index a248f3d5eb3..5d4433a6c0f 100644 --- a/src/main/java/spoon/reflect/meta/impl/ModelRoleHandlers.java +++ b/src/main/java/spoon/reflect/meta/impl/ModelRoleHandlers.java @@ -6,7 +6,7 @@ * Spoon is available either under the terms of the MIT License (see LICENSE-MIT.txt) or the Cecill-C License (see LICENSE-CECILL-C.txt). You as the user are entitled to choose the terms under which to adopt Spoon. */ package spoon.reflect.meta.impl; - +import java.lang.annotation.Annotation; import spoon.reflect.code.BinaryOperatorKind; import spoon.reflect.code.CaseKind; import spoon.reflect.code.CtAbstractInvocation; @@ -114,8 +114,6 @@ import spoon.reflect.reference.CtVariableReference; import spoon.reflect.reference.CtWildcardReference; import spoon.support.reflect.CtExtendedModifier; - -import java.lang.annotation.Annotation; /** * Contains implementations of {@link RoleHandler}s for all {@link CtRole}s of all model elements */ @@ -123,7 +121,7 @@ class ModelRoleHandlers { private ModelRoleHandlers() { } - static final RoleHandler[] roleHandlers = new RoleHandler[]{ new CtTypeAccess_ACCESSED_TYPE_RoleHandler(), new CtClass_ANNONYMOUS_EXECUTABLE_RoleHandler(), new CtElement_ANNOTATION_RoleHandler(), new CtAnnotation_ANNOTATION_TYPE_RoleHandler(), new CtAbstractInvocation_ARGUMENT_RoleHandler(), new CtExecutableReference_ARGUMENT_TYPE_RoleHandler(), new CtAssignment_ASSIGNED_RoleHandler(), new CtRHSReceiver_ASSIGNMENT_RoleHandler(), new CtBodyHolder_BODY_RoleHandler(), new CtSynchronized_BODY_RoleHandler(), new CtIntersectionTypeReference_BOUND_RoleHandler(), new CtWildcardReference_BOUNDING_TYPE_RoleHandler(), new CtAbstractSwitch_CASE_RoleHandler(), new CtCase_CASE_KIND_RoleHandler(), new CtExpression_CAST_RoleHandler(), new CtTry_CATCH_RoleHandler(), new CtElement_COMMENT_RoleHandler(), new CtComment_COMMENT_CONTENT_RoleHandler(), new CtJavaDocTag_COMMENT_CONTENT_RoleHandler(), new CtJavaDoc_COMMENT_TAG_RoleHandler(), new CtComment_COMMENT_TYPE_RoleHandler(), new CtConstructor_COMPACT_CONSTRUCTOR_RoleHandler(), new CtAssert_CONDITION_RoleHandler(), new CtCasePattern_CONDITION_RoleHandler(), new CtConditional_CONDITION_RoleHandler(), new CtIf_CONDITION_RoleHandler(), new CtClass_CONSTRUCTOR_RoleHandler(), new CtPackage_CONTAINED_TYPE_RoleHandler(), new CtCompilationUnit_DECLARED_IMPORT_RoleHandler(), new CtCompilationUnit_DECLARED_MODULE_RoleHandler(), new CtCompilationUnit_DECLARED_MODULE_REF_RoleHandler(), new CtCompilationUnit_DECLARED_TYPE_RoleHandler(), new CtCompilationUnit_DECLARED_TYPE_REF_RoleHandler(), new CtExecutableReference_DECLARING_TYPE_RoleHandler(), new CtFieldReference_DECLARING_TYPE_RoleHandler(), new CtTypeReference_DECLARING_TYPE_RoleHandler(), new CtAnnotationMethod_DEFAULT_EXPRESSION_RoleHandler(), new CtCase_DEFAULT_EXPRESSION_RoleHandler(), new CtVariable_DEFAULT_EXPRESSION_RoleHandler(), new CtNewArray_DIMENSION_RoleHandler(), new CtJavaDocTag_DOCUMENTATION_TYPE_RoleHandler(), new CtJavaDocTag_DOCUMENTATION_TYPE_REALNAME_RoleHandler(), new CtConditional_ELSE_RoleHandler(), new CtIf_ELSE_RoleHandler(), new CtModifiable_EMODIFIER_RoleHandler(), new CtAbstractInvocation_EXECUTABLE_REF_RoleHandler(), new CtExecutableReferenceExpression_EXECUTABLE_REF_RoleHandler(), new CtModule_EXPORTED_PACKAGE_RoleHandler(), new CtAbstractSwitch_EXPRESSION_RoleHandler(), new CtArrayAccess_EXPRESSION_RoleHandler(), new CtAssert_EXPRESSION_RoleHandler(), new CtCase_EXPRESSION_RoleHandler(), new CtDo_EXPRESSION_RoleHandler(), new CtFor_EXPRESSION_RoleHandler(), new CtForEach_EXPRESSION_RoleHandler(), new CtLambda_EXPRESSION_RoleHandler(), new CtNewArray_EXPRESSION_RoleHandler(), new CtReturn_EXPRESSION_RoleHandler(), new CtSynchronized_EXPRESSION_RoleHandler(), new CtThrow_EXPRESSION_RoleHandler(), new CtUnaryOperator_EXPRESSION_RoleHandler(), new CtWhile_EXPRESSION_RoleHandler(), new CtYieldStatement_EXPRESSION_RoleHandler(), new CtType_FIELD_RoleHandler(), new CtTry_FINALIZER_RoleHandler(), new CtForEach_FOREACH_VARIABLE_RoleHandler(), new CtFor_FOR_INIT_RoleHandler(), new CtFor_FOR_UPDATE_RoleHandler(), new CtProvidedService_IMPLEMENTATION_TYPE_RoleHandler(), new CtImport_IMPORT_REFERENCE_RoleHandler(), new CtType_INTERFACE_RoleHandler(), new CtTypeInformation_INTERFACE_RoleHandler(), new CtMethod_IS_DEFAULT_RoleHandler(), new CtFieldReference_IS_FINAL_RoleHandler(), new CtElement_IS_IMPLICIT_RoleHandler(), new CtLocalVariable_IS_INFERRED_RoleHandler(), new CtParameter_IS_INFERRED_RoleHandler(), new CtShadowable_IS_SHADOW_RoleHandler(), new CtExecutableReference_IS_STATIC_RoleHandler(), new CtFieldReference_IS_STATIC_RoleHandler(), new CtWildcardReference_IS_UPPER_RoleHandler(), new CtParameter_IS_VARARGS_RoleHandler(), new CtJavaDocTag_JAVADOC_TAG_VALUE_RoleHandler(), new CtStatement_LABEL_RoleHandler(), new CtBinaryOperator_LEFT_OPERAND_RoleHandler(), new CtLiteral_LITERAL_BASE_RoleHandler(), new CtType_METHOD_RoleHandler(), new CtModifiable_MODIFIER_RoleHandler(), new CtModule_MODIFIER_RoleHandler(), new CtModuleRequirement_MODIFIER_RoleHandler(), new CtTypeInformation_MODIFIER_RoleHandler(), new CtModule_MODULE_DIRECTIVE_RoleHandler(), new CtModuleRequirement_MODULE_REF_RoleHandler(), new CtPackageExport_MODULE_REF_RoleHandler(), new CtMultiTypedElement_MULTI_TYPE_RoleHandler(), new CtNamedElement_NAME_RoleHandler(), new CtReference_NAME_RoleHandler(), new CtNewClass_NESTED_TYPE_RoleHandler(), new CtType_NESTED_TYPE_RoleHandler(), new CtModule_OPENED_PACKAGE_RoleHandler(), new CtPackageExport_OPENED_PACKAGE_RoleHandler(), new CtBinaryOperator_OPERATOR_KIND_RoleHandler(), new CtOperatorAssignment_OPERATOR_KIND_RoleHandler(), new CtUnaryOperator_OPERATOR_KIND_RoleHandler(), new CtCompilationUnit_PACKAGE_DECLARATION_RoleHandler(), new CtPackageDeclaration_PACKAGE_REF_RoleHandler(), new CtPackageExport_PACKAGE_REF_RoleHandler(), new CtTypeReference_PACKAGE_REF_RoleHandler(), new CtCatch_PARAMETER_RoleHandler(), new CtExecutable_PARAMETER_RoleHandler(), new CtCasePattern_PATTERN_RoleHandler(), new CtRecordPattern_PATTERN_RoleHandler(), new CtSealable_PERMITTED_TYPE_RoleHandler(), new CtElement_POSITION_RoleHandler(), new CtModule_PROVIDED_SERVICE_RoleHandler(), new CtExecutable_RECEIVER_PARAMETER_RoleHandler(), new CtRecord_RECORD_COMPONENT_RoleHandler(), new CtModule_REQUIRED_MODULE_RoleHandler(), new CtBinaryOperator_RIGHT_OPERAND_RoleHandler(), new CtModule_SERVICE_TYPE_RoleHandler(), new CtProvidedService_SERVICE_TYPE_RoleHandler(), new CtUsedService_SERVICE_TYPE_RoleHandler(), new CtCodeSnippet_SNIPPET_RoleHandler(), new CtStatementList_STATEMENT_RoleHandler(), new CtModule_SUB_PACKAGE_RoleHandler(), new CtPackage_SUB_PACKAGE_RoleHandler(), new CtType_SUPER_TYPE_RoleHandler(), new CtTypeInformation_SUPER_TYPE_RoleHandler(), new CtTargetedExpression_TARGET_RoleHandler(), new CtLabelledFlowBreak_TARGET_LABEL_RoleHandler(), new CtConditional_THEN_RoleHandler(), new CtIf_THEN_RoleHandler(), new CtExecutable_THROWN_RoleHandler(), new CtTryWithResource_TRY_RESOURCE_RoleHandler(), new CtArrayTypeReference_TYPE_RoleHandler(), new CtExecutableReference_TYPE_RoleHandler(), new CtTypedElement_TYPE_RoleHandler(), new CtVariableReference_TYPE_RoleHandler(), new CtActualTypeContainer_TYPE_ARGUMENT_RoleHandler(), new CtType_TYPE_MEMBER_RoleHandler(), new CtFormalTypeDeclarer_TYPE_PARAMETER_RoleHandler(), new CtRecordPattern_TYPE_REF_RoleHandler(), new CtTypeMemberWildcardImportReference_TYPE_REF_RoleHandler(), new CtAnnotation_VALUE_RoleHandler(), new CtEnum_VALUE_RoleHandler(), new CtLiteral_VALUE_RoleHandler(), new CtTextBlock_VALUE_RoleHandler(), new CtTypePattern_VARIABLE_RoleHandler(), new CtVariableAccess_VARIABLE_RoleHandler() }; + static final RoleHandler[] roleHandlers = new RoleHandler[]{ new CtTypeAccess_ACCESSED_TYPE_RoleHandler(), new CtClass_ANNONYMOUS_EXECUTABLE_RoleHandler(), new CtElement_ANNOTATION_RoleHandler(), new CtAnnotation_ANNOTATION_TYPE_RoleHandler(), new CtAbstractInvocation_ARGUMENT_RoleHandler(), new CtExecutableReference_ARGUMENT_TYPE_RoleHandler(), new CtAssignment_ASSIGNED_RoleHandler(), new CtRHSReceiver_ASSIGNMENT_RoleHandler(), new CtBodyHolder_BODY_RoleHandler(), new CtSynchronized_BODY_RoleHandler(), new CtIntersectionTypeReference_BOUND_RoleHandler(), new CtWildcardReference_BOUNDING_TYPE_RoleHandler(), new CtAbstractSwitch_CASE_RoleHandler(), new CtCase_CASE_KIND_RoleHandler(), new CtExpression_CAST_RoleHandler(), new CtTry_CATCH_RoleHandler(), new CtElement_COMMENT_RoleHandler(), new CtComment_COMMENT_CONTENT_RoleHandler(), new CtJavaDocTag_COMMENT_CONTENT_RoleHandler(), new CtJavaDoc_COMMENT_TAG_RoleHandler(), new CtComment_COMMENT_TYPE_RoleHandler(), new CtConstructor_COMPACT_CONSTRUCTOR_RoleHandler(), new CtAssert_CONDITION_RoleHandler(), new CtCase_CONDITION_RoleHandler(), new CtConditional_CONDITION_RoleHandler(), new CtIf_CONDITION_RoleHandler(), new CtClass_CONSTRUCTOR_RoleHandler(), new CtPackage_CONTAINED_TYPE_RoleHandler(), new CtCompilationUnit_DECLARED_IMPORT_RoleHandler(), new CtCompilationUnit_DECLARED_MODULE_RoleHandler(), new CtCompilationUnit_DECLARED_MODULE_REF_RoleHandler(), new CtCompilationUnit_DECLARED_TYPE_RoleHandler(), new CtCompilationUnit_DECLARED_TYPE_REF_RoleHandler(), new CtExecutableReference_DECLARING_TYPE_RoleHandler(), new CtFieldReference_DECLARING_TYPE_RoleHandler(), new CtTypeReference_DECLARING_TYPE_RoleHandler(), new CtAnnotationMethod_DEFAULT_EXPRESSION_RoleHandler(), new CtCase_DEFAULT_EXPRESSION_RoleHandler(), new CtVariable_DEFAULT_EXPRESSION_RoleHandler(), new CtNewArray_DIMENSION_RoleHandler(), new CtJavaDocTag_DOCUMENTATION_TYPE_RoleHandler(), new CtJavaDocTag_DOCUMENTATION_TYPE_REALNAME_RoleHandler(), new CtConditional_ELSE_RoleHandler(), new CtIf_ELSE_RoleHandler(), new CtModifiable_EMODIFIER_RoleHandler(), new CtAbstractInvocation_EXECUTABLE_REF_RoleHandler(), new CtExecutableReferenceExpression_EXECUTABLE_REF_RoleHandler(), new CtModule_EXPORTED_PACKAGE_RoleHandler(), new CtAbstractSwitch_EXPRESSION_RoleHandler(), new CtArrayAccess_EXPRESSION_RoleHandler(), new CtAssert_EXPRESSION_RoleHandler(), new CtCase_EXPRESSION_RoleHandler(), new CtDo_EXPRESSION_RoleHandler(), new CtFor_EXPRESSION_RoleHandler(), new CtForEach_EXPRESSION_RoleHandler(), new CtLambda_EXPRESSION_RoleHandler(), new CtNewArray_EXPRESSION_RoleHandler(), new CtReturn_EXPRESSION_RoleHandler(), new CtSynchronized_EXPRESSION_RoleHandler(), new CtThrow_EXPRESSION_RoleHandler(), new CtUnaryOperator_EXPRESSION_RoleHandler(), new CtWhile_EXPRESSION_RoleHandler(), new CtYieldStatement_EXPRESSION_RoleHandler(), new CtType_FIELD_RoleHandler(), new CtTry_FINALIZER_RoleHandler(), new CtForEach_FOREACH_VARIABLE_RoleHandler(), new CtFor_FOR_INIT_RoleHandler(), new CtFor_FOR_UPDATE_RoleHandler(), new CtProvidedService_IMPLEMENTATION_TYPE_RoleHandler(), new CtImport_IMPORT_REFERENCE_RoleHandler(), new CtType_INTERFACE_RoleHandler(), new CtTypeInformation_INTERFACE_RoleHandler(), new CtMethod_IS_DEFAULT_RoleHandler(), new CtFieldReference_IS_FINAL_RoleHandler(), new CtElement_IS_IMPLICIT_RoleHandler(), new CtLocalVariable_IS_INFERRED_RoleHandler(), new CtParameter_IS_INFERRED_RoleHandler(), new CtShadowable_IS_SHADOW_RoleHandler(), new CtExecutableReference_IS_STATIC_RoleHandler(), new CtFieldReference_IS_STATIC_RoleHandler(), new CtWildcardReference_IS_UPPER_RoleHandler(), new CtParameter_IS_VARARGS_RoleHandler(), new CtJavaDocTag_JAVADOC_TAG_VALUE_RoleHandler(), new CtStatement_LABEL_RoleHandler(), new CtBinaryOperator_LEFT_OPERAND_RoleHandler(), new CtLiteral_LITERAL_BASE_RoleHandler(), new CtType_METHOD_RoleHandler(), new CtModifiable_MODIFIER_RoleHandler(), new CtModule_MODIFIER_RoleHandler(), new CtModuleRequirement_MODIFIER_RoleHandler(), new CtTypeInformation_MODIFIER_RoleHandler(), new CtModule_MODULE_DIRECTIVE_RoleHandler(), new CtModuleRequirement_MODULE_REF_RoleHandler(), new CtPackageExport_MODULE_REF_RoleHandler(), new CtMultiTypedElement_MULTI_TYPE_RoleHandler(), new CtNamedElement_NAME_RoleHandler(), new CtReference_NAME_RoleHandler(), new CtNewClass_NESTED_TYPE_RoleHandler(), new CtType_NESTED_TYPE_RoleHandler(), new CtModule_OPENED_PACKAGE_RoleHandler(), new CtPackageExport_OPENED_PACKAGE_RoleHandler(), new CtBinaryOperator_OPERATOR_KIND_RoleHandler(), new CtOperatorAssignment_OPERATOR_KIND_RoleHandler(), new CtUnaryOperator_OPERATOR_KIND_RoleHandler(), new CtCompilationUnit_PACKAGE_DECLARATION_RoleHandler(), new CtPackageDeclaration_PACKAGE_REF_RoleHandler(), new CtPackageExport_PACKAGE_REF_RoleHandler(), new CtTypeReference_PACKAGE_REF_RoleHandler(), new CtCatch_PARAMETER_RoleHandler(), new CtExecutable_PARAMETER_RoleHandler(), new CtCasePattern_PATTERN_RoleHandler(), new CtRecordPattern_PATTERN_RoleHandler(), new CtSealable_PERMITTED_TYPE_RoleHandler(), new CtElement_POSITION_RoleHandler(), new CtModule_PROVIDED_SERVICE_RoleHandler(), new CtExecutable_RECEIVER_PARAMETER_RoleHandler(), new CtRecord_RECORD_COMPONENT_RoleHandler(), new CtModule_REQUIRED_MODULE_RoleHandler(), new CtBinaryOperator_RIGHT_OPERAND_RoleHandler(), new CtModule_SERVICE_TYPE_RoleHandler(), new CtProvidedService_SERVICE_TYPE_RoleHandler(), new CtUsedService_SERVICE_TYPE_RoleHandler(), new CtCodeSnippet_SNIPPET_RoleHandler(), new CtStatementList_STATEMENT_RoleHandler(), new CtModule_SUB_PACKAGE_RoleHandler(), new CtPackage_SUB_PACKAGE_RoleHandler(), new CtType_SUPER_TYPE_RoleHandler(), new CtTypeInformation_SUPER_TYPE_RoleHandler(), new CtTargetedExpression_TARGET_RoleHandler(), new CtLabelledFlowBreak_TARGET_LABEL_RoleHandler(), new CtConditional_THEN_RoleHandler(), new CtIf_THEN_RoleHandler(), new CtExecutable_THROWN_RoleHandler(), new CtTryWithResource_TRY_RESOURCE_RoleHandler(), new CtArrayTypeReference_TYPE_RoleHandler(), new CtExecutableReference_TYPE_RoleHandler(), new CtTypedElement_TYPE_RoleHandler(), new CtVariableReference_TYPE_RoleHandler(), new CtActualTypeContainer_TYPE_ARGUMENT_RoleHandler(), new CtType_TYPE_MEMBER_RoleHandler(), new CtFormalTypeDeclarer_TYPE_PARAMETER_RoleHandler(), new CtRecordPattern_TYPE_REF_RoleHandler(), new CtTypeMemberWildcardImportReference_TYPE_REF_RoleHandler(), new CtAnnotation_VALUE_RoleHandler(), new CtEnum_VALUE_RoleHandler(), new CtLiteral_VALUE_RoleHandler(), new CtTextBlock_VALUE_RoleHandler(), new CtTypePattern_VARIABLE_RoleHandler(), new CtVariableAccess_VARIABLE_RoleHandler() }; static class CtVariableAccess_VARIABLE_RoleHandler extends SingleHandler> { private CtVariableAccess_VARIABLE_RoleHandler() { @@ -2220,9 +2218,9 @@ public void setValue(T element, U value) { } } - static class CtCasePattern_CONDITION_RoleHandler extends SingleHandler> { - private CtCasePattern_CONDITION_RoleHandler() { - super(CtRole.CONDITION, CtCasePattern.class, CtExpression.class); + static class CtCase_CONDITION_RoleHandler extends SingleHandler> { + private CtCase_CONDITION_RoleHandler() { + super(CtRole.CONDITION, CtCase.class, CtExpression.class); } @SuppressWarnings("unchecked") diff --git a/src/main/java/spoon/reflect/visitor/CtBiScannerDefault.java b/src/main/java/spoon/reflect/visitor/CtBiScannerDefault.java index c5f4745f3da..896b6b31661 100644 --- a/src/main/java/spoon/reflect/visitor/CtBiScannerDefault.java +++ b/src/main/java/spoon/reflect/visitor/CtBiScannerDefault.java @@ -182,6 +182,7 @@ public void visitCtCase(final spoon.reflect.code.CtCase caseStatement) { enter(caseStatement); biScan(spoon.reflect.path.CtRole.ANNOTATION, caseStatement.getAnnotations(), other.getAnnotations()); biScan(spoon.reflect.path.CtRole.EXPRESSION, caseStatement.getCaseExpressions(), other.getCaseExpressions()); + biScan(spoon.reflect.path.CtRole.CONDITION, caseStatement.getGuard(), other.getGuard()); biScan(spoon.reflect.path.CtRole.STATEMENT, caseStatement.getStatements(), other.getStatements()); biScan(spoon.reflect.path.CtRole.COMMENT, caseStatement.getComments(), other.getComments()); exit(caseStatement); @@ -1101,7 +1102,6 @@ public void visitCtCasePattern(spoon.reflect.code.CtCasePattern casePattern) { biScan(spoon.reflect.path.CtRole.CAST, casePattern.getTypeCasts(), other.getTypeCasts()); biScan(spoon.reflect.path.CtRole.ANNOTATION, casePattern.getAnnotations(), other.getAnnotations()); biScan(spoon.reflect.path.CtRole.PATTERN, casePattern.getPattern(), other.getPattern()); - biScan(spoon.reflect.path.CtRole.CONDITION, casePattern.getGuard(), other.getGuard()); biScan(spoon.reflect.path.CtRole.TYPE, casePattern.getType(), other.getType()); biScan(spoon.reflect.path.CtRole.COMMENT, casePattern.getComments(), other.getComments()); exit(casePattern); diff --git a/src/main/java/spoon/reflect/visitor/CtScanner.java b/src/main/java/spoon/reflect/visitor/CtScanner.java index 4637485f1ae..d90c36e46b9 100644 --- a/src/main/java/spoon/reflect/visitor/CtScanner.java +++ b/src/main/java/spoon/reflect/visitor/CtScanner.java @@ -338,6 +338,7 @@ public void visitCtCase(final CtCase caseStatement) { enter(caseStatement); scan(CtRole.ANNOTATION, caseStatement.getAnnotations()); scan(CtRole.EXPRESSION, caseStatement.getCaseExpressions()); + scan(CtRole.CONDITION, caseStatement.getGuard()); scan(CtRole.STATEMENT, caseStatement.getStatements()); scan(CtRole.COMMENT, caseStatement.getComments()); exit(caseStatement); @@ -1099,7 +1100,6 @@ public void visitCtCasePattern(CtCasePattern casePattern) { scan(CtRole.CAST, casePattern.getTypeCasts()); scan(CtRole.ANNOTATION, casePattern.getAnnotations()); scan(CtRole.PATTERN, casePattern.getPattern()); - scan(CtRole.CONDITION, casePattern.getGuard()); scan(CtRole.TYPE, casePattern.getType()); scan(CtRole.COMMENT, casePattern.getComments()); exit(casePattern); diff --git a/src/main/java/spoon/reflect/visitor/DefaultJavaPrettyPrinter.java b/src/main/java/spoon/reflect/visitor/DefaultJavaPrettyPrinter.java index b6172282896..969e27bce8b 100644 --- a/src/main/java/spoon/reflect/visitor/DefaultJavaPrettyPrinter.java +++ b/src/main/java/spoon/reflect/visitor/DefaultJavaPrettyPrinter.java @@ -653,6 +653,10 @@ public void visitCtCase(CtCase caseStatement) { } else { printer.writeKeyword("default"); } + if (caseStatement.getGuard() != null) { + printer.writeSpace().writeKeyword("when").writeSpace(); + scan(caseStatement.getGuard()); + } String separator = caseStatement.getCaseKind() == CaseKind.ARROW ? "->" : ":"; printer.writeSpace().writeSeparator(separator).incTab(); @@ -2349,10 +2353,6 @@ public void visitCtRecordComponent(CtRecordComponent recordComponent) { @Override public void visitCtCasePattern(CtCasePattern casePattern) { scan(casePattern.getPattern()); - if (casePattern.getGuard() != null) { - printer.writeSpace().writeKeyword("when").writeSpace(); - scan(casePattern.getGuard()); - } } @Override diff --git a/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java b/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java index da6441b8d9f..691eb7164ee 100644 --- a/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java +++ b/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java @@ -797,11 +797,6 @@ public void endVisit(CompilationUnitDeclaration compilationUnitDeclaration, Comp context.compilationUnitSpoon = null; } - @Override - public void endVisit(GuardedPattern guardedPattern, BlockScope scope) { - context.exit(guardedPattern); - } - @Override public boolean visit(Javadoc javadoc, BlockScope scope) { // Use a custom compiler. @@ -1742,8 +1737,13 @@ public boolean visit(CaseStatement caseStatement, BlockScope scope) { @Override public boolean visit(GuardedPattern guardedPattern, BlockScope scope) { - context.enter(factory.Core().createCasePattern(), guardedPattern); - return true; + if (guardedPattern.primaryPattern != null) { + guardedPattern.primaryPattern.traverse(this, scope); + } + if (guardedPattern.condition != null) { + guardedPattern.condition.traverse(this, scope); + } + return false; // we cover this ourselves } @Override diff --git a/src/main/java/spoon/support/compiler/jdt/ParentExiter.java b/src/main/java/spoon/support/compiler/jdt/ParentExiter.java index f0aa679a234..aeadd6ad802 100644 --- a/src/main/java/spoon/support/compiler/jdt/ParentExiter.java +++ b/src/main/java/spoon/support/compiler/jdt/ParentExiter.java @@ -511,6 +511,8 @@ public void visitCtCase(CtCase caseStatement) { } else if (child instanceof CtStatement) { caseStatement.addStatement((CtStatement) child); return; + } else if (child instanceof CtExpression guard) { + caseStatement.setGuard(guard); } super.visitCtCase(caseStatement); } @@ -544,8 +546,6 @@ public void visitCtCatchVariable(CtCatchVariable e) { public void visitCtCasePattern(CtCasePattern casePattern) { if (child instanceof CtPattern pattern) { casePattern.setPattern(pattern); - } else if (child instanceof CtExpression guard) { - casePattern.setGuard(guard); } super.visitCtCasePattern(casePattern); } diff --git a/src/main/java/spoon/support/reflect/code/CtCaseImpl.java b/src/main/java/spoon/support/reflect/code/CtCaseImpl.java index 3d3a9c30186..b4ee6c19cd6 100644 --- a/src/main/java/spoon/support/reflect/code/CtCaseImpl.java +++ b/src/main/java/spoon/support/reflect/code/CtCaseImpl.java @@ -40,6 +40,9 @@ public class CtCaseImpl extends CtStatementImpl implements CtCase { @MetamodelPropertyField(role = CtRole.DEFAULT_EXPRESSION) private boolean includesDefault = false; + @MetamodelPropertyField(role = CtRole.CONDITION) + private CtExpression guard; + @Override public void accept(CtVisitor visitor) { visitor.visitCtCase(this); @@ -124,6 +127,22 @@ public CtCase setIncludesDefault(boolean includesDefault) { return this; } + @Override + public CtExpression getGuard() { + return guard; + } + + @Override + public CtCase setGuard(CtExpression guard) { + if (guard != null) { + guard.setParent(this); + } + getFactory().getEnvironment().getModelChangeListener() + .onObjectUpdate(this, CtRole.CONDITION, guard, this.guard); + this.guard = guard; + return this; + } + @Override public T setStatements(List statements) { if (statements == null || statements.isEmpty()) { diff --git a/src/main/java/spoon/support/reflect/code/CtCasePatternImpl.java b/src/main/java/spoon/support/reflect/code/CtCasePatternImpl.java index 6c690ee9e8f..7b1b798478c 100644 --- a/src/main/java/spoon/support/reflect/code/CtCasePatternImpl.java +++ b/src/main/java/spoon/support/reflect/code/CtCasePatternImpl.java @@ -9,7 +9,6 @@ import spoon.reflect.annotations.MetamodelPropertyField; import spoon.reflect.code.CtCasePattern; -import spoon.reflect.code.CtExpression; import spoon.reflect.code.CtPattern; import spoon.reflect.path.CtRole; import spoon.reflect.visitor.CtVisitor; @@ -21,8 +20,6 @@ public class CtCasePatternImpl extends CtExpressionImpl implements CtCaseP private static final long serialVersionUID = 1L; @MetamodelPropertyField(role = CtRole.PATTERN) private CtPattern pattern; - @MetamodelPropertyField(role = CtRole.CONDITION) - private CtExpression guard; @Override public CtPattern getPattern() { @@ -40,22 +37,6 @@ public CtCasePattern setPattern(CtPattern pattern) { return this; } - @Override - public CtExpression getGuard() { - return guard; - } - - @Override - public CtCasePattern setGuard(CtExpression guard) { - if (guard != null) { - guard.setParent(this); - } - getFactory().getEnvironment().getModelChangeListener() - .onObjectUpdate(this, CtRole.CONDITION, guard, this.guard); - this.guard = guard; - return this; - } - @Override public void accept(CtVisitor visitor) { visitor.visitCtCasePattern(this); diff --git a/src/main/java/spoon/support/visitor/clone/CloneVisitor.java b/src/main/java/spoon/support/visitor/clone/CloneVisitor.java index ad616be8226..8c5aeb08858 100644 --- a/src/main/java/spoon/support/visitor/clone/CloneVisitor.java +++ b/src/main/java/spoon/support/visitor/clone/CloneVisitor.java @@ -171,6 +171,7 @@ public void visitCtCase(final spoon.reflect.code.CtCase caseStatement) { this.builder.copy(caseStatement, aCtCase); aCtCase.setAnnotations(this.cloneHelper.clone(caseStatement.getAnnotations())); aCtCase.setCaseExpressions(this.cloneHelper.clone(caseStatement.getCaseExpressions())); + aCtCase.setGuard(this.cloneHelper.clone(caseStatement.getGuard())); aCtCase.setStatements(this.cloneHelper.clone(caseStatement.getStatements())); aCtCase.setComments(this.cloneHelper.clone(caseStatement.getComments())); this.cloneHelper.tailor(caseStatement, aCtCase); @@ -1168,7 +1169,6 @@ public void visitCtCasePattern(spoon.reflect.code.CtCasePattern casePattern) { aCtCasePattern.setTypeCasts(this.cloneHelper.clone(casePattern.getTypeCasts())); aCtCasePattern.setAnnotations(this.cloneHelper.clone(casePattern.getAnnotations())); aCtCasePattern.setPattern(this.cloneHelper.clone(casePattern.getPattern())); - aCtCasePattern.setGuard(this.cloneHelper.clone(casePattern.getGuard())); aCtCasePattern.setType(this.cloneHelper.clone(casePattern.getType())); aCtCasePattern.setComments(this.cloneHelper.clone(casePattern.getComments())); this.cloneHelper.tailor(casePattern, aCtCasePattern); diff --git a/src/main/java/spoon/support/visitor/replace/ReplacementVisitor.java b/src/main/java/spoon/support/visitor/replace/ReplacementVisitor.java index 130fb14af6b..82a299e137d 100644 --- a/src/main/java/spoon/support/visitor/replace/ReplacementVisitor.java +++ b/src/main/java/spoon/support/visitor/replace/ReplacementVisitor.java @@ -40,20 +40,6 @@ public void set(spoon.reflect.reference.CtTypeReference replace) { } } - // auto-generated, see spoon.generating.ReplacementVisitorGenerator - static class CtCasePatternGuardReplaceListener implements spoon.support.visitor.replace.ReplaceListener { - private final spoon.reflect.code.CtCasePattern element; - - CtCasePatternGuardReplaceListener(spoon.reflect.code.CtCasePattern element) { - this.element = element; - } - - @java.lang.Override - public void set(spoon.reflect.code.CtExpression replace) { - this.element.setGuard(replace); - } - } - // auto-generated, see spoon.generating.ReplacementVisitorGenerator static class CtCasePatternPatternReplaceListener implements spoon.support.visitor.replace.ReplaceListener { private final spoon.reflect.code.CtCasePattern element; @@ -1160,6 +1146,20 @@ public void set(spoon.reflect.code.CtCatchVariable replace) { } } + // auto-generated, see spoon.generating.ReplacementVisitorGenerator + static class CtCaseGuardReplaceListener implements spoon.support.visitor.replace.ReplaceListener { + private final spoon.reflect.code.CtCase element; + + CtCaseGuardReplaceListener(spoon.reflect.code.CtCase element) { + this.element = element; + } + + @java.lang.Override + public void set(spoon.reflect.code.CtExpression replace) { + this.element.setGuard(replace); + } + } + // auto-generated, see spoon.generating.ReplacementVisitorGenerator static class CtCaseCaseExpressionsReplaceListener implements spoon.support.visitor.replace.ReplaceListListener { private final spoon.reflect.code.CtCase element; @@ -1690,6 +1690,7 @@ public void visitCtBreak(final spoon.reflect.code.CtBreak breakStatement) { public void visitCtCase(final spoon.reflect.code.CtCase caseStatement) { replaceInListIfExist(caseStatement.getAnnotations(), new spoon.support.visitor.replace.ReplacementVisitor.CtElementAnnotationsReplaceListener(caseStatement)); replaceInListIfExist(caseStatement.getCaseExpressions(), new spoon.support.visitor.replace.ReplacementVisitor.CtCaseCaseExpressionsReplaceListener(caseStatement)); + replaceElementIfExist(caseStatement.getGuard(), new spoon.support.visitor.replace.ReplacementVisitor.CtCaseGuardReplaceListener(caseStatement)); replaceInListIfExist(caseStatement.getStatements(), new spoon.support.visitor.replace.ReplacementVisitor.CtStatementListStatementsReplaceListener(caseStatement)); replaceInListIfExist(caseStatement.getComments(), new spoon.support.visitor.replace.ReplacementVisitor.CtElementCommentsReplaceListener(caseStatement)); } @@ -2415,7 +2416,6 @@ public void visitCtCasePattern(spoon.reflect.code.CtCasePattern casePattern) { replaceInListIfExist(casePattern.getTypeCasts(), new spoon.support.visitor.replace.ReplacementVisitor.CtExpressionTypeCastsReplaceListener(casePattern)); replaceInListIfExist(casePattern.getAnnotations(), new spoon.support.visitor.replace.ReplacementVisitor.CtElementAnnotationsReplaceListener(casePattern)); replaceElementIfExist(casePattern.getPattern(), new spoon.support.visitor.replace.ReplacementVisitor.CtCasePatternPatternReplaceListener(casePattern)); - replaceElementIfExist(casePattern.getGuard(), new spoon.support.visitor.replace.ReplacementVisitor.CtCasePatternGuardReplaceListener(casePattern)); replaceElementIfExist(casePattern.getType(), new spoon.support.visitor.replace.ReplacementVisitor.CtTypedElementTypeReplaceListener(casePattern)); replaceInListIfExist(casePattern.getComments(), new spoon.support.visitor.replace.ReplacementVisitor.CtElementCommentsReplaceListener(casePattern)); } diff --git a/src/test/java/spoon/test/api/Metamodel.java b/src/test/java/spoon/test/api/Metamodel.java index 3779efb7bf8..57ab38f9670 100644 --- a/src/test/java/spoon/test/api/Metamodel.java +++ b/src/test/java/spoon/test/api/Metamodel.java @@ -1055,6 +1055,7 @@ private static void initTypes(List types) { .field(CtRole.CASE_KIND, false, false) .field(CtRole.ANNOTATION, false, false) .field(CtRole.EXPRESSION, false, false) + .field(CtRole.CONDITION, false, false) .field(CtRole.STATEMENT, false, false) .field(CtRole.COMMENT, false, false) @@ -1371,7 +1372,6 @@ private static void initTypes(List types) { .field(CtRole.CAST, false, false) .field(CtRole.ANNOTATION, false, false) .field(CtRole.PATTERN, false, false) - .field(CtRole.CONDITION, false, false) .field(CtRole.TYPE, false, false) .field(CtRole.COMMENT, false, false) diff --git a/src/test/java/spoon/test/pattern/RecordPatternTest.java b/src/test/java/spoon/test/pattern/RecordPatternTest.java index 74b77257a61..5edbee3f952 100644 --- a/src/test/java/spoon/test/pattern/RecordPatternTest.java +++ b/src/test/java/spoon/test/pattern/RecordPatternTest.java @@ -1,7 +1,5 @@ package spoon.test.pattern; -import org.assertj.core.api.Assertions; -import org.assertj.core.api.Condition; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -21,6 +19,7 @@ import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -185,19 +184,20 @@ record Inner(Node left, Node right) implements Node {} assertEquals(cases.size(), 5); // includes default CtCasePattern c0 = assertInstanceOf(CtCasePattern.class, cases.get(0).getCaseExpression()); new Leaf("s").assertMatches(c0.getPattern()); - assertNotNull(c0.getGuard()); + assertNotNull(cases.get(0).getGuard()); + assertThat(cases.get(0).toString()).contains(" when "); // guard must be printed CtCasePattern c1 = assertInstanceOf(CtCasePattern.class, cases.get(1).getCaseExpression()); new Leaf("s").assertMatches(c1.getPattern()); - assertNull(c1.getGuard()); + assertNull(cases.get(1).getGuard()); CtCasePattern c2 = assertInstanceOf(CtCasePattern.class, cases.get(2).getCaseExpression()); new Inner(new SimpleLeaf("leaf"), new SimpleLeaf("right")).assertMatches(c2.getPattern()); - assertNull(c2.getGuard()); + assertNull(cases.get(2).getGuard()); CtCasePattern c3 = assertInstanceOf(CtCasePattern.class, cases.get(3).getCaseExpression()); new Inner(new SimpleLeaf("left"), new SimpleLeaf("right")).assertMatches(c3.getPattern()); - assertNull(c3.getGuard()); + assertNull(cases.get(3).getGuard()); } interface Node { diff --git a/src/test/java/spoon/test/pattern/SwitchPatternTest.java b/src/test/java/spoon/test/pattern/SwitchPatternTest.java index a4536842c17..408c4c15c09 100644 --- a/src/test/java/spoon/test/pattern/SwitchPatternTest.java +++ b/src/test/java/spoon/test/pattern/SwitchPatternTest.java @@ -69,7 +69,7 @@ void testCasePatternWithGuardInSwitch() { assertThat(ctCase.getIncludesDefault()).isFalse(); CtExpression caseExpression = ctCase.getCaseExpression(); assertThat(caseExpression).isInstanceOf(CtCasePattern.class); - CtExpression guard = ((CtCasePattern) caseExpression).getGuard(); + CtExpression guard = ctCase.getGuard(); assertThat(guard).isInstanceOf(CtBinaryOperator.class); CtPattern pattern = ((CtCasePattern) caseExpression).getPattern(); diff --git a/src/test/java/spoon/testing/assertions/CtCaseAssertInterface.java b/src/test/java/spoon/testing/assertions/CtCaseAssertInterface.java index 75d506bb144..278d2a56728 100644 --- a/src/test/java/spoon/testing/assertions/CtCaseAssertInterface.java +++ b/src/test/java/spoon/testing/assertions/CtCaseAssertInterface.java @@ -16,6 +16,10 @@ default ObjectAssert getCaseKind() { return Assertions.assertThatObject(actual().getCaseKind()); } + default CtExpressionAssertInterface getGuard() { + return SpoonAssertions.assertThat(actual().getGuard()); + } + default AbstractBooleanAssert getIncludesDefault() { return Assertions.assertThat(actual().getIncludesDefault()); } diff --git a/src/test/java/spoon/testing/assertions/CtCasePatternAssertInterface.java b/src/test/java/spoon/testing/assertions/CtCasePatternAssertInterface.java index 4f3f8d45cc0..a5bfa9cb15b 100644 --- a/src/test/java/spoon/testing/assertions/CtCasePatternAssertInterface.java +++ b/src/test/java/spoon/testing/assertions/CtCasePatternAssertInterface.java @@ -2,10 +2,6 @@ import org.assertj.core.api.AbstractObjectAssert; import spoon.reflect.code.CtCasePattern; public interface CtCasePatternAssertInterface, W extends CtCasePattern> extends SpoonAssert , CtExpressionAssertInterface { - default CtExpressionAssertInterface getGuard() { - return SpoonAssertions.assertThat(actual().getGuard()); - } - default CtPatternAssertInterface getPattern() { return SpoonAssertions.assertThat(actual().getPattern()); }