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

Commit

Permalink
introduced AssertionMap in domain model
Browse files Browse the repository at this point in the history
  • Loading branch information
andresteingress committed Mar 3, 2011
1 parent 8ce0df9 commit 97db253
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 51 deletions.
Expand Up @@ -156,12 +156,16 @@ private void visitAnnotatedNode(AnnotatedNode annotatedNode, ClassNode classNode

for (AnnotationNode annotationNode : annotationNodes) {
AnnotationProcessor processor = createAnnotationProcessor(annotationNode);
if (processor == null || !(annotationNode.getMember(CLOSURE_ATTRIBUTE_NAME) instanceof ClosureExpression)) continue;
if (processor == null) continue;

if (methodNode == null) {
processor.process(pci, pci.contract(), annotatedNode, ExpressionUtils.getBooleanExpression((ClosureExpression) annotationNode.getMember(CLOSURE_ATTRIBUTE_NAME)));
if (annotationNode.getMember(CLOSURE_ATTRIBUTE_NAME) instanceof ClosureExpression) {
if (methodNode == null) {
processor.process(pci, pci.contract(), annotatedNode, ExpressionUtils.getBooleanExpression((ClosureExpression) annotationNode.getMember(CLOSURE_ATTRIBUTE_NAME)));
} else {
processor.process(pci, pci.contract(), annotatedNode, methodNode, ExpressionUtils.getBooleanExpression((ClosureExpression) annotationNode.getMember(CLOSURE_ATTRIBUTE_NAME)));
}
} else {
processor.process(pci, pci.contract(), annotatedNode, methodNode, ExpressionUtils.getBooleanExpression((ClosureExpression) annotationNode.getMember(CLOSURE_ATTRIBUTE_NAME)));
processor.process(pci, pci.contract(), annotatedNode, methodNode);
}
}
}
Expand Down
Expand Up @@ -64,11 +64,11 @@ public DomainModelInjectionVisitor(final SourceUnit sourceUnit, final ReaderSour
public void visitClass(ClassNode type) {
addClassInvariant(type, contract.classInvariant());

for (Map.Entry<MethodNode, Precondition> entry : contract.preconditions().entrySet()) {
for (Map.Entry<MethodNode, Precondition> entry : contract.preconditions()) {
addPrecondition(entry.getKey(), entry.getValue());
}

for (Map.Entry<MethodNode, Postcondition> entry : contract.postconditions().entrySet()) {
for (Map.Entry<MethodNode, Postcondition> entry : contract.postconditions()) {
addPostcondition(entry.getKey(), entry.getValue());
}

Expand Down
Expand Up @@ -40,6 +40,6 @@ public void process(ProcessingContextInformation processingContextInformation, C
if (!processingContextInformation.isPostconditionsEnabled()) return;
if (booleanExpression == null) return;

contract.addPostcondition((MethodNode) annotatedNode, new Postcondition(booleanExpression));
contract.postconditions().and((MethodNode) annotatedNode, new Postcondition(booleanExpression));
}
}
Expand Up @@ -44,15 +44,15 @@
public class NotNullAnnotationProcessor extends AnnotationProcessor {

@Override
public void process(ProcessingContextInformation processingContextInformation, Contract contract, AnnotatedNode annotatedNode, MethodNode methodNode, BooleanExpression booleanExpression) {
public void process(ProcessingContextInformation processingContextInformation, Contract contract, AnnotatedNode annotatedNode, MethodNode methodNode) {
if (!processingContextInformation.isPreconditionsEnabled()) return;

booleanExpression = new BooleanExpression(new BinaryExpression(
BooleanExpression booleanExpression = new BooleanExpression(new BinaryExpression(
new VariableExpression((Parameter) annotatedNode),
Token.newSymbol(Types.COMPARE_NOT_EQUAL, -1, -1),
ConstantExpression.NULL
));

contract.addPrecondition(methodNode, new Precondition(booleanExpression));
contract.preconditions().join(methodNode, new Precondition(booleanExpression));
}
}
Expand Up @@ -40,6 +40,6 @@ public void process(ProcessingContextInformation processingContextInformation, C
if (!processingContextInformation.isPreconditionsEnabled()) return;
if (booleanExpression == null) return;

contract.addPrecondition((MethodNode) annotatedNode, new Precondition(booleanExpression));
contract.preconditions().or((MethodNode) annotatedNode, new Precondition(booleanExpression));
}
}
Expand Up @@ -41,7 +41,7 @@ public void afterProcessingMethodNode(ProcessingContextInformation processingCon

final PostconditionGenerator postconditionGenerator = new PostconditionGenerator(processingContextInformation.readerSource());

if (processingContextInformation.contract().postconditions().containsKey(methodNode)) {
if (processingContextInformation.contract().postconditions().contains(methodNode)) {
postconditionGenerator.addOldVariablesMethod(classNode);
} else {
postconditionGenerator.generateDefaultPostconditionStatement(classNode, methodNode);
Expand Down
Expand Up @@ -38,7 +38,7 @@ public class PreconditionLifecycle extends BaseLifecycle {
public void afterProcessingMethodNode(ProcessingContextInformation processingContextInformation, ClassNode classNode, MethodNode methodNode) {
if (!processingContextInformation.isPreconditionsEnabled()) return;
if (!CandidateChecks.isPreOrPostconditionCandidate(classNode, methodNode)) return;
if (processingContextInformation.contract().preconditions().containsKey(methodNode)) return;
if (processingContextInformation.contract().preconditions().contains(methodNode)) return;

final PreconditionGenerator preconditionGenerator = new PreconditionGenerator(processingContextInformation.readerSource());
preconditionGenerator.generateDefaultPreconditionStatement(classNode, methodNode);
Expand Down
Expand Up @@ -32,6 +32,7 @@
*/
public abstract class AnnotationProcessor {

public void process(final ProcessingContextInformation processingContextInformation, final Contract contract, final AnnotatedNode annotatedNode, final MethodNode methodNode) {}
public void process(final ProcessingContextInformation processingContextInformation, final Contract contract, final AnnotatedNode annotatedNode, final BooleanExpression booleanExpression) {}
public void process(final ProcessingContextInformation processingContextInformation, final Contract contract, final AnnotatedNode annotatedNode, final MethodNode methodNode, final BooleanExpression booleanExpression) {}
}
@@ -0,0 +1,62 @@
package org.gcontracts.domain;

import org.codehaus.groovy.ast.MethodNode;
import org.gcontracts.util.Validate;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
* @author andre.steingress@gmail.com
*/
public class AssertionMap<T extends Assertion<T>> implements Iterable<Map.Entry<MethodNode, T>> {

private final Map<MethodNode, T> internalMap;

public AssertionMap() {
this.internalMap = new HashMap<MethodNode, T>();
}

public void and(final MethodNode methodNode, final T assertion) {
Validate.notNull(methodNode);
Validate.notNull(assertion);

if (!internalMap.containsKey(methodNode)) {
internalMap.put(methodNode, assertion);
} else {
internalMap.get(methodNode).and(assertion);
}
}

public void or(final MethodNode methodNode, final T assertion) {
Validate.notNull(methodNode);
Validate.notNull(assertion);

if (!internalMap.containsKey(methodNode)) {
internalMap.put(methodNode, assertion);
} else {
internalMap.get(methodNode).or(assertion);
}
}

public void join(final MethodNode methodNode, final T assertion) {
and(methodNode, assertion);
}

public boolean contains(final MethodNode methodNode) {
return internalMap.containsKey(methodNode);
}

public Iterator<Map.Entry<MethodNode, T>> iterator() {
return internalMap.entrySet().iterator();
}

public int size() {
return internalMap.size();
}

public T get(final MethodNode methodNode) {
return internalMap.get(methodNode);
}
}
39 changes: 6 additions & 33 deletions gcontracts-core/src/main/java/org/gcontracts/domain/Contract.java
Expand Up @@ -23,12 +23,8 @@
package org.gcontracts.domain;

import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.MethodNode;
import org.gcontracts.util.Validate;

import java.util.HashMap;
import java.util.Map;

/**
* Represents a contract between a supplier and a customer of a class.
*
Expand All @@ -39,16 +35,15 @@ public class Contract {
private final ClassNode classNode;

private ClassInvariant classInvariant = ClassInvariant.DEFAULT;
private final Map<MethodNode, Precondition> preconditionMap;
private final Map<MethodNode, Postcondition> postconditionMap;

private AssertionMap<Precondition> preconditions;
private AssertionMap<Postcondition> postconditions;

public Contract(final ClassNode classNode) {
Validate.notNull(classNode);

this.classNode = classNode;
this.preconditionMap = new HashMap<MethodNode, Precondition>();
this.postconditionMap = new HashMap<MethodNode, Postcondition>();
this.preconditions = new AssertionMap<Precondition>();
this.postconditions = new AssertionMap<Postcondition>();
}

public ClassNode classNode() { return classNode; }
Expand All @@ -58,30 +53,8 @@ public void setClassInvariant(final ClassInvariant classInvariant) {
this.classInvariant = classInvariant;
}

public void addPrecondition(final MethodNode methodNode, final Precondition precondition) {
Validate.notNull(methodNode);
Validate.notNull(precondition);

if (!preconditionMap.containsKey(methodNode)) {
preconditionMap.put(methodNode, precondition);
} else {
preconditionMap.get(methodNode).or(precondition);
}
}

public void addPostcondition(final MethodNode methodNode, final Postcondition postcondition) {
Validate.notNull(methodNode);
Validate.notNull(postcondition);

if (!postconditionMap.containsKey(methodNode)) {
postconditionMap.put(methodNode, postcondition);
} else {
postconditionMap.get(methodNode).and(postcondition);
}
}

public Map<MethodNode, Precondition> preconditions() { return preconditionMap; }
public Map<MethodNode, Postcondition> postconditions() { return postconditionMap; }
public AssertionMap<Precondition> preconditions() { return preconditions; }
public AssertionMap<Postcondition> postconditions() { return postconditions; }

public boolean hasDefaultClassInvariant() { return classInvariant == ClassInvariant.DEFAULT; }
public ClassInvariant classInvariant() { return classInvariant; }
Expand Down
Expand Up @@ -36,7 +36,7 @@ class ContractTests extends TestCase {
Contract contract = new Contract(classNode)

Precondition precondition = new Precondition(new BooleanExpression(new ConstantExpression(true)))
contract.addPrecondition(classNode.getMethod("some_method", [] as Parameter[]), precondition)
contract.preconditions().or(classNode.getMethod("some_method", [] as Parameter[]), precondition)

assertEquals(1, contract.preconditions().size())
}
Expand All @@ -48,8 +48,8 @@ class ContractTests extends TestCase {
Precondition precondition1 = new Precondition(new BooleanExpression(new ConstantExpression(true)))
Precondition precondition2 = new Precondition(new BooleanExpression(new ConstantExpression(true)))

contract.addPrecondition(methodNode, precondition1)
contract.addPrecondition(methodNode, precondition2)
contract.preconditions().or(methodNode, precondition1)
contract.preconditions().or(methodNode, precondition2)

assertEquals(1, contract.preconditions().size())
assertTrue(contract.preconditions().get(methodNode).booleanExpression().expression.operation.type == Types.LOGICAL_OR)
Expand All @@ -62,10 +62,25 @@ class ContractTests extends TestCase {
Postcondition postcondition = new Postcondition(new BooleanExpression(new ConstantExpression(true)))
Postcondition postcondition1 = new Postcondition(new BooleanExpression(new ConstantExpression(true)))

contract.addPostcondition(methodNode, postcondition)
contract.addPostcondition(methodNode, postcondition1)
contract.postconditions().and(methodNode, postcondition)
contract.postconditions().and(methodNode, postcondition1)

assertEquals(1, contract.postconditions().size())
assertTrue(contract.postconditions().get(methodNode).booleanExpression().expression.operation.type == Types.LOGICAL_AND)
}

void test_joining_preconditions() {

Contract contract = new Contract(classNode)

Precondition precondition1 = new Precondition(new BooleanExpression(new ConstantExpression(true)))
Precondition precondition2 = new Precondition(new BooleanExpression(new ConstantExpression(true)))

contract.preconditions().join(methodNode, precondition1)
contract.preconditions().join(methodNode, precondition2)

assertEquals(1, contract.preconditions().size())
assertTrue(contract.preconditions().get(methodNode).booleanExpression().expression.operation.type == Types.LOGICAL_AND)
}

}

0 comments on commit 97db253

Please sign in to comment.