Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 364974

Summary: [Xtend] overwritten method with type params not recognized
Product: [Tools] Xtend Reporter: Moritz Eysholdt <moritz.eysholdt>
Component: CoreAssignee: Holger Schill <Holger.Schill>
Status: CLOSED FIXED QA Contact:
Severity: major    
Priority: P3 CC: Holger.Schill, sebastian.zarnekow, sven.efftinge
Version: 2.2.0Flags: sven.efftinge: juno+
Target Milestone: M7   
Hardware: Macintosh   
OS: Mac OS X   
Whiteboard:
Attachments:
Description Flags
Potential fix
none
Missing guard
none
Potential fix
none
Potential fix
none
Potential fix
none
patch
none
Patch for Xtext
none
Patch for Xtend (Tests) none

Description Moritz Eysholdt CLA 2011-11-28 11:37:41 EST
Example:

--- Java ----
public interface MyList {
	<T> T toArray(T a);
}
-----------

--- Xtend ---
class bar extends MyList implements MyIf{
	override <T> toArray(T a) {
	}
}
------------

the Xtend method is flagged with two errors:
---
- Name clash: The method toArray(T) of type bar has the same erasure as toArray (T) of type MyList but does not override it. 
- Function does not override any function
 ---
 
 I'd expect no errors.
Comment 1 Sebastian Zarnekow CLA 2012-04-04 03:43:18 EDT
Moritz, could you please update your example and reopen the ticket if necessary?

class bar extends MyList seems bogus to me since MyList is an interface in your example.

I tried this one instead and it compiled without errors:

Java:

public interface MyIntf {
	<T> T toArray(T a);
}

Xtend:

class bar implements MyIntf {
	override <T> toArray(T a) {
		throw new UnsupportedOperationException("Auto-generated function stub")
	}
}
Comment 2 Moritz Eysholdt CLA 2012-04-04 06:33:19 EDT
I tried the following, and the error still exits:

1. create a new Xtend class that implements java.util.list<Object> 
2. use the quick fix to add the unimplementd methods.

get the following errors:
- Duplicate method toArray(T[]) in type Foo
- The method toArray(T[]) : void of type Foo must override a
   superclass method.

the method override <T> toArray(T[] arg0) is indeed create twice.

If I delete one of them, these errors remain:

- Name clash: The method toArray(T[]) of type Foo has the same erasure as toArray(T[]) of type List but does not override it. 
- The method toArray(T[]) : void of type Foo must override a superclass method. 
- Name clash: The method toArray(T[]) of type Foo has the same erasure as toArray(T[]) of type Collection but does not override it.
Comment 3 Holger Schill CLA 2012-05-03 09:56:51 EDT
I thin the typeParameter is the problem. After some debugging I can see that EcoreUtil.equals(overridingType, overriddenType) in org.eclipse.xtext.common.types.util.FeatureOverridesService.isSameArgumentTypes(JvmOperation, JvmOperation, ITypeArgumentContext) is answering with false because the Type T has different declarators List and the overwriting type. The rest of the implementation of org.eclipse.xtext.common.types.util.FeatureOverridesService.isSameArgumentTypes(JvmOperation, JvmOperation, ITypeArgumentContext) cares only for JvmTypeParameter and not for JvmArrayType.
Comment 4 Holger Schill CLA 2012-05-03 10:15:37 EDT
Created attachment 215000 [details]
Potential fix

This patch solves the problem but it feels hacky and I am not sure if there are sideeffects.

Any opinions?
Comment 5 Holger Schill CLA 2012-05-03 10:20:06 EDT
Created attachment 215001 [details]
Missing guard
Comment 6 Holger Schill CLA 2012-05-03 10:20:33 EDT
Created attachment 215002 [details]
Potential fix
Comment 7 Holger Schill CLA 2012-05-03 10:21:15 EDT
Created attachment 215003 [details]
Potential fix
Comment 8 Holger Schill CLA 2012-05-03 10:21:43 EDT
Created attachment 215004 [details]
Potential fix

But still feels hacky.
Comment 9 Sebastian Zarnekow CLA 2012-05-03 10:23:09 EDT
I doubt that this'll fix the issue since we get the same problems with this example:

import java.util.List

abstract class A<T> {
    def <T1> T1[] getValue1(List<T1> t)
    def <T2> T2[] getValue2(T2[] t)
    def <T3> List<T3> getValue3(List<T3> t)
}

abstract class B<T> extends A<T> {
    override <V> V[] getValue1(List<V> v) {}
}

abstract class C<T> extends A<T> {
    override <V> V[] getValue2(V[] t) {}
}

abstract class D<T> extends A<T> {
    override <V> List<V> getValue3(List<V> t) {}
}
Comment 10 Holger Schill CLA 2012-05-03 10:26:46 EDT
Right. But EcoreUtil.equals will not solve the problem.
Comment 11 Holger Schill CLA 2012-05-03 11:10:49 EDT
Created attachment 215009 [details]
patch

This patch potentially solves the problem discussed in this bug but after all methods are accepted as overriding methods the returnType is not valid. I think this is another bug caused by the same issue -> TypeParameters I think.

package foo.bar
import java.util.List

abstract class A<T> {
    def <T1> T1[] getValue1(List<T1> t)
    def <T2> T2[] getValue2(T2[] t)
    def <T3> List<T3> getValue3(List<T3> t)
}

abstract class B<T> extends A<T> {
    override <V> V[] getValue1(List<V> v) {}
}
 
abstract class C<T> extends A<T> {
    override <V> V[] getValue2(V[] t) {}
}

abstract class D<T> extends A<T> {
    override <V> List<V> getValue3(List<V> t) {} 
}

Errors:

The return type is incompatible with foo.bar.A.getValue1(java.util.List)

The return type is incompatible with foo.bar.A.getValue2(T2[])

The return type is incompatible with foo.bar.A.getValue3(java.util.List)
Comment 12 Holger Schill CLA 2012-05-04 08:05:53 EDT
Created attachment 215054 [details]
Patch for Xtext

Patch for org.eclipse.xtext.common.types.util.FeatureOverridesService
Comment 13 Holger Schill CLA 2012-05-04 08:06:29 EDT
Created attachment 215055 [details]
Patch for Xtend (Tests)

Tests for Xtend
Comment 14 Holger Schill CLA 2012-05-04 08:10:27 EDT
Created 378484 for the problems with the returntypes as mentioned in comment11.
Comment 15 Sebastian Zarnekow CLA 2012-05-04 08:13:54 EDT
We have to check the compatibility of the type parameters, too.

The following is invalid in Java:

class A {
	<T extends CharSequence> void foo() {}
}
class B extends A {
	@Override
	<T extends String> void foo() {}
}


Please add some tests for function types, too:

Java:
class A {
  <T> void foo(T t, Procedure0<? super T> proc)
}

could be overwritten by

class B extends A {
  <T> void foo(T t, (T)=>void proc)
}
Comment 16 Holger Schill CLA 2012-05-04 09:20:43 EDT
Pushed additional tests fix to master
Comment 17 Eclipse Webmaster CLA 2017-10-31 11:23:56 EDT
Requested via bug 522520.

-M.