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

Eric Milles edited comment on GROOVY-8955 at 5/3/19 5:09 PM:
-------------------------------------------------------------

To allow "def" as a substitute for the "T" type parameter, {{Verifier}} could 
have an addition like this.  -The return type {{testmr}} could be used if the 
AIC specified generics.  So this is just a trial change using 
{{cleanType(omr)}}.-

{code:java}
    private MethodNode getCovariantImplementation(final MethodNode oldMethod, 
final MethodNode overridingMethod, Map genericsSpec, boolean ignoreError) {
        ...
        // return type
        ClassNode mr = overridingMethod.getReturnType();
        ClassNode omr = oldMethod.getReturnType();
        boolean equalReturnType = mr.equals(omr);
        ...
        if (!equalReturnType) {
            boolean oldM = 
ClassHelper.isPrimitiveType(oldMethod.getReturnType());
            boolean newM = 
ClassHelper.isPrimitiveType(overridingMethod.getReturnType());
            if (oldM || newM) {
                String message = "";
                if (oldM && newM) {
                    message = " with old and new method having different 
primitive return types";
                } else if (newM) {
                    message = " with new method having a primitive return type 
and old method not";
                } else /* oldM */ {
                    message = " with old method having a primitive return type 
and new method not";
                }
                throw new RuntimeParserException(
                        "Cannot override method " +
                                oldMethod.getTypeDescriptor() +
                                " in " + 
oldMethod.getDeclaringClass().getName() +
                                message,
                        overridingMethod);
            }
            // GRECLIPSE add -- GROOVY-8955
            if (overridingMethod.isDynamicReturnType() && 
normalEqualParameters) {
                overridingMethod.setReturnType(cleanType(omr));
                return null;
            }
            // GRECLIPSE end
        }
{code}


was (Author: emilles):
To allow "def" as a substitute for the "T" type parameter, {{Verifier}} could 
have an addition like this.  The return type {{testmr}} could be used if the 
AIC specified generics.  So this is just a trial change using 
{{cleanType(omr)}}.

{code:java}
    private MethodNode getCovariantImplementation(final MethodNode oldMethod, 
final MethodNode overridingMethod, Map genericsSpec, boolean ignoreError) {
        ...
        // return type
        ClassNode mr = overridingMethod.getReturnType();
        ClassNode omr = oldMethod.getReturnType();
        boolean equalReturnType = mr.equals(omr);
        ...
        if (!equalReturnType) {
            boolean oldM = 
ClassHelper.isPrimitiveType(oldMethod.getReturnType());
            boolean newM = 
ClassHelper.isPrimitiveType(overridingMethod.getReturnType());
            if (oldM || newM) {
                String message = "";
                if (oldM && newM) {
                    message = " with old and new method having different 
primitive return types";
                } else if (newM) {
                    message = " with new method having a primitive return type 
and old method not";
                } else /* oldM */ {
                    message = " with old method having a primitive return type 
and new method not";
                }
                throw new RuntimeParserException(
                        "Cannot override method " +
                                oldMethod.getTypeDescriptor() +
                                " in " + 
oldMethod.getDeclaringClass().getName() +
                                message,
                        overridingMethod);
            }
            // GRECLIPSE add -- GROOVY-8955
            if (overridingMethod.isDynamicReturnType() && 
normalEqualParameters) {
                overridingMethod.setReturnType(cleanType(omr));
                return null;
            }
            // GRECLIPSE end
        }
{code}

> VerifyError when AIC with @CS can't be detected as not valid
> ------------------------------------------------------------
>
>                 Key: GROOVY-8955
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8955
>             Project: Groovy
>          Issue Type: Bug
>            Reporter: Paul King
>            Priority: Major
>
> In this buggy code the return type of  {{getMappedForm}} method in the AIC 
> should be property. None-the-less, it shouldn't result in a {{VerifyError}}:
> {code}
> import groovy.transform.CompileStatic
> class Property {
>     String generator
> }
> interface PMapping<T extends Property> {
>     T getMappedForm()
> }
> interface PProperty {
>     PMapping getMapping()
> }
> @CompileStatic
> class GPEntity {
>     def method() {
>         PProperty identity = getIdentity()
>         String generatorType = 
> identity.getMapping().getMappedForm().getGenerator()
>     }
>     PProperty getIdentity() {
>         new PProperty() {
>             PMapping getMapping() {
>                 new PMapping() {
>                    def getMappedForm() {
>                        new Property() {
>                            String getGenerator() { 'foo' }
>                        }
>                    }
>                 }
>             }
>         }
>     }
> }
> new GPEntity().method()
> {code}
> The error is:
> {noformat}
> java.lang.VerifyError: Bad return type
> Exception Details:
>   Location:
>     GPEntity$1$2.getMappedForm()LProperty; @4: areturn
>   Reason:
>     Type 'java/lang/Object' (current frame, stack[0]) is not assignable to 
> 'Property' (from method signature)
>   Current Frame:
>     bci: @4
>     flags: { }
>     locals: { 'GPEntity$1$2' }
>     stack: { 'java/lang/Object' }
>   Bytecode:
>     0x0000000: 2ab6 0099 b0                           
>       at GPEntity$1.getMapping(ConsoleScript13:25)
>         ...
> {noformat}
> If the {{PMapping}} method is written without generics, e.g.:
> {code}
> interface PMapping {
>     Property getMappedForm()
> }
> {code}
> Then the error becomes the expected compilation error:
> {noformat}
> The return type of java.lang.Object getMappedForm() in GPEntity$1$2 is 
> incompatible with Property in PMapping
> {noformat}



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

Reply via email to