| Summary: | [Xtend] validation of dispatch methods in subclasses | ||
|---|---|---|---|
| Product: | [Tools] Xtend | Reporter: | Sven Efftinge <sven.efftinge> |
| Component: | Backlog | Assignee: | Project Inbox <xtend-inbox> |
| Status: | VERIFIED FIXED | QA Contact: | |
| Severity: | major | ||
| Priority: | P3 | CC: | btickets, sebastian.zarnekow, st.oehme |
| Version: | 2.2.0 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Mac OS X - Carbon (unsup.) | ||
| Whiteboard: | v2.6 | ||
Let's explore how this applies to dynamic dispatch over static methods. (In reply to comment #0) > If a dispatch method adds a case to a set of dispatch methods from its > superclass the override keyword is mandatory. > If the inferred synthetic dispatch method overrides a regular method from a > super type the override is mandatory. > If one of the car methods overrides a regular method from the super type > override is also mandatory. I assume the "overrides" keyword is not expected in any of the three cases above for static methods? However, would it make sense to make it explicit when a method adds a case to a super-classes' dispatch group? > Only cases which are within the signature of the super dispatch method are > allowed in subclass. We could enforce this for static methods, too, even though it would not be required, since in the static scenario the dispatch method can not override the super-classes' dispatch-method. (In reply to comment #1) > Let's explore how this applies to dynamic dispatch over static methods. > > (In reply to comment #0) > > If a dispatch method adds a case to a set of dispatch methods from its > > superclass the override keyword is mandatory. > > If the inferred synthetic dispatch method overrides a regular method from a > > super type the override is mandatory. > > If one of the car methods overrides a regular method from the super type > > override is also mandatory. > > I assume the "overrides" keyword is not expected in any of the three cases > above for static methods? > However, would it make sense to make it explicit when a method adds a case to a > super-classes' dispatch group? Since we use 'override' for regular static methods, we should use them here as well. > > > Only cases which are within the signature of the super dispatch method are > > allowed in subclass. > > We could enforce this for static methods, too, even though it would not be > required, since in the static scenario the dispatch method can not override the > super-classes' dispatch-method. We should enforce this force static methods, too. If there arise valid use cases why we should relax this constraint we can still do. Pushed to view. I didn't go the cast-validation path, though. Given this example from comment #0 class Base { def dispatch foo(CharSequence c) { 'charseq' } def dispatch foo(String s) { 'string' } } class Sub extends Base { override dispatch foo(InputStream in) { 'inputstream' } } Clients of Base or Sub will see a signature foo(CharSequence). That is, they won't be able to pass a plain InputStream to foo(..) even though they see a case for foo(InputStream) right in the code. Since that's surprising and the implementation would be more involving, I used a plain subtype relationship for the validation of the parameter types in dispatch cases, that were added in subtypes. Please reopen if that was the wrong choice. |
If a dispatch method adds a case to a set of dispatch methods from its superclass the override keyword is mandatory. If the inferred synthetic dispatch method overrides a regular method from a super type the override is mandatory. If one of the car methods overrides a regular method from the super type override is also mandatory. Only cases which are within the signature of the super dispatch method are allowed in subclass. That is the following is invalid: class Base { def dispatch foo(CharSequence c) { 'charseq' } def dispatch foo(String s) { 'string' } } class Sub extends Base { override dispatch foo(Object o) { 'object' } // invalid since CharSequence cannot be casted to Object } We have to apply the cast semantics here, which means that the following would be valid: class Sub extends Base { override dispatch foo(InputStream in) { 'inputstream' } } since a class could exist which implements CharSequene and InputStream. The inferred synthetic dispatch method must always override the one from the super class. That is even with InputStream the inferred dispatch must use CharSequence as its first argument type.