Skip to content

Commit

Permalink
feature: Spoon meta model
Browse files Browse the repository at this point in the history
  • Loading branch information
pvojtechovsky committed Oct 21, 2017
1 parent 8084760 commit bad27a8
Show file tree
Hide file tree
Showing 5 changed files with 881 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/main/java/spoon/metamodel/MMContainerType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* 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.metamodel;

/**
* Represents type of container used for field value.
*/
public enum MMContainerType {
/**
* it is a single value field
* Example: CtClassImpl.simpleName
*/
SINGLE,
/**
* It is a list of values
* Example: CtClassImpl.typeMembers
*/
LIST,
/**
* It is a set of values
* Example: CtPackageImpl.types
*/
SET,
/**
* It is a map<String, T> of values
* Example: CtAnnotationImpl.elementValues
*/
MAP;
}
177 changes: 177 additions & 0 deletions src/main/java/spoon/metamodel/MMField.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/**
* 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.metamodel;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import spoon.reflect.declaration.CtMethod;
import spoon.reflect.path.CtRole;
import spoon.reflect.reference.CtTypeReference;

import static spoon.metamodel.SpoonMetaModel.addUniqueObject;
import static spoon.metamodel.SpoonMetaModel.getOrCreate;

/**
* Represents a field of Spoon model type.
* Each MMField belongs to one MMType
*/
public class MMField {
/**
* Name of the field
*/
final String name;
/**
* {@link CtRole} of the field
*/
final CtRole role;
/**
* The list of {@link MMType}s which contains this field
*/
final MMType ownerType;
/**
* Type of value container [single, list, set, map]
*/
MMContainerType valueContainerType;
/**
* The type of value of this field - can be Set, List, Map or any non collection type
*/
CtTypeReference<?> valueType;
/**
* The item type of value of this field - can be non collection type
*/
CtTypeReference<?> itemValueType;

Boolean derived;

CtMethod<?> get;
CtMethod<?> set;
CtMethod<?> add;
CtMethod<?> addFirst;
CtMethod<?> addLast;
CtMethod<?> addOn;
CtMethod<?> remove;


/**
* methods of this field defined directly on ownerType.
* There is PropertyGetter or PropertySetter annotation with `role` of this {@link MMField}
*/
final List<CtMethod<?>> roleMethods = new ArrayList<>();
/**
* List of fields with same `role`, from super type of `ownerType` {@link MMType}
*/
final List<MMField> superFields = new ArrayList<>();

/**
* own and inherited methods grouped by method signature and the methods
* in list ordered by own methods are first
*/
final Map<String, List<CtMethod<?>>> allRoleMethodsBySignature = new HashMap<>();

MMField(String name, CtRole role, MMType ownerType) {
super();
this.name = name;
this.role = role;
this.ownerType = ownerType;
}

void addMethod(CtMethod<?> method) {
roleMethods.add(method);
List<CtMethod<?>> methods = getOrCreate(allRoleMethodsBySignature, method.getSignature(),
() -> new ArrayList<>());
addUniqueObject(methods, method);
}

void addSuperField(MMField superMMField) {
if (addUniqueObject(superFields, superMMField)) {
for (Map.Entry<String, List<CtMethod<?>>> e : superMMField.allRoleMethodsBySignature.entrySet()) {
getOrCreate(allRoleMethodsBySignature, e.getKey(), () -> new ArrayList<>()).addAll(e.getValue());
}
}
}

public String getName() {
return name;
}

public CtRole getRole() {
return role;
}

public MMType getOwnerType() {
return ownerType;
}

public MMContainerType getValueContainerType() {
return valueContainerType;
}

public CtTypeReference<?> getValueType() {
return valueType;
}

public CtTypeReference<?> getItemValueType() {
return itemValueType;
}

public Boolean getDerived() {
return derived;
}

public CtMethod<?> getGet() {
return get;
}

public CtMethod<?> getSet() {
return set;
}

public CtMethod<?> getAdd() {
return add;
}

public CtMethod<?> getAddFirst() {
return addFirst;
}

public CtMethod<?> getAddLast() {
return addLast;
}

public CtMethod<?> getAddOn() {
return addOn;
}

public CtMethod<?> getRemove() {
return remove;
}

public List<CtMethod<?>> getRoleMethods() {
return roleMethods;
}

public List<MMField> getSuperFields() {
return superFields;
}

public Map<String, List<CtMethod<?>>> getAllRoleMethodsBySignature() {
return allRoleMethodsBySignature;
}
}
91 changes: 91 additions & 0 deletions src/main/java/spoon/metamodel/MMType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* 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.metamodel;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtInterface;
import spoon.reflect.path.CtRole;

/**
* Represents a type of Spoon model class
*/
public class MMType {
/**
* Kind of this type
*/
MMTypeKind kind;
/**
* Name of the type
*/
final String name;
/**
* List of fields ordered same like CtScanner scans them
*/
final Map<CtRole, MMField> role2field = new LinkedHashMap<>();

/**
* List of super types of this type
*/
final List<MMType> superTypes = new ArrayList<>();

/**
* The {@link CtClass} linked to this {@link MMType}. Is null in case of class without interface
*/
CtClass<?> modelClass;
/**
* The {@link CtInterface} linked to this {@link MMType}. Is null in case of interface without class
*/
CtInterface<?> modelInteface;

MMType(String name) {
super();
this.name = name;
}

MMField getOrCreateMMField(CtRole role) {
return SpoonMetaModel.getOrCreate(role2field, role, () -> new MMField(role.getCamelCaseName(), role, this));
}

public MMTypeKind getKind() {
return kind;
}

public String getName() {
return name;
}

public Map<CtRole, MMField> getRole2field() {
return role2field;
}

public List<MMType> getSuperTypes() {
return superTypes;
}

public CtClass<?> getModelClass() {
return modelClass;
}

public CtInterface<?> getModelInteface() {
return modelInteface;
}
}
33 changes: 33 additions & 0 deletions src/main/java/spoon/metamodel/MMTypeKind.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* 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.metamodel;

/**
* Represents type of Spoon model class
*/
public enum MMTypeKind {
/**
* Kind of type which represents leaf of Spoon model.
* Examples: CtClass, CtField, CtThrow
*/
LEAF,
/**
* Kind of type which represents some abstract concept of Spoon model
* Examples: CtExecutable, CtReference, CtBodyHolder, ...
*/
ABSTRACT;
}
Loading

0 comments on commit bad27a8

Please sign in to comment.