Skip to content

Commit

Permalink
* Collect references for type declarations. (#475)
Browse files Browse the repository at this point in the history
* Collect references for parameter references
  • Loading branch information
jongerrish authored Feb 5, 2021
1 parent 0ebede9 commit d52aca7
Show file tree
Hide file tree
Showing 3 changed files with 289 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,15 @@ class KotlinJvmTaskExecutor @Inject internal constructor(
context,
compiler,
args = baseArgs()
.plugin(plugins.jdeps) {
flag("output", outputs.jdeps)
flag("target_label", info.label)
inputs.directDependenciesList.forEach {
flag("direct_dependencies", it)
.given(outputs.jdeps).notEmpty {
plugin(plugins.jdeps) {
flag("output", outputs.jdeps)
flag("target_label", info.label)
inputs.directDependenciesList.forEach {
flag("direct_dependencies", it)
}
flag("strict_kotlin_deps", info.strictKotlinDeps)
}
flag("strict_kotlin_deps", info.strictKotlinDeps)
}
.given(outputs.jar).notEmpty {
append(codeGenArgs())
Expand Down
52 changes: 38 additions & 14 deletions src/main/kotlin/io/bazel/kotlin/plugin/jdeps/JdepsGenExtension.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.container.StorageComponentContainer
import org.jetbrains.kotlin.container.useInstance
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
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.SourceElement
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
Expand All @@ -36,6 +39,8 @@ import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.typeUtil.supertypes
import java.io.BufferedOutputStream
import java.io.File
import java.nio.file.Paths
Expand Down Expand Up @@ -92,6 +97,10 @@ class JdepsGenExtension(
else -> null
}
}

fun getClassCanonicalPath(typeConstructor: TypeConstructor): String? {
return (typeConstructor.declarationDescriptor as? DeclarationDescriptorWithSource)?.let { getClassCanonicalPath(it) }
}
}

private val explicitClassesCanonicalPaths = mutableSetOf<String>()
Expand All @@ -117,10 +126,14 @@ class JdepsGenExtension(
) {
when (val resultingDescriptor = resolvedCall.resultingDescriptor) {
is FunctionDescriptor -> {
resultingDescriptor.returnType?.let { addImplicitDep(it) }
val virtualFileClass = resultingDescriptor.getContainingKotlinJvmBinaryClass() as? VirtualFileKotlinClass
?: return
explicitClassesCanonicalPaths.add(virtualFileClass.file.path)
}
is ParameterDescriptor -> {
getClassCanonicalPath(resultingDescriptor)?.let { explicitClassesCanonicalPaths.add(it) }
}
is FakeCallableDescriptorForObject -> {
getClassCanonicalPath(resultingDescriptor)?.let { explicitClassesCanonicalPaths.add(it) }
}
Expand All @@ -140,6 +153,11 @@ class JdepsGenExtension(
context: DeclarationCheckerContext
) {
when (descriptor) {
is ClassDescriptor -> {
descriptor.typeConstructor.supertypes.forEach {
collectTypeReferences(it)
}
}
is FunctionDescriptor -> {
descriptor.returnType?.let { collectTypeReferences(it) }
descriptor.valueParameters.forEach { valueParameter ->
Expand All @@ -152,32 +170,38 @@ class JdepsGenExtension(
is PropertyDescriptor -> {
collectTypeReferences(descriptor.type)
}
is LocalVariableDescriptor -> {
collectTypeReferences(descriptor.type)
}
}
}

private fun addImplicitDep(it: KotlinType) {
getClassCanonicalPath(it.constructor)?.let { implicitClassesCanonicalPaths.add(it) }
}

private fun addExplicitDep(it: KotlinType) {
getClassCanonicalPath(it.constructor)?.let { explicitClassesCanonicalPaths.add(it) }
}

/**
* Records direct and indirect references for a given type. Direct references are explicitly
* used in the code, e.g: a type declaration or a generic type declaration. Indirect references
* are other types required for compilation such as supertypes and interfaces of those explicit
* types.
*/
private fun collectTypeReferences(kotlinType: KotlinType) {
val constructor = kotlinType.constructor
getClassCanonicalPath(constructor.declarationDescriptor as DeclarationDescriptorWithSource)?.let { explicitClassesCanonicalPaths.add(it) }
private fun collectTypeReferences(kotlinType: KotlinType, collectSuperTypes: Boolean = true) {
addExplicitDep(kotlinType)

constructor.supertypes.forEach {
val classCanonicalPath = getClassCanonicalPath(it.constructor.declarationDescriptor as DeclarationDescriptorWithSource)
classCanonicalPath?.let { implicitClassesCanonicalPaths.add(classCanonicalPath) }
if (collectSuperTypes) {
kotlinType.constructor.supertypes.forEach {
addImplicitDep(it)
}
}

kotlinType.arguments
.map { it.type.constructor }
.forEach { typeArgument ->
getClassCanonicalPath(typeArgument.declarationDescriptor as DeclarationDescriptorWithSource)?.let { explicitClassesCanonicalPaths.add(it) }
typeArgument.supertypes.forEach {
val classCanonicalPath = getClassCanonicalPath(it.constructor.declarationDescriptor as DeclarationDescriptorWithSource)
classCanonicalPath?.let { implicitClassesCanonicalPaths.add(classCanonicalPath) }
}
kotlinType.arguments.map { it.type }.forEach { typeArgument ->
addExplicitDep(typeArgument)
typeArgument.supertypes().forEach { addImplicitDep(it) }
}
}
}
Expand Down
Loading

0 comments on commit d52aca7

Please sign in to comment.