Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 364940 - [Xtend] validation of dispatch methods in subclasses
Summary: [Xtend] validation of dispatch methods in subclasses
Status: VERIFIED FIXED
Alias: None
Product: Xtend
Classification: Tools
Component: Backlog (show other bugs)
Version: 2.2.0   Edit
Hardware: PC Mac OS X - Carbon (unsup.)
: P3 major (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard: v2.6
Keywords:
Depends on:
Blocks:
 
Reported: 2011-11-28 07:09 EST by Sven Efftinge CLA
Modified: 2014-05-13 04:09 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sven Efftinge CLA 2011-11-28 07:09:52 EST
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.
Comment 1 Moritz Eysholdt CLA 2011-11-28 07:57:05 EST
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.
Comment 2 Sven Efftinge CLA 2011-11-28 08:35:34 EST
(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.
Comment 3 Sebastian Zarnekow CLA 2014-04-25 02:57:27 EDT
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.