aviadbd / winter

Zero boilerplate configuration framework
Apache License 2.0
0 stars 0 forks source link

Flow validation through annotaions #17

Open eztzachi opened 9 years ago

eztzachi commented 9 years ago

Was first discussed on issue #12

aviadbd commented 9 years ago

I think the challenge here will be to do this without any change to the basic RouteUnit, WorkUnit, LogicUnit and Looper. Then we can see if it can be enhanced otherwise?

eztzachi commented 9 years ago

Few things that made me busy today:

  1. Should the annotation be at method level or class level? I know we spoke about method level, but I do not see any reason why not to make it class since: a. There is anyway maximum 1 annotation per class; b. We are not able to check the function parameters anyway (throw reflection), since there is not it a instantiation during the validation.
  2. How the annotation will look like? At first I thought to use direct java boolean expressions, but it is not possible to pass non constant values, so the go to is a string representation of a condition.
  3. Do we want to write our own parser to support different boolean expressions? how much control do we want the user to have? How can we support every possible data for queries? I can try using "jexl" or groovy/JavaScript with the Java ScriptEngineManager object. Let me know your thoughts....
aviadbd commented 9 years ago
  1. I still think they should be on the method-level. We said we'd want to allow examination for every method that returns or accepts a WorkUnit. I guess we should change that to any method that returns or accepts a T-value. The reasoning behind this is to allow for validity checks on sub-methods of the LogicUnit, to make sure the methods it calls on other classes do what they claim to do. If it's easier to start with class-level and more specifically on LogicUnit implementations only, then let's start there, but I think this should expand rather quickly.
  2. JavaScript/Groovy etc is a nice idea. I'd also take a look at MPS: https://www.jetbrains.com/mps/
  3. See 2 :)
aviadbd commented 9 years ago

For reference:

  1. Groovy's GContracts: http://gcontracts.org
  2. JavaDoc enabled contracts, OpenJML: http://openjml.org
  3. Jetbrains' Contract annotation: http://blog.jetbrains.com/idea/2013/10/better-control-flow-analysis-with-contract-annotations-and-intellij-idea-13/
eztzachi commented 9 years ago

OK, for now I am moving on with ScriptEngine using Groovy, and reflection (of course). It is also quite clear that the @PreCondition will reflect a Boolean expression. But what about the @PostCondition? Do we want is a Boolean expression as well, because sometimes it is just not enough, and more than that, it will require another level of translation. I am adding few example, and wait to hear what do you think.

Let's say that our generic T is class A:

Ex. 1 - Boolean Condition - the state of a by the end of the function is not clear (is the new a is 2, 5, -9) : @PreCondition(expression = "a != null && a.x == 1") @PostCondition(expression = "old.a.x < a.x") public static void useA(A a){ a.increaseX(); }

Ex.2 - Script execution - it is not only as simple as this @PreCondition(expression = "a != null && a.x == 1") @PostCondition(expression = "a.x=-9") public static void useA(A a){ a.x=-9 }

Ex.3 -Bollean condition - but it is not really clear what I should to with that @PreCondition(expression = "a != null") @PostCondition(expression = "a.map.get('hello')!=null") public static void useA(A a){ // something here }

eztzachi commented 9 years ago

Another issue here is how to implement it when the return value is an array - like in the LogicUnit

aviadbd commented 9 years ago

I think PostCondition being a boolean is everything we need - its a condition, it makes sense for it to be like that. Can you give an example where it should be something else?

About the array, I think the PostCondition should just apply to all elements of the array. Users could have a big “OR” between the post conditions, if they wanted to have different results. Perhaps we should also have an operator for “exists”, to make sure that a certain condition applies to at least one (or exactly one?) result.

On Sun, Jan 4, 2015 at 3:40 AM, eztzachi notifications@github.com wrote:

Another issue here is how to implement it when the return value is an array - like in the LogicUnit

Reply to this email directly or view it on GitHub: https://github.com/aviadbd/winter/issues/17#issuecomment-68617164

eztzachi commented 9 years ago

Lets put the array as a separate issue for now....

I do not think that a boolean itself is not enough. Let's take for example @PostCondition(expression = "a.map.get('hello')!=null"):

Let me know your thoughts

By the way, the PreCondition has a pretty simple implementation without any translation needed - just by using the eval function - since no change on the object is needed