Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix import-ordering editorconifg generation #1011

Merged
merged 3 commits into from
Dec 16, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Fix import-ordering editorconifg generation
  • Loading branch information
romtsn committed Dec 14, 2020
commit 308701d091d345c27c035fb0f200c5705bc808d6
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import com.pinterest.ktlint.ruleset.standard.ImportOrderingRule.Companion.ASCII_
import com.pinterest.ktlint.ruleset.standard.ImportOrderingRule.Companion.IDEA_PATTERN
import com.pinterest.ktlint.ruleset.standard.internal.importordering.ImportSorter
import com.pinterest.ktlint.ruleset.standard.internal.importordering.PatternEntry
import com.pinterest.ktlint.ruleset.standard.internal.importordering.parseImportsLayout
import org.ec4j.core.model.PropertyType
import org.jetbrains.kotlin.com.intellij.lang.ASTNode
import org.jetbrains.kotlin.com.intellij.psi.PsiWhiteSpace
Expand Down Expand Up @@ -40,7 +39,7 @@ public class ImportOrderingRule :
Rule("import-ordering"),
UsesEditorConfigProperties {

private lateinit var importsLayout: List<PatternEntry>
private lateinit var importsLayout: String
private lateinit var importSorter: ImportSorter

public companion object {
Expand All @@ -55,7 +54,7 @@ public class ImportOrderingRule :
*
* https://developer.android.com/kotlin/style-guide#import_statements
*/
private val ASCII_PATTERN = parseImportsLayout("*")
private const val ASCII_PATTERN = "*"

/**
* Default IntelliJ IDEA style: Alphabetical with capital letters before lower case letters (e.g. Z before a),
Expand All @@ -65,7 +64,7 @@ public class ImportOrderingRule :
*
* https://github.com/JetBrains/kotlin/blob/ffdab473e28d0d872136b910eb2e0f4beea2e19c/idea/formatter/src/org/jetbrains/kotlin/idea/core/formatter/KotlinCodeStyleSettings.java#L87-L91
*/
private val IDEA_PATTERN = parseImportsLayout("*,java.**,javax.**,kotlin.**,^")
private const val IDEA_PATTERN = "*,java.**,javax.**,kotlin.**,^"

private const val IDEA_ERROR_MESSAGE = "Imports must be ordered in lexicographic order without any empty lines in-between " +
"with \"java\", \"javax\", \"kotlin\" and aliases in the end"
Expand All @@ -77,16 +76,12 @@ public class ImportOrderingRule :
ASCII_PATTERN to ASCII_ERROR_MESSAGE
)

private val editorConfigPropertyParser: (String, String?) -> PropertyType.PropertyValue<List<PatternEntry>> =
private val editorConfigPropertyParser: (String, String?) -> PropertyType.PropertyValue<String> =
{ _, value ->
when {
value == null -> PropertyType.PropertyValue.invalid(
value.isNullOrBlank() -> PropertyType.PropertyValue.invalid(
value,
"Null is not supported for import layout"
)
value.isBlank() -> PropertyType.PropertyValue.valid(
value,
emptyList()
"Import layout must contain at least one entry of a wildcard symbol (*)"
)
value == "idea" -> PropertyType.PropertyValue.valid(
value,
Expand All @@ -96,22 +91,15 @@ public class ImportOrderingRule :
value,
ASCII_PATTERN
)
else -> try {
PropertyType.PropertyValue.valid(
value,
parseImportsLayout(value)
)
} catch (e: IllegalArgumentException) {
PropertyType.PropertyValue.invalid(
value,
"Unexpected imports layout: $value"
)
}
else -> PropertyType.PropertyValue.valid(
value,
value
)
}
}

internal val ktlintCustomImportsLayoutProperty =
UsesEditorConfigProperties.EditorConfigProperty<List<PatternEntry>>(
UsesEditorConfigProperties.EditorConfigProperty<String>(
type = PropertyType(
KTLINT_CUSTOM_IMPORTS_LAYOUT_PROPERTY_NAME,
PROPERTY_DESCRIPTION,
Expand All @@ -122,7 +110,7 @@ public class ImportOrderingRule :
)

internal val ideaImportsLayoutProperty =
UsesEditorConfigProperties.EditorConfigProperty<List<PatternEntry>>(
UsesEditorConfigProperties.EditorConfigProperty<String>(
type = PropertyType(
IDEA_IMPORTS_LAYOUT_PROPERTY_NAME,
PROPERTY_DESCRIPTION,
Expand Down Expand Up @@ -220,13 +208,10 @@ public class ImportOrderingRule :

private fun EditorConfigProperties.resolveImportsLayout(
android: Boolean
): List<PatternEntry> = when {
containsKey(KTLINT_CUSTOM_IMPORTS_LAYOUT_PROPERTY_NAME) ->
getValue(KTLINT_CUSTOM_IMPORTS_LAYOUT_PROPERTY_NAME).getValueAs()
containsKey(IDEA_IMPORTS_LAYOUT_PROPERTY_NAME) ->
getValue(IDEA_IMPORTS_LAYOUT_PROPERTY_NAME).getValueAs()
else ->
if (android) ideaImportsLayoutProperty.defaultAndroidValue else ideaImportsLayoutProperty.defaultValue
): String = if (containsKey(KTLINT_CUSTOM_IMPORTS_LAYOUT_PROPERTY_NAME)) {
getEditorConfigValue(ktlintCustomImportsLayoutProperty, android)
} else {
getEditorConfigValue(ideaImportsLayoutProperty, android)
}

private fun importsAreEqual(actual: List<ASTNode>, expected: List<ASTNode>): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import org.jetbrains.kotlin.resolve.ImportPath
*
* Adopted from https://github.com/JetBrains/kotlin/blob/a270ee094c4d7b9520e0898a242bb6ce4dfcad7b/idea/src/org/jetbrains/kotlin/idea/util/ImportPathComparator.kt#L15
*/
internal class ImportSorter(
val patterns: List<PatternEntry>
) : Comparator<KtImportDirective> {
internal class ImportSorter(importsLayout: String) : Comparator<KtImportDirective> {

val patterns: List<PatternEntry> = parseImportsLayout(importsLayout)

override fun compare(import1: KtImportDirective, import2: KtImportDirective): Int {
val importPath1 = import1.importPath!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ internal class PatternEntry(
return entry.packageName.count { it == '.' } < packageName.count { it == '.' }
}

override fun toString(): String = packageName
override fun toString(): String = when (this) {
ALL_OTHER_IMPORTS_ENTRY -> WILDCARD_CHAR
ALL_OTHER_ALIAS_IMPORTS_ENTRY -> ALIAS_CHAR
else -> "$packageName.$WILDCARD_CHAR" + if (withSubpackages) WILDCARD_CHAR else ""
}

override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand All @@ -67,6 +71,6 @@ internal class PatternEntry(
companion object {
val BLANK_LINE_ENTRY = PatternEntry(BLANK_LINE_CHAR, withSubpackages = true, hasAlias = false)
val ALL_OTHER_IMPORTS_ENTRY = PatternEntry(WILDCARD_CHAR, withSubpackages = true, hasAlias = false)
val ALL_OTHER_ALIAS_IMPORTS_ENTRY = PatternEntry((ALIAS_CHAR + WILDCARD_CHAR), withSubpackages = true, hasAlias = true)
val ALL_OTHER_ALIAS_IMPORTS_ENTRY = PatternEntry(ALIAS_CHAR, withSubpackages = true, hasAlias = true)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.pinterest.ktlint.ruleset.standard.importordering

import com.pinterest.ktlint.core.api.EditorConfigProperties
import com.pinterest.ktlint.core.api.FeatureInAlphaState
import com.pinterest.ktlint.ruleset.standard.ImportOrderingRule
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test

@OptIn(FeatureInAlphaState::class)
class ImportOrderingEditorconfigTest {

@Test
fun `import ordering gets written correctly to editorconfig`() {
val properties: EditorConfigProperties = emptyMap()
val rule = ImportOrderingRule()
with(rule) {
val raw = properties.getEditorConfigValue(ImportOrderingRule.ideaImportsLayoutProperty).toString()
assertThat(raw).isEqualTo("*,java.**,javax.**,kotlin.**,^")
}
}
}