Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Kotlin 1.4.10 to leverage Kotlin SAM #1948

Merged
merged 4 commits into from
Dec 2, 2020
Merged

Conversation

chao2zhang
Copy link
Contributor

So that we do not need to declare a companion object implementing invoke operator

@pyricau
Copy link
Member

pyricau commented Sep 26, 2020

Thanks!

Can we do this in a way that keeps the define maven dependency as Kotlin 1.3 so that consumers don't have to upgrade?

cc @zach-klippenstein who did this recently for Radiography.

@chao2zhang
Copy link
Contributor Author

Good call. I do see the use case that we do not want library changes to be breaking for clients.

I am not familiar with maven publishing/dependency topics (My company used Ivy). If there are some examples that I could learn from that would be great. Otherwise, I can spend some time figuring it out.

@pyricau
Copy link
Member

pyricau commented Sep 26, 2020

We've talked about it in this slack thread

See radiography: square/radiography#50

@chao2zhang
Copy link
Contributor Author

chao2zhang commented Sep 28, 2020

There are still some limitations but I have verified that clients can keep Kotlin 1.3.72: Build scan

There is one caveat: If clients choose to keep Kotlin 1.3.72, they cannot leverage the invoke() overriding hack and have to declare an object as follows:

       object : OnHeapAnalyzedListener {
            override fun onHeapAnalyzed(heapAnalysis: HeapAnalysis) {
                TODO("Not yet implemented")
            }
        })

If they have 1.4 Kotlin IDE plugin installed, while on their build script still point to Kotlin 1.3, the IDE prompt to convert to lambda constructor would break their build.

Copy link
Collaborator

@zach-klippenstein zach-klippenstein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you'll also want to tell the compiler you're intentionally using an older stdlib version, so it doesn't complain. See https://github.com/square/radiography/pull/50/files#diff-392475fdf2bc320d17762ed97109a121R77

@chao2zhang
Copy link
Contributor Author

I do find warnings from the console like
w: Runtime JAR files in the classpath have the version 1.3, which is older than the API version 1.4. Consider using the runtime of version 1.4, or pass '-api-version 1.3' explicitly to restrict the available APIs to the runtime of version 1.3. You can also pass '-language-version 1.3' instead, which will restrict not only the APIs to the specified version, but also the language features

Looks like we want to address those warnings.

@pyricau
Copy link
Member

pyricau commented Sep 29, 2020

So that we do not need to declare a companion object implementing invoke operator

Question about that: what happens to existing code that was previously using that pattern? This is probably not binary compatible which is ok (LeakCanary is typically recompiled by consumers) but is it source compatible? ie if I drop in the new version of LeakCanary and recompile, will it work?

edit: it looks like yes?

edit2: unless they're using kotlin 1.3, I guess? In that case the API is now gone.

@chao2zhang
Copy link
Contributor Author

chao2zhang commented Sep 29, 2020

If the client was using the syntax with LeakCanary 2.24:

        LeakCanary.config = LeakCanary.config.copy(onHeapAnalyzedListener = OnHeapAnalyzedListener {
                TODO("Not yet implemented")
        })

They need to update it to the following if using 1.3

        LeakCanary.config = LeakCanary.config.copy(onHeapAnalyzedListener = object : OnHeapAnalyzedListener {
            override fun onHeapAnalyzed(heapAnalysis: HeapAnalysis) {
                TODO("Not yet implemented")
            }
        })

If they update it to 1.4, the source code could remain unchanged.

@pyricau
Copy link
Member

pyricau commented Sep 29, 2020

Thx!

Yeah it looks like there's no other way around, unless we create whole new separate interfaces and deprecate the old ones, which wouldn't be great either.

@pyricau
Copy link
Member

pyricau commented Sep 30, 2020

@chao2zhang I think we should probably keep the companion object invoke operators for backward compatibility with Kotlin 1.3 users. That being said, I'm also excited about updating to 1.4. Do you think you could update the PR to bring the companion object invoke operators back?

Thanks!

@chao2zhang
Copy link
Contributor Author

Definitely, but I would still propose to mark it as deprecated as this is a hacky workaround before Kotlin support SAM.

@pyricau
Copy link
Member

pyricau commented Oct 1, 2020

Can we have both "fun" and the companion object? Does one rake precedence?

@chao2zhang
Copy link
Contributor Author

We can. I verified it in a separate project depending on leak canary. It can compile successfully when in Kotlin 1.3 using the invoke hack. It also compiles successfully in Kotlin 1.4.

@pyricau pyricau merged commit f9de5e4 into square:main Dec 2, 2020
@pyricau
Copy link
Member

pyricau commented Dec 2, 2020

Thanks! Sorry it took so long to merge :)

@Goooler Goooler mentioned this pull request Dec 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants