KT-12100 convert try / finally to use: safe close() is allowed in finally + correct new lines

This commit is contained in:
Mikhail Glukhikh
2016-12-01 19:23:18 +03:00
parent 0ac443066e
commit 0cc52e2ff8
9 changed files with 37 additions and 11 deletions

View File

@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.contentRange
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
@@ -40,7 +39,7 @@ class ConvertTryFinallyToUseCallIntention : SelfTargetingOffsetIndependentIntent
override fun applyTo(element: KtTryExpression, editor: Editor?) {
val finallySection = element.finallyBlock!!
val finallyExpression = finallySection.finalExpression.statements.single()
val finallyExpressionReceiver = (finallyExpression as? KtDotQualifiedExpression)?.receiverExpression
val finallyExpressionReceiver = (finallyExpression as? KtQualifiedExpression)?.receiverExpression
val resourceReference = finallyExpressionReceiver as? KtNameReferenceExpression
val resourceName = resourceReference?.getReferencedNameAsName()
@@ -61,9 +60,10 @@ class ConvertTryFinallyToUseCallIntention : SelfTargetingOffsetIndependentIntent
appendName(resourceName)
appendFixedText("->")
}
appendFixedText("\n")
appendChildRange(element.tryBlock.contentRange())
appendFixedText("}")
appendFixedText("\n}")
}
element.replace(useCallExpression)
@@ -77,8 +77,8 @@ class ConvertTryFinallyToUseCallIntention : SelfTargetingOffsetIndependentIntent
val context = element.analyze()
val resolvedCall = finallyExpression.getResolvedCall(context) ?: return false
if (resolvedCall.call.isSafeCall()) return false
if (resolvedCall.candidateDescriptor.name.asString() != "close") return false
if (resolvedCall.extensionReceiver != null) return false
val receiver = resolvedCall.dispatchReceiver ?: return false
if (receiver.type.supertypes().all {
it.constructor.declarationDescriptor?.fqNameSafe?.asString().let {

View File

@@ -3,5 +3,7 @@ import java.io.File
fun main(args: Array<String>) {
val reader = File("hello-world.txt").bufferedReader()
reader.use { reader -> // do stuff with reader }
reader.use { reader ->
// do stuff with reader
}
}

View File

@@ -3,5 +3,7 @@ import java.io.File
import java.io.BufferedReader
fun BufferedReader.foo() {
use { readLine() }
use {
readLine()
}
}

View File

@@ -3,5 +3,7 @@ import java.io.File
import java.io.BufferedReader
fun foo(reader: BufferedReader) {
reader.use { reader -> reader.readLine() }
reader.use { reader ->
reader.readLine()
}
}

View File

@@ -1,11 +1,13 @@
// IS_APPLICABLE: false
// WITH_RUNTIME
import java.io.File
import java.io.BufferedReader
fun bar() {}
fun foo(reader: BufferedReader?) {
try {
reader?.readLine()
bar()
}
<caret>finally {
reader?.close()

View File

@@ -0,0 +1,12 @@
// WITH_RUNTIME
import java.io.File
import java.io.BufferedReader
fun bar() {}
fun foo(reader: BufferedReader?) {
reader.use { reader ->
reader?.readLine()
bar()
}
}

View File

@@ -3,5 +3,7 @@ import java.io.File
fun main(args: Array<String>) {
val reader = File("hello-world.txt").bufferedReader()
reader.use { reader -> reader.readLine() }
reader.use { reader ->
reader.readLine()
}
}

View File

@@ -3,5 +3,7 @@ import java.io.File
import java.io.BufferedReader
fun BufferedReader.foo() {
this.use { this.readLine() }
this.use {
this.readLine()
}
}

View File

@@ -8,6 +8,8 @@ class MyCloseable : Closeable {
fun process(x: Int) = x
fun Int.foo() {
this@MyCloseable.use { this@MyCloseable.process(this) }
this@MyCloseable.use {
this@MyCloseable.process(this)
}
}
}