Validate new file or class name for empty parts (KT-27903)
#KT-27903 Fixed
This commit is contained in:
@@ -35,9 +35,11 @@ import com.intellij.openapi.project.DumbAware
|
|||||||
import com.intellij.openapi.project.DumbService
|
import com.intellij.openapi.project.DumbService
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.roots.ProjectRootManager
|
import com.intellij.openapi.roots.ProjectRootManager
|
||||||
|
import com.intellij.openapi.ui.InputValidatorEx
|
||||||
import com.intellij.psi.PsiDirectory
|
import com.intellij.psi.PsiDirectory
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.util.IncorrectOperationException
|
import com.intellij.util.IncorrectOperationException
|
||||||
|
import org.jetbrains.annotations.TestOnly
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
@@ -86,6 +88,8 @@ class NewKotlinFileAction : CreateFileFromTemplateAction(
|
|||||||
.addKind("Interface", KotlinIcons.INTERFACE, "Kotlin Interface")
|
.addKind("Interface", KotlinIcons.INTERFACE, "Kotlin Interface")
|
||||||
.addKind("Enum class", KotlinIcons.ENUM, "Kotlin Enum")
|
.addKind("Enum class", KotlinIcons.ENUM, "Kotlin Enum")
|
||||||
.addKind("Object", KotlinIcons.OBJECT, "Kotlin Object")
|
.addKind("Object", KotlinIcons.OBJECT, "Kotlin Object")
|
||||||
|
|
||||||
|
builder.setValidator(NameValidator)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getActionName(directory: PsiDirectory, newName: String, templateName: String) = "Kotlin File/Class"
|
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.createFileFromTemplate(name, template, dir)
|
||||||
|
|
||||||
companion object {
|
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 className = name.substringBeforeLast(".kt")
|
||||||
var targetDir = dir
|
var targetDir = dir
|
||||||
|
|
||||||
@@ -157,8 +188,11 @@ class NewKotlinFileAction : CreateFileFromTemplateAction(
|
|||||||
return element?.containingFile
|
return element?.containingFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val FILE_SEPARATORS = charArrayOf('/', '\\')
|
||||||
|
private val FQNAME_SEPARATORS = charArrayOf('/', '\\', '.')
|
||||||
|
|
||||||
fun createFileFromTemplate(name: String, template: FileTemplate, dir: PsiDirectory): PsiFile? {
|
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 (className, targetDir) = findOrCreateTarget(dir, name, directorySeparators)
|
||||||
|
|
||||||
val service = DumbService.getInstance(dir.project)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user