Bug 479358 - Type not allowed in forEach declarator
Summary: Type not allowed in forEach declarator
Status: NEW
Alias: None
Product: QVTo
Classification: Modeling
Component: Engine (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows NT
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-10-08 12:12 EDT by Ed Willink CLA
Modified: 2016-02-19 04:48 EST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ed Willink CLA 2015-10-08 12:12:23 EDT
The following example fails to parse

query Collection(String)::test(body : OclAny) : Sequence(OclAny) =
	self->forEach(iterator : String) { iterator.toUpper(); };


But this is ok

query Collection(String)::test(body : OclAny) : Sequence(OclAny) =
	self->forEach(iterator) { iterator.toUpper(); };

Why isn't the gratuitous type permitted?
Comment 1 Sergey Boyko CLA 2016-02-19 03:32:49 EST
(In reply to Ed Willink from comment #0)
> The following example fails to parse
> 
> query Collection(String)::test(body : OclAny) : Sequence(OclAny) =
> 	self->forEach(iterator : String) { iterator.toUpper(); };
> 
> 
> But this is ok
> 
> query Collection(String)::test(body : OclAny) : Sequence(OclAny) =
> 	self->forEach(iterator) { iterator.toUpper(); };
> 
> Why isn't the gratuitous type permitted?

While BNF allows to use typespec for the iterator I don't see any reasonable use of this.

There are three possibilities:

* Collection(String)->forEach(i : String) {}  - here typespec for 'i' is redundant and should be omitted

* Collection(String)->forEach(i : OclAny) {}  - here typespec for 'i' is almost redundant since all operations for OclAny type are also available for String

* Collection(ENameElement)->forEach(i : EPackage) {}  - possible shortcut for 'i|i.oclIsKindOf(EPackage)' but such behavior is totally unspecified


Thus no sense for using typespec for iterator declaration.
Comment 2 Ed Willink CLA 2016-02-19 04:48:03 EST
(In reply to Sergey Boyko from comment #1)
> * Collection(String)->forEach(i : String) {}  - here typespec for 'i' is
> redundant and should be omitted

"could" not "should"
> 
> * Collection(String)->forEach(i : OclAny) {}  - here typespec for 'i' is
> almost redundant since all operations for OclAny type are also available for
> String

almost redundant usually, but for complex expressions the user may find that it is a useful form of 'documentation'. In the case of conflicting overloads, 

Collection(AandB){...}->forEach(i : A) {i.x()} 

the selection of a specific superclass can avoid the need to use oclAsType() to disambiguate.

> * Collection(ENameElement)->forEach(i : EPackage) {}  - possible shortcut
> for 'i|i.oclIsKindOf(EPackage)' but such behavior is totally unspecified

should be invalid at compile time.

----

The 'documentation' case becomes an 'assertion' case once the extension to non-nullable types using multiplicity is adopted by OCL.

Collection(AandB)->forEach(i : A[1]) {...} 
 
asserts that i cannot be null.

(In reply to Sergey Boyko from comment #1)
> Thus no sense for using typespec for iterator declaration.

It's in the spec and certainly not an error so it should be in tooling.