Validate new file or class name for empty parts (KT-27903)

#KT-27903 Fixed
This commit is contained in:
Nikolay Krasko
2018-11-01 12:11:24 +03:00
parent 0e7520fde3
commit 9978ba4aaa
2 changed files with 93 additions and 2 deletions
@@ -35,9 +35,11 @@ import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.ui.InputValidatorEx
import com.intellij.psi.PsiDirectory
import com.intellij.psi.PsiFile
import com.intellij.util.IncorrectOperationException
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.KotlinIcons
import org.jetbrains.kotlin.idea.util.application.runWriteAction
@@ -86,6 +88,8 @@ class NewKotlinFileAction : CreateFileFromTemplateAction(
.addKind("Interface", KotlinIcons.INTERFACE, "Kotlin Interface")
.addKind("Enum class", KotlinIcons.ENUM, "Kotlin Enum")
.addKind("Object", KotlinIcons.OBJECT, "Kotlin Object")
builder.setValidator(NameValidator)
}
override fun getActionName(directory: PsiDirectory, newName: String, templateName: String) = "Kotlin File/Class"
@@ -114,7 +118,34 @@ class NewKotlinFileAction : CreateFileFromTemplateAction(
Companion.createFileFromTemplate(name, template, dir)
companion object {
private fun findOrCreateTarget(dir: PsiDirectory, name: String, directorySeparators: Array<Char>): Pair<String, PsiDirectory> {
private object NameValidator : InputValidatorEx {
override fun getErrorText(inputString: String): String? {
if (inputString.trim().isEmpty()) {
return "Name can't be empty"
}
val parts: List<String> = inputString.split(*FQNAME_SEPARATORS)
if (parts.any { it.trim().isEmpty() }) {
return "Name can't have empty parts"
}
return null
}
override fun checkInput(inputString: String): Boolean {
return true
}
override fun canClose(inputString: String): Boolean {
return getErrorText(inputString) == null
}
}
@get:TestOnly
val nameValidator: InputValidatorEx
get() = NameValidator
private fun findOrCreateTarget(dir: PsiDirectory, name: String, directorySeparators: CharArray): Pair<String, PsiDirectory> {
var className = name.substringBeforeLast(".kt")
var targetDir = dir
@@ -157,8 +188,11 @@ class NewKotlinFileAction : CreateFileFromTemplateAction(
return element?.containingFile
}
private val FILE_SEPARATORS = charArrayOf('/', '\\')
private val FQNAME_SEPARATORS = charArrayOf('/', '\\', '.')
fun createFileFromTemplate(name: String, template: FileTemplate, dir: PsiDirectory): PsiFile? {
val directorySeparators = if (template.name == "Kotlin File") arrayOf('/', '\\') else arrayOf('/', '\\', '.')
val directorySeparators = if (template.name == "Kotlin File") FILE_SEPARATORS else FQNAME_SEPARATORS
val (className, targetDir) = findOrCreateTarget(dir, name, directorySeparators)
val service = DumbService.getInstance(dir.project)
@@ -0,0 +1,57 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. 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.actions
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import org.junit.Assert
class NewKotlinFileActionTest: LightCodeInsightFixtureTestCase() {
companion object {
private val EMPTY_PARTS_ERROR = "Name can't have empty parts"
private val EMPTY_ERROR = "Name can't be empty"
}
fun testEmptyName() {
validateName("", EMPTY_ERROR)
}
fun testSpaces() {
validateName(" ", EMPTY_ERROR)
}
fun testEmptyEnd() {
validateName("Foo/", EMPTY_PARTS_ERROR)
}
fun testEmptyPartInQualified() {
validateName("a..b", EMPTY_PARTS_ERROR)
}
fun testFileWithKt() {
validateName("test.kt", null)
}
fun testFileWithUnixPathKt() {
validateName("a/b/test.kt", null)
}
fun testFileWithWinPathKt() {
validateName("a\\b\\test.kt", null)
}
fun testSimpleFile() {
validateName("some", null)
}
fun testSimpleFileWithPath() {
validateName("a/bb\\some", null)
}
private fun validateName(name: String, errorMessage: String?) {
val actualError = NewKotlinFileAction.nameValidator.getErrorText(name)
Assert.assertEquals("Invalid error message", errorMessage, actualError)
}
}