From 6ee78fb629054645c41016bd94b7d15b4ed63efd Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Fri, 25 Jan 2019 18:18:07 +0300 Subject: [PATCH] Refactoring: extract name verifier code to settings class --- .../NamingConventionInspections.kt | 95 +++++++++++++------ 1 file changed, 67 insertions(+), 28 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/NamingConventionInspections.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/NamingConventionInspections.kt index 3fae190a03a..9fbf373b01e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/NamingConventionInspections.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/NamingConventionInspections.kt @@ -18,6 +18,7 @@ import com.intellij.ui.EditorTextField import com.siyeh.ig.psiutils.TestUtils import org.intellij.lang.annotations.Language import org.intellij.lang.regexp.RegExpFileType +import org.jdom.Element import org.jetbrains.kotlin.idea.quickfix.RenameIdentifierFix import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* @@ -71,15 +72,18 @@ private val NO_BAD_CHARACTERS_OR_UNDERSCORE = NamingRule("may contain only lette it.any { c -> c !in 'a'..'z' && c !in 'A'..'Z' && c !in '0'..'9' && c != '_' } } -abstract class NamingConventionInspection( +class NamingConventionInspectionSettings( private val entityName: String, - @Language("RegExp") protected val defaultNamePattern: String, + @Language("RegExp") val defaultNamePattern: String, + private val setNamePatternCallback: ((value: String) -> Unit), private vararg val rules: NamingRule -) : AbstractKotlinInspection() { - protected var nameRegex: Regex? = defaultNamePattern.toRegex() +) { + var nameRegex: Regex? = defaultNamePattern.toRegex() + var namePattern: String = defaultNamePattern set(value) { field = value + setNamePatternCallback.invoke(value) nameRegex = try { value.toRegex() } catch (e: PatternSyntaxException) { @@ -87,7 +91,7 @@ abstract class NamingConventionInspection( } } - protected fun verifyName(element: PsiNameIdentifierOwner, holder: ProblemsHolder) { + fun verifyName(element: PsiNameIdentifierOwner, holder: ProblemsHolder) { val name = element.name val nameIdentifier = element.nameIdentifier if (name != null && nameIdentifier != null && nameRegex?.matches(name) == false) { @@ -108,9 +112,61 @@ abstract class NamingConventionInspection( return findRuleMessage(name, rules) ?: getDefaultErrorMessage() } - protected fun getDefaultErrorMessage() = "doesn't match regex '$namePattern'" + fun getDefaultErrorMessage() = "doesn't match regex '$namePattern'" - override fun createOptionsPanel() = NamingConventionOptionsPanel(this) + fun createOptionsPanel(): JPanel = NamingConventionOptionsPanel(this) + + private class NamingConventionOptionsPanel(settings: NamingConventionInspectionSettings) : JPanel() { + init { + layout = BorderLayout() + + val regexField = EditorTextField(settings.namePattern, null, RegExpFileType.INSTANCE).apply { + setOneLineMode(true) + } + regexField.document.addDocumentListener(object : DocumentAdapter() { + override fun documentChanged(e: DocumentEvent) { + settings.namePattern = regexField.text + } + }) + val labeledComponent = LabeledComponent.create(regexField, "Pattern:", BorderLayout.WEST) + add(labeledComponent, BorderLayout.NORTH) + } + } +} + + +sealed class NamingConventionInspection( + entityName: String, + @Language("RegExp") defaultNamePattern: String, + vararg rules: NamingRule +) : AbstractKotlinInspection() { + + // Serialized inspection state + @Suppress("MemberVisibilityCanBePrivate") + var namePattern: String = defaultNamePattern + + protected val namingSettings = NamingConventionInspectionSettings( + entityName, defaultNamePattern, + setNamePatternCallback = { value -> + namePattern = value + }, + rules = *rules + ) + + protected fun verifyName(element: PsiNameIdentifierOwner, holder: ProblemsHolder) { + namingSettings.verifyName(element, holder) + } + + protected fun getNameMismatchMessage(name: String): String { + return namingSettings.getNameMismatchMessage(name) + } + + override fun createOptionsPanel(): JPanel = namingSettings.createOptionsPanel() + + override fun readSettings(node: Element) { + super.readSettings(node) + namingSettings.namePattern = namePattern + } } class ClassNameInspection : NamingConventionInspection( @@ -252,11 +308,11 @@ class PackageNameInspection : return packageDirectiveVisitor { directive -> val packageNameExpression = directive.packageNameExpression ?: return@packageDirectiveVisitor val qualifiedName = directive.qualifiedName - if (qualifiedName.isEmpty() || nameRegex?.matches(qualifiedName) != false) { + if (qualifiedName.isEmpty() || namingSettings.nameRegex?.matches(qualifiedName) != false) { return@packageDirectiveVisitor } - val partErrorMessage = if (namePattern == defaultNamePattern) { + val partErrorMessage = if (namePattern == namingSettings.defaultNamePattern) { directive.packageNames.asSequence() .mapNotNull { simpleName -> val referencedName = simpleName.getReferencedName() @@ -270,7 +326,7 @@ class PackageNameInspection : val descriptionTemplate = if (partErrorMessage != null) { "Package name #ref part $partErrorMessage #loc" } else { - "Package name #ref ${getDefaultErrorMessage()} #loc" + "Package name #ref ${namingSettings.getDefaultErrorMessage()} #loc" } holder.registerProblem( @@ -287,21 +343,4 @@ class PackageNameInspection : return JavaPsiFacade.getInstance(element.project).findPackage(packageDirective.qualifiedName) } } -} - -class NamingConventionOptionsPanel(owner: NamingConventionInspection) : JPanel() { - init { - layout = BorderLayout() - - val regexField = EditorTextField(owner.namePattern, null, RegExpFileType.INSTANCE).apply { - setOneLineMode(true) - } - regexField.document.addDocumentListener(object : DocumentAdapter() { - override fun documentChanged(e: DocumentEvent) { - owner.namePattern = regexField.text - } - }) - val labeledComponent = LabeledComponent.create(regexField, "Pattern:", BorderLayout.WEST) - add(labeledComponent, BorderLayout.NORTH) - } -} +} \ No newline at end of file