From 986eaeb7ea283a98b76442c913d85f695a423e64 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Wed, 24 May 2017 23:16:45 +0300 Subject: [PATCH] Refactoring --- .../inline/KotlinInlineFunctionHandler.kt | 10 ++++- .../inline/KotlinInlineValHandler.kt | 41 +++++-------------- .../idea/refactoring/inline/inlineUtils.kt | 21 ++++++---- 3 files changed, 31 insertions(+), 41 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineFunctionHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineFunctionHandler.kt index 36a41757d98..66c87c7054a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineFunctionHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineFunctionHandler.kt @@ -32,7 +32,6 @@ import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.codeInliner.CallableUsageReplacementStrategy -import org.jetbrains.kotlin.idea.codeInliner.PropertyUsageReplacementStrategy import org.jetbrains.kotlin.idea.references.KtSimpleNameReference import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtNamedFunction @@ -64,7 +63,14 @@ class KotlinInlineFunctionHandler: InlineActionHandler() { } val descriptor = element.resolveToDescriptor() as SimpleFunctionDescriptor - val codeToInline = buildCodeToInline(element, descriptor.returnType, editor) ?: return + val codeToInline = buildCodeToInline( + element, + descriptor.returnType, + element.hasDeclaredReturnType(), + element.bodyExpression!!, + element.hasBlockBody(), + editor + ) ?: return val replacementStrategy = CallableUsageReplacementStrategy(codeToInline) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt index 10a32c6a7f0..71c72381f9c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt @@ -29,22 +29,16 @@ import com.intellij.refactoring.HelpID import com.intellij.refactoring.RefactoringBundle import com.intellij.refactoring.util.CommonRefactoringUtil import com.intellij.util.containers.MultiMap -import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.descriptors.VariableDescriptor +import org.jetbrains.kotlin.descriptors.ValueDescriptor import org.jetbrains.kotlin.idea.KotlinLanguage -import org.jetbrains.kotlin.idea.analysis.analyzeInContext -import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.codeInliner.CodeToInline -import org.jetbrains.kotlin.idea.codeInliner.CodeToInlineBuilder import org.jetbrains.kotlin.idea.codeInliner.PropertyUsageReplacementStrategy -import org.jetbrains.kotlin.idea.core.copied import org.jetbrains.kotlin.idea.project.builtIns import org.jetbrains.kotlin.idea.refactoring.checkConflictsInteractively import org.jetbrains.kotlin.idea.references.KtSimpleNameReference import org.jetbrains.kotlin.idea.references.ReferenceAccess import org.jetbrains.kotlin.idea.references.readWriteAccess -import org.jetbrains.kotlin.idea.util.getResolutionScope import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtElement @@ -52,8 +46,6 @@ import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.types.TypeUtils class KotlinInlineValHandler : InlineActionHandler() { @@ -93,16 +85,21 @@ class KotlinInlineValHandler : InlineActionHandler() { val readReplacement: CodeToInline? val writeReplacement: CodeToInline? val assignmentToDelete: KtBinaryExpression? + val descriptor = declaration.resolveToDescriptor() as ValueDescriptor + val isTypeExplicit = declaration.typeReference != null if (getter == null && setter == null) { val initialization = extractInitialization(declaration, referenceExpressions, project, editor) ?: return - readReplacement = buildCodeToInline(declaration, initialization.value) + readReplacement = buildCodeToInline(declaration, descriptor.type, isTypeExplicit, initialization.value, false, editor) ?: return writeReplacement = null assignmentToDelete = initialization.assignment } else { - val descriptor = declaration.resolveToDescriptor() as PropertyDescriptor - readReplacement = getter?.let { buildCodeToInline(getter, descriptor.type, editor) ?: return } - writeReplacement = setter?.let { buildCodeToInline(setter, setter.builtIns.unitType, editor) ?: return } + readReplacement = getter?.let { + buildCodeToInline(getter, descriptor.type, isTypeExplicit, getter.bodyExpression!!, getter.hasBlockBody(), editor) ?: return + } + writeReplacement = setter?.let { + buildCodeToInline(setter, setter.builtIns.unitType, true, setter.bodyExpression!!, setter.hasBlockBody(), editor) ?: return + } assignmentToDelete = null } @@ -175,24 +172,6 @@ class KotlinInlineValHandler : InlineActionHandler() { } } - private fun buildCodeToInline(declaration: KtProperty, initializer: KtExpression): CodeToInline { - val descriptor = declaration.resolveToDescriptor() as VariableDescriptor - val expectedType = if (declaration.typeReference != null) - descriptor.returnType ?: TypeUtils.NO_EXPECTED_TYPE - else - TypeUtils.NO_EXPECTED_TYPE - - val initializerCopy = initializer.copied() - fun analyzeInitializerCopy(): BindingContext { - return initializerCopy.analyzeInContext(initializer.getResolutionScope(), - contextExpression = initializer, - expectedType = expectedType) - } - - val codeToInlineBuilder = CodeToInlineBuilder(descriptor, declaration.getResolutionFacade()) - return codeToInlineBuilder.prepareCodeToInline(initializerCopy, emptyList(), ::analyzeInitializerCopy) - } - private fun performRefactoring( declaration: KtProperty, readReplacement: CodeToInline?, diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/inlineUtils.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/inlineUtils.kt index de49cf3fbd9..0581925b25c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/inlineUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/inlineUtils.kt @@ -29,7 +29,6 @@ import com.intellij.refactoring.util.CommonRefactoringUtil import com.intellij.refactoring.util.RefactoringMessageDialog import com.intellij.usageView.UsageInfo import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.idea.analysis.analyzeInContext import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor @@ -114,24 +113,30 @@ internal fun postProcessInternalReferences(inlinedElement: E): E return pointer.element } -internal fun buildCodeToInline(declaration: KtDeclarationWithBody, returnType: KotlinType?, editor: Editor?): CodeToInline? { - val bodyExpression = declaration.bodyExpression!! - val bodyCopy = bodyExpression.copied() +internal fun buildCodeToInline( + declaration: KtDeclaration, + returnType: KotlinType?, + isReturnTypeExplicit: Boolean, + bodyOrInitializer: KtExpression, + isBlockBody: Boolean, + editor: Editor? +): CodeToInline? { + val bodyCopy = bodyOrInitializer.copied() - val expectedType = if (!declaration.hasBlockBody() && declaration.hasDeclaredReturnType()) + val expectedType = if (!isBlockBody && isReturnTypeExplicit) returnType ?: TypeUtils.NO_EXPECTED_TYPE else TypeUtils.NO_EXPECTED_TYPE fun analyzeBodyCopy(): BindingContext { - return bodyCopy.analyzeInContext(bodyExpression.getResolutionScope(), - contextExpression = bodyExpression, + return bodyCopy.analyzeInContext(bodyOrInitializer.getResolutionScope(), + contextExpression = bodyOrInitializer, expectedType = expectedType) } val descriptor = declaration.resolveToDescriptor() val builder = CodeToInlineBuilder(descriptor as CallableDescriptor, declaration.getResolutionFacade()) - if (declaration.hasBlockBody()) { + if (isBlockBody) { bodyCopy as KtBlockExpression val statements = bodyCopy.statements