use of org.codehaus.groovy.ast.stmt.ReturnStatement in project gcontracts by andresteingress.
the class OldVariableGenerationUtility method addOldVariableMethodNode.
/**
* Creates a synthetic method handling generation of the <tt>old</tt> variable map. If a super class declares
* the same synthetic method it will be called and the results will be merged.
*
* @param classNode which contains postconditions, so an old variable generating method makes sense here.
*/
public static void addOldVariableMethodNode(final ClassNode classNode) {
if (classNode.getDeclaredMethod(OLD_VARIABLES_METHOD, Parameter.EMPTY_ARRAY) != null)
return;
final BlockStatement methodBlockStatement = new BlockStatement();
final MapExpression oldVariablesMap = new MapExpression();
// create variable assignments for old variables
for (final FieldNode fieldNode : classNode.getFields()) {
if (fieldNode.getName().startsWith("$"))
continue;
final ClassNode fieldType = ClassHelper.getWrapper(fieldNode.getType());
if (fieldType.getName().startsWith("java.lang") || ClassHelper.isPrimitiveType(fieldType) || fieldType.getName().startsWith("java.math") || fieldType.getName().startsWith("java.util") || fieldType.getName().startsWith("java.sql") || fieldType.getName().equals("groovy.lang.GString") || fieldType.getName().equals("java.lang.String")) {
MethodNode cloneMethod = fieldType.getMethod("clone", Parameter.EMPTY_ARRAY);
// if a clone classNode is available, the value is cloned
if (cloneMethod != null && fieldType.implementsInterface(ClassHelper.make("java.lang.Cloneable"))) {
VariableExpression oldVariable = new VariableExpression("$old$" + fieldNode.getName(), fieldNode.getType());
oldVariable.setAccessedVariable(oldVariable);
final MethodCallExpression methodCall = new MethodCallExpression(new FieldExpression(fieldNode), "clone", ArgumentListExpression.EMPTY_ARGUMENTS);
// return null if field is null
methodCall.setSafe(true);
ExpressionStatement oldVariableAssignment = new ExpressionStatement(new DeclarationExpression(oldVariable, Token.newSymbol(Types.ASSIGN, -1, -1), methodCall));
methodBlockStatement.addStatement(oldVariableAssignment);
oldVariablesMap.addMapEntryExpression(new MapEntryExpression(new ConstantExpression(oldVariable.getName().substring("$old$".length())), oldVariable));
} else if (ClassHelper.isPrimitiveType(fieldType) || ClassHelper.isNumberType(fieldType) || fieldType.getName().startsWith("java.math") || fieldType.getName().equals("groovy.lang.GString") || fieldType.getName().equals("java.lang.String")) {
VariableExpression oldVariable = new VariableExpression("$old$" + fieldNode.getName(), fieldNode.getType());
oldVariable.setAccessedVariable(oldVariable);
ExpressionStatement oldVariableAssignment = new ExpressionStatement(new DeclarationExpression(oldVariable, Token.newSymbol(Types.ASSIGN, -1, -1), new FieldExpression(fieldNode)));
methodBlockStatement.addStatement(oldVariableAssignment);
oldVariablesMap.addMapEntryExpression(new MapEntryExpression(new ConstantExpression(oldVariable.getName().substring("$old$".length())), oldVariable));
}
}
}
VariableExpression oldVariable = new VariableExpression("old", new ClassNode(Map.class));
oldVariable.setAccessedVariable(oldVariable);
ExpressionStatement oldVariabeStatement = new ExpressionStatement(new DeclarationExpression(oldVariable, Token.newSymbol(Types.ASSIGN, -1, -1), oldVariablesMap));
methodBlockStatement.addStatement(oldVariabeStatement);
VariableExpression mergedOldVariables = null;
// let's ask the super class for old variables...
if (classNode.getSuperClass() != null && classNode.getSuperClass().getMethod(OLD_VARIABLES_METHOD, Parameter.EMPTY_ARRAY) != null) {
mergedOldVariables = new VariableExpression("mergedOldVariables", new ClassNode(Map.class));
mergedOldVariables.setAccessedVariable(mergedOldVariables);
ExpressionStatement mergedOldVariablesStatement = new ExpressionStatement(new DeclarationExpression(mergedOldVariables, Token.newSymbol(Types.ASSIGN, -1, -1), new MethodCallExpression(oldVariable, "plus", new ArgumentListExpression(new MethodCallExpression(VariableExpression.SUPER_EXPRESSION, OLD_VARIABLES_METHOD, ArgumentListExpression.EMPTY_ARGUMENTS)))));
methodBlockStatement.addStatement(mergedOldVariablesStatement);
}
methodBlockStatement.addStatement(new ReturnStatement(mergedOldVariables != null ? mergedOldVariables : oldVariable));
final MethodNode preconditionMethodNode = classNode.addMethod(OLD_VARIABLES_METHOD, Opcodes.ACC_PROTECTED, new ClassNode(Map.class), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, methodBlockStatement);
preconditionMethodNode.setSynthetic(true);
}
use of org.codehaus.groovy.ast.stmt.ReturnStatement in project gcontracts by andresteingress.
the class ClassInvariantGenerator method addInvariantAssertionStatement.
/**
* Adds the current class-invariant to the given <tt>method</tt>.
*
* @param type the {@link org.codehaus.groovy.ast.ClassNode} which declared the given {@link org.codehaus.groovy.ast.MethodNode}
* @param method the current {@link org.codehaus.groovy.ast.MethodNode}
*/
public void addInvariantAssertionStatement(final ClassNode type, final MethodNode method) {
final String invariantMethodName = getInvariantMethodName(type);
final MethodNode invariantMethod = type.getDeclaredMethod(invariantMethodName, Parameter.EMPTY_ARRAY);
if (invariantMethod == null)
return;
Statement invariantMethodCall = new ExpressionStatement(new MethodCallExpression(VariableExpression.THIS_EXPRESSION, invariantMethod.getName(), ArgumentListExpression.EMPTY_ARGUMENTS));
final Statement statement = method.getCode();
if (statement instanceof BlockStatement && method.getReturnType() != ClassHelper.VOID_TYPE && !(method instanceof ConstructorNode)) {
final BlockStatement blockStatement = (BlockStatement) statement;
final List<ReturnStatement> returnStatements = AssertStatementCreationUtility.getReturnStatements(method);
for (ReturnStatement returnStatement : returnStatements) {
AssertStatementCreationUtility.addAssertionCallStatementToReturnStatement(blockStatement, returnStatement, invariantMethodCall);
}
if (returnStatements.isEmpty())
blockStatement.addStatement(invariantMethodCall);
} else if (statement instanceof BlockStatement) {
final BlockStatement blockStatement = (BlockStatement) statement;
blockStatement.addStatement(invariantMethodCall);
} else {
final BlockStatement assertionBlock = new BlockStatement();
assertionBlock.addStatement(statement);
assertionBlock.addStatement(invariantMethodCall);
method.setCode(assertionBlock);
}
}
use of org.codehaus.groovy.ast.stmt.ReturnStatement in project hale by halestudio.
the class VertexEntityTransformation method buildFindByMethod.
/**
* Create a static method to retrieve objects by property value.
*
* @param clazz the entity class node
* @param entityName the entity name
* @param typeProperty the name of the property holding the entity name in a
* vertex
* @param propertyName the property name
* @param propertyType the property type
* @return the method
*/
private MethodNode buildFindByMethod(ClassNode clazz, Expression entityName, Expression typeProperty, String propertyName, ClassNode propertyType) {
clazz = ClassHelper.make(clazz.getName());
propertyType = ClassHelper.make(propertyType.getName());
ClassNode returnType = ITERABLE_CLASS.getPlainNodeReference();
// add generic type argument
returnType.setGenericsTypes(new GenericsType[] { new GenericsType(clazz) });
String methodName = "findBy" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
BlockStatement code = new BlockStatement();
// initialize graph
code.addStatement(callInitGraph(clazz, new VariableExpression("graph")));
/*
* def vertices = VertexEntityDelegates.findByDelegate(graph,
* entityName, typeProperty, propertyName, value)
*/
VariableExpression vertices = new VariableExpression("vertices");
ArgumentListExpression args = new ArgumentListExpression();
args.addExpression(new VariableExpression("graph"));
args.addExpression(entityName);
args.addExpression(typeProperty);
args.addExpression(new ConstantExpression(propertyName));
args.addExpression(new VariableExpression("value"));
code.addStatement(AbstractASTTransformUtil.declStatement(vertices, new StaticMethodCallExpression(VE_DELEGATES_CLASS, VertexEntityDelegates.METHOD_FIND_BY, args)));
/*
* return new IterableDelegate(vertices, EntityClass, graph)
*/
ArgumentListExpression createDelegateArgs = new ArgumentListExpression();
createDelegateArgs.addExpression(vertices);
createDelegateArgs.addExpression(new ClassExpression(clazz));
createDelegateArgs.addExpression(new VariableExpression("graph"));
code.addStatement(new ReturnStatement(new ConstructorCallExpression(VE_ITERABLE_DELEGATE_CLASS, createDelegateArgs)));
return new MethodNode(methodName, Modifier.STATIC | Modifier.PUBLIC, returnType, new Parameter[] { new Parameter(GRAPH_CLASS, "graph"), new Parameter(propertyType, "value") }, new ClassNode[0], code);
}
use of org.codehaus.groovy.ast.stmt.ReturnStatement in project hale by halestudio.
the class VertexEntityTransformation method buildGetByIdMethod.
/**
* Create a static method to get an entity by its ID.
*
* @param clazz the entity class node
* @return the method
*/
private MethodNode buildGetByIdMethod(ClassNode clazz) {
clazz = ClassHelper.make(clazz.getName());
BlockStatement code = new BlockStatement();
// initialize graph
code.addStatement(callInitGraph(clazz, new VariableExpression("graph")));
// def vertex = graph.getVertex(id)
VariableExpression vertex = new VariableExpression("vertex");
code.addStatement(AbstractASTTransformUtil.declStatement(vertex, new MethodCallExpression(new VariableExpression("graph"), "getVertex", new ArgumentListExpression(new VariableExpression("id")))));
/*
* return new EntityClass(vertex, graph)
*/
Statement returnEntity = new ReturnStatement(new ConstructorCallExpression(clazz, new ArgumentListExpression(vertex, new VariableExpression("graph"))));
// return null
Statement returnNull = new ReturnStatement(new ConstantExpression(null));
// if (vertex == null) ... else ...
code.addStatement(new IfStatement(AbstractASTTransformUtil.equalsNullExpr(vertex), returnNull, returnEntity));
return new MethodNode("getById", Modifier.STATIC | Modifier.PUBLIC, clazz, new Parameter[] { new Parameter(GRAPH_CLASS, "graph"), new Parameter(ClassHelper.OBJECT_TYPE, "id") }, new ClassNode[] { VE_NON_UNIQUE_EXCEPTION }, code);
}
use of org.codehaus.groovy.ast.stmt.ReturnStatement in project hale by halestudio.
the class VertexEntityTransformation method createGetter.
private Statement createGetter(String name, FieldNode vertexField, ClassNode propertyType, Expression initialExpression) {
BlockStatement block = new BlockStatement();
// def tmp
VariableExpression tmpValue = new VariableExpression("tmp");
/*
* > tmp = v.getProperty(name)
*/
ArgumentListExpression args = new ArgumentListExpression();
args.addExpression(new ConstantExpression(name));
block.addStatement(AbstractASTTransformUtil.declStatement(tmpValue, new MethodCallExpression(new FieldExpression(vertexField), "getProperty", args)));
if (ClassHelper.isPrimitiveType(propertyType) && initialExpression != null) {
// if the class is a primitive, we must do a null check here
// if (tmp == null) return <initial-value>
block.addStatement(new IfStatement(AbstractASTTransformUtil.equalsNullExpr(tmpValue), new ReturnStatement(initialExpression), new EmptyStatement()));
}
block.addStatement(new ReturnStatement(tmpValue));
return block;
}
Aggregations