Code style setting to import nested classes
This commit is contained in:
@@ -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 int NAME_COUNT_TO_USE_STAR_IMPORT = ApplicationManager.getApplication().isUnitTestMode() ? Integer.MAX_VALUE : 5;
|
||||||
public boolean IMPORT_PACKAGES = true;
|
public boolean IMPORT_PACKAGES = true;
|
||||||
|
public boolean IMPORT_NESTED_CLASSES = false;
|
||||||
|
|
||||||
public static JetCodeStyleSettings getInstance(Project project) {
|
public static JetCodeStyleSettings getInstance(Project project) {
|
||||||
return CodeStyleSettingsManager.getSettings(project).getCustomSettings(JetCodeStyleSettings.class);
|
return CodeStyleSettingsManager.getSettings(project).getCustomSettings(JetCodeStyleSettings.class);
|
||||||
|
|||||||
@@ -139,13 +139,18 @@ public class ImportInsertHelperImpl(private val project: Project) : ImportInsert
|
|||||||
val importable = descriptor.getImportableDescriptor()
|
val importable = descriptor.getImportableDescriptor()
|
||||||
return when (importable) {
|
return when (importable) {
|
||||||
is PackageViewDescriptor -> JetCodeStyleSettings.getInstance(project).IMPORT_PACKAGES
|
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 {
|
override fun importDescriptor(file: JetFile, descriptor: DeclarationDescriptor)
|
||||||
return Importer(file).importDescriptor(descriptor)
|
= Importer(file).importDescriptor(descriptor)
|
||||||
}
|
|
||||||
|
|
||||||
private inner class Importer(
|
private inner class Importer(
|
||||||
private val file: JetFile
|
private val file: JetFile
|
||||||
@@ -155,11 +160,11 @@ public class ImportInsertHelperImpl(private val project: Project) : ImportInsert
|
|||||||
|
|
||||||
fun importDescriptor(descriptor: DeclarationDescriptor): ImportDescriptorResult {
|
fun importDescriptor(descriptor: DeclarationDescriptor): ImportDescriptorResult {
|
||||||
val target = descriptor.getImportableDescriptor()
|
val target = descriptor.getImportableDescriptor()
|
||||||
|
if (!target.canBeReferencedViaImport()) return ImportDescriptorResult.FAIL
|
||||||
|
|
||||||
val name = target.getName()
|
val name = target.getName()
|
||||||
val topLevelScope = resolutionFacade.getFileTopLevelScope(file)
|
val topLevelScope = resolutionFacade.getFileTopLevelScope(file)
|
||||||
|
val targetFqName = target.importableFqNameSafe
|
||||||
val targetFqName = target.importableFqName ?: return ImportDescriptorResult.FAIL
|
|
||||||
|
|
||||||
// check if import is not needed
|
// check if import is not needed
|
||||||
when (target) {
|
when (target) {
|
||||||
@@ -174,11 +179,6 @@ public class ImportInsertHelperImpl(private val project: Project) : ImportInsert
|
|||||||
return ImportDescriptorResult.FAIL
|
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)
|
val imports = if (file is JetCodeFragment)
|
||||||
file.importsAsImportList()?.getImports() ?: listOf()
|
file.importsAsImportList()?.getImports() ?: listOf()
|
||||||
else
|
else
|
||||||
@@ -379,16 +379,13 @@ public class ImportInsertHelperImpl(private val project: Project) : ImportInsert
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun targetFqName(ref: JetReferenceExpression): FqName? {
|
private fun targetFqName(ref: JetReferenceExpression): FqName?
|
||||||
return ref.resolveTargets().map { it.importableFqName }.toSet().singleOrNull()
|
= ref.resolveTargets().map { it.importableFqName }.toSet().singleOrNull()
|
||||||
}
|
|
||||||
|
|
||||||
private fun JetReferenceExpression.resolveTargets(): Collection<DeclarationDescriptor> {
|
private fun JetReferenceExpression.resolveTargets(): Collection<DeclarationDescriptor>
|
||||||
return this.getImportableTargets(resolutionFacade.analyze(this, BodyResolveMode.PARTIAL))
|
= this.getImportableTargets(resolutionFacade.analyze(this, BodyResolveMode.PARTIAL))
|
||||||
}
|
|
||||||
|
|
||||||
private fun addImport(fqName: FqName, allUnder: Boolean): JetImportDirective {
|
private fun addImport(fqName: FqName, allUnder: Boolean): JetImportDirective
|
||||||
return addImport(file, ImportPath(fqName, allUnder))
|
= addImport(file, ImportPath(fqName, allUnder))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
// IMPORT: kotlin.Map.Entry
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Failed to add import
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
// IMPORT: kotlin.Map.Entry
|
||||||
|
// IMPORT_NESTED_CLASSES: true
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import kotlin.Map.*
|
||||||
|
|
||||||
|
// IMPORT: kotlin.Map.Entry
|
||||||
|
// IMPORT_NESTED_CLASSES: true
|
||||||
@@ -17,11 +17,11 @@
|
|||||||
package org.jetbrains.kotlin
|
package org.jetbrains.kotlin
|
||||||
|
|
||||||
import com.intellij.codeInsight.CodeInsightSettings
|
import com.intellij.codeInsight.CodeInsightSettings
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import org.jdom.Element
|
||||||
import com.intellij.openapi.command.CommandProcessor
|
|
||||||
import org.jetbrains.kotlin.idea.JetLightCodeInsightFixtureTestCase
|
import org.jetbrains.kotlin.idea.JetLightCodeInsightFixtureTestCase
|
||||||
import org.jetbrains.kotlin.idea.JetWithJdkAndRuntimeLightProjectDescriptor
|
import org.jetbrains.kotlin.idea.JetWithJdkAndRuntimeLightProjectDescriptor
|
||||||
import org.jetbrains.kotlin.idea.core.formatter.JetCodeStyleSettings
|
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.idea.util.application.executeWriteCommand
|
||||||
import org.jetbrains.kotlin.psi.JetFile
|
import org.jetbrains.kotlin.psi.JetFile
|
||||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||||
@@ -35,8 +35,8 @@ public abstract class AbstractImportsTest : JetLightCodeInsightFixtureTestCase()
|
|||||||
protected fun doTest(testPath: String) {
|
protected fun doTest(testPath: String) {
|
||||||
val codeInsightSettings = CodeInsightSettings.getInstance()
|
val codeInsightSettings = CodeInsightSettings.getInstance()
|
||||||
val codeStyleSettings = JetCodeStyleSettings.getInstance(getProject())
|
val codeStyleSettings = JetCodeStyleSettings.getInstance(getProject())
|
||||||
val optimizeImportsBefore = codeInsightSettings.OPTIMIZE_IMPORTS_ON_THE_FLY
|
val codeStyleSettingsSaved = codeStyleSettings.clone() as JetCodeStyleSettings
|
||||||
val nameCountToUseStarBefore = codeStyleSettings.NAME_COUNT_TO_USE_STAR_IMPORT
|
val optimizeImportsSaved = codeInsightSettings.OPTIMIZE_IMPORTS_ON_THE_FLY
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val fixture = myFixture
|
val fixture = myFixture
|
||||||
@@ -54,17 +54,23 @@ public abstract class AbstractImportsTest : JetLightCodeInsightFixtureTestCase()
|
|||||||
val file = fixture.getFile() as JetFile
|
val file = fixture.getFile() as JetFile
|
||||||
|
|
||||||
codeInsightSettings.OPTIMIZE_IMPORTS_ON_THE_FLY = InTextDirectivesUtils.getPrefixedBoolean(file.getText(), "// OPTIMIZE_IMPORTS:") ?: false
|
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.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("") {
|
getProject().executeWriteCommand("") {
|
||||||
doTest(file)
|
doTest(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
fixture.checkResultByFile(testPath + ".after")
|
JetTestUtils.assertEqualsToFile(File(testPath + ".after"), myFixture.getFile().getText())
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
codeInsightSettings.OPTIMIZE_IMPORTS_ON_THE_FLY = optimizeImportsBefore
|
codeInsightSettings.OPTIMIZE_IMPORTS_ON_THE_FLY = optimizeImportsSaved
|
||||||
codeStyleSettings.NAME_COUNT_TO_USE_STAR_IMPORT = nameCountToUseStarBefore
|
|
||||||
|
val root = Element("fake")
|
||||||
|
codeStyleSettingsSaved.writeExternal(root, codeStyleSettings)
|
||||||
|
codeStyleSettings.readExternal(root)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -143,6 +143,12 @@ public class AddImportTestGenerated extends AbstractAddImportTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("DoNotImportNestedClass.kt")
|
||||||
|
public void testDoNotImportNestedClass() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/addImport/DoNotImportNestedClass.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("DropExplicitImports.kt")
|
@TestMetadata("DropExplicitImports.kt")
|
||||||
public void testDropExplicitImports() throws Exception {
|
public void testDropExplicitImports() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/addImport/DropExplicitImports.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/addImport/DropExplicitImports.kt");
|
||||||
@@ -185,6 +191,12 @@ public class AddImportTestGenerated extends AbstractAddImportTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ImportNestedClass.kt")
|
||||||
|
public void testImportNestedClass() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/addImport/ImportNestedClass.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("ImportPackage.kt")
|
@TestMetadata("ImportPackage.kt")
|
||||||
public void testImportPackage() throws Exception {
|
public void testImportPackage() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/addImport/ImportPackage.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/addImport/ImportPackage.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user