[jira] [Commented] (GROOVY-9059) Failed to parse/compile generic methods with "extends"

2019-08-06 Thread Eric Milles (JIRA)


[ 
https://issues.apache.org/jira/browse/GROOVY-9059?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16901316#comment-16901316
 ] 

Eric Milles commented on GROOVY-9059:
-

Taking another look at this, it appears that 
{{GenericsUtils.addMethodGenerics}} is where the information loss occurs for 
groovyc.

{code:java}
public static Map addMethodGenerics(MethodNode current, 
Map oldSpec) {
Map ret = new HashMap(oldSpec);
// ret starts with the original type specs, now add gts for the current 
method if any
GenericsType[] sgts = current.getGenericsTypes();
if (sgts != null) {
for (GenericsType sgt : sgts) {
String name = sgt.getName();
if (sgt.isPlaceholder()) {
ClassNode redirect;
if (sgt.getUpperBounds() != null) {
redirect = sgt.getUpperBounds()[0];
} else if (sgt.getLowerBound() != null) {
redirect = sgt.getLowerBound();
} else {
redirect = ClassHelper.OBJECT_TYPE;
}
ClassNode type = ClassHelper.makeWithoutCaching(name);
type.setGenericsPlaceHolder(true); // type is "O" and 
redirect is "T -> Object"
type.setRedirect(redirect); // after this, type is "O -> 
Object"; "T" has been lost
ret.put(name, type);
} else {
ret.put(name, sgt.getType());
}
}
}
return ret;
}
{code}

For the {{correctToGenericsSpec}} calls to work after this, "T" must be 
retained in the redirect of "O".

> Failed to parse/compile generic methods with "extends"
> --
>
> Key: GROOVY-9059
> URL: https://issues.apache.org/jira/browse/GROOVY-9059
> Project: Groovy
>  Issue Type: Bug
>  Components: Static compilation
>Affects Versions: 2.4.16, 3.0.0-alpha-4, 2.5.6
>Reporter: Xiaoguang Wang
>Priority: Major
> Attachments: image-2019-03-30-13-10-20-819.png
>
>
>  
> {code:java}
> import groovy.transform.CompileStatic
> // This bug affects: groovy-2.4.16, groovy-2.5.6, groovy-3.0.0-alpha-4
> // This bug also affect IDEA's syntax parser
> interface X {
> // Intellij IDEA reports that 'public' is not necessary
> // BUT without the 'public' modifier, there is a syntax error
> public  T foo(T o);
> }
> interface Y {
> public  O foo(O o);
> }
> @CompileStatic
> class TestGroovyGeneric {
> static void main(String[] args) {
> def x = new X() {
> // it compiles
> // BUT: Intellij IDEA reports: ERROR: Method 'foo' is not 
> implemented
> @Override
> String foo(String o) { return o }
> }
> // Strangely, such code compiles
> // BUT: Intellij IDEA reports: ERROR: Method 'foo' is not implemented
> def y1 = new Y() {
> @Override
> public  String foo(String o) { return o }
> }
> // Can not compile:
> // BUT: Intellij IDEA reports no error 
> def y2 = new Y() {
> @Override
> String foo(String o) { return o }
> }
> }
> }
> {code}
> !image-2019-03-30-13-10-20-819.png!
>  



--
This message was sent by Atlassian JIRA
(v7.6.14#76016)


[jira] [Commented] (GROOVY-9059) Failed to parse/compile generic methods with "extends"

2019-04-19 Thread Eric Milles (JIRA)


[ 
https://issues.apache.org/jira/browse/GROOVY-9059?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16822125#comment-16822125
 ] 

Eric Milles commented on GROOVY-9059:
-

So by including the generics of {{oldMethod}}, {{equalParametersWithGenerics}} 
can get from {{O -> Object}} to {{O -> T -> Object}}.  Since {{genericsSpec}} 
is only used to convert types from {{oldMethod}}, I removed the existing call 
{{addMethodGenerics(overridingMethod, genericsSpec)}}.
{code:java}
// org.codehaus.groovy.classgen.Verifier
private MethodNode getCovariantImplementation(final MethodNode oldMethod, 
final MethodNode overridingMethod, Map genericsSpec, boolean ignoreError) {
// method name
if (!oldMethod.getName().equals(overridingMethod.getName())) return 
null;
if ((overridingMethod.getModifiers() & ACC_BRIDGE) != 0) return null;
if (oldMethod.isPrivate()) return null;

// GRECLIPSE add -- GROOVY-9059
genericsSpec = GenericsUtils.addMethodGenerics(oldMethod, genericsSpec);
// GRECLIPSE end

// parameters
boolean normalEqualParameters = equalParametersNormal(overridingMethod, 
oldMethod);
boolean genericEqualParameters = 
equalParametersWithGenerics(overridingMethod, oldMethod, genericsSpec);
if (!normalEqualParameters && !genericEqualParameters) return null;

/* GRECLIPSE edit -- GROOVY-9059
//correct to method level generics for the overriding method
genericsSpec = GenericsUtils.addMethodGenerics(overridingMethod, 
genericsSpec);
*/

// return type
ClassNode mr = overridingMethod.getReturnType();
ClassNode omr = oldMethod.getReturnType();
boolean equalReturnType = mr.equals(omr);

ClassNode testmr = correctToGenericsSpec(genericsSpec, omr);
{code}

>From there, it needs some help to use the entry {{T=T->java.lang.String}} from 
>{{genericsSpec}}.  I did it using a special method from ClassNode that was 
>introduced for a previous fix:
{code:java}
// org.codehaus.groovy.ast.tools.GenericsUtils
public static ClassNode correctToGenericsSpec(Map 
genericsSpec, ClassNode type) {
if (type.isArray()) {
return correctToGenericsSpec(genericsSpec, 
type.getComponentType()).makeArray();
}
if (type.isGenericsPlaceHolder()) {
String name = type.getGenericsTypes()[0].getName();
type = genericsSpec.get(name);
// GRECLIPSE add -- GROOVY-9059
if (type != null && type.isGenericsPlaceHolder()) {
type = type.asGenericsType().getUpperBounds()[0];
return correctToGenericsSpec(genericsSpec, type);
}
// GRECLIPSE end
}
if (type == null) type = ClassHelper.OBJECT_TYPE;
return type;
}
{code}

{code:java}
// org.codehaus.groovy.ast.ClassNode
public GenericsType asGenericsType() {
if (!isGenericsPlaceHolder()) {
return new GenericsType(this);
} else {
ClassNode upper = (redirect != null ? redirect : this);
return new GenericsType(this, new ClassNode[]{upper}, null);
}
}
{code}

With that in place, you can do this without error:
{code:groovy}
class Why implements Y {
  @Override
  public  CS foo(CS s) { s }
}
// or
def why = new Y() {
  @Override
  public  CS foo(CS s) { s }
}
{code}

However, your example of using String and no method generics still produces 1 
errors (from groovyc) and 1 warning (from eclipse):
1. Method 'foo' from class 'Bar$1' does not override method from its superclass 
or interfaces but is annotated with @Override.
2. The return type String for foo(String) from the type new Y(){} needs 
unchecked conversion to conform to O from the type Y

> Failed to parse/compile generic methods with "extends"
> --
>
> Key: GROOVY-9059
> URL: https://issues.apache.org/jira/browse/GROOVY-9059
> Project: Groovy
>  Issue Type: Bug
>  Components: Static compilation
>Affects Versions: 2.4.16, 3.0.0-alpha-4, 2.5.6
>Reporter: Xiaoguang Wang
>Priority: Major
> Attachments: image-2019-03-30-13-10-20-819.png
>
>
>  
> {code:java}
> import groovy.transform.CompileStatic
> // This bug affects: groovy-2.4.16, groovy-2.5.6, groovy-3.0.0-alpha-4
> // This bug also affect IDEA's syntax parser
> interface X {
> // Intellij IDEA reports that 'public' is not necessary
> // BUT without the 'public' modifier, there is a syntax error
> public  T foo(T o);
> }
> interface Y {
> public  O foo(O o);
> }
> @CompileStatic
> class TestGroovyGeneric {
> static void main(String[] args) {
> def x = new X() {
> // it compiles
> // BUT: Intellij IDEA reports: ERROR: Method 'foo' is not 
> implemented
>

[jira] [Commented] (GROOVY-9059) Failed to parse/compile generic methods with "extends"

2019-04-19 Thread Eric Milles (JIRA)


[ 
https://issues.apache.org/jira/browse/GROOVY-9059?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16822059#comment-16822059
 ] 

Eric Milles commented on GROOVY-9059:
-

{code:java}
private MethodNode getCovariantImplementation(final MethodNode oldMethod, 
final MethodNode overridingMethod, Map genericsSpec, boolean ignoreError) {
// method name
if (!oldMethod.getName().equals(overridingMethod.getName())) return 
null;
if ((overridingMethod.getModifiers() & ACC_BRIDGE) != 0) return null;
if (oldMethod.isPrivate()) return null;

// GRECLIPSE add -- GROOVY-9059
genericsSpec = GenericsUtils.addMethodGenerics(overridingMethod, 
genericsSpec);
// GRECLIPSE end

// parameters
boolean normalEqualParameters = equalParametersNormal(overridingMethod, 
oldMethod);
boolean genericEqualParameters = 
equalParametersWithGenerics(overridingMethod, oldMethod, genericsSpec);
if (!normalEqualParameters && !genericEqualParameters) return null;
/* GRECLIPSE edit -- GROOVY-9059
//correct to method level generics for the overriding method
genericsSpec = GenericsUtils.addMethodGenerics(overridingMethod, 
genericsSpec);
*/
{code}

> Failed to parse/compile generic methods with "extends"
> --
>
> Key: GROOVY-9059
> URL: https://issues.apache.org/jira/browse/GROOVY-9059
> Project: Groovy
>  Issue Type: Bug
>  Components: Static compilation
>Affects Versions: 2.4.16, 3.0.0-alpha-4, 2.5.6
>Reporter: Xiaoguang Wang
>Priority: Major
> Attachments: image-2019-03-30-13-10-20-819.png
>
>
>  
> {code:java}
> import groovy.transform.CompileStatic
> // This bug affects: groovy-2.4.16, groovy-2.5.6, groovy-3.0.0-alpha-4
> // This bug also affect IDEA's syntax parser
> interface X {
> // Intellij IDEA reports that 'public' is not necessary
> // BUT without the 'public' modifier, there is a syntax error
> public  T foo(T o);
> }
> interface Y {
> public  O foo(O o);
> }
> @CompileStatic
> class TestGroovyGeneric {
> static void main(String[] args) {
> def x = new X() {
> // it compiles
> // BUT: Intellij IDEA reports: ERROR: Method 'foo' is not 
> implemented
> @Override
> String foo(String o) { return o }
> }
> // Strangely, such code compiles
> // BUT: Intellij IDEA reports: ERROR: Method 'foo' is not implemented
> def y1 = new Y() {
> @Override
> public  String foo(String o) { return o }
> }
> // Can not compile:
> // BUT: Intellij IDEA reports no error 
> def y2 = new Y() {
> @Override
> String foo(String o) { return o }
> }
> }
> }
> {code}
> !image-2019-03-30-13-10-20-819.png!
>  



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)


[jira] [Commented] (GROOVY-9059) Failed to parse/compile generic methods with "extends"

2019-04-19 Thread Eric Milles (JIRA)


[ 
https://issues.apache.org/jira/browse/GROOVY-9059?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16822054#comment-16822054
 ] 

Eric Milles commented on GROOVY-9059:
-

Just after this, the method generics spec is loaded:
{code}
genericsSpec = GenericsUtils.addMethodGenerics(overridingMethod, genericsSpec);
{code}

This is probably needed to correctly determine covariance.

> Failed to parse/compile generic methods with "extends"
> --
>
> Key: GROOVY-9059
> URL: https://issues.apache.org/jira/browse/GROOVY-9059
> Project: Groovy
>  Issue Type: Bug
>  Components: Static compilation
>Affects Versions: 2.4.16, 3.0.0-alpha-4, 2.5.6
>Reporter: Xiaoguang Wang
>Priority: Major
> Attachments: image-2019-03-30-13-10-20-819.png
>
>
>  
> {code:java}
> import groovy.transform.CompileStatic
> // This bug affects: groovy-2.4.16, groovy-2.5.6, groovy-3.0.0-alpha-4
> // This bug also affect IDEA's syntax parser
> interface X {
> // Intellij IDEA reports that 'public' is not necessary
> // BUT without the 'public' modifier, there is a syntax error
> public  T foo(T o);
> }
> interface Y {
> public  O foo(O o);
> }
> @CompileStatic
> class TestGroovyGeneric {
> static void main(String[] args) {
> def x = new X() {
> // it compiles
> // BUT: Intellij IDEA reports: ERROR: Method 'foo' is not 
> implemented
> @Override
> String foo(String o) { return o }
> }
> // Strangely, such code compiles
> // BUT: Intellij IDEA reports: ERROR: Method 'foo' is not implemented
> def y1 = new Y() {
> @Override
> public  String foo(String o) { return o }
> }
> // Can not compile:
> // BUT: Intellij IDEA reports no error 
> def y2 = new Y() {
> @Override
> String foo(String o) { return o }
> }
> }
> }
> {code}
> !image-2019-03-30-13-10-20-819.png!
>  



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)


[jira] [Commented] (GROOVY-9059) Failed to parse/compile generic methods with "extends"

2019-04-19 Thread Eric Milles (JIRA)


[ 
https://issues.apache.org/jira/browse/GROOVY-9059?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16822042#comment-16822042
 ] 

Eric Milles commented on GROOVY-9059:
-

This last line in {{Verifier.getCovariantImplementation}} fails to identify the 
link between {{String foo(String o)}} in the impl and {{ O foo(O 
o)}} in the interface.  And so, without the covariant method, the abstract 
method errors are produced.

{code:java}
private MethodNode getCovariantImplementation(final MethodNode oldMethod, 
final MethodNode overridingMethod, Map genericsSpec, boolean ignoreError) {
// method name
if (!oldMethod.getName().equals(overridingMethod.getName())) return 
null;
if ((overridingMethod.getModifiers() & ACC_BRIDGE) != 0) return null;
if (oldMethod.isPrivate()) return null;

// parameters
boolean normalEqualParameters = equalParametersNormal(overridingMethod, 
oldMethod);
boolean genericEqualParameters = 
equalParametersWithGenerics(overridingMethod, oldMethod, genericsSpec);
{code}

> Failed to parse/compile generic methods with "extends"
> --
>
> Key: GROOVY-9059
> URL: https://issues.apache.org/jira/browse/GROOVY-9059
> Project: Groovy
>  Issue Type: Bug
>  Components: Static compilation
>Affects Versions: 2.4.16, 3.0.0-alpha-4, 2.5.6
>Reporter: Xiaoguang Wang
>Priority: Major
> Attachments: image-2019-03-30-13-10-20-819.png
>
>
>  
> {code:java}
> import groovy.transform.CompileStatic
> // This bug affects: groovy-2.4.16, groovy-2.5.6, groovy-3.0.0-alpha-4
> // This bug also affect IDEA's syntax parser
> interface X {
> // Intellij IDEA reports that 'public' is not necessary
> // BUT without the 'public' modifier, there is a syntax error
> public  T foo(T o);
> }
> interface Y {
> public  O foo(O o);
> }
> @CompileStatic
> class TestGroovyGeneric {
> static void main(String[] args) {
> def x = new X() {
> // it compiles
> // BUT: Intellij IDEA reports: ERROR: Method 'foo' is not 
> implemented
> @Override
> String foo(String o) { return o }
> }
> // Strangely, such code compiles
> // BUT: Intellij IDEA reports: ERROR: Method 'foo' is not implemented
> def y1 = new Y() {
> @Override
> public  String foo(String o) { return o }
> }
> // Can not compile:
> // BUT: Intellij IDEA reports no error 
> def y2 = new Y() {
> @Override
> String foo(String o) { return o }
> }
> }
> }
> {code}
> !image-2019-03-30-13-10-20-819.png!
>  



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)