Missing try-catch-block generation when using judgment inside a lambda expression #36

Closed
clericc opened this Issue Sep 4, 2014 · 4 comments

Comments

Projects
None yet
2 participants
@clericc

clericc commented Sep 4, 2014

The following rule

rule InsertDirectValues
    G |- InsertDirectValues idv : SqlAnyType t
from {
    val types = new ArrayList<SqlAnyType>(idv.values.size)

    idv.values.forEach[ v, i |
        G, 'i' <- i |- v : var SqlAnyType valueType
        types += valueType
    ]

    // create result type
    if(types.size == 1)
        t = types.head
    else
        t = DatatypesFactory::eINSTANCE.createSqlTuple => [components.addAll(types)]

}

procudes wrong java code, as the generated lambda is missing the try-catch-clause for the judgment call:

// ...
    final Procedure2<InsertValueExpression, Integer> _function = new Procedure2<InsertValueExpression, Integer>() {
      public void apply(final InsertValueExpression v, final Integer i) {
        /* G, 'i' <- i |- v : var SqlAnyType valueType */
        SqlAnyType valueType = null;
        Result<SqlAnyType> result = typeInternal(environmentComposition(
          G, environmentEntry("i", i)
        ), _trace_, v);
        checkAssignableTo(result.getFirst(), SqlAnyType.class); // Unhandled exception type RuleFailedException
        valueType = (SqlAnyType) result.getFirst();

        types.add(valueType);
      }
    };
// ...

Simple workaround is to use the new explicit for-loops in xtend

@clericc clericc changed the title from Missing try-catch-block generation when using judgment inside xtends lambda to Missing try-catch-block generation when using judgment inside xtend lambda Sep 4, 2014

@LorenzoBettini LorenzoBettini changed the title from Missing try-catch-block generation when using judgment inside xtend lambda to Missing try-catch-block generation when using judgment inside a lambda expression Sep 4, 2014

@LorenzoBettini LorenzoBettini added the bug label Sep 4, 2014

@LorenzoBettini LorenzoBettini added this to the 1.6.0 milestone Sep 4, 2014

@LorenzoBettini LorenzoBettini self-assigned this Sep 4, 2014

@LorenzoBettini

This comment has been minimized.

Show comment
Hide comment
@LorenzoBettini

LorenzoBettini Sep 4, 2014

Collaborator

Thanks for reporting.
I had problems with rule invocations inside lambda expressions in the past...

I think that simply surrounding the generated code with try {} catch {} would not work, because the computation should be interrupted anyway so an exception should be thrown (meaning that if typeInternal throws a RuleFailedException then this should be propagated)...

I guess the only solution is to make RuleFailedException extends RuntimeException so that the generated code compiles fine and respects the semantics of rule invocation. This was proposed in the past by @JensN4

Collaborator

LorenzoBettini commented Sep 4, 2014

Thanks for reporting.
I had problems with rule invocations inside lambda expressions in the past...

I think that simply surrounding the generated code with try {} catch {} would not work, because the computation should be interrupted anyway so an exception should be thrown (meaning that if typeInternal throws a RuleFailedException then this should be propagated)...

I guess the only solution is to make RuleFailedException extends RuntimeException so that the generated code compiles fine and respects the semantics of rule invocation. This was proposed in the past by @JensN4

@clericc

This comment has been minimized.

Show comment
Hide comment
@clericc

clericc Sep 4, 2014

Interesting point.

Another solution would possibly be to embed any information about failures in the Result type and generate early exists with an appropiate result wrapper instead of leveraging the exception mechanism

EDIT: but that would not stop the for each loop and there is no return type, i just realize, forget it :)

clericc commented Sep 4, 2014

Interesting point.

Another solution would possibly be to embed any information about failures in the Result type and generate early exists with an appropiate result wrapper instead of leveraging the exception mechanism

EDIT: but that would not stop the for each loop and there is no return type, i just realize, forget it :)

@LorenzoBettini

This comment has been minimized.

Show comment
Hide comment
@LorenzoBettini

LorenzoBettini Sep 8, 2014

Collaborator

This is an input to be used as a reproducible test:

system my.test.ruleinvokations.System

judgments {
    type |- Object o : output Object
}

rule Type G |- String s : Object res
from {
    val list = newArrayList("first", "second")
    list.forEach[
        element |
        G |- element : var Object r
    ]
}
Collaborator

LorenzoBettini commented Sep 8, 2014

This is an input to be used as a reproducible test:

system my.test.ruleinvokations.System

judgments {
    type |- Object o : output Object
}

rule Type G |- String s : Object res
from {
    val list = newArrayList("first", "second")
    list.forEach[
        element |
        G |- element : var Object r
    ]
}
@LorenzoBettini

This comment has been minimized.

Show comment
Hide comment
@LorenzoBettini

LorenzoBettini Sep 11, 2014

Collaborator

Please have a look at http://xsemantics.sourceforge.net/snapshots-for-xsemantics-1-6-for-xtext-2-7/ if you want to try the snapshots with this fix

Collaborator

LorenzoBettini commented Sep 11, 2014

Please have a look at http://xsemantics.sourceforge.net/snapshots-for-xsemantics-1-6-for-xtext-2-7/ if you want to try the snapshots with this fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment