From 0f9858bb75a1d840b43bdfe0f0b509ffad199507 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Fri, 10 Apr 2015 18:52:10 +0300 Subject: [PATCH] Code style setting to import nested classes --- .../core/formatter/JetCodeStyleSettings.java | 1 + .../idea/util/ImportInsertHelperImpl.kt | 37 +++++++++---------- .../addImport/DoNotImportNestedClass.kt | 1 + .../addImport/DoNotImportNestedClass.kt.after | 1 + idea/testData/addImport/ImportNestedClass.kt | 2 + .../addImport/ImportNestedClass.kt.after | 4 ++ .../jetbrains/kotlin/AbstractImportsTest.kt | 20 ++++++---- .../addImport/AddImportTestGenerated.java | 12 ++++++ 8 files changed, 51 insertions(+), 27 deletions(-) create mode 100644 idea/testData/addImport/DoNotImportNestedClass.kt create mode 100644 idea/testData/addImport/DoNotImportNestedClass.kt.after create mode 100644 idea/testData/addImport/ImportNestedClass.kt create mode 100644 idea/testData/addImport/ImportNestedClass.kt.after diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/formatter/JetCodeStyleSettings.java b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/formatter/JetCodeStyleSettings.java index bc3d8dbb6e6..298c6840f2e 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/formatter/JetCodeStyleSettings.java +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/formatter/JetCodeStyleSettings.java @@ -44,6 +44,7 @@ public class JetCodeStyleSettings extends CustomCodeStyleSettings { public int NAME_COUNT_TO_USE_STAR_IMPORT = ApplicationManager.getApplication().isUnitTestMode() ? Integer.MAX_VALUE : 5; public boolean IMPORT_PACKAGES = true; + public boolean IMPORT_NESTED_CLASSES = false; public static JetCodeStyleSettings getInstance(Project project) { return CodeStyleSettingsManager.getSettings(project).getCustomSettings(JetCodeStyleSettings.class); diff --git a/idea/src/org/jetbrains/kotlin/idea/util/ImportInsertHelperImpl.kt b/idea/src/org/jetbrains/kotlin/idea/util/ImportInsertHelperImpl.kt index 091a76ba3a4..416e17ce6e0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/util/ImportInsertHelperImpl.kt +++ b/idea/src/org/jetbrains/kotlin/idea/util/ImportInsertHelperImpl.kt @@ -139,13 +139,18 @@ public class ImportInsertHelperImpl(private val project: Project) : ImportInsert val importable = descriptor.getImportableDescriptor() return when (importable) { is PackageViewDescriptor -> JetCodeStyleSettings.getInstance(project).IMPORT_PACKAGES - else -> importable.getContainingDeclaration() is PackageFragmentDescriptor // do not import nested classes and non-top-level declarations + + is ClassDescriptor -> { + importable.getContainingDeclaration() is PackageFragmentDescriptor + || JetCodeStyleSettings.getInstance(project).IMPORT_NESTED_CLASSES + } + + else -> importable.getContainingDeclaration() is PackageFragmentDescriptor // do not import members (e.g. java static members) } } - override fun importDescriptor(file: JetFile, descriptor: DeclarationDescriptor): ImportDescriptorResult { - return Importer(file).importDescriptor(descriptor) - } + override fun importDescriptor(file: JetFile, descriptor: DeclarationDescriptor) + = Importer(file).importDescriptor(descriptor) private inner class Importer( private val file: JetFile @@ -155,11 +160,11 @@ public class ImportInsertHelperImpl(private val project: Project) : ImportInsert fun importDescriptor(descriptor: DeclarationDescriptor): ImportDescriptorResult { val target = descriptor.getImportableDescriptor() + if (!target.canBeReferencedViaImport()) return ImportDescriptorResult.FAIL val name = target.getName() val topLevelScope = resolutionFacade.getFileTopLevelScope(file) - - val targetFqName = target.importableFqName ?: return ImportDescriptorResult.FAIL + val targetFqName = target.importableFqNameSafe // check if import is not needed when (target) { @@ -174,11 +179,6 @@ public class ImportInsertHelperImpl(private val project: Project) : ImportInsert return ImportDescriptorResult.FAIL } - // cannot import for non-top level function or property - if (target is CallableDescriptor && target.getContainingDeclaration() !is PackageFragmentDescriptor) { - return ImportDescriptorResult.FAIL - } - val imports = if (file is JetCodeFragment) file.importsAsImportList()?.getImports() ?: listOf() else @@ -379,16 +379,13 @@ public class ImportInsertHelperImpl(private val project: Project) : ImportInsert return result } - private fun targetFqName(ref: JetReferenceExpression): FqName? { - return ref.resolveTargets().map { it.importableFqName }.toSet().singleOrNull() - } + private fun targetFqName(ref: JetReferenceExpression): FqName? + = ref.resolveTargets().map { it.importableFqName }.toSet().singleOrNull() - private fun JetReferenceExpression.resolveTargets(): Collection { - return this.getImportableTargets(resolutionFacade.analyze(this, BodyResolveMode.PARTIAL)) - } + private fun JetReferenceExpression.resolveTargets(): Collection + = this.getImportableTargets(resolutionFacade.analyze(this, BodyResolveMode.PARTIAL)) - private fun addImport(fqName: FqName, allUnder: Boolean): JetImportDirective { - return addImport(file, ImportPath(fqName, allUnder)) - } + private fun addImport(fqName: FqName, allUnder: Boolean): JetImportDirective + = addImport(file, ImportPath(fqName, allUnder)) } } diff --git a/idea/testData/addImport/DoNotImportNestedClass.kt b/idea/testData/addImport/DoNotImportNestedClass.kt new file mode 100644 index 00000000000..a8315a8b19a --- /dev/null +++ b/idea/testData/addImport/DoNotImportNestedClass.kt @@ -0,0 +1 @@ +// IMPORT: kotlin.Map.Entry diff --git a/idea/testData/addImport/DoNotImportNestedClass.kt.after b/idea/testData/addImport/DoNotImportNestedClass.kt.after new file mode 100644 index 00000000000..81c2e19b906 --- /dev/null +++ b/idea/testData/addImport/DoNotImportNestedClass.kt.after @@ -0,0 +1 @@ +Failed to add import diff --git a/idea/testData/addImport/ImportNestedClass.kt b/idea/testData/addImport/ImportNestedClass.kt new file mode 100644 index 00000000000..9f06e411bf9 --- /dev/null +++ b/idea/testData/addImport/ImportNestedClass.kt @@ -0,0 +1,2 @@ +// IMPORT: kotlin.Map.Entry +// IMPORT_NESTED_CLASSES: true diff --git a/idea/testData/addImport/ImportNestedClass.kt.after b/idea/testData/addImport/ImportNestedClass.kt.after new file mode 100644 index 00000000000..0f5940edd65 --- /dev/null +++ b/idea/testData/addImport/ImportNestedClass.kt.after @@ -0,0 +1,4 @@ +import kotlin.Map.* + +// IMPORT: kotlin.Map.Entry +// IMPORT_NESTED_CLASSES: true diff --git a/idea/tests/org/jetbrains/kotlin/AbstractImportsTest.kt b/idea/tests/org/jetbrains/kotlin/AbstractImportsTest.kt index f1106bfaafb..d964434aae2 100644 --- a/idea/tests/org/jetbrains/kotlin/AbstractImportsTest.kt +++ b/idea/tests/org/jetbrains/kotlin/AbstractImportsTest.kt @@ -17,11 +17,11 @@ package org.jetbrains.kotlin import com.intellij.codeInsight.CodeInsightSettings -import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.command.CommandProcessor +import org.jdom.Element import org.jetbrains.kotlin.idea.JetLightCodeInsightFixtureTestCase import org.jetbrains.kotlin.idea.JetWithJdkAndRuntimeLightProjectDescriptor import org.jetbrains.kotlin.idea.core.formatter.JetCodeStyleSettings +import org.jetbrains.kotlin.idea.testUtils.dumpTextWithErrors import org.jetbrains.kotlin.idea.util.application.executeWriteCommand import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.test.InTextDirectivesUtils @@ -35,8 +35,8 @@ public abstract class AbstractImportsTest : JetLightCodeInsightFixtureTestCase() protected fun doTest(testPath: String) { val codeInsightSettings = CodeInsightSettings.getInstance() val codeStyleSettings = JetCodeStyleSettings.getInstance(getProject()) - val optimizeImportsBefore = codeInsightSettings.OPTIMIZE_IMPORTS_ON_THE_FLY - val nameCountToUseStarBefore = codeStyleSettings.NAME_COUNT_TO_USE_STAR_IMPORT + val codeStyleSettingsSaved = codeStyleSettings.clone() as JetCodeStyleSettings + val optimizeImportsSaved = codeInsightSettings.OPTIMIZE_IMPORTS_ON_THE_FLY try { val fixture = myFixture @@ -54,17 +54,23 @@ public abstract class AbstractImportsTest : JetLightCodeInsightFixtureTestCase() val file = fixture.getFile() as JetFile codeInsightSettings.OPTIMIZE_IMPORTS_ON_THE_FLY = InTextDirectivesUtils.getPrefixedBoolean(file.getText(), "// OPTIMIZE_IMPORTS:") ?: false + codeStyleSettings.NAME_COUNT_TO_USE_STAR_IMPORT = InTextDirectivesUtils.getPrefixedInt(file.getText(), "// NAME_COUNT_TO_USE_STAR_IMPORT:") ?: nameCountToUseStarImportDefault + codeStyleSettings.IMPORT_PACKAGES = InTextDirectivesUtils.getPrefixedBoolean(file.getText(), "// IMPORT_PACKAGES:") ?: true + codeStyleSettings.IMPORT_NESTED_CLASSES = InTextDirectivesUtils.getPrefixedBoolean(file.getText(), "// IMPORT_NESTED_CLASSES:") ?: false getProject().executeWriteCommand("") { doTest(file) } - fixture.checkResultByFile(testPath + ".after") + JetTestUtils.assertEqualsToFile(File(testPath + ".after"), myFixture.getFile().getText()) } finally { - codeInsightSettings.OPTIMIZE_IMPORTS_ON_THE_FLY = optimizeImportsBefore - codeStyleSettings.NAME_COUNT_TO_USE_STAR_IMPORT = nameCountToUseStarBefore + codeInsightSettings.OPTIMIZE_IMPORTS_ON_THE_FLY = optimizeImportsSaved + + val root = Element("fake") + codeStyleSettingsSaved.writeExternal(root, codeStyleSettings) + codeStyleSettings.readExternal(root) } } diff --git a/idea/tests/org/jetbrains/kotlin/addImport/AddImportTestGenerated.java b/idea/tests/org/jetbrains/kotlin/addImport/AddImportTestGenerated.java index a06fa9a1a1a..bd21706542f 100644 --- a/idea/tests/org/jetbrains/kotlin/addImport/AddImportTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/addImport/AddImportTestGenerated.java @@ -143,6 +143,12 @@ public class AddImportTestGenerated extends AbstractAddImportTest { doTest(fileName); } + @TestMetadata("DoNotImportNestedClass.kt") + public void testDoNotImportNestedClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/addImport/DoNotImportNestedClass.kt"); + doTest(fileName); + } + @TestMetadata("DropExplicitImports.kt") public void testDropExplicitImports() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/addImport/DropExplicitImports.kt"); @@ -185,6 +191,12 @@ public class AddImportTestGenerated extends AbstractAddImportTest { doTest(fileName); } + @TestMetadata("ImportNestedClass.kt") + public void testImportNestedClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/addImport/ImportNestedClass.kt"); + doTest(fileName); + } + @TestMetadata("ImportPackage.kt") public void testImportPackage() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/addImport/ImportPackage.kt");