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

Paul King edited comment on GROOVY-8722 at 8/6/18 10:38 PM:
------------------------------------------------------------

I have added support for final methods but in the most backward compatible way 
possible for now. We could make it stricter (produce compilation errors in some 
cases) for Groovy 3 but I am disinclined to at this point. We could write 
Codenarc rules to detect cases that are considered bad style.

For your example, both {{ActivityOverride}} and {{ActivityInherit}} will have 
{{final}} {{start}} and {{stop}} methods but they are overridden in 
{{ActivityOverride}} and in fact would be non-final if the overridden methods 
weren't final. So basically, existing rules for method selection apply and 
don't look at the final modifier during method selection but after a method is 
selected, if it is final, that will be reflected in the resulting woven 
method's modifiers. You can achieve the affect you are after using a base 
class. The base class can multiply inherit from traits (if needed) and then 
your activity classes would extend from the base class instead of implement the 
traits. The class would look like this:
{code}
abstract class SuspendableBase implements Suspendable {}
{code}
You would find that the override version wouldn't compile - you'd need to not 
override the final methods.


was (Author: paulk):
I have added support for final methods but in the most backward compatible way 
possible for now. We could make it stricter (produce compilation errors in some 
cases) for Groovy 3 but I am disinclined to at this point. We could write 
Codenarc rules to detect cases that are considered bad style.

For your example, both {{ActivityOverride}} and {{ActivityInherit}} will have 
{{final}} {{start}} and {{stop}} methods but they are overridden in 
{{ActivityOverride}} and in fact would be non-final if the overridden methods 
weren't final. So basically, existing rules for method selection apply and 
don't look at the final modifier during method selection but after a method is 
selected, if it is final, that will be reflected in the resulting woven 
method's modifiers. You can achieve the affect you are after using a base 
class. The base class can multiply inherit from traits (if needed) and then 
your application class would extend from the base class instead of implement 
the traits. The class would look like this:
{code}
abstract class SuspendableBase implements Suspendable {}
{code}

> final modifier for non-abstract methods in traits is ignored
> ------------------------------------------------------------
>
>                 Key: GROOVY-8722
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8722
>             Project: Groovy
>          Issue Type: Bug
>          Components: Compiler, Documentation
>    Affects Versions: 2.4.15, 2.5.1
>            Reporter: Dmytro Buryak
>            Assignee: Paul King
>            Priority: Major
>              Labels: breaking, documentation
>             Fix For: 2.5.2
>
>
> When using the {{final}} modifier in a trait non-abstract method signature, 
> then:
>  * compiler successfully compiles trait and class that implements it
>  * final method of trait may be overridden in class that implements trait
>  * if class implements trait and doesn't override trait final method, then 
> this method is available as non-final method in class
>  * documentation says absolutely nothing about this
> In other words, {{final}} modifier is ignored in trait methods: code works 
> the same with or without it. Even if this behavior is expected, there's 
> nothing about it in the documentation.
> Here's simple example gradle groovy project to demonstrate the issue: 
> https://github.com/dburyak/groovy-bug-trait-final



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

Reply via email to