Giter VIP home page Giter VIP logo

c4j's People

Contributors

benromberg avatar florianmeyerer avatar marcphilipp avatar pikooh avatar timmr avatar ursmetz avatar yanastoeva avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

c4j's Issues

Mavenize

optional: publish on any public repo

Contracts for static methods

The only way this seems possible while keeping the ability to refactor is with an annotation on the static method, e.g.:

public class SomeClass {
  @StaticContractReference(StaticMethodContract.class)
  public static void staticMethod() {
    // ...
  }
}

public class StaticMethodContract {
  @StaticContract
  public void contractMethod() {
    if (preCondition()) {
      assert ...;
    }
    // ...
  }
}

This would not be possible when using external contracts, where a naming-convention is the only thing I can come up with. On the other hand, static methods should be rarely used. Maybe the Annotation-hassle isn't worth the effort at all.

Change constructor contract functionality

Up until now, constructor contracts were defined within the contract method's constructors themselves, matched by the signature of the constructor. This caused some problems, as there's always a default constructor available, and some of the initialization of the contract class is generated from the compiler.

Going forward, there has to be exactly one no-arg constructor in a contract class, which is solely responsible for initialization.

Contracts for constructors should be defined using the @ConstructorContract annotation on an arbitrarily named contract method. The signature is still responsible for matching the contract method and the actual target constructor.

The same should also apply for static initializers, using a static no-arg contract method with the @ConstructorContract annotation.

Cleanup unchanged() Objects

In cases where a post-condition is not called after the corresponding pre-condition was called, and the post-condition is using the unchanged()-mechanism, the Objects being stored in the PureEvaluator.unpureCache are not being cleaned up, causing a memory leak.

Class-invariant is being executed after post-condition throws an AssertionError

This probably also happens if the pre-condition throws an AssertionError. The only time the class-invariant is not executed is when the method itself throws a non-AssertionError.

To sum up, the behavior should be as follows:

  • Pre-condition fails -> no further execution
  • Method fails with AssertionError -> no further execution
  • Method fails with non-AE -> execute Post-Condition
  • Post-condition fails -> no further execution

Unchanged + Pure for arrays

Unchanged and Pure doesn't work properly for:

param[0].setValue("abc");
param[0] = new SetLike();

See c4j-systemtest/de.andrena.c4j.systemtest.unchanged.UnchangedForObjectsSystemTest.

instrumenting too much?

According to the section Under the hood "C4J contains an instrumentor class that instruments all loaded classes that are protected by a contract class". But looking at the log I see that every class in the project is instrumented (even java.util and springframework).
Is this correct?

Checking whether a precondition is strengthening a super-defined precondition seems to be to strict in case of using external contract classes.

Given the following scenario

  1. Having a SuperClass with external contract class SuperContractClass and methode void method(int a)
  2. TargetClass, a sub class of SuperClass, with external contract TargetContractClass
  3. no if (precondition()) block inside the definition of method method of SuperContractClass
  4. but a if (precondition()) inside the overrided method method in TargetContractClass
  5. setting the configuration variable <default-precondition> to `undefined

` (or omitting it)

Expected behaviour: no "Found strengthening pre-condition" error

Observed behaviour: "Found strengthening pre-condition in method(int)" error is raised

Use SLF4J instead of Log4J

This allows a more generic approach to logging, leaving the decision, which logging framework to use, to the framework user.

Move ContractError out of internal package

C4J ERROR - Contract Violation in post-condition.
de.andrena.c4j.internal.ContractError: Contract Error in post-condition.
at de.andrena.c4j.internal.ContractErrorHandler.handleContractException(ContractErrorHandler.java:20)
at external.Stack.push(Stack.java:19)
at external.StackTest.isFullTestRight(StackTest.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ArrayIndexOutOfBoundsException: -1
at external.Stack.top(Stack.java:31)
at external.StackSpecContract.push(StackSpecContract.java:44)
... 27 more

Allow unchanged and old within class-invariants

This makes it possible to define so-called history properties of a class (as defined by Barbara Liskov). For example for a bounded Stack with a fixed capacity, the fact that the capacity may never be changed could be expressed with the folling statement in the class-invariant:

assert unchanged(target.capacity());

Register custom domain

Just a thought: How about registering a custom domain for C4J? The website can be hosted on GitHub as well. In addition we could have nice email addresses and use it to name the Java packages accordingly.

Suggestion: c4j.org (if available)

Warn when calling an overridden contract method - most likely missing the target reference

Example - assert getX() should really be assert target.getX():

public class A {

    private int x;

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

}

import static de.andrena.c4j.Condition.postCondition;
import static de.andrena.c4j.Condition.preCondition;
import de.andrena.c4j.Target;

public class AContract extends A {

    @Override
    public void setX(int x) {
        if (preCondition()) {
            assert x > 0 : "x > 0";
        }
        if (postCondition()) {
            assert getX() == x : "x set";
        }
    }

}

import org.junit.Test;

public class ATest {

    @Test
    public void test() {
        A a = new A();
        a.setX(5);
    }

}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.