Skip to content
This repository has been archived by the owner on Jan 7, 2020. It is now read-only.

Commit

Permalink
allow multiple labels in contracts [#15]
Browse files Browse the repository at this point in the history
  • Loading branch information
andresteingress committed Apr 7, 2011
1 parent d04bab1 commit 9185733
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import org.codehaus.groovy.ast.expr.BooleanExpression;
import org.codehaus.groovy.ast.expr.ClassExpression;
import org.codehaus.groovy.ast.expr.ClosureExpression;
import org.codehaus.groovy.ast.stmt.AssertStatement;
import org.codehaus.groovy.ast.stmt.BlockStatement;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.control.io.ReaderSource;
Expand Down Expand Up @@ -86,17 +85,15 @@ public void visitClass(ClassNode node) {

List<Parameter> parameters = new ArrayList<Parameter>(Arrays.asList(closureExpression.getParameters()));

final BooleanExpression booleanExpression = ExpressionUtils.getBooleanExpression(closureExpression);
if (booleanExpression == null) continue;

final AssertStatement assertStatement = AssertStatementCreationUtility.getAssertionStatement(booleanExpression);
final List<BooleanExpression> booleanExpressions = ExpressionUtils.getBooleanExpression(closureExpression);
if (booleanExpressions == null || booleanExpressions.isEmpty()) continue;

BlockStatement closureBlockStatement = (BlockStatement) closureExpression.getCode();

BlockStatement newClosureBlockStatement = TryCatchBlockGenerator.generateTryCatchBlock(
ClassHelper.makeWithoutCaching(ClassInvariantViolation.class),
"<" + annotationNode.getClassNode().getName() + "> " + classNode.getName() + " \n\n",
assertStatement
AssertStatementCreationUtility.getAssertionStatemens(booleanExpressions)
);

newClosureBlockStatement.setSourcePosition(closureBlockStatement);
Expand Down Expand Up @@ -157,17 +154,15 @@ private void replaceWithClosureClassReference(AnnotationNode annotationNode, Met

parameters.addAll(new ArrayList<Parameter>(Arrays.asList(methodNode.getParameters())));

final BooleanExpression booleanExpression = ExpressionUtils.getBooleanExpression(closureExpression);
if (booleanExpression == null) return;

final AssertStatement assertStatement = AssertStatementCreationUtility.getAssertionStatement(booleanExpression);
final List<BooleanExpression> booleanExpressions = ExpressionUtils.getBooleanExpression(closureExpression);
if (booleanExpressions == null || booleanExpressions.isEmpty()) return;

BlockStatement closureBlockStatement = (BlockStatement) closureExpression.getCode();

BlockStatement newClosureBlockStatement = TryCatchBlockGenerator.generateTryCatchBlock(
isPostcondition ? ClassHelper.makeWithoutCaching(PostconditionViolation.class) : ClassHelper.makeWithoutCaching(PreconditionViolation.class),
"<" + annotationNode.getClassNode().getName() + "> " + classNode.getName() + "." + methodNode.getTypeDescriptor() + " \n\n",
assertStatement
AssertStatementCreationUtility.getAssertionStatemens(booleanExpressions)
);

newClosureBlockStatement.setSourcePosition(closureBlockStatement);
Expand Down Expand Up @@ -202,17 +197,15 @@ private void replaceWithAnnotationProcessorClosureWithClassReference(ClassNode a

List<Parameter> parameters = new ArrayList<Parameter>(Arrays.asList(closureExpression.getParameters()));

final BooleanExpression booleanExpression = ExpressionUtils.getBooleanExpression(closureExpression);
if (booleanExpression == null) return;

final AssertStatement assertStatement = AssertStatementCreationUtility.getAssertionStatement(booleanExpression);
final List<BooleanExpression> booleanExpressions = ExpressionUtils.getBooleanExpression(closureExpression);
if (booleanExpressions == null || booleanExpressions.isEmpty()) return;

BlockStatement closureBlockStatement = (BlockStatement) closureExpression.getCode();

BlockStatement newClosureBlockStatement = TryCatchBlockGenerator.generateTryCatchBlock(
isPostcondition ? ClassHelper.makeWithoutCaching(PostconditionViolation.class) : ClassHelper.makeWithoutCaching(PreconditionViolation.class),
"<" + annotation.getName() + "> Annotation Closure Contract has been violated \n\n",
assertStatement
AssertStatementCreationUtility.getAssertionStatemens(booleanExpressions)
);

newClosureBlockStatement.setSourcePosition(closureBlockStatement);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.codehaus.groovy.ast.expr.BooleanExpression;
import org.codehaus.groovy.ast.stmt.*;

import java.util.ArrayList;
import java.util.List;

/**
Expand All @@ -40,6 +41,26 @@
*/
public final class AssertStatementCreationUtility {

/**
* Reusable method for creating assert statements for the given <tt>booleanExpression</tt>.
*
* @param booleanExpressions the assertion's {@link org.codehaus.groovy.ast.expr.BooleanExpression} instances
*
* @return a newly created {@link org.codehaus.groovy.ast.stmt.AssertStatement}
*/
public static BlockStatement getAssertionStatemens(final List<BooleanExpression> booleanExpressions) {

List<AssertStatement> assertStatements = new ArrayList<AssertStatement>();
for (BooleanExpression booleanExpression : booleanExpressions) {
assertStatements.add(getAssertionStatement(booleanExpression));
}

final BlockStatement blockStatement = new BlockStatement();
blockStatement.getStatements().addAll(assertStatements);

return blockStatement;
}

/**
* Reusable method for creating assert statements for the given <tt>booleanExpression</tt>.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
*/
public class TryCatchBlockGenerator {

public static BlockStatement generateTryCatchBlock(final ClassNode assertionErrorClass, final String message, final AssertStatement assertStatement) {
public static BlockStatement generateTryCatchBlock(final ClassNode assertionErrorClass, final String message, final Statement assertStatement) {

final String $_gc_closure_result = "$_gc_closure_result";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.codehaus.groovy.ast.stmt.ExpressionStatement;
import org.codehaus.groovy.ast.stmt.Statement;

import java.util.ArrayList;
import java.util.List;

/**
Expand All @@ -47,28 +48,30 @@ public class ExpressionUtils {
* @param closureExpression the assertion's {@link org.codehaus.groovy.ast.expr.ClosureExpression}
* @return the first {@link org.codehaus.groovy.ast.expr.Expression} found in the given {@link org.codehaus.groovy.ast.expr.ClosureExpression}
*/
public static BooleanExpression getBooleanExpression(ClosureExpression closureExpression) {
public static List<BooleanExpression> getBooleanExpression(ClosureExpression closureExpression) {
if (closureExpression == null) return null;

final BlockStatement closureBlockStatement = (BlockStatement) closureExpression.getCode();
final List<Statement> statementList = closureBlockStatement.getStatements();

List<BooleanExpression> booleanExpressions = new ArrayList<BooleanExpression>();

for (Statement stmt : statementList) {
if (stmt instanceof ExpressionStatement && ((ExpressionStatement) stmt).getExpression() instanceof BooleanExpression) {
final BooleanExpression expression = (BooleanExpression) ((ExpressionStatement) stmt).getExpression();
expression.setNodeMetaData("statementLabel", stmt.getStatementLabel());
return expression;
BooleanExpression tmp = null;

if (stmt instanceof ExpressionStatement && ((ExpressionStatement) stmt).getExpression() instanceof BooleanExpression) {
tmp = (BooleanExpression) ((ExpressionStatement) stmt).getExpression();
tmp.setNodeMetaData("statementLabel", stmt.getStatementLabel());
} else if (stmt instanceof ExpressionStatement) {
Expression expression = ((ExpressionStatement) stmt).getExpression();
BooleanExpression result = new BooleanExpression(expression);
result.setSourcePosition(expression);
result.setNodeMetaData("statementLabel", stmt.getStatementLabel());

return result;
tmp = new BooleanExpression(expression);
tmp.setSourcePosition(expression);
tmp.setNodeMetaData("statementLabel", stmt.getStatementLabel());
}

booleanExpressions.add(tmp);
}

return null;
return booleanExpressions;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,19 @@ import org.gcontracts.annotations.*
class A {
@Ensures({
result_is_a_result: result == param
result_is_no_result: result != param
})
def some_operation(def param) {
null
}
}
'''

shouldFail PostconditionViolation, {
def a = create_instance_of(source1)
a.some_operation null
}

shouldFail PostconditionViolation, {
def a = create_instance_of(source1)
a.some_operation "test"
Expand Down

0 comments on commit 9185733

Please sign in to comment.