com.github.shyiko.ktlint.ruleset.standard.FilenameRule.kt Maven / Gradle / Ivy
package com.github.shyiko.ktlint.ruleset.standard
import com.github.shyiko.ktlint.core.KtLint
import com.github.shyiko.ktlint.core.Rule
import com.github.shyiko.ktlint.core.ast.ElementType.BLOCK_COMMENT
import com.github.shyiko.ktlint.core.ast.ElementType.CLASS
import com.github.shyiko.ktlint.core.ast.ElementType.EOL_COMMENT
import com.github.shyiko.ktlint.core.ast.ElementType.FILE_ANNOTATION_LIST
import com.github.shyiko.ktlint.core.ast.ElementType.IDENTIFIER
import com.github.shyiko.ktlint.core.ast.ElementType.IMPORT_LIST
import com.github.shyiko.ktlint.core.ast.ElementType.KDOC
import com.github.shyiko.ktlint.core.ast.ElementType.OBJECT_DECLARATION
import com.github.shyiko.ktlint.core.ast.ElementType.PACKAGE_DIRECTIVE
import com.github.shyiko.ktlint.core.ast.ElementType.SHEBANG_COMMENT
import com.github.shyiko.ktlint.core.ast.ElementType.TYPEALIAS
import com.github.shyiko.ktlint.core.ast.ElementType.WHITE_SPACE
import com.github.shyiko.ktlint.core.ast.prevCodeSibling
import org.jetbrains.kotlin.com.intellij.lang.ASTNode
import org.jetbrains.kotlin.com.intellij.psi.tree.IElementType
import java.nio.file.Paths
/**
* If there is only one top level class/object/typealias in a given file, then its name should match the file's name.
*/
class FilenameRule : Rule("filename"), Rule.Modifier.RestrictToRoot {
private val ignoreSet = setOf(
FILE_ANNOTATION_LIST,
PACKAGE_DIRECTIVE,
IMPORT_LIST,
WHITE_SPACE,
EOL_COMMENT,
BLOCK_COMMENT,
KDOC,
SHEBANG_COMMENT
)
override fun visit(
node: ASTNode,
autoCorrect: Boolean,
emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit
) {
val filePath = node.getUserData(KtLint.FILE_PATH_USER_DATA_KEY)
if (filePath?.endsWith(".kt") != true) {
// ignore all non ".kt" files (including ".kts")
return
}
var type: String? = null
var className: String? = null
for (el in node.getChildren(null)) {
if (el.elementType == CLASS ||
el.elementType == OBJECT_DECLARATION ||
el.elementType == TYPEALIAS
) {
if (className != null) {
// more than one class/object/typealias present
return
}
val id = el.findChildByType(IDENTIFIER)
type = id?.prevCodeSibling()?.text
className = id?.text
} else if (!ignoreSet.contains(el.elementType)) {
// https://github.com/android/android-ktx/blob/51005889235123f41492eaaecde3c623473dfe95/src/main/java/androidx/core/graphics/Path.kt case
return
}
}
if (className != null) {
val unescapedClassName = className.replace("`", "")
val name = Paths.get(filePath).fileName.toString().substringBefore(".")
if (name != "package" && name != unescapedClassName) {
emit(0, "$type $className should be declared in a file named $unescapedClassName.kt", false)
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy