[
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)