GradleKotlinConverter icon indicating copy to clipboard operation
GradleKotlinConverter copied to clipboard

ApplicationVariants.all conversion

Open AlexHuicu opened this issue 6 years ago • 5 comments

In groovy we have applicationVariants.all { variant -> //do stuff }

but, when converting to kotlin, the same block of code changes it's functionality: applicationVariants.all { variant -> //do stuff }

This is due the fact that in groovy the closure given as a parameter to .all method can rename it's receiver (in this case it's renamed to variant). BUT the same block code in kotlin is not a closure anymore, it becomes a lambda. The ".all" method called now is the one in the Iterable interface. (before it was calling the .all inside DomainObjectSet<> interface)

The real kotlin correspondent is: applicationVariants.all { val variant = this //do stuff }.

I do not expect your converter to go so deep into the conversion, but please add this information to this wiki as it is very tricky to observe it

AlexHuicu avatar Apr 07 '20 14:04 AlexHuicu

Further more:

applicationVariants.all {
          val variant = this
          variant.outputs.all { output ->
              //Do something with the output
         }
}

should be converted to

applicationVariants.all {
        val variant = this

        variant.outputs.all { 
              val output = this
              //Do something with the output
         }
}

To improve it further: val output = this should be changed to val output = this as ApkVariantOutputImpl Groovy has loose typing and output is automatically casted to it's actual type, but kotlin will see "option" as a BaseVariantOutput, which is not very usefull.

AlexHuicu avatar Apr 07 '20 15:04 AlexHuicu

Oh ohhh.. Makes sense. I can add a comment before it like // HEY THIS IS BROKEN or just add what you suggested, but I'm not sure how it would work in more complex scenarios. Do you have a few examples? It doesn't look too complex to implement.

bernaferrari avatar Apr 07 '20 15:04 bernaferrari

applicationVariants.all {
        val variant = this
        var flavor = variant.mergedFlavor
        var name = flavor.versionName
        var code =  getCustomCodeNumber()
        variant.outputs.all {
            this as ApkVariantOutputImpl
            versionNameOverride = name
            versionCodeOverride = code
            outputFileName =getOutputFileName(flavor,name,code)
        }
    }

AlexHuicu avatar Apr 07 '20 15:04 AlexHuicu

This is the usage of the code I wrote above

AlexHuicu avatar Apr 07 '20 15:04 AlexHuicu

Something like: "Check if the correct .all method is called. Does it belongs to DomainObjectSet interface? If not, please remove the named argument inside the closure," - and here maybe an url to the wiki where this problem is stated.

AlexHuicu avatar Apr 07 '20 15:04 AlexHuicu