KT-39869 Add inspection for FQN usages of kotlin.browser package
- `kotlin.dom` does not need this because it contains only extensions - Add test for launching whole project fix; mute it because currently it does not pass - The test fails because in tests `RefJavaManager` tries to create `RefJavaFileImpl` for .kt files. It will try to use UAST, but it does not work for JS files. In production this is disabled, so no problems occur
This commit is contained in:
committed by
Roman Golyshev
parent
91fa5d38b3
commit
5cf6b860a6
+57
-1
@@ -6,14 +6,23 @@
|
||||
package org.jetbrains.kotlin.idea.inspections.migration
|
||||
|
||||
import com.intellij.codeInspection.*
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.backend.common.serialization.findPackage
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedRefactoringRequests
|
||||
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
|
||||
internal class ObsoleteKotlinJsPackagesInspection : ObsoleteCodeMigrationInspection() {
|
||||
override val fromVersion: LanguageVersion = LanguageVersion.KOTLIN_1_3
|
||||
override val toVersion: LanguageVersion = LanguageVersion.KOTLIN_1_4
|
||||
|
||||
override val problemReporters: List<ObsoleteCodeProblemReporter> = listOf(
|
||||
KotlinBrowserFullyQualifiedUsageReporter,
|
||||
KotlinBrowserImportUsageReporter,
|
||||
KotlinDomImportUsageReporter
|
||||
)
|
||||
@@ -25,6 +34,7 @@ private object ObsoleteKotlinJsPackagesUsagesInWholeProjectFix : ObsoleteCodeInW
|
||||
}
|
||||
|
||||
private const val KOTLIN_BROWSER_PACKAGE = "kotlin.browser"
|
||||
private const val KOTLINX_BROWSER_PACKAGE = "kotlinx.browser"
|
||||
private const val KOTLIN_DOM_PACKAGE = "kotlin.dom"
|
||||
|
||||
private class ObsoleteKotlinBrowserUsageFix(delegate: ObsoleteCodeFix) : ObsoleteCodeFixDelegateQuickFix(delegate) {
|
||||
@@ -35,9 +45,55 @@ private class ObsoleteKotlinDomUsageFix(delegate: ObsoleteCodeFix) : ObsoleteCod
|
||||
override fun getFamilyName(): String = KotlinBundle.message("obsolete.package.usage.fix.family.name", KOTLIN_DOM_PACKAGE)
|
||||
}
|
||||
|
||||
/**
|
||||
* We have such inspection only for 'kotlin.browser' package; it is because 'kotlin.dom' package has only extension functions. Such
|
||||
* functions cannot be used with fully qualified name.
|
||||
*/
|
||||
private object KotlinBrowserFullyQualifiedUsageReporter : ObsoleteCodeProblemReporter {
|
||||
override fun report(holder: ProblemsHolder, isOnTheFly: Boolean, simpleNameExpression: KtSimpleNameExpression): Boolean {
|
||||
val fullyQualifiedExpression = simpleNameExpression.parent as? KtDotQualifiedExpression ?: return false
|
||||
|
||||
val kotlinBrowserQualifier = fullyQualifiedExpression.receiverExpression as? KtDotQualifiedExpression ?: return false
|
||||
if (kotlinBrowserQualifier.text != KOTLIN_BROWSER_PACKAGE) return false
|
||||
|
||||
if (!resolvesToKotlinBrowserPackage(simpleNameExpression)) return false
|
||||
|
||||
holder.registerProblem(
|
||||
kotlinBrowserQualifier,
|
||||
KotlinBundle.message("package.usages.are.obsolete.since.1.4", KOTLIN_DOM_PACKAGE),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
*fixesWithWholeProject(
|
||||
isOnTheFly,
|
||||
fix = ObsoleteKotlinBrowserUsageFix(KotlinBrowserFullyQualifiedUsageFix),
|
||||
wholeProjectFix = ObsoleteKotlinJsPackagesUsagesInWholeProjectFix
|
||||
)
|
||||
)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun resolvesToKotlinBrowserPackage(simpleNameExpression: KtSimpleNameExpression): Boolean {
|
||||
val referencedDescriptor =
|
||||
simpleNameExpression.resolveMainReferenceToDescriptors().singleOrNull() as? CallableDescriptor ?: return false
|
||||
|
||||
return referencedDescriptor.findPackage().fqName.asString() == KOTLIN_BROWSER_PACKAGE
|
||||
}
|
||||
|
||||
object KotlinBrowserFullyQualifiedUsageFix : ObsoleteCodeFix {
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val oldQualifier = descriptor.psiElement as? KtDotQualifiedExpression ?: return
|
||||
|
||||
val newQualifier = KtPsiFactory(oldQualifier).createExpression(KOTLINX_BROWSER_PACKAGE)
|
||||
oldQualifier.replace(newQualifier)
|
||||
|
||||
performDelayedRefactoringRequests(project)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private object KotlinBrowserImportUsageReporter : ObsoleteImportsUsageReporter() {
|
||||
override val textMarker: String = "browser"
|
||||
override val packageBindings: Map<String, String> = mapOf(KOTLIN_BROWSER_PACKAGE to "kotlinx.browser")
|
||||
override val packageBindings: Map<String, String> = mapOf(KOTLIN_BROWSER_PACKAGE to KOTLINX_BROWSER_PACKAGE)
|
||||
|
||||
override val wholeProjectFix: LocalQuickFix = ObsoleteKotlinJsPackagesUsagesInWholeProjectFix
|
||||
override fun problemMessage(): String = KotlinBundle.message("package.usages.are.obsolete.since.1.4", KOTLIN_BROWSER_PACKAGE)
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Fix 'kotlin.browser' package usage" "true"
|
||||
// JS
|
||||
|
||||
package test
|
||||
|
||||
fun use(a: Any) {}
|
||||
|
||||
fun usage() {
|
||||
use(kotlin.<caret>browser.localStorage.toString())
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
// "Fix 'kotlin.browser' package usage" "true"
|
||||
// JS
|
||||
|
||||
package test
|
||||
|
||||
fun use(a: Any) {}
|
||||
|
||||
fun usage() {
|
||||
use(kotlinx.browser.localStorage.toString())
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// "Fix 'kotlin.dom' and 'kotlin.browser' packages usages in the project" "true"
|
||||
// JS
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.<caret>browser.localStorage
|
||||
import kotlin.dom.addClass
|
||||
|
||||
fun usage() {
|
||||
kotlin.browser.document.toString()
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// "Fix 'kotlin.dom' and 'kotlin.browser' packages usages in the project" "true"
|
||||
// JS
|
||||
|
||||
package test
|
||||
|
||||
import kotlinx.browser.localStorage
|
||||
import kotlinx.dom.addClass
|
||||
|
||||
fun usage() {
|
||||
kotlinx.browser.document.toString()
|
||||
}
|
||||
@@ -9898,6 +9898,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/quickfix/obsoleteKotlinJsPackages"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("kotlinBrowserFullyQualifiedProperty.kt")
|
||||
public void testKotlinBrowserFullyQualifiedProperty() throws Exception {
|
||||
runTest("idea/testData/quickfix/obsoleteKotlinJsPackages/kotlinBrowserFullyQualifiedProperty.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlinBrowserPropertyImport.kt")
|
||||
public void testKotlinBrowserPropertyImport() throws Exception {
|
||||
runTest("idea/testData/quickfix/obsoleteKotlinJsPackages/kotlinBrowserPropertyImport.kt");
|
||||
@@ -9908,6 +9913,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
runTest("idea/testData/quickfix/obsoleteKotlinJsPackages/kotlinBrowserStarImport.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlinDomAndBrowserImport.kt")
|
||||
public void testKotlinDomAndBrowserImport() throws Exception {
|
||||
runTest("idea/testData/quickfix/obsoleteKotlinJsPackages/kotlinDomAndBrowserImport.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kotlinDomPropertyImport.kt")
|
||||
public void testKotlinDomPropertyImport() throws Exception {
|
||||
runTest("idea/testData/quickfix/obsoleteKotlinJsPackages/kotlinDomPropertyImport.kt");
|
||||
|
||||
@@ -45,6 +45,7 @@ org.jetbrains.kotlin.idea.quickfix.QuickFixMultiModuleTestGenerated.CreateActual
|
||||
org.jetbrains.kotlin.idea.quickfix.QuickFixTestGenerated.CreateFromUsage.CreateClass.CallExpression.testCallInWhenEntry, KT-35728,,
|
||||
org.jetbrains.kotlin.idea.quickfix.QuickFixTestGenerated.Libraries.testJunit, ERROR: Couldn't find the following libraries,,
|
||||
org.jetbrains.kotlin.idea.quickfix.QuickFixTestGenerated.Libraries.testTestNG, ERROR: Couldn't find the following libraries,,
|
||||
org.jetbrains.kotlin.idea.quickfix.QuickFixTestGenerated.ObsoleteKotlinJsPackages.testKotlinDomAndBrowserImport, Always red because UAST does not work with JS,,
|
||||
org.jetbrains.kotlin.idea.refactoring.move.MultiModuleMoveTestGenerated.testMoveFromJvmModuleToJsModule_MoveFromJvmModuleToJsModule, KT-34106,,
|
||||
org.jetbrains.kotlin.idea.refactoring.move.MultiModuleMoveTestGenerated.testMoveJdkDependentToJsModule_MoveJdkDependentToJsModule, KT-34106,,
|
||||
org.jetbrains.kotlin.idea.resolve.PartialBodyResolveTestGenerated.testSmartCastInTheSameStatement, KT-35922,,
|
||||
|
||||
|
Reference in New Issue
Block a user