diff --git a/plugins/kotlin/idea/resources-en/inspectionDescriptions/ReplaceWithImportAlias.html b/plugins/kotlin/idea/resources-en/inspectionDescriptions/ReplaceWithImportAlias.html
new file mode 100644
index 000000000000..f0e2bb362661
--- /dev/null
+++ b/plugins/kotlin/idea/resources-en/inspectionDescriptions/ReplaceWithImportAlias.html
@@ -0,0 +1,19 @@
+
+
+Reports fully qualified names that can be replaced with an existing import alias.
+Example:
+
+import foo.Foo as Bar
+fun main() {
+ foo.Foo()
+}
+
+After the quick-fix is applied:
+
+import foo.Foo as Bar
+fun main() {
+ Bar()
+}
+
+
+
diff --git a/plugins/kotlin/idea/resources-en/messages/KotlinBundle.properties b/plugins/kotlin/idea/resources-en/messages/KotlinBundle.properties
index e56f22547b6b..12121d021726 100644
--- a/plugins/kotlin/idea/resources-en/messages/KotlinBundle.properties
+++ b/plugins/kotlin/idea/resources-en/messages/KotlinBundle.properties
@@ -2375,3 +2375,6 @@ floating.point.literal.precision.inspection=Floating-point literal cannot be rep
inspection.replace.mapIndexed.with.list.generator.display.name=Replace 'mapIndexed' with List generator
should.be.replaced.with.list.generator=Should be replaced with List generator
replace.with.list.generator.fix.text=Replace with List generator
+
+inspection.replace.with.import.alias.display.name=Fully qualified name can be replaced with existing import alias
+replace.with.import.alias=Replace with import alias
diff --git a/plugins/kotlin/idea/resources/META-INF/inspections.xml b/plugins/kotlin/idea/resources/META-INF/inspections.xml
index d5490eb9445a..718a52280dc0 100644
--- a/plugins/kotlin/idea/resources/META-INF/inspections.xml
+++ b/plugins/kotlin/idea/resources/META-INF/inspections.xml
@@ -2672,6 +2672,14 @@
language="kotlin"
key="inspection.replace.mapIndexed.with.list.generator.display.name" bundle="messages.KotlinBundle"/>
+
+
\ No newline at end of file
diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceWithImportAliasInspection.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceWithImportAliasInspection.kt
new file mode 100644
index 000000000000..864977dc2a77
--- /dev/null
+++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceWithImportAliasInspection.kt
@@ -0,0 +1,51 @@
+// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+
+package org.jetbrains.kotlin.idea.inspections
+
+import com.intellij.codeInspection.LocalQuickFix
+import com.intellij.codeInspection.ProblemDescriptor
+import com.intellij.codeInspection.ProblemsHolder
+import com.intellij.openapi.project.Project
+import com.intellij.psi.PsiElement
+import com.intellij.psi.SmartPsiElementPointer
+import org.jetbrains.kotlin.idea.KotlinBundle
+import org.jetbrains.kotlin.idea.imports.importableFqName
+import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
+import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElement
+import org.jetbrains.kotlin.psi.psiUtil.isInImportDirective
+import org.jetbrains.kotlin.utils.addToStdlib.safeAs
+
+class ReplaceWithImportAliasInspection : AbstractKotlinInspection() {
+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) = simpleNameExpressionVisitor (fun(expression) {
+ if (expression !is KtNameReferenceExpression || expression.getIdentifier() == null || expression.isInImportDirective()) return
+ val qualifiedElement = expression.getQualifiedElement()
+ if (qualifiedElement !is KtDotQualifiedExpression && qualifiedElement !is KtUserType) return
+ val aliasNameIdentifier = expression.aliasNameIdentifier() ?: return
+ holder.registerProblem(
+ expression,
+ KotlinBundle.message("replace.with.import.alias"),
+ ReplaceWithImportAliasFix(aliasNameIdentifier.createSmartPointer(), aliasNameIdentifier.text)
+ )
+ })
+
+ private fun KtNameReferenceExpression.aliasNameIdentifier(): PsiElement? {
+ val fqName = resolveMainReferenceToDescriptors().firstOrNull()?.importableFqName ?: return null
+ return containingKtFile.findAliasByFqName(fqName)?.nameIdentifier
+ }
+
+ private class ReplaceWithImportAliasFix(
+ private val aliasNameIdentifierPointer: SmartPsiElementPointer,
+ private val aliasName: String
+ ): LocalQuickFix {
+ override fun getName() = KotlinBundle.message("replace.with.0", aliasName)
+ override fun getFamilyName() = name
+ override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
+ val expression = descriptor.psiElement as? KtNameReferenceExpression ?: return
+ val aliasNameIdentifier = aliasNameIdentifierPointer.element ?: return
+ expression.getIdentifier()?.replace(aliasNameIdentifier.copy())
+ expression.getQualifiedElement().replace(expression.parent.safeAs() ?: expression)
+ }
+ }
+}
diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java
index eb49d1d59d6e..64d31528aff6 100644
--- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java
+++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java
@@ -12978,6 +12978,54 @@ public abstract class LocalInspectionTestGenerated extends AbstractLocalInspecti
}
}
+ @RunWith(JUnit3RunnerWithInners.class)
+ @TestMetadata("testData/inspectionsLocal/replaceWithImportAlias")
+ public static class ReplaceWithImportAlias extends AbstractLocalInspectionTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
+ }
+
+ @TestMetadata("class.kt")
+ public void testClass() throws Exception {
+ runTest("testData/inspectionsLocal/replaceWithImportAlias/class.kt");
+ }
+
+ @TestMetadata("extension.kt")
+ public void testExtension() throws Exception {
+ runTest("testData/inspectionsLocal/replaceWithImportAlias/extension.kt");
+ }
+
+ @TestMetadata("function.kt")
+ public void testFunction() throws Exception {
+ runTest("testData/inspectionsLocal/replaceWithImportAlias/function.kt");
+ }
+
+ @TestMetadata("inImport.kt")
+ public void testInImport() throws Exception {
+ runTest("testData/inspectionsLocal/replaceWithImportAlias/inImport.kt");
+ }
+
+ @TestMetadata("multipleAliases.kt")
+ public void testMultipleAliases() throws Exception {
+ runTest("testData/inspectionsLocal/replaceWithImportAlias/multipleAliases.kt");
+ }
+
+ @TestMetadata("notQualifed.kt")
+ public void testNotQualifed() throws Exception {
+ runTest("testData/inspectionsLocal/replaceWithImportAlias/notQualifed.kt");
+ }
+
+ @TestMetadata("property.kt")
+ public void testProperty() throws Exception {
+ runTest("testData/inspectionsLocal/replaceWithImportAlias/property.kt");
+ }
+
+ @TestMetadata("type.kt")
+ public void testType() throws Exception {
+ runTest("testData/inspectionsLocal/replaceWithImportAlias/type.kt");
+ }
+ }
+
@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("testData/inspectionsLocal/replaceWithOperatorAssignment")
public static class ReplaceWithOperatorAssignment extends AbstractLocalInspectionTest {
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/.inspection b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/.inspection
new file mode 100644
index 000000000000..365d2bd9e3ee
--- /dev/null
+++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/.inspection
@@ -0,0 +1 @@
+org.jetbrains.kotlin.idea.inspections.ReplaceWithImportAliasInspection
\ No newline at end of file
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/class.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/class.kt
new file mode 100644
index 000000000000..a2aa3dc65900
--- /dev/null
+++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/class.kt
@@ -0,0 +1,10 @@
+package foo
+
+import foo.Foo as Bar
+
+class Foo
+
+fun main() {
+ foo.Foo()
+ foo.Foo()
+}
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/class.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/class.kt.after
new file mode 100644
index 000000000000..6ed34da8545d
--- /dev/null
+++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/class.kt.after
@@ -0,0 +1,10 @@
+package foo
+
+import foo.Foo as Bar
+
+class Foo
+
+fun main() {
+ Bar()
+ foo.Foo()
+}
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/extension.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/extension.kt
new file mode 100644
index 000000000000..34445905fe5c
--- /dev/null
+++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/extension.kt
@@ -0,0 +1,7 @@
+package foo
+
+import foo.Foo as Bar
+
+class Foo
+
+fun foo.Foo.test() {}
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/extension.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/extension.kt.after
new file mode 100644
index 000000000000..e36962f5c979
--- /dev/null
+++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/extension.kt.after
@@ -0,0 +1,7 @@
+package foo
+
+import foo.Foo as Bar
+
+class Foo
+
+fun Bar.test() {}
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/function.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/function.kt
new file mode 100644
index 000000000000..197f7f3662fb
--- /dev/null
+++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/function.kt
@@ -0,0 +1,10 @@
+package foo
+
+import foo.foo as bar
+
+fun foo() {}
+
+fun main() {
+ foo.foo()
+ foo.foo()
+}
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/function.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/function.kt.after
new file mode 100644
index 000000000000..48f15ad1eb50
--- /dev/null
+++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/function.kt.after
@@ -0,0 +1,10 @@
+package foo
+
+import foo.foo as bar
+
+fun foo() {}
+
+fun main() {
+ bar()
+ foo.foo()
+}
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/inImport.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/inImport.kt
new file mode 100644
index 000000000000..844a05b1fdb5
--- /dev/null
+++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/inImport.kt
@@ -0,0 +1,6 @@
+// PROBLEM: none
+package foo
+
+import foo.Foo as Bar
+
+class Foo
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/multipleAliases.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/multipleAliases.kt
new file mode 100644
index 000000000000..ff8cdd17a852
--- /dev/null
+++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/multipleAliases.kt
@@ -0,0 +1,10 @@
+package foo
+
+import foo.Foo as Bar
+import foo.Foo as Baz
+
+class Foo
+
+fun main() {
+ foo.Foo()
+}
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/multipleAliases.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/multipleAliases.kt.after
new file mode 100644
index 000000000000..67b7dcf67eae
--- /dev/null
+++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/multipleAliases.kt.after
@@ -0,0 +1,10 @@
+package foo
+
+import foo.Foo as Bar
+import foo.Foo as Baz
+
+class Foo
+
+fun main() {
+ Bar()
+}
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/notQualifed.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/notQualifed.kt
new file mode 100644
index 000000000000..d2b8be6f0e37
--- /dev/null
+++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/notQualifed.kt
@@ -0,0 +1,10 @@
+// PROBLEM: none
+package foo
+
+import foo.Foo as Bar
+
+class Foo
+
+fun main() {
+ Bar()
+}
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/property.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/property.kt
new file mode 100644
index 000000000000..016af8f49c0e
--- /dev/null
+++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/property.kt
@@ -0,0 +1,10 @@
+package foo
+
+import foo.foo as bar
+
+val foo = 1
+
+fun main() {
+ foo.foo
+ foo.foo
+}
\ No newline at end of file
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/property.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/property.kt.after
new file mode 100644
index 000000000000..ab56d1769c56
--- /dev/null
+++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/property.kt.after
@@ -0,0 +1,10 @@
+package foo
+
+import foo.foo as bar
+
+val foo = 1
+
+fun main() {
+ foo.foo
+ bar
+}
\ No newline at end of file
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/type.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/type.kt
new file mode 100644
index 000000000000..29d73dafd069
--- /dev/null
+++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/type.kt
@@ -0,0 +1,7 @@
+package foo
+
+import foo.Foo as Bar
+
+class Foo
+
+fun test(): foo.Foo? = null
diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/type.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/type.kt.after
new file mode 100644
index 000000000000..acb29e81710e
--- /dev/null
+++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceWithImportAlias/type.kt.after
@@ -0,0 +1,7 @@
+package foo
+
+import foo.Foo as Bar
+
+class Foo
+
+fun test(): Bar? = null