From dev-return-5257-archive-asf-public=cust-asf.ponee.io@groovy.apache.org Mon Aug 20 03:28:39 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id 74F27180656 for ; Mon, 20 Aug 2018 03:28:38 +0200 (CEST) Received: (qmail 5342 invoked by uid 500); 20 Aug 2018 01:28:37 -0000 Mailing-List: contact dev-help@groovy.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@groovy.apache.org Delivered-To: mailing list dev@groovy.apache.org Received: (qmail 5332 invoked by uid 99); 20 Aug 2018 01:28:36 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 20 Aug 2018 01:28:36 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id 6FE041A04B1 for ; Mon, 20 Aug 2018 01:28:36 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 1.989 X-Spam-Level: * X-Spam-Status: No, score=1.989 tagged_above=-999 required=6.31 tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, HTML_MESSAGE=2, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, T_DKIMWL_WL_MED=-0.01] autolearn=disabled Authentication-Results: spamd2-us-west.apache.org (amavisd-new); dkim=pass (2048-bit key) header.d=asert-com-au.20150623.gappssmtp.com Received: from mx1-lw-us.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id 9P352qNrWnNl for ; Mon, 20 Aug 2018 01:28:33 +0000 (UTC) Received: from mail-oi0-f48.google.com (mail-oi0-f48.google.com [209.85.218.48]) by mx1-lw-us.apache.org (ASF Mail Server at mx1-lw-us.apache.org) with ESMTPS id 05E245F2F0 for ; Mon, 20 Aug 2018 01:28:32 +0000 (UTC) Received: by mail-oi0-f48.google.com with SMTP id b15-v6so23031794oib.10 for ; Sun, 19 Aug 2018 18:28:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=asert-com-au.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:reply-to:from:date:message-id :subject:to; bh=pWxe+ioqvGrt53dUJy9YMvOPyL1SpA02FsPK7Ga+vt0=; b=ADSds32WqLnxWaCqobpFqQmZcqNIO1XkFnAd9ETeQc9TURe/E661Fs8gu/ekWNqBLm o3rKDV4VU4SwpQLyQ7NajS1x+sVxe3lTJqGNUY8JjsECXqLJO7EkTYbLUxMz8dqOdblr BHZxyhUZhv7errFRngcxDhnN3T1I/CS1Zd1L/TZsCZqGBSrzEWrzm/qYhg1PBNIpQlVQ xn211jEgIi6ALZ5SDKesYU8KNySrT0Uny/bky8Xl2kylq6AoOWq4B9fi++UBSB9XWLWZ mHEH9aFYq5OfG2Q6s4ZBv2W9dS5aXDTwUGXSlHilhiZy/sxpHdxynwVjDctwc2ODEFPi aQKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:reply-to :from:date:message-id:subject:to; bh=pWxe+ioqvGrt53dUJy9YMvOPyL1SpA02FsPK7Ga+vt0=; b=Chc1e1Wz2Dkampg1N+qHAQ2pMymCJcIe5Sm3BAckCMwDmw4Qym1YUZ2x62yy1OwG+M bxdoZotI2LL/A8VPp4gm6ubJwtgctDRtkS6QBmoBAaNZTYwj0tBGb73OBnhADnDxGfwo jq3PjN1CQLdyp+N/7jlsON2ANbjXakOf6wx21dLF4xO8le8juRtLa5VvpF9OSXPLFZaD gimQgdvFcpbn3HkO/3EMqc9jasErNQTN8b4mDybvvuBNVNK9RY8grdDonisVt6CprzQr nkzvg5zYWsgMYdufBkl01uJv75YtZMG9VWBpIKNxBpjn1mKMGTlZm0tOA/5iPoFtTc83 cnDQ== X-Gm-Message-State: AOUpUlGev4TDp4e+tWAxd4sa0mIZ7zJzaKEtVNSXMacGgh8VmG5UvNH2 JIqYdk24RI9MSA6CqxwRvSze3CEQ9rj6eP+FYVZaUs1/ X-Google-Smtp-Source: AA+uWPz0OHl1Azt91fum5KKTKO2Zax3ZWi3tyWHPqF6iWWr7VOObeqdIqL/cIklpD7xY2JDh+xrSMHEboXkJ7AHaWr0= X-Received: by 2002:aca:5489:: with SMTP id i131-v6mr12557510oib.340.1534728506393; Sun, 19 Aug 2018 18:28:26 -0700 (PDT) MIME-Version: 1.0 References: <2523764A-538C-4FAD-8C92-27E25C185E64@gmail.com> In-Reply-To: <2523764A-538C-4FAD-8C92-27E25C185E64@gmail.com> Reply-To: paulk@asert.com.au From: Paul King Date: Mon, 20 Aug 2018 11:28:15 +1000 Message-ID: Subject: Re: Updates on JaCoCo support To: dev@groovy.apache.org Content-Type: multipart/alternative; boundary="0000000000007362d70573d3d3c9" --0000000000007362d70573d3d3c9 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable I'm +1 for adding whatever we need to make coverage work. Having said that, we shouldn't need to add it for methods (classes?) already marked synthetic. I also noticed that the kotlin support looks for a lack of line number information. Could we do something similar? We leave line number info as -1 in many cases and could do that check just for classes implementing GroovyObject. Or was this approach ruled out earlier? The line number approach is more of a hack I guess but we could leave that as the fall back. That could enable things to almost totally work now and we can improve incrementally by adding synthetic or @Generated in more places over time. Thoughts? Paul. On Thu, Aug 16, 2018 at 6:53 AM Andres Almiray wrote: > There=E2=80=99s a difference between synthetic and having the @Generated > annotation, they are not equivalent. Synthetic signals tools to ignore th= e > method altogether (JaCoCo honors this behavior). @Generated should be > applied to non-synthetic methods/classes; what a particular tool decides = to > do with that information is up to the tool itself, in the case of JaCoCo > it=E2=80=99ll skip the method/class from coverage. > > The reason I raises this issue is to see if there are any objections in > adding @Generated to most (if not all) compiler generated methods (proper= ty > getter/setter, core AST xforms) as this change touches lots of files, > however it has no impact of Groovy behavior, rather it impacts tools that > may parse Groovy bytecode (like JaCoCo). > > Cheers > Andres (with no extra a) > > Sent from my primitive Tricorder > > On 15 Aug 2018, at 22:43, Milles, Eric (TR Technology & Ops) < > eric.milles@thomsonreuters.com> wrote: > > Andreas, > > > One place to start is everywhere that "AnnotatedNode.setSynthetic(true)" > is currently called. I think this misses the methods added for a > property. But it does cover several AST transforms. And maybe the > transforms that add methods and don't call this method could do so in > addition to the modification to add "@Generated". Maybe the call to > setSynthetic could actually add the annotation. Or you could create a > utility method that sets synthetic and adds "@Generated". > > > ------------------------------ > *From:* Andres Almiray > *Sent:* Tuesday, August 14, 2018 3:42 PM > *To:* dev@groovy.apache.org > *Subject:* Updates on JaCoCo support > > Hello everyone, > > I've spent a couple of hours with JaCoCo team members at the Hackergarten > Bern this evening. > The goal of the session was to get started with an integration test for > the @Generated feature > added in Groovy 2.5.0. > > You can see the outcome at https://github.com/jacoco/jacoco/pull/733 > > > The good news is that Groovy applies @Generated on constructors added by > @Cannonical as well > as methods defined by the GroovyObject interface. The bad news is that th= e > test still fails > because the expectation is that *every* method generated by the compiler > that does not map > to a particular source line *should* be annotated with @Generated. The > following source > > ---- > // This annotation generates the following > // - a constructor that takes an int as argument > // - a suitable implementation of toString() > // - a suitable implementation of hashCode() > // - a suitable implementation of equals(Object) > // - a public method named canEqual(Object) > // - a getter & setter for the valRead property > @groovy.transform.Canonical > class GroovyDataClassTarget { // assertFullyCovered() > > int valRead // assertNotCovered() > > static void main(String[] args) { > new GroovyDataClassTarget() // assertFullyCovered() > } > } > ---- > > Generates bytecode equivalent to (decompiled with IntelliJ) > > ---- > // > // Source code recreated from a .class file by IntelliJ IDEA > // (powered by Fernflower decompiler) > // > > package org.jacoco.core.test.validation.groovy.targets; > > import groovy.lang.GroovyObject; > import groovy.lang.MetaClass; > import groovy.transform.EqualsAndHashCode; > import groovy.transform.Generated; > import groovy.transform.ToString; > import org.codehaus.groovy.runtime.InvokerHelper; > import org.codehaus.groovy.runtime.ScriptBytecodeAdapter; > import org.codehaus.groovy.runtime.callsite.CallSite; > import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation= ; > import org.codehaus.groovy.runtime.typehandling.ShortTypeHandling; > import org.codehaus.groovy.util.HashCodeHelper; > > @ToString > @EqualsAndHashCode > public class GroovyDataClassTarget implements GroovyObject { > private int valRead; > > @Generated > public GroovyDataClassTarget(int valRead) { > CallSite[] var2 =3D $getCallSiteArray(); > super(); > MetaClass var3 =3D this.$getStaticMetaClass(); > this.metaClass =3D var3; > this.valRead =3D DefaultTypeTransformation.intUnbox(valRead); > } > > public GroovyDataClassTarget() { > CallSite[] var1 =3D $getCallSiteArray(); > this(Integer.valueOf(0)); > } > > public static void main(String... args) { > CallSite[] var1 =3D $getCallSiteArray(); > var1[0].callConstructor(GroovyDataClassTarget.class); > } > > public String toString() { > CallSite[] var1 =3D $getCallSiteArray(); > Object _result =3D var1[1].callConstructor(StringBuilder.class); > Object $toStringFirst =3D Boolean.TRUE; > var1[2].call(_result, > "org.jacoco.core.test.validation.groovy.targets.GroovyDataClassTarget("); > if (DefaultTypeTransformation.booleanUnbox($toStringFirst)) { > Boolean var4 =3D Boolean.FALSE; > } else { > var1[3].call(_result, ", "); > } > > var1[4].call(_result, var1[5].callStatic(InvokerHelper.class, > var1[6].callCurrent(this))); > var1[7].call(_result, ")"); > return > (String)ShortTypeHandling.castToString(var1[8].call(_result)); > } > > public int hashCode() { > CallSite[] var1 =3D $getCallSiteArray(); > Object _result =3D var1[9].callStatic(HashCodeHelper.class); > if > (!DefaultTypeTransformation.booleanUnbox(var1[10].call(var1[11].callCurre= nt(this), > this))) { > Object var3 =3D var1[12].callStatic(HashCodeHelper.class, > _result, var1[13].callCurrent(this)); > _result =3D var3; > } > > return DefaultTypeTransformation.intUnbox(_result); > } > > public boolean canEqual(Object other) { > CallSite[] var2 =3D $getCallSiteArray(); > return other instanceof GroovyDataClassTarget; > } > > public boolean equals(Object other) { > CallSite[] var2 =3D $getCallSiteArray(); > if (ScriptBytecodeAdapter.compareEqual(other, (Object)null)) { > return false; > } else if > (DefaultTypeTransformation.booleanUnbox(var2[14].callCurrent(this, other)= )) > { > return true; > } else if (!(other instanceof GroovyDataClassTarget)) { > return false; > } else { > GroovyDataClassTarget otherTyped =3D > (GroovyDataClassTarget)other; > if > (!DefaultTypeTransformation.booleanUnbox(var2[15].call(otherTyped, this))= ) { > return false; > } else { > return > ScriptBytecodeAdapter.compareEqual(var2[16].callCurrent(this), > var2[17].call(otherTyped)); > } > } > } > > public int getValRead() { > return this.valRead; > } > > public void setValRead(int var1) { > this.valRead =3D var1; > } > } > ---- > > We can appreciate that the methods added by @ToString, @EqualsAndHashcode= , > and the property getter/setter are not > annotated with @Generated, which will prompt JaCoCo to mark them as not > covered. The rationale from the JaCoCo team > is that these methods should be annotated as the compiler is "trusted", > only those methods explicitly added to the > source should be covered. > > Thus, here comes the call to action and the reason why I wanted to start > this conversation in the first place: > - modify the Groovy compiler to add @Generated on property getters and > setters. > - modify core AST xforms to add @Generated where it makes sense. > > Related to the original @Generated issue (as commented by Evgeny at > https://github.com/jacoco/jacoco/pull/610 > = ) > fields > do not have line numbers, would be good to have them. > > What do you think? > > Cheers, > Andres > > ------------------------------------------- > Java Champion; Groovy Enthusiast > JCP EC Associate Seat > http://andresalmiray.com > > http://www.linkedin.com/in/aalmiray > > -- > What goes up, must come down. Ask any system administrator. > There are 10 types of people in the world: Those who understand binary, > and those who don't. > To understand recursion, we must first understand recursion. > > --0000000000007362d70573d3d3c9 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
I'm=C2=A0+1 for adding whatever we need to make covera= ge work.

Having said that, we shouldn't need to add = it for methods (classes?) already marked synthetic. I also noticed that the= kotlin support looks for a lack of line number information. Could we do so= mething similar? We leave line number info as -1 in many cases and could do= that check just for classes implementing GroovyObject. Or was this approac= h ruled out earlier? The line number approach is more of a hack I guess but= we could leave that as the fall back. That could enable things to almost t= otally work now and we can improve incrementally by adding synthetic or=C2= =A0@Generated in more places over time.

Thoughts?
<= div>
Paul.


On Thu, Aug 16, 2018 at 6:53 AM Andres Almira= y <aalmiray@gmail.com> wrot= e:
There=E2=80=99= s a difference between synthetic and having the @Generated annotation, they= are not equivalent. Synthetic signals tools to ignore the method altogethe= r (JaCoCo honors this behavior). @Generated should be applied to non-synthe= tic methods/classes; what a particular tool decides to do with that informa= tion is up to the tool itself, in the case of JaCoCo it=E2=80=99ll skip the= method/class from coverage.=C2=A0

The reason I raises t= his issue is to see if there are any objections in adding @Generated to mos= t (if not all) compiler generated methods (property getter/setter, core AST= xforms) as this change touches lots of files, however it has no impact of = Groovy behavior, rather it impacts tools that may parse Groovy bytecode (li= ke JaCoCo).=C2=A0

Cheers
Andres (with no= extra a)

Sent fr= om my primitive Tricorder

On 15 Aug 2018, at 22:43, Milles, E= ric (TR Technology & Ops) <eric.milles@thomsonreuters.com> wrote:

Andreas,


One place to start is everywhere = that "AnnotatedNode.setSynthetic(true)" is currently called.=C2= =A0 I think this misses the methods added for a property.=C2=A0 But it does= cover several AST transforms.=C2=A0 And maybe the transforms that add methods and don't call this method could do so in addition to= the modification to add "@Generated".=C2=A0 Maybe the call to se= tSynthetic could actually add the annotation.=C2=A0 Or you could create a u= tility method that sets synthetic and adds "@Generated".



From: A= ndres Almiray <a= almiray@gmail.com>
Sent: Tuesday, August 14, 2018 3:42 PM
To: dev@g= roovy.apache.org
Subject: Updates on JaCoCo support
=C2=A0
Hello everyone,

I've spent a couple of hours with JaCoCo team members at the Hackergart= en Bern this evening.
The goal of the session was to get started with an integration test for the= @Generated feature
added in Groovy 2.5.0.

You can see the outcome at https://github.com/jacoco/jacoco/pull/733

The good news is that Groovy applies @Generated on constructors added by @C= annonical as well
as methods defined by the GroovyObject interface. The bad news is that the = test still fails
because the expectation is that *every* method generated by the compiler th= at does not map
to a particular source line *should* be annotated with @Generated. The foll= owing source

----
// This annotation generates the following
// - a constructor that takes an int as argument
// - a suitable implementation of toString()
// - a suitable implementation of hashCode()
// - a suitable implementation of equals(Object)
// - a public method named canEqual(Object)
// - a getter & setter for the valRead property
@groovy.transform.Canonical
class GroovyDataClassTarget { // assertFullyCovered()

=C2=A0=C2=A0=C2=A0 int valRead // assertNotCovered()

=C2=A0=C2=A0=C2=A0 static void main(String[] args) {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 new GroovyDataClassTarget() // a= ssertFullyCovered()
=C2=A0=C2=A0=C2=A0 }
}
----

Generates bytecode equivalent to (decompiled with IntelliJ)

----
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.jacoco.core.test.validation.groovy.targets;

import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import groovy.transform.EqualsAndHashCode;
import groovy.transform.Generated;
import groovy.transform.ToString;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
import org.codehaus.groovy.runtime.callsite.CallSite;
import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;<= br> import org.codehaus.groovy.runtime.typehandling.ShortTypeHandling;
import org.codehaus.groovy.util.HashCodeHelper;

@ToString
@EqualsAndHashCode
public class GroovyDataClassTarget implements GroovyObject {
=C2=A0=C2=A0=C2=A0 private int valRead;

=C2=A0=C2=A0=C2=A0 @Generated
=C2=A0=C2=A0=C2=A0 public GroovyDataClassTarget(int valRead) {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 CallSite[] var2 =3D $getCallSite= Array();
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 super();
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 MetaClass var3 =3D this.$getStat= icMetaClass();
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 this.metaClass =3D var3;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 this.valRead =3D DefaultTypeTran= sformation.intUnbox(valRead);
=C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 public GroovyDataClassTarget() {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 CallSite[] var1 =3D $getCallSite= Array();
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 this(Integer.valueOf(0));
=C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 public static void main(String... args) {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 CallSite[] var1 =3D $getCallSite= Array();
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 var1[0].callConstructor(GroovyDa= taClassTarget.class);
=C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 public String toString() {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 CallSite[] var1 =3D $getCallSite= Array();
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Object _result =3D var1[1].callC= onstructor(StringBuilder.class);
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Object $toStringFirst =3D Boolea= n.TRUE;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 var1[2].call(_result, "org.= jacoco.core.test.validation.groovy.targets.GroovyDataClassTarget("); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (DefaultTypeTransformation.bo= oleanUnbox($toStringFirst)) {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Boolean = var4 =3D Boolean.FALSE;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } else {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 var1[3].= call(_result, ", ");
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 var1[4].call(_result, var1[5].ca= llStatic(InvokerHelper.class, var1[6].callCurrent(this)));
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 var1[7].call(_result, ")&qu= ot;);
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return (String)ShortTypeHandling= .castToString(var1[8].call(_result));
=C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 public int hashCode() {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 CallSite[] var1 =3D $getCallSite= Array();
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Object _result =3D var1[9].callS= tatic(HashCodeHelper.class);
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (!DefaultTypeTransformation.b= ooleanUnbox(var1[10].call(var1[11].callCurrent(this), this))) {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Object v= ar3 =3D var1[12].callStatic(HashCodeHelper.class, _result, var1[13].callCur= rent(this));
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 _result = =3D var3;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return DefaultTypeTransformation= .intUnbox(_result);
=C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 public boolean canEqual(Object other) {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 CallSite[] var2 =3D $getCallSite= Array();
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return other instanceof GroovyDa= taClassTarget;
=C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 public boolean equals(Object other) {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 CallSite[] var2 =3D $getCallSite= Array();
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (ScriptBytecodeAdapter.compar= eEqual(other, (Object)null)) {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return f= alse;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } else if (DefaultTypeTransforma= tion.booleanUnbox(var2[14].callCurrent(this, other))) {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return t= rue;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } else if (!(other instanceof Gr= oovyDataClassTarget)) {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return f= alse;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } else {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 GroovyDa= taClassTarget otherTyped =3D (GroovyDataClassTarget)other;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (!Def= aultTypeTransformation.booleanUnbox(var2[15].call(otherTyped, this))) {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 return false;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } else {=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 return ScriptBytecodeAdapter.compareEqual(var2[16].callCurr= ent(this), var2[17].call(otherTyped));
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 public int getValRead() {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return this.valRead;
=C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 public void setValRead(int var1) {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 this.valRead =3D var1;
=C2=A0=C2=A0=C2=A0 }
}
----

We can appreciate that the methods added by @ToString, @EqualsAndHashcode, = and the property getter/setter are not
annotated with @Generated, which will prompt JaCoCo to mark them as not cov= ered. The rationale from the JaCoCo team
is that these methods should be annotated as the compiler is "trusted&= quot;, only those methods explicitly added to the
source should be covered.

Thus, here comes the call to action and the reason why I wanted to start th= is conversation in the first place:
=C2=A0- modify the Groovy compiler to add @Generated on property getters an= d setters.
=C2=A0- modify core AST xforms to add @Generated where it makes sense.

Related to the original @Generated issue (as commented by Evgeny at https://github.com/jacoco/jacoco/pull/610) fields
do not have line numbers, would be good to have them.

What do you think?

Cheers,
Andres

-------------------------------------------
Java Champion; Groovy Enthusiast
JCP EC Associate Seat
http://andresalmiray.com
http://www.linkedin.com/= in/aalmiray
--
What goes up, must come down. Ask any system administrator.
There are 10 types of people in the world: Those who understand binary, and= those who don't.
To understand recursion, we must first understand recursion.
--0000000000007362d70573d3d3c9--