Migrate for moved and renamed buildSequence/buildIterator (KT-26679)

#KT-26679 Fixed
This commit is contained in:
Nikolay Krasko
2018-09-18 14:35:34 +03:00
parent 082801efb4
commit 64d2cdf0c2
6 changed files with 93 additions and 6 deletions
@@ -12,6 +12,7 @@ import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedRefactoringRequests
import org.jetbrains.kotlin.idea.configuration.MigrationInfo
import org.jetbrains.kotlin.idea.configuration.isLanguageVersionUpdate
import org.jetbrains.kotlin.idea.imports.importableFqName
@@ -52,10 +53,21 @@ class ObsoleteExperimentalCoroutinesInspection : AbstractKotlinInspection(), Cle
companion object {
private val PROBLEMS = listOf(
ObsoleteTopLevelFunctionUsage(
"buildSequence",
"kotlin.coroutines.experimental.buildSequence",
"kotlin.sequences.sequence"
),
ObsoleteTopLevelFunctionUsage(
"buildIterator",
"kotlin.coroutines.experimental.buildIterator",
"kotlin.sequences.iterator"
),
ObsoleteExtensionFunctionUsage(
"resume",
"kotlin.coroutines.experimental.Continuation.resume",
"kotlin.coroutines.resume"),
"kotlin.coroutines.resume"
),
ObsoleteExtensionFunctionUsage(
"resumeWithException",
"kotlin.coroutines.experimental.Continuation.resumeWithException",
@@ -87,6 +99,56 @@ private class ObsoleteCoroutineUsageFix(val delegate: CoroutineFix) : LocalQuick
}
}
private class ObsoleteTopLevelFunctionUsage(
val textMarker: String, val oldFqName: String, val newFqName: String
) : CoroutineMigrationProblem {
override fun report(holder: ProblemsHolder, isOnTheFly: Boolean, simpleNameExpression: KtSimpleNameExpression): Boolean {
if (simpleNameExpression.text != textMarker) return false
if (simpleNameExpression.parent !is KtCallExpression) return false
val descriptor = simpleNameExpression.resolveMainReferenceToDescriptors().firstOrNull() ?: return false
val callableDescriptor = descriptor as? CallableDescriptor ?: return false
val resolvedToFqName = callableDescriptor.fqNameOrNull()?.asString() ?: return false
if (resolvedToFqName != oldFqName) return false
val project = simpleNameExpression.project
KotlinTopLevelFunctionFqnNameIndex.getInstance()
.get(newFqName, project, GlobalSearchScope.allScope(project))
.asSequence()
.firstOrNull() ?: return false
val problemDescriptor = holder.manager.createProblemDescriptor(
simpleNameExpression,
simpleNameExpression,
"`$newFqName` is expected to be used since Kotlin 1.3",
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
isOnTheFly,
ObsoleteCoroutineUsageFix(fix)
)
holder.registerProblem(problemDescriptor)
return true
}
private val fix = RebindReferenceFix(newFqName)
companion object {
private class RebindReferenceFix(val fqName: String) : ObsoleteCoroutineUsageFix.Companion.CoroutineFix {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.psiElement
if (element !is KtSimpleNameExpression) return
element.mainReference.bindToFqName(FqName(fqName), KtSimpleNameReference.ShorteningMode.DELAYED_SHORTENING)
performDelayedRefactoringRequests(project)
}
}
}
}
private class ObsoleteExtensionFunctionUsage(
val textMarker: String, val oldFqName: String, newFqName: String
) : CoroutineMigrationProblem {
+5 -3
View File
@@ -1,8 +1,10 @@
// "Fix experimental coroutines usage" "true"
// ERROR: Unresolved reference: buildSequence
import kotlin.coroutines.<caret>experimental.buildSequence
// WITH_RUNTIME
package some
import kotlin.coroutines.experimental.buildSequence
fun main(args: Array<String>) {
val lazySeq = buildSequence<Int> {
val lazySeq = <caret>buildSequence<Int> {
}
}
@@ -1,7 +1,10 @@
// "Fix experimental coroutines usage" "true"
// ERROR: Unresolved reference: buildSequence
// WITH_RUNTIME
package some
import kotlin.coroutines.experimental.buildSequence
fun main(args: Array<String>) {
val lazySeq = buildSequence<Int> {
val lazySeq = sequence<Int> {
}
}
@@ -0,0 +1,8 @@
// "Fix experimental coroutines usage" "true"
// ERROR: Unresolved reference: buildSequence
import kotlin.coroutines.<caret>experimental.buildSequence
fun main(args: Array<String>) {
val lazySeq = buildSequence<Int> {
}
}
@@ -0,0 +1,7 @@
// "Fix experimental coroutines usage" "true"
// ERROR: Unresolved reference: buildSequence
fun main(args: Array<String>) {
val lazySeq = buildSequence<Int> {
}
}
@@ -8304,6 +8304,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
runTest("idea/testData/quickfix/obsoleteCoroutines/buildSequence.kt");
}
@TestMetadata("buildSequenceImport.kt")
public void testBuildSequenceImport() throws Exception {
runTest("idea/testData/quickfix/obsoleteCoroutines/buildSequenceImport.kt");
}
@TestMetadata("resume.kt")
public void testResume() throws Exception {
runTest("idea/testData/quickfix/obsoleteCoroutines/resume.kt");