From 34c3b2e4f55f0ed7313dc3d62c94fabad045c0a8 Mon Sep 17 00:00:00 2001
From: Pavel Vojtechovsky
Date: Sat, 3 Mar 2018 11:48:11 +0100
Subject: [PATCH 001/131] feat: Metamodel provides metadata about Spoon types
and fields
---
src/main/java/spoon/Metamodel.java | 1248 +++++++++++++++++
.../spoon/generating/MetamodelGenerator.java | 115 ++
.../java/spoon/test/api/MetamodelTest.java | 36 +
3 files changed, 1399 insertions(+)
create mode 100644 src/test/java/spoon/generating/MetamodelGenerator.java
diff --git a/src/main/java/spoon/Metamodel.java b/src/main/java/spoon/Metamodel.java
index fd67e6b3ed8..7bda0513a56 100644
--- a/src/main/java/spoon/Metamodel.java
+++ b/src/main/java/spoon/Metamodel.java
@@ -16,17 +16,35 @@
*/
package spoon;
+import spoon.reflect.code.CtForEach;
+import spoon.reflect.declaration.CtClass;
+import spoon.reflect.declaration.CtElement;
+import spoon.reflect.declaration.CtInterface;
import spoon.reflect.declaration.CtModuleDirective;
import spoon.reflect.declaration.CtPackageExport;
import spoon.reflect.declaration.CtProvidedService;
import spoon.reflect.declaration.CtType;
import spoon.reflect.factory.Factory;
import spoon.reflect.factory.FactoryImpl;
+import spoon.reflect.meta.ContainerKind;
+import spoon.reflect.meta.RoleHandler;
+import spoon.reflect.meta.impl.RoleHandlerHelper;
+import spoon.reflect.path.CtRole;
+import spoon.reflect.visitor.CtScanner;
import spoon.support.DefaultCoreFactory;
import spoon.support.StandardEnvironment;
+import spoon.support.reflect.code.CtForEachImpl;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
+import java.util.function.Consumer;
/**
* This class enables to reason on the Spoon metamodel directly
@@ -161,4 +179,1234 @@ public static Set> getAllMetamodelInterfaces() {
return result;
}
+ public static Collection getAllMetamodelTypes() {
+ return typesByName.values();
+ }
+
+ public static Type getMetamodelTypeByClass(Class extends CtElement> clazz) {
+ return typesByClass.get(clazz);
+ }
+
+ /**
+ * Describes a Spoon metamodel type
+ */
+ public static class Type {
+ /**
+ * Name of the type
+ */
+ private final String name;
+
+ /**
+ * The {@link CtClass} linked to this {@link MMType}. Is null in case of class without interface
+ */
+ private final Class extends CtElement> modelClass;
+ /**
+ * The {@link CtInterface} linked to this {@link MMType}. Is null in case of interface without class
+ */
+ private final Class extends CtElement> modelInterface;
+
+ private final List fields;
+ private final Map fieldsByRole;
+
+ private Type(String name, Class extends CtElement> modelInterface, Class extends CtElement> modelClass, Consumer fieldsCreator) {
+ super();
+ this.name = name;
+ this.modelClass = modelClass;
+ this.modelInterface = modelInterface;
+ List fields = new ArrayList<>();
+ this.fields = Collections.unmodifiableList(fields);
+ fieldsCreator.accept(new FieldMaker() {
+ @Override
+ public FieldMaker field(CtRole role, boolean derived, boolean unsettable) {
+ fields.add(new Field(Type.this, role, derived, unsettable));
+ return this;
+ }
+ });
+ Map fieldsByRole = new LinkedHashMap<>(fields.size());
+ fields.forEach(f -> fieldsByRole.put(f.getRole(), f));
+ this.fieldsByRole = Collections.unmodifiableMap(fieldsByRole);
+ }
+
+ /**
+ * @return interface name of Spoon model type. For example CtClass, CtForEach, ...
+ * It is never followed by xxxImpl
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return {@link Class} which implements this type. For example {@link CtForEachImpl}
+ */
+ public Class> getModelClass() {
+ return modelClass;
+ }
+ /**
+ * @return {@link Class} which defines interface of this type. For example {@link CtForEach}
+ */
+ public Class> getModelInterface() {
+ return modelInterface;
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+
+ /**
+ * @return {@link List} of {@link Field}s of this spoon model {@link Type} in the same order, like they are processed by {@link CtScanner}
+ */
+ public List getFields() {
+ return fields;
+ }
+
+ /**
+ * @param role the {@link CtRole} of to be returned {@link Field}
+ * @return {@link Field} of this {@link Type} by {@link CtRole} or null if this {@link CtRole} doesn't exist on this {@link Type}
+ */
+ public Field getField(CtRole role) {
+ return fieldsByRole.get(role);
+ }
+ }
+ /**
+ * Describes a Spoon metamodel Field
+ */
+ public static class Field {
+ private final Type owner;
+ private final CtRole role;
+ private final RoleHandler roleHandler;
+ private final boolean derived;
+ private final boolean unsettable;
+
+ private Field(Type owner, CtRole role, boolean derived, boolean unsettable) {
+ super();
+ this.owner = owner;
+ this.role = role;
+ this.derived = derived;
+ this.unsettable = unsettable;
+ this.roleHandler = RoleHandlerHelper.getRoleHandler(owner.modelClass, role);
+ }
+
+ /**
+ * @return {@link Type}, which contains this {@link Field}
+ */
+ public Type getOwner() {
+ return owner;
+ }
+
+ /**
+ * @return {@link CtRole} of this {@link Field}
+ */
+ public CtRole getRole() {
+ return role;
+ }
+
+ /**
+ * @return {@link RoleHandler} providing generic access to the value of this Field
+ */
+ public RoleHandler getRoleHandler() {
+ return roleHandler;
+ }
+
+ /**
+ * @return true if this field is derived (value is somehow computed)
+ */
+ public boolean isDerived() {
+ return derived;
+ }
+
+ /**
+ * @return true if it makes no sense to set this field on this type
+ */
+ public boolean isUnsettable() {
+ return unsettable;
+ }
+
+ /**
+ * @param element an instance whose attribute value is read
+ * @return a value of attribute defined by this {@link Field} from the provided `element`
+ */
+ public U getValue(T element) {
+ return roleHandler.getValue(element);
+ }
+
+ /**
+ * @param element an instance whose attribute value is set
+ * @param value to be set value of attribute defined by this {@link Field} on the provided `element`
+ */
+ public void setValue(T element, U value) {
+ roleHandler.setValue(element, value);
+ }
+
+ /**
+ * @return {@link Class} of {@link Field}'s value.
+ */
+ public Class> getValueClass() {
+ return roleHandler.getValueClass();
+ }
+
+ /**
+ * @return the container kind, to know whether an element, a list, a map, etc is returned.
+ */
+ public ContainerKind getContainerKind() {
+ return roleHandler.getContainerKind();
+ }
+
+ @Override
+ public String toString() {
+ return getOwner().toString() + "#" + getRole().getCamelCaseName();
+ }
+ }
+
+ private interface FieldMaker {
+ /**
+ * Creates a instance of Field in Type
+ * @param role a role of the {@link Field}
+ * @param derived marker if field is derived
+ * @param unsettable marker if field is unsettable
+ * @return this to support fluent API
+ */
+ FieldMaker field(CtRole role, boolean derived, boolean unsettable);
+ }
+
+ private static final Map typesByName = new HashMap<>();
+ private static final Map, Type> typesByClass = new HashMap<>();
+
+ static {
+ List types = new ArrayList<>();
+ initTypes(types);
+ types.forEach(type -> {
+ typesByName.put(type.getName(), type);
+ typesByClass.put(type.getModelClass(), type);
+ typesByClass.put(type.getModelInterface(), type);
+ });
+ }
+ private static void initTypes(List types) {
+ /**
+ * body of this method was generated by /spoon-core/src/test/java/spoon/generating/MetamodelGenerator.java
+ * Run the method main and copy the System output here
+ */
+ types.add(new Type("CtConditional", spoon.reflect.code.CtConditional.class, spoon.support.reflect.code.CtConditionalImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.CONDITION, false, false)
+ .field(CtRole.THEN, false, false)
+ .field(CtRole.ELSE, false, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.CAST, false, false)
+
+ ));
+
+ types.add(new Type("CtProvidedService", spoon.reflect.declaration.CtProvidedService.class, spoon.support.reflect.declaration.CtProvidedServiceImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.SERVICE_TYPE, false, false)
+ .field(CtRole.IMPLEMENTATION_TYPE, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+
+ ));
+
+ types.add(new Type("CtParameter", spoon.reflect.declaration.CtParameter.class, spoon.support.reflect.declaration.CtParameterImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.IS_VARARGS, false, false)
+ .field(CtRole.DEFAULT_EXPRESSION, true, true)
+ .field(CtRole.MODIFIER, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtWhile", spoon.reflect.code.CtWhile.class, spoon.support.reflect.code.CtWhileImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.EXPRESSION, false, false)
+ .field(CtRole.BODY, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtTypeReference", spoon.reflect.reference.CtTypeReference.class, spoon.support.reflect.reference.CtTypeReferenceImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.MODIFIER, false, true)
+ .field(CtRole.INTERFACE, true, true)
+ .field(CtRole.SUPER_TYPE, true, true)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.PACKAGE_REF, false, false)
+ .field(CtRole.DECLARING_TYPE, false, false)
+ .field(CtRole.TYPE_ARGUMENT, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.COMMENT, false, true)
+
+ ));
+
+ types.add(new Type("CtCatchVariableReference", spoon.reflect.reference.CtCatchVariableReference.class, spoon.support.reflect.reference.CtCatchVariableReferenceImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.COMMENT, false, true)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+
+ ));
+
+ types.add(new Type("CtContinue", spoon.reflect.code.CtContinue.class, spoon.support.reflect.code.CtContinueImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.TARGET_LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtInterface", spoon.reflect.declaration.CtInterface.class, spoon.support.reflect.declaration.CtInterfaceImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.MODIFIER, false, false)
+ .field(CtRole.SUPER_TYPE, true, true)
+ .field(CtRole.NESTED_TYPE, true, false)
+ .field(CtRole.METHOD, true, false)
+ .field(CtRole.FIELD, true, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.INTERFACE, false, false)
+ .field(CtRole.TYPE_PARAMETER, false, false)
+ .field(CtRole.TYPE_MEMBER, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtAssignment", spoon.reflect.code.CtAssignment.class, spoon.support.reflect.code.CtAssignmentImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.ASSIGNED, false, false)
+ .field(CtRole.ASSIGNMENT, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtBinaryOperator", spoon.reflect.code.CtBinaryOperator.class, spoon.support.reflect.code.CtBinaryOperatorImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.OPERATOR_KIND, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.LEFT_OPERAND, false, false)
+ .field(CtRole.RIGHT_OPERAND, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtEnumValue", spoon.reflect.declaration.CtEnumValue.class, spoon.support.reflect.declaration.CtEnumValueImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.ASSIGNMENT, true, true)
+ .field(CtRole.MODIFIER, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.DEFAULT_EXPRESSION, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtModuleRequirement", spoon.reflect.declaration.CtModuleRequirement.class, spoon.support.reflect.declaration.CtModuleRequirementImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.MODIFIER, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.MODULE_REF, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+
+ ));
+
+ types.add(new Type("CtForEach", spoon.reflect.code.CtForEach.class, spoon.support.reflect.code.CtForEachImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.FOREACH_VARIABLE, false, false)
+ .field(CtRole.EXPRESSION, false, false)
+ .field(CtRole.BODY, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtConstructor", spoon.reflect.declaration.CtConstructor.class, spoon.support.reflect.declaration.CtConstructorImpl.class, fm -> fm
+ .field(CtRole.NAME, false, true)
+ .field(CtRole.TYPE, true, true)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.MODIFIER, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.PARAMETER, false, false)
+ .field(CtRole.THROWN, false, false)
+ .field(CtRole.TYPE_PARAMETER, false, false)
+ .field(CtRole.BODY, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtSuperAccess", spoon.reflect.code.CtSuperAccess.class, spoon.support.reflect.code.CtSuperAccessImpl.class, fm -> fm
+ .field(CtRole.TYPE, true, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.TARGET, false, false)
+ .field(CtRole.VARIABLE, false, false)
+
+ ));
+
+ types.add(new Type("CtAnonymousExecutable", spoon.reflect.declaration.CtAnonymousExecutable.class, spoon.support.reflect.declaration.CtAnonymousExecutableImpl.class, fm -> fm
+ .field(CtRole.NAME, false, true)
+ .field(CtRole.TYPE, true, true)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.PARAMETER, true, true)
+ .field(CtRole.THROWN, true, true)
+ .field(CtRole.MODIFIER, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.BODY, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtComment", spoon.reflect.code.CtComment.class, spoon.support.reflect.code.CtCommentImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.COMMENT_CONTENT, false, false)
+ .field(CtRole.COMMENT_TYPE, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+
+ ));
+
+ types.add(new Type("CtWildcardReference", spoon.reflect.reference.CtWildcardReference.class, spoon.support.reflect.reference.CtWildcardReferenceImpl.class, fm -> fm
+ .field(CtRole.NAME, false, true)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_UPPER, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.MODIFIER, false, true)
+ .field(CtRole.COMMENT, false, true)
+ .field(CtRole.INTERFACE, true, true)
+ .field(CtRole.SUPER_TYPE, true, true)
+ .field(CtRole.TYPE_ARGUMENT, true, true)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.PACKAGE_REF, false, false)
+ .field(CtRole.DECLARING_TYPE, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.BOUNDING_TYPE, false, false)
+
+ ));
+
+ types.add(new Type("CtThisAccess", spoon.reflect.code.CtThisAccess.class, spoon.support.reflect.code.CtThisAccessImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.TARGET, false, false)
+
+ ));
+
+ types.add(new Type("CtArrayWrite", spoon.reflect.code.CtArrayWrite.class, spoon.support.reflect.code.CtArrayWriteImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.TARGET, false, false)
+ .field(CtRole.EXPRESSION, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtPackageReference", spoon.reflect.reference.CtPackageReference.class, spoon.support.reflect.reference.CtPackageReferenceImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.COMMENT, false, true)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+
+ ));
+
+ types.add(new Type("CtJavaDoc", spoon.reflect.code.CtJavaDoc.class, spoon.support.reflect.code.CtJavaDocImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.COMMENT_CONTENT, false, false)
+ .field(CtRole.COMMENT_TYPE, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.COMMENT_TAG, false, false)
+
+ ));
+
+ types.add(new Type("CtArrayRead", spoon.reflect.code.CtArrayRead.class, spoon.support.reflect.code.CtArrayReadImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.TARGET, false, false)
+ .field(CtRole.EXPRESSION, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtStatementList", spoon.reflect.code.CtStatementList.class, spoon.support.reflect.code.CtStatementListImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.STATEMENT, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtVariableWrite", spoon.reflect.code.CtVariableWrite.class, spoon.support.reflect.code.CtVariableWriteImpl.class, fm -> fm
+ .field(CtRole.TYPE, true, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.VARIABLE, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtParameterReference", spoon.reflect.reference.CtParameterReference.class, spoon.support.reflect.reference.CtParameterReferenceImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.COMMENT, false, true)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+
+ ));
+
+ types.add(new Type("CtOperatorAssignment", spoon.reflect.code.CtOperatorAssignment.class, spoon.support.reflect.code.CtOperatorAssignmentImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.OPERATOR_KIND, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.ASSIGNED, false, false)
+ .field(CtRole.ASSIGNMENT, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtAnnotationFieldAccess", spoon.reflect.code.CtAnnotationFieldAccess.class, spoon.support.reflect.code.CtAnnotationFieldAccessImpl.class, fm -> fm
+ .field(CtRole.TYPE, true, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.TARGET, false, false)
+ .field(CtRole.VARIABLE, false, false)
+
+ ));
+
+ types.add(new Type("CtUnboundVariableReference", spoon.reflect.reference.CtUnboundVariableReference.class, spoon.support.reflect.reference.CtUnboundVariableReferenceImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.COMMENT, false, true)
+ .field(CtRole.ANNOTATION, true, true)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.TYPE, false, false)
+
+ ));
+
+ types.add(new Type("CtAnnotationMethod", spoon.reflect.declaration.CtAnnotationMethod.class, spoon.support.reflect.declaration.CtAnnotationMethodImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.BODY, true, true)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.IS_DEFAULT, false, false)
+ .field(CtRole.PARAMETER, true, true)
+ .field(CtRole.THROWN, true, true)
+ .field(CtRole.MODIFIER, false, false)
+ .field(CtRole.TYPE_PARAMETER, true, true)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.DEFAULT_EXPRESSION, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtClass", spoon.reflect.declaration.CtClass.class, spoon.support.reflect.declaration.CtClassImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, true)
+ .field(CtRole.MODIFIER, false, false)
+ .field(CtRole.NESTED_TYPE, true, false)
+ .field(CtRole.CONSTRUCTOR, true, false)
+ .field(CtRole.METHOD, true, false)
+ .field(CtRole.ANNONYMOUS_EXECUTABLE, true, false)
+ .field(CtRole.FIELD, true, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.SUPER_TYPE, false, false)
+ .field(CtRole.INTERFACE, false, false)
+ .field(CtRole.TYPE_PARAMETER, false, false)
+ .field(CtRole.TYPE_MEMBER, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtBlock", spoon.reflect.code.CtBlock.class, spoon.support.reflect.code.CtBlockImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.STATEMENT, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtPackage", spoon.reflect.declaration.CtPackage.class, spoon.support.reflect.declaration.CtPackageImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.SUB_PACKAGE, false, false)
+ .field(CtRole.CONTAINED_TYPE, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtTryWithResource", spoon.reflect.code.CtTryWithResource.class, spoon.support.reflect.code.CtTryWithResourceImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TRY_RESOURCE, false, false)
+ .field(CtRole.BODY, false, false)
+ .field(CtRole.CATCH, false, false)
+ .field(CtRole.FINALIZER, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtAssert", spoon.reflect.code.CtAssert.class, spoon.support.reflect.code.CtAssertImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.CONDITION, false, false)
+ .field(CtRole.EXPRESSION, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtSwitch", spoon.reflect.code.CtSwitch.class, spoon.support.reflect.code.CtSwitchImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.EXPRESSION, false, false)
+ .field(CtRole.CASE, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtTry", spoon.reflect.code.CtTry.class, spoon.support.reflect.code.CtTryImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.BODY, false, false)
+ .field(CtRole.CATCH, false, false)
+ .field(CtRole.FINALIZER, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtSynchronized", spoon.reflect.code.CtSynchronized.class, spoon.support.reflect.code.CtSynchronizedImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.EXPRESSION, false, false)
+ .field(CtRole.BODY, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtImport", spoon.reflect.declaration.CtImport.class, spoon.support.reflect.declaration.CtImportImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.IMPORT_REFERENCE, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtTypeParameterReference", spoon.reflect.reference.CtTypeParameterReference.class, spoon.support.reflect.reference.CtTypeParameterReferenceImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_UPPER, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.MODIFIER, false, true)
+ .field(CtRole.COMMENT, false, true)
+ .field(CtRole.INTERFACE, true, true)
+ .field(CtRole.SUPER_TYPE, true, true)
+ .field(CtRole.TYPE_ARGUMENT, true, true)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.PACKAGE_REF, false, false)
+ .field(CtRole.DECLARING_TYPE, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.BOUNDING_TYPE, false, false)
+
+ ));
+
+ types.add(new Type("CtInvocation", spoon.reflect.code.CtInvocation.class, spoon.support.reflect.code.CtInvocationImpl.class, fm -> fm
+ .field(CtRole.TYPE, true, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.TYPE_ARGUMENT, true, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.TARGET, false, false)
+ .field(CtRole.EXECUTABLE_REF, false, false)
+ .field(CtRole.ARGUMENT, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtCodeSnippetExpression", spoon.reflect.code.CtCodeSnippetExpression.class, spoon.support.reflect.code.CtCodeSnippetExpressionImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.SNIPPET, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.CAST, false, false)
+
+ ));
+
+ types.add(new Type("CtFieldWrite", spoon.reflect.code.CtFieldWrite.class, spoon.support.reflect.code.CtFieldWriteImpl.class, fm -> fm
+ .field(CtRole.TYPE, true, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.TARGET, false, false)
+ .field(CtRole.VARIABLE, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtUnaryOperator", spoon.reflect.code.CtUnaryOperator.class, spoon.support.reflect.code.CtUnaryOperatorImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.OPERATOR_KIND, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.EXPRESSION, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtExecutableReference", spoon.reflect.reference.CtExecutableReference.class, spoon.support.reflect.reference.CtExecutableReferenceImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_STATIC, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.DECLARING_TYPE, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.ARGUMENT_TYPE, false, false)
+ .field(CtRole.TYPE_ARGUMENT, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.COMMENT, false, true)
+
+ ));
+
+ types.add(new Type("CtFor", spoon.reflect.code.CtFor.class, spoon.support.reflect.code.CtForImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.FOR_INIT, false, false)
+ .field(CtRole.EXPRESSION, false, false)
+ .field(CtRole.FOR_UPDATE, false, false)
+ .field(CtRole.BODY, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtVariableRead", spoon.reflect.code.CtVariableRead.class, spoon.support.reflect.code.CtVariableReadImpl.class, fm -> fm
+ .field(CtRole.TYPE, true, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.VARIABLE, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtTypeParameter", spoon.reflect.declaration.CtTypeParameter.class, spoon.support.reflect.declaration.CtTypeParameterImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.MODIFIER, false, true)
+ .field(CtRole.INTERFACE, true, true)
+ .field(CtRole.TYPE_MEMBER, true, true)
+ .field(CtRole.NESTED_TYPE, true, true)
+ .field(CtRole.METHOD, true, true)
+ .field(CtRole.FIELD, true, true)
+ .field(CtRole.TYPE_PARAMETER, true, true)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.SUPER_TYPE, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtLocalVariable", spoon.reflect.code.CtLocalVariable.class, spoon.support.reflect.code.CtLocalVariableImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.ASSIGNMENT, true, true)
+ .field(CtRole.MODIFIER, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.DEFAULT_EXPRESSION, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtIf", spoon.reflect.code.CtIf.class, spoon.support.reflect.code.CtIfImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.CONDITION, false, false)
+ .field(CtRole.THEN, false, false)
+ .field(CtRole.ELSE, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtModule", spoon.reflect.declaration.CtModule.class, spoon.support.reflect.declaration.CtModuleImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.MODIFIER, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.REQUIRED_MODULE, true, false)
+ .field(CtRole.EXPORTED_PACKAGE, true, false)
+ .field(CtRole.OPENED_PACKAGE, true, false)
+ .field(CtRole.SERVICE_TYPE, true, false)
+ .field(CtRole.PROVIDED_SERVICE, true, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.MODULE_DIRECTIVE, false, false)
+ .field(CtRole.SUB_PACKAGE, false, false)
+
+ ));
+
+ types.add(new Type("CtPackageExport", spoon.reflect.declaration.CtPackageExport.class, spoon.support.reflect.declaration.CtPackageExportImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.OPENED_PACKAGE, false, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.PACKAGE_REF, false, false)
+ .field(CtRole.MODULE_REF, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+
+ ));
+
+ types.add(new Type("CtConstructorCall", spoon.reflect.code.CtConstructorCall.class, spoon.support.reflect.code.CtConstructorCallImpl.class, fm -> fm
+ .field(CtRole.TYPE, true, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.TYPE_ARGUMENT, true, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.EXECUTABLE_REF, false, false)
+ .field(CtRole.TARGET, false, false)
+ .field(CtRole.ARGUMENT, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtCase", spoon.reflect.code.CtCase.class, spoon.support.reflect.code.CtCaseImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.EXPRESSION, false, false)
+ .field(CtRole.STATEMENT, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtModuleReference", spoon.reflect.reference.CtModuleReference.class, spoon.support.reflect.reference.CtModuleReferenceImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.COMMENT, false, true)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+
+ ));
+
+ types.add(new Type("CtCatch", spoon.reflect.code.CtCatch.class, spoon.support.reflect.code.CtCatchImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.PARAMETER, false, false)
+ .field(CtRole.BODY, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtArrayTypeReference", spoon.reflect.reference.CtArrayTypeReference.class, spoon.support.reflect.reference.CtArrayTypeReferenceImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.MODIFIER, false, true)
+ .field(CtRole.INTERFACE, true, true)
+ .field(CtRole.SUPER_TYPE, true, true)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.COMMENT, false, true)
+ .field(CtRole.PACKAGE_REF, false, false)
+ .field(CtRole.DECLARING_TYPE, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.TYPE_ARGUMENT, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+
+ ));
+
+ types.add(new Type("CtMethod", spoon.reflect.declaration.CtMethod.class, spoon.support.reflect.declaration.CtMethodImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.IS_DEFAULT, false, false)
+ .field(CtRole.MODIFIER, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE_PARAMETER, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.PARAMETER, false, false)
+ .field(CtRole.THROWN, false, false)
+ .field(CtRole.BODY, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtLambda", spoon.reflect.code.CtLambda.class, spoon.support.reflect.code.CtLambdaImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.PARAMETER, false, false)
+ .field(CtRole.THROWN, false, true)
+ .field(CtRole.BODY, false, false)
+ .field(CtRole.EXPRESSION, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtNewArray", spoon.reflect.code.CtNewArray.class, spoon.support.reflect.code.CtNewArrayImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.EXPRESSION, false, false)
+ .field(CtRole.DIMENSION, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtUsedService", spoon.reflect.declaration.CtUsedService.class, spoon.support.reflect.declaration.CtUsedServiceImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.SERVICE_TYPE, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+
+ ));
+
+ types.add(new Type("CtIntersectionTypeReference", spoon.reflect.reference.CtIntersectionTypeReference.class, spoon.support.reflect.reference.CtIntersectionTypeReferenceImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.MODIFIER, false, true)
+ .field(CtRole.COMMENT, false, true)
+ .field(CtRole.INTERFACE, true, true)
+ .field(CtRole.SUPER_TYPE, true, true)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.PACKAGE_REF, false, false)
+ .field(CtRole.DECLARING_TYPE, false, false)
+ .field(CtRole.TYPE_ARGUMENT, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.BOUND, false, false)
+
+ ));
+
+ types.add(new Type("CtThrow", spoon.reflect.code.CtThrow.class, spoon.support.reflect.code.CtThrowImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.EXPRESSION, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtLiteral", spoon.reflect.code.CtLiteral.class, spoon.support.reflect.code.CtLiteralImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.VALUE, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtReturn", spoon.reflect.code.CtReturn.class, spoon.support.reflect.code.CtReturnImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.EXPRESSION, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtJavaDocTag", spoon.reflect.code.CtJavaDocTag.class, spoon.support.reflect.code.CtJavaDocTagImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.COMMENT_CONTENT, false, false)
+ .field(CtRole.DOCUMENTATION_TYPE, false, false)
+ .field(CtRole.JAVADOC_TAG_VALUE, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+
+ ));
+
+ types.add(new Type("CtField", spoon.reflect.declaration.CtField.class, spoon.support.reflect.declaration.CtFieldImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.ASSIGNMENT, true, true)
+ .field(CtRole.MODIFIER, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.DEFAULT_EXPRESSION, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtTypeAccess", spoon.reflect.code.CtTypeAccess.class, spoon.support.reflect.code.CtTypeAccessImpl.class, fm -> fm
+ .field(CtRole.TYPE, true, true)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.ACCESSED_TYPE, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtCodeSnippetStatement", spoon.reflect.code.CtCodeSnippetStatement.class, spoon.support.reflect.code.CtCodeSnippetStatementImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.SNIPPET, false, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+
+ ));
+
+ types.add(new Type("CtDo", spoon.reflect.code.CtDo.class, spoon.support.reflect.code.CtDoImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.EXPRESSION, false, false)
+ .field(CtRole.BODY, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtAnnotation", spoon.reflect.declaration.CtAnnotation.class, spoon.support.reflect.declaration.CtAnnotationImpl.class, fm -> fm
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.CAST, true, true)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.ANNOTATION_TYPE, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.VALUE, false, false)
+
+ ));
+
+ types.add(new Type("CtFieldRead", spoon.reflect.code.CtFieldRead.class, spoon.support.reflect.code.CtFieldReadImpl.class, fm -> fm
+ .field(CtRole.TYPE, true, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.TARGET, false, false)
+ .field(CtRole.VARIABLE, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtBreak", spoon.reflect.code.CtBreak.class, spoon.support.reflect.code.CtBreakImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.TARGET_LABEL, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtFieldReference", spoon.reflect.reference.CtFieldReference.class, spoon.support.reflect.reference.CtFieldReferenceImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_FINAL, false, false)
+ .field(CtRole.IS_STATIC, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.COMMENT, false, true)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.DECLARING_TYPE, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+
+ ));
+
+ types.add(new Type("CtEnum", spoon.reflect.declaration.CtEnum.class, spoon.support.reflect.declaration.CtEnumImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, true)
+ .field(CtRole.MODIFIER, false, false)
+ .field(CtRole.SUPER_TYPE, true, true)
+ .field(CtRole.NESTED_TYPE, true, false)
+ .field(CtRole.CONSTRUCTOR, true, false)
+ .field(CtRole.METHOD, true, false)
+ .field(CtRole.ANNONYMOUS_EXECUTABLE, true, false)
+ .field(CtRole.FIELD, true, false)
+ .field(CtRole.TYPE_PARAMETER, true, true)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.INTERFACE, false, false)
+ .field(CtRole.TYPE_MEMBER, false, false)
+ .field(CtRole.VALUE, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtNewClass", spoon.reflect.code.CtNewClass.class, spoon.support.reflect.code.CtNewClassImpl.class, fm -> fm
+ .field(CtRole.TYPE, true, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.LABEL, false, false)
+ .field(CtRole.TYPE_ARGUMENT, true, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.EXECUTABLE_REF, false, false)
+ .field(CtRole.TARGET, false, false)
+ .field(CtRole.ARGUMENT, false, false)
+ .field(CtRole.NESTED_TYPE, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtLocalVariableReference", spoon.reflect.reference.CtLocalVariableReference.class, spoon.support.reflect.reference.CtLocalVariableReferenceImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.COMMENT, false, true)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+
+ ));
+
+ types.add(new Type("CtAnnotationType", spoon.reflect.declaration.CtAnnotationType.class, spoon.support.reflect.declaration.CtAnnotationTypeImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.IS_SHADOW, false, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.MODIFIER, false, false)
+ .field(CtRole.INTERFACE, true, true)
+ .field(CtRole.SUPER_TYPE, true, true)
+ .field(CtRole.NESTED_TYPE, true, false)
+ .field(CtRole.METHOD, true, false)
+ .field(CtRole.FIELD, true, false)
+ .field(CtRole.TYPE_PARAMETER, true, true)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE_MEMBER, false, false)
+ .field(CtRole.COMMENT, false, false)
+
+ ));
+
+ types.add(new Type("CtCatchVariable", spoon.reflect.code.CtCatchVariable.class, spoon.support.reflect.code.CtCatchVariableImpl.class, fm -> fm
+ .field(CtRole.NAME, false, false)
+ .field(CtRole.TYPE, true, false)
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.DEFAULT_EXPRESSION, true, true)
+ .field(CtRole.MODIFIER, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.MULTI_TYPE, false, false)
+
+ ));
+
+ types.add(new Type("CtExecutableReferenceExpression", spoon.reflect.code.CtExecutableReferenceExpression.class, spoon.support.reflect.code.CtExecutableReferenceExpressionImpl.class, fm -> fm
+ .field(CtRole.IS_IMPLICIT, false, false)
+ .field(CtRole.POSITION, false, false)
+ .field(CtRole.COMMENT, false, false)
+ .field(CtRole.ANNOTATION, false, false)
+ .field(CtRole.TYPE, false, false)
+ .field(CtRole.CAST, false, false)
+ .field(CtRole.EXECUTABLE_REF, false, false)
+ .field(CtRole.TARGET, false, false)
+
+ ));
+ }
}
diff --git a/src/test/java/spoon/generating/MetamodelGenerator.java b/src/test/java/spoon/generating/MetamodelGenerator.java
new file mode 100644
index 00000000000..1feafc8aa5c
--- /dev/null
+++ b/src/test/java/spoon/generating/MetamodelGenerator.java
@@ -0,0 +1,115 @@
+package spoon.generating;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.text.StrSubstitutor;
+
+import spoon.Metamodel.Type;
+import spoon.SpoonException;
+import spoon.reflect.declaration.CtClass;
+import spoon.reflect.declaration.CtElement;
+import spoon.reflect.factory.Factory;
+import spoon.reflect.path.CtRole;
+import spoon.reflect.visitor.CtScanner;
+import spoon.test.metamodel.MMField;
+import spoon.test.metamodel.MMType;
+import spoon.test.metamodel.MMTypeKind;
+import spoon.test.metamodel.SpoonMetaModel;
+
+public class MetamodelGenerator {
+
+ public static void main(String[] args) {
+ SpoonMetaModel mm = new SpoonMetaModel(new File("src/main/java"));
+ mm.getFactory().getEnvironment().useTabulations(true);
+ StringBuilder sb = new StringBuilder();
+ for (MMType type : mm.getMMTypes()) {
+ if (type.getKind()==MMTypeKind.LEAF) {
+ sb.append(printType(mm.getFactory(), type));
+ }
+ }
+ System.out.println(sb.toString());
+ }
+
+
+ private static String printType(Factory factory, MMType type) {
+ Map valuesMap = new HashMap<>();
+ valuesMap.put("typeName", type.getName());
+ valuesMap.put("ifaceName", type.getModelInterface().getQualifiedName());
+ valuesMap.put("implName", type.getModelClass().getQualifiedName());
+ valuesMap.put("fields", printFields(factory, type));
+
+ StrSubstitutor strSubst = new StrSubstitutor(valuesMap);
+ return strSubst.replace(
+ "types.add(new Type(\"${typeName}\", ${ifaceName}.class, ${implName}.class, fm -> fm\n" +
+ "${fields}\n" +
+ "));\n\n");
+
+ }
+
+ private static String printFields(Factory factory, MMType type) {
+ Map allFields = new LinkedHashMap<>(type.getRole2field());
+ List rolesByScanner = getRoleScanningOrderOfType(factory, (Class) type.getModelInterface().getActualClass());
+ List elementFields = new ArrayList<>();
+ for (CtRole ctRole : rolesByScanner) {
+ MMField field = allFields.remove(ctRole);
+ elementFields.add(printField(field));
+ }
+ //generate remaining primitive fields, sorted by Enum#ordinal of CtRole - just to have a stable order
+ List primitiveFields = new ArrayList<>();
+ new ArrayList(allFields.keySet()).stream().sorted().forEach(role -> {
+ MMField field = allFields.remove(role);
+ primitiveFields.add(printField(field));
+ });
+ if (allFields.isEmpty() == false) {
+ throw new SpoonException("There remained some fields?");
+ }
+ StringBuilder sb = new StringBuilder();
+ primitiveFields.addAll(elementFields);
+ primitiveFields.forEach(s->sb.append(s).append('\n'));
+ return sb.toString();
+ }
+
+ private static String printField(MMField field) {
+ Map valuesMap = new HashMap<>();
+ valuesMap.put("role", field.getRole().name());
+ valuesMap.put("derived", String.valueOf(field.isDerived()));
+ valuesMap.put("unsetable", String.valueOf(field.isUnsettable()));
+
+ StrSubstitutor strSubst = new StrSubstitutor(valuesMap);
+ return strSubst.replace("\t.field(CtRole.${role}, ${derived}, ${unsetable})");
+ }
+
+
+ private static List getRoleScanningOrderOfType(Factory factory, Class extends CtElement> iface) {
+ List roles = new ArrayList<>();
+ //generate fields in the same order like they are visited in CtScanner
+ CtElement ele = factory.Core().create(iface);
+ ele.accept(new CtScanner() {
+ @Override
+ public void scan(CtRole role, CtElement element) {
+ roles.add(role);
+ }
+ @Override
+ public void scan(CtRole role, Collection extends CtElement> elements) {
+ roles.add(role);
+ }
+ @Override
+ public void scan(CtRole role, Map elements) {
+ roles.add(role);
+ }
+ });
+ return roles;
+ }
+
+/*
+ types.add(new Type("CtClass", CtClassImpl.class, CtClass.class, fm ->
+ fm.field(CtRole.NAME, false, false)
+ ));
+*/
+}
diff --git a/src/test/java/spoon/test/api/MetamodelTest.java b/src/test/java/spoon/test/api/MetamodelTest.java
index 1b850a412a5..a52959c5dc2 100644
--- a/src/test/java/spoon/test/api/MetamodelTest.java
+++ b/src/test/java/spoon/test/api/MetamodelTest.java
@@ -26,16 +26,26 @@
import spoon.reflect.visitor.filter.AnnotationFilter;
import spoon.reflect.visitor.filter.SuperInheritanceHierarchyFunction;
import spoon.reflect.visitor.filter.TypeFilter;
+import spoon.test.metamodel.MMField;
+import spoon.test.metamodel.MMType;
+import spoon.test.metamodel.MMTypeKind;
+import spoon.test.metamodel.SpoonMetaModel;
+import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
public class MetamodelTest {
@@ -50,6 +60,30 @@ public void testGetAllMetamodelInterfacess() {
assertThat(Metamodel.getAllMetamodelInterfaces().stream().map(x->x.getQualifiedName()).collect(Collectors.toSet()), equalTo(interfaces.getModel().getAllTypes().stream().map(x->x.getQualifiedName()).collect(Collectors.toSet())));
}
+ @Test
+ public void testRuntimeMetamodel() {
+ // contract: Spoon supports runtime introspection on the metamodel - all (non abstract) Spoon classes and their fields are accessible by Metamodel
+ SpoonMetaModel testMetaModel = new SpoonMetaModel(new File("src/main/java"));
+ Map expectedTypesByName = new HashMap<>();
+ testMetaModel.getMMTypes().forEach(t -> {
+ if (t.getKind() == MMTypeKind.LEAF) {
+ expectedTypesByName.put(t.getName(), t);
+ }
+ });
+ for (Metamodel.Type type : Metamodel.getAllMetamodelTypes()) {
+ MMType expectedType = expectedTypesByName.remove(type.getName());
+ assertSame(expectedType.getModelClass().getActualClass(), type.getModelClass());
+ assertSame(expectedType.getModelInterface().getActualClass(), type.getModelInterface());
+ Map expectedRoleToField = new HashMap<>(expectedType.getRole2field());
+ for (Metamodel.Field field : type.getFields()) {
+ MMField expectedField = expectedRoleToField.remove(field.getRole());
+ assertSame(expectedField.isDerived(), field.isDerived());
+ assertSame(expectedField.isUnsettable(), field.isUnsettable());
+ }
+ assertTrue("These Metamodel.Field instances are missing on Type " + type.getName() +": " + expectedRoleToField.keySet(), expectedRoleToField.isEmpty());
+ }
+ assertTrue("These Metamodel.Type instances are missing: " + expectedTypesByName.keySet(), expectedTypesByName.isEmpty());
+ }
@Test
@@ -162,4 +196,6 @@ public boolean matches(CtField candidate) {
}
}
+
+
}
From 274efacbee53ac3c2e73c5a0d7a9410540ac2353 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20Vojt=C4=9Bchovsk=C3=BD?=
Date: Wed, 7 Mar 2018 10:38:38 +0100
Subject: [PATCH 002/131] rename MMType, MMField - runtime metamodel
---
src/main/java/spoon/Metamodel.java | 4 ++--
.../spoon/generating/MetamodelGenerator.java | 18 +++++++++---------
.../java/spoon/test/api/MetamodelTest.java | 14 +++++++-------
3 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/src/main/java/spoon/Metamodel.java b/src/main/java/spoon/Metamodel.java
index 7bda0513a56..32e42d45d88 100644
--- a/src/main/java/spoon/Metamodel.java
+++ b/src/main/java/spoon/Metamodel.java
@@ -197,11 +197,11 @@ public static class Type {
private final String name;
/**
- * The {@link CtClass} linked to this {@link MMType}. Is null in case of class without interface
+ * The {@link CtClass} linked to this {@link MetamodelConcept}. Is null in case of class without interface
*/
private final Class extends CtElement> modelClass;
/**
- * The {@link CtInterface} linked to this {@link MMType}. Is null in case of interface without class
+ * The {@link CtInterface} linked to this {@link MetamodelConcept}. Is null in case of interface without class
*/
private final Class extends CtElement> modelInterface;
diff --git a/src/test/java/spoon/generating/MetamodelGenerator.java b/src/test/java/spoon/generating/MetamodelGenerator.java
index 1feafc8aa5c..79beb980fd5 100644
--- a/src/test/java/spoon/generating/MetamodelGenerator.java
+++ b/src/test/java/spoon/generating/MetamodelGenerator.java
@@ -17,8 +17,8 @@
import spoon.reflect.factory.Factory;
import spoon.reflect.path.CtRole;
import spoon.reflect.visitor.CtScanner;
-import spoon.test.metamodel.MMField;
-import spoon.test.metamodel.MMType;
+import spoon.test.metamodel.MetamodelProperty;
+import spoon.test.metamodel.MetamodelConcept;
import spoon.test.metamodel.MMTypeKind;
import spoon.test.metamodel.SpoonMetaModel;
@@ -28,7 +28,7 @@ public static void main(String[] args) {
SpoonMetaModel mm = new SpoonMetaModel(new File("src/main/java"));
mm.getFactory().getEnvironment().useTabulations(true);
StringBuilder sb = new StringBuilder();
- for (MMType type : mm.getMMTypes()) {
+ for (MetamodelConcept type : mm.getConcepts()) {
if (type.getKind()==MMTypeKind.LEAF) {
sb.append(printType(mm.getFactory(), type));
}
@@ -37,7 +37,7 @@ public static void main(String[] args) {
}
- private static String printType(Factory factory, MMType type) {
+ private static String printType(Factory factory, MetamodelConcept type) {
Map valuesMap = new HashMap<>();
valuesMap.put("typeName", type.getName());
valuesMap.put("ifaceName", type.getModelInterface().getQualifiedName());
@@ -52,18 +52,18 @@ private static String printType(Factory factory, MMType type) {
}
- private static String printFields(Factory factory, MMType type) {
- Map allFields = new LinkedHashMap<>(type.getRole2field());
+ private static String printFields(Factory factory, MetamodelConcept type) {
+ Map allFields = new LinkedHashMap<>(type.getRoleToProperty());
List rolesByScanner = getRoleScanningOrderOfType(factory, (Class) type.getModelInterface().getActualClass());
List elementFields = new ArrayList<>();
for (CtRole ctRole : rolesByScanner) {
- MMField field = allFields.remove(ctRole);
+ MetamodelProperty field = allFields.remove(ctRole);
elementFields.add(printField(field));
}
//generate remaining primitive fields, sorted by Enum#ordinal of CtRole - just to have a stable order
List primitiveFields = new ArrayList<>();
new ArrayList(allFields.keySet()).stream().sorted().forEach(role -> {
- MMField field = allFields.remove(role);
+ MetamodelProperty field = allFields.remove(role);
primitiveFields.add(printField(field));
});
if (allFields.isEmpty() == false) {
@@ -75,7 +75,7 @@ private static String printFields(Factory factory, MMType type) {
return sb.toString();
}
- private static String printField(MMField field) {
+ private static String printField(MetamodelProperty field) {
Map valuesMap = new HashMap<>();
valuesMap.put("role", field.getRole().name());
valuesMap.put("derived", String.valueOf(field.isDerived()));
diff --git a/src/test/java/spoon/test/api/MetamodelTest.java b/src/test/java/spoon/test/api/MetamodelTest.java
index a52959c5dc2..c42bebc2512 100644
--- a/src/test/java/spoon/test/api/MetamodelTest.java
+++ b/src/test/java/spoon/test/api/MetamodelTest.java
@@ -26,8 +26,8 @@
import spoon.reflect.visitor.filter.AnnotationFilter;
import spoon.reflect.visitor.filter.SuperInheritanceHierarchyFunction;
import spoon.reflect.visitor.filter.TypeFilter;
-import spoon.test.metamodel.MMField;
-import spoon.test.metamodel.MMType;
+import spoon.test.metamodel.MetamodelProperty;
+import spoon.test.metamodel.MetamodelConcept;
import spoon.test.metamodel.MMTypeKind;
import spoon.test.metamodel.SpoonMetaModel;
@@ -64,19 +64,19 @@ public void testGetAllMetamodelInterfacess() {
public void testRuntimeMetamodel() {
// contract: Spoon supports runtime introspection on the metamodel - all (non abstract) Spoon classes and their fields are accessible by Metamodel
SpoonMetaModel testMetaModel = new SpoonMetaModel(new File("src/main/java"));
- Map expectedTypesByName = new HashMap<>();
- testMetaModel.getMMTypes().forEach(t -> {
+ Map expectedTypesByName = new HashMap<>();
+ testMetaModel.getConcepts().forEach(t -> {
if (t.getKind() == MMTypeKind.LEAF) {
expectedTypesByName.put(t.getName(), t);
}
});
for (Metamodel.Type type : Metamodel.getAllMetamodelTypes()) {
- MMType expectedType = expectedTypesByName.remove(type.getName());
+ MetamodelConcept expectedType = expectedTypesByName.remove(type.getName());
assertSame(expectedType.getModelClass().getActualClass(), type.getModelClass());
assertSame(expectedType.getModelInterface().getActualClass(), type.getModelInterface());
- Map expectedRoleToField = new HashMap<>(expectedType.getRole2field());
+ Map expectedRoleToField = new HashMap<>(expectedType.getRoleToProperty());
for (Metamodel.Field field : type.getFields()) {
- MMField expectedField = expectedRoleToField.remove(field.getRole());
+ MetamodelProperty expectedField = expectedRoleToField.remove(field.getRole());
assertSame(expectedField.isDerived(), field.isDerived());
assertSame(expectedField.isUnsettable(), field.isUnsettable());
}
From 5c4f60562121041f4d9cfc3acbc493c1ae776f6b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20Vojt=C4=9Bchovsk=C3=BD?=
Date: Wed, 7 Mar 2018 09:55:42 +0100
Subject: [PATCH 003/131] Pattern
---
src/main/java/spoon/Metamodel.java | 54 +-
.../spoon/pattern/AbstractItemAccessor.java | 424 ++++++++
.../pattern/AbstractPrimitiveMatcher.java | 70 ++
.../pattern/AbstractRepeatableMatcher.java | 124 +++
.../spoon/pattern/ConflictResolutionMode.java | 37 +
src/main/java/spoon/pattern/ConstantNode.java | 66 ++
src/main/java/spoon/pattern/ElementNode.java | 194 ++++
src/main/java/spoon/pattern/ForEachNode.java | 139 +++
src/main/java/spoon/pattern/ListAccessor.java | 117 +++
src/main/java/spoon/pattern/ListOfNodes.java | 82 ++
.../spoon/pattern/LiveStatementsBuilder.java | 229 +++++
src/main/java/spoon/pattern/ModelNode.java | 164 +++
.../java/spoon/pattern/NamedItemAccessor.java | 135 +++
src/main/java/spoon/pattern/Node.java | 114 +++
.../java/spoon/pattern/ParameterInfo.java | 85 ++
.../java/spoon/pattern/ParameterNode.java | 86 ++
.../spoon/pattern/ParameterValueProvider.java | 40 +
.../ParameterValueProviderFactory.java | 24 +
.../java/spoon/pattern/ParametersBuilder.java | 694 +++++++++++++
src/main/java/spoon/pattern/Pattern.java | 266 +++++
.../java/spoon/pattern/PatternBuilder.java | 935 ++++++++++++++++++
.../java/spoon/pattern/PrimitiveMatcher.java | 30 +
.../java/spoon/pattern/RepeatableMatcher.java | 56 ++
src/main/java/spoon/pattern/ResultHolder.java | 147 +++
src/main/java/spoon/pattern/SetAccessor.java | 91 ++
src/main/java/spoon/pattern/StringNode.java | 237 +++++
.../spoon/pattern/SubstitutionCloner.java | 257 +++++
.../pattern/SubstitutionRequestProvider.java | 28 +
src/main/java/spoon/pattern/SwitchNode.java | 185 ++++
.../java/spoon/pattern/TemplateBuilder.java | 140 +++
.../UnmodifiableParameterValueProvider.java | 145 +++
.../java/spoon/pattern/ValueConvertor.java | 25 +
.../spoon/pattern/ValueConvertorImpl.java | 171 ++++
src/main/java/spoon/pattern/concept.md | 189 ++++
.../pattern/matcher/ChainOfMatchersImpl.java | 68 ++
.../spoon/pattern/matcher/MapEntryNode.java | 69 ++
.../java/spoon/pattern/matcher/Match.java | 116 +++
.../java/spoon/pattern/matcher/Matchers.java | 32 +
.../pattern/matcher/MatchingScanner.java | 139 +++
.../pattern/matcher/NodeListMatcher.java | 38 +
.../spoon/pattern/matcher/Quantifier.java | 44 +
.../spoon/pattern/matcher/TobeMatched.java | 235 +++++
.../reflect/reference/CtTypeReference.java | 5 +
.../spoon/support/template/Parameters.java | 31 +-
.../support/template/SubstitutionVisitor.java | 1 +
.../java/spoon/template/AbstractTemplate.java | 5 +-
.../java/spoon/template/BlockTemplate.java | 3 +-
.../spoon/template/ExpressionTemplate.java | 8 +-
.../spoon/template/StatementTemplate.java | 22 +-
.../java/spoon/template/Substitution.java | 40 +-
.../java/spoon/template/TemplateMatcher.java | 701 ++-----------
src/test/java/spoon/MavenLauncherTest.java | 2 +-
.../SpoonArchitectureEnforcerTest.java | 2 +
.../spoon/test/template/CodeReplaceTest.java | 83 ++
.../java/spoon/test/template/PatternTest.java | 59 ++
.../test/template/TemplateMatcherTest.java | 835 ++++++++++++++++
.../spoon/test/template/TemplateTest.java | 200 +++-
.../test/template/core/ParameterInfoTest.java | 433 ++++++++
.../template/testclasses/ToBeMatched.java | 25 +
.../testclasses/bounds/CheckBound.java | 5 +
.../testclasses/bounds/CheckBoundMatcher.java | 4 +
.../template/testclasses/match/Check.java | 6 +
.../testclasses/match/MatchForEach.java | 37 +
.../testclasses/match/MatchForEach2.java | 44 +
.../testclasses/match/MatchIfElse.java | 49 +
.../template/testclasses/match/MatchMap.java | 55 ++
.../testclasses/match/MatchModifiers.java | 42 +
.../testclasses/match/MatchMultiple.java | 48 +
.../testclasses/match/MatchMultiple2.java | 52 +
.../testclasses/match/MatchMultiple3.java | 47 +
.../match/MatchWithParameterCondition.java | 36 +
.../match/MatchWithParameterType.java | 34 +
.../testclasses/replace/DPPSample1.java | 34 +
.../template/testclasses/replace/Item.java | 4 +
.../testclasses/replace/NewPattern.java | 81 ++
.../testclasses/replace/OldPattern.java | 78 ++
76 files changed, 8907 insertions(+), 725 deletions(-)
create mode 100644 src/main/java/spoon/pattern/AbstractItemAccessor.java
create mode 100644 src/main/java/spoon/pattern/AbstractPrimitiveMatcher.java
create mode 100644 src/main/java/spoon/pattern/AbstractRepeatableMatcher.java
create mode 100644 src/main/java/spoon/pattern/ConflictResolutionMode.java
create mode 100644 src/main/java/spoon/pattern/ConstantNode.java
create mode 100644 src/main/java/spoon/pattern/ElementNode.java
create mode 100644 src/main/java/spoon/pattern/ForEachNode.java
create mode 100644 src/main/java/spoon/pattern/ListAccessor.java
create mode 100644 src/main/java/spoon/pattern/ListOfNodes.java
create mode 100644 src/main/java/spoon/pattern/LiveStatementsBuilder.java
create mode 100644 src/main/java/spoon/pattern/ModelNode.java
create mode 100644 src/main/java/spoon/pattern/NamedItemAccessor.java
create mode 100644 src/main/java/spoon/pattern/Node.java
create mode 100644 src/main/java/spoon/pattern/ParameterInfo.java
create mode 100644 src/main/java/spoon/pattern/ParameterNode.java
create mode 100644 src/main/java/spoon/pattern/ParameterValueProvider.java
create mode 100644 src/main/java/spoon/pattern/ParameterValueProviderFactory.java
create mode 100644 src/main/java/spoon/pattern/ParametersBuilder.java
create mode 100644 src/main/java/spoon/pattern/Pattern.java
create mode 100644 src/main/java/spoon/pattern/PatternBuilder.java
create mode 100644 src/main/java/spoon/pattern/PrimitiveMatcher.java
create mode 100644 src/main/java/spoon/pattern/RepeatableMatcher.java
create mode 100644 src/main/java/spoon/pattern/ResultHolder.java
create mode 100644 src/main/java/spoon/pattern/SetAccessor.java
create mode 100644 src/main/java/spoon/pattern/StringNode.java
create mode 100644 src/main/java/spoon/pattern/SubstitutionCloner.java
create mode 100644 src/main/java/spoon/pattern/SubstitutionRequestProvider.java
create mode 100644 src/main/java/spoon/pattern/SwitchNode.java
create mode 100644 src/main/java/spoon/pattern/TemplateBuilder.java
create mode 100644 src/main/java/spoon/pattern/UnmodifiableParameterValueProvider.java
create mode 100644 src/main/java/spoon/pattern/ValueConvertor.java
create mode 100644 src/main/java/spoon/pattern/ValueConvertorImpl.java
create mode 100644 src/main/java/spoon/pattern/concept.md
create mode 100644 src/main/java/spoon/pattern/matcher/ChainOfMatchersImpl.java
create mode 100644 src/main/java/spoon/pattern/matcher/MapEntryNode.java
create mode 100644 src/main/java/spoon/pattern/matcher/Match.java
create mode 100644 src/main/java/spoon/pattern/matcher/Matchers.java
create mode 100644 src/main/java/spoon/pattern/matcher/MatchingScanner.java
create mode 100644 src/main/java/spoon/pattern/matcher/NodeListMatcher.java
create mode 100644 src/main/java/spoon/pattern/matcher/Quantifier.java
create mode 100644 src/main/java/spoon/pattern/matcher/TobeMatched.java
create mode 100644 src/test/java/spoon/test/template/CodeReplaceTest.java
create mode 100644 src/test/java/spoon/test/template/PatternTest.java
create mode 100644 src/test/java/spoon/test/template/TemplateMatcherTest.java
create mode 100644 src/test/java/spoon/test/template/core/ParameterInfoTest.java
create mode 100644 src/test/java/spoon/test/template/testclasses/ToBeMatched.java
create mode 100644 src/test/java/spoon/test/template/testclasses/match/Check.java
create mode 100644 src/test/java/spoon/test/template/testclasses/match/MatchForEach.java
create mode 100644 src/test/java/spoon/test/template/testclasses/match/MatchForEach2.java
create mode 100644 src/test/java/spoon/test/template/testclasses/match/MatchIfElse.java
create mode 100644 src/test/java/spoon/test/template/testclasses/match/MatchMap.java
create mode 100644 src/test/java/spoon/test/template/testclasses/match/MatchModifiers.java
create mode 100644 src/test/java/spoon/test/template/testclasses/match/MatchMultiple.java
create mode 100644 src/test/java/spoon/test/template/testclasses/match/MatchMultiple2.java
create mode 100644 src/test/java/spoon/test/template/testclasses/match/MatchMultiple3.java
create mode 100644 src/test/java/spoon/test/template/testclasses/match/MatchWithParameterCondition.java
create mode 100644 src/test/java/spoon/test/template/testclasses/match/MatchWithParameterType.java
create mode 100644 src/test/java/spoon/test/template/testclasses/replace/DPPSample1.java
create mode 100644 src/test/java/spoon/test/template/testclasses/replace/Item.java
create mode 100644 src/test/java/spoon/test/template/testclasses/replace/NewPattern.java
create mode 100644 src/test/java/spoon/test/template/testclasses/replace/OldPattern.java
diff --git a/src/main/java/spoon/Metamodel.java b/src/main/java/spoon/Metamodel.java
index 32e42d45d88..79b7d66f6ce 100644
--- a/src/main/java/spoon/Metamodel.java
+++ b/src/main/java/spoon/Metamodel.java
@@ -238,13 +238,13 @@ public String getName() {
/**
* @return {@link Class} which implements this type. For example {@link CtForEachImpl}
*/
- public Class> getModelClass() {
+ public Class extends CtElement> getModelClass() {
return modelClass;
}
/**
* @return {@link Class} which defines interface of this type. For example {@link CtForEach}
*/
- public Class> getModelInterface() {
+ public Class extends CtElement> getModelInterface() {
return modelInterface;
}
@@ -438,7 +438,7 @@ private static void initTypes(List types) {
.field(CtRole.NAME, false, false)
.field(CtRole.IS_SHADOW, false, false)
.field(CtRole.IS_IMPLICIT, false, false)
- .field(CtRole.MODIFIER, false, true)
+ .field(CtRole.MODIFIER, true, true)
.field(CtRole.INTERFACE, true, true)
.field(CtRole.SUPER_TYPE, true, true)
.field(CtRole.POSITION, false, false)
@@ -446,7 +446,7 @@ private static void initTypes(List types) {
.field(CtRole.DECLARING_TYPE, false, false)
.field(CtRole.TYPE_ARGUMENT, false, false)
.field(CtRole.ANNOTATION, false, false)
- .field(CtRole.COMMENT, false, true)
+ .field(CtRole.COMMENT, true, true)
));
@@ -454,7 +454,7 @@ private static void initTypes(List types) {
.field(CtRole.NAME, false, false)
.field(CtRole.IS_IMPLICIT, false, false)
.field(CtRole.POSITION, false, false)
- .field(CtRole.COMMENT, false, true)
+ .field(CtRole.COMMENT, true, true)
.field(CtRole.TYPE, false, false)
.field(CtRole.ANNOTATION, false, false)
@@ -551,7 +551,7 @@ private static void initTypes(List types) {
));
types.add(new Type("CtConstructor", spoon.reflect.declaration.CtConstructor.class, spoon.support.reflect.declaration.CtConstructorImpl.class, fm -> fm
- .field(CtRole.NAME, false, true)
+ .field(CtRole.NAME, true, true)
.field(CtRole.TYPE, true, true)
.field(CtRole.IS_SHADOW, false, false)
.field(CtRole.IS_IMPLICIT, false, false)
@@ -579,7 +579,7 @@ private static void initTypes(List types) {
));
types.add(new Type("CtAnonymousExecutable", spoon.reflect.declaration.CtAnonymousExecutable.class, spoon.support.reflect.declaration.CtAnonymousExecutableImpl.class, fm -> fm
- .field(CtRole.NAME, false, true)
+ .field(CtRole.NAME, true, true)
.field(CtRole.TYPE, true, true)
.field(CtRole.IS_IMPLICIT, false, false)
.field(CtRole.PARAMETER, true, true)
@@ -604,12 +604,12 @@ private static void initTypes(List types) {
));
types.add(new Type("CtWildcardReference", spoon.reflect.reference.CtWildcardReference.class, spoon.support.reflect.reference.CtWildcardReferenceImpl.class, fm -> fm
- .field(CtRole.NAME, false, true)
+ .field(CtRole.NAME, true, true)
.field(CtRole.IS_SHADOW, false, false)
.field(CtRole.IS_UPPER, false, false)
.field(CtRole.IS_IMPLICIT, false, false)
- .field(CtRole.MODIFIER, false, true)
- .field(CtRole.COMMENT, false, true)
+ .field(CtRole.MODIFIER, true, true)
+ .field(CtRole.COMMENT, true, true)
.field(CtRole.INTERFACE, true, true)
.field(CtRole.SUPER_TYPE, true, true)
.field(CtRole.TYPE_ARGUMENT, true, true)
@@ -647,7 +647,7 @@ private static void initTypes(List types) {
types.add(new Type("CtPackageReference", spoon.reflect.reference.CtPackageReference.class, spoon.support.reflect.reference.CtPackageReferenceImpl.class, fm -> fm
.field(CtRole.NAME, false, false)
.field(CtRole.IS_IMPLICIT, false, false)
- .field(CtRole.COMMENT, false, true)
+ .field(CtRole.COMMENT, true, true)
.field(CtRole.POSITION, false, false)
.field(CtRole.ANNOTATION, false, false)
@@ -700,7 +700,7 @@ private static void initTypes(List types) {
types.add(new Type("CtParameterReference", spoon.reflect.reference.CtParameterReference.class, spoon.support.reflect.reference.CtParameterReferenceImpl.class, fm -> fm
.field(CtRole.NAME, false, false)
.field(CtRole.IS_IMPLICIT, false, false)
- .field(CtRole.COMMENT, false, true)
+ .field(CtRole.COMMENT, true, true)
.field(CtRole.POSITION, false, false)
.field(CtRole.TYPE, false, false)
.field(CtRole.ANNOTATION, false, false)
@@ -736,7 +736,7 @@ private static void initTypes(List types) {
types.add(new Type("CtUnboundVariableReference", spoon.reflect.reference.CtUnboundVariableReference.class, spoon.support.reflect.reference.CtUnboundVariableReferenceImpl.class, fm -> fm
.field(CtRole.NAME, false, false)
.field(CtRole.IS_IMPLICIT, false, false)
- .field(CtRole.COMMENT, false, true)
+ .field(CtRole.COMMENT, true, true)
.field(CtRole.ANNOTATION, true, true)
.field(CtRole.POSITION, false, false)
.field(CtRole.TYPE, false, false)
@@ -765,7 +765,7 @@ private static void initTypes(List types) {
.field(CtRole.NAME, false, false)
.field(CtRole.IS_SHADOW, false, false)
.field(CtRole.IS_IMPLICIT, false, false)
- .field(CtRole.LABEL, false, true)
+ .field(CtRole.LABEL, true, true)
.field(CtRole.MODIFIER, false, false)
.field(CtRole.NESTED_TYPE, true, false)
.field(CtRole.CONSTRUCTOR, true, false)
@@ -876,8 +876,8 @@ private static void initTypes(List types) {
.field(CtRole.IS_SHADOW, false, false)
.field(CtRole.IS_UPPER, false, false)
.field(CtRole.IS_IMPLICIT, false, false)
- .field(CtRole.MODIFIER, false, true)
- .field(CtRole.COMMENT, false, true)
+ .field(CtRole.MODIFIER, true, true)
+ .field(CtRole.COMMENT, true, true)
.field(CtRole.INTERFACE, true, true)
.field(CtRole.SUPER_TYPE, true, true)
.field(CtRole.TYPE_ARGUMENT, true, true)
@@ -950,7 +950,7 @@ private static void initTypes(List types) {
.field(CtRole.ARGUMENT_TYPE, false, false)
.field(CtRole.TYPE_ARGUMENT, false, false)
.field(CtRole.ANNOTATION, false, false)
- .field(CtRole.COMMENT, false, true)
+ .field(CtRole.COMMENT, true, true)
));
@@ -982,7 +982,7 @@ private static void initTypes(List types) {
.field(CtRole.NAME, false, false)
.field(CtRole.IS_SHADOW, false, false)
.field(CtRole.IS_IMPLICIT, false, false)
- .field(CtRole.MODIFIER, false, true)
+ .field(CtRole.MODIFIER, true, true)
.field(CtRole.INTERFACE, true, true)
.field(CtRole.TYPE_MEMBER, true, true)
.field(CtRole.NESTED_TYPE, true, true)
@@ -1079,7 +1079,7 @@ private static void initTypes(List types) {
types.add(new Type("CtModuleReference", spoon.reflect.reference.CtModuleReference.class, spoon.support.reflect.reference.CtModuleReferenceImpl.class, fm -> fm
.field(CtRole.NAME, false, false)
.field(CtRole.IS_IMPLICIT, false, false)
- .field(CtRole.COMMENT, false, true)
+ .field(CtRole.COMMENT, true, true)
.field(CtRole.POSITION, false, false)
.field(CtRole.ANNOTATION, false, false)
@@ -1099,11 +1099,11 @@ private static void initTypes(List types) {
.field(CtRole.NAME, false, false)
.field(CtRole.IS_SHADOW, false, false)
.field(CtRole.IS_IMPLICIT, false, false)
- .field(CtRole.MODIFIER, false, true)
+ .field(CtRole.MODIFIER, true, true)
.field(CtRole.INTERFACE, true, true)
.field(CtRole.SUPER_TYPE, true, true)
.field(CtRole.POSITION, false, false)
- .field(CtRole.COMMENT, false, true)
+ .field(CtRole.COMMENT, true, true)
.field(CtRole.PACKAGE_REF, false, false)
.field(CtRole.DECLARING_TYPE, false, false)
.field(CtRole.TYPE, false, false)
@@ -1137,7 +1137,7 @@ private static void initTypes(List types) {
.field(CtRole.TYPE, false, false)
.field(CtRole.CAST, false, false)
.field(CtRole.PARAMETER, false, false)
- .field(CtRole.THROWN, false, true)
+ .field(CtRole.THROWN, true, true)
.field(CtRole.BODY, false, false)
.field(CtRole.EXPRESSION, false, false)
.field(CtRole.COMMENT, false, false)
@@ -1169,8 +1169,8 @@ private static void initTypes(List types) {
.field(CtRole.NAME, false, false)
.field(CtRole.IS_SHADOW, false, false)
.field(CtRole.IS_IMPLICIT, false, false)
- .field(CtRole.MODIFIER, false, true)
- .field(CtRole.COMMENT, false, true)
+ .field(CtRole.MODIFIER, true, true)
+ .field(CtRole.COMMENT, true, true)
.field(CtRole.INTERFACE, true, true)
.field(CtRole.SUPER_TYPE, true, true)
.field(CtRole.POSITION, false, false)
@@ -1310,7 +1310,7 @@ private static void initTypes(List types) {
.field(CtRole.IS_FINAL, false, false)
.field(CtRole.IS_STATIC, false, false)
.field(CtRole.IS_IMPLICIT, false, false)
- .field(CtRole.COMMENT, false, true)
+ .field(CtRole.COMMENT, true, true)
.field(CtRole.POSITION, false, false)
.field(CtRole.DECLARING_TYPE, false, false)
.field(CtRole.TYPE, false, false)
@@ -1322,7 +1322,7 @@ private static void initTypes(List types) {
.field(CtRole.NAME, false, false)
.field(CtRole.IS_SHADOW, false, false)
.field(CtRole.IS_IMPLICIT, false, false)
- .field(CtRole.LABEL, false, true)
+ .field(CtRole.LABEL, true, true)
.field(CtRole.MODIFIER, false, false)
.field(CtRole.SUPER_TYPE, true, true)
.field(CtRole.NESTED_TYPE, true, false)
@@ -1359,7 +1359,7 @@ private static void initTypes(List types) {
types.add(new Type("CtLocalVariableReference", spoon.reflect.reference.CtLocalVariableReference.class, spoon.support.reflect.reference.CtLocalVariableReferenceImpl.class, fm -> fm
.field(CtRole.NAME, false, false)
.field(CtRole.IS_IMPLICIT, false, false)
- .field(CtRole.COMMENT, false, true)
+ .field(CtRole.COMMENT, true, true)
.field(CtRole.POSITION, false, false)
.field(CtRole.TYPE, false, false)
.field(CtRole.ANNOTATION, false, false)
diff --git a/src/main/java/spoon/pattern/AbstractItemAccessor.java b/src/main/java/spoon/pattern/AbstractItemAccessor.java
new file mode 100644
index 00000000000..6a93ad50023
--- /dev/null
+++ b/src/main/java/spoon/pattern/AbstractItemAccessor.java
@@ -0,0 +1,424 @@
+/**
+ * Copyright (C) 2006-2017 INRIA and contributors
+ * Spoon - http://spoon.gforge.inria.fr/
+ *
+ * This software is governed by the CeCILL-C License under French law and
+ * abiding by the rules of distribution of free software. You can use, modify
+ * and/or redistribute the software under the terms of the CeCILL-C license as
+ * circulated by CEA, CNRS and INRIA at http://www.cecill.info.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
+ *
+ * The fact that you are presently reading this means that you have had
+ * knowledge of the CeCILL-C license and that you accept its terms.
+ */
+package spoon.pattern;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import spoon.Launcher;
+import spoon.SpoonException;
+import spoon.pattern.matcher.Quantifier;
+import spoon.reflect.code.CtBlock;
+import spoon.reflect.meta.ContainerKind;
+import spoon.reflect.reference.CtTypeReference;
+
+/**
+ */
+abstract class AbstractItemAccessor implements ParameterInfo {
+
+ /**
+ * is used as return value when value cannot be added
+ */
+ protected static final Object NO_MERGE = new Object();
+
+ private final AbstractItemAccessor containerItemAccessor;
+
+ private ContainerKind containerKind = null;
+ private Boolean repeatable = null;
+ private int minOccurences = 0;
+ private int maxOccurences = UNLIMITED_OCCURENCES;
+ private Quantifier matchingStrategy = Quantifier.GREEDY;
+ private ValueConvertor valueConvertor;
+
+ private Predicate