diff --git a/.idea/inspectionProfiles/idea_default.xml b/.idea/inspectionProfiles/idea_default.xml
index 5486cf6edd6..4f20b3cd9ec 100644
--- a/.idea/inspectionProfiles/idea_default.xml
+++ b/.idea/inspectionProfiles/idea_default.xml
@@ -280,6 +280,7 @@
+
diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt
index a6937ee8d42..2c54a6e904d 100644
--- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt
+++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ApplicationUtils.kt
@@ -18,6 +18,9 @@ package org.jetbrains.kotlin.idea.util.application
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.command.CommandProcessor
+import com.intellij.openapi.progress.ProgressIndicator
+import com.intellij.openapi.progress.ProgressIndicatorProvider
+import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.project.Project
fun runReadAction(action: () -> T): T {
@@ -41,4 +44,10 @@ fun Project.executeCommand(name: String, groupId: Any? = null, command: () -
CommandProcessor.getInstance().executeCommand(this, { result = command() }, name, groupId)
@Suppress("USELESS_CAST")
return result as T
-}
\ No newline at end of file
+}
+
+/**
+ * ProgressManager.getProgressIndicator() is nullable in 181 and dynamic again in 182
+ * BUNCH: 181
+ */
+val ProgressManager.progressIndicatorNullable: ProgressIndicator? get() = progressIndicator
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/actions/internal/SearchNotPropertyCandidatesAction.kt b/idea/src/org/jetbrains/kotlin/idea/actions/internal/SearchNotPropertyCandidatesAction.kt
index 6fb3e2426a0..c9c99eddf9b 100644
--- a/idea/src/org/jetbrains/kotlin/idea/actions/internal/SearchNotPropertyCandidatesAction.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/actions/internal/SearchNotPropertyCandidatesAction.kt
@@ -29,6 +29,7 @@ import com.intellij.psi.PsiModifier
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
+import org.jetbrains.kotlin.idea.util.application.progressIndicatorNullable
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.load.java.isFromJava
import org.jetbrains.kotlin.name.FqName
@@ -54,7 +55,7 @@ class SearchNotPropertyCandidatesAction : AnAction() {
ProgressManager.getInstance().runProcessWithProgressSynchronously(
{
runReadAction {
- ProgressManager.getInstance().progressIndicator.isIndeterminate = true
+ ProgressManager.getInstance().progressIndicatorNullable!!.isIndeterminate = true
processAllDescriptors(packageDesc, project)
}
},
diff --git a/idea/src/org/jetbrains/kotlin/idea/actions/internal/SearchNotPropertyCandidatesAction.kt.181 b/idea/src/org/jetbrains/kotlin/idea/actions/internal/SearchNotPropertyCandidatesAction.kt.181
deleted file mode 100644
index 998844a3b11..00000000000
--- a/idea/src/org/jetbrains/kotlin/idea/actions/internal/SearchNotPropertyCandidatesAction.kt.181
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright 2010-2016 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.kotlin.idea.actions.internal
-
-
-import com.intellij.openapi.actionSystem.AnAction
-import com.intellij.openapi.actionSystem.AnActionEvent
-import com.intellij.openapi.actionSystem.CommonDataKeys
-import com.intellij.openapi.progress.ProgressManager
-import com.intellij.openapi.progress.ProgressManager.progress
-import com.intellij.openapi.project.Project
-import com.intellij.openapi.ui.Messages
-import com.intellij.psi.PsiMethod
-import com.intellij.psi.PsiModifier
-import org.jetbrains.kotlin.descriptors.*
-import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
-import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
-import org.jetbrains.kotlin.idea.util.application.runReadAction
-import org.jetbrains.kotlin.load.java.isFromJava
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.psi.KtFile
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
-
-
-class SearchNotPropertyCandidatesAction : AnAction() {
- override fun actionPerformed(e: AnActionEvent?) {
- val project = e?.project!!
- val psiFile = e.getData(CommonDataKeys.PSI_FILE) as? KtFile ?: return
-
- val desc = psiFile.findModuleDescriptor()
- val result = Messages.showInputDialog("Enter package FqName", "Search for Not Property candidates", Messages.getQuestionIcon())
- val packageDesc = try {
- val fqName = FqName.fromSegments(result!!.split('.'))
- desc.getPackage(fqName)
- }
- catch (e: Exception) {
- return
- }
-
- ProgressManager.getInstance().runProcessWithProgressSynchronously(
- {
- runReadAction {
- ProgressManager.getInstance().progressIndicator!!.isIndeterminate = true
- processAllDescriptors(packageDesc, project)
- }
- },
- "Searching for Not Property candidates",
- true,
- project)
- }
-
-
- private fun processAllDescriptors(desc: DeclarationDescriptor, project: Project) {
- val processed = mutableSetOf()
- var pFunctions = 0
- val matchedDescriptors = mutableSetOf()
-
- fun recursive(desc: DeclarationDescriptor) {
- if (desc in processed) return
- progress("Step 1: Collecting ${processed.size}:$pFunctions:${matchedDescriptors.size}", "$desc")
- when (desc) {
-
- is ModuleDescriptor -> recursive(desc.getPackage(FqName("java")))
- is ClassDescriptor -> desc.unsubstitutedMemberScope.getContributedDescriptors { true }.forEach(::recursive)
- is PackageViewDescriptor -> desc.memberScope.getContributedDescriptors { true }.forEach(::recursive)
-
- is FunctionDescriptor -> {
- if (desc.isFromJava) {
- val name = desc.fqNameUnsafe.shortName().asString()
- if (name.length > 3 &&
- ((name.startsWith("get") && desc.valueParameters.isEmpty() && desc.returnType != null) ||
- (name.startsWith("set") && desc.valueParameters.size == 1))) {
- if (desc in matchedDescriptors) return
- matchedDescriptors += desc
- }
- }
- pFunctions++
- return
- }
-
- }
- processed += desc
- }
- recursive(desc)
- val resultDescriptors = mutableSetOf()
- matchedDescriptors.flatMapTo(resultDescriptors) {
- sequenceOf(it, *(it.overriddenDescriptors.toTypedArray())).asIterable()
- }
- println("Found ${resultDescriptors.size} accessors")
-
-
- fun PsiMethod.isTrivial(): Boolean {
- val t = this.text
- val s = t.indexOf('{')
- val e = t.lastIndexOf('}')
- return if (s != e && s != -1) t.substring(s, e).lines().size <= 3 else true
- }
-
-
- val descriptorToPsiBinding = mutableMapOf()
-
-
- var i = 0
- resultDescriptors.forEach { desc ->
- progress("Step 2: ${i++} of ${resultDescriptors.size}", "$desc")
- val source = DescriptorToSourceUtilsIde.getAllDeclarations(project, desc)
- .filterIsInstance()
- .firstOrNull() ?: return@forEach
- val abstract = source.modifierList.hasModifierProperty(PsiModifier.ABSTRACT)
- if (!abstract) {
- if (!source.isTrivial()) {
- descriptorToPsiBinding[desc] = source
- }
- }
- }
-
- val nonTrivial = mutableSetOf()
- i = 0
- descriptorToPsiBinding.forEach { t, u ->
- progress("Step 3: ${i++} of ${descriptorToPsiBinding.size}", "$t")
- val descriptors = t.overriddenDescriptors
- var impl = false
- descriptors.forEach {
- val source = DescriptorToSourceUtilsIde.getAllDeclarations(project, it).filterIsInstance().firstOrNull()
- if (source != null) {
- if (source.body != null || source.hasModifierProperty(PsiModifier.ABSTRACT))
- nonTrivial += it
- impl = true
- }
- }
- if (u.body != null)
- if (!impl)
- nonTrivial += t
- }
- nonTrivial.forEach(::println)
- println("Non trivial count: ${nonTrivial.size}")
- }
-
- override fun update(e: AnActionEvent) {
- if (!KotlinInternalMode.enabled) {
- e.presentation.isVisible = false
- e.presentation.isEnabled = false
- }
- else {
- e.presentation.isVisible = true
- e.presentation.isEnabled = e.getData(CommonDataKeys.PSI_FILE) is KtFile
- }
- }
-
-}
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeParameterToReceiverIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeParameterToReceiverIntention.kt
index 7de2e4b5a77..67b6091ffe9 100644
--- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeParameterToReceiverIntention.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeParameterToReceiverIntention.kt
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.idea.references.KtSimpleReference
import org.jetbrains.kotlin.idea.runSynchronouslyWithProgress
import org.jetbrains.kotlin.idea.search.usagesSearch.searchReferencesOrMethodReferences
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
+import org.jetbrains.kotlin.idea.util.application.progressIndicatorNullable
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
@@ -186,7 +187,7 @@ class ConvertFunctionTypeParameterToReceiverIntention : SelfTargetingRangeIntent
runReadAction {
val progressStep = 1.0/callables.size
for ((i, callable) in callables.withIndex()) {
- ProgressManager.getInstance().progressIndicator.fraction = (i + 1) * progressStep
+ ProgressManager.getInstance().progressIndicatorNullable!!.fraction = (i + 1) * progressStep
if (callable !is PsiNamedElement) continue
diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeParameterToReceiverIntention.kt.181 b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeParameterToReceiverIntention.kt.181
deleted file mode 100644
index b1f10a8a30c..00000000000
--- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeParameterToReceiverIntention.kt.181
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright 2010-2016 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.kotlin.idea.intentions
-
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.progress.ProgressManager
-import com.intellij.openapi.util.TextRange
-import com.intellij.openapi.util.text.StringUtil
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiNamedElement
-import com.intellij.psi.search.LocalSearchScope
-import com.intellij.psi.search.searches.ReferencesSearch
-import com.intellij.refactoring.util.RefactoringUIUtil
-import com.intellij.util.containers.MultiMap
-import org.jetbrains.kotlin.descriptors.CallableDescriptor
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.idea.caches.resolve.analyze
-import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
-import org.jetbrains.kotlin.idea.core.*
-import org.jetbrains.kotlin.idea.refactoring.CallableRefactoring
-import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.explicateReceiverOf
-import org.jetbrains.kotlin.idea.refactoring.checkConflictsInteractively
-import org.jetbrains.kotlin.idea.refactoring.getAffectedCallables
-import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinIntroduceVariableHandler
-import org.jetbrains.kotlin.idea.references.KtReference
-import org.jetbrains.kotlin.idea.references.KtSimpleReference
-import org.jetbrains.kotlin.idea.runSynchronouslyWithProgress
-import org.jetbrains.kotlin.idea.search.usagesSearch.searchReferencesOrMethodReferences
-import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
-import org.jetbrains.kotlin.idea.util.application.runReadAction
-import org.jetbrains.kotlin.psi.*
-import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
-import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
-import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
-import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
-import org.jetbrains.kotlin.psi.typeRefHelpers.setReceiverTypeReference
-import org.jetbrains.kotlin.resolve.BindingContext
-import org.jetbrains.kotlin.resolve.bindingContextUtil.getAbbreviatedTypeOrType
-import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getArgumentByParameterIndex
-import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
-import org.jetbrains.kotlin.types.KotlinType
-
-class ConvertFunctionTypeParameterToReceiverIntention : SelfTargetingRangeIntention(
- KtTypeReference::class.java,
- "Convert function type parameter to receiver"
-) {
- class FunctionDefinitionInfo(element: KtFunction) : AbstractProcessableUsageInfo(element) {
- override fun process(data: ConversionData, elementsToShorten: MutableList) {
- val function = element ?: return
- val functionParameter = function.valueParameters.getOrNull(data.functionParameterIndex) ?: return
- val functionType = functionParameter.typeReference?.typeElement as? KtFunctionType ?: return
- val functionTypeParameterList = functionType.parameterList ?: return
- val parameterToMove = functionTypeParameterList.parameters.getOrNull(data.typeParameterIndex) ?: return
- val typeReferenceToMove = parameterToMove.typeReference ?: return
- functionType.setReceiverTypeReference(typeReferenceToMove)
- functionTypeParameterList.removeParameter(parameterToMove)
- }
- }
-
- class ParameterCallInfo(element: KtCallExpression) : AbstractProcessableUsageInfo(element) {
- override fun process(data: ConversionData, elementsToShorten: MutableList) {
- val callExpression = element ?: return
- val argumentList = callExpression.valueArgumentList ?: return
- val expressionToMove = argumentList.arguments.getOrNull(data.typeParameterIndex)?.getArgumentExpression() ?: return
- val callWithReceiver = KtPsiFactory(callExpression).createExpressionByPattern("$0.$1", expressionToMove, callExpression) as KtQualifiedExpression
- (callWithReceiver.selectorExpression as KtCallExpression).valueArgumentList!!.removeArgument(data.typeParameterIndex)
- callExpression.replace(callWithReceiver)
- }
- }
-
- class InternalReferencePassInfo(element: KtSimpleNameExpression) : AbstractProcessableUsageInfo(element) {
- override fun process(data: ConversionData, elementsToShorten: MutableList) {
- val expression = element ?: return
- val lambdaType = data.lambdaType
- val validator = CollectingNameValidator()
- val parameterNames = lambdaType.arguments
- .dropLast(1)
- .map { KotlinNameSuggester.suggestNamesByType(it.type, validator, "p").first() }
- val receiver = parameterNames.getOrNull(data.typeParameterIndex) ?: return
- val arguments = parameterNames.filter { it != receiver }
- val adapterLambda = KtPsiFactory(expression).createLambdaExpression(
- parameterNames.joinToString(),
- "$receiver.${expression.text}(${arguments.joinToString()})"
- )
- expression.replaced(adapterLambda).let {
- MoveLambdaOutsideParenthesesIntention.moveFunctionLiteralOutsideParenthesesIfPossible(it)
- }
- }
- }
-
- class LambdaInfo(element: KtExpression) : AbstractProcessableUsageInfo(element) {
- override fun process(data: ConversionData, elementsToShorten: MutableList) {
- val expression = element ?: return
- val context = expression.analyze(BodyResolveMode.PARTIAL)
- val psiFactory = KtPsiFactory(expression)
-
- if (expression is KtLambdaExpression || (expression !is KtSimpleNameExpression && expression !is KtCallableReferenceExpression)) {
- expression.forEachDescendantOfType {
- if (it.getLabelName() != null) return@forEachDescendantOfType
- val descriptor = context[BindingContext.REFERENCE_TARGET, it.instanceReference] ?: return@forEachDescendantOfType
- it.replace(psiFactory.createExpression(explicateReceiverOf(descriptor)))
- }
- }
-
- if (expression is KtLambdaExpression) {
- expression.valueParameters.getOrNull(data.typeParameterIndex)?.let { parameterToConvert ->
- val thisRefExpr = psiFactory.createThisExpression()
- for (ref in ReferencesSearch.search(parameterToConvert, LocalSearchScope(expression))) {
- (ref.element as? KtSimpleNameExpression)?.replace(thisRefExpr)
- }
- val lambda = expression.functionLiteral
- lambda.valueParameterList!!.removeParameter(parameterToConvert)
- if (lambda.valueParameters.isEmpty()) {
- lambda.arrow?.delete()
- }
- }
- return
- }
-
- val originalLambdaTypes = data.lambdaType
- val originalParameterTypes = originalLambdaTypes.arguments.dropLast(1).map { it.type }
-
- val calleeText = when (expression) {
- is KtSimpleNameExpression -> expression.text
- is KtCallableReferenceExpression -> "(${expression.text})"
- else -> generateVariable(expression)
- }
-
- val parameterNameValidator = CollectingNameValidator(
- if (expression !is KtCallableReferenceExpression) listOf(calleeText) else emptyList()
- )
- val parameterNamesWithReceiver = originalParameterTypes.mapIndexed { i, type ->
- if (i != data.typeParameterIndex) KotlinNameSuggester.suggestNamesByType(type, parameterNameValidator, "p").first() else "this"
- }
- val parameterNames = parameterNamesWithReceiver.filter { it != "this" }
-
- val body = psiFactory.createExpression(parameterNamesWithReceiver.joinToString(prefix = "$calleeText(", postfix = ")"))
-
- val replacingLambda = psiFactory.buildExpression {
- appendFixedText("{ ")
- appendFixedText(parameterNames.joinToString())
- appendFixedText(" -> ")
- appendExpression(body)
- appendFixedText(" }")
- } as KtLambdaExpression
-
- expression.replaced(replacingLambda).let {
- MoveLambdaOutsideParenthesesIntention.moveFunctionLiteralOutsideParenthesesIfPossible(it)
- }
- }
-
- private fun generateVariable(expression: KtExpression): String {
- var baseCallee = ""
- KotlinIntroduceVariableHandler.doRefactoring(project, null, expression, false, emptyList()) {
- baseCallee = it.name!!
- }
- return baseCallee
- }
- }
-
- private inner class Converter(
- private val data: ConversionData
- ) : CallableRefactoring(data.function.project, data.functionDescriptor, text) {
- override fun performRefactoring(descriptorsForChange: Collection) {
- val callables = getAffectedCallables(project, descriptorsForChange)
-
- val conflicts = MultiMap()
-
- val usages = ArrayList>()
-
- project.runSynchronouslyWithProgress("Looking for usages and conflicts...", true) {
- runReadAction {
- val progressStep = 1.0/callables.size
- for ((i, callable) in callables.withIndex()) {
- ProgressManager.getInstance().progressIndicator!!.fraction = (i + 1) * progressStep
-
- if (callable !is PsiNamedElement) continue
-
- if (!checkModifiable(callable)) {
- val renderedCallable = RefactoringUIUtil.getDescription(callable, true).capitalize()
- conflicts.putValue(callable, "Can't modify $renderedCallable")
- }
-
- usageLoop@ for (ref in callable.searchReferencesOrMethodReferences()) {
- val refElement = ref.element ?: continue
- when (ref) {
- is KtSimpleReference<*> -> processExternalUsage(conflicts, refElement, usages)
- is KtReference -> continue@usageLoop
- else -> {
- if (data.isFirstParameter) continue@usageLoop
- conflicts.putValue(
- refElement,
- "Can't replace non-Kotlin reference with call expression: " + StringUtil.htmlEmphasize(refElement.text)
- )
- }
- }
- }
-
- if (callable is KtFunction) {
- usages += FunctionDefinitionInfo(callable)
- processInternalUsages(callable, usages)
- }
- }
- }
- }
-
- project.checkConflictsInteractively(conflicts) {
- project.executeWriteCommand(text) {
- val elementsToShorten = ArrayList()
- usages.forEach { it.process(data, elementsToShorten) }
- ShortenReferences.DEFAULT.process(elementsToShorten)
- }
- }
- }
-
- private fun processExternalUsage(
- conflicts: MultiMap,
- refElement: PsiElement,
- usages: ArrayList>
- ) {
- val callElement = refElement.getParentOfTypeAndBranch { calleeExpression }
- if (callElement != null) {
- val context = callElement.analyze(BodyResolveMode.PARTIAL)
- val expressionToProcess = getArgumentExpressionToProcess(callElement, context) ?: return
-
- if (!data.isFirstParameter
- && callElement is KtConstructorDelegationCall
- && expressionToProcess !is KtLambdaExpression
- && expressionToProcess !is KtSimpleNameExpression
- && expressionToProcess !is KtCallableReferenceExpression) {
- conflicts.putValue(
- expressionToProcess,
- "Following expression won't be processed since refactoring can't preserve its semantics: ${expressionToProcess.text}"
- )
- return
- }
-
- if (!checkThisExpressionsAreExplicatable(conflicts, context, expressionToProcess)) return
-
- if (data.isFirstParameter && expressionToProcess !is KtLambdaExpression) return
-
- usages += LambdaInfo(expressionToProcess)
- return
- }
-
- if (data.isFirstParameter) return
-
- val callableReference = refElement.getParentOfTypeAndBranch { callableReference }
- if (callableReference != null) {
- conflicts.putValue(
- refElement,
- "Callable reference transformation is not supported: " + StringUtil.htmlEmphasize(callableReference.text)
- )
- return
- }
- }
-
- private fun getArgumentExpressionToProcess(callElement: KtCallElement, context: BindingContext): KtExpression? {
- return callElement
- .getArgumentByParameterIndex(data.functionParameterIndex, context)
- .singleOrNull()
- ?.getArgumentExpression()
- ?.let { KtPsiUtil.safeDeparenthesize(it) }
- }
-
- private fun checkThisExpressionsAreExplicatable(conflicts: MultiMap, context: BindingContext, expressionToProcess: KtExpression): Boolean {
- for (thisExpr in expressionToProcess.collectDescendantsOfType()) {
- if (thisExpr.getLabelName() != null) continue
- val descriptor = context[BindingContext.REFERENCE_TARGET, thisExpr.instanceReference] ?: continue
- if (explicateReceiverOf(descriptor) == "this") {
- conflicts.putValue(
- thisExpr,
- "Following expression won't be processed since refactoring can't preserve its semantics: ${thisExpr.text}"
- )
- return false
- }
- }
- return true
- }
-
- private fun processInternalUsages(callable: KtFunction, usages: ArrayList>) {
- val body = when (callable) {
- is KtConstructor<*> -> callable.containingClassOrObject?.getBody()
- else -> callable.bodyExpression
- }
- if (body != null) {
- val functionParameter = callable.valueParameters.getOrNull(data.functionParameterIndex) ?: return
- for (ref in ReferencesSearch.search(functionParameter, LocalSearchScope(body))) {
- val element = ref.element as? KtSimpleNameExpression ?: continue
- val callExpression = element.getParentOfTypeAndBranch { calleeExpression }
- if (callExpression != null) {
- usages += ParameterCallInfo(callExpression)
- }
- else if (!data.isFirstParameter) {
- usages += InternalReferencePassInfo(element)
- }
- }
- }
- }
- }
-
- class ConversionData(
- val typeParameterIndex: Int,
- val functionParameterIndex: Int,
- val lambdaType: KotlinType,
- val function: KtFunction
- ) {
- val isFirstParameter: Boolean get() = typeParameterIndex == 0
- val functionDescriptor by lazy { function.unsafeResolveToDescriptor() as FunctionDescriptor }
- }
-
- private fun KtTypeReference.getConversionData(): ConversionData? {
- val parameter = parent as? KtParameter ?: return null
- val functionType = parameter.getParentOfTypeAndBranch { parameterList } ?: return null
- if (functionType.receiverTypeReference != null) return null
- val lambdaType = functionType.getAbbreviatedTypeOrType(functionType.analyze(BodyResolveMode.PARTIAL)) ?: return null
- val containingParameter = (functionType.parent as? KtTypeReference)?.parent as? KtParameter ?: return null
- val ownerFunction = containingParameter.ownerFunction as? KtFunction ?: return null
- val typeParameterIndex = functionType.parameters.indexOf(parameter)
- val functionParameterIndex = ownerFunction.valueParameters.indexOf(containingParameter)
- return ConversionData(typeParameterIndex, functionParameterIndex, lambdaType, ownerFunction)
- }
-
- override fun startInWriteAction(): Boolean = false
-
- override fun applicabilityRange(element: KtTypeReference): TextRange? {
- val data = element.getConversionData() ?: return null
-
- val elementBefore = data.function.valueParameters[data.functionParameterIndex].typeReference!!.typeElement as KtFunctionType
- val elementAfter = elementBefore.copied().apply {
- setReceiverTypeReference(element)
- parameterList!!.removeParameter(data.typeParameterIndex)
- }
- text = "Convert '${elementBefore.text}' to '${elementAfter.text}'"
-
- return element.textRange
- }
-
- override fun applyTo(element: KtTypeReference, editor: Editor?) {
- element.getConversionData()?.let { Converter(it).run() }
- }
-}
diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeReceiverToParameterIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeReceiverToParameterIntention.kt
index b7eb85efc2c..5044cc70520 100644
--- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeReceiverToParameterIntention.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeReceiverToParameterIntention.kt
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.idea.references.KtSimpleReference
import org.jetbrains.kotlin.idea.runSynchronouslyWithProgress
import org.jetbrains.kotlin.idea.search.usagesSearch.searchReferencesOrMethodReferences
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
+import org.jetbrains.kotlin.idea.util.application.progressIndicatorNullable
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.*
@@ -125,7 +126,7 @@ class ConvertFunctionTypeReceiverToParameterIntention : SelfTargetingRangeIntent
runReadAction {
val progressStep = 1.0/callables.size
for ((i, callable) in callables.withIndex()) {
- ProgressManager.getInstance().progressIndicator.fraction = (i + 1) * progressStep
+ ProgressManager.getInstance().progressIndicatorNullable!!.fraction = (i + 1) * progressStep
if (callable !is KtFunction) continue
diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeReceiverToParameterIntention.kt.181 b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeReceiverToParameterIntention.kt.181
deleted file mode 100644
index f9b059be672..00000000000
--- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeReceiverToParameterIntention.kt.181
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright 2010-2016 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.kotlin.idea.intentions
-
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.progress.ProgressManager
-import com.intellij.openapi.util.TextRange
-import com.intellij.psi.PsiElement
-import com.intellij.psi.search.LocalSearchScope
-import com.intellij.psi.search.searches.ReferencesSearch
-import com.intellij.refactoring.util.RefactoringUIUtil
-import com.intellij.util.containers.MultiMap
-import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
-import org.jetbrains.kotlin.descriptors.CallableDescriptor
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.idea.caches.resolve.analyze
-import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
-import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
-import org.jetbrains.kotlin.idea.core.*
-import org.jetbrains.kotlin.idea.refactoring.CallableRefactoring
-import org.jetbrains.kotlin.idea.refactoring.checkConflictsInteractively
-import org.jetbrains.kotlin.idea.refactoring.getAffectedCallables
-import org.jetbrains.kotlin.idea.references.KtSimpleReference
-import org.jetbrains.kotlin.idea.runSynchronouslyWithProgress
-import org.jetbrains.kotlin.idea.search.usagesSearch.searchReferencesOrMethodReferences
-import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
-import org.jetbrains.kotlin.idea.util.application.runReadAction
-import org.jetbrains.kotlin.psi.*
-import org.jetbrains.kotlin.psi.psiUtil.*
-import org.jetbrains.kotlin.psi.typeRefHelpers.setReceiverTypeReference
-import org.jetbrains.kotlin.resolve.BindingContext
-import org.jetbrains.kotlin.resolve.bindingContextUtil.getAbbreviatedTypeOrType
-import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getArgumentByParameterIndex
-import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
-import org.jetbrains.kotlin.types.KotlinType
-
-class ConvertFunctionTypeReceiverToParameterIntention : SelfTargetingRangeIntention(
- KtTypeReference::class.java,
- "Convert function type receiver to parameter"
-) {
- class ConversionData(
- val functionParameterIndex: Int,
- val lambdaReceiverType: KotlinType,
- val function: KtFunction
- ) {
- val functionDescriptor by lazy { function.unsafeResolveToDescriptor() as FunctionDescriptor }
- }
-
- class FunctionDefinitionInfo(element: KtFunction) : AbstractProcessableUsageInfo(element) {
- override fun process(data: ConversionData, elementsToShorten: MutableList) {
- val function = element ?: return
- val functionParameter = function.valueParameters.getOrNull(data.functionParameterIndex) ?: return
- val functionType = functionParameter.typeReference?.typeElement as? KtFunctionType ?: return
- val functionTypeParameterList = functionType.parameterList ?: return
- val functionTypeReceiver = functionType.receiverTypeReference ?: return
- val parameterToAdd = KtPsiFactory(project).createFunctionTypeParameter(functionTypeReceiver)
- functionTypeParameterList.addParameterBefore(parameterToAdd, functionTypeParameterList.parameters.firstOrNull())
- functionType.setReceiverTypeReference(null)
- }
- }
-
- class ParameterCallInfo(element: KtCallExpression) : AbstractProcessableUsageInfo(element) {
- override fun process(data: ConversionData, elementsToShorten: MutableList) {
- val callExpression = element ?: return
- val qualifiedExpression = callExpression.getQualifiedExpressionForSelector() ?: return
- val receiverExpression = qualifiedExpression.receiverExpression
- val argumentList = callExpression.getOrCreateValueArgumentList()
- argumentList.addArgumentBefore(KtPsiFactory(project).createArgument(receiverExpression), argumentList.arguments.firstOrNull())
- qualifiedExpression.replace(callExpression)
- }
- }
-
- class LambdaInfo(element: KtLambdaExpression) : AbstractProcessableUsageInfo(element) {
- override fun process(data: ConversionData, elementsToShorten: MutableList) {
- val lambda = element?.functionLiteral ?: return
- val context = lambda.analyze(BodyResolveMode.PARTIAL)
-
- val psiFactory = KtPsiFactory(project)
-
- val validator = CollectingNameValidator(
- lambda.valueParameters.mapNotNull { it.name },
- NewDeclarationNameValidator(lambda.bodyExpression!!, null, NewDeclarationNameValidator.Target.VARIABLES)
- )
- val newParameterName = KotlinNameSuggester.suggestNamesByType(data.lambdaReceiverType, validator, "p").first()
- val newParameterRefExpression = psiFactory.createExpression(newParameterName)
-
- lambda.forEachDescendantOfType {
- val thisTarget = context[BindingContext.REFERENCE_TARGET, it.instanceReference] ?: return@forEachDescendantOfType
- if (DescriptorToSourceUtilsIde.getAnyDeclaration(project, thisTarget) == lambda) {
- it.replace(newParameterRefExpression)
- }
- }
-
- val lambdaParameterList = lambda.getOrCreateParameterList()
- val parameterToAdd = psiFactory.createLambdaParameterList(newParameterName).parameters.first()
- lambdaParameterList.addParameterBefore(parameterToAdd, lambdaParameterList.parameters.firstOrNull())
- }
- }
-
- private inner class Converter(
- private val data: ConversionData
- ) : CallableRefactoring(data.function.project, data.functionDescriptor, text) {
- override fun performRefactoring(descriptorsForChange: Collection) {
- val callables = getAffectedCallables(project, descriptorsForChange)
-
- val conflicts = MultiMap()
-
- val usages = ArrayList>()
-
- project.runSynchronouslyWithProgress("Looking for usages and conflicts...", true) {
- runReadAction {
- val progressStep = 1.0/callables.size
- for ((i, callable) in callables.withIndex()) {
- ProgressManager.getInstance().progressIndicator!!.fraction = (i + 1) * progressStep
-
- if (callable !is KtFunction) continue
-
- if (!checkModifiable(callable)) {
- val renderedCallable = RefactoringUIUtil.getDescription(callable, true).capitalize()
- conflicts.putValue(callable, "Can't modify $renderedCallable")
- }
-
- for (ref in callable.searchReferencesOrMethodReferences()) {
- if (ref !is KtSimpleReference<*>) continue
- processExternalUsage(ref, usages)
- }
-
- usages += FunctionDefinitionInfo(callable)
-
- processInternalUsages(callable, usages)
- }
- }
- }
-
- project.checkConflictsInteractively(conflicts) {
- project.executeWriteCommand(text) {
- val elementsToShorten = ArrayList()
- usages.forEach { it.process(data, elementsToShorten) }
- ShortenReferences.DEFAULT.process(elementsToShorten)
- }
- }
- }
-
- private fun processExternalUsage(ref: KtSimpleReference<*>, usages: java.util.ArrayList>) {
- val callElement = ref.element.getParentOfTypeAndBranch { calleeExpression } ?: return
- val context = callElement.analyze(BodyResolveMode.PARTIAL)
- val expressionToProcess = callElement
- .getArgumentByParameterIndex(data.functionParameterIndex, context)
- .singleOrNull()
- ?.getArgumentExpression()
- ?.let { KtPsiUtil.safeDeparenthesize(it) }
- ?: return
- if (expressionToProcess is KtLambdaExpression) {
- usages += LambdaInfo(expressionToProcess)
- }
- }
-
- private fun processInternalUsages(callable: KtFunction, usages: java.util.ArrayList>) {
- val body = when (callable) {
- is KtConstructor<*> -> callable.containingClassOrObject?.getBody()
- else -> callable.bodyExpression
- }
- if (body != null) {
- val functionParameter = callable.valueParameters.getOrNull(data.functionParameterIndex) ?: return
- for (ref in ReferencesSearch.search(functionParameter, LocalSearchScope(body))) {
- val element = ref.element as? KtSimpleNameExpression ?: continue
- val callExpression = element.getParentOfTypeAndBranch { calleeExpression } ?: continue
- usages += ParameterCallInfo(callExpression)
- }
- }
- }
- }
-
- private fun KtTypeReference.getConversionData(): ConversionData? {
- val functionTypeReceiver = parent as? KtFunctionTypeReceiver ?: return null
- val functionType = functionTypeReceiver.parent as? KtFunctionType ?: return null
- val lambdaReceiverType = functionType
- .getAbbreviatedTypeOrType(functionType.analyze(BodyResolveMode.PARTIAL))
- ?.getReceiverTypeFromFunctionType()
- ?: return null
- val containingParameter = (functionType.parent as? KtTypeReference)?.parent as? KtParameter ?: return null
- val ownerFunction = containingParameter.ownerFunction as? KtFunction ?: return null
- val functionParameterIndex = ownerFunction.valueParameters.indexOf(containingParameter)
- return ConversionData(functionParameterIndex, lambdaReceiverType, ownerFunction)
- }
-
- override fun startInWriteAction(): Boolean = false
-
- override fun applicabilityRange(element: KtTypeReference): TextRange? {
- val data = element.getConversionData() ?: return null
-
- val elementBefore = data.function.valueParameters[data.functionParameterIndex].typeReference!!.typeElement as KtFunctionType
- val elementAfter = elementBefore.copied().apply {
- parameterList!!.addParameterBefore(
- KtPsiFactory(element).createFunctionTypeParameter(element),
- parameterList!!.parameters.firstOrNull()
- )
- setReceiverTypeReference(null)
- }
- text = "Convert '${elementBefore.text}' to '${elementAfter.text}'"
-
- return element.textRange
- }
-
- override fun applyTo(element: KtTypeReference, editor: Editor?) {
- element.getConversionData()?.let { Converter(it).run() }
- }
-}
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertPropertyToFunctionIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertPropertyToFunctionIntention.kt
index f4cef3242f0..4149f1f0e52 100644
--- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertPropertyToFunctionIntention.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertPropertyToFunctionIntention.kt
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.idea.references.KtReference
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
import org.jetbrains.kotlin.idea.runSynchronouslyWithProgress
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
+import org.jetbrains.kotlin.idea.util.application.progressIndicatorNullable
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.load.java.JvmAbi
@@ -97,7 +98,7 @@ class ConvertPropertyToFunctionIntention : SelfTargetingIntention(Kt
runReadAction {
val progressStep = 1.0/callables.size
for ((i, callable) in callables.withIndex()) {
- ProgressManager.getInstance().progressIndicator.fraction = (i + 1)*progressStep
+ ProgressManager.getInstance().progressIndicatorNullable!!.fraction = (i + 1)*progressStep
if (callable !is PsiNamedElement) continue
diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertPropertyToFunctionIntention.kt.181 b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertPropertyToFunctionIntention.kt.181
deleted file mode 100644
index 93d464dc37a..00000000000
--- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertPropertyToFunctionIntention.kt.181
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright 2010-2015 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.kotlin.idea.intentions
-
-import com.intellij.codeInsight.intention.LowPriorityAction
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.progress.ProgressManager
-import com.intellij.openapi.project.Project
-import com.intellij.openapi.util.text.StringUtil
-import com.intellij.psi.*
-import com.intellij.psi.search.searches.ReferencesSearch
-import com.intellij.refactoring.util.RefactoringUIUtil
-import com.intellij.util.containers.MultiMap
-import org.jetbrains.kotlin.asJava.namedUnwrappedElement
-import org.jetbrains.kotlin.descriptors.CallableDescriptor
-import org.jetbrains.kotlin.idea.caches.resolve.analyze
-import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
-import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
-import org.jetbrains.kotlin.idea.refactoring.*
-import org.jetbrains.kotlin.idea.references.KtReference
-import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
-import org.jetbrains.kotlin.idea.runSynchronouslyWithProgress
-import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
-import org.jetbrains.kotlin.idea.util.application.runReadAction
-import org.jetbrains.kotlin.incremental.components.NoLookupLocation
-import org.jetbrains.kotlin.load.java.JvmAbi
-import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
-import org.jetbrains.kotlin.psi.KtProperty
-import org.jetbrains.kotlin.psi.KtPsiFactory
-import org.jetbrains.kotlin.psi.KtSimpleNameExpression
-import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
-import org.jetbrains.kotlin.psi.psiUtil.siblings
-import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
-import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
-import org.jetbrains.kotlin.resolve.scopes.utils.findFunction
-import java.util.*
-
-class ConvertPropertyToFunctionIntention : SelfTargetingIntention(KtProperty::class.java, "Convert property to function"), LowPriorityAction {
- private inner class Converter(
- project: Project,
- descriptor: CallableDescriptor
- ): CallableRefactoring(project, descriptor, text) {
- private val newName: String = JvmAbi.getterName(callableDescriptor.name.asString())
-
- private fun convertProperty(originalProperty: KtProperty, psiFactory: KtPsiFactory) {
- val property = originalProperty.copy() as KtProperty
- val getter = property.getter
-
- val sampleFunction = psiFactory.createFunction("fun foo() {\n\n}")
-
- property.valOrVarKeyword.replace(sampleFunction.funKeyword!!)
- property.addAfter(psiFactory.createParameterList("()"), property.nameIdentifier)
- if (property.initializer == null) {
- if (getter != null) {
- val dropGetterTo = (getter.equalsToken ?: getter.bodyExpression)
- ?.siblings(forward = false, withItself = false)
- ?.firstOrNull { it !is PsiWhiteSpace }
- getter.deleteChildRange(getter.firstChild, dropGetterTo)
-
- val dropPropertyFrom = getter
- .siblings(forward = false, withItself = false)
- .first { it !is PsiWhiteSpace }
- .nextSibling
- property.deleteChildRange(dropPropertyFrom, getter.prevSibling)
- }
- }
- property.setName(newName)
-
- originalProperty.replace(psiFactory.createFunction(property.text))
- }
-
- override fun performRefactoring(descriptorsForChange: Collection) {
- val propertyName = callableDescriptor.name.asString()
- val nameChanged = propertyName != newName
- val getterName = JvmAbi.getterName(callableDescriptor.name.asString())
- val conflicts = MultiMap()
- val callables = getAffectedCallables(project, descriptorsForChange)
- val kotlinRefsToReplaceWithCall = ArrayList()
- val refsToRename = ArrayList()
- val javaRefsToReplaceWithCall = ArrayList()
-
- project.runSynchronouslyWithProgress("Looking for usages and conflicts...", true) {
- runReadAction {
- val progressStep = 1.0/callables.size
- for ((i, callable) in callables.withIndex()) {
- ProgressManager.getInstance().progressIndicator!!.fraction = (i + 1) * progressStep
-
- if (callable !is PsiNamedElement) continue
-
- if (!checkModifiable(callable)) {
- val renderedCallable = RefactoringUIUtil.getDescription(callable, true).capitalize()
- conflicts.putValue(callable, "Can't modify $renderedCallable")
- }
-
- if (callable is KtProperty) {
- callableDescriptor.getContainingScope()
- ?.findFunction(callableDescriptor.name, NoLookupLocation.FROM_IDE) { it.valueParameters.isEmpty() }
- ?.let { DescriptorToSourceUtilsIde.getAnyDeclaration(project, it) }
- ?.let { reportDeclarationConflict(conflicts, it) { "$it already exists" } }
- }
- else if (callable is PsiMethod) {
- callable.containingClass
- ?.findMethodsByName(propertyName, true)
- // as is necessary here: see KT-10386
- ?.firstOrNull { it.parameterList.parametersCount == 0 && !callables.contains(it.namedUnwrappedElement as PsiElement?) }
- ?.let { reportDeclarationConflict(conflicts, it) { "$it already exists" } }
- }
-
- val usages = ReferencesSearch.search(callable)
- for (usage in usages) {
- if (usage is KtReference) {
- if (usage is KtSimpleNameReference) {
- val expression = usage.expression
- if (expression.getCall(expression.analyze(BodyResolveMode.PARTIAL)) != null
- && expression.getStrictParentOfType() == null) {
- kotlinRefsToReplaceWithCall.add(expression)
- }
- else if (nameChanged) {
- refsToRename.add(usage)
- }
- }
- else {
- val refElement = usage.element
- conflicts.putValue(
- refElement,
- "Unrecognized reference will be skipped: " + StringUtil.htmlEmphasize(refElement.text)
- )
- }
- continue
- }
-
- val refElement = usage.element
-
- if (refElement.text.endsWith(getterName)) continue
-
- if (usage is PsiJavaReference) {
- if (usage.resolve() is PsiField && usage is PsiReferenceExpression) {
- javaRefsToReplaceWithCall.add(usage)
- }
- continue
- }
-
- conflicts.putValue(
- refElement,
- "Can't replace foreign reference with call expression: " + StringUtil.htmlEmphasize(refElement.text)
- )
- }
- }
- }
- }
-
- project.checkConflictsInteractively(conflicts) {
- project.executeWriteCommand(text) {
- val kotlinPsiFactory = KtPsiFactory(project)
- val javaPsiFactory = PsiElementFactory.SERVICE.getInstance(project)
- val newKotlinCallExpr = kotlinPsiFactory.createExpression("$newName()")
-
- kotlinRefsToReplaceWithCall.forEach { it.replace(newKotlinCallExpr) }
- refsToRename.forEach { it.handleElementRename(newName) }
- javaRefsToReplaceWithCall.forEach {
- val getterRef = it.handleElementRename(newName)
- getterRef.replace(javaPsiFactory.createExpressionFromText("${getterRef.text}()", null))
- }
- callables.forEach {
- when (it) {
- is KtProperty -> convertProperty(it, kotlinPsiFactory)
- is PsiMethod -> it.name = newName
- }
- }
- }
- }
- }
- }
-
- override fun startInWriteAction(): Boolean = false
-
- override fun isApplicableTo(element: KtProperty, caretOffset: Int): Boolean {
- val identifier = element.nameIdentifier ?: return false
- if (!identifier.textRange.containsOffset(caretOffset)) return false
- return element.delegate == null && !element.isVar && !element.isLocal && (element.initializer == null || element.getter == null)
- }
-
- override fun applyTo(element: KtProperty, editor: Editor?) {
- val descriptor = element.resolveToDescriptorIfAny(BodyResolveMode.FULL) as? CallableDescriptor ?: return
- Converter(element.project, descriptor).run()
- }
-}