diff --git a/src/main/java/spoon/reflect/declaration/CtMultiTypedElement.java b/src/main/java/spoon/reflect/declaration/CtMultiTypedElement.java index a78ff54256a..b80fbbdc164 100644 --- a/src/main/java/spoon/reflect/declaration/CtMultiTypedElement.java +++ b/src/main/java/spoon/reflect/declaration/CtMultiTypedElement.java @@ -22,7 +22,7 @@ import java.util.List; -import static spoon.reflect.path.CtRole.TYPE; +import static spoon.reflect.path.CtRole.MULTI_TYPE; /** * Defined an element with several types. @@ -31,24 +31,24 @@ public interface CtMultiTypedElement extends CtElement { /** * Adds a type for the element. */ - @PropertySetter(role = TYPE) + @PropertySetter(role = MULTI_TYPE) T addMultiType(CtTypeReference ref); /** * Removes a type for the element. */ - @PropertySetter(role = TYPE) + @PropertySetter(role = MULTI_TYPE) boolean removeMultiType(CtTypeReference ref); /** * Gets all types of the element. */ - @PropertyGetter(role = TYPE) + @PropertyGetter(role = MULTI_TYPE) List> getMultiTypes(); /** * Adds a type for the element. */ - @PropertySetter(role = TYPE) + @PropertySetter(role = MULTI_TYPE) T setMultiTypes(List> types); } diff --git a/src/main/java/spoon/reflect/meta/impl/ModelRoleHandlers.java b/src/main/java/spoon/reflect/meta/impl/ModelRoleHandlers.java index cf328881c4d..e176058358a 100644 --- a/src/main/java/spoon/reflect/meta/impl/ModelRoleHandlers.java +++ b/src/main/java/spoon/reflect/meta/impl/ModelRoleHandlers.java @@ -17,6 +17,7 @@ package spoon.reflect.meta.impl; +import java.lang.annotation.Annotation; import spoon.reflect.code.BinaryOperatorKind; import spoon.reflect.code.CtAbstractInvocation; import spoon.reflect.code.CtArrayAccess; @@ -108,8 +109,6 @@ import spoon.reflect.reference.CtTypeReference; import spoon.reflect.reference.CtVariableReference; -import java.lang.annotation.Annotation; - /** * Contains implementations of {@link RoleHandler}s for all {@link CtRole}s of all model elements @@ -1431,6 +1430,23 @@ public void setValue(T element, U value) { } } + static class CtMultiTypedElement_MULTI_TYPE_RoleHandler extends ListHandler> { + private CtMultiTypedElement_MULTI_TYPE_RoleHandler() { + super(CtRole.MULTI_TYPE, CtMultiTypedElement.class, CtTypeReference.class); + } + + @SuppressWarnings("unchecked") + @Override + public U getValue(T element) { + return ((U) ((Object) (castTarget(element).getMultiTypes()))); + } + + @Override + public void setValue(T element, U value) { + castTarget(element).setMultiTypes(castValue(value)); + } + } + static class CtNamedElement_NAME_RoleHandler extends SingleHandler { private CtNamedElement_NAME_RoleHandler() { super(CtRole.NAME, CtNamedElement.class, String.class); @@ -1987,23 +2003,6 @@ public void setValue(T element, U value) { } } - static class CtMultiTypedElement_TYPE_RoleHandler extends ListHandler> { - private CtMultiTypedElement_TYPE_RoleHandler() { - super(CtRole.TYPE, CtMultiTypedElement.class, CtTypeReference.class); - } - - @SuppressWarnings("unchecked") - @Override - public U getValue(T element) { - return ((U) ((Object) (castTarget(element).getMultiTypes()))); - } - - @Override - public void setValue(T element, U value) { - castTarget(element).setMultiTypes(castValue(value)); - } - } - static class CtTypedElement_TYPE_RoleHandler extends SingleHandler> { private CtTypedElement_TYPE_RoleHandler() { super(CtRole.TYPE, CtTypedElement.class, CtTypeReference.class); @@ -2160,6 +2159,6 @@ public void setValue(T element, U value) { 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 CtTypeParameterReference_BOUNDING_TYPE_RoleHandler(), new CtSwitch_CASE_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 CtAssert_CONDITION_RoleHandler(), new CtConditional_CONDITION_RoleHandler(), new CtIf_CONDITION_RoleHandler(), new CtClass_CONSTRUCTOR_RoleHandler(), new CtPackage_CONTAINED_TYPE_RoleHandler(), new CtExecutableReference_DECLARING_TYPE_RoleHandler(), new CtFieldReference_DECLARING_TYPE_RoleHandler(), new CtTypeReference_DECLARING_TYPE_RoleHandler(), new CtAnnotationMethod_DEFAULT_EXPRESSION_RoleHandler(), new CtVariable_DEFAULT_EXPRESSION_RoleHandler(), new CtNewArray_DIMENSION_RoleHandler(), new CtJavaDocTag_DOCUMENTATION_TYPE_RoleHandler(), new CtConditional_ELSE_RoleHandler(), new CtIf_ELSE_RoleHandler(), new CtAbstractInvocation_EXECUTABLE_REF_RoleHandler(), new CtExecutableReferenceExpression_EXECUTABLE_REF_RoleHandler(), new CtModule_EXPORTED_PACKAGE_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 CtSwitch_EXPRESSION_RoleHandler(), new CtSynchronized_EXPRESSION_RoleHandler(), new CtThrow_EXPRESSION_RoleHandler(), new CtUnaryOperator_EXPRESSION_RoleHandler(), new CtWhile_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 CtTypeInformation_INTERFACE_RoleHandler(), new CtMethod_IS_DEFAULT_RoleHandler(), new CtFieldReference_IS_FINAL_RoleHandler(), new CtElement_IS_IMPLICIT_RoleHandler(), new CtShadowable_IS_SHADOW_RoleHandler(), new CtExecutableReference_IS_STATIC_RoleHandler(), new CtFieldReference_IS_STATIC_RoleHandler(), new CtTypeParameterReference_IS_UPPER_RoleHandler(), new CtParameter_IS_VARARGS_RoleHandler(), new CtJavaDocTag_JAVADOC_TAG_VALUE_RoleHandler(), new CtStatement_LABEL_RoleHandler(), new CtBinaryOperator_LEFT_OPERAND_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 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 CtPackageExport_PACKAGE_REF_RoleHandler(), new CtTypeReference_PACKAGE_REF_RoleHandler(), new CtCatch_PARAMETER_RoleHandler(), new CtExecutable_PARAMETER_RoleHandler(), new CtElement_POSITION_RoleHandler(), new CtModule_PROVIDED_SERVICE_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 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 CtMultiTypedElement_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 CtAnnotation_VALUE_RoleHandler(), new CtEnum_VALUE_RoleHandler(), new CtLiteral_VALUE_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 CtTypeParameterReference_BOUNDING_TYPE_RoleHandler(), new CtSwitch_CASE_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 CtAssert_CONDITION_RoleHandler(), new CtConditional_CONDITION_RoleHandler(), new CtIf_CONDITION_RoleHandler(), new CtClass_CONSTRUCTOR_RoleHandler(), new CtPackage_CONTAINED_TYPE_RoleHandler(), new CtExecutableReference_DECLARING_TYPE_RoleHandler(), new CtFieldReference_DECLARING_TYPE_RoleHandler(), new CtTypeReference_DECLARING_TYPE_RoleHandler(), new CtAnnotationMethod_DEFAULT_EXPRESSION_RoleHandler(), new CtVariable_DEFAULT_EXPRESSION_RoleHandler(), new CtNewArray_DIMENSION_RoleHandler(), new CtJavaDocTag_DOCUMENTATION_TYPE_RoleHandler(), new CtConditional_ELSE_RoleHandler(), new CtIf_ELSE_RoleHandler(), new CtAbstractInvocation_EXECUTABLE_REF_RoleHandler(), new CtExecutableReferenceExpression_EXECUTABLE_REF_RoleHandler(), new CtModule_EXPORTED_PACKAGE_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 CtSwitch_EXPRESSION_RoleHandler(), new CtSynchronized_EXPRESSION_RoleHandler(), new CtThrow_EXPRESSION_RoleHandler(), new CtUnaryOperator_EXPRESSION_RoleHandler(), new CtWhile_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 CtTypeInformation_INTERFACE_RoleHandler(), new CtMethod_IS_DEFAULT_RoleHandler(), new CtFieldReference_IS_FINAL_RoleHandler(), new CtElement_IS_IMPLICIT_RoleHandler(), new CtShadowable_IS_SHADOW_RoleHandler(), new CtExecutableReference_IS_STATIC_RoleHandler(), new CtFieldReference_IS_STATIC_RoleHandler(), new CtTypeParameterReference_IS_UPPER_RoleHandler(), new CtParameter_IS_VARARGS_RoleHandler(), new CtJavaDocTag_JAVADOC_TAG_VALUE_RoleHandler(), new CtStatement_LABEL_RoleHandler(), new CtBinaryOperator_LEFT_OPERAND_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 CtPackageExport_PACKAGE_REF_RoleHandler(), new CtTypeReference_PACKAGE_REF_RoleHandler(), new CtCatch_PARAMETER_RoleHandler(), new CtExecutable_PARAMETER_RoleHandler(), new CtElement_POSITION_RoleHandler(), new CtModule_PROVIDED_SERVICE_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 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 CtAnnotation_VALUE_RoleHandler(), new CtEnum_VALUE_RoleHandler(), new CtLiteral_VALUE_RoleHandler(), new CtVariableAccess_VARIABLE_RoleHandler() }; } diff --git a/src/main/java/spoon/reflect/path/CtRole.java b/src/main/java/spoon/reflect/path/CtRole.java index a5e83d971d9..28680c9d811 100644 --- a/src/main/java/spoon/reflect/path/CtRole.java +++ b/src/main/java/spoon/reflect/path/CtRole.java @@ -26,6 +26,7 @@ public enum CtRole { NAME, TYPE, + MULTI_TYPE, DECLARING_TYPE, CONTAINED_TYPE, BODY, diff --git a/src/main/java/spoon/reflect/visitor/CtBiScannerDefault.java b/src/main/java/spoon/reflect/visitor/CtBiScannerDefault.java index 205e815507c..af8ee444eaf 100644 --- a/src/main/java/spoon/reflect/visitor/CtBiScannerDefault.java +++ b/src/main/java/spoon/reflect/visitor/CtBiScannerDefault.java @@ -463,7 +463,7 @@ public void visitCtCatchVariable(final spoon.reflect.code.CtCatchVariable enter(catchVariable); biScan(spoon.reflect.path.CtRole.COMMENT, catchVariable.getComments(), other.getComments()); biScan(spoon.reflect.path.CtRole.ANNOTATION, catchVariable.getAnnotations(), other.getAnnotations()); - biScan(spoon.reflect.path.CtRole.TYPE, catchVariable.getMultiTypes(), other.getMultiTypes()); + biScan(spoon.reflect.path.CtRole.MULTI_TYPE, catchVariable.getMultiTypes(), other.getMultiTypes()); exit(catchVariable); } diff --git a/src/main/java/spoon/reflect/visitor/CtScanner.java b/src/main/java/spoon/reflect/visitor/CtScanner.java index 655022829c2..613d0d32cc4 100644 --- a/src/main/java/spoon/reflect/visitor/CtScanner.java +++ b/src/main/java/spoon/reflect/visitor/CtScanner.java @@ -534,7 +534,7 @@ public void visitCtCatchVariable(final CtCatchVariable catchVariable) { enter(catchVariable); scan(CtRole.COMMENT, catchVariable.getComments()); scan(CtRole.ANNOTATION, catchVariable.getAnnotations()); - scan(CtRole.TYPE, catchVariable.getMultiTypes()); + scan(CtRole.MULTI_TYPE, catchVariable.getMultiTypes()); exit(catchVariable); } diff --git a/src/main/java/spoon/support/reflect/code/CtCatchVariableImpl.java b/src/main/java/spoon/support/reflect/code/CtCatchVariableImpl.java index 91a6a2fa7ce..68a4051f009 100644 --- a/src/main/java/spoon/support/reflect/code/CtCatchVariableImpl.java +++ b/src/main/java/spoon/support/reflect/code/CtCatchVariableImpl.java @@ -43,7 +43,7 @@ import static spoon.reflect.ModelElementContainerDefaultCapacities.CATCH_VARIABLE_MULTI_TYPES_CONTAINER_DEFAULT_CAPACITY; import static spoon.reflect.path.CtRole.NAME; -import static spoon.reflect.path.CtRole.TYPE; +import static spoon.reflect.path.CtRole.MULTI_TYPE; public class CtCatchVariableImpl extends CtCodeElementImpl implements CtCatchVariable { private static final long serialVersionUID = 1L; @@ -51,7 +51,7 @@ public class CtCatchVariableImpl extends CtCodeElementImpl implements CtCatch @MetamodelPropertyField(role = CtRole.NAME) String name = ""; - @MetamodelPropertyField(role = CtRole.TYPE) + @MetamodelPropertyField(role = MULTI_TYPE) List> types = emptyList(); @MetamodelPropertyField(role = CtRole.MODIFIER) @@ -138,7 +138,7 @@ public T addMultiType(CtTypeReference type) { types = new ArrayList<>(CATCH_VARIABLE_MULTI_TYPES_CONTAINER_DEFAULT_CAPACITY); } type.setParent(this); - getFactory().getEnvironment().getModelChangeListener().onListAdd(this, TYPE, this.types, type); + getFactory().getEnvironment().getModelChangeListener().onListAdd(this, MULTI_TYPE, this.types, type); types.add(type); return (T) this; } @@ -148,7 +148,7 @@ public boolean removeMultiType(CtTypeReference ref) { if (this.types == CtElementImpl.>emptyList()) { return false; } - getFactory().getEnvironment().getModelChangeListener().onListDelete(this, TYPE, types, types.indexOf(ref), ref); + getFactory().getEnvironment().getModelChangeListener().onListDelete(this, MULTI_TYPE, types, types.indexOf(ref), ref); return types.remove(ref); } @@ -159,7 +159,7 @@ public List> getMultiTypes() { @Override public T setMultiTypes(List> types) { - getFactory().getEnvironment().getModelChangeListener().onListDeleteAll(this, TYPE, this.types, new ArrayList<>(this.types)); + getFactory().getEnvironment().getModelChangeListener().onListDeleteAll(this, MULTI_TYPE, this.types, new ArrayList<>(this.types)); if (types == null || types.isEmpty()) { this.types = CtElementImpl.emptyList(); return (T) this; diff --git a/src/test/java/spoon/test/main/MainTest.java b/src/test/java/spoon/test/main/MainTest.java index ff5a096d7de..e1497778274 100644 --- a/src/test/java/spoon/test/main/MainTest.java +++ b/src/test/java/spoon/test/main/MainTest.java @@ -41,6 +41,7 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayDeque; +import java.util.Collection; import java.util.Deque; import java.util.HashSet; import java.util.IdentityHashMap; @@ -52,6 +53,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; public class MainTest { @@ -439,6 +441,38 @@ public void scan(CtRole role, CtElement element) { }); } + @Test + public void testElementIsContainedInAttributeOfItsParent() { + rootPackage.accept(new CtScanner() { + @Override + public void scan(CtRole role, CtElement element) { + if (element != null) { + //contract: element is contained in attribute of element's parent + CtElement parent = element.getParent(); + Object attributeOfParent = parent.getValueByRole(role); + if(attributeOfParent instanceof CtElement) { + assertSame("Element of type " + element.getClass().getName() + + " is not the value of attribute of role " + role.name() + + " of parent type " + parent.getClass().getName(), element, attributeOfParent); + } else if (attributeOfParent instanceof Collection) { + assertTrue("Element of type " + element.getClass().getName() + + " not found in Collection value of attribute of role " + role.name() + + " of parent type " + parent.getClass().getName(), + ((Collection) attributeOfParent).stream().anyMatch(e -> e == element)); + } else if (attributeOfParent instanceof Map){ + assertTrue("Element of type " + element.getClass().getName() + + " not found in Map#values of attribute of role " + role.name() + + " of parent type " + parent.getClass().getName(), + ((Map) attributeOfParent).values().stream().anyMatch(e -> e == element)); + } else { + fail("Attribute of Role " + role + " not checked"); + } + } + super.scan(role, element); + } + }); + } + @Test public void testTest() throws Exception { // the tests should be spoonable