Do not inline property setter if it's not required (e.g. ReplaceWith)

So #KT-21237 Fixed
This commit is contained in:
Mikhail Glukhikh
2017-11-28 13:24:51 +03:00
parent bddaab9d48
commit 834c3fe62b
10 changed files with 20 additions and 14 deletions
@@ -24,7 +24,10 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class CallableUsageReplacementStrategy(private val replacement: CodeToInline) : UsageReplacementStrategy {
class CallableUsageReplacementStrategy(
private val replacement: CodeToInline,
private val inlineSetter: Boolean = false
) : UsageReplacementStrategy {
override fun createReplacer(usage: KtSimpleNameExpression): (() -> KtElement?)? {
val bindingContext = usage.analyze(BodyResolveMode.PARTIAL)
val resolvedCall = usage.getResolvedCall(bindingContext) ?: return null
@@ -48,7 +51,7 @@ class CallableUsageReplacementStrategy(private val replacement: CodeToInline) :
createReplacer(nameExpression)?.invoke()
}
else {
CodeInliner(usage, bindingContext, resolvedCall, callElement, replacement).doInline()
CodeInliner(usage, bindingContext, resolvedCall, callElement, inlineSetter, replacement).doInline()
}
}
}
@@ -33,7 +33,9 @@ class ClassUsageReplacementStrategy(
private val typeReplacement = typeReplacement?.takeIf { it.referenceExpression != null }
private val typeReplacementQualifierAsExpression = typeReplacement?.qualifier?.let { factory.createExpression(it.text) }
private val constructorReplacementStrategy = constructorReplacement?.let(::CallableUsageReplacementStrategy)
private val constructorReplacementStrategy = constructorReplacement?.let {
CallableUsageReplacementStrategy(it, inlineSetter = false)
}
override fun createReplacer(usage: KtSimpleNameExpression): (() -> KtElement?)? {
if (usage !is KtNameReferenceExpression) return null
@@ -52,6 +52,7 @@ class CodeInliner<TCallElement : KtElement>(
private val bindingContext: BindingContext,
private val resolvedCall: ResolvedCall<out CallableDescriptor>,
private val callElement: TCallElement,
private val inlineSetter: Boolean,
codeToInline: CodeToInline
) {
private val codeToInline = codeToInline.toMutable()
@@ -67,7 +68,7 @@ class CodeInliner<TCallElement : KtElement>(
?.getAssignmentByLHS()
?.takeIf { it.operationToken == KtTokens.EQ }
val callableForParameters = if (assignment != null && descriptor is PropertyDescriptor)
descriptor.setter?.takeIf { it.hasBody() } ?: descriptor
descriptor.setter?.takeIf { inlineSetter && it.hasBody() } ?: descriptor
else
descriptor
val elementToBeReplaced = assignment.takeIf { callableForParameters is PropertySetterDescriptor } ?: qualifiedElement
@@ -22,8 +22,12 @@ import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
class PropertyUsageReplacementStrategy(readReplacement: CodeToInline?, writeReplacement: CodeToInline?) : UsageReplacementStrategy {
private val readReplacementStrategy = readReplacement?.let { CallableUsageReplacementStrategy(it) }
private val writeReplacementStrategy = writeReplacement?.let { CallableUsageReplacementStrategy(it) }
private val readReplacementStrategy = readReplacement?.let {
CallableUsageReplacementStrategy(it, inlineSetter = false)
}
private val writeReplacementStrategy = writeReplacement?.let {
CallableUsageReplacementStrategy(it, inlineSetter = true)
}
override fun createReplacer(usage: KtSimpleNameExpression): (() -> KtElement?)? {
val access = usage.readWriteAccess(useResolveForReadWrite = true)
@@ -141,7 +141,7 @@ abstract class DeprecatedSymbolUsageFixBase(
val resolvedCall = element.getResolvedCall(bindingContext) ?: return null
if (!resolvedCall.isReallySuccess()) return null
val replacement = ReplaceWithAnnotationAnalyzer.analyzeCallableReplacement(replaceWith, target, resolutionFacade) ?: return null
return CallableUsageReplacementStrategy(replacement)
return CallableUsageReplacementStrategy(replacement, inlineSetter = false)
}
is ClassifierDescriptorWithTypeParameters -> {
@@ -72,7 +72,7 @@ class KotlinInlineFunctionHandler: InlineActionHandler() {
editor
) ?: return
val replacementStrategy = CallableUsageReplacementStrategy(codeToInline)
val replacementStrategy = CallableUsageReplacementStrategy(codeToInline, inlineSetter = false)
val dialog = KotlinInlineFunctionDialog(project, element, nameReference, replacementStrategy,
allowInlineThisOnly = recursive)
@@ -14,6 +14,5 @@ class A {
fun foo() {
val a = A()
// Works incorrectly yet
a.<caret>old = "foo"
}
@@ -14,6 +14,5 @@ class A {
fun foo() {
val a = A()
// Works incorrectly yet
a.new
a.new = "foo"
}
@@ -15,7 +15,6 @@ class A {
fun foo() {
val a = A()
a.apply {
// Works incorrectly yet
<caret>old = "foo"
}
}
@@ -15,7 +15,6 @@ class A {
fun foo() {
val a = A()
a.apply {
// Works incorrectly yet
new
new = "foo"
}
}