-
Notifications
You must be signed in to change notification settings - Fork 213
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
Improve jdeps logic to find more explicit and implicit dependencies #1118
Improve jdeps logic to find more explicit and implicit dependencies #1118
Conversation
…ncies (bazelbuild#17) # Problem Kotlin jdeps do not collect many direct and indirect dependencies that are required for compilation. These missing jdep found dependencies were discovered as Airbnb tests a "jdeps compile-time pruning" optimization which provides significant IntelliJ indexing, UI, and compilation performance benefits in our fork of the [Bazel IntelliJ Plugin](https://github.com/bazelbuild/intellij). # Solution As a followup to bazelbuild#1045, write test cases to repro missing dependencies found in Airbnb's monorepo, and then fix the underlying issues. In addition to these fixes helping our "jdeps compile-time pruning" optimization, these fixes should also help when the normal Bazel IntelliJ Plugin is used, as it also consults jdeps when deciding what jars to import into IntelliJ. # Test Plan: * Wrote Kotlin and Java test cases to repro missing dependencies found in the Airbnb monorepo * Updated Airbnb's minimal rules_kotlin fork to use the changes in this PR, which has been successfully running CI for over a week.
@@ -46,6 +46,7 @@ class KotlinBuilderJvmJdepsTest(private val enableK2Compiler: Boolean) { | |||
val ctx = KotlinJvmTestBuilder() | |||
|
|||
val TEST_FIXTURES_DEP = Dep.fromLabel(":JdepsParserTestFixtures") | |||
val TEST_FIXTURES2_DEP = Dep.fromLabel(":JdepsParserTestFixtures2") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To enable test cases where Java deps depend on other Java deps I added a second set of java test fixtures here
@@ -1385,7 +1621,7 @@ class KotlinBuilderJvmJdepsTest(private val enableK2Compiler: Boolean) { | |||
|
|||
assertExplicit(jdeps).contains(depWithFunction.singleCompileJar()) | |||
assertImplicit(jdeps).contains(depWithReturnType.singleCompileJar()) | |||
assertImplicit(jdeps).doesNotContain(depWithReturnTypesSuperType) | |||
assertImplicit(jdeps).contains(depWithReturnTypesSuperType.singleCompileJar()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the prior assertion always succeeded as it was missing .singleCompileJar()
When .singleCompileJar() is correctly added, the assertion fails.
We can confirm that depWithReturnTypesSuperType is needed for compilation by commenting out:
c.addTransitiveDependencies(depWithReturnTypesSuperType)
and then seeing the compilation fail with:
error: supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath:
class something.SomeType, unresolved supertypes: something.SomeSuperType
Because the super type is actually needed, we've changed the assertion to assert that it is an implicit dep.
@@ -1659,7 +1896,34 @@ class KotlinBuilderJvmJdepsTest(private val enableK2Compiler: Boolean) { | |||
|
|||
assertExplicit(jdeps).containsAtLeast(depWithFunction.singleCompileJar(), depWithReturnType.singleCompileJar()) | |||
assertImplicit(jdeps).doesNotContain(depWithReturnType.singleCompileJar()) | |||
assertImplicit(jdeps).doesNotContain(depWithReturnTypesSuperType) | |||
assertImplicit(jdeps).contains(depWithReturnTypesSuperType.singleCompileJar()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the prior assertion always succeeded as it was missing .singleCompileJar()
When .singleCompileJar() is correctly added, the assertion fails.
We can confirm that depWithReturnTypesSuperType is needed by commenting out:
c.addTransitiveDependencies(depWithReturnTypesSuperType)
and then seeing the compilation fail with:
error: supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath:
class something.SomeType, unresolved supertypes: something.SomeSuperType
Because the super type is actually needed, we've changed the assertion to assert that it is an implicit dep.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a PR up that does full Deps
diffing which should hopefully avoid issues like this where assertions aren't being correctly done.
https://github.com/bazelbuild/rules_kotlin/pull/1116/files
) | ||
} | ||
|
||
println("=====================================") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to check this in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for flagging. Removed.
java_library( | ||
name = "JdepsParserTestFixtures2", | ||
testonly = True, | ||
srcs = glob(["testFixtures2/*.java"]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might look less copy-paste grouping these different test figures inside directories within the testFixtures
directory instead of just duplicating and adding a numerical index. Ex: testFixtures/a-sources/
testFixtures/b-sources/
@scosenza are you able to rebase this branch and resolve the conflicts + organize the test fixtures? |
FYI, it looks like |
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor | ||
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor | ||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor | ||
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor | ||
import org.jetbrains.kotlin.js.translate.callTranslator.getReturnType |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the right function to be using? It looks like it's being loaded from the javascript package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I briefly looked around and didn't see anything that stands out. If anything you can just inline the function itself, which is just calling into another function with resolvedCall
as an argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for flagging this.
…azelbuild#1118) * Improve Kotlin jdeps logic to find more explicit and implicit dependencies (bazelbuild#17) # Problem Kotlin jdeps do not collect many direct and indirect dependencies that are required for compilation. These missing jdep found dependencies were discovered as Airbnb tests a "jdeps compile-time pruning" optimization which provides significant IntelliJ indexing, UI, and compilation performance benefits in our fork of the [Bazel IntelliJ Plugin](https://github.com/bazelbuild/intellij). # Solution As a followup to bazelbuild#1045, write test cases to repro missing dependencies found in Airbnb's monorepo, and then fix the underlying issues. In addition to these fixes helping our "jdeps compile-time pruning" optimization, these fixes should also help when the normal Bazel IntelliJ Plugin is used, as it also consults jdeps when deciding what jars to import into IntelliJ. # Test Plan: * Wrote Kotlin and Java test cases to repro missing dependencies found in the Airbnb monorepo * Updated Airbnb's minimal rules_kotlin fork to use the changes in this PR, which has been successfully running CI for over a week. * formatting * formatting * revert * Remove println used for testing * use new assertion style in jdeps test * add newline to trigger another build * Remove class in "js" package, that shouldn't be used and also is no longer needed. * Remove class in "js" package, that shouldn't be used and also is no longer needed. --------- Co-authored-by: Steve Cosenza <steve.cosenza@airbnb.com>
@scosenza the uses of the jdeps pruning sound really exciting. Any chance that people outside of airbnb could use a similar setup or does it all depend on your bazel intellij plugin fork? |
…azelbuild#1118) * Improve Kotlin jdeps logic to find more explicit and implicit dependencies (bazelbuild#17) # Problem Kotlin jdeps do not collect many direct and indirect dependencies that are required for compilation. These missing jdep found dependencies were discovered as Airbnb tests a "jdeps compile-time pruning" optimization which provides significant IntelliJ indexing, UI, and compilation performance benefits in our fork of the [Bazel IntelliJ Plugin](https://github.com/bazelbuild/intellij). # Solution As a followup to bazelbuild#1045, write test cases to repro missing dependencies found in Airbnb's monorepo, and then fix the underlying issues. In addition to these fixes helping our "jdeps compile-time pruning" optimization, these fixes should also help when the normal Bazel IntelliJ Plugin is used, as it also consults jdeps when deciding what jars to import into IntelliJ. # Test Plan: * Wrote Kotlin and Java test cases to repro missing dependencies found in the Airbnb monorepo * Updated Airbnb's minimal rules_kotlin fork to use the changes in this PR, which has been successfully running CI for over a week. * formatting * formatting * revert * Remove println used for testing * use new assertion style in jdeps test * add newline to trigger another build * Remove class in "js" package, that shouldn't be used and also is no longer needed. * Remove class in "js" package, that shouldn't be used and also is no longer needed. --------- Co-authored-by: Steve Cosenza <steve.cosenza@airbnb.com>
…azelbuild#1118) * Improve Kotlin jdeps logic to find more explicit and implicit dependencies (bazelbuild#17) # Problem Kotlin jdeps do not collect many direct and indirect dependencies that are required for compilation. These missing jdep found dependencies were discovered as Airbnb tests a "jdeps compile-time pruning" optimization which provides significant IntelliJ indexing, UI, and compilation performance benefits in our fork of the [Bazel IntelliJ Plugin](https://github.com/bazelbuild/intellij). # Solution As a followup to bazelbuild#1045, write test cases to repro missing dependencies found in Airbnb's monorepo, and then fix the underlying issues. In addition to these fixes helping our "jdeps compile-time pruning" optimization, these fixes should also help when the normal Bazel IntelliJ Plugin is used, as it also consults jdeps when deciding what jars to import into IntelliJ. # Test Plan: * Wrote Kotlin and Java test cases to repro missing dependencies found in the Airbnb monorepo * Updated Airbnb's minimal rules_kotlin fork to use the changes in this PR, which has been successfully running CI for over a week. * formatting * formatting * revert * Remove println used for testing * use new assertion style in jdeps test * add newline to trigger another build * Remove class in "js" package, that shouldn't be used and also is no longer needed. * Remove class in "js" package, that shouldn't be used and also is no longer needed. --------- Co-authored-by: Steve Cosenza <steve.cosenza@airbnb.com>
Problem
Kotlin jdeps do not collect many direct and indirect dependencies that are required for compilation. These missing jdep found dependencies were discovered as Airbnb tests a "jdeps compile-time pruning" optimization which provides significant IntelliJ indexing, UI, and compilation performance benefits in our fork of the Bazel IntelliJ Plugin. See also #1115 as @Bencodes and I unknowingly started looking at this issue at about the same time!
Solution
As a followup to #1045, write test cases to repro missing deps found when compiling Airbnb's JVM monorepo, and then fix the underlying issues. Note that these fixes were made with very minimal knowledge of Kotlin compiler internals, so please suggest alternatives if there are better ways to collect these types. Thanks!
Test Plan:
Appendix
For anyone interested in how we're planning to use jdeps pruning: