Skip to content

Commit

Permalink
feature: PatternBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
pvojtechovsky committed Nov 15, 2017
1 parent 721d774 commit d943134
Show file tree
Hide file tree
Showing 36 changed files with 3,109 additions and 400 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* 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.Map;

import spoon.reflect.declaration.CtElement;
import spoon.reflect.path.CtRole;
import spoon.template.TemplateMatcher;

/**
* Represents the request for substitution of an attribute of AST node by different value.
* For example: CtModifiable.modifiers, CtBinaryOperator.leftHandOperand, ...
* Whole values of CtNamedElement.simpleName, CtStatement.label, CtComment.comment
* All statements of CtBlock, ...
*/
public abstract class AbstractAttributeSubstitutionRequest implements SubstitutionRequest {
private final NodeAttributesSubstitionRequest owner;
private final CtRole roleOfSubstitutedValue;


AbstractAttributeSubstitutionRequest(NodeAttributesSubstitionRequest owner, CtRole roleOfSubstitutedValue) {
this.owner = owner;
this.roleOfSubstitutedValue = roleOfSubstitutedValue;
}

public NodeAttributesSubstitionRequest getOwner() {
return owner;
}

@Override
public CtRole getRoleOfSubstitutedValue() {
return roleOfSubstitutedValue;
}

public CtElement getSubstitutedNode() {
return owner.getSubstitutedNode();
}

@Override
public CtElement getParentNode() {
return owner.getSubstitutedNode();
}

public abstract <T extends CtElement> void substitute(T clonedElement, Map<String, Object> params);
public abstract boolean matches(TemplateMatcher matcher, Object target, Object template);
}
52 changes: 52 additions & 0 deletions src/main/java/spoon/pattern/AbstractNodeSubstitutionRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* 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.List;
import java.util.Map;

import spoon.pattern.Pattern.ModelCloner;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.path.CtRole;

/**
* Represents the generic request for some substitution of Pattern model node
*/
public abstract class AbstractNodeSubstitutionRequest implements SubstitutionRequest {

private final CtElement substitutedNode;


AbstractNodeSubstitutionRequest(CtElement substitutedNode) {
super();
this.substitutedNode = substitutedNode;
}

public CtElement getSubstitutedNode() {
return substitutedNode;
}

public CtRole getRoleOfSubstitutedValue() {
return getSubstitutedNode().getRoleInParent();
}

public CtElement getParentNode() {
return getSubstitutedNode().getParent();
}

public abstract <T extends CtElement> List<T> substitute(ModelCloner cloneHelper, Map<String, Object> params);
}
66 changes: 66 additions & 0 deletions src/main/java/spoon/pattern/AttributeSubstitutionRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* 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.List;
import java.util.Map;

import spoon.reflect.declaration.CtElement;
import spoon.reflect.meta.ContainerKind;
import spoon.reflect.path.CtRole;
import spoon.template.TemplateMatcher;

/**
* Represents the request for substitution of an attribute of AST node by different value.
* For example: CtModifiable.modifiers, CtBinaryOperator.leftHandOperand, ...
* Whole values of CtNamedElement.simpleName, CtStatement.label, CtComment.comment
* All statements of CtBlock, ...
*/
public class AttributeSubstitutionRequest extends AbstractAttributeSubstitutionRequest {

private final ParameterInfo parameterInfo;

AttributeSubstitutionRequest(NodeAttributesSubstitionRequest owner, ParameterInfo parameterInfo, CtRole roleOfSubstitutedValue) {
super(owner, roleOfSubstitutedValue);
this.parameterInfo = parameterInfo;
this.parameterInfo.addSubstitutionRequest(this);
}

public ParameterInfo getParameterInfo() {
return parameterInfo;
}

@Override
public <T extends CtElement> void substitute(T clonedElement, Map<String, Object> params) {
ConversionContext context = new ConversionContext(this, getParameterInfo(), params);
List<Object> convertedValues = getParameterInfo().getValueConvertor().getValueAs(context);
if (context.getRoleHandler().getContainerKind() == ContainerKind.SINGLE) {
if (convertedValues.isEmpty()) {
context.getRoleHandler().setValue(clonedElement, null);
} else {
context.getRoleHandler().setValue(clonedElement, convertedValues.get(0));
}
} else {
context.getRoleHandler().setValue(clonedElement, convertedValues);
}
}

@Override
public boolean matches(TemplateMatcher matcher, Object target, Object template) {
return matcher.addMatch(getParameterInfo(), target);
}
}
85 changes: 85 additions & 0 deletions src/main/java/spoon/pattern/ConversionContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* 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.Map;

import spoon.SpoonException;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.meta.RoleHandler;
import spoon.reflect.meta.impl.RoleHandlerHelper;
import spoon.reflect.path.CtRole;

/**
* Converts the individual parameter values to required type
*/
public class ConversionContext {
private final SubstitutionRequest substitutionRequest;
private final Object value;
private Class requiredClass;
private final CtRole roleInParent;
private final CtElement parent;
private final RoleHandler roleHandler;
private final ParameterInfo parameterInfo;

public ConversionContext(SubstitutionRequest substitutionRequest, ParameterInfo parameterInfo, Map<String, Object> params) {
this.value = params.get(parameterInfo.getName());
this.substitutionRequest = substitutionRequest;
this.parameterInfo = parameterInfo;
this.roleInParent = substitutionRequest.getRoleOfSubstitutedValue();
this.parent = substitutionRequest.getParentNode();
this.roleHandler = RoleHandlerHelper.getRoleHandler(parent.getClass(), roleInParent);
}

public SubstitutionRequest getSubstitutionRequest() {
return substitutionRequest;
}

public Object getValue() {
return value;
}

public CtRole getRoleInParent() {
return roleInParent;
}

public CtElement getParent() {
return parent;
}

public RoleHandler getRoleHandler() {
return roleHandler;
}

public ParameterInfo getParameterInfo() {
return parameterInfo;
}

public Class getRequiredClass() {
if (requiredClass == null) {
return roleHandler.getValueClass();
}
return requiredClass;
}

public void setRequiredClass(Class requiredClass) {
if (roleHandler.getValueClass().isAssignableFrom(requiredClass) == false) {
throw new SpoonException("Cannot force required type to " + requiredClass.getName() + " for Role of type " + roleHandler.getValueClass().getName());
}
this.requiredClass = requiredClass;
}
}
65 changes: 65 additions & 0 deletions src/main/java/spoon/pattern/NodeAttributesSubstitionRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* 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.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import spoon.SpoonException;
import spoon.pattern.Pattern.ModelCloner;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.path.CtRole;

/**
* Represents the request for substitution of attributes of node of Pattern model
*/
public class NodeAttributesSubstitionRequest extends AbstractNodeSubstitutionRequest {

private final Map<CtRole, AbstractAttributeSubstitutionRequest> attributeSubstititionRequests = new HashMap<>();


NodeAttributesSubstitionRequest(CtElement substitutedNode) {
super(substitutedNode);
}

void addAttributeSubstitutionRequest(AbstractAttributeSubstitutionRequest sr) {
AbstractAttributeSubstitutionRequest old = attributeSubstititionRequests.put(sr.getRoleOfSubstitutedValue(), sr);
if (old != null && old != sr) {
throw new SpoonException("Cannot add two substitution requests to the same node attribute " + sr.getRoleOfSubstitutedValue());
}
}

public Map<CtRole, AbstractAttributeSubstitutionRequest> getAttributeSubstititionRequests() {
return Collections.unmodifiableMap(attributeSubstititionRequests);
}

public AbstractAttributeSubstitutionRequest getAttributeSubstititionRequest(CtRole attributeRole) {
return attributeSubstititionRequests.get(attributeRole);
}

@Override
public <T extends CtElement> List<T> substitute(ModelCloner cloneHelper, Map<String, Object> params) {
@SuppressWarnings("unchecked")
T clonedElement = (T) cloneHelper.originClone(getSubstitutedNode());
for (AbstractAttributeSubstitutionRequest attributeSubstitutionRequest : attributeSubstititionRequests.values()) {
attributeSubstitutionRequest.substitute(clonedElement, params);
}
return Collections.singletonList(clonedElement);
}
}
Loading

0 comments on commit d943134

Please sign in to comment.