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

fill function / constructor of external library #119

Merged
merged 2 commits into from
Jul 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,11 @@ plugins {
id 'org.jetbrains.kotlin.jvm' version '1.8.10'
}

apply plugin: 'org.jetbrains.intellij'
apply plugin: 'kotlin'

sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11

intellij {
version = '2023.1.4'
version = '2023.2'
plugins = ['Kotlin', 'java']
pluginName = 'kotlin-fill-class'
updateSinceUntilBuild = false
Expand All @@ -33,15 +30,9 @@ intellij {
}
}

repositories {
mavenCentral()
}

group 'com.github.suusan2go.kotlin-fill-class'
version '1.0.21'

sourceCompatibility = 11

repositories {
mavenCentral()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import com.intellij.openapi.ui.popup.PopupStep
import com.intellij.openapi.ui.popup.util.BaseListPopupStep
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiDocumentManager
import org.jetbrains.kotlin.backend.jvm.ir.psiElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
Expand All @@ -32,6 +31,7 @@ import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
import org.jetbrains.kotlin.idea.inspections.findExistingEditor
import org.jetbrains.kotlin.idea.intentions.callExpression
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
import org.jetbrains.kotlin.idea.util.textRangeIn
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
Expand All @@ -48,7 +48,6 @@ import org.jetbrains.kotlin.psi.KtValueArgumentList
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
import org.jetbrains.kotlin.psi.psiUtil.getPrevSiblingIgnoringWhitespaceAndComments
import org.jetbrains.kotlin.psi.valueArgumentListVisitor
import org.jetbrains.kotlin.resolve.BindingContext.DECLARATION_TO_DESCRIPTOR
import org.jetbrains.kotlin.resolve.calls.components.isVararg
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
Expand All @@ -69,7 +68,7 @@ abstract class BaseFillClassInspection(
) = valueArgumentListVisitor(fun(element: KtValueArgumentList) {
val callElement = element.parent as? KtCallElement ?: return
val descriptors = analyze(callElement).ifEmpty { return }
val description = if (descriptors.any { (_, descriptor) -> descriptor is ClassConstructorDescriptor }) {
val description = if (descriptors.any { descriptor -> descriptor is ClassConstructorDescriptor }) {
getConstructorPromptTitle()
} else {
getFunctionPromptTitle()
Expand Down Expand Up @@ -113,22 +112,21 @@ abstract class BaseFillClassInspection(
}
}

private fun analyze(call: KtCallElement): List<Pair<KtFunction, FunctionDescriptor>> {
private fun analyze(call: KtCallElement): List<FunctionDescriptor> {
val context = call.analyze(BodyResolveMode.PARTIAL)
val resolvedCall = call.calleeExpression?.getResolvedCall(context)
val descriptors = if (resolvedCall != null) {
val descriptor = resolvedCall.resultingDescriptor as? FunctionDescriptor ?: return emptyList()
val func = descriptor.psiElement as? KtFunction ?: return emptyList()
listOf(func to descriptor)
listOf(descriptor)
} else {
call.calleeExpression?.mainReference?.multiResolve(false).orEmpty().mapNotNull {
val func = it.element as? KtFunction ?: return@mapNotNull null
val descriptor = context[DECLARATION_TO_DESCRIPTOR, func] as? FunctionDescriptor ?: return@mapNotNull null
func to descriptor
val descriptor = func.descriptor as? FunctionDescriptor ?: return@mapNotNull null
descriptor
}
}
val argumentSize = call.valueArguments.size
return descriptors.filter { (_, descriptor) ->
return descriptors.filter { descriptor ->
descriptor !is JavaCallableMemberDescriptor &&
descriptor.valueParameters.filterNot { it.isVararg }.size > argumentSize
}
Expand Down Expand Up @@ -156,7 +154,7 @@ open class FillClassFix(
?: ImaginaryEditor(project, argumentList.containingFile.viewProvider.document)
if (descriptors.size == 1 || editor is ImaginaryEditor) {
argumentList.fillArgumentsAndFormat(
descriptor = descriptors.first().second,
descriptor = descriptors.first(),
editor = editor,
lambdaArgument = lambdaArgument,
)
Expand All @@ -169,26 +167,26 @@ open class FillClassFix(
private fun createListPopup(
argumentList: KtValueArgumentList,
lambdaArgument: KtLambdaArgument?,
descriptors: List<Pair<KtFunction, FunctionDescriptor>>,
descriptors: List<FunctionDescriptor>,
editor: Editor,
): BaseListPopupStep<String> {
val functionName = descriptors.first().let { (_, descriptor) ->
val functionName = descriptors.first().let { descriptor ->
if (descriptor is ClassConstructorDescriptor) {
descriptor.containingDeclaration.name.asString()
} else {
descriptor.name.asString()
}
}
val functions = descriptors
.sortedBy { (_, descriptor) -> descriptor.valueParameters.size }
.associate { (function, descriptor) ->
val key = function.valueParameters.joinToString(
.sortedBy { descriptor -> descriptor.valueParameters.size }
.associateBy { descriptor ->
val key = descriptor.valueParameters.joinToString(
separator = ", ",
prefix = "$functionName(",
postfix = ")",
transform = { "${it.name}: ${it.typeReference?.text ?: ""}" },
transform = { "${it.name}: ${it.type}" },
)
key to descriptor
key
}
return object : BaseListPopupStep<String>("Choose Function", functions.keys.toList()) {
override fun isAutoSelectionEnabled() = false
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</change-notes>

<!-- please see https://confluence.jetbrains.com/display/IDEADEV/Build+Number+Ranges for description -->
<idea-version since-build="0"/>
<idea-version since-build="221.*"/>

<depends>com.intellij.modules.lang</depends>
<depends>org.jetbrains.kotlin</depends>
Expand Down