Skip to content

Commit

Permalink
Mark receiver parameter type as referenced.
Browse files Browse the repository at this point in the history
  • Loading branch information
aeremin committed Aug 6, 2022
1 parent b76353d commit 6ac7055
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 7 deletions.
27 changes: 20 additions & 7 deletions src/main/kotlin/io/bazel/kotlin/plugin/jdeps/JdepsGenExtension.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
Expand Down Expand Up @@ -139,7 +140,7 @@ class JdepsGenExtension(
is FunctionDescriptor -> {
resultingDescriptor.returnType?.let { addImplicitDep(it) }
resultingDescriptor.valueParameters.forEach { valueParameter ->
addImplicitDep(valueParameter.type)
collectTypeReferences(valueParameter.type, isExplicit = false)
}
val virtualFileClass = resultingDescriptor.getContainingKotlinJvmBinaryClass() as? VirtualFileKotlinClass
?: return
Expand Down Expand Up @@ -217,25 +218,37 @@ class JdepsGenExtension(
* are other types required for compilation such as supertypes and interfaces of those explicit
* types.
*/
private fun collectTypeReferences(kotlinType: KotlinType, collectSuperTypes: Boolean = true) {
addExplicitDep(kotlinType)
private fun collectTypeReferences(kotlinType: KotlinType,
isExplicit: Boolean = true,
collectSuperTypes: Boolean = true) {
if (isExplicit) {
addExplicitDep(kotlinType)
} else {
addImplicitDep(kotlinType)
}

if (collectSuperTypes) {
kotlinType.supertypes().forEach {
addImplicitDep(it)
}
}

collectTypeArguments(kotlinType)
collectTypeArguments(kotlinType, isExplicit)
}

fun collectTypeArguments(kotlinType: KotlinType, visitedKotlinTypes: MutableSet<KotlinType> = mutableSetOf()) {
fun collectTypeArguments(kotlinType: KotlinType,
isExplicit: Boolean,
visitedKotlinTypes: MutableSet<KotlinType> = mutableSetOf()) {
visitedKotlinTypes.add(kotlinType)
kotlinType.arguments.map { it.type }.forEach { typeArgument ->
addExplicitDep(typeArgument)
if (isExplicit) {
addExplicitDep(typeArgument)
} else {
addImplicitDep(typeArgument)
}
typeArgument.supertypes().forEach { addImplicitDep(it) }
if (!visitedKotlinTypes.contains(typeArgument)) {
collectTypeArguments(typeArgument, visitedKotlinTypes)
collectTypeArguments(typeArgument, isExplicit, visitedKotlinTypes)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,74 @@ class KotlinBuilderJvmJdepsTest {
assertImplicit(jdeps).doesNotContain(depWithReturnTypesSuperType)
}

@Test
fun `function call receiver type`() {
val depWithReceiverTypeSuperType = ctx.runCompileTask(Consumer { c: KotlinJvmTestBuilder.TaskBuilder ->
c.addSource("SomeSuperType.kt",
"""
package something
open class SomeSuperType {}
""")
c.outputJar()
c.outputJdeps()
c.compileKotlin()
c.setLabel("depWithSuperType")
})
val depWithReceiverType = ctx.runCompileTask(Consumer { c: KotlinJvmTestBuilder.TaskBuilder ->
c.addSource("SomeType.kt",
"""
package something
class SomeType : SomeSuperType() {}
""")
c.outputJar()
c.outputJdeps()
c.compileKotlin()
c.setLabel("depWithReceiverType")
c.addDirectDependencies(depWithReceiverTypeSuperType)
})

val depWithFunction = ctx.runCompileTask(Consumer { c: KotlinJvmTestBuilder.TaskBuilder ->
c.addSource("ContainsFunction.kt",
"""
package something
fun receiverSomeType(arg: SomeType.() -> Unit) {}
""")
c.outputJar()
c.compileKotlin()
c.addDirectDependencies(depWithReceiverType)
c.addTransitiveDependencies(depWithReceiverTypeSuperType)
c.setLabel("depWithFunction")
})

val dependingTarget = ctx.runCompileTask(Consumer { c: KotlinJvmTestBuilder.TaskBuilder ->
c.addSource("CallsFunctionWithReceiver.kt",
"""
package something
fun foo() {
receiverSomeType {
}
}
""")
c.outputJar()
c.compileKotlin()
c.addDirectDependencies(depWithFunction)
c.addTransitiveDependencies(depWithReceiverType, depWithReceiverTypeSuperType)
c.outputJdeps()
c.setLabel("dependingTarget")
})
val jdeps = depsProto(dependingTarget)

assertThat(jdeps.ruleLabel).isEqualTo(dependingTarget.label())

assertExplicit(jdeps).contains(depWithFunction.singleCompileJar())
assertImplicit(jdeps).contains(depWithReceiverType.singleCompileJar())
assertImplicit(jdeps).contains(depWithReceiverTypeSuperType.singleCompileJar())
}

@Test
fun `constructor parameters are required implicit dependencies`() {
val fooDep = ctx.runCompileTask(Consumer { c: KotlinJvmTestBuilder.TaskBuilder ->
Expand Down

0 comments on commit 6ac7055

Please sign in to comment.