Code style setting to import nested classes

This commit is contained in:
Valentin Kipyatkov
2015-04-10 18:52:10 +03:00
parent be896b7d8e
commit 0f9858bb75
8 changed files with 51 additions and 27 deletions
@@ -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);
@@ -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<DeclarationDescriptor> {
return this.getImportableTargets(resolutionFacade.analyze(this, BodyResolveMode.PARTIAL))
}
private fun JetReferenceExpression.resolveTargets(): Collection<DeclarationDescriptor>
= 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))
}
}
@@ -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
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)
}
}
@@ -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");