eclipse-ocl / org.eclipse.ocl

Eclipse Public License 2.0
0 stars 0 forks source link

[evaluator] invalid not properly assigned to let-variables #681

Closed eclipse-ocl-bot closed 1 month ago

eclipse-ocl-bot commented 1 month ago

| --- | --- | | Bugzilla Link | 342644 | | Status | CLOSED FIXED | | Importance | P3 normal | | Reported | Apr 12, 2011 17:37 EDT | | Modified | May 27, 2011 03:13 EDT | | Version | 3.1.0 | | Depends on | 342561 | | Blocks | 344391 | | Reporter | Axel Uhl |

Description

In the expression

let a:Integer='123a'.toInteger() in a.oclIsInvalid()

invalid results instead of the expected true.

eclipse-ocl-bot commented 1 month ago

By Ed Willink on Apr 29, 2011 14:54

(In reply to comment #42)

uml EvaluationHaltedTest; I'm not clear what the purpose of the change is

The way testHaltedQuery evaluated the queryExp, it passed null as self context. This now would lead to a Sequence containing as its single element the null value which is then bound to the i iterator during the collect and therefore an attempt to invoke halt on null which now fails fast with an invalid, as I think the spec says it should. Furthermore, the self argument to halt is null, causing InterruptibleEvalEnv.callOperation to fail on its assertEquals(HALT_KIND_NONE, kind). Therefore, for the specific test I felt I had to change the query the way I did.

Perhaps this will be unnecessary when 'oclAsSet' semantics is realised as in comment #49. I would certainly prefer not to change this test.


org.eclipse.ocl.tests.GenericIteratorsTest

sole change is to introduce an unneeded @SuppressWarnings("unchecked")

It's required because otherwise Indigo with default Java settings complains about "Type safety : A generic array of PK is created for a varargs parameter."

Ok. Probably a Java 5/6 issue.\


org.eclipse.ocl.ecore.tests.RegressionTest.test_bagIterationWithNullOccurrences()

This is difficult to read: contrast with org.eclipse.ocl.ecore.tests.EvaluationCollectionOperationTest.testCollectionExcludingNullValue which has more powerful helper functions.

Please note that test_bagIterationWithNullOccurrences is not about any OCL expression parsing and evaluation. It is testing the raw BagImpl class with raw Java values because there was a respective bug in the implementation. I can't see how, e.g., assertExpressionResults from testCollectionExcludingNullValue would help here. Can you maybe provide more concrete hints as to how you think readability can be improved?

Laurent introduced the nice usage of assertResults which allowed an OCL expression to define the results avoiding the complexity of Java collection poking; it also makes the tests more portable.

org.eclipse.ocl.ecore.tests.CollectionsTest, org.eclipse.ocl.uml.tests.CollectionsTest

test_flatten_notNested, test_flatten_emptySource_195252

the sibling tests are testing that the expected result is obtained, so you should rt5est for the truth of an OrderedSet result, not the falsity of a Set result; that is a different test.

I was trying to preserve Laurent's test semantics as far as possible. I suggest I add the positive tests you mention.

Yes. Though the assertFalse sub-test might belong in a different test.\


oclstdlib.ecore

Addition of Collection::=, <> is suspect, in so far as the covariant overload has undefined semantics in OCL 2.3. It is likely to be eliminated in OCL 2.4, so since they're currently not in I'm inclined to leave them out. Espexcially suince oclstdlib.uml has no equivalents.

But that would make many correct and useful comparisons fail to parse. I think this would not be a good solution for our users. What semantics could the covariant overload have in your opinion, other than the one implemented? Conversely, if you think there is something missing in oclstdlib.uml, then I suggest we add it there. How and where is oclstdlib.uml used? I've now added the two operations to Collection Type Collection(T) in oclstdlib.uml.

Where does this change help? I'm puzzled that it's been wrong for so long.

Simple Java overload is that OclAny::"="(OclAny) can be overloaded by Collection::"="(OclAny) requiring tedious run-time type tests and conversions.

As I finished writing my 'Modeling the OCL Standard Library' paper, I realized that covariant overload could be supported by the definition OclAny::"="(OclSelf) in which OclSelf is a special template parameter denoting the statically determined derived 'self' type. i.e. 4=4.0 would therefore look first for UnlimitedNatural::"="(OclSelf) fail statically on the argument and so try Integer::"="(OclSelf) and again fail on the argument and so eventually settle on Real::"="(OclSelf) as the statically 'referredOperation', assuming such a definition exists else OclAny::"="(OclSelf). This is all done at compile time. At run-time Real::"="(OclSelf) is guaranteed to have conformant-to-Real self and argument.\

Addition of UnlimitedNatural instanceTypeName. Is this necessary. OclInvalid, OclVoid, Real still have no instanceTypeName. It's not even accurate, the instance is variously Integer, Long amd BigInteger.

I though it was accurate from what I could see regarding the mature Ecore implementation as I haven't come across a non-Integer representation of an UnlimitedNatural. Where / when is an UnlimitedNatural instance represented by a Long or BigInteger in the mature implementation?

BigInteger and BigDecimal may be used explicitly in Ecore models. They are sometimes used when extended precision is attempted.\

If the instanceTypeName is missing, UnlimitedNatural objects are not comparable. The UMLReflectionImpl.isComparable(EClassifier) implementation looks like this:

public boolean isComparable(EClassifier type) {
    Class<?> javaClass = type.getInstanceClass();

    return (javaClass != null) &&

Comparable.class.isAssignableFrom(javaClass); } \

If no instance class is defined, objects are not comparable. Alternatively, the isComparable operation may be tweaked, but I expect trouble in other areas too, perhaps when the sorting is to be carried out because there again reference may be made to the instance class. Therefore I really prefer the current proposal that sets the instance class to java.lang.Integer, particularly if there is no evidence that BigInteger or Long may be used in the mature implementation anyhow.

You may be right, but I'm very worried about the ripple with respect to current code. If this also fixes bugs for Real then it may be good; if not I suspect that the current code is not fully understood.


CollectionUtil.union

No. e.g. A union o SEquences is a Sequence. See the pivot's AbstractCollectionValue.union for more plausible logic.

I claim the implementation proposed by the patch handles this correctly. The change affects the otherwise failing case (as the comment I introduced tries to explain) of one argument being a Bag. In this case, even if it's empty, the result has to be a Bag, no matter whether the Bag is the self or the operand. If two sequences are to be united, none is a bag, so createNewSequence(self) is executed as before. You could make the above clearer by providing a failing test case.

I misread the code. The debatable cases such as Sequence{}->union(Set{1}) are not semantically valid, so how CollectionUtil behaves is irrelevant.\

Pivot derives OrderedSetImpl from LinkedHashSet in order to fix equals() for ordering.

The mature Ecore impl uses LinkedHashSet as OrderedSet implementation. What are you getting at?

LinkedHashSet treats {1,2,3} and {3,2,1} as equal!!!! It is a set that maintains elements in a linked list. Ordering is not part of the semantics.\


BagImpl

A variety of non-use of OCL-value semantics issues remain.

What are you suggesting? I thought we agreed that in particular the numerical aspects (3.0 vs. 3 and so on) would be too hard to fix with the resources given and with a potential perspective of making the Pivot evaluator work with less effort for Ecore in post-Indigo releases. No?

Besides: what exactly are you referring to by "non-use of OCL value semantics" in the concrete context of BagImpl?

No Problem. WONTFIX. (Currently 3.0 and 3 would be in different 'bins');\


AbstractTypeChecker ??? very hard to comment; probably better but ... this is one of the nightmare areas. I see very little improvement to the analyzer so I'm a bit concerned about making just these possibly useful changes.

So let me try to explain the changes in detail.

The changes in getRelationship are owed to the occasional existence of two distinct AnyType instances, one being distinct from stdlib.getOclAny(). Therefore, I relaxed the identity comparisons into "instanceof AnyType" comparisons. Besides, the possibility of both types to compare being OclAny was not handled. So I had to add the SAME_TYPE branch.

The changes around line 196 relate to the conformance of UnlimitedNatural to Integer which so far was not acknowledged properly by getRelationship. So far, only the conformance of UnlimitedNatural to Real and Integer to Real was considered. This caused some of the new tests to fail and clearly contradicts the specification.

The changes to findOperationMatching starting in line 1093, as the comment tries to explain, for one thing ensure again that the UnlimitedNatural conformance to Integer is also considered appropriately during operation lookup because otherwise *.div(1) doesn't parse. The other change there relates to the lookup of collection operations. There are many of the new tests which otherwise fail because operations available on Collection are not re-modeled on Collection's subclasses. If you will, this is a partial "polymorphic lookup" that at least makes the stdlib behave as the spec and Laurent's tests suggests it should.

I don't doubt that your change is locally better. The problem is that I do not understand the code, but have observed that it is distributed in too many places. I'm therefore worried that a 'fix' in one place causes bugs in other places.


EvaluationVisitorImpl.UNLIMITED duplicates UnlimitedNaturalLiteralExp.UNLIMITED use the old value.

Not really. UnlimitedNaturalLiteralExp.UNLIMITED is type int. When using it for auto-boxing, a new java.lang.Integer(-1) will be constructed each time. I introduced EvaluationVisitorImpl.UNLIMITED to avoid this repetitive auto-boxing effort.

Ok. Perhaps makes a noticeable difference; just re-use the -1 then.


EvaluationVisitorImpl.visitOperationCallExp:PredefinedType.OCL_AS_TYPE UNLIMITED is an invalid Integer or Real! there is no PLUS_INFINITY (yet; I would like to add PLUS_INFINITY so that we can lose UnlimitedNatural altogether). the value conformance check for Real to Integer and Integer to UnlimitedNatural is missing conversions for BigInteger and BigDecimal are missing.

I think this behavior was missing before the patch, too. The tests so far hadn't obviated the need for change. I agree that an according test should be added, requiring the behavior to become stricter here too.

Use of BigXXX is very patchy and associated with some CCEs. Improvements would be good but perhaps too hard.\


EvaluationVisitorImpl.visitOperationCallExp:OR etc Better. But can still malfunction for an e.g. Integer argument.

But that would have been caught by the analyzer and shouldn't have compiled in the first place. Therefore, I don't think such a check is required here. null and invalid, though, do conform to Boolean and therefore need to be considered. I therefore now do a "shortcut" for sourceVal instanceof Boolean. If false, I still have to check for the Boolean operations because I don't want to enter the if-branch for each invalid value.

Probably. It is best not to rely too much on the analyzer if possible.

[End of current batch of comments]

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on Apr 29, 2011 17:19

(In reply to comment #49)

Clearly the mature code will not reify the oclAsSet operation, but it can achieve the same observable semantics; it is the creation of the collection from null that is special not the usage of a collection containing null.

Explanation of pivot work on oclAsSet appreciated. My understanding of the mature code is that the implicit set conversion for -> on an expression with upper multiplicity 1 happens by a conversion to a Set{...} collection literal at compile time, not at run time. A quick test with a breakpoint in OCL.evaluate and entering self.name->isEmpty() in the console on an Ecore element gives "Set{self.name}->isEmpty()" as the expression. So fixing this would require deep changes in the parser which would have to introduce a new element into the AST which is a much deeper, less compatible change, I'm afraid.

[The pivot evaluator does not actually use dynamic dispatch for oclAsSet; the behaviour is all folded into OclAny::oclAsSet(), which one day will allow analysis to recognize OclAny::oclAsSet() as 'final' and allow the dispatch overhead to be reduced.]

What do you suggest for the mature impl?

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on Apr 29, 2011 17:23

(In reply to comment #50)\ Well... I'd call it a draw, and I don't care so much. Next week I'll look into it and try to ensure that oclIsKindOf and oclIsTypeOf don't respond with invalid when called on null or invalid for the cases discussed.

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on Apr 29, 2011 17:51

(In reply to comment #51)

(In reply to comment #42)

uml EvaluationHaltedTest; I'm not clear what the purpose of the change is

The way testHaltedQuery evaluated the queryExp, it passed null as self context. This now would lead to a Sequence containing as its single element the null value which is then bound to the i iterator during the collect and therefore an attempt to invoke halt on null which now fails fast with an invalid, as I think the spec says it should. Furthermore, the self argument to halt is null, causing InterruptibleEvalEnv.callOperation to fail on its assertEquals(HALT_KIND_NONE, kind). Therefore, for the specific test I felt I had to change the query the way I did.

Perhaps this will be unnecessary when 'oclAsSet' semantics is realised as in comment #49. I would certainly prefer not to change this test.

As mentioned in my other comment: please make a suggestion. Personally, I think starting to mess with the parser/analyzer and probably also with the stdlib to introduce something like oclAsSet is too hard for now.

Please also note that prior to the change suggested by my patch it was entirely impossible to have null in a CollectionLiteralExp which is even worse. So far, all null values were ignored which is clearly against the spec. I relaxed this such that it's largely possible to have null in CollectionLiterals except for the special case of Set{null} which is a workaround for the missing oclAsSet. I'm very willing to document this special case in the conformance documentation and think that the patch by far improves the situation, not aggravates it.


org.eclipse.ocl.ecore.tests.RegressionTest.test_bagIterationWithNullOccurrences()

This is difficult to read: contrast with org.eclipse.ocl.ecore.tests.EvaluationCollectionOperationTest.testCollectionExcludingNullValue which has more powerful helper functions.

Please note that test_bagIterationWithNullOccurrences is not about any OCL expression parsing and evaluation. It is testing the raw BagImpl class with raw Java values because there was a respective bug in the implementation. I can't see how, e.g., assertExpressionResults from testCollectionExcludingNullValue would help here. Can you maybe provide more concrete hints as to how you think readability can be improved?

Laurent introduced the nice usage of assertResults which allowed an OCL expression to define the results avoiding the complexity of Java collection poking; it also makes the tests more portable.

Again: this is not about OCL, it's about a bug in an implementation class that I want to unit-test in isolation, independent of any OCL magic. If you disagree with the test location, please suggest a better one.

org.eclipse.ocl.ecore.tests.CollectionsTest, org.eclipse.ocl.uml.tests.CollectionsTest

test_flatten_notNested, test_flatten_emptySource_195252

the sibling tests are testing that the expected result is obtained, so you should rt5est for the truth of an OrderedSet result, not the falsity of a Set result; that is a different test.

I was trying to preserve Laurent's test semantics as far as possible. I suggest I add the positive tests you mention.

Yes. Though the assertFalse sub-test might belong in a different test.

Suggestions?


oclstdlib.ecore

Addition of Collection::=, <> is suspect, in so far as the covariant overload has undefined semantics in OCL 2.3. It is likely to be eliminated in OCL 2.4, so since they're currently not in I'm inclined to leave them out. Espexcially suince oclstdlib.uml has no equivalents.

But that would make many correct and useful comparisons fail to parse. I think this would not be a good solution for our users. What semantics could the covariant overload have in your opinion, other than the one implemented? Conversely, if you think there is something missing in oclstdlib.uml, then I suggest we add it there. How and where is oclstdlib.uml used? I've now added the two operations to Collection Type Collection(T) in oclstdlib.uml.

Where does this change help? I'm puzzled that it's been wrong for so long.

Well, you complained above about it not having equivalents in oclstdlib.uml. Now it does and you're unhappy again. It probably didn't have any equivalent because oclstdlib.uml is not used anywhere. I'm ok with adding it for documentation. However, it would make for another good bugzilla to ask what oclstdlib.uml is good for and whether we may dare to simply remove it if we don't understand it anymore.

I though it was accurate from what I could see regarding the mature Ecore implementation as I haven't come across a non-Integer representation of an UnlimitedNatural. Where / when is an UnlimitedNatural instance represented by a Long or BigInteger in the mature implementation?

BigInteger and BigDecimal may be used explicitly in Ecore models. They are sometimes used when extended precision is attempted.

How would such values have UnlimitedNatural as their static type? Most certainly BigInteger and BigDecimal cannot be used for integral types in the mature implementation because all integral values are coerced to long before being operated on. What would BigInteger and BigDecimal map to in mature OCL land anyway? Certainly not UnlimitedNatural. So I currently don't see the point.

If the instanceTypeName is missing, UnlimitedNatural objects are not comparable. The UMLReflectionImpl.isComparable(EClassifier) implementation looks like this:

public boolean isComparable(EClassifier type) {
    Class<?> javaClass = type.getInstanceClass();

    return (javaClass != null) &&

Comparable.class.isAssignableFrom(javaClass); }

If no instance class is defined, objects are not comparable. Alternatively, the isComparable operation may be tweaked, but I expect trouble in other areas too, perhaps when the sorting is to be carried out because there again reference may be made to the instance class. Therefore I really prefer the current proposal that sets the instance class to java.lang.Integer, particularly if there is no evidence that BigInteger or Long may be used in the mature implementation anyhow.

You may be right, but I'm very worried about the ripple with respect to current code. If this also fixes bugs for Real then it may be good; if not I suspect that the current code is not fully understood.

Easy thing: there were bugs. The change proposed fixed them. No other noticeable harm done, in particular all other tests green. You say you don't understand the details. I suggest you try to provide failing tests, then we have a case. I spent quite some time over this code and only see positive effects of specifying Integer as the instance class, no negative ones.

Pivot derives OrderedSetImpl from LinkedHashSet in order to fix equals() for ordering.

The mature Ecore impl uses LinkedHashSet as OrderedSet implementation. What are you getting at?

LinkedHashSet treats {1,2,3} and {3,2,1} as equal!!!! It is a set that maintains elements in a linked list. Ordering is not part of the semantics.

Good point. I'll have to check on Monday. I suppose that so far OrderedSet::=(OrderedSet) misbehaves in the mature implementation, also pre-342644. Separate bugzilla, maybe?


AbstractTypeChecker ??? very hard to comment; probably better but ... this is one of the nightmare areas. I see very little improvement to the analyzer so I'm a bit concerned about making just these possibly useful changes.

So let me try to explain the changes in detail.

The changes in getRelationship are owed to the occasional existence of two distinct AnyType instances, one being distinct from stdlib.getOclAny(). Therefore, I relaxed the identity comparisons into "instanceof AnyType" comparisons. Besides, the possibility of both types to compare being OclAny was not handled. So I had to add the SAME_TYPE branch.

The changes around line 196 relate to the conformance of UnlimitedNatural to Integer which so far was not acknowledged properly by getRelationship. So far, only the conformance of UnlimitedNatural to Real and Integer to Real was considered. This caused some of the new tests to fail and clearly contradicts the specification.

The changes to findOperationMatching starting in line 1093, as the comment tries to explain, for one thing ensure again that the UnlimitedNatural conformance to Integer is also considered appropriately during operation lookup because otherwise *.div(1) doesn't parse. The other change there relates to the lookup of collection operations. There are many of the new tests which otherwise fail because operations available on Collection are not re-modeled on Collection's subclasses. If you will, this is a partial "polymorphic lookup" that at least makes the stdlib behave as the spec and Laurent's tests suggests it should.

I don't doubt that your change is locally better. The problem is that I do not understand the code, but have observed that it is distributed in too many places. I'm therefore worried that a 'fix' in one place causes bugs in other places.

Same as above. I find it little convincing to put up a vague doubt against a bug fixed that includes tests. Again, I spent quite some time analyzing what happens with collection operation resolution. If you don't feel you want to get into the details, one way may just be to accept that if I provide a fix that doesn't hurt other tests then the changes may just be assumed okay until a reasonable test proves otherwise.


EvaluationVisitorImpl.UNLIMITED duplicates UnlimitedNaturalLiteralExp.UNLIMITED use the old value.

Not really. UnlimitedNaturalLiteralExp.UNLIMITED is type int. When using it for auto-boxing, a new java.lang.Integer(-1) will be constructed each time. I introduced EvaluationVisitorImpl.UNLIMITED to avoid this repetitive auto-boxing effort.

Ok. Perhaps makes a noticeable difference; just re-use the -1 then.

You mean the other int UNLIMITED = -1 constant? Ok.

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on Apr 29, 2011 18:15

LinkedHashSet treats {1,2,3} and {3,2,1} as equal!!!! It is a set that maintains elements in a linked list. Ordering is not part of the semantics.

The problem here will be similar to that of numeric equivalence. Since the mature implementation throughout chose to implement OrderedSet as LinkedHashSet, equality is usually mapped to that of LinkedHashSet which ignores ordering as you pointed out. This will particularly be a problem for OrderedSets nested in other collections as long as their Java equals is used.

Therefore, fixing it in one place will create another inconsistency in the other place. Suggestion: WONTFIX, document in conformance doc. Ok?

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on Apr 29, 2011 18:25

(In reply to comment #55)

LinkedHashSet treats {1,2,3} and {3,2,1} as equal!!!! It is a set that maintains elements in a linked list. Ordering is not part of the semantics.

The problem here will be similar to that of numeric equivalence. Since the mature implementation throughout chose to implement OrderedSet as LinkedHashSet, equality is usually mapped to that of LinkedHashSet which ignores ordering as you pointed out. This will particularly be a problem for OrderedSets nested in other collections as long as their Java equals is used.

Therefore, fixing it in one place will create another inconsistency in the other place. Suggestion: WONTFIX, document in conformance doc. Ok?

I checked ObjectUtil. It's possible to at least support the non-nested case. Only nested case remains an issue to be documented in a conformance statement. Ok?

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on Apr 29, 2011 18:47

Created attachment 194415 (attachment deleted)\ invalid/null.oclIs[Kind|Type]Of fix, OrderedSet comparison with ordering

See my previous comments

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on Apr 29, 2011 18:48

Created attachment 194416 (attachment deleted)\ Commented unicode-dependent tests (until Hudson copes)

Same a 194415, as git patch, helping to preserve commented Unicode tests

eclipse-ocl-bot commented 1 month ago

By Ed Willink on Apr 30, 2011 01:04

(In reply to comment #52)

A quick test with a breakpoint in OCL.evaluate and entering self.name->isEmpty() in the console on an Ecore element gives "Set{self.name}->isEmpty()" as the expression. So fixing this would require deep changes in the parser which would have to introduce a new element into the AST which is a much deeper, less compatible change, I'm afraid.

What do you suggest for the mature impl?

If the mature evaluator cannot distinguish whether an AST looking like Set{null}->isEmpty() originated from Set{null}->isEmpty() or null->isEmpty(), you're in trouble. You need backward traceability, or some magic 'implicit' flag somewhere.

This was all going to be WONTFIX anyway, so no-change is probably better than partial-change.

eclipse-ocl-bot commented 1 month ago

By Ed Willink on Apr 30, 2011 01:18

(In reply to comment #56)

(In reply to comment #55)

LinkedHashSet treats {1,2,3} and {3,2,1} as equal!!!! It is a set that maintains elements in a linked list. Ordering is not part of the semantics.

I checked ObjectUtil. It's possible to at least support the non-nested case. Only nested case remains an issue to be documented in a conformance statement. Ok?

Yes. There's probably just a general conformance statement about nested collections ignoring OCL equality, set ordering, ????.

eclipse-ocl-bot commented 1 month ago

By Ed Willink on Apr 30, 2011 02:13

(In reply to comment #54)

(In reply to comment #51)

(In reply to comment #42)

uml EvaluationHaltedTest; I'm not clear what the purpose of the change is

The way testHaltedQuery evaluated the queryExp, it passed null as self context. This now would lead to a Sequence containing as its single element the null value which is then bound to the i iterator during the collect and therefore an attempt to invoke halt on null which now fails fast with an invalid, as I think the spec says it should. Furthermore, the self argument to halt is null, causing InterruptibleEvalEnv.callOperation to fail on its assertEquals(HALT_KIND_NONE, kind). Therefore, for the specific test I felt I had to change the query the way I did.

Perhaps this will be unnecessary when 'oclAsSet' semantics is realised as in comment #49. I would certainly prefer not to change this test.

As mentioned in my other comment: please make a suggestion. Personally, I think starting to mess with the parser/analyzer and probably also with the stdlib to introduce something like oclAsSet is too hard for now.

Please also note that prior to the change suggested by my patch it was entirely impossible to have null in a CollectionLiteralExp which is even worse. So far, all null values were ignored which is clearly against the spec. I relaxed this such that it's largely possible to have null in CollectionLiterals except for the special case of Set{null} which is a workaround for the missing oclAsSet. I'm very willing to document this special case in the conformance documentation and think that the patch by far improves the situation, not aggravates it.

I see. But the problem is that this is application code that is broken by 'correct' OCL. Rather than change the query wouldn't it be better to either call evaluator(Object) to provide a context, or change the halt() implementation to handle a null argument.

(In reply to comment #59)

(In reply to comment #52)

A quick test with a breakpoint in OCL.evaluate and entering self.name->isEmpty() in the console on an Ecore element gives "Set{self.name}->isEmpty()" as the expression. So fixing this would require deep changes in the parser which would have to introduce a new element into the AST which is a much deeper, less compatible change, I'm afraid.

What do you suggest for the mature impl?

If the mature evaluator cannot distinguish whether an AST looking like Set{null}->isEmpty() originated from Set{null}->isEmpty() or null->isEmpty(), you're in trouble. You need backward traceability, or some magic 'implicit' flag somewhere.

This was all going to be WONTFIX anyway, so no-change is probably better than partial-change.

The above makes me uncomfortable for arbitrary users.

In 3.0.0, the bug was:

'null' cannot exist in collection literals, and is inconsistent if included in other ways and is handled inconsistently if a null is in a collection.

null->... 'works'

The current patch:

null can work in collections, except that Set{null} is converted to Set{}

null->... 'works'

This seems unequivocably better but irregular.


Suggestion:

Change the analyzer to encode Collection{xxx} rather than Set{xxx} for xxx-> so that the evaluator can recognize Collection{xxx} as oclAsSet.

Collection{xxx} is not a legal concrete syntax, so there is no ambiguity for the evaluator.

Old ASTs will malfunction as before with the revised evaluator.

New ASTs should not be processed by an old evaluator.

If you're happy with this idea we'd better double check with Obeo.

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on Apr 30, 2011 02:49

(In reply to comment #61)

I see. But the problem is that this is application code that is broken by 'correct' OCL. Rather than change the query wouldn't it be better to either call evaluator(Object) to provide a context, or change the halt() implementation to handle a null argument.

Ok, if the duplicated/modified query is the problem, I can change the test to use evaluate(Object) to avoid null being passed in. It then should be possible to use the existing query.

On the Set{null} issue:

Suggestion:

Change the analyzer to encode Collection{xxx} rather than Set{xxx} for xxx-> so that the evaluator can recognize Collection{xxx} as oclAsSet.

Collection{xxx} is not a legal concrete syntax, so there is no ambiguity for the evaluator.

Old ASTs will malfunction as before with the revised evaluator.

New ASTs should not be processed by an old evaluator.

If you're happy with this idea we'd better double check with Obeo.

I don't think this is such a good idea. 10-11-42, Section 7.5.3: "Because the multiplicity of the role manager is one, self.manager is an object of type Person. Such a single object can be\ used as a Set as well. It then behaves as if it is a Set containing the single object. The usage as a set is done through the\ arrow followed by a property of Set." This makes it very explicit that a Set needs to be produced, not a Collection.

Let me again summarize my conviction on this topic: Instead of failing for all null values in CollectionLiterals we should only fail for a single null in a Set literal which reduces the chances for errors. Collections were already correctly able to hold null values, so ->including or ->insertAt already handled things correctly. The number of deviations from the spec goes down. The remaining non-conformance is necessary because of the way the implementation handles the implicit Set conversion (putting it into the abstract syntax as a Set literal). The spec and pragmatics demand that a null value converted to a Set this way results in an empty Set.

One workaround I may think of but that also has its quirks: the parser / analyzer could add an EAnnotation to the Set{...} literal resulting from the implicit -> conversion, and the evaluator could check for such an annotation. If such an annotation exists and the literal contains only one item and this single item evaluates to null, an empty Set results. Otherwise, the null value is inserted into the Set.

The problem then would only be that a non-standard annotation controls the behavior of a Set literal. What do you think?

eclipse-ocl-bot commented 1 month ago

By Ed Willink on Apr 30, 2011 03:04

(In reply to comment #54)

If the instanceTypeName is missing, UnlimitedNatural objects are not comparable. The UMLReflectionImpl.isComparable(EClassifier) implementation looks like this:

public boolean isComparable(EClassifier type) {
    Class<?> javaClass = type.getInstanceClass();

    return (javaClass != null) &&

Comparable.class.isAssignableFrom(javaClass); }

If no instance class is defined, objects are not comparable. Alternatively, the isComparable operation may be tweaked, but I expect trouble in other areas too, perhaps when the sorting is to be carried out because there again reference may be made to the instance class. Therefore I really prefer the current proposal that sets the instance class to java.lang.Integer, particularly if there is no evidence that BigInteger or Long may be used in the mature implementation anyhow.

You may be right, but I'm very worried about the ripple with respect to current code. If this also fixes bugs for Real then it may be good; if not I suspect that the current code is not fully understood.

Easy thing: there were bugs. The change proposed fixed them. No other noticeable harm done, in particular all other tests green. You say you don't understand the details. I suggest you try to provide failing tests, then we have a case. I spent quite some time over this code and only see positive effects of specifying Integer as the instance class, no negative ones.

You suggest that the only interesting thing about the instanceTypeName is that\ it is Comparable. However a find references on getInstanceClass reveals another\ critical usage; isKindOf and isTypeOf. Their code makes me very uncomfortable.\ It is extremely simplistic, failing totally for Long, BigInteger and\ BigDecimal, and possibly exploiting the null instanceTypeName for Double.

Since UnlimitedNatural barely exists in the current code. I don't like this\ change; it is just too risky. You need to start with some white box tests that\ pass and fail on the current code for at least Long/Integer and Double (and\ ideally BigInteger, Short, Float and BigDecimal too). This can then demonstrate\ that the revision is clearly better. I currently see new bugs in isKindOf and\ isTypeOf.

But: surely the only UnlimitedNatural objects are ''? So this fix is solely to\ make '' comparison work. Too much risk for a cosmetic gain. WONTFIX unless you\ can provide a thorough revision of Long/Integer etc.

eclipse-ocl-bot commented 1 month ago

By Ed Willink on Apr 30, 2011 03:21

(In reply to comment #62)

(In reply to comment #61)

I see. But the problem is that this is application code that is broken by 'correct' OCL. Rather than change the query wouldn't it be better to either call evaluator(Object) to provide a context, or change the halt() implementation to handle a null argument.

Ok, if the duplicated/modified query is the problem, I can change the test to use evaluate(Object) to avoid null being passed in. It then should be possible to use the existing query.

On the Set{null} issue:

Suggestion:

Change the analyzer to encode Collection{xxx} rather than Set{xxx} for xxx-> so that the evaluator can recognize Collection{xxx} as oclAsSet.

Collection{xxx} is not a legal concrete syntax, so there is no ambiguity for the evaluator.

Old ASTs will malfunction as before with the revised evaluator.

New ASTs should not be processed by an old evaluator.

If you're happy with this idea we'd better double check with Obeo.

I don't think this is such a good idea. 10-11-42, Section 7.5.3: "Because the multiplicity of the role manager is one, self.manager is an object of type Person. Such a single object can be used as a Set as well. It then behaves as if it is a Set containing the single object. The usage as a set is done through the arrow followed by a property of Set." This makes it very explicit that a Set needs to be produced, not a Collection.

Let me again summarize my conviction on this topic: Instead of failing for all null values in CollectionLiterals we should only fail for a single null in a Set literal which reduces the chances for errors. Collections were already correctly able to hold null values, so ->including or ->insertAt already handled things correctly. The number of deviations from the spec goes down. The remaining non-conformance is necessary because of the way the implementation handles the implicit Set conversion (putting it into the abstract syntax as a Set literal). The spec and pragmatics demand that a null value converted to a Set this way results in an empty Set.

One workaround I may think of but that also has its quirks: the parser / analyzer could add an EAnnotation to the Set{...} literal resulting from the implicit -> conversion, and the evaluator could check for such an annotation. If such an annotation exists and the literal contains only one item and this single item evaluates to null, an empty Set results. Otherwise, the null value is inserted into the Set.

The problem then would only be that a non-standard annotation controls the behavior of a Set literal. What do you think?

I was thinking of an EAnnotation too. It works but is klunky.

I also though of an new 'implicit' property for CollectionLiteral.

You miss the point of my suggestion.

With the improved code, there is an ambiguity for Set{null}. I propose to change one of the ambiguities to Collection{null}, but only in the AST, not in the observable behaviour.

Yes the spec says a Set is produced. (It elsewhere says that a Bag is produced). I'm suggesting that visitCollectionLiteralExp, which formerly threw away all nulls, and is improved to throw away only singleton set nulls, instead recognises collection something as oclAsSet and consequently creates an empty set or a singleton set according to the null-ness of the argument. The Collection kind is solely in the AST as a flag avoiding extra objects.

Both approaches will be incorrectly handled by a different evluator that doesn't understand the new protocol. An EAnnotation will probably be silently ignored, but might get lost in a careless copy. A Collection kind will not get lost, but might fail a surprisingly strict validation, and might fail to evaluate since Collection is abstract.

In both cases this is a semantic API change for a proprietary representation. I don't think we support alternative evaluators. I prefer the Collection approach since it is more compact.

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on Apr 30, 2011 04:26

(In reply to comment #64)

I also though of an new 'implicit' property for CollectionLiteral.

You miss the point of my suggestion.

Maybe you just have to make it more clear... Along the same lines it seems I haven't made my point sufficiently clear. Using Collection{...} in the AST is not good because operation calls will be resolved based on its type. Collection has only a subset of the operations that Set has. This may cause lots of code to fail which so far works based on Set's operations.

Both approaches will be incorrectly handled by a different evluator that doesn't understand the new protocol. An EAnnotation will probably be silently

How likely is this? We have to judge the overall qualities of the holistic set-up. It will always have flaws, and we have to make trade offs. Either we can't use any null in collection literals (current code), or we have a special case for Set{null}, or we have an annotation that the evaluator that comes with the parser handles correctly, and other evaluators would evaluate erroneously to a single-element Set containing a single null value instead of being empty. Other evaluators based on the current analyzer will fail in the same way, so an annotation doesn't make things worse.

In both cases this is a semantic API change for a proprietary representation.

I don't think we support alternative evaluators. I prefer the Collection approach since it is more compact.

...but flawed because of the operations offered on Set and not on Collection. I'll provide a patch with the annotation that you may choose to review.

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on Apr 30, 2011 04:32

(In reply to comment #63)

But: surely the only UnlimitedNatural objects are ''? So this fix is solely to make '' comparison work. Too much risk for a cosmetic gain. WONTFIX unless you can provide a thorough revision of Long/Integer etc.

Not cosmetic at all. Any multiplicity comparison on any Ecore element will fail because at another place in the code there is this magic conversion of the upper bounds to static type UnlimitedNatural. Therefore I argue this shall not be WONTFIX.

What exactly is the problem with Long/Integer?

eclipse-ocl-bot commented 1 month ago

By Ed Willink on Apr 30, 2011 05:18

(In reply to comment #65)

Using Collection{...} in the AST is not good because operation calls will be resolved based on its type. Collection has only a subset of the operations that Set has. This may cause lots of code to fail which so far works based on Set's operations.

You're right. There may be very unpleasant downstream analysis ripples if oclAsSet is encoded as a Collection kind. Too hard to follow and fix.\ ----\ So three choices:

WONTFIX for the x->/Set{x}-> ambiguity for null x.

An EAnnotation; extra AST objects for all oclAsSet usages.

A new 'implicit' property. Oops; an API change, requiring rather enlightened interpretation of internal model APIs to introduce after M6.\ ----\ So the only difficult thing is the EAnnotation URI. Looking at the existing ecore models perhaps:

"http://www.eclipse.org/ocl/1.1.0/OCL/Annotations" with an "oclAsSet" detail of "true".

I think 1.1.0 rather than 3.1.0 since this is an upward compatible change in the style of emf/2002's many evolutions.

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on Apr 30, 2011 07:04

(In reply to comment #67)

WONTFIX for the x->/Set{x}-> ambiguity for null x.

An EAnnotation; extra AST objects for all oclAsSet usages.

A new 'implicit' property. Oops; an API change, requiring rather enlightened interpretation of internal model APIs to introduce after M6.

So the only difficult thing is the EAnnotation URI. Looking at the existing ecore models perhaps:

"http://www.eclipse.org/ocl/1.1.0/OCL/Annotations" with an "oclAsSet" detail of "true".

I think 1.1.0 rather than 3.1.0 since this is an upward compatible change in the style of emf/2002's many evolutions.

Annotation solution implemented. Works like a charm. Tests that so far had trouble with Set{null} adjusted. Will attach patch in a few minutes.

Remaining open issue as far as I see it is the UnlimitedNatural instance class issue. Would be great if you could detail the cases that concern you.

eclipse-ocl-bot commented 1 month ago

By Ed Willink on Apr 30, 2011 07:05

(In reply to comment #66)

(In reply to comment #63)

But: surely the only UnlimitedNatural objects are ''? So this fix is solely to make '' comparison work. Too much risk for a cosmetic gain. WONTFIX unless you can provide a thorough revision of Long/Integer etc.

Not cosmetic at all. Any multiplicity comparison on any Ecore element will fail because at another place in the code there is this magic conversion of the upper bounds to static type UnlimitedNatural. Therefore I argue this shall not be WONTFIX.

Looking again. I got confused between the classes and co-classes in\ oclstdlib.ecore. The extra instanceTypeName matches the static code. Ok.\ Dangerous but see next Long/Integer sub-thread.

eclipse-ocl-bot commented 1 month ago

By Ed Willink on Apr 30, 2011 07:12

(In reply to comment #66)

What exactly is the problem with Long/Integer?

I think we can postpone this to RC1, so at to get something out for M7. See Bug 344368.

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on Apr 30, 2011 07:14

Created attachment 194420 (attachment deleted)\ Solves the Set{null} problem using a CollectionLiteralExp annotation

See last comment, fixes the Set{null} problem by adding an annotation to a CollectionLiteralExp that the analyzer creates only for implicit set conversion. The evaluator then doesn't add a null value to the collection if it finds this annotation.

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on Apr 30, 2011 07:15

Created attachment 194421 (attachment deleted)\ Same as 194420 but as git patch, preserving Unicode characters in tests

Same as 194420

eclipse-ocl-bot commented 1 month ago

By Ed Willink on Apr 30, 2011 08:53

Getting close:

AbstractOCLAnalyzer.getCollectionSourceExpression\ wrong URI in getEAnnotation(Environment.OCL_NAMESPACE_URI)

EcoreEvaluationEnvironment.createTuple\ // do numeric coercion if necessary:\ if (value instanceof Number && property.getEType().getInstanceClass() != null &&\ !(value instanceof Double) &&\ Double.class.isAssignableFrom(property.getEType().getInstanceClass())) {\ value = ((Number) value).doubleValue();\ }\ should be shared functionality and probably handle Long correctly too. ? Bug 344368\ if (value != null || !(property.getEType() instanceof VoidType)) {\ // don't try to set null on a VoidType property; it's already null; trying to\ // set it will cause an exception in the EMF setting delegate infrastructure\ // because VoidType does not conform to EClass.\ tuple.eSet(property, value);\ }\ Ugh! comment just screams bug to hide bug. Deleting the || !(property.getEType() instanceof VoidType) doesn't fail any test.\ Is the comment and code obsolete?\ Same issue in TupleFactory, where, if needed, a single derivation of eGet seems called for.

EcoreEvaluationEnvironment.isKindOf\ } else if (classifier instanceof AnyType) {\ return Boolean.TRUE;\ What does this do? It isn't an OclAny conformance test and it isn't needed to make any test pass?

EvaluationVisitorImpl..OCL_AS_TYPE

EvaluationVisitorImpl.visitCollectionLiteralExp

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on Apr 30, 2011 15:31

(In reply to comment #73)

Getting close:

AbstractOCLAnalyzer.getCollectionSourceExpression wrong URI in getEAnnotation(Environment.OCL_NAMESPACE_URI)

Oh, thanks, good catch.

EcoreEvaluationEnvironment.createTuple // do numeric coercion if necessary: if (value instanceof Number && property.getEType().getInstanceClass() != null && !(value instanceof Double) &&

Double.class.isAssignableFrom(property.getEType().getInstanceClass())) { value = ((Number) value).doubleValue(); } should be shared functionality and probably handle Long correctly too. ? Bug 344368

As you suggest, 344368 should handle this.

if (value != null || !(property.getEType() instanceof VoidType)) {
    // don't try to set null on a VoidType property; it's already null;

trying to // set it will cause an exception in the EMF setting delegate infrastructure // because VoidType does not conform to EClass. tuple.eSet(property, value); } Ugh! comment just screams bug to hide bug. Deleting the || !(property.getEType() instanceof VoidType) doesn't fail any test. Is the comment and code obsolete? Same issue in TupleFactory, where, if needed, a single derivation of eGet seems called for.

Absolutely required. I ran into a ClassCastException where a VoidTypeImpl cannot be cast to an EClass. It happened during playing with the OCL console in the context of Ecore navigation and queries for EReferences with UnlimitedNaturals as upper bounds where I constructed tuples with the references' names and upper bounds. In some combination that I'm yet to reproduce the analyzer inferred OclVoid as a tuple component's type, leading up to the NPE. I'm yet to integrate this into the OCL test suite in TuplesTest.

Adding these tests showed other problems related to OclVoid in Tuples which I'm providing a fix for now.

EcoreEvaluationEnvironment.isKindOf } else if (classifier instanceof AnyType) { return Boolean.TRUE; What does this do? It isn't an OclAny conformance test and it isn't needed to make any test pass?

If I comment it, seven tests fail. Example: EvaluationStringOperationTest.testStringOclIsKindOf, with 'test'.oclIsKindOf(OclAny).

EvaluationVisitorImpl..OCL_AS_TYPE

  • sourceVal != getInvalid() && is redundant

Correct. Removed.

EvaluationVisitorImpl.visitCollectionLiteralExp

  • | parts.size() > 1 | is redundant

Redundant, but more efficient. The isImplicitSetConversion test operation needs to fiddle with the annotations which requires several hash lookup operations which are expensive compared to a size() (usually a simple getter on a cached field) and int comparison. That's why I argue it should stay.

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on Apr 30, 2011 15:37

Created attachment 194430 (attachment deleted)\ Solves null/OclVoid in Tuples and adds according tests

See my last comment

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on Apr 30, 2011 15:38

Created attachment 194431 (attachment deleted)\ Same as 194430 but as git patch, preserving Unicode characters in tests

Same as 194430 but as git patch, preserving Unicode characters in tests

eclipse-ocl-bot commented 1 month ago

By Ed Willink on May 01, 2011 01:07

(In reply to comment #75)

Created attachment 194430 [details]

o.e.o is missing\ EcoreEvaluationenvironment is missing

the git patch doesn't work for me; no git

eclipse-ocl-bot commented 1 month ago

By Ed Willink on May 01, 2011 01:38

(In reply to comment #74)\ Although I can't review 194430, there were only trivial changes required to 194420. so I can +1 194420 with the trivial changes and careful commit of the Unicode characters.

if (value != null || !(property.getEType() instanceof VoidType)) {
    // don't try to set null on a VoidType property; it's already null;

trying to // set it will cause an exception in the EMF setting delegate infrastructure // because VoidType does not conform to EClass. tuple.eSet(property, value); } Ugh! comment just screams bug to hide bug. Deleting the || !(property.getEType() instanceof VoidType) doesn't fail any test. Is the comment and code obsolete? Same issue in TupleFactory, where, if needed, a single derivation of eGet seems called for.

Absolutely required. I ran into a ClassCastException where a VoidTypeImpl cannot be cast to an EClass. It happened during playing with the OCL console in the context of Ecore navigation and queries for EReferences with UnlimitedNaturals as upper bounds where I constructed tuples with the references' names and upper bounds. In some combination that I'm yet to reproduce the analyzer inferred OclVoid as a tuple component's type, leading up to the NPE. I'm yet to integrate this into the OCL test suite in TuplesTest.

Adding these tests showed other problems related to OclVoid in Tuples which I'm providing a fix for now.

Raise a seprate Bugzilla for these tests. The extra code looks redundant and smelly =ratyher than wrong, so we can run with it.

EcoreEvaluationEnvironment.isKindOf } else if (classifier instanceof AnyType) { return Boolean.TRUE; What does this do? It isn't an OclAny conformance test and it isn't needed to make any test pass?

If I comment it, seven tests fail. Example: EvaluationStringOperationTest.testStringOclIsKindOf, with 'test'.oclIsKindOf(OclAny).

Yes. I now get 4 failure on Ecore standalone. I msread of test of souyrce not test of target.

EvaluationVisitorImpl.visitCollectionLiteralExp

  • | parts.size() > 1 | is redundant

Redundant, but more efficient. The isImplicitSetConversion test operation needs to fiddle with the annotations which requires several hash lookup operations which are expensive compared to a size() (usually a simple getter on a cached field) and int comparison. That's why I argue it should stay.

Yes, a marginal improvement.

eclipse-ocl-bot commented 1 month ago

By Ed Willink on May 01, 2011 01:56

(In reply to comment #78)

if (value != null || !(property.getEType() instanceof VoidType)) {
    // don't try to set null on a VoidType property; it's already null;

trying to // set it will cause an exception in the EMF setting delegate infrastructure // because VoidType does not conform to EClass. tuple.eSet(property, value); } Ugh! comment just screams bug to hide bug. Deleting the || !(property.getEType() instanceof VoidType) doesn't fail any test. Is the comment and code obsolete? Same issue in TupleFactory, where, if needed, a single derivation of eGet seems called for.

Absolutely required. I ran into a ClassCastException where a VoidTypeImpl cannot be cast to an EClass. It happened during playing with the OCL console in the context of Ecore navigation and queries for EReferences with UnlimitedNaturals as upper bounds where I constructed tuples with the references' names and upper bounds. In some combination that I'm yet to reproduce the analyzer inferred OclVoid as a tuple component's type, leading up to the NPE. I'm yet to integrate this into the OCL test suite in TuplesTest.

I guess the problem comes from the following revised test

public void test_tuplePartAccess_238049() {\
    OCLExpression<EClassifier> expr = parse(\
        "package ocltest context Fruit " +\
        "inv: Tuple{first : OclVoid = 'Roger', last : OclVoid = null}.first " +\
        "endpackage");\
\
    assertEquals("Roger", evaluate(expr));\
}

but it generates a static error.

Behind the scenes it is clearly a propblem to assign to OclVoid. The comment is very misleading. Any assignmment to OclVoid is liable to encounter conformance trouble and quite rightly so. Change comment to "Don't try to set an OclVoid property", except that why do we protect OclVoid. Setting "1_2_3_4" on an Integer will cause EMF to barf too. The problem is upstream.

Adding these tests showed other problems related to OclVoid in Tuples which I'm providing a fix for now.

I had considerable difficulties getting the correct homogeneous tuple type for the pivot model so you may have trouble here too.

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on May 01, 2011 03:11

(In reply to comment #77)

(In reply to comment #75)

Created attachment 194430 [details] [details] o.e.o is missing EcoreEvaluationenvironment is missing

the git patch doesn't work for me; no git

Should work if you set the "Apply patch" dialog to ignore the first two path elements. That's how I get the git-exported patch applied to my CVS workspace.

eclipse-ocl-bot commented 1 month ago

By Ed Willink on May 01, 2011 04:27

(In reply to comment #80)

(In reply to comment #77)

(In reply to comment #75)

Created attachment 194430 [details] [details] [details] o.e.o is missing EcoreEvaluationenvironment is missing

the git patch doesn't work for me; no git

Should work if you set the "Apply patch" dialog to ignore the first two path elements. That's how I get the git-exported patch applied to my CVS workspace.

No. Apply Patch knwos nothing abour a/plugins... ; nothing exists.

Did you miss the +1 for 194420 + trivia in #78?

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on May 01, 2011 04:31

(In reply to comment #78)

(In reply to comment #74) Although I can't review 194430, there were only trivial changes required to

  1. so I can +1 194420 with the trivial changes and careful commit of the Unicode characters.

But 194420 still has the oclIsTypeOf bugs that 194430 fixes. If you insist to\ keep the Tuple issue separate, I'll raise a separate bugzilla for it and\ provide the fix there. I'll quickly argue below why I think it's essential,\ contrary to your reasoning.

I will prepare one more patch that contains the oclIsTypeOf-related fixes that\ 194430 contained, reverting the fix for the Tuple bug, hoping to get your +1\ for that, too.

if (value != null || !(property.getEType() instanceof VoidType)) {
    // don't try to set null on a VoidType property; it's already null;

trying to // set it will cause an exception in the EMF setting delegate infrastructure // because VoidType does not conform to EClass. tuple.eSet(property, value); } Ugh! comment just screams bug to hide bug. Deleting the || !(property.getEType() instanceof VoidType) doesn't fail any test. Is the comment and code obsolete? Same issue in TupleFactory, where, if needed, a single derivation of eGet seems called for.

Absolutely required. I ran into a ClassCastException where a VoidTypeImpl cannot be cast to an EClass. It happened during playing with the OCL console in the context of Ecore navigation and queries for EReferences with UnlimitedNaturals as upper bounds where I constructed tuples with the references' names and upper bounds. In some combination that I'm yet to reproduce the analyzer inferred OclVoid as a tuple component's type, leading up to the NPE. I'm yet to integrate this into the OCL test suite in TuplesTest.

Adding these tests showed other problems related to OclVoid in Tuples which I'm providing a fix for now.

Raise a seprate Bugzilla for these tests. The extra code looks redundant and smelly =ratyher than wrong, so we can run with it.

OclVoid is the type the analyzer assigns to a single "null" value. So\ Tuple{a=null, b="abc"} will be inferred to Tuple(a:OclVoid, b:String). The\ evaluator doesn't execute this properly and fails with the aforementioned CCE.\ This is a bug, and it's easily fixed by the patch I provided. I'm okay with\ extracting this into a separate bugzilla.

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on May 01, 2011 04:33

(In reply to comment #81)

(In reply to comment #80)

(In reply to comment #77)

(In reply to comment #75)

Created attachment 194430 [details] [details] [details] [details] o.e.o is missing EcoreEvaluationenvironment is missing

the git patch doesn't work for me; no git

Should work if you set the "Apply patch" dialog to ignore the first two path elements. That's how I get the git-exported patch applied to my CVS workspace.

No. Apply Patch knwos nothing abour a/plugins... ; nothing exists.

Did you miss the +1 for 194420 + trivia in #78?

My apply patch dialog has a drop-down that lets me choose how many leading path segments to ignore in the patch. My CVS workspace has the bundles immediately checked-out into the workspace dir. So if I tell apply-patch to ignore two leading segments, a/plugins and a/tests gets ignored, and the remaining path matches my workspace. Maybe you have a different workspace setup?

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on May 01, 2011 04:53

(In reply to comment #79)\ I also have to revise Laurent's tests then and split off one test for 344391\ because without the Tuple-null fix it fails:

EvaluationCollectionOperationTest.testCollectionProductNullValue fails with\ exceptions without the fix.

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on May 01, 2011 05:03

Created attachment 194437 (attachment deleted)\ Reverts the Tuple-null fix, fixes oclIsTypeOf for null/invalid

Tuple null fix moved to bug 344391. Had to comment one more of Laurent's tests that depend on null in Tuples which then depends on 344391. In addition to 194420 this patch fixes the oclIsTypeOf behavior for null/invalid where so far the results were wrong, considering null and invalid as oclIsTypeOf anything although they should only be oclIsTypeOf OclVoid and OclInvalid, respectively.

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on May 01, 2011 05:27

Created attachment 194438 Reverts the Tuple-null fix, fixes oclIsTypeOf for null/invalid

Sorry, 194437 forgot to revert one part of the Tuple-null fix. This one should be ok now.

:notepad_spiral: 342644.patch

eclipse-ocl-bot commented 1 month ago

By Ed Willink on May 01, 2011 06:09

(In reply to comment #82)

(In reply to comment #78)

(In reply to comment #74) Although I can't review 194430, there were only trivial changes required to

  1. so I can +1 194420 with the trivial changes and careful commit of the Unicode characters.

But 194420 still has the oclIsTypeOf bugs that 194430 fixes. If you insist to keep the Tuple issue separate, I'll raise a separate bugzilla for it and provide the fix there. I'll quickly argue below why I think it's essential, contrary to your reasoning.

I'm losing track of where we are. I thought that I raised 7 queries against 194420 on which we quickly agreed about 6. Only the tuples are oustanding. So commit 194420 plus the trivial changes for the 6 agreements.

I suspect the tuple change is correct, but I'm not sure what I'm checking. It's just that this bug has many issues resolved and I/we want it committed for M7 tomorrow.

If we have to bounce a tuple discussion back and forth a couple of times the commit gets to be very late. The tuples were broken in M6 so waiting till RC1 for the fix should be no hardship.

Please commit this as soon as possible so that we have a new CVS reference for other patches. (Patches on patches are a nightmare.)

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on May 01, 2011 06:33

(In reply to comment #87)

(In reply to comment #82)

(In reply to comment #78)

(In reply to comment #74) Although I can't review 194430, there were only trivial changes required to

  1. so I can +1 194420 with the trivial changes and careful commit of the Unicode characters.

But 194420 still has the oclIsTypeOf bugs that 194430 fixes. If you insist to keep the Tuple issue separate, I'll raise a separate bugzilla for it and provide the fix there. I'll quickly argue below why I think it's essential, contrary to your reasoning.

I'm losing track of where we are. I thought that I raised 7 queries against 194420 on which we quickly agreed about 6. Only the tuples are oustanding. So commit 194420 plus the trivial changes for the 6 agreements.

I suspect the tuple change is correct, but I'm not sure what I'm checking. It's just that this bug has many issues resolved and I/we want it committed for M7 tomorrow.

If we have to bounce a tuple discussion back and forth a couple of times the commit gets to be very late. The tuples were broken in M6 so waiting till RC1 for the fix should be no hardship.

Please commit this as soon as possible so that we have a new CVS reference for other patches. (Patches on patches are a nightmare.)

Good, I take this as a +1 for 194438 which I'll commit now, with the Unicode stuff manually patched to get it into CVS. Based on this I'll then produce a CVS patch for 344391. Maybe we get 344391 into CVS too today, for M7. That would be great.

eclipse-ocl-bot commented 1 month ago

By Axel Uhl on May 01, 2011 06:57

Committed to CVS HEAD.

eclipse-ocl-bot commented 1 month ago

By Ed Willink on May 27, 2011 03:13

Closing