KT-10974 - add import layout configuration table
This commit is contained in:
+11
-5
@@ -13,8 +13,6 @@ import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.PackageEntry;
|
||||
import com.intellij.psi.codeStyle.PackageEntryTable;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -26,7 +24,8 @@ import org.jetbrains.kotlin.idea.util.ReflectionUtil;
|
||||
import static com.intellij.util.ReflectionUtil.copyFields;
|
||||
|
||||
public class KotlinCodeStyleSettings extends CustomCodeStyleSettings {
|
||||
public final PackageEntryTable PACKAGES_TO_USE_STAR_IMPORTS = new PackageEntryTable();
|
||||
public final KotlinPackageEntryTable PACKAGES_TO_USE_STAR_IMPORTS = new KotlinPackageEntryTable();
|
||||
public final KotlinPackageEntryTable PACKAGES_IMPORT_LAYOUT = new KotlinPackageEntryTable();
|
||||
public boolean SPACE_AROUND_RANGE = false;
|
||||
public boolean SPACE_BEFORE_TYPE_COLON = false;
|
||||
public boolean SPACE_AFTER_TYPE_COLON = true;
|
||||
@@ -78,8 +77,14 @@ public class KotlinCodeStyleSettings extends CustomCodeStyleSettings {
|
||||
|
||||
// defaults in IDE but not in tests
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
PACKAGES_TO_USE_STAR_IMPORTS.addEntry(new PackageEntry(false, "java.util", false));
|
||||
PACKAGES_TO_USE_STAR_IMPORTS.addEntry(new PackageEntry(false, "kotlinx.android.synthetic", true));
|
||||
PACKAGES_TO_USE_STAR_IMPORTS.addEntry(new KotlinPackageEntry("java.util", false));
|
||||
PACKAGES_TO_USE_STAR_IMPORTS.addEntry(new KotlinPackageEntry("kotlinx.android.synthetic", true));
|
||||
|
||||
PACKAGES_IMPORT_LAYOUT.addEntry(KotlinPackageEntry.ALL_OTHER_IMPORTS_ENTRY);
|
||||
PACKAGES_IMPORT_LAYOUT.addEntry(new KotlinPackageEntry("java", true));
|
||||
PACKAGES_IMPORT_LAYOUT.addEntry(new KotlinPackageEntry("javax", true));
|
||||
PACKAGES_IMPORT_LAYOUT.addEntry(new KotlinPackageEntry("kotlin", true));
|
||||
PACKAGES_IMPORT_LAYOUT.addEntry(KotlinPackageEntry.ALL_OTHER_ALIAS_IMPORTS_ENTRY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +109,7 @@ public class KotlinCodeStyleSettings extends CustomCodeStyleSettings {
|
||||
private void copyFrom(@NotNull KotlinCodeStyleSettings from) {
|
||||
copyFields(getClass().getFields(), from, this);
|
||||
PACKAGES_TO_USE_STAR_IMPORTS.copyFrom(from.PACKAGES_TO_USE_STAR_IMPORTS);
|
||||
PACKAGES_IMPORT_LAYOUT.copyFrom(from.PACKAGES_IMPORT_LAYOUT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.core.formatter
|
||||
|
||||
import org.jetbrains.kotlin.resolve.ImportPath
|
||||
|
||||
data class KotlinPackageEntry(
|
||||
val packageName: String,
|
||||
val withSubpackages: Boolean
|
||||
) {
|
||||
companion object {
|
||||
@JvmField
|
||||
val ALL_OTHER_IMPORTS_ENTRY = KotlinPackageEntry("<all other imports>", withSubpackages = true)
|
||||
|
||||
@JvmField
|
||||
val ALL_OTHER_ALIAS_IMPORTS_ENTRY = KotlinPackageEntry("<all other alias imports>", withSubpackages = true)
|
||||
}
|
||||
|
||||
fun matchesPackageName(otherPackageName: String): Boolean {
|
||||
if (this == ALL_OTHER_IMPORTS_ENTRY || this == ALL_OTHER_ALIAS_IMPORTS_ENTRY) return true
|
||||
|
||||
if (otherPackageName.startsWith(packageName)) {
|
||||
if (otherPackageName.length == packageName.length) return true
|
||||
if (withSubpackages) {
|
||||
if (otherPackageName[packageName.length] == '.') return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun isBetterMatchForPackageThan(entry: KotlinPackageEntry?, path: ImportPath): Boolean {
|
||||
if (!matchesPackageName(path.pathStr)) return false
|
||||
if (entry == null) return true
|
||||
|
||||
if (this == ALL_OTHER_ALIAS_IMPORTS_ENTRY && path.hasAlias()) return true
|
||||
if (entry == ALL_OTHER_ALIAS_IMPORTS_ENTRY && path.hasAlias()) return false
|
||||
|
||||
if (entry == ALL_OTHER_IMPORTS_ENTRY && this != ALL_OTHER_ALIAS_IMPORTS_ENTRY) return true
|
||||
if (this == ALL_OTHER_IMPORTS_ENTRY && entry != ALL_OTHER_ALIAS_IMPORTS_ENTRY) return false
|
||||
if (entry.withSubpackages != withSubpackages) return !withSubpackages
|
||||
|
||||
return entry.packageName.count { it == '.' } < packageName.count { it == '.' }
|
||||
}
|
||||
|
||||
val isSpecial: Boolean get() {
|
||||
return (this == ALL_OTHER_IMPORTS_ENTRY || this == ALL_OTHER_ALIAS_IMPORTS_ENTRY)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return packageName
|
||||
}
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.core.formatter
|
||||
|
||||
import com.intellij.openapi.util.InvalidDataException
|
||||
import com.intellij.openapi.util.JDOMExternalizable
|
||||
import org.jdom.Element
|
||||
|
||||
class KotlinPackageEntryTable: JDOMExternalizable, Cloneable {
|
||||
private val entries = mutableListOf<KotlinPackageEntry>()
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is KotlinPackageEntryTable) return false
|
||||
if (other.entries.size != entries.size) return false
|
||||
|
||||
return entries.zip(other.entries).any { (entry, otherEntry) -> entry != otherEntry }
|
||||
}
|
||||
|
||||
public override fun clone(): KotlinPackageEntryTable {
|
||||
val clone = KotlinPackageEntryTable()
|
||||
clone.copyFrom(this)
|
||||
return clone
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return entries.firstOrNull()?.hashCode() ?: 0
|
||||
}
|
||||
|
||||
fun copyFrom(packageTable: KotlinPackageEntryTable) {
|
||||
entries.clear()
|
||||
entries.addAll(packageTable.entries)
|
||||
}
|
||||
|
||||
fun getEntries(): Array<KotlinPackageEntry> {
|
||||
return entries.toTypedArray()
|
||||
}
|
||||
|
||||
fun insertEntryAt(entry: KotlinPackageEntry, index: Int) {
|
||||
entries.add(index, entry)
|
||||
}
|
||||
|
||||
fun removeEntryAt(index: Int) {
|
||||
entries.removeAt(index)
|
||||
}
|
||||
|
||||
fun getEntryAt(index: Int): KotlinPackageEntry {
|
||||
return entries[index]
|
||||
}
|
||||
|
||||
fun getEntryCount(): Int {
|
||||
return entries.size
|
||||
}
|
||||
|
||||
fun setEntryAt(entry: KotlinPackageEntry, index: Int) {
|
||||
entries[index] = entry
|
||||
}
|
||||
|
||||
operator fun contains(packageName: String): Boolean {
|
||||
for (entry in entries) {
|
||||
if (packageName.startsWith(entry.packageName)) {
|
||||
if (packageName.length == entry.packageName.length) return true
|
||||
if (entry.withSubpackages) {
|
||||
if (packageName[entry.packageName.length] == '.') return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun removeEmptyPackages() {
|
||||
entries.removeAll { it.packageName.isBlank() }
|
||||
}
|
||||
|
||||
fun addEntry(entry: KotlinPackageEntry) {
|
||||
entries.add(entry)
|
||||
}
|
||||
|
||||
override fun readExternal(element: Element) {
|
||||
entries.clear()
|
||||
|
||||
element.children.forEach {
|
||||
if (it.name == "package") {
|
||||
val packageName = it.getAttributeValue("name") ?: throw InvalidDataException()
|
||||
val alias = it.getAttributeValue("alias")?.toBoolean() ?: false
|
||||
val withSubpackages = it.getAttributeValue("withSubpackages")?.toBoolean() ?: false
|
||||
|
||||
val entry = when {
|
||||
packageName.isEmpty() && !alias -> KotlinPackageEntry.ALL_OTHER_IMPORTS_ENTRY
|
||||
packageName.isEmpty() && alias -> KotlinPackageEntry.ALL_OTHER_ALIAS_IMPORTS_ENTRY
|
||||
else -> KotlinPackageEntry(packageName, withSubpackages)
|
||||
}
|
||||
|
||||
entries.add(entry)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun writeExternal(parentNode: Element) {
|
||||
for (entry in entries) {
|
||||
val element = Element("package")
|
||||
parentNode.addContent(element)
|
||||
val name = if (entry == KotlinPackageEntry.ALL_OTHER_IMPORTS_ENTRY || entry == KotlinPackageEntry.ALL_OTHER_ALIAS_IMPORTS_ENTRY) "" else entry.packageName
|
||||
val alias = (entry == KotlinPackageEntry.ALL_OTHER_ALIAS_IMPORTS_ENTRY)
|
||||
|
||||
element.setAttribute("name", name)
|
||||
element.setAttribute("alias", alias.toString())
|
||||
element.setAttribute("withSubpackages", entry.withSubpackages.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user